样本分布不平衡的问题的解决策略调研
0. 前言
文中公式和文字内容可能有误
1. 基于Re-weighting (Loss加权) 的方法
这一类方法通过修正不同类别的Loss权重,达成对长尾分布中尾部类别的补偿
1.1 Class-Balanced Loss Based on Effective Number of Samples (CVPR2019)
研究动机
- 解决长尾分布的通常方法包括重采样(Re-sampling)和Loss加权/重加权(Re-weighting)两种方法。对于重采样,对头部分类(主要类别)欠采样可能导致丢弃有价值的样本,而过采样会导致引入重复样本,造成过拟合或者延长训练时间。因此Re-weighting的方法更好
- 通常对Loss加权的权重 $w_i$反比与类别的$i$样本数量$c_i$,但是已有证明这样效果不好。因此,一种新的Re-weighting的方法对于处理长尾问题有价值
主要贡献
- 提出了一种基于Reweighting的长尾训练方法,使用“有效样本数量” (Effective Number of Samples)设计Loss中关于分类的加权项(即class-balance term)的取值。
- 在常用的Loss函数(如Sigmoid交叉熵、Softmax交叉熵、Focal Loss等)前附加上述的加权系数,就能够实现较好的性能提升。
算法内容
问题定义
作者将采样过程定义为一个简化的随机覆盖问题。数据集中的样本不再被看成一个单独的点,而是被看做一个小块的区域。即每一个样本可能和其它的样本之间有一定概率重合。设同一类的样本在特征空间中构成的集合为$S$,容量(原文是Volume,这里翻译可能不正确)是$N$,每一个其中样本具有单位容量$1$。
有效样本数量(Effective number of samples)定义为集合的期望容量。
采样过程被定义为一个覆盖过程,一个新采样的样本有$p$概率在已经采样的样本构成的集合中,有$(1-p)$概率在其之外。另外类别中样本越多,新采样的样本被已采样的样本覆盖的可能性更高。这里的覆盖表征的是同一类别中两个不同样本的相似性,$N$越大,表示着$S$中原始的独特样本越多(即数据增强之前的差别大的样本)。
系数计算
定义 $E_n$为采样$S$中$n$个样本时,获得的期望有效样本数量的个数,那么可以根据数学归纳法推出
$$
E_n=\frac{1-\beta^n}{1-\beta}
$$
其中超参$\beta=(N-1)/N$,如果$\beta\to1$表示类别中每一个样本都是独一无二的;反之$\beta\to0$表示所有样本都重叠。
修正Loss
在实践中,对于每一个类别需要设定一个$N_i,\beta_i$,但是实现起来不方便(超参不好确定),因此可以对一个数据集下的所有类别使用同一个超参$N$和$\beta$。设$n_i$为第$i$类的样本数,则定义权重参数$c_i$
$$
c_i=\frac{1}{E_{n_i}}
$$
保证Loss的尺度在加上权重项和之前一样,对其归一化得到规范化权重参数$\alpha_i$,其中$C$是总共类别数量
$$
\alpha_i=\frac{c_iC}{\sum_{i=1}^C c_i}
$$
在原有Loss前附加一个修正项$\alpha_i$即得到类平衡(Class-balanced)修正后的Loss函数。比如Class-balanced Softmax如下
$$
CB_{softmax}(\mathbf{z},y)=-\alpha_{n_y}\log\left(\frac{\exp(z_y)}{\sum_{i=1}^C\exp(z_i)}\right)
$$
实验结果
在Longtail CIFAR-10上,使用超参$\beta=0.9999$,约降低使用系数之前3%的错误率。
在Longtail CIFAR-100上,使用超参$\beta=0.99$和FocalLoss或Sigmoid时,降低使用系数之前1%错误率
代码
PyTorch: https://github.com/vandit15/Class-balanced-loss-pytorch
1.2 Distributional Robustness Loss for Long-tail Learning (ICCV2021)
研究动机
- 传统训练策略遵循最小化经验风险(Empirical Risk Minimization)的策略,缺陷是训练分布和真实(测试)分布一致,这显然是难以实现的。因此,引入Distributionally Robust Optimization (DRO) 能够有效解决长尾问题。(鲁棒性优化还没看)
- 将DRO的思想引入到长尾Loss的设计上:已有小样本的中心和其实际分布中心差距很大,通过DRO优化可能的最坏情况可以缓解这一问题。
主要贡献
- 将数据不平衡下的学习问题,定义为鲁棒性优化问题。
- 设计了一个新的Loss,DRO-LT。基于DRO-LT训练能够同时覆盖头部和尾部分类表征
- 在CIFAR100-LT等数据集上测试,得到了好的效果。
代码
PyTorch: https://github.com/dvirsamuel/DRO-LT
1.3 Asymmetric Loss For Multi-Label Classification (ICCV2021)
研究动机
- 重采样方法不适用于多标签任务
- 多任务语境下正负标签数量不均衡,一张图可能有几个Positive的标签,但是有很多Negative的标签。(Positive-negative imbalance)
- Focal Loss更聚焦于困难样本,因此有理由认为多任务中类似Focal-Loss的思路也有效果——使得模型更关注于困难的负样本(Hard Negative Samples)。但是Focal Loss中正负类别共用超参数可能不合理——在Positive-negative imbalance假设下,负样本数量更多,导致Focal Loss忽略数量少的正样本。基于正负样本的非对称性,作者认为具有改进空间。
主要贡献
- 提出了基于Positive-negative imbalance和解决Groundtruth错误标签(Mis-labeling)的“非对称Loss” (Asymmetric Loss, ASL)
- 研究了ASL的性质,提出了控制Loss超参的一些方法
- 在MS-COCO数据集上取得了更好的效果,且不需要花费额外推理和训练时间
算法定义
非对称聚焦
类比于Focal Loss的$\gamma$值,作者将其对正负样本解耦,即定义$\gamma_+$和$\gamma_-$,之后正类别Loss$L_+$和负类别Loss$L_-$定义为
$$
L_+=(1-p)^{\gamma_+}\log(p);L_-=p^{\gamma_-}\log(1-p)
$$
根据正负样本不平衡的经验假设,有约束$\gamma_->\gamma_+$。在约束下,负样本的Loss权重衰减比正样本Loss衰减更大,帮助网络从正样本处学习特征,缓解正样本少造成学习情况不佳的问题。
非对称概率分布偏移
由于多标签分类中的不平衡程度可能非常高,因此这种衰减(非对称聚焦)并不总是足够的。基于此,作者提出了额外的非对称机制,即非对称概率偏移。记偏移后的概率是$p_m$,则
$$
p_m=\max(p-m,0)
$$
定义中$m\geq 0$是可调超参数。
偏移后,网络在对低概率负样本(Easy Negative Sample)预测时,其对Loss的贡献被直接丢弃,从而进一步使得网络关注正样本。
ASL定义
基于以上的非对称机制,可以定义ASL函数,即
$$
L_+=(1-p)^{\gamma_+}\log(p);L_-=p^{\gamma_-}_m\log(1-p_m)
$$
ASL具有三个超参数:$\gamma_+,\gamma_-,m$,由于作者基于正样本数小于负样本数量的假设,因此要求不高时,正样本Loss不需要衰减,直接使用交叉熵即可($\gamma_+=0$)。基于这三个参数,ASL提供三种机制解决正负不平衡问题。
- (A) Hard thresholding:对于负样本$p<m$,直接丢弃这些简单负样本(使得网络关注困难样本)
- (B) Soft thresholding:对于负样本$p>m$,Loss具有一定衰减
- (C) Mislabeld:即非常困难的负样本(Hard negative),认为是错误标记,此时其对Loss贡献值为0
梯度分析中的,负样本ASL函数类似于负偏态分布函数(?),即$p$小时,Loss小,$p$大时Loss梯度大,$p$接近于1时,认为错误样本,此时Loss梯度仍然很小
自适应非对称性调整
ASL的几个超参数描述了正负样本的非对称性,作者提出了自适应调整这些参数的方法。即每一个Epoch后,更新一次$\gamma_-$
$$
\gamma_-\gets\gamma_-+\lambda(\Delta p-\Delta p_{target})
$$
其中$\Delta p$是平均的正样本概率与负样本概率差值。
实验结果
在MS-COCO数据集上较原有的SOTA模型,mAP提高2.8%;Pascal-VOC上,较原有SOTA模型,mAP提高0.6%;
代码
PyTorch: https://github.com/Alibaba-MIIL/ASL
1.4 Distribution-Balanced Loss for Multi-Label Classification in Long-Tailed Datasets (ECCV2020)
研究动机
- 已有的多标签学习方法(如使用BCELoss、在Loss前加一个反比与类别中样本数的系数)忽略了多标签数据集的两个重要特征,即标签共存(Label co-occurrence,一个样本中具有多个标签)和负标签支配(Dominance of negative labels,即大多数样本中仅有少数正标签,大多数为负标签,对于尾部类别而言,该现象更严重。这一假设和论文Asymmetric Loss For Multi-Label Classification相同)
- 标签共存问题造成MLD的重采样难以进行,一般重采样方法很难按照类别对采样进行平衡
- 负标签支配问题造成Loss中对负样本施加更大的惩罚项,从而导致正样本被忽略的问题(尤其是长尾分布中的尾部类别),作者将这种现象定义为负标签过抑制(over-suppression of negative labels)
- 基于上述两个问题,可以导出两个优化方向
- 在Loss中添加一个系数项,补偿由于采样造成的不平衡问题(即Rebalance Weighting)。通过这一项补偿某个样本预期采样次数和实际采样次数之间的差距
- 在Loss中引入抗负样本的正则化项目,避免原有Loss对负样本施加过大惩罚。
主要贡献
- 针对重采样困难和M正负样本失衡这两个MLD中常见非对称问题,对BCELoss引入两个修正项,进而提出Distribution-Balanced Loss(DBL)函数。基于消融实验,证明两个修正项的有效性。
- 使用DBL,在VOC-MLT和COCO-MLT等数据集上取得比原有SOTA模型更好的结果
算法定义
重采样后的重平衡赋权(Re-balancing Weighting)
以Class-aware的采样方法为例,设随机选取一个类别的样本,该样本有标签$i$的概率是$\hat{p_i}$,$C$是总标签数量,$n_x$表示满足标签条件$x$的样本数量。$\hat{p_i}$等于
$$
\hat{p_i}=\frac{1}{C}\sum_{j=1}^C\frac{n_{i\cap j}}{n_j}
$$
定义按照Class-aware方法,不考虑标签重叠(Label co-occurrence)时,一个具有标签$i$的样本$x^k$被采样到概率记作
$$
P^C_i(x^k)=\frac{1}{Cn_i}
$$
引入Label co-occurrence后,样本被采样到的概率记作$P^I(x^k)$
$$
P^I(x^k)=\frac{1}{C}\sum_{y_i^k=1}\frac{1}{n_i}
$$
实际采样概率$P^I$和期望采样概率$P^C_i$之间的差距记作$r^k_i$,有
$$
r^k_i=\frac{P^C_i(x^k)}{P^I(x^k)}
$$
避免极端情况下参数取值极端,用类Sigmoid的函数对$r^k_i$规范化
$$
\hat{r^k_i}=\alpha+sigmoid(-\beta(r_i^k-\mu))
$$
之后导出重平衡赋权后的BCELoss,即在每一类后面乘一个$\hat{r_i^k}$
$$
L_{R-BCE}(x^k,y^k)=\frac{1}{C}\sum_{i=0}^C\left(y_i^k\log(1+\exp(z^k_i))+(1-y_i^k)\log(1+\exp(-z^k_i))\right)\hat{r_i^k}
$$
抗负样本的正则化项
$$
L_{NT-BCE}(x^k,y^k)=\frac{1}{C}\sum_{i=0}^C\left(y_i^k\log(1+\exp(z^k_i-v_i)+\frac{1}{\lambda}(1-y_i^k)\log(1+\exp(-\lambda(z^k_i-v_i))\right)
$$
其中参数$\lambda$控制抗负样本的程度(值越大,同样的负Logit对应的梯度值越小,Loss函数在接近Logit=0处越陡)
关于另一个参数$v_i$,作者给出解释如下:
可以理解为,给每个类别的输出添加一个随样本频率递增的额外 bias (也相当于初始化),因为即使不这样,训练集的样本分布也会自然让网络学出一个不均衡的全连接层偏置量,手动初始化 bias 可以把这种本征概率分布 encode 进学习过程中,便于网络更多地学习频率分布之外的类别特征。
DBLoss
综合上述两个Loss,得到最终Loss
$$
L_{NT-BCE}(x^k,y^k)=\frac{1}{C}\sum_{i=0}^C\left(y_i^k\log(1+\exp(z^k_i-v_i)+\frac{1}{\lambda}(1-y_i^k)\log(1+\exp(-\lambda(z^k_i-v_i))\right)\hat{r_i^k}
$$
实验结果
VOCMLT上Tail类别高5.34%,总共高2.49%。COCOMLT上表现也很好
代码
PyTorch https://github.com/wutong16/DistributionBalancedLoss
论文地址
Distribution-Balanced Loss for Multi-Label Classification in Long-Tailed Datasets
https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123490154.pdf
https://zhuanlan.zhihu.com/p/187552464
2. 基于Re-sample (重采样) 的方法
这一类方法通过修正采样时不同类别的采样概率,达成对长尾分布中尾部类别的补偿
2.1 Decoupling representation and classifier for long-tailed recognition (ICLR2020)
研究动机
- 已有研究缺乏对长尾学习效果的分析——一个好的模型来自于其更好的表征,还是通过对分类器中决策边界的移动达到对不平衡类别更好的效果。因此作者将模型训练拆成了特征学习和分类两部分,进行实验。
主要贡献
- 全程对分类器按照Class-balanced的方式采样(即每一个类别采样概率相同),效果不一定好。
- 对一个训练好的Joint Model(即原有模型,包括特征提取部分+分类器)的分类器按Class-Balanced进行Retrain效果更好。
- 将这个训练策略应用到常见模型上,在ImageNet-LT,Places-LT,iNaturalist上效果超出已有的SOTA模型
算法内容
采样策略定义
一个类别$j$中的样本被采样到的概率定义如下,其中$n_j^q$表示第$j$类中的样本数量,$C$为类别数量。
$$
p_j=\frac{n_j^q}{\sum_{i=1}^Cn_i^q}
$$
参数$q$则定义了采样策略。对于$q=1$,则每一个样本有均等概率取得,此时采样策略是Instance-balanced(基于实例平衡的)的;对于$q=0$,则每一个类别有均等概率取得,此时采样策略是Class-balanced(基于类别平衡的)的。中间值则是这两种方法的混合。
分类器调整策略定义
将联合模型(Joint Model,即原有模型,包括特征提取部分+分类器)训练好后,冻结特征提取部分网络参数,调整分类器参数的过程称为分类器的调整。作者给出了三种调整策略。
- **分类器重训练 Classfier Re-training (cRT)**:按照Class-balanced策略对分类器参数重置后训练
- **最近类别均值分类器 Nearset Class Mean classifier (NCM)**:先使用训练集计算出个类别的中心 feature tensor,然后每次做预测的时候使用 cosine similarity或者 MSE loss计算出每个样本离这些中心feature的距离。
- τ-normalized classifier :给最后一层的分类器加上正则限制,防止其都预测成类别多的那类。即对第$i$类的分类器参数$w_i$除以$w_i$对的$\tau$范数
实验结果
对于长尾类别,使用Instance-balanced的方法对联合模型训练完后,使用cRT或者τ-norm的方法进行分类器调整效果最好,提高的精确度达到25%左右;对于整体,准确率提升在5%左右。
3. 其他
Just Pick a Sign: Optimizing Deep Multitask Models with Gradient Sign Dropout
研究动机
- 梯度更新得到的局部最优时的参数,通常是较优的。对于多任务的loss平面,每一个任务成分的loss最小值一般在不同的网络参数下取得。因此直接loss加和后更新网络效果可能不好。因此使用联合loss最小值(joint minima)——即一个靠近于所有成分的loss最小值点的临界点上。
- 放任多个多个不同符号梯度值更新一个标量会出现tug-of-wars(拔河)的现象,结果不好。因此所有在一个位置上的梯度更新保证符号相同(pure in sign)
- 梯度随机和模型鲁棒性具有关系。当一个网络找到一个低质量的最小值时,其中批梯度更新内在的噪声会讲模型更新到一个更鲁棒的最小值。因此在梯度(符号?)冲突更大的方向上引入随机性会更好
提出算法
- 在网络负责预测的Head前引入一个Gradient Sign Dropout层。
- 定义正向梯度符号纯度P(Gradient Positive Sign Purity),为正向梯度和与所有梯度绝对值和的比值*0.5+0.5
- 之后对每一个梯度Mi应用如下的Mask
$$
M_i=I(f(P)>U) * I(L_i>0) + I(f(P)<U) * I(L_i<0)
$$
其中U满足(0,1)上的均匀分布,L_i是梯度分量,I是指示函数,f是单调递增函数(通常f(x)=x)。之后按照权重M_i对L_i加权求和得到最终梯度。
- 将GradDrop扩展到batch-separated的梯度上。考虑一个激活层A,则将上述算法中的L_i更改为sgn(A)与Li对A梯度的乘积。
结果
- 在CelebA数据集
- 错误率较Baseline低0.19%,较原有SOTA?低0.08%
- F1较Baseline高0.22,较原有SOTA?高0.15
- 时间消耗上仅为原有Baseline的45%
- 从ImageNet2012到CIFAR-10的迁移学习Loss低于MixedBatch有0.21,错误率低1%
- Waymo数据集上结果也有提升
代码和论文
https://github.com/tensorflow/lingvo/blob/master/lingvo/core/graddrop.py
https://paperswithcode.com/paper/just-pick-a-sign-optimizing-deep-multitask