我使用的是Tensorflow/Keras 2.4.1,我有一个(无监督的)自定义指标,它将我的几个模型输入作为参数,例如:
model = build_model() # returns a tf.keras.Model object
my_metric = custom_metric(model.output, model.input[0], model.input[1])
model.add_metric(my_metric)
[...]
model.fit([...]) # training with fit
字符串
然而,custom_metric
非常昂贵,所以我希望它只在验证过程中计算。我发现了这个answer,但我几乎不明白如何将解决方案适应我的度量,使用多个模型输入作为参数,因为update_state
方法似乎不灵活。
在我的上下文中,除了编写我自己的训练循环之外,有没有一种方法可以避免在训练过程中计算我的指标?另外,我很惊讶我们不能在Tensorflow中原生地指定某些指标只应该在验证时计算,这有什么原因吗?
此外,由于模型经过训练以优化损失,并且训练数据集不应用于评估模型,我甚至不明白为什么Tensorflow默认情况下在训练期间计算指标。
3条答案
按热度按时间nfs0ujit1#
我认为只在验证时计算指标的最简单的解决方案是使用自定义回调。
在这里,我们定义我们的虚拟回调:
字符串
假设这个虚拟模型:
型
这个数据:
型
您可以使用自定义回调来计算train和validation上的度量:
型
仅在验证时:
型
仅在火车上:
型
只需记住回调函数对数据进行一次性评估,就像keras在
validation_data
上默认计算的任何指标/损失一样。here是运行代码。
ztmd8pv52#
我可以使用
learning_phase
,但只能在符号Tensor模式(图)模式下使用:因此,首先我们需要禁用eager模式(这必须在导入tensorflow之后立即完成):
字符串
然后你可以使用符号if(
backend.switch
)来创建你的指标:型
方法
add_metric
将要求提供名称和聚合方法,您可以将其设置为"mean"
。这里有一个例子:
型
pw136qt23#
由于指标是在x1m1 n1x的x1m0 n1x函数中运行的,因此在不更改API的情况下过滤出train禁用的指标需要子类化x1m2 n1x。
我们定义一个简单的度量 Package 器:
字符串
和子类
keras.Model
以在训练期间过滤掉那些度量:型
现在给出一个keras模型,我们可以 Package 它并使用train disabled metrics编译它:
型
SparseCategoricalCrossentropy
仅在验证期间计算:型