我正在尝试使用torch
张量和一些内置的损失函数从头训练MLP。我已下载IRIS数据并将其存储在张量(100, 4)
中,并在(100)
和data_tr
中标记了targets_tr
(整数0-2)。我在输入数据data_tr.requires_grad=True
我有一个这样初始化的两层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。现在的问题是,权重或偏差(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