CNN图像分类计算混淆矩阵时出现LabelBinarizer无classes_属性报错
错误修复方案
错误根因
你实例化LabelBinarizer后没有对原始标签数据执行拟合操作,classes_是LabelBinarizer拟合数据后才会生成的属性,未拟合直接调用就会触发该报错。你查到的「在model.fit执行后再实例化LabelBinarizer」的方案是错误的,LabelBinarizer的实例化和拟合应该在标签编码阶段完成,和模型训练顺序无关。
修复方法
根据你的使用场景二选一即可:
场景1:你原本就是用LabelBinarizer做标签独热编码
把LabelBinarizer的实例化、拟合逻辑移到标签处理阶段,全程使用同一个实例即可,修改后完整代码如下:
from keras.models import Sequential from keras.layers import Dense,Activation,Flatten,Dropout from keras.layers import Conv2D,MaxPooling2D from keras.callbacks import ModelCheckpoint import numpy as np from sklearn.preprocessing import LabelBinarizer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report, confusion_matrix # 提前初始化LabelBinarizer并拟合原始标签 lb = LabelBinarizer() # 你的target已经是独热编码,所以用解码后的标签拟合即可 lb.fit(np.argmax(target, axis=1)) model=Sequential() model.add(Conv2D(200,(3,3),input_shape=data.shape[1:])) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Conv2D(100,(3,3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dropout(0.5)) model.add(Dense(50,activation='relu')) model.add(Dense(2,activation='softmax')) model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) train_data,test_data,train_target,test_target=train_test_split(data,target,test_size=0.1) checkpoint = ModelCheckpoint('model-{epoch:03d}.model',monitor='val_loss',verbose=0,save_best_only=True,mode='auto') history=model.fit(train_data,train_target,epochs=4,callbacks=[checkpoint],validation_split=0.2) print("[INFO] evaluating network...") predIdxs = model.predict(test_data, batch_size=28) predIdxs = np.argmax(predIdxs, axis=1) print(classification_report(test_target.argmax(axis=1), predIdxs, target_names=lb.classes_)) cm = confusion_matrix(test_target.argmax(axis=1), predIdxs) total = sum(sum(cm)) acc = (cm[0, 0] + cm[1, 1]) / total sensitivity = cm[0, 0] / (cm[0, 0] + cm[0, 1]) specificity = cm[1, 1] / (cm[1, 0] + cm[1, 1]) print(cm) print("acc: {:.4f}".format(acc)) print("sensitivity: {:.4f}".format(sensitivity)) print("specificity: {:.4f}".format(specificity))
场景2:你已经手动完成了标签独热编码,不需要复用LabelBinarizer
直接删掉LabelBinarizer相关代码,手动传入分类名称即可,修改对应部分代码为:
# 删掉 lb = LabelBinarizer() 这一行 print(classification_report(test_target.argmax(axis=1), predIdxs, target_names=["类别1名称", "类别2名称"])) # 替换为你实际的分类名称
内容的提问来源于stack exchange,提问作者Khalid Hasan
相关产品推荐
相关产品推荐

