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
投稿

猜你喜欢

  • 分类、属性、关键词与Tag

    2009-08-27 12:57:00
  • python爬虫之基金信息存储

    2021-12-25 03:20:04
  •  Go 语言实现 HTTP 文件上传和下载

    2023-06-23 01:42:24
  • SQL中 patindex函数的用法详解

    2024-01-23 14:55:39
  • Python解压 rar、zip、tar文件的方法

    2023-07-22 10:51:38
  • MySQL 函数过程递归

    2008-07-25 19:32:00
  • Pycharm快捷键配置详细整理

    2021-06-25 05:46:17
  • Python实现视频中添加音频工具详解

    2022-06-03 12:32:28
  • 解决mysql连接超时和mysql连接错误的问题

    2024-01-14 22:16:36
  • python中利用Future对象异步返回结果示例代码

    2021-09-10 06:59:52
  • VSCODE添加open with code实现右键打开文件夹

    2022-02-06 05:09:43
  • 10分钟搭建自己的Git仓库

    2023-05-18 21:10:19
  • python正则表达式函数match()和search()的区别

    2021-10-05 10:25:52
  • Webpack中publicPath路径问题详解

    2024-05-11 09:06:15
  • 关于Python自动化操作Excel

    2022-07-19 23:25:48
  • PyQt5实现画布小程序

    2022-03-02 07:37:46
  • 使用Python制作一个数据预处理小工具(多种操作一键完成)

    2023-07-06 20:50:21
  • python使用pygame框架实现推箱子游戏

    2022-02-12 00:34:13
  • python实现剪切功能

    2023-02-27 17:52:01
  • ubuntu 18.04 安装opencv3.4.5的教程(图解)

    2022-10-29 16:36:01
  • asp之家 网络编程 m.aspxhome.com