pytorch F.cross_entropy 不对权重应用梯度

pytorch F.cross_entropy does not apply gradient to weights

我正在尝试使用 torch 张量和一些内置损失函数从头开始训练 MLP。我已将 IRIS 数据下载并存储在张量 (100, 4) 和标签 (100)(整数 0-2)中 data_trtargets_tr。我在输入数据上启用了渐变 data_tr.requires_grad=True

我有一个像这样初始化的 2 层 MLP:

W1 = torch.randn([4, 64], requires_grad=True)
W2 = torch.randn([64, 3], requires_grad=True)
b1 = torch.tensor([1.0], requires_grad=True)
b2 = torch.tensor([1.0], requires_grad=True

我明白我应该这样训练:

for epoch in range(num_epochs):
    W1.grad = None
    W2.grad = None
    b1.grad = None
    b2.grad = None

    f = torch.relu(data_tr @ W1 + b1) @ W2 + b2
    error = torch.nn.functional.cross_entropy(f, targets_tr)
    error.backward()

    W1 = W1 - lr * W1.grad
    W2 = W2 - lr * W2.grad
    b1 = b1 - lr * b1.grad
    b2 = b2 - lr * b2.grad

这使得一个 2 层 MLP 和 cross_entropy 应用 softmax。 现在的问题是 none 的权重或偏差 (W1, W2, b1, b2) 在向后传递后有任何梯度。所以我在第一次尝试更新权重时得到了 TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'

如果您想在不使用优化器的情况下更新权重,则必须使用 torch.no_grad() 或直接更新它们的 data 以确保 autograd 不会跟踪更新操作。

with torch.no_grad():
    W1 -= lr * W1.grad
    W2 -= lr * W2.grad

b1.data = b1 - lr * b1.grad
b2.data = b2 - lr * b2.grad

请注意,在第一种情况下,如果您不减去赋值,requires_grad 的权重将设置为 False,这将再次导致梯度的 None 值.

with torch.no_grad():
    W1 = W1 - lr * W1.grad
    W2 = W2 - lr * W2.grad
print(W1.requires_grad, W2.requires_grad)
>>> False False