【发布时间】:2019-10-09 04:32:59
【问题描述】:
我使用 CNN 对不平衡数据集进行图像分类。我对 tensorflow 后端完全陌生。这是多类问题(不是多标签),我有 16 个类。类是一种热编码。
我想计算每个时期的 MACRO 指标:F1、精度和召回率。
我找到了打印这些宏指标的代码,但它仅适用于验证集 来自:https://medium.com/@thongonary/how-to-compute-f1-score-for-each-epoch-in-keras-a1acd17715a2
class Metrics(Callback):
def on_train_begin(self, logs={}):
self.val_f1s = []
self.val_recalls = []
self.val_precisions = []
def on_epoch_end(self, epoch, logs={}):
val_predict = (np.asarray(self.model.predict(self.validation_data[0]))).round()
val_targ = self.validation_data[1]
_val_f1 = f1_score(val_targ, val_predict,average='macro')
_val_recall = recall_score(val_targ, val_predict,average='macro')
_val_precision = precision_score(val_targ, val_predict,average='macro')
self.val_f1s.append(_val_f1)
self.val_recalls.append(_val_recall)
self.val_precisions.append(_val_precision)
print (" — val_f1: %f — val_precision: %f — val_recall %f" % (_val_f1, _val_precision, _val_recall))
return
metrics = Metrics()
我什至不确定这段代码是否真的有效,因为我们使用了
val_predict = (np.asarray(self.model.predict(self.validation_data[0]))).round()
在多类分类的情况下,ROUND 会导致错误吗?
我使用此代码在训练集上打印指标(仅回忆起对我来说很重要的指标)(也计算验证集,因为它在 model.compute 中使用) 代码改编自:Custom macro for recall in keras
def recall(y_true,y_pred):
true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
return true_positives / (possible_positives + K.epsilon())
def unweightedRecall(y_true, y_pred):
return (recall(y_true[:,0],y_pred[:,0]) + recall(y_true[:,1],y_pred[:,1])+recall(y_true[:,2],y_pred[:,2]) + recall(y_true[:,3],y_pred[:,3])
+recall(y_true[:,4],y_pred[:,4]) + recall(y_true[:,5],y_pred[:,5])
+recall(y_true[:,6],y_pred[:,6]) + recall(y_true[:,7],y_pred[:,7])
+recall(y_true[:,8],y_pred[:,8]) + recall(y_true[:,9],y_pred[:,9])
+recall(y_true[:,10],y_pred[:,10]) + recall(y_true[:,11],y_pred[:,11])
+recall(y_true[:,12],y_pred[:,12]) + recall(y_true[:,13],y_pred[:,13])
+recall(y_true[:,14],y_pred[:,14]) + recall(y_true[:,15],y_pred[:,15]))/16.
我运行我的模型
model.compile(optimizer="adam", loss="categorical_crossentropy",metrics=[unweightedRecall,"accuracy"]) #model compilation with unweightedRecall metrics
train =model.fit_generator(image_gen.flow(train_X, train_label, batch_size=64),epochs=100,verbose=1,validation_data=(valid_X, valid_label),class_weight=class_weights,callbacks=[metrics],steps_per_epoch=len(train_X)/64) #run the model
VALIDATION 宏调用不同于 2 个不同的代码。
即(查看 val_unweightedRecall 和 val_recall)
Epoch 10/100
19/18 [===============================] - 13s 703ms/step - loss: 1.5167 - unweightedRecall: 0.1269 - acc: 0.5295 - val_loss: 1.5339 - val_unweightedRecall: 0.1272 - val_acc: 0.5519
— val_f1: 0.168833 — val_precision: 0.197502 — val_recall 0.15636
为什么使用两个不同的代码对我的宏验证召回有不同的价值?
额外问题:对于已经尝试过这个的人,是否真的值得使用基于我们感兴趣的指标(例如召回)的自定义损失或带有权重的分类交叉熵产生相同的结果?
【问题讨论】:
标签: python tensorflow machine-learning keras