keras 根据预测得分计算模型编译损失和指标

kuhbmx9i  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(168)

在训练模型之后,我使用predict方法从测试数据中推断分数。
从预测得分中,我如何使用模型编制的损失和指标来计算我的预测损失?

我所尝试的

基于Customizing what happens in fit()指南,我尝试使用compiled_loss方法

y_pred = model.predict(x_test)
model.compiled_loss(y_test, y_pred, regularization_losses=model.losses)

但它返回错误

---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-6-3eb62dca0b87> in <module>()
      1 y_pred = model.predict(x_test)
----> 2 loss = model.compiled_loss(y_test, y_pred)

1 frames

/usr/local/lib/python3.7/dist-packages/keras/engine/compile_utils.py in match_dtype_and_rank(y_t, y_p, sw)
    673 def match_dtype_and_rank(y_t, y_p, sw):
    674   """Match dtype and rank of predictions."""
--> 675   if y_t.shape.rank == 1 and y_p.shape.rank == 2:
    676     y_t = tf.expand_dims(y_t, axis=-1)
    677   if sw is not None:

AttributeError: 'tuple' object has no attribute 'rank'

如何重现

我使用了Simple MNIST convnet示例,后跟

y_pred = model.predict(x_test)
model.compiled_loss(y_test, y_pred, regularization_losses=model.losses)

重现错误

关于我的问题

我正在自定义指标上验证我的数据。但是,某些Keras用户建议不应按批计算全局指标的平均值,而应根据回调中整个验证数据的预测得分进行计算。
请参阅:
Issue #5794
How to calculate F1 Macro in Keras?
这个问题的糟糕解决方案是从evaluate方法计算损失和指标,从predict计算我的自定义指标。
一个不那么糟糕的解决方案是单独实现我的损失函数,这样它就可以根据预测的分数来工作。
请参阅:
在不运行模型的情况下计算损失(单位:Keras)
这样做的问题是,我选择损失函数的灵活性较低,因为我必须在稍后的回调中分别实现每个损失函数。
但我真的很想知道,难道汇编的损失和指标不是已经可以在某个地方访问了吗?

nhjlsmyf

nhjlsmyf1#

下面是一个函数,它可以根据之前预测的输出计算指标:

import tensorflow as tf

def calculate_metrics(model, y, y_pred, sample_weight=None):
    y = tf.convert_to_tensor(y)
    y_pred = tf.convert_to_tensor(y_pred)
    if not sample_weight is None:
        sample_weight = tf.convert_to_tensor(sample_weight)
    model.compute_loss(x=None, y=y, y_pred=y_pred, sample_weight=sample_weight)
    metrics = model.compute_metrics(x=None, y=y, y_pred=y_pred,
                                    sample_weight=sample_weight)
    for k,v in metrics.items():
        metrics[k] = float(v)
    return metrics

它要求yy_predsample_weight(如果提供的话)是numpy数组。这意味着它们需要立即适应内存。这也意味着指标值可能与model.evaluate返回的值略有不同,但我认为您应该理解这一点,因为您的评论是“全局指标不应按批处理取平均值”。
但它返回错误
AttributeError: 'tuple' object has no attribute 'rank'
model.compiled_loss(以及model.compute_lossmodel.compute_metrics)期望每个输入都是Tensor。Tensor有一个属性shape,它的类型是TensorShape,它又有一个属性rank。我期望您的y_test是一个ndarray,它也有一个属性shape。但是它的类型是tuple,它没有rank属性,这就是为什么我的函数将输入转换为Tensor,返回的度量值也是Tensor,所以我手动将它们转换为普通的python float
但我真的很想知道,难道汇编的损失和指标不是已经可以在某个地方访问了吗?
指标在model.fit方法返回的History对象中可用,因此如果您正在评估一个新训练的模型,您不需要重新计算指标。但是,如果您正在加载一个先前训练的模型并希望获得指标,您需要使用model.evaluate或从model.predict的结果中计算指标,就像我们在这里所做的那样。看一下代码,您可以分别比较model.test_stepmodel.predict_step。请注意,model.predict_step只运行推理并返回预测,因此在运行model.predict时不会计算度量。一个比我提供的解决方案更好的解决方案是将model.predict的元素组合到model.evaluate中,以便它可以选择性地返回y_pred,而不是丢弃它在计算度量之后,但是这将需要修改tensorflow 代码。

相关问题