Downloads · 30 days
0
lzeeorno666/HBFormer-Synapse-Multi-Organ-Segmentation
HBFormer-Synapse-Multi-Organ-Segmentation is a image segmentation model from lzeeorno666. Use it for the image segmentation task on the model card, and read the license before you ship it in a product. The card lists the license as apache-2.0.
Accepted by IEEE International Conference on Bioinformatics and Biomedicine (BIBM 2025)
Downloads · 30 days
0
Access
Public
Updated Dec 18, 2025
Repo size
262 MB
Likes
0
Public
Click a slice to open those files.
.pth262 MB · 100%
From the Hugging Face model README
Accepted by IEEE International Conference on Bioinformatics and Biomedicine (BIBM 2025)
If you find our work helpful for your research, please cite:
@article{zheng2025hbformer,
title={HBFormer: A Hybrid-Bridge Transformer for Microtumor and Miniature Organ Segmentation},
author={Zheng, Fuchen and Chen, Xinyi and Li, Weixuan and Li, Quanjun and Zhou, Junhua and Guo, Xiaojiao and Chen, Xuhang and Pun, Chi-Man and Zhou, Shoujun},
journal={arXiv preprint arXiv:2512.03597},
year={2025}
}
HBFormer: A Hybrid-Bridge Transformer for Microtumor and Miniature Organ Segmentation
University of Macau & SIAT CAS
AFFSegNnet_VMUnetVis/
├── configs/ # 各数据集训练配置
│ ├── config_setting_synapse.py
│ ├── config_setting_lits2017.py
│ ├── config_setting_ACDC.py
│ └── config_setting_bladder.py
├── datasets/ # 数据集加载与增广
│ ├── dataset.py # Synapse(.npz 切片 / .npy.h5 体)
│ ├── dataset_lits2017.py
│ ├── dataset_ACDC.py
│ └── dataset_bladder.py
├── models/ # 模型实现
│ ├── DWSegNet.py
│ ├── HBFormer.py
│ ├── DZZMamba.py
│ └── vmunet/
├── engine_synapse.py # 训练/验证/评估(Synapse专用)
├── engine_lits2017.py # LiTS2017 训练/验证
├── engine_ACDC.py # ACDC 训练/验证
├── train_synapse.py # Synapse 训练入口
├── train_lits2017.py # LiTS2017 训练入口
├── train_ACDC.py # ACDC 训练入口
├── train_bladder.py # Bladder 训练入口
├── test_synapse.py # Synapse 体数据评估(如有)
├── pre_trained_weights/ # 预训练/外部权重
├── results/ # 输出:日志/权重/评估
├── 3D_Vis/ # 3D/切片查看工具
└── utils.py # 通用工具、日志、优化器/调度器构建
conda create -n hbformer python=3.8 -y
conda activate hbformer
pip install torch==1.13.0 torchvision==0.14.0 torchaudio==0.13.0 \
--extra-index-url https://download.pytorch.org/whl/cu117
pip install packaging timm==0.4.12 pytest chardet yacs termcolor
pip install submitit tensorboardX triton==2.0.0
pip install scikit-learn matplotlib thop h5py SimpleITK scikit-image medpy
pip install opencv-python pandas tqdm nibabel scipy einops
可选:
pip install ptflops # 计算FLOPs/参数量
也可参考:ui/vmunet_environment.yml 与 ui/vmunet_conda_env.txt。
目录要求(与代码默认一致):
./data/Synapse/
├── lists/
│ └── lists_Synapse/
│ ├── all.lst
│ ├── train.txt
│ ├── test_vol.txt # 体数据验证/测试
│ └── test_slice.txt # 切片验证(与训练一致的数据预处理)
├── train_npz/ # 切片级 .npz(训练 & 切片验证使用)
│ └── caseXXXX_sliceYYY.npz # 含键 image/label
└── test_vol_h5/ # 体数据 .npy.h5(体验证使用)
└── caseXXXX.npy.h5 # 含键 image/label
### Synapse(8类)test result follow SwinUnet‘s test framework
================================================================================
测试完成!
================================================================================
Slice评估 Dice: 0.9856, HD95: 0.0000, mIoU: 0.9743
Volume评估 Dice: 0.8782, HD95: 6.9185
结果保存路径: test_result/HBFormer_synapse
️ 预测可视化: test_result/HBFormer_synapse/prediction_visualization
注意力热图: test_result/HBFormer_synapse/attention_heatmaps
⚡ 激活热图: test_result/HBFormer_synapse/activation_heatmaps
================================================================================
获取方式:可参考 Swin-UNet 的 Synapse 数据下载与预处理,或使用你已有的预处理结果。若需自制 .npz,可参考 data_proprecessing.py 示例将 NIfTI 切片为 .npz(确保 .npz 内含键 image 与 label,并与 test_slice.txt 命名一致)。
test_slice.txt 样例(每行一个切片名,不带扩展名):
case0001_slice001
case0001_slice002
...
./data/LITS2017_nii/
├── CT/ # volume-*.nii
└── seg/ # segmentation-*.nii
./data/ACDC/
└── database/
├── training/patient*/patient*_frame*.nii.gz
└── testing/patient*/
./data/Bladder/
├── images ...
└── masks ...
所有训练入口脚本会读取对应配置文件(configs/),日志/权重输出目录位于 results/{Model}_{Dataset}/。
在 configs/config_setting_synapse.py 中:
available_models = ['DWSegNet', 'AFFSegNet', 'vmunet', 'HBFormer']network = 'HBFormer'from configs.config_setting_synapse import setting_config
setting_config.set_model('DWSegNet') # 或 'HBFormer'、'vmunet'、'AFFSegNet'
# Synapse(包含切片验证)
python train_synapse.py
# LiTS2017(支持交叉验证)
python train_lits2017.py
# ACDC
python train_ACDC.py
# Bladder
python train_bladder.py
train_synapse.py 内调用 val_one_epoch_slice 自动完成(读 train_npz/ 与 test_slice.txt)。engine_synapse.val_one_epoch(读 test_vol_h5/ 与 test_vol.txt)。engine_*.py 中的验证逻辑与 test_*.py 测试脚本(如提供)。训练过程会在 results/.../log/ 写入训练/验证日志,并将指标记录到 CSV:
train_record.csv(loss、avg_dice、mIoU、各器官Dice)val_record.csv(avg_dice、avg_hd95、mIoU、各器官Dice/HD95)权重保存:
checkpoints/best.pth / best_dice.pth(最佳)checkpoints/latest.pth(最近)save_interval 定期保存(见各配置)。目录:pre_trained_weights/
提示:若使用 AFFSegNet/DWSegNet/HBFormer 的外部权重,可在各自 model_config 中设置 load_ckpt_path(若脚本支持),或在训练脚本中按需加载。
engine_synapse.py 相关函数)。3D_Vis/ 与 Pathplanning/ 提供三维与切片查看工具,可按需运行其中的 run.py/main.py 类型脚本进行交互式浏览。.npy.h5?请确认 datasets/dataset.py 的逻辑:split in ["train","test_slice"] 读取 .npz,split in ["test_vol","val_vol"] 读取 .npy.h5,并确保 list_dir 下存在对应的 test_slice.txt/test_vol.txt。ui/vmunet_environment.yml 创建一致环境。results/{Model}_{Dataset}/ 是否已创建;脚本会自动创建必要目录。若本项目对您的研究有帮助,欢迎引用或在论文中致谢本仓库。
本节总结从“优化 HBFormer 性能”开始,到后续结构调整、SwinBackbone 兼容性修改以及多轮 Bug 排查直至
train_synapse.py能够在seg环境中正常启动训练的全过程,便于后续复现和维护。
timm 的 SwinTransformer 实现,随着库版本升级,Swin 的接口(特别是 PatchEmbed 输出格式、Stage/Block 的输入形状约定)发生变化,导致 HBFormer 中的 Swin 作为编码器时出现维度不匹配与运行错误。B x C x H x W 形状及通道数,以便后续 proj_enc* 等 1×1 卷积投影层能正确工作。基于上述目标,整个优化过程大致分为三类问题:
下面按时间线梳理主要问题、排查思路与最终解决方案。
seg 环境下运行:source ~/anaconda3/etc/profile.d/conda.sh
conda activate seg
cd /home/ipprlab/zfc/AFFSegNnet_VMUnetVis
python train_synapse.py
models/swin_backbone.py:
B, L, C = x.shape 时出现 “too many values to unpack (expected 3)” 或 “not enough values to unpack”。x.transpose(1, 2).reshape(B, C, h, w) 时提示目标形状与 numel 不一致。sqrt(L) 或硬编码的 H=W=int(L**0.5) 恢复空间尺寸的方式,在某些版本的 Swin 中已经不再成立。timm 中 SwinTransformer 相关模块(特别是 SwinTransformerStage、SwinTransformerBlock 和 PatchEmbed)对输入/输出形状有严格约定:
PatchEmbed 输出往往是 4D 张量:(B, H, W, C) 或旧式 3D (B, L, C),取决于实现版本。SwinTransformerStage 和 SwinTransformerBlock 内部的 _attn 等函数一般要求 输入为 (B, H, W, C),并在内部完成 window 分块与还原。SwinBackbone 假定 Swin 所有层都是 (B, L, C) 形式并通过 sqrt(L) 恢复 H, W,这与当前 timm 版本存在偏差。因此:
B×L×C 再传入,触发 layer norm 或 _attn 内部报错。直接 probe PatchEmbed 输出形状
seg 环境下编写最小脚本,打印 self.backbone.patch_embed(x) 的形状:from models.swin_backbone import SwinBackbone
import torch
m = SwinBackbone(pretrained_path=None, img_size=256, window_size=8)
x = torch.randn(1, 3, 256, 256)
pe_out = m.backbone.patch_embed(x)
print('patch_embed out shape:', pe_out.shape)
(B, H, W, C),例如 (1, 64, 64, 96)。对照 timm 源码理解 Swin 正确的前向期望
sed 查看 timm/models/swin_transformer.py 内 SwinTransformerBlock 和 SwinTransformerStage 的 forward:
SwinTransformerBlock.forward 的第一行通常是:B, H, W, C = x.shape。SwinTransformerStage.forward 则基本是:
def forward(self, x):
x = self.downsample(x)
x = self.blocks(x) # blocks 内部同样用 HWC
return x
B×L×C。重新设计 SwinBackbone.forward 的数据流
(B, 3, H, W)。(B, H_pe, W_pe, C),整个 Swin 主干内部一直以 HWC 形式前向。B×C×H×W。x 传入 layer(x)。for idx, layer in enumerate(self.backbone.layers))之后,x 的形状是 (B, H_i, W_i, C_i)。x.permute(0, 3, 1, 2).contiguous() 得到 feat_i,作为 HBFormer 的多尺度特征。兼容 window_size 为 tuple 的情况
int 或 tuple,如果要基于 window 对 H/W 做取模或 pad,需要统一成标量:
win = window_size[0] if isinstance(window_size, (tuple, list)) else window_size
win 计算需要的 pad,避免 TypeError: unsupported operand type(s) for %: 'int' and 'tuple'。在多轮调整过程中出现了典型的几类报错:
ValueError: too many/not enough values to unpack
B, L, C = x.shape 或 B, H, W, C = x.shape 时,x.dim() 与期望不一致。print('before layer', idx, x.shape)
RuntimeError: shape '...' is invalid for input of size ...
B×L×C 误 reshape 成 B×C×H×W,而 H×W≠L。sqrt(L) 推测 H、W” 的做法。sqrt(L) 推断,改为在 PatchEmbed 处显式记录 h, w,并在整个 forward 流中沿用/更新这两个变量。LayerNorm 维度错误:Given normalized_shape=[96], expected input with shape [*, 96], but got [1, 64, 96, 64]
SwinTransformerBlock 传入了 B×H×C×W 或 B×W×H×C 等错误顺序的 4D 张量。x.transpose(1,2))之后再调用 layer(x),破坏了 block 对输入为 [*, C] 的 LayerNorm 假设。(B, H, W, C),不要额外 permute C 轴。通过一轮轮修正,SwinBackbone 最终被简化为:
F.pad)。在解决完 SwinBackbone 的大部分 shape 问题后,train_synapse.py 在进行 FLOPs 统计(cal_params_flops 调用 thop.profile)或前向时出现:
RuntimeError: Given groups=1, weight of size [96, 192, 1, 1], expected input[1, 96, 64, 64] to have 192 channels, but got 96 channels instead
这类报错典型地说明:
weight 的 in_channels 与输入特征图的通道数不一致。
weight of size [96, 192, 1, 1] 为例:
in_channels=192, out_channels=96。结合 HBFormer 代码,可以判断这些卷积层多为 encoder 特征通道投影层,例如:self.proj_enc2(c2)、self.proj_enc3(c3) 等。
预期设计:
C1=96, C2=192, C3=384, C4=768(对应 Tiny/Small 不同配置)。proj_enc2 的卷积 weight 通常设为 [C_target, C2, 1, 1]。实际情况:
打印多尺度特征的 shape
c1, c2, c3, c4)的 shape:feats = self.MWAencoder(x_in)
for i, f in enumerate(feats):
print(f"feat[{i}] shape:", f.shape)
feat[0]: (B, 96, H/4, W/4)feat[1]: (B, 192, H/8, W/8)feat[2]: (B, 384, H/16, W/16)feat[3]: (B, 768, H/32, W/32)(根据具体 Swin 配置)。若发现通道不对,应优先检查 SwinBackbone 中对应 stage 的 permute/裁剪逻辑
embed_dim 和 out_dim 决定,几乎不会在 stage 间自行“变成” 96;.view(B, H, W, C) → 通道/空间轴顺序搞错;.flatten(2) 与 .transpose(1, 2) 的顺序使用不当,导致 C 与 HW 维互换。permute(0, 3, 1, 2) 转回 BCHW。避免临时性的“改卷积通道数”补丁
proj_enc2 的 in_channels 改为 96;但这只是在现有错误特征通道基础上的“将错就错”,最终,伴随 SwinBackbone 的 shape 流顺利梳理清楚,多尺度特征通道恢复正常后,上述卷积通道数错误随之消失。
train_synapse.py 在 main 函数中会调用:cal_params_flops(model, config.input_size_w, logger)
其内部通过 thop.profile(model, inputs=(input,)) 对整个 HBFormer+SwinBackbone 进行一次前向推理,用于统计参数量与 FLOPs。
这一步非常“严格”,因为:
thop.profile 帮我们提前扫清了一些潜在的 shape/接口问题。调试建议:
cal_params_flops 调用,待模型结构稳定后再恢复统计。cal_params_flops 中构造的 dummy input 尺寸与真实训练尺寸不一致导致的。本次调试中,我们保持了 FLOPs 调用不变,通过修正 SwinBackbone 与 HBFormer 的接口,使其能够顺利完成完整前向,保证统计结果可用。
尽量遵循第三方库的“官方数据流”
timm 这类不断演进的模型库,强行沿用早期版本中 B×L×C 的习惯做法非常容易在升级后出问题。forward 的输入/输出约定(如 HWC vs BCHW);Backbone 封装中尽可能少地做 shape hack,优先使用库内部的 set_input_size 等接口。记录并显式维护空间尺寸 H/W,而非依赖 sqrt(L)
sqrt(L) 自动推断空间尺寸非常脆弱。H, W 以及 pad 量;在 encoder-decoder 结构中优先保证“特征通道语义”的稳定性
利用 FLOPs/参数统计作为“结构体检”工具
thop.profile 虽然只是用来算 FLOPs,但其“全网前向一次”的特性,本节记录的 HBFormer + SwinBackbone 兼容性修复与性能调优过程,旨在作为后续结构修改和 timm 升级时的参考。若未来更换为新的 Swin 变体或其他 Transformer backbone,推荐沿用类似的调试思路: