1.感受野
“感受野”的概念来源于生物神经科学。就好比于我们的“感受器”,当我们的手受到刺激之后,会将刺激传输至中枢神经,但是并不是一个神经元就能够接受整个皮肤的刺激,因为皮肤面积大,一个神经元可想而知肯定接受不完,而且我们同时可以感受到身上皮肤在不同的地方,如手、脚,的不同的刺激,如痛、痒等。这说明皮肤感受器是由很多不同的神经元控制的,那么每一个神经元所能够反映的那块感受器的区域就称之为“感受野”,感受野即每一个神经元所支配的区域,也可以说这个神经元的活动受到那一块区域的影响。
感受野在卷积中的定义:在卷积神经网络(CNN)中,决定某一层输出结果中一个元素所对应的输入层的区域大小,被称作感受野receptive field。我们看这段定义非常简单,用数学的语言就是感受野是CNN中的某一层输出结果的一个元素对应输入层的一个映射。再通俗点的解释是,特征映射(feature map)上的一个点对应输入图上的区域。注意这里是输入图,不是原始图。好多博客写的都是原图上的区域,经过一番的资料查找,发现并不是原图。下图是传统全连接神经网络与卷积的区别。左图传统全连接神经网络,右图卷积神经网络。
从上图就可看出卷积神经网络的权值存储空间要小于传统神经网络的。而且卷积神经网络海通权值共享进一步减少了权值存储空间。所以卷积神经网络大幅度缓解了传统神经网络因为权值太多造成的存储量大、计算量大以及需要更多的样本的问题。
这里我之所以先介绍感受野就是为了大家能够更好地理解卷积的本质以及理解CNN的整个架构。
2.CNN的结构
CNN的组成包括:输入层、卷积层、激活函数、池化层和全连接层。
2.1卷积层
微积分的卷积的表达式为:
s
(
t
)
=
∫
x
(
a
)
w
(
t
−
a
)
d
a
s\left( t \right)=\int x\left( a \right)w\left( t-a \right)da
s(t)=∫x(a)w(t−a)da
离散形式为:
s
(
t
)
=
∑
a
x
(
a
)
w
(
t
−
a
)
d
a
s\left( t \right)=\sum\limits_{a}{x\left( a \right)w\left( t-a \right)da}
s(t)=a∑x(a)w(t−a)da
卷积矩阵形式为:
s
(
t
)
=
(
x
∗
w
)
(
t
)
s\left( t \right)=\left( x*w \right)\left( t \right)
s(t)=(x∗w)(t)
其中星号表示卷积。
在卷积网络中的术语中,卷积的第一个参数(函数x)叫作输入,第二个参数(函数w)叫作核函数(kernel function)。输出优势被称作特征映射(feature map)。
二维卷积表示为:
s
(
i
,
j
)
=
(
X
∗
W
)
(
i
,
j
)
=
∑
m
∑
n
X
(
i
−
m
,
j
−
n
)
W
(
m
,
n
)
s\left( i,j \right)=\left( X*W \right)\left( i,j \right)=\sum\limits_{m}{\sum\limits_{n}{X\left( i-m,j-n \right)W\left( m,n \right)}}
s(i,j)=(X∗W)(i,j)=m∑n∑X(i−m,j−n)W(m,n)
在CNN中,我们说的卷积与严格意义数学总的定义稍有不同,定义如下:
s
(
i
,
j
)
=
(
X
∗
W
)
(
i
,
j
)
=
∑
m
∑
n
X
(
i
+
m
,
j
+
n
)
W
(
m
,
n
)
s\left( i,j \right)=\left( X*W \right)\left( i,j \right)=\sum\limits_{m}{\sum\limits_{n}{X\left( i+m,j+n \right)W\left( m,n \right)}}
s(i,j)=(X∗W)(i,j)=m∑n∑X(i+m,j+n)W(m,n)
其中, W为卷积核, X为输入。如果X是一个二维输入的矩阵,而W也是一个二维的矩阵。如果X是多维张量,那么W也是一个多维的张量。
下图演示了一个在二维张量上的卷积运算的例子
在斯坦福大学的cs231n的课程上,有一个动态的例子,链接在这。建议大家对照着例子中的动图看下面的讲解。
例子里面使用了两个卷积核,我们先关注于卷积核W0。和上面的例子相比,由于输入是3个7x7的矩阵(彩色图有三个通道R、G、B,所以3个7x7矩阵),或者说是7x7x3的张量,则我们对应的卷积核W0也必须最后一维是3的张量,这里卷积核W0的单个子矩阵维度为3x3。那么卷积核W0实际上是一个3x3x3的张量。同时和上面的例子比,这里的步幅为2,也就是每次卷积后会移动2个像素的位置。
最终的卷积过程和上面的2维矩阵类似,上面是矩阵的卷积,即两个矩阵对应位置的元素相乘后相加。这里是张量的卷积,即两个张量的3个子矩阵卷积后,再把卷积的结果相加后再加上偏倚b。
7x7x3的张量和3x3x3的卷积核张量W0卷积的结果是一个3x3的矩阵。由于我们有两个卷积核W0和W1,因此最后卷积的结果是两个3x3的矩阵。或者说卷积的结果是一个3x3x2的张量。
2.2padding
上面的斯坦福大学的例子,仔细观察可以发现在矩阵的四周填加了一圈0,这种操作就是padding操作。下面我将介绍三种padding操作。
①无论怎样都不使用零填充,并且卷积核只允许访问那些图像中能够完全包含整个核的位置,叫作有效(valid)卷积。在这种情况下,输出的所有像素都是输中的相同数量像素的函数,这使得输出像素的表示更加规范。然而输出的大小在每一层都会缩减。如果输入的图像宽度是m,核的宽度是k,那么输出的宽度就是m-k+1。这就限制了卷积层的层数,当层数增加时,网络空间的维度最终会缩减到1x1,这种情况增加卷积层就没有意义了。但是这种情况对边缘区域有着欠拟合问题,因为在扫描时,矩阵中间区域会被扫描多次,但是边缘区域只会被扫描一次,存在着欠拟合问题。
②只进行足够的零填充来保持输出和输入具有相同的大小,叫作相同(same)卷积。只要硬件支持,网络就能包含任意多的卷积层,这是因为卷积运算不改变下一层的结构。虽然在一定程度上缓解了边缘区域只扫描一次的问题,但是仍然存在一定程度的欠表示。这使得第三种情况产生。
③进行足够多的零填充,使得每个像素在每个方向上恰好被访问了k次,最终输出图像的宽度为m+k-1,叫作全(full)卷积。在这种情况下,输出像素中靠近边缘的部分相比于中间部分是更少像素的函数。这将导致学得一个在卷积特征映射的左右位置都表现不错的单核更为困难。
通常零填充的最优数量(对于测试集的分类正确率)处于“有效卷积”和“相同卷积”之间的某个位置。
计算输出大小,假设filter个数K,filter大小F,步长S,边界填充P
输出:
W
2
=
(
W
1
−
F
+
2
P
)
/
S
+
1
{{W}_{2}}=\left( {{W}_{1}}-F+2P \right)/S+1
W2=(W1−F+2P)/S+1
H
2
=
(
H
1
−
F
+
2
P
)
/
S
+
1
{{H}_{2}}=\left( {{H}_{1}}-F+2P \right)/S+1
H2=(H1−F+2P)/S+1
D
2
=
K
{{D}_{2}}=K
D2=K
2.3参数共享
参数共享是指在一个模型的多个函数中使用相同的参数。之所以参数共享是因为全连接的结构参数过于多,无论是效果还是效率上来说,都存在很大的问题。卷积神经网络有一个重要的特性,就是它会做一个权重的共享。权重共享:在每个特征图上,每个点,都进行权重共享。举一个简单的例子,输入为32x32x3的特征图,下一层为32x32x10。对于卷积神经网络来说,对应的卷积核是5x5x3的,算上一个偏置,一共需要76个参数。如果提取10个特征图,就需要760个参数。对于传统神经网络来说,需要32x32x10的32x32x3次方个参数,显然在存储和计算上效率极低。
2.4池化
池化函数使用某一个位置的相邻输出的总体统计特征代替网络在该位置的输出。例如最大池化函数给出相邻矩形区域内的最大值。其他的池化函数包括相邻矩形区域内的平均值、L2范数以及基于据中心像素距离的加权平均函数。
不管采用什么样的池化函数,当输入做出少量平移时,池化能够帮助输入的表示近似不变。平移的不变性是指当我们对输入进行少量平移时,经过池化函数后的大多数输出不会发生改变。局部平移不变性是一个很有用的性质,尤其是当我们关心某个特征是否出现而不关心它出现的位置具体位置时。例如,当我们判定一张图像中是否包含人脸时,我们并不需要知道眼睛的精确像素位置,我们只需要知道有一只眼睛在脸的左边,另一只在右边就好。但是在一些其他领域,保存特征的具体位置却很重要。例如当我们想要寻找一个由两条边相交而成的拐角时,就需要很好地保存变的位置来判定他们是否相交。
使用池化可以看作增加了一个无限强的先验:这一层学得的函数必须具有相对少量平移的不变性。当这个假设成立时,池化可以极大地提高网络的统计效率。对空间区域进行池化产生了平移不变性,但当我们对分离参数的卷积的输出进行池化时,特征能够学得应该对于哪种变换具有不变性(学到具有不变性的特征,以便于更好地决策)。
接下来介绍一下池化的过程:
同样地采用一个2*2的filter,max pooling是在每一个区域中寻找最大值,这里的stride=2,最终在原特征图中提取主要特征得到右图。
注意:这里的pooling操作是特征图缩小,有可能影响网络的准确度,因此可以通过增加特征图的深度来弥补。
2.5激活函数
激活函数应该具有的性质:
①非线性。线性激活层对于深层神经网络没有作用,因为其作用以后仍然是输入的各种线性变换。。
②连续可微。梯度下降法的要求。
③范围最好不饱和,当有饱和的区间段时,若系统优化进入到该段,梯度近似为0,网络的学习就会停止。
④单调性,当激活函数是单调时,单层神经网络的误差函数是凸的,好优化。
⑤在原点处近似线性,这样当权值初始化为接近0的随机值时,网络可以学习的较快,不用调节网络的初始值。
目前常用的激活函数都只拥有上述性质的部分,没有一个拥有全部的。
(1)Sigmoid函数(目前已被淘汰)
f
(
x
)
=
1
1
+
e
−
x
f\left( x \right)=\frac{1}{1+{{e}^{-x}}}
f(x)=1+e−x1
缺点:
①饱和时梯度值非常小。由于BP算法反向传播的时候后层的梯度是以乘性方式传递到前层,因此当层数比较多的时候,传到前层的梯度就会非常小,网络权值得不到有效的更新,即梯度耗散。如果该层的权值初始化使得f(x) 处于饱和状态时,网络基本上权值无法更新。
②输出值不是以0为中心值。
(2)Tanh函数
tanh
(
x
)
=
2
σ
(
2
x
)
−
1
\tanh \left( x \right)=2\sigma \left( 2x \right)-1
tanh(x)=2σ(2x)−1
其中σ(x) 为sigmoid函数,仍然具有饱和的问题。
(3)ReLU函数(Alex在2012年提出的一种新的激活函数。该函数的提出很大程度的解决了BP算法在优化深层神经网络时的梯度耗散问题)
f
(
x
)
=
max
(
0
,
x
)
f\left( x \right)=\max \left( 0,x \right)
f(x)=max(0,x)
优点:
① x>0 时,梯度恒为1,无梯度耗散问题,收敛快;
② 增大了网络的稀疏性。当x<0 时,该层的输出为0,训练完成后为0的神经元越多,
稀疏性越大,提取出来的特征就约具有代表性,泛化能力越强。即得到同样的效果,真正起作用的神经元越少,网络的泛化性能越好;
③ 运算量很小。
缺点:
①如果后层的某一个梯度特别大,导致W更新以后变得特别大,导致该层的输入(WX+b)<0,输出为0,这时该层就会‘die’,没有更新。当学习率比较大时可能会有40%的神经元都会在训练开始就‘die’,因此需要对学习率进行一个好的设置。
由优缺点可知max(0,x) 函数为一把双刃剑,既可以形成网络的稀疏性,也可能造成有很多永远处于‘die’的神经元,需要权衡(tradeoff)。
(4)Leaky ReLU函数
f
(
x
)
=
{
1
,
x
<
0
a
x
+
1
,
x
≥
0
f\left( x \right)=\left\{ \begin{matrix} 1,x<0 \\ ax+1,x\ge 0 \\ \end{matrix} \right.
f(x)={1,x<0ax+1,x≥0
改善了ReLU的死亡特性,但是也同时损失了一部分稀疏性,且增加了一个超参数,目前来说其好处不太明确
(5)Maxout函数
f
(
x
)
=
max
(
w
1
T
x
+
b
1
,
w
2
T
x
+
b
2
)
f\left( x \right)=\max \left( w_{1}^{T}x+{{b}_{1}},w_{2}^{T}x+{{b}_{2}} \right)
f(x)=max(w1Tx+b1,w2Tx+b2)
泛化了ReLU和Leaky ReLU,改善了死亡特性,但是同样损失了部分稀疏性,每个非线性函数增加了两倍的参数。
(6)激活函数小结
真实使用的时候最常用的还是ReLU函数,注意学习率的设置以及死亡节点所占的比例即可。
2.6全连接层
全连接层:连接所有的特征,将输出值送给分类器(如softmax分类器)。
3 CNN的前向与反向传播
3.1前向传播
(1)输入层前向传播到卷积层
前向传播可以表示为:
a
(
2
)
=
σ
(
z
(
2
)
)
=
σ
(
a
(
1
)
∗
W
(
2
)
+
b
(
2
)
)
{{a}^{\left( 2 \right)}}=\sigma \left( {{z}^{\left( 2 \right)}} \right)=\sigma \left( {{a}^{\left( 1 \right)}}*{{W}^{\left( 2 \right)}}+{{b}^{\left( 2 \right)}} \right)
a(2)=σ(z(2))=σ(a(1)∗W(2)+b(2))
其中,上标代表层数,星号代表卷积,而b代表偏置, σ为激活函数,这里一般都是ReLU。
需要我们自己定义的CNN模型参数是:
①一般我们的卷积核不止一个,比如有K个,那么我们输入层的输出,或者说第二层卷积层的对应的输入就K个。
②卷积核中每个子矩阵的的大小,一般我们都用子矩阵为方阵的卷积核,比如FxF的子矩阵。
③填充padding(以下简称P),我们卷积的时候,为了可以更好的识别边缘,一般都会在输入矩阵在周围加上若干圈的0再进行卷积,加多少圈则P为多少。
④步幅stride(以下简称S),即在卷积过程中每次移动的像素距离大小。
(2)隐藏层前向传播到卷积层
假设隐藏层的输出是M个矩阵对应的三维张量,则输出到卷积层的卷积核也是M个子矩阵对应的三维张量。这时表达式和输入层的很像,也是
a
(
l
)
=
σ
(
z
(
l
)
)
=
σ
(
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
{{a}^{\left( l \right)}}=\sigma \left( {{z}^{\left( l \right)}} \right)=\sigma \left( {{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
a(l)=σ(z(l))=σ(a(l−1)∗W(l)+b(l))
也可以写成M个子矩阵卷积后对应位置相加的形式,即:
a
(
l
)
=
σ
(
z
(
l
)
)
=
σ
(
∑
k
=
1
M
z
k
(
l
)
)
=
σ
(
∑
k
=
1
M
a
k
(
l
−
1
)
∗
W
k
(
l
)
+
b
(
l
)
)
{{a}^{\left( l \right)}}=\sigma \left( {{z}^{\left( l \right)}} \right)=\sigma \left( \sum\limits_{k=1}^{M}{z_{k}^{\left( l \right)}} \right)=\sigma \left( \sum\limits_{k=1}^{M}{a_{^{k}}^{\left( l-1 \right)}*W_{^{k}}^{\left( l \right)}+{{b}^{\left( l \right)}}} \right)
a(l)=σ(z(l))=σ(k=1∑Mzk(l))=σ(k=1∑Mak(l−1)∗Wk(l)+b(l))
和上一节唯一的区别仅仅在于,这里的输入是隐藏层来的,而不是我们输入的原始图片样本形成的矩阵。
需要我们定义的CNN模型参数也和上一节一样,这里我们需要定义卷积核的个数K,卷积核子矩阵的维度F,填充大小P以及步幅S。
(3)隐藏层前向传播到池化层
池化层的处理逻辑是比较简单的,我们的目的就是对输入的矩阵进行缩小概括。比如输入的若干矩阵是NxN维的,而我们的池化大小是kxk的区域,则输出的矩阵都是
N
k
×
N
k
\frac{N}{k}\times \frac{N}{k}
kN×kN维的。
这里需要需要我们定义的CNN模型参数是:
① 池化区域的大小k;
②池化的标准,一般是MAX或者Average。
(4)隐藏层前向传播到全连接层
前向传播依然表示为:
a
(
l
)
=
σ
(
z
(
l
)
)
=
σ
(
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
{{a}^{\left( l \right)}}=\sigma \left( {{z}^{\left( l \right)}} \right)=\sigma \left( {{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
a(l)=σ(z(l))=σ(a(l−1)∗W(l)+b(l))
这里的激活函数一般是sigmoid或者tanh。
经过了若干全连接层之后,最后的一层为Softmax输出层。此时输出层和普通的全连接层唯一的区别是,激活函数是softmax函数。
这里需要需要我们定义的CNN模型参数是:
①全连接层的激活函数;
②全连接层各层神经元的个数。
(5)前向传播算法小结
输入:1个图片样本,CNN模型的层数L和所有隐藏层的类型,对于卷积层,要定义卷积核的大小K,卷积核子矩阵的维度F,填充大小P,步幅S。对于池化层,要定义池化区域大小k和池化标准(MAX或Average),对于全连接层,要定义全连接层的激活函数(输出层除外)和各层的神经元个数。
输出:CNN模型的输出
a
(
L
)
{{a}^{\left( L \right)}}
a(L)
Step1:根据输入层的填充大小P,填充原始图片的边缘,得到输入张量
a
(
l
)
{{a}^{\left( l \right)}}
a(l)
Step2:初始化所有隐藏层的参数W,b
Step3:for l=2 to L-1
a)如果第l层是卷积层,则输出为
a
(
l
)
=
R
e
L
U
(
z
(
l
)
)
=
R
e
L
U
(
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
{{a}^{\left( l \right)}}=ReLU\left( {{z}^{\left( l \right)}} \right)=ReLU\left( {{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
a(l)=ReLU(z(l))=ReLU(a(l−1)∗W(l)+b(l))
b) 如果第l层是池化层,则输出为
a
(
l
)
=
p
o
o
l
(
a
(
l
−
1
)
)
{{a}^{\left( l \right)}}=pool\left( {{a}^{\left( l-1 \right)}} \right)
a(l)=pool(a(l−1)), 这里的pool指按照池化区域大小k和池化标准将输入张量缩小的过程。
c)如果第l层是全连接层,则输出为
a
(
l
)
=
σ
(
z
(
l
)
)
=
σ
(
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
{{a}^{\left( l \right)}}=\sigma \left( {{z}^{\left( l \right)}} \right)=\sigma \left( {{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
a(l)=σ(z(l))=σ(a(l−1)∗W(l)+b(l))
Step4:对于输出层第L层:
a
(
L
)
=
s
o
f
t
m
a
x
(
z
(
l
)
)
=
s
o
f
t
m
a
x
(
a
(
L
−
1
)
∗
W
(
L
)
+
b
(
L
)
)
{{a}^{\left( L \right)}}=softmax\left( {{z}^{\left( l \right)}} \right)=softmax\left( {{a}^{\left( L-1 \right)}}*{{W}^{\left( L \right)}}+{{b}^{\left( L \right)}} \right)
a(L)=softmax(z(l))=softmax(a(L−1)∗W(L)+b(L))
3.2反向传播
卷积神经网络反向传播算法需要解决以下几个问题:
①池化层没有激活函数,因此令池化层的激活函数为σ(z)=z,即激活后便是本身,这样池化层激活函数的导数为1。另池化层在前向传播算法之中,对输入进行了压缩,那么现在反向推倒
δ
(
l
−
1
)
{{\delta }^{\left( l-1 \right)}}
δ(l−1),如何求解呢。
②卷积层是通过张量进行卷积,而DNN的全连接层是直接进行矩阵乘法计算,然后得到当前层的输出,那么卷积层进行反向传播时如何推导
δ
(
l
−
1
)
{{\delta }^{\left( l-1 \right)}}
δ(l−1)呢。
③对于卷积层,由于和W的运算是卷积,那么从
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)推导出当前层卷积的W,b方式也不同,针对卷积神经网络如何求解W,b呢。
由于卷积层可以有多个卷积核,各个卷积核之间的处理方式是完全相同的,为了简化算法公式的复杂度,下面推导时只针对卷积层中若干卷积核中的一个。
(1)已知池化层
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l),推导上一隐藏层
δ
(
l
−
1
)
{{\delta }^{\left( l-1 \right)}}
δ(l−1)
针对上述问题1,CNN前向传播算法时,池化层一般会采用Max或Average对输入进行池化,池化的区域大小已知。现在我们反过来,从缩小后的误差
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l),还原前一次较大区域对应的误差。
在反向传播时,我们首先会把
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)的所有子矩阵矩阵大小还原成池化之前的大小,然后如果是MAX,则把
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)的所有子矩阵的各个池化局域的值放在之前做前向传播算法得到最大值的位置。如果是Average,则把
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)的所有子矩阵的各个池化局域的值取平均后放在还原后的子矩阵位置。这个过程一般叫做upsample。
用一个例子表示:假设我们的池化区域大小是2x2。
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)的第k个字矩阵为:
δ
k
(
l
)
=
(
2
8
4
6
)
\delta _{k}^{\left( l \right)}=\left( \begin{matrix} 2 & 8 \\ 4 & 6 \\ \end{matrix} \right)
δk(l)=(2486)
由于池化区域为2x2,先将
δ
k
(
l
)
\delta _{k}^{\left( l \right)}
δk(l)做还原,即变成:
(
0
0
0
0
0
2
8
0
0
4
6
0
0
0
0
0
)
\left( \begin{matrix} 0 & 0 & 0 & 0 \\ 0 & 2 & 8 & 0 \\ 0 & 4 & 6 & 0 \\ 0 & 0 & 0 & 0 \\ \end{matrix} \right)
⎝⎜⎜⎛0000024008600000⎠⎟⎟⎞
如果是MAX,假设之前在前向传播时记录的最大值位置分别是左上,右下,右上,左下,则转换后的矩阵为:
(
2
0
0
0
0
0
0
8
0
4
0
0
0
0
6
0
)
\left( \begin{matrix} 2 & 0 & 0 & 0 \\ 0 & 0 & 0 & 8 \\ 0 & 4 & 0 & 0 \\ 0 & 0 & 6 & 0 \\ \end{matrix} \right)
⎝⎜⎜⎛2000004000060800⎠⎟⎟⎞
如果是Average,则进行平均:转换后的矩阵为:
(
0.5
0.5
2
2
0.5
0.5
2
2
1
1
1.5
1.5
1
1
1.5
1.5
)
\left( \begin{matrix} 0.5 & 0.5 & 2 & 2 \\ 0.5 & 0.5 & 2 & 2 \\ 1 & 1 & 1.5 & 1.5 \\ 1 & 1 & 1.5 & 1.5 \\ \end{matrix} \right)
⎝⎜⎜⎛0.50.5110.50.511221.51.5221.51.5⎠⎟⎟⎞
这样就得到了上一层
∂
J
(
W
,
b
)
∂
a
k
(
l
−
1
)
\frac{\partial J\left( W,b \right)}{\partial a_{k}^{\left( l-1 \right)}}
∂ak(l−1)∂J(W,b)的值,要得到
δ
k
(
l
−
1
)
\delta _{k}^{\left( l-1 \right)}
δk(l−1):
δ
k
(
l
−
1
)
=
∂
J
(
W
,
b
)
∂
a
k
(
l
−
1
)
∂
a
k
(
l
−
1
)
∂
z
k
(
l
−
1
)
=
u
p
s
a
m
p
l
e
(
δ
k
(
l
)
)
⊙
σ
′
(
z
k
(
l
−
1
)
)
\delta _{k}^{\left( l-1 \right)}=\frac{\partial J\left( W,b \right)}{\partial a_{k}^{\left( l-1 \right)}}\frac{\partial a_{k}^{\left( l-1 \right)}}{\partial z_{k}^{\left( l-1 \right)}}=upsample\left( \delta _{k}^{\left( l \right)} \right)\odot {{\sigma }^{'}}\left( z_{k}^{\left( l-1 \right)} \right)
δk(l−1)=∂ak(l−1)∂J(W,b)∂zk(l−1)∂ak(l−1)=upsample(δk(l))⊙σ′(zk(l−1))
其中,upsample函数完成了池化误差矩阵方法与误差重新分配的逻辑。
(2)已知卷积层的
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l),推导上一隐藏层的
δ
(
l
−
1
)
{{\delta }^{\left( l-1 \right)}}
δ(l−1)
对于卷积层的前向传播,首先回忆下卷积层的前向传播公式:
a
(
l
)
=
σ
(
z
(
l
)
)
=
σ
(
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
{{a}^{\left( l \right)}}=\sigma \left( {{z}^{\left( l \right)}} \right)=\sigma \left( {{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
a(l)=σ(z(l))=σ(a(l−1)∗W(l)+b(l))
在深度神经网络(DNN)中,
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)和
δ
(
l
−
1
)
{{\delta }^{\left( l-1 \right)}}
δ(l−1)递推关系如下:
δ
(
l
)
=
∂
J
(
W
,
b
)
∂
z
(
l
)
=
∂
J
(
W
,
b
)
∂
z
(
l
+
1
)
∂
z
(
l
+
1
)
∂
z
(
l
)
=
δ
(
l
+
1
)
∂
z
(
l
+
1
)
∂
z
(
l
)
{{\delta }^{\left( l \right)}}=\frac{\partial J\left( W,b \right)}{\partial {{z}^{\left( l \right)}}}=\frac{\partial J\left( W,b \right)}{\partial {{z}^{\left( l+1 \right)}}}\frac{\partial {{z}^{\left( l+1 \right)}}}{\partial {{z}^{\left( l \right)}}}={{\delta }^{\left( l+1 \right)}}\frac{\partial {{z}^{\left( l+1 \right)}}}{\partial {{z}^{\left( l \right)}}}
δ(l)=∂z(l)∂J(W,b)=∂z(l+1)∂J(W,b)∂z(l)∂z(l+1)=δ(l+1)∂z(l)∂z(l+1)
因此要推导出
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)和
δ
(
l
−
1
)
{{\delta }^{\left( l-1 \right)}}
δ(l−1)的关系,必须计算
∂
z
(
l
+
1
)
∂
z
(
l
)
\frac{\partial {{z}^{\left( l+1 \right)}}}{\partial {{z}^{\left( l \right)}}}
∂z(l)∂z(l+1)的梯度表达式。
注意到
z
(
l
)
{{z }^{\left( l \right)}}
z(l)和
z
(
l
−
1
)
{{z }^{\left( l-1 \right)}}
z(l−1)的关系为:
z
(
l
)
=
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
=
σ
(
z
(
l
−
1
)
)
∗
W
(
l
)
+
b
(
l
)
{{z}^{\left( l \right)}}={{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}}=\sigma \left( {{z}^{\left( l-1 \right)}} \right)*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}}
z(l)=a(l−1)∗W(l)+b(l)=σ(z(l−1))∗W(l)+b(l)
因此我们有:
δ
(
l
−
1
)
=
δ
(
l
)
∂
z
(
l
)
∂
z
(
l
−
1
)
=
δ
(
l
)
∗
r
o
t
180
(
W
(
l
)
)
⊙
σ
′
(
z
(
l
−
1
)
)
{{\delta }^{\left( l-1 \right)}}={{\delta }^{\left( l \right)}}\frac{\partial {{z}^{\left( l \right)}}}{\partial {{z}^{\left( l-1 \right)}}}={{\delta }^{\left( l \right)}}*rot180\left( {{W}^{\left( l \right)}} \right)\odot {{\sigma }^{'}}\left( {{z}^{\left( l-1 \right)}} \right)
δ(l−1)=δ(l)∂z(l−1)∂z(l)=δ(l)∗rot180(W(l))⊙σ′(z(l−1))
这里的式子其实和DNN的类似,区别在于对于含有卷积的式子求导时,卷积核被旋转了180度。即式子中的rot180(),翻转180度的意思是上下翻转一次,接着左右翻转一次。在DNN中这里只是矩阵的转置。那么为什么呢?由于这里都是张量,直接推演参数太多了。我们以一个简单的例子说明为啥这里求导后卷积核要翻转。
假设我们l−1层的输出
a
(
l
−
1
)
{{a}^{\left( l-1 \right)}}
a(l−1)是一个3x3矩阵,第l层的卷积核
W
(
l
)
{{W}^{\left( l \right)}}
W(l)是一个2x2矩阵,采用1像素的步幅,则输出 是一个2x2的矩阵。我们简化
b
(
l
)
{{b}^{\left( l \right)}}
b(l)都是0,则有
a
(
l
−
1
)
∗
W
(
l
)
=
z
(
l
)
{{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}={{z}^{\left( l \right)}}
a(l−1)∗W(l)=z(l)
列出a,W,z的矩阵表达式如下:
(
a
11
a
12
a
13
a
21
a
22
a
23
a
31
a
32
a
33
)
∗
(
w
11
w
12
w
21
w
22
)
=
(
z
11
z
12
z
21
z
22
)
\left( \begin{matrix} {{a}_{11}} & {{a}_{12}} & {{a}_{13}} \\ {{a}_{21}} & {{a}_{22}} & {{a}_{23}} \\ {{a}_{31}} & {{a}_{32}} & {{a}_{33}} \\ \end{matrix} \right)*\left( \begin{matrix} {{w}_{11}} & {{w}_{12}} \\ {{w}_{21}} & {{w}_{22}} \\ \end{matrix} \right)=\left( \begin{matrix} {{z}_{11}} & {{z}_{12}} \\ {{z}_{21}} & {{z}_{22}} \\ \end{matrix} \right)
⎝⎛a11a21a31a12a22a32a13a23a33⎠⎞∗(w11w21w12w22)=(z11z21z12z22)
利用卷积的定义,很容易得出:
z
11
=
a
11
w
11
+
a
12
w
12
+
a
21
w
21
+
a
22
w
22
{{z}_{11}}={{a}_{11}}{{w}_{11}}+{{a}_{12}}{{w}_{12}}+{{a}_{21}}{{w}_{21}}+{{a}_{22}}{{w}_{22}}
z11=a11w11+a12w12+a21w21+a22w22
z
12
=
a
12
w
11
+
a
13
w
12
+
a
22
w
21
+
a
23
w
22
{{z}_{12}}={{a}_{12}}{{w}_{11}}+{{a}_{13}}{{w}_{12}}+{{a}_{22}}{{w}_{21}}+{{a}_{23}}{{w}_{22}}
z12=a12w11+a13w12+a22w21+a23w22
z
21
=
a
21
w
11
+
a
22
w
12
+
a
31
w
21
+
a
32
w
22
{{z}_{21}}={{a}_{21}}{{w}_{11}}+{{a}_{22}}{{w}_{12}}+{{a}_{31}}{{w}_{21}}+{{a}_{32}}{{w}_{22}}
z21=a21w11+a22w12+a31w21+a32w22
z
22
=
a
22
w
11
+
a
23
w
13
+
a
32
w
21
+
a
33
w
22
{{z}_{22}}={{a}_{22}}{{w}_{11}}+{{a}_{23}}{{w}_{13}}+{{a}_{32}}{{w}_{21}}+{{a}_{33}}{{w}_{22}}
z22=a22w11+a23w13+a32w21+a33w22
接着反向求导:
∇
a
(
l
−
1
)
=
∂
J
(
W
,
b
)
∂
a
(
l
−
1
)
=
∂
J
(
W
,
b
)
∂
z
(
l
)
∂
z
(
l
)
∂
a
(
l
−
1
)
=
δ
(
l
)
∂
z
(
l
)
∂
a
(
l
−
1
)
\nabla {{a}^{\left( l-1 \right)}}=\frac{\partial J\left( W,b \right)}{\partial {{a}^{\left( l-1 \right)}}}=\frac{\partial J\left( W,b \right)}{\partial {{z}^{\left( l \right)}}}\frac{\partial {{z}^{\left( l \right)}}}{\partial {{a}^{\left( l-1 \right)}}}={{\delta }^{\left( l \right)}}\frac{\partial {{z}^{\left( l \right)}}}{\partial {{a}^{\left( l-1 \right)}}}
∇a(l−1)=∂a(l−1)∂J(W,b)=∂z(l)∂J(W,b)∂a(l−1)∂z(l)=δ(l)∂a(l−1)∂z(l)
从上式可以看出,对于
a
(
l
−
1
)
{{a}^{\left( l-1 \right)}}
a(l−1)的梯度误差
∇
a
(
l
−
1
)
\nabla {{a}^{\left( l-1 \right)}}
∇a(l−1),等于第l层的梯度误差乘以
∂
z
(
l
)
∂
a
(
l
−
1
)
\frac{\partial {{z}^{\left( l \right)}}}{\partial {{a}^{\left( l-1 \right)}}}
∂a(l−1)∂z(l),而
∂
z
(
l
)
∂
a
(
l
−
1
)
\frac{\partial {{z}^{\left( l \right)}}}{\partial {{a}^{\left( l-1 \right)}}}
∂a(l−1)∂z(l)对应上面的例子中相关联的w的值。假设我们的z矩阵对应的反向传播误差是
δ
11
,
δ
12
,
δ
21
,
δ
22
{{\delta }_{11}},{{\delta }_{12}},{{\delta }_{21}},{{\delta }_{22}}
δ11,δ12,δ21,δ22组成的2x2矩阵,则利用上面梯度的式子和4个等式,我们可以分别写出
∇
a
(
l
−
1
)
\nabla {{a}^{\left( l-1 \right)}}
∇a(l−1)的9个标量的梯度。
比如
a
11
{{a}_{11}}
a11的梯度,由于在4个等式中
a
11
{{a}_{11}}
a11只和
z
11
{{z}_{11}}
z11有乘积关系,从而我们有
∇
a
11
=
δ
11
w
11
\nabla {{a}_{11}}={{\delta }_{11}}{{w}_{11}}
∇a11=δ11w11
对于
a
12
{{a}_{12}}
a12的梯度,由于在4个等式中
a
12
{{a}_{12}}
a12和
z
12
{{z}_{12}}
z12,
z
11
{{z}_{11}}
z11有乘积关系,从而我们有:
∇
a
12
=
δ
11
w
12
+
δ
12
w
11
\nabla {{a}_{12}}={{\delta }_{11}}{{w}_{12}}+{{\delta }_{12}}{{w}_{11}}
∇a12=δ11w12+δ12w11
同理可推出a其他的误差值。用一个矩阵相乘的式子表示为:
(
0
0
0
0
0
δ
11
δ
12
0
0
δ
21
δ
22
0
0
0
0
0
)
∗
(
w
22
w
21
w
12
w
11
)
=
(
∇
a
11
∇
a
12
∇
a
13
∇
a
21
∇
a
22
∇
a
23
∇
a
31
∇
a
32
∇
a
33
)
\left( \begin{matrix} 0 & 0 & 0 & 0 \\ 0 & {{\delta }_{11}} & {{\delta }_{12}} & 0 \\ 0 & {{\delta }_{21}} & {{\delta }_{22}} & 0 \\ 0 & 0 & 0 & 0 \\ \end{matrix} \right)*\left( \begin{matrix} {{w}_{22}} & {{w}_{21}} \\ {{w}_{12}} & {{w}_{11}} \\ \end{matrix} \right)=\left( \begin{matrix} \nabla {{a}_{11}} & \nabla {{a}_{12}} & \nabla {{a}_{13}} \\ \nabla {{a}_{21}} & \nabla {{a}_{22}} & \nabla {{a}_{23}} \\ \nabla {{a}_{31}} & \nabla {{a}_{32}} & \nabla {{a}_{33}} \\ \end{matrix} \right)
⎝⎜⎜⎛00000δ11δ2100δ12δ2200000⎠⎟⎟⎞∗(w22w12w21w11)=⎝⎛∇a11∇a21∇a31∇a12∇a22∇a32∇a13∇a23∇a33⎠⎞
为了符合梯度计算,我们在误差矩阵周围填充了一圈0,此时我们将卷积核翻转后和反向传播的梯度误差进行卷积,就得到了前一次的梯度误差。这个例子直观的介绍了为什么对含有卷积的式子反向传播时,卷积核要翻转180度的原因。
(3)已知卷积层的
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l),推导改成的W,b的梯度
现在已经递推出每一层的梯度误差
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)了,对于全连接层,可以按照DNN的反向传播算法求该层W,b的梯度,而池化层并没有W,b,也不用求W,b的梯度了。只有卷积层的W,b需要求出。
注意到卷积层z和W,b的关系为:
z
(
l
)
=
a
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
{{z}^{\left( l \right)}}={{a}^{\left( l-1 \right)}}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}}
z(l)=a(l−1)∗W(l)+b(l)
因此我们有:
∂
J
(
W
,
b
)
∂
W
(
l
)
=
∂
J
(
W
,
b
)
∂
z
(
l
)
∂
z
(
l
)
∂
W
(
l
)
=
a
(
l
−
1
)
∗
δ
(
l
)
\frac{\partial J\left( W,b \right)}{\partial {{W}^{\left( l \right)}}}\text{=}\frac{\partial J\left( W,b \right)}{\partial {{z}^{\left( l \right)}}}\frac{\partial {{z}^{\left( l \right)}}}{\partial {{W}^{\left( l \right)}}}={{a}^{\left( l-1 \right)*}}{{\delta }^{\left( l \right)}}
∂W(l)∂J(W,b)=∂z(l)∂J(W,b)∂W(l)∂z(l)=a(l−1)∗δ(l)
注意到此时卷积核并没有反转,主要是此时是层内的求导,而不是反向传播到上一层的求导。具体过程可以分析如下:
∂
J
(
W
,
b
)
∂
W
p
q
(
l
)
=
∑
i
∑
j
(
δ
i
j
(
l
)
a
i
+
p
−
1
,
j
+
q
−
1
(
l
−
1
)
)
\frac{\partial J\left( W,b \right)}{\partial W_{pq}^{\left( l \right)}}=\sum\limits_{i}{\sum\limits_{j}{\left( \delta _{ij}^{^{\left( l \right)}}a_{i+p-1,j+q-1}^{^{\left( l-1 \right)}} \right)}}
∂Wpq(l)∂J(W,b)=i∑j∑(δij(l)ai+p−1,j+q−1(l−1))
假设我们输入a是4x4的矩阵,卷积核W是3x3的矩阵,输出z是2x2的矩阵,那么反向传播的z的梯度误差也是2x2的矩阵。
那么根据上面的式子,我们有:
∂
J
(
W
,
b
)
∂
W
11
(
l
)
=
a
11
δ
11
+
a
12
δ
12
+
a
21
δ
21
+
a
22
δ
22
\frac{\partial J\left( W,b \right)}{\partial W_{11}^{\left( l \right)}}={{a}_{11}}{{\delta }_{11}}+{{a}_{12}}{{\delta }_{12}}+{{a}_{21}}{{\delta }_{21}}+{{a}_{22}}{{\delta }_{22}}
∂W11(l)∂J(W,b)=a11δ11+a12δ12+a21δ21+a22δ22
∂
J
(
W
,
b
)
∂
W
12
(
l
)
=
a
12
δ
11
+
a
13
δ
12
+
a
22
δ
21
+
a
23
δ
22
\frac{\partial J\left( W,b \right)}{\partial W_{12}^{\left( l \right)}}={{a}_{12}}{{\delta }_{11}}+{{a}_{13}}{{\delta }_{12}}+{{a}_{22}}{{\delta }_{21}}+{{a}_{23}}{{\delta }_{22}}
∂W12(l)∂J(W,b)=a12δ11+a13δ12+a22δ21+a23δ22
∂
J
(
W
,
b
)
∂
W
13
(
l
)
=
a
13
δ
11
+
a
14
δ
12
+
a
23
δ
21
+
a
24
δ
22
\frac{\partial J\left( W,b \right)}{\partial W_{13}^{\left( l \right)}}={{a}_{13}}{{\delta }_{11}}+{{a}_{14}}{{\delta }_{12}}+{{a}_{23}}{{\delta }_{21}}+{{a}_{24}}{{\delta }_{22}}
∂W13(l)∂J(W,b)=a13δ11+a14δ12+a23δ21+a24δ22
∂
J
(
W
,
b
)
∂
W
21
(
l
)
=
a
21
δ
11
+
a
22
δ
12
+
a
31
δ
21
+
a
32
δ
22
\frac{\partial J\left( W,b \right)}{\partial W_{21}^{\left( l \right)}}={{a}_{21}}{{\delta }_{11}}+{{a}_{22}}{{\delta }_{12}}+{{a}_{31}}{{\delta }_{21}}+{{a}_{32}}{{\delta }_{22}}
∂W21(l)∂J(W,b)=a21δ11+a22δ12+a31δ21+a32δ22
最终我们可以一共得到9个式子。整理成矩阵形式可得:
∂
J
(
W
,
b
)
∂
W
(
l
)
=
(
a
11
a
12
a
13
a
14
a
21
a
22
a
23
a
24
a
31
a
32
a
33
a
34
a
41
a
42
a
43
a
44
)
∗
(
δ
11
δ
12
δ
21
δ
22
)
\frac{\partial J\left( W,b \right)}{\partial {{W}^{\left( l \right)}}}=\left( \begin{matrix} {{a}_{11}} & {{a}_{12}} & {{a}_{13}} & {{a}_{14}} \\ {{a}_{21}} & {{a}_{22}} & {{a}_{23}} & {{a}_{24}} \\ {{a}_{31}} & {{a}_{32}} & {{a}_{33}} & {{a}_{34}} \\ {{a}_{41}} & {{a}_{42}} & {{a}_{43}} & {{a}_{44}} \\ \end{matrix} \right)*\left( \begin{matrix} {{\delta }_{11}} & {{\delta }_{12}} \\ {{\delta }_{21}} & {{\delta }_{22}} \\ \end{matrix} \right)
∂W(l)∂J(W,b)=⎝⎜⎜⎛a11a21a31a41a12a22a32a42a13a23a33a43a14a24a34a44⎠⎟⎟⎞∗(δ11δ21δ12δ22)
从而可以清楚地看到这次我们为什么没有反转的原因。
而对于b,则稍微有些特殊,因为
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)是三维张量,二b只是一个响亮,不能像DNN那样直接和
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)相等。通常的做法是将
δ
(
l
)
{{\delta }^{\left( l \right)}}
δ(l)的各个子矩阵的项分别求和,得到一个误差向量,即为b的梯度:
∂
J
(
W
,
b
)
∂
b
(
l
)
=
∑
u
,
v
(
δ
(
l
)
)
u
,
v
\frac{\partial J\left( W,b \right)}{\partial {{b}^{\left( l \right)}}}\text{=}{{\sum\limits_{u,v}{\left( {{\delta }^{\left( l \right)}} \right)}}_{u,v}}
∂b(l)∂J(W,b)=u,v∑(δ(l))u,v
(4)反向传播算法小结
输入:m个图片样本,CNN模型的层数L和所有隐藏层的类型,对于卷积层,要定义卷积核的大小K,卷积核子矩阵的维度F,填充大小P,步幅S。对于池化层,要定义池化区域大小k和池化标准(MAX或Average),对于全连接层,要定义全连接层的激活函数(输出层除外)和各层的神经元个数。梯度迭代参数迭代步长α,最大迭代次数MAX与停止迭代阈值ϵ。
输出:CNN模型各隐藏层与输出层的W,b
Step1:初始化各隐藏层与输出层的各W,b的值为一个随机值。
Step2:for iter=1 to MAX:
Step2-1:for i=1 to m:
a)将CNN输入
a
(
1
)
{{a}^{\left( 1 \right)}}
a(1)设置为
x
i
{{x}_{i}}
xi对应的张量
b)for l=2 to L-1,根据下面3中情况进行前向传播算法计算:
b-1)如果当前是全连接层:则有
a
i
(
l
)
=
σ
(
z
i
(
l
)
)
=
σ
(
a
i
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
a_{^{i}}^{\left( l \right)}=\sigma \left( z_{^{i}}^{\left( l \right)} \right)=\sigma \left( a_{^{i}}^{\left( l-1 \right)}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
ai(l)=σ(zi(l))=σ(ai(l−1)∗W(l)+b(l))
b-2)如果当前是卷积层:则有
a
i
(
l
)
=
σ
(
z
i
(
l
)
)
=
σ
(
a
i
(
l
−
1
)
∗
W
(
l
)
+
b
(
l
)
)
a_{^{i}}^{\left( l \right)}=\sigma \left( z_{^{i}}^{\left( l \right)} \right)=\sigma \left( a_{^{i}}^{\left( l-1 \right)}*{{W}^{\left( l \right)}}+{{b}^{\left( l \right)}} \right)
ai(l)=σ(zi(l))=σ(ai(l−1)∗W(l)+b(l))
b-3)如果当前是池化层:则有
a
i
(
l
)
=
p
o
o
l
(
a
i
(
l
−
1
)
)
a_{^{i}}^{\left( l \right)}=pool\left( a_{^{i}}^{\left( l-1 \right)} \right)
ai(l)=pool(ai(l−1)),这里的pool指按照池化区域大小k和池化标准将输入张量缩小的过程。
c) 对于输出层第L层:
a
i
(
L
)
=
s
o
f
t
m
a
x
(
z
i
(
L
)
)
=
s
o
f
t
m
a
x
(
a
i
(
L
−
1
)
∗
W
(
L
)
+
b
(
L
)
)
a_{^{i}}^{\left( L \right)}=softmax\left( z_{^{i}}^{\left( L \right)} \right)=softmax\left( a_{^{i}}^{\left( L-1 \right)}*{{W}^{\left( L \right)}}+{{b}^{\left( L \right)}} \right)
ai(L)=softmax(zi(L))=softmax(ai(L−1)∗W(L)+b(L))
c)通过损失函数计算输出层的
δ
i
(
L
)
\delta _{i}^{\left( L \right)}
δi(L)
d)for l=L-1 to 2,根据下面3中情况进行反向传播算法计算:
d-1)如果当前是全连接层:
δ
i
(
l
)
=
(
W
(
l
+
1
)
)
T
δ
i
(
l
+
1
)
⊙
σ
′
(
z
i
(
l
)
)
\delta _{i}^{\left( l \right)}={{\left( {{W}^{\left( l+1 \right)}} \right)}^{T}}\delta _{i}^{\left( l+1 \right)}\odot {{\sigma }^{'}}\left( z_{^{i}}^{\left( l \right)} \right)
δi(l)=(W(l+1))Tδi(l+1)⊙σ′(zi(l))
d-2)如果当前是卷积层:
δ
i
(
l
)
=
δ
i
(
l
+
1
)
∗
r
o
t
180
(
W
(
l
+
1
)
)
⊙
σ
′
(
z
i
(
l
)
)
\delta _{i}^{\left( l \right)}=\delta _{i}^{\left( l+1 \right)}*rot180\left( {{W}^{\left( l+1 \right)}} \right)\odot {{\sigma }^{'}}\left( z_{^{i}}^{\left( l \right)} \right)
δi(l)=δi(l+1)∗rot180(W(l+1))⊙σ′(zi(l))
d-3)如果当前是池化层:
δ
i
(
l
)
=
u
p
s
a
m
p
l
e
(
δ
i
(
l
+
1
)
)
⊙
σ
′
(
z
i
(
l
)
)
\delta _{i}^{\left( l \right)}=upsample\left( \delta _{i}^{\left( l+1 \right)} \right)\odot {{\sigma }^{'}}\left( z_{^{i}}^{\left( l \right)} \right)
δi(l)=upsample(δi(l+1))⊙σ′(zi(l))
Step2-2:for l=2 to L,根据下面2种情况更新第l层的
W
(
l
)
,
b
(
l
)
{{W}^{\left( l \right)}},{{b}^{\left( l \right)}}
W(l),b(l):
Step2-2-1:如果当前是全连接层:
W
(
l
)
=
W
(
l
)
−
α
∑
i
=
1
m
δ
i
(
l
)
(
a
i
(
l
)
)
T
,
b
(
l
)
=
b
(
l
)
−
α
∑
i
=
1
m
δ
i
(
l
)
{{W}^{\left( l \right)}}={{W}^{\left( l \right)}}-\alpha \sum\limits_{i=1}^{m}{\delta _{i}^{\left( l \right)}{{\left( a_{i}^{\left( l \right)} \right)}^{T}}},{{b}^{\left( l \right)}}={{b}^{\left( l \right)}}-\alpha \sum\limits_{i=1}^{m}{\delta _{i}^{\left( l \right)}}
W(l)=W(l)−αi=1∑mδi(l)(ai(l))T,b(l)=b(l)−αi=1∑mδi(l)
Step2-2-2:如果当前是卷积层,对于每一个卷积核有:
W
(
l
)
=
W
(
l
)
−
α
∑
i
=
1
m
δ
i
(
l
)
(
a
i
(
l
)
)
,
b
(
l
)
=
b
(
l
)
−
α
∑
i
=
1
m
∑
u
,
v
(
δ
i
(
l
)
)
u
,
v
{{W}^{\left( l \right)}}={{W}^{\left( l \right)}}-\alpha \sum\limits_{i=1}^{m}{\delta _{i}^{\left( l \right)}\left( a_{i}^{\left( l \right)} \right)},{{b}^{\left( l \right)}}={{b}^{\left( l \right)}}-\alpha \sum\limits_{i=1}^{m}{\sum\limits_{u,v}{{{\left( \delta _{i}^{\left( l \right)} \right)}_{u,v}}}}
W(l)=W(l)−αi=1∑mδi(l)(ai(l)),b(l)=b(l)−αi=1∑mu,v∑(δi(l))u,v
Step2-3:如果所有W,b的变化值都小于停止迭代阈值ϵ,则跳出迭代循环到步骤3。
Step3:输出各隐藏层与输出层的线性关系系数矩阵W和偏置向量b。
4 CNN总结
CNN通过感受野和权值共享减少了神经网络需要训练的参数个数。
CNN网络中前几层的卷积层参数量占比小,计算量占比大;而后面的全连接层正好相反,大部分CNN网络都具有这个特点。因此我们在进行计算加速优化时,重点放在卷积层;进行参数优化、权值裁剪时,重点放在全连接层。
CNN训练中最昂贵的部分是学习特征。输出层的计算代价通常相对不高,因为在通过若干层池化之后作为该层输入的特征的数量较少。当时用梯度下降执行监督训练时,每部梯度计算需要完整地进行整个网络的前向传播和反向传播。减少卷积网络训练成本的一种方式是使用那些不是由监督方式训练得到的特征。有三种策略可以不通过监督训练而得到卷积核:①简单地随机初始化他们;②手动设计他们。例如设置每个核在一个特定的方向或尺度来检测边缘;③使用无监督的标准学习核。例如将k均值聚类算法应用于小图像块,然后使用每个学得的中心作为卷积核。
参考文章:
《深度学习》
https://blog.csdn.net/qq_36653505/article/details/83473943
https://blog.csdn.net/u010725283/article/details/78593410
https://www.cnblogs.com/pinard/p/6483207.html
https://blog.csdn.net/yjl9122/article/details/70198357
https://blog.csdn.net/XiaoYi_Eric/article/details/83245421
https://www.cnblogs.com/pinard/p/6489633.html
https://www.cnblogs.com/pinard/p/6494810.html