關於深度神經網路壓縮(下)
關於深度神經網路壓縮(上) | 「小聲嘟囔」專欄
本篇文章是來自集智俱樂部粉絲趙威的投稿,趙威是集智俱樂部粉絲,也是華米科技的演算法工程師,中科院遙感與數字地球所博士,研究興趣在於深度學習,視覺目標識別,人體生物信號識別。本篇文章主要是關於深度神經網路壓縮的一些方法討論,具體內容如下:
上半部分主要介紹了SqueezeNet[1]和 Deep Compression[2]兩篇文章,前者主要思路是通過使用更小的卷積核(1*1)來設計網路架構,讓參數數量變少;後者主要思路是通過網路剪枝、參數壓縮讓網路模型文件變小。
導語
今天要分享的兩篇文章則是探討網路壓縮的另一個重要方向:網路二值化,也就是用1bit的數去代替傳統網路中的單精度浮點係數。二值化的係數大小是單精度浮點數值的1/32,也就是可以將網路壓縮到原來的3%。其實我覺得二值化的神經網路與人腦應該更加相似,我們大腦中的每個神經元只能傳導興奮、抑制兩種狀態,而無法傳導很精確的數值,所以雖然現在二值網路暫時比單精度網路性能略低,但我們完全有理由相信單精度網路能做到的,二值網路應該都能做到。
二值網路最早的突破是Matthieu於2015年11月發表的BinaryConnect[3],它實現了網路權重係數的二值化,但只能達到2倍的加速度。不過三個月後,Matthieu發表了BinaryNet [4],實現了權重係數和中間結果的二值化,由於中間結果的二值化,BinaryNet能夠達到7倍的加速。之後,Mohammad改進BinaryNet的得到XNOR-Net[4],實現了輸入數據、權重係數全部二值化,相比Alexnet,它能達到58倍的加速。
BinaryNet
1. 二值化
浮點型係數的二值化有兩種思路,一種是根據係數的符號轉換為+1/-1,如下:
第二種方法是按照根據浮點數算出一個概率p,按照這個概率將它變成+1/-1。
從數學上講,概率轉換更好,但是要去不斷產生隨機數,是很難實現的,所以文章還是用第一種方法進行二值化。
2. 訓練時梯度計算與更新
BinaryNet其實並沒有完全二值化,而是在訓練時保持了一份浮點型的權重,在前向傳播時,要先把浮點型權重二值化,然後再做卷積。
另一個問題是,Sign(x)函數的梯度都是零,那就無法用梯度下降法來訓練網路了,所以文章用一個Hard tanh函數(圖 1)來近似Sign(x)函數,這樣反向傳播時,就可以計算梯度了。
值得注意的是,既然前向傳播時我們使用的是二值化權值,那麼這裡計算得到的梯度也是相對於的,但在做權值更新時,我們是對浮點型權值進行更新,這主要還是因為二值化權值很難做小幅的更新調整。
圖 1 Sign函數與Htanh函數
3. 卷積計算的優化
在CNN網路中最主要的計算就是卷積 ,其本質來說是兩個向量按位相乘後相加,而在二值網路中,權值矩陣和激活值都二值化後,卷積操作可以用簡單的位操作來實現。
假設一個二值激活向量和一個二值權重向量做卷積,結果累加到,我們可以通過以下位操作實現:
其中popcount的是計算一串二進位中有多少個1,xnor就是對兩個二進位串按位取異或,這樣比逐個做乘法,再累加減少了大量計算。
BinaryNet的優勢主要在於其預測時的速度快(在GPU上快了7倍),佔用內存小(與32bit DNN相比,它的內存佔用減少了32倍),內存訪問是比計算耗能更大的操作,所以內存減小對能耗的降低非常顯著。
XNOR-Net
Xnor-net其實和BinaryNet整體思路也是差不多的,只是在二值化上做得更加徹底,它將輸入、權重、中間結果、反向傳播梯度等全部二值化了,從而達到了更高的加速比,當然完全二值化後,性能降低了。
1. 二值化
與BinaryNet直接用符號將權值二值化為+1/-1,Xnor-net的做法略有不同,假設權重矩陣為,文章提出用一個標量和二值矩陣的乘積來近似,即通過簡單推導(見論文),可以發現,也就是說二值矩陣可以由符號函數Sign得到,而標量係數可以由實值權重絕對值的平均值來近似。這是對權重矩陣的二值化,對輸入數據二值化也是一樣,假設輸入數據,也可以將其近似為一個標量和二值矩陣的乘積,即,其中, 與BinaryNet相比,在二值化時加入了一個標量係數,表達能力是能夠得到一些增加的。
圖 2 是作者給出的上述二值化思路示意圖,其中輸入X的二值化有一些技巧,圖中(2)是直接按照一個個卷積核的大小去對輸入的每個數據塊去計算標量係數,這樣其實有很多的冗餘計算,圖中(3)是作者實際使用的快速做法,也就是先將輸入的每個像素點所有通道(channel)值求平均,將三維輸入轉成二維矩陣A,然後在二維矩陣A上做局域平均來計算每個卷積區域的係數。最終效果是將卷積操作近似成計算成本低得多的二值操作與標量的乘法操作,如下式所示:
圖 2 卷積層輸入、權重二值化的思路圖示
2. 其他優化
一般的CNN網路中,一個完整的卷積層是按照1)卷積,2)Batch Normalize,3)激活,4)池化這樣的順序進行的,然而對二值化後,每層的激活值都是二值的,對二值數組做MaxPool後,大部分值都會變成+1,這樣數據信息就丟失了,所以XNOR-net做了個調整,將池化放在卷積之後,而把Batch Normalize用在輸入數據上。不過個人感覺這樣一個小的trick,似乎不太有什麼好的理論支撐,通用性也有待驗證。
圖 3 XNOR-net與典型CNN網路中卷積層的順序區別
與BinaryNet一樣,因為訓練時,要採用隨機梯度下降法,而符號函數會使得梯度消失,所以在訓練時要使用一個實值的權重來做訓練。
通過二值化,原先的卷積操作中的乘法,都可以轉換成二值位運算的異或操作和操作,這與BinaryNet思路也是一樣的,只不過現在所有地方都二值化了,都可以這樣優化計算了。
XNOR-net將Alexnet二值化後再Imagenet上做了分類實驗,預測速度提升了58倍,但分類精度下降了超過10個點。
總結
總的來說,SqueezeNet、DeepCompression兩篇文章討論的思路更加清晰直接,效果非常好,也容易去重複實驗;而BinaryNet和XnorNet這兩篇文章討論的網路二值化,其實還是有很大未知的方向,由於目前還缺乏比較好的二值網路底層框架,二值化後分類性能的降低,在不同網路架構上的可擴展性都還有很大問題,所以網路二值化在學術界還沒有受到非常大的重視,不過從工業界的角度來考慮,網路二值化所能帶來的價值是非常重大的,目前很多公司都已經在投入資源研發深度學習晶元,相信不久的將來二值化神經網路會和深度學習晶元一道成熟起來。
參考文獻
[1]. Iandola F N, Moskewicz M W, Ashraf K, et al. SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 1MB model size[J]. arXiv preprint arXiv:1602.07360, 2016.
[2]. Han S, Mao H, Dally W J. Deep compression: Compressing deep neural network with pruning, trained quantization and huffman coding[J]. CoRR, abs/1510.00149, 2015, 2.
[3]. Courbariaux M, Bengio Y, David J P. Binaryconnect: Training deep neural networks with binary weights during propagations[C]//Advances in Neural Information Processing Systems. 2015: 3123-3131.
[4]. Courbariaux M, Bengio Y. Binarynet: Training deep neural networks with weights and activations constrained to+ 1 or-1[J]. arXiv preprint arXiv:1602.02830, 2016.
[5]. Rastegari M, Ordonez V, Redmon J, et al. XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks[J]. arXiv preprint arXiv:1603.05279, 2016.
如果想了解更多的深度學習的框架,請搜索集智俱樂部公眾號
推薦閱讀:
※數學 · 神經網路(四)· Normalize
※神經網路與TensorFlow實踐-前言
※C++實現神經網路之一 | Net類的設計和神經網路的初始化
※Faster R-CNN
TAG:深度学习DeepLearning | 神经网络 | 压缩 |