BP (Back Propagation) 神经网络是1986年由 Rumelhart 和 McClelland 为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是应用最广泛的神经网络。
1 BP 神经网络的结构和传播规则
BP神经网络由 输入层、隐含层(也称中间层)和 输出层 构成 ,其中隐含层有一层或者多层。每一层可以有若干个节点。层与层之间节点的连接状态通过 权重 来体现。
BP神经网络的核心步骤如下。其中,实线代表正向传播,虚线代表反向传播。
1.1 正向传播
数据(信息、信号)从输入端输入后,沿着网络的指向,乘以对应的权重后再加和,再将结果作为输入在激活函数中计算,将计算的结果作为输入传递给下一个节点。依次计算,直到得到最终结果。
通过每一层的感知器,层层计算,得到输出,每个节点的输出作为下一个节点的输入。这个过程就是正向传播。
1.1.1 激活函数
必须处处可导(一般都使用S型函数)。
sigmoid 函数:
δ ( x ) = 1 1 + e − x \delta(x) = \frac{1}{1 + e^{-x}} δ(x)=1+e−x1
sigmoid 函数的导函数:
δ ′ ( x ) = δ ( x ) ( 1 − δ ( x ) ) \delta ^{'} (x) = \delta(x) (1 - \delta(x)) δ′(x)=δ(x)(1−δ(x))
1.1.2 前向传播计算
如前面的 BP 神经网络结构图所示,使用 w j k l w_{jk}^{l} wjkl 表示从网络第 (l-1)层中的第 k 个神经元指向网络第 l 层中的第 j 个神经元的连接权重; b j l b_{j}^{l} bjl 表示网络第 l 层中的第 j 个神经元的 bias; y j l y_{j}^{l} yjl 表示网络第 l 层中的第 j 个神经元的线性输出的结果; x j l x_{j}^{l} xjl 表示网络第 l 层中的第 j 个神经元的激活函数的输出。
那么网络第 l 层中的第 j 个神经元的激活函数的输出可以表示成:
x j l = δ ( ∑ k w j k l a k l − 1 + b l l ) x_{j}^{l} = \delta (\sum _k w_{jk}^{l}a_k^{l-1} + b_l^l) xjl=δ(k∑wjklakl−1+bll)
写成矩阵形式,定义权重矩阵 w l w^l wl,权重矩阵的每一个元素都代表一个权重:
w l = [ w 11 l w 12 l w 13 l w 21 l w 22 l w 23 l w 31 l w 32 l w 33 l ] w^l = \left[ \begin{matrix} w_{11}^l & w_{12}^l & w_{13}^l \\ w_{21}^l & w_{22}^l & w_{23}^l \\ w_{31}^l & w_{32}^l & w_{33}^l \\ \end{matrix} \right] wl= w11lw21lw31lw12lw22lw32lw13lw23lw33l
同样可以写出 x、b、y 的矩阵形式:
x l = [ x 1 l x 2 l x 3 l ] x^l = \left[ \begin{matrix} x_1^l \\ x_2^l \\ x_3^l \\ \end{matrix} \right] xl= x1lx2lx3l
b l = [ b 1 l b 2 l b 3 l ] b^l = \left[ \begin{matrix} b_1^l \\ b_2^l \\ b_3^l \\ \end{matrix} \right] bl= b1lb2lb3l
y l = δ ( [ w 11 l w 12 l w 13 l w 21 l w 22 l w 23 l w 31 l w 32 l w 33 l ] ⋅ [ x 1 l − 1 x 2 l − 1 x 3 l − 1 ] + [ b 1 l b 2 l b 3 l ] ) y^l = \delta \left( \left[ \begin{matrix} w_{11}^l & w_{12}^l & w_{13}^l \\ w_{21}^l & w_{22}^l & w_{23}^l \\ w_{31}^l & w_{32}^l & w_{33}^l \\ \end{matrix} \right] \cdot \left[ \begin{matrix} x_1^{l-1} \\ x_2^{l-1} \\ x_3^{l-1} \\ \end{matrix} \right] + \left[ \begin{matrix} b_1^l \\ b_2^l \\ b_3^l \\ \end{matrix} \right] \right) yl=δ w11lw21lw31lw12lw22lw32lw13lw23lw33l ⋅ x1l−1x2l−1x3l−1 + b1lb2lb3l
即,
y l = δ ( [ w 11 l x 1 l − 1 + w 12 l x 2 l − 1 + w 13 l x 3 l − 1 + b 1 l w 21 l x 1 l − 1 + w 22 l x 2 l − 1 + w 23 l x 3 l − 1 + b 2 l w 31 l x 1 l − 1 + w 32 l x 2 l − 1 + w 33 l x 3 l − 1 + b 3 l ] ) y^l = \delta \left( \left[ \begin{matrix} w_{11}^lx_1^{l-1} + w_{12}^lx_2^{l-1} + w_{13}^lx_3^{l-1} + b_1^l \\ w_{21}^lx_1^{l-1} + w_{22}^lx_2^{l-1} + w_{23}^lx_3^{l-1} + b_2^l \\ w_{31}^lx_1^{l-1} + w_{32}^lx_2^{l-1} + w_{33}^lx_3^{l-1} + b_3^l \\ \end{matrix} \right] \right) yl=δ w11lx1l−1+w12lx2l−1+w13lx3l−1+b1lw21lx1l−1+w22lx2l−1+w23lx3l−1+b2lw31lx1l−1+w32lx2l−1+w33lx3l−1+b3l
前向传播的一般形式:
y l = δ ( w l ⋅ x l − 1 + b l ) y^l = \delta (w^l \cdot x^{l-1} + b^l) yl=δ(wl⋅xl−1+bl)
这里的输入只有一条数据,因此输入数据表现为一维列向量。多样本输入的时候是一样的,只是输入数据变成了一个二维的矩阵,矩阵的每一列都是一个输入样本数据。
多样本输入可以表示为:
Y l = δ ( w l ⋅ X l − 1 + b l ) X l = δ ( Y l ) Y^l = \delta (w^l \cdot X^{l-1} +b^l) \\ X^l = \delta (Y^l) Yl=δ(wl⋅Xl−1+bl)Xl=δ(Yl)
1.2 梯度下降算法
梯度下降法是训练神经网络和线性分类器的一种普遍方法。斜率是函数的导数。梯度上的每个元素都会指明函数在该点处各个方向的斜率,梯度指向函数变化最快的方向。正梯度和负梯度指向变大最快的方向和变小最快的方向。
在正向传播的过程中,有一个 与期望的结果比较是否满意 的环节,在这个环节中实际的输出结果与期望的输出结果之间就会产生一个误差。为了减小这个误差,这个问题就转换为了一个优化问题。在这个优化问题中,目标函数就是损失函数(Loss function)。
L o s s = 1 2 ∑ i = 1 n ( y i − y ^ i ) 2 = 1 2 ∑ i = 1 n [ y i − ( w x i + b ) ] 2 Loss = \frac{1}{2} \sum _{i=1}^{n} (y_i - \hat{y}_{i})^2 \\ = \frac{1}{2} \sum _{i=1}^{n} [y_i - (wx_i + b)]^2 Loss=21i=1∑n(yi−y^i)2=21i=1∑n[yi−(wxi+b)]2
为了让实际的输出结果与期望的输出结果之间的误差最小,需要寻找损失函数的最小值。
1.2.1 使用迭代的方式寻找最小值
解析解:通过严格的公示推倒计算,给出的方程的精确解,任意精度下满足方程。
数值解:在一定条件下,通过某种近似计算得到的解,能够在给定的精度下满足方程。
迭代的方法寻找损失最小值 就是通过 梯度下降 + 迭代 的方式寻找数值解。
在迭代过程中,每次迭代各层节点之间的权重将不断地更新。
W ( t + 1 ) = W ( t ) − η ∂ L o s s ∂ w + α [ W ( t ) − W ( t − 1 ) ] W_{(t+1)}=W_{(t)} - \eta \frac{\partial Loss}{\partial w} + \alpha [W_{(t)} - W_{(t - 1)}] W(t+1)=W(t)−η∂w∂Loss+α[W(t)−W(t−1)]
- η ∂ L o s s ∂ w \eta \frac{\partial Loss}{\partial w} η∂w∂Loss,每次更新权重的调整量
- α [ W ( t ) − W ( t − 1 ) ] \alpha [W_{(t)} - W_{(t - 1)}] α[W(t)−W(t−1)],更新权重时的平滑项
每次迭代都会更新一次权重,之后将更新的权重与训练样本进行正向传播,如果得到的结果不满意,则进行反向传播,继续迭代。如此往复,直到得到满意的结果为止。
1.2.2 局部最小值和全局最小值
梯度下降学习法,总是沿着梯度下降的方向对权重进行调整。考虑梯度存在多个极值点,那么这些极值点中只有一个时全局最小值点,其他都是局部最小值点。
当权重调整至某个局部最小值附近的时候,由于总是沿着梯度下降的方向对权重进行调整,那么最终就会将权重调整至这个局部最小值点,并把它当作是全局最小值点了。但是实际上此时权重并不是处于全局最小值点,这样的情况并不是我们期望的。
1.2.3 算法改进
1.2.3.1 引入动量项
W ( t + 1 ) = W ( t ) − η [ ( 1 − α ) ∂ L o s s ∂ W ( t ) + α ∂ L o s s ∂ W ( t − 1 ) ] W_{(t+1)}=W_{(t)} - \eta [(1 - \alpha) \frac{\partial Loss}{\partial W_{(t)}} + \alpha \frac{\partial Loss}{\partial W_{(t-1)}}] W(t+1)=W(t)−η[(1−α)∂W(t)∂Loss+α∂W(t−1)∂Loss]
- η > 0 \eta > 0 η>0,为学习率
- 0 ≤ α < 1 0 \le \alpha < 1 0≤α<1 ,为动量因子
- 通过引入动量项,给权重调整量添加一个梯度正方向的修正,类似于物体的惯性的效果,可以一定成都解决把局部最小值当做全局最小值的问题。
1.2.3.2 变步长法
学习率 η \eta η 选的太小,会导致收敛太慢;选的太大,会导致权重调整过头,导致震荡甚至发散。可以采用变步长法进行改进:
W ( t + 1 ) = W ( t ) − η ( t ) ∂ L o s s ∂ w η ( t ) = 2 λ η ( t − 1 ) λ = s g n [ ∂ L o s s ∂ w ( t ) ⋅ ∂ L o s s ∂ w ( t − 1 ) ] W_{(t+1)}=W_{(t)} - \eta (t) \frac{\partial Loss}{\partial w} \\ \eta (t) = 2^{\lambda} \eta (t - 1) \\ \lambda = sgn[\frac{\partial Loss}{\partial w_{(t)}} \cdot \frac{\partial Loss}{\partial w_{(t - 1)}}] W(t+1)=W(t)−η(t)∂w∂Lossη(t)=2λη(t−1)λ=sgn[∂w(t)∂Loss⋅∂w(t−1)∂Loss]
- 上面第三个式子根据相邻两次计算的梯度乘积来计算符号函数,可以实时调整学习率。当连续两次迭代的梯度的方向相同,说明下降太慢,这时通过上面第二个式子使步长加倍;当连续两次迭代的梯度的方向相反,说明下降过头,这时通过上面第二个式子使步长减半。
- 上面的第二个式子里面的 2,可以根据实际需要,改成其他值,以此来控制步长的变化快慢。
1.3 反向传播
1.3.1 求梯度矩阵
假设函数 f : R m × n → R f: R^{m \times n} \rightarrow R f:Rm×n→R 可以把输入矩阵映射为一个实数,那么函数 f f f 的梯度定义为:
∇ A f ( A ) = [ ∂ f ( A ) ∂ A 11 ∂ f ( A ) ∂ A 12 … ∂ f ( A ) ∂ A 1 n ∂ f ( A ) ∂ A 21 ∂ f ( A ) ∂ A 22 … ∂ f ( A ) ∂ A 2 n ⋮ ⋮ ⋱ ⋮ ∂ f ( A ) ∂ A m 1 ∂ f ( A ) ∂ A m 2 … ∂ f ( A ) ∂ A m n ] \nabla _A f(A) = \left[ \begin{matrix} \frac{\partial f(A)}{\partial A_{11}} & \frac{\partial f(A)}{\partial A_{12}} & \dotsc & \frac{\partial f(A)}{\partial A_{1n}} \\ \frac{\partial f(A)}{\partial A_{21}} & \frac{\partial f(A)}{\partial A_{22}} & \dotsc & \frac{\partial f(A)}{\partial A_{2n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial f(A)}{\partial A_{m1}} & \frac{\partial f(A)}{\partial A_{m2}} & \dotsc & \frac{\partial f(A)}{\partial A_{mn}} \\ \end{matrix} \right] ∇Af(A)= ∂A11∂f(A)∂A21∂f(A)⋮∂Am1∂f(A)∂A12∂f(A)∂A22∂f(A)⋮∂Am2∂f(A)……⋱…∂A1n∂f(A)∂A2n∂f(A)⋮∂Amn∂f(A)
即
( ∇ A f ( A ) ) i j = ∂ f ( A ) ∂ A i j (\nabla_A f(A))_{ij} = \frac{\partial f(A)}{\partial A_{ij}} (∇Af(A))ij=∂Aij∂f(A)
同样地,对于输入向量的函数 f : R n × 1 → R f: R^{n \times 1} \rightarrow R f:Rn×1→R,那么:
∇ x f ( x ) = [ ∂ f ( x ) ∂ x 1 ∂ f ( x ) ∂ x 2 ⋮ ∂ f ( x ) ∂ x n ] \nabla_x f(x) = \left[ \begin{matrix} \frac{\partial f(x)}{\partial x_1} \\ \frac{\partial f(x)}{\partial x_2} \\ \vdots \\ \frac{\partial f(x)}{\partial x_n} \\ \end{matrix} \right] ∇xf(x)= ∂x1∂f(x)∂x2∂f(x)⋮∂xn∂f(x)
根据上面的矩阵和向量的梯度矩阵的定义,可以得到:
∇ x ( f ( x ) + g ( x ) ) = ∇ x f ( x ) + ∇ x g ( x ) ∇ x ( t f ( x ) ) = t ∇ x f ( x ) , t ∈ R \nabla_x (f(x) + g(x)) = \nabla_x f(x) + \nabla_x g(x) \\ \nabla_x (tf(x)) = t\nabla_x f(x), t \in R ∇x(f(x)+g(x))=∇xf(x)+∇xg(x)∇x(tf(x))=t∇xf(x),t∈R