上一讲PyTorch深度学习实践概论笔记3-梯度下降算法讲解了梯度下降算法理论和代码实现。接下来第4讲:back propagation。这是神经网络比较重要的一个算法。
关于反向传播的详细理论推荐吴恩达老师讲解:1-3 Coursera吴恩达《神经网络与深度学习》第三周课程笔记-浅层神经网络的3.10小节。
0 Computer gradient in simple network
回归上一讲的线性模型,它可以看成一个比较简单的神经网络。
1 What about the complicated network?
对于复杂的神经网络,权重w有很多个,写具体的梯度解析式看着是几乎不可能的事情。那么能不能把复杂网络看成一个图,然后在图上传播,根据链式法则求梯度。这种算法就叫反向传播算法。
1.1 Computational Graph
先看一下计算图,介绍两层的神经网络。
MM是矩阵乘法(matrix multiplication)的缩写,ADD是向量加法(vector addition)的缩写。对于矩阵的求导找这本书:The Matrix Cookbook。重点看第二章2 Derivatives。
1.2 What problem about this two layer neural network?
1.2.1 sigmiod
如果只是线性运算,每一层之间没有什么区别。所以上图加非线性函数做变换,让每一个x值都带入非线性函数,此处的非线性函数用的是sigmoid。
1.2.2 The composition of functions and Chain Rule
把网络看成一个图,在图上传播梯度,然后根据链式法则把梯度求出来。反向传播算法权重可以是权重矩阵,偏置通常定义成向量形式。
链式法则:
(1)创造计算图(FORWARD)
(2)计算梯度
(3)从分离节点给出梯度
(4)使用链式法则计算梯度(BACKWARD)
1.3 Example
f =x*w,x=2,w=3
1.3.1 Chain Rule-1 Create Computational Graph(Forward)
forward指前向传播或前馈传播。先沿着上图的蓝色箭头计算loss。
1.3.2 Chain Rule-2 Loss Gradient
上图红色部分:计算梯度。
1.3.3 Chain Rule-3 Given gradient from successive node
从输出节点给定梯度,求loss对z的偏导。
1.3.4 Chain Rule-4 Use chain rule to compute the gradient(Backward)
使用链式法则计算梯度,上图的红色标记。
2 Computation Graph of Linear Model
pytorch是把梯度存在变量里面的。最下面一行是反向传播步骤,最终得到损失对权重的导数。
3 Tensor in PyTorch
接下来看在PyTorch中进行前馈和反馈运算。
3.1 Tensor
Tensor是PyTorch中重要的数据形式。
3.2 Implementation of linear model with PyTorch
用PyTorch实现线性模型的代码:
#If autograd mechanics are required, the element variable requires_grad of Tensor has to be set to True.
import torch
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
w = torch.Tensor([1.0])
w.requires_grad = True #默认是不计算的,等于True表示w是需要计算梯度的
#定义模型
def forward(x):
return x * w #x会自动进行类型转换,成tensor
#定义损失函数
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(100):
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 #注意进行权重更新的时候不能使用tensor
#.backward()计算的梯度会累加,注意把梯度清零。为什么不默认清零?因为有些算法就是需要累加。
w.grad.data.zero_()
print("progress:", epoch, l.item())
print("predict (after training)", 4, forward(4).item())
我的输出结果:
前几次
后几次
可以看到随着训练的进行,Loss越来越小了。
说明:记录学习笔记,如果错误欢迎指正!写文章不易,转载请联系我。