如何将内置 tensorflow 的 logits 自定义损失函数转换为 keras?

Posted

技术标签:

【中文标题】如何将内置 tensorflow 的 logits 自定义损失函数转换为 keras?【英文标题】:How to convert a custom loss function with logits, built in tensorflow to keras? 【发布时间】:2019-11-11 23:32:56 【问题描述】:

我在 tensorflow 中内置了一个损失函数,它需要 logits 和标签作为输入:

   def median_weight_class_loss(labels, logits):
       epsilon = tf.constant(value=1e-10)
       logits = logits + epsilon
       softmax = tf.nn.softmax(logits)
       #this is just the number of samples in each class in my dataset divided by the sum of samples 10015.
       weight_sample = np.array([1113,6705,514,327,1099,115,142])/10015
       weight_sample = 0.05132302/weight_sample
       xent = -tf.reduce_sum(tf.multiply(labels * tf.log(softmax + epsilon), weight_sample), axis=1)
       return xent

问题在于 keras 损失函数的格式不同:

   custom_loss(y_true, y_pred)

它使用 y_true、y_pred 作为输入,

我找到了一种在 keras 中获取 logits 的方法,即在模型的最后一层使用线性激活而不是 softmax。

   model.add(Activation('linear'))

但是我需要我的模型在最后一层激活 softmax,你认为解决方案是什么? 谢谢。

【问题讨论】:

【参考方案1】:

严格来说,这个loss不需要logits,可以直接输入softmax概率,修改loss如下:

def median_weight_class_loss(y_true, y_pred):
       epsilon = tf.constant(value=1e-10)
       weight_sample = np.array([1113,6705,514,327,1099,115,142])/10015
       weight_sample = 0.05132302/weight_sample
       xent = -tf.reduce_sum(tf.multiply(y_true * tf.log(y_pred + epsilon), weight_sample), axis=1)
       return xent

【讨论】:

但是当使用它与来自 softmax 的 y_pred 一样使用时,误差并没有减少并且永远保持在 3.x,而使用正常的分类准确度,误差会减少。当我在 tensorflow 中使用它时,它工作得很好! @GuissousAllaeddine 尝试使用 -tf.reduce_sum(y_true * tf.log(y_pred + epsilon) * weight_sample, axis=1) 感谢您的回复,我原来的问题是关于转换函数的,我想您已经回答了。

以上是关于如何将内置 tensorflow 的 logits 自定义损失函数转换为 keras?的主要内容,如果未能解决你的问题,请参考以下文章

在 Tensorflow RNN 中,logits 和标签必须是可广播的错误

tensorflow代码学习:sigmoid_cross_entropy_with_logits

[tensorflow] tf.nn.sparse_softmax_cross_entropy_with_logits的使用

如何使用 tensorflow softmax_cross_entropy_with_logits 缩放和重新规范化输出以解决类不平衡

TensorFlow ValueError:logits 和标签必须具有相同的形状 ((25, 1) vs (1, 1))

Tensorflow:权重衰减与 logits 归一化