如何在 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?的主要内容,如果未能解决你的问题,请参考以下文章