pytorch实现focal loss的两种方式小结
更新时间:2020年5月2日 10:15 点击:1953
我就废话不多说了,直接上代码吧!
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) '''
以上这篇pytorch实现focal loss的两种方式小结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。
上一篇: PyTorch中topk函数的用法详解
相关文章
pytorch nn.Conv2d()中的padding以及输出大小方式
今天小编就为大家分享一篇pytorch nn.Conv2d()中的padding以及输出大小方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27- 这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
Linux安装Pytorch1.8GPU(CUDA11.1)的实现
这篇文章主要介绍了Linux安装Pytorch1.8GPU(CUDA11.1)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-25- 这篇文章主要介绍了Pytorch之扩充tensor的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-05
- 今天小编就为大家分享一篇pytorch 自定义卷积核进行卷积操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-06
- 这篇文章主要介绍了解决pytorch 交叉熵损失输出为负数的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-08
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
今天小编就为大家分享一篇pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-02- 这篇文章主要介绍了pytorch 实现冻结部分参数训练另一部分,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-27
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
这篇文章主要介绍了从Pytorch模型pth文件中读取参数成numpy矩阵的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-04Pytorch 的损失函数Loss function使用详解
今天小编就为大家分享一篇Pytorch 的损失函数Loss function使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-02- 今天小编就为大家分享一篇pytorch中的上采样以及各种反操作,求逆操作详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-30
- 这篇文章主要介绍了基于Pytorch版yolov5的滑块验证码破解思路详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-25
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
今天小编就为大家分享一篇pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-02- 这篇文章主要介绍了pytorch深度学习中对softmax实现进行了详细解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步...2021-09-30
- 今天小编就为大家分享一篇Pytorch 计算误判率,计算准确率,计算召回率的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
- 今天小编就为大家分享一篇Pytorch实现LSTM和GRU示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
- 这篇文章主要介绍了Pytorch如何切换 cpu和gpu的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-01
- 今天小编就为大家分享一篇pytorch动态网络以及权重共享实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-29
- 这篇文章主要介绍了解决Pytorch修改预训练模型时遇到key不匹配的情况,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-05
- 这篇文章主要介绍了pytorch中的squeeze函数、cat函数使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-05-20