首先,grad为None 不止一种情况。我这里给出因为使用(view/reshape)修改维度造成的grad为None。
气死我了!!!!
刚开始学 pytorch 的基础操作,然后自己模拟了一个数据。 这个是函数,就是两个个初等函数相加,再加上一个随机数(模拟噪声)。然后用五阶泰勒展开来模拟这条曲线,不了解泰勒展开的同学可以先去了解一下泰勒展开,不用管他的余项是什么,咱关注点不是这个。
泰勒展开 幂函数 前面的常数就是我们要学习的参数,我出错就是因为这个东西。
- func 是 x**5, x**4, x**3, x**2, x**1, x,组成的 5 * 100 的矩阵
那我的参数总得是个1*5 的矩阵来进行计算出预测值对吧。
先给出错因:
起初是因为我用了 view。将 (5,) 的张量转换为了 (1, 5) 的张量去和 func 进行计算。结果,backward 之后。找不到params.grad,返回值是 None。我在网上找了半天终于找到一个小网站,解决了这个问题。
不是因为view返回了一个形状不同数据相同的张量引起的错误,我 DeBug 的时候看过requires_grad,依然是 True。
怎么解决pytorch损失反向传播后梯度为none的问题 | w3cschool笔记
params = torch.randn(5, requires_grad=True, dtype=torch.float32).view(1, 5)
但是,这不是没有梯度,而是放在了其他的地方。给你们看看我在什么地方找到了梯度。按理说,直接对 张量.grad 就能找到梯度的。
完整正确的代码,你们可以试试加上view。
import torch
import numpy as np
size = 100
# 创建模拟数据
x = np.array([ele / 100 for ele in range(-size, size+1)])
y = np.array([3 * np.sin(5 * ele) + ele * 2 + 10 + np.random.rand() for ele in x])
# 泰勒5阶展开的x
func = torch.tensor(np.array([x ** i for i in range(5, 0, -1)]), dtype=torch.float32, requires_grad=True)
# 数据格式转换
x = torch.from_numpy(x)
y = torch.from_numpy(y)
# 泰勒五阶展开x前面的常数
params = torch.randn(1, 5, requires_grad=True, dtype=torch.float32)
# f(a)
bias = torch.randn(1, requires_grad=True, dtype=torch.float32)
lr = 0.01
print(func.shape) # torch.Size([5, 100])
print(params.shape)
losses = []
for _ in range(2000):
predict = torch.matmul(params, func) + bias
loss = torch.sum((predict - y) ** 2) / size # 修正损失计算
loss.backward()
params.data -= lr * params.grad
bias.data -= lr * bias.grad
params.grad.zero_()
bias.grad.zero_()
print(loss.item()) # 使用loss.item()来获取损失的标量值
losses.append(loss.item())