返回列表

15th Place (3DResnet Part)

388. TReNDS Neuroimaging | trends-assessment-prediction

开始: 2020-04-23 结束: 2020-06-29 医学影像分析 数据算法赛
第15名方案 (3D Resnet 部分)

第15名方案 (3D Resnet 部分)

作者: Rob Mulla (以及团队成员 @cpmpml, @philippsinger, @ericfreeman, @fakeplastictrees)
比赛排名: 第15名

感谢 Kaggle 和主办方举办了这场非常有趣的比赛。能与 @cpmpml@philippsinger@ericfreeman@fakeplastictrees 这样才华横溢的队友一起合作真是太棒了——我在很短的时间内从他们身上学到了很多东西,非常感谢他们的组队。同时也要祝贺所有获得金牌的选手,我非常期待阅读你们的解决方案!

3D (4D?) Resnet

我对团队的主要贡献是构建了一个 3D Resnet。我决定使用 Keras,架构的大部分是基于我在 github 上找到的这段代码,我只是对其进行了一些修改以适配 tf2.0。模型本身在排行榜(LB)上的表现并不好,但与优秀的表格数据模型混合后,分数有了显著提升。

我们最初有一个 LB 分数为 0.1589 的表格模型 -> 与 3D Resnet 按 20/80 比例混合后,LB 提升至 0.1587 -> 加入 mixup 数据增强后,LB 进一步提升至 0.1578。

我还将所有的 fMRI 和表格数据转换为 tfrecords 格式,以优化磁盘加载速度。

模型的主要部分如下所示:

input = Input(shape=input_shape, name='fMRI')
# first conv
conv1 = conv_bn_relu3D(filters=64, kernel_size=(7, 7, 7),
                        strides=(2, 2, 2),
                        kernel_regularizer=l2(reg_factor)
                        )(input)
pool1 = MaxPooling3D(pool_size=(3, 3, 3),
                     strides=(2, 2, 2),
                     padding="same")(conv1)
# repeat blocks
block = pool1
filters = 64
for i, r in enumerate(repetitions):
    block = residual_block3d(block_fn, filters=filters,
                                kernel_regularizer=l2(reg_factor),
                                repetitions=r, is_first_layer=(i == 0)
                                )(block)
    filters *= 2
# last activation
block_output = bn_relu(block)
# average poll and classification
pool2 = AveragePooling3D()(block_output)
pool_dense = Dense(256*4*4, activation='sigmoid')(pool2)
flatten1 = Flatten()(pool_dense)
# Dense output
dense_out = Dense(units=num_outputs))(flatten1)

数据增强

4D Mixup

我在这个模型中最大的收益来自于添加了针对 4D 的定制版 mixup。其思路与图像的 mixup 相同——我将两张随机图像混合,然后将这个“新”大脑的目标标签设为原标签的加权平均值。我在 TensorFlow 的数据集管道中按批次执行此操作。虽然这确实显著减慢了训练速度(每个 epoch 从 200 秒变成了 300 秒),但在混合后,它使 CV 和 LB 分数提高了约 0.001。

增强代码参考了 @cdeotte 针对 2D 图像的笔记本,链接在这里

4D Mixup 示意图
def mixup4D(image, label, prob=1.0):
    """
    4D Mixup of fMRI images size (BATCH,53, 63, 52, 53)
    """
    imgs = []; labs = []
    for j in range(BATCH):
        P = tf.cast( tf.random.uniform([],0,1)<=prob, tf.float32)
        k = tf.cast( tf.random.uniform([],0,BATCH),tf.int32