pytorch实现focal loss的两种方式小结


Posted in Python onJanuary 02, 2020

我就废话不多说了,直接上代码吧!

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的两种方式小结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
本地文件上传到七牛云服务器示例(七牛云存储)
Jan 11 Python
Python中的__new__与__init__魔术方法理解笔记
Nov 08 Python
github配置使用指南
Nov 18 Python
Python 序列化 pickle/cPickle模块使用介绍
Nov 30 Python
对Python中gensim库word2vec的使用详解
May 08 Python
Sanic框架基于类的视图用法示例
Jul 18 Python
python操作excel的方法
Aug 16 Python
python排序函数sort()与sorted()的区别
Sep 18 Python
python如何获取当前文件夹下所有文件名详解
Jan 25 Python
python 实现绘制整齐的表格
Nov 18 Python
python+opencv3生成一个自定义纯色图教程
Feb 19 Python
python 实现单例模式的5种方法
Sep 23 Python
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
Jan 02 #Python
基于torch.where和布尔索引的速度比较
Jan 02 #Python
Python魔法方法 容器部方法详解
Jan 02 #Python
python 图像的离散傅立叶变换实例
Jan 02 #Python
Python加密模块的hashlib,hmac模块使用解析
Jan 02 #Python
在win64上使用bypy进行百度网盘文件上传功能
Jan 02 #Python
pytorch实现onehot编码转为普通label标签
Jan 02 #Python
You might like
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
wordpress自定义标签云与随机获取标签的方法详解
2019/03/22 PHP
如何使用jquery动态加载js,css文件实现代码
2013/04/03 Javascript
jQuery插件实现屏蔽单个元素使用户无法点击
2013/04/12 Javascript
Jquery通过JSON字符串创建JSON对象
2014/08/24 Javascript
JS对象与json字符串格式转换实例
2014/10/28 Javascript
JQuery显示隐藏DIV的方法及代码实例
2015/04/16 Javascript
javascript实现label标签跳出循环操作
2016/03/06 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
JS+Canvas实现的俄罗斯方块游戏完整实例
2016/12/12 Javascript
vue-router配合ElementUI实现导航的实例
2018/02/11 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
vue.js项目 el-input 组件 监听回车键实现搜索功能示例
2018/08/25 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
2019/01/08 Javascript
小程序红包雨的实现示例
2019/02/19 Javascript
Nest.js散列与加密实例详解
2021/02/24 Javascript
[03:48]大碗DOTA
2019/07/25 DOTA
Python中的descriptor描述器简明使用指南
2016/06/02 Python
对Python中TKinter模块中的Label组件实例详解
2019/06/14 Python
python实现LBP方法提取图像纹理特征实现分类的步骤
2019/07/11 Python
python pygame实现挡板弹球游戏
2019/11/25 Python
python读取mysql数据绘制条形图
2020/03/25 Python
python 线程的五个状态
2020/09/22 Python
韩国保养品、日本药妆购物网:小三美日
2018/12/30 全球购物
eDreams加拿大:廉价航班、酒店和度假
2019/03/29 全球购物
英文版餐饮运营管理求职信
2013/11/06 职场文书
小学生评语集锦
2014/04/18 职场文书
小学端午节活动总结
2015/02/11 职场文书
拾金不昧表扬稿大全
2015/05/05 职场文书
MySQL锁机制
2021/04/05 MySQL
Golang 正则匹配效率详解
2021/04/25 Golang
HTML5中 rem适配方案与 viewport 适配问题详解
2021/04/27 HTML / CSS
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL
springboot 自定义配置 解决Boolean属性不生效
2022/03/18 Java/Android
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js
详解Mysql数据库平滑扩容解决高并发和大数据量问题
2022/05/25 MySQL