渣画质的救赎:基于GAN的超分辨率方案

本次给大家介绍2篇文章——SRGAN[3]和ESRGAN[5],基于生成对抗网络的超分辨率方案。

先回顾一下以往的方法:

1. 图像放大与基于CNN的超分方案

所有使用电脑的人都会用到图片放大的操作,而把图片放大超过其分辨率后,图片就会模糊。传统放大图片都是采用插值的方法,最常用的有最近邻插值(Nearest-neighbor)、双线性插值(Bilinear)、双立方插值(bicubic)等,这些方法的速度非常快,因此被广泛采用。

基于卷积神经网络/深度学习超分方案的开山之作叫做SRCNN(Super-Resolution Convolutional Neural Network),由港中大多媒体实验室在2015年提出。

基于卷积神经网络的方案很容易理解:传统插值方法可以看做把像素复制放大倍数后,用某种固定的卷积核去卷积;而基于卷积神经网络的超分方法无非是去学习这个卷积核,根据构建出的超分图像与真实的高分辨率图像(Ground Truth)的差距去更新网络参数。

这种方法的损失函数一般都采用均方误差MSE——即构建出来的超分图像与真实超分图像逐像素差的平方:

 (1)

 是网络参数,  是低分辨率图像,  是重建出来的高分辨率图像,  是真实的高分辨率图像, 分别是图片数量、图片宽和高,都可以看成常数。

这种方法存在一个问题:尽管在客观评价指标——MSE(均方误差)、PSNR(峰值信噪比)上成绩很好,但总是倾向于生成过于平滑的图像,如下图所示:

左边是基于优化MSE的深度学习方法,中间是下面要介绍的SRGAN,右边是真实的超分图片。

2. SRGAN

2.1 SRGAN对比GAN

SRGAN率先把GAN引入到超分辨领域。了解GAN的朋友可以快速理解SRGAN:与标准的GAN结构相比,SRGAN生成器的输入不再是噪声,而是低分辨率图像;而判别器结构跟普通的GAN没有什么区别。

2.2 SRGAN的损失函数

与先前的基于深度学习的超分方法相比,SRGAN只有一个明显的变化: (生成器的)Loss函数不再单是对构建出来图片与真实高分辨率图片求均方误差,而是加上对构建出图片的特征图与真实高分辨率图片的特征图求均方误差。

作者定义了一个内容损失(Content loss),为原MSE与特征图MSE加权和[4]:

 (2)

 

 即上面的公式(1),  的具体做法是分别得到真实图片与构建图片在VGG19下的某个层的特征图(tensorlayer的实现是用所有的特征图),在特征图下求MSE,这部分loss被称为VGG loss:

 (3)

公式(2)与公式(1)相比,无非是多了个  。  指的是第i个maxpooling层前的第j个卷积的特征图。

我这里用的是TensorLayer的实现,和原论文有些不同:原文并没有提到公式(2),只说了  ,没说要加上  ...  的权重是个超参,  是TensorLayer的设置,设置到这么小应该是因为用了所有的特征图。这个超参不要乱动,不知道是前辈们调了多久调出来的……

为什么能提升效果?

我们知道,CNN主要是靠纹理来识别物体的,一个在ImageNet上训练好的CNN包含的丰富的纹理信息。低分辨率的图像和高分辨率的图像在形状、位置上是严格对等的,缺的只是纹理。相近,则就是纹理相近。

整个生成器的损失函数被作者称为“感知损失(Perceptual loss)”,除了内容损失以外还要加上一个GAN原有的对抗损失:

 (4)

 是判别器对于生成超分图片的输出,-log(x)在(0,1)上是个单调递减的函数。生成器希望  的值越大越好,也就是 

越小越好,因此梯度更新的时候需要最小化  。

最终生成器的损失函数为:

 (5)

该部分代码[4]如下:

g_gan_loss = 1e-3 * tl.cost.sigmoid_cross_entropy(logits_fake, tf.ones_like(logits_fake))
mse_loss = tl.cost.mean_squared_error(fake_patchs, hr_patchs, is_mean=True)
vgg_loss = 2e-6 * tl.cost.mean_squared_error(feature_fake, feature_real, is_mean=True)
g_loss = mse_loss + vgg_loss + g_gan_loss

代码中的logits_reallogits_fake分别判别器对是真实高分图片、GAN生成的高分图片的输出。fake_patchshr_patchs分别是生成器的输出、真实的高分图片。feature_fakefeature_real是构建的图片、真实图片在VGG网络中的特征图:

feature_fake = VGG((fake_patchs+1)/2.) # the pre-trained VGG uses the input range of [0, 1]
feature_real = VGG((hr_patchs+1)/2.)

至于判别器的损失,没有什么特别之处:

d_loss1 = tl.cost.sigmoid_cross_entropy(logits_real, tf.ones_like(logits_real))
d_loss2 = tl.cost.sigmoid_cross_entropy(logits_fake, tf.zeros_like(logits_fake))
d_loss = d_loss1 + d_loss2

到这里SRGAN就差不多讲完了,至于生成器和判别器使用了什么样的CNN不是本文重点,大家看一眼就行:

 

 

注意生成器里面使用的是残差结构,并使用了BN,这两个点是ESRGAN改进的地方。

3. ESRGAN

ESRGAN[5]这篇论文中的是ECCV2018的workshop,没中ECCV应该是因为这篇文章中绝大部分改进都是直接使用别人的方法,但这并不代表这篇论文不够出色。这篇论文是港中大多媒体实验室拿到超分比赛冠军的模型,打比赛当然是追求效果好了。该论文在Google Scholar上的引用已经有200多次,其GitHub项目有2000多个Star!

ESRGAN的整体框架和SRGAN保持一致,相比SRGAN,ESRGAN有4处改进。

3.1 改进一:用Dense Block替换Residual Block,并去掉BN层

 

如题,如图……

去掉BN并加上Dense Block效果为什么好?作者对该问题的答案并没有给出很好的解释,这是因为,作者写这篇文章的时候,[6,7]这两项研究还没有出世,所以作者的解释不用看了,让我来解释吧…

3.1.1 为什么要去掉BN?

推荐这篇博客https://zhuanlan.zhihu.com/p/43200897 这里直接引用如下:

对于有些像素级图片生成任务来说,BN效果不佳;
对于图片分类等任务,只要能够找出关键特征,就能正确分类,这算是一种粗粒度的任务,在这种情形下通常BN是有积极效果的。但是对于有些输入输出都是图片的像素级别图片生成任务,比如图片风格转换等应用场景,使用BN会带来负面效果,这很可能是因为在Mini-Batch内多张无关的图片之间计算统计量,弱化了单张图片本身特有的一些细节信息。

以及这篇博客http://www.pianshen.com/article/2449328261/

以图像超分辨率来说,网络输出的图像在色彩、对比度、亮度上要求和输入一致,改变的仅仅是分辨率和一些细节。而Batch Norm,对图像来说类似于一种对比度的拉伸,任何图像经过Batch Norm后,其色彩的分布都会被归一化。也就是说,它破坏了图像原本的对比度信息,所以Batch Norm的加入反而影响了网络输出的质量。ResNet可以用BN,但也仅仅是在残差块当中使用。

 

3.1.2 为什么要使用Dense Block?

论文[6] How does batch normalization help optimization指出,BN的作用是网络更容易优化,不容易陷入局部极小值。ESRGAN去掉了BN,可以猜想,如果保持原有的Residual Block结构,网络会变得非常难易训练,而且很容易陷入局部极小值导致结果不好。论文[7] Visualizing the loss landscape of neural nets可视化了一些网络的解空间:

 

 

可以看到,DenseNet的解空间非常平滑,也就是说,DenseNet相比其他网络要容易训练的多,Dense Block和BN提升网络性能的原因是相同的!(划重点!!!)

BN有副作用所以去掉了BN,所以要拿Dense Block来弥补!

推荐下我的这篇博客,https://zhuanlan.zhihu.com/p/86886887 对这个问题有更详尽的说明。

3.2 改进二:改进对抗损失函数——使用Relativistic GAN

Relativistic GAN[8]改进了GAN的损失函数:

 

 

 表示判别器的输出,  是sigmoid函数。  是对一个batch的数据求平均,可以不用看。上图的意思就是:原来的判别器希望【输入真实图片】后输出趋近于1,现在判别器希望【输入真实图片-输入生成图片】后输出趋近于1;原来的判别器希望【输入生成图片】后输出趋近于0,现在判别器希望【输入生成图片-输入真实图片】后的输出趋近于0。

判别器该部分的损失为:

 (6)

生成器该部分的损失为:

 (7)

下面我推导一下(6,7)两个公式是怎么来的:

Ian Goodfellow 在GAN开篇之作给出的公式:

 (8)

可以改写为:

 (9)

 (10)

(10)的另一种形式:

 (11)

(x表示真实图片,z表示输入G网络的噪声)

将公式(9)的  换成  ,  换成  就变成了公式(6)。公式(11)比公式(7)和(8)少一项是因为公式(8)中的第1项和生成器G无关。而Relativistic GAN,这里变成了相关的,把公式(11)改写为:

 (12)

再次将公式(12)的  换成  , 换成 就变成了公式(7)。

 

改进三:改进生成器——使用relu激活前的特征图计算损失

作者解释有两个原因:

  1. 激活后的特征图变的非常稀疏,丢失了很多信息。
  2. 使用激活后的特征图会造成重建图片在亮度上的不连续。

此时,就可以求出生成器的损失函数:

 (13)

其中,  是重建图片与真实高清图片逐像素差的绝对值,也就是把MSE换成绝对值。  感知损失就是前面公式(3),只是把激活前的特征图换成激活后的特征图。

顺便说一句,SRGAN和ESRGAN给损失函数起的名字不同!我不知道ESRGAN作者没延续SRGAN的名字是写错了还是有意为之,反正ESRGAN给loss起的名字比SRGAN合理!SRGAN中的Perceptual Loss是指整个生成器的损失函数,而ESRGAN是指由特征图计算出来的Loss;SRGAN中的Content Loss是指原图的MSE+其特征图的MSE,而ESRGAN是指由真实高清图与重建图直接计算的L1 loss。

来个表格对比一下两篇论文的命名:

3.4 改进四:使用网络插值(network interpolation)方法平衡解决客观评价指标与主观评价指标的矛盾

基于GAN的方法有一个缺点,经常会生成奇怪的纹理,而非GAN的方法总是缺失细节,能不能把两种方法生成的图片加权相加呢?这就是所谓的Network Interpolation。

训练一个非GAN的网络,在这个网络的基础上fine-tuning出GAN的生成器,然后把两个网络的参数加权相加:

 (14)

这个公式非常好理解了两个网络的参数相加。其实等价于两种方法的输出分别相加。

通过  这个参数可以对生成图片的平滑程度进行调控,这点还是很爽的。

到这里ESRGAN也介绍完了,最后强烈推荐官方代码

https://github.com/xinntao/ESRGAN​github.com

 

我git clone完在pytorch环境下可以直接运行,测试下效果:

左,中,右分别为低分辨率图像,ESRGAN生成的图像,原始高清图像。可以看到中间的图生成了很多纹理,看起来比右边的原图还要清晰。。。

代码解析如果有空的话我会补一下(我好忙啊...)

 

[1] Noh, Junhyug, et al. "Better to Follow, Follow to Be Better: Towards Precise Supervision of Feature Super-Resolution for Small Object Detection." Proceedings of the IEEE International Conference on Computer Vision. 2019.

[2] Li, Jianan, et al. "Perceptual generative adversarial networks for small object detection." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2017.

[3] Ledig, Christian, et al. "Photo-realistic single image super-resolution using a generative adversarialnetwork." Proceedings of the IEEE conference on computer vision and pattern recognition. 2017.

[4] tensorlayer/srgan [https://github.com/tensorlayer/srgan]

[5] Wang, Xintao, et al. "Esrgan: Enhanced super-resolution generative adversarial networks." Proceedings of the European Conference on Computer Vision (ECCV). 2018.

[6] Santurkar, Shibani, et al. "How does batch normalization help optimization?." Advances in Neural Information Processing Systems. 2018.

[7] Li, Hao, et al. "Visualizing the loss landscape of neural nets." Advances in Neural Information Processing Systems. 2018.

 

原文 https://zhuanlan.zhihu.com/p/101771429

 

[8] Jolicoeur-Martineau, Alexia. "The relativistic discriminator: a key element missing from standard GAN." arXiv preprint arXiv:1807.00734 (2018).

图像超分是指将低分辨率的图像通过计算机算法提升到高分辨率的过程,这在计算机视觉领域非常重要。GAN(Generative Adversarial Networks)是一种深度学习模型,在图像处理中广泛应用。下面简要介绍一下如何用GAN网络实现图像超分。 GAN网络由生成器(Generator)和判别器(Discriminator)两个部分组成。在训练过程中,生成器通过生成高分辨率图像来欺骗判别器,而判别器则试图区分真实图像和生成图像。通过不断迭代训练,生成器可以生成越来越真实的图像。 下面是用GAN网络实现图像超分的步骤: 1. 准备数据集,包括低分辨率图像和高分辨率图像。低分辨率图像是输入,高分辨率图像是标签。 2. 构建生成器网络,将低分辨率图像作为输入,输出高分辨率图像。生成器通常由卷积层、反卷积层、残差块等组成。 3. 构建判别器网络,将生成器生成的图像和真实图像作为输入,输出一个二元分类结果。判别器通常由卷积层、全连接层等组成。 4. 定义损失函数,用于衡量生成器生成的图像和真实图像之间的差异。损失函数通常包括像素差损失(Pixel Loss)、感知损失(Perceptual Loss)和对抗损失(Adversarial Loss)等。 5. 进行训练,通过不断迭代优化生成器和判别器的参数,使生成器生成的图像越来越接近真实图像。 6. 在训练过程中,可以使用一些技巧来提高模型的性能,比如使用残差块、增加噪声等。 7. 最后,用训练好的模型来对新的低分辨率图像进行超分处理,得到高分辨率图像。 以上是用GAN网络实现图像超分的基本步骤,具体实现中还需根据具体情况进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值