Keras 版本的组合交叉熵和校准损失

Posted

技术标签:

【中文标题】Keras 版本的组合交叉熵和校准损失【英文标题】:Keras version of the combined cross-entropy and calibration loss 【发布时间】:2021-10-15 17:28:47 【问题描述】:

我最近阅读了一篇题为“Improved Trainable Calibration Method for Neural Networks on Medical Imaging Classification”的论文。该研究通过测量预测置信度和准确度 (DCA) 之间的差异并将其作为辅助项添加到交叉熵损失中,将校准纳入深度学习模型训练过程。 GitHub 代码位于https://github.com/GB-TonyLiang/DCA。据说 DCA 项适用于在交叉熵损失减少但准确度处于稳定状态时应用惩罚。 Pytorch中的代码如下:

import torch
from torch.nn import functional as F

def cross_entropy_with_dca_loss(logits, labels, weights=None, alpha=1., beta=10.):        
    ce = F.cross_entropy(logits, labels, weight=weights)

    softmaxes = F.softmax(logits, dim=1)
    confidences, predictions = torch.max(softmaxes, 1)
    accuracies = predictions.eq(labels)
    mean_conf = confidences.float().mean()
    acc = accuracies.float().sum()/len(accuracies)
    dca = torch.abs(mean_conf-acc)
    loss = alpha*ce+beta*dca
    
    return loss

我需要帮助将其转换为 Keras 中的自定义函数,并将其用于使用真实标签 (y_true) 和预测概率 (y_pred) 而不是 logits 的多类分类的分类交叉熵损失。

【问题讨论】:

【参考方案1】:

以下代码可能与 Keras 中的上述 PyTorch 代码等效。

权重参数除外。下面的 sn-p 可能对你有帮助。

请检查输出。如果有什么不对。如果有的话,分享你的 cmets。

import tensorflow as tf
from keras.losses import CategoricalCrossentropy
from keras.activations import softmax

def cross_entropy_with_dca_loss(logits, labels, weights=None, alpha=1., beta=10.):
    cce = CategoricalCrossentropy() 
    ce = cce(logits, labels) # not sure about weights parameter.
    softmaxes = softmax(logits, axis=1)
    confidences = tf.reduce_max(softmaxes, axis=1)
    mean_conf = tf.reduce_mean(confidences)
    acc = tf.reduce_mean(tf.cast(tf.equal(logits, labels), dtype=tf.float32))
    dca = tf.abs(mean_conf - acc)
    loss = alpha * ce + beta * dca
    return loss

【讨论】:

谢谢。您能否澄清一下转换是否适用于真实标签和预测概率,但不适用于 logits。因为,概率取值从 0 到 1,而 logits 取值从 (−∞,∞)。 Logits 和标签应该在同一范围内。因为两者都是分类的。我认为两者都应该从 0 到 1。您可以应用 softmax 来获得概率keras.io/api/losses/probabilistic_losses/…【参考方案2】:

此代码 sn-p 可以采用真实标签和预测概率。 y_pred 是概率张量。无需使用softmax函数。

import tensorflow as tf
from keras.metrics import CategoricalAccuracy
from keras.losses import CategoricalCrossentropy

# Assuming y_pred is prob tensor, y_true is one-hot encoded
def cross_entropy_with_dca_loss(y_true, y_pred, alpha=1., beta=10.):        
    ce = CategoricalCrossentropy(from_logits=False)(y_true,y_pred)
    predictions = tf.math.argmax(y_pred, axis=1)
    confidences = tf.reduce_max(y_pred, axis=1)
    mean_conf = tf.reduce_mean(confidences)
    acc_m = CategoricalAccuracy()
    acc_m.update_state(y_true, y_pred)
    acc = acc_m.result().numpy()
    dca = tf.abs(mean_conf-acc)
    loss = alpha*ce+beta*dca
    return loss

# test on a sample data
y_true = tf.constant([[0, 1, 0], [0, 0, 1]])
y_pred = tf.constant([[0.05, 0.95, 0], [0.1, 0.8, 0.1]])
L = cross_entropy_with_dca_loss(y_true, y_pred)
print("loss", L.numpy())

【讨论】:

以上是关于Keras 版本的组合交叉熵和校准损失的主要内容,如果未能解决你的问题,请参考以下文章

交叉熵和对数损失函数之间的关系

分类交叉熵和标签编码

交叉熵与KL散度

Keras 和 TensorFlow 中所有这些交叉熵损失之间有啥区别?

语义分割 Keras 的交叉熵损失

自定义 keras 损失函数二元交叉熵给出不正确的结果