【发布时间】:2022-06-30 01:25:27
【问题描述】:
我正在使用包含 5 类图像的数据集,其中大约 4000 张图像在训练数据集中,2000 张在测试数据集中。
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
from keras import optimizers
from matplotlib import pyplot as plt
import numpy as np
import seaborn as sns
from sklearn.metrics import confusion_matrix
img_width, img_height = 512, 384
categories = ["cardboard", "glass", "metal", "paper", "plastic"]
train_data_dir = '/Users/lukasrois/ve/Train_Data'
test_data_dir = '/Users/lukasrois/ve/Test_Data'
classifier = Sequential()
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
classifier.add(Conv2D(64,(3,3),input_shape = (64,64,3), activation= 'relu'))
classifier.add(Dropout(.1))
classifier.add(MaxPooling2D(pool_size=(2,2)))
classifier.add(Conv2D(32,(3,3),input_shape = (32,32,3), activation= 'relu'))
classifier.add(Dropout(.1))
classifier.add(MaxPooling2D(pool_size=(2,2)))
classifier.add(Flatten())
classifier.add(Dense(1024, activation='relu'))
classifier.add(Dense(1024, activation='relu'))
classifier.add(Dense(5, activation='softmax'))
classifier.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
train_datagen = ImageDataGenerator(
rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip=True
)
test_datagen = ImageDataGenerator(rescale=1./255)
train_set = train_datagen.flow_from_directory(train_data_dir, target_size=(64,64),
batch_size=10, class_mode='categorical', shuffle=True)
test_set = test_datagen.flow_from_directory(test_data_dir, target_size=(64,64),
batch_size=10, class_mode='categorical', shuffle=True)
nb_train_samples = len(train_set)
nb_validation_samples = len(test_set)
train_labels = train_set.classes
hist = classifier.fit_generator(train_set, steps_per_epoch=None, epochs=50,
validation_data=test_set, shuffle=True)
plt.plot(hist.history['acc'])
plt.plot(hist.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
plt.plot(hist.history['loss'])
plt.plot(hist.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
y_pred = classifier.predict_generator(test_set)
y_pred = np.rint(y_pred)
y_true = test_set.classes
predict_class = np.argmax(y_pred, axis=1)
predict_class = predict_class.tolist()
print(confusion_matrix(y_true, predict_class))
sns.heatmap(confusion_matrix(y_true, predict_class), square=True, annot=True, cmap='Blues', fmt='d', cbar=False)
当我训练我的模型时,这是完成训练后的输出:
Epoch 50/50
426/426 [==============================] - 336s 788ms/step - loss: 0.0405 - acc: 0.9881 - val_loss: 0.5690 - val_acc: 0.8882
我的混淆矩阵是这样的:
[[ 17 38 15 35 16]
[ 80 280 80 173 143]
[ 45 129 55 76 49]
[ 54 187 56 121 76]
[ 43 140 50 85 87]]
但是,如果我将混淆矩阵上的所有正确特征相加,然后除以不正确特征的总数,我得到 560/1570= 0.36。那么为什么准确率不同呢?
编辑 我改变了创建混淆矩阵的方法。我制作了自己的函数,它不依赖于 test_set,像这样:
def config_confusion_matrix():
actual_values = []
predicted_values = []
for i in range(50):
c = categories.index(random.choice(categories))
r = categories[c]
path = "/Users/lukasrois/ve/Test_Data/"+r+"/"
random_filename = random.choice([x for x in os.listdir(path) if os.path.isfile(os.path.join(path, x))])
new_path = "/Users/lukasrois/ve/Test_Data/"+r+"/"+random_filename
result = cast_predict(new_path)
predicted_values.append(result)
actual_values.append(c)
return (actual_values, predicted_values)
混淆矩阵:
array([[ 6, 0, 0, 0, 4],
[ 0, 0, 5, 0, 3],
[ 0, 0, 8, 0, 0],
[ 3, 1, 10, 0, 1],
[ 0, 4, 5, 0, 0]])
当前精度:
>>> classifier.evaluate_generator(test_set)
[0.28701336261618293, 0.9285955914520505]
但是,我的混淆矩阵在训练时仍然不能反映相同的准确性。为什么?
【问题讨论】:
-
因为这不是您应该使用生成器计算任何指标的方式,所以您不能使用 test_set.classes,因为它与生成器中的样本顺序不同。
-
有什么方法可以让我的混淆矩阵得到匹配的类?
标签: python tensorflow machine-learning keras deep-learning