Kaggle百万美元大赛优胜者:如何用CNN识别CT图像检测肺癌?

本文来自AI新媒体量子位(QbitAI)

640?wx_fmt=png&wxfrom=5&wx_lazy=1


今年,Kaggle网站举办了一场用肺部CT图像进行肺癌检测的比赛Data Science Bowl 2017,提供百万美元奖金池。美国国家癌症研究所为比赛提供了高分辨率的肺部CT图像,在比赛中,参赛者根据给定的一组病人肺部CT三维图像,预测癌症风险。

Julian de Wit和Daniel Hammack合作完成的解决方案获得了比赛的第二名。Wit最近写了一篇博客来介绍他们的方案。他们通过3D卷积神经网络,来构建结节探测器,预测患癌可能性。Wit在64位的Windows10系统下,结合TensorFlow 0.12.0和Keras库实现该网络模型。

BTW,第2名的奖金是20万美元。

以下内容编译自Wit的文章:

初步了解和制定计划

在决定参赛之前,我观看了一个Bram van Ginneken关于肺部CT图像的介绍视频,有了基本的了解。我试图直接观察一些CT扫描样本,发现这是一个很难的问题,难度与大海捞针相当。视频中提到,图像的信噪比大约为1:1000。论坛中的一些讨论也提到,神经网络不能直接从这些原始图像中学习到有用信息。目前只有1300个训练样本及对应的癌症标签,这与网络提取出的图像实际特征相差甚远。

我们希望获得更高信噪比的训练集,或是找到标签和图像特征之间更直接的关系,来训练神经网络。幸运的是,比赛组织者指出,可以借鉴一个先前举办的比赛LUNA16。在LUNA16数据集中,医生为800多个病人CT图像中精心标记了1000多个肺结节。当然,LUNA16比赛也提供没有标记结节的数据集。

因此,你可以从整体CT图像中的标记周围裁剪出小型3D图像块,最终可以用更小的3D图像块与结节标记直接对应。结节大小是癌症的一个影响因素,数据集也说明了结节的大小,所以我认为这是一个有用的信息。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

图1:方法网络示意图

我还注意到LUNA16数据集是由另一个公开数据集LIDC-IDRI转化过来的。在原始数据集中,医生不仅要检测结节,而且还评估了结节的恶性程度和其他指标。我们发现,恶性程度是评估患癌风险的最佳指标,也是神经网络可以学习的。

最终的计划方案是训练一个神经网络来检测结节,并评估结节的恶性程度。在预测时,网络通过滑动窗口来遍历整体CT图像,分别判断每个滑动窗口的区域包含恶性信息的可能性。最后基于这种信息和其他特征,估计该患者发展成癌症的可能性。

数据预处理和创建训练集

在预处理中,要使扫描图像的尺度尽可能一致。我首先重新缩放了CT图像,使每个像素点只表示1x1x1毫米的体积。我们也尝试了一些其他尺度的实验,最终确定了采用1毫米的尺度,这能很好地平衡计算精度和计算负荷。对于CT图像,像素强度可以用Hounsfield来表示,一般叫做亨氏单位。论坛里提到,要尽量降低像素强度,即最大化hounsfield值,然后归一化处理。同时还要确保所有CT扫描都具有相同的方向,因为CT图像旋转超过45度,意味着在图像采集过程中出现错误。

极大部分关于结节检测的文献都是先从CT扫描图像中分离出肺组织。然而目前没有合适的分割方法,能够很好地处理隐藏在肺组织边缘周围的结节和肿块。在CT图像中,这些区域会直接被删除,更不用说使用结节探测器进行类型判定。我想要训练一个U-net网络,来更好地分割肺部。与传统的分割方法相比,U-net网络能够更有效地解决实际的图像分割问题,在同为Kaggle举办的卫星图像分割比赛中被广泛地使用。当我观察这些CT图像时,我认为可以通过肺组织的边缘,构建框架来找到肺结节。这么做可能是有用的,最后我决定对原始图像进行训练和预测。在调整训练数据后,该网络效果不错,似乎没有负面影响。

在这个竞赛中,给定了训练数据,可能没有很大的发挥空间。然而处理训练集是必须的,但不是最重要的那部分工作。我使用样本中的标签,自动生成训练集的标签,也采用主动学习方法,添加部分人工标记。以下是带有标记的不同数据集。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

表1:标记后的训练集

LIDC数据集中被正面标记的数量是LUNA16数据集样本数的五倍。因为这些标记是4名医生的综合注释,所以一个结节可能被标记了4次。但LUNA16也忽略了不到3名医生标注的结节。我决定在训练集中保留这些被忽视的结节,因为他们也提供了宝贵的结节恶性信息。

LUNA16 v2数据集的标签是直接从LUNA16传来,一般是多个结节检测系统错误标出的假阳性结节。要注意的是,部分结节是上面提到的不到3名医生标记的结节。我保留了这些结节标记,是为了平衡那些可疑的假阳性结节。

为了得到肺部轮廓,我需要得到非肺组织的底片。我使用了论坛中提到的简单肺分割算法,在分割掩码边缘周围进行采样标注,从而分割得到肺部组织。

在进行第一轮训练之后,我在LUNA16数据集上进行结节预测,得到了所有假阳性结节,也并入LUNA16 v2数据集中。

随着比赛的进行,我想建立第二个模型。对于这个模型,我做了放射科医生的工作,在NDSB数据集上训练网络。我手动地从癌症样本中选择明显的阳性结节,并从非癌症样本中选择假阳性结节,用这些数据训练了第二个模型。我希望效果不错,但我是一个不合格的放射科医生,实际上第二个模型比无手动标注的模型要糟糕得多。但是结合这两个模型,这个得到的融合模型比单独的模型效果更好,所以我保留了第二个模型。

我简单地建立了一个结节观察器,来调试所有的标记。在观察时,我注意到医生忽略了一些大于3cm的大结节。在LIDC数据集的说明文档中,我发现医生被要求忽略掉大于3cm的结节。我担心这些被忽视的结节区域会迷惑分类器,故删除了相重叠的底片。下面是肺部CT图像的一些截图。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

图2:图像中的标记。
左上:LUNA16 v2数据,右上:非肺组织的边缘,
左下:假阳性的区域,右下:被移除的无标注区域。

3D卷积神经网络的训练方法和网络结构

在一个高质量的训练集下,我们仍需要多次调整来有效地训练神经网络。数据集的两类样本量严重不平衡,正反两类样本量的比为5000:500000,且正面例子的大小和形状有很大差异。我曾考虑使用U-net网络,但2D U-net不能完全利用结节本身的三维结构信息,3D U-net网络的训练过程非常缓慢而且不灵活。我不使用U-net的主要原因是不需要建立细粒度的概率图,而只是一个粗略的检测器。在CT图像的滑动窗口中,建立小型的3D Convnet,这更加轻便和灵活。

我的第一个目标是训练一个可作为基础的结节检测器。我先要对正面例子进行过采样,将正反两类的样本比上调到1:20。为了提高模型的泛化能力,我尝试了一些图像增强操作,但是只有一些无损的操作是有用的。最后我用了大量的转化操作和所有3D翻转操作。

设计好分类器后,我想训练一个用于估计恶化程度的回归模型。将肿瘤恶化程度分为从1(很可能不是恶性)到5(很可能是恶性的)。为了强调肿瘤的恶性程度,我将标签平方,范围扩大为从1到25。最开始,我考虑了分阶段的一种方法,用第一个网络来分类节点,然后训练另一个网络估计结节的恶化程度。为了缩短计算时间,我尝试只用一个网络,以多任务学习的方法,同时进行训练这两个任务。当编程实现后,我发现这个方法简单快速,网络的效果也很好。

通常,神经网络的结构是比赛和案例研究中最重要的成果之一。对于这场比赛,我在神经网络的结构上花费的时间相对较少,因为已经有很多优秀网络可供参考。刚开始我使用了一些简单的VGG网络和Resnet网络的相似结构,但是它们的性能大致相同。然后我尝试用一个预训练好的C3D网络,原有的网络权重根本没有帮助,但直接初始化权重后,这种网络结构的效果很好。基于C3D网络进行若干次调整后,我得到最终的分类评估网络。

我首先调整了输入大小,设置为32x32x32 mm。这看起来可能太小,但是在后续的网络层中加入一些技巧,发现这种维度的实际效果很好。这个想法是保持一切轻量化,并在比赛结束后再建立一个更大输入维度的网络。但是由于Daniel的网络输入是64x64x64 mm,我决定保持目前的输入大小,使网络的输出互补。接下来我立即对z轴进行平均池化操作,使得每个体素表示2mm的区域。这进一步减少了网络的参数量,并没有影响到精度,因为在大多数扫描中,z轴会比x轴和y轴更粗糙。最后,我在网络顶部引入了64个节点的全连接层。这里,我们不是直接预测恶性肿瘤,而是通过训练图片的中级特征,输出结节的恶化程度。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

表2:3D Convnet的网络结构示意图

有趣的插曲:“奇怪组织”检测器

看着论坛的帖子,我发现所有的团队都在做类似的工作,我也在寻找一个能直接上手的方法。在观察CT扫描图像时,我发现了一些其他的事情。与LUNA16数据集一样,大部分的工作集中在识别肺结节上。然而,当癌症发展时,它们转变成肺肿块或更复杂的组织。并且我注意到,当扫描图像中有很多“奇怪组织”时,它发展为癌症的概率更大。此外,在很多CT图像中,我的结节探测器没有发现任何结节,这造成了一些很不好的假阴性现象。

在训练集中有10例存在上述现象,其中的5例为癌症病例。为了解决这些严重的假阴性,在扫描时,需要检测获得奇怪组织的数量。很幸运,在LUNA16数据集上包含了很多这样的样本,所以我很快对数据集进行标记并训练了一个U-net网络。加入奇怪组织检测器后,效果不错,我因此提高了本地CV值和LB上的排名。因为它对于不同的模型提升不同,很难评定实际效果,但我认为它大约提升了0.002-0.005。说实话,我认为这种改进是一个创新性的补充。以下是一些包含有奇怪组织的样本。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

图3:带有奇怪组织的CT图像样本。

肺气肿基本上是由吸烟导致的,我也试图建立一个肺气肿检测器。论坛上的医生都说,当肺气肿存在时,患有癌症的概率升高。有一些简单的算法公布了如何评估CT扫描中肺气肿区域的数量,设置hounsfield单位为950,来扫描CT图像。然而,我应用这种方法后,发现效果并不好。然后我标记了一些例子来训练一个U-net,发现效果不错,但是我的本地CV值没有丝毫提升。我的猜测是,因为肺部出现问题,进行扫描得到数据集中的许多病例,因此很多肺气肿样本没有看做是肺结节和癌症病例。我不能确定这个想法的正确性。

最后一步:癌症预测

训练好网络后,下一步是让神经网络检测结节并估计其恶化程度。我建立的CT结节观察器很容易查看网络结果。我觉得神经网络的效果很好:它检测到了许多我完全忽视的结节,而我只看到很少量的假阳性结节。但是还存在一个严重的问题:由于它错过了一些非常大的明显结节,所以影响了对于假阴性的得分,有时使LogLoss升高了3.00。作为尝试,我试图对CT图像进行了两次降采样,看看检测器是否会检测大结节。值得注意的是,它的效果非常好。因此,我调整了网络结构,让网络预测3个尺度,分别为1,1.5和2.0。我觉得值得花这么多的时候来改善这方面的性能。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

图4:在缩放1x的左图中,没有很好地检测到大结节;但是在2x放大的右图时,效果较好。矩形的大小表示坚持到的恶性肿瘤。

鉴于这些数据和一些其他特征,我想训练一个以梯度推进的分类器来预测一年内癌症的发病率,这是比较容易实现的。但是问题在于,排行榜的得分是基于给定的200名患者,这里面意外地包含了大量异常患者。经过一些调整后,我通过交叉验证得到了本地的平均值为0.39-0.40,而排行榜得分在0.44和0.47之间变化。此时很难将排行榜得分与本地CV值相关联。提高了本地CV值可能导致LB评分的降低,反之亦然。

我花了很多时间来研究本地CV值和LB评分的关系。我没有成功,所以我只使用能同时改进CV值和LB排名的技巧和特征。这是一场两阶段的比赛,而且与实际的训练集相比,第二阶段的数据存在与LB数据集更相似的可能。在这个地方,很多队伍也只能碰运气,结果显示排行榜上的很多队伍模型处于过拟合状态。最后我只使用7个特征来训练梯度推进器,分别是3个尺度下的最大恶性结节及其Z轴的位置和样本中奇怪组织的数量。

我也融合了两个模型来提高效果。第一个模型是在完整的LUNA16数据集上训练的。第二次,我试图从NDSB训练集中选择明显的阳性样本和假阳性样本,应用主动学习来训练。由于我不是放射科医师,所以我为了保险起见,只选择癌症病例的阳性例子和非癌症病例的阴性例子。我做错了,因为第二个模型比没有额外标注的LUNA16模型更糟糕。通过平均两个模型的输出,对LB排名有了很好的推动作用,并且显著提高了本地CV值。

与Daniel合作

在进行机器学习比赛时,将不同角度的解决方案组合在一起往往是个好主意。我和Daniel在以前的医疗比赛中一起合作过,知道他是一个非常聪明的人,且他的参赛思路一般和我不同。他是从研究的角度来看问题,而我一般以工程的角度来看问题。当我们合作时,我们确信结合两者互补的方法,能有一个很棒的解决方案。

我们这次组队,一开始就发现两个人对LIDC数据集中的恶性信息有完全相同的观察角度,解决方案也很相似,感到有点失望。不过幸运的是,剩余部分的设计方法完全不同,结合后显著改进了LB排名和本地CV值。下面列举出一些主要的区别。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

表3:Julian和Daniel之间设计方法的差异

强强联合是一个很好的选择。虽然我因为LB得分感到担忧,但Daniel觉得应该主要关注本地CV值。所以最终我减少研究本地CV值和LB的匹配关系,并着重于改进本地CV值。在最后的排行榜上,证明这是一个很好的决定,因为在最后,第二阶段的排行榜与本地CV值相当匹配,我们获得了比赛的第二名。尽管有许多队伍,在第一阶段取得了很好的排行榜得分,后来被证明模型过拟合。

总结与感想

我们在观察网络对CT图像的结节检测时,模型效果很好。第一阶段,logloss为0.43,公开排行榜的ROC准确率为0.85,第二阶段,logloss为0.40,私人数据集的ROC准确率更高。这让我很兴奋,因为在这个数据集上,我们的模型已经是一位训练有素的放射科医生了。

对于放射科医师来说,这个自动结节检测的模型可能很有帮助,因为在实际判断中,部分结节容易被忽视。模型对肿瘤恶化程度的评估效果也很好,但训练样本量只有1000个,所以应该有很大的改进空间。

在Daniel和我合作的解决方案中,应用了相当多的工程办法,许多步骤和决定是基于经验和直觉来确定的。我们没有足够的时间来准确地验证所有方法的效果。下面提出进一步研究的一些建议。

1. 建立放射科医师基准线。根据一个放射学家在这个数据集上的具体表现,建立一个具有参考意义的基准。

2. 对NDSB数据集的恶性肿瘤标注。在这场比赛中,训练样本只有约1000个结节。输入更多精确标记的例子,肯定进一步提升算法准确度。

3. 尝试更多不同的神经网络结构。我花了很少时间来选择效果最佳的网络结构,可能会错过一些效果更好的结构。

相关资源

这次比赛的Kaggle地址(含说明、数据集等):https://www.kaggle.com/c/data-science-bowl-2017/

文中提到的另一个比赛LUNA16:https://luna16.grand-challenge.org/

该项目的完整程序请查看GitHub链接:https://github.com/juliandewit/kaggle_ndsb2017

Dan Hammack也公布了他的代码:https://github.com/dhammack/DSB2017/

(完)

本文作者:王小新 
原文发布时间:2017-05-07 
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值