带权重的损失函数nn.crossEntropyLoss中的weight使用

使用场景

Pytorch的nn.CrossEntropyLoss()的weight使用场景:

现实工程中,经常出现以下情况:

label标注的0-3四类,0类的比重过大,1类其次,2,3类都很少,怎么使用loss的weight来减轻样本不平衡问题?weight参数该如何设置?

此时,

  1. 大体的思想应该是对 样本较多的类别,使用较小的权重惩罚;
  2. 对于样本少的类别,使用较大的权重惩罚;

比如设置loss weight代码,(0.1、 0.8、 1、 1 )四个类别的比例是我自己设置的)

weight=torch.from_numpy(np.array([0.1, 0.8, 1.0, 1.0])).float()

criterion = nn.CrossEntropyLoss(weight=weight).to(device)

2.  问题分析

如何设置weight才能提升分类的性能。

一般情况下,假 n u m m a x num_{max} nummax 表示数量最多类别的样本个数, n u m m i n num_{min} nummin表示数量最少类别的样本个数,当 n u m m a x n u m m i n ≤ 10 \frac{num_{max}}{num_{min}}\leq10 numminnummax10的时候,是不需要考虑样本不平衡问题的。

当它们的比值大于(或者远远)10的时候是要考虑样本不平衡问题,为什么要考虑样本不平衡问题呢?接下来我们来解释一下:

假设有三类,标签类别为0, 1, 2,所对应的样本数量为100000,100, 10。

此时就有一个问题,在网络学习的过程中,假设预测出来的标签都是0(100000个样本),它的准确率为 100000 100110 ≈ 0.9989 \frac{100000}{100110}\approx0.9989 1001101000000.9989 ,将近100%,所以模型就会朝着拟合标签0的方向更新,导致对标签0的样本过拟合,对其它两个类别的样本欠拟合,泛化能力很差。

3. nn.CroEntropyLoss()

那 nn.CrossEntropyLoss()的weight如何解决样本不平衡问题的。

当类别中的样本数量不均衡的时候,

  • 对于训练图像数量较少的类,你给它更多的权重,这样如果网络在预测这些类的标签时出错,就会受到更多的惩罚。

  • 对于具有大量图像的类,您可以赋予它较小的权重。那我们如何选择weight的值呢?

一般有两种方式(建议第二种):

第一种,用样本数的倒数当做权重。即 1 C l a s s S i z e \frac{1}{ClassSize} ClassSize1
用上述的三分类表示就是, w e i g h t = [ 1 100000 , 1 100 , 1 10 ] weight=[\frac{1}{100000}, \frac{1}{100}, \frac{1}{10}] weight=[1000001,1001,101] 。之前测试过几次,这种方式会造成分类准确率下降。

第二种,Max(Numberof occurrences in most common class) / (Number of occurrences in rare classes)。即用类别中最大样本数量除以当前类别样本的数量,作为权重系数。

用上述的三分类表示就是, w e i g h t = [ 100000 100000 , 100000 100 , 100000 10 ] = [ 1.0 , 1000 , 10000 ] weight=[\frac{100000}{100000}, \frac{100000}{100}, \frac{100000}{10}]=[1.0, 1000, 10000] weight=[100000100000,100100000,10100000]=[1.0,1000,10000]

代码表示如下:

weights = [1.0, 1000, 10000]
class_weights = torch.FloatTensor(weights).to(device)
criterion = nn.CrossEntropyLoss(weight=class_weights)


你可能感兴趣的:(#,深度学习,深度学习,机器学习,python)