梯度下降和反向传播
梯度下降(GD, Gradient Descent)和反向传播(BP, Back Propagation)是理解神经网络学习原理的核心,本文试图从数学原理、实例来分析梯度下降和反向传播在神经网络中是如何工作的
数学原理
为了理解梯度下降算法和反向传播算法的工作原理,需要理解以下数学知识
- 方向导数和梯度
- 链式法则
方向导数
梯度在数学中的概念,源于方向导数。在一元函数中,我们用导数来描述和分析函数的变化趋势,二元函数或多元函数我们用偏导数来分析函数变化情况。但是一旦变成多元,偏导数只能反应在坐标轴方向的变化情况,如果想要知道函数在任意方向上的变化情况,偏导数是无法做到的。因此引入了方向导数的概念
\begin{equation}
\frac{f(x{0}+t\cos{\alpha}, y{0}+t\cos{\beta}) - f(x{0}, y{0})}{t}
\end{equation}
当
- 如果函数在某一点可微,函数在该点的任何方向的方向导数存在
梯度
函数在很多方向上都有方向导数,那么在哪个方向上变化率最大呢?
如果函数在点 $P{0}
\begin{equation}
\frac{\partial f}{\partial l} = \nabla f\left ( x{0}, y{0} \right ) \cdot e{l} = \left | \nabla f\left ( x{0}, y_{0} \right ) \right |cos\theta
\end{equation}
其中 $\nabla f\left ( x{0},y{0} \right )
梯度的表达式为
本质上是函数的各个偏导数合成的向量
链式法则
微积分中的链式法则用于计算复合函数的导数。设
扩展到向量,假设
\begin{equation}
\frac{\partial z}{\partial x{i}} = \sum{j}\frac{\partial z}{\partial y{i}}\frac{\partial y{i}}{\partial x_{i}}
\end{equation}
使用向量写法,可等价为
\begin{equation}
\nabla{x}{z} = \left(\frac{\partial \boldsymbol{y}}{\partial \boldsymbol{x}}\right)^{T}\nabla{y}{z}
\end{equation}
其中
梯度下降
梯度下降属于神经网络中优化器的一种,另外还有AdaGrad、RMSProp、Adam等。由于梯度永远指向函数增长最快的方向,那么函数下降最快的方向就是负梯度
设
其中
在每次迭代时
反向传播
反向传播这个术语经常被误认为只是用于神经网络的整个学习算法中,实际上反向传播算法只是用于计算梯度的方法,它可以用来计算任何函数的导数。由于按照梯度的定义直接求解是非常复杂的,反向传播能够使用非常简单的计算步骤来求解梯度
链式法则求复合函数的导数
反向传播的核心在于运用链式法则,以下使用函数
1 | # input value |
对于输入x=-2, y=5, z=-4
先进行前向传播,依次向后计算,最后得出函数值为-12,前向传播的方向为从输入到输出(绿色)。反向传播(红色)是从输出开始,根据链式法则递归的向前计算梯度,梯度在链路中回流。最终计算得到梯度[dfdx, dfdy, dfdz]
为[-4,-4,3]
,如图所示
反向传播的直观理解——门单元间梯度的传递
任何可微的函数都可以看做若干个门单元的组合形式,例如加法门、乘法门、除法门、取最大值门等
在整个计算图过程中,每个单元门都会得到一些输入,并计算两个东西:
- 这个门的输出
- 其输出值关于输入值的局部梯度
在反向传播过程中,门单元会获得整个网络输出值在自己的输出值上的梯度
在梯度的回流中,不同的门单元有不同的作用。下图展示了一个反向传播的例子,加法操作将梯度相等地分发给它的输入。取最大操作将梯度路由给更大的输入。乘法门拿取输入激活数据,对它们进行交换,然后乘以梯度
神经网络中的反向传播
在神经网络中,反向传播是对权重和偏置变化影响代价函数
\begin{equation}
\delta{j}^{l} = \frac{\partial C}{\partial z{j}^{l}}
\end{equation}
其中
反向传播的四个基本方程
定义
\begin{equation}
\delta{j}^{L} = \frac{\partial C}{\partial z{j}^{L}} \
= \frac{\partial C}{\partial a{j}^{L}}\sigma’(z{j}^{L})
\end{equation}
其向量形式为公式(BP1)
使用下一层误差
其中
代价函数关于网络中任意偏置的改变率为
\begin{equation}
\frac{\partial C}{\partial b{j}^{l}} = \delta{j}^{l}
\end{equation}
这表示误差就是偏置的偏导数,向量形式为
代价函数关于权重的改变率为
\begin{equation}
\frac{\partial C}{\partial \omega{jk}^{l}} = a{k}^{l-1}\delta_{j}^{l}
\end{equation}
向量形式为
显示的描述反向传播的步骤
- 输入
:为输入层设置对应的激活值 - 前向传播:对每个层,计算相应的
和 - 输出层误差
:通过BP1计算 - 反向传播误差:通过BP2计算
- 更新
:通过BP3和BP4计算和
实例
以下图网络结构举例来说明反向传播算法是如何工作的
初始化参数
网络中由输入层、1层隐藏层和输出层共3层构成,按照以下参数初始化网络
1 | # 初始化输入输出 |
正向传播
1 | # 计算隐藏层神经元 h1 的输入加权和 |
正向传播结束后的输出结果为[0.7989476413779711, 0.8390480283342561]
,但是希望的输出是[0.01, 0.99]
,因此利用反向传播更新权重和偏置,然后重新计算输出
反向传播
代价函数使用
\begin{equation}
C = \frac{1}{2}\sum{j}\left(y{j} - a_{j}^{l} \right)
\end{equation}
其导数为
\begin{equation}
\frac{\partial C}{\partial a{j}^{l}} = a{j} - y_{j}
\end{equation}
根据BP1,输出层神经元的误差
1 | # 计算输出层神经元 o1 的误差 |
根据BP2,隐藏层神经元的误差
\begin{equation}
\delta{j}^{2} = ((\boldsymbol{\omega}^{3})^{T}\boldsymbol{\delta}^{3}) \odot \sigma’(z{j}^{2})
\end{equation}
在计算时只需要计算与该神经元相关的连接,例如计算隐藏层神经元h1
时,只需要计算权重w5
和w7
,设
\begin{equation}
\delta{1}^{2} = (\omega{11}^{3}\delta{1}^{3} + \omega{12}^{3}\delta{1}^{3})(a{1}^{2}*(1-a_{1}^{2}))
\end{equation}
1 | # 计算隐藏层神经元 h1 的误差 |
根据BP4可计算某个权重的偏导数,例如w5
,其偏导数为
\begin{equation}
\frac{\partial C}{\partial \omega{11}^{3}} = a{1}^{2}\delta_{1}^{3}
\end{equation}
1 | # 计算权重 w5 的偏导数 |