ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

分割方向论文精读:从语义分割到复现踩坑实战指南

分割方向论文精读:从语义分割到复现踩坑实战指南 做分割方向的同学应该都有体会这两年论文的产出速度已经到了看都看不完的程度。语义分割刚消停一点实例分割、全景分割、医学影像分割、遥感影像分割、点云分割又一轮接一轮地刷榜。我长期做视觉相关的研究和工程落地每周都要精读一两篇分割方向的论文这几年攒下来的笔记比读研时候的教材还厚。这篇内容就围绕“分割方向论文精读”这件事说说我是怎么拆解一篇论文、怎么把论文里的东西吃到自己代码里、又踩过哪些坑。适合刚入门的研究生、准备复现论文做实验的工程师以及需要快速跟踪前沿但没时间逐字啃的人。方法不一定适用于所有人但至少能让你少走一些弯路。1. 精读之前先把“分割”这张地图看清楚1.1 “分割”这个词到底覆盖了多少个子方向先别急着打开PDF。我在带新人的时候发现一个普遍问题大家拿到一篇标题带“Segmentation”的论文就开始读读了一半才发现这个方向和自己的课题根本不是一回事。原因很简单“分割”这个词在技术领域里覆盖面太广了。计算机视觉里的语义分割、实例分割、全景分割这是最常见的主线医学图像里还有息肉分割、肿瘤分割、器官分割一个息肉分割数据集就能养活一整条研究线遥感领域有建筑物分割、地块分割、道路提取渔网分割shp这种GIS里的网格划分也算一类点云方向有地面分割、聚类分割DBSCAN这种经典算法现在依然在用再往远了说字符串分割、DataX字段分隔符、二层交换机划分局域网这些也都带着“分割”两个字。我提这些不是为了凑热点而是想说明一个道理精读论文之前先明确你关注的“分割”到底是哪个层次的分割。CV里的分割解决的是像素级别的分类问题输出是一张和输入等大的mask图而字符串分割解决的是数据解析问题输出是若干子串二层交换机的网段分割解决的是广播域隔离问题输出是网络拓扑。这三者的数学工具、评估方式、落地方案完全不同混在一起读只会越来越乱。所以这篇文章里提到的“分割方向”我默认框定在计算机视觉这条线上——语义分割、实例分割、全景分割顺便扩展到医学影像、遥感、点云这三个高频落地场景。其他领域的分割可以在方法论层面做类比借鉴但不作为精读主角。1.2 语义分割、实例分割、全景分割的任务边界很多入门读者分不清语义分割和实例分割的区别更别提全景分割了。这里我用一个生活化的场景说清楚。想象你在看一张街景照片。语义分割要做的事情是给每个像素贴一个类别标签这上百万个像素里哪些是道路、哪些是行人、哪些是建筑、哪些是天空。它不关心这堆“行人”像素里到底有几个人只要是行人就统一标成一个类别。实例分割则往前多走了一步它不仅要区分“行人”和“道路”还要把不同的行人分开给第1个人、第2个人、第3个人分别标不同的颜色也就是“同一类别的不同个体”也要区分开。全景分割是这俩的融合版它把背景类和物体类放在同一个框架里处理背景区域用语义分割的思路前景物体用实例分割的思路最后输出一张统一的、每个像素都有明确归属的分割图。这个区别直接影响论文阅读方式。语义分割论文的核心通常在网络结构和特征融合上loss一般就是交叉熵或者它的变体实例分割论文的核心通常在检测和分割的结合机制上比如YOLO系列的实例分割就是在一阶段检测框架上加了mask分支你读的时候要重点关注它怎么解决“多个物体重叠时怎么分配像素”这个问题全景分割论文则要额外关注它怎么协调背景类分支和物体类分支怎么处理类别之间的互斥关系。1.3 分割论文按什么维度归类五条主线我自己的习惯是把读到的一篇论文先塞进一个分类框架里塞不进去的才需要额外花时间。分割方向的论文大体逃不出这五条主线。第一条是网络结构创新典型代表是U-Net、DeepLab系列、SegFormer、Mask2Former这类论文的核心贡献是提出了一种新的编码器-解码器结构、注意力机制或者Transformer结构解决的问题是“怎么让网络更好地利用多尺度信息和全局上下文”。第二条是损失函数与训练策略代表是Dice Loss、Focal Loss、Boundary Loss、OHEM这类工作它们不改网络结构改的是优化目标专门对付类别不平衡、小目标、边缘不清晰这些老大难问题。第三条是数据集与评测代表是Cityscapes、ADE20K、息肉分割数据集、遥感影像分割数据集等这类论文会发布新的数据集并提出对应的评测协议属于“定标准”的工作分量很重但容易被新手忽略。读这类论文时你要重点研究的是它的标注规范、类别定义和评估指标而不是网络结构。第四条是特定场景的解决方案比如遥感影像语义分割复现类的工作、点云地面分割、水下图像分割、医学内镜息肉分割它们会把通用的分割算法针对某个场景做出适配核心看点在于场景约束和工程技巧。这个类别在工业落地里最常见很多工作网络结构并不新颖但解决了一个实际业务问题价值同样很高。第五条是效率与落地比如轻量化分割网络、知识蒸馏、剪枝、实时分割这类论文不追求刷最高的指标追求的是“在算力受限的情况下把分割做得又快又好”。如果你要上移动端或者做实时系统这类论文要重点精读。有了这个框架你拿到一篇论文就可以先问自己它属于哪条主线它改进的是哪个环节如果答得上来这篇论文阅读的性价比就已经很高了。2. 精读一篇论文我建议按这五个维度拆2.1 任务定义与问题设定先搞清楚它到底改了什么很多人精读论文是从摘要开始逐字读的读完了还是说不出这篇论文到底贡献了什么。我的习惯是先看Motivation也就是作者为什么要做这件事。具体操作是三步。第一步找到论文Introduction里“previous methods have... limitations”这类表述把作者指出的现有方法痛点记下来第二步找到“we propose... to address...”这类表述把作者声称的解决方案记下来第三步把前两步对照起来看解决方案是否真的有对应痛点这是判断一篇论文含金量最直接的方法。举个例子有一类分割论文的痛点是“小目标分割效果差”作者的方案通常会是“引入注意力机制聚焦小目标区域”或者“利用多尺度特征保留细节”。这里就要追问了它说的注意力机制是怎么算的是在通道维度算还是在空间维度算多尺度特征是金字塔式逐层融合还是空洞卷积式并行提取这些问题才是精读的抓手。如果一篇论文的解决方案和它提出的痛点对不上那这篇论文基本可以降级为泛读。另外一个常被忽略的动作是去看论文的“假设边界”。所有方法都有适用条件医学分割的方法未必适合遥感影像室内点云的分割方法未必适合道路场景。读论文时要留意作者有没有明确说明它的方法在什么情况下会失效这类信息往往藏在实验部分的failure case分析里很值得精读。2.2 网络结构编码器-解码器这条主线怎么变分割网络的主干到现在依然是编码器-解码器但结构细节已经走了好几代。最早是FCN把全连接层换成卷积层解决“输入任意尺寸输出分割图”的问题然后是U-Net引入跳跃连接把编码器的浅层细节传给解码器医学分割至今还在用再往后是DeepLab系列用空洞卷积扩大感受野用ASPP在不同空洞率下并行提取多尺度特征Transformer火起来之后SegFormer、Mask2Former这些结构把全局自注意力搬到了分割任务里。精读网络结构时我建议画一张自己的结构图不要直接抄论文里的图。画图的过程会逼你把每个模块的连接方式搞清楚比如分辨率在哪个阶段降的、通道数在哪个阶段变的、跳跃连接具体连接的是哪两层、decoder输出的logits怎么上采样到原始分辨率。画完之后你再去读代码就会快很多因为你对结构已经有预判了。这里有个实操心得代码里的张量形状变化是最好的结构说明书。我会在每个关键模块后面打印输入输出的shape对照论文里的结构图逐层验证。很多时候论文画图和代码实现并不完全一致比如论文里为了美观省略了BN层的细节代码里却有。这种细微出入才是精读最值钱的部分。2.3 损失函数与优化交叉熵之外的进阶选择分割任务最常见的损失就是像素级交叉熵但凡是实际跑过分割训练的人都会发现直接用交叉熵在很多场景下不够用。类别不平衡的时候占大头的背景类别会主导梯度前景小目标学不进去边界区域像素容易出现归属模糊交叉熵对这类像素的惩罚不够尖锐。Dice Loss是一个很好的补充它直接优化分割区域和真实区域的重叠度对小目标和类别不平衡比较友好医学分割尤其是息肉这类小目标特别常用。Focal Loss则是从难易样本角度出发降低易分类样本的权重让模型更关注难分类的像素。还有Boundary Loss专门针对边界区域设计适合边缘质量要求高的场景。精读这类论文时要算清楚损失函数每一项的权重是怎么配的。比如一个多任务分割网络总损失是L L_seg λ1 * L_edge λ2 * L_smooth你要能理解为什么λ1取0.5、λ2取0.1这些权重背后的经验规律是什么最好从优化方向的角度理解如果λ太大辅助任务会主导梯度方向主分割任务反而学不好。我一般会做个小实验固定其他设置只把λ1从0.1调到0.5观察指标变化这样就能直观感受这个损失项对结果的影响有多大。2.4 评估指标mIoU、Dice、PQ、Boundary IoU评估指标是精读论文时最容易被忽略但最值得较真的部分。语义分割主流指标是mIoU计算方法是每个类别计算预测和真实区域的交并比然后对所有类别取平均。这里有个关键细节mIoU对类别均衡比较敏感如果一个类别占了90%的像素它的IoU会把整体均值拉得很高所以读论文时要特别留意作者有没有报告每个类别的IoU而不是只看一个均值。医学分割常用Dice系数它和IoU是单调相关的但对小目标更敏感。息肉分割这类场景目标在图像里可能只占几个百分点Dice分数掉一两个点都说明问题很大。全景分割用PQPanoptic Quality它把识别质量和分割质量合在一起算是一个综合性的评估指标。边界质量要求高的场景还会看Boundary IoU它只计算物体边界附近的区域能反映出分割边界的精细程度。读论文时有一个习惯值得培养把论文的指标表拆开来看看它到底在什么协议下测的。同样的模型用不同的评估脚本、不同的后处理、不同的多尺度测试指标能差出两三个点。复现对不上的时候先检查协议再怀疑模型这是我踩过很多次坑之后得出的结论。2.5 数据与场景息肉、遥感、点云、渔网shp各自的特殊性分割论文和数据集绑定得非常紧同一个网络在不同数据上的表现天差地别。我举几个典型场景说说。息肉分割数据集比如CVC-ClinicDB、Kvasir-SEG、ETIS的特点是目标小、边界模糊、对比度低而且不同数据集的分布差异大泛化性很难提升。读这类论文要关注它怎么处理目标尺度过小的问题很多方法会用到多重特征融合或者注意力机制。有个常见的坑是息肉分割的公开数据集总量很小很多论文会拿多个数据集做交叉验证复现时要特别注意它的数据划分方式划分不对结果完全没法对比。遥感影像语义分割有自己的特殊性图像尺寸巨大动辄上万乘上万的像素、地物尺度差异悬殊一栋楼和一条路的大小差几个量级、标注稀疏且类别不均衡。复现这类论文时裁剪策略滑窗大小、重叠率和标签处理往往比网络结构更影响最终精度。遥感里还有渔网分割shp这种偏GIS的需求本质上是把栅格分割结果矢量化转换成shp文件这里面涉及的坐标配准和后处理环节论文里通常不会细讲但工程上特别耗时间建议做之前就预留足够的排错时间。点云分割的经典方法是DBSCAN这种基于密度的聚类虽然现在深度学习点云分割也很多但DBSCAN因为无监督、无参数训练、可解释性强在工业场景里仍然是常青树。读这类内容要理解的是调参逻辑邻域半径eps和最小样本数min_samples怎么定这两个参数直接决定分割粒度。eps太大容易把不同物体连成一片太小会把一个物体切成碎片实际使用时要结合点云密度做试验。还有一个跨界的现象值得多说一句不同领域的“分割”经常互相启发。比如医学分割里常用的Dice Loss现在也被用到遥感分割里点云里的区域生长思想和图像分割里的超像素方法就很像。精读时保持这种横向对比收益会远超一篇论文本身。3. 从论文到复现一次完整的精读实操3.1 选样本怎么挑一篇值得精读的分割论文不是所有论文都值得精读这一点要先想清楚。我选精读对象的标准有三条第一引用量高或者在顶会拿到过强结果说明这个工作经过了同行验证第二代码开源因为精读的最后一步是复现没有代码只能纸上谈兵第三和你的场景直接相关比如你做医学影像那息肉分割的工作就比Cityscapes上的工作优先级高。这里说一个我常用的方法先看论文的Related Work把里面反复被引用、反复被对比的那些工作挑出来。这些通常是某个子方向的“锚点论文”比如语义分割里的FCN、DeepLabV3实例分割里的Mask R-CNN、YOLO系列分割版本。把这些锚点论文精读一遍整个子方向的地图就自然搭起来了。选好论文之后我建议先快速浏览三个地方再做精读摘要、结论、可视化结果图。摘要告诉你论文做了什么结论告诉你效果如何可视化结果图告诉你方法在直观上好不好用。如果这三样看完你觉得还有深入的价值再进入逐段精读环节。这个前置筛选能帮你省下大量时间避免读了半天发现论文质量很差。3.2 环境与依赖训练框架和基础模型选型精读和复现是绑在一起的。我的复现环境一般是这样准备的PyTorch作为主框架配合MMSegmentation这类分割工具箱做基线对比再自己写自定义模块插入进去。为什么推荐这么做因为MMSegmentation的评估脚本经过大量验证mIoU的计算方式和论文社区基本对齐比自己从头写评估脚本靠谱得多。自己做论文实验时省去评估脚本的维护成本能省出很多精力。如果是为了理解原理我建议从小数据集开始复现别一上来就啃完整数据集。比如语义分割可以先在PASCAL VOC上用ResNet18这种轻量backbone跑通全流程医学分割先拿小的息肉数据集跑一个U-Net基准。小数据集迭代快几分钟就能看到结果调试效率高很多。等小数据集上跑通了再切到完整数据集这时候再遇到问题基本都是数据层面的排查起来更有方向。依赖管理上有个实用技巧用Docker或者conda锁住环境把PyTorch版本、CUDA版本、各依赖包版本都固定下来。分割领域的复现问题有一大半是环境问题版本不匹配导致的错误提示往往能把人带偏到模型逻辑上去。我遇到过因为PyTorch小版本升级导致某个算子的精度变化最终mIoU差了一个多点这种问题如果没有锁定环境你排查几天可能都找不到原因。3.3 核心模块拆解把关键代码读透拿到开源代码后我一般按这个顺序去读数据处理dataset和dataloader→ 模型结构model和backbone→ 损失函数loss→ 训练循环train和validate→ 推理后处理inference和postprocess。数据处理是第一个要仔细看的。比如遥感影像语义分割原始影像可能是1万×1万的tif你需要在dataloader里做滑窗裁剪这时候要看它裁剪尺寸多大、重叠率多少、有没有做数据增强、增强的随机种子怎么设的。这些细节直接影响训练效果而且论文正文通常只写一句“we use random crop and flip”具体参数全在代码里。模型结构部分我会把论文里的结构图和代码逐层对照。这里有个心得遇到不确定的模块直接打印中间张量的shape和值比反复看代码更高效。比如一个注意力模块输入[B, C, H, W]出来还是[B, C, H, W]但里面的加权过程、softmax在哪个维度算只有打印出来或者手动算一遍才能彻底搞懂。有时候计算图很绕打印一次就能看出它到底在做什么效率比读十遍代码高得多。损失函数部分要区分开它是在哪个粒度上计算的。有些论文的loss是在decoder的多个输出上分别计算再求和有些只计算最后一层的输出有的用了辅助监督就需要设置辅助loss的权重。这些细节决定了一个模型能不能训练起来我见过很多次复现失败都是因为辅助loss的权重被错误地设成了0相当于辅助监督根本没参与训练。3.4 训练与评测跑通和看指标的过程复现的最终目标是让指标和论文对齐。我的做法是分三步。第一步先把代码跑通不管指标多少先确保整个流程能从数据加载到模型输出再到评估不报错。这一步通常最难因为环境问题、显存问题、数据路径问题都会冒出来。跑通之后保存一份checkpoint作为后续所有实验的基线。第二步检查单步训练是否符合预期。具体做法是打印第一个batch的输入shape、输出shape、loss初始值用一个小脚本手动计算一下loss是否在合理范围。比如语义分割第一轮训练loss在2左右类别数是20左右时如果loss直接是0或者nan说明前向传播或loss计算有问题。这时候不要继续训练先修bug。第三步用小规模数据集做限制epoch的训练比如只训练20个epoch观察loss下降曲线和验证集指标变化。如果曲线符合预期快速下降后趋于平缓再用完整配置训练。这样做的好处是能快速发现训练配置错误不用浪费时间等完整训练。很多训练配置的错误在训练早期就能暴露小规模试验是最快的验证方式。训练完成后的评测环节也有讲究。要看清楚评测时的预处理和后处理比如评价语义分割时模型输出的logits要经过argmax但argmax之前要不要经过softmax多尺度测试时不同尺度的结果怎么融合翻转增强在测试时开不开每个变量都可能带来指标波动。所以我会单独保存一个评测脚本把预处理和后处理流程固定下来所有模型用同一套评测协议对比这样出来的指标才可信。4. 常见问题与排查实录4.1 复现指标对不上论文时的排查顺序这是复现过程中最让人崩溃的环节我经历过很多次。现在的排查顺序已经固定了分享给大家。第一步筛查数据处理。先检查训练集和验证集的划分方式是不是和论文一致是不是同一个划分版本再检查数据增强的参数比如随机裁剪的尺寸、翻转概率、归一化的mean和std。数据没对齐后面全是白做。第二步筛查模型结构。把代码里的模型定义和论文结构图逐层对照重点检查下采样次数、通道数、激活函数位置、norm层的引入顺序。有时候论文里一句“with BN”在代码里就成了“BN在ReLU之后”和“BN在ReLU之前”的差别这种细节会导致几个点的指标差异。第三步筛查训练配置。batch size、学习率、优化器、权重衰减、训练epoch数、学习率调度策略每一项都要和论文对齐。特别注意batch size变化时要按比例调整学习率这是大家最容易忽视的。比如论文用的是batch size 16你机器只够跑8学习率最好也跟着降一半左右否则训练可能不稳定。第四步筛查评估协议。多尺度测试有没有开、翻转测试有没有开、评估时的图像尺寸是不是和训练时一样、mIoU计算时包不包括背景类。这四项任何一个不一样指标就能差出2到3个点。如果以上四步都对齐了指标还是对不上那就要花点时间看代码里有没有论文没提的“隐藏技巧”比如特殊的初始化、EMA、蒸馏辅助、额外的数据增强。这些在开源代码里很常见作者为了刷指标不会写进论文但对复现者来说都属于必须掌握的关键信息。4.2 Loss不下降、训练震荡的调试思路训练分割模型遇到loss不下降或者震荡先别急着调网络结构九成问题出在超参数和数据处理上。我的排查顺序是这样的先看学习率是不是太大分割模型的初始学习率一般在1e-4到1e-2之间Transformer类backbone通常要比CNN类backbone用更小的学习率。我见过很多次loss震荡都是因为学习率设成了CNN的默认值直接套在Transformer上改成小一个量级之后立刻稳定下来。再看loss是不是变成nan如果loss出现nan优先检查归一化层和损失函数里有没有log(0)或者除0的操作。Dice Loss在预测结果全为0的时候会算出0/0所以实现时一般会在分子分母加一个平滑项epsilonepsilon太小就容易触发数值不稳定。类似的还有softmax里exp溢出特征值过大的时候softmax里面的指数可能直接返回inf这种情况通常需要调整初始化或者加梯度裁剪。数据层面也要检查标签有没有空洞值类别编号是不是从0开始连续编码归一化后的输入值范围是否合理我遇到过标签文件里混了255作为ignore index结果loss一直在高位波动排查了半天才发现是标签问题。还有一些数据集在标注时把边缘区域标成特殊的过渡类别这种标注风格会导致网络在边界上始终学不好需要专门的边界处理策略。如果模型结构本身是Transformer分支还要检查位置编码的实现是否正确位置编码的维度是否和输入特征的维度匹配。这个错在代码里很隐蔽表现为loss能降但指标上不去因为模型把位置信息学错了看起来在收敛实际上并没有学到有效的空间结构。4.3 小目标与边缘分割的经典痛点分割任务里小目标和边缘区域是两个永恒难点。读论文和复现论文时都会遇到。小目标分割效果差的根本原因是下采样过程中小目标的信息被逐层稀释到最后几个stage可能只剩一两个像素。经典解决方案有几种一是利用ASPP这类多尺度模块在不降低分辨率的情况下扩大感受野二是引入跳跃连接把编码器浅层的细节直接传给解码器三是用注意力机制让网络聚焦小目标区域。复现时如果发现小目标效果差可以先检查backbone的下采样倍数如果下采样倍数太高比如32倍小目标基本没救了可以考虑用下采样更低的backbone或者加大输入分辨率。很多医学分割网络放弃ImageNet预训练而直接在原分辨率上训练原因就在于此。边界分割模糊的问题常见的诱因是标签本身边界标注粗糙也可能是Focal Loss或者交叉熵对边界像素的关注不足。解决方案包括用Boundary Loss加权边界像素或者在解码器后接一个边缘提取头。实操中还有个简单有效的办法条件随机场CRF后处理虽然现在深度方法很少用了但在某些边缘模糊的老数据集上依然能带来零点几到一两个点的提升。在新数据集上用不用CRF建议先做个消融实验有效就用无效就舍弃不要盲目跟风。4.4 数据集与标注的坑从息肉数据到遥感影像到了实际数据集环节各种坑更多。我专门挑两个高频场景展开一下。息肉分割数据集这一类医学分割任务最大的坑是数据规模小、标注方差大。CVC-ClinicDB才六百多张图Kvasir-SEG也才一千张在这种规模下训练预训练权重的选择比网络结构更影响最终结果。我的经验是优先用ImageNet预训练的backbone再配合强数据增强。另外医学分割的ground truth标注是医生在特定内镜视野下勾画的不同医生勾画同一张图可能差好几个像素所以复现时对指标的微小波动别太纠结更多要关注的是方法本身的稳定性。还有一个容易忽略的问题有些息肉数据集是多中心采集的图像的光照、内镜型号、清晰度差异大直接混合训练可能比单独训练效果还差需要先做风格归一化。遥感影像语义分割的坑主要在于标签处理和计算资源的组织。遥感影像的标签通常是单通道tif类别值直接从0开始编但有些数据集把背景算成255或者其他值读取时要统一映射。训练时由于影像巨大必须用滑窗方式切patch滑窗重叠率、patch尺寸、基准坐标是否对齐这些都对验证指标的稳定性影响很大。评测时尤其要注意切割出来的patch预测完之后要拼接回原图拼接处的重叠区域如何处理取平均还是取最大值也会影响最终成图的效果。如果我不小心把重叠区域处理写错整个拼接图会留下明显的网格痕迹指标看着还行但成图完全没法用。5. 精读多了之后的一点体会最后分享一点我个人的经验不算是结论只能算是这几年读分割论文攒下来的习惯。我现在的习惯是每精读一篇论文必做三件事写一页纸的结构笔记把论文的主线、结构图、关键超参数、评估协议都浓缩进去把论文的代码跑通并记录环境配置和复现结果把论文的核心思想和自己的项目场景做一个对照写下“如果我要用改哪里、哪里可能踩坑”。这三件事做完一篇论文才算真正吃透。有人会觉得精读论文很慢一个月读不了几篇。但我的体会是精读的价值不在数量在于建立连接。当你精读过FCN、U-Net、DeepLab、Mask R-CNN、SegFormer、Mask2Former这些锚点论文之后再看新的分割论文你会发现大部分工作都是在这些主线上做局部改进。那时候你读一篇新论文的时间会从一天缩短到一小时因为你知道该看哪里、不该看哪里、哪里是真正的创新、哪里只是换了个数据集的包装。分割方向还会继续往前演进新的结构、新的loss、新的评测方法会不断出来但精读的方法论是不变的搞清任务边界拆解结构细节理解loss和指标对齐数据协议最后亲手复现一遍。踩过的坑越多你对这个方向的理解就越扎实。希望这篇内容能帮你在读分割论文的时候少走一些弯路。
返回列表