Tensorflow 一种用于多输出模型的自定义指标
Tensorflow one custom metric for multioutput models
我在文档中找不到信息,所以我在这里问。
我有一个具有 3 个不同输出的多输出模型:
model = tf.keras.Model(inputs=[input], outputs=[output1, output2, output3])
用于验证的预测标签由这 3 个输出构成,仅形成一个,这是一个 post 处理步骤。用于训练的数据集是这 3 个中间输出的数据集,为了验证,我在标签数据集而不是 3 种中间数据上进行评估。
我想使用处理 post 处理并与基本事实进行比较的自定义指标来评估我的模型。
我的问题是,在自定义指标的代码中,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()])
根据您给定的模型定义,这是一个标准的多输出模型。
model = tf.keras.Model(inputs=[input], outputs=[output_1, output_2, output_3])
一般来说,所有(自定义)指标和(自定义)损失都会在每个输出上单独调用(如y_pred)!在 loss/metric 函数中,您只会看到一个输出和一个
相应的目标张量。
通过传递损失函数列表(长度 == 模型的输出数),您可以指定哪个损失将用于哪个输出:
model.compile(optimizer=Adam(), loss=[loss_for_output_1, loss_for_output_2, loss_for_output_3], loss_weights=[1, 4, 8])
总损失(即要最小化的 objective 函数)将是所有损失乘以给定损失权重的加法组合。
指标都差不多!在这里,您可以传递(至于损失)一个指标列表(长度 == 输出数量),并告诉 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 的多输出模型文档中有详细解释。他们还展示了使用字典(将 loss/metric 函数映射到特定输出)而不是列表的示例。
https://keras.io/getting-started/functional-api-guide/#multi-input-and-multi-output-models
更多信息:
如果我对你的理解正确,你想使用损失函数来训练你的模型
三个模型输出具有三个基本真实值,并希望通过比较来进行某种性能评估
来自三个模型输出的派生值和单个地面真值。
通常,模型会在评估时使用相同的 objective 进行训练,否则您可能会得到较差的结果
评估您的模型!
无论如何...为了在单个标签上评估您的模型,我建议您:
1. (干净的解决方案)
重写您的模型并合并 post 处理步骤。添加所有必要的操作(作为图层)并映射它们
到辅助输出。为了训练您的模型,您可以将辅助输出的 loss_weight 设置为零。
合并您的数据集,以便您可以为模型提供模型输入、中间目标输出以及标签。
如上所述,您现在可以定义一个指标,将辅助模型输出与给定目标标签进行比较。
2.
或者您训练您的模型并推导指标,例如通过在 model.predict(输入) 的三个输出上计算您的 post-处理步骤,在自定义回调中。
如果您想在张量板上跟踪这些值,这将需要编写自定义摘要!这就是为什么我不推荐这个解决方案。
我在文档中找不到信息,所以我在这里问。
我有一个具有 3 个不同输出的多输出模型:
model = tf.keras.Model(inputs=[input], outputs=[output1, output2, output3])
用于验证的预测标签由这 3 个输出构成,仅形成一个,这是一个 post 处理步骤。用于训练的数据集是这 3 个中间输出的数据集,为了验证,我在标签数据集而不是 3 种中间数据上进行评估。
我想使用处理 post 处理并与基本事实进行比较的自定义指标来评估我的模型。
我的问题是,在自定义指标的代码中,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()])
根据您给定的模型定义,这是一个标准的多输出模型。
model = tf.keras.Model(inputs=[input], outputs=[output_1, output_2, output_3])
一般来说,所有(自定义)指标和(自定义)损失都会在每个输出上单独调用(如y_pred)!在 loss/metric 函数中,您只会看到一个输出和一个 相应的目标张量。 通过传递损失函数列表(长度 == 模型的输出数),您可以指定哪个损失将用于哪个输出:
model.compile(optimizer=Adam(), loss=[loss_for_output_1, loss_for_output_2, loss_for_output_3], loss_weights=[1, 4, 8])
总损失(即要最小化的 objective 函数)将是所有损失乘以给定损失权重的加法组合。
指标都差不多!在这里,您可以传递(至于损失)一个指标列表(长度 == 输出数量),并告诉 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 的多输出模型文档中有详细解释。他们还展示了使用字典(将 loss/metric 函数映射到特定输出)而不是列表的示例。 https://keras.io/getting-started/functional-api-guide/#multi-input-and-multi-output-models
更多信息:
如果我对你的理解正确,你想使用损失函数来训练你的模型 三个模型输出具有三个基本真实值,并希望通过比较来进行某种性能评估 来自三个模型输出的派生值和单个地面真值。 通常,模型会在评估时使用相同的 objective 进行训练,否则您可能会得到较差的结果 评估您的模型!
无论如何...为了在单个标签上评估您的模型,我建议您:
1. (干净的解决方案)
重写您的模型并合并 post 处理步骤。添加所有必要的操作(作为图层)并映射它们 到辅助输出。为了训练您的模型,您可以将辅助输出的 loss_weight 设置为零。 合并您的数据集,以便您可以为模型提供模型输入、中间目标输出以及标签。 如上所述,您现在可以定义一个指标,将辅助模型输出与给定目标标签进行比较。
2.
或者您训练您的模型并推导指标,例如通过在 model.predict(输入) 的三个输出上计算您的 post-处理步骤,在自定义回调中。 如果您想在张量板上跟踪这些值,这将需要编写自定义摘要!这就是为什么我不推荐这个解决方案。