解决样本不均衡的问题-调整类权重 修改交叉熵loss

处理不平衡数据

我们在进行机器学习和深度学习的时候,常常会遇到样本不均衡的问题,解决样本不均衡的问题常常有以下几种方法,达到平衡数据集:

  1. 过采样少数类
  2. 降采样多数类
  3. 合成新的少数类
  4. 调整类权重(误判成本)

这篇文章就讲如何通过修改交叉熵loss调整类权重


交叉熵误差

交叉熵公式如下

这里,log表示以e为底数的自然对数。y_k是神经网络的输出,t_k是正确的标签。并且,t_k中只有正确的标签的索引为1,其他均为0(one-hot表示)。用mnist数据举例,如果是3,那么标签是[0,0,0,1,0,0,0,0,0,0],除了第4个值为1,其他全为0。

因此,上公式实际上只计算对应正确的标签的输出的自然对数,交叉熵误差的值是由正确的标签所对应的输出结果决定的。

在tensorflow里面,是用

tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y)

来计算交叉熵的。predicttion就是神经网络最后一层的输出,y就是实际的标签。


带权重的交叉熵loss

那么现在我们修改交叉熵loss的权重,要增加少数类的分错的权重,就是在交叉熵的公式里面对应的少数类乘上一个系数:

假设k类里面,第i类是少数类,为了加大分错第类的成本,在交叉熵上给第i类乘以一个大于1的系数,这样如果分错第i类的话,交叉熵loss就会增加。

下面,就用一个二分类的例子的代码来说明一下,以下是用tensorflow来举例。

在硬盘故障预测里面,由于损坏的硬盘数量远远小于健康硬盘的数量,样本极其不均衡,所以通过修稿交叉熵的loss视图体改算法的准确率。

假设健康硬盘样本的标签为[1,0],损坏硬盘样本的标签为[0,1],即在标签中第一个索引为1的是健康硬盘的样本,第二个索引为1的是损坏的样本。

假设在网络中,最后一层输出的结果是prediction,我们要先对prediction做一个softmax,求取输出属于某一类的概率:

yprediction = tf.nn.softmax(prediction)

然后给实际标签乘上一个系数,健康的样本保持系数1不变,损坏样本乘上系数10,这样健康样本的标签就变为[1,0],损坏样本的标签就变为[0,10],再计算交叉熵loss:

coe = tf.constant([1.0,10.0])
y_coe = y*coe
loss = -tf.reduce_mean(y_coe*tf.log(yprediction))

这样就达到了修改交叉熵loss增大分错损坏样本的成本的目的。这时候公式就变为:


tensorflow官方的权重交叉熵

tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None)

参考文献

https://blog.csdn.net/mao_xiao_feng/article/details/53382790
https://www.svds.com/learning-imbalanced-classes/
http://scikitlearn.org/stable/modules/generated/sklearn.utils.class_weight.compute_class_weight.html
深度学习入门-基于python的与实现 by 斋藤康毅

你可能感兴趣的:(深度学习算法)