[tensorflow]如何处理样本不均衡?

样本不均衡的主要处理方法有:

1、上采样

2、下采样

3、构造少量样本

4、修改loss函数


其中修改loss函数也有不同的方法,包括交叉熵、Focal Loss等,本文主要讲TensorFlow中交叉熵损失函数如何实现样本不均衡的处理。这是一种比较常见的损失函数。


TensorFlow中有四种交叉熵的实现,分别如下:

  • tf.nn.sigmoid_cross_entropy_with_logits
  • tf.nn.softmax_cross_entropy_with_logits
  • tf.nn.sparse_softmax_cross_entropy_with_logits
  • tf.nn.weighted_cross_entropy_with_logits

  • [tensorflow]如何处理样本不均衡?


    注意这四个函数使用的情况是不同的,下面我会分别将这几个函数的原理和作用场景


    tf.nn.sigmoid_cross_entropy_with_logits和tf.nn.weighted_cross_entropy_with_logits是直接通过logits进行sigmoid,然后输出每个类别的概率。一般用在多标签分类,如一张图片可以同时是狗和猫。


    比如 上面的例子,三分类时,模型的 logist 为 [3, 3, 1]。输入标签为[1, 1, 0],表示这张图片既属于猫也属于狗,tf.nn.sigmoid_cross_entropy_with_logits的计算公式为:

    <code>z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))/<code>

    根据上面的例子,将logist每一维度进行sigmoid为[0. 6, 0.6, 0.2] ,然后再和[1, 1, 0]相乘。

    然后加上[0, 4, 0.4, 0.8] 和 [0, 0, 1](1-z的值)相乘结果。

    本质上这是把每个label的维度都当做一个二分类,然后把所有的二分类的的交叉熵损失函数相加。


    tf.nn.weighted_cross_entropy_with_logits的作用是对每个二分类的标签,给正样本赋更高的权重,从而处理样本不均衡问题。


    tf.nn.sigmoid_cross_entropy_with_logits和tf.nn.softmax_cross_entropy_with_logits都是对单标签分类进行处理,也就是说每个样本分类的值是唯一的。


    tf.nn.sigmoid_cross_entropy_with_logits和tf.nn.softmax_cross_entropy_with_logits的不同在于前者输入是onehot向量,后者是单个维度的标签值,这样在类别很多的情况下,能节省资源,计算得更快。


    那么这种情况的样本不均衡怎么处理呢?

    我一般的做法是在lable上做手脚,因为交叉熵需要乘以一个label项,将onehot向量放大相应的倍数就可以达到对loss进行加权的目的,比如我们有样本数目A,B,C类分别为6W 、1.5W、1W的数据,我们的损失函数的代码可以写成:

    <code>class_weights = tf.constant([[1.0, 4.0, 6.0]])
    weights = tf.reduce_sum(class_weights * self.label, axis=1)
    unweight_loss = tf.nn.softmax_cross_entropy_with_logits(labels=self.label, logits=logits)

    self.loss = self.cross_entropy = tf.reduce_mean(weights * unweight_loss)/<code>

    参考文献:

    [1] https://zhuanlan.zhihu.com/p/67650069

    [2] https://www.jianshu.com/p/88d1eac07d57


    如果觉得内容不错或者有问题,可以在评论区留言,或者私信我,谢谢大家!


    分享到:


    相關文章: