loss的定义
class CrossEntropyLoss2d(torch.nn.Module):
def __init__(self, weight=None):
super().__init__()
self.loss = torch.nn.NLLLoss(weight)
def forward(self, outputs, targets):
return self.loss(torch.nn.functional.log_softmax(outputs, dim=1), targets)
PyTorch模型训练梯度反向传播
optimizer.zero_grad()
loss = criterion(outputs, targets[:, 0])
loss.backward()
optimizer.step()
epoch_loss.append(loss.data[0])
出现这个错的第一时间,我显示尝试在model的每一个module的输入输出设置的断点,打印了一下输入输出的requires_grad是否为True,方法如下:
print(x.requires_grad)
检查完发现,输入输出都没有问题。于是继续网上冲浪查问题出在哪里。
看到几个帖子提到把loss.requires_grad设置为True,就试着打印了一下loss.requires_grad,就很奇怪居然为False。
于是将代码改为:
optimizer.zero_grad()
loss = criterion(outputs, targets[:, 0])
loss.requires_grad = True
loss.backward()
optimizer.step()
epoch_loss.append(loss.data[0])
tensor.item()
in Python or tensor.item()
in C++ to convert a 0-dim tensor to a number解决了上面的RuntimeError后,出现了这个错。
发现错误出在这一句:
epoch_loss.append(loss.data[0])
改为:
epoch_loss.append(loss.data)
就可以了。
继续调试,loss function不应该输出default的requires_grad为False的loss值。于是继续在网上找答案。
查了一圈发现,应该是model的outputs有问题,可能在model中的某个步骤,outputs被detach了。首先,确定一下outputs是不是有问题,可以通过:
print(outputs.grad_fn)
看一下是不是有输出。如果没有,okay,确定了是模型的问题,去检查模型就对了。