Python 为什么';训练VGG-16的准确度变化大吗?

Python 为什么';训练VGG-16的准确度变化大吗?,python,tensorflow,keras,deep-learning,Python,Tensorflow,Keras,Deep Learning,目前,我正在尝试在VGG-16模型上训练数据集。问题是精度变化不大,但并没有固定的精度。图中的图形如下所示。有什么建议可以解释为什么会发生这种情况吗 我已经遵循了一些指南来解决这个关于精度的问题,但是它们不起作用 编辑: 200个时代 使用图像净重的50个时代 代码 模型的输入大小为600张224x224x3的图像。此外,还有两个标签dog和cat(0,1) 属性 imageSize = (224,224,3) epochs = 25 batch_size = 32 型号 from ke

目前,我正在尝试在VGG-16模型上训练数据集。问题是精度变化不大,但并没有固定的精度。图中的图形如下所示。有什么建议可以解释为什么会发生这种情况吗

我已经遵循了一些指南来解决这个关于精度的问题,但是它们不起作用

编辑:

200个时代

使用图像净重的50个时代

代码 模型的输入大小为600张224x224x3的图像。此外,还有两个标签dog和cat(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'])
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,
                       )


图像生成器

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)
适合车型

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'])
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,
                       )



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

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

不要使用
adam
优化器来训练VGG,众所周知,由于VGG网络中的大量参数,它会失败。只需使用
sgd
并调整学习率,比如从0.01开始,增加10倍或0.1倍,直到训练损失很好地减少。

不要使用
adam
优化器训练VGG,众所周知,由于VGG网络中的大量参数,它会失败。只需使用
sgd
并调整学习速率,比如从0.01开始,增加10倍或0.1倍,直到训练损失很好地减少。

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


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


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

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

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

对于可能有类似问题的人,你可以尝试以下方法:

  • 加载预先训练的VGG-16砝码
  • 仅使最后几个卷积层可训练
  • 使用SGD Optimizer并将学习率设置为低
  • 在输出层设置正确的激活功能
  • 增加年代
关于使用预训练权重,使用预训练权重的好处是,您可以克服小数据集的限制,例如OP的600幅图像的情况。但你必须确保只有最后几层是可训练的,其余的是不可训练的。

你在寻找发生这种情况的原因,我猜,你似乎没有得到答案,所以在这里

原因是在VGGNet中,AlexNet的参数空间是巨大的,为了解决这个问题,它没有任何像BatchNorm这样的复杂技术用于ResNet和后面的模型。因此,在VGGNet中,要使模型收敛,你必须自己动手,使用超参数,尤其是学习率,实证结果表明,从低至1e-6开始甚至有助于收敛。另外,如果您可以对权重使用一些不同的权重初始化,这将在收敛方面显示出巨大的结果,因为默认的权重初始化在这种情况下不能很好地工作。最后,让模型训练更长的时间(比如100年),因为(参数的)空间非常不平坦,你会看到它有点振荡,但如果使用适当的lr,它会收敛,但需要一些时间

希望它能给你一点直觉…

我猜你在寻找它发生的原因,似乎你没有得到答案,所以这里是

原因是在VGGNet中,AlexNet的参数空间是巨大的,为了解决这个问题,它没有任何像BatchNorm这样的复杂技术用于ResNet和后面的模型。因此,在VGGNet中,要使模型收敛,你必须自己动手,使用超参数,尤其是学习率,实证结果表明,从低至1e-6开始甚至有助于收敛。另外,如果您可以对权重使用一些不同的权重初始化,这将在收敛方面显示出巨大的结果,因为默认的权重初始化在这种情况下不能很好地工作。最后,让模型训练更长的时间(比如100年),因为(参数的)空间非常不平坦,你会看到它有点振荡,但如果使用适当的lr,它会收敛,但需要一些时间


希望它能给你一点直觉…

sry,我再次检查模型。原始vgg模型没有输出层。因此,您需要添加一个输出层。keras.layers.Dense(1,Activation='sigmoid')感谢您的建议。在我试过之后,我会给你回信。如果更多的纪元仍然不起作用的话。你能试着使用预先训练好的重量,然后检查结果吗?目前,我正在尝试使用200个纪元,然后我会给你数字图。是的,我能做到:)我两个都试过了,但似乎都不起作用。我已经编辑了我的帖子,并在其中添加了绘图:)sry,我再次检查了模型。原始vgg模型没有输出层。因此,您需要添加一个输出层。keras.layers.Dense(1,Activation='sigmoid')感谢您的建议。在我试过之后,我会给你回信。如果更多的纪元仍然不起作用的话。你能试着使用预先训练好的重量,然后检查结果吗?目前,我正在尝试使用200个纪元,然后我会给你数字图。是的,我能做到:)我两个都试过了,但似乎都不起作用。我已经编辑了我的帖子,并在其中添加了情节