【发布时间】:2019-08-20 08:42:52
【问题描述】:
我正在尝试对属于 16 个类别的图像进行分类。这些图像具有不同的几何形状 (see Fig. 2)。训练集包含 16 x 320 = 5120 张图片,验证集包含 16 x 160 = 2560 张图片,测试集包含 16 x 2 = 32 张图片。
我正在使用以下代码构建 CNN 并进行预测。
import numpy as np
np.random.seed(0)
import keras
from keras.models import Sequential,Input,Model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.advanced_activations import LeakyReLU
from keras import regularizers
from keras.layers import Activation
num_classes = 16
classifier = Sequential()
classifier.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(64, 64, 3),padding='same'))
classifier.add(MaxPooling2D((2, 2),padding='same'))
classifier.add(Dropout(0.2))
classifier.add(Conv2D(64, (3, 3), activation='relu',padding='same'))
#classifier.add(LeakyReLU(alpha=0.1))
classifier.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
classifier.add(Dropout(0.2))
classifier.add(Conv2D(64, (3, 3), activation='relu',padding='same'))
classifier.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
classifier.add(Dropout(0.25))
classifier.add(Conv2D(128, (3, 3), activation='relu',padding='same'))
classifier.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
classifier.add(Dropout(0.25))
classifier.add(Flatten())
classifier.add(Dense(128, activation='relu'))
classifier.add(Dropout(0.25))
classifier.add(Dense(num_classes, activation='softmax'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
from IPython.display import display
from PIL import Image
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
width_shift_range=0.1,
height_shift_range=0.1)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('dataset/training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
from keras.callbacks import ModelCheckpoint
from keras.callbacks import EarlyStopping
STEP_SIZE_TRAIN = training_set.n//training_set.batch_size
STEP_SIZE_TEST = test_set.n//test_set.batch_size
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=3)
checkpoint_callback = ModelCheckpoint('model' + '.h5', monitor='val_loss', verbose=1, save_best_only=True, mode='min')
classifier.fit_generator(training_set,
steps_per_epoch = STEP_SIZE_TRAIN,
epochs = 10,
validation_data = test_set,
validation_steps = STEP_SIZE_TEST,
callbacks=[early_stopping_callback, checkpoint_callback],
workers = 32)
from keras.models import load_model
model = load_model('model.h5')
# Part 3 - making new predictions
import numpy as np
from keras.preprocessing import image
for i in range(1,33):
test_image = image.load_img('dataset/single_prediction/Image ' + str(i) +'.bmp', target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
#print(model.predict(test_image)[0])
print(model.predict(test_image)[0].argmax()+1)
我得到以下训练和验证准确性和损失的结果。
Epoch 1/10
160/160 [==============================] - 29s 179ms/step - loss: 1.3693 - acc: 0.5299 - val_loss: 0.1681 - val_acc: 0.9297
Epoch 00001: val_loss improved from inf to 0.16809, saving model to model.h5
Epoch 2/10
160/160 [==============================] - 18s 112ms/step - loss: 0.2668 - acc: 0.8984 - val_loss: 0.0773 - val_acc: 0.9699
Epoch 00002: val_loss improved from 0.16809 to 0.07725, saving model to model.h5
Epoch 3/10
160/160 [==============================] - 18s 111ms/step - loss: 0.1469 - acc: 0.9482 - val_loss: 0.0133 - val_acc: 1.0000
Epoch 00003: val_loss improved from 0.07725 to 0.01327, saving model to model.h5
Epoch 4/10
160/160 [==============================] - 18s 111ms/step - loss: 0.0990 - acc: 0.9650 - val_loss: 0.0147 - val_acc: 1.0000
Epoch 00004: val_loss did not improve from 0.01327
Epoch 5/10
160/160 [==============================] - 18s 113ms/step - loss: 0.0700 - acc: 0.9740 - val_loss: 7.3014e-04 - val_acc: 1.0000
Epoch 00005: val_loss improved from 0.01327 to 0.00073, saving model to model.h5
Epoch 6/10
160/160 [==============================] - 18s 114ms/step - loss: 0.0545 - acc: 0.9809 - val_loss: 0.0012 - val_acc: 1.0000
Epoch 00006: val_loss did not improve from 0.00073
Epoch 7/10
160/160 [==============================] - 18s 111ms/step - loss: 0.0374 - acc: 0.9865 - val_loss: 0.0101 - val_acc: 1.0000
Epoch 00007: val_loss did not improve from 0.00073
Epoch 8/10
160/160 [==============================] - 18s 111ms/step - loss: 0.0489 - acc: 0.9832 - val_loss: 0.0200 - val_acc: 0.9992
当试图在测试集的 32 张图像上测试模型时,我只得到了 3 个正确的预测。所以我的问题是:
1) 为什么我的验证准确度很高,但模型在测试集上却失败了?
2) 我如何显示验证集的随机样本(例如 10 张图像)及其预测类别,以了解 CNN 在验证集上的表现?
3) 关于如何提高测试集准确率的一般提示?
感谢任何帮助! 非常感谢:)
【问题讨论】:
-
validation acc 在某些时期为 1。数据从火车泄漏到有效的可能性。
-
@Sreeram TP :你对如何解决这个问题有想法吗?
-
这 3 个数据集是独立的。我的意思是,图像是完全随机分配给每个图像的?如果是,另一种可能性可能是验证集上的过度拟合。尝试在验证集中使用很少的图像,看看它是如何工作的。然后逐渐增加它的大小,看看你是否达到了测试集准确度降低而验证准确度增加的地步。另外,您可以尝试提前停止。
-
@DavideVisentin:我在我的代码中使用了提前停止。问题是我有点新手,我不知道样本数量是否足以用于训练和验证。 “图像完全随机分配给每个图像”是什么意思?我有三个文件夹,我将图像随机放入每个文件夹中。这有意义吗?
-
对第二个问题有帮助吗?谢谢:)
标签: keras deep-learning classification conv-neural-network multiclass-classification