如何在 PyTorch 中使用 numpy 函数作为损失函数并避免在运行时出错?

对于我的任务,我不需要计算梯度。我只是在损失评估nn.L1Loss中用 numpy 函数 ( corrcoef)替换,但出现以下错误:


RuntimeError: Can’t call numpy() on Variable that requires grad. Use var.detach().numpy() instead.

我不知道我应该如何分离图表(我试过torch.Tensor.detach(np.corrcoef(x, y)),但我仍然遇到同样的错误。我最终使用torch.no_grad以下方法包装了所有内容:


with torch.no_grad():

    predFeats = self.forward(x)

    targetFeats = self.forward(target)

    loss = torch.from_numpy(np.corrcoef(predFeats.cpu().numpy().astype(np.float32), targetFeats.cpu().numpy().astype(np.float32))[1][1])

但是这次我收到以下错误:


TypeError: expected np.ndarray (got numpy.float64)

我想知道,我做错了什么?


郎朗坤
浏览 792回答 1
1回答

慕哥6287543

with torch.no_grad():    predFeats = self(x)    targetFeats = self(target)    loss = torch.tensor(np.corrcoef(predFeats.cpu().numpy(),                                    targetFeats.cpu().numpy())[1][1]).float()您可以RuntimeError通过从计算图中分离张量 (predFeats和targetFeats) 来避免第一个。即获取没有梯度和梯度函数 ( grad_fn)的张量数据的副本。所以,而不是torch.Tensor.detach(np.corrcoef(x.numpy(), y.numpy())) # Detaches a newly created tensor!# x and y still may have gradients. Hence the first error.什么都不做,做# Detaches x and y properlytorch.Tensor(np.corrcoef(x.detach().numpy(), y.detach().numpy()))但是,让我们不要打扰所有的支队。就像您正确修复一样,让我们禁用渐变。torch.no_grad()现在,计算特征。predFeats = self(x) # No need for the explicit .forward() calltargetFeats = self(target)我发现打破你的最后一条线很有帮助。loss = np.corrcoef(predFeats.numpy(), targetFeats.numpy()) # We don't need to detach# Notice that we don't need to cast the arguments to fp32# since the `corrcoef` casts them to fp64 anyway.print(loss.shape, loss.dtype) # A 2-dimensional fp64 matrixloss = loss[1][1]print(type(loss)) # Output: numpy.float64# Loss now just a simple fp64 number这就是问题所在!因为,当我们做loss = torch.from_numpy(loss)我们传入一个数字 ( numpy.float64) 而它需要一个 numpy 张量 ( np.ndarray)。如果您使用的是 PyTorch 0.4 或更高版本,则内置了对标量的支持。只需将from_numpy()方法替换为通用tensor()创建方法即可。loss = torch.tensor(loss)PS 您可能还想查看设置rowvar=False,corrcoef因为 PyTorch 张量中的行通常表示观察结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python