哪些损失函数和指标用于具有非常高的负数与正数比率的多标签分类?

Posted

技术标签:

【中文标题】哪些损失函数和指标用于具有非常高的负数与正数比率的多标签分类?【英文标题】:Which loss function and metrics to use for multi-label classification with very high ratio of negatives to positives? 【发布时间】:2020-04-07 18:03:13 【问题描述】:

我正在训练一个用于检测衣服属性的多标签分类模型。我在 Keras 中使用迁移学习,重新训练 vgg-19 模型的最后几层。

属性总数为 1000,其中大约 99% 为 0。准确度、精确度、召回率等指标都失败了,因为模型可以预测全零并且仍然获得非常高的分数。二元交叉熵、汉明损失等在损失函数的情况下都不起作用。

我正在使用深度时尚数据集。

那么,我可以使用哪些指标和损失函数来正确衡量我的模型?

【问题讨论】:

【参考方案1】:

我也遇到过类似你的情况

您可以在输出层使用 softmax 激活函数和 categorical_crossentropy 来检查其他指标,例如精度、召回率和 f1 分数,您可以使用 sklearn 库,如下所示:

from sklearn.metrics import classification_report

y_pred = model.predict(x_test, batch_size=64, verbose=1)
y_pred_bool = np.argmax(y_pred, axis=1)

print(classification_report(y_test, y_pred_bool))

至于训练阶段,据了解准确度指标如下

model.compile(loss='categorical_crossentropy'
              , metrics=['acc'], optimizer='adam')

如果对您有帮助,您可以使用 matplotlib 绘制训练阶段的损失和准确性的训练历史,如下所示:

hist = model.fit(x_train, y_train, batch_size=24, epochs=1000, verbose=2,
                 callbacks=[checkpoint],
                 validation_data=(x_valid, y_valid)

                 )
# Plot training & validation accuracy values
plt.plot(hist.history['acc'])
plt.plot(hist.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# Plot training & validation loss values
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

【讨论】:

【参考方案2】:

哈桑的建议是不正确的—— 分类交叉熵损失或 Softmax 损失是 Softmax 激活加上交叉熵损失。如果我们使用这种损失,我们将训练一个 CNN 来输出每个图像的 C 类的概率。用于多类分类

您想要的是多标签分类,因此您将使用 Binary Cross-Entropy Loss 或 Sigmoid Cross-Entropy loss。这是一个Sigmoid 激活加上一个交叉熵损失。与 Softmax 损失不同,它对于每个向量分量(类)都是独立的,这意味着为每个 CNN 输出向量分量计算的损失不受其他分量值的影响。这就是为什么它被用于多标签分类,其中某个类的元素的洞察力不应影响另一个类的决策。

现在为了处理类不平衡,您可以使用加权 Sigmoid 交叉熵损失。所以你会根据正例的数量/比率来惩罚错误的预测。

【讨论】:

【参考方案3】:

其实你应该使用tf.nn.weighted_cross_entropy_with_logits。 它不仅用于多标签分类,而且还具有pos_weight,可以像您预期的那样关注正类。

【讨论】:

【参考方案4】:

多类和二元类分类决定了输出单元的数量,即最后一层的神经元数量。 多标签和单标签决定了您应该使用的最后一层的激活函数和损失函数的选择。 对于单标签,标准选择是具有分类交叉熵的 Softmax;对于多标签,切换到具有二元交叉熵的 Sigmoid 激活。

分类交叉熵:

二元交叉熵:

C 是类数,m 是当前 mini-batch 中的示例数。 L 是损失函数,J 是成本函数。你也可以看到here。 在损失函数中,您正在迭代不同的类。在成本函数中,您正在迭代当前小批量中的示例。

【讨论】:

【参考方案5】:

你可以参考这个github。它们具有二元、多类、多标签以及强制模型学习接近 0 和 1 或简单地学习概率的选项。

https://github.com/monkeyDemon/AI-Toolbox/blob/master/computer_vision/image_classification_keras/loss_function/focal_loss.py

史蒂夫

【讨论】:

对于那些感到困惑的人,focal loss 是一种自定义损失函数,它导致“好”预测对整体损失的影响较小,而导致“坏”预测的影响与常规损失函数大致相同。对于稀疏输出,这意味着你强制网络面对你做错的事情,同时大多忽略它做对的事情(对多数输出的随机猜测)。

以上是关于哪些损失函数和指标用于具有非常高的负数与正数比率的多标签分类?的主要内容,如果未能解决你的问题,请参考以下文章

成交量比率VR指标的原理是啥?

使 DeepLabV3 损失函数加权

为啥我要选择与我的指标不同的损失函数?

Pyspark 列转换具有正数和负数的字符串

python做BP神经网络,进行数据预测,训练的输入和输出值都存在负数,为啥预测值永远为正数?

10. 回归损失最小化