【发布时间】:2019-03-18 01:11:16
【问题描述】:
我正在尝试将自定义指标传递给 keras.compile。我也在学习 OOP 并尝试将其应用于机器学习。我想做的也是跟踪每个时期的 f1、精度和召回率。
例如,我可以将 f1、召回率和精度作为单独的函数传递给函数,但不能作为具有 init 方法的类。
这是我一直在尝试做的事情:
class Metrics:
def __init__(self, y_true, y_pred):
self.y_true = y_true
self.y_pred = y_pred
self.tp = K.sum(K.cast(y_true * y_pred, 'float'), axis=0)
self.fp = K.sum(K.cast((1 - y_true) * y_pred, 'float'), axis=0)
self.fn = K.sum(K.cast(y_true*(1 - y_pred), 'float'), axis=0)
def precision_score(self):
precision = self.tp / (self.tp + self.fp + K.epsilon())
return precision
def recall_score(self):
recall = self.tp / (self.tp + self.fn + K.epsilon())
return recall
def f1_score(self):
precision = precision_score(self.y_true, self.y_pred)
recall = recall_score(self.y_true, self.y_pred)
f1 = 2 * precision * recall / (precision + recall + K.epsilon())
f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)
f1 = K.mean(f1)
return f1
if __name__ == '__main__':
# Some images
train_generator = DataGenerator().create_data()
validation_generator = DataGenerator().create_data()
model = create_model(
input_shape = INPUT_SHAPE,
n_out = N_CLASSES)
model.compile(
loss = 'binary_crossentropy',
optimizer = Adam(0.03),
# This is the part in question:
metrics = ['acc', Metrics.f1_score, Metrics.recall_score, Metrics.precision_score]
)
history = model.fit_generator(
train_generator,
steps_per_epoch = 5,
epochs = 5,
validation_data = next(validation_generator),
validation_steps = 7,
verbose = 1
)
它也可以通过传入 Metrics.f1_score 来在没有 def init 部分的情况下工作,但为什么它不能用于初始化?
如果我传入 Metrics.f1_score 我会得到:
TypeError: f1_score() takes 1 positional argument but 2 were given
如果我传入 Metrics.f1_score() 我会得到:
TypeError: f1_score() missing 1 required positional argument: 'self'
如果我传入 Metrics().f1_score 我会得到:
TypeError: __init__() missing 2 required positional arguments: 'y_true' and 'y_pred'
如果我传入 Metrics().f1_score() 我会得到:
TypeError: __init__() missing 2 required positional arguments: 'y_true' and 'y_pred'
【问题讨论】: