代码之家  ›  专栏  ›  技术社区  ›  Amir

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

  •  1
  • Amir  · 技术社区  · 6 年前

    对于我的任务,我不需要计算渐变。我只是简单地替换 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)
    

    1 回复  |  直到 6 年前
        1
  •  2
  •   Vaisakh    6 年前

    TL;博士

    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 i、 e.在没有梯度和梯度函数的情况下获得张量数据的副本( 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 properly
    torch.Tensor(np.corrcoef(x.detach().numpy(), y.detach().numpy()))
    

    就像你正确地修复的那样,让我们禁用渐变。

    torch.no_grad()
    

    现在,计算特征。

    predFeats = self(x) # No need for the explicit .forward() call
    targetFeats = 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 matrix
    
    loss = 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 ).

    只需更换 from_numpy() tensor() 创建方法。

    loss = torch.tensor(loss)
    

    rowvar=False corrcoef 因为PyTorch张量中的行通常表示观测值。