【问题标题】:How to prevent one fold to perform a lot worse than the other 9 in 10-fold cross validation for CNN classification在 CNN 分类的 10 倍交叉验证中,如何防止一个倍的性能比其他 9 倍差很多
【发布时间】:2020-01-12 07:06:31
【问题描述】:

我目前正在 Keras 中研究用于 MRI 分类的 2D CNN。班级比例约为 60/40,我有 155 名患者,每个患者都有一个 MRI,由大约 180 个切片组成,CNN 的输入是 MRI 图像的切片(256*256 px)(因此总共输入约为 27900图片,每个 256*256 像素)。

我测试了不同的模型,并总是使用混洗分层 10 折交叉验证和 EarlyStopping 监视器对它们进行评估,它们都表现得非常好,验证准确率约为 95% 到 98%。但每一次,一两折的表现都比其他的差很多(70% 到 80% 的验证准确率)。由于褶皱是随机的,我希望这些褶皱的表现都一样好。

有人能解释一下这种情况是如何发生的以及如何预防吗?

准确度和损失图:

Train accuracy and validation accuracy

Train loss and validation loss

这是其中一种模型的一部分:

num_classes = 2
img_size = 256
batch_size = 200

# Because of EarlyStopping monitor, the number of epochs doesn't really matter
num_epochs = 1000

kfold_splits = 10
skf = StratifiedKFold(n_splits=kfold_splits, shuffle=True)

# Here the data is split 
for index, (train_index, test_index) in enumerate(skf.split(x_data_paths, y_data_paths)):

    x_train, x_test = np.array(x_data_paths)[train_index.astype(int)], np.array(x_data_paths)[test_index.astype(int)]
    y_train, y_test = np.array(y_data_paths)[train_index.astype(int)], np.array(y_data_paths)[test_index.astype(int)]

    training_batch_generator = BcMRISequence(x_train, y_train_one_hot, batch_size)
    test_batch_generator = BcMRISequence(x_test, y_test_one_hot, batch_size)

    # region Create model (using the functional API)
    inputs = Input(shape=(img_size, img_size, 1))
    conv1 = Conv2D(64, kernel_size=5, strides=1, activation='relu')(inputs)
    pool1 = MaxPooling2D(pool_size=3, strides=(2, 2), padding='valid')(conv1)
    conv2 = Conv2D(32, kernel_size=3, activation='relu')(pool1)
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
    conv3 = Conv2D(16, kernel_size=3, activation='relu')(pool2)
    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)
    flat = Flatten()(pool3)
    hidden1 = Dense(10, activation='relu')(flat)
    output = Dense(num_classes, activation='softmax')(hidden1)
    model = Model(inputs=inputs, outputs=output)

【问题讨论】:

  • 你有很多图像,所以没有任何理由使用 k-fold,只需使用像 Resnet50 这样的大模型,不要使用交叉验证。
  • 确实如此,但我仍然想知道这是怎么发生的,因为这可能表明存在潜在问题,你不觉得吗?
  • 很多人怀疑模型在某些数据中会变坏,但看看你的代码,你的模型很可能太小了,没有Batch Normalization 也没有Dropout,真的容易过拟合。
  • 我能想到的另一个嫌疑人是batch_size 太大,根据我的经验,这有时也会导致过度拟合。
  • 但是训练损失和验证损失图表明它并没有过度拟合,因为它们都在下降,不是吗?

标签: python keras conv-neural-network cross-validation k-fold


【解决方案1】:

以防万一其他人偶然发现我的问题:通过使用分层随机拆分和 10 次迭代而不是 10 折交叉验证,我摆脱了异常值折叠。我的猜测是由于某种“批量效应”而出现了这种糟糕的折叠(10 折叠交叉验证不会改变 MRI 切片,只有患者)。另一方面,shuffle split 在拆分为训练和测试之前确实对整个数据集进行了洗牌,因此避免了“坏”患者一起出现在一个折叠中。

这些是新的情节,以防有人感兴趣。与之前的模型相同,只是随机拆分而不是 k 折交叉验证。

Train accuracy and validation accuracy

Train loss and validation loss

【讨论】:

    猜你喜欢
    • 2020-04-09
    • 2015-01-11
    • 1970-01-01
    • 2012-12-11
    • 2018-09-12
    • 1970-01-01
    • 2014-11-06
    • 2018-05-19
    • 2021-11-05
    相关资源
    最近更新 更多