https://arxiv.org/pdf/2203.09...
https://github.com/csjliang/LDL
图像超分要想具有优异的纹理信息,那么GAN就是必经之路。但是,GAN存在训练不稳定问题与伪影问题。关于GAN的训练不稳定问题,目前已经有了一些trick缓解;但是关于GAN导致的伪影问题,暂无有效的方案。
本文对GAN生成的伪影问题进行了探索并提出一种行之有效的方案:局部区域统计信息有助于伪影判别并进而生成mask引导训练过程。所提方案简单有效,可以轻易嵌入到现有超分方案中并提升其性能。
1、Method
一般来讲,GAN-SR方案的训练损失可以描述如下:
其中,分别表示重建损失、感知损失以及对抗损失。如SRGAN一文所分析:仅采用重建损失训练会导致重建结果过于模糊,而对抗损失引入可以重建更多纹理,但同时会引入伪影问题。
上图给出了ESRGAN在不同类型区域的重建前后下过对比,可以看到:
- 对于A类图像块,LRs输入仅包含结构信息且保持完整,现有方案可以有效重建;
- 对于B类图像块,由于纹理的随机分布性,尽管重建结构仍为"假性纹理"但视觉感知良好;
- 对于C类图像块,同时包含结构与纹理信息,此时重建的"假性纹理"会呈现不自然状态。
上图从训练稳定性角度出发对前述三种类型块的MAD()信息进行了对比,可以看到:A类图像块的训练比较稳定;B类图像块存在大波动(意味着更高不确定性);C类图像块具有最大的波动与不稳定性。
Discriminating Artifacts from Realistic Details
结合前述分析,为使得GAN-SR具有更优异的重建效果,我们需要抑制C类型块的伪影生成,同时保持A和B类型块的纹理重建效果。为达成该目的,我们精心设计了一种pixel-wise map进行伪影与细节的判别并用于引导GAN-SR训练,下图各处了该map生成过程示意图。
从上面图示第三列可以看到:A类型块具有非常小的残差;而B与C类型块具有较大残差,B的残差具有更强的随机性。基于上述残差图,我们进一步计算局部方差生成“粗糙版”M:
尽管上述方案已经可以有效判别不同块的伪影,但它仍会过度惩罚C类块中的真实细节、轻度惩罚A和B的重建细节,尤其是在训练早期阶段。为缓解该问题,我们进一步稳定训练过程并对伪影map进行精制。具体来说,我们引入EMA技术并构建两个残差图:
从上面的图示第6列可以看到:经过此时的处理,细粒度纹理与边缘已从map中移除,确保了更精度的伪影像素惩罚调制。
Loss and Learning Strategy
2、Experiments
上表与图给出了合成数据集上不同方案的性能与重建效果对比,可以看到:
- 所提LDL方案可以有效提升感知质量指标(LPIPS, DISTS, FID)与重建精度(PSNR, SSIM);
- SRResNet+LDL在大多数数据集上均优于SFTGAN与SRGAN;RRDB+LDL方案同样具有比其他方案更优的客观指标;SwinIR+LDL的组合同样取得了进一步的性能提升。
- 从重建结果来看,相比ESRGAN、USRGAN以及SPSR,LDL的结果具有更少的伪影、更好的细节。当然,从图示最后一行来看,LDL方案重建结果仍存在一定伪影,并未完全解决,但提供了一个非常好的前进方向。
上图给出了真实尝尽盲超分的效果对比,可以看到:相比BSRGAN与Real-ESRGAN,RealESRGAN+LDL方案重建结果具有更少的伪影、更锐利的纹理细节。
3、实现细节
由于作者既进行了合成数据实验(对标ESRGAN),也进行了盲超分实验(对标Real-ESRGAN),所以我们对比一下这两组code即可:
- 合成数据实验:
- 盲超分实验:realesrgan/models/realesrganArtifactsDis_model.py与realesrgan/models/realesrgan_model.py
从对比可以看到,区别仅在这四行code:
pixel_weight = get_refined_artifact_map(self.gt, self.output, self.output_ema, 7)
l_g_artifacts = self.cri_artifacts(torch.mul(pixel_weight, self.output), torch.mul(pixel_weight, self.gt))
l_g_total += l_g_artifacts
loss_dict['l_g_artifacts'] = l_g_artifacts
def get_local_weights(residual, ksize):
pad = (ksize - 1) // 2
residual_pad = F.pad(residual, pad=[pad, pad, pad, pad], mode='reflect')
unfolded_residual = residual_pad.unfold(2, ksize, 1).unfold(3, ksize, 1)
pixel_level_weight = torch.var(unfolded_residual, dim=(-1, -2), unbiased=True, keepdim=True).squeeze(-1).squeeze(-1)
return pixel_level_weight
def get_refined_artifact_map(img_gt, img_output, img_ema, ksize):
residual_ema = torch.sum(torch.abs(img_gt - img_ema), 1, keepdim=True)
residual_SR = torch.sum(torch.abs(img_gt - img_output), 1, keepdim=True)
patch_level_weight = torch.var(residual_SR.clone(), dim=(-1, -2, -3), keepdim=True) ** (1/5)
pixel_level_weight = get_local_weights(residual_SR.clone(), ksize)
overall_weight = patch_level_weight * pixel_level_weight
overall_weight[residual_SR < residual_ema] = 0
return overall_weight
来源:AIWalker
作者:Happy
推荐阅读
- 真实用!ETH团以合成数据+Swin-Conv构建新型实用盲图像降噪
- CVPR2022 无需人脸GAN先验,字节团队提出细节可控的人脸超分方案GCFSR
- NAFNet :无需非线性激活,真“反直觉”!但复原性能也是真强!
- 视频复原领域YYDS!BasicVSR++再次刷新视频降噪与视频去模糊
本文章著作权归作者所有,任何形式的转载都请注明出处。更多动态滤波,图像质量,超分辨相关请关注我的专栏AIWalker。