keras 为什么训练VGG-16时的准确度变化不大?

kq0g1dla  于 2022-11-13  发布在  其他
关注(0)|答案(7)|浏览(308)

目前,我正在尝试在VGG-16模型上训练数据集。问题是精度变化不大,但它并没有固定在一个固定的精度上。绘图可以在下面看到。有什么建议为什么会发生这种情况?
我已经遵循了几个指南来解决这个问题,这是关于卡住的准确性,但他们不工作。

编辑:

200个历元

具有Imagenet权重的50个历元

代码

模型的输入大小为600张224 x224 x3的图像。此外,还有两个标签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'])

图像生成器

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,
                       )
yb3bgrhw

yb3bgrhw1#

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

zzlelutf

zzlelutf2#

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

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

j13ufse23#

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

  • 加载预先训练的VGG-16砝码
  • 仅使最后几个卷积层可训练
  • 使用SGD优化器并将学习率设置为低
  • 在输出层设置正确的激活函数
  • 递增历元

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

kcrjzv8t

kcrjzv8t4#

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

原因是在VGGNet,AlexNet中,参数空间*巨大**,为了处理这个问题,它没有任何复杂的技术,如ResNet和后面的模型中使用的BatchNorm。因此,在VGGNet中,要使模型收敛,您必须自己动手,使用超参数,尤其是学习率,经验结果显示,从低至1 e-6开始甚至有助于收敛。2而且,如果你能为权重使用一些不同的权重初始化,这将在收敛方面显示出巨大的结果,因为默认的权重初始化在这种情况下不能很好的工作。最后,让模型训练更长的时间(比如100),因为(参数的)空间是相当不稳定的,你会看到它有点振荡,但是如果有合适的lr,它会收敛,但是需要一些时间。
希望它能给你一点直觉...

bvjxkvbb

bvjxkvbb5#

原因

在预测层之前缺少完全连接的层。
背景
您可以将VGG模型(实际上大多数其他模型也是如此)视为由以下内容组成
1.特征提取器(卷积层和池化层),以及
1.完全连接的网络,其使用所提取的特征来学习期望的分类。
通过使用include_top=False,您可以删除VGG 16模型中完全连接的层。因此,您最终只得到了特征提取器。没有网络使用这些特征进行分类。

溶液

在特征提取器(vgg)和预测层之间添加两个完全连接的隐藏层。同时建议使用 * 迁移学习 *,因为对于包含数百万参数的庞大vgg网络来说,您的数据集太小了。代码应该如下所示(还没有测试过):

# load the model (only the feature extractor) with the imagenet weights 
vgg = VGG16(input_shape=imageSize, weights='imagenet', include_top=False, pooling='avg')
# freeze the feature extractor values, as they're already pretrained on imagenet
vgg.trainable = False
# build the classificator model
model = Sequential()
# use vgg as feature extractor
model.add(vgg)
# add two hidden layers for classification
model.add(Dense(512, activation=('relu'))
model.add(Dense(256, activation=('relu'))
# add the prediction layer
model.add(Dense(1, activation=('sigmoid'))

祝大家好运!

gj3fmq9x

gj3fmq9x6#

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
4c8rllxm

4c8rllxm7#

如果您从头开始训练模型,请不要忘记权重初始化-some example is here

相关问题