提高 3D CNN 的验证损失和准确性

人工智能 神经网络 卷积神经网络 喀拉斯 3d-卷积
2021-10-26 05:53:18

我使用了 3D CNN 架构,通过使用 FLAIR 脑部扫描来检测特定启动子 (MGMT) 的存在。(每位患者 64 片)。输出应该是二进制(0/1)。

我已经正确地进行了预处理,并在将“训练”数据集分成训练集和验证集后使用了分层(80-20 比率)。我的模型初始化和训练内核如下所示:

def get_model(width=128, height=128, depth=64):
"""Build a 3D convolutional neural network model."""

inputs = keras.Input((width, height, depth, 1))

x = layers.Conv3D(filters=64, kernel_size=3, activation="relu")(inputs)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)

x = layers.Conv3D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)

x = layers.Conv3D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)

x = layers.Conv3D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)

x = layers.GlobalAveragePooling3D()(x)
x = layers.Dense(units=512, activation="relu")(x)
x = layers.Dropout(0.3)(x)

outputs = layers.Dense(units=1, activation="sigmoid")(x)

# Define the model.
model = keras.Model(inputs, outputs, name="3dcnn")
return model


# Build model.
model = get_model(width=128, height=128, depth=64)
model.summary()

编译模型:

initial_learning_rate = 0.0001
lr_schedule = keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True
)
model.compile(
    loss="binary_crossentropy",
    optimizer=keras.optimizers.Adam(learning_rate=lr_schedule),
    metrics=["acc"],
)

# Define callbacks.
checkpoint_cb = keras.callbacks.ModelCheckpoint(
    "Brain_3d_classification.h5", save_best_only=True,monitor = 'val_acc', 
                             mode = 'max', verbose = 1
)
early_stopping_cb = keras.callbacks.EarlyStopping(monitor="val_acc", patience=20,mode = 'max', verbose = 1,
                           restore_best_weights = True)

# Train the model, doing validation at the end of each epoch
epochs = 60
model.fit(
    train_dataset,
    validation_data=valid_dataset,
    epochs=epochs,
    shuffle=True,
    verbose=2,
    callbacks=[checkpoint_cb, early_stopping_cb],
)

这是我第一次使用 3D CNN,我使用了这个 keras 网页的格式:https ://keras.io/examples/vision/3D_image_classification/

在我的案例中,(最大)验证准确度约为 54%。我尝试降低初始学习率,对于 0.00001,我达到了 66.7% 的最大值。对于 0.00005、0.00002 的学习率,我得到的最大准确率约为 60% 和 62%。

学习率 0.0001、0.00005、0.00002 和 0.00001 的准确度与历元图:

0.0001 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

尽管准确率仍然很低,但降低初始学习率似乎对准确率有积极影响。

我可以调整哪些其他参数来获得更好的准确性?是否可以继续降低初始学习率,直到我们达到目标准确度?

我知道这是一个相当广泛的问题,但我很困惑我们应该如何提高 CNN 的准确性(也就是 3D),那里似乎有很多事情正在发生。我是否在初始化中更改了某些内容?添加更多图层?还是改参数?我是减少还是增加它们?有这么多事情发生,我不认为尝试每一种组合并不断重复训练过程是一个有效的想法......

完整笔记本(包括预处理步骤):https ://www.kaggle.com/shivamee682003/3d-image-preprocessing-17cd03/edit

2个回答

什么是无信息率 (NIR)?即正面和负面标签的百分比是多少?你看过你的模型的预测吗?如果全为 0 或全为 1,那么除了预测多数类别之外,它可能什么也没学到。

当谈到架构选择和超参数时,尤其是当您开始使用 NN 时,Andrej Karpathy 的博客文章名为“训练神经网络的秘诀”是一个非常好的起点。当你没有太多直觉时,它为如何在一开始处理事情提供了很好的参考。如果您的模型太小,简单地降低学习率将无济于事。您可能还会发现添加类似 ResNet的跳过连接以提高非常深的模型(即多层)的性能很有用。

尝试在预测层之前移除 dropout。我找不到我读到的有关此的论文或文章(一旦找到就会更新帖子),只是找到了一个没有添加太多信息的交叉验证帖子。就像你一样

如果你要降低学习率,你也应该相应地降低批量大小

至于批量标准化层,它们可能应该在卷积层之后应用。