過二值化,使模型的引數佔用更小的儲存空間;同時利用位移操作來代替網路中的乘法運算,大大降低了運算時間。
1、二值化
二值網路的二值化方法有兩種,一種是Deterministic(確定性方法),一種是Stochastic(機率統計方法)。
Deterministic方法:大於0就為+1,小於0則為-1。
Stochastic方法:對x計算一個機率p,當p大於一個闕值(計算機隨機產生)時為+1,否則為-1。
其中,
由於Stochastic方法需要由硬體生成隨機數,這比較難實施。所以論文中的實驗用的是Deterministic方法。
2、權值更新演算法
在理解權值更新之前,先看看前向傳播演算法。下圖為論文中給出的第一個演算法,該演算法是二值網路的訓練演算法,其中包括了前向傳播和權值更新。
訓練時的前向傳播:二值網路訓練時的權值引數W,必須包含實數型的引數,然後將實數型權值引數二值化得到二值型權值引數,即。然後利用二值化後的引數計算得到實數型的中間向量,該向量再透過Batch Normalization操作,得到實數型的隱藏層啟用向量。如果不是輸出層的話,就將該向量二值化。
求梯度:根據鏈式法則,在求解第k層和第k+1層的權值引數的梯度之前,必須先求解第k+1層的誤差值即。由於二值網路中,除了輸出層,其他隱藏層都經過二值化。所以在求Batch Normalization的引數時,必須先求二值操作層(我們把二值化也當做一層來看待)的梯度,即。其中,可以用
表示。另外一個不同點是,二值網路在對權值求梯度的時候,是對二值化後的權值求梯度,而不是對二值化前的實數型權值求梯度。這是因為二值化前的權值並沒有真正的參與網路的前向傳播過程。
權值更新:在求權值(W)梯度的時候是對二值化後的權值求梯度,但是在權值更新的時候,是利用上面求得的權值梯度對實數型的權值進行更新。
注:關於Batch Normalization的相關求導可參考我的博文:http://blog.csdn.net/linmingan/article/details/50780761
3、乘法最佳化
Shift-based Batch Normalization:二值網路對Batch Normalization操作的最佳化主要是透過AP2(x)操作和<<>>操作來代替普通的乘法。AP2(x)的作用是求與x最接近的2的冪次方,如AP2(3.14)=4,AP2(2.5)=2;而<<>>操作就是位移操作。AP2(x)的操作,在作者給出的原始碼中能夠找到;但是<<>>的操作,從原始碼中只能看到Torch的點乘函式cmul()。(注:Shift-based AdaMax中的乘法操作也是用上述兩個操作代替 )
前向傳播:二值網路中最重要的乘法最佳化是前向傳播中隱藏層的輸出乘以權值W的乘法最佳化。這個最佳化是利用兩個累積連乘命令完成,即popcount和xnor。下圖是論文中BNN的測試時前向傳播演算法。需要注意的是,只有輸入資料是8位二進位制,而啟用向量和權值矩陣中的元素全都是1位二進位制表示的。因此,輸入層與第一層隱藏層之間的乘法是用操作實現的。(注:從作者給出的程式碼來看,似乎並沒有採用這個操作,而是直接用普通的乘法。作者在論文中也說明了這一層的乘法的耗費很小。)
對於除了輸入層與第一層隱藏層之間的乘法之外,作者的GPU加速演算法就是利用操作實現,其中popcount的意思是計算一串二進位制串中有多少個1,xnor(程式碼裡面是xor,xnor應該是作者搞錯了)就是對兩個二進位制串按位取亦或。
看個例子,大家就明白怎麼計算了。
假設某一層隱藏層的啟用向量二值化後a=[1,-1, 1, 1, -1],同時又有二值化後的權值W=[-1,1,1,-1,-1]。在程式中是以a=[1,0,1,1,0],W=[0,1,1,0,0]表示的。
那麼按照正常的乘法應該是:
a1*w1+a2*w2+a3*w3+a4*w4+a5*w5=1*-1+-1*1+1*1+1*-1+-1*-1=-1
按照作者給出的操作應該是:
a^W=[1^0,0^1,1^1,1^0,0^0]=11010
Popcount(a^w)=3
這明顯不等於-1呀。這是因為作者沒在論文中寫清楚,我透過作者給的GPU最佳化程式碼發現,在進行Popcount(a^w)操作後,還有一個計算,即-(2*Popcount(a^w)-5) = -1;其中5表示的是二進位制串的長度,不同的長度的二進位制串這個數值是不一樣的,因為我這個例子的長度是5,所以才減去5。
4、總結
由於二值網路權值W中的元素只佔一位二進位制,因此在儲存訓練好後的模型時所需的記憶體非常小;同時又去除了普通的乘法操作。在減少模型引數所佔的記憶體和運算量的同時還能保持神經網路的效能,這給深度學習在移動端的應用帶來了非常大的前景。
過二值化,使模型的引數佔用更小的儲存空間;同時利用位移操作來代替網路中的乘法運算,大大降低了運算時間。
1、二值化
二值網路的二值化方法有兩種,一種是Deterministic(確定性方法),一種是Stochastic(機率統計方法)。
Deterministic方法:大於0就為+1,小於0則為-1。
Stochastic方法:對x計算一個機率p,當p大於一個闕值(計算機隨機產生)時為+1,否則為-1。
其中,
由於Stochastic方法需要由硬體生成隨機數,這比較難實施。所以論文中的實驗用的是Deterministic方法。
2、權值更新演算法
在理解權值更新之前,先看看前向傳播演算法。下圖為論文中給出的第一個演算法,該演算法是二值網路的訓練演算法,其中包括了前向傳播和權值更新。
訓練時的前向傳播:二值網路訓練時的權值引數W,必須包含實數型的引數,然後將實數型權值引數二值化得到二值型權值引數,即。然後利用二值化後的引數計算得到實數型的中間向量,該向量再透過Batch Normalization操作,得到實數型的隱藏層啟用向量。如果不是輸出層的話,就將該向量二值化。
求梯度:根據鏈式法則,在求解第k層和第k+1層的權值引數的梯度之前,必須先求解第k+1層的誤差值即。由於二值網路中,除了輸出層,其他隱藏層都經過二值化。所以在求Batch Normalization的引數時,必須先求二值操作層(我們把二值化也當做一層來看待)的梯度,即。其中,可以用
表示。另外一個不同點是,二值網路在對權值求梯度的時候,是對二值化後的權值求梯度,而不是對二值化前的實數型權值求梯度。這是因為二值化前的權值並沒有真正的參與網路的前向傳播過程。
權值更新:在求權值(W)梯度的時候是對二值化後的權值求梯度,但是在權值更新的時候,是利用上面求得的權值梯度對實數型的權值進行更新。
注:關於Batch Normalization的相關求導可參考我的博文:http://blog.csdn.net/linmingan/article/details/50780761
3、乘法最佳化
Shift-based Batch Normalization:二值網路對Batch Normalization操作的最佳化主要是透過AP2(x)操作和<<>>操作來代替普通的乘法。AP2(x)的作用是求與x最接近的2的冪次方,如AP2(3.14)=4,AP2(2.5)=2;而<<>>操作就是位移操作。AP2(x)的操作,在作者給出的原始碼中能夠找到;但是<<>>的操作,從原始碼中只能看到Torch的點乘函式cmul()。(注:Shift-based AdaMax中的乘法操作也是用上述兩個操作代替 )
前向傳播:二值網路中最重要的乘法最佳化是前向傳播中隱藏層的輸出乘以權值W的乘法最佳化。這個最佳化是利用兩個累積連乘命令完成,即popcount和xnor。下圖是論文中BNN的測試時前向傳播演算法。需要注意的是,只有輸入資料是8位二進位制,而啟用向量和權值矩陣中的元素全都是1位二進位制表示的。因此,輸入層與第一層隱藏層之間的乘法是用操作實現的。(注:從作者給出的程式碼來看,似乎並沒有採用這個操作,而是直接用普通的乘法。作者在論文中也說明了這一層的乘法的耗費很小。)
對於除了輸入層與第一層隱藏層之間的乘法之外,作者的GPU加速演算法就是利用操作實現,其中popcount的意思是計算一串二進位制串中有多少個1,xnor(程式碼裡面是xor,xnor應該是作者搞錯了)就是對兩個二進位制串按位取亦或。
看個例子,大家就明白怎麼計算了。
假設某一層隱藏層的啟用向量二值化後a=[1,-1, 1, 1, -1],同時又有二值化後的權值W=[-1,1,1,-1,-1]。在程式中是以a=[1,0,1,1,0],W=[0,1,1,0,0]表示的。
那麼按照正常的乘法應該是:
a1*w1+a2*w2+a3*w3+a4*w4+a5*w5=1*-1+-1*1+1*1+1*-1+-1*-1=-1
按照作者給出的操作應該是:
a^W=[1^0,0^1,1^1,1^0,0^0]=11010
Popcount(a^w)=3
這明顯不等於-1呀。這是因為作者沒在論文中寫清楚,我透過作者給的GPU最佳化程式碼發現,在進行Popcount(a^w)操作後,還有一個計算,即-(2*Popcount(a^w)-5) = -1;其中5表示的是二進位制串的長度,不同的長度的二進位制串這個數值是不一樣的,因為我這個例子的長度是5,所以才減去5。
4、總結
由於二值網路權值W中的元素只佔一位二進位制,因此在儲存訓練好後的模型時所需的記憶體非常小;同時又去除了普通的乘法操作。在減少模型引數所佔的記憶體和運算量的同時還能保持神經網路的效能,這給深度學習在移動端的應用帶來了非常大的前景。