【刘二大人】《PyTorch深度学习实践》——反向传播代码(自用)
·
反向传播
使用反向传播的原因:
利用梯度下降来找到最优的权重,需要计算梯度,而计算每个中间结果的梯度又想当繁琐,所以利用反向传播的方式来取得最终值对于权重的梯度。
反向传播过程:
前向计算每个中间结果节点的梯度,前向传播生成计算图,然后利用链式法则,反向将最终结果关于权重的梯度表示出来。
仅添加部分注释
代码如下:
# 如果是复杂的网络,没办法都自己写gradient的计算。
import torch
import matplotlib.pyplot as plt
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
def forward(x, w):
return x * w
def loss(x, y, w):
y_pred = forward(x, w)
loss = (y - y_pred) ** 2
return loss
print('predict (before training)', 4, forward(4, w.item()))
epoch_list = []
loss_list = []
for epoch in range(100):
for x, y in zip(x_data, y_data):
l = loss(x, y, w)
l.backward()
print('\tgrad:', x, y, w.grad.item())
w.data = w.data - 0.01 * w.grad.data #w.grad是张量tensor,w.grad.data是标量
w.grad.data.zero_() # 对梯度进行清零,否则梯度会进行累加
print('process:', epoch, l.item())
epoch_list.append(epoch)
loss_list.append(l.item())
print('predict (after training)', 4, forward(4, w))
plt.plot(epoch_list, loss_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
【注意点】
(1)w.grad是张量,而w.grad.data是标量。张量w包含data和grad的,grad也是一个张量,grad.data才是它的标量值。
(2)每一个样本进行权重更新时,最后都需要将梯度值清零,利用w.grad.data.zero_(),不然,梯度值会累加到下一个样本梯度值中。
运行结果:

更多推荐
所有评论(0)