論文:XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks
連結:https://arxiv.org/abs/1603.05279
代碼位址:http://allenai.org/plato/xnornet
模型壓縮和加速是深度學習算法應用在移動端必須要解決的問題,也是近年來的研究熱點,這篇ECCV2016的文章就是做這樣的事。在這篇文章中作者主要提到兩種二值化網絡:Binary-Weight-Networks和XNOR-Networks。Figure1簡單列出了這兩種網絡和标準的卷積網絡的差别,根據實驗結果,這裡主網絡應該采用的是AlexNet。Binary-Weight-Networks通過對權重W做二值化操作,達到減少模型存儲空間的目的,準确率影響并不明顯(不過後面在ResNet-18上的實驗對準确率的影響還比較大)。XNOR-Networks通過同時對權重W和輸入I做二值化操作,達到既減少模型存儲空間,又加速模型的目的,當然準确率影響也比較明顯。

接下來依次介紹這兩種二值化網絡,另外這裡說的權重是指網絡中的卷積層參數和全連接配接層參數,因為全連接配接層可以用卷積層代替,是以接下來我都用卷積層來介紹二值化操作。
Binary-Weight-Networks
首先Binary-weights的目的是将權重W的值都用二值表示,也就是W的值要麼是-1,要麼是1。這個替代過程貫穿整個forward和backward過程,但是在更新參數時候還是采用原來的權重W,主要是因為更新參數需要的精度比較高。
接下來詳細介紹怎麼實作和公式推導,公式部分雖然多,但是很簡單。一個卷積層的操作可以用I*W表示,I表示輸入,次元是c*win*hin,W表示卷積核(或者叫權重),次元是c*w*h。那麼當我用二值卷積核B以及一個尺度參數a代替原來的卷積核W,那麼就可以得到下面這個式子:
這裡有個圓圈裡面帶加号的符号表示沒有乘法的卷積計算。這裡:
注意這裡a預設是個正數,a和B是相對的,因為如果a和B都取相反數的話,二者相乘的結果不變。前面的B和W表示某一層的卷積操作的寫法,因為每一層卷積都包含多個卷積核,是以如果具體到某一層的某個卷積操作,則可以用下面這個式子表示:
下标lk表示第l層的第k個卷積核。這裡
既然我們希望用一個尺度參數a和二值矩陣B來代替原來的權重W,那麼肯定希望前者能盡可能等于後者,于是就有了下面的優化目标函數,也就是希望下面這個式子中的J越小越好,這種情況下的a和B就是我們需要的。另外這裡将矩陣W和B變換成向量,也就是W和B的次元是1*n,這裡n=c*w*h,這主要是為了後面推導的友善。
是以接下來就是要求a和B的最優值,使得滿足上面那個優化目标。那麼這個優化具體要怎麼實作呢?來看作者的推導。上面那個優化函數展開後可以寫成下面這個形式。應該比較容易了解。
因為B是一個1*n的向量,裡面的值要麼是-1,要麼是1,是以:
也就是一個常量。同時因為W是已知的,是以:
也是一個常量。另外a是個正數。這些常量在優化函數中都可以去掉,不影響優化結果。就可以得到B的最優值的計算公式(可以結合前面第一個和第二個優化函數看):
顯然,根據這個式子,B的最優值就是W的值的符号。也就是(這個式子是求B最優值的最終式子):
舉個例子,當W中某個位置的值是正數時,B中對應位置的值就是+1,反之為-1.
知道了B的最優值,接下來就是求a的最優值。這裡采用上面第2個J函數表達式對a求導,并讓求導結果等于0,進而得到最優值。式子如下:
通過簡單換算并利用前面計算得到的B的最優值就可以得到下面這個求a最優值的最終的式子:
也就是說a的最優值是W的每個元素的絕對值之和的均值。|| ||l1表示一範數。
是以Binary-Weight-Networks的算法總結可以看下面這個介紹:第一個for循環是周遊所有層,第二個for循環是周遊某一層的所有卷積核。通過得到Alk和Blk就可以近似約等于原來的權重Wlk了,另外在backward過程中的梯度計算也是基于二值權重。
XNOR-Networks
前面介紹的Binary-weights是将權重W的值都用二值表示,而接下來要介紹的XNOR-Networks不僅将權重W用二值表示,而且也将輸入用二值表示。
XNOR又叫同或門,假設輸入是0或1,那麼當兩個輸入相同時輸出為1,當兩個輸入不同時輸出為0。
我們知道卷積操作就是用卷積核去點乘(element-wise product)輸入的某個區域然後得到最後的值,是以假設你的輸入是X,卷積核是W,那麼我們就希望得到β,H,a和B使得:
這裡是用βH近似表示輸入X,另外:
是以就有了下面這個優化式子:
這裡有個符号是圓圈中有的點号,表示的是element-wise product,也就是點乘(dot product)。如果用Y代替XW,C代替HB,γ=βa,那麼優化式子就變成下面這樣:
這個式子就和Binary-Weight-Networks部分介紹的優化式子:
類似。
是以可以利用Binary-Weight-Networks的推導結果來解這個優化式子。根據前面a和B的計算公式,相應可以得到這裡C和γ的計算公式(就是下面兩個式子的第一個等号):
γ式子的第二個等号是因為|Xi|和|Wi|是互相獨立的,是以可以直接拆開。
兩個等式的最右端就是4個參數的最優解。以上就是關于輸入和權值都二值化的最優值的解。
接下來的Figure2是具體的二值操作。第一行就是前面介紹的Binary-Weight-Networks的最優值的求解。第二行是XNOR-Networks的最優值的求解,不過因為存在重複計算,是以采用第三行的方式,c表示通道數,A是通過對輸入I求均值得到的。第四行其實和第三行含義是一樣的,更加完整地表達了XNOR的計算過程,這裡的K就是第三行計算得到的K,中括号裡面的式子就是剛剛計算得到的最優的C。
這裡第四行有個符号是圓圈裡面有個*,表示的是convolutional opration using XNOR and bitcount operation。也就是說正常兩個矩陣之間的點乘如果用在兩個二值矩陣之間,那麼就可以将點乘換成XNOR-Bitcounting operation,從32位浮點數之間的操作直接變成1位的XNOR門操作,這就是加速的核心。
實際添加了XNOR的網絡如Figure3所示。設計細節可以參看論文。
實驗結果:
Table1是兩種二值化方式和其他二值化方式的對比。最後的Full-Precision是不經過二值化的模型準确率。
Table2是兩種二值化方式和正常的ResNet18的準确率對比,可以看出在ResNet18上Binary-Weight-Networks對準确率的影響也比較大。
其他更多實驗結果可以參看論文。