My App
Paper/TakingHeadGeneration

Towards Robust Blind Face Restoration with Codebook Lookup Transformer

讲难点: 1) 输入的信息比输出少(不确定性); 2) 实现高质量的细节(模糊性). 本论文通过转换为code预测任务解决这些难题. 提出Transformer-base预测网络CodeFormer, 建模global composition和低质量脸部的上下文, 有一个可控模块灵活控制保真度和质量, 以适应不同质量的输入.

介绍

从互联网获取的面部图片存在压缩, 模糊, 噪声等各种各样的degradation, 从low-quality(LQ)恢复high-quality(HQ)存在无限个可能, 在没有其他指导条件下修复还是很棘手的, 导致当前的模型只能达到次优的结果, 为了改善质量, 本论文从不确定性和模糊性两个问题着手.

对于不确定性, 已经存在很多解决方法, 几何先验, 参考先验, 生成式先验, 尽管在纹理和细节上有所改善, 对degradation过度敏感, 或者limited prior expressiveness, 这些方法提供重构的条件是不充足的, 直接导致LQ到HQ的映射依旧是不确定的. 生成式的方法虽然质量很高, 但是存在保真度不足的问题(无法在多种不同程度的degradation中准确找到一个latent vector, 为了提升保真度, 在编码器和解码器中建立一个skip connection是很有必要的, 但是degradation太严重会出现伪影.).

CodeFormer-discretePrior

接着作者就提出了自己的方案, 盲脸修复问题变成code预测问题, 生成式的方法会有无限的space, 但是discrete codebook prior包含有限的基数, 这就对各种退化表现出健壮性, 另外从结果定性分析, 保真度也不错.

CodeFormer-codeComposition

尽管基于codebook离散的表示已经用于图像生成, 但是准确的code composition仍然面临困难, 观察上图, 对于HQ的图像, 使用nearest-neighber方法确实可以区分, 但是对于LQ的图像, 因为内在纹理通常已经被侵蚀, 无论怎么微调编码器, LQ特征没法很好的聚类.

后面讲具体的结构到具体章节再看.

相关工作

盲脸修复

geometric prior(ficial landmark, face parsing maps, facial component heatmaps): 对于degradation图像很难准确提取信息, 不能提供详细的面部细节.

reference prior(提供另一张相同身份的HQ图片): HQ图片并不一直可获得. DFDNet预构建(不可学习)包含高清脸部特征的字典, 但是对皮肤头发等部位的重建不够; VQGAN探索使用一个可学习的HQ字典, 包含更多丰富的细节.

最近生成式的方法兴起, 如StyleGAN2, 但是由于degradation face对应无数可能的latent vector, 维持高保真很困难; GLEAN, GPEN, GPFGAN都探索了编解码加残差连接的方式, 容易造成伪影.

字典学习

借助学习到的字典离散表示在超分辨率, 去噪任务上显示优越性, 激发了和reference-base prior的结合, 但是需要迭代的优化大量计算成本. VQVAE介绍了高压缩率的codebook, VQGAN使用对抗损失和感知损失增强了生成质量. 本文的方法固定编码器, 通过全局建模预测code序列, 这样的好处是不依赖于LQ cues的特征融合, 增强鲁棒性.

方法

CodeFormer-overview

Codebook Learnning

观察method图, 上面部分. 我先介绍forword流程, HQ image的shape为IhRH×W×3I_h \in \mathbb{R}^{H \times W \times 3}, 通过编码器压缩后 ZhRm×n×d\mathbb{Z}_h \in \mathbb{R}^{m \times n \times d}, 这时我们有一个密码本, shape为 C={ckRd}k=0N\mathcal{C} =\{ c_k \in \mathbb{R}^d \}^N_{k=0}, 就是N个d维向量, 现在我们使用最近邻将ZhRm×n×d\mathbb{Z}_h \in \mathbb{R}^{m \times n \times d}Zc(i,j)Z^{(i, j)}_c换成密码本中最近的一个向量, 得到ZhZ_h, s用来存在密码本中索引.

注意到其中可以更新的权重有编码器, 解码器和密码本, 在反向传播中我们引入这样几种损失.

L1=IhIrec1;Lper=Φ(Ih)Φ(Irec)22;Ladv=[logD(Ih)+log(1D(Irec))]\mathcal{L}_{1} = \lVert I_h - I_{rec} \rVert_1;\quad \mathcal{L}_{per} = \lVert \Phi(I_h) - \Phi(I_{rec}) \rVert_2^2;\quad \mathcal{L}_{adv} = \bigl[ \log D(I_h) + \log(1 - D(I_{rec})) \bigr]

分别表示L1损失, 对抗损失, 感知损失, 感知损失的特征提取器是VGG19. 这里要介绍一种技术叫做straight-through gradient estimator, 观察上图我们发现一个问题, ZhZ_hZcZ_c这一步是不可微的, 就是说梯度传不过去, 那我们怎么更新编码器的权重呢, straight-through gradient estimator的思想就是说, 我假设ZhZ_hZcZ_c这里做的是恒等变换, 用ZcZ_c的梯度代替ZhZ_h的梯度, 梯度恒等的传递过去了.

为了更新codebook, 我们又引入了LcodefeatL^{feat}_{code}, 这里有介绍了stop gradient, 先看这个损失的公式

Lcodefeat=sg(Zh)Zc22+βZhsg(Zc)22\mathcal{L}^{\text{feat}}_{\text{code}} = \left\lVert \operatorname{sg}(Z_h) - Z_c \right\rVert_2^2 + \beta \left\lVert Z_h - \operatorname{sg}(Z_c) \right\rVert_2^2

sg()sg(*)表示stop gradient, codebook的使命是使ZhZ_hZcZ_c尽可能的接近, 我们用L2损失来衡量, 问题还是ZhZ_hZcZ_c不可微, 怎么办了, stop gradient, 观察loss的前面部分 sg(Zh)Zc22\left\lVert \operatorname{sg}(Z_h) - Z_c \right\rVert_2^2, 梯度在ZhZ_h这里消失了, 把ZhZ_h看作输出, 只更新codebook, 再观察后面这部分, Zhsg(Zc)22\left\lVert Z_h - \operatorname{sg}(Z_c) \right\rVert_2^2, 把ZcZ_c看作输出, 只更新编码器. β\beta用来控制encoder和codebook的更新速率的.(发现stop gradient -> 当作输出很好理解)

Codebook Lookup Transformer Learnning

上一步我们得到一个表现很好的codebook和解码器, 下面我们要应用到LQ图像了, 正常思路是一个编码器, 最近邻找codebook索引, 重建. 但是还记得前面阐述的吗, 最近邻在LQ不适用, 我们改为使用Transformer预测codebook索引.

Transformer是9个自注意力块, 每块的结尾都过softmax, Q和K加了sinusoidal positional embedding, 这一阶段训练Transformer和编码器(L)

Controllable Feature Transformation

第三点是锦上添花, 核心思想是在 HQ Decoder 的特征 FdF_d 上, 注入一小部分 LQ 信息, 让模型能根据用户需求调整保真度.

方法是在解码器上注入一下LQ信息, 维持保真度.

实验不看, 限制是侧脸处理不好, codebook很少关于侧脸的建模.

感受

作者的思路很清晰, 调研 -> 复现 -> 发现问题 -> 提出方法 -> 实验 的路径. 在实践中发现常识中的问题, 很厉害, 比如nearest-neighber featrue matching, 如果是我的话这里想都不想直接用的.

straight-through gradient estimator 和 stop gradient 理解了.

On this page