v1: (1)單片卷積 + 1x1 通道改維度;
(2)寬度因子a + 分辨率因子 b ; (以最低的精度損失換取大量的參數減少)
v2: (1)加入殘差結構(先升維:增加信息量,再降維度:較少參數,與Resnet相反),增加梯度傳播
(2)較少block最後的Relu,爲lineat,減少信息破壞;
(3)全卷積(減少參數)+relu6(採用float16,防止數值爆炸)
文章目錄
一、參數數量和理論計算量
1、定義
- 參數數量(params):關係到模型大小,單位通常爲M,通常參數用 float32 表示,所以
模型大小是參數數量的 4 倍
- 理論計算量(FLOPs):
- 是 floating point operations 的縮寫(注意 s 小寫),可以用來
衡量算法/模型的複雜度
,這關係到算法速度,大模型的單位通常爲 G,小模型單位通常爲 M- 通常只考慮乘加操作
(Multi-Adds)
的數量,而且只考慮CONV 和 FC
等參數層的計算量,忽略 BN 和PReLU 等等。一般情況,CONV 和 FC 層也會忽略僅純加操作
的計算量,如 bias 偏置加和 shotcut 殘差加等,目前技術有 BN 的 CNN 可以不加 bias
2、計算公式
假設卷積核大小爲 Kh×KwK_h \times K_wKh×Kw,輸入通道數爲 CinC_{in}Cin,輸出通道數爲 CoutC_{out}Cout,輸出特徵圖的寬和高分別爲 WWW 和 HHH,這裏忽略偏置項
CONV 標準卷積層:
- params: Kh×Kw×Cin×CoutK_h \times K_w \times C_{in} \times C_{out}Kh×Kw×Cin×Cout
- FLOPs:Kh×Kw×Cin×Cout×H×W=params×H×WK_h \times K_w \times C_{in} \times C_{out} \times H \times W = params \times H \times WKh×Kw×Cin×Cout×H×W=params×H×W
FC 全連接層(相當於 k=1):
- params: Cin×CoutC_{in} \times C_{out}Cin×Cout
- FLOPs:Cin×CoutC_{in} \times C_{out}Cin×Cout
二、MobileNetV1: Efficient Convolutional Neural Networks for Mobile Vision Application
1、能夠減少參數數量和計算量的原理
- 深度可分離卷積的使用
- 在進行 depthwise 卷積時只使用了
一種
維度爲in_channels
的卷積核進行特徵提取(沒有進行特徵組合) - 在進行 pointwise 卷積時只使用了
output_channels 種
維度爲in_channels
1*1 的卷積核進行特徵組合,普通卷積不同 depth 層的權重是按照 1:1:1…:1的比例進行相加的,而在這裏不同 depth 層的權重是按照 不同比例(可學習的參數) 進行相加的 - 參數數量由原來的
p1 = F*F*in_channels*output_channels
變爲了p2 = F*F*in_channels*1 + 1*1*in_channels*output_channels
,減小爲原來的p2/p1 = 1/output_channels + 1/F*F
,其中 F 爲卷積核的尺寸,若 F=3F = 3F=3,參數量大約會減少到原來的 1/8→1/91/8 \to 1/91/8→1/9 - Note: 原論文中對第一層沒有用此卷積,深度可分離卷積中的每一個後面都跟 BN 和 RELU
- 在進行 depthwise 卷積時只使用了
- Global Average Pooling 的使用:這一層沒有參數,計算量可以忽略不計
- 用
CONV/s2
(步進2的卷積)代替MaxPool+CONV
:使得參數數量不變,計算量變爲原來的 1/4 左右,且省去了MaxPool 的計算量 - Note:採用 depth-wise convolution 會有一個問題,就是導致
信息流通不暢
,即輸出的 feature map 僅包含輸入的 feature map 的一部分
,在這裏,MobileNet 採用了 point-wise(1*1) convolution 幫助信息在通道之間流通
2、MobileNetV1 中引入的兩個超參數
- Width Multiplier(α\alphaα): Thinner Models
- 所有層的 通道數(channel) 乘以 α\alphaα 參數(四捨五入),模型大小近似下降到原來的 α2\alpha^{2}α2 倍,計算量下降到原來的 α2\alpha^{2}α2 倍
- α∈(0,1]\alpha \in (0, 1]α∈(0,1] with typical settings of 1, 0.75, 0.5 and 0.25,降低模型的寬度
- Resolution Multiplier(ρ\rhoρ): Reduced Representation
- 輸入層的 分辨率(resolution) 乘以 ρ\rhoρ 參數 (四捨五入),等價於所有層的分辨率乘 ρ\rhoρ,模型大小不變,計算量下降到原來的 ρ2\rho^{2}ρ2 倍
- ρ∈(0,1]\rho \in (0, 1]ρ∈(0,1],降低輸入圖像的分辨率
3、標準卷積和深度可分離卷積的區別
4、TensorFlow 中的代碼實現
- 可使用 tensorflow 中的
tf.nn.separable_conv2d()
來實現, 參數depthwise_filter
中的channel_multiplier 設爲 1
即可
# 使用 slim 來實現
def _depthwise_separable_conv(inputs,
num_pwc_filters,
kernel_width,
phase,
sc,
padding='SAME',
width_multiplier=1,
downsample=False):
""" Helper function to build the depth-wise separable convolution layer.
"""
num_pwc_filters = round(num_pwc_filters * width_multiplier)
_stride = 2 if downsample else 1
# skip pointwise by setting num_outputs=None
depthwise_conv = slim.separable_convolution2d(inputs,
num_outputs=None,
stride=_stride,
depth_multiplier=1,
kernel_size=[kernel_width, kernel_width],
padding=padding,
activation_fn=None,
scope=sc + '/depthwise_conv')
bn = slim.batch_norm(depthwise_conv, activation_fn=tf.nn.relu, is_training=phase, scope=sc + '/dw_batch_norm')
pointwise_conv = slim.convolution2d(bn,
num_pwc_filters,
kernel_size=[1, 1],
activation_fn=None,
scope=sc + '/pointwise_conv')
bn = slim.batch_norm(pointwise_conv, activation_fn=tf.nn.relu, is_training=phase, scope=sc + '/pw_batch_norm')
return bn
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
5、Caffe 中的代碼實現
三、MobileNetV2:Inverted Residuals and Linear Bottlenecks
1、主要改進點
- 引入殘差結構,先升維再降維,增強梯度的傳播,顯著減少推理期間所需的內存佔用(
Inverted Residuals
) - 去掉 Narrow layer(low dimension or depth) 後的 ReLU,保留特徵多樣性,增強網絡的表達能力(
Linear Bottlenecks
) - 網絡爲
全卷積
的,使得模型可以適應不同尺寸的圖像;使用RELU6(最高輸出爲 6)
激活函數,使得模型在低精度計算下具有更強的魯棒性 - MobileNetV2 building block 如下所示,若需要下采樣,可在 DWise 時採用
步長爲 2
的卷積;小網絡使用小的擴張係數(expansion factor
),大網絡使用大一點的擴張係數(expansion factor),推薦是5~10,論文中 t=6t = 6t=6