反向传播 (BP) 算法深入理解——神经网络偏导数的计算

/ Deep Learning / 没有评论 / 496浏览

文章导语

反向传播算法(Back Propagation),在 1970 年就被提出, 1986 年的 David Rumelhart, Geoffrey Hinton, and Ronald Williams 提出的论文才得到重视, 可以解决神经网络中的学习问题

如果想了解神经网络算法,请查看神经网络 (NN) 算法入门简介——深度学习 (DL) 理论基础

解决的问题

Backpropagation 核心解决的问题是针对 cost 函数 C,计算偏导数

$$\frac{\partial C}{\partial w}, \qquad \frac{\partial C}{\partial b}$$

相关概念

二次损失函数

$$\overline{C} = \frac{1}{2n} \sum_{x} \parallel y(x) - a^L \parallel ^2$$

L: 神经网络的层数
求和是对于所有单个的训练实例 x 加起来, 然后求平均 Cost

假设

$$C = \frac{1}{2} \parallel y - a^L \parallel ^2$$

那么

$$\overline{C} = \frac{1}{n} \sum_{x} C_x$$

对于 backpropagation, $\frac{\partial C}{\partial w}$ 与 $\frac{\partial C}{\partial b}$ 的计算是通过单个实例 x 完成的,Cost 可以写成神经网络输出的函数

$$C = \frac{1}{2} \parallel y -a^L \parallel^2 = \frac{1}{2}\sum_{j} (y_j - a_{j}^L)^2$$

由链式法则知

$$\frac{\partial C}{\partial w_{ij}^l} = \frac{\partial C}{\partial z_i^l} \frac{\partial z_i^l}{\partial w_{ij}^l}$$

又因为 $z_i^l = w_{ij}^l a_i^{l-1} + b_i^l$,所以

$$\frac{\partial C}{\partial w_{ij}} = \begin{cases} a_j^{l-1}, & l > 1 \\ x_j, & l = 1 \end{cases}$$

元素分别相乘

英文名:The Hadamard product

符号:$\odot$

$$s \odot t = \begin{bmatrix} 1 \\ 2 \end{bmatrix} = \begin{bmatrix} 3 \\ 4 \end{bmatrix} = \begin{bmatrix} 1*3 \\ 2*4 \end{bmatrix} = \begin{bmatrix} 3 \\ 8 \end{bmatrix}$$

四个关键公式

定义一个变量 $\delta_j^l$, 表示在第 $l$ 层的第 j 个神经元上的误差。

该神经元的输出为 $\sigma(z_j^l)$,假设有一个微变化 $\Delta z_j^l$,使得输出变为 $\sigma(z_j^l + \Delta z_j^l)$

从而使得 Cost 的变化

$$\Delta C = \frac{\partial C}{\partial z_j^l}\Delta z_j^l$$

假设可以找到一个 $\Delta z_j^l$ 来降低 cost。显然,

所以 $\frac{\partial C}{\partial z_j^l}$ 可以作为误差的一个衡量,于是我们定义

$$\delta_j^l = \frac{\partial C}{\partial z_j^l}$$

输出层的误差

$$\delta_j^L = \frac{\partial C}{\partial a_j^L} \sigma^{'}(z_j^L)$$

$\frac{\partial C}{\partial a_j^L}$ 是衡量 Cost 对于第 j 个activation 输出的变化
$\sigma^{'}(z_j^L)$ 是衡量 activation 方程对于 $z_j^L$ 的变化

转化为矩阵的表达方式

$$\delta^L = \bigtriangledown_aC \odot \sigma^{'}(z^L)\tag{BP1}$$

$\bigtriangledown_aC$ 是 C 在输出层 activation 上的变化率

对于上面二次 Cost 方程

$$\delta^L = (y - a^L) \odot \sigma^{'}(z^L)$$

层间误差

第 $l$ 层的误差

$$\delta^l = \left [ (w^{l+1})^T\delta^{l+1} \right ] \odot \sigma^{'}(z^l)\tag{BP2}$$

可证明(证明略)

$$\frac{\partial C}{\partial b_j^l} = \delta_j^l\tag{BP3}$$

简化为

$$\frac{\partial C}{\partial b} = \delta$$

$$\frac{\partial C}{\partial w_{ij}^l} = a_i^{l-1}\delta_j^l\tag{BP4}$$

简化为

$$\frac{\partial C}{\partial w} = a_{in}\delta_{out}$$

显然,如果 $a_j^l$ 比较小,则得到的 $\frac{\partial C}{\partial w}$ 也比较小,从而导致使用梯度下降算法更新缓慢。

查看 激活函数与损失函数深入理解——优化神经网络的学习效率 了解如何提高学习效率

BP 算法

Backpropagation 被使用在多层向前神经网络上

算法描述

通过迭代来训练模型

对比经过神经网络后输入层预测值 (predicted value) 与真实值 (target value) 之间的差异,反方向(从输出层=>隐藏层=>输入层)以最小化误差 (error) 来更新每个连接的权重(weight) 和 偏向 bais

算法步骤

随机初始化在 -1 到 1 之间,或者 -0.5 到 0.5 之间,每个单元有一个偏向

对于每一个训练实例 X,经过每层向前传送

$$a_j = \sigma \left ( \sum_{i} w_{ij}a_i + b_j \right )$$

输出层

$$\delta_j = a_j(1-a_j)(y - a_j)$$

隐藏层

$$\delta_j = a_j(1-a_j)\sum_{k} w_{jk}\delta_k$$

权重更新

$$w_{ij} = w_{ij} - \eta \Delta w_{ij} =w_{ij} - \eta a_i \delta_j$$

偏向更新

$$b_j = b_j - \eta \Delta b_{j} = b_j - \eta \delta_j$$

终止条件