【问题标题】:Tensorflow one custom metric for multioutput modelsTensorflow 一种用于多输出模型的自定义指标
【发布时间】:2025-12-10 09:15:01
【问题描述】:

我在文档中找不到信息,所以我在这里问。

我有一个具有 3 个不同输出的多输出模型:

model = tf.keras.Model(inputs=[input], outputs=[output1, output2, output3])

用于验证的预测标签由这 3 个输出构成,仅形成一个,这是一个后处理步骤。用于训练的数据集是这 3 种中间输出的数据集,为了验证,我在标签数据集而不是 3 种中间数据上进行评估。

我想使用一个自定义指标来评估我的模型,该指标处理后处理并与基本事实进行比较。

我的问题是,在自定义指标的代码中,y_pred 会是模型的 3 个输出的列表吗?

class MyCustomMetric(tf.keras.metrics.Metric):

  def __init__(self, name='my_custom_metric', **kwargs):
    super(MyCustomMetric, self).__init__(name=name, **kwargs)

  def update_state(self, y_true, y_pred, sample_weight=None):
    # ? is y_pred a list [batch_output_1, batch_output_2, batch_output_3] ? 

  def result(self):
    pass 

# one single metric handling the 3 outputs?
model.compile(optimizer=tf.compat.v1.train.RMSPropOptimizer(0.01),
              loss=tf.keras.losses.categorical_crossentropy,
              metrics=[MyCustomMetric()])

【问题讨论】:

  • 你运行了这个,看看它是否有效?如果是这样,您遇到了什么错误?
  • 不,我没有,这只是一段看起来像我想要的地方但缺少部分的代码。我正在寻找一个可以帮助我填补缺失部分的答案。

标签: python tensorflow keras tensorflow2.0


【解决方案1】:

根据您给定的模型定义,这是一个标准的多输出模型。

model = tf.keras.Model(inputs=[input], outputs=[output_1, output_2, output_3])

一般来说,所有(自定义)指标以及(自定义)损失将分别在每个输出上调用(如 y_pred)!在损失/度量函数中,您只会看到一个输出和一个 对应的目标张量。 通过传递损失函数列表(长度 == 模型的输出数量),您可以指定哪个损失将用于哪个输出:

model.compile(optimizer=Adam(), loss=[loss_for_output_1, loss_for_output_2, loss_for_output_3], loss_weights=[1, 4, 8])

总损失(这是要最小化的目标函数)将是所有损失乘以给定损失权重的加法组合。

指标几乎相同!在这里,您可以传递(至于损失)指标列表(长度 == 输出数量),并告诉 Keras 哪个指标用于您的模型输出。

model.compile(optimizer=Adam(), loss='mse', metrics=[metrics_for_output_1, metrics_for_output2, metrics_for_output3])

这里的metrics_for_output_X 可以是一个函数,也可以是一个函数列表,它们都被调用,对应的output_X 为y_pred。

这在 Keras 的 Multi-Output Models 文档中有详细说明。他们还展示了使用字典(将损失/度量函数映射到特定输出)而不是列表的示例。 https://keras.io/getting-started/functional-api-guide/#multi-input-and-multi-output-models

更多信息:

如果我对您的理解正确,您想使用比较损失函数来训练您的模型 三个具有三个基本真实值的模型输出,并希望通过比较来进行某种性能评估 来自三个模型输出的派生值和一个单一的真实值。 通常,模型会在与评估相同的目标上进行训练,否则您可能会得到更差的结果 评估您的模型!

无论如何...对于在单个标签上评估您的模型,我建议您:

1. (干净的解决方案)

重写您的模型并合并后处理步骤。添加所有必要的操作(作为图层)并映射它们 到辅助输出。为了训练您的模型,您可以将辅助输出的 loss_weight 设置为零。 合并您的数据集,以便您可以为模型提供模型输入、中间目标输出以及标签。 如上所述,您现在可以定义一个指标,将辅助模型输出与给定的目标标签进行比较。

2.

或者您训练您的模型并得出指标,例如通过计算 model.predict(input) 的三个输出的后处理步骤,在自定义回调中。 如果您想在 tensorboard 中跟踪这些值,则有必要编写自定义摘要!这就是我不推荐此解决方案的原因。

【讨论】:

  • 谢谢,这是一个明确的答案,您发现了问题。使用回调是我正在考虑的。基本上我要实现的模型是Personlab(人体姿势估计),后处理涉及排序和创建可以是可变长度的人体骨架实例列表,所以我不确定我可以实现将它添加到图中)。使用回调的唯一缺点是它不会在张量板上打印任何内容......你知道是否有办法从回调中将一些指标值添加到张量板上?
  • 另外我就我试图解决的同一个问题问了另一个问题,也许你可以看看:*.com/questions/59972212/…
  • 我知道这是一个老问题,但对于遇到相同问题的任何人来说,一个可能更好的解决方案是覆盖模型的 compute_metrics 方法,它确实获得了模型的所有输入和输出
最近更新 更多