Keras:训练损失减少(准确度增加),同时验证损失增加(准确度降低)

时间:2017-11-13 19:49:49

标签: python deep-learning keras classification

我正在研究一个非常稀疏的数据集,其中包含预测6个类的要点。 我尝试过使用很多模型和架构,但问题仍然存在。

当我开始训练时,训练的acc将慢慢开始增加并且损失将减少,因为验证将完全相反。

我已经真的尝试来处理过度拟合,而我根本无法相信这就是这个问题的原因。

我尝试了什么

在VGG16上转学:

  • 排除顶层并添加256个单位和6个单位softmax输出层的密集层
  • 微调顶级CNN区块
  • 微调前3-4个CNN区块

为了解决过度拟合问题,我在Keras中使用了大量增强,在p = 0.5的256密集层之后使用了丢失。

使用VGG16-ish架构创建自己的CNN:

  • 尽可能包括批量标准化
  • 每个CNN +密集层上的L2正则化
  • 在每个CNN +密集+汇集层之后从0.5-0.8之间的任何地方辍学
  • 在飞行中大量数据增加"在Keras

意识到我可能有太多的免费参数:

  • 将网络减少到仅包含2个CNN块+密集+输出。
  • 以与上述相同的方式处理过度拟合。

毫无例外所有培训课程如下所示: Training & Validation loss+accuracy

最后提到的架构如下所示:

    reg = 0.0001

    model = Sequential()

    model.add(Conv2D(8, (3, 3), input_shape=input_shape, padding='same',
            kernel_regularizer=regularizers.l2(reg)))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Dropout(0.7))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.5))

    model.add(Conv2D(16, (3, 3), input_shape=input_shape, padding='same',
            kernel_regularizer=regularizers.l2(reg)))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Dropout(0.7))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.5))

    model.add(Flatten())
    model.add(Dense(16, kernel_regularizer=regularizers.l2(reg)))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Dropout(0.5))

    model.add(Dense(6))
    model.add(Activation('softmax'))

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

数据由Keras中的生成器增强,并加载了flow_from_directory:

    train_datagen = ImageDataGenerator(rotation_range=10,
                                width_shift_range=0.05,
                                height_shift_range=0.05,
                                shear_range=0.05,
                                zoom_range=0.05,
                                rescale=1/255.,
                                fill_mode='nearest',
                                channel_shift_range=0.2*255)
    train_generator = train_datagen.flow_from_directory(
                train_data_dir,
                target_size=(img_width, img_height),
                batch_size=batch_size,
                shuffle = True,
                class_mode='categorical')

    validation_datagen = ImageDataGenerator(rescale=1/255.)
    validation_generator = validation_datagen.flow_from_directory(
                                            validation_data_dir,
                                            target_size=(img_width, img_height),
                                            batch_size=1,
                                            shuffle = True,
                                            class_mode='categorical')

4 个答案:

答案 0 :(得分:3)

通过分析您的指标输出(来自您提供的link)我能想到的是:

enter image description here

对我来说,大约在纪元30附近你的模特开始过度装修。因此,您可以尝试在该迭代中停止训练,或者只训练约30个时期(或确切的数字)。 Keras Callbacks在这里可能很有用,特别是ModelCheckpoint可以让您在需要时(Ctrl + C)或满足某些条件时停止训练。以下是基本ModelCheckpoint使用的示例:

#save best True saves only if the metric improves
chk = ModelCheckpoint("myModel.h5", monitor='val_loss', save_best_only=False) 
callbacks_list = [chk]
#pass callback on fit
history = model.fit(X, Y, ... , callbacks=callbacks_list)

(编辑:)根据评论中的建议,您可以使用的另一个选项是使用EarlyStopping回调,您可以在其中指定容忍的最小变化和“耐心”或时代在停止训练之前没有这样的改进。如果使用此方法,则必须将其传递给callbacks参数,如前所述。

在目前的设置中,您的模型已经(并且已经尝试过修改),您的训练中的这一点似乎是您案例的最佳训练时间; 进一步培训将不会给您的模型带来任何好处(事实上,这将使其更加普遍化)。

鉴于您已经尝试了多项修改,您可以做的一件事是尝试增加网络深度,以便为其提供更多容量。尝试一次添加一个层,并检查是否有改进。此外,在尝试使用多层解决方案之前,您通常首先想要从更简单的模型开始

如果简单模型不起作用,请添加一个图层并再次测试,重复直到满意或可能。简单来说,我的意思是非常简单,你尝试过非卷积方法吗?虽然CNN非常适合拍照,但也许你在这里过分苛刻。

如果似乎没有任何效果,也许是时候获取更多数据,或者通过采样或其他技术从您拥有的数据中生成更多数据。对于最后一个建议,请尝试检查我发现真正有用的this keras博客。深度学习算法通常需要大量的训练数据,特别是对于像图像这样的复杂模型,所以要注意这可能不是一件容易的事。希望这会有所帮助。

答案 1 :(得分:2)

恕我直言,这只是DL的正常情况。在Keras中,您可以设置一个回调来保存最佳模型(取决于您提供的评估指标),以及如果模型没有改进则会停止训练的回调。

ModelCheckpoint& EarlyStopping分别回调。

P.S。对不起,也许我误解了问题 - 你是否在第一步中减少了验证损失?

答案 2 :(得分:0)

验证损失正在增加。这意味着您需要更多数据或更多正则化。这里的标准情况,没有什么可担心的。顺便说一句,除非您解决此问题,否则更多参数(更大的模型)只会使此问题恶化。

因此,您现在可以通过引入更多示例(L2,L1或辍学)来进行有益的调查。

答案 3 :(得分:0)

我遇到了类似的问题,并设法通过删除输出密集层之前的批量标准化层来解决它。这产生了很大的不同。我得到的建议之一是删除 Dropout 层,因为它可能会导致 Shift Variance。检查这个paper

我从这个 thread 中得到了部分解决方案。