【问题标题】:Lower accuracy of VGG16 using data augmentation in Keras在 Keras 中使用数据增强的 VGG16 精度较低
【发布时间】:2018-08-07 10:28:00
【问题描述】:

我有一个关于在 Keras 中使用数据增强进行特征提取的问题。我正在构建一个狗品种分类器。

通过特征提取,我指的是通过在顶部添加 Dense 层来扩展模型 (conv_base, VGG16),并在输入数据上端到端运行整个事情。这将允许我使用数据增强,因为每个输入图像每次被模型看到时都会通过卷积基础。

训练集:6680 张图像,属于 133 个类别

验证集:属于 133 个类别的 835 张图像

测试集:属于 133 个类别的 836 张图像

我能够成功地实现彼此独立的数据增强和特征提取,但是当我尝试将两者结合起来时,由于某种原因,我的准确度变得非常小。为什么是这样?我的方法有什么严重错误吗?

from keras.applications import VGG16

from keras.preprocessing.image import ImageDataGenerator

conv_base = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape=(224, 224, 3))

model = Sequential()

model.add(conv_base)

conv_base.trainable = False

model.add(GlobalAveragePooling2D())

model.add(Dense(133, activation='softmax'))

model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

train_datagen_aug = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,)

test_datagen_aug = ImageDataGenerator(rescale=1./255)

train_generator_aug = train_datagen_aug.flow_from_directory(
    'myImages/train',
    target_size=(224, 224),
    batch_size=50,
    class_mode='categorical')

validation_generator_aug = test_datagen_aug.flow_from_directory(
        'myImages/valid',
        target_size=(224, 224),
        batch_size=32,
        class_mode='categorical')

checkpointer_aug = ModelCheckpoint(filepath='saved_models/dogs_transfer_aug_model.h5', 
                            save_best_only=True)

history = model.fit_generator(
      train_generator_aug,
      steps_per_epoch=130,
      epochs=20,
      validation_data=validation_generator_aug,
      verbose=1,
      callbacks=[checkpointer_aug],
      validation_steps=26)

输出如下所示:

Epoch 1/20
130/130 [==============================] - 293s - loss: 15.9044 - acc: 0.0083 - val_loss: 16.0019 - val_acc: 0.0072
Epoch 2/20
130/130 [==============================] - 281s - loss: 15.9972 - acc: 0.0075 - val_loss: 15.9977 - val_acc: 0.0075
Epoch 3/20
130/130 [==============================] - 280s - loss: 16.0220 - acc: 0.0060 - val_loss: 15.9977 - val_acc: 0.0075
Epoch 4/20
130/130 [==============================] - 280s - loss: 15.9941 - acc: 0.0077 - val_loss: 16.0019 - val_acc: 0.0072

【问题讨论】:

  • 您能否澄清一下“特征提取”是指什么?另外,你能确认一下,如果你用train_datagen_aug = ImageDataGenerator(rescale=1./255)匹配test_datagen_aug,你有同样的问题吗
  • 请耐心等待,因为我对 DL 比较陌生,但我正在扩展模型(conv_base),方法是在顶部添加 Dense 层,并在输入数据上端到端运行整个事情。这将允许您使用数据增强,因为每个输入图像每次被模型看到时都会通过卷积基础。
  • 我还是有点困惑。 “特征提取”是指使用 VGG 网络作为基础吗?还是您在顶部添加的额外层?还是别的什么?
  • 好的,这很清楚。我要测试的第一件事是,如果您删除增强,是否会出现同样的问题,即按照我之前的评论设置 train_datagen_aug = ImageDataGenerator(rescale=1./255)。由于您使用的是预训练模型,因此您的预处理步骤与用于训练该模型的步骤相匹配非常重要。可能是您的数据缩放不正确,或者您的颜色通道的顺序错误。一旦你让它在没有增强的情况下工作,只有这样我才会重新添加增强。
  • 尝试对rmsprop 使用较低的学习率。您可以通过将优化器更改为此:optimizer=optimizers.RMSprop(lr=X)。用1e-52e-5 代替X 看看会发生什么。请勿伪造添加此行:from keras import optimizers.

标签: neural-network keras conv-neural-network feature-extraction


【解决方案1】:

我建议这是模型过度拟合问题,如模型的损失和准确性所示。我们可以尝试使用 VGG16 的较小版本(减少层数)

from keras.models import Sequential
from keras.layers.core import Flatten, Dense, Dropout
from keras.layers.convolutional import MaxPooling2D, ZeroPadding2D

NUMBER_OF_TRAINING_SAMPLES = 6668 
NUMBER_OF_VALIDATION_SAMPLES = 835 # let's say you have 400 dogs and 400 cats
batch_size = 32
out_classes = 133
input_shape=(224, 224, 3)

def buildSmallVGG(out_classes, input_shape):
    model = Sequential()
    model.add(ZeroPadding2D((1,1),input_shape=input_shape))
    model.add(Conv2D(16, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(32, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))


    model.add(ZeroPadding2D((1,1)))
    model.add(Conv2D(64, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(Flatten())
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))

    model.add(Dense(out_classes, activation='softmax'))
    return model

model = buildSmallVGG(out_classes, input_shape)

history = model.fit_generator(
      train_generator_aug,
      steps_per_epoch=NUMBER_OF_TRAINING_SAMPLES // batch_size,
      epochs=20,
      validation_data=validation_generator_aug,
      callbacks=[checkpointer_aug],
      validation_steps=NUMBER_OF_VALIDATION_SAMPLES // batch_size)

以上内容未经测试。如果你能分享你在损失、准确性等方面得到的结果,那就太好了。

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 2020-02-12
    相关资源
    最近更新 更多