輕量級網絡
本文大綱
- squeezenet: 還沒寫…
- mobilenet v1:《MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications》
- mobilenet v2:《MobileNetV2: Inverted Residuals and Linear Bottlenecks》
- mobilenet v3: 還沒看…
- shufflenet v1:《ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices》
- shufflenet v2:《ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design》
一、mobilenet v1
1.核心貢獻:
- 提出用深度可分離卷積代替傳統卷積方式降低網絡參數並提高運算速度;
- 利用深度可分離卷積和兩個超參數構建一個參數少又快速的輕量級網絡結構,可以滿足移動和嵌入式視覺應用的設計要求。
2.深度可分離卷積
-
標準卷積定義:
對所有的輸入channel進行計算得到一個新的channel。圖a -
深度可分離卷積定義:
將標準卷積分解成深度卷積和一個逐點卷積(1 * 1 卷積),深度卷積負責對單個輸入channel用單個卷積核進行計算,逐點卷積負責1x1的卷積來結合所有深度卷積得到的輸出,這種分解能夠有效的大量減少計算量以及模型的大小。圖b和圖c -
傳統卷積計算方式:
傳統的卷積使用的是和輸入channel相同的卷積核,每次計算和所有輸入channel卷積後求和得出一個數作爲結果,計算量爲
其中爲輸入的通道數,爲卷積核的寬和高
一個卷積核在padding情況下對輸入數據的計算量爲: ,爲輸入的寬和高
但是一般我們希望下一層輸出個channel,就需要使用N個卷積核,所以一層的計算量爲: -
深度可分離卷積計算方式:
-
depth-wise conv計算量?
depth-wise:每個卷積核的channel爲1,只和一個輸入channel做卷積計算,計算量爲,輸入和輸出的channel都是,所以計算量是。 -
point-wise conv計算量?
point-wise:使用1* 1卷積核來處理之前depth-wise輸出的特徵圖,將輸出通道數變爲一個,計算量爲。 -
深度可分離卷積計算量?
depth-wise+point-wise總計算量爲:
深度可分離卷積和傳統卷積計算量比值:
-
-
例子:
如果是64*64*32的輸入,希望用3*3的卷積核(其實是3*3*64*128,每個卷積核64channel,一共128個)得到64*64*128的輸出,
channel從32變成了128,這裏得到一個新channel就需要對輸入的32個channel進行計算,
總的計算是 (3*3) * (32*128) * (64*64) = 150,994,944;
還是剛纔說的例子:深度卷積每個channel之和一個卷積覈計算: 32 * (64 * 64) * (3 * 3) = 1,179,648,
逐點卷積: 32 * 128 (64 * 64) * (1 * 1) = 131,072, 加起來爲 1,310,720 和普通卷積整整差了兩個量級。
3.mobilenet結構
- 模塊結構:
3 * 3 depth-wise conv和 1 * 1 point-wise 後鬥接了BN和RELU。 - 網絡結構
標準的分類網絡輸出size 224 * 224 * 3,5次降採樣, 最後對7 * 7 * 1024做global avgpooling + FC + softmax分類。 - 網絡各個部分計算量
參數量主要幾種在1 * 1 conv的地方,因爲1 * 1 conv纔是跨通道信息的融合,計算量需要與輸入輸出channel都有關,但是1 * 1 conv不需要在內存中重新排序可以直接被GEMM(最優化的數值線性代數算法)實現。可以大大優化速度。
除了1 * 1 conv外的參數主要幾種在FC層,可見卷積部分改成深度可分離卷積減少了很多計算。 - 兩個超參數 :爲了能構建更小的網絡,文中提出了兩個超參數,一個控制channel,一個控制分辨率
- 寬度因子:
控制輸入和輸出的channel,即輸入channel從變爲, 輸出channel從變爲;
,通常設置爲1,0.75,0.5和0.25 - 分辨率因子:
控制輸入圖像的分辨率和網絡中各層分辨率;
,通常設置輸入分辨率爲224,192,160,128。
- 寬度因子:
二、mobilenet v2
1.核心貢獻.
-
爲什麼引入殘差模塊?
引入殘差模塊,更好的複用特徵,而且梯度更容易傳播; -
爲什麼這裏的residual模塊叫 Inverted residuals?
殘差模塊改爲對channel先升維在降維(resnet裏是先降維再升維),因爲depth-wise conv本來維度就低,這樣防止信息丟失;
resnet是高維輸入-轉化低維-恢復高維,Inverted residuals是低維輸入-轉換高維-恢復低維所以叫Invertedde(相反的) 。 -
爲什麼去掉residual模塊的最後一個RELU?
Linear bottlenecks: ReLU會對channel數低的張量造成較大的信息損耗(因爲relu會把<0的激活置0,並且無法恢復), 深度可分離卷積維度本來就很低,爲了避免Relu丟失太多特徵,去掉residual block的eltwise sum之前的那個 1*1 conv後的Relu; -
爲什麼用RELU6,而不是RELU?
RELU改爲RELU6: 限制最高輸出爲 6激活函數,爲了在移動端設備的float16的低精度也能使用,不限制,輸出的話可以到正無窮,如果激活值特別大,轉換成floap16會有很多精度損失。
2.mobilenet v2結構
- 模塊結構
【圖片來自1】
mobilenet v1: 3 * 3 depthwise conv +bn + relu + 1 * 1 point-wise conv + bn + relu;
mobilenet v2: 1 * 1 point-wise conv + bn + relu6 + 3 * 3 depthwise conv +bn + relu6 + 1 * 1 point-wise conv + bn 並且第一個1 * 1卷積升維到6倍輸入channel,最後一個1 * 1卷積降維到輸入channel,最後無relu;
resnet: 1 * 1 point-wise conv + bn + relu+ 3 * 3 conv +bn + relu + 1 * 1 point-wise conv + bn + relu並且第一個1 * 1卷積降維到0.25倍輸入channel,最後一個1 * 1卷積升維到輸入channel,最後有relu; - 網絡結構
除了模塊的改進之外,一個最大的改動就是mobilenet v1最後的FC改成了卷積,所以mobilenet v2其實是一個全卷積的網絡。
三、shuffleNet v1
1.核心貢獻
- 結合 group conv 和 channel shuffle 來設計卷積神經網絡模型, 減少模型使用的參數數量並加速運行;
2.group conv
- 如何做 group conv 和 channel shuffle ?
把各組的 channel 平均分爲 份(文中設置g=3),然後按照順序的重新構成 新的feature map;
本文把group conv用在1 * 1卷積裏,所以是point-wise group conv。 - 計算量
resnet模塊: 1 * 1 conv + 3 * 3 conv + 1 * 1 conv, 跳躍連接求和;
ResNeXt模塊: 1 * 1 conv + 3 * 3 group conv + 1 * 1 conv, 跳躍連接求和;
shufflenet v1模塊: 1 * 1 conv + 3 * 3 depth-wise conv + 1 * 1 conv,跳躍連接求和;
假設輸入是c × h × w, bottleneck channels 是m,
ResNet計算量爲
ResNeXt計算量爲
ShuffleNet計算量爲
說明:
h*w*c是輸入feature map大小,1*1 conv改變channel爲m,所以計算量爲h*w*c*m,
但是因爲最後還原channel爲n,所以是h*w*c*m*2,
因爲kernelsize是3*3,且輸入輸出channel都是m,所以普通conv計算是h*w*3*3*m*m,
group conv計算量是h*w*3*3*m*m/g,
depthwise conv計算式h*w*3*3*m,
ShuffleNet裏的group conv操作放在了1*1,所以它的1*1卷積計算量除以g。
-
爲什麼flops評估模型速度不合理?
有些時候即使flops小也可能計算比較慢,因爲有內存消耗、GPU並行性、IO次數等等的影響因素;
比如有時候需要多次IO或者改變數據分佈(img2col)等。 -
爲什麼要group conv?
group conv其實是conv和深度可分離卷積的折中,對channel分組計算,每個輸出只跟幾個輸入channel有關,能大大***減小計算量***,在ResNeXt中就有使用。 -
爲什麼用在point-wise卷積裏?
1 * 1卷積其實也需要很大計算量(mobilenet v1中佔70%多計算量),ResNeXt裏有很多pointwise卷積其實影響了網絡速度,但是目前都是對3 * 3改成group-wise卷積或者depthwise卷積其實不是很合理,所以本文進一步對1 * 1改進。 -
爲什麼要channel shuffle?
mobilenet v1的1 * 1卷積計算量大,是考慮所有輸入channel的 計算,改成group-wise conv可以減少計算量和參數量,但是channel之前沒有了信息流通,尤其是depthwise+pointswise的結構,本身depthwise就沒考慮channel之間交互,pointwise改成了group又減少了channel交互,所以使用channel shuffle,將feature map 的 channel 有序打亂,構成新的 feature map,從而解決 group conv 信息不流通的問題。
3.網絡結構
- 模塊結構
圖中b和c是shufflenet結構,b是沒有改變h和w的,c是降採樣2倍的結構,相比之下c結構在跳躍連接的地方多了一個kernel size3 * 3,步長爲2 的平均池化
總體就是: 1 * 1 group conv + channel shuffle + 3 * 3 depth-wise conv + 1 * 1 group conv; - 整體結構
三、shuffleNet v2
1.核心貢獻
- flops衡量網絡速度不準確,即使參數量相同,但是速度也不同,改爲直接用速度來衡量;
- 提出輕量級網絡設計的4條準則:
MAC爲memory access cost(內存訪問成本).
G1: 儘可能使用輸入通道和輸出通道相同的卷積操作,point-wise conv 的升維降維會影響速度;
G2: 分組越多,MAC越大;
G3: 減少網絡分支數,因爲網絡分支會影響GPU運算的並行化;
G4: 減少element-wise操作; - 引入channel split,設計了一個更高效高精度的網絡shufflenet v2;
2. channel split
c和d分別是v2的basic unit和下采樣2倍的unit:
v2主要引入了channel split,分割channel爲2份(滿足G3,只分爲2份);
右側的分支輸入和輸出channel一致(滿足G1);
右側的卷積沒有使用分組卷積(滿足G2);
左側和右側合併的時候使用concat而不是element-wise sum(滿足G4)
堆疊ShuffleNet v2模塊時,concat,channel shuffle,channel split可以合併成1個element-wise操作(滿足G4)。
3.網絡結構
- 整體結構: