pytorch 交叉熵损失教程(3)-torch.nn.BCELoss

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytorch 交叉熵损失教程(3)-torch.nn.BCELoss相关的知识,希望对你有一定的参考价值。

参考技术A

1.2 torch.nn.NLLLoss
Binary Cross Entropy between the target and the input probabilities
(1)计算公式
计算N个标签的损失

将N个标签的损失求和或平均(默认是平均)

(2)输入
1)模型经过 softmax后 预测输出 ,shape(n_samples), dtype(torch.float)
2)真实标签,shape=(n_samples), dtype(torch.float)

(3)例子1

(4)例子2
data

model

trainning

analysis of the model

pytorch 中的交叉熵损失如何工作?

【中文标题】pytorch 中的交叉熵损失如何工作?【英文标题】:How is cross entropy loss work in pytorch? 【发布时间】:2021-01-21 02:27:57 【问题描述】:

我正在试验一些 pytorch 代码。通过交叉熵损失,我发现了一些有趣的结果,我同时使用了二元交叉熵损失和 pytorch 的交叉熵损失。

import torch
import torch.nn as nn

X = torch.tensor([[1,0],[1,0],[0,1],[0,1]],dtype=torch.float)
softmax = nn.Softmax(dim=1)


bce_loss = nn.BCELoss()
ce_loss= nn.CrossEntropyLoss()

pred = softmax(X)

bce_loss(X,X) # tensor(0.)
bce_loss(pred,X) # tensor(0.3133)
bce_loss(pred,pred) # tensor(0.5822)

ce_loss(X,torch.argmax(X,dim=1)) # tensor(0.3133)

我预计相同输入和输出的交叉熵损失为零。这里 X, pred 和 torch.argmax(X,dim=1) 是相同/相似的一些变换。这种推理仅适用于bce_loss(X,X) # tensor(0.),否则所有其他导致损失大于零。我推测bce_loss(pred,X)bce_loss(pred,pred)ce_loss(X,torch.argmax(X,dim=1)) 的输出应该为零。

这里有什么错误?

【问题讨论】:

这能回答你的问题吗? is crossentropy loss of pytorch different than "categorical_crossentropy" of keras? 【参考方案1】:

您看到这个的原因是因为nn.CrossEntropyLoss 接受 logits 和目标,也就是 X 应该是 logits,但已经在 0 和 1 之间。X 应该更大,因为在 softmax 之后它将在 0 之间和 1.

ce_loss(X * 1000, torch.argmax(X,dim=1)) # tensor(0.)

nn.CrossEntropyLoss 与 logits 一起使用,以利用 log sum 技巧。

激活后你当前尝试的方式,你的预测变成了[0.73, 0.26]

二进制交叉熵示例有效,因为它接受已激活的 logits。顺便说一句,您可能想使用nn.Sigmoid 来激活二进制交叉熵 logits。对于2-class的例子,softmax也是可以的。

【讨论】:

【参考方案2】:

我已经发布了交叉熵和 NLLLoss here 的手动实现作为对相关 pytorch CrossEntropyLoss 问题的回答。它可能并不完美,但请检查一下。

编辑:我之前的帖子中没有包含代码,所以帖子被删除了。按照给定的建议,计算 CrossEntropyLoss 的部分代码(直接从上面的链接复制)如下:

def compute_crossentropyloss_manual(x,y0):
    """
    x is the vector of probabilities with shape (batch_size,C)
    y0 shape is the same (batch_size), whose entries are integers from 0 to C-1
    """
    loss = 0.
    n_batch, n_class = x.shape
    # print(n_class)
    for x1,y1 in zip(x,y0):
        class_index = int(y1.item())
        loss = loss + torch.log(torch.exp(x1[class_index])/(torch.exp(x1).sum()))
    loss = - loss/n_batch
    return loss

【讨论】:

以上是关于pytorch 交叉熵损失教程(3)-torch.nn.BCELoss的主要内容,如果未能解决你的问题,请参考以下文章

pytorch 中的交叉熵损失如何工作?

PyTorch中的交叉熵

使用 PyTorch 的交叉熵损失函数是不是需要 One-Hot Encoding?

Sigmoid 与二元交叉熵损失

Pytorch常用的交叉熵损失函数CrossEntropyLoss()详解

交叉熵损失 Pytorch