我正在努力训练一个非常简单的图像识别模型,没什么了不起的。当我使用图像重新缩放时,我的第一次尝试工作正常:
# this is the augmentation configuration to enhance the training dataset
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# validation generator, only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical')
然后我只是训练模型:
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size)
这完全正常,并且导致合理的准确性。然后我认为尝试平均减法可能是一个好主意,正如VGG16模型所使用的那样。我没有手动操作,而是选择使用ImageDataGenerator.fit()。然而,为此,你需要为它提供训练图像作为numpy数组,所以我首先阅读图像,转换它们,然后将它们输入它:
train_datagen = ImageDataGenerator(
featurewise_center=True,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(featurewise_center=True)
def process_images_from_directory(data_dir):
x = []
y = []
for root, dirs, files in os.walk(data_dir, topdown=False):
class_names = sorted(dirs)
global class_indices
if len(class_indices) == 0:
class_indices = dict(zip(class_names, range(len(class_names))))
for dir in class_names:
filenames = os.listdir(os.path.join(root,dir))
for file in filenames:
img_array = img_to_array(load_img(os.path.join(root,dir,file), target_size=(224, 224)))[np.newaxis]
if len(x) == 0:
x = img_array
else:
x = np.concatenate((x,img_array))
y.append(class_indices[dir])
#this step converts an array of classes [0,1,2,3...] into sparse vectors [1,0,0,0], [0,1,0,0], etc.
y = np.eye(len(class_names))[y]
return x, y
x_train, y_train = process_images_from_directory(train_data_dir)
x_valid, y_valid = process_images_from_directory(validation_data_dir)
nb_train_samples = x_train.shape[0]
nb_validation_samples = x_valid.shape[0]
train_datagen.fit(x_train)
test_datagen.mean = train_datagen.mean
train_generator = train_datagen.flow(
x_train,
y_train,
batch_size=batch_size,
shuffle=False)
validation_generator = test_datagen.flow(
x_valid,
y_valid,
batch_size=batch_size,
shuffle=False)
然后,我以同样的方式训练模型,简单地给它两个迭代器。训练结束后,即使在50个时期之后,准确度仍基本保持在~25%:
80/80 [==============================] - 77s 966ms /步 - 损失:12.0886 - acc: 0.2500 - val_loss:12.0886 - val_acc:0.2500
当我对上述模型进行预测时,它只能正确地对总共4个类进行分类,其他3个类中的所有图像都归类为属于第一类 - 显然25%的百分比与此事实有关,我无法弄清楚我做错了什么。
我意识到我可以手动计算平均值然后只是为两个生成器设置它,或者我可以使用ImageDataGenerator.fit()然后仍然使用flow_from_directory,但这将浪费已处理的图像,我会做两次相同的处理。
关于如何使其一直使用flow()的任何意见?
答案 0 :(得分:-1)
您是否尝试在生成器中设置shuffle = True?
您没有在第一种情况下指定改组(默认情况下应为True),而在第二种情况下将其设置为False。
您的输入数据可能按类排序。在不进行改组的情况下,您的模型首先只会看到#1类,而只会学习总是预测#1类。然后,它看到#2类,并学会总是预测#2类,依此类推。在一个时代结束时,您的模型将学习始终预测第4类,因此验证的准确性为25%。