pytorch 实现二分类交叉熵逆样本频率权重

 更新时间:2021年05月24日 10:16:34   作者:*小呆  
这篇文章主要介绍了pytorch 实现二分类交叉熵逆样本频率权重的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

通常,由于类别不均衡,需要使用weighted cross entropy loss平衡。

def inverse_freq(label):
 """
 输入label [N,1,H,W],1是channel数目
 """
    den = label.sum() # 0
    _,_,h,w= label.shape
    num = h*w
    alpha = den/num # 0
    return torch.tensor([alpha, 1-alpha]).cuda()
# train
...
loss1 = F.cross_entropy(out1, label.squeeze(1).long(), weight=inverse_freq(label))

补充:Pytorch踩坑记之交叉熵(nn.CrossEntropy,nn.NLLLoss,nn.BCELoss的区别和使用)

在Pytorch中的交叉熵函数的血泪史要从nn.CrossEntropyLoss()这个损失函数开始讲起。

从表面意义上看,这个函数好像是普通的交叉熵函数,但是如果你看过一些Pytorch的资料,会告诉你这个函数其实是softmax()和交叉熵的结合体。

然而如果去官方看这个函数的定义你会发现是这样子的:

哇,竟然是nn.LogSoftmax()和nn.NLLLoss()的结合体,这俩都是什么玩意儿啊。再看看你会发现甚至还有一个损失叫nn.Softmax()以及一个叫nn.nn.BCELoss()。

我们来探究下这几个损失到底有何种关系。

nn.Softmax和nn.LogSoftmax

首先nn.Softmax()官网的定义是这样的:

嗯...就是我们认识的那个softmax。那nn.LogSoftmax()的定义也很直观了:

果不其然就是Softmax取了个log。可以写个代码测试一下:

import torch
import torch.nn as nn
 
a = torch.Tensor([1,2,3])
#定义Softmax
softmax = nn.Softmax()
sm_a = softmax=nn.Softmax()
print(sm)
#输出:tensor([0.0900, 0.2447, 0.6652])
 
#定义LogSoftmax
logsoftmax = nn.LogSoftmax()
lsm_a = logsoftmax(a)
print(lsm_a)
#输出tensor([-2.4076, -1.4076, -0.4076]),其中ln(0.0900)=-2.4076

nn.NLLLoss

上面说过nn.CrossEntropy()是nn.LogSoftmax()和nn.NLLLoss的结合,nn.NLLLoss官网给的定义是这样的:

The negative log likelihood loss. It is useful to train a classification problem with C classes

负对数似然损失 ,看起来好像有点晦涩难懂,写个代码测试一下:

import torch
import torch.nn
 
a = torch.Tensor([[1,2,3]])
nll = nn.NLLLoss()
target1 = torch.Tensor([0]).long()
target2 = torch.Tensor([1]).long()
target3 = torch.Tensor([2]).long()
 
#测试
n1 = nll(a,target1)
#输出:tensor(-1.)
n2 = nll(a,target2)
#输出:tensor(-2.)
n3 = nll(a,target3)
#输出:tensor(-3.)

看起来nn.NLLLoss做的事情是取出a中对应target位置的值并取负号,比如target1=0,就取a中index=0位置上的值再取负号为-1,那这样做有什么意义呢,要结合nn.CrossEntropy往下看。

nn.CrossEntropy

看下官网给的nn.CrossEntropy()的表达式:

看起来应该是softmax之后取了个对数,写个简单代码测试一下:

import torch
import torch.nn as nn
 
a = torch.Tensor([[1,2,3]])
target = torch.Tensor([2]).long()
logsoftmax = nn.LogSoftmax()
ce = nn.CrossEntropyLoss()
nll = nn.NLLLoss()
 
#测试CrossEntropyLoss
cel = ce(a,target)
print(cel)
#输出:tensor(0.4076)
 
#测试LogSoftmax+NLLLoss
lsm_a = logsoftmax(a)
nll_lsm_a = nll(lsm_a,target)
#输出tensor(0.4076)

看来直接用nn.CrossEntropy和nn.LogSoftmax+nn.NLLLoss是一样的结果。为什么这样呢,回想下交叉熵的表达式:

l(x,y)=-\sum y*logx=\left\{\begin{matrix} -logx , y=1& \\ 0,y=0& \end{matrix}\right.

其中y是label,x是prediction的结果,所以其实交叉熵损失就是负的target对应位置的输出结果x再取-log。这个计算过程刚好就是先LogSoftmax()再NLLLoss()。

所以我认为nn.CrossEntropyLoss其实应该叫做softmaxloss更为合理一些,这样就不会误解了。

nn.BCELoss

你以为这就完了吗,其实并没有。还有一类损失叫做BCELoss,写全了的话就是Binary Cross Entropy Loss,就是交叉熵应用于二分类时候的特殊形式,一般都和sigmoid一起用,表达式就是二分类交叉熵:

直觉上和多酚类交叉熵的区别在于,不仅考虑了y_n=1的样本,也考虑了y_n=0的样本的损失。

总结

nn.LogSoftmax是在softmax的基础上取自然对数

nn.NLLLoss是负的似然对数损失,但Pytorch的实现就是把对应target上的数取出来再加个负号,要在CrossEntropy中结合LogSoftmax来用

BCELoss是二分类的交叉熵损失,Pytorch实现中和多分类有区别

Pytorch是个深坑,让我们一起扎根使用手册,结合实践踏平这些坑吧暴风哭泣

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python正则表达式函数match()和search()使用全面指南

    Python正则表达式函数match()和search()使用全面指南

    在Python中,正则表达式是强大的工具,能够用于文本匹配、搜索和替换,re模块提供了许多函数来处理正则表达式,其中match()和search()是两个常用的函数,本文将深入探讨这两个函数的用法、区别和示例,帮助你更好地理解它们的功能
    2024-01-01
  • python 绘制3D图案例分享

    python 绘制3D图案例分享

    这篇文章主要介绍了python 绘制3D图案例分享,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-07-07
  • 浅谈python 调用open()打开文件时路径出错的原因

    浅谈python 调用open()打开文件时路径出错的原因

    这篇文章主要介绍了浅谈python 调用open()打开文件时路径出错的原因,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • 关于pyinstaller生成.exe程序报错:缺少.ini文件的分析

    关于pyinstaller生成.exe程序报错:缺少.ini文件的分析

    这篇文章主要介绍了关于pyinstaller生成.exe程序报错:缺少.ini文件的分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Python爬虫进阶之Beautiful Soup库详解

    Python爬虫进阶之Beautiful Soup库详解

    这篇文章主要介绍了Python爬虫进阶之Beautiful Soup库详解,文中有非常详细的代码示例,对正在学习python爬虫的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • Pandas爆炸函数的使用技巧

    Pandas爆炸函数的使用技巧

    同事举了个简单的例子来说明爆炸函数的功能,我当场就记下了这个函数名称:爆炸函数。Hive在我的工作中使用的并不多,于是我在想:Pandas能够实现这个功能吗?本文就来了解一下
    2021-05-05
  • 在python中实现强制关闭线程的示例

    在python中实现强制关闭线程的示例

    今天小编就为大家分享一篇在python中实现强制关闭线程的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Python学习之加密模块使用详解

    Python学习之加密模块使用详解

    加密模块在工作中被广泛应用。比如数据的传入 不希望被捕获,通过把数据加密,这样即使被捕获也无法获取到数据的真实信息。本文将学习一下Python中的加密模块的使用 方法,需要的可以参考一下
    2022-03-03
  • WIndows10系统下面安装Anaconda、Pycharm及Pytorch环境全过程(NVIDIA GPU版本)

    WIndows10系统下面安装Anaconda、Pycharm及Pytorch环境全过程(NVIDIA GPU版本)

    这篇文章主要给大家介绍了关于WIndows10系统下面安装Anaconda、Pycharm及Pytorch环境(NVIDIA GPU版本)的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • Python动态导入模块的方法实例分析

    Python动态导入模块的方法实例分析

    这篇文章主要介绍了Python动态导入模块的方法,结合实例形式较为详细的分析了Python动态导入系统模块、自定义模块以及模块列表的相关操作技巧,需要的朋友可以参考下
    2018-06-06

最新评论