1.反向传播神经网络的结构
1.1神经网络概述
神经网络自GPU蓬勃发展以来,已经渐渐地家喻户晓,门口买烧饼的大爷都知道人工智能下棋很厉害。神经网络被广泛应用于各种领域,图像识别,语音处理,三维重建,脑电处理等等,细化出了无数的模型,比如著名的YOLO,INCEPTION,RNN,RESNET等等,把这些全部讲完是不可能的。但是万变不离其中,神经网络就像是堆积木,固然每个算法都有自己的独特之处,网络的绝大部分都是卷积层和全连接层的堆叠。本篇将重点放在最原始的梯度反向传播神经网络,因为反向传播的算法实在是太关键了。
1.2BP神经网络结构
back propagation net,又称bpnet,是最为基础的一类神经网络,由输入层,中间层和输出层组成,基本结构就是下图:
如何理解这个图呢?我们可以把每一层都想象成一个特征向量
x
i
x_i
xi,特征向量的每一个维度记作
x
i
j
x_{ij}
xij,其中
i
i
i表示第
i
i
i层的神经元。那么下一层的第
j
j
j个神经元的输出结果就可以表示为:
x
i
+
1
,
j
=
θ
(
w
i
j
x
i
)
x_{i+1 ,j} = \theta(w_{ij} x_i)
xi+1,j=θ(wijxi)
拓展到所有神经元,式子就可以写成:
x
i
+
1
=
θ
(
w
i
x
i
)
x_{i+1} = \theta(w_i x_i)
xi+1=θ(wixi)
其中
x
i
x_i
xi是一个m维的向量,
x
i
+
1
x_{i+1}
xi+1是一个n维的向量,
w
i
w_i
wi是一个n*m的矩阵。
θ
\theta
θ表示激活函数,常用的激活函数有:sigmoid,tanh,relu等等。在介绍这些激活函数前首先说明以下一下为什么需要激活函数。激活函数出现的目的就是引入非线性的变换,从而使网络可以拟合非线性的分类面。试设想,假如没有非线性环节,那么神经网络的层数堆叠就毫无意义,神经网络归根结底是加权和,形式为:
θ
(
w
n
T
.
.
.
θ
(
w
2
T
θ
(
w
1
T
x
+
b
)
+
b
)
.
.
.
.
.
.
+
b
)
\theta(w_n^T...\theta(w_2^T\theta(w_1^Tx + b)+b)......+b)
θ(wnT...θ(w2Tθ(w1Tx+b)+b)......+b)
假如是线性变换,例如:
4
(
5
(
3
x
+
5
)
+
8
)
+
2
=
60
x
+
135
4(5(3x+5)+8)+2 = 60x+135
4(5(3x+5)+8)+2=60x+135
那么中间那些环节其实没有起到作用,线性变换是可以合一的,因此需要进行非线性变换,常用的激活函数有sigmoid:
θ
(
x
)
=
1
1
+
e
−
x
\theta(x) = \frac{1}{1+e^{-x}}
θ(x)=1+e−x1
这个式子在logistic回归中出现过,可以看到,使用这个函数后,每一个神经元其实都是一次logistic回归。tanh函数的式子是:
e
x
−
e
−
x
e
x
+
e
−
x
\frac{e^x-e^{-x}}{e^x+e^{-x}}
ex+e−xex−e−x
将输出映射到(-1,1)区间。Relu的形式是:
θ
(
x
)
=
{
x
,
x
≥
0
0
,
x
<
0
\theta(x)=\left \{\begin{aligned} &x, \quad x\ge 0 \\ &0, \quad x < 0 \end{aligned}\right.
θ(x)={x,x≥00,x<0
此举避免了梯度消失,因为上两种激活函数往往会到达饱和区,求导梯度趋向于0,从而难以更新权重。
2.反向传播算法推导
2.1什么是反向传播
反向传播这句话缺了宾语,补上之后就显得一目了然,那就是反向传播梯度。我们在之前的梯度下降法中已经讲过,权重更新公式:
w
t
+
1
=
w
t
−
η
⋅
∂
E
∂
w
t
\mathbf{w}_{t+1} = \mathbf{w}_t - \eta \cdot \frac{\partial E}{\partial \mathbf{w}_t}
wt+1=wt−η⋅∂wt∂E
而神经网络每一层都有权重,但是计算损失函数的时候只有最后一层的损失,那么怎么用这一个损失梯度来更新全部的权重呢?我们的神经网络是由线性和非线性部分组成,而使用的非线性激活函数都是可以求导的。因此,应用微积分中的链式法则,就可以一步一步将偏导逐渐传到每一层。我们看一个例子。假如我们的函数是
f
=
(
x
+
y
)
3
z
f = (x+y)^3z
f=(x+y)3z,那么如何求
∂
f
∂
x
\frac{\partial f}{\partial x}
∂x∂f呢,那么令
q
=
x
+
y
q=x+y
q=x+y,
p
=
q
3
p=q^3
p=q3就可以把偏导拆成
∂
f
∂
p
⋅
∂
p
∂
q
⋅
∂
q
∂
x
\frac{\partial f}{\partial p}\cdot \frac{\partial p}{\partial q}\cdot \frac{\partial q}{\partial x}
∂p∂f⋅∂q∂p⋅∂x∂q,最后得到结果
z
∗
3
(
x
+
y
)
2
z*3(x+y)^2
z∗3(x+y)2,那我们是不是可以把这三个导数看成三层神经元?第一层的激活函数是一个线性的
∗
1
*1
∗1,第二层的激活函数是一个
x
3
x^3
x3,第三层的激活函数是一个倍增
x
z
xz
xz。
2.2BPNet反向传播推导
有了反向传播的概念,我们现在可以开始推导神经网络的反向传播了,还是拿之前那张图,这样一来可以更加具体:
在这个例子里,
x
i
x_i
xi是一个3维的向量,
x
i
+
1
x_{i+1}
xi+1是一个4维的向量,那么
w
i
w_i
wi就是一个4*3的矩阵,
x
i
+
1
=
θ
(
w
i
x
i
)
x_{i+1} = \theta(w_i x_i)
xi+1=θ(wixi),
w
i
j
w_{ij}
wij是箭头指向
x
i
+
1
,
j
x_{i+1, j}
xi+1,j的三条线上的权重,而
w
i
w_i
wi的列向量则是从
x
i
j
x_{ij}
xij发出的四条指向
x
i
+
1
x_{i+1}
xi+1的线上的权重。现在我们假设
x
i
+
1
x_{i+1}
xi+1上收到后方传来的梯度为
δ
(
x
i
+
1
)
\delta(x_{i+1})
δ(xi+1),即
∂
E
∂
x
i
+
1
=
δ
(
x
i
+
1
)
\frac{\partial E}{\partial x_{i+1}} =\delta(x_{i+1})
∂xi+1∂E=δ(xi+1)这是一个4维的向量。那么对照上图
∂
E
∂
w
i
j
\frac{\partial E}{\partial w_{ij}}
∂wij∂E的值就很容易得到(注意
w
i
j
是
1
∗
3
的
向
量
)
w_{ij}是1*3的向量)
wij是1∗3的向量),即:
∂
E
∂
w
i
j
=
δ
(
x
i
+
1
)
∗
∂
x
i
+
1
∂
w
i
j
x
i
∗
∂
w
i
j
x
i
∂
w
i
j
=
δ
(
x
i
+
1
,
j
)
θ
′
(
w
i
j
x
i
)
x
i
T
\frac{\partial E}{\partial w_{ij}}=\delta(x_{i+1})*\frac{\partial x_{i+1}}{\partial w_{ij}x_i} * \frac{\partial w_{ij}x_i}{\partial w_{ij}} =\delta(x_{i+1,j})\theta'(w_{ij}x_i)x_i^T
∂wij∂E=δ(xi+1)∗∂wijxi∂xi+1∗∂wij∂wijxi=δ(xi+1,j)θ′(wijxi)xiT
拓展到每一个
j
j
j
∂
E
∂
w
i
=
δ
(
x
i
+
1
,
j
)
θ
′
(
w
i
x
i
)
x
i
T
\frac{\partial E}{\partial w_{i}}= \delta(x_{i+1,j})\theta'(w_{i}x_i)x_i^T
∂wi∂E=δ(xi+1,j)θ′(wixi)xiT
用这个公式去更新
w
i
w_i
wi就可以了。
利用上层梯度更新这层权重已经完成了,接下来就是向下层传递梯度,也就是求
∂
E
∂
x
i
\frac{\partial E}{\partial x_{i}}
∂xi∂E,我们可以看到,
x
i
x_i
xi的每一个维度向下一层发出了四条线,那么回传偏导的时候,这四条线都要给他传递偏导,而这四条线正好就是
w
i
w_i
wi的列向量,那么只要用
w
i
w_i
wi的列向量去乘以
δ
(
x
i
+
1
,
j
)
θ
′
(
w
i
x
i
)
\delta(x_{i+1,j})\theta'(w_{i}x_i)
δ(xi+1,j)θ′(wixi),不就得到了
∂
E
∂
x
i
\frac{\partial E}{\partial x_{i}}
∂xi∂E也就是
δ
(
x
i
)
\delta(x_i)
δ(xi)了吗?由此写出公式:
δ
(
x
i
)
=
w
i
T
δ
(
x
i
+
1
,
j
)
θ
′
(
w
i
x
i
)
\delta(x_i)=w_i^T \delta(x_{i+1,j})\theta'(w_{i}x_i)
δ(xi)=wiTδ(xi+1,j)θ′(wixi)
是不是很简单?由上,已知
δ
(
x
i
+
1
)
\delta(x_{i+1})
δ(xi+1)就能得到
δ
(
x
i
)
\delta(x_{i})
δ(xi),那么BP网络的学习过程就是两个:首先,正向地计算出各个
x
i
x_i
xi的值,并且计算loss,求到
∂
E
∂
x
n
\frac{\partial E}{\partial x_n}
∂xn∂E,这是最后一层的梯度。然后,反向通过网络,由上面的两个公式,通过
δ
(
x
i
)
\delta(x_i)
δ(xi)不断计算出
∂
E
∂
w
i
−
1
\frac{\partial E}{\partial w_{i-1}}
∂wi−1∂E和
δ
(
x
i
−
1
)
\delta(x_{i-1})
δ(xi−1),一直到输入层为止。最后简单地根据梯度下降法更新一下权重,就可以开始下一轮的训练了。
另外提一嘴,pooling层虽然我不会开篇将,但是pooling的梯度回传比较特殊,因为pooling是取极大极小或者平均,这时候就是人为地规定梯度传给选择的那一片区域,或者是平均一下传给所有的区域。