OCTFlow / results /EXPERIMENT_LOG.md
MaybeRichard's picture
OCTFlow v1 (2026-06-21): 13 weights (core+downstream) + S0-S7 report + experiment log; public release
941b719 verified
|
Raw
History Blame Contribute Delete
8.72 kB

OCTFlow 下游评测 — 实验日志(整段会话整理)

  • 模型:SD3-medium(KL-VAE 16ch + 2B MMDiT,rectified flow)+ Vision-Banana 式指令微调
  • 环境:8× NVIDIA L20Y 80GB(h800,共享);base conda(torch2.10 / diffusers0.37 / sklearn / timm / smp / lpips);HF_HUB_OFFLINE=1
  • 基座:sd3_multimodal_base_v2/step-0240000.pt(探针 + 生成)、指令模型 sd3_vb_stageC_v3a/step-0030000.pt、层分割锚 sd3_vb_layer_100k/step-0030000.pt
  • 交付:reports/octflow_downstream_report.html(§0–§7,宽屏,~20MB) + 本日志
  • 总基调:逐维度诚实压到 competitive-非-SOTA;唯一独占能力 = 零样本指令泛化(§7) + 可共享数据。

一、实验时间线与结果

§2 多任务分类探针(14 任务 / 7 backend,冻结特征线性探针)

  • 动机:作为眼科 foundation,对标 RETFound/MIRAGE/VisionFM/DINOv2/DINOv3。
  • 方法:冻结编码器特征 + 线性探针;本会话从 7 任务扩到 14(+OCT-C8 8类/OCTDL/OCTID/Srinivasan/NEH/OLIVES/Messidor),头部 backend(ours/DINOv2/RETFound)3-seed。
  • 结果(14 任务平均 top1):DINOv2 0.849 ≥ RETFound 0.844 ≥ ours 0.837 > DINOv3 0.824 > MIRAGE 0.808 > VisionFM 0.796 ≫ 随机 0.621。
  • 结论:ours 第 3/7,落后 leaders 仅 ~0.01,但 14 任务逐项排名都 #2–#5、无一第一(MIRAGE 拿多数 OCT、DINOv2 拿眼底/UWF)。competitive-非-SOTA;远超只训 OCT 的 MIRAGE/VisionFM(它们在眼底/UWF 崩、我们三模态不崩)。

§3 分割:本模型 vs 公平微调 FM vs 监督 U-Net

  • 关键修正:原先 FM 基线是冻结探针(eval@224)=不公平下界,导致"碾压 FM"的错误结论。本会话改成 端到端微调 FM(编码器解冻 + 稠密解码头 + CE+Dice,eval@512,3-seed,fm_seg_ft.py)。
  • 结果(miou_fg,ours vs 最强微调FM vs U-Net):9层 0.53 / 0.59 / —;血管 0.51 / 0.51 / 0.66;OCTA大血管 0.53 / 0.50 / 0.61;FAZ 0.66 / 0.72 / 0.70;积液 0.63 / 0.66 / 0.78;视盘杯盘 0.74 / 0.80 / 0.79;OCTA500 0.82 / 0.84 / 0.85
  • 结论(诚实,推翻旧版):公平后 ours 多数任务略逊于为单任务单独微调的最强 FM(尤 DINOv2,差 0.03–0.09),仅 OCTA 大血管领先、血管打平;团块任务微调 FM 常反超 U-Net;细血管两者都低于 CNN U-Net(ViT patch 分辨率瓶颈)。

§4 去噪:本模型(生成式)vs 公平微调 FM

  • 方法:FM 也端到端微调 + L1+LPIPS(fm_denoise_ft.py)。
  • 结果:微调 FM 的 PSNR/SSIM 反而 ≥ 我们(MIRAGE-FT 28.2dB/0.77 vs 我们 27.6/0.71);我们只在感知 LPIPS 占优(0.135 vs 0.37–0.41,约 3×)。
  • 修复:对比图里 FM 列伪彩 = 我的解码头预测 3 独立通道,对灰度 OCT 无约束。改为预测 1 通道亮度→复制 3 通道,全列通道差归 0。

§5 生成式数据增广(分类)

  • 方法:train_classifier.py--mode aug(计数对齐的强经典增广对照);real / +经典增广 / +合成(我们 base 生成)× 数据量 × 3-seed。
  • 结果:Kermany(易,95%):+合成 > 仅真实(+0.5)但 ≈ 经典增广;EyePACS DR 分级(难,50–66%):+合成 ≈ 仅真实、**明显输给经典增广(−1.6 平均)**。
  • 结论:纯靠合成"涨点"不成立(易任务≈、难任务<经典增广)。

§6 生成式语义合成增广(分割,最完善范式)

  • 方法:训 mask→image 生成器(train_vb_sd3.py --mask2img:条件=彩色层图、生成=OCT;warmstart Stage A*;12k 步);用真 GT 掩膜(零噪声)生成多样外观 OCT →(真掩膜+合成图)对;ResNet-50 U-Net,real/经典增广/合成 × 标注预算 × 3-seed。
  • 结果(miou_fg,N=100/250/500/1000):仅真实 14.5/25.3/27.3/45.5;+经典增广 18.3/31.7/49.0/56.6;+合成 18.6/32.4/38.5/54.2。+合成远好于不加(+4+11),但 vs 经典增广:**低标注(100/250)打平、高标注(500/1000)输 −2−10**。
  • 结论:即便最完善范式,合成增广"涨点"≈/<经典增广、不稳超越。

§7 零样本指令泛化(护城河,核心成果)

  • 方法:zeroshot_spectrum.py — 同一指令模型(只训 9/5/3 层),测训练从未见过的层数(8/7/6/4/2,加进 seg_schemes.SCHEMES 但不在 SCHEME_WEIGHTS→训练永不采样)。
  • 结果(N=120,miou_fg):见过均值 0.430 vs 未见均值 0.441(未见甚至略高);跨设备零样本 OCTA500 二值视网膜 IoU 0.897、5 类 mIoU 0.480。montage 肉眼可见层数随 prompt 从 9 带变到 2 区、几何保留。
  • 结论:模型按 prompt 组合层数、非记忆。判别式 FM / U-Net 单一固定输出头做不到;换分割方案它们要重训一个网络,我们换一句 prompt 即可。这是论文真正且唯一独占的差异化。

二、失败 / 负结果 / 踩坑(诚实记录)

推翻的旧结论(本会话纠正)

  • "生成式分割/去噪碾压 FM" → 仅因 FM 用了冻结探针;公平微调后多数任务略逊。
  • hero 能力矩阵"分割顶尖 / 去噪第一" → 同因,需改/降级。
  • "合成增广是真卖点(mixed>real)" → 旧单 seed 无对照夸大;严谨后 ≈/<经典增广。
  • "线性探针打赢 RETFound" → 仅 kermany 单任务偶然;扩到 14 任务后 competitive-非-SOTA。

关键踩坑(供后续自检)

  • 协议不对等:冻结探针 vs 端到端微调是巨大不公平(细血管 0.0→0.5);对比必须同协议。
  • 饱和任务掩盖效应:kermany 95% 几乎无头部空间,增广效应测不出;难/低标注任务才显。
  • 去噪伪彩:灰度模态别预测多通道,要 1 通道→复制。
  • 半写 ckpt 竞态:16GB ckpt 写盘中被 ls -t|head -1 读到 → "failed finding central directory";评测/生成前应确认 ckpt 写完(本会话靠"评测在训练后串行"+ §6 加 sleep 40 规避)。
  • 掩膜粒度:mask→image 生成要用完整 9 层掩膜(与配对的 GT 标签一致),否则细层不匹配。
  • DINOv2 分辨率:probe 用 224、其他处 518,注意一致性。

三、成功 / 正向结论

  • §7 零样本指令泛化:未见层数 ≈ 见过(0.44/0.43)+ 跨设备 0.90 — 唯一独占能力,硬证据。
  • 公平、诚实、完整的下游基准:§0–§7,全部带对照、多 seed(头部)、宽屏报告。
  • mask→image 生成器:可生成匹配 9 层几何的真实 OCT(语义合成可行)。
  • 统一基座:一个模型换 prompt 覆盖 生成 + 全部分割方案(含未见)+ 去噪。

四、诚实定位(论文叙事骨架)

单一生成式指令通才:逐任务 competitive-非-SOTA(分类/分割/去噪/增广都不是单点夺冠),但 ①统一基座一个 prompt 覆盖生成+7类分割+去噪;②零样本指令泛化(§7,判别式做不到);③可共享/可定制数据(隐私/补稀有类)。冲 Nature 的核心 = ②+③+覆盖面,而非任何单点 SOTA。


五、后续计划

  1. 手稿对齐(最高优先):把诚实结论同步进 octflow_main.tex —— 砍掉"碾压 FM / 分割去噪第一 / 增广真卖点"等过度声明;把 §7 零样本指令泛化立为主结果 + hero 矩阵据实重画。
  2. 临床(用户侧,外部 gate):多中心外部验证 + 医生 reader study(Nature 硬门槛)。
  3. 可选:补 octa/oct_enface 数据后重训分清两者(task #51,等医院数据);§7 再加单层选择/色彩跟随两条指令轴做厚。
  4. 磁盘清理:见下,~1TB 中间权重待清(需确认)。

六、产物 / 文件清理摘要

  • 脚本(本会话,均 pilot/path1/scripts/foundation/scripts/):fm_seg_ft.py/fm_denoise_ft.py(公平微调 FM)、train_vb_sd3.py --mask2imggen_mask2img.pycompare_panels_ft.py/compare_denoise_ft.pytrain_classifier.py(+aug/+label)、build_seg_aug_manifests.pyunet_seg_baseline.py(+strong-aug)、zeroshot_spectrum.pymultitask_probe.py(+7任务)、build_multitask_report.py(§0–§7)、各 run_*.sh
  • 代码审查:无规则违反(weights_only=False 全部到位)、无致命 bug(实验均验证通过);仅robustness 提示(半写 ckpt 竞态、硬编码路径、seg_schemes.SCHEMES 加了 eval-only 未见方案)。
  • 磁盘清理(已执行 A+B,2026-06-21):results/ 1.5T → 396G(释放 ~1.1T)。删 61 个中间步 ckpt(每个实验仅留最新/锚点)+ 2 个被取代的整目录(sd3_vb_vessel 原始、sd3_vb_lesion_fluid)。保留:base_v2/240k、stageA_v3/20k、stageC_v3a/30k、layer_100k/30k、layer_100k_v3b/15k、mask2img/12k、long_9mod/150k、各下游 _100k/_v3b 最新(step-4000)、foundation/(24G 结果 json+图)。未删 Tier-C(privacy_gen×3 / denoise_ft / stageC_v3b2,用户选择保留)。脚本 /tmp/cleanup_ckpts.sh(留存可复核)。