RSNA Pneumonia Detection Challenge项目简单学习<4>

kaggle中的解决方案和总结

第一名

内容:

- 分类使用了pipeline分类检测
	- 对于分类用了10折(交叉验证)集成分类,5个10折集成用于检测(50个模型)。

在检测方面用到了:

	- retinaNet:[https](https://github.com/fizyr/keras-retinanet) : [//github.com/fizyr/keras-retinanet](https://github.com/fizyr/keras-retinanet)
	- 可变换的R-FCN:[https](https://github.com/msracver/Deformable-ConvNets) : [//github.com/msracver/Deformable-ConvNets](https://github.com/msracver/Deformable-ConvNets)
	- 可变换的关系网络:[https](https://github.com/msracver/Relation-Networks-for-Object-Detection):[//github.com/msracver/Relation-Networks-for-Object-Detction](https://github.com/msracver/Relation-Networks-for-Object-Detection)
	- 将boxes组合在一起,一种用于目标检测的基本集成方法:[https](https://github.com/ahrnbom/ensemble-objdet) : [//github.com/ahrnbom/ensemble-objdet](https://github.com/ahrnbom/ensemble-objdet) 

代码地址:https : //www.github.com/i-pan/kaggle-rsna18

git下来代码后看到对于检测用到的模型:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 在这里插入图片描述
对应了上面说的检测模型

分类

使用Keras 2.2进行分类。分类模型由以下各个模型组成 [format: modelArchitecture (numClasses) (imgSize)]。对模型进行2类(不透明vs.透明)或3类(不透明vs.非正常/透明vs正常)的训练。每个模型都经过不同的折叠训练

  • InceptionResNetV2 (2) (256), InceptionResNetV2 (2) (320)
  • InceptionResNetV2 (3) (256), InceptionResNetV2 (3) (320)
  • Xception (2) (384), Xception (2) (448)
  • Xception (3) (384), Xception (3) (448)
  • DenseNet169 (2) (512), DenseNet169 (3) (512)

从上面的地方可以看出对于分类用到了InceptionResNetV2 、Xception 、DenseNet169 模型去实现。代码中对应在这里插入图片描述
是对灰度图像的分类

预训练权重:

首先,我们使用15类(14个发现+异常与正常)在NIH ChestX-ray14数据集上训练了ImageNet预训练网络。然后我们在肺炎数据集上微调这些权重。使用ImageNet权重进行局部训练仅能提高约1%的效果。经过折叠后,得到了约0.88-0.90 AUC。

(补充AUC:基于 ROC 线下面积。例如0.7的 AUC,其含义可以大概理解为:给定一个正样本和一个负样本,在70%的情况下,模型对正样本的打分高于对负样本的打分。可以看出在这个解释下,我们关心的只有正负样本之间的分数高低,而具体的分值则无关紧要。)

数据增强:

对模型进行训练,有50%发生颜色反转,50%发生翻转,50%进行其他某种增强(例如,对比度增强,裁剪,旋转)的增强。我们对每个模型的最终预测使用了15倍的TTA, ,并将150个预测的平均值作为最终分类分数。当发布第1阶段的测试标签时,我们的分类集成的AUC为0.93。

检测

这里作者用到了不同的检测组合详细的给我们说明了用不同网络组合得到的过程结果。

  1. 检测组合1:每个折叠都以不同的分辨率进行训练(224-512,增量为32),只在Positive图像上。发现较低的分辨率并不会降低本地性能,实际上会提高公共LB(排行榜)的性能。第一个检测集合是可变形R-FCN的10倍CV集合。除了解冻默认配置中冻结的非BN(批量归一化)层外,我们主要使用默认参数。这些模型使用ResNet101 ImageNet预训练的主干网。我们还将每个图像的最大检测次数更改为5,但将阈值保持在0.001。数据增强仅使用的是翻转。这些模型训练非常快(〜2小时),具体取决于***图像分辨率***。
  2. 检测组合2:与检测组合1基本相同,但是多了一部分就是使用了可变形的关系网络。尝试学习要使用的NMS阈值的版本,但是效果很差。
  3. 检测组合3:与检测组合2完全相同,但是将主干层冻结。使主干层保持冻结状态会使性能略有下降,但是我们加入了集成以降低与其他集合的模型相关性,并且在我们的第1阶段公共LB得分中有轻微的改善。
  4. 检测组合4:这是一个RetinaNet集成,也是10倍CV,但仅在384 x 384分辨率下进行了训练,因为我们在更改锚点大小方面遇到了问题。我们对级联图像(concatenated images)进行了训练,在该级联图像中,每个negative 图像均与左侧或右侧相同折叠处的正图像随机级联(因此最终图像尺寸为384 x 768)。我们训练了8000步/epoch,bitch大小为1,进行了8 epoch,在第4 epoch和第6 epoch后将学习率除以10。我们选择了在8个时期内具有最佳mAP指标的模型。使用了--random-transform,它使得训练更加的不稳定,所以没有指定他,所以只有数据增强的时候是有翻转的。==10倍CV集成中的一半使用ResNet101主干进行训练,另一半使用ResNet152进行训练。ResNet101明显优于ResNet50,但ResNet152与ResNet101相同。==对级联图像的培训使RetinaNet可以更好地平衡精度和召回率。
  5. 检测组合5:和4相同,但是将negative 图像换成了Positive图像

组合之前的检测方法:

  1. 检测集成1+2+3:对于1-3个检测集合,我们应用了6倍的TTA(Test Time Augmentation)(原始的,翻转的,原始和翻转的均为80%/ 120%)。使用了上面说的boxes组合,然后通过乘以包含该框的TTA的分数来调整框得分的预测(即,如果5/6 TTA预测框的平均得分为0.5,则将其乘以5/6)。这段代码在计算getCoords函数中盒子之间的IoU重叠时需要中心坐标。为了结合分类网络,我们将集成平均框得分预测乘以该图像的分类得分。我们消除了调整后分数 <0.225 的框。

  2. 检测集成4+5:我们应用了 10 倍 TTA(原始/翻转的分辨率为 320、352、384、416、448),执行与上述相同类型的集成,包括基于预测该框的 TTA 分数进行分数调整。然而,在这个阶段,我们没有将两个集成中 20 个模型的预测结合起来。相反,我们使用 0.2 的分类分数阈值和 0.3 的框分数阈值来检测集成 4。我们上面使用的乘法方法对 RetinaNet 效果不佳。尽管我们说检测集成 4 不一定需要配对分类器,但它确实将阶段 1 公共 LB 分数提高了约 0.003。

    应用这些阈值后,我们使用相同的代码和 IoU 阈值 0.4 组合了来自 ensemble 4 和 5 的框。

最终的组合:

​ 剩下 2 个集成。如上所述,我们使用相同的调整策略,使用相同的权重和 IoU 阈值将它们组合在一起。使用的最终框阈值为 0.15。

总结

作者在做肺炎检测时,先是使用了InceptionResNetV2XceptionDenseNet169网络作为分类处理网络,使用ImageNet预训练网络得到预训练数据。在数据增强方面最终预测使用了15倍的TTA,提高结果的精度。在检测方面,作者提出了5中方法,其中1、2、3主要是在主干为ResNet101进行检测的,使用到了R-FCN集成检测,而数据增强只用到了翻转。4、5方法是RetinaNet集成检测,主干一半是ResNet101,另一半是ResNet152,这两个效果相同。最终是123组合和45组合。

但是第一名的方案太过于复杂,使用了很多模型结合起来运用,而且在有些地方作者说了没必要加的东西加上之后反而使得LB有了改善,所以说如果第一名的使用起来一定是比较麻烦的,感觉第一名是无限往第一名的LB方向去的而不是一个非常好的方法。

第二名

参考<3>

内容

作者主要是在RetinaNet 网络的基础上进行了修改。单个模型,4倍的集成输出。

修改内容:对原始pytorch-retinanet实现进行了修改:

  • 测试了不同的基本模型,se-resnext101效果最好,se-resnext50稍差
  • 为较小的锚点(2级金字塔层)添加了额外的输出以处理较小的盒子
  • 添加了另一个分类输出,可预测整个图像的类别(“无肺部不透明度/不正常”,“正常”,“肺部不透明度”)。没有使用输出,但是甚至使模型预测其他相关功能也改善了结果。
  • 原来的pytorch-retinanet实现忽略了没有框的图像,我对其进行了更改以计算它们的损失。
  • 与锚点位置/大小回归输出相比,分类输出过拟合快得多,因此我为锚点和整个图像类输出添加了失活率。除了额外的正则化,它还有助于在同一时期实现最佳的分类和回归结果。

**主干网:**使用到了SE-ResNext体系结构,并取得了最佳性能。

在这里插入图片描述

**数据增强预处理方面:**预处理,原始图像按比例缩放为512×512像素分辨率。数据增强,轻微旋转(最多6度);移位,缩放,剪切;水平翻转;对于某些图像,模糊处理,添加噪声,进行伽玛值随机变化;有限提高亮度/伽玛增强量等

优化:4折交叉验证的输出合并。

总结

作者使用了retinaNet网络检测并在其基础上进行改进为retinaNet SSD网络,结构结构相较于Fast R-CNN简单,并且在实验中数据进行调节更加的容易。因此我认为第二名作者的方法是这次比赛中的优秀解决方案。

第三名

摘要

模型基于 keras-retinanet 代码模型,论文是 focal loss paper by Lin et al 。这是一个单阶段卷积神经网络检测体系结构。我使用Keras优化了两个RetinaNet模型,用的是在ImageNet图像上预先训练过的resnet-50resnet-101主干。我使用非最大抑制NMS来消除每个网络中任何重叠的边界框。然后我从两个训练好的神经网络中取重叠边界框的加权平均值。我还对所有最终边界框应用了全局固定百分比大小缩减,可以显著提高第一阶段的测试分数。

代码地址:https://github.com/pmcheng/rsna-pneumonia

特征选择

使用了DICOM视图投影(AP与PA),没有在训练集中使用标签,没有手动特征选择工程,没有用外部培训数据。

训练

对于肺炎边界框预测,不需要高图像分辨率。我使用了224 x 224分辨率的训练图像,这使得在我的硬件上训练的效率大大提高。我使用https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html

sklearn的分层K折函数将25684个训练图像分为大训练集(24399个图像,占95%)和一个小的验证集(1285个图像,占5%)。我最初使用的是更大的验证集,但后来发现当我将更多图像转移到训练中时,我的训练结果明显更好。通过旋转,平移,缩放和水平翻转(关闭了剪切垂直翻转)来增强图像。 我还在图片中添加了随机常数,这是我从@ZFTurbo的一篇文章中发现的https://www.kaggle.com/c/google-ai-open-images-object-detection-track/discussion/64633,这篇文章是关于之前的一次竞赛中RetinaNet的。

修改了默认的训练参数以匹配焦点损失论文(即,学习率= 0.01,动量= 0.9,衰减= 0.0001, nesterov = True的SGD), 这是由于与Adam相比,SGD的动量模型更具有普遍性。在最终模型中,我使用了resnet-50resnet-101主干。我确实使用resnet-152进行了实验,但是培训花费了更长的时间,结果却稍差一些。

我训练了25个epoch,每个epoch 2500个步骤,bitch大小为8,在每个epoch后保存了模型快照。在每个epoch之后,我在验证集中计算了边界框;我将filter_detections层中的分数阈值从keras-retinanet更改为0.01(从0.05),以便可以评估较低的分数阈值。在每个时期,我都会计算得分阈值,以提供验证集上的最大 Youden指标(敏感性+特异性– 1)。更具体地说,我计算了对图像的sensitivity和specificity ,而不是对边界框, 我的想法是,从评分的角度来看,系统对整个图像对肺炎是阳性还是阴性很重要。我还计算了在Yicheng Chen的出色内核中实施的RSNA度量https://www.kaggle.com/chenyc15/mean-average-precision-metric。 我发现,在排行榜上表现最好的快照是Youden指数最高的,并且降低了得分阈值以使灵敏度接近90%。我怀疑分数阈值降低的好处是由于相对于训练集,测试集中肺炎的患病率更高

我积极地使用非最大抑制来消除给定图像的每个网络输出中任何重叠的边界框。我的想法是医生注释者很可能会指定不重叠的地面真相边界框。尽管Tensorflow具有NMS功能,但我发现修改Adrian Rosebrock在他的博客上发布的代码更加有用和有益。https://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python

然后,我从两个训练好的神经网络中取重叠边界框的加权平均值,将每个网络中的边界框的分数作为权重。我尝试了边界框的交并比IoU,但效果并不理想。对于两个神经网络之间不重叠的边界框, 我使用一个单独的更高的阈值来决定是否应该保留单独的框。我还对所有最终边界框应用了全局固定百分比大小缩减,这显著提高了阶段1的测试分数。

总结

第三名的方法比较的简单,主要是在一些方法上使用了一些小小的优化,第三名的主要的实现是基于Keras中retinaNet和论文Focal Loss for Dense Object Detection 进行的,对于输入来说设置了低像素值,数据增强用到了旋转,平移,缩放和水平翻转,而且在图片中添加了随机常数。对于retinaNet网络进行优化,主干网是在ImageNet图像上预先训练过的resnet-50和resnet-101。第三名和第二名一样都是在retinaNet模型为基础进行了其他的改进。

第四名

摘要

我们开发了三个卷积神经网络对象检测器(Mask RCNNYOLOv3Fast RCNN体系结构)的集成,以及用于减少假阳性的分类网络(DenseNet-121体系结构),以检测胸部x射线肺炎(见图1)。我们发现,在目标检测中使用一个宽松的检测阈值,同时要求检测器之间达成一致,有效地减少了误报和漏报。通过优化曲线下面积(AUC)计算分类器的检测阈值。采用自适应直方图均衡化作为数据预处理步骤,提高图像对比度。我们使用年龄、性别和视图位置作为分类器倒数第二层的输入,以提高性能。

在这里插入图片描述

模型集成方法

首先是获取了10个Mask R-CNN的bbox预测交点,每个检测器都在训练数据的子集上进行了3次训练。接下来获取了10个边界框它们构成了相交图像中的结果区域,并计算了加权平均边界框。image-20210819190203989

上述两种方法产生两个框:一个小框(对应于交叉点这个是mask R-CNN的)和一个大框(对应于平均值 加权平均框)。我们假设最优边界框位于两者之间。因此,我们使用3:1的比率重新加权交点和平均边界框的坐标

在这里插入图片描述

重复上面的方法组合mask R-CNN、YOLOv3、Fast R-CNN。

权重和代码地址:

https://github.com/matterport/Mask_RCNN

https://github.com/qqwweee/keras-yolo3

https://github.com/tensorflow/models/tree/master/research/object_detection

https://github.com/arnoweng/CheXNet

总结

第四名的方案是将Mask R-CNN、YOLOv3、Fast R-CNN结合起来,主干网是DenseNet-121用来分类。作者反复强调自己用到了加权平均框去设置最后的框。因此使用加权平均法去得到bbox是一个考虑因素。

第六名

解决方案基于语义分割,使用类似 U-net 的网络架构。我们的一个关键见解是检测边界框的“边缘”至关重要。我们试图分别预测边界框的上、下、左、右边缘。

U-net-like为主干网络

采用 Imagenet 预训练的 ResNet152 作为特征提取器。输入图像被调整为 512x512,由提取器处理为 16x16 大小,然后unpooling操作4次获得256x256 输出。对于 unpooling 的每一步,特征向量与对应的 ResNet 层级联,然后处理 3x3 卷积和 ReLU 两次。最终输出的形状为 64x256x256。

‘seg’ and ‘edge’ 预测

一个1通道1x1卷积应用于此输出获得‘seg’层。该层表示每个像素在边界框内的置信度。这一层的sigmoid被复制并连接到64通道输出,应用3x3卷积和ReLU两次,最后应用1x1卷积产生4通道’edge’层。该层的第一个通道表示每个像素作为边界框“最顶部”像素之一的置信度。其他 3 个通道分别用于最底部、最左侧和最右侧。

‘seg’ 层的损失为1 - f1,其中 f1 是分割的可微 F1 分数。“边缘”层的损失是交叉熵损失。网络的整体损失是这两个损失的总和。

由于“edge”层的大多数地面实况像素为负(即使对于具有边界框的图像),因此此类负像素被适当地欠采样。

训练详情

我们使用 x 翻转、90 度旋转、放大/缩小和随机对比度变化(假设k是 [-10, 10] 之间的随机整数,添加k所有像素)作为数据增强。正样本被过采样三倍。批量大小为 10。

我们使用了权重衰减为 1e-4 的 Adam 优化器,并训练了 30 个 epoch。在 20 和 27 个 epoch 结束后,Lr 除以 10。我们在前 200 次迭代中冻结了提取器的权重,然后在剩余的训练中进行了微调。

Inference

首先我们将每个图像通过线 分成两部分(右和左)x = c,其中 c 是所有像素的 x 坐标的加权平均值(权重 = 像素值)。对于每个片图像的,我们检查与至少40像素的高度和宽度每一个可能的矩形,并找到一个最大化p = p_top * p_bottom * p_left * p_right,其中p_top是“edge”层的第一信道的S形的几何平均值,在矩形之中的最上面像素检查(与p_bottomp_left和相同p_right)。最后,如果 p >= 0.3,则认为是预测。

总结

第六名与之前的用的方法不同他使用到了U-Net网络,而在前面与第六名有点关系的是使用mask R-CNN网络,一个是语义分割,一个是实例分割,作者对U-Net网络进行了简单的改进,主干网是 ResNet152 ,用到了‘seg’ and ‘edge’ 预测,数据增强为 x 翻转、90 度旋转、放大/缩小和随机对比度变化。

第八名

第八名的检测框架与 S3FD(人脸检测框架)相似,并且使用了Pytorch 实现。

在训练阶段,我选择了 5158 个正样本(‘肺炎’)作为训练集。验证集包括 500 张“肺炎”图像、500 张“无肺不透明”/非正常图像和 500 张“肺不透明”图像。由于时间限制,我没有使用交叉验证方法。为了减少 GPU 内存并保持高分辨率,我将输入图像的大小调整为 800 x 800。并且在训练阶段使用了一些数据增强技术(RandomSampleCrop 和 RandomMirror)。

首先,我设计了我的多层检测损失来计算没有ground truth的输入图像,所以我可以使用所有图像来训练检测模型。实际上,实验的结果并不好。之后,我裁剪了肺炎图像中的框区域并将其放入普通图像中以生成新的训练集。最后,Anchor锚点设计对于检测任务非常重要,所以我使用k-menas 设计了两个锚点解决方案。

损失函数:在损失函数中,将原来的带有交叉熵的分类损失和带有平滑L1的回归损失分别改为加权交叉熵和加权平滑L1。权重取决于 GT 盒和锚点之间的 IOU。这种方法可以稍微减少回归置信度和分类置信度之间的不平衡。

**检测网络:**为了提高我的检测模型的特征提取能力,还使用了一个特征金字塔网络(FPN)。我还尝试实施 RefineDet(两阶段 SSD https://arxiv.org/abs/1711.06897)来检测肺炎,但它有很多假阳性样本。

Backbone:基本模型只使用预训练的 VGG16 模型。

后期处理:在推理阶段使用了两阶段 NMS方法,首先我删除了重叠 >= 0.7 的预测框,但是保留框的 xmin、ymin、xmax、ymax 是被删除的框和它本身的平均值。然后将重叠 >= 0.05 的普通 NMS 方法作为两阶段 NMS 方法。

总结

该作者使用了VGG16做为分类的主干网,在数据增强上用到了RandomSampleCrop 和 RandomMirror,检测网络使用到了类似于S3FD的框架加入了FPN。作者的方法比较新颖但是对于检测网络方面没有说的很详细。主干网我是第一次看见用VGG16的,因为之前基本上都是resnet模型。

从中得到的方案

在网上使用的解决方案是mask R-CNN,使用了迁移学习COCO的预训练权重,最后得到的LB为:0.155。

Backbone

首先就是主干网可以优化,从上面的前几名的方案中可以知道我可以在我的config中对一些超参数进行配置,上面的高亮部分是可以对我运行的模型进行优化的地方。一半使用ResNet101主干进行训练,另一半使用ResNet152进行训练。ResNet101明显优于ResNet50,但ResNet152与ResNet101相同。还有就是第三名所表达的我使用了resnet-50resnet-101主干。我确实使用resnet-152进行了实验,但是培训花费了更长的时间,结果却稍差一些。

因此就是对于主干网取ResNet101可能更为合理。

代码:在这里插入图片描述

修改该代码resnet101,并且修改为resnet152可能会对项目有所帮助。由于在跑代码的时间不够因此没有进行测试。

数据增强

第二个我认为可以优化的地方在于数据增强,源代码中的数据增强使用的是imgaug模块提供的函数,使用到了几何变换、亮度对比度变换、图像清晰度变换三种。而第一名在使用时只用到了翻转,因此我认为可以在数据增强方面去掉后面的两种方法。

代码:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XNwpndEa-1629870777507)(D:\STUDY\Note\image\image-20210819204030876.png)]

mask R-CNN

通过论文《一种改进的 Mask RCNN 特征融合实例分割方法》,该论文中也使用到了COCO的训练权重,由于特征金字塔网络低层特征到高层特征的融合路径太长, 导致低层特征在整个特征层次中的作用较弱。在特征金字塔网络的基础上, 引入一条自下而上的路径来增强整个特征层次, 缩短较低层特征与顶部特征之间的融合路径, 增强低层特征在整个特征层次中的作用;在卷积神经网络中引入空洞卷积算法扩大卷积感受域, 进一步提升掩膜预测准确度。

空洞卷积神经网络

img img

大概意思就是在处理图像的过程中卷积运算可能使图像的尺寸越来越小,而使用了same的padding会使得图像的边缘越来越模糊,因此使用空洞卷积去处理图像。

在这里插入图片描述

因此使用空洞卷积对mask R-CNN进行优化。

没有完成代码复现。

参考:1. https://blog.csdn.net/lk3030/article/details/84847879 【Xception】

  1. https://www.zhihu.com/question/399611596 【backbone】

  2. https://www.cnblogs.com/yuehouse/p/9742647.html 【InceptionResNetV2】

  3. https://www.zhihu.com/question/39840928【AUC】

  4. https://blog.csdn.net/qq_38900441/article/details/106047525【BN层】

  5. https://blog.csdn.net/DoReAGON/article/details/102568782【TTA】

  6. https://blog.csdn.net/JNingWei/article/details/80038594?utm_medium=distribute.pc_feed_404.none-task-blog-2defaultBlogCommendFromMachineLearnPai2default-4.nonecase&depth_1-utm_source=distribute.pc_feed_404.none-task-blog-2defaultBlogCommendFromMachineLearnPai2default-4.nonecas【RetinaNet】

  7. https://blog.csdn.net/qq_42278791/article/details/90613191【SSD】

  8. https://blog.csdn.net/sunflower_sara/article/details/100531046【SE-ResNext】

  9. https://blog.csdn.net/dQCFKyQDXYm3F8rB0/article/details/80240645【随机加权平均】

  10. https://blog.csdn.net/u014380165/article/details/83477516【S3FD】

  11. https://www.zhihu.com/question/54149221【空洞卷积】

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值