返回顶部

请叫我杨先生

导航

Pytorch 4.7 前向传播和反向传播剖析

前向传播

  • 前向传播(forward propagation或forward pass) 指的是:按顺序(从输入层到输出层)计算和存储神经网络中每层的结果。

为了搞清楚前向传播是如何实现的,我们以简单的例子作为切入点,假设输入的样本是 \(X\in R^{d×1}\) ,隐藏层不包括偏置项 \(b\) ,那么中间变量就是:

\[z = W^{(1)}X \]

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

\[h=ϕ(z) \]

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

\[o=W^{(2)}h \]

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

\[L=l(o,y) \]

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

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

模型在给定数据样本上的正则化损失为:

\[J = L+s \]

  • 如果用计算图来表示我们的前向传播的过程就是:

反向传播

  • 反向传播(backward propagation或backpropagation)指的是:计算神经网络参数梯度的方法。简言之,该方法根据微积分中的链式规则,按相反的顺序从输出层到输入层遍历网络。

我们定义高纬张量相乘:

\[\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) \]

在计算图中的单隐藏层简单网络的参数是 \(W^{(1)}\)\(W^{(2)}\) 。反向传播的目的是计算梯度 \(\partial J / \partial W^{(1)}\)\(\partial J / \partial 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 W^{(2)}\):

\[\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)} \]

继续沿着输出层到隐藏层反向传播,得到关于隐藏层输出的梯度 \(\partial J /\partial h \in R^h\)

\[\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)\]

根据链式法则,我们得到 \(\partial J/\partial W^{(1)}\)

\[\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)}\]

最后做个总结的话就是:
(1)前向传播在神经网络定义的计算图中按照从输入到输出的顺序计算、存储中间变量。
(2)反向传播按照相反的顺序(从输入到输出层)计算和存储神经网络的中间变量和参数的梯度。
(3)在训练深度学习模型时,前向传播和反向传播是相互依赖的。
(4)训练比预测需要更多的显存和内存。

posted on 2022-01-08 23:37  YangShusen'  阅读(891)  评论(0编辑  收藏  举报