我花了两周跑遍主流医学图像模型,发现没一个省心
前阵子我干了件特别上头的事——花了两周时间,把深度学习在医学图像分析上能跑的主流模型全都撸了一遍。你猜结果怎么着?
那些综述文章列出的方法,SAE、RBM、CNN、U‑Net、FCNN、FRCNN……看着是真全,但真正敲下第一行代码,我才发现:没一个省油的灯!就像你走进一家工具店,货架上摆满电钻、电锯、激光切割机,以为拎回家就能造别墅,结果发现全是杂牌军,用起来一个比一个扯。
来,带你看看我踩过的坑、流过的泪、闪过的光。
先说模型:每一个都有“你以为”和“实际是”
CNN,深度学习的亲儿子。AlexNet、VGG16在ImageNet上跑得呼啦啦,我心想把这套搬到医学图像上,那还不跟开挂一样?结果倒好——水土不服,直接拉胯!你想想,医学图像大部分是灰度图,通道就一个,病灶区域经常只占几个像素,你拖出ImageNet那套卷积核上去扫,跟拿渔网捉蚊虫没区别。我用VGG16加微调做肺结节检测,效果居然比一个简单的滑动窗口加手工特征还差。后来换了Inception v3(GoogleNet的升级版),才算好了一点。这说明啥?医学图像吃的是局部特征和多尺度融合,自然图像那套不能硬套。
U‑Net,分割任务里绝对的扛把子,没之一!我拿它做肝脏分割,Dice系数直接飙到0.9。但是别急,我说的是2D U‑Net处理单层切片。一上CT三维数据,问题就来了:显存瞬间爆炸!一个256×256×200的体积,哪怕我的Titan X都快塞爆了。而且3D U‑Net虽然能捕捉空间上下文,但性能提升跟计算量压根不成正比。我当时也纠结半天,我的建议很实在:如果你跟我一样只有单机单卡,老老实实2D加轴向切片,然后用后处理做三维连通;如果你有集群或者能忍受训练一周,再考虑3D。
UNet++,后来我也试了。Zhou那篇MICCAI文章里的,加入了嵌套密集跳跃连接,在边界模糊的区域确实比原始U‑Net强。比如胰腺分割,Dice大概提2‑3个点。但代价呢?参数量翻倍,训练时间长50%。值不值?看你的精度要求。我对精度不是变态严苛的话,觉得有点亏。
循环神经网络(RNN),我被它的概念忽悠过一次。用LSTM把连续几层CT切片当作时间序列,想建模器官间的连续形变。结果非常感人——跟直接用U‑Net处理单帧再做个时间平滑差不多,但训练难度大了好几倍。我对RNN在医学图像上的有效性,只能微笑保留态度。
FRCNN,目标检测还行,比如定位肺部结节。但我踩过一个巨坑:RPN网络生成的proposal框在CT图像上,老是高密度血管误认为结节。为什么?因为这个网络原本为自然图像设计,对形状要求不严格。我后来加入形状先验,在FPN基础上改进了特征金字塔设计,才有所改善。
三个大坑,你一定会遇到
第一个坑:标注数据太少,迁移学习也不是万能的。
有研究用4万多张CT才能训练出和放射科医生精度相当的肺癌诊断模型。我当时头铁,上来就用单中心2000张胸部X光片做分类,结果换了一个医院的数据,精度直接从0.93掉到0.65!两个医院用的X光机品牌都不一样,对比度、噪声分布完全不同,模型直接懵了。
你问我后来怎么补救的?数据增强救了一半,另一半靠ImageNet预训练权重做初始化。但说句难听的,ImageNet的彩色自然图跟医学灰度图差距太大了。文献里Esteva和Gulshan那两项工作在皮肤病和眼科上成功,本质上是因为皮肤镜图像和视网膜图像跟自然图像的纹理结构有相似性。换成CT、MRI这种灰度体积数据,预训练模型的效果远没传说中那么神。
第二个坑:模型黑盒,你永远不知道它什么时候抽风。
我第一次把一个训练好的结节分割模型交给医生验收。连续20个病例,表现都正常。第21个病例的CT扫描有金属植入物伪影,模型直接把伪影区域全分割成了结节——比真实结节还大!医生当场笑了我一句:“你写的算法还不如我看两分钟。”
我当时真不知道为什么会错。后来试了Grad‑CAM可视化,才明白模型学的是图像中高对比度的边界,而不是结节的形态。说白了,深度学习在医学图像上的可解释性还是个硬伤。你没法跟医生解释说“我的模型学到了一个你不知道的隐藏特征”,人家只相信病理依据。
第三个坑:数据类别极度不均衡,二分类模型根本不够用。
二分类模型过于简单,难以胜任更复杂的情形。比如病变分级(正常、良性、可疑、恶性),用多分类加softmax直接训,模型会永远猜样本量最大的那个类。我后来试了OHEM(难例挖掘)和Focal Loss,才把少数类的召回率从30%拉到70%。但代价呢?调参花了我两周!
希望之光:这些方向让我眼睛一亮
VoxelMorph,配准的惊喜。用深度学习做三维图像配准,速度比传统方法快了1000倍!传统配准跑一对脑部MRI要十几分钟,它几秒钟搞定。虽然精度跟经典的SyN方法还有差距,但速度优势太明显了——尤其适合大样本队列分析。文献也提到这个方法,真的值得关注。
自监督学习,这两年我最看好的方向。Zhou那篇Models Genesis,用图像修复、重建等代理任务预训练一个3D模型,然后再在下游任务上微调。我在肺结节分类和脑部分割上都试过,只需要10%的标注数据就能达到从头训练100%数据的精度!这招对标注稀缺的医学领域太关键了。
获取高质量数据集,这事儿比任何模型都重要。CheXpert和斯坦福一篇博士论文都强调过:与其花大力气调模型,不如先把数据集质量搞上去。我后来找了一个只有几百张但每张都有三个放射科医师标签的少见病数据集,效果比五千张只有一个专家粗糙标注的数据好得多。真金不怕火炼,数据不怕少,就怕烂。
最后说句实话
深度学习在医学图像分析上确实能干点活,但远没到能替代医生的地步。我自己现在的打法是用U‑Net做分割、用Inception做分类、用VoxelMorph做配准——这三板斧就足够应对大部分问题了。别被那些花哨的模型框架带偏,真正让你出成果的往往是数据清洗、标注质量、后处理这些脏活累活。别看不起传统方法,有些问题用形态学滤波加决策树一样能解决,还不会翻车。
我现在接手新任务,第一件事:先上最简单的手工特征加随机森林,打Baseline;然后才上深度学习。这样至少不会因为模型黑盒而被人问住。因为你知道,在医学战场,最锋利的刀不是模型多新颖,而是你对数据的敬畏、对死磕的耐心。
记住了:别怕脏活累活,它们才是你真正牛逼的理由。
读者评论 3