ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

语义分割与医学图像分割论文阅读指南:从FCN到Transformer的演进路线

语义分割与医学图像分割论文阅读指南:从FCN到Transformer的演进路线

搞语义分割和医学图像分割方向的同学,应该都经历过这种阶段:每次想系统性读论文,从一堆名字里筛出值得精读的文章,本身就够花掉不少时间。这个论文合集,就是把语义分割、医学图像分割这两个方向里的经典思路和近期值得关注的工作,按“解决什么问题、用了什么思路、适合什么场景”这类线索串起来,方便大家直接对着目录找方向。我把它定位成一份“阅读地图”:适合刚入门、想快速建立全局认识的研究生,也适合准备做落地选型的工程师。

1. 先搞清楚语义分割和医学图像分割到底在解决什么问题

1.1 分割任务在一众视觉任务里的位置

分类、检测、分割这三类任务,很多人刚接触时会觉得边界模糊,其实只要抓住“输出粒度”就很好区分。分类回答的是“整个图里面有什么”,输出是一个类别标签;检测回答的是“物体在哪里”,输出是边界框;而语义分割回答的是“每一个像素属于什么类别”,输出是一张跟原图尺寸一致的像素级标签图。把这个任务放到实际场景里,例子就非常直观:自动驾驶里要让车知道眼前是道路、行人、车辆,只识别出“有辆车”是不够的,还得画出车辆精确的轮廓、路面精确的范围,这时像素级的分割就是绕不开的底层能力。

医学图像分割也建立在同一个语义分割框架上,只不过输入变成了CT、MRI这类影像,输出变成器官、病灶的精细轮廓。和自然图像分割相比,它的核心诉求更偏向“准确性和可解释性”:医生在判断一个肺结节边界的时候,不能接受模型随手画出一个大致的区域,每个体素的分界都要尽可能接近解剖结构。这也是为什么医学图像分割论文往往会围绕“边界是否清晰”“小病灶是否容易漏检”这类问题展开,脱离这个前提去讨论模型结构,很容易做偏。

1.2 医学图像分割和通用语义分割的差异在哪里

虽然底层都是像素级分类,但医学图像分割在很多维度上和通用语义分割差别很大。首先数据规模就完全不同,自然图像分割有海量标注数据可用,医学影像因为标注成本和隐私问题,公开数据集小很多,很多内部项目甚至只有几十例到几百例标注,这直接决定了模型不能一味追求大参数量。其次类别不平衡问题在医学影像里更极端,一个器官可能占了整张CT的大部分体积,而一个早期病灶可能只有几十个像素;如果用朴素交叉熵训练,模型很容易学着把所有像素都预测成背景。

评价指标也反映了任务差异。通用语义分割最常用mIoU,医学分割除了Dice之外,很看重豪斯多夫距离这类衡量边界差异的指标,因为临床关注的不只是“重叠了多少”,还有“边缘偏差了多少”。我见过不少同学刚转过来时不适应,模型Dice涨了不少,医生一看图却觉得边缘飘得很夸张,就是因为没留意边界类指标。做这个方向的论文解读,如果只看网络结构不看任务定义的差异,读再多篇也很难内化成自己的方法论。

2. 通用语义分割论文的演进脉络:从FCN到Transformer

2.1 全卷积网络为什么被当成起点

读语义分割论文,最先绕不开的是FCN。现在看这个概念很朴素,就是把分类网络里的全连接层替换成卷积层,让网络输出空间尺寸的特征图,再通过上采样恢复到原图分辨率。但站在当时的角度,这个改动解决了一个非常关键的问题:分类网络在下采样过程中会把空间信息不断压缩,最后只剩一个向量,而你做分割需要的是“每个像素的预测”,必须保留空间对应关系。FCN的核心贡献说白了就是证明了“分类网络改一改也能做像素级预测”。

当然FCN的局限也很明显,直接上采样到原尺寸会损失很多精细结构,分割结果边界比较粗糙。后续大量工作其实都在围绕“如何恢复空间细节”“如何利用多尺度上下文”这两个问题做文章。我当时复现FCN的时候有一个很直观的感受:它启动成本低,结构简单,非常适合用来跑通一套完整的分割训练流程,但指望它直接达到实用精度是不现实的。它更适合作为“地基型论文”来读,能帮你理解后续几乎所有分割模型的出发点。

2.2 多尺度上下文和特征融合成了后续主线

FCN之后,语义分割论文有好几条演进路线,其中最清晰的一条是“多尺度上下文”。DeepLab系列里引入的空洞卷积,就是在不降低特征图分辨率的前提下扩大感受野,让每个像素能“看到”更大的区域;PSPNet提出的金字塔池化更是直白,把特征图切成不同尺寸的池化区域,再融合起来,让模型同时获取全局和局部信息。这个思路本质上是在应对一个大问题:语义分割里的同一个类别,在图像里的尺度可能差异很大,一个行人和一个路牌,都可能属于“人”或“交通标志”这个类别,网络需要同时处理大小差异极大的目标。

另一条路线是编码器-解码器结构。这里的编码器负责逐级提取语义特征,解码器负责把低分辨率特征逐步恢复成高分辨率预测图。UNet虽然最早出现在医学图像领域,但它的U型结构后来在通用分割里也影响很深,核心在于“跳跃连接”把编码器浅层的空间细节直接传给解码器,弥补了下采样丢失的信息。SegNet这类工作则侧重把下采样时的位置信息记录下来,在解码阶段复用。读这些论文时,我开始意识到它们之间不是完全互斥的,比如DeepLabV3+就把空洞卷积和编码器-解码器两种思想合在了一起,实际效果确实比单一方案更稳。

2.3 注意力机制和Transformer带来的变化

Transformer进入视觉领域之后,语义分割的格局又有一次比较大的变化。自注意力机制的优势在于可以建模任意两个位置之间的依赖关系,比卷积只能看局部区域要灵活得多,这让网络有机会捕捉到长距离上下文。不过纯粹用Transformer做密集预测,分辨率高的特征图会带来巨大的计算量,所以后续很多工作都在做“如何在保持效率的前提下引入全局建模能力”。

在这些工作里,有几类思路很值得一起读。一类是直接把Transformer当作编码器,替换原来的卷积骨干网络;另一类是把Transformer模块嵌入到U型架构的某个环节里,比如替换最底层的特征提取部分,再通过卷积解码器恢复细节;还有一类是设计轻量化的注意力模块,插到卷积网络中间层,用可控的额外开销换取精度提升。我个人的阅读体验是,Transformer类论文不能只看结构图,还要关注它的输入序列是怎么构建的,比如是切成一个个patch,还是用特征图展平,这直接决定了位置编码和计算量的设计方式。对初学者来说,不必追求读最新最复杂的变体,先把这类方法解决的“全局上下文建模”问题和带来的“显存开销”问题理解清楚,就抓住了本质。

3. 医学图像分割里更实用的论文思路

3.1 U型结构和跳跃连接为什么在医学场景特别能打

如果只让我给刚接触医学图像分割的人推荐一篇论文,我会毫不犹豫推荐UNet。它已经被验证太多次了:标注数据有限、目标结构相对固定、需要精细边界,这些医学影像的特点似乎正好和U型结构合拍。为什么跳跃连接在这里这么重要?因为CT或MRI中的器官边界很多时候依赖浅层特征里的高频信息,比如纹理变化、边缘梯度,而深层特征虽然语义丰富,却容易丢失这些细节。跳跃连接等于给解码器开了一条直达通道,让它能同时参考语义和细节,相当于做设计时既看了整体布局图,又看了局部照片,自然画得更准。

后续的UNet++和Attention UNet也值得对照着读。UNet++做了密集的跳跃连接,让不同层级的特征反复融合,好处是梯度的流转路径更短,小目标的信息不容易在中途被稀释;Attention UNet则在学习过程中自动抑制不相关区域的特征响应,相当于给解码器加了一个筛选机制,让模型把注意力放到目标区域上。这两种改进的角度不同,一个是改结构,一个是改特征选择策略,但都围绕一个核心目标:在有限数据下让模型更高效地利用已有信息。

3.2 损失函数设计在医学分割里的特殊地位

很多刚做医学分割的同学,会把大部分精力放在选网络上,却忽略了损失函数这个关键变量。医学影像里前景和背景的比例经常极度失衡,比如一个胰腺癌病灶可能只占几百个体素,而整个腹部CT有上百万个体素,直接用交叉熵训练,模型只要学会输出“背景”就能把损失压得很低。Dice损失就是把预测区域和真实区域的重叠程度作为优化目标,天生对前景区域更敏感,但它也有自己的毛病,梯度在极端情况下不太稳定,单独使用容易让训练震荡。

所以实操中更常见的做法是组合损失,把交叉熵和Dice损失按一定权重加在一起,或者再加一项边界损失来约束边缘。我自己常用的组合是“交叉熵+Dice+边界惩罚项”,前两项负责整体区域拟合,边界项负责让预测边界贴近真实边界。读论文时你会发现,很多医学分割文章其实不是靠网络多复杂取胜,而是在损失函数上做了非常细致的适配。这一点给我的启发是:读论文不能只看模型图,损失函数里写出的公式、权重设置,往往才是一个方法能否适应特定数据的关键。A同学复现某篇论文训练不稳定,后来发现就是损失权重没按原文设置,这说明细节对结果的影响远大于结构上的微小差异。

3.3 数据问题:增强、半监督和自监督为什么盛行

医学图像分割论文里,如果统计出现频率最高的词,数据增强一定名列前茅。原因很直接,医学标注依赖专业医生,成本极高,很多项目能拿到的标注数据只有几十例,常规的随机旋转、缩放、平移只能提供有限的多样性。针对医学影像的特点,弹性形变是一种非常有效的增强方式,它能模拟组织器官在不同个体间的形变差异,帮助模型学习到更鲁棒的解剖结构变化。

当标注数据特别少的时候,半监督和自监督的思路就显得格外重要。半监督方法通常利用大量无标注数据来辅助训练,常见手段包括一致性正则化——让模型对同一个输入在不同扰动下给出相近的预测,相当于强迫模型从无标注数据里也学到稳定特征;伪标签也很常见,先用少量标注数据训练一个粗糙模型,再去给无标注数据生成伪标签,逐步迭代。自监督则是用无标注数据设计一个代理任务来预训练编码器,比如预测图像的旋转角度、恢复被遮挡的区域,然后在少量标注数据上微调。有一篇实验给我的印象很深,在只有十几例标注的肺结节数据上,用一个自监督预训练模型微调,比随机初始化的模型Dice高了近8个百分点,这在医学场景里是相当大的提升。

4. 论文复现与落地选型的实操经验

4.1 快速复现一个分割模型的基本流程

无论是精读论文还是做对比实验,复现都是绕不开的一环。我的习惯是先用一套固定的流水线把框架跑通,再针对论文的核心模块做替换,这样能快速定位到创新点的实际贡献。具体流程一般是这样:第一步准备数据和标签,医学图像通常需要做窗宽窗位调整、重采样到统一体素间距、归一化;第二步把数据切成合适的patch,既要照顾显存限制,又要保证patch里有足够的上下文信息;第三步搭模型,从骨干网络到分割头完整定义清楚;第四步选优化器和学习率策略,我一般先用Adam配合多项式衰减跑一版基线,再考虑换SGD做精细调优;第五步定义损失函数和评估指标;第六步进入训练循环,同时定期保存模型和可视化预测结果。

这个流程里,数据预处理的细节经常决定最终结果的上限。CT影像的HU值范围很宽,如果不做窗宽窗位调整,模型学习到的对比度信息可能不是医生实际关注的窗口。我之前有个实验,只改了预处理阶段的窗宽,Dice直接掉了3个多点。所以读医学图像分割论文时,最应该先确认的是它对数据做了哪些预处理,这比模型结构的影响更靠前,也更隐蔽。

4.2 评估指标怎么选,避开常见的指标坑

论文合集中涉及的指标,主要就集中在mIoU、Dice、HD95这几个上。mIoU是通用语义分割里的标配,代表预测集合与真实集合的交集占并集的比例,直观且易于理解;Dice系数则是医学分割里最常见的指标,计算的是两倍交集除以两个集合的元素数之和,可以看成一种更关注重叠程度的度量。有意思的是,对于二分类问题,Dice和mIoU之间存在单调变换关系,Dice高了mIoU一般也会高,但两个指标对误差的“感知”不完全一样。

真正容易踩坑的是豪斯多夫距离。它衡量的是两个边界之间的最大不匹配程度,对边界离群点极其敏感,有时候一个像素的离群噪声就会让HD95从2mm跳变到8mm,看起来模型好像“崩了”,实际上整体分割质量还行。反过来,一个模型的Dice很高但HD95很差,恰恰说明它的边界可能在某些局部区域偏离非常严重,这在临床场景里是不能接受的。我的建议是,医学项目不要只看单一指标,至少要同时看区域类指标和距离类指标,然后结合科室的临床需求来判断哪个指标更优先。曾经有个项目,A同学用Dice选出来的模型在上线测试时被医生否了,换成边界质量更好的模型虽然Dice略低,但医生接受度明显提升,这个教训我一直记得。

4.3 模型选型的实用建议

面对论文合集里的一大堆模型,最忌讳的是每个都想试一遍,最后时间全花在换模型上。更务实的策略是先定基线,再用增量思路加复杂度。数据量很小、刚起步时,最优先的应该是UNet及其轻量变体,它们结构简单、训练稳定、显存友好,而且大量开源实现可以借鉴;如果发现边界模糊,可以考虑加上注意力机制的变体,比如Attention UNet;如果发现大目标整体结构把握不好,再考虑Transformer类模型,它擅长捕捉全局关系,代价是显存占用更高,需要更大的显卡或更小的patch尺寸来配合。

我强烈建议在做复杂模型之前,先花一周时间把数据、增强、损失这几个因素调到位,因为很多情况下一个带深监督的UNet已经能达到不错的效果,复杂模型带来的提升远没有那么大。论文里展示的mIoU提升通常是在特定数据集、特定训练策略下取得的,换到你的数据上不一定能复现。换句话说,读论文时要把“这模型好强”和“适不适合我的问题”分开判断。

5. 训练过程中的常见问题与排查技巧实录

5.1 损失不收敛或者训练震荡怎么办

训练分割模型时最常遇到的第一个问题,是损失下不去或者上下乱跳。先别急着换模型,按下面的顺序排查:第一步看数据预处理和标签是否对齐,比如医学图像和标签有没有因为旋转、resize操作出现空间错位,这个问题最简单但影响最致命;第二步看学习率,医学分割常用batch size不大,过高的学习率很容易导致震荡,我一般建议初始学习率从1e-4开始,如果震荡明显再降到3e-5;第三步看损失权重,尤其是组合损失里各项的量纲差异,Dice损失的数值范围是0到1,而交叉熵可能是几十甚至上百,如果不做平衡,训练容易被单项主导。

还有一个容易被忽略的是类别分布问题。如果一个batch里几乎没有前景样本,模型很容易在这一步产生很大的梯度波动。方案包括用带权重的采样器,确保每个batch都有正样本,或者在损失计算时做类别频率加权。我之前在一次肝脏肿瘤分割实验里,损失曲线每隔几个epoch就突然跳高一次,后来定位到是某些切片里肿瘤像素极少,模型偶发误判导致Dice骤降,用难例采样就平稳多了。

5.2 小目标预测不完整、边缘粗糙怎么办

医学图像分割里小目标漏检或者边缘不精细,是仅次于不收敛的高频问题。漏检小目标的核心原因是特征在下采样过程中被层层压缩后,小目标的信息已经很难在深层特征中保留,所以解决思路也围绕这点展开。最简单有效的手段是调大输入patch的分辨率,让目标在模型输入里占更多像素;还可以在网络里加深监督,让浅层、中层、深层的输出都参与损失计算,相当于给浅层特征额外加力。数据增强里对目标区域做随机裁剪放大,也能让模型见识到更多“大”目标样本。

边缘粗糙的问题则更多需要从损失函数和后处理两个角度去解决。损失函数层面,可以引入边界损失或者给轮廓附近的像素更高权重;后处理层面,可以用连通域分析过滤掉小噪点,用形态学闭运算填补细小空洞,或者用CRF这类条件随机场做精细的边界修正。要注意后处理别过度,医学影像里有些细微结构本身就很细小,后处理参数设置不好反而可能把真实边界抹掉。调后处理参数时,我习惯在验证集上多看几组可视化结果再做决定,而不是只看指标。

5.3 模型泛化能力差的检查清单

换到新数据源上性能明显下降,是所有落地项目都会遇到的一道坎。泛化差的原因通常不是单一的,我一般按这几项逐个排查:第一个检查预处理是否有偏差,不同设备的CT扫描参数差异会导致像素分布不同,如果有跨设备数据,最好做直方图匹配或归一化策略对齐;第二个检查数据增强是否过于单一,只有微弱平移旋转变换的模型,对新场景的抗变化能力往往不够;第三个检查模型容量是否相对于数据量过大,小数据上跑大模型很容易记住训练集细节,适当地加Dropout、加正则、减小骨干网络规模反而能提升泛化。

还有一个容易被忽略的点是交叉验证。医学数据量小,随机划分一次就得出结论非常危险,也许只是某几个难例恰好落在了训练集里。用K折交叉验证就能更准确地评估模型稳定性,我在实际项目里发现,有些模型从单次划分看Dice很高,但换一折就明显下降,这通常是数据分布不均或者模型过拟合的信号。

6. 最后分享一点我的论文阅读体会

读论文合集和读单篇论文的心态完全不一样,合集要求你带着“比较”的眼光去读,而不是每篇都从头到尾抠公式。我自己的习惯是先从题目和摘要判断这篇论文解决的问题是否和当前项目相关,再看图片和表格形成直观认识,最后才深入方法细节。通常同一主题下的几篇工作会形成一条清晰的演进链:先有人提出问题,然后有人改进结构,再有人引入范式,读的时候沿着这条链走,比按时间顺序零散地读更容易形成体系。

还有一个小技巧是,每读完一组论文,我会用一两段话写一个“问题-方法-代价”的笔记:这篇论文解决了什么问题,用了什么核心手段,为此付出了什么代价(比如显存增加、训练时间变长、数据需求变大)。这个习惯帮我避免了一个常见误区——只记住模型名字和涨点数字,却说不清它适用的边界。做医学图像分割这几年,我最深的体会是这个领域从来不缺新模型,缺的是能准确判断“哪个方法适配什么问题”的工程判断力。希望这份论文合集式的梳理,能帮你少走一些弯路。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进