简体   繁体   English

使用 vgg16 验证集的准确性低

[英]Accuracy low on validation set using vgg16

I'm doing dog breed classification for a project and I encounter a major issue I have no idea how to solve it.我正在为一个项目进行犬种分类,但遇到了一个我不知道如何解决的主要问题。

The dataset is the images of dogs provided by Stanford Dogs dataset .该数据集是由Stanford Dogs dataset提供的狗的图像。

I do a data augmentation with keras:我使用 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')

Then I'm using transfer learning with VGG16 to train my model:然后我使用带有 VGG16 的迁移学习来训练我的 model:

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

When I trained the model it seems like it's overfitting: I got 0.99 accuracy on train and 0.23 on validation.当我训练 model 时,它似乎过拟合了:我在训练中获得了 0.99 的准确度,在验证时获得了 0.23 的准确度。

When looking to the images in the train and validation set there are no apparent reasons it gives me such a bad accuracy for the validation.当查看火车和验证集中的图像时,没有明显的原因它给我的验证准确度如此差。

What I've done is checked manually what breed the model predicts for several images (more than 50) in the vaidation and test and more than 80% are corrects predictions.我所做的是手动检查 model 在验证和测试中预测的几张图像(超过 50 张)的品种,超过 80% 是正确的预测。

So I'm thinking there is a problem on the validation accuracy but have no idea how to fix it.所以我认为验证准确性存在问题,但不知道如何解决。

Thanks for your help !谢谢你的帮助 !

There are few things that may improve the classification accuracy on training as well as validation dataset:很少有事情可以提高训练和验证数据集的分类准确性:

  1. Firstly, set layer.trainable=True, because the Imagenet dataset is trained on different dataset.首先,设置 layer.trainable=True,因为 Imagenet 数据集是在不同的数据集上训练的。 Just fine-tuning the top layers will directly lead to overfitting.只是微调顶层将直接导致过度拟合。 Load imagenet weights but re-train all or couple of layers.加载 imagenet 权重,但重新训练所有或几层。

  2. Use EfficientNet with noisy_student weights.使用具有噪声学生权重的 EfficientNet。 There are less number of parameters to train.要训练的参数数量较少。 It gives better accuracy due to the scalable architecture it has.由于它具有可扩展的架构,它提供了更好的准确性。 Convert the whole dataset to numpy array.将整个数据集转换为 numpy 数组。 I guess np array will load faster.我猜 np 数组会加载得更快。 Split the training data using sklearn train_test_split function.使用 sklearn train_test_split function 拆分训练数据。 Normalize the dataset (1/255).标准化数据集 (1/255)。 Calculate np.mean along axis 0 on train data and subtract it from both train and val dataset.在火车数据上沿轴 0 计算 np.mean 并将其从火车和 val 数据集中减去。

  3. You can use test time augmentation.您可以使用测试时间增加。 In your test data generator, do a simple horizontal flip, vertical flip (if data looks realistic) and affine transformations.在您的测试数据生成器中,进行简单的水平翻转、垂直翻转(如果数据看起来很真实)和仿射变换。 It will generate multiple views of the data and helps the model to average out more probable class.它将生成数据的多个视图,并帮助 model 平均出更可能的 class。

  4. Checkout imgaug library (embossing, sharpening, noise addition, etc.).检查 imgaug 库(压纹、锐化、噪声添加等)。 Plus, there are random_eraser, cut out and mix up strategies that have been proved to be useful.此外,还有一些已被证明有用的 random_eraser、剪切和混合策略。 Add this to preprocessing function rather putting preprocess_input.将此添加到预处理 function而不是放入 preprocess_input。 It will also help to regularize your model.它还有助于规范您的 model。

  5. Try label smoothing.尝试 label 平滑。 It can also help your classifier to give more probability to the correct class.它还可以帮助您的分类器为正确的 class 提供更多概率。

  6. Try learning rate warmup.尝试学习率预热。 Something like this:像这样的东西:

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. You can also extract features and apply ensemble feature classification(XGBoost, Adaboost, BaggingClassifier) or triplet loss.您还可以提取特征并应用集成特征分类(XGBoost、Adaboost、BaggingClassifier)或三元组损失。

  2. Try increasing your image resolution to 299. Better the resolution better the fine grained classification.尝试将图像分辨率提高到 299。分辨率越高,细粒度分类越好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM