y=wx的反向传播代码实现
import torch
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]#w是Tensor(张量类型),Tensor中包含data和grad,data和grad也是Tensor。
# grad初始为None,调用l.backward()方法后w.grad为Tensor,
# 故更新w.data时需使用w.grad.data。
# 如果w需要计算梯度,那构建的计算图中,跟w相关的tensor都默认需要计算梯度。
w=torch.Tensor([1.0])
#True:需要计算梯度
w.requires_grad=Truedef forward(x):return x * w# 构建计算图
def loss(x,y):y_pred=forward(x)return (y_pred-y)*(y_pred-y)print("训练之前:",4,forward(4).item())
for epoch in range(100):for x,y in zip(x_data,y_data):l=loss(x,y)#自动将需要梯度的地方计算出来#存储到w中#l.backward()会把计算图中所有需要梯度(grad)的地方都会求出来,# 然后把梯度都存在对应的待求的参数中,最终计算图被释放。l.backward()print("grad:",x,y,w.grad.item())#grad是修改后的w权值#data是转化为标量 不能使用张量计算 会发生自动类型转换w.data=w.data-0.01*w.grad.data#要单个所以要释放,如果是连续的则不需要清零# w.data.zero_() 错w.grad.data.zero_()print("进程轮数:",epoch,l.item())
print("训练之后:",4,forward(4).item())
y=w1x+w2x+b的反向传播代码实现
import torchx_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
#学习率
learn_rate=0.01#True:需要计算梯度
w1=torch.tensor([1.0])
w1.requires_grad=Truew2=torch.tensor([1.0])
w2.requires_grad=Trueb=torch.tensor([1.0])
b.requires_grad=Truedef forward(x):return w1*x+w2*x+bdef loss(x,y):y_test=forward(x)return (y_test-y)*(y_test-y)print("训练之前:",4,forward(4).item())
for epoch in range(100):for x,y in zip(x_data,y_data):#损失函数原型l=loss(x,y)l.backward()#pytorch中,.item()方法 是得到一个元素张量里面的元素值print("grad:",x,y,w1.grad.item(),w2.grad.item(),b.grad.item())#orch.autograd包主要功能是完成网络反向传播时的链式求导#过程大致为:先通过输入的tensor数据类型的变量在神经网络的前向传播中生成一张计算图,#然后再根据这个计算图和输出结果准确计算出各个参数需要更新的梯度,并通过完成反向传播对参数进行梯度更新。#在实践中使用autograd包中的variable类进行封装,封装之后计算图中每一个节点就是一个variable对象#因此如果用X代表选中的节点,那么X.data 就是tensor数据对象,X.grad就是X的梯度对象,X.grad.data就是X的梯度数据值啦w1.data=w1.data-learn_rate*w1.grad.dataw2.data=w2.data-learn_rate*w2.grad.datab.data=b.data-learn_rate*b.grad.dataw1.grad.data.zero_()w2.grad.data.zero_()b.grad.data.zero_()print("轮数:",epoch,l.item())
print("训练之后:",4,forward(4).item())