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

作者:*小呆 时间:2021-04-29 00:25:29 

通常,由于类别不均衡,需要使用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()和交叉熵的结合体。

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

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

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

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

nn.Softmax和nn.LogSoftmax

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

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

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

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

果不其然就是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

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

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


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()的表达式:

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

看起来应该是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是一样的结果。为什么这样呢,回想下交叉熵的表达式:

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

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

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

nn.BCELoss

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

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

直觉上和多酚类交叉熵的区别在于,不仅考虑了pytorch 实现二分类交叉熵逆样本频率权重的样本,也考虑了pytorch 实现二分类交叉熵逆样本频率权重的样本的损失。

来源:https://blog.csdn.net/qq_39575835/article/details/104336713

标签:pytorch,交叉熵,样本,权重
0
投稿

猜你喜欢

  • Python删除windows垃圾文件的方法

    2023-08-24 15:38:23
  • 如何把ASP源代码编写成DLL组件

    2007-10-19 13:49:00
  • 从零开始学Golang的接口

    2023-10-09 02:26:03
  • struts2+jsp+jquery+Jcrop实现图片裁剪并上传实例

    2023-06-19 16:30:10
  • 在Python 字典中一键对应多个值的实例

    2023-07-25 23:45:02
  • pandas loc与iloc用法及区别

    2023-01-22 08:26:53
  • Python依赖包整体迁移方法详解

    2022-11-03 05:32:55
  • ASP 下载时重命名已上传文件的新下载文件名的实现代码

    2012-11-30 20:33:45
  • Python操作Jira库常用方法解析

    2022-02-06 01:56:11
  • 2011年网页设计发展趋势

    2011-01-10 20:45:00
  • 使用模板实现ASP代码与页面分离

    2008-09-12 16:07:00
  • pytorch 输出中间层特征的实例

    2022-06-08 07:36:39
  • Python代码实现列表分组计数

    2022-11-03 07:58:38
  • python3.6中anaconda安装sklearn踩坑实录

    2023-03-16 19:17:15
  • Python实现命令行通讯录实例教程

    2023-10-18 01:51:28
  • 缓存是如何实现的?

    2009-11-01 15:35:00
  • python清除字符串里非数字字符的方法

    2023-08-12 02:47:32
  • Python项目 基于Scapy实现SYN泛洪攻击的方法

    2023-01-15 01:34:30
  • javabean servlet jsp实现分页功能代码解析

    2023-06-13 15:21:24
  • php解析字符串里所有URL地址的方法

    2023-08-19 08:31:38
  • asp之家 网络编程 m.aspxhome.com