在TensorFlow 2.0中,有类tf.keras.metrics.AUC
。它可以很容易地添加到compile
方法的度量列表中,如下所示。
# Example taken from the documentation
model.compile('sgd', loss='mse', metrics=[tf.keras.metrics.AUC()])
然而,在我的例子中,我的神经网络的输出是一个NxM
张量,其中N
是批大小,M
是单独输出的数目。我想单独计算每个M
输出的N
度量(跨批处理的所有N
实例)。因此,应该有M
的AUC度量,它们中的每一个都是用N
观测来计算的。我试图创建一个自定义度量,但我面临一些问题。以下是我的第一次尝试。
def get_custom_auc(output):
auc = tf.metrics.AUC()
@tf.function
def custom_auc(y_true, y_pred):
y_true = y_true[:, output]
y_pred = y_pred[:, output]
auc.update_state(y_true, y_pred)
return auc.result()
custom_auc.__name__ = "custom_auc_" + str(output)
return custom_auc
重命名custom_auc.__name__
的需要在以下文章中描述:是否有可能有一个返回数组(或张量)而不是数字的度量?。但是,此实现会引发错误。
tensorflow.python.framework.errors_impl.InvalidArgumentError:断言失败:预测必须是>= 0 x (strided_slice_1:0) =y (Cast_1/x:0) =[{节点metrics/custom_auc_2/StatefulPartitionedCall/assert_greater_equal/Assert/AssertGuard/else/_161/Assert}}] ]
我还尝试在AUC
中创建custom_auc
对象,但这是不可能的,因为我使用的是@tf.function
,所以我将得到错误ValueError: tf.function-decorated function tried to create variables on non-first call.
。即使我删除了@tf.function
(因为我可能在实现中使用了一些if - get语句),我也会得到另一个错误。
从容器: localhost读取资源变量_AnonymousVar33时出错。这可能意味着变量未初始化。未找到:资源localhost/_AnonyousVar33/N10tensorflow 3VarE不存在。[节点度量/自定义_auc_0/add/ReadVariableOp(定义在/train.py:173上)]
注意,目前我正在添加这些AUC度量,每个M
输出都有一个,如这个答案中所描述的。此外,我不能简单地返回对象auc
,因为显然Keras期望自定义度量的输出是张量,而不是AUC对象。因此,如果您这样做,您将得到以下错误。
TypeError:要与tf.contrib.eager.defun兼容,Python函数必须返回零或多个张量;在.custom_auc at 0x1862e6680>的编译中,可以找到类型的返回值,而不是张量。
我还尝试实现一个定制的度量类,如下所示。
class CustomAUC(tf.metrics.Metric):
def __init__(self, num_outputs, name="custom_auc", **kwargs):
super(CustomAUC, self).__init__(name=name, **kwargs)
assert num_outputs >= 1
self.num_outputs = num_outputs
self.aucs = [tf.metrics.AUC() for _ in range(self.num_outputs)]
def update_state(self, y_true, y_pred, sample_weight=None):
for output in range(self.num_outputs):
y_true1 = y_true[:, output]
y_pred1 = y_pred[:, output]
self.aucs[output].update_state(y_true1, y_pred1)
def result(self):
return [auc.result() for auc in self.aucs]
但是,我目前正在收到错误。
ValueError:形状(200,)和()不兼容
这个错误似乎与reset_states
有关,所以也许我也应该重写这个方法。实际上,如果我用以下实现覆盖reset_states
def reset_states(self):
for auc in self.aucs:
auc.reset_states()
我不再理解这个错误了,但是我得到了另一个错误
tensorflow.python.framework.errors_impl.InvalidArgumentError:断言失败:预测必须是>= 0 x (strided_slice_1:0) =y (Cast_1/x:0) =[{节点metrics/custom_auc/PartitionedFunctionCall/assert_greater_equal/Assert/AssertGuard/else/_98/Assert}}] ]
那么,如何实现这个自定义的AUC度量,为网络的每个M
输出提供一个度量?基本上,我想做一些类似于这个答案描述的解决方案,但使用的是AUC度量。
我还在TensorFlow的Github问题跟踪器上打开了相关问题。
发布于 2021-02-03 15:25:40
我也有类似的问题。我有一个具有3个输出的模型,并且我希望为这3个输出(每个输出有不同数量的类)计算一个自定义度量(ConfusionMatricMetric)。我在这里使用了一个解决方案-- 适配/ --更低的层次。我现在的问题是我不能训练这个模型,因为
ValueError: tf.function-decorated function tried to create variables on non-first call.
然后我用
tf.config.run_functions_eagerly(True)
现在,模型训练,非常慢,但可以保存。
我还用tf.keras.metrics.KLDivergence()
代替了我的自定义度量,并复制了相同的实验,结果与上述训练和保存(tf.saved_model.save
)的结果相同。
https://stackoverflow.com/questions/59958089
复制相似问题