首页 文章

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

提问于
浏览
5

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

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

我有 really tried 处理过度拟合,我根本不能相信这就是这个问题 .

我尝试了什么

在VGG16上转学:

  • 排除顶层并添加256个单位和6个单位softmax输出层的密集层

  • 微调顶级CNN区块

  • 微调前3-4个CNN区块

为了处理过度拟合,我在Keras中使用了大量增强,在p = 0.5的256密集层之后使用了丢失 .

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

  • 包括尽可能的批量标准化

  • 每个CNN密集层上的L2正则化

  • 在每个CNN密集池之后从0.5-0.8之间的任何地方辍学

  • 在Keras的"on the fly"中进行了大量数据扩充

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

  • 减少网络只包含2个CNN块密集输出 .

  • 以与上述相同的方式处理过度拟合 .

无一例外 all 培训课程如下: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')

2 回答

  • 1

    通过分析您的指标输出(来自您提供的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回调,您可以在停止训练之前指定容许的最小变化和'patience'或没有这些改进的纪元 . 如果使用此方法,则必须将其传递给 callbacks 参数,如前所述 .

    在当前的设置中,您的模型已经(以及您已经尝试过的修改),您的训练中的这一点似乎是您案例的最佳训练时间; training it further will bring no benefits to your model (事实上,这会使它更加普遍化) .

    鉴于您已尝试过多次修改,您可以做的一件事是 try to increase your Network Depth ,以便为其提供更多容量 . 尝试一次添加一个层,并检查是否有改进 . 此外,在尝试使用多层解决方案之前,通常首先需要 start with simpler models .

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

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

  • 3

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

    分别参见ModelCheckpointEarlyStopping回调 .

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

相关问题