Pytorch中的NLLLoss代码解释

在分类以及语义分割任务中,CrossEntropy是十分常用的一个损失函数,pytorch也对其进行了实现用于直接使用。

但本人在阅读其源码时,发现nn.CrossEropyLoss并不是直接按照交叉熵公式: L o s s ( p , y ) = − ∑ i = 1 n y i l o g ( p i ) Loss(p, y)=-\sum_{i=1}^{n}y_ilog(p_i) Loss(p,y)=i=1nyilog(pi)计算而得,实际上其是融合了多个计算而成:softmax计算+log计算+nll_loss计算。其具体原理,推荐一篇讲解得十分详细的pytorch语义分割中CrossEntropyLoss()损失函数的理解与分析,博主本人也是看了这篇博客才算真正理解了pytorch里面的交叉熵实现。

不过今天我不是要讲交叉熵,而是想讲一下其中的NLLLoss。这篇博客中也有举例解释NLLLoss的情况,但其用的例子是二维的,我们实际使用过程中大多数都是处理4D的tensor,因此,可能不够直观,接下来我就贴出我自己对NLLLoss理解后的实现代码,大家阅读一下就能更加清楚明白了。

N, C, H, W = 2, 2, 3, 3
loss = nn.NLLLoss()
data = torch.randn(N, C, H, W)
target = torch.empty(N, H, W, dtype=torch.long).random_(0, C)
output = loss(data, target)

print(data)
print(target)
print(output)


loss = 0.0
for batch in range(N):
    for i in range(H):
        for j in range(W):
            index = target[batch][i][j]  # 获取target,实际也就是该计算loss的索引值
            item = data[batch][index][i][j]  # 根据target得到的索引值,取出对应值,并添加负号
            loss -= item
print(loss / N / H / W)

代码输出

data:  tensor([[[[ 0.4086, -1.0978,  1.2770],
          [ 0.2216,  1.0113,  1.0838],
          [ 0.4149,  2.6782,  0.1263]],

         [[-0.2087,  1.2173,  0.6427],
          [-1.1500,  0.0756,  0.4218],
          [ 0.9435, -1.5560, -1.0130]]],


        [[[ 1.4858, -0.2244,  2.0683],
          [ 0.4505, -0.3687, -0.8775],
          [-0.7105,  0.0538,  0.9036]],

         [[ 0.6779, -0.4425,  1.3001],
          [ 0.4512, -1.3058, -0.4361],
          [ 0.5120, -0.0333,  0.2222]]]])
target: tensor([[[0, 0, 0],
         [1, 0, 0],
         [1, 0, 1]],

        [[0, 1, 1],
         [0, 1, 1],
         [1, 1, 0]]])
nll_loss by pytorch: tensor(-0.3653)
nll_loss by hand: tensor(-0.3653)

实际上NLLLoss就是遍历target的每个空间位置 ( i , j ) , 0 < = i < H , 0 < = j < W (i,j),0<=i<H,0<=j<W (i,j),0<=i<H,0<=j<W,从而得到每个位置的正确的类别,即索引值,然后根据索引值取出输入对应位置 ( i , j ) (i,j) (i,j)的值,然后取负值,即可作为loss。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值