如何在 Keras 中将损失函数指定为二次加权 kappa?

Posted

技术标签:

【中文标题】如何在 Keras 中将损失函数指定为二次加权 kappa?【英文标题】:How can I specify a loss function to be quadratic weighted kappa in Keras? 【发布时间】:2019-07-16 18:45:32 【问题描述】:

我的理解是keras需要损失函数才能有签名:

def custom_loss(y_true, y_pred):

我正在尝试使用sklearn.metrics.cohen_kappa_score,这需要 (y1, y2, labels=None, weights=None, sample_weight=None)`

如果我按原样使用它:

model.compile(loss=metrics.cohen_kappa_score,
              optimizer='adam', metrics=['accuracy'])

那么weights 将不会被设置。我想将其设置为quadtratic。有什么可以通过的吗?

【问题讨论】:

sklearn.metrics.cohen_kappa_score 不是有效的 Keras 损失,因为它不适用于 Keras 张量 @rvinas 可以通过keras.io/scikit-learn-api(Keras 的 Scikit Learn API)访问类似 sklearn.metrics.cohen_kappa_score 的内容吗?这可能允许 OP 基本上以这种方式做到这一点 @seisvelas 我不这么认为——这些包装器允许在您的 Scikit-learn 工作流程中使用 Keras 模型,但不能相反。我看到的唯一解决方案是使用 Keras 操作实现sklearn.metrics.cohen_kappa_score @seisvelas 如何使用 Keras 操作实现? 也许this question 中的答案正是您想要的。 【参考方案1】:

在 Keras 中实现参数化自定义损失函数 (cohen_kappa_score) 有两个步骤。由于有满足您需求的实现功能,因此您无需自己实现它。但是,根据TensorFlow Documentation,sklearn.metrics.cohen_kappa_score 不支持加权矩阵。 因此,我建议 TensorFlow 的 cohen_kappa 的实现。然而,在 Keras 中使用 TensorFlow 并不是那么容易…… 根据Question,他们使用control_dependencies 在 Keras 中使用 TensorFlow 指标。这是一个例子:

import keras.backend as K
def _cohen_kappa(y_true, y_pred, num_classes, weights=None, metrics_collections=None, updates_collections=None, name=None):
   kappa, update_op = tf.contrib.metrics.cohen_kappa(y_true, y_pred, num_classes, weights, metrics_collections, updates_collections, name)
   K.get_session().run(tf.local_variables_initializer())
   with tf.control_dependencies([update_op]):
      kappa = tf.identity(kappa)
   return kappa

由于Keras loss functions 将(y_true, y_pred) 作为参数,您需要一个返回另一个函数的包装函数。这是一些代码:

def cohen_kappa_loss(num_classes, weights=None, metrics_collections=None, updates_collections=None, name=None):
   def cohen_kappa(y_true, y_pred):
      return -_cohen_kappa(y_true, y_pred, num_classes, weights, metrics_collections, updates_collections, name)
   return cohen_kappa

最后,你可以在 Keras 中按如下方式使用它:

# get the loss function and set parameters
model_cohen_kappa = cohen_kappa_loss(num_classes=3,weights=weights)
# compile model
model.compile(loss=model_cohen_kappa,
          optimizer='adam', metrics=['accuracy'])

关于使用 Cohen-Kappa 度量作为损失函数。一般来说,可以使用加权 kappa 作为损失函数。这是一个paper,使用加权 kappa 作为多类分类的损失函数。

【讨论】:

感谢您的解决方案,但我遇到了以下问题:ValueError:无法挤压暗淡[1],预期尺寸为 1,'loss_7/dense_8_loss/cohen_kappa/remove_squeezable_dimensions/Squeeze 得到 5 ' (op: 'Squeeze') 输入形状:[?,5]。有什么想法吗? 此解决方案未使用二次加权 kappa。 您找到二次 kappa 分数的解决方案了吗?我也遇到了同样的问题。 还没有 :( 但我会尝试为 tensorflow 2 制作一个版本,因为它看起来更容易。【参考方案2】:

您可以将其定义为自定义损失,是的,keras 在损失函数中只接受两个参数是对的。以下是定义损失的方法:

def get_cohen_kappa(weights=None):
    def cohen_kappa_score(y_true, y_pred):
        """
        Define your code here. You can now use `weights` directly
        in this function
        """
        return score
    return cohen_kappa_score

现在你可以将这个函数传递给你的模型:

model.compile(loss=get_cohen_kappa_score(weights=weights),
              optimizer='adam')
model.fit(...)

【讨论】:

修改了我的问题以表明quadratic weighted kappa 只需在内部函数中插入逻辑,它就会按预期工作 还有一件事。 Kappa 是一个metric,为什么要把它用作损失函数? 我想最小化 kappa,所以用它作为损失函数不是很有意义吗? 你可以使用任何度量作为损失函数,只要它是可微的

以上是关于如何在 Keras 中将损失函数指定为二次加权 kappa?的主要内容,如果未能解决你的问题,请参考以下文章

Keras 中的像素加权损失函数 - TensorFlow 2.0

keras中的加权mse自定义损失函数

keras中的加权mse自定义损失函数 - 自定义权重

R Keras 中的自定义损失函数

如何在 Keras 中屏蔽损失函数(mae)?

如何使用自定义损失函数加载 Keras 模型?