![0386c2933946e08282221a5a16df51f4.png](https://i-blog.csdnimg.cn/blog_migrate/0c5341b475629059d8b6f6ad5c2b93b9.jpeg)
本次给大家介绍2篇文章——SRGAN[3]和ESRGAN[5],基于生成对抗网络的超分辨率方案。
先回顾一下以往的方法:
1. 图像放大与基于CNN的超分方案
所有使用电脑的人都会用到图片放大的操作,而把图片放大超过其分辨率后,图片就会模糊。传统放大图片都是采用插值的方法,最常用的有最近邻插值(Nearest-neighbor)、双线性插值(Bilinear)、双立方插值(bicubic)等,这些方法的速度非常快,因此被广泛采用。
基于卷积神经网络/深度学习超分方案的开山之作叫做SRCNN(Super-Resolution Convolutional Neural Network),由港中大多媒体实验室在2015年提出。
基于卷积神经网络的方案很容易理解:传统插值方法可以看做把像素复制放大倍数后,用某种固定的卷积核去卷积;而基于卷积神经网络的超分方法无非是去学习这个卷积核,根据构建出的超分图像与真实的高分辨率图像(Ground Truth)的差距去更新网络参数。
这种方法的损失函数一般都采用均方误差MSE——即构建出来的超分图像与真实超分图像逐像素差的平方:
这种方法存在一个问题:尽管在客观评价指标——MSE(均方误差)、PSNR(峰值信噪比)上成绩很好,但总是倾向于生成过于平滑的图像,如下图所示:
![51371862666123548f7b57690fcda84f.png](https://i-blog.csdnimg.cn/blog_migrate/9bffc3101f26cdf829034106d0cac80e.jpeg)
左边是基于优化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)相比,无非是多了个
我这里用的是TensorLayer的实现,和原论文有些不同:原文并没有提到公式(2),只说了
我们知道,CNN主要是靠纹理来识别物体的,一个在ImageNet上训练好的CNN包含的丰富的纹理信息。低分辨率的图像和高分辨率的图像在形状、位置上是严格对等的,缺的只是纹理。
整个生成器的损失函数被作者称为“感知损失(Perceptual loss)”,除了内容损失以外还要加上一个GAN原有的对抗损失:
越小越好,因此梯度更新的时候需要最小化
最终生成器的损失函数为:
该部分代码[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_real
和logits_fake
分别判别器对是真实高分图片、GAN生成的高分图片的输出。fake_patchs
, hr_patchs
分别是生成器的输出、真实的高分图片。feature_fake
、feature_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不是本文重点,大家看一眼就行:
![29a4e9d81984fc747053958e6df7a745.png](https://i-blog.csdnimg.cn/blog_migrate/3e6fc3732603accfc5ee4fe2b3edd3c8.jpeg)
注意生成器里面使用的是残差结构,并使用了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层
![5865f7c7a0386b4d758599c7a1db0ce0.png](https://i-blog.csdnimg.cn/blog_migrate/dc96b6d311a5a0f8561a89a67dce7535.jpeg)
如题,如图……
去掉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可视化了一些网络的解空间:
![9af001d58a05954c08c49fdfb165ca47.png](https://i-blog.csdnimg.cn/blog_migrate/21ba60fb195aebfbe03b1f680c322bca.jpeg)
可以看到,DenseNet的解空间非常平滑,也就是说,DenseNet相比其他网络要容易训练的多,Dense Block和BN提升网络性能的原因是相同的!(划重点!!!)
BN有副作用所以去掉了BN,所以要拿Dense Block来弥补!
推荐下我的这篇博客,https://zhuanlan.zhihu.com/p/86886887 对这个问题有更详尽的说明。
3.2 改进二:改进对抗损失函数——使用Relativistic GAN
Relativistic GAN[8]改进了GAN的损失函数:
![aa9967e2e6250027511ece2810678bae.png](https://i-blog.csdnimg.cn/blog_migrate/61595d140cdaf02c6c3642b485e52ec6.jpeg)
判别器该部分的损失为:
生成器该部分的损失为:
下面我推导一下(6,7)两个公式是怎么来的:
Ian Goodfellow 在GAN开篇之作给出的公式:
可以改写为:
(10)的另一种形式:
(x表示真实图片,z表示输入G网络的噪声)
将公式(9)的
再次将公式(12)的
改进三:改进生成器——使用relu激活前的特征图计算损失
![70aa35283d6f294d805bb01c2f23ce97.png](https://i-blog.csdnimg.cn/blog_migrate/e1e1d6e7fe645bb6cb7e4ff4c2c673d3.jpeg)
作者解释有两个原因:
- 激活后的特征图变的非常稀疏,丢失了很多信息。
- 使用激活后的特征图会造成重建图片在亮度上的不连续。
此时,就可以求出生成器的损失函数:
其中,
顺便说一句,SRGAN和ESRGAN给损失函数起的名字不同!我不知道ESRGAN作者没延续SRGAN的名字是写错了还是有意为之,反正ESRGAN给loss起的名字比SRGAN合理!SRGAN中的Perceptual Loss是指整个生成器的损失函数,而ESRGAN是指由特征图计算出来的Loss;SRGAN中的Content Loss是指原图的MSE+其特征图的MSE,而ESRGAN是指由真实高清图与重建图直接计算的L1 loss。
来个表格对比一下两篇论文的命名:
![cff153e44d3d6f5f33a35c95f8a5b6d8.png](https://i-blog.csdnimg.cn/blog_migrate/1e2e47db5ca6662d8f3cc162f9fd625d.jpeg)
3.4 改进四:使用网络插值(network interpolation)方法平衡解决客观评价指标与主观评价指标的矛盾
基于GAN的方法有一个缺点,经常会生成奇怪的纹理,而非GAN的方法总是缺失细节,能不能把两种方法生成的图片加权相加呢?这就是所谓的Network Interpolation。
训练一个非GAN的网络,在这个网络的基础上fine-tuning出GAN的生成器,然后把两个网络的参数加权相加:
这个公式非常好理解了两个网络的参数相加。其实等价于两种方法的输出分别相加。
![a190062109d1681eeb1586856d25c632.png](https://i-blog.csdnimg.cn/blog_migrate/9b28bd095b7426de43c6f5d98661dc34.jpeg)
通过
到这里ESRGAN也介绍完了,最后强烈推荐官方代码
https://github.com/xinntao/ESRGANgithub.com我git clone完在pytorch环境下可以直接运行,测试下效果:
![ee7df6578f07b453610833b90abafdea.png](https://i-blog.csdnimg.cn/blog_migrate/2bc5e2d2a76b29d558562fd2b4b5355d.jpeg)
左,中,右分别为低分辨率图像,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.
[8] Jolicoeur-Martineau, Alexia. "The relativistic discriminator: a key element missing from standard GAN." arXiv preprint arXiv:1807.00734 (2018).