【刘二大人】《PyTorch深度学习实践》——反向传播代码(自用)
反向传播
使用反向传播的原因:
利用梯度下降来找到最优的权重,需要计算梯度,而计算每个中间结果的梯度又想当繁琐,所以利用反向传播的方式来取得最终值对于权重的梯度。
反向传播过程:
前向计算每个中间结果节点的梯度,前向传播生成计算图,然后利用链式法则,反向将最终结果关于权重的梯度表示出来。
代码来源:https://blog.csdn.net/qq_39804263/article/details/139685123?fromshare=blogdetail&sharetype=blogdetail&sharerId=139685123&sharerefer=PC&sharesource=m0_63829662&sharefrom=from_link
仅添加部分注释
代码如下:
# 如果是复杂的网络,没办法都自己写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_(),不然,梯度值会累加到下一个样本梯度值中。
运行结果:
