带有keras的CNN,准确性保持不变并且没有提高

Posted

技术标签:

【中文标题】带有keras的CNN,准确性保持不变并且没有提高【英文标题】:CNN with keras, accuracy remains constant and does not improve 【发布时间】:2018-11-22 17:15:45 【问题描述】:

我正在尝试通过 finetuning 一个预训练的 model(vggface) 来训练我的模型。我的模型有 12 个类,有 1774 个训练图像和 313 个验证图像,每个类有大约 150 个图像。 到目前为止,我已经能够在 keras 中使用以下脚本实现 80% 左右的最大准确度:

img_width, img_height = 224, 224

vggface = VGGFace(model='resnet50', include_top=False, input_shape=(img_width, img_height, 3))

last_layer = vggface.get_layer('avg_pool').output
x = Flatten(name='flatten')(last_layer)
out = Dense(12, activation='softmax', name='classifier')(x)
custom_vgg_model = Model(vggface.input, out)


# Create the model
model = models.Sequential()

# Add the convolutional base model
model.add(custom_vgg_model)

train_datagen = ImageDataGenerator(
      rescale=1./255,
      rotation_range=20,
      width_shift_range=0.2,
      height_shift_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')

validation_datagen = ImageDataGenerator(rescale=1./255)

# Change the batchsize according to your system RAM
train_batchsize = 16
val_batchsize = 16

train_generator = train_datagen.flow_from_directory(
        train_data_path,
        target_size=(img_width, img_height),
        batch_size=train_batchsize,
        class_mode='categorical')

validation_generator = validation_datagen.flow_from_directory(
        validation_data_path,
        target_size=(img_width, img_height),
        batch_size=val_batchsize,
        class_mode='categorical',
        shuffle=True)

# Compile the model
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-3),
              metrics=['acc'])
# Train the model
history = model.fit_generator(
      train_generator,
      steps_per_epoch=train_generator.samples/train_generator.batch_size ,
      epochs=50,
      validation_data=validation_generator,
      validation_steps=validation_generator.samples/validation_generator.batch_size,
      verbose=1)

到目前为止我已经尝试过:

通过将 epoch 增加到 100。 通过更改学习率。 通过将优化器更改为 rmsprop。但这带来了更糟糕的结果。 有人建议我添加更多具有 dropout 和批量标准化的 FC 层。一世 这样做了,验证准确率仍然在 79% 左右。

这是我的改变:

vggface = VGGFace(model='resnet50', include_top=False, input_shape=(img_width, img_height, 3))

#vgg_model = VGGFace(include_top=False, input_shape=(224, 224, 3))

last_layer = vggface.get_layer('avg_pool').output
x = Flatten(name='flatten')(last_layer)
xx = Dense(256, activation = 'relu')(x)
x1 = BatchNormalization()(xx)
x2 = Dropout(0.3)(xx)

y = Dense(256, activation = 'relu')(x2)
yy = BatchNormalization()(y)
y1 = Dropout(0.3)(y)

z = Dense(256, activation = 'relu')(y1)
zz = BatchNormalization()(z)
z1 = Dropout(0.6)(zz)

x3 = Dense(12, activation='softmax', name='classifier')(z1)

custom_vgg_model = Model(vggface.input, x3)

按照SymbolixAUhere 的建议,我现在已将我的激活设置为 softmax。 val acc 现在仍然是 81%,而训练 acc 接近 99%

我做错了什么?

【问题讨论】:

对于任何可能看到此内容的人,请从更高的学习率开始或使用学习率调度程序。 【参考方案1】:

小心你的连接。在前两个块中,BatchNormalization 未连接到 dropout。改变前两个dropout的输入。

xx = Dense(256, activation = 'relu')(x)
x1 = BatchNormalization()(xx)
x2 = Dropout(0.3)(x1)

y = Dense(256, activation = 'relu')(x2)
yy = BatchNormalization()(y)
y1 = Dropout(0.3)(yy)

您提供的值意味着您的网络过度拟合。批量标准化或添加更多 dropout 可能会有所帮助。但是,鉴于图像数量很少,您应该尝试图像增强来增加训练图像的数量。

【讨论】:

抱歉。那是我的错误。我已经更正了。 我应该使用带有 0.8 之类的值的 dropout 吗?或者我应该逐渐增加,看看哪个效果更好 我记得在某处读到 Dense 层的 dropout 应该是 0.3 到 0.4,而 Conv2D 层的 dropout 应该是 0.2。但是,这可能会因您的数据集过度拟合的可能性而有所不同,您必须进行试验,看看哪一个适合您。 你真的应该做图像增强:改变比例、旋转、剪切……这样网络就可以训练更多的例子。这可能会给你最好的改进。登录 keras 网站

以上是关于带有keras的CNN,准确性保持不变并且没有提高的主要内容,如果未能解决你的问题,请参考以下文章

Keras DNN 预测模型准确率没有提高

Pytorch CNN 不学习

CNN 训练准确率在训练期间变得更好,但测试准确率保持在 40% 左右

为啥训练时准确率和损失保持不变?

使用Python,Keras和TensorFlow训练第一个CNN

使用Python,Keras和TensorFlow训练第一个CNN