【问题标题】:Overfitting problem with my validation data我的验证数据过拟合问题
【发布时间】:2026-01-06 09:55:02
【问题描述】:

我正在使用 keras 应用 CNN 模型。我将离散小波变换级别 5 的细节系数作为大小 (5,3840) 的二维数组输入 CNN。我想使用 CNN 预测癫痫发作。问题是我的网络过度拟合。关于如何解决过拟合问题的任何建议。

    input_shape=(1, 22, 5, 3844)
    model = Sequential()
    #C1
    model.add(Conv3D(16, (22, 5, 5), strides=(1, 2, 2), padding='same',activation='relu',data_format= "channels_first", input_shape=input_shape))
    model.add(keras.layers.MaxPooling3D(pool_size=(1, 2, 2),data_format= "channels_first",  padding='same'))
    model.add(BatchNormalization())
    #C2
    model.add(Conv3D(32, (1, 3, 3), strides=(1, 1,1), padding='same',data_format= "channels_first",  activation='relu'))#incertezza se togliere padding
    model.add(keras.layers.MaxPooling3D(pool_size=(1,2, 2),data_format= "channels_first", ))
    model.add(BatchNormalization())

     #C3
    model.add(Conv3D(64, (1,3, 3), strides=(1, 1,1), padding='same',data_format= "channels_first",  activation='relu'))#incertezza se togliere padding
    model.add(keras.layers.MaxPooling3D(pool_size=(1,2, 2),data_format= "channels_first",padding='same' ))
    model.add(BatchNormalization())

    model.add(Flatten())
    model.add(Dropout(0.5))
    model.add(Dense(256, activation='sigmoid'))
    model.add(Dropout(0.5))
    model.add(Dense(2, activation='softmax'))

    opt_adam = keras.optimizers.Adam(lr=0.00001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
    model.compile(loss='categorical_crossentropy', optimizer=opt_adam, metrics=['accuracy'])

    return model

【问题讨论】:

    标签: python tensorflow keras deep-learning conv-neural-network


    【解决方案1】:

    有两种常用的正则化技术可以避免过拟合:

    1. L1 & L2 正则化:正则化器允许在优化期间对层参数或层活动施加惩罚。这些惩罚包含在网络优化的损失函数中。

      from keras import regularizers
      model.add(Dense(64, input_dim=64,
                kernel_regularizer=regularizers.l2(0.01),
                activity_regularizer=regularizers.l1(0.01)))
      
    2. Dropout :Dropout 包括在训练期间的每次更新时将输入单元的分数率随机设置为 0,这有助于防止 过拟合。

      from keras.layers import Dropout
      model.add(Dense(60, input_dim=60, activation='relu'))
      model.add(Dropout(rate=0.2))
      model.add(Dense(30, activation='relu'))
      model.add(Dropout(rate=0.2))
      model.add(Dense(1, activation='sigmoid'))
      

    当验证损失不再减少时,您还可以使用 Early-Stopping 中断训练

    from keras.callbacks import EarlyStopping
    early_stopping = EarlyStopping(monitor='val_loss', patience=2)
    model.fit(x, y, validation_split=0.2, callbacks=[early_stopping])
    

    此外,您可能需要考虑 数据增强 技术,例如裁剪、填充和水平翻转。使用这些技术,您可以增加可用于训练模型的数据的多样性,而无需实际收集新数据。所以你可以捕捉数据不变性并减少过拟合

    (x_train, y_train), (x_test, y_test) = cifar10.load_data()
    y_train = np_utils.to_categorical(y_train, num_classes)
    y_test = np_utils.to_categorical(y_test, num_classes)
    
    datagen = ImageDataGenerator(
        featurewise_center=True,
        featurewise_std_normalization=True,
        rotation_range=20,
        width_shift_range=0.2,
        height_shift_range=0.2,
        horizontal_flip=True)
    
    model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
                        steps_per_epoch=len(x_train) / 32, epochs=epochs)
    

    【讨论】:

    • 非常感谢您提供的解决方案,它确实帮助了我。
    • @Abduallah Deliogullari 我想知道你是否可以帮助我减轻体重。
    • @gigi 你能创建一个新问题吗?所以我可以对这个问题添加广泛的解释
    • 完成,我创建一个新问题。
    【解决方案2】:

    去除过拟合的步骤:

    • 减少隐藏层中的神经单元数量

    我认为在 sigmoid 层之后不需要 softmax 层。因此,您的模型可能会过度拟合。

    尝试将 sigmoid 层替换为具有 relu 激活和输出 (n, 2) 的密集层,然后是 softmax 层。

    您的学习率也非常低,这表明您的模型需要很长时间才能找到全局最小值,因此欠拟合,但这里不会发生这种情况。这巩固了我对 sigmoid 层是原因的怀疑。

    【讨论】: