恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
IRDiff 图像修复框架:扩散先验与可学习退化算子的统一实现
首页
资讯中心
/
IRDiff 图像修复框架:扩散先验与可学习退化算子的统一实现
IRDiff 图像修复框架:扩散先验与可学习退化算子的统一实现
发布时间:2026/10/15 10:25:57
简介IRDiff 完整评测文档与可运行代码资源包面向分子生成、扩散模型及药物设计方向的研究者。IRDiff 是基于蛋白质-配体相互作用的检索增强 3D 分子扩散模型由清华深圳国际研究生院与鹏城实验室团队提出发表于 ICML 2024通过精心挑选的参考配体集合引导扩散模型生成目标感知的分子在 CrossDocked 2020 数据集上取得领先的结合亲和力表现。资源包含 1 个 PDF 文档压缩包约 12.23MB文档完整呈现项目背景、模型框架PMINet、评测过程与结果并详细标注代码报错位置及修改方法、缺失模块文件、测试案例与个人分析注释。修正后的代码可针对特定蛋白口袋体系进行分子生成计算 vina_score、QED、SA 等指标也支持自定义数据集的微调与训练便于读者理解算法细节、复现实验并开展后续改进。目前已有 121 人学习下载。1. 接手 IRDiff 完整评测文档加可运行项目代码先搞清楚它到底是什么大多数人第一次接触 IRDiff是带着一份完整评测文档和一套可运行项目代码来的第一反应往往是这跟我跑过的图像修复网络有什么区别。IRDiff 是一套统一图像修复框架核心思路是用预训练的扩散模型当图像先验再用一个可学习的退化算子去模拟噪声、雨纹、模糊和下采样在采样过程中用观测图把生成结果逐步拉回到退化约束上。它跟 DPS、DDRM 这类免训练修复方法不同退化算子不是手工假设的线性模型而是训练出来的。跟 Restormer 这类专用修复网络不同它不需要针对每个任务训练一个端到端模型。这套方案最合适的人群有两种一是复现扩散修复基线做对比实验的研究者二是想借扩散先验做自定义退化任务、又没有资源重训大模型的工程师。这份文档加代码能帮你绕开的正是从头训扩散模型和写评测脚本这两件最耗时的事。2. IRDiff 原理拆解冻结的扩散先验、可学习退化算子与采样引导2.1 骨架冻结的扩散先验与可学习退化算子先解释为什么修复可以交给扩散模型。扩散模型的生成过程本质上学到的是“一张自然图像长什么样”而修复任务可以重新理解为带约束的生成问题结果既要落在自然图像流形上又要满足退化约束。IRDiff 把这两件事拆成两个模块各管一摊。第一个模块是预训练的无条件扩散模型。所谓无条件指它训练时只学了从噪声生成自然图像没有专门学过按退化图还原。IRDiff 在整条修复链路里冻结它不更新任何权重。这么设计最直接的好处是自然图像分布是跨任务共享的去噪、去雨、超分、去模糊最终都要落到“生成一张可信的干净图像”上一个通用先验就够用不用每个任务重训生成模型。第二个模块是可学习退化算子。它以一张干净图为输入输出一张与观测图同尺寸的退化结果。超分任务是先下采样再加模糊去雨任务是叠加雨纹去噪任务是加噪声。算子用一个带下采样结构的小网络实现训练时用一批干净图像和对应合成退化图像做监督目标函数可以写成L_deg || h(x; φ) - y_syn ||^2其中 h 是退化算子φ 是它的参数。更完整的做法是给这个算子额外输入一个退化条件向量把任务类型、超分倍数、噪声强度这些信息传进去这样多任务可以共用一个算子网络这也是评测文档里“统一模型”这个表述的来源。这里有一个最容易看走眼的地方退化算子学习的方向是从干净图到退化图不是从退化图到干净图。很多第一次看代码的人会在训练脚本里找“修复网络”结果找不到因为真正被训练的小模块只有这个退化算子真正干修复活的是那个冻结的扩散先验。2.2 采样引导残差是怎么回传到生成过程的推理阶段是这套框架最不直观的部分。扩散模型采样时从随机噪声出发逐步去噪到干净图。每走一步当前状态会经过去噪网络网络会预测一张“当前估计的干净图”。IRDiff 的关键动作就发生在这里每一步做四件事把当前估计的干净图 x̂0 送进退化算子得到 h(x̂0)计算 h(x̂0) 与观测图 y 的均方误差求这个误差对当前采样状态的梯度沿梯度方向修正这一轮的去噪结果进入下一步采样。这样走完整个采样链生成图会同时满足两个条件看起来自然扩散先验保证又和观测图对得上引导梯度保证。这里有个重要认知推理时所有网络参数都冻结只有采样状态在动。换任务时不需要重新训练扩散先验只需要重新训练那个小的退化算子几十到一百个 epoch 通常就能收敛这是 IRDiff 这类方案工程上最划算的地方。有一个参数值得单独说引导强度代码里一般叫 guide_scale 或 guidance。它控制引导残差对采样结果的修正比例。这个值太小结果像普通扩散生成图和观测对不上太大结果被硬拉回观测先验失效出现噪点和伪影。常见调试手法是从 1.0 往下试每次除以 10观察修复结果在“约束满足”和“图像自然度”之间的变化。2.3 评测文档的三张表PSNR、SSIM、LPIPS 该信哪个一份完整的 IRDiff 评测文档核心常常是几张指标表。横向是任务去噪、去雨、超分、去模糊纵向是 PSNR、SSIM、LPIPS对比对象一般分成两类一类是专用修复模型一类是 DPS、DDRM 这类免训练引导方法。读这张表要抓三件事。第一看它是不是一模型打全场。IRDiff 类方法的价值主张是统一性固定扩散先验换任务只换退化算子。如果专用模型在单项任务上 PSNR 更高这是正常的不代表框架失败还要看综合维度和部署成本。第二看它用了几步采样。扩散修复里采样步数是质量与耗时的最大杠杆1000 步和 50 步差一个量级的时间复现时不看这一行比较结论就不公平。第三LPIPS 比 PSNR 更能反映扩散先验的价值。PSNR 对像素级误差敏感对纹理细节不敏感LPIPS 在感知层面更接近人眼。扩散修复的典型特点就是像素指标略逊、感知指标领先评测文档里两类指标并列不是没道理的。3. 把 IRDiff 跑起来环境、数据准备与两条最小命令3.1 依赖与硬件门槛先看 requirements再决定拿什么卡跑跑 IRDiff 这类扩散修复工程依赖可以分成三组核心计算用 PyTorch 和 torchvision数据与图像处理用 numpy、opencv、Pillow、scikit-image评测工具用 lpips 和 pytorch-fid。最后一组最容易缺评测脚本跑到最后一步报 ModuleNotFoundError 的十有八九是它没装。PyTorch 版本搭配 CUDA 版本以自己机器的驱动为准但我建议优先按仓库 requirements 里锁定的版本装没锁再选当前稳定的 2.x。常见做法是新建一个独立环境避免和别的项目互相污染依赖conda create -n irdiff python3.9 -y conda activate irdiff pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txt硬件方面12GB 显存是比较现实的起步线。原因是采样时的引导需要对当前状态回传梯度计算图长度和采样步数成正比远比训练一个小分类头占显存。8GB 卡跑 50 步很容易 OOM正确做法是先用 20 步把流程跑通再往上加步数。CPU 不是不能跑但只能用来验证代码逻辑完整采样在 CPU 上是灾难别浪费时间。3.2 数据准备与配置文件在线生成退化对统一像素范围数据目录我一般按“一个任务一个子目录”组织每个任务下面分 train、val、test。以去噪为例data/ denoise/ train/ # 干净图像训练时现加噪声 val/ test/ deblur/ train/这里要注意一个实现上的差别有些工程在数据准备阶段就生成退化图像离线固化到硬盘有些则在训练循环里现算。IRDiff 训练退化算子时推荐用在线生成。原因是退化算子要学习的就是“干净到退化”的映射如果训练数据是离线固定的算子学到的只是这批噪声实例的拟合泛化能力差。在线生成时每个 epoch 的噪声强度、雨纹方向、模糊核都不一样退化算子见到的输入分布更宽学出来的映射更稳定。配置用 YAML 管理。典型训练配置的关键字段如下我按调试频率从高到低排data_root: ./data/denoise save_dir: ./logs/denoise batch_size: 8 lr: 1e-4 max_epochs: 100 sample_steps: 50 # 训练退化算子时用不到推理时才生效 guide_scale: 0.5 # 引导强度推理时最常调 seed: 42 pixel_range: [-1, 1] # 所有 tensor 的像素范围约定pixel_range 这个字段值得重点盯。它决定你读图后把像素归一化到什么范围后面一大堆翻车都跟它有关。seed 也重要评测文档多数会写明随机种子配置里不设的话采样噪声每次不同PSNR 能差 1dB 以上复现就无从谈起。3.3 两条最小命令训练退化算子再采样修复拿到代码后我习惯先把入口整理成两条命令一条训练退化算子一条采样修复。不同仓库的脚本名不一定一致但职责基本都是这两个角色。# 训练退化算子超分 ×4 任务示例 python train_degradation.py --config configs/sr4.yaml # 测试修复单张图推理 python sample.py \ --config configs/sr4.yaml \ --checkpoint ./logs/sr4/best.pt \ --input ./data/test/hr_001_lr.png \ --output ./results/sr4/hr_001_sr.png \ --sample_steps 50 \ --guide_scale 0.5train_degradation.py 负责训练那个可学习退化算子--config 指向的 YAML 决定数据路径、学习率和训练轮数。训练产物 checkpoint 里只有退化算子网络的权重不要拿它当修复模型直接输出结果。sample.py 是完整推理入口读入退化图、初始化噪声、跑采样循环在循环里调用冻结的扩散先验和训练好的退化算子最后写出修复图。--sample_steps 是采样步数直接决定推理耗时。50 步是质量和速度的常见折中20 步能看个大概但细节粗糙100 步适合最终评测出指标。--guide_scale 就是引导强度这是全项目最值得单独调试的参数。这两条命令能跑通代码主链路就跑通了剩下的事都是参数微调。4. 复现评测文档里的指标先抄默认值再算 PSNR/SSIM/LPIPS4.1 实验设置速查表从评测文档里抄默认值复现评测文档的第一步不是跑代码而是建一张实验设置速查表。评测文档的正文或脚注里通常藏着这些默认值要逐项摘出来项目默认值配置位置随机种子通常是 42 或 0配置 seed 字段测试图像数100 张/任务评测文档测试集说明采样步数50 或 100采样脚本参数 sample_steps引导强度0.1~1.0 之间采样脚本 guide_scale图像尺寸256×256 或 512×512 中心裁剪配置 preprocess这张表的价值在于代码仓库里的 config 默认值和评测文档不一致的情况经常发生。我遇到过不止一次仓库里 sample_steps 写 20评测文档写 100直接跑出来的结果当然对不上。以评测文档为准改配置再跑这是复现的第一条规矩。4.2 跑完怎么评评测脚本的三个隐藏错误点评测脚本是整条链路里最容易复制错的部分。下面是一个我反复使用的三指标评估脚本import numpy as np from skimage.metrics import peak_signal_noise_ratio as psnr from skimage.metrics import structural_similarity as ssim import lpips import torch def evaluate(restored, target, netalex, pixel_range1.0): # restored/target: [H,W,C] or [C,H,W], RGB, 0~1 restored np.clip(restored, 0, 1).astype(np.float32) target np.clip(target, 0, 1).astype(np.float32) psnr_val psnr(target, restored, data_rangepixel_range) # 图像是 [H,W,C] ssim_val ssim(target, restored, data_rangepixel_range, channel_axis-1) # LPIPS 需要 [B,C,H,W]输入范围是 [-1,1] loss_fn lpips.LPIPS(netnet) t1 torch.tensor(restored).permute(2, 0, 1).unsqueeze(0) * 2 - 1 t2 torch.tensor(target).permute(2, 0, 1).unsqueeze(0) * 2 - 1 lpips_val loss_fn(t1, t2).item() return psnr_val, ssim_val, lpips_val这个脚本有三个容易出错的地方。第一ssim 的通道参数在不同版本里写法不同旧版 skimage 是 multichannelTrue新版是 channel_axis-1版本不对会直接报错或算错。第二LPIPS 期望输入范围是 [-1,1]不是 [0,1]忘了乘 2 减 1LPIPS 数值会整体被放大。第三data_range 必须和像素范围对应图是 0~1 就传 1.0传 255 会让 PSNR 和 SSIM 整体偏低。评测文档里如果提到“边缘裁剪”意思是评估前把图像四周裁掉若干像素因为扩散模型的边界填充会带边缘伪影。不做这步PSNR 会被边缘区域拉低在小尺寸图像上差距能被放大到 0.5dB 以上。看文档里有没有这一句有就照做。4.3 数字对不上论文三个自检方向跑完的数字比评测文档低是这个方向最常见的情况。别急着怀疑代码按下面三个方向查。第一退化算子对不对。每个任务有独立的退化算子 checkpoint用去噪的去跑超分结果一定会崩。先确认 checkpoint 指向的是当前任务对应的训练产物。第二采样设置对不对。把 sample_steps、seed、guide_scale 三个值和速查表逐一对照。seed 最容易被忽略因为采样噪声随机PSNR 会跳guide_scale 差一个数量级修复结果不是“不贴合观测”就是“过度贴合观测”指标都低。第三数据加载和配对的顺序对不对。输出文件名如果命名不统一脚本按字符串排序配对结果图和标签对不上指标会惨不忍睹。先存一张并排对比图肉眼确认配对无误再上指标。5. IRDiff 落地避坑显存 OOM、像素范围与偏色问题排查5.1 显存不够梯度回传计算图和采样步数成正比现象batch size 已经调到 1采样步数降到 20显存还是溢出。原因IRDiff 的引导需要对当前采样状态回传梯度这要求保留从采样状态到干净图估计、再到退化算子的完整计算图。如果代码没有手动截断每步的图整条采样链的计算图会逐层叠加显存占用随步数线性上涨。解决优先做两步。第一在采样循环里对引导传播路径做 detach 控制只保留当前步需要的梯度这一步通常能省一半以上显存。第二降低引导频率每 5 步做一次引导而不是每步都做对最终指标影响有限显存和时间都明显下降。另外开启 fp16 混合精度在这个场景收益明显12GB 显存基本可以跑 50 步以内但要注意反向传播的数值稳定性。5.2 退化算子不收敛先查像素范围是否统一现象训练 loss 几十个 epoch 几乎不降或者输出的退化图像整体偏亮或偏暗一个固定倍数。原因退化算子的输出范围和监督信号的像素范围不一致。典型情况是扩散先验内部用 [-1,1]而训练脚本读图后停留在 [0,255] 或 [0,1] 就送进算子。梯度方向没问题但数值尺度差了几十倍优化过程在小学习率下原地踏步大学习率下震荡。解决在训练脚本开头加一个断言检查输入 tensor 和标签 tensor 的范围一致并把 pixel_range 写进配置。我习惯统一用 [-1,1]读图、归一化、进网络、退化算子输出全部保持在同一数值约定下。这样扩散先验、退化算子、引导 loss 三段代码的数值基础完全一致后续一切调参才有稳定前提。5.3 修复结果发灰、偏色先怀疑通道顺序和归一化现象修复结果整体饱和度低像蒙了一层灰或者颜色通道错位。原因两个高频来源。第一是 OpenCV 读图默认返回 BGR而扩散先验训练时用的是 RGB通道顺序不一致生成结果颜色必然错乱。第二是引导强度过大把生成结果硬拉到观测约束上而观测图和先验分布范围不一致结果被拉出伪影和灰色。解决读图后立刻转成 RGB并维护一条固定输入链路读图、转 RGB、归一化、送采样脚本所有任务共用。排查发灰问题时先把 guide_scale 降到原来的十分之一跑一张如果颜色恢复问题在引导强度如果还是灰的去查通道顺序和归一化链路。5.4 指标比评测文档低一截先对速查表再对评测口径现象PSNR 比文档低 2dB 以上SSIM 也低但修复结果肉眼看上去没问题。原因大多数时候不是模型坏了是复现条件不一致。采样步数、随机种子、测试集条数、边缘裁剪任何一项不同都能造成这个量级的偏差。尤其是测试集条数文档用 100 张求平均你只跑 10 张几张难例就能把均值拖下来。解决按 4.1 的速查表一字不差核对设置再单独检查评测脚本是否做了边缘裁剪、图像尺寸是否一致。最后把生成结果和标签存成并排图肉眼确认不是系统性偏暗偏糊。对比图正常但指标就是低基本可以锁定是评测脚本的口径问题回到 PSNR 的 data_range 和通道顺序上检查。6. 进阶把 IRDiff 接进自己的退化任务6.1 自定义任务只改一个模块写一个可微的退化算子接自定义退化任务时最稳妥的路径是只替换退化算子。需要提供的接口极其简单class MyDegradation(nn.Module): def forward(self, x_clean): # x_clean: [B, C, H, W]数值范围与配置的 pixel_range 一致 # 返回与观测 y 同尺寸的退化图 return degraded只要这个 forward 是可微的不要在里面用随机采样、硬阈值这类不可导操作采样引导的逻辑完全不用动。写完算子先做静态验证拿一张干净图过算子生成 y再跟真实观测图对比看退化风格是否贴近。这一步能提前暴露算子设计上的方向性错误。6.2 每个新任务都先跑单图冒烟测试我的习惯是每个新任务只跑一张图干净图、自己做退化、走修复、看能否回到干净图。这一张图同时验证了退化算子、采样链路、评测脚本三段代码跑通了再上完整测试集能避免在 100 张图上反复试错。最后说一个自己的教训。早期我热衷于把退化算子做得复杂认为越贴近真实物理退化越好结果在复杂算子上反复调参效果反而不如一个简单算子配合理引导强度。后来我意识到扩散先验的分布范围和退化算子的数值约定保持一致比算子本身的复杂度更影响最终效果。先跑通最简单版本再逐步加复杂度每一步都守着观测对比图验证是这个方向最省时间的做法。希望帮到你。本文还有配套的精品资源点击获取