我正在安装train_generator,并且通过自定义回调,我想在validation_generator上计算自定义指标。
如何在自定义回调中访问参数var matchingStartNumber = startNumList.FirstOrDefault(x => request.ReferenceNumber.StartsWith(x));
if (matchingStartNumber != null)
{
// Do stuff with startNum
}
和validation_steps
?
它不在validation_data
中,也无法在self.params
中找到它。这就是我想做的事情。任何不同的方法都会受到欢迎。
self.model
keras:2.1.1
更新
我设法将验证数据传递给自定义回调的构造函数。但是,这会导致令人讨厌的“内核似乎已经死亡。它会自动重启”。信息。我怀疑这是否是正确的方法。有什么建议吗?
model.fit_generator(generator=train_generator,
steps_per_epoch=steps_per_epoch,
epochs=epochs,
validation_data=validation_generator,
validation_steps=validation_steps,
callbacks=[CustomMetrics()])
class CustomMetrics(keras.callbacks.Callback):
def on_epoch_end(self, batch, logs={}):
for i in validation_steps:
# features, labels = next(validation_data)
# compute custom metric: f(features, labels)
return
答案 0 :(得分:0)
我一直在寻找相同问题的解决方案,然后在接受的答案here中找到了您的解决方案和另一个解决方案。如果第二个解决方案有效,那么我认为比在“时代末期”再次遍历所有验证要好
这个想法是将目标和占位符保存在变量中,并通过“批处理结束时”的自定义回调来更新变量
答案 1 :(得分:0)
您可以直接在self.validation_data上进行迭代,以在每个时期结束时汇总所有验证数据。如果要计算精度,请在整个验证数据集中调用和F1:
# Validation metrics callback: validation precision, recall and F1
# Some of the code was adapted from https://medium.com/@thongonary/how-to-compute-f1-score-for-each-epoch-in-keras-a1acd17715a2
class Metrics(callbacks.Callback):
def on_train_begin(self, logs={}):
self.val_f1s = []
self.val_recalls = []
self.val_precisions = []
def on_epoch_end(self, epoch, logs):
# 5.4.1 For each validation batch
for batch_index in range(0, len(self.validation_data)):
# 5.4.1.1 Get the batch target values
temp_targ = self.validation_data[batch_index][1]
# 5.4.1.2 Get the batch prediction values
temp_predict = (np.asarray(self.model.predict(
self.validation_data[batch_index][0]))).round()
# 5.4.1.3 Append them to the corresponding output objects
if(batch_index == 0):
val_targ = temp_targ
val_predict = temp_predict
else:
val_targ = np.vstack((val_targ, temp_targ))
val_predict = np.vstack((val_predict, temp_predict))
val_f1 = round(f1_score(val_targ, val_predict), 4)
val_recall = round(recall_score(val_targ, val_predict), 4)
val_precis = round(precision_score(val_targ, val_predict), 4)
self.val_f1s.append(val_f1)
self.val_recalls.append(val_recall)
self.val_precisions.append(val_precis)
# Add custom metrics to the logs, so that we can use them with
# EarlyStop and csvLogger callbacks
logs["val_f1"] = val_f1
logs["val_recall"] = val_recall
logs["val_precis"] = val_precis
print("— val_f1: {} — val_precis: {} — val_recall {}".format(
val_f1, val_precis, val_recall))
return
valid_metrics = Metrics()
然后,您可以将有效参数添加到回调参数:
your_model.fit_generator(..., callbacks = [valid_metrics])
如果您希望其他回调使用这些措施,请确保将其放在回调的开头。
答案 2 :(得分:0)
Verdant89犯了一些错误,没有实现所有功能。下面的代码应该可以工作。
class Metrics(callbacks.Callback):
def on_train_begin(self, logs={}):
self.val_f1s = []
self.val_recalls = []
self.val_precisions = []
def on_epoch_end(self, epoch, logs):
# 5.4.1 For each validation batch
for batch_index in range(0, len(self.validation_data[0])):
# 5.4.1.1 Get the batch target values
temp_target = self.validation_data[1][batch_index]
# 5.4.1.2 Get the batch prediction values
temp_predict = (np.asarray(self.model.predict(np.expand_dims(
self.validation_data[0][batch_index],axis=0)))).round()
# 5.4.1.3 Append them to the corresponding output objects
if batch_index == 0:
val_target = temp_target
val_predict = temp_predict
else:
val_target = np.vstack((val_target, temp_target))
val_predict = np.vstack((val_predict, temp_predict))
tp, tn, fp, fn = self.compute_tptnfpfn(val_target, val_predict)
val_f1 = round(self.compute_f1(tp, tn, fp, fn), 4)
val_recall = round(self.compute_recall(tp, tn, fp, fn), 4)
val_precis = round(self.compute_precision(tp, tn, fp, fn), 4)
self.val_f1s.append(val_f1)
self.val_recalls.append(val_recall)
self.val_precisions.append(val_precis)
# Add custom metrics to the logs, so that we can use them with
# EarlyStop and csvLogger callbacks
logs["val_f1"] = val_f1
logs["val_recall"] = val_recall
logs["val_precis"] = val_precis
print("— val_f1: {} — val_precis: {} — val_recall {}".format(
val_f1, val_precis, val_recall))
return
def compute_tptnfpfn(self,val_target,val_predict):
# cast to boolean
val_target = val_target.astype('bool')
val_predict = val_predict.astype('bool')
tp = np.count_nonzero(val_target * val_predict)
tn = np.count_nonzero(~val_target * ~val_predict)
fp = np.count_nonzero(~val_target * val_predict)
fn = np.count_nonzero(val_target * ~val_predict)
return tp, tn, fp, fn
def compute_f1(self,tp, tn, fp, fn):
f1 = tp*1. / (tp + 0.5*(fp+fn) + sys.float_info.epsilon)
return f1
def compute_recall(self,tp, tn, fp, fn):
recall = tp*1. / (tp + fn + sys.float_info.epsilon)
return recall
def compute_precision(self,tp, tn, fp, fn):
precision = tp*1. / (tp + fp + sys.float_info.epsilon)
return precision
答案 3 :(得分:-1)
方法如下:
from sklearn.metrics import r2_score
class MetricsCallback(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
if epoch:
print(self.validation_data[0])
x_test = self.validation_data[0]
y_test = self.validation_data[1]
predictions = self.model.predict(x_test)
print('r2:', r2_score(prediction, y_test).round(2))
model.fit( ..., callbacks=[MetricsCallback()])
Keras 2.2.4