綜述:輕量級CNN架構設計(2)
· 空洞卷積 (Dilated Convolution)
空洞卷積是針對圖像語義分割問題中下采樣會降低圖像分辨率、丟失信息而提出的一種卷積思路。通過間隔取值擴大感受野,讓原本3x3的卷積核,在相同參數量和計算量下?lián)碛懈蟮母惺芤?。這里面有個擴張率(dilation rate)的系數,這個系數定義了這個間隔的大小,標準卷積相當于dilation rate為1的空洞卷積,下圖展示的是dilation rate為2的空洞卷積計算過程,可以看出3×3的卷積核可以感知標準的5×5卷積核的范圍,還有一種理解思路就是先對3×3的卷積核間隔補0,使它變成5×5的卷積,然后再執(zhí)行標準卷積的操作。
空洞卷積
· 轉置卷積 (Transposed Convolutions)
轉置卷積又稱反卷積(Deconvolution),它和空洞卷積的思路正好相反,是為上采樣而生,也應用于語義分割當中,而且他的計算也和空洞卷積正好相反,先對輸入的feature map間隔補0,卷積核不變,然后使用標準的卷積進行計算,得到更大尺寸的feature map。
· 可變形卷積 (deformable convolution)
以上的卷積計算都是固定的,每次輸入不同的圖像數據,卷積計算的位置都是完全固定不變,即使是空洞卷積/轉置卷積,0填充的位置也都是事先確定的。而可變性卷積是指卷積核上對每一個元素額外增加了一個h和w方向上偏移的參數,然后根據這個偏移在feature map上動態(tài)取點來進行卷積計算,這樣卷積核就能在訓練過程中擴展到很大的范圍。而顯而易見的是可變性卷積雖然比其他卷積方式更加靈活,可以根據每張輸入圖片感知不同位置的信息,類似于注意力,從而達到更好的效果,但是它比可行變卷積在增加了很多計算量和實現(xiàn)難度,目前感覺只在GPU上優(yōu)化的很好,在其他平臺上還沒有見到部署。
其他算子
· 池化(pooling)
池化這個操作比較簡單,一般在上采樣和下采樣的時候用到,沒有參數,不可學習,但操作極為簡單,和depthwise卷積類似,只是把乘累加操作替換成取最大/取平均操作。
· 最大池化和平均池化
最大池化和平均池化
· 全局平均池化
全局平均池化的操作是對一個維度為(C,H,W)的feature map,在HW方向整個取平均,然后輸出一個長度為C的向量,這個操作一般在分類模型的最后一個feature map之后出現(xiàn),然后接一個全連接層就可以完成分類結果的輸出了。早期的分類模型都是把最后一個feature map直接拉平成C×H×W的向量,然后再接全連接層,但是顯然可以看出來這個計算量極大,甚至有的模型最后一個全連接層占了整個模型計算量的50%以上,之后由研究人員發(fā)現(xiàn)對這個feature map做一個全局平均池化,然后再加全連接層可以達到相似的效果,且計算量降低到了原來的1/HW。
· 最大向上池化
這個操作在前面基本概念一節(jié)上采樣段落中有描述,故不贅述。
· 全連接計算(Full Connected)
這個本質其實就是矩陣乘法,輸入一個(B, iC)的數據,權重為(iC, oC),那么輸出為(B, oC),在多層感知機和分類模型最后一層常常見到。
全連接結構
· Addition / Concatenate分支
Addition和Concatenate分支操作統(tǒng)稱為shortcut,如下圖所示,操作極為簡單。Addition是在ResNet中提出,兩個相同維度的feature map相同位置點的值直接相加,得到新的相同維度feature map,這個操作可以融合之前的特征,增加信息的表達,Concatenate操作是在Inception中首次使用,被DenseNet發(fā)揚光大,和addition不同的是,它只要求兩個feature map的HW相同,通道數可以不同,然后兩個feature map在通道上直接拼接,得到一個更大的feature map,它保留了一些原始的特征,增加了特征的數量,使得有效的信息流繼續(xù)向后傳遞。
Add & Concat
· Channel shuffle
channel shuffle是ShuffleNet中首次提出,主要是針對分組卷積中不同組之間信息不流通,對不同組的feature map進行混洗的一個操作,如下圖所示,假設原始的feature map維度為(1,9,H,W),被分成了3個組,每個組有三個通道,那么首先將這個feature map進行reshape操作,得到(1,3,3,H,W),然后對中間的兩個大小為3的維度進行轉置,依然是(1,3,3,H,W),最后將通道拉平,變回(1,9,H,W),就完成了通道混洗,使得不同組的feature map間隔保存,增強了信息的交互。
channel shuffle
常用激活函數
激活函數的非線性是神經網絡發(fā)揮作用最重要的因素之一,而對于實際部署,激活函數的實現(xiàn)也是很重要的一個方面,實現(xiàn)的不好對加速效果影響很大,這里主要講幾個部署當中常見的激活函數。
· ReLU系列
這里主要指常用的ReLU,ReLU6和leaky ReLU。ReLU比較好部署,小于0的部分為0,大于0的部分為原始值,只需要判斷一下符號位就行;ReLU6與ReLU相比也只是在正向部分多了個閾值,大于6的值等于6,在實現(xiàn)時多了個比較也不算麻煩;而leaky ReLU和ReLU正向部分一樣,都是大于0等于原始值,但負向部分卻是等于原始值的1/10,浮點運算的話乘個0.1就好了,如果因為量化要實現(xiàn)整數運算,這塊可以做個近似,如0.1用13>>7來代替,具體實現(xiàn)方法多種多樣 ,還算簡單。
ReLU & LeakyReLU
· Sigmoid系列
這里主要指sigmoid,還有和他相關的swish:
可以看出,如果按照公式來實現(xiàn)sigmoid對低性能的硬件來說非常不友好,因為涉及到大量的exp指數運算和除法運算,于是有研究人員針對此專門設計了近似的硬件友好的函數h-sigmoid和h-swish函數,這里的h指的就是hardware的意思:
可視化的對比如下圖所示,可以看出在保證精度的同時又能大大方便硬件的實現(xiàn),當然要直接實現(xiàn)sigmoid也是可以的,畢竟sigmoid是有限輸出,當輸入小于-8或大于8的時候,輸出基本上接近于-1和1,可以根據這個特點設計一個查找表,速度也超快,且我們實測對精度沒啥影響。
經典輕量化模型
早期比較經典的卷積神經網絡,如AlexNet,VGG,GoogleNet(或Inception),ResNet,DenseNet都是以提升模型在ImageNet數據集上的分類精度為主了,很少考慮參數量和計算量的問題,他們的主要結構解析起來也比較簡單,基本都是由標準卷積(7×7,5×5,3×3和1×1),Pooling和shortcut操作(Addition / Concatenate)構成,而且以3×3及其以上的卷積核為主,通道數也是動輒上千,所以參數量和計算量巨大。后續(xù)研究人員慢慢發(fā)現(xiàn)兩個3×3卷積可以代替一個5×5卷積的效果,三個3×3卷積可以代替一個7×7卷積的效果,大量使用1×1卷積,使用3×3 depthwise conv + pointwise conv(1×1標準卷積)可以代替3×3普通卷積......一系列操作可以減少參數量和計算量,所以下面講述一下一些輕量級神經網絡發(fā)展的歷史,因為這塊很多人都講過,所以我會簡單一些,挑重點說說。
· SqueezeNet
SqueezeNet是公認的輕量級模型設計最早期的工作之一,作者提出了三種策略來實現(xiàn)在保持精度的情況下大大減少當時主流模型(以AlexNet為例)的計算量和參數量:
1.將模型中一部分的3×3卷積用1×1來代替,1×1卷積是3×3參數量和計算量的1/9,所以可以大大減少參數量和計算量;
2.減少3×3卷積的輸入通道數,這個可以通過在進入3×3卷積之前加一個1×1卷積來實現(xiàn)通道數量的減少;
3.將下采樣層的位置往后推,使得模型可以在更大的feature map上進行更多的學習,這一步雖然會在增加計算量,但是和上面兩個策略結合可以在維持模型精度的情況下仍大大減少參數量和計算量;
fire module
根據上面的策略,作者提出了fire module的子結構,如下圖所示,然后整個模型由這樣的子結構堆疊而成。這個fire module由squeeze部分和expand部分構成,squeeze部分是1×1的卷積層,而expand部分是1×1的卷積和3×3的卷積拼接起來的,每次feature map輸入這個fire module會在squeeze層降低通道數,然后在expand通道增加通道數,從而在參數量更少的情況下仍然可以得到充分的學習。最后結合一些模型壓縮的方法可以使得SqueezeNet在達到AlexNet同等精度的情況下,參數量減少到后者的1/50,計算量減少到后者的1/510。
這篇論文使用大量1×1的卷積核代替3×3卷積,并且利用1×1卷積改變大尺度卷積層輸入feature map的通道數從而減少計算量的思想是非常有意義的,后續(xù)的很多輕量級網路的論文都沿用了這種套路。
MobileNet系列
MobileNet系列一共有V1,V2和V3三篇論文,簡要的講:
1.MobileNet V1主要思想是提出了一種新的結構—深度可分離卷積(Depthwise Separable Convolution)來代替標準3×3卷積,從而大大減少模型的參數量和計算量;
2.MobileNet V2在V1的基礎上提出了一種倒置殘差的模塊,這個模塊有三個卷積,第一個部分是一個1×1標準卷積,用來升維,第二個部分是由3×3深度卷積+1×1標準卷積構成的深度分離卷積,用來學習特征和降維,模塊的輸出和輸入再進行一個Addition的操作,由于和ResNet中維度升降方式相反,所以稱為倒置殘差。中間升維的作用是讓深度可分離卷積得到更充分的學習,計算量相對于標準卷積來說也不大,而且這種升降維的方式非常靈活,可以大大減少計算量。本文還從流形學的角度探究了輸入深度可分離卷積上一層的ReLU6對信息傳遞的影響,理論證明去掉上一個1×1標準卷積的ReLU激活函數能更有利于后面的深度可分離卷積對特征的學習。
MobileNet V2
3. MobileNet V3感覺相對于前兩篇沒有那么大的結構創(chuàng)新了,主要思想是神經架構搜索(NAS)和硬件友好結構,總的來看V3的結構是在V2的基礎上進行了一些修改,如增加了SE block這種已被提出的注意力機制,激活函數換成了H-swish,last stage減少了幾層計算,針對語義分割提出了Lite R-ASPP的head(不在討論之列),整個論文看著像是堆tricks,重點不是很突出,有點年底沖業(yè)績的嫌疑。
MobileNet V3
根據我自己的比賽和項目經驗來看,還是MobileNet V1和V2的結構比較實用,參數量和計算量小,可拓展性好,SE block這種模塊對延時影響還是不小,而且我們發(fā)現(xiàn)其他各種花里胡哨的激活函數跟ReLU/ReLU6相比都差不多,對精度沒有很大的影響,還不如直接部署ReLU/ReLU6來的方便。
*博客內容為網友個人發(fā)布,僅代表博主個人觀點,如有侵權請聯(lián)系工作人員刪除。