反向传播算法
引言
在上一篇《梯度下降》中,对于没有隐层的网络(文章中是拟合的线性函数),有直接的输入和输出,可以直接使用梯度下降求解。但对于有隐层的神经网络,在输出层可以通过梯度下降直接求出误差来更新参数,但隐层的误差是不存在的,不能对它直接应用梯度下降进行优化,而是先将误差反向传播至隐层,然后再应用梯度下降,其中将误差从末层往前传递的过程需要链式法则(Chain Rule)的帮助,因此反向传播算法可以说是梯度下降在链式法则中的应用。可以快速的从参数空间里找到较好的参数组合。
所以对于含隐层的神经网络来说,反向传播是一种用来训练人工神经网络的常见方法。算法使梯度可以在计算图上进行传播。该方法计算网络中损失函数对神经网络每一层临时输出值的梯度,用来更新权值以最小化损失函数。
反向传播算法的主要步骤如下:
前向传播->反向传播->权重更新->循环迭代
更加详细的推导,这篇文章讲的非常好:反向传播之我见 。
反向传播通过使用计算图在Tensorflow,Torch等深度学习框架中实现。
pytorch反向传播
在pytorch中进行反向传播,首先要构建计算图。
Pytorch构建计算图
计算图是用来描述运算的有向无环图。 是一种描述方程的“语言”。主要包含节点(数据)和边(运算)
如下便构建了一个计算图:
1 2 3 4 5 6 7 8 9 import torchx_data = [i for i in range(10 )] y_data = [2 *i for i in range(10 )] w = torch.Tensor([1.0 ]) w.requires_grad = True for x, y in zip(x_data,y_data): loss = (w*x - y) ** 2 loss.backward()
pytoch构建的计算图是动态图,每次一轮迭代完之后计算图就被释放,不能进行多次的backward
这里的动态主要有两重含义。
第一层含义是:计算图的正向传播是立即执行的。无需等待完整的计算图创建完毕,每条语句都会在计算图中动态添加节点和边,并立即执行正向传播得到计算结果。
第二层含义是:计算图在反向传播后立即销毁。下次调用需要重新构建计算图。如果在程序中使用了backward方法执行了反向传播,或者利用torch.autograd.grad方法计算了梯度,那么创建的计算图会被立即销毁,释放存储空间,下次调用需要重新创建。
Pytorch构建单层网络的反向传播
然后我们使用pytorch构建一个完整的反向传播流程:
这里还是使用f ( x ) = w ∗ x f(x)=w*x f ( x ) = w ∗ x 作为拟合函数,使用单层的神经网络,并将每次迭代的误差与梯度输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import torchx_data = [1 , 2 , 3 ] y_data = [2 , 4 , 6 ] w = torch.Tensor([1.0 ]) w.requires_grad = True def forward (x ): return w*x def loss (x, y ): y_pred = forward(x) return (y_pred - y) ** 2 print("predict (before training)" , 4 , forward(4 ).item()) for epoch in range(10 ): for x, y in zip(x_data,y_data): l = loss(x,y) l.backward() print('\tgrad:' , x, y, w.grad.item()) w.data = w.data - 0.01 * w.grad.data w.grad.data.zero_() print("progress:" , epoch, l.item()) print("predict (after training)" , 4 , forward(4 ).item())
输出如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 predict (before training) 4 4.0 grad: 1 2 -2.0 grad: 2 4 -7.840000152587891 grad: 3 6 -16.228801727294922 progress: 0 7.315943717956543 grad: 1 2 -1.478623867034912 grad: 2 4 -5.796205520629883 grad: 3 6 -11.998146057128906 省略。。。。。。 progress: 7 0.10662525147199631 grad: 1 2 -0.17850565910339355 grad: 2 4 -0.699742317199707 grad: 3 6 -1.4484672546386719 progress: 8 0.0582793727517128 grad: 1 2 -0.1319713592529297 grad: 2 4 -0.5173273086547852 grad: 3 6 -1.070866584777832 progress: 9 0.03185431286692619 predict (after training) 4 7.804864406585693
每一步对梯度的求导过程如下:
参考: