首页 > 解决方案 > Tensorflow 一种用于多输出模型的自定义指标

问题描述

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

我有一个具有 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()])

标签: pythontensorflowkerastensorflow2.0

解决方案


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

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 中的多输出模型文档中有详细说明。他们还展示了使用字典(将损失/度量函数映射到特定输出)而不是列表的示例。 https://keras.io/getting-started/functional-api-guide/#multi-input-and-multi-output-models

更多的信息:

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

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

1.(清洁溶液)

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

2.

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


推荐阅读