【发布时间】:2022-11-18 14:07:29
【问题描述】:
我正在尝试为本文之后的分类任务实施归一化二进制交叉熵:Normalized Loss Functions for Deep Learning with Noisy Labels。 数学计算如下:
这是我的实现:
import tensorflow as tf
from keras.utils import losses_utils
class NormalizedBinaryCrossentropy(tf.keras.losses.Loss):
def __init__(
self,
from_logits=False,
label_smoothing=0.0,
axis=-1,
reduction=tf.keras.losses.Reduction.NONE,
name="normalized_binary_crossentropy",
**kwargs
):
super().__init__(
reduction=reduction, name=name
)
self.from_logits = from_logits
self._epsilon = tf.keras.backend.epsilon()
def call(self, target, logits):
if tf.is_tensor(logits) and tf.is_tensor(target):
logits, target = losses_utils.squeeze_or_expand_dimensions(
logits, target
)
logits = tf.convert_to_tensor(logits)
target = tf.cast(target, logits.dtype)
if self.from_logits:
logits = tf.math.sigmoid(logits)
logits = tf.clip_by_value(logits, self._epsilon, 1.0 - self._epsilon)
numer = target * tf.math.log(logits) + (1 - target) * tf.math.log(1 - logits)
denom = - (tf.math.log(logits) + tf.math.log(1 - logits))
return - numer / denom
def get_config(self):
config = super().get_config()
config.update({"from_logits": self._from_logits})
return config
我正在使用这种损失来训练二元分类器(CTR 预测器),但模型的损失并没有减少,ROC-AUC 保持在 ~0.49-0.5。为了验证分子的实现,我尝试通过删除分母来进行训练并且它工作正常。
# Example Usage
labels = np.array([[0], [1], [0], [0], [0]]).astype(np.int64)
logits = np.array([[-1.024], [2.506], [1.43], [0.004], [-2.0]]).astype(np.float64)
tf_nce = NormalizedBinaryCrossentropy(
reduction=tf.keras.losses.Reduction.NONE,
from_logits=True
)
tf_nce(labels, logits)
#<tf.Tensor: shape=(5, 1), dtype=float64, numpy=
# array([[0.18737159],
# [0.02945536],
# [0.88459308],
# [0.50144269],
# [0.05631594]])>
我手动检查了一些极端情况,发现损失没有达到 nans 或 0s。
谁能帮我调试为什么模型无法收敛于这种损失?我对损失函数或实现的理解有问题吗?
编辑 1:模型架构是具有 6 个任务的多门混合专家。所有 6 个任务都是二进制分类,将所有任务的损失加在一起得到最终损失。
【问题讨论】:
标签: tensorflow keras deep-learning loss-function