用于具有大量类的多标签分类的神经网络仅输出零

时间:2017-02-10 11:58:50

标签: machine-learning neural-network classification keras

我正在训练一个用于多标签分类的神经网络,具有大量的类(1000)。这意味着每个输入都可以激活多个输出。平均而言,每个输出帧有两个活动类。在具有交叉熵损失的训练中,神经网络倾向于仅输出零,因为它具有该输出的最小损失,因为99.8%的我的标签是零。关于我如何推动网络给予积极课程更多权重的任何建议?

1 个答案:

答案 0 :(得分:5)

Tensorflow具有丢失函数weighted_cross_entropy_with_logits,可用于为1提供更多权重。因此它应该适用于像您这样的稀疏多标签分类设置。

来自documentation

  

这就像sigmoid_cross_entropy_with_logits(),除了pos_weight,允许通过向上或向下加权相对于负误差的正误差的成本来权衡召回和精确度。

     

参数pos_weight用作正目标的乘数

如果你在Keras中使用tensorflow后端,你可以使用像这样的损失函数(Keras 2.1.1):

import tensorflow as tf
import keras.backend.tensorflow_backend as tfb

POS_WEIGHT = 10  # multiplier for positive targets, needs to be tuned

def weighted_binary_crossentropy(target, output):
    """
    Weighted binary crossentropy between an output tensor 
    and a target tensor. POS_WEIGHT is used as a multiplier 
    for the positive targets.

    Combination of the following functions:
    * keras.losses.binary_crossentropy
    * keras.backend.tensorflow_backend.binary_crossentropy
    * tf.nn.weighted_cross_entropy_with_logits
    """
    # transform back to logits
    _epsilon = tfb._to_tensor(tfb.epsilon(), output.dtype.base_dtype)
    output = tf.clip_by_value(output, _epsilon, 1 - _epsilon)
    output = tf.log(output / (1 - output))
    # compute weighted loss
    loss = tf.nn.weighted_cross_entropy_with_logits(targets=target,
                                                    logits=output,
                                                    pos_weight=POS_WEIGHT)
    return tf.reduce_mean(loss, axis=-1)

然后在你的模型中:

model.compile(loss=weighted_binary_crossentropy, ...)

我还没有找到很多资源,它们报告了pos_weight与班级数,平均活跃班级等相关的良好工作价值。