首先我们来回顾CNN与ANN前向传播操作:
Y
(
u
,
v
,
c
)
=
X
∗
F
=
∑
i
=
1
d
∑
j
=
1
d
∑
k
=
1
c
i
n
X
(
u
+
i
,
v
+
j
,
k
)
⋅
F
(
i
,
j
,
k
,
c
)
Y(u,v,c)=X* F=\sum_{i=1}^d\sum_{j=1}^d\sum_{k=1}^{c_{in}}X(u+i,v+j,k)\cdot F(i,j,k,c)
Y(u,v,c)=X∗F=∑i=1d∑j=1d∑k=1cinX(u+i,v+j,k)⋅F(i,j,k,c)
Y
(
u
,
v
,
c
)
=
X
⊙
F
=
−
∑
i
=
1
d
∑
j
=
1
d
∑
k
=
1
c
i
n
∣
X
(
u
+
i
,
v
+
j
,
k
)
−
F
(
i
,
j
,
k
,
c
)
∣
Y(u,v,c)=X\odot F=-\sum_{i=1}^d\sum_{j=1}^d\sum_{k=1}^{c_{in}}|X(u+i,v+j,k)- F(i,j,k,c)|
Y(u,v,c)=X⊙F=−∑i=1d∑j=1d∑k=1cin∣X(u+i,v+j,k)−F(i,j,k,c)∣ 但是相同结构的CNN和ANN还是有比较大的精度差别,本文就是为了解决这个问题。
2.2初步解决方案
作者想通过知识蒸馏的方法来提升ANN的精度: 我们来回顾一下KD loss function:
L
k
d
=
∑
i
=
1
n
H
c
r
o
s
s
(
y
s
,
y
t
)
L_{kd}=\sum_{i=1}^nH_{cross}(y_s,y_t)
Lkd=∑i=1nHcross(ys,yt)
H
c
r
o
s
s
H_{cross}
Hcross也就是交叉熵损失,
y
s
y_s
ys也就是S-net网络的输出,
y
t
y_t
yt也就是T-net的输出 传统的KD loss使用软标签融合ground-truth和T-net的输出,因此有:
L
b
l
e
n
d
=
∑
i
=
1
n
{
α
H
c
r
o
s
s
(
y
s
,
y
t
)
+
H
c
r
o
s
s
(
y
s
,
y
g
t
)
}
L_{blend}=\sum_{i=1}^n\{\alpha H_{cross}(y_s,y_t)+H_{cross}(y_s,y_{gt})\}
Lblend=∑i=1n{αHcross(ys,yt)+Hcross(ys,ygt)} (有关知识蒸馏的具体细节可以在网上查阅) 作者提到,由于CNN和ANN使用相同的神经网络结构,因此更容易学到一些每层间的知识。从此处开始探索如何应用知识蒸馏的方法进行学习。
2.3具体分析
两者前向传播函数大不相同,而ANN输出分布函数和CNN输出分布函数也有很大的不同: CNN:
i
a
(
x
)
∗
w
a
(
x
)
=
∫
−
∞
∞
i
a
(
t
)
⋅
w
a
(
x
−
t
)
d
t
=
∫
−
∞
∞
i
a
(
t
)
⋅
1
2
π
σ
e
−
(
x
−
t
)
2
2
σ
2
d
t
i_a(x)* w_a(x)=\int_{-\infty}^{\infty}i_a(t)\cdot w_a(x-t)\,{\rm d}t=\int_{-\infty}^{\infty}i_a(t)\cdot\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-t)^2}{2\sigma ^2}}{\rm d}t
ia(x)∗wa(x)=∫−∞∞ia(t)⋅wa(x−t)dt=∫−∞∞ia(t)⋅2πσ1e−2σ2(x−t)2dt ANN:
i
a
(
x
)
⊙
w
a
(
x
)
=
∫
−
∞
∞
∣
i
a
(
t
)
−
w
a
(
x
−
t
)
∣
d
t
=
∫
−
∞
∞
∣
i
a
(
t
)
−
1
2
λ
e
∣
x
−
t
∣
λ
∣
d
t
i_a(x)\odot w_a(x)=\int_{-\infty}^{\infty}|i_a(t)-w_a(x-t)|\,{\rm d}t=\int_{-\infty}^{\infty}|i_a(t)-\frac{1}{2\lambda}e^{\frac{|x-t|}{\lambda}}|{\rm d}t
ia(x)⊙wa(x)=∫−∞∞∣ia(t)−wa(x−t)∣dt=∫−∞∞∣ia(t)−2λ1eλ∣x−t∣∣dt 通过比较以上两个输出分布函数可以看出,除非巧妙设计输入的分布,否则ANN与CNN的分布几乎不可能相同。因此很难通过MSEloss来匹配输出特征。因此不能套用原来的蒸馏方法。
2.4问题解决——用核方法来解决这个问题
首先我们先来看一下本文中用到的两个核函数: 高斯核:
k
(
x
,
y
)
=
e
−
∣
∣
x
−
y
∣
∣
2
2
σ
2
k(x,y)=e^{-\frac{||x-y||^2}{2\sigma^2}}
k(x,y)=e−2σ2∣∣x−y∣∣2 拉普拉斯核:
k
(
x
,
y
)
=
e
−
∣
∣
x
−
y
∣
∣
σ
k(x,y)=e^{-\frac{||x-y||}{\sigma}}
k(x,y)=e−σ∣∣x−y∣∣ 基于以上两个函数更改前后输出特征对比: CNN:
h
(
x
c
m
,
f
c
m
)
=
x
c
m
∗
f
c
m
→
h
(
x
c
m
,
f
c
m
)
=
e
−
x
c
m
∗
f
c
m
2
σ
2
h(x_c^m,f_c^m)=x_c^m*f_c^m\rightarrow h(x_c^m,f_c^m)=e^{-\frac{x_c^m*f_c^m}{2\sigma ^2}}
h(xcm,fcm)=xcm∗fcm→h(xcm,fcm)=e−2σ2xcm∗fcm ANN:
g
(
x
a
m
,
f
a
m
)
=
x
a
m
∗
f
a
m
→
g
(
x
a
m
,
f
a
m
)
=
e
−
x
a
m
⊙
f
a
m
σ
a
g(x_a^m,f_a^m)=x_a^m*f_a^m\rightarrow g(x_a^m,f_a^m)=e^{-\frac{x_a^m\odot f_a^m}{\sigma _a}}
g(xam,fam)=xam∗fam→g(xam,fam)=e−σaxam⊙fam 这便将输入和权重映射到更高维度的空间。在新的空间输出特征图。 我们可以看到此处新的公式高斯核的形式有所改变,但是效果是不变的,作者在原文中给出了证明:
除了使用核函数,作者还提到进一步用线性变换来匹配新输出的两个分布。 总结就是选取合适的核函数的参数——平滑输出分布,并使用线性变换,减小输出特征分布差异,更好的匹配两者的特征。 因此,作者将用于计算KD loss的中间层输出定义为: CNN:
y
C
m
=
ρ
(
h
(
x
C
m
,
f
C
m
)
,
w
ρ
c
m
)
y_C^m=\rho(h(x_C^m,f_C^m),w_{\rho c}^m)
yCm=ρ(h(xCm,fCm),wρcm) ANN:
y
a
m
=
ρ
(
g
(
x
a
m
,
f
a
m
)
,
w
ρ
a
m
)
y_a^m=\rho(g(x_a^m,f_a^m),w_{\rho a}^m)
yam=ρ(g(xam,fam),wρam)
w
ρ
a
,
w
ρ
c
w_{\rho a},w_{\rho c}
wρa,wρc分别是ANN,CNN的线性变换层的参数。 将KD loss应用于除第一层和最后一层的所有中间层:
L
m
i
d
=
∑
i
=
1
n
∑
m
=
1
M
H
m
s
e
(
y
a
m
,
y
c
m
)
L_{mid}=\sum_{i=1}^n\sum_{m=1}^MH_{mse}(y_a^m,y_c^m)
Lmid=∑i=1n∑m=1MHmse(yam,ycm) 最后的loss function为:
L
=
β
L
m
i
d
+
L
b
l
e
n
d
=
∑
i
=
1
n
∑
m
=
1
M
β
H
m
s
e
(
y
a
m
,
y
c
m
)
+
∑
i
=
1
n
{
α
H
c
r
o
s
s
(
y
s
,
y
t
)
+
H
c
r
o
s
s
(
y
s
,
y
g
t
)
}
L=\beta L_{mid}+L_{blend}=\sum_{i=1}^n\sum_{m=1}^M\beta H_{mse}(y_a^m,y_c^m)+\sum_{i=1}^n\{\alpha H_{cross}(y_s,y_t)+H_{cross}(y_s,y_{gt})\}
L=βLmid+Lblend=∑i=1n∑m=1MβHmse(yam,ycm)+∑i=1n{αHcross(ys,yt)+Hcross(ys,ygt)}
2.5渐进式学习
总体算法流程如下:
作者首先分析了目前某些情况下,知识蒸馏不能很好发挥作用的原因。 1.T-net和S-net的结构差异较大 2.T-net和S-net的训练阶段差别较大 作者经过分析,认为问题主要出现在第二个原因上 因此设计此处具体步骤为:给定一批输入数据,首先用交叉熵损失更新CNN参数,之后ANN使用当前的CNN权重通过KD loss进行学习:
L
b
=
β
L
m
i
d
b
+
L
b
l
e
n
d
b
L^b=\beta L_{mid}^b+L_{blend}^b
Lb=βLmidb+Lblendb b为当前的步数。更新ANN的参数,在进行反向传播时,KD损失仅通过ANN进行反向传播,CNN的学习不受干扰。