在 Keras 图像分类中不会减少的损失验证

Posted

技术标签:

【中文标题】在 Keras 图像分类中不会减少的损失验证【英文标题】:Loss validation that don't decrease in Keras images classification 【发布时间】:2019-06-13 00:20:31 【问题描述】:

我正在尝试使用一堆用于分类的图像来微调我的 VGG19 模型。 有 18 个班级,每个班级有 6000 张图片。 使用 Keras 2.2.4

型号:

INIT_LR = 0.00001
BATCH_SIZE = 128
IMG_SIZE = (256, 256)
epochs = 150

model_base = keras.applications.vgg19.VGG19(include_top=False, input_shape=(*IMG_SIZE, 3), weights='imagenet')
 output = Flatten()(model_base.output)

output = BatchNormalization()(output)
output = Dropout(0.5)(output)
output = Dense(64, activation='relu')(output)
output = BatchNormalization()(output)
output = Dropout(0.5)(output)
output = Dense(len(all_character_names), activation='softmax')(output)
model = Model(model_base.input, output)
for layer in model_base.layers[:-10]:
    layer.trainable = False


opt = optimizers.Adam(lr=INIT_LR, decay=INIT_LR / epochs)
model.compile(optimizer=opt,
              loss='categorical_crossentropy',
               metrics=['accuracy', 'top_k_categorical_accuracy'])

数据增强:

image_datagen = ImageDataGenerator(
    rotation_range=15,
    width_shift_range=.15,
    height_shift_range=.15,
    #rescale=1./255,
    shear_range=0.15,
    zoom_range=0.15,
    channel_shift_range=1,
    vertical_flip=True,
    horizontal_flip=True)

模型火车:

validation_steps = data_generator.validation_samples/BATCH_SIZE
steps_per_epoch = data_generator.train_samples/BATCH_SIZE 

model.fit_generator(
        generator,
        steps_per_epoch=steps_per_epoch,
        epochs=epochs,
        validation_data=validation_data,
        validation_steps=validation_steps
    ) 

模型总结:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 256, 256, 3)       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 256, 256, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 256, 256, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 128, 128, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 128, 128, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 128, 128, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 64, 64, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 64, 64, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 64, 64, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 64, 64, 256)       590080    
_________________________________________________________________
block3_conv4 (Conv2D)        (None, 64, 64, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 32, 32, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 32, 32, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block4_conv4 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 16, 16, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_conv4 (Conv2D)        (None, 16, 16, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 8, 8, 512)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 32768)             0         
_________________________________________________________________
batch_normalization_1 (Batch (None, 32768)             131072    
_________________________________________________________________
dropout_1 (Dropout)          (None, 32768)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 64)                2097216   
_________________________________________________________________
batch_normalization_2 (Batch (None, 64)                256       
_________________________________________________________________
dropout_2 (Dropout)          (None, 64)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 19)                1235      
=================================================================
Total params: 22,254,163
Trainable params: 19,862,931
Non-trainable params: 2,391,232
_________________________________________________________________
<keras.engine.input_layer.InputLayer object at 0x00000224568D0D68> False
<keras.layers.convolutional.Conv2D object at 0x00000224568D0F60> False
<keras.layers.convolutional.Conv2D object at 0x00000224568F0438> False
<keras.layers.pooling.MaxPooling2D object at 0x00000224570A5860> False
<keras.layers.convolutional.Conv2D object at 0x00000224570A58D0> False
<keras.layers.convolutional.Conv2D object at 0x00000224574196D8> False
<keras.layers.pooling.MaxPooling2D object at 0x0000022457524048> False
<keras.layers.convolutional.Conv2D object at 0x0000022457524D30> False
<keras.layers.convolutional.Conv2D object at 0x0000022457053160> False
<keras.layers.convolutional.Conv2D object at 0x00000224572E15C0> False
<keras.layers.convolutional.Conv2D object at 0x000002245707B080> False
<keras.layers.pooling.MaxPooling2D object at 0x0000022457088400> False
<keras.layers.convolutional.Conv2D object at 0x0000022457088E10> True
<keras.layers.convolutional.Conv2D object at 0x00000224575DB240> True
<keras.layers.convolutional.Conv2D object at 0x000002245747A320> True
<keras.layers.convolutional.Conv2D object at 0x0000022457486160> True
<keras.layers.pooling.MaxPooling2D object at 0x00000224574924E0> True
<keras.layers.convolutional.Conv2D object at 0x0000022457492D68> True
<keras.layers.convolutional.Conv2D object at 0x00000224574AD320> True
<keras.layers.convolutional.Conv2D object at 0x00000224574C6400> True
<keras.layers.convolutional.Conv2D object at 0x00000224574D2240> True
<keras.layers.pooling.MaxPooling2D object at 0x00000224574DAF98> True
<keras.layers.core.Flatten object at 0x00000224574EA080> True
<keras.layers.normalization.BatchNormalization object at 0x00000224574F82B0> True
<keras.layers.core.Dropout object at 0x000002247134BA58> True
<keras.layers.core.Dense object at 0x000002247136A7B8> True
<keras.layers.normalization.BatchNormalization object at 0x0000022471324438> True
<keras.layers.core.Dropout object at 0x00000224713249B0> True
<keras.layers.core.Dense object at 0x00000224713BF7F0> True
batchsize:128
LR:1e-05

注定的图:

尝试:

试了几个LR 在没有训练的情况下尝试了最后 10、5 层,这是最差的,根本没有收敛 尝试了几个批量大小,128 给出了最好的结果 也尝试了 resnet50,但完全没有收敛(即使最后 3 层可训练) 尝试了 VGG16,但运气不佳。

我每天添加大约 2000 张新图片以尝试达到每个班级大约 20000 张图片,因为我认为这是我的问题。

【问题讨论】:

你的训练数据怎么样?您是否尝试过更改增强管道?你也用过vertical flips。这些类是什么? 这是过拟合。 (训练越来越好,验证停止)。学习率、批量大小等没有问题。解决这个问题在很大程度上取决于数据的类型。更多图像、更多增强、更好的模型是通常的解决方案。 @AnkishBansal 我尝试了很多不同的数据增强选项,从简单的缩放到您可以在此处看到的所有参数。课程是关于人的大小、头发颜色、肤色、过胖或过胖、男性、女性等 @DanielMöller,是的,这是过度拟合,这就是我不断添加新图像的原因。我只是不确定要使用哪种模型,目前 vgg16 和 vgg19 只能“工作”,我不明白为什么densenet、xception 会给出非常糟糕的结果。我可能也错过了一些东西。 @kollo 这些模型经过训练可以检测汽车、人、动物等类别。但是您正在处理一个特定类别的子类别,即人。这一点你也需要考虑。 【参考方案1】:

在较低层,网络学习了边缘、轮廓等低级特征。在较高层,这些特征结合在一起。因此,在您的情况下,您需要更精细的特征,例如头发颜色、人的大小等。您可以尝试从最后几层(从第 4-5 块)进行微调。您也可以使用不同的学习率,VGG 块的学习率非常低,而全新的dense 层则稍高一些。对于实施,this-thread 会有所帮助。

【讨论】:

以上是关于在 Keras 图像分类中不会减少的损失验证的主要内容,如果未能解决你的问题,请参考以下文章

Keras 损失函数不会因均方误差而减少

图像分类。验证损失在初始训练期间卡住(v1)

Keras图像分类验证准确率更高

Keras CIFAR-10图像分类 GoogleNet 篇

Keras CIFAR-10图像分类 GoogleNet 篇

Keras CIFAR-10图像分类 AlexNet篇