论文精读
目录

论文精读 · 第 1 篇 · 2026-08

单图反射分离:一个扩散模型,同时生成透射层与反射层

这一页写给刚从 LLM 世界回来的你:先用你熟悉的语言把扩散模型补齐,再把这篇论文的四个组件一个一个拆开——每一步都有公式、有原文插图,还有两个可以动手拖的小实验。

Reflection Separation from a Single Image via Joint Latent Diffusion
Zheng-Hui Huang · Zhixiang Wang · Yu-Lun Liu · Yung-Yu Chuang
Shanda AI Research Tokyo / NTU / NYCU · arXiv 2606.04107 · 项目主页 · 代码

§1问题:一张图,拆成两层

隔着玻璃拍照,传感器收到的是两个场景的叠加:玻璃后面你想拍的东西,叫透射层 \(\mathcal T\)(transmission);玻璃反射出来的东西,叫反射层 \(\mathcal R\)(reflection)。反射分离要做的,就是从一张混合图 \(\mathcal I\) 出发,把 \(\mathcal T\) 和 \(\mathcal R\) 还原出来。

四组示例:每组给出输入混合图、分离出的透射层与反射层,涵盖夜景强反射、山景弱反射、木门橱窗等场景
图 1 · 论文原图无论反射是强是弱,这个方法都能同时给出透射层和反射层——注意第二列山景里那层淡淡的反射,也被完整抓了出来。

难点在于:这是一个严重病态(ill-posed)的问题。一张图要拆成两张图,未知数是观测量的两倍,解本质上不唯一——同一张混合图,可以有无数种「两层怎么分」的方案。要选出合理的那一种,只能靠先验:你得知道自然图像长什么样、反射通常长什么样。

从 LLM 视角看

这就像给你一段两个人同时说话被混在一起的转写文本,让你还原出各自说了什么——单看混合结果信息不够,必须依赖「人说话的先验」。在 LLM 世界里,先验来自预训练语言模型;在这里,先验来自预训练扩散模型。整篇论文的主张一句话就能说完:把 Stable Diffusion 的生成先验,微调来做反射分离。

为什么以前的方法不够用?看两个极端:

强反射/眩光——透射层的内容被反射整个盖掉,被盖住的信息根本不在输入里。判别式网络(DSRNet、DSIT 这类直接回归输出的模型)只能给出模糊或带伪影的结果,因为它们没有「脑补」的能力。
弱反射/低光——反射信号太微弱,大多数方法干脆输出一张几乎全黑的反射层,把有意义的反射内容全丢掉。

动机对比:DSIT 与 DSRNet 在强反射场景失败;直接朴素地用扩散模型逐层预测会产生不真实的伪影;论文方法联合建模两层后注意力更聚焦
图 2 · 论文原图左:现有最强的判别式方法(b、g)在难例上留下残影或失真;朴素地拿扩散模型单层预测(c、h)会幻构出不真实的内容。右:联合建模两层之后,特征图对各自层的关注明显更聚焦。

生成式先验恰好补上这两个短板:强反射时,模型可以像文生图那样幻构出被盖住的细节;弱反射时,它知道「反射层应该长什么样」,能把微弱的信号捞出来。这篇论文是第一个专门为反射分离微调的扩散模型,而且两层一起出。此前最接近的 L-DiffER 只输出干净透射层,还要依赖对每张图的文字描述;这篇只用两个固定 prompt——"Transmission""Reflection"——就把两层全都要了。

§2补课:从 LLM 到扩散模型

你熟 transformer、熟后训练,但扩散这套可能生疏了。好消息是:两边的骨架惊人地对称,补的其实只有「生成范式」这一层。先上对照表:

概念LLM 世界扩散世界(本文用的 LDM)
生成方式自回归,一次一个 token迭代去噪,一次「干净一点」
模型学什么预测下一个 token 的分布预测当前图里掺了什么噪声 \(\varepsilon\)
压缩表示tokenizer:文本 → token 序列VAE:图像 → latent(下采样 8×)
主干网络TransformerU-Net(里面同样塞满 attention)
条件注入prompt 拼进上下文文本经 cross-attention 进 U-Net
「引导采样」对比解码 / logit 处理Classifier-Free Guidance(§6 要用)
推理时补算力test-time compute、self-consistency测试时 latent 优化(§7 要用)

2.1 前向:把图一步步埋进噪声里

取一张干净图的 latent \(z_0\),扩散的前向过程按预定的噪声表 \(\{\beta_t\}\) 一步步加高斯噪声。妙处是任意时刻 \(t\) 都有闭式解,一步就能从 \(z_0\) 跳到 \(z_t\):

$$z_t=\sqrt{\bar\alpha_t}\,z_0+\sqrt{1-\bar\alpha_t}\,\varepsilon,\qquad \varepsilon\sim\mathcal N(0,\mathbf I),\qquad \bar\alpha_t=\prod_{s=1}^{t}(1-\beta_s)$$

\(t\) 越大,\(\bar\alpha_t\) 越小:信号系数 \(\sqrt{\bar\alpha_t}\) 缩水,噪声系数 \(\sqrt{1-\bar\alpha_t}\) 长大,直到 \(z_T\) 几乎是纯噪声。拖一拖下面的滑块,亲手感受一下:

小实验 · 前向加噪

t = 0
你的浏览器不支持 canvas,想象一张照片被雪花噪声逐渐淹没。

√ᾱₜ = 1.000(信号系数) · √(1−ᾱₜ) = 0.000(噪声系数)

图取自论文图 1 的山景样例。t≈300 时人眼已难辨认,但网络还能;t=1000 时信息几乎清零——生成就是把这条路倒着走回来

2.2 反向:训练一个「猜噪声」的网络

生成的任务是从纯噪声一步步走回干净图。为此训练一个网络 \(\varepsilon_\theta\),输入带噪 latent \(z_t\)、时间步 \(t\)、文本条件 \(c\),让它猜出「刚才掺进去的噪声是什么」:

$$\min_\theta\;\mathbb E_{z_0,\,\varepsilon\sim\mathcal N(0,1),\,t}\Big[\big\lVert\varepsilon-\varepsilon_\theta(z_t,\,t,\,c)\big\rVert_2^2\Big]$$
从 LLM 视角看

把它当作扩散世界的 next-token prediction:一个简单得不像话的自监督目标,规模上去之后,模型被迫学会了「自然图像是什么样」的全部知识。你做 SFT 时复用的是语言先验;这篇论文微调时复用的,就是这个噪声预测网络里压着的图像先验。

推理时从 \(z_T\sim\mathcal N(0,\mathbf I)\) 出发,反复「预测噪声 → 去掉一点 → 得到 \(z_{t-1}\)」,走 50 步(本文的设置)就得到干净的 \(z_0\)。

2.3 Tweedie 公式:随时偷看「当前的答案」

还有一个后面反复要用的工具。在任意中间时刻 \(t\),不必走完全程,用当前的噪声预测就能一步估出干净 latent:

$$z_{0|t}=\frac{z_t-\sqrt{1-\bar\alpha_t}\;\varepsilon_\theta(z_t,t,c)}{\sqrt{\bar\alpha_t}}$$
这个式子从哪来?(30 秒推导)

把前向闭式解 \(z_t=\sqrt{\bar\alpha_t}\,z_0+\sqrt{1-\bar\alpha_t}\,\varepsilon\) 当作方程,把 \(z_0\) 解出来:\(z_0=(z_t-\sqrt{1-\bar\alpha_t}\,\varepsilon)/\sqrt{\bar\alpha_t}\)。真噪声 \(\varepsilon\) 不知道,但网络的预测 \(\varepsilon_\theta\) 就是它的最优估计,代入即得。这是 Tweedie 公式在扩散里的形式——「当前图减掉预测噪声,再把幅度缩放回去」。§7 的 latent 优化全靠它把中间状态变成可以打分的「预览图」。

2.4 Latent Diffusion:在 VAE 的隐空间里做这一切

Stable Diffusion 的「L」指 latent:先用一个冻结的 VAE 编码器 \(\mathcal E\) 把 \(H\times W\times 3\) 的图压成 \(\tfrac H8\times\tfrac W8\times 4\) 的 latent,扩散全程在这个小空间里做,最后用解码器 \(\mathcal D\) 还原回像素。本文推理分辨率 960×960,对应 latent 只有 120×120——这就是为什么后面的「latent 空间优化」能比像素空间快一个数量级。

U-Net 内部有两种 attention,和你熟悉的公式一模一样(\(H=\operatorname{softmax}(QK^{\top}/\sqrt d)\,V\)):self-attention 里 \(Q,K,V\) 都来自空间特征(把图的每个位置当 token);cross-attention 里 \(K,V\) 来自文本编码。§5 的改动,动的就是 self-attention。

§3方法鸟瞰:一个 U-Net,两条轨迹

整体设计先看一眼,再逐个拆。输入图 \(\mathcal I\) 编码成 \(z^{\mathcal I}\);两条扩散轨迹 \(z_t^{\mathcal T}\) 和 \(z_t^{\mathcal R}\) 从各自的纯噪声出发,共享同一个微调过的 U-Net,分别被 "Transmission" / "Reflection" 两个固定 prompt 引导,同步去噪 \(T\) 步,最后解码出两层图像。

框架总览:输入图经冻结 VAE 编码;两条带噪 latent 轨迹与输入 latent 拼接后进入共享权重的 U-Net,分别由 Transmission 和 Reflection prompt 引导;两支之间有 Cross-Layer Self-Attention;采样时经过 Disjoint Sampling;Latent Composition Function 提供组合损失做 latent 优化;FGFM 模块在解码时注入原图特征;最终解码出反射层与透射层
图 3 · 论文原图全家福:红色支路生成透射层,蓝色支路生成反射层,权重共享;雪花=冻结,火苗=可训练。四个新组件都标在图上了,下面按顺序拆。
  1. 条件微调(§4)

    把输入图的 latent 拼进 U-Net 输入,全量微调,一个模型靠 prompt 区分两层。这是地基。

  2. 跨层自注意力 CLSA(§5)

    让两条轨迹在 U-Net 内部互相「看见」对方,各自认领自己的内容,减少互相污染。

  3. 互斥采样 Disjoint Sampling(§6)

    采样时把对方层的预测噪声当负向引导,每一步都把两条轨迹往两边推;带出的色偏由 FGFM 修正。

  4. 测试时 latent 优化(§7)

    用一个学出来的「组合函数」检验两层能否拼回原图,不满足就对 latent 做梯度修正。

§4组件一:条件微调——扩散模型的「SFT」

怎么让文生图模型「看着一张图」工作?做法直白:把输入图的 VAE 编码 \(z^{\mathcal I}\) 和带噪 latent \(z_t\) 沿通道维拼接成 \([z_t;\,z^{\mathcal I}]\) 喂给 U-Net。唯一的结构改动是 U-Net 第一层卷积的输入通道翻倍(4→8),新增通道零初始化。这是 Marigold 一路「扩散模型做感知任务」的标准做法。

一个模型要管两层,靠 prompt 区分:训练时两层各算一个噪声预测损失,加在一起:

$$\mathbb E_{\varepsilon,\,t,\,\mathcal I,\mathcal T,\mathcal R}\Big[\big\lVert\varepsilon^{\mathcal T}-\varepsilon_\theta\big(z_t^{\mathcal T},z^{\mathcal I},t,c^{\mathcal T}\big)\big\rVert_2^2+\big\lVert\varepsilon^{\mathcal R}-\varepsilon_\theta\big(z_t^{\mathcal R},z^{\mathcal I},t,c^{\mathcal R}\big)\big\rVert_2^2\Big]$$

其中 \(c^{\mathcal T}\)="Transmission",\(c^{\mathcal R}\)="Reflection",两层的噪声 \(\varepsilon^{\mathcal T},\varepsilon^{\mathcal R}\) 独立采样。真实数据往往没有反射层的真值(想想怎么采集:透射层可以撤掉玻璃再拍一张,反射层很难单独拍),那就只算透射那一项。

从 LLM 视角看

这一步在气质上就是 SFT:拿一个强预训练基座,换上任务格式(条件拼接 + 两个固定 prompt),小学习率全量微调。连「预训练权重有多重要」的消融都和 LLM 世界一致——§8 会看到,从头训 PSNR 掉 3.4 dB,反射层掉得更惨,因为反射信号弱、真实数据又没监督,全靠生成先验撑着。

只做到这一步,效果已经「还行」(§9 消融表的第一行),但难例里两层会互相拖泥带水:透射层里残留反射影子,反射层里带进透射内容。下面三个组件就是冲着这个来的。

§5组件二:跨层自注意力——让两层互相看见

标准做法里,两条轨迹各自过 U-Net,谁也不知道对方在生成什么。CLSA(Cross-Layer Self-Attention)把每个 self-attention 块改成联合处理两层:每层的 query 去 attend 两层拼起来的 key/value:

$$H^{i}=\operatorname{softmax}\!\Big(\frac{Q^{i}\,\big[K^{\mathcal T};K^{\mathcal R}\big]^{\top}}{\sqrt d}\Big)\big[V^{\mathcal T};V^{\mathcal R}\big],\qquad i\in\{\mathcal T,\mathcal R\}$$

\([\,\cdot\,;\cdot\,]\) 是沿空间(token)维拼接;\(Q^i,K^i,V^i\) 由对应 prompt 激活的那条支路产生。

跨层自注意力机制示意:上半部分为普通 self-attention,各层只看自己的 key/value;下半部分为 CLSA,透射与反射的 query 各自 attend 两层拼接后的 key/value
图 4 · 论文原图上:各扫门前雪的普通 self-attention。下:CLSA——query 不变,key/value 换成两层的拼接,信息在注意力层面互通。
从 LLM 视角看

公式完全是你熟悉的味道:相当于把「另一层的特征」拼进了上下文窗口。直觉像两个 agent 各写一份摘要,但共享一块草稿区——透射支路能看到反射支路正在认领哪些内容,于是「这块你要了,我就不要了」,在真值监督下形成显式分工。

消融很能说明问题:CLSA 对反射层帮助最大(SIR² 上反射层 DISTS 从 0.382 → 0.284)。反射层质量上去之后,反过来又给透射层提供了更准的「减数」,透射也跟着变干净:

CLSA 消融:不加 CLSA 时反射层几乎全黑;加上后反射层完整恢复出桥的结构,透射层也更干净
图 7 · 论文原图没有 CLSA(w/o),反射层近乎全黑;有了它(w/),整座桥被从反射里认了出来。

§6组件三:互斥采样——把对方当负向引导

6.1 先补一块地基:Classifier-Free Guidance

文生图的标准操作 CFG:同一个模型算两次噪声预测——一次带条件 \(\varepsilon_{\text{cond}}\),一次无条件 \(\varepsilon_{\text{uncond}}\)——然后沿「有条件相对无条件的方向」外推:

$$\hat\varepsilon=(1+k)\,\varepsilon_{\text{cond}}-k\,\varepsilon_{\text{uncond}}=\varepsilon_{\text{cond}}+k\,(\varepsilon_{\text{cond}}-\varepsilon_{\text{uncond}})$$

效果是采样更「听 prompt 的话」。原理:噪声预测正比于分数函数(score,对数概率的梯度),这样组合等价于在采样 \(p(z\mid c)\bigl[p(z\mid c)/p(z)\bigr]^{k}\)——把条件与无条件的概率比抬了 \(k\) 次方。

从 LLM 视角看

这就是扩散版的 contrastive decoding:拿「想要的分布」减去「不想要的分布」,放大差异方向。LLM 里是 logits 相减,这里是预测噪声相减——同一个念头,不同的空间。

6.2 Disjoint Sampling:负向引导换成「对方那层」

微调加 CLSA 之后仍有残留重叠。作者的招数:透射轨迹想最大化的不是 \(p(z_t\mid\mathcal T)\),而是概率比 \(p(z_t\mid\mathcal T)/p(z_t\mid\mathcal R)\)——既要像透射,又要不像反射。由于微调后 \(\varepsilon^{\mathcal T},\varepsilon^{\mathcal R}\) 分别对应 \(\nabla\log p(z_t\mid\mathcal T)\) 和 \(\nabla\log p(z_t\mid\mathcal R)\),照 CFG 的葫芦画瓢:

$$\hat\varepsilon^{\mathcal T}=\varepsilon^{\mathcal T}+k\,\big(\varepsilon^{\mathcal T}-\varepsilon^{\mathcal R}\big),\qquad \hat\varepsilon^{\mathcal R}=\varepsilon^{\mathcal R}+k\,\big(\varepsilon^{\mathcal R}-\varepsilon^{\mathcal T}\big),\qquad k=0.2$$

再用修改后的 \(\hat\varepsilon\) 走标准 DDPM 一步:\(z_{t-1}^{\mathcal T}=\tfrac{1}{\sqrt{1-\beta_t}}\big(z_t^{\mathcal T}-\tfrac{\beta_t}{\sqrt{1-\bar\alpha_t}}\hat\varepsilon^{\mathcal T}\big)\)。每一步都推一把,整条轨迹被持续拉开。拖下面的 \(k\) 看看向量怎么动:

小实验 · 互斥采样的几何

k = 0.20
ε_T ε_R ε̂_T ε̂_R z_t

ε̂_T = ε_T + 0.20·(ε_T − ε_R):沿着「远离对方」的方向外推。

k=0 时就是原始预测;k 越大两层被推得越开——分离更干净,但推得太狠会伤保真度(见 6.3)。论文取 k=0.2。虚线是差向量 ε_T−ε_R 的方向。

互斥采样示意:在扩散流形上,混合区域的轨迹被噪声差向量作为负向引导分别推向透射簇与反射簇
图 5 · 论文原图论文的官方视角:在逐步去噪的流形上,\(\varepsilon^{\mathcal T}-\varepsilon^{\mathcal R}\) 作为互相的负向引导,把两条轨迹从「混合区」(绿)分别推向各自的簇。
互斥采样消融:不加时反射层混入杯子和花盆等透射内容;加上后分离干净
图 8 · 论文原图没有互斥采样(w/o),反射层里混进了杯子、花盆这些明明属于透射的内容;加上(w/)之后各归各位。

6.3 副作用与解药:FGFM

直接改噪声预测会带来色偏(color drift)——毕竟你在偏离模型认为「最可能」的方向。解药是 FGFM(Fidelity-Guided Feature Modulation,保真引导的特征调制):解码时,把原始混合图的编码特征「抄」回来调制解码特征:

$$\hat y_{\mathrm{dec}}=y_{\mathrm{dec}}+w\cdot f\big([\,y_{\mathrm{enc}}\,\vert\,y_{\mathrm{dec}}\,]\big),\qquad w=0.8$$

\(f\) 是几层卷积,\(y_{\mathrm{enc}}\) 是原图特征,\(w\) 是保真度旋钮。训练用 L2 + LPIPS(\(\beta_1{=}1,\beta_2{=}0.1\)):\(\;\mathcal L=\beta_1\lVert\hat{\mathcal T}-\mathcal T\rVert_2^2+\beta_2\sum_i w_i\lVert\phi_i(\hat{\mathcal T})-\phi_i(\mathcal T)\rVert_2^2\)。FGFM 只用在透射层——反射层本来就没多少高频内容可抄。

FGFM 参数 w 的敏感性分析:左图为不同 w 下各指标的归一化得分,右图为 w=0、0.5、1 的视觉效果对比
图 10 · 论文原图\(w\) 大,细节足但可能带回残留反射;\(w<0.5\) 质量明显掉。折中取 0.8。这是你复现时最值得先扫的一个旋钮。

§7组件四:测试时 latent 优化——用「能拼回原图」自检

一次前向分离不保证满足组合约束:两层拼回去应该还原输入。传统做法假设像素空间线性叠加 \(\mathcal I=\mathcal T+\mathcal R\),但真实成像(玻璃吸收、二次反射、色移)并不严格满足。这篇有两个聪明点:

7.1 组合函数是「学」出来的,而且在 latent 空间

训一个小卷积网络 \(\mathcal C\),吃两层的 latent,吐出混合图的 latent。在有真值三元组的合成数据上,用组合损失训练:

$$\mathcal L_{\mathrm{comp}}=\big\lVert\hat z^{\mathcal I}-z^{\mathcal I}\big\rVert_2^2,\qquad \hat z^{\mathcal I}=\mathcal C\big(z_{0|t}^{\mathcal T},\,z_{0|t}^{\mathcal R}\big)$$

比手写 \(\mathcal I=\mathcal T+\mathcal R\) 更贴真实成像;而且工作在 120×120 的 latent 上,梯度不需要穿过 VAE 解码器和大特征图

7.2 推理时用它迭代修 latent

每 5 个扩散步做一轮、每轮 4 次:先用 Tweedie 公式(§2.3)从当前 \(z_t\) 一步估出两层的「预览」\(\hat z_0^{\mathcal T},\hat z_0^{\mathcal R}\),拼成伪混合图和真的 \(z^{\mathcal I}\) 比,把误差梯度回传到两层 latent 上:

$$z^{\mathcal T}\;\leftarrow\;z^{\mathcal T}-\gamma_i\,\lVert z^{\mathcal T}\rVert\;\nabla_{z^{\mathcal T}}\mathcal L_{\mathrm{comp}}$$

(反射层同理;梯度按 latent 范数归一化,步长稳定。)关键在于:这一轮里 \(\varepsilon\) 是固定的——每个 \(t\) 只跑一次 U-Net,Tweedie 映射是线性的,所以梯度只流过小小的 \(\mathcal C\),完全不反传 U-Net 和解码器。代价便宜得惊人:512² 下每次更新 0.15 秒;像素空间优化要 1.53 秒还更费显存,指标反而更差:

latent 空间 vs 像素空间优化(Nature 数据集,较低分辨率;表 5)
优化空间PSNR ↑SSIM ↑LPIPS ↓DISTS ↓每次更新耗时
像素空间(\(\mathcal I=\mathcal T+\mathcal R\))21.530.7350.1680.1271.53 s
latent 空间(本文)25.540.8080.1640.1160.15 s
从 LLM 视角看

这就是图像版的 test-time compute:推理时多花一点算力,用一个可验证的信号(组合一致性,类似 verifier)来修正生成。补充材料里还有个很妙的实验:拿一个完全没微调过的文生图模型、空 prompt,光靠这个组合引导也能做出像样的两层分离——「约束本身就是很强的监督」。

latent 优化消融:无优化与有优化的对比,加优化后细节更清晰、伪影更少
图 9 · 论文原图不加(w/o)与加(w/)latent 优化:细节被找补回来,伪影减少。

7.3 完整推理流程

把 §4–§7 串起来,就是补充材料的 Algorithm 1。先看原文,再看小c给你标注的伪代码:

论文补充材料中的 Algorithm 1:反射互斥采样策略完整伪代码
算法 1 · 论文原图论文原版。注意第 4 行的 mod 5(每 5 步做一轮 latent 优化)、第 5 行的 4 次内循环、第 12 行的互斥采样。
z_T^T, z_T^R ~ N(0, I);   z_I = Encoder(I)          # 两条轨迹从纯噪声出发
for t = 50 … 1:
    ε_T = ε_θ([z_t^T ; z_I], t, "Transmission")     ┐ 同一个 U-Net
    ε_R = ε_θ([z_t^R ; z_I], t, "Reflection")       ┘ CLSA 让两支互通
    if t % 5 == 0:                                   # —— latent 优化,每 5 步一轮
        for j = 1 … 4:
            ẑ0_T, ẑ0_R = Tweedie(z_t^T, ε_T), Tweedie(z_t^R, ε_R)
            L = ‖ z_I − C(ẑ0_T, ẑ0_R) ‖²            # 拼回去像不像原图?
            z_t^T −= γ·‖z_t^T‖·∇L;   z_t^R −= γ·‖z_t^R‖·∇L
    ε̂_T = ε_T + k·(ε_T − ε_R)                        # —— 互斥采样,k = 0.2
    ε̂_R = ε_R + k·(ε_R − ε_T)
    z_{t−1}^T, z_{t−1}^R = DDPM_step(ε̂_T), DDPM_step(ε̂_R)

T = Decoder(z_0^T)  with FGFM(w=0.8)                 # 透射层解码时抄回原图特征
R = Decoder(z_0^R)

§8训练配方

训练分两阶段,和「先预训练、再对齐」的直觉一致:阶段一从 Stable Diffusion 2.1 初始化,按 §4 的联合损失全量微调 U-Net;阶段二冻住 U-Net,单独训 FGFM(只训 10 个扩散步、只作用于透射层)。组合网络 \(\mathcal C\) 只用合成数据单独训。

复现要点速查
基座模型Stable Diffusion 2.1(冻结 VAE,全量微调 U-Net)
优化器 / 学习率Adam · 3×10⁻⁵
等效 batch size32
训练硬件单张 NVIDIA A6000(48 GB)
数据与 DSRNet 相同(Setting 2 w/ Nature,合成 + 真实;真实数据只有透射真值)
推理设置50 步 DDPM · 960×960 · k=0.2 · w=0.8 · latent 优化每 5 步 × 4 次

补充材料里最值得记住的一张小表:预训练权重有多重要(SIR²,不带优化与互斥采样):

预训练权重消融(表 10)
设置PSNR ↑SSIM ↑LPIPS ↓DISTS ↓
透射 · 从头训21.310.7630.1910.171
透射 · 用 SD 预训练权重24.670.8580.1200.094
反射 · 从头训19.340.5950.5430.365
反射 · 用 SD 预训练权重20.870.6590.3810.285

反射层的感知指标差距(LPIPS 0.543 → 0.381)比透射还大:反射信号弱、真实数据没监督,重建质量几乎全押在生成先验上。这验证了整篇论文的立论。

§9实验结果怎么读

三个真实数据集:Real20(20 张)、Nature(20 张)、SIR²(454 张);四个指标:PSNR/SSIM(逐像素保真)、LPIPS/DISTS(感知质量)。作者把七个对比方法在同一份数据上重训了做公平对比(重训版普遍还比官方权重更强),官方权重的对照表在补充材料里,结论一致。

9.1 透射层

透射层对比(表 1;重训基线;每行最优标红)
数据集指标YTMTRobustSIRRDSRNetRRWDSITRDNetControlNetOurs
Real20PSNR ↑23.0122.9123.7520.6624.0424.8918.6825.32
SSIM ↑0.7910.7960.8090.7370.7960.8260.6450.850
LPIPS ↓0.1810.2060.1570.2690.1730.1450.3120.107
DISTS ↓0.1230.1370.1100.1650.1180.1030.2160.089
NaturePSNR ↑24.7025.4326.1125.8325.9026.4419.9226.71
SSIM ↑0.8220.8260.8350.8280.8250.8360.7210.837
LPIPS ↓0.1270.1680.1400.1740.1670.1140.2420.080
DISTS ↓0.0820.1040.0900.1100.1000.0780.1680.064
SIR²PSNR ↑23.9423.6423.9523.0525.0325.6220.6525.35
SSIM ↑0.8870.8750.9010.8620.9110.9090.8120.911
LPIPS ↓0.1290.1780.1130.1710.1080.1090.1740.075
DISTS ↓0.0880.1080.0780.1080.0770.0740.1380.065

读法:感知指标(LPIPS/DISTS)全面第一且优势大;PSNR/SSIM 大都第一,SIR² 的 PSNR 略输 RDNet。作者的辩护有道理——分离问题的解本身逐像素不唯一(能量在两层间怎么分不唯一),PSNR 会惩罚「合理但不同」的解,感知指标更能反映分离质量。你实测时也建议以视觉效果和 LPIPS/DISTS 为主。

9.2 反射层——这篇的杀手锏

反射层对比(SIR²;表 2;只列能输出反射层的方法)
指标YTMTDSRNetDSITRDNetOurs
PSNR ↑16.6420.5918.5118.0021.14
SSIM ↑0.2520.6710.4620.3620.681
LPIPS ↓0.6460.5330.5200.5260.373
DISTS ↓0.5760.3800.4020.3400.275

别的方法反射层经常输出一片黑;这篇能把反射内容真的画出来。对我们的课题来说,这一点比透射层的分数更重要——3DGS 那边要的就是「有内容的反射层」。

定性对比:两组真实场景中各方法输出的透射层与反射层,论文方法的反射层完整恢复出桥体和玩偶等内容,其他方法多为黑图或残缺
图 6 · 论文原图第一组的真值反射层是一整座桥——只有本文方法(最右)把它认了出来;其余方法不是全黑就是残影。

9.3 消融:三个组件各自值多少

消融(SIR²;表 3。C=CLSA,O=latent 优化,D=互斥采样)
配置PSNR ↑SSIM ↑LPIPS ↓DISTS ↓
基线(仅条件微调)24.660.8430.1330.107
+ C24.670.8580.1200.094
+ C + O25.030.8660.1150.091
+ C + O + D(完整)25.350.9110.0750.065

三个组件都有贡献,互斥采样带来最后一大跳(LPIPS 0.115 → 0.075)。官方代码里三个组件都有开关,正好可以逐个复现这张表——这是你上手实验的最佳起点。

还有一个对课题很有意义的结果:分离后的透射层拿去做目标检测、深度估计,下游任务直接受益:

下游任务示例:对输入、透射层、反射层分别做目标检测与深度估计,分离后的透射层上检测与深度都明显更准
图 11 · 论文原图反射会污染检测和深度估计;先分离再做下游任务,结果明显变好。对「先分层再重建 3D」是个直接的好信号。

§10局限,以及对我们 3DGS 课题的意义

作者自己承认的局限:优化阶段的参数(\(\gamma_i\)、\(k\)、\(w\))需要仔细调;FGFM 偶尔压不干净反射,透射层会残留少量伪影。

站在课题的角度,小c补三条更要紧的:

① 它给的是逐视角的 2D 分离先验。每张训练视图都能拆出「有内容的」\(\mathcal T/\mathcal R\) 两层,可以当 3DGS 重建的伪真值或正则来用——这正是把它选作课题第一步的理由。

② 但要小心多视角一致性。它是生成式的:强反射区域靠幻构补内容,不同视角、甚至不同随机种子下补出的内容可能不一致。实测时建议专门拿同一场景的相邻几帧跑,看两层输出的跨视角稳定性——这直接决定它能不能直接喂给 3DGS,还是需要在重建端做一致性约束。

③ 预处理成本要心里有数。50 步扩散 × 双分支,一张图几十秒量级;一个场景几百张训练视图,预处理是小时级的。

§11术语表

VAE(变分自编码器)
SD 里负责「图像 ↔ latent」的压缩器,8× 下采样、4 通道;本文全程冻结。类比 tokenizer。
latent / 隐空间
VAE 压缩后的表示空间。960×960 的图对应 120×120×4 的 latent,扩散和 §7 的优化都在这里做。
DDPM 采样
逐步去噪的标准采样器,每步用预测噪声算出上一时刻的均值。本文推理用 50 步。
Tweedie 公式
\(z_{0|t}=(z_t-\sqrt{1-\bar\alpha_t}\,\varepsilon_\theta)/\sqrt{\bar\alpha_t}\):任意中间步一步估出干净 latent,「偷看当前答案」。
CFG(Classifier-Free Guidance)
用「条件 − 无条件」的噪声差做外推,放大对条件的服从。本文互斥采样是它的变体:负向端换成对方层。
score / 分数函数
\(\nabla_z\log p(z)\),对数概率的梯度。噪声预测与它成正比,这是 CFG 一族方法的理论根基。
PSNR / SSIM
逐像素/局部结构的保真指标,对「合理但不同」的生成解偏严苛。
LPIPS / DISTS
用深度特征算的感知相似度,更接近人眼判断;本文主张以这两个为准。
ill-posed(病态问题)
解不唯一或不稳定的反问题。一图拆两层未知数翻倍,必须靠先验收窄解空间。
U-Net
编码-解码带跳连的卷积主干,SD 2.1 的噪声预测网络(≈0.87B 参数),内部混有 self-/cross-attention。

§12上手:在 3080 Ti 上跑起来

官方仓库只提供推理(没有训练脚本),结构基于 Marigold 的 pipeline 改造。在实验室那台 Windows 3080 Ti(12 GB)上,推理大概率能直接跑:SD 2.1 U-Net 的 fp16 权重约 1.7 GB,latent 优化又特意设计成不反传 U-Net——显存大头只是 960² 下的注意力和 VAE 解码。万一 OOM,把分辨率降到 768 或 640,先看效果完全够用。

conda create -n diffrefsep python=3.10 -y
conda activate diffrefsep
pip install torch==2.5.1 torchvision==0.20.1 --index-url https://download.pytorch.org/whl/cu121

git clone https://github.com/Brian90709/diff-reflection-separation-code
cd diff-reflection-separation-code
pip install -r requirements.txt

权重从 Hugging Face 的 Brian9999/diff-reflection-separation 下载到 ./checkpoints;SD 2.1 基座首次运行自动下载。国内网络先设镜像:

# PowerShell 里:$env:HF_ENDPOINT = "https://hf-mirror.com"
set HF_ENDPOINT=https://hf-mirror.com
hf download Brian9999/diff-reflection-separation --local-dir ./checkpoints

python infer_layersep.py --input_dir ./samples --save_to_dir ./outputs

每张输入会输出透射层、反射层和一个中间结果。命令行开关正好对应论文三个组件(关 latent 优化、调 refinement 强度、关互斥采样)——照着 §9.3 的消融表逐个开关跑一遍,是理解这篇论文最快的动手路径。

如果 Windows 上有包装不动(个别编译依赖偶尔闹脾气),WSL2 + Ubuntu 是最稳的兜底。需要微调或复现训练时再考虑租卡:作者用单张 A6000(48 GB)、等效 batch 32 做全量微调,12 GB 不够;按小时租 A100 40G/80G 或 A6000/L40S 最省心。