为什么训练VGG-16的准确性没有太大变化?

时间:2019-05-19 12:09:45

标签: python tensorflow keras deep-learning

当前,我正在尝试在VGG-16模型上训练数据集。问题是精度没有太大变化,但并没有固定的精度。该图可以在下面看到。有什么建议为什么会发生这种情况?

我遵循了一些指南来解决有关卡住精度的问题,但是它们不起作用。

Figure of accuracy plot

编辑:

200个时代

200 Epoch Plot

50个具有Imagenet权重的时代

50 Epochs with Imagenet Weights

代码

模型的输入大小是600张224x224x3图像。此外,还有两个标签,狗和猫(0,1)。

属性

imageSize = (224,224,3)
epochs = 25
batch_size = 32

模型

from keras.applications.vgg16 import VGG16
vgg = VGG16(input_shape=imageSize,weights=None,include_top=False)

x = Flatten()(vgg.output)
prediction = Dense(1,activation='sigmoid')(x)

model = Model(inputs=vgg.input,outputs=prediction)
model.compile(loss='binary_crossentropy', optimizer='adam',metrics=['accuracy'])

图像生成器

from keras.applications.vgg16 import preprocess_input
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator

imgGen = ImageDataGenerator(rotation_range=20,
                            width_shift_range=0.1,
                            height_shift_range=0.1,
                            shear_range=0.1,
                            zoom_range=0.2,
                            horizontal_flip=True,
                            vertical_flip=True,
                            preprocessing_function = preprocess_input)

合适的型号

r = model.fit_generator(imgGen.flow(trainX, trainY, batch_size=batch_size),
                        validation_data = imgGen.flow(testX, testY, batch_size=batch_size),
                        epochs=epochs,
                        steps_per_epoch=len(trainX)//batch_size,
                        validation_steps=len(testX)//batch_size,
                        verbose = 1,
                       )


5 个答案:

答案 0 :(得分:1)

对于可能有类似问题的人,您可以尝试以下操作:

  • 加载预先训练的VGG-16重量
  • 仅使最后几个卷积层可训练
  • 使用SGD优化器并将学习率设置为低
  • 在输出层设置正确的激活功能
  • 增加时代

关于使用预先训练的权重,使用预先训练的权重的好处是您可以克服小型数据集的局限性,例如OP具有600张图像的情况。但是您必须确保只有最后几层是可训练的,其余的层是不可训练的。

答案 1 :(得分:1)

您正在寻找发生这种情况的原因,我认为您似乎没有得到答案,所以这里是...

原因是在 VGGNet 中,AlexNet 参数空间 巨大,为了解决这个问题,它没有像 ResNet 中使用的 BatchNorm 和后一种型号。所以在 VGGNet 中要使模型收敛你必须自己做,玩超参数尤其是学习率,经验结果表明从低至 1e-6 开始甚至有助于收敛。此外,如果您可以对权重使用一些不同的权重初始化,这将在收敛方面显示出巨大的结果,导致默认权重初始化在这种情况下无法正常工作。最后,让模型训练更长的 epochs(比如 100),因为(参数的)空间非常颠簸,你会看到它有点振荡,但如果使用适当的 lr,它会收敛但需要一些时间。

希望它能给你一点直觉......

答案 2 :(得分:0)

25个时代是不够的,请尝试100个或200个时代

def model(self):
    inputs = keras.layers.Input(shape=self.input_Shape)
    x = keras.layers.Conv2D(16, (3,3), activation='relu')(inputs)
    x = keras.layers.MaxPooling2D(2,2)(x)
    x = keras.layers.Conv2D(32,(3,3),activation='relu')(x)
    x = keras.layers.MaxPooling2D(2,2)(x)
    x = keras.layers.Conv2D(64,(3,3),activation='relu')(x)
    x = keras.layers.MaxPooling2D(2,2)(x)
    x = keras.layers.Flatten()(x)
    x = keras.layers.Dense(512,activation='relu')(x)
    outputs = keras.layers.Dense(1,activation='sigmoid')(x)

    model = keras.models.Model(inputs, outputs)
    model.summary()
    model.compile(optimizer=RMSprop(lr=0.001),
                  loss='binary_crossentropy',
                  metrics = ['acc'])

    return model

答案 3 :(得分:0)

请勿使用adam优化器来训练VGG,众所周知,由于VGG网络中的大量参数,它会失败。只需使用sgd并调整学习率即可,例如从0.01开始,增加10倍或0.1倍,直到训练损失降低为止。

答案 4 :(得分:0)

我建议您微调预先训练的模型,并冻结前几层的权重。 喜欢:

vgg = VGG16(input_shape=imageSize,weights='imagenet',include_top=False)
for layer in vgg.layers[0:-10]:
    layer.trainable = false