使用vgg16进行验证时准确性低 [英] Accuracy low on validation set using vgg16

查看:715
本文介绍了使用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.

我使用keras进行数据增强:

I do a data augmentation with 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一起使用来训练我的模型:

Then I'm using transfer learning with VGG16 to train my 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'])

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

When I trained the model it seems like it's overfitting : I got 0.99 accuracy on train and 0.23 on validation.

当查看火车和验证集中的图像时,没有明显的原因使验证的准确性如此差.

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.

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

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.

因此,我认为验证准确性存在问题,但不知道如何解决.

So I'm thinking there is a problem on the validation accuracy but have no idea how to fix it.

感谢您的帮助!

推荐答案

很少有可以提高训练和验证数据集分类准确度的事情:

There are few things that may improve the classification accuracy on training as well as validation dataset:

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

  1. Firstly, set layer.trainable=True, because the Imagenet dataset is trained on different dataset. Just fine-tuning the top layers will directly lead to overfitting. Load imagenet weights but re-train all or couple of layers.

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

Use EfficientNet with noisy_student weights. 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. I guess np array will load faster. Split the training data using sklearn train_test_split function. Normalize the dataset (1/255). Calculate np.mean along axis 0 on train data and subtract it from both train and val dataset.

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

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.

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

Checkout imgaug library (embossing, sharpening, noise addition, etc.). Plus, there are random_eraser, cut out and mix up strategies that have been proved to be useful. Add this to preprocessing function rather putting preprocess_input. It will also help to regularize your model.

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

Try label smoothing. It can also help your classifier to give more probability to the correct class.

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

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. 您还可以提取特征并应用整体特征分类(XGBoost,Adaboost,BaggingClassifier)或三元组损失.

  1. You can also extract features and apply ensemble feature classification(XGBoost, Adaboost, BaggingClassifier) or triplet loss.

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

Try increasing your image resolution to 299. Better the resolution better the fine grained classification.

这篇关于使用vgg16进行验证时准确性低的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆