tensorflow - 张量流中的自定义 f1_score 指标
问题描述
我想为 tf.keras 实现 f1_score 指标。
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras.metrics import Accuracy, BinaryAccuracy
from sklearn.metrics import accuracy_score
import numpy as np
import tensorflow as tf
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')
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 函数试图在非第一次调用时创建变量。
解决方案
您收到此错误是因为您想tf.Variable
在 update_state 函数期间实例化一些 s。当从 Precision 和 Recall 类实例化对象时,您正在创建一些tf.Variable
s。
在构造函数中实例化对象,并在 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)
# since f1 is a variable, we use assign
self.f1.assign(2 * ((p * r) / (p + r + 1e-6)))
def result(self):
return self.f1
def reset_states(self):
# we also need to reset the state of the precision and recall objects
self.precision_fn.reset_states()
self.recall_fn.reset_states()
self.f1.assign(0)
行为说明:
Tensorflow 允许仅在第一次调用 a 时创建变量tf.function
,请参阅文档:
tf.function 仅允许在第一次调用时创建新的 tf.Variable 对象
Keras 指标封装在 tf.function 中,以允许与 tensorflow v1 兼容。您可以在代码中找到此注释
如果
update_state
不在 eager/tf.function 中并且不是来自内置指标,则将其包装在tf.function
. 这样一来,在 v1 中编写自定义指标的用户就不必担心控制依赖和返回操作。
您的课程中还有另一个错误,就是您通过f1 tf.Variable
计算 f1 分数覆盖了您创建的错误。要更新变量的值,您需要使用assign
. 我们不能忘记重置正在使用的 Precision 和 Recall Metrics 对象的状态!
推荐阅读
- wagtail - 鹡鸰更新后管理面板图标消失了
- java - 父类可以有一个字段,其泛型类型是当前后代的类型吗?
- python - 如何使用 Python 请求异步调用 aws lambda 函数
- c# - 是否可以在 c# 中将大量结构直接写入二进制文件?
- javascript - 在 create-react-app 中使用具有依赖关系的 webworkers
- django - 禁用prefers-color-scheme:django admin中的dark
- tensorflow - 调用 keras 模型作为函数
- javascript - React on conditions 中的多步表单
- java - ConcurrentHashMap.keySet().stream() 的一致性行为
- javascript - 我可以从 ReactJS 中的父元素中检索属性值吗?