生成用于多标签分类的sklearn度量的问题



我已经在视网膜(眼睛)图像上实现了一个高效网络预训练模型,我不知道为什么我的指标不起作用!如果这是问题,我愿意使用其他度量包(keras?)。

# Loading a pretrained conv base model
input_shape = (256, 256, 3)
conv_base = EfficientNetB7(weights=None, include_top=False, input_shape=input_shape)
dropout_rate = 0.2
number_of_classes = 3
initial_learning_rate=2e-5
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
initial_learning_rate,
decay_steps=100000,
decay_rate=0.96,
staircase=True
)
en_model = models.Sequential()
en_model.add(conv_base)
en_model.add(layers.GlobalMaxPooling2D(name='gap'))
# Avoid overfitting 
en_model.add(layers.Dropout(rate=dropout_rate, name='dropout_out'))
# Set number_of_classes to the number of your final predictions
en_model.add(layers.Dense(number_of_classes, activation='sigmoid', name='fc_out')) #replaced softmax with sigmoid
conv_base.trainable = False
en_model.compile(
#loss='sparse_categorical_crossentropy',
#loss='categorical_crossentropy',
#optimizer=optimizers.RMSprop(learning_rate=2e-5),
loss='binary_crossentropy',
optimizer=optimizers.Adam(learning_rate=lr_schedule),
metrics=['accuracy']
)
history = en_model.fit(
train_generator,
steps_per_epoch=10,
epochs=100,
validation_data=val_generator,
#validation_steps=None,
validation_freq=1,
verbose=1,
callbacks=[tensorboard_callbacks],
use_multiprocessing=True,
workers=4
)
print('Average test loss: ', np.average(history.history['loss']))

指标——这是视网膜(眼睛)图像数据,有三个类别/标签——糖尿病视网膜病变、青光眼和其他。我将展示第一个类的代码,您可以看到每个指标的数字都是相同的,并且混淆矩阵为零。我不知道发生了什么事!

from sklearn.metrics import confusion_matrix, accuracy_score, f1_score, precision_score, recall_score
# y_true are the labels from the validation generator; we have three labels (DR, glaucoma, other)
print(f'Accuracy = {accuracy_score(val_generator.labels[:,0],[round(x) for x in val_pred[:,0]])}')
print(f"F1 = {f1_score(val_generator.labels[:,0],[round(x) for x in val_pred[:,0]], average='micro')}")
print(f"Precision = {precision_score(val_generator.labels[:,0],[round(x) for x in val_pred[:,0]], average='micro')}")
print(f"Recall = {recall_score(val_generator.labels[:,0],[round(x) for x in val_pred[:,0]], average='micro')}")
print('Confusion matrix =')
confusion_matrix(val_generator.labels[:,0],[round(x) for x in val_pred[:,0]])

输出
Accuracy = 0.7807953443258971
F1 = 0.7807953443258971
Precision = 0.7807953443258971
Recall = 0.7807953443258971
Confusion matrix =
array([[805,   0],
[226,   0]])

上面相同的代码(用1和2替换0)产生以下结果:

Accuracy = 0.8244422890397672
F1 = 0.8244422890397672
Precision = 0.8244422890397672
Recall = 0.8244422890397672
Confusion matrix =
array([[850,   0],
[181,   0]])
Accuracy = 0.6876818622696411
F1 = 0.6876818622696411
Precision = 0.6876818622696411
Recall = 0.6876818622696411
Confusion matrix =
array([[  0, 322],
[  0, 709]])

Keras和Tensorflow已经有很多指标,如果不是全部,如果你正在寻找替代品的话:


!pip install -U tensorflow-addons
import tensorflow as tf
from tensorflow.python.keras.metrics import Accuracy
from tensorflow.python.keras.metrics import Recall
from tensorflow.python.keras.metrics import Precision
from tensorflow.python.keras.metrics import AUC
import tensorflow_addons as tfa
tf.math.confusion_matrix
tfa.metrics.F1Score

关于你的Sigmoid激活函数,你提到你有3个类;为什么不考虑使用Softmax激活函数,这实际上是用于多类逻辑回归?您还必须根据标签的编码方式将binary_crossentropy损失函数替换为categorical_crossentropysparse_categorical_crossentropy。如果你有一个多标签分类问题,旨在预测零个或多个类标签(0,1),那么binary_crossentropy是你的正确选择。

最新更新