1.模型計算複雜度的度量
不同模型在不同硬體下速度、準確率、MFLOPs 的關係
FLOPs 指浮點運算數,也就是計算量,是一種比較常見的衡量模型計算複雜度的指標。但 FLOPs 並不是一種直接指標,不能用於準確衡量兩個模型計算的速度。例如 FLOPs 相同的 MobileNetV2 和 NASNET-A 模型,MobileNetV2 要遠遠快於 NASNET-A。
如上圖所示,圖 a 和圖 c 是在 GPU 上訓練的,圖 b 和圖 d 是在 ARM 上訓練的。透過圖 c 和圖 d 可以看到在相同 FLOPs 的情況下,不同模型的計算速度有很大的差別。ShuffleNetV2 的作者認為這種差別主要有兩個原因:
有很多影響速度的因素是 FLOPs 沒有考慮到的,例如 MAC (記憶體使用量,memory access cost) 和模型並行度。在分組卷積中,MAC 的花銷佔了執行花銷很大一部分,對於 GPU 這種計算能力比較強的硬體,這種花銷佔比會更大,因此不能簡單地忽略。另外模型的並行度也是影響速度的重要因素,在相同的 FLOPs 下,並行度高的模型速度更快。具有相同 FLOPs 的操作在不同硬體 (GPU,ARM) 上的執行速度存在差異,不同的計算庫也會對速度產生影響 (例如不同版本的 CUDNN)。因此 ShuffleNetV2 的作者認為在設計模型結構的時候,應該遵循以下兩個原則:
應該使用直接的度量方式 (速度),而不是間接的度量方式 (FLOPs)。需要在不同的硬體平臺上評估。下圖是 MobileNetV2 和 ShuffleNet 在不同硬體平臺上的時間花銷圖。
ShuffleNet 和 MobileNetV2 在不同平臺的時間佔比
2.四個實踐指導準則作者透過實驗得到四個對於提高模型效率有用的指導準則。
2.1 G1: 相同的通道數可以減少 MAC
給定一個 1×1 的卷積層,其輸入維度是 c1,輸出維度是 c2,feature map 尺寸為 h×w。則其對應的 FLOPs 為:
FLOPs 計算公式
該卷積對應的 MAC 值包括輸入、輸出的 feature map 和卷積核權重。的在記憶體足夠的前提下,MAC 的值為:
MAC 計算公式
B 為 FLOPs 的值,我們固定 B 的取值 (即保證模型 FLOPs 相同)。根據均值不等式,可以得到下面的公式,該不等式只有在 c1=c2 時取得最小值,即說明當輸入和輸出的 channel 相同時,MAC 最小:
MAC 的下限
作者同樣採用了實驗驗證 c1 和 c2 比例對於速度的影響,結果如下表所示,實驗中作者保持模型的 FLOPs 是一致的。可以看到 c1=c2 時模型速度最快。
G1 實驗
2.2 G2: 過多的分組卷積會增加 MAC
在 ShuffleNet 和 MobileNet 裡都用到了分組卷積 (Group Convolution),因為分組卷積可以減少模型的 FLOPs,但是當 FLOPs 值固定時,分組 g 越多,MAC 也會越大。分組卷積的 FLOPs 計算公式如下:
分組卷積 FLOPs 計算公式
當 FLOPs 值固定,輸入的 feature map 尺寸固定 c1×h×w 時,MAC 與分組數量 g 成正比,如下所示:
MAC 和 g 成正比
作者用實驗驗證了在 FLOPs 固定的情況下,分組數量 g 對於模型速度的影響,結果如下表所示,可以看到 g=1 時模型比較快。
G2 實驗
2.3 G3: 模型碎片化會降低並行度
在 GoogleNet、NASNET-A 等網路中採用了不少多路結構,在一個 Block 裡面包含很多小的操作,例如多個小的卷積操作或者池化操作。雖然這種碎片化的結構對於模型準確性有利,但是會降低效率,因為它對於具有具有強大的平行計算能力的裝置不友好,例如GPU。
作者透過實驗驗證了碎片化結構對模型速度的影響,實驗中保持各模型 FLOPs 值相同,結果如下表所示。
G3 實驗
2.4 G4: 元素操作是不可忽略的
模型中的一些元素級操作 (element-wise operators) 通常 FLOPs 值不大,但是 MAC 值卻比較大,常見的元素級操作包括 ReLU、Add 等。作者使用 ResNet 中的 bottleneck 單元進行實驗,發現移除 ReLU 和 shortcut 後可以提高 20% 的速度,實驗結果如下表所示。
G4 實驗
3.ShuffleNetV2根據上面提到的四種實踐指導準則,我們可以發現 ShuffleNet 和 MobileNetV2 中存在的問題。其中 ShuffleNet 存在的問題:
使用了大量的分組卷積,違反了 G2。使用了 bottleneck 結構,即輸入、輸出 channel 大小不一樣,違反了 G1。MobileNetV2 存在的問題:
使用了 bottleneck 結構,違反了 G1。在 feature map 上使用了 depthwise 卷積和 ReLU,違反了 G4。下圖展示了 ShuffleNetV2 的結構,其中圖 a 是 ShuffleNet,圖 b 是進行下采樣 (即設定 stride,減小 feature map 的尺寸) 的 ShuffleNet,圖 c 是 ShuffleNetV2,圖 d 是進行下采樣的 ShuffleNetV2。
ShuffleNet 和 ShuffleNetV2
ShuffleNetV2 使用了一種新的操作 channel split,如上圖 c 所示。channel split 會把原始通道數 c 拆成兩個部分 c-c' 和 c',根據原則 G3,其中一個分支保持不變,另一個分支包含三個卷積操作,這些卷積操作輸入輸出的通道數是一樣的,保證 G1 滿足。
ShuffleNetV2 中的 1×1 卷積不再分組,一方面這滿足了 G2,另一方面 channel split 操作本身就已經將通道分為了兩組。經過卷積之後,ShuffleNetV2 會將兩個分支拼接在一起 (concat),而不是採用 Add 操作,從而減少元素級操作,滿足 G4。最後 ShuffleNetV2 再用 channel shuffle 混合通道。
ShuffleNetV2 的整體結構如下表:
ShuffleNetV2
4.實驗效果實驗結果
5.參考文獻ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design