(此问题已更新。)
我是比利时根特大学的研究生,我的研究方向是使用深度卷积神经网络进行情感识别。我使用Caffe框架来实现CNNs。
最近我遇到了一个关于类别不平衡的问题。我使用了9216个训练样本,其中大约5%被标记为正类(1),其余样本被标记为负类(0)。
我使用SigmoidCrossEntropyLoss层来计算损失。在训练过程中,损失逐渐减少,并且在几个epoch后准确率极高。这是由于不平衡造成的:网络简单地总是预测负类(0)。(精确率和召回率均为零,支持这一说法)
为了解决这个问题,我希望根据预测-真实组合调整样本对总损失的贡献(严重惩罚假阴性)。我的导师/教练还建议我在通过随机梯度下降(sgd)进行反向传播时使用一个缩放因子:该因子将与批次中的不平衡相关。一个仅包含负样本的批次将不会更新权重。
我只在Caffe中添加了一个自定义层:用于报告其他指标,如精确率和召回率。我对Caffe代码的经验有限,但我有丰富的C++编程经验。
是否有人能帮助我或指导我如何调整SigmoidCrossEntropyLoss和Sigmoid层以适应以下更改:
- 根据预测-真实组合(真阳性、假阳性、真阴性、假阴性)调整样本对总损失的贡献。
- 根据批次中的不平衡(负类与正类)缩放随机梯度下降执行的权重更新。
提前感谢!
更新
我已经按照@某人的建议,加入了InfogainLossLayer。我还添加了另一个自定义层,用于根据当前批次中的不平衡构建信息增益矩阵H
。
目前,矩阵的配置如下:
H(i, j) = 0 if i != jH(i, j) = 1 - f(i) if i == j (其中f(i) = 批次中类别i的频率)
我计划在未来尝试不同的矩阵配置。
我已经在一个10:1的不平衡数据集上进行了测试。结果显示网络现在正在学习有用的东西:(30个epoch后的结果)
- 准确率大约为~70%(从~97%下降);
- 精确率大约为~20%(从0%上升);
- 召回率大约为~60%(从0%上升)。
这些数字在约20个epoch时达到,并且之后没有显著变化。
!! 上述结果仅为概念验证,是通过在一个10:1不平衡数据集上训练一个简单网络获得的。 !!
回答:
为什么不使用InfogainLoss层来补偿训练集中的不平衡呢?
信息增益损失是使用一个权重矩阵H
定义的(在你的情况下是2×2),其条目的含义是
[预测1时实际为0的成本, 预测0时实际为0的成本 预测1时实际为1的成本, 预测0时实际为1的成本]
因此,你可以设置H
的条目来反映预测0或1的错误之间的差异。
你可以在这个线程中找到如何为caffe定义矩阵H
的方法。
关于样本权重,你可能会发现这篇文章很有趣:它展示了如何修改SoftmaxWithLoss层以考虑样本权重。
最近,林宗毅、普里亚·戈亚尔、罗斯·吉尔希克、何恺明、彼得·多拉尔 用于密集对象检测的焦点损失,(ICCV 2017)提出了一种对交叉熵损失的修改。
焦点损失的理念是根据预测每个样本的相对难度为每个样本分配不同的权重(而不是基于类别大小等)。从我短暂试验这个损失的经验来看,它似乎比使用类别大小权重的"InfogainLoss"
更优越。