自定义TensorFlow中的f1_score指标

我想在tf.keras中实现f1_score指标。

from tensorflow.keras.models import Model, Sequentialfrom tensorflow.keras.layers import Densefrom tensorflow.keras.optimizers import Adamfrom tensorflow.keras.losses import binary_crossentropyfrom tensorflow.keras.metrics import Accuracy, BinaryAccuracyfrom sklearn.metrics import accuracy_scoreimport numpy as npimport tensorflow as tfclass F1_Score(tf.keras.metrics.Metric):    def __init__(self, name='f1_score', **kwargs):        super().__init__(name=name, **kwargs)        self.f1 = self.add_weight(name='f1', initializer='zeros')    def update_state(self, y_true, y_pred, sample_weight=None):        p = Precision(thresholds=0.5)(y_true, y_pred)        r = Recall(thresholds=0.5)(y_true, y_pred)        self.f1 = 2 * ((p * r) / (p + r + 1e-6))    def result(self):        return self.f1    def reset_states(self):        self.f1.assign(0)        model = Sequential([  Dense(64, activation='relu', input_shape=(784,)),  Dense(64, activation='relu'),  Dense(4, activation='sigmoid'),])x = np.random.normal(size=(10, 784))y = np.random.choice(2, size=(10, 4))model.compile(optimizer=Adam(0.001), loss='binary_crossentropy',                  metrics=['accuracy', , F1_Score()])model.fit(x[:1], y[:1], batch_size=1, epochs=1, verbose=1)

我遇到了一个错误:

ValueError: tf.function-decorated function tried to create variableson non-first call.


回答:

您会遇到这个错误是因为您想在update_state函数中实例化一些tf.Variable。当从Precision和Recall类实例化对象时,您正在创建一些tf.Variable

在构造函数中实例化这些对象,并在update_state函数中调用它们:

class F1_Score(tf.keras.metrics.Metric):    def __init__(self, name='f1_score', **kwargs):        super().__init__(name=name, **kwargs)        self.f1 = self.add_weight(name='f1', initializer='zeros')        self.precision_fn = Precision(thresholds=0.5)        self.recall_fn = Recall(thresholds=0.5)    def update_state(self, y_true, y_pred, sample_weight=None):        p = self.precision_fn(y_true, y_pred)        r = self.recall_fn(y_true, y_pred)        # 由于f1是一个变量,我们使用assign        self.f1.assign(2 * ((p * r) / (p + r + 1e-6)))    def result(self):        return self.f1    def reset_states(self):        # 我们还需要重置Precision和Recall对象的状态        self.precision_fn.reset_states()        self.recall_fn.reset_states()        self.f1.assign(0)

行为解释:

TensorFlow只允许在tf.function的第一次调用时创建新的tf.Variable对象,请查看文档

tf.function只允许在第一次调用时创建新的tf.Variable对象

Keras指标被包装在tf.function中以支持TensorFlow v1的兼容性。您可以在代码中找到这个注释

如果update_state不在eager/tf.function中,并且它不是来自内置指标,则将其包装在tf.function中。这样,用户在v1中编写自定义指标时无需担心控制依赖和返回操作。

您的类中还有另一个错误,就是您用f1分数的计算覆盖了您创建的f1 tf.Variable。要更新变量的值,您需要使用assign。并且我们必须不要忘记重置正在使用的Precision和Recall Metrics对象的状态!

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注