首页 文章

解决阶级失衡问题:缩减对损失和sgd的贡献

提问于
浏览
29

(An update to this question has been added.)

我是比利时根特大学的研究生;我的研究是用深度卷积神经网络进行情绪识别 . 我正在使用Caffe框架来实现CNN .

最近我遇到了关于 class 不 balancer 的问题 . 我正在使用9216个训练样本,约5%标记为阳性(1),其余样品标记为阴性(0) .

我正在使用SigmoidCrossEntropyLoss图层来计算损失 . 在训练时,即使在几个时期之后,损失也会减少并且准确度非常高 . 这是由于不 balancer :网络总是预测为负(0) . (精确度和召回率均为零,支持此声明)

为了解决这个问题,我想 scale the contribution to the loss depending on the prediction-truth combination (严厉惩罚假阴性) . 我的导师/教练还建议我通过随机梯度下降(sgd):该因子将与批次中的不 balancer 相关联 . 仅包含负样本的批次根本不会更新权重 .

我只向Caffe添加了一个自定义图层:报告其他指标,如精度和召回 . 我对Caffe代码的经验有限,但我有很多编写C代码的专业知识 .


Could anyone help me or point me in the right direction on how to adjust the SigmoidCrossEntropyLoss and Sigmoid layers to accomodate the following changes:

  • 根据预测 - 真值组合调整样本对总损失的贡献(真阳性,假阳性,真阴性,假阴性) .

  • 缩放由随机梯度下降执行的权重更新,具体取决于批次中的不 balancer (负数与正数) .

提前致谢!


更新

我已合并 InfogainLossLayer as suggested by Shai . 我还添加了另一个自定义图层,根据当前批次中的不 balancer 构建了infogain矩阵 H .

目前,矩阵配置如下:

H(i, j) = 0          if i != j
H(i, j) = 1 - f(i)   if i == j (with f(i) = the frequency of class i in the batch)

我计划将来为矩阵试验不同的配置 .

我已经用10:1的不 balancer 测试了这个 . 结果表明网络现在正在学习有用的东西:( 30个时期后的结果)

  • 准确度约为 . ~70%(低于~97%);

  • 精度大约是~20%(从0%起);

  • 召回约 . ~60%(从0%上调) .

这些数字在大约20个时期达到,之后没有显着变化 .

!上述结果仅仅是概念证明,它们是通过在10:1不 balancer 数据集上训练一个简单网络获得的 . !

2 回答

  • 20

    为什么不使用InfogainLoss图层来补偿训练集中的不 balancer ?

    使用权重矩阵 H (在您的情况下为2乘2)定义Infogain损失 . 其条目的含义是

    [cost of predicting 1 when gt is 0,    cost of predicting 0 when gt is 0
     cost of predicting 1 when gt is 1,    cost of predicting 0 when gt is 1]
    

    因此,您可以设置 H 的条目以反映预测0或1时的错误之间的差异 .

    您可以在this thread中找到如何为caffe定义矩阵 H .

    关于样本权重,您可能会发现this post有趣:它显示了如何修改 SoftmaxWithLoss 图层以考虑样本权重 .


    最近,Tsung-Yi Lin, Priya Goyal, Ross Girshick, Kaiming He, Piotr Dollár Focal Loss for Dense Object Detection, (ICCV 2017)提出了对交叉熵损失的修改 .
    焦点损失背后的想法是基于预测该示例的相对难度(而不是基于类大小等)为每个示例分配不同的权重 . 从短暂的时间开始我尝试这种损失,它感觉优于 "InfogainLoss" 与类大小的权重 .

  • 0

    我在分类任务中也遇到了这个类不 balancer 问题 . 现在我正在使用CrossEntropyLoss和重量(文档here),它工作正常 . 这个想法是为具有较少图像数量的类中的样本提供更多损失 .

    计算重量

    每个等级的权重与该等级中的图像数量成反比 . 这是一个使用numpy计算所有课程重量的片段,

    cls_num = []
    # train_labels is a list of class labels for all training samples
    # the labels are in range [0, n-1] (n classes in total)
    train_labels = np.asarray(train_labels)
    num_cls = np.unique(train_labels).size
    
    for i in range(num_cls):
        cls_num.append(len(np.where(train_labels==i)[0]))
    
    cls_num = np.array(cls_num)
    
    cls_num = cls_num.max()/cls_num
    x = 1.0/np.sum(cls_num)
    
    # the weight is an array which contains weight to use in CrossEntropyLoss
    # for each class.
    weight = x*cls_num
    

相关问题