一,引子
这篇文章来自清华的Xiaohan Ding, Xiangyu Zhang与Jungong Han
文章地址:Diverse Branch Block: Building a Convolution as an Inception-like Unit
这篇文章也就几个小地方的公式有点复杂,就当是给自己巩固一下刚刚理解的公式叭~
ps:先读原文再用原文和本文公式解读做对比食用更佳嗷
二,文章简略介绍
文章用重参数的技巧复杂化原来的训练模型,使训练模型拥有更好的特征表达能力,但在推理阶段时把复杂化的地方转化为原来的模型。这就使得这个模型即拥有优秀的特征表达能力,又完全没增加推理时间。
那么具体就从第三章开始讲了~
三,公式梳理
3.1 卷积的线性
这一小节是概念的引入阶段,所以没什么难理解的地方
一个卷积层有C个输入通道和D个输出通道,卷积核的大小为K*K,此卷积核和偏差的维度为 F ∈ R D × C × K × K , b ∈ R D F \in R^{D\times C\times K\times K},\ b\in R^D F∈RD×C×K×K, b∈RD
输入和输出的维度为 I ∈ R C × H × W , O ∈ R D × H ′ × W ′ I \in R^{C\times H\times W}, O \in R^{D\times H'\times W'} I∈RC×H×W,O∈RD×H′×W′
扩张偏差的维度到 R E B ( b ) ∈ R D × H ′ × W ′ REB(b) \in R^{D\times H'\times W'} REB(b)∈RD×H′×W′
这时我们就有一个标准的卷积公式:
O
=
I
∗
F
+
R
E
P
(
b
)
.
O=I * F + REP(b).
O=I∗F+REP(b). (1)
在第j个输出通道上坐标为
(
h
,
w
)
(h,w)
(h,w)的值为:
O
j
,
h
,
w
=
∑
c
=
1
C
∑
u
=
1
K
∑
v
=
1
K
F
j
,
c
,
u
,
v
X
(
c
,
h
,
w
)
u
,
v
+
b
j
O_{j,h,w}=\sum\limits_{c=1}^C\sum\limits_{u=1}^K\sum\limits_{v=1}^KF_{j,c,u,v}X(c,h,w)_{u,v}+b_j
Oj,h,w=c=1∑Cu=1∑Kv=1∑KFj,c,u,vX(c,h,w)u,v+bj
在这 X ( c , h , w ) ∈ R K × K X(c,h,w) \in R^{K \times K} X(c,h,w)∈RK×K是在输入 I I I的第c个通道与输出 O O O的位置 ( h , w ) (h,w) (h,w)相关的的滑动窗口。
这里引入了卷积的homogeneity和additivity:
I
∗
(
p
F
)
=
p
(
I
∗
F
)
,
∀
p
∈
R
,
I*(pF)=p(I*F), \forall p\in R,
I∗(pF)=p(I∗F),∀p∈R, (3)
I
∗
F
(
1
)
+
I
∗
F
(
2
)
=
I
∗
(
F
(
1
)
+
F
(
2
)
)
I*F^{(1)}+I*F^{(2)}=I*(F^{(1)}+F^{(2)})
I∗F(1)+I∗F(2)=I∗(F(1)+F(2)) (4)
3.2 A Convolution for Diverse Branches
公式警告
文中总结了六种transformation
Transform 1:a conv for conv-BN
一个卷积层带一个batch标准化层,看看作者怎么把这两者合二为一。
让j代表通道index,
μ
j
,
σ
j
\mu_j,\sigma_j
μj,σj分别为累积的通道角度的均值和标准差,
γ
j
,
β
j
\gamma_j,\beta_j
γj,βj是被学习的放缩因子和偏差项,那通道j的输出就变成了:
O
j
,
:
,
:
=
(
(
I
∗
F
)
j
,
:
,
:
−
μ
j
)
γ
j
σ
j
+
β
j
O_{j,:,:}=((I*F)_{j,:,:}-\mu_j)\frac{\gamma_j}{\sigma_j}+\beta_j
Oj,:,:=((I∗F)j,:,:−μj)σjγj+βj(5)
为啥会变成这样呢?看不懂的同学回去好好理解下batch normalization。我们首先来看看普通的batch标准化公式:
z
=
x
−
μ
σ
γ
+
β
z=\frac{x-\mu}{\sigma}\gamma+\beta
z=σx−μγ+β
两个可学习的参数是为了恢复数据本身的表达能力,对规范化后的数据进行线性变换,
γ
\gamma
γ为斜率,
β
\beta
β为偏差项。
这么一看我们的 ( I ∗ F ) j , : , : (I*F)_{j,:,:} (I∗F)j,:,:就相当于x,公式5也就相当于对I和F做卷积后的结果进行标准化处理,最后再加上偏差项
接下来我们要把公式5变成标准形式公式1,因为我们Transform1的目的是把卷积层+BN层转变为推理时的一个卷积层,我们把公式5摊开:
O
j
,
:
,
:
=
(
I
∗
F
)
j
,
:
,
:
γ
j
σ
j
−
μ
j
γ
j
σ
j
+
β
j
O_{j,:,:}=(I*F)_{j,:,:}\frac{\gamma_j}{\sigma_j}-\mu_j\frac{\gamma_j}{\sigma_j}+\beta_j
Oj,:,:=(I∗F)j,:,:σjγj−μjσjγj+βj
O
j
,
:
,
:
=
(
I
∗
γ
j
σ
j
F
)
j
,
:
,
:
+
(
β
j
−
μ
j
γ
j
σ
j
)
O_{j,:,:}=(I*\frac{\gamma_j}{\sigma_j}F)_{j,:,:}+(\beta_j-\mu_j\frac{\gamma_j}{\sigma_j})
Oj,:,:=(I∗σjγjF)j,:,:+(βj−μjσjγj)
我们与公式1对比下:
O
=
I
∗
F
+
R
E
P
(
b
)
.
O=I * F + REP(b).
O=I∗F+REP(b).
那我们就可以很清楚的得到输出通道j的F’和b’了:
F
j
,
:
,
:
,
:
′
←
γ
j
σ
j
F
j
,
:
,
:
,
:
,
F'_{j,:,:,:} \leftarrow \frac{\gamma_j}{\sigma_j}F_{j,:,:,:},
Fj,:,:,:′←σjγjFj,:,:,:,
b
j
,
:
,
:
,
:
′
←
β
j
−
μ
j
γ
j
σ
j
.
b'_{j,:,:,:} \leftarrow \beta_j-\mu_j\frac{\gamma_j}{\sigma_j}.
bj,:,:,:′←βj−μjσjγj. (6)
Transform 3:a conv for sequential convolutions
transform 2就不多讲了,直接合并两个F与两个b
重点是Transform 3,也就是把训练阶段的
1
∗
1
+
B
N
1*1+BN
1∗1+BN再跟着一个
K
∗
K
+
B
N
K*K+BN
K∗K+BN层转变为推理阶段的一个
K
∗
K
K*K
K∗K的卷积层。
设
F
(
1
)
∈
R
D
×
C
×
1
×
1
,
b
(
1
)
∈
R
D
F^{(1)}\in R^{D \times C \times 1 \times 1},b^{(1)}\in R^D
F(1)∈RD×C×1×1,b(1)∈RD
F
(
2
)
∈
R
E
×
D
×
K
×
K
,
b
(
2
)
∈
R
E
F^{(2)}\in R^{E \times D \times K \times K},b^{(2)}\in R^E
F(2)∈RE×D×K×K,b(2)∈RE
那输出则为:
O
′
=
(
I
∗
F
(
1
)
+
R
E
P
(
b
(
1
)
)
)
∗
F
(
2
)
+
R
E
P
(
b
(
2
)
)
.
O'=(I*F^{(1)}+REP(b^{(1)}))*F^{(2)}+REP(b^{(2)}).
O′=(I∗F(1)+REP(b(1)))∗F(2)+REP(b(2)).(8)
我们想把公式8变成标准式1:
O
′
=
I
∗
F
′
+
R
E
P
(
b
′
)
O'=I*F'+REP(b')
O′=I∗F′+REP(b′)
在这里首先我们把公式8展开:
O
′
=
I
∗
F
(
1
)
∗
F
(
2
)
+
R
E
P
(
b
(
1
)
)
∗
F
(
2
)
+
R
E
P
(
b
(
2
)
)
.
O'=I*F^{(1)}*F^{(2)}+REP(b^{(1)})*F^{(2)}+REP(b^{(2)}).
O′=I∗F(1)∗F(2)+REP(b(1))∗F(2)+REP(b(2)).(10)
我们的目的是公式10转成公式1,那么首先看第一项
I
∗
F
(
1
)
∗
F
(
2
)
I*F^{(1)}*F^{(2)}
I∗F(1)∗F(2),由于
1
∗
1
1*1
1∗1的卷积处理的是通道级的线性放缩操作,也就是第i个通道中的所有像素同时乘上某一个数(比如2)。所以
1
∗
1
1*1
1∗1卷积也就没有进行空间维度的聚合操作,于是我们就可以通过以下的式子把
1
∗
1
1*1
1∗1卷积
F
(
1
)
F^{(1)}
F(1)和
K
∗
K
K*K
K∗K卷积
F
(
2
)
F^{(2)}
F(2)结合起来变成
F
′
F'
F′:
F
′
←
F
(
2
)
∗
T
R
A
N
S
(
F
(
1
)
)
.
F' \leftarrow F^{(2)}*TRANS(F^{(1)}).
F′←F(2)∗TRANS(F(1)). (11)
此刻注意到 T R A N S ( F ( 1 ) ) ∈ R C × D × 1 × 1 TRANS(F^{(1)}) \in R^{C \times D \times 1 \times 1} TRANS(F(1))∈RC×D×1×1是 F ( 1 ) ∈ R D × C × 1 × 1 F^{(1)} \in R^{D \times C \times 1 \times 1} F(1)∈RD×C×1×1的转置,也就是把前两个维度调换了。
我们把 F ( 2 ) ∈ R E × D × K × K F^{(2)}\in R^{E \times D \times K \times K} F(2)∈RE×D×K×K看作是输入X(X一般是三维的,这里可以理解为E个DKK)
X与 T R A N S ( F ( 1 ) ) ∈ R C × D × 1 × 1 TRANS(F^{(1)})\in R^{C \times D \times 1 \times 1} TRANS(F(1))∈RC×D×1×1做卷积操作就可以得到一个 F ′ ∈ R E × C × K × K F' \in R^{E \times C \times K \times K} F′∈RE×C×K×K。在这里有同学想问了,这样做卷积操作真的可以吗,不会改变这个卷积核的结构吗,这样对原数据的卷积还是原来的卷积吗?
同学,可以哦!不会哦!是的哦!前面提到了 F ( 1 ) F^{(1)} F(1)其实是通道级别的线性放缩,并没有改变原数据的空间结构,所以先给数据做通道级别的线性放缩和进行 F ( 2 ) F^{(2)} F(2)之后再进行放缩都是一样的,所以我们可以直接给 F ( 2 ) F^{(2)} F(2)进行通道级别的放缩。
那么我们公式10的第一项就已经处理完了,下面看到第二项 R E P ( b ( 1 ) ) ∗ F ( 2 ) REP(b^{(1)})*F^{(2)} REP(b(1))∗F(2)。这该怎么处理呢?我们可以先简单的理解下接下来的步骤:
设
P
∈
R
H
×
W
P \in R^{H \times W}
P∈RH×W为常数矩阵,且里面的每个元素都为p,那么
(
P
∗
W
)
:
,
:
=
p
S
U
M
(
W
)
(P*W)_{:,:}=pSUM(W)
(P∗W):,:=pSUM(W) (12)
P与W做卷积,单个滑动窗口产生的值就为pSUM(W),这也很好理解,比如我们都是2的输入,与W=「1,2,3;4,5,6;7,8,9」这种3x3的卷积核做卷积,单个滑动窗口得到的就是1x2+2x2+3x2+4x2+5x2+6x2+7x2+8x2+9x2=2(1+2+3+4+5+6+7+8+9)=2SUM(W)
有了公式12,我们可以构建 b ^ ← ∑ d = 1 D ∑ u = 1 K ∑ v = 1 K b d ( 1 ) F j , d , u , v ( 2 ) , 1 ≤ j ≤ E . \hat b \leftarrow \sum\limits_{d=1}^D\sum\limits_{u=1}^K\sum\limits_{v=1}^Kb_{d}^{(1)}F_{j,d,u,v}^{(2)},1 \leq j \leq E. b^←d=1∑Du=1∑Kv=1∑Kbd(1)Fj,d,u,v(2),1≤j≤E.(13)
换个样子: b ^ ← ∑ d = 1 D b d ( 1 ) ∑ u = 1 K ∑ v = 1 K F j , d , u , v ( 2 ) , 1 ≤ j ≤ E . \hat b \leftarrow \sum\limits_{d=1}^D b_{d}^{(1)}\sum\limits_{u=1}^K\sum\limits_{v=1}^KF_{j,d,u,v}^{(2)},1 \leq j \leq E. b^←d=1∑Dbd(1)u=1∑Kv=1∑KFj,d,u,v(2),1≤j≤E.后面就是一个滑动窗口KxK里的SUM(W),前面就是我们的p,由于我们有D个通道,就有D个不同的p。
依据这个我们就可以得出公式14:
R
E
P
(
b
(
1
)
)
∗
F
(
2
)
=
R
E
P
(
b
^
)
REP(b^{(1)})*F^{(2)}=REP(\hat b)
REP(b(1))∗F(2)=REP(b^) (14)
我们来看看公式14的维度情况:
R
E
P
(
b
(
1
)
)
∈
R
D
×
H
×
W
,
F
(
2
)
∈
R
E
×
D
×
K
×
K
REP(b^{(1)}) \in R^{D \times H \times W}, F^{(2)}\in R^{E \times D \times K \times K}
REP(b(1))∈RD×H×W,F(2)∈RE×D×K×K
所以这俩是可以做卷积的,得出的结果维度为
R
E
P
(
b
^
)
∈
R
E
×
H
′
×
W
′
REP(\hat b) \in R^{E \times H' \times W'}
REP(b^)∈RE×H′×W′
由于公式13只是构建单个滑动窗口的值,所以 R E P ( b ^ ) REP(\hat b) REP(b^)的操作是把Ex1x1的维度扩张到ExH’xW’的维度。
那这就好办了,我们把公式10的第三项和第二项合并到一起:
b
′
←
b
^
+
b
(
2
)
b' \leftarrow \hat b+b^{(2)}
b′←b^+b(2),就此我们得到了F‘和b’,也就实现了把1x1-BN-KxK-BN转变成KxK的转化。
这里有一种情况:关于KxK卷积,有用0填充输入的padding操作时,公式8就不能使用了。因为 F ( 2 ) F^{(2)} F(2)不能直接卷积 I ∗ F ( 1 ) + R E P ( b ( 1 ) ) I*F^{(1)}+REP(b^{(1)}) I∗F(1)+REP(b(1)), I ∗ F ( 1 ) + R E P ( b ( 1 ) ) I*F^{(1)}+REP(b^{(1)}) I∗F(1)+REP(b(1))要首先进行padding操作才能给 F ( 2 ) F^{(2)} F(2)卷积。那我们这时候要想把公式全部展开再进行第一项处理,第二项第三项合并的操作就要用到一些方案。
这有俩解决方案:
方案1 用padding配置第一个卷积核,而第二个卷积核不用进行padding操作。也就相当于在1x1卷积操作时padding input和卷积核
F
(
1
)
F^{(1)}
F(1),这样得到的结果和普通的
I
∗
F
(
1
)
I*F^{(1)}
I∗F(1)一样,只是多了一圈padding,而KxK卷积则不做处理。
方案2 用 b ( 1 ) b^{(1)} b(1)进行padding而不是用0进行padding。通常比较有效的操作是我们定制第一个BN为:(1)正常地batch标准化input,然后(2)用公式6计算 b ( 1 ) b^{(1)} b(1),(3)用 b ( 1 ) b^{(1)} b(1)padding batch标准化后的结果,而不是用0填充。
Transform 4: a conv for depth concatenation,这里的公式没啥难的,略!
Transform 5: a conv for average pooling只是把平均池化层看成卷积操作,略!
Transform 6: a conv for multi-scale convolutions,略!!!
四,尾声
完结撒花!现在才知道参考答案里面写“略”是多爽的一件事~
希望大家好好研究公式里每个符号代表的含义,这样理解起来就很简单啦~
大家有疑问和纠错欢迎在评论区讨论,手敲公式不易,请给个一键三连支持下叭~
ps:公式13其实是这样手打出来的,博取同情ing
\hat b \leftarrow \sum\limits_{d=1}D\sum\limits_{u=1}K\sum\limits_{v=1}Kb_{d}{(1)}F_{j,d,u,v}^{(2)},1 \leq j \leq E.