輕量級卷積神經網路的設計技巧
這篇文章將從一個證件檢測網路(Retinanet)的輕量化談起,簡潔地介紹,我在實操中使用到的設計原則和idea,並貼出相關的參考資料和成果供讀者參考。因此本文是一篇注重工程性、總結個人觀點的文章,存在不恰當的地方,請讀者在評論區指出,方便交流。
目前已有的輕量網路有:MobileNet V2和ShuffleNet v2為代表。在實際業務中,Retinanet僅需要檢測證件,不涉及過多的類別物體的定位和分類,因此,我認為僅僅更換上述兩個骨架網路來優化模型的效能是不夠的,需要針對證件檢測任務,專門設計一個更加輕量的卷積神經網路來提取、糅合特徵。
設計原則:
1. 更多的資料
輕量的淺層網路特徵提取能力不如深度網路,訓練也更需要技巧。假設保證有足夠多的訓練的資料,輕量網路訓練會更加容易。
Facebook研究院的一篇論文[1]提出了“資料蒸餾”的方法。實際上,標註資料相對未知資料較少,我使用已經訓練好、效果達標的base resnet50的retinanet來進行自動標註,得到一批10萬張機器標註的資料。這為後來的輕量網路設計奠定了資料基礎。我認為這是構建一個輕量網路必要的條件之一,網路結構的有效性驗證離不開大量的實驗結果來評估。
接下來,這一部分我將簡潔地介紹輕量CNN地設計的四個原則
2. 卷積層的輸入、輸出channels數目相同時,計算需要的MAC(memory access cost)最少
3. 過多的分組卷積會增加MAC
對於1x1的分組卷積(例如:MobileNetv2的深度可分離卷積採用了分組卷積),其MAC和FLOPS的關係為:
g代表分組卷積數量,很明顯g越大,MAC越大。詳細參考[2]
4. 網路結構的碎片化會減少可平行計算
這些碎片化更多是指網路中的多路徑連線,類似於short-cut,bottle neck等不同層特徵融合,還有如FPN。拖慢並行的一個很主要因素是,運算快的模組總是要等待運算慢的模組執行完畢。
5. Element-wise操作會消耗較多的時間(也就是逐元素操作)
從表中第一行資料看出,當移除了ReLU和short-cut,大約提升了20%的速度。
以上是從此篇論文[2]中轉譯過來的設計原則,在實操中,這四條原則需要靈活使用。
根據以上幾個原則進行網路的設計,可以將模型的引數量、訪存量降低很大一部分。
接下來介紹一些自己總結的經驗。
6. 網路的層數不宜過多
通常18層的網路屬於深層網路,在設計時,應選擇一個參考網路基線,我選擇的是resnet18。由於Retinanet使用了FPN特徵金字塔網路來融合各個不同尺度範圍的特徵,因此Retinanet仍然很“重”,需要儘可能壓縮骨架網路的冗餘,減少深度。
7. 首層卷積層用空洞卷積和深度可分離卷積替換
一個3x3,d=2的空洞卷積在感受野上,可以看作等效於5x5的卷積,提供比普通3x3的卷積更大的感受野,這在網路的淺層設計使用它有益。計算出網路各個層佔有的MAC和引數量,將引數量和計算量“重”的卷積層替換成深度可分離卷積層,可以降低模型的引數量。
這裡提供一個計算pytorch 模型的MAC和FLOPs的python packages[3]。
if __name__ == "__main__":
from ptflops import get_model_complexity_info
net = SNet(num_classes=1)
x = torch.Tensor(1, 3, 224, 224)
net.eval()
if torch.cuda.is_available():
net = net.cuda()
x = x.cuda()
with torch.cuda.device(0):
flops, params = get_model_complexity_info(net, (224, 224), print_per_layer_stat=True, as_strings=True, is_cuda=True)
print("FLOPS:", flops)
print("PARAMS:", params)
output:
(regressionModel): RegressionModel(
0.045 GMac, 27.305% MACs,
(conv1): Conv2d(0.009 GMac, 5.257% MACs, 128, 256, kernel_size=(1, 1), stride=(1, 1))
(act1): ReLU(0.0 GMac, 0.041% MACs, )
(conv2): Conv2d(0.017 GMac, 10.472% MACs, 256, 256, kernel_size=(1, 1), stride=(1, 1))
(act2): ReLU(0.0 GMac, 0.041% MACs, )
(conv3): Conv2d(0.017 GMac, 10.472% MACs, 256, 256, kernel_size=(1, 1), stride=(1, 1))
(act3): ReLU(0.0 GMac, 0.041% MACs, )
(output): Conv2d(0.002 GMac, 0.982% MACs, 256, 24, kernel_size=(1, 1), stride=(1, 1))
)
(classificationModel): ClassificationModel(
0.044 GMac, 26.569% MACs,
(conv1): Conv2d(0.009 GMac, 5.257% MACs, 128, 256, kernel_size=(1, 1), stride=(1, 1))
(act1): ReLU(0.0 GMac, 0.041% MACs, )
(conv2): Conv2d(0.017 GMac, 10.472% MACs, 256, 256, kernel_size=(1, 1), stride=(1, 1))
(act2): ReLU(0.0 GMac, 0.041% MACs, )
(conv3): Conv2d(0.017 GMac, 10.472% MACs, 256, 256, kernel_size=(1, 1), stride=(1, 1))
(act3): ReLU(0.0 GMac, 0.041% MACs, )
(output): Conv2d(0.0 GMac, 0.245% MACs, 256, 6, kernel_size=(1, 1), stride=(1, 1))
(output_act): Sigmoid(0.0 GMac, 0.000% MACs, )
)
8. Group Normalization 替換 Batch Normalization
BN在諸多論文中已經被證明了一些缺陷,而訓練目標檢測網路耗費視訊記憶體,開銷巨大,通常凍結BN來訓練,原因是小批次會讓BN失效,影響訓練的穩定性。建議一個BN的替代--GN,pytorch 0.4.1內建了GN的支援。
9. 減少不必要的shortcut連線和RELU層
網路不夠深,沒有必要使用shortcut連線,不必要的shortcut會增加計算量。RELU與shortcut一樣都會增加計算量。同樣RELU沒有必要每一個卷積後連線(需要實際訓練考慮刪減RELU)。
10. 善用1x1卷積
1x1卷積可以改變通道數,而不改變特徵圖的空間解析度,引數量低,計算效率也高。如使用kernel size=3,stride=1,padding=1,可以保證特徵圖的空間解析度不變,1x1的卷積設定stride=1,padding=0達到相同的目的,而且1x1卷積運算的效率目前有很多底層演算法支援,效率更高。[5x1] x [1x5] 兩個卷積可以替換5x5卷積,同樣可以減少模型引數。
11. 降低通道數
降低通道數可以減少特徵圖的輸出大小,視訊記憶體佔用量下降明顯。參考原則2
12. 設計一個新的骨架網路找對參考網路
一個好的骨架網路需要大量的實驗來支撐它的驗證,因此在工程上,參考一些實時網路結構設計自己的骨架網路,事半功倍。我在實踐中,參考了這篇[4]paper的骨架來設計自己的輕量網路。
總結
我根據以上的原則和經驗對Retinanet進行瘦身,不僅侷限於骨架的新設計,FPN支路瘦身,兩個子網路(迴歸網路和分類網路)均進行了修改,期望效能指標FPS提升到63,增幅180%。
FPS
mAP
Model size
注:本文中部分觀點參考來源
1 https://towardsdatascience.com/types-of-convolutions-in-deep-learning-717013397f4d
2 The Receptive Field, the Effective RF, and how it s hurting your results
https://www.linkedin.com/pulse/receptive-field-effective-rf-how-its-hurting-your-rosenberg/
3 https://arxiv.org/abs/1807.11164
4 mp.weixin.qq.com/s?
參考
Data Distillation Towards Omni-Supervised Learning
ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
https://github.com/zhouyuangan/flops-counter.pytorch
ThunderNet: TowardsReal-timeGenericObjectDetection
喜歡文章,點個在看
相關文章
- 輕量級卷積神經網路的設計卷積神經網路
- 卷積神經網路的引數量和計算量卷積神經網路
- 卷積神經網路卷積神經網路
- 卷積神經網路-AlexNet卷積神經網路
- 5.2.1 卷積神經網路卷積神經網路
- 卷積神經網路CNN卷積神經網路CNN
- 卷積神經網路概述卷積神經網路
- 解密卷積神經網路!解密卷積神經網路
- 卷積神經網路-1卷積神經網路
- 卷積神經網路-2卷積神經網路
- 卷積神經網路-3卷積神經網路
- 卷積神經網路四種卷積型別卷積神經網路型別
- 全卷積神經網路FCN卷積神經網路
- 深度剖析卷積神經網路卷積神經網路
- 設計卷積神經網路CNN為什麼不是程式設計?卷積神經網路CNN程式設計
- 【深度學習篇】--神經網路中的卷積神經網路深度學習神經網路卷積
- 卷積神經網路鼻祖LeNet網路分析卷積神經網路
- 卷積神經網路中的Winograd快速卷積演算法卷積神經網路演算法
- 何為神經網路卷積層?神經網路卷積
- 卷積神經網路(CNN)詳解卷積神經網路CNN
- CNN神經網路之卷積操作CNN神經網路卷積
- 卷積神經網路 part2卷積神經網路
- 14 卷積神經網路(進階)卷積神經網路
- Tensorflow-卷積神經網路CNN卷積神經網路CNN
- Matlab程式設計之——卷積神經網路CNN程式碼解析Matlab程式設計卷積神經網路CNN
- 吳恩達《卷積神經網路》課程筆記(1)– 卷積神經網路基礎吳恩達卷積神經網路筆記
- (四)卷積神經網路 -- 8 網路中的網路(NiN)卷積神經網路
- 淺聊卷積神經網路的發展卷積神經網路
- 卷積神經網路中感受野的理解和計算卷積神經網路
- 卷積神經網路-啟用函式卷積神經網路函式
- 深度學習三:卷積神經網路深度學習卷積神經網路
- 一文看懂卷積神經網路卷積神經網路
- 卷積神經網路:Convolutional Neural Networks(CNN)卷積神經網路CNN
- 卷積神經網路(Convolutional Neural Network,CNN)卷積神經網路CNN
- 直白介紹卷積神經網路(CNN)卷積神經網路CNN
- 卷積神經網路—基本部件(2)卷積神經網路
- 從MobileNet看輕量級神經網路的發展神經網路
- 經典卷積神經網路LeNet&AlexNet&VGG卷積神經網路