CNN keras 中图像的混淆矩阵
Posted
技术标签:
【中文标题】CNN keras 中图像的混淆矩阵【英文标题】:Confusion matrix on images in CNN keras 【发布时间】:2018-11-22 08:51:21 【问题描述】:我已经使用 keras 训练了我的 CNN 模型(多类分类),现在我想在我的测试图像集上评估该模型。
除了准确度、精确度和召回率之外,还有哪些可能的选项来评估我的模型?我知道如何从自定义脚本中获得精确度和召回率。但是我找不到一种方法来获取我的 12 类 图像 的混淆矩阵。 Scikit-learn 显示 way,但不适用于图像。 我正在使用 model.fit_generator ()
有没有办法为我的所有类创建混淆矩阵或找到我的类的分类置信度?我使用的是 Google Colab,不过我可以下载模型并在本地运行。
任何帮助将不胜感激。
代码:
train_data_path = 'dataset_cfps/train'
validation_data_path = 'dataset_cfps/validation'
#Parametres
img_width, img_height = 224, 224
vggface = VGGFace(model='resnet50', include_top=False, input_shape=(img_width, img_height, 3))
#vgg_model = VGGFace(include_top=False, input_shape=(224, 224, 3))
last_layer = vggface.get_layer('avg_pool').output
x = Flatten(name='flatten')(last_layer)
xx = Dense(256, activation = 'sigmoid')(x)
x1 = BatchNormalization()(xx)
x2 = Dropout(0.3)(x1)
y = Dense(256, activation = 'sigmoid')(x2)
yy = BatchNormalization()(y)
y1 = Dropout(0.6)(yy)
x3 = Dense(12, activation='sigmoid', name='classifier')(y1)
custom_vgg_model = Model(vggface.input, x3)
# Create the model
model = models.Sequential()
# Add the convolutional base model
model.add(custom_vgg_model)
model.summary()
#model = load_model('facenet_resnet_lr3_SGD_sameas1.h5')
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
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1./255)
# Change the batchsize according to your system RAM
train_batchsize = 32
val_batchsize = 32
train_generator = train_datagen.flow_from_directory(
train_data_path,
target_size=(img_width, img_height),
batch_size=train_batchsize,
class_mode='categorical')
validation_generator = validation_datagen.flow_from_directory(
validation_data_path,
target_size=(img_width, img_height),
batch_size=val_batchsize,
class_mode='categorical',
shuffle=True)
# Compile the model
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-3),
metrics=['acc', recall, precision])
# Train the model
history = model.fit_generator(
train_generator,
steps_per_epoch=train_generator.samples/train_generator.batch_size ,
epochs=100,
validation_data=validation_generator,
validation_steps=validation_generator.samples/validation_generator.batch_size,
verbose=1)
# Save the model
model.save('facenet_resnet_lr3_SGD_new_FC.h5')
【问题讨论】:
将预测值保存到y_pred
变量并使用sklearn.metrics.confusion_matrix(y_true, y_pred)
你能显示一些代码吗?我正在使用 model.fit_generator () 顺便说一句。
@AbhishekSingh 你能添加一些数据来运行代码并提供答案吗?
【参考方案1】:
为什么 scikit-learn 函数不能完成这项工作?您将训练/测试集中的所有样本(图像)向前传递,将 one-hot-encoding 转换为标签编码(请参阅link)并将其作为y_pred
传递给sklearn.metrics.confusion_matrix
。您以与y_true
类似的方式继续进行操作(一键标记)。
示例代码:
import sklearn.metrics as metrics
y_pred_ohe = KerasClassifier.predict(X) # shape=(n_samples, 12)
y_pred_labels = np.argmax(y_pred_ohe, axis=1) # only necessary if output has one-hot-encoding, shape=(n_samples)
confusion_matrix = metrics.confusion_matrix(y_true=y_true_labels, y_pred=y_pred_labels) # shape=(12, 12)
【讨论】:
能否请您显示一些代码,以便我更好地理解和投票/接受您的答案并关闭它? 嘿@Jan K 我已经更新了我的代码。谢谢你的帮助。我可以在这里添加什么?【参考方案2】:以下是如何获取所有类的混淆矩阵(或者可能是使用 scikit-learn 的统计数据):
1.预测类
test_generator = ImageDataGenerator()
test_data_generator = test_generator.flow_from_directory(
test_data_path, # Put your path here
target_size=(img_width, img_height),
batch_size=32,
shuffle=False)
test_steps_per_epoch = numpy.math.ceil(test_data_generator.samples / test_data_generator.batch_size)
predictions = model.predict_generator(test_data_generator, steps=test_steps_per_epoch)
# Get most likely class
predicted_classes = numpy.argmax(predictions, axis=1)
2.获取ground-truth类和类标签
true_classes = test_data_generator.classes
class_labels = list(test_data_generator.class_indices.keys())
3。使用 scikit-learn 获取统计数据
report = metrics.classification_report(true_classes, predicted_classes, target_names=class_labels)
print(report)
您可以阅读更多here
编辑: 如果上述方法不起作用,请观看此视频Create confusion matrix for predictions from Keras model。如果您有问题,可能会查看 cmets。 或Make predictions with a Keras CNN Image Classifier
【讨论】:
【参考方案3】:这里的猫和狗是类标签:
#Confusion Matrix and Classification Report
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
Y_pred = model.predict_generator(validation_generator, nb_validation_samples //
batch_size+1)
y_pred = np.argmax(Y_pred, axis=1)
print('Confusion Matrix')
print(confusion_matrix(validation_generator.classes, y_pred))
print('Classification Report')
target_names = ['Cats', 'Dogs']
print(classification_report(validation_generator.classes, y_pred, target_names=target_names))
【讨论】:
以上是关于CNN keras 中图像的混淆矩阵的主要内容,如果未能解决你的问题,请参考以下文章
使用 sklearn 使用 Keras 数据生成器绘制混淆矩阵