我有一个不平衡的数据集(真标签比假标签大约 10 倍),因此使用 f_beta 分数作为模型性能的指标,如下所示:
def fbeta(beta):
def f1(y_true, y_pred):
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)))
recall = true_positives / (possible_positives + K.epsilon())
return recall
def precision(y_true, y_pred):
true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
precision = true_positives / (predicted_positives + K.epsilon())
return precision
beta_squared = beta ** 2
precision = precision(y_true, y_pred)
recall = recall(y_true, y_pred)
fbeta_score = (beta_squared + 1) * (precision * recall) / (beta_squared * precision + recall + K.epsilon())
return fbeta_score
return f1
运行我的模型,我得到以下输出。
Epoch 00001:val_f1 从 -inf 提高到 0.90196,将模型保存到 output\LSTM\weights\floods_weights.h5 Epoch 2/3
- 0s - loss: 0.4114 - f1: 0.8522 - val_loss: 0.4193 - val_f1: 0.9020 Epoch 00002: val_f1 did从 0.90196
时期 3/3
- 0s - 损失:0.3386 - f1:0.8867 - val_loss:0.3589 - val_f1:0.9020 时期 00003:val_f1 没有从 0.90196 改进
评估:
51/51 [========= =====================] - 0s 372us/步
最终精度:0.9019607305526733
但是,当使用交换的 y 标签(True->False,False->True)再次运行模型时,我得到完全相同的值,但不明白为什么 f 测量不太可能给出完全相同的结果。
在使用以下代码评估最终模型的精度和召回率时,我确实得到了不同的结果:0.6 vs 0.95788:
prediction = model.predict(data['X_test'], batch_size=64)
tp = 0
fp = 0
fn = 0
for y, p in zip(data['y_test'], np.argmax(prediction, axis=1)):
y = y[0]
if y == 1 and p == 1:
tp += 1
elif p == 1 and y == 0:
fp += 1
elif p == 0 and y == 1:
fn += 1
precision = tp / (tp + fp)
recall = tp / (tp + fn)
print(2 * (precision * recall) / (precision + recall))
发生了什么?
编辑:
我正在编译模型:
beta = 1
model.compile(
optimizer=Adam(lr=1e-3),
loss='categorical_crossentropy',
metrics=[fbeta(beta)]
)