二值化神經(jīng)網(wǎng)絡(luò)(BNN)綜述
【GiantPandaCV導(dǎo)語】二值化神經(jīng)網(wǎng)絡(luò)BNN由于可以實(shí)現(xiàn)極高的壓縮比和加速效果,所以它是推動(dòng)以深度神經(jīng)網(wǎng)絡(luò)為代表的人工智能模型在資源受限和功耗受限的移動(dòng)端設(shè)備,嵌入式設(shè)備上落地應(yīng)用的一門非常有潛力的技術(shù)。雖然目前的BNN仍然存在著很多不足,如模型精度仍然比全精度低了不少,無法有效地泛化到更復(fù)雜的任務(wù)上,依賴于特定的硬件架構(gòu)和軟件框架......,但我們同時(shí)也能看到BNN從最初的2015年ImageNet上只有27%的Top-1準(zhǔn)確率發(fā)展到2020年ReActNet-C的71.4%的進(jìn)步,這五年時(shí)間眾多研究人員在這條道路上不斷推動(dòng)著BNN朝著更準(zhǔn)更快更穩(wěn)的方向發(fā)展,所以我們有理由相信,BNN未來可期!
英文原文 : Simons T, Lee D J. A review of binarized neural networks[J]. Electronics, 2019, 8(6): 661.
下載鏈接:
A review of binarized neural networks(https://www.mdpi.com/2079-9292/8/6/661/pdfwww.mdpi.com)
**注:**本文主要是對上述英文綜述論文的部分中文翻譯和一些對BNN的個(gè)人理解,這篇綜述的發(fā)表日期是2019年6月份,個(gè)人感覺這篇綜述寫的很好,語言簡潔,內(nèi)容詳實(shí)。后續(xù)2020年3月北航發(fā)表了一篇更新的二值化綜述,但因?yàn)橐呀?jīng)有人翻譯過了,所以不再重復(fù)造輪子,原文鏈接貼在下面,中文翻譯知乎隨便一搜就能找到。
Binary Neural Networks: A Survey(https://arxiv.org/pdf/2004.03333)
閑扯淡
自大四畢業(yè)進(jìn)入課題組以來,在模型壓縮與優(yōu)化加速領(lǐng)域的學(xué)習(xí)也有一年多了。過去的一年雖然主要是做的模型8-bit量化方面的工程實(shí)踐(給硬件組當(dāng)狗),但是同時(shí)也看了很多論文,陸陸續(xù)續(xù)也對整個(gè)領(lǐng)域其他方面如剪枝,知識(shí)蒸餾,矩陣低秩分解等,和一些基本的輕量級網(wǎng)絡(luò)如SqueezeNet, ShuffleNet系列,MobileNet系列,EfficientNet系列的結(jié)構(gòu)設(shè)計(jì)有了一定的了解。其中,二值化神經(jīng)網(wǎng)絡(luò)(BNN)尤為引起我的興趣,因?yàn)樗兄顬闃O端的壓縮率和極低的計(jì)算量。雖然BNN仍受限于復(fù)雜數(shù)據(jù)集/任務(wù)上很不理想的準(zhǔn)確率和對特定硬件架構(gòu)或軟件框架的依賴,而模型壓縮領(lǐng)域真正能應(yīng)用于實(shí)處且算得上通用的技術(shù)仍然限于通道剪枝,8bit量化和輕量級網(wǎng)絡(luò)設(shè)計(jì)(如果可以歸類為模型壓縮領(lǐng)域的話),但是我仍然認(rèn)為BNN是模型壓縮領(lǐng)域皇冠上的明珠,因?yàn)榇蟮乐梁啞?/p>
開始正文
二值化神經(jīng)網(wǎng)絡(luò)(BNN)指的是僅使用+1和-1兩個(gè)值來表示weights和activations的神經(jīng)網(wǎng)絡(luò),相比于全精度的神經(jīng)網(wǎng)絡(luò),它可以用XNOR+popcount這樣極簡單的組合代替float32的乘累加來實(shí)現(xiàn)卷積操作,從而節(jié)省了大量的內(nèi)存和計(jì)算,大大方便了模型在資源受限設(shè)備上的部署。但同時(shí),由于二值所能表達(dá)的信息量有限,所以BNN在模型精度方面一直都是遠(yuǎn)低于全精度模型,雖然最近的研究如MeliusNet,IRNet和ReActNet已經(jīng)努力地將BNNs在ImageNet數(shù)據(jù)集上的Top-1拉到了0.70以上,與相應(yīng)的全精度模型差距拉到3個(gè)點(diǎn)左右,但他們同時(shí)也增加了不少計(jì)算量,并且暫時(shí)還難以有效地推廣到目標(biāo)檢測,語義分割等復(fù)雜任務(wù)上,所以BNN的升級打怪之路仍然道阻且長。目前有關(guān)BNN的研究從大的方面來說就是兩個(gè):如何提升BNN的精度和如何有效地部署在低功耗且資源受限的平臺(tái)上。
本篇綜述主要從以下幾個(gè)方面進(jìn)行的闡述:
二值化神經(jīng)網(wǎng)絡(luò)的基本介紹; 二值化神經(jīng)網(wǎng)絡(luò)的主要發(fā)展; 提升二值化神經(jīng)網(wǎng)絡(luò)精度和推理速度的技巧; 二值化神經(jīng)網(wǎng)絡(luò)在不同數(shù)據(jù)集上的精度表現(xiàn); 二值化神經(jīng)網(wǎng)絡(luò)的硬件實(shí)現(xiàn);
特意說明,因?yàn)楸酒C述是2019年6月發(fā)表的,所以這個(gè)時(shí)間點(diǎn)之后的相關(guān)論文的貢獻(xiàn)并沒有被總結(jié)在內(nèi),而我發(fā)現(xiàn)這段時(shí)間出現(xiàn)了不少優(yōu)秀的論文,如Bi-real Net, MeliusNet,IRNet, ReActNet等等,他們提出了很多巧妙的技術(shù)來解決目前二值化神經(jīng)網(wǎng)絡(luò)中存在的問題,所以我會(huì)將自己對這些論文的一些總結(jié)穿插在接下來的闡述中,其中勢必有一些理解不正確的地方,希望能夠指出,我們共同進(jìn)步!
基本介紹
二值化神經(jīng)網(wǎng)絡(luò)的idea最初源于2016年深度學(xué)習(xí)三巨頭之一Yoshua Bengio的論文《BinaryNet: Training Deep Neural Networks with Weights and Activations Constrained to +1 or -1.》,它首次提出一種方法,可以用隨機(jī)梯度下降的方式訓(xùn)練同時(shí)使用二值化的weights和activations的神經(jīng)網(wǎng)絡(luò)。為了解決二值化weights中梯度的傳遞問題,作者提出在訓(xùn)練過程中保持一個(gè)實(shí)值(float32)的weights,然后使用信號函數(shù)sign來獲得二值化的weights
并且針對sign函數(shù)在0處不可導(dǎo),其他地方導(dǎo)數(shù)為0無法有效進(jìn)行梯度傳遞的問題,設(shè)計(jì)了直通估計(jì)器STE (straight through estimator),即當(dāng)梯度傳遞遇到sign函數(shù)時(shí),直接跳過這個(gè)函數(shù),或者說默認(rèn)sign函數(shù)輸出對輸入的梯度為1,即:
前向和反向計(jì)算的流程如下圖所示

STE的可視化
使用了STE之后,實(shí)值的weights就可以使用如SGD和Adam這樣常見的優(yōu)化器來進(jìn)行更新了,同時(shí)考慮到這個(gè)實(shí)值weights是沒有設(shè)置邊界的,這樣它就有可能會(huì)一直累加到特別大的值,從而與二值化的weights之間的量化誤差越來越大,積重難返,所以作者對實(shí)值的weights還單獨(dú)加了一個(gè)截?cái)嗪瘮?shù)clip(x,-1,1),將其限制在-1和+1之間,這樣使得實(shí)值weights和二值化weights的距離更近。對于activations的二值化和weights是相似的,并且在實(shí)驗(yàn)中作者發(fā)現(xiàn),當(dāng)sign函數(shù)的輸入的絕對值大于1的時(shí)候,將梯度置0可以得到更好的實(shí)驗(yàn)結(jié)果,即:
簡單總結(jié)一下,我們可以看到作者在訓(xùn)練過程中對weights和activations做了不同的設(shè)置,兩個(gè)在梯度更新上都是遵照STE的原則,直接將sign函數(shù)跳過,而實(shí)值weights在更新之后會(huì)裁剪到[-1,1]之間,從而減小實(shí)值weights和二值化weights之間的距離,而activations的梯度在更新的時(shí)候,當(dāng)實(shí)值activations的絕對值大于1時(shí)會(huì)將梯度置0,避免特別大的梯度向下傳遞使得訓(xùn)練時(shí)候出現(xiàn)震蕩。
花這么大的力氣來訓(xùn)練這個(gè)BNN,然而最后實(shí)驗(yàn)結(jié)果看起來與全精度相比也沒有什么任何優(yōu)勢,肯定是這個(gè)模型存在什么驚喜?我來翻譯翻譯,作者設(shè)計(jì)BNN的初衷還是為了加速模型的前向推理,這里面最大的功勞就是用1bit數(shù)的XNOR和popcount代替了傳統(tǒng)卷積的float32乘累加操作,用腳想也能理解這個(gè)在理論上不僅能減少32倍的參數(shù)存儲(chǔ),還能跑的比曹操快。雖然在BNN各個(gè)數(shù)據(jù)集上的實(shí)驗(yàn)都是強(qiáng)差人意,但快不快就完事了。同時(shí)也有些亟待畢業(yè)的博士研究發(fā)現(xiàn)BNN在對抗攻擊方面有很強(qiáng)的魯棒性,除了快,還穩(wěn),好家伙,直呼BNN牛逼。

主要發(fā)展
Yoshua Bengio作為BNN的開山祖師,不僅給眾多人指明了山的方向 —— 更快更準(zhǔn)更泛化,還在一路上留下了數(shù)不清的果實(shí)讓后來者去慢慢摘 —— STE的優(yōu)化,二值友好結(jié)構(gòu)的設(shè)計(jì),更細(xì)致的training tricks......,于是這個(gè)領(lǐng)域開始了轟轟烈烈的刷榜競賽,以下將介紹一些在BNN發(fā)展道路上帶來創(chuàng)新的模型,其中綜述中談到的DeReFa-Net,個(gè)人認(rèn)為它主要是為低比特量化及訓(xùn)練設(shè)計(jì)的,將乘法用多個(gè)bitwise+shift的操作代替,梯度也可以用低比特?cái)?shù)來表示,但如果把它的W/A的位寬設(shè)置為1/1,并沒有看出很多結(jié)構(gòu)上的創(chuàng)新,故在此處不闡述。
XNOR-Net
在第一篇BNN發(fā)表不久,XNOR-Net橫空出世,這篇論文其實(shí)提出了兩個(gè)模型,一個(gè)是BWN(Binary Weight Networks),另一個(gè)才是XNOR-Net,BWN只使用了二值化的weights,而activation仍然采取的float32全精度,按照BNN的定義其實(shí)BWN不能算在二值化網(wǎng)絡(luò)的范疇,但它的效果那是杠杠的,跟全精度相差不大,看來神經(jīng)網(wǎng)絡(luò)對weights的二值化還挺不敏感的。而該文的主角XNOR-Net是正兒八經(jīng)不摻水的二值化神經(jīng)網(wǎng)絡(luò),weights和activations都采取的二值化。它主要是在原始BNN基礎(chǔ)上考慮了量化誤差,并且提出了對實(shí)值weights每個(gè)輸出通道方向上提取出一個(gè)scaling factor,用于恢復(fù)二值化weights的信息,同時(shí)對activation在HW方向上每個(gè)pixel上提取一個(gè)scaling factor,用于恢復(fù)二值化activations的信息,這兩種scaling factor都無需學(xué)習(xí),直接計(jì)算相應(yīng)的L-1范數(shù)就能得到,且不影響二值化高效的卷積計(jì)算過程。最后的實(shí)驗(yàn)也比原始的BNN要好不少,并且首次展示了BNN在ImageNet這種大型數(shù)據(jù)集上的實(shí)驗(yàn)結(jié)果,還聲稱在卷積計(jì)算上可以達(dá)到58倍的加速效果,節(jié)省32倍的內(nèi)存。

本文是BNN領(lǐng)域一個(gè)非常重要的工作,用scaling factor恢復(fù)量化誤差來提升精度的思想一直被沿用至今,在各個(gè)論文中都能看到。但同時(shí)該文也有一些詬病的地方,如計(jì)算結(jié)果無法復(fù)現(xiàn)(我翻譯的這篇英文綜述說的,不是我說的),沒有真正部署在硬件上實(shí)測加速效果,只是闡述了一個(gè)理論值,畢竟在前向推理過程中每層activation在HW方向每個(gè)pixel上計(jì)算scaling factor的操作是非常耗時(shí)的。
ABC-Net
這是大疆創(chuàng)新被NIPS2017收錄的論文,論文中主要針對二值化數(shù)據(jù)表達(dá)信息太弱的問題,提出使用多個(gè)二值化weights和activations線性加權(quán)求和的方式來近似表示全精度的weights和activations,如下面的公式所示。為了得到不同的二值化的bases,作者通過在sign函數(shù)中加入變量u,結(jié)合weights的均值和方差,通過改變u的值就可以獲得不同的二值化tensor。而對于activations來說,使用相同的二值化操作會(huì)和XNOR-Net一樣在前向推理過程中為了計(jì)算均值方差增加大量計(jì)算,所以這里選擇在sign函數(shù)中使用N個(gè)可學(xué)習(xí)的變量u來進(jìn)行二值化。其實(shí)可以看出,這篇論文的思想和DoReFa-Net還是挺相似的,只不過DoReFa-Net是低比特量化,而ABC-Net使用的更巧妙一些,本質(zhì)還是BNN,但我們一眼也能看出,這個(gè)ABC-Net比之前的BNN在計(jì)算量上增加了很多,相當(dāng)于是用時(shí)間和空間換取精度。論文說用5個(gè)bases可以達(dá)到非常好的實(shí)驗(yàn)效果,但實(shí)際上消耗的資源比W/A=2/2還多了。
MeliusNet
這是一篇BNN結(jié)構(gòu)設(shè)計(jì)的論文,作者從兩大經(jīng)典的網(wǎng)絡(luò)結(jié)構(gòu)ResNet和DenseNet獲得啟發(fā),針對在此之前的二值化feature map信息表達(dá)很弱的問題提出了兩個(gè)概念:Quality(質(zhì)量)和Capacity(數(shù)量),即ResNet的shortcut可以增強(qiáng)了每個(gè)通道的feature map的信息表達(dá),DenseNet中的concat可以增加feature map的通道數(shù),從而增強(qiáng)整體的信息表達(dá)。其實(shí)這兩個(gè)想法在前作Bi-real Net和BinaryDenseNet中也分別提到了,本來打算單獨(dú)講這兩篇,但是考慮到和MeliusNet思想的重合,就只單獨(dú)把這一篇拎出來講一下,但實(shí)際上述兩篇論文的BNN結(jié)構(gòu)上個(gè)人覺得更加的簡潔,有興趣的可以下下來看一下。
Bi-Real Net
BinaryDenseNet
話題轉(zhuǎn)回來,MeliusNet根據(jù)用shotcut和concat增強(qiáng)Quality和Capacity的指導(dǎo)思想設(shè)計(jì)了兩個(gè)二值友好的模塊,如下圖所示,一個(gè)是Dense Block,另一個(gè)是Improvement Block,這兩個(gè)模塊在網(wǎng)絡(luò)中每次都是交錯(cuò)出現(xiàn),在整個(gè)信息流中不斷地增強(qiáng)二值化feature map的信息表達(dá),從而提升精度。這篇論文除了這個(gè)核心思想之外,還提出了一個(gè)我覺得比較有意思的思路,那就是二值化網(wǎng)絡(luò)應(yīng)該有一套自己的網(wǎng)絡(luò)結(jié)構(gòu),這種二值化友好結(jié)構(gòu)的效果要優(yōu)于相似FLOPs下全精度模型二值化后的結(jié)構(gòu),并且做了相應(yīng)的實(shí)驗(yàn)進(jìn)行驗(yàn)證,通俗地來講就是倡導(dǎo)大家要走二值化特色社會(huì)主義道路。

IR-Net
這是一篇很有意思,我非常喜歡的一篇論文,它的作者就是最開始我提到另一篇綜述的作者,2020年上半年也有機(jī)會(huì)在商湯的泰坦公開課中聆聽了主創(chuàng)們對這篇論文的解讀。這篇論文主要針對的是二值化在前向計(jì)算和反向梯度傳播中帶來的信息損失問題,作者分別提出了兩個(gè)技術(shù),一個(gè)是 Libra-PB(Libra Parameter Binarization),用于在前向計(jì)算中同時(shí)最小化weights的量化損失和信息熵?fù)p失,另一個(gè)是EDE(Error Decay Estimator),通過漸進(jìn)近似sign函數(shù)來最小化反向傳播過程中梯度的信息損失。Libra-PB簡單來說就是在weights被二值化之前,先對它做歸一化處理,即減均值除方差,這樣的話在二值化之前,就大概有一半的weights是大于0,一半的weights小于0,從而使得二值化之后的weights信息熵?fù)p失最小。

而EDE則是利用k×tanh(t×x)在不同訓(xùn)練階段漸進(jìn)近似sign函數(shù),并用其梯度來代替sign函數(shù)的梯度進(jìn)行反向傳播,從而使得整個(gè)訓(xùn)練過程可以更加的平滑,從而減少信息損失。

之所以喜歡這篇論文,是因?yàn)樗岢龅膬蓚€(gè)技術(shù)非常的簡潔有效,一下子就能讓人理解,一點(diǎn)都不花里胡哨,然后得到的結(jié)果也非常的好。
ReActNet
這篇論文的一座和Bi-Real Net是同一個(gè)人——?jiǎng)纱海髡咧斑€在知乎上和另一個(gè)未經(jīng)作者允許就直接發(fā)表了Bi-Real Net V2的研究人員發(fā)生了爭辯,快來一起吃瓜呀!
ICLR 2021 有什么值得關(guān)注的投稿?
并且從這個(gè)爭論中才了解到ReActNet這篇論文,于是趕忙去下載下來,焚香沐浴,仔細(xì)拜讀了大佬的作品。這篇論文是延續(xù)Bi-Real Net的一篇二值化神經(jīng)網(wǎng)絡(luò)研究的工作,作者首先利用Bi-Real Net的思路,即在原始網(wǎng)絡(luò)中增加shortcut層來改造了MobileNetV1,然后通過大量的實(shí)驗(yàn)發(fā)現(xiàn)BNN的性能對activations的分布變化特別敏感,即對Activations進(jìn)行平移/縮放對BNN的性能影響很明顯,那么作者思考的是肯定每一層的Activations都各自有一個(gè)最適合的偏移值和縮放值使得整個(gè)模型的性能最優(yōu),于是作者提出了對sign函數(shù)和PReLU函數(shù)進(jìn)行改造,加入可學(xué)習(xí)的參數(shù)變量,讓模型自動(dòng)去學(xué)每一層最佳的偏移值和縮放值,命名為ReAct-Sign(簡稱RSign)和ReAct-PReLU(簡稱RPReLU),另外需要說明的是這些參數(shù)都是channel-wise的,計(jì)算量其實(shí)還是有些的哈,但是因?yàn)檫x的模型是MobileNetV1,參數(shù)量較小,所以相比其他的BNN模型在整個(gè)計(jì)算量上還是少了很多,且精度還高了不少。

另外基于之前的觀測結(jié)果,作者將最后一層輸出經(jīng)過softmax的結(jié)果與label的cross entropy 換成了與全精度模型的最后一層輸出經(jīng)過softmax的cross entropy,以此來學(xué)習(xí)全精度模型最后一層輸出的數(shù)據(jù)分布,稱之為distributional loss,有知識(shí)蒸餾那味了,并且作者強(qiáng)調(diào)相比于之前一些論文將二值化模型每一層輸出都與全精度模型對應(yīng)層輸出進(jìn)行匹配的做法,這個(gè)distributional loss更加簡潔,且效果非也很好。

以上就是個(gè)人結(jié)合本篇英文綜述和自己看過的一些論文總結(jié)的二值化神經(jīng)網(wǎng)絡(luò)發(fā)展史上一些重要進(jìn)展的論文。因?yàn)楸救怂接邢?,勢必不夠完整,如有遺漏請多多見諒!
提升性能的技術(shù)總結(jié)
現(xiàn)在來總結(jié)一下自最初的BNNs論文出來之后,為了提升性能用到的技術(shù)總結(jié):
Gain term 增益項(xiàng)
這個(gè)主要指的是一些為了減少數(shù)據(jù)二值化損失而增加的一些額外的項(xiàng),如XNOR-Net首次提出的在weights二值化之前計(jì)算一個(gè)channel-wise的scaling factors(一般是每個(gè)通道權(quán)重的均值)用于恢復(fù)量化損失,這個(gè)思想被沿用至今簡單有效。還有各種在activations上增加的可學(xué)習(xí)的參數(shù),如ReActNet提到的RSign和RPReLU,這些增益項(xiàng)雖然增加一點(diǎn)點(diǎn)的計(jì)算,但對模型精度卻有大幅度的提升。另外要說明的XNOR-Net里面對activations在HW方向上每個(gè)pixel計(jì)算一個(gè)scale,這個(gè)雖然可以減少二值化的信息損失,但是在前向過程中對推理速度的影響很嚴(yán)重,所以暫不列入其中,這也說明了一點(diǎn),weights上的增益項(xiàng)無論是可學(xué)習(xí)的還是在線計(jì)算的都不會(huì)對推理速度有較大影響,因?yàn)橛?xùn)練結(jié)束之后可以得到固定的系數(shù)。而activations的增益項(xiàng)最好是用可學(xué)習(xí)的,因?yàn)樵谇跋蛲评磉^程中,每次輸入數(shù)據(jù)不同,在線計(jì)算的增益項(xiàng)都需要重新計(jì)算,這個(gè)對推理速度影響很大。
2. ?多個(gè)二值化base
這個(gè)特指ABC-Net的做法,用多個(gè)二值化的base線性加權(quán)近似全精度的weights和activations,性能不錯(cuò),典型的以時(shí)間和空間換取精度的做法。
3. ?二值友好的結(jié)構(gòu)設(shè)計(jì)
Bi-Real Net,BinaryDenseNet和MeliusNet三篇論文驗(yàn)證了在BNNs網(wǎng)絡(luò)結(jié)構(gòu)中加入shortcut和concat操作能夠大大增強(qiáng)模型的Quality和Capacity,從而大大提升性能。
4. 關(guān)鍵層的設(shè)計(jì)
神經(jīng)網(wǎng)絡(luò)中關(guān)鍵層一般指的第一層,下采樣層和最后一層,這些層相對于其他普通層對模型性能影響更大,所以需要額外注意。
第一層
第一層的輸入是原始數(shù)據(jù),且卷積核的參數(shù)量較少,如果第一層出現(xiàn)了巨大的信息損失,那么后面層基本上也學(xué)不到啥了,原始BNN論文沒有對輸入直接二值化,因?yàn)檩斎氲膱D像數(shù)據(jù)是UINT8類型,范圍[0,255],二值化基本都是1了,信息損失殆盡,所以作者直接輸入原始的數(shù)據(jù)與二值weights進(jìn)行卷積計(jì)算。為了提升計(jì)算效率,作者將輸入按比特位切片出來,用移位和XNOR代替乘法,如下圖所示。

但這個(gè)做法不太妥當(dāng)?shù)氖牵斎霐?shù)據(jù)雖然沒有丟失信息,但是沒有做數(shù)據(jù)的歸一化。在主流的模型訓(xùn)練中我們可以知道,數(shù)據(jù)的normalize對結(jié)果影響還蠻大的,所以目前主流的BNNs基本上第一層都是使用全精度的卷積層,輸入數(shù)據(jù)正常歸一化處理后輸入網(wǎng)絡(luò),因?yàn)橥ǔUJ(rèn)為這塊計(jì)算量不大。但是MeliusNet在實(shí)驗(yàn)中發(fā)現(xiàn)目前很多BNNs計(jì)算中,浮點(diǎn)計(jì)算占了60%以上,第一層很多人使用的7×7的卷積核,計(jì)算量還是蠻大的,所以MeliusNet用三個(gè)3×3的卷積進(jìn)行了代替,節(jié)省了一半的計(jì)算。
輸入數(shù)據(jù)需要做normalize和二值化結(jié)構(gòu)真的就無緣了嗎?在FBNA論文中我們發(fā)現(xiàn),可以使用如下技巧,輸入數(shù)據(jù)正常歸一化之后,縮放到[-128,128]的范圍并取整,然后每個(gè)pixel的值用一個(gè)長度為256的一維二值化向量表示,兩者關(guān)系是這個(gè)二值化向量累加求和之后的結(jié)果除以2等于這個(gè)整數(shù)值,如下所示:

下圖中(a,b,c)以2Bit的數(shù)據(jù)為例再次展示了上述分解過程。輸入數(shù)據(jù)假設(shè)為CIFAR10,分辨率是(32,32,3),那么經(jīng)過分解之后就會(huì)變成(32,32,256,3),這個(gè)時(shí)候我們會(huì)發(fā)現(xiàn)輸入數(shù)據(jù)巨大無比,第一層計(jì)算量指數(shù)級增加,于是作者將原圖像8bit數(shù)據(jù)的高位截掉,在分解向量中的體現(xiàn)就是直接去掉右側(cè)的正負(fù)1的數(shù),如下圖所示,我們可以發(fā)現(xiàn)pruning之后的圖像其實(shí)仍然保留了大多數(shù)的信息,且可以大大降低計(jì)算量,整個(gè)過程如下圖(d)所示。

下采樣層
下采樣層的特點(diǎn)是圖像分辨率會(huì)直接減少一半,這個(gè)過程是一個(gè)不可逆的信息損失的過程。早期的BNNs都傾向于使用MaxPooling來進(jìn)行下采樣操作,但是存在一個(gè)問題是,如果在每一層activations二值化之后進(jìn)行MaxPooling,會(huì)導(dǎo)致梯度反傳到這塊的時(shí)候?qū)⑻荻染鶆虻姆纸o多個(gè)+1或者多個(gè)-1,然而實(shí)際上只有real-value最大的那個(gè)值真正起了作用,這樣的分配是不公平的,所以比較好的做法是遇到MaxPooling操作的時(shí)候,將activations的二值化延后,對實(shí)值的weights進(jìn)行下采樣,這樣可以得到更好的效果。但目前的網(wǎng)絡(luò)設(shè)計(jì)人員通常認(rèn)為MaxPooling是不可學(xué)習(xí)的算子,傾向于使用stride=2的卷積層來進(jìn)行下采樣,這樣可以保留更多的信息,所以在目前的BNNs當(dāng)中,這塊通常也是使用全精度的卷積來計(jì)算,避免造成較大精度損失,同時(shí)可以利用組卷積+channel shuffle的方式來進(jìn)一步降低浮點(diǎn)的計(jì)算量。
輸出層
這一層在分類任務(wù)中通常是全連接的結(jié)構(gòu),輸出最后的預(yù)測結(jié)果,為了避免二值化的影響,通常也是采取全精度的計(jì)算,本來想提一下很多人對FC做的random pruning能降低計(jì)算,但又仔細(xì)想了想,這中任意剪枝方式在硬件上實(shí)現(xiàn)尤為麻煩,估計(jì)很難加速。
5. 漸進(jìn)式地學(xué)習(xí)
如IR-Net中的EDE,用其他可微的函數(shù)來代替sign函數(shù),并且在訓(xùn)練過程中不斷地逼近真正的sign,使得整個(gè)訓(xùn)練過程梯度傳遞更加的平滑。還有一些論文在訓(xùn)練的時(shí)候漸進(jìn)地對weights和activations進(jìn)行二值化,根據(jù)一些原則,一開始的時(shí)候二值化部分?jǐn)?shù)據(jù),然后在訓(xùn)練過程中漸漸增大二值化的比例,最后將整個(gè)模型二值化,這個(gè)過程也是相對平滑的,比直接二值化更有效,這讓我想起了老本行模型量化中的INQ。
6. padding策略
在實(shí)值卷積神經(jīng)網(wǎng)絡(luò)中,我們通常在輸入四周padding的0,但是在BNN當(dāng)中并沒有0這種數(shù)的存在,所以大家大多數(shù)選擇全-1或者全+1。有研究者發(fā)現(xiàn)這種padding策略對結(jié)果是有影響的,畢竟使得整個(gè)輸入數(shù)據(jù)朝著1或者-1發(fā)生了偏移,上述的ReActNet也說過activations的發(fā)生偏移對結(jié)果影響還是很明顯的,所以有人提出了Odd-Even padding的方式,即奇偶填充,1和-1間隔填充,如下圖所示,并且發(fā)現(xiàn)這種填充方式可以達(dá)到填充0的效果。

7. 其他訓(xùn)練技巧
使用全精度模型在數(shù)據(jù)集上訓(xùn)練好的參數(shù)作為對應(yīng)BNN的初始化參數(shù); Batch Normlization 和輸入數(shù)據(jù)的normalize是必要操作; 損失函數(shù)增加正則項(xiàng),如下圖中的L-1 norm和L-2 norm,將α設(shè)為1,可以使得weights在訓(xùn)練過程中絕對值更加趨近于1,有利于減少量化誤差;

使用較小的學(xué)習(xí)率,然后累計(jì)梯度,間隔更新的方式;
8. 前向加速
用INT4/INT8/FP16的卷積代替全精度卷積計(jì)算的部分; 將Batch Normalization和sign函數(shù)合并起來,將浮點(diǎn)計(jì)算變成符號判斷和數(shù)值大小比較;

不同數(shù)據(jù)集上的精度表現(xiàn)
由于BNN的模型實(shí)在是太多,而每一篇論文的實(shí)驗(yàn)結(jié)果也非常豐富,故我從兩篇綜述中截取出CIFAR10,ImageNet,PASCAL VOC2007和MS COCO2017最好的一些結(jié)果,如下所示:(注意:其中MS COCO2017的結(jié)果我似乎沒有在論文原文中找到依據(jù),所以大家就圖個(gè)樂,不要較真)

硬件實(shí)現(xiàn)
由于我不是搞硬件的,所以這塊只能簡述一下。由于BNN的主要加速原因就是用XNOR+bitcount操作來代替了傳統(tǒng)卷積中昂貴的乘累加操作,而我們使用的x86計(jì)算架構(gòu)基本上都是對float32類型數(shù)據(jù)的計(jì)算做了很大程度的優(yōu)化,所以直接將BNN部署在現(xiàn)有的x86計(jì)算平臺(tái)上是很吃虧的,有可能不僅沒有加速效果,甚至比同等的全精度模型跑的還慢。在我的調(diào)研中,硬件部署實(shí)現(xiàn)有如下兩種方式:
ARM CPU,可以部署在手機(jī)端
BMXNet框架,來自于德國的Hasso Plattner Institute,MeliusNet的作者,支持ios和Android的部署; daBNN框架,來自京東AI研究院,目前僅支持Android手機(jī)上的部署;
2. FPGA和ASIC
相比于傳統(tǒng)的CPU,F(xiàn)PGA在硬件架構(gòu)設(shè)計(jì)方面很靈活,可以支持bitswise的高效運(yùn)算,而且功耗很低,其對應(yīng)的終極版的專用集成電路ASIC更是如此,可以比FPGA運(yùn)算更高效,更節(jié)能。目前用FPGA設(shè)計(jì)AI加速器基本都是以Xilinx的器件和開發(fā)工具為主,而他們也為二值化神經(jīng)網(wǎng)絡(luò)專門設(shè)計(jì)了一款架構(gòu)FINN,開發(fā)者可以利用高層次綜合工具(HLS),用C語言進(jìn)行開發(fā),直接將二值化模型部署到FPGA上,下圖是一些對比結(jié)果。而Intel的Accelerator Architecture Lab也為BNN設(shè)計(jì)了一款layer accelerator的ASIC,不過并沒有找到很多的相關(guān)數(shù)據(jù),就不贅述。


最后的總結(jié)
二值化神經(jīng)網(wǎng)絡(luò)BNN由于可以實(shí)現(xiàn)極高的壓縮比和加速效果,所以它是推動(dòng)以深度神經(jīng)網(wǎng)絡(luò)為代表的人工智能模型在資源受限和功耗受限的移動(dòng)端設(shè)備,嵌入式設(shè)備上落地應(yīng)用的一門非常有潛力的技術(shù)。雖然目前的BNN仍然存在著很多不足,如模型精度仍然比全精度低了不少,無法有效地泛化到更復(fù)雜的任務(wù)上,依賴于特定的硬件架構(gòu)和軟件框架......,但我們同時(shí)也能看到BNN從最初的2015年ImageNet上只有27%的Top-1準(zhǔn)確率發(fā)展到2020年ReActNet-C的71.4%的進(jìn)步,這五年時(shí)間眾多研究人員在這條道路上不斷推動(dòng)著BNN朝著更準(zhǔn)更快更穩(wěn)的方向發(fā)展,所以我們有理由相信,BNN未來可期!
歡迎關(guān)注GiantPandaCV, 在這里你將看到獨(dú)家的深度學(xué)習(xí)分享,堅(jiān)持原創(chuàng),每天分享我們學(xué)習(xí)到的新鮮知識(shí)。( ? ?ω?? )?
有對文章相關(guān)的問題,或者想要加入交流群,歡迎添加BBuf微信:
為了方便讀者獲取資料以及我們公眾號的作者發(fā)布一些Github工程的更新,我們成立了一個(gè)QQ群,二維碼如下,感興趣可以加入。
