文章目录
后向传播(Backpropagation)
后向传播是什么?
在神经网络中,后向传播是指通过比较输出结果和真实标签,计算损失函数对每个权重和偏置的偏导数,并将其传递回网络中的每一层,从而更新权重和偏置的过程。通过反向传播误差信号来优化模型参数,使得模型的预测结果更加准确。
掌握后向传播的基本原理和步骤,对于理解神经网络的训练过程具有重要的意义。
后向传播步骤
后向传播的步骤可以简单地概括为以下几步:
- 计算输出层的误差信号
- 传递误差信号到隐藏层
- 计算隐藏层的误差信号
- 计算权重和偏置的偏导数
- 更新权重和偏置
1. 计算输出层的误差信号
假设我们的神经网络有 K K K个输出节点,用 y k y_k yk表示第 k k k个输出节点的输出值, t k t_k tk表示第 k k k个输出节点的真实值,则损失函数可以表示为:
L = 1 2 ∑ k = 1 K ( y k − t k ) 2 L=\frac{1}{2}\sum_{k=1}^K(y_k-t_k)^2 L=21k=1∑K(yk−tk)2
损失函数中除以2是为了方便计算导数。在实际应用中,我们往往使用梯度下降等基于梯度的方法最小化损失函数。对该损失函数求导数得到的结果中会有一个常数因子2,如果不在损失函数中除以2,会导致在梯度下降的过程中,每一次更新参数的步长过大,可能无法找到全局最优解。因此在实际应用中,将损失函数除以2后,可以避免过大的参数更新,从而更稳定地达到全局最优解。
我们需要计算每个输出节点的误差信号,即 ∂ L ∂ y k \frac{\partial L}{\partial y_k} ∂yk∂L。根据链式法则,可以得到:
∂ L ∂ y k = ( y k − t k ) ⋅ σ ′ ( z k ) \frac{\partial L}{\partial y_k}=(y_k-t_k)\cdot\sigma'(z_k) ∂yk∂L=(yk−tk)⋅σ′(zk)
其中, z k z_k zk表示第 k k k个输出节点的带权输入, σ ′ \sigma' σ′表示激活函数的导数。
- K K K:输出节点的数量
- y k y_k yk:第 k k k个输出节点的输出值
- t k t_k tk:第 k k k个输出节点的真实值
- L L L:损失函数
- ∂ L ∂ y k \frac{\partial L}{\partial y_k} ∂yk∂L:第 k k k个输出节点的误差信号
- σ ( z k ) \sigma(z_k) σ(zk):第 k k k个输出节点的激活函数
- σ ′ ( z k ) \sigma'(z_k) σ′(zk):第 k k k个输出节点激活函数的导数
- z k z_k zk:第 k k k个输出节点的带权输入
其中,误差信号 ∂ L ∂ y k \frac{\partial L}{\partial y_k} ∂yk∂L表示损失函数 L L L对第 k k k个输出节点输出值 y k y_k yk的偏导数,可以通过链式法则和输出节点的误差项来计算。误差项包括输入加权和 z k z_k zk的导数(即激活函数的导数)和输出误差 ( y k − t k ) (y_k-t_k) (yk−tk)。
2. 传递误差信号到隐藏层
对于隐藏层的每个节点 j j j,我们需要计算其误差信号 ∂ L ∂ z j \frac{\partial L}{\partial z_j} ∂zj∂L。根据链式法则,可以得到:
∂ L ∂ z j = ∑ k = 1 K ∂ L ∂ y k ⋅ ∂ y k ∂ z j \frac{\partial L}{\partial z_j}=\sum_{k=1}^K\frac{\partial L}{\partial y_k}\cdot\frac{\partial y_k}{\partial z_j} ∂zj∂L=k=1∑K∂yk∂L⋅∂zj∂yk
其中, ∂ y k ∂ z j \frac{\partial y_k}{\partial z_j} ∂zj∂yk可以表示为:
∂ y k ∂ z j = ∂ ∂ z j σ ( z k ⋅ w k j + b k ) = σ ′ ( z j ) ⋅ w k j \frac{\partial y_k}{\partial z_j}=\frac{\partial}{\partial z_j}\sigma(z_k\cdot w_{kj}+b_k)=\sigma'(z_j)\cdot w_{kj} ∂zj∂yk=∂zj∂σ(zk⋅wkj+bk)=σ′(zj)⋅wkj
- ∂ L ∂ z j \frac{\partial L}{\partial z_j} ∂zj∂L:表示误差信号,即损失函数 L L L 对隐藏层第 j j j 个神经元的加权输入 z j z_j zj 的偏导数;
- K K K:表示输出层的神经元个数;
- ∂ L ∂ y k \frac{\partial L}{\partial y_k} ∂yk∂L:表示损失函数 L L L 对输出层第 k k k 个神经元的输出值 y k y_k yk 的偏导数;
- ∂ y k ∂ z j \frac{\partial y_k}{\partial z_j} ∂zj∂yk:表示输出层第 k k k 个神经元的输出值 y k y_k yk 对隐藏层第 j j j 个神经元的加权输入 z j z_j zj 的偏导数;
- w k j w_{kj} wkj:表示输出层连接到隐藏层第 j j j 个神经元的权重;
- b k b_k bk:表示输出层第 k k k 个神经元的偏置;
- σ \sigma σ:表示激活函数;
- σ ′ ( z j ) \sigma'(z_j) σ′(zj):表示激活函数在 z j z_j zj 处的导数。
3. 计算隐藏层的误差信号
对于隐藏层的每个节点 j j j,我们还需要计算其误差信号 ∂ L ∂ a j \frac{\partial L}{\partial a_j} ∂aj∂L,其中 a j a_j aj表示第 j j j个隐藏节点的输出值。根据链式法则,可以得到:
∂ L ∂ a j = ∂ L ∂ z j ⋅ ∂ z j ∂ a j \frac{\partial L}{\partial a_j}=\frac{\partial L}{\partial z_j}\cdot\frac{\partial z_j}{\partial a_j} ∂aj∂L=∂zj∂L⋅∂aj∂zj
其中,
∂ z j ∂ a j = ∂ ∂ a j ∑ i = 1 m w j i ⋅ x i = b j \frac{\partial z_j}{\partial a_j}=\frac{\partial}{\partial a_j}\sum_{i=1}^m w_{ji}\cdot x_i=b_j ∂aj∂zj=∂aj∂i=1∑mwji⋅xi=bj
- L L L:损失函数
- a j a_j aj:第 j j j个隐藏节点的输出值
- z j z_j zj:第 j j j个隐藏节点的加权输入
- w j i w_{ji} wji:连接输入层第 i i i个节点和隐藏层第 j j j个节点的权重
- x i x_i xi:输入样本的第 i i i个分量
- b j b_j bj:第 j j j个隐藏节点的偏置
- ∂ L ∂ a j \frac{\partial L}{\partial a_j} ∂aj∂L:损失函数 L L L对第 j j j个隐藏节点输出值 a j a_j aj的偏导数,即第 j j j个隐藏节点的误差信号
- ∂ L ∂ z j \frac{\partial L}{\partial z_j} ∂zj∂L:损失函数 L L L对第 j j j个隐藏节点加权输入 z j z_j zj的偏导数
- ∂ z j ∂ a j \frac{\partial z_j}{\partial a_j} ∂aj∂zj:第 j j j个隐藏节点的加权输入 z j z_j zj对输出值 a j a_j aj的偏导数
4. 计算权重和偏置的偏导数
对于输出层的权重和偏置,偏导数可以使用链式法则计算:
∂
L
∂
w
k
i
=
∂
L
∂
y
k
⋅
∂
y
k
∂
z
k
⋅
∂
z
k
∂
w
k
j
=
y
i
⋅
(
y
k
−
t
k
)
⋅
σ
′
(
z
k
)
\frac{\partial L}{\partial w_{ki}}=\frac{\partial L}{\partial y_k}\cdot\frac{\partial y_k}{\partial z_k}\cdot\frac{\partial z_k}{\partial w_{kj}}=y_i\cdot(y_k - t_k)\cdot\sigma'(z_k)
∂wki∂L=∂yk∂L⋅∂zk∂yk⋅∂wkj∂zk=yi⋅(yk−tk)⋅σ′(zk)
∂ L ∂ b k = ∂ L ∂ y k ⋅ ∂ y k ∂ z k ⋅ ∂ z k ∂ b k = ( y k − t k ) ⋅ σ ′ ( z k ) \frac{\partial L}{\partial b_k}=\frac{\partial L}{\partial y_k}\cdot\frac{\partial y_k}{\partial z_k}\cdot\frac{\partial z_k}{\partial b_k}=(y_k - t_k)\cdot\sigma'(z_k) ∂bk∂L=∂yk∂L⋅∂zk∂yk⋅∂bk∂zk=(yk−tk)⋅σ′(zk)
对于隐藏层的权重和偏置,偏导数可以使用相似的方式进行计算:
∂
L
∂
w
j
i
=
∂
L
∂
z
j
⋅
∂
z
j
∂
w
j
i
=
x
i
⋅
∂
L
∂
z
j
\frac{\partial L}{\partial w_{ji}}=\frac{\partial L}{\partial z_j}\cdot\frac{\partial z_j}{\partial w_{ji}}=x_i\cdot\frac{\partial L}{\partial z_j}
∂wji∂L=∂zj∂L⋅∂wji∂zj=xi⋅∂zj∂L
∂ L ∂ b j = ∂ L ∂ z j ⋅ ∂ z j ∂ b j = ∂ L ∂ z j \frac{\partial L}{\partial b_j}=\frac{\partial L}{\partial z_j}\cdot\frac{\partial z_j}{\partial b_j}=\frac{\partial L}{\partial z_j} ∂bj∂L=∂zj∂L⋅∂bj∂zj=∂zj∂L
- L L L:损失函数
- y k y_k yk:输出层第 k k k个节点的输出值
- t k t_k tk:对于当前输入样本,输出层第 k k k个节点应该输出的目标值
- z k z_k zk:输出层第 k k k个节点的加权输入
- σ ( z k ) \sigma(z_k) σ(zk):激活函数,将加权输入 z k z_k zk映射为输出值 y k y_k yk的非线性函数
- σ ′ ( z k ) \sigma'(z_k) σ′(zk):激活函数的导数,即 σ ( z ) \sigma(z) σ(z)对 z z z的偏导数
- w k j w_{kj} wkj:连接隐藏层第 j j j个节点和输出层第 k k k个节点的权重
- x i x_i xi:输入样本的第 i i i个分量
- w j i w_{ji} wji:连接输入层第 i i i个节点和隐藏层第 j j j个节点的权重
- a j a_j aj:第 j j j个隐藏节点的输出值
- z j z_j zj:第 j j j个隐藏节点的加权输入
- b j b_j bj:第 j j j个隐藏节点的偏置
- b k b_k bk:输出层第k个节点的偏置
- k k k:输出层节点的索引
- j j j:隐藏层节点的索引
- i i i:输入层节点的索引
- ∂ L ∂ w k i \frac{\partial L}{\partial w_{ki}} ∂wki∂L:损失函数 L L L对连接隐藏层第 i i i个节点和输出层第 k k k个节点的权重 w k i w_{ki} wki的偏导数
- ∂ L ∂ b k \frac{\partial L}{\partial b_k} ∂bk∂L:损失函数 L L L对输出层第 k k k个节点的偏置 b k b_k bk的偏导数
- ∂ L ∂ w j i \frac{\partial L}{\partial w_{ji}} ∂wji∂L:损失函数 L L L对连接输入层第 i i i个节点和隐藏层第 j j j个节点的权重 w j i w_{ji} wji的偏导数
- ∂ L ∂ b j \frac{\partial L}{\partial b_j} ∂bj∂L:损失函数 L L L对隐藏层第 j j j个节点的偏置 b j b_j bj的偏导数
5.更新权重和偏置
最后,根据梯度下降法,我们可以使用下面的公式来更新权重和偏置:
w
k
j
←
w
k
j
−
η
∂
L
∂
w
k
j
w_{kj} \leftarrow w_{kj}-\eta\frac{\partial L}{\partial w_{kj}}
wkj←wkj−η∂wkj∂L
b k ← b k − η ∂ L ∂ b k b_k \leftarrow b_k-\eta\frac{\partial L}{\partial b_k} bk←bk−η∂bk∂L
w j i ← w j i − η ∂ L ∂ w j i w_{ji} \leftarrow w_{ji}-\eta\frac{\partial L}{\partial w_{ji}} wji←wji−η∂wji∂L
b j ← b j − η ∂ L ∂ b j b_j \leftarrow b_j-\eta\frac{\partial L}{\partial b_j} bj←bj−η∂bj∂L
其中 η \eta η是学习率,控制每次更新的步长。
- L L L:损失函数
- η \eta η:学习率,控制梯度下降更新权重的步长大小
- ∂ L ∂ w k j \frac{\partial L}{\partial w_{kj}} ∂wkj∂L:损失函数 L L L对连接隐藏层第 j j j个节点和输出层第 k k k个节点的权重 w k j w_{kj} wkj的偏导数
- w k j w_{kj} wkj:连接隐藏层第 j j j个节点和输出层第 k k k个节点的权重
- ∂ L ∂ b k \frac{\partial L}{\partial b_k} ∂bk∂L:损失函数 L L L对输出层第 k k k个节点的偏置 b k b_k bk的偏导数
- b k b_k bk:输出层第 k k k个节点的偏置
- ∂ L ∂ w j i \frac{\partial L}{\partial w_{ji}} ∂wji∂L:损失函数 L L L对连接输入层第 i i i个节点和隐藏层第 j j j个节点的权重 w j i w_{ji} wji的偏导数
- w j i w_{ji} wji:连接输入层第 i i i个节点和隐藏层第 j j j个节点的权重
- ∂ L ∂ b j \frac{\partial L}{\partial b_j} ∂bj∂L:损失函数 L L L对隐藏层第 j j j个节点的偏置 b j b_j bj的偏导数
- b j b_j bj:隐藏层第 j j j个节点的偏置
- ← \leftarrow ←:数学符号,表示赋值操作,将等号左侧的值赋给等号右侧的变量
总结
这份后向传播的入门教程主要包括以下内容:
- 后向传播的目的是通过反向传播误差信号来优化神经网络的参数。
- 后向传播的第一步是计算输出层的误差信号,具体计算方法是使用损失函数的导数,结合输出层的激活函数的导数。
- 后向传播的第二步是传递误差信号,将误差信号沿着神经网络的反向传播,计算每一层的误差信号,具体计算方法是使用权重矩阵的转置,结合下一层的误差信号和当前层的激活函数的导数。
- 通过计算每一层的误差信号,我们可以使用梯度下降等优化算法来更新神经网络的参数,以减小误差信号,提高模型的准确性。
当然,这只是后向传播的基础,实际应用中还需要考虑很多细节和优化方法,例如使用批量归一化、随机失活等技巧来提高模型的泛化能力,使用动量优化器、自适应学习率等方法来优化参数更新过程,等等。