【发布时间】:2017-06-28 18:30:24
【问题描述】:
我正在训练一个用于多标签分类的神经网络,其中包含大量类(1000 个)。这意味着每个输入都可以激活多个输出。平均而言,每个输出帧有两个活动类。在使用交叉熵损失进行训练时,神经网络只输出零,因为它的输出损失最小,因为我的标签中有 99.8% 是零。关于如何推动网络给予积极类更多权重的任何建议?
【问题讨论】:
标签: machine-learning neural-network classification keras
我正在训练一个用于多标签分类的神经网络,其中包含大量类(1000 个)。这意味着每个输入都可以激活多个输出。平均而言,每个输出帧有两个活动类。在使用交叉熵损失进行训练时,神经网络只输出零,因为它的输出损失最小,因为我的标签中有 99.8% 是零。关于如何推动网络给予积极类更多权重的任何建议?
【问题讨论】:
标签: machine-learning neural-network classification keras
Tensorflow 有一个损失函数weighted_cross_entropy_with_logits,可用于赋予 1 更多的权重。所以它应该适用于像你这样的稀疏多标签分类设置。
这类似于 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 在课程数量、平均活跃课程等方面的良好工作价值。
【讨论】:
weighted_binary_accuracy 指标也可用于模型? (否则binary_accuracy 也会偏向于负面预测)。