Python 试图理解PyTorch的实现

Python 试图理解PyTorch的实现,python,machine-learning,pytorch,Python,Machine Learning,Pytorch,我一直在尝试遍历PyTorch中的所有损失函数,并从头开始构建它们,以更好地理解它们。我遇到了我的娱乐问题,或者PyTorch的实现问题 根据Pytorch的SmoothL1Loss文档,它只是简单地说明,如果预测的绝对值减去地面真实值小于β,我们使用顶部方程。否则,我们使用底部的一个。有关方程式,请参见 以下是我以最低测试的形式对此的实施: import torch import torch.nn as nn import numpy as np predictions = torch.ra

我一直在尝试遍历PyTorch中的所有损失函数,并从头开始构建它们,以更好地理解它们。我遇到了我的娱乐问题,或者PyTorch的实现问题

根据Pytorch的SmoothL1Loss文档,它只是简单地说明,如果预测的绝对值减去地面真实值小于β,我们使用顶部方程。否则,我们使用底部的一个。有关方程式,请参见

以下是我以最低测试的形式对此的实施:

import torch
import torch.nn as nn
import numpy as np

predictions = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)

def l1_loss_smooth(predictions, targets, beta = 1.0):
    
    loss = 0
    for x, y in zip(predictions, targets):
        if abs(x-y).mean() < beta:
            loss += (0.5*(x-y)**2 / beta).mean()
        else:
            loss += (abs(x-y) - 0.5 * beta).mean()

    loss = loss/predictions.shape[0]

output = l1_loss_smooth(predictions, target)
print(output)
Gives an output of:
tensor(0.7475, grad_fn=<DivBackward0>)
导入火炬
导入torch.nn作为nn
将numpy作为np导入
预测=torch.randn(3,5,需要_grad=True)
目标=火炬。随机数(3,5)
def l1_损耗_平滑(预测、目标、β=1.0):
损失=0
对于zip中的x、y(预测、目标):
如果abs(x-y).mean()
现在,Pytorch实现:

loss = nn.SmoothL1Loss(beta=1.0)
output = loss(predictions, target)
Gives an output of:
tensor(0.7603, grad_fn=<SmoothL1LossBackward>)
loss=nn.SmoothL1Loss(beta=1.0)
输出=损失(预测、目标)
给出以下输出:
张量(0.7603,梯度fn=)
我不知道实现中的错误在哪里

在深入查看
\u C
模块(文件:
smooth\u C\u loss\u op.cc
)中的
smooth\u l1\u loss函数时,我注意到doc字符串提到它是Huber loss的一个变体,但是
SmoothL1Loss
的文档说它是Huber loss


因此,总的来说,对于它是如何实现的,以及它是否是SmoothL1Loss和Huber Loss的组合,只是Huber Loss,还是其他什么,我们感到困惑。

文档中的描述是正确的。您的实现错误地将案例选择应用于数据的平均值。相反,它应该是一个元素选择(如果您考虑普通L1损失的实现,以及平滑L1损失的动机)

以下代码给出了一致的结果:

import torch
import torch.nn as nn
import numpy as np

predictions = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)

def l1_loss_smooth(predictions, targets, beta = 1.0):
    
    loss = 0

    diff = predictions-targets
    mask = (diff.abs() < beta)
    loss += mask * (0.5*diff**2 / beta)
    loss += (~mask) * (diff.abs() - 0.5*beta)
    
    return loss.mean()

output = l1_loss_smooth(predictions, target)
print(output)

loss = nn.SmoothL1Loss(beta=1.0)
output = loss(predictions, target)
print(output)

导入火炬
导入torch.nn作为nn
将numpy作为np导入
预测=torch.randn(3,5,需要_grad=True)
目标=火炬。随机数(3,5)
def l1_损耗_平滑(预测、目标、β=1.0):
损失=0
diff=预测目标
遮罩=(差值abs()