[17.07] ShuffleNet
通道洗牌網路
ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices
輕量網路的競賽才剛開始。
ShuffleNet 也在這個時候加入戰局。
定義問題
計算量與速度不一致
在本研究中,作者和之前研究一樣,想解決的還是同一件事:
- 如何在保持高精度的同時,為運算能力非常有限的移動設備設計一個高效的神經網路?
雖然如 MobileNet 和 SENet 等模型已向低計算成本方向邁出了一步,但這些模型在非常低的計算預算下(例如小於 150 MFLOPs)的性能仍有提升空間。
作者指出,現有的高效模型「在實際硬體上的實際推理時間和預期性能之間常常存在較大差距」。
大量 1x1 卷積
在 MobileNet-V1 中,作者有對整個網路架構的計算量進行分析,如上表。
本篇論文的作者 認為大量的 1x1 卷積是計算量的主要來源,應該要從這個角度著手,縮減計算量。
解決問題
組卷積
一個主要的挑戰是如何減少 1x1 卷積的計算量,作者認為提高分組數量是解決問題的辦法。
假設輸入和輸出的通道數都為 128。在不使用分組的情況下,1x1 卷積需要對每個輸出通道的每個輸入通道進行計算,因此乘法運算的總數為 次。然而,如果設定分組數量為 8,則每個分組所包含的通道數變成 。在這種情況下,每組內部的捲積計算僅涉及 16 個輸入通道與 16 個輸出通道之間的乘法,因此每個分組的計算量為 次乘法。 由於共有 8 個這樣的分組,總的乘法運算數為 次。
透過比較,可以看出分組卷積可以將計算量減少到原始 1x1 卷積的大約 12.5%,從 16,384 次降低到 2,048 次。
但是天下沒有白吃的午餐。
分組卷積的確可以減少計算量,但也會帶來一個問題:分組卷積會破壞通道之間的關聯性,如上圖 (a) 所示。
最終使整個網路的表現會大幅降低。
通道洗牌
為了解決分組卷積帶來的問題,作者提出了一個新的操作:通道洗牌,如上圖 (b) 所示。
概念是:既然分組限制了通道間互相流通信息的能力,那麼我們可以在分組內部引入一個操作,將不同分組的通道進行混合,以保持通道間的關聯性。
這個操作看似不好理解,但是我們可以直接實作洗牌的函數,就能理解這個操作的意義。
import torch
def shuffle_channel(x: torch.Tensor, groups: int) -> torch.Tensor:
batch_size, num_channels, height, width = x.size()
channels_per_group = num_channels // groups
x = x.view(batch_size, groups, channels_per_group, height, width)
x = x.permute(0, 2, 1, 3, 4).contiguous()
x = x.view(batch_size, num_channels, height, width)
return x
如上述函數,首先把通道數量分成幾個組,然後移動通道的位置,這樣就可以實現通道洗牌的效果。舉例來說,如果原本的通道是:AAA,BBB,CCC,經過洗牌後變成:ABC,ABC,ABC。
雖然說是洗牌,但不是隨機的洗牌,而是有規則的洗牌,反正就是要讓不同組的通道能夠互相交流信息就對了。
洗牌模組放置位置
最後是洗牌模組的放置位置,如上圖所示。
ShuffleNet 單元的設計起源於對殘差塊瓶頸單元的借鑒,特別是在其殘差 路徑中,運用了計算效率較高的深度卷積來處理瓶頸特徵圖。在這個基礎上,透過使用分組逐點卷積代替傳統的卷積,並結合通道洗牌操作,形成了 ShuffleNet 單元的核心結構(如上圖(b)所示)。
為了匹配快捷路徑並恢復通道維度,單元中的第二個逐點卷積也是分組的,但在此之後並沒有添加額外的通道洗牌操作,以保持操作的簡潔性。在這種結構中,批量歸一化(BN)和非線性活化的應用與其他研究中的使用相似,不過不採用在深度卷積後立即使用 ReLU 的常規建議。
另外,當涉及到步長(stride)的使用時,ShuffleNet 單元進行了兩項主要的調整,如上圖(c)所示:
- 首先,在快捷路徑上引入了的平均池化操作
- 其次,透過通道串聯代替逐元素加法,有效地擴展了通道維度而幾乎不增加計算成本。
這種設計使得單元中的所有組件都可以有效地計算,特別是在分組逐點卷積中實現了通道洗牌。
模型架構
基於上述的所有模組,最終組成了 ShuffleNet 的整體架構,如上表所示。到右邊有一個 到 的表格,這個 就是分組數量。
作者在這裡考慮到提高分組數量會減少計算量,而為了讓每個模型能夠有一致的計算量(一致的比較基準),因此提升分組數量的同時,也同時提升網路的每層的通道數量。