$$
\definecolor{input}{RGB}{66, 133, 244}
\definecolor{output}{RGB}{219, 68, 55}
\definecolor{dinput}{RGB}{244, 180, 0}
\definecolor{doutput}{RGB}{15, 157, 88}
\definecolor{dweight}{RGB}{102, 0, 255}
$$
反向传播算法
反向传播算法对于快速训练大型神经网络至关重要。本文将介绍算法的工作原理。
请向下滚动...
简单的神经网络
右侧显示了一个神经网络,其中包含一个输入节点、一个输出节点以及两个隐藏层(分别有两个节点)。
相邻层中的节点使用权重 \(w_{ij}\)(网络参数)连接。
激活函数
每个节点都有一个总输入 \(\color{input}x\)、一个激活函数 \(f(\color{input}x\color{black})\)和一个输出 \(\color{output}y\color{black}=f(\color{input}x\color{black})\)。 \(f(\color{input}x\color{black})\) 必须是非线性函数,否则神经网络将只能学习线性模型。
常用的激活函数是 S 型函数: \(f(\color{input}x\color{black}) = \frac{1}{1+e^{-\color{input}x}}\)。
错误函数
目标是自动从数据中学习网络的权重,以使预测的输出 \(\color{output}y_{output}\)接近所有输入的目标 \(\color{output}y_{target}\) 。 \(\color{input}x_{input}\)
为了衡量目标的完成程度,我们使用误差函数 \(E\)。
常用的错误函数是 \(E(\color{output}y_{output}\color{black},\color{output}y_{target}\color{black}) = \frac{1}{2}(\color{output}y_{output}\color{black} - \color{output}y_{target}\color{black})^2 \)。
正向传播
首先,我们以输入示例为例 \((\color{input}x_{input}\color{black},\color{output}y_{target}\color{black})\) 并更新网络的输入层。
为保持一致,我们认为输入与任何其他节点类似,但没有激活函数,因此其输出等于其输入,即 \( \color{output}y_1 \color{black} = \color{input} x_{input} \)。
正向传播
现在,我们更新第一个隐藏层。我们会获取上一层中节点的输出 \(\color{output}y\) ,并使用权重来计算下一层中节点的输入 \(\color{input}x\) 。
$$ \color{input} x_j \color{black} = $$$$ \sum_{i\in in(j)} w_{ij}\color{output} y_i\color{black} +b_j$$
正向传播
然后,更新第一个隐藏层中节点的输出。
为此,我们使用激活函数 \( f(x) \)。$$ \color{output} y \color{black} = f(\color{input} x \color{black})$$
正向传播
根据这两个公式,我们针对网络的剩余部分进行传播,并获取网络的最终输出。$$ \color{output} y \color{black} = f(\color{input} x \color{black})$$
$$ \color{input} x_j \color{black} = $$$$ \sum_{i\in in(j)} w_{ij}\color{output} y_i \color{black} + b_j$$
求导数
在针对特定示例将预测输出与理想输出进行比较后,反向传播算法会决定更新网络的每个权重的大小。为此,我们需要计算误差相对于各个权重的变化 \(\color{dweight}\frac{dE}{dw_{ij}}\)。
获得误差导数后,我们可以使用一个简单的更新规则来更新权重:
$$w_{ij} = w_{ij} - \alpha \color{dweight}\frac{dE}{dw_{ij}}$$
其中 \(\alpha\) 是一个正数,称为学习速率,我们需要根据经验对其进行微调。
[注意] 更新规则非常简单:如果权重在权重增加时下降 (\(\color{dweight}\frac{dE}{dw_{ij}}\color{black} < 0\)),则增加权重;否则,如果错误在权重增加 (\(\color{dweight}\frac{dE}{dw_{ij}} \color{black} > 0\)) 时增加,则降低权重。
其他导数
为帮助计算 \(\color{dweight}\frac{dE}{dw_{ij}}\),我们还为每个节点另外存储了两个导数:误差随以下因素的变化情况:
- 节点的总输入值 \(\color{dinput}\frac{dE}{dx}\)
- 节点的输出 \(\color{doutput}\frac{dE}{dy}\)。
反向传播
让我们开始反向传播误差导数。
由于我们有这个特定输入样本的预测输出,因此我们可以计算误差随输出的变化情况。鉴于我们的错误函数, \(E = \frac{1}{2}(\color{output}y_{output}\color{black} - \color{output}y_{target}\color{black})^2\) :$$ \color{doutput} \frac{\partial E}{\partial y_{output}} \color{black} = \color{output} y_{output} \color{black} - \color{output} y_{target}$$
反向传播
现在, \(\color{doutput} \frac{dE}{dy}\) 我们可以 \(\color{dinput}\frac{dE}{dx}\) 使用链式规则了。
$$\color{dinput} \frac{\partial E}{\partial x} \color{black} = \frac{dy}{dx}\color{doutput}\frac{\partial E}{\partial y} \color{black} = \frac{d}{dx}f(\color{input}x\color{black})\color{doutput}\frac{\partial E}{\partial y}$$
其中, \(\frac{d}{dx}f(\color{input}x\color{black}) = f(\color{input}x\color{black})(1 - f(\color{input}x\color{black}))\) \(f(\color{input}x\color{black})\) 为 S 型激活函数。
反向传播
一旦我们根据节点的总输入获得误差导数,就可以得出相对于进入该节点的权重的误差导数。$$\color{dweight} \frac{\partial E}{\partial w_{ij}} \color{black} = \frac{\partial x_j}{\partial w_{ij}} \color{dinput}\frac{\partial E}{\partial x_j} \color{black} = \color{output}y_i \color{dinput} \frac{\partial E}{\partial x_j}$$
反向传播
此外,借助链规则,我们还可以从上一层 \(\frac{dE}{dy}\) 。我们已经创建了一个完整的圆圈。
$$ \color{doutput} \frac{\partial E}{\partial y_i} \color{black} = \sum_{j\in out(i)} \frac{\partial x_j}{\partial y_i} \color{dinput} \frac{\partial E}{\partial x_j} \color{black} = \sum_{j\in out(i)} w_{ij} \color{dinput} \frac{\partial E}{\partial x_j}$$
反向传播
剩下的就要重复前面的三个公式,直到我们计算完所有误差导数为止。