博客專欄

        EEPW首頁 > 博客 > 綜述:輕量級CNN架構設計(3)

        綜述:輕量級CNN架構設計(3)

        發布人:計算機視覺工坊 時間:2021-09-14 來源:工程師 發布文章

        ·  ShuffleNet系列

        曠視出品的ShuffleNet系列有兩篇論文,且后一篇在打前一篇的臉,很有意思。

        1.ShuffleNet V1是在MobileNet V1后MobileNet V2前提出的,說實話結構上和MobileNet V2還挺像,大家可以上下兩張圖片對比一下。兩者都想到了學習ResNet的殘差結構,區別在于ShuffleNet V1覺得block當中的1×1標準卷積也非常耗時,于是用1×1的分組卷積外加channel shuffle的操作給替換了,然后MobileNet V2會先升維讓深度可分離卷積得到充分的學習再降維回來,ShuffleNet V1中stride為2的模塊也有自己的特色,雖然看著MobileNet V2的結構更簡潔一些,但ShuffleNet V1創新也是不少,尤其那個用channel shuffle增強不同組之間信息交互的操作。

        19.png

        ShuffleNet V1

        2. ShuffleNet V2論文是一篇誠意滿滿之作,作者通過分析ShuffleNet v1與MobileNet v2這兩個移動端網絡在GPU/ARM兩種平臺下的時間消耗分布,看出Conv等計算密集型操作占了絕大多數時間,但其它像Elemwise和IO等內存讀寫密集型操作也占了相當比例的時間,因此像以往那樣僅以FLOPs來作為指導準則來設計CNN網絡是不完備的,雖然它可以反映出占大比例時間的Conv操作,但不夠準確。于是作者提出了高效網絡設計的四個指導原則:

        1. 當輸入和輸出的通道數相同時,conv計算所需的MAC(memory access cost)最小;

        2. 大量的分組卷積會增加MAC開銷;

        3. 網絡結構的碎片化會減少其可并行優化的程度,GoogleNet系列和NASNet中很多分支進行不同的卷積/pool計算非常碎片,對硬件運行很不友好;

        4. Element-wise操作不可忽視,對延時影響很大,包括ReLU,Addition,AddBias等,主要是因為這些操作計算與內存訪問的占比太小;

        基于此,作者提出了ShuffleNet V2的blocks,如下所示,與V1相比,去掉了分組卷積的操作,去掉了Add操作,換成了Concat,stride為2的block的旁路把平均池化換成了深度可分離卷積,為了繼續延續channel shuffle的操作,作者在block進去的地方做了個split的操作,最后再concat+channel shuffle,這里是為了替換掉之前的Add,同時也可以減少計算量。

        20.png

        ShuffleNet V2

        Shift: A Zero FLOP, Zero Parameter Alternative to Spatial Convolutions

        這是一篇很有意思的論文,主要是提出了一種無參數,無計算的移位算子來代替ResNet中計算量占比很高的3×3卷積,這種算子稱為shift kernel,如下圖所示,只需要根據kernel上的shift信息對feature map進行位置上的上下左右偏移即可得到新的feature map,沒有計算,僅僅是訪存操作。詳細一點說就是如下面Shift框里面的第一個卷積核,它只在黃色的區域為1,其他白色的區域為0,在做卷積計算的時候其實就相當于把輸入feature map中間偏左邊的那個點的值平移到輸出feature map中間的地方,正如作者標注的向右的箭頭所示。而且這個操作都是per-channel的,所以每個卷積核只有k×k種可能性,當通道數大于k×k時,就需要將所有通道分成iC/(k×k)組,剩下的channel設置為center,即中間為1,其余為0,然后怎么去選取每個卷積核的類型呢,論文在兩個shift kernel中間夾了一個1×1的標準卷積,要保證第二次shift操作之后數據與第一次輸入shift kernel之前順序一致,并且這個shift操作可以通過SGD的方式進行端到端訓練,再具體的細節論文其實也沒有闡述的很清楚,而且我目前也沒有看到作者公布源代碼,不過這篇論文看起來還是很有意思的,論文中還分析了depthwise計算不高效的原因在于計算/IO時間導致運行更慢的問題,其實這個shift kernel的作用并沒有產生新的信息或者去進行特征的學習(畢竟連參數都沒有),而是對feature map空域的信息做了個混洗,使得與他相接的1×1卷積可以學到更豐富的特征,在我看來有點類似于在網絡內部做數據增強的感覺。

        21.png

        Shift

        · GhostNet

        GhostNet也是一篇很有意思且簡潔的架構設計的論文,作者在可視化一些訓練好的神經網絡中間feature map時發現它們通常會包含一些相似且冗余的特征圖,使得神經網絡能得到更充分的學習。基于這個想法,作者通過設定一系列廉價的線性運算操作來代替部分卷積計算,以此來產生更多的特征圖,僅僅這么一個簡單的操作就可以減少模型的參數量和計算量,而且在幾個視覺公開數據集上取得了很不錯的效果,甚至超越了MobileNet V3,感覺非常的大道至簡,這也是我比較喜歡的原因。

        22.png

        GhostNet

        基于特定硬件的神經架構搜索

        基于特定硬件的神經架構搜索(MIT HAN Lab論文總結

        https://zhuanlan.zhihu.com/p/320290820)

        設計方法總結

        接下來我將結合自己看過的論文,還有這一年多的項目比賽經歷談一談我所理解的圖像分類和目標檢測相關輕量級模型設計,本文思想還比較淺薄,主要是給自己的工作做個總結,有不正確的地方希望大家能共同討論。

        設計之前

        通常我們都是基于已有的硬件架構去進行模型的部署,這個時候就需要確定這個架構下能部署什么算子,可以通過已有的接口自己拓展哪些算子,并且哪些算子不是很高效。就拿我去年參加的某視覺加速比賽來說,當時初出茅廬,不太懂硬件底層,頭鐵要在Xilinx ultra96 V1板子 + 我們組自研的硬件架構上部署當時最新,準確率最高的EfficientNet,因為準確率確實高,老板就欽定必須使用這個模型,并且選擇了比較合適的EfficientNet-B4,輸入分辨率由384改成256。后來一頓開搞發現有很多swish操作,這個雖然之前還沒有經驗,但是還好很快想到用查找表去實現了,并且還發現我們的架構尚且不能實現全連接層(勿噴,之前都是在搞全卷積網絡),所以里面的SE block還有最后一層都無法用我們的架構部署,然后博士師兄就想到了利用ultra96板子上的ARM+NEON加速技術去實現這一部分,每次PS和PL交互數據,當時只有一個月的開發時間,因為這個模型比較大且當時我們開發模式的問題,連續熬夜差點沒把整個組人的命搭進去,最后上板跑幀率也只有6幀(師兄最開始預估能達到80幀,所以大家一直不停的往下做hhhhh),在ImageNet驗證集上純浮點準確率是0.805,INT8準確率是0.793,幀率低的原因有兩點,一個是模型確實很大,另一個是因為SE block在每一個stride為1的module中都出現了,整個模型PS和PL交互十分頻繁,而我們當時間很緊剛剛完成一版就必須提交了,所以這塊也根本沒有優化,導致了延時很高,并且當時我們的架構只跑了100M的頻率,更高頻率會有一些bug(貌似是板子的問題),所以幀率非常低,這個真的是血的教訓:一定要量力而行,仔細研究評價指標,在硬件友好程度和精度上做一個trade-off,一味片面地追求精度真的要命呀。

        輕量級CNN架構設計

        總的思路: 選定合適結構 + 通道剪枝 + 量化

        訓練 :ImageNet pretrain model + Data Normalization(統計自己數據集的均值和方差) + Batch Normlization + 大batch size + 一堆數據增強tricks + 嘗試各種花里胡哨的loss function和optimizer

        (再次說明這部分只討論圖像分類和目標檢測兩種任務,目前的視覺加速比賽基本都是基于這兩個任務做的,按照計算資源和內存從小到大排列,不用問,沒有劃分原則)

        1.絕對貧窮人口

        輸入分辨率要小,如128,160,192或256;

        下采樣使用MaxPooling;

        特征學習層使用Depthwise Separable Convolution,即一層3×3的Depthwise + 一層pointwise(1×1標準卷積)堆疊;

        激活函數用ReLU;

        另外這里推薦看看MCUNet,感覺非常呦西,MIT韓松團隊yyds!

        2. 相對貧窮人口

        輸入分辨率依舊要小,記住分辨率對計算量的影響都是翻倍的;

        下采樣可以使用MaxPooling或者stride為2的Depthwise Separable Convolution;

        特征學習層使用Depthwise Separable Convolution,或者MobileNet V2的倒置殘差結構,又或是ShuffleNet V2的unit,1×1的Group convolution能處理的比較好的話其實也推薦使用(主要是計算/訪存);

        激活函數用ReLU或者ReLU6;

        3. 低收入人口

        輸入數據選用小分辨率,如果對精度要求高一些可以適當增大;

        下采樣可以使用MaxPooling或者stride為2的Depthwise Separable Convolution;

        特征學習層可以使用MobileNet V2的倒置殘差結構,又或是ShuffleNet V2的unit,也可以使用通道數小一點的3×3標準卷積;

        激活函數用ReLU,ReLU6或者leaky ReLU,看效果了;

        4.一般收入人口

        輸入數據可以稍微大一些,288,320,384啥的可以考慮上了;

        下采樣使用stride為2的Depthwise Separable Convolution或者stride為2的3×3卷積;

        特征學習層既可以使用上述的,也可以使用3×3標準卷積 + 1×1標準卷積的堆疊形式,SE block這種硬件支持的還不錯的可以嘗試加上;

        激活函數除了上述的可以試試H-sigmoid和H-swish,不過據我經驗效果基本和ReLU差不多;

        5.高收入人口

        輸入數據的分辨率可以往500-600靠攏了;

        下采樣和上述一樣;

        特征學習層可以上ResNet + SE block的配置,ResNet是真的牛逼,5×5的卷積啥的也可以整上,第一層直接上7×7的標準卷積也不是不可以,資源再多了可以增加通道數和深度 或者 上多核并行計算;

        激活函數可以用H-swish;

        番外

        目標檢測任務中感覺Tiny YOLO V3非常受歡迎,建議嘗試!計算量太大可以換更輕量的backbone或者改輸入分辨率,輕量級的backbone+FPN的結構也很棒,且推薦使用商湯開源的mmdetection,訓練調參當場起飛。

        另外之前閱讀MIT HAN lab基于特定硬件的神經架構搜索相關文章時發現他們設計模型常用的一個子結構:MobileNetV2的倒置殘差模塊 + SE block + H-swish,看他們在很多算法加速比賽上拿了冠軍,感覺百試不爽呀,且根據硬件資源進行拓展的靈活度也很高,具體可以參見他們今年發表的OnceForAll論文中的模型,源代碼都在Github上能找到,MIT HAN lab真學術界良心,再喊一句MIT韓松團隊yyds!

        最后總結

        過去的一年被導師安排著參加各種比賽,去年啥也不懂的時候還能拿幾個不錯的獎,今年感覺學了很多懂了很多,使用的模型也都對硬件比較友好,量化后幾乎無損(一個點以內),反倒連連受挫,心情非常沮喪,而且總被奇奇怪怪的模型打敗,總有一種自己學了一身正派功夫,最后反倒被野路子出招一擊即潰的感覺,然后論文也被拒了,沒心思改投,回想一下碰上疫情的這一年真的好失落,可能還是我太菜了吧。

        馬上也要開始投入找實習(希望老板能放我)刷題找工作的階段了,最近也在培養下一屆,把工作慢慢移交給他們,一想到找工作,整個人的心態都不一樣了,無心科研,這篇文章就算是對我過去一年多的工作做個總結吧,同時也希望我們課題組能夠發展的越來越好,多多拿比賽大獎,多多發論文。

        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。

        pid控制器相關文章:pid控制器原理




        關鍵詞: AI

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 连云港市| 芜湖县| 乌兰县| 广汉市| 北京市| 陆川县| 兴安盟| 凯里市| 婺源县| 滦平县| 淅川县| 珠海市| 房山区| 土默特左旗| 河池市| 西乌珠穆沁旗| 玉树县| 太白县| 封开县| 临武县| 江安县| 和平县| 武隆县| 德江县| 长葛市| 山东| 呼伦贝尔市| 冷水江市| 马山县| 武清区| 都江堰市| 福鼎市| 聂荣县| 平湖市| 阿城市| 松阳县| 万载县| 扶余县| 潜山县| 汶上县| 上林县|