带有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,准确性保持不变并且没有提高的主要内容,如果未能解决你的问题,请参考以下文章
CNN 训练准确率在训练期间变得更好,但测试准确率保持在 40% 左右