MMSegmentation 医学影像实战:DR HAGIS 眼底视网膜血管分割数据集接入与 UNet 训练指南
【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
导读
本文基于 MMSegmentation 仓库中的 DR HAGIS 医学影像分割项目,系统讲解如何将 DR HAGIS 眼底照片(fundus photography)数据集接入 MMSegmentation 1.x 训练框架,完成视网膜血管(retinal vessel)语义分割模型的训练与测试。读者将掌握:数据集背景与标签统计、目录整理与数据集切分流程、自定义数据集的注册方式、UNet 分割模型配置文件的逐项含义,以及使用mim一键训练/测试的命令行操作,最终能够在自己的眼底影像分割任务上直接复用这套流程。
一、项目背景:DR HAGIS 数据集是什么
1.1 数据集定位与来源
projects/medical/2d_image/fundus_photography/dr_hagis/目录下的这个子项目,支持的是DR HAGIS(Diabetic Retinopathy, Hypertension, Age-related macular degeneration and Glacuoma ImageS)数据集,其原始出处是 Holm 等人 2017 年发表于《Journal of Medical Imaging》的论文:
DR HAGIS—a fundus image database for the automatic extraction of retinal surface vessels from diabetic patients
该数据库专为辅助视网膜筛查计划中的血管提取算法开发而建立。全部 39 张眼底图像均来自英国一项糖尿病视网膜病变筛查项目,因此所有图像都来自糖尿病患者。除眼底原图外,数据还提供了由专业分级人员(expert grader)手工标注的视网膜表层血管分割图(ground truth),以及用于限定评估范围的FOV(视野)掩膜——这样可以在仅 FOV 区域内量化血管提取精度。
从数据采集的工程细节看(见 README.md):
- 图像采集自多个不同的筛查中心,因此分辨率、数码相机与眼底相机型号各不相同,天然具备临床真实场景的多样性;
- 相机型号涵盖 Topcon TRC-NW6s、Topcon TRC-NW8 与 Canon CR DGi,水平视野角 45°;
- 图像尺寸为 4752×3168、3456×2304、3126×2136、2896×1944、2816×1880 像素等五种规格。
1.2 原始统计信息
| 数据集名称 | 解剖区域 | 任务类型 | 模态 | 类别数 | 训练/验证/测试图像 | 训练/验证/测试标注 | 发布日期 | License |
|---|---|---|---|---|---|---|---|---|
| DR HAGIS | head and neck | segmentation | fundus photography | 2 | 40/-/- | yes/-/- | 2017 | - |
原始数据仅有训练集 40 张图像(官方未提供带标注的验证/测试集),像素级类别占比为:
| 类别 | 训练数 | 训练占比 | 验证数 | 验证占比 | 测试数 | 测试占比 |
|---|---|---|---|---|---|---|
| background(背景) | 40 | 96.38 | - | - | - | - |
| vessel(血管) | 40 | 3.62 | - | - | - | - |
说明:
Pct表示该类像素占全部像素的百分比。血管像素仅占约 3.62%,属于典型的前景极度稀疏的分割任务,对损失函数与训练策略的选择有重要影响。
二、项目结构与自定义数据集实现
2.1 目录布局
projects/medical/2d_image/fundus_photography/dr_hagis/ ├── configs/ │ ├── dr-hagis_512x512.py # 数据集与数据管线配置 │ ├── fcn-unet-s5-d16_unet_1xb16-0.0001-20k_dr-hagis-512x512.py │ ├── fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.py │ └── fcn-unet-s5-d16_unet_1xb16-0.01-20k_dr-hagis-512x512.py ├── datasets/ │ └── dr-hagis_dataset.py # 自定义数据集类 ├── tools/ │ └── prepare_dataset.py # 数据格式整理脚本 └── README.md这三个部分各司其职:datasets/负责把 DR HAGIS 注册为 MMSegmentation 可识别的数据集;tools/负责把原始下载数据整理成标准目录结构;configs/负责组合模型、数据与训练策略。下面逐一深入。
2.2 自定义数据集类:DRHAGISDataset
DR HAGIS 没有现成的官方数据加载器,项目通过继承 MMSegmentation 的BaseSegDataset实现了一个轻量数据集类,代码见 dr-hagis_dataset.py:
from mmseg.datasets import BaseSegDataset from mmseg.registry import DATASETS @DATASETS.register_module() class DRHAGISDataset(BaseSegDataset): """DRHAGISDataset dataset. In segmentation map annotation for DRHAGISDataset, ``reduce_zero_label`` is fixed to False. The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. """ METAINFO = dict(classes=('background', 'vessel')) def __init__(self, img_suffix='.png', seg_map_suffix='.png', **kwargs) -> None: super().__init__( img_suffix=img_suffix, seg_map_suffix=seg_map_suffix, reduce_zero_label=False, **kwargs)关键设计点:
- 注册机制:通过
@DATASETS.register_module()装饰器将类注册进mmseg.registry,这样配置文件中直接写type='DRHAGISDataset'即可实例化,无需修改框架核心代码——这正是 MMSegmentation 1.x 的模块化设计; - METAINFO:声明类别为
('background', 'vessel')两分类,配置中decode_head=dict(num_classes=2)与之一一对应; - reduce_zero_label=False:DR HAGIS 的掩膜中 0 号像素就是背景类别(而不是需要忽略的未标注区域),因此必须关闭零标签归约,否则背景类会被错误剔除导致类别数错位;
- 固定后缀:图像与分割图统一使用
.png后缀,这是后续prepare_dataset.py转换的目标格式。
2.3 数据整理脚本:prepare_dataset.py
原始下载的 DR HAGIS 数据格式并不直接满足 MMSegmentation 的加载约定,需要先运行 prepare_dataset.py 做格式整理。脚本核心逻辑:
root_path = 'data/' img_suffix = '.jpg' seg_map_suffix = '_manual_orig.png' x_train = glob.glob(os.path.join('data/DRHAGIS/**/*' + img_suffix)) # ... 创建 data/images/train 与 data/masks/train 目录 ... D3_palette = {0: (0, 0, 0), 1: (1, 1, 1)} D2_255_convert_dict = {0: 0, 255: 1} # 遍历每张图:复制原图为 .png;打开 Manual_Segmentations 下的手工标注, # 将标注中 255 的像素值映射为 1(vessel),0 保持为 0(background),另存为掩膜 .png mask = np.array(Image.open(mask_path)).astype(np.uint8) mask[mask == 255] = 1这段代码揭示了数据集工程化的两个要点:
- 格式归一化:把 JPG 原图统一转存为
.png,与DRHAGISDataset中img_suffix='.png'的约定对齐; - 标签语义化:原始标注中血管用 255 表示,脚本将其映射为 1(vessel),背景为 0(background),最终标签恰好是
{0, 1}两值,与METAINFO的类别顺序严格一致。注意脚本中D2_255_convert_dict已定义但实际用mask[mask == 255] = 1完成转换。
三、数据集切分与目录结构
3.1 切分说明
由于官方仅提供 40 张带标注训练图像、无公开的验证/测试标注,项目采用如下策略(见 README.md):
- 运行
prepare_dataset.py完成格式整理后; - 再运行切分脚本生成
train.txt、val.txt和test.txt; - 当官方验证集/测试集标注无法获取时,脚本会从训练集中随机划分出验证集,即"由我们自己划分"(README 中明确标注The table information below is divided by ourselves)。
切分脚本位于 projects/medical/2d_image/tools/split_seg_dataset.py,是一个在projects/medical下多个数据集子项目中通用的工具。
3.2 整理后的目录结构
数据与标注统一存放于data/下,图像与掩膜分离、训练/验证分目录组织:
mmsegmentation ├── mmseg ├── projects │ ├── medical │ │ ├── 2d_image │ │ │ ├── fundus_photography │ │ │ │ ├── dr_hagis │ │ │ │ │ ├── configs │ │ │ │ │ ├── datasets │ │ │ │ │ ├── tools │ │ │ │ │ ├── data │ │ │ │ │ │ ├── train.txt │ │ │ │ │ │ ├── val.txt │ │ │ │ │ │ ├── images │ │ │ │ │ │ │ ├── train │ │ │ │ │ │ │ │ ├── xxx.png │ │ │ │ │ │ │ │ └── ... │ │ │ │ │ │ ├── masks │ │ │ │ │ │ │ ├── train │ │ │ │ │ │ │ │ ├── xxx.png │ │ │ │ │ │ │ │ └── ...train.txt/val.txt中每行是一条样本记录(图像路径与掩膜路径按约定成对解析),data_prefix配置img_path='images/'、seg_map_path='masks/'即指向上述目录。
3.3 切分后的数据统计
| 类别 | 训练数 | 训练占比 | 验证数 | 验证占比 | 测试数 | 测试占比 |
|---|---|---|---|---|---|---|
| background | 32 | 96.21 | 8 | 97.12 | - | - |
| vessel | 32 | 3.79 | 8 | 2.88 | - | - |
即从 40 张中随机抽出 8 张作为验证集,剩余 32 张训练;血管像素占比在训练集(3.79%)与验证集(2.88%)中仍保持稀疏分布。
四、配置文件逐层解析
DR HAGIS 子项目提供了 3 份可训练配置,分别对应学习率 0.0001 / 0.001 / 0.01(文件名中的0.0001-20k即 lr-iterations),用于对比不同学习率对血管分割训练的影响。每份配置均通过_base_继承机制组装四部分内容。
4.1 数据集与数据管线配置:dr-hagis_512x512.py
完整内容见 dr-hagis_512x512.py,核心片段:
dataset_type = 'DRHAGISDataset' data_root = 'data/' img_scale = (512, 512) train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='LoadAnnotations'), dict(type='Resize', scale=img_scale, keep_ratio=False), dict(type='RandomFlip', prob=0.5), dict(type='PhotoMetricDistortion'), dict(type='PackSegInputs') ] test_pipeline = [ dict(type='LoadImageFromFile'), dict(type='Resize', scale=img_scale, keep_ratio=False), dict(type='LoadAnnotations'), dict(type='PackSegInputs') ] train_dataloader = dict( batch_size=16, num_workers=4, persistent_workers=True, sampler=dict(type='InfiniteSampler', shuffle=True), dataset=dict( type=dataset_type, data_root=data_root, ann_file='train.txt', data_prefix=dict(img_path='images/', seg_map_path='masks/'), pipeline=train_pipeline)) val_dataloader = dict( batch_size=1, num_workers=4, persistent_workers=True, sampler=dict(type='DefaultSampler', shuffle=False), dataset=dict( type=dataset_type, data_root=data_root, ann_file='val.txt', data_prefix=dict(img_path='images/', seg_map_path='masks/'), pipeline=test_pipeline)) test_dataloader = val_dataloader val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice'])参数含义与设计考量:
- 统一缩放到 512×512:
Resize使用keep_ratio=False直接拉伸,兼顾不同来源图像的分辨率差异(原始图像从 2816×1880 到 4752×3168 不等),使不同尺寸图像可组成 batch; - 训练增强:
RandomFlip(水平翻转概率 0.5)与PhotoMetricDistortion(光度扰动,模拟不同眼底相机光照/色彩差异)针对眼底图像拍摄条件多变的特点设计; - 采样器差异:训练用
InfiniteSampler(无限迭代采样,配合按 iteration 计数的 20k 训练计划),验证用DefaultSampler且shuffle=False保证评估可复现; - 评估指标:
IoUMetric同时计算mIoU与mDice两种指标——血管分割任务前景占比极低,Dice 系数能更敏感地反映血管区域的重合质量,这是医学分割评估的常见做法; - batch_size:训练 16、验证 1,验证单卡逐张推理。
4.2 模型骨架:FCN-UNet-s5-d16
模型部分继承自仓库基础配置 fcn_unet_s5-d16.py,即UNet 编码器 + FCN 解码头:
- backbone=UNet:
in_channels=3(RGB 眼底图)、base_channels=64、num_stages=5个下采样阶段、每层 2 个卷积、使用InterpConv上采样、SyncBN归一化; - decode_head=FCNHead:
in_channels=64、in_index=4(取 UNet 最深一层特征)、num_classes=2、损失为CrossEntropyLoss(use_sigmoid=False,即多类 Softmax 交叉熵); - auxiliary_head=FCNHead:在
in_index=3的中间层附加辅助头,loss_weight=0.4加权辅助监督,帮助深监督训练; - data_preprocessor:
SegDataPreProcessor使用 ImageNet 统计的均值/标准差(mean=[123.675, 116.28, 103.53]、std=[58.395, 57.12, 57.375])做标准化,bgr_to_rgb=True处理通道顺序。
4.3 训练计划与运行时
训练计划继承 schedule_20k.py:
- 优化器:
SGD(momentum=0.9, weight_decay=0.0005),子项目配置通过optimizer = dict(lr=0.0001)覆盖学习率; - 调度策略:
PolyLR(power=0.9,eta_min=1e-4),迭代式衰减,总迭代20000; - 训练循环:
IterBasedTrainLoop,max_iters=20000,每 2000 次迭代验证一次;CheckpointHook同样每 2000 迭代保存一次权重; - 运行时继承 default_runtime.py,含
LocalVisBackend可视化后端、SegLocalVisualizer、cudnn_benchmark=True等默认设置。
4.4 子项目特有覆盖项
以fcn-unet-s5-d16_unet_1xb16-0.0001-20k_dr-hagis-512x512.py为例(见 该配置文件):
_base_ = [ './dr-hagis_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', 'mmseg::_base_/default_runtime.py', 'mmseg::_base_/schedules/schedule_20k.py' ] custom_imports = dict(imports='datasets.dr-hagis_dataset') img_scale = (512, 512) data_preprocessor = dict(size=img_scale) optimizer = dict(lr=0.0001) optim_wrapper = dict(optimizer=optimizer) model = dict( data_preprocessor=data_preprocessor, decode_head=dict(num_classes=2), auxiliary_head=None, test_cfg=dict(mode='whole', _delete_=True)) vis_backends = None visualizer = dict(vis_backends=vis_backends)覆盖项逐一说明:
- custom_imports:声明
datasets.dr-hagis_dataset,使DRHAGISDataset在使用mim train/test时能被自动导入注册,这是项目内自定义数据集在 MMSegmentation 1.x 中生效的必要步骤; - decode_head num_classes=2:与
METAINFO类别数对齐; - auxiliary_head=None:关闭辅助头,即本子项目采用单 FCNHead 输出的简化结构(注意这与基础配置默认带辅助头不同);
- test_cfg mode='whole' +delete=True:覆盖基础配置默认的
mode='slide', crop_size=256, stride=170(滑窗推理),改为整图推理;_delete_=True是 MMEngine 配置语法,用于删除被继承的旧键,避免slide参数残留; - vis_backends=None:关闭可视化后端(
SegLocalVisualizer无后端),在无显示环境的服务器上避免可视化相关开销; - 三份配置唯一差异:
optimizer = dict(lr=0.0001 / 0.001 / 0.01),分别命名在文件名中,便于对比学习率敏感性。
五、环境准备与数据预处理实操
5.1 环境依赖
按 README.md 中的 Prerequisites,推荐环境版本为:
- Python v3.8
- PyTorch v1.10.0
- MIM v0.3.4
- MMCV v2.0.0rc4
- MMEngine v0.2.0 或更高
- MMSegmentation v1.0.0rc5
版本说明:上述版本为项目文档编写时使用的组合。MMSegmentation 1.x 后续版本仍兼容本项目结构(
BaseSegDataset、DATASETS注册机制、_base_继承等核心 API 保持稳定),实际使用时请以你安装的 MMSegmentation 版本要求为准。
5.2 设置 PYTHONPATH
mim命令与配置文件依赖 Python 正确解析模块路径。在dr_hagis/根目录(即projects/medical/2d_image/fundus_photography/dr_hagis/)下执行:
export PYTHONPATH=`pwd`:$PYTHONPATH这一步确保custom_imports = dict(imports='datasets.dr-hagis_dataset')能定位到本目录下的datasets/包。
5.3 数据准备三步走
- 下载并解压:从 DR HAGIS 数据集页面下载数据,解压到
data/目录; - 格式整理:运行脚本
python tools/prepare_dataset.py,将原始 JPG 图像与_manual_orig.png手工标注转换为统一的images/、masks/结构与{0,1}标签(详见第二章); - 切分数据集:运行脚本
python ../../tools/split_seg_dataset.py生成train.txt、val.txt、test.txt;若官方验证/测试标注不可得,将从训练集中随机划分验证集。
完成后的目录结构即第三章所示。tools/split_seg_dataset.py位于 projects/medical/2d_image/tools/split_seg_dataset.py,注意它是projects/medical/2d_image/层的公共工具,因此相对路径为../../tools/。
六、训练与测试命令
6.1 单卡单机训练
在正确设置PYTHONPATH后,使用 MIM 一行启动训练:
mim train mmseg ./configs/${CONFIG_FILE}其中${CONFIG_FILE}替换为具体配置文件名,例如:
mim train mmseg ./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.pymim train会解析配置、构建模型/数据/优化器,并按schedule_20k.py迭代训练 20000 次,每 2000 迭代在验证集上评估一次 mIoU/mDice 并保存 checkpoint。三份配置可通过替换0.0001/0.001/0.01快速对比学习率效果。
6.2 单卡单机测试
mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH}例如:
mim test mmseg ./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.py --checkpoint work_dirs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.py/iter_20000.pth测试时模型按test_cfg=dict(mode='whole')对整张 512×512 图像直接推理,评估器输出验证集的mIoU 与 mDice两项指标,可据此对比不同学习率配置下的血管分割质量。
注意:以上命令默认在单 GPU 上运行;如需多卡分布式训练/测试,仓库提供了
tools/dist_train.sh与tools/dist_test.sh脚本,用法为bash tools/dist_train.sh ${CONFIG} ${GPU_NUM}。
七、训练技巧与注意事项
结合源码实现,针对 DR HAGIS 这类小样本(32 张训练图)+ 极稀疏前景(血管约 3.6%)的医学分割任务,有以下实操要点:
- 学习率需显著调低:基础
schedule_20k.py默认 SGD 学习率为 0.01,本子项目将学习率降至 0.0001~0.01 区间并提供了三档对比配置,反映小数据量下默认学习率易发散的经验; - 关闭辅助头与滑窗:配置通过
auxiliary_head=None与test_cfg=dict(mode='whole', _delete_=True)覆盖基础 UNet 配置,简化模型并采用整图推理,推理时无需像slide模式那样拼接多个 crop(基础配置的滑动窗口参数见 fcn_unet_s5-d16.py 末尾); - 标签语义一致性:
prepare_dataset.py将 255 映射为 1、reduce_zero_label=False、METAINFO类别顺序('background', 'vessel')、num_classes=2四处必须严格对齐,任一环节错位都会导致训练时类别错乱; - 验证集随机划分的可复现性:验证集由
split_seg_dataset.py从训练集随机抽出,如需复现实验请固定该脚本的随机种子; - 血管像素占比监控:训练日志中应重点观察 vessel 类别的 IoU/Dice(而非只看 mIoU),因为背景占 96% 以上,整体指标容易被背景主导、掩盖血管分割的真实退化。
八、引用与后续路线
8.1 引用方式
若该数据集与项目对你的研究有帮助,请引用原始论文:
@article{holm2017dr, title={DR HAGIS—a fundus image database for the automatic extraction of retinal surface vessels from diabetic patients}, author={Holm, Sven and Russell, Greg and Nourrit, Vincent and McLoughlin, Niall}, journal={Journal of Medical Imaging}, volume={4}, number={1}, pages={014503--014503}, year={2017}, publisher={Society of Photo-Optical Instrumentation Engineers} }8.2 项目成熟度说明
从 README.md 末尾的 Checklist 可以看出该子项目当前状态:
- ✅Milestone 1 基本完成:代码完成、基础 docstring 与引用齐全、README 完整,已具备 PR-ready 条件;
- ⬜Milestone 2 未完成:尚未完成训练期正确性验证(training-time correctness);
- ⬜Milestone 3 未完成:尚未补充类型注解、单元测试、代码打磨与
metafile.yml,模块尚未迁入mmseg/核心包。
因此,本文介绍的工作流适合作为接入新医学数据集的参考模板:若要将其用于正式研究复现,建议先运行mim train/mim test完成训练期与测试期正确性验证,再依据自身实验需求调整学习率、迭代数与数据增强策略。该项目的目录结构、数据集类与切分工具同样适用于projects/medical下其他眼底/视网膜影像数据集子项目,可直接对照复用。
【免费下载链接】mmsegmentationOpenMMLab Semantic Segmentation Toolbox and Benchmark.项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考