尧图精选

医学图像分割实战:从CNN到Transformer的架构演进与调优指南

🕒 发布时间:2026/10/1 7:04:36 📁 来源:尧图网络
1. 医学图像分割的技术演进与核心挑战医学图像分割这个方向我从几年前做肝脏肿瘤勾画开始接触到后来做视网膜血管提取、细胞核分割一路踩坑过来。早期用纯 CNN 方案后来逐步过渡到 Transformer 架构中间还试过 CNN 和 Transformer 混合的路线。这个领域最核心的问题其实一直没变在标注数据极其稀缺的情况下如何让模型稳定地学到器官边界和病灶区域的精确轮廓。医学图像和自然图像有本质区别。自然图像里一只猫就是一只猫轮廓清晰、纹理丰富、光照充足。但医学图像尤其是 CT 和 MRI不同软组织之间的灰度差异可能只有十几个 HU 值边界模糊到肉眼都难以分辨。更麻烦的是同一个器官在不同患者身上的形态差异巨大肝脏可能差出两倍体积肿瘤的形状更是千奇百怪。这就导致一个很现实的问题模型必须同时具备局部细节捕捉能力和全局语义理解能力缺一不可。CNN 天然擅长前者。卷积核在局部感受野上滑动能精确提取边缘、纹理、角点这些低级特征再通过层层堆叠逐步抽象出高级语义。但 CNN 有个致命短板——感受野受限。一个 3x3 卷积核堆叠十层理论感受野也就 20 多像素对于一张 512x512 的 CT 切片来说模型很难在早期层就建立起器官之间的空间关系。这就导致 CNN 在分割大器官时容易出现“局部正确、全局矛盾”的情况比如把左肾和右肾的边界搞混或者把肿瘤区域和周围正常组织混淆。Transformer 的出现改变了这个局面。自注意力机制让每个像素都能直接和图像中任意其他像素建立关联全局感受野从第一层就建立起来了。但 Transformer 也有自己的问题计算复杂度是序列长度的平方级一张 512x512 的图像展平成序列后长度是 262144直接算自注意力显存根本扛不住。而且医学图像标注数据通常只有几百到几千例Transformer 这种参数量巨大的架构很容易过拟合。所以从 CNN 到 Transformer 的演进本质上是在局部精度和全局语义之间寻找平衡点。我个人的经验是纯 CNN 方案在数据量充足、目标形态规整的场景下依然能打比如肺部分割、心脏分割这些任务U-Net 系列至今仍是很多医院的基线方案。但一旦遇到多器官分割、病灶边界模糊、小目标检测这些场景Transformer 的优势就体现出来了。下面我按实际项目经验把这条技术路线拆开来讲。1.1 CNN 在医学分割中的经典范式与局限先说 CNN 这条线。医学图像分割领域最经典的架构毫无疑问是 U-Net2015 年提出到现在快十年了依然是很多论文的 baseline。它的结构很简单编码器逐步下采样提取语义特征解码器逐步上采样恢复空间分辨率中间用跳跃连接把编码器的浅层特征直接拼到解码器对应层。这个设计在医学图像上特别有效因为医学分割既需要深层语义判断“这是什么器官”又需要浅层细节确定“边界在哪里”。我早期做肝脏分割时用的就是 2D U-Net输入 512x512 的 CT 切片编码器用 VGG16 的前几层做初始化解码器用转置卷积上采样。训练数据是 200 例腹部 CT每例取 50 张切片总共 10000 张。在验证集上 Dice 能到 0.92 左右看起来不错。但实际部署时发现一个问题肝脏和胃壁、肝脏和右肾的边界经常出错。原因是这些器官在灰度上太接近CNN 的局部感受野无法区分它们之间的细微差异。后来我试了 DeepLab 系列用空洞卷积扩大感受野。空洞卷积的好处是不增加参数量的情况下扩大感受野比如 rate2 的 3x3 卷积感受野等效于 5x5。但空洞卷积有个理论问题它会导致特征图出现网格效应相邻像素之间的信息不连续。在医学图像上这种不连续性会放大边界模糊的问题。我试过在 DeepLabv3 上加后处理 CRF效果有提升但推理速度太慢一张 512x512 的图要跑 2 秒临床根本没法用。还有一条路是 nnU-Net这个框架在 2020 年前后几乎统治了医学分割挑战赛。它的核心思想不是设计新架构而是把预处理、训练策略、后处理全部自动化。比如自动计算归一化参数、自动选择 patch size、自动做数据增强。我实测下来nnU-Net 在大多数任务上确实比手工调参的 U-Net 高 2-3 个 Dice 点。但它的局限性也很明显对 3D 数据的显存占用极大我试过在 24G 显存的卡上跑 3D nnU-Netpatch size 只能开到 128x128x128再大就 OOM 了。CNN 方案还有一个共性问题对旋转和形变的不变性不足。医学图像里器官的形态变化很大比如肝脏在呼吸过程中会有明显形变但 CNN 的卷积核是固定方向的对旋转的鲁棒性靠数据增强来补。我试过用可变形卷积Deformable Conv来缓解这个问题效果有提升但提升有限而且可变形卷积的 offset 学习在医学图像上不太稳定容易学出奇怪的形变场。1.2 Transformer 的引入动机与医学场景适配Transformer 进入医学分割领域大概是 2021 年之后的事。最早是 TransUNet 这篇工作把 ViT 作为 U-Net 的编码器在多个医学分割数据集上刷了 SOTA。它的核心思路是用 Transformer 的全局自注意力替代 CNN 的局部卷积让模型从第一层就能建立长距离依赖。我最早复现 TransUNet 时踩了不少坑。第一个问题是位置编码。医学图像的空间结构很重要肝脏在右上腹、脾脏在左上腹这些位置信息必须编码进去。但标准的正弦位置编码是 1D 的直接用在 2D 图像上会丢失空间关系。TransUNet 用的是可学习的位置编码我试过固定正弦编码和可学习编码后者在医学数据上明显更好因为医学图像的位置分布相对固定可学习编码能捕捉到这种先验。第二个问题是数据量。ViT 在 ImageNet 上预训练需要上千万张图医学数据通常只有几百例。我试过直接在医学数据上从头训练 ViT结果 Dice 只有 0.6 左右远不如 U-Net。后来用 ImageNet 预训练权重做初始化Dice 直接跳到 0.88。这说明 Transformer 对预训练权重的依赖远大于 CNN如果没有足够的预训练数据Transformer 在医学场景下很难发挥优势。第三个问题是计算量。一张 512x512 的图ViT 的 patch size 设为 16序列长度就是 1024。自注意力的计算复杂度是 O(n^2)1024 的平方是 100 万看起来还能接受。但如果做 3D 分割比如 128x128x128 的 volumepatch size 设为 16序列长度就是 4096平方后是 1600 万显存直接爆炸。所以早期的 Transformer 医学分割方案基本都是 2D 的3D 方案要到 Swin Transformer 出来之后才逐渐可行。Swin Transformer 的核心创新是窗口注意力。它把图像划分成不重叠的窗口只在窗口内算自注意力然后通过移位操作让窗口之间产生交互。这样计算复杂度就从 O(n^2) 降到了 O(n)。我实测下来Swin UNet 在 3D 医学分割上比纯 ViT 方案快 3-4 倍显存占用降低一半以上Dice 还能保持相当。但 Swin 的窗口大小是个超参窗口太小全局建模能力弱窗口太大计算量又上去了。我试过 4、7、8、12 几种窗口大小在肝脏分割任务上 7 和 8 效果最好4 太小、12 太大。1.3 CNN 与 Transformer 的融合趋势纯 Transformer 方案在医学分割上有一个明显短板浅层细节捕捉能力弱。ViT 的第一层就是 patch embedding把 16x16 的区域直接压成一个向量这个过程中大量边缘和纹理信息丢失了。而医学分割恰恰对边界极其敏感肿瘤的毛刺征、血管的细小分支这些都需要高分辨率特征。所以现在主流的方案都是 CNN 和 Transformer 混合。比如 TransUNet 用 CNN 做浅层特征提取Transformer 做深层语义建模Swin UNet 用 Swin Transformer 块替换 U-Net 的卷积块但保留了 U-Net 的跳跃连接结构还有 MISSFormer 这种专门为 2D 医学分割设计的 Transformer在编码器和解码器之间加了增强的注意力模块。我个人的经验是混合架构在医学分割上确实比纯 CNN 或纯 Transformer 更稳。CNN 负责浅层细节Transformer 负责全局语义两者互补。但混合架构的调参难度也更大学习率、权重衰减、dropout 这些超参对 CNN 和 Transformer 部分可能需要不同的设置。我通常会给 Transformer 部分用更小的学习率因为它的参数量更大、更容易过拟合。2. 核心架构拆解与关键模块实现2.1 CNN 编码器的设计要点与参数选择先讲 CNN 编码器。在医学分割里编码器的核心任务是把输入图像逐步下采样提取多尺度特征。我通常用 4 层下采样每层分辨率减半、通道数翻倍。比如输入 512x512x1 的 CT 切片第一层输出 256x256x64第二层 128x128x128第三层 64x64x256第四层 32x32x512。卷积核大小我一般用 3x3这是最通用的选择。3x3 的感受野虽然小但堆叠两层就能等效 5x5堆叠三层等效 7x7而且参数量更少、非线性更强。5x5 和 7x7 的卷积核在医学图像上我试过效果没有明显提升反而增加了计算量。1x1 卷积主要用来做通道压缩和特征融合不单独作为特征提取层。激活函数方面ReLU 是最常用的但我更推荐 LeakyReLU负斜率设 0.01。医学图像里有很多低对比度区域ReLU 在负半轴梯度为零容易导致神经元死亡。LeakyReLU 能缓解这个问题。我试过在肝脏分割任务上对比 ReLU 和 LeakyReLU后者在训练初期收敛更快最终 Dice 高 0.5-1 个点。归一化层我一般用 BatchNorm但医学图像有个特殊情况不同扫描设备的灰度分布差异很大。同一家医院的不同 CT 机或者不同医院的 CT 机图像的均值和方差可能差很多。BatchNorm 在训练时依赖 batch 统计量如果 batch 里混了不同设备的数据归一化效果会打折扣。我试过用 InstanceNorm 替代 BatchNorm在小 batch 场景下更稳定但训练速度会慢一些。GroupNorm 是折中方案group 数设 8 或 16效果介于两者之间。下采样方式我推荐用步长为 2 的卷积而不是最大池化。最大池化会丢失空间信息而步长卷积是可学习的能保留更多细节。我试过在 U-Net 里把 MaxPool 换成 Strided ConvDice 提升了 0.3 左右虽然不多但很稳定。2.2 Transformer 模块的自注意力机制与位置编码Transformer 的核心是自注意力。给定输入序列 X先通过三个线性变换得到 Q、K、V然后计算 Attention(Q,K,V) softmax(QK^T / sqrt(d_k)) V。这里的 d_k 是 key 的维度除以 sqrt(d_k) 是为了防止点积过大导致 softmax 梯度消失。在医学图像里自注意力的计算有几个关键点。第一是patch size 的选择。patch size 越小序列越长全局建模能力越强但计算量也越大。我试过 8、16、32 三种 patch size在 512x512 的 CT 切片上16 是性价比最高的。8 的序列长度是 4096显存占用太大32 的序列长度是 256全局建模能力不足。第二是多头注意力的头数。标准 Transformer 用 8 或 16 个头每个头的维度是 d_model / num_heads。医学图像我一般用 8 个头d_model 设 512每个头 64 维。头数太少注意力模式单一头数太多每个头的维度太小表达能力不足。我试过 4、8、12、16 几种配置8 和 12 效果最好。第三是位置编码。前面提过医学图像的位置信息很重要。我通常用可学习的 2D 位置编码形状是 (H/patch_size) x (W/patch_size) x d_model。初始化用截断正态分布标准差设 0.02。训练时位置编码和模型参数一起更新。我试过固定正弦编码效果比可学习编码差 1-2 个 Dice 点因为医学图像的位置分布有很强的先验可学习编码能捕捉到这种先验。第四是注意力 dropout。Transformer 参数量大容易过拟合。我一般在注意力权重上加 dropoutrate 设 0.1。另外在 FFN 层也加 dropoutrate 设 0.1。如果数据量特别少比如少于 500 例dropout rate 可以加到 0.2 甚至 0.3。2.3 跳跃连接与多尺度特征融合策略跳跃连接是 U-Net 的精髓也是 CNN 和 Transformer 混合架构的关键。在纯 CNN U-Net 里跳跃连接把编码器的浅层特征直接拼到解码器的对应层。但在混合架构里编码器可能是 CNN解码器可能是 Transformer特征维度不匹配不能直接拼。我常用的做法是用 1x1 卷积做维度对齐。比如编码器输出 64 通道解码器需要 512 通道就用 1x1 卷积把 64 通道升到 512再和 Transformer 的输出相加或拼接。相加的计算量小拼接的表达能力强我一般用拼接后面接一个 3x3 卷积做融合。多尺度特征融合我试过几种方案。最简单的是 U-Net 的逐层拼接但这种方式对尺度差异大的特征融合效果一般。后来我试了 ASPP空洞空间金字塔池化用不同 rate 的空洞卷积提取多尺度特征再拼接。ASPP 在医学分割上效果不错尤其是对大小不一的病灶。但 ASPP 的计算量较大我一般只在编码器最后一层用。还有一种方案是注意力门控。在跳跃连接上加一个注意力模块让解码器自动学习哪些编码器特征更重要。我试过在肝脏分割任务上加注意力门控Dice 提升了 1 个点左右但训练时间增加了 20%。如果对推理速度有要求这个方案要慎重。2.4 损失函数选择与类别不平衡处理医学分割的损失函数选择很关键。最常用的是 Dice Loss因为它直接优化 Dice 系数和评价指标一致。但 Dice Loss 在训练初期梯度不稳定尤其是当预测和真实标签完全不相交时梯度会爆炸。我一般用 Dice Loss 和 CrossEntropy Loss 的加权和权重比 1:1 或 1:2。类别不平衡是医学分割的常见问题。比如肝脏分割肝脏像素可能只占整张图的 5%背景占 95%。如果直接用 CrossEntropy模型会倾向于预测背景因为这样 loss 更低。我试过几种解决方案一是用加权 CrossEntropy给前景像素更高的权重二是用 Focal Loss降低易分类样本的权重三是用 Tversky Loss调整 FP 和 FN 的权重。我实测下来Focal Loss Dice Loss 的组合在大多数任务上最稳。Focal Loss 的 gamma 设 2alpha 设 0.25。如果前景特别小比如小于 1%可以把 alpha 调到 0.5 甚至 0.75。Tversky Loss 适合对 FP 和 FN 有不同容忍度的场景比如肿瘤分割FN 的代价远大于 FP可以把 FN 的权重调高。还有一个技巧是深监督。在解码器的每一层都加一个辅助损失让浅层也能学到有意义的特征。我试过在 U-Net 的 4 层解码器上都加辅助损失最终 Dice 提升了 0.5-1 个点。但辅助损失的权重不能太大一般设为主损失的 0.1-0.3。3. 完整实操流程与关键环节实现3.1 数据预处理与增强策略医学图像预处理的第一步是重采样。不同设备的层厚可能不同有的 1mm有的 5mm。如果直接混在一起训练模型会学到层厚这个无关特征。我一般把所有数据重采样到统一层厚比如 1mm 或 2mm。重采样用三线性插值标签用最近邻插值。第二步是灰度归一化。CT 图像的 HU 值范围是 -1000 到 3000但大部分组织的 HU 值在 -100 到 200 之间。我一般先做窗宽窗位调整把腹部 CT 的窗宽设 400、窗位设 50这样能突出软组织对比。然后做 Z-score 归一化减均值除标准差。均值和标准差从训练集统计验证集和测试集用同样的参数。第三步是数据增强。医学图像的数据增强要特别小心因为有些增强会破坏解剖结构。我常用的增强包括随机旋转-15 到 15 度、随机缩放0.9 到 1.1、随机平移-10 到 10 像素、随机弹性形变alpha 设 1000sigma 设 50、随机亮度对比度调整0.1 到 0.3。绝对不要用水平翻转因为肝脏在右边、脾脏在左边翻转后解剖结构就错了。垂直翻转也要慎用胸腔和腹腔的上下关系不能乱。弹性形变是医学分割里最有效的增强之一。我一般用 SimpleITK 或 scipy 的弹性形变实现alpha 控制形变强度sigma 控制平滑度。alpha 太大形变太剧烈可能把器官形状搞乱alpha 太小形变不明显增强效果有限。我试过 alpha500、1000、20001000 效果最好。3.2 模型训练配置与超参数调优训练配置我一般用 AdamW 优化器学习率设 1e-4权重衰减设 1e-5。Transformer 部分的学习率可以设小一点比如 5e-5因为它的参数量大、容易过拟合。学习率调度用 Cosine Annealing从 1e-4 降到 1e-6训练 200 个 epoch。Batch size 我一般设 8 或 16。医学图像通常比较大512x512 的图 batch size 设 8 就需要 16G 显存。如果显存不够可以用梯度累积累积 4 步等效 batch size 32。但梯度累积会让 BatchNorm 的统计量不准确如果用了 BatchNorm最好还是用真实的大 batch。训练 epoch 数我一般设 200-300。医学数据量小模型容易过拟合训练太多 epoch 验证集 loss 会上升。我通常用早停策略验证集 Dice 连续 20 个 epoch 不提升就停止。如果数据量特别少比如少于 200 例可以先用 ImageNet 预训练权重初始化再微调 100 个 epoch。混合精度训练我强烈推荐。用 AMP自动混合精度可以把显存占用降低 30-40%训练速度提升 20-30%。我试过在 Swin UNet 上开 AMPbatch size 从 8 提到 12训练时间从 8 小时降到 5 小时Dice 基本不变。但 AMP 对 loss scaling 比较敏感如果 loss 出现 NaN要把 loss scale 调小。3.3 推理与后处理技巧推理阶段我一般用滑动窗口。医学图像可能很大比如 512x512x200 的 3D volume直接整图推理显存不够。滑动窗口的窗口大小设 128x128x128步长设 64x64x64重叠区域用高斯加权平均。这样能保证边界区域也有足够的上下文信息。后处理我常用两种一是连通域分析去掉小的孤立区域。比如肝脏分割如果某个连通域小于 100 个体素很可能是噪声直接去掉。二是形态学操作用开运算去掉小突起用闭运算填充小孔洞。我试过在肝脏分割上加连通域分析Dice 提升了 0.5 个点尤其是对边界区域。还有一个技巧是测试时增强。对同一张图做多次增强旋转、缩放分别推理然后取平均。我试过 8 次增强4 个旋转角度 x 2 个缩放比例Dice 提升了 1-1.5 个点但推理时间增加了 8 倍。如果对精度要求高、对速度要求低可以用这个方案。3.4 评估指标与结果分析医学分割最常用的评估指标是 Dice 系数和 IoU。Dice 2|A∩B| / (|A||B|)IoU |A∩B| / |A∪B|。Dice 对边界更敏感IoU 对整体重叠更敏感。我一般两个都报但以 Dice 为主。除了 Dice 和 IoU我还看HD9595% 豪斯多夫距离。HD95 衡量的是预测边界和真实边界之间的最大偏差对边界精度要求高的任务比如放疗计划很重要。我试过在肝脏分割上Dice 0.95 的模型 HD95 可能差 10mm而 Dice 0.93 的模型 HD95 只有 5mm。所以 Dice 高不代表边界一定准。结果分析我一般做可视化对比。把预测结果和真实标签叠加在原始图像上用不同颜色标注 TP、FP、FN。TP 用绿色FP 用红色FN 用蓝色。这样能直观看到模型在哪里出错。我经常发现模型在器官边界处 FP 和 FN 都很多说明边界区域的判别能力不足。这时候可以考虑加边界损失或者用更精细的跳跃连接。4. 常见问题与排查技巧实录4.1 训练不收敛或 Dice 震荡的排查思路训练不收敛是新手最常遇到的问题。我总结了几种常见原因和排查方法。第一种是学习率太大。Transformer 对学习率特别敏感1e-3 的学习率很可能导致 loss 爆炸。我一般从 1e-4 开始试如果 loss 还是震荡降到 5e-5 或 1e-5。CNN 部分可以用大一点的学习率但混合架构里我通常统一用 1e-4。第二种是数据归一化有问题。医学图像的灰度分布差异大如果归一化参数不对模型很难学到有效特征。我一般先统计训练集的均值和标准差然后可视化几张归一化后的图确认器官边界清晰可见。如果归一化后图像一片灰说明窗宽窗位没调好。第三种是batch size 太小。BatchNorm 在 batch size 小于 8 时统计量不稳定会导致训练震荡。如果显存不够可以用 GroupNorm 替代 BatchNorm或者用梯度累积模拟大 batch。第四种是损失函数权重不对。Dice Loss 和 CrossEntropy Loss 的权重比如果设成 10:1Dice 的梯度会主导训练导致模型只关注前景、忽略背景。我一般设 1:1 或 1:2让两个损失平衡。4.2 过拟合与欠拟合的识别与应对过拟合在医学分割里很常见因为数据量小、模型参数量大。识别过拟合的方法是看训练集和验证集的 loss 曲线。如果训练集 loss 持续下降验证集 loss 先降后升就是过拟合。应对过拟合我一般用这几招一是加数据增强尤其是弹性形变和随机裁剪二是加 dropoutTransformer 部分 dropout rate 设 0.1-0.3三是加权重衰减AdamW 的权重衰减设 1e-5 到 1e-4四是早停验证集 Dice 连续 20 个 epoch 不提升就停五是用预训练权重ImageNet 预训练能显著缓解过拟合。欠拟合相对少见但如果模型在训练集上 Dice 就很低说明模型容量不够或者训练不充分。我一般先检查学习率是不是太小然后看模型参数量是不是不够。如果 CNN 只有 4 层、通道数最大 256可能欠拟合可以加到 5 层、通道数最大 512。4.3 显存不足与推理速度优化显存不足是 Transformer 医学分割的常见问题。我总结了几种优化方案。第一种是梯度检查点。把中间层的激活值不保存反向传播时重新计算。这样能把显存占用降低 50-70%但训练速度会慢 20-30%。我试过在 Swin UNet 上开梯度检查点batch size 从 4 提到 8训练时间从 6 小时增到 8 小时。第二种是混合精度训练。前面提过AMP 能把显存降低 30-40%速度提升 20-30%。这是性价比最高的优化方案。第三种是减小 patch size 或窗口大小。Swin Transformer 的窗口从 8 降到 4显存占用能降一半但全局建模能力会下降。我一般先试窗口 8如果 OOM 再降到 4。第四种是用轻量级架构。比如 MobileViT、EfficientNet 这些轻量级 backbone参数量只有标准 Transformer 的 1/5 到 1/10显存占用小很多。但精度可能会降 1-2 个 Dice 点。推理速度优化我一般用 TensorRT 或 ONNX Runtime。TensorRT 能把推理速度提升 2-3 倍尤其是对 Transformer 这种计算密集的模型。但 TensorRT 的转换比较麻烦尤其是自定义的注意力模块可能需要手写 plugin。4.4 常见问题速查表问题现象可能原因排查方法解决方案训练 loss 震荡学习率太大打印每步 loss降低学习率到 1e-5验证集 Dice 低过拟合对比训练/验证 loss加数据增强、dropout显存 OOMbatch size 太大打印显存占用开 AMP、梯度检查点边界分割不准浅层特征丢失可视化边界区域加跳跃连接、边界损失小目标漏检类别不平衡统计前景像素比例用 Focal Loss、加权采样推理速度慢模型太大测单张推理时间用 TensorRT、剪枝位置信息丢失位置编码不对可视化注意力图用可学习 2D 位置编码多设备数据混训效果差灰度分布不一致统计各设备均值方差用 InstanceNorm、直方图匹配5. 技术选型建议与实战心得5.1 不同数据规模下的架构选择数据量是决定架构选择的最关键因素。我按数据规模分三档来说。数据量小于 500 例这个规模下我强烈建议用 CNN 方案比如 nnU-Net 或 U-Net。Transformer 参数量太大500 例数据根本不够训练。如果一定要用 Transformer必须用 ImageNet 预训练权重而且只微调最后几层。我试过在 300 例肝脏数据上从头训练 Swin UNetDice 只有 0.75而 nnU-Net 能到 0.90。数据量 500-2000 例这个规模下混合架构最合适。CNN 做编码器提取浅层特征Transformer 做解码器建模全局语义。TransUNet 和 Swin UNet 都是不错的选择。我试过在 1000 例腹部 CT 上对比 TransUNet 和 nnU-NetTransUNet 的 Dice 高 1.5 个点尤其是多器官分割任务。数据量大于 2000 例这个规模下纯 Transformer 方案开始有优势。ViT 或 Swin Transformer 直接做编码器配合 U-Net 解码器。我试过在 3000 例数据上训练纯 Swin UNetDice 比混合架构高 0.8 个点但训练时间多 50%。5.2 2D 与 3D 方案的取舍2D 和 3D 方案的选择取决于任务需求。2D 方案把 3D volume 切成切片逐片分割再拼回去。优点是显存占用小、训练快、可以用 2D 预训练权重。缺点是切片之间的连续性丢失可能出现“切片间跳变”。3D 方案直接处理 volume能保留空间连续性。优点是分割结果更平滑、对 3D 形态的建模更准。缺点是显存占用大、训练慢、预训练权重少。我一般这样选如果层厚大于 3mm用 2D 方案因为层间信息本来就少如果层厚小于 2mm用 3D 方案层间信息丰富。如果任务对边界平滑度要求高比如放疗计划用 3D 方案如果对速度要求高比如术中导航用 2D 方案。还有一种折中方案是2.5D把相邻的 3 个切片作为 3 通道输入这样既能利用层间信息又不用 3D 卷积。我试过在肝脏分割上用 2.5DDice 比 2D 高 0.5 个点训练时间只增加 20%。5.3 预训练权重与迁移学习策略预训练权重对 Transformer 医学分割至关重要。我试过从头训练和用预训练权重差距能有 10 个 Dice 点以上。常用的预训练权重来源有 ImageNet、RadImageNet、MedicalNet 等。ImageNet 预训练权重最容易获取但它是自然图像和医学图像差异大。我一般用 ImageNet 预训练初始化 CNN 部分Transformer 部分随机初始化。如果数据量特别少Transformer 部分也可以用 ImageNet 预训练但需要更小的学习率。RadImageNet 是专门用放射图像预训练的包括 CT、MRI、超声。我试过用 RadImageNet 预训练初始化 Swin UNet比 ImageNet 预训练高 1-2 个 Dice 点。但 RadImageNet 的权重不是所有架构都有需要自己转换。迁移学习策略我一般分两步先冻结编码器只训练解码器 20 个 epoch然后解冻全部用更小的学习率微调 100 个 epoch。这样能防止预训练权重被破坏同时让模型适应医学数据。5.4 实操心得与避坑清单最后分享几条我踩坑踩出来的经验。第一条不要迷信 SOTA。论文里的 SOTA 是在特定数据集上调出来的换一个数据集可能就不行了。我试过把某个 SOTA 模型直接搬到自己的数据上Dice 比 nnU-Net 低 5 个点。一定要在自己的数据上做 baseline 对比。第二条数据质量比模型架构重要。我见过太多人花几周调模型Dice 提升 1 个点但数据里有一批标注错误的样本清理后 Dice 直接提升 5 个点。标注质量、标注一致性、标注规范这些比模型架构重要得多。第三条可视化是排查问题的利器。Loss 曲线、Dice 曲线只能告诉你“有问题”可视化能告诉你“什么问题”。我一般每 10 个 epoch 可视化一批验证集结果看模型在哪里出错。边界出错就加边界损失小目标漏检就加 Focal Loss大器官分割不全就加全局注意力。第四条不要忽略后处理。后处理能提升 1-2 个 Dice 点而且不需要重新训练。连通域分析、形态学操作、测试时增强这些技巧简单但有效。我一般先跑 baseline再加后处理看提升多少。第五条多尺度推理很有效。把输入图像缩放到不同尺度分别推理然后取平均。我试过 3 个尺度0.75x、1.0x、1.25xDice 提升了 1 个点。但推理时间增加 3 倍需要权衡。第六条模型集成是最后的杀手锏。训练 5 个不同初始化的模型推理时取平均。Dice 能提升 1.5-2 个点但训练和推理成本都增加 5 倍。如果对精度要求极高、对成本不敏感可以用这个方案。第七条注意数据的伦理和隐私。医学数据涉及患者隐私使用前必须脱敏去除 DICOM 头里的患者信息。如果是多中心数据还要注意数据使用协议不能随意共享。第八条临床落地要考虑推理速度。我见过很多论文模型 Dice 很高但推理一张图要 10 秒临床根本没法用。实际部署时推理速度要控制在 1 秒以内最好 500 毫秒以内。这时候可能需要模型剪枝、量化、TensorRT 加速。第九条持续学习很重要。医学数据是不断增加的新设备、新协议、新病种都会带来数据分布变化。模型部署后要持续监控定期用新数据微调。我一般每 3 个月用新数据微调一次保持模型性能。第十条不要重复造轮子。nnU-Net、MONAI、MedicalSeg 这些开源框架已经做了大量工程优化直接用它们能省很多时间。我早期自己写数据加载、增强、训练循环花了两个月后来发现 MONAI 里都有而且比我写的好。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →