2--前向传播和反向传播

2.1 前向传播

        前向传播(forward propagation或forward pass)指的是:按顺序(从输入层到输出层)计算和存储神经网络中每层的结果。假设输入样本是 x∈R(d), 并且我们的隐藏层不包括偏置项。 这里的中间变量是:

\mathbf{z}= \mathbf{W}^{(1)} \mathbf{x},

        其中W(1)∈R(h×d)是隐藏层的权重参数。 将中间变量z∈R(h)通过激活函数ϕ后, 我们得到长度为h的隐藏激活向量:

\mathbf{h}= \phi (\mathbf{z}).

隐藏变量h也是一个中间变量。 假设输出层的参数只有权重W(2)∈R(q×h),我们可以得到输出层变量,它是一个长度为q的向量: 

\mathbf{o}= \mathbf{W}^{(2)} \mathbf{h}.

        假设损失函数为l,样本标签为y,我们可以计算单个数据样本的损失项,

L = l(\mathbf{o}, y).

        根据L2正则化的定义,给定超参数λ,正则化项为 :

s = \frac{\lambda}{2} \left(\|\mathbf{W}^{(1)}\|_F^2 + \|\mathbf{W}^{(2)}\|_F^2\right),

        其中矩阵的Frobenius范数是将矩阵展平为向量后应用的L2范数。 最后,模型在给定数据样本上的正则化损失为:

J = L + s.

        根据上述描述得到下面的计算图( 其中正方形表示变量,圆圈表示操作符):

 

2.2 反向传播

        反向传播(backward propagation或backpropagation)指的是计算神经网络参数梯度的方法。该方法根据微积分中的链式规则,按相反的顺序从输出层到输入层遍历网络。 该算法存储了计算某些参数梯度时所需的任何中间变量(偏导数)。

        假设我们有函数Y=f(X)和Z=g(Y), 其中输入和输出X,Y,Z是任意形状的张量。 利用链式法则,我们可以计算Z关于X的导数:(使用prod运算符在执行必要的操作,如换位和交换输入位置,后将其参数相乘)

\frac{\partial \mathsf{Z}}{\partial \mathsf{X}} = \text{prod}\left(\frac{\partial \mathsf{Z}}{\partial \mathsf{Y}}, \frac{\partial \mathsf{Y}}{\partial \mathsf{X}}\right).

        如上图所示,反向传播的目的是计算梯度∂J/∂W(1)和 \partial J/\partial \mathbf{W}^{(2)},应用链式法则,依次计算每个中间变量和参数的梯度。 计算的顺序与前向传播中执行的顺序相反,因为需要从计算图的结果开始,并朝着参数的方向努力。

        第一步是计算目标函数J=L+s相对于损失项L和正则项s的梯度。

\frac{\partial J}{\partial L} = 1 \; \text{and} \; \frac{\partial J}{\partial s} = 1. 

        目标函数关于输出层变量o的梯度:

 \frac{\partial J}{\partial \mathbf{o}} = \text{prod}\left(\frac{\partial J}{\partial L}, \frac{\partial L}{\partial \mathbf{o}}\right) = \frac{\partial L}{\partial \mathbf{o}} \in \mathbb{R}^q.

        计算正则化项相对于两个参数的梯度: 

 \frac{\partial s}{\partial \mathbf{W}^{(1)}} = \lambda \mathbf{W}^{(1)} \; \text{and} \; \frac{\partial s}{\partial \mathbf{W}^{(2)}} = \lambda \mathbf{W}^{(2)}.

        计算最接近输出层的模型参数的梯度\partial J/\partial \mathbf{W}^{(2)} \in \mathbb{R}^{q \times h}

\frac{\partial J}{\partial \mathbf{W}^{(2)}}= \text{prod}\left(\frac{\partial J}{\partial \mathbf{o}}, \frac{\partial \mathbf{o}}{\partial \mathbf{W}^{(2)}}\right) + \text{prod}\left(\frac{\partial J}{\partial s}, \frac{\partial s}{\partial \mathbf{W}^{(2)}}\right)= \frac{\partial J}{\partial \mathbf{o}} \mathbf{h}^\top + \lambda \mathbf{W}^{(2)}.

        关于隐藏层输出的梯度∂J/∂h∈Rh由下式给出:

\frac{\partial J}{\partial \mathbf{h}} = \text{prod}\left(\frac{\partial J}{\partial \mathbf{o}}, \frac{\partial \mathbf{o}}{\partial \mathbf{h}}\right) = {\mathbf{W}^{(2)}}^\top \frac{\partial J}{\partial \mathbf{o}}. 

        由于激活函数ϕ是按元素计算的, 计算中间变量z的梯度∂J/∂z∈Rh 需要使用按元素乘法运算符,我们用⊙表示 :

\frac{\partial J}{\partial \mathbf{z}} = \text{prod}\left(\frac{\partial J}{\partial \mathbf{h}}, \frac{\partial \mathbf{h}}{\partial \mathbf{z}}\right) = \frac{\partial J}{\partial \mathbf{h}} \odot \phi'\left(\mathbf{z}\right).

        最后,我们可以得到最接近输入层的模型参数的梯度 ∂J/∂W(1)∈Rh×d。 根据链式法则,我们得到:

\frac{\partial J}{\partial \mathbf{W}^{(1)}} = \text{prod}\left(\frac{\partial J}{\partial \mathbf{z}}, \frac{\partial \mathbf{z}}{\partial \mathbf{W}^{(1)}}\right) + \text{prod}\left(\frac{\partial J}{\partial s}, \frac{\partial s}{\partial \mathbf{W}^{(1)}}\right) = \frac{\partial J}{\partial \mathbf{z}} \mathbf{x}^\top + \lambda \mathbf{W}^{(1)}. 

2.3 小结

        在训练神经网络时,前向传播和反向传播相互依赖。 对于前向传播,我们沿着依赖的方向遍历计算图并计算其路径上的所有变量。 然后将这些用于反向传播,其中计算顺序与计算图的相反。 

        因此,在训练神经网络时,在初始化模型参数后, 我们交替使用前向传播和反向传播,利用反向传播给出的梯度来更新模型参数。 注意,反向传播重复利用前向传播中存储的中间值,以避免重复计算。 

        带来的影响之一是我们需要保留中间值,直到反向传播完成。 这也是训练比单纯的预测需要更多的内存(显存)的原因之一。 此外,这些中间值的大小与网络层的数量和批量的大小大致成正比。 因此,使用更大的批量来训练更深层次的网络更容易导致内存不足(out of memory)错误。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值