NLP类别不均衡问题之loss合集

nlp 任务中,数据类别不均衡问题应该是一个极常见又头疼的的问题了。最近在工作中也是碰到这个问题,花了些时间梳理并实践了下类别不均衡问题的解决方式,主要实践了下“魔改”loss(focal loss, ghm loss, dice loss 等),整理了下。所有的 loss 实践代码在这里:
https://github.com/shuxinyin/nlp-loss-pytorch
数据不均衡问题也可以说是一个长尾问题,但长尾那部分数据往往是重要且不能被忽略的,它不仅仅是分类标签下样本数量的不平衡,实质上也是 难易样本的不平衡 。
解决不均衡问题一般从两方面入手:
数据层面:重采样,使得参与迭代计算的数据是均衡的;模型层面:重加权,修改模型的 loss,在 loss 计算上,加大对少样本的 loss 奖励。数据层面的重采样
关于数据层面的重采样,方式都是通过采样,重新构造数据分布,使得数据平衡。一般常用的有三种:1)欠采样;2)过采样;3)smote。
欠采样:指某类别下数据较多,则只采取部分数据,直接抛弃一些数据,这种方式太简单粗暴,拟合出来的模型的偏差大,泛化性能较差;过采样:这种方式与欠采样相反,某类别下数据较少,进行重复采样,达到数据平衡。因为这些少的数据反复迭代计算,会使得模型产生过拟合的现象。smote:一种近邻插值,可以降低过拟合风险,但它是适用于回归预测场景下,而 nlp 任务一般是离散的情况。这几种方法单独使用会或多或少造成数据的浪费或重,一般会与 ensemble 方式结合使用,sample 多份数据,训练出多个模型,最后综合。
但以上几种方式在工程实践中往往是少用的,一是因为数真实据珍贵,二也是 ensemble 的方式部署中资源消耗大,没法接受。因此,就集中看下重加权 loss 改进的部分。
模型层面的重加权
重加权主要指的是在 loss 计算阶段,通过设计 loss,调整类别的权值对 loss 的贡献。比较经典的 loss 改进应该是 focal loss, ghm loss, dice loss。
2.1 focal loss
focal loss 是一种解决不平衡问题的经典 loss,基本思想就是把注意力集中于那些预测不准的样本上。
何为预测不准的样本?比如正样本的预测值小于 0.5 的,或者负样本的预测值大于 0.5 的样本。再简单点,就是当正样本预测值>0.5 时,在计算该样本的 loss 时,给它一个小的权值,反之,正样本预测值 0).sum().item() gd = bin_count * nonempty_bins gd = torch.clamp(gd, min=0.0001) beta = n / gd # 计算好样本的gd值 # 借由binary_cross_entropy_with_logits,gd值当作参数传入 return f.binary_cross_entropy_with_logits(x, target, weight=beta[bin_idx])2.3 dice loss & dsc loss
dice loss 是来自文章 v-net 提出的,dsc loss 是香侬科技的 dice loss for data-imbalanced nlp tasks。
按照上面的逻辑,看一下 dice loss 是怎么演变过来的。dice loss 主要来自于 dice coefficient,dice coefficient 是一种用于评估两个样本的相似性的度量函数。
定义是这样的:取值范围在 0 到 1 之间,值越大表示越相似。若令 x 是所有模型预测为正的样本的集合,y 为所有实际上为正类的样本集合,dice coefficient 可重写为:
同时,结合 f1 的指标计算公式推一下,可得:
可以动手推一下,就能得到 dice coefficient 是等同 f1 score 的,**因此本质上 dice loss 是直接优化 f1 指标的。 **
上述表达式是离散的,需要把上述 dsc 表达式转化为连续的版本,需要进行软化处理。对单个样本 x,可以直接定义它的 dsc:
但是当样本为负样本时,y1=0,loss 就为 0 了,需要加一个平滑项。
上面有说到 dice coefficient 是一种两个样本的相似性的度量函数,上式中,假设正样本 p 越大,dice 值越大,说明模型预测的越准,则应该 loss 值越小,因此 dice loss 的就变成了下式这也就是最终 dice loss 的样子。
为了能得到 focal loss 同样的功能,让 dice loss 集中关注预测不准的样本,可以与 focal loss 一样加上一个调节系数 ,就得到了香侬提出的适用于 nlp 任务的自调节 dsc-loss。
弄明白了原理,看下代码的实现。
class dscloss(torch.nn.module): def __init__(self, alpha: float = 1.0, smooth: float = 1.0, reduction: str = mean): super().__init__() self.alpha = alpha self.smooth = smooth self.reduction = reduction def forward(self, logits, targets): probs = torch.softmax(logits, dim=1) probs = torch.gather(probs, dim=1, index=targets.unsqueeze(1)) probs_with_factor = ((1 - probs) ** self.alpha) * probs loss = 1 - (2 * probs_with_factor + self.smooth) / (probs_with_factor + 1 + self.smooth) if self.reduction == mean: return loss.mean()总结
本文主要讨论了类别不均衡问题的解决办法,可分为数据层面的重采样及模型 loss 方面的改进,如 focal loss, dice loss 等。最后说一下实践下来的经验,由于不同数据集的数据分布特点各有不同,dice loss 以及 ghm loss 会出现些抖动、不稳定的情况。当不想挨个实践的时候,首推 focal loss,dice loss。

基于DDK的TLV320AIC23音频编解码器驱动程序设计
四通道高速直接数字频率合成器AD9959的功能特点和应用
鸿海的面板工厂再陷亏损 夏普电视难与中国电视竞争
关于汽车线束测试,你了解多少?
艾拉比芮亚楠:当OTA普及,我们将在物联网和车联网看到三个变化
NLP类别不均衡问题之loss合集
国产操作系统到底什么水平?鸿蒙能否后来者居上
UIS测试是什么?雪崩能量对实际应用的影响
联想推出K5 Pro国民手机,支持18W QC3.0快充实现充电五分钟追剧一小时
LED显示屏成为LED应用领域最成熟的细分市场
NVIDIA高性能GPU硬件助力Cloudpick智能门店数字化运营
关于土壤温湿度测量仪的作用以及功能的分析
Qualcomm发布骁龙虚拟现实软件开发包
红米S2评测 同价位竞品强势红米S2主攻线下
如何正确教育青少年使用应用程序与科技?
优化的Micrium OS和新Platform Builder加速嵌入式的设计
NASA的开源软件是什么?NASA的开源软件的详细分析
近红外光谱技术发展及原理
webgis的开发技术分析
红米Note7系列全球销量突破2000万台