使用vgg16进行验证时准确性低

时间:2020-06-11 17:56:06

标签: python tensorflow machine-learning keras vgg-net

我正在为一个项目进行犬种分类,但是遇到一个主要问题,我不知道如何解决。

数据集是Stanford Dogs dataset提供的狗的图像。

我使用keras进行数据增强:

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from keras import optimizers
from keras.callbacks import History 
from keras.applications import vgg16

batch_size = 16

# this is the augmentation configuration I will use for training
 train_datagen = ImageDataGenerator(rotation_range=20,
                               zoom_range=0.2,
                               horizontal_flip=True,
                               fill_mode='nearest',
                               preprocessing_function=vgg16.preprocess_input)

 # This is the augmentation configuration I will use for testing/validation... just a rescale
 test_datagen = ImageDataGenerator(rescale=1./255)

 # This is the generator which will read pictures found in my training subset
 train_generator = train_datagen.flow_from_directory('../data/train/',
                                                target_size = (224, 224),
                                                batch_size = batch_size,
                                                shuffle=True,
                                                class_mode = 'categorical',
                                                seed=42)

  # This is the generator for validation data
  validation_generator = test_datagen.flow_from_directory('../data/validation/',
                                                    target_size = (224, 224),
                                                    batch_size = batch_size,
                                                    class_mode = 'categorical')

然后我将转移学习与VGG16一起使用来训练我的模型:

from keras.applications.vgg16 import VGG16
from keras.layers import Input, Dense, Flatten, GlobalAveragePooling2D
from keras.models import Model, Sequential

pretrained_model = VGG16(weights="imagenet", include_top=False, input_shape=(224, 224, 3))

for layer in pretrained_model.layers:
    layer.trainable = False

x = pretrained_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation="relu")(x)
predictions = Dense(120, activation='softmax')(x)

model = Model(inputs = pretrained_model.input, outputs=predictions) 

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

当我训练模型时,似乎过拟合了: 我在火车上的准确性为0.99,而在验证中为0.23。

当查看火车和验证集中的图像时,没有明显的原因使验证的准确性下降。

我所做的是手动检查模型在验证和测试中对几幅图像(超过50张)预测的品种,并且80%以上是正确的预测。

所以我认为验证准确性存在问题,但不知道如何解决。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

几乎没有什么可以提高训练和验证数据集分类的准确性:

  1. 首先,设置layer.trainable = True,因为Imagenet数据集是在不同的数据集上训练的。仅对顶层进行微调将直接导致过度拟合。加载imagenet权重,但重新训练所有或几层。

  2. 使用带有Nosy_student权重的EfficientNet。需要训练的参数数量较少。由于它具有可扩展的体系结构,因此可以提供更好的准确性。将整个数据集转换为numpy数组。我猜np数组将加载得更快。使用sklearn train_test_split函数拆分训练数据。标准化数据集(1/255)。在火车数据上沿轴0计算np.mean,并从火车和val数据集中减去np.mean。

  3. 您可以使用测试时间增加。在测试数据生成器中,执行简单的水平翻转,垂直翻转(如果数据看起来逼真)和仿射变换。它将生成数据的多个视图,并帮助模型对更可能的类进行平均。

  4. 检出图像库(压纹,锐化,添加噪点等)。另外,还提供了random_eraser,剪切和混合策略,这些方法已被证明是有用的。将此添加到预处理功能中,而不是放置preprocess_input。这也将有助于规范化模型。

  5. 尝试平滑标签。它还可以帮助您的分类器将更多概率分配给正确的分类。

  6. 尝试学习率预热。像这样的东西:

LR_START = 0.0001
LR_MAX = 0.00005
LR_MIN = 0.0001
LR_RAMPUP_EPOCHS = 4
LR_SUSTAIN_EPOCHS = 6
LR_EXP_DECAY = .8


def lrfn(epoch):
    if epoch < LR_RAMPUP_EPOCHS:
        lr = (LR_MAX - LR_START) / LR_RAMPUP_EPOCHS * epoch + LR_START
    elif epoch < LR_RAMPUP_EPOCHS + LR_SUSTAIN_EPOCHS:
        lr = LR_MAX
    else:
        lr = (LR_MAX - LR_MIN) * LR_EXP_DECAY**(epoch - LR_RAMPUP_EPOCHS - LR_SUSTAIN_EPOCHS) + LR_MIN
    return lr

  1. 您还可以提取特征并应用整体特征分类(XGBoost,Adaboost,BaggingClassifier)或三元组损失。

  2. 尝试将图像分辨率提高到299。分辨率越高,细分类效果越好。