ULTRA 论文复现报告

1. 背景与说明

本文档用于记录论文 ULTRA: Uncertainty-aware Label Distribution Learning for Breast Tumor Cellularity Assessment 的完整复现过程、实验配置、运行结果与论文结果对比。


2. 论文信息

论文标题:ULTRA: Uncertainty-aware Label Distribution Learning for Breast Tumor Cellularity Assessment

会议版本:MICCAI 2022

代码仓库:https://github.com/PerceptionComputingLab/ULTRA

论文 PDF:https://arxiv.org/pdf/2206.06623.pdf

Springer 页面:https://link.springer.com/chapter/10.1007/978-3-031-16437-8_29

数据集页面:https://breastpathq.grand-challenge.org/Data/

论文研究的问题是:在乳腺癌新辅助治疗后的病理图像中,自动估计肿瘤细胞密度。与传统回归方法不同ULTRA 不再把标签视为唯一精确数值,而是把标签转为标签分布,从而建模病理医生标注中的不确定性和模糊性。


3. 论文简介

3.1 核心思想

论文把传统的 TC 回归问题改写为标签分布学习问题。

假设一张图像的 TC 标签是某个实数 s,传统方法直接回归 s。而 ULTRA 会围绕 s 构建一个高斯分布,将标签从单点扩展成一个概率分布。这个分布的宽窄由 sigmastd 控制:

std 越小,分布越尖锐,越接近“单点标签”

std 越大,分布越平滑,越强调标签的不确定性

论文还通过多分支特征融合模块 MBFF 模拟“多阅片者”的融合过程,进一步增强模型对标签不确定性的建模能力。

3.2 参数设置

根据论文正文,主要设置如下:

  1. 数据集:BreastPathQ
  2. 训练集 patch 数:2394
  3. 验证集 patch 数:185
  4. 测试集 patch 数:1119
  5. 两阶段训练:第一阶段训练 backbone,第二阶段训练整个 ULTRA
  6. 每个阶段训练 150 epochs
  7. 优化器:Adam
  8. 初始学习率:1e-4
  9. 学习率衰减:每 100 epochs 衰减为原来的 0.1
  10. 批大小:8
  11. 标签离散数:100
  12. 分支数:N = 3
  13. 论文正文写 sigma = 0.04(But GitHub数值为0.02)

4. 论文原始结果整理

为了后面做严格对比,先把论文正文里与本次复现直接相关的数据整理出来。

4.1 论文主表 Table 3:BreastPathQ 验证集结果

方法 ICC Kappa MSE
Baseline 0.901 [0.870, 0.930] 0.688 [0.602, 0.774] 0.015 [0.011, 0.019]
Peikari et al. 0.750 [0.710, 0.790] 0.380 - 0.420 未报告
Akbar et al. 0.830 [0.790, 0.860] 未报告 未报告
Rakhlin et al. 0.883 [0.858, 0.905] 0.689 [0.642, 0.734] 0.010 [0.009, 0.012]
ULTRA 0.941 [0.920, 0.950] 0.703 [0.620, 0.787] 0.011 [0.007, 0.014]

4.2 论文 Table 1:不同分支数 N 的消融实验

模型 ICC Kappa MSE
ULTRA (N=1) 0.919 0.688 0.013
ULTRA (N=2) 0.921 0.693 0.014
ULTRA (N=3) 0.941 0.703 0.011

结论:论文认为 N=3 最优。

4.3 论文 Table 2:LDL 与回归分支消融

模型 ICC Kappa MSE
ULTRA w/o KL 0.918 0.600 0.012
ULTRA w/o MSE 0.926 0.650 0.014
ULTRA 0.941 0.703 0.011

结论:论文认为 KL 分支与回归分支联合使用效果最好。


5. 复现目标

本次复现的目标一方面把程序跑起来,另一方面完整完成如下流程:

  1. 获取数据集
  2. 整理成仓库可识别的数据结构
  3. 在 H200 服务器上部署环境
  4. 运行第一阶段 backbone 训练
  5. 运行第二阶段 ULTRA 训练
  6. 从日志中提取最佳结果
  7. 与论文报告值逐项对比
  8. 分析差异来源

本次复现实际上完成了以上全部步骤。


6. 复现实验环境

6.1 服务器信息

训练时服务器实际资源状态如下:

  • GPU:NVIDIA H200 NVL × 2
  • 驱动版本:570.211.01
  • CUDA 版本:12.8
  • 内存:125 GiB
  • 目录磁盘可用空间:约 11 TB

因此本次训练主要使用 GPU 1

6.2 Python 与依赖环境

由于 H200 属于较新的 Hopper 架构,如果严格按仓库最初的 torch==1.8.0 安装,极有可能遇到 CUDA 兼容问题。因此本次采用“新版本 PyTorch + 保留算法逻辑”的兼容部署方案。

实际部署思路如下:

conda create -n ultra python=3.9 -y
conda activate ultra

python -m pip install --upgrade pip setuptools wheel
pip install torch==2.3.1 torchvision==0.18.1 --index-url https://download.pytorch.org/whl/cu121
pip install numpy pillow tqdm tensorboard pandas scipy scikit-learn seaborn statsmodels pingouin pretrainedmodels matplotlib imageio opencv-python scikit-image openpyxl

7. 数据获取

7.1 数据下载

从 BreastPathQ 页面获取下载入口后,实际下载了两个压缩包:

  1. SPIE_BreastPathQ2019_Training_Validation.zip
  2. SPIE_BreastPathQ2019_Testing.zip

7.2 数据解压后的结构检查

通过压缩包检查可知:

Training_Validation.zip 中包含:

train/

validation/

train_labels.csv

Testing.zip 中包含:

test_patches/

val_labels.csv

7.3 数据数量核对

实际统计结果为:

​ 训练集 patch:2394

​ 验证集 patch:185

​ 测试集 patch:1119

这与论文实验部分描述完全一致。

7.4 最终数据目录结构

为了让仓库代码直接读取,最终整理为:

~/data/BreastPathQ/ultra_data/
├── train/
├── validation/
├── test_patches/
├── train_labels.csv
└── val_labels.csv

其中图像目录使用了软链接方式整理,标签文件使用了实际 CSV 拷贝。


8. 代码获取与修复

8.1 代码下载

git clone https://github.com/PerceptionComputingLab/ULTRA.git
cd ~/ULTRA/ULTRA

8.2 复现中遇到的问题与修复

问题 1:config.py 的 Windows 注释触发 unicodeescape

仓库的 config.py 顶部作者注释中含有类似 \ULTRA\src\config.py 的 Windows 路径。Python 会把 \U 误识别为 Unicode 转义,直接报错。

修复方法:把顶部注释改为原始字符串形式,避免 \U 解析。

问题 2:train_backbone.pykappa() 返回元组

训练 backbone 时,日志格式化阶段报错:

TypeError: must be real number, not tuple

原因是 kappa() 返回元组,但原代码只用单变量接收。

修复方法:改为 kappa_, _ = kappa(...)

问题 3:GPU 选择问题

原仓库部分脚本默认写死 CUDA_VISIBLE_DEVICES="1"

复现时应看清并依据具体服务器情况来选择GPU。

由于目前我复现时计算机资源较为充足,因此继续沿用 GPU 1 实际上是更合理的选择。

问题 4:第二阶段预训练权重格式问题

train_ldl.py 不能直接读取第一阶段保存的完整 checkpoint,需要的是纯 backbone 权重。因此从第一阶段的 best_valloss_metric.pt 中额外抽取了:best_valloss_metric_backbone_only.pt


9. 第一阶段复现:Backbone 训练

9.1 第一阶段目的

第一阶段的目标是获得一个可靠的 backbone 初始化权重,为第二阶段 ULTRA 提供预训练特征提取器。

9.2 训练命令

nohup python -u train_backbone.py --data_path ~/data/BreastPathQ/ultra_data > ~/ultra_backbone.log 2>&1 &

9.3 训练设置

第一阶段日志显示:

model = resnet34

batchsize = 8

num_epoch = 150

lr_S = 1e-4

第一阶段完整跑满 150 epochs,并成功生成best_valloss.ptbest_valloss_metric.pt

之后又进一步抽取得到:best_valloss_metric_backbone_only.pt供第二阶段使用。

第一阶段不作为论文主表最终对比对象,因此本报告不把它作为最终成绩,只作为第二阶段的前置步骤。


10. 第二阶段复现:ULTRA 模型训练

10.1 第二阶段训练命令

本次第二阶段实际运行命令对应日志如下:

CUDA_VISIBLE_DEVICES=1 nohup python -u train_ldl.py \
  --data_path ~/data/BreastPathQ/ultra_data \
  --pre_train_path ~/ULTRA/ULTRA/runs/runs_resnet34_backbone_Apr05_23-23-48/best_valloss_metric_backbone_only.pt \
  > ~/ultra_ldl.log 2>&1 &

10.2 第二阶段真实配置

根据 ultra_ldl.log 头部信息,本次第二阶段真实运行配置如下:

architecture = LDL

model = resnet34

batchsize = 8

num_epoch = 150

num_discretizing = 100

num_raters = 3

std = 0.02

lr_S = 0.0001

lr_ratio = 0.1

lr_step_size = 60

augmentation = True

10.3 采用 std=0.02

本次实验采用 std=0.02 的原因是:

  1. 官方公开仓库默认参数就是 0.02
    train_ldl.py 默认参数中 --std 的默认值为 0.02
  2. 本次复现优先遵循“官方仓库可运行版本”
    由于首次目标是先在 H200 上流程测试,优先选择公开代码的默认参数完成可复现实验。

11. 复现与论文设置的差异

为了保证报告严谨,此章节指出GitHub的开源代码与论文中实际参数的差异问题

11.1 std=0.02 与论文 sigma=0.04 的差异

论文正文写的是sigma = 0.04

而本次真实运行的是:std = 0.02

两者本质上都是标签分布高斯函数的标准差参数。

0.020.04 更小,意味着分布更尖、更强调标签中心值。

11.2 学习率衰减步长差异

论文正文写的是每 100 epochs 衰减一次

本次实际日志显示lr_step_size = 60

11.3 数据增强差异

论文正文提到增强包括:水平翻转、垂直翻转、弹性变换等

而“自我认为”公开代码的实现主要是翻转增强。

11.4 损失权重差异

论文正文公式写的是:

L = L_KL + α L_MSE

并且正文写 α = 1

但GitHub的开源代码代码中实际使用的是:

loss = loss1 + 20 * loss2

即代码里回归分支损失权重实际上是 20,与论文正文表述不一致。

11.5 差异结论

基于官方公开仓库默认配置、在 H200 服务器上完成复现。


12. 复现结果

12.1 结果文件

第二阶段最终输出目录为:

runs/runs_resnet34_0.02_100_3_LDL_Apr06_00-11-22

目录中包含:best_valloss_metric.ptlogs.txt、多个中间 checkpoint_*.pt

12.2 最佳结果

logs.txt 全部 150 个 epoch 进行扫描后,得到:

best_icc 出现在 epoch 52

best_kappa 出现在 epoch 52

best_mse 出现在 epoch 52

best_pk 出现在 epoch 52

best_score = icc + kappa - mse 也出现在 epoch 52

最佳结果为:

指标 数值
Epoch 52
ICC 0.938
Kappa 0.710
MSE 0.011
PK 0.91177
综合分数 ICC + Kappa - MSE 1.637

bc271c7e04c53cb430aa814b07caf1b7

最终第 149 轮结果为:

指标 数值
ICC 0.921
Kappa 0.670
MSE 0.014
PK 0.89571

13. 与论文对比

13.1 主指标对比

指标 论文 ULTRA 本次复现最佳 差值
ICC 0.941 0.938 -0.003
Kappa 0.703 0.710 +0.007
MSE 0.011 0.011 0.000

13.2 相对差异分析

  1. ICC

    • 论文:0.941
    • 本次:0.938
    • 差值:-0.003
    • 说明:仅低 0.003,偏差极小
  2. Kappa

    • 论文:0.703
    • 本次:0.710
    • 差值:+0.007
    • 说明:本次结果略优于论文报告值
  3. MSE

    • 论文:0.011
    • 本次:0.011
    • 差值:0
    • 说明:完全一致

13.3 论文 95% 置信区间

论文报告的 95% 置信区间如下:

ICC:[0.920, 0.950]

Kappa:[0.620, 0.787]

MSE:[0.007, 0.014]

本次结果是否落在论文区间内:

指标 本次结果 论文 95% CI 是否落入
ICC 0.938 [0.920, 0.950]
Kappa 0.710 [0.620, 0.787]
MSE 0.011 [0.007, 0.014]

结论:本次复现的三项核心指标全部落在论文报告的 95% 置信区间内。

这意味着从统计对比角度看,本次复现结果与论文结果是一致且可信的


14. 局限

尽管本次结果非常接近论文,但有以下局限:

  1. 本次真实运行参数(按照GitHub)是 std=0.02,而论文正文写的是 sigma=0.04
  2. 学习率衰减步长与论文正文不一致
  3. 数据增强实现与论文文字描述不完全一致
  4. 代码中回归损失权重与论文公式文字不一致
  5. 本次只复现了主配置,没有额外复现实验表中的全部消融实验

15. 改进

如果后续时间允许,可继续如下两类补充实验:

15.1 论文正文参数版

单独重新跑第二阶段:

  1. std 改为 0.04
  2. 将学习率衰减步长改为 100
  3. 对比 0.020.04 两个版本的差异

15.2 论文消融实验版

根据论文 Table 1 和 Table 2,进一步补跑:

  1. 不同 N 的消融:N=1,2,3
  2. 去掉 KL 分支
  3. 去掉 MSE 分支

16. 结论

本次 ULTRA 论文复现已经基本成功完成。

在 BreastPathQ 验证集上,基于官方仓库默认 std=0.02 配置完成的第二阶段训练,在 epoch 52 取得了最佳结果:

ICC = 0.938

Kappa = 0.710

MSE = 0.011

PK = 0.91177

与论文报告的:

ICC = 0.941

Kappa = 0.703

MSE = 0.011

相比:

  1. ICC 仅低 0.003
  2. Kappa0.007
  3. MSE 完全一致
  4. 三项核心指标全部落在论文 95% 置信区间内
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐