pytorch实现focal loss的两种方式小结
作者:WYXHAHAHA123 发布时间:2023-07-02 14:43:22
标签:pytorch,focal,loss
我就废话不多说了,直接上代码吧!
import torch
import torch.nn.functional as F
import numpy as np
from torch.autograd import Variable
'''
pytorch实现focal loss的两种方式(现在讨论的是基于分割任务)
在计算损失函数的过程中考虑到类别不平衡的问题,假设加上背景类别共有6个类别
'''
def compute_class_weights(histogram):
classWeights = np.ones(6, dtype=np.float32)
normHist = histogram / np.sum(histogram)
for i in range(6):
classWeights[i] = 1 / (np.log(1.10 + normHist[i]))
return classWeights
def focal_loss_my(input,target):
'''
:param input: shape [batch_size,num_classes,H,W] 仅仅经过卷积操作后的输出,并没有经过任何激活函数的作用
:param target: shape [batch_size,H,W]
:return:
'''
n, c, h, w = input.size()
target = target.long()
input = input.transpose(1, 2).transpose(2, 3).contiguous().view(-1, c)
target = target.contiguous().view(-1)
number_0 = torch.sum(target == 0).item()
number_1 = torch.sum(target == 1).item()
number_2 = torch.sum(target == 2).item()
number_3 = torch.sum(target == 3).item()
number_4 = torch.sum(target == 4).item()
number_5 = torch.sum(target == 5).item()
frequency = torch.tensor((number_0, number_1, number_2, number_3, number_4, number_5), dtype=torch.float32)
frequency = frequency.numpy()
classWeights = compute_class_weights(frequency)
'''
根据当前给出的ground truth label计算出每个类别所占据的权重
'''
# weights=torch.from_numpy(classWeights).float().cuda()
weights = torch.from_numpy(classWeights).float()
focal_frequency = F.nll_loss(F.softmax(input, dim=1), target, reduction='none')
'''
上面一篇博文讲过
F.nll_loss(torch.log(F.softmax(inputs, dim=1),target)的函数功能与F.cross_entropy相同
可见F.nll_loss中实现了对于target的one-hot encoding编码功能,将其编码成与input shape相同的tensor
然后与前面那一项(即F.nll_loss输入的第一项)进行 element-wise production
相当于取出了 log(p_gt)即当前样本点被分类为正确类别的概率
现在去掉取log的操作,相当于 focal_frequency shape [num_samples]
即取出ground truth类别的概率数值,并取了负号
'''
focal_frequency += 1.0#shape [num_samples] 1-P(gt_classes)
focal_frequency = torch.pow(focal_frequency, 2) # torch.Size([75])
focal_frequency = focal_frequency.repeat(c, 1)
'''
进行repeat操作后,focal_frequency shape [num_classes,num_samples]
'''
focal_frequency = focal_frequency.transpose(1, 0)
loss = F.nll_loss(focal_frequency * (torch.log(F.softmax(input, dim=1))), target, weight=None,
reduction='elementwise_mean')
return loss
def focal_loss_zhihu(input, target):
'''
:param input: 使用知乎上面大神给出的方案 https://zhuanlan.zhihu.com/p/28527749
:param target:
:return:
'''
n, c, h, w = input.size()
target = target.long()
inputs = input.transpose(1, 2).transpose(2, 3).contiguous().view(-1, c)
target = target.contiguous().view(-1)
N = inputs.size(0)
C = inputs.size(1)
number_0 = torch.sum(target == 0).item()
number_1 = torch.sum(target == 1).item()
number_2 = torch.sum(target == 2).item()
number_3 = torch.sum(target == 3).item()
number_4 = torch.sum(target == 4).item()
number_5 = torch.sum(target == 5).item()
frequency = torch.tensor((number_0, number_1, number_2, number_3, number_4, number_5), dtype=torch.float32)
frequency = frequency.numpy()
classWeights = compute_class_weights(frequency)
weights = torch.from_numpy(classWeights).float()
weights=weights[target.view(-1)]#这行代码非常重要
gamma = 2
P = F.softmax(inputs, dim=1)#shape [num_samples,num_classes]
class_mask = inputs.data.new(N, C).fill_(0)
class_mask = Variable(class_mask)
ids = target.view(-1, 1)
class_mask.scatter_(1, ids.data, 1.)#shape [num_samples,num_classes] one-hot encoding
probs = (P * class_mask).sum(1).view(-1, 1)#shape [num_samples,]
log_p = probs.log()
print('in calculating batch_loss',weights.shape,probs.shape,log_p.shape)
# batch_loss = -weights * (torch.pow((1 - probs), gamma)) * log_p
batch_loss = -(torch.pow((1 - probs), gamma)) * log_p
print(batch_loss.shape)
loss = batch_loss.mean()
return loss
if __name__=='__main__':
pred=torch.rand((2,6,5,5))
y=torch.from_numpy(np.random.randint(0,6,(2,5,5)))
loss1=focal_loss_my(pred,y)
loss2=focal_loss_zhihu(pred,y)
print('loss1',loss1)
print('loss2', loss2)
'''
in calculating batch_loss torch.Size([50]) torch.Size([50, 1]) torch.Size([50, 1])
torch.Size([50, 1])
loss1 tensor(1.3166)
loss2 tensor(1.3166)
'''
来源:https://blog.csdn.net/WYXHAHAHA123/article/details/88343945


猜你喜欢
- 1.urlopen()方法urllib.urlopen(url[, data[, proxies]]) :创建一个表示远程url的类文件对象
- 写个小教程,以期能让大家对jQuery有所了解,甚至喜欢上它(请不要怪我)。不废话,先说明我们的目的。我们知道,当代浏览器(modern b
- 正在看的ORACLE教程是:Oracle与SQL Server在企业应用的比较。在我供职的公司不仅仅拥有Oracle数据库,同时还拥有SQL
- 本文实例为大家分享了python3 pillow模块验证码的具体代码,供大家参考,具体内容如下直接放代码吧,该写的注释基本都写了# -*-
- 目前使用MySQL的网站,多半同时使用Memcache作为键值缓存。虽然这样的架构极其流行,有众多成功的案例,但过于依赖Memcache,无
- 一、线程编程(Thread)1、线程基本概念1.1、什么事线程线程被称为轻量级的进程线程也可以使用计算机多核资源,是多任务编程方式线程是系统
- 1,不带参数的存储过程2,带输入参数的存储过程3,带输入和输出参数的存储过程4,带返回值的存储过程不带参数的存储过程例如,以下存储过程返回E
- Frame切换在本文中,将介绍如何使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换。1、Fram
- 废话不多说了,具体代码如下所示:<html><head>< >function selectAll(){
- 本文实例讲述了JS求解三元一次方程组值的方法。分享给大家供大家参考,具体如下:// 求用js 码一段代码求 三元一次方程组的值!// a1
- 1. 介绍上传的图片文件:如pic = request.FILES["picture"]# pic是 <class
- 本文实例讲述了python版本的读写锁操作方法。分享给大家供大家参考,具体如下:最近要用到读写锁的机制,但是python2.7的自带库里居然
- 画布可以做很多事情,比如可以绘图,也可以做海报。在这里只是想拿它来的实现亲笔签名,开启不一样的亲笔签名姿势。开发框架:uniapp开发语言:
- JOSN字符串转换为自定义类实例对象有时候我们有这种需求就是把一个JSON字符串转换为一个具体的Python类的实例,比如你接收到这样一个J
- 内容摘要:当我们不想让某IP服务我们的网站时,我们就要写段程序来限制IP地址。asp中如何对ip进行过滤限制?本文介绍了一种方法,这个函数只
- 场景:按下按钮,将左边的下拉选框内容发送给后端,后端再将返回的结果传给前端显示。按下按钮之前:按下按钮之后:代码结构这是flask默认的框架
- 项目中有这样的需求,通过IP地址判断客户端是网通的还是电信的。从同事那拿了个纯文本的IP纯真数据库,用Python写了一个小程序,感觉挺好的
- 不管是录入信息时需要用扫码器扫码录入、核对信息时用于扫码识别,还是有别的生成条形码的需要,那我们如何把表格中的数字、文本列快速生成条形码图片
- 首先呢,我们来看看一般项目路由是怎么划分的。为什么这么划分呢?如果大项目业务非常多,单纯的单页面很难维护,我们只有这样规范化,才能高效率。模
- 一、现象最近在数据库中删除了一张表,重新执行python manage.py migrate时出错,提示不存在这张表。通过查找相关的资料,最