我正在使用 Keras 2.0.4(TensorFlow 后端)进行图像分类任务。我正在尝试训练自己的网络(没有任何预训练参数)。由于我的数据很大,我无法将所有数据都加载到内存中。出于这个原因,我使用ImageDataGenerator()
,flow_from_directory()
和fit_generator()
。
创建ImageDataGenerator
对象:
train_datagen = ImageDataGenerator(preprocessing_function = my_preprocessing_function) # only preprocessing; no augmentation; static data set
my_preprocessing_function 将图像重新缩放到域 [0,255] 并通过均值缩减来居中数据(类似于 VGG16 或 VGG19 的预处理)
flow_from_directory()
对象中的使用方法ImageDataGenerator
:
train_generator = train_datagen.flow_from_directory(
path/to/training/directory/with/five/subfolders,
target_size=(img_width, img_height),
batch_size=64,
classes = ['class1', 'class2', 'class3', 'class4', 'class5'],
shuffle = True,
seed = 1337,
class_mode='categorical')
(同样是为了创建一个validation_generator。)
在定义和编译模型(损失函数:categorical crossentropy
,优化器:)后Adam
,我使用以下方法训练模型fit_generator()
:
model.fit_generator(
train_generator,
steps_per_epoch=total_amount_of_train_samples/batch_size,
epochs=400,
validation_data=validation_generator,
validation_steps=total_amount_of_validation_samples/batch_size)
问题:
没有错误消息,但训练效果不佳。在 400 个 epoch 之后,准确率仍然在 20% 左右波动(这与随机选择其中一个类一样好)。事实上,分类器总是预测“class1”。在仅一个时期的训练之后也是如此。尽管我正在初始化随机权重,但为什么会出现这种情况?怎么了?我错过了什么?
使用型号
x = Input(shape=input_shape)
# Block 1
x = Conv2D(16, (3, 3), activation='relu', padding='same', name='block1_conv1')(x)
x = Conv2D(16, (5, 5), activation='relu', padding='same', name='block1_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)
# Block 2
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
x = Conv2D(64, (5, 5), activation='relu', padding='same', name='block2_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)
# Block 3
x = Conv2D(16, (1, 1), activation='relu', padding='same', name='block3_conv1')(x)
# Block 4
x = Conv2D(256, (3, 3), activation='relu', padding='valid', name='block4_conv1')(x)
x = Conv2D(256, (5, 5), activation='relu', padding='valid', name='block4_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)
# Block 5
x = Conv2D(1024, (3, 3), activation='relu', padding='valid', name='block5_conv1')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)
# topping
x = Dense(1024, activation='relu', name='fc1')(x)
x = Dense(1024, activation='relu', name='fc2')(x)
predictions = Dense(5, activation='softmax', name='predictions')(x)