10分钟理解基于GAN的超分辨率方案——SRGAN,ESRGAN

本文首发于渣画质的救赎——基于GAN的超分辨率方案

欢迎关注专栏深度学习下的计算机视觉


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

我自己不是研究GAN或者超分的,而这个工作至少对我或者其它计算机视觉领域的研究者有两个帮助:

计算机视觉里总会遇到小物体、模糊物体,不妨试试把超分网络加入进去,如[1,2]。

所有输出一张图片的任务都可以尝试用GAN去解决,比如各种质量改善:图像去噪,去雾,去模糊;显著性检测,图像分割…… 而GAN用作超分重建算是GAN所有任务中最简单又最容易拓展的一个。

下面进入正题:


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

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

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

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

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

l_{M S E}^{S R}=\frac{1}{r^{2} W H} \sum_{x=1}^{r W} \sum_{y=1}^{r H}\left(I_{x, y}^{H R}-G_{\theta_{\sigma}}\left(I^{L R}\right)_{x, y}\right)^{2}          (1)

\theta_{\sigma} 是网络参数, I^{L R} 是低分辨率图像, G_{\theta_{\sigma}}\left(I^{L R}\right)_{x, y} 是重建出来的高分辨率图像,  G_{\theta_{\sigma}}\left(I^{L R}\right)_{x, y} 是真实的高分辨率图像,r, W, H 分别是图片数量、图片宽和高,都可以看成常数。

这种方法存在一个问题:尽管在客观评价指标——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]:

l_{\mathrm{X}}^{S R}=l_{M S E}^{S R}+10^{-6 *} l_{G e n}^{S R}  (2)

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

l_{V G G / l, j}^{S R}=\frac{1}{W_{i, j} H_{i, j}} \sum_{x=1}^{W_{i, j}} \sum_{y=1}^{M_{i, j}}\left(\phi_{i, j}\left(I^{H R}\right)_{x, y}-\phi_{i, j}\left(G_{\theta_{c}}\left(I^{L R}\right)\right)_{x, y}\right)^{2}       (3)

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

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

至于 10^{-6} 为什么能提升效果不好证明,我的理解是使用特征图计算MSE相对于直接计算MSE约束变弱了。直接计算MSE约束太强,生成的图片有很低的MSE但过于平滑,降低要求后,MSE变高,但人眼看上去反而觉得效果变好了。

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

l_{G e n}^{S R}=\sum_{n=1}^{N}-\log D_{\theta_{D}}\left(G_{\theta_{G}}\left(I^{L R}\right)\right)       (4)

D_{\theta_{D}}\left(G_{\theta_{\mathrm{G}}}\left(I^{L R}\right)\right) 是判别器对于生成超分图片的输出,-log(x)在(0,1)上是个单调递减的函数。生成器希望 D_{\theta_{D}}\left(G_{\theta_{G}}\left(I^{L R}\right)\right) 的值越大越好,也就是 -\log D_{\theta_{D}}\left(G_{\theta_{G}}\left(I^{L R}\right)\right)越小越好,因此梯度更新的时候需要最小化 l_{\text {Gen }}^{S R}

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

l^{S R}=l_{M S E}^{S R}+10^{-6} * l_{G e n}^{S R}+10^{-3} l_{G e n}^{S R}         (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_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不是本文重点,大家看一眼就行:

注意生成器里面使用的是残差结构,并使用了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的损失函数:

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

判别器该部分的损失为:

L_{D}^{R a}=-\mathbb{E}_{x_{r}}\left[\log \left(D_{R a}\left(x_{r}, x_{f}\right)\right)\right]-\mathbb{E}_{x_{f}}\left[\log \left(1-D_{R a}\left(x_{f}, x_{r}\right)\right)\right]       (6)

生成器该部分的损失为:

L_{G}^{R a}=-\mathbb{E}_{x_{r}}\left[\log \left(1-D_{R a}\left(x_{r}, x_{f}\right)\right)\right]-\mathbb{E}_{x_{f}}\left[\log \left(D_{R a}\left(x_{f}, x_{r}\right)\right)\right]       (7)

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

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

\min _{G} \max _{D} V(D, G)=\mathbb{E}_{\mathbf{x} \sim p_{\text {data }}(\mathbf{x})}[\log D(\mathbf{x})]+\mathbb{E}_{\mathbf{z}-p_{t}(\mathbf{z})}[\log (1-D(G(\mathbf{z})))] (8)

可以改写为:

L_{D}=-\mathbb{E}_{\mathrm{x}-p_{\text {data }}(\mathrm{x})}[\log D(\mathbf{x})]-\mathbb{E}_{\mathbf{z}-p_{k}(\mathbf{z})}[\log (1-D(G(\mathbf{z})))]          (9)

L_{G}=E_{x-P_{z}}[\log (1-D(G(z)))]                                      (10)

(10)的另一种形式:

L_{G}=-E_{x-P_{z}}[\log (D(G(z)))]                                       (11)

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

将公式(9)的L_{G}=-E_{x-P_{z}}[\log (D(G(z)))]   换成{D_{Ra}}\left( {{x_r},{x_f}} \right), G({\bf{z}})换成 {D_{Ra}}\left( {{x_{\rm{f}}},{x_r}} \right) 就变成了公式(6)。公式(11)比公式(7)和(8)少一项是因为公式(8)中的第1项和生成器G无关。而Relativistic GAN,这里变成了相关的,把公式(11)改写为:

L_{G}=-E_{x-P_{data}}[\log (1-D(x))]-E_{x-P_{z}}[\log (D(G(z)))]                  (12)

再次将公式(12)的 D(\mathbf{x}) 换成{D_{Ra}}\left( {{x_r},{x_f}} \right),G({\bf{z}})换成{D_{Ra}}\left( {{x_{\rm{f}}},{x_r}} \right)就变成了公式(7)。

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

作者解释有两个原因:

激活后的特征图变的非常稀疏,丢失了很多信息。

使用激活后的特征图会造成重建图片在亮度上的不连续。

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

{L_G} = {L_{{\rm{percep }}}} + \lambda L_G^{Ra} + \eta {L_1}                                      (13)

其中,{L_1} = {\mathbb{E}_{{x_i}}}{\left\| {G\left( {{x_i}} \right) - y} \right\|_1}是重建图片与真实高清图片逐像素差的绝对值,也就是把MSE换成绝对值。 {L_{{\rm{percep }}}} 感知损失就是前面公式(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的生成器,然后把两个网络的参数加权相加:

\theta _G^{{\rm{INTERP}}} = (1 - \alpha )\theta _G^{{\rm{PSNR}}} + \alpha \theta _G^{{\rm{GAN}}}                                        (14)

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

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

到这里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.

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353