作者:我只是狼却有幅羊的心肠_152 | 来源:互联网 | 2023-10-12 16:15
前言
平时生活中,我们经常碰到一些自己喜欢的图片却苦于分辨率很低,而原图又找不太到。 现在,神经网络可以帮助我们从一张给定的低分辨率图片恢复出高分辨率的图片。 这个功能听上去既炫酷又实用,具体是怎么做的呢,详见下文!
Demo效果
上图就是训练了2000次后的模型的效果,只需要输入一张左边的低精度的图片, 就可以生成右边的高精度的图片。肉眼看上去效果还是非常不错的!
这张GIF则展示了整个训练过程的变化, 左边的图是由神经网络生成的, 中间的是原始的高精度的图片, 右边的是输入到神经网络的低分辨率图片, 神经网络在整个生成过程中是没有得到高精度图片信息的,这里给出高精度图片只是为了对比体现生成的效果。可以看到在100次epoch迭代之后,性能已经非常不错了。
链接
项目源码:基于keras的SRGAN实现.
主要参考了著名的keras-GAN这个库,做了一些小改动使得节目效果更好,适合作为Demo来展示哈哈。如果对你有帮助的话请Star一下哈!
论文地址 被引用了1500多次,很强了!这个代码也是根据论文里的参数写的。
数据集地址 这个链接给出了百度云和谷歌云盘的下载地址,笔者是用百度云下载的,非会员用户, 5M/s的速度,很给力!
原理分析
这里提供非常概括性的分析,想深入理解的同学建议参考原文。
系统模型
首先作者使用了非常火热的GAN生成对抗网络(对GAN不熟悉的可以百度一下GAN,已经有许多优质的资料)。 生成网络(上图上半部)接收低精度图片作为输入,通过残差网络等,生成高精度图片。 然后 判别器网络(上图下半部)接收一个输入, 判断其是否为生成的图片。 损失函数为:
min θ G max θ D E I H R ∼ p r a n i n ( I H R ) [ log D θ D ( I H R ) ] + E I L R ∼ p G ( I L R ) [ log ( 1 − D θ D ( G θ G ( I L R ) ) ] \begin{array}{c}{\min _{\theta_{G}} \max _{\theta_{D}} \mathbb{E}_{I^{H R} \sim p_{\mathrm{ranin}}\left(I^{H R}\right)}\left[\log D_{\theta_{D}}\left(I^{H R}\right)\right]+} {\mathbb{E}_{I^{L R} \sim p_{G}\left(I^{L R}\right)}\left[\log \left(1-D_{\theta_{D}}\left(G_{\theta_{G}}\left(I^{L R}\right)\right)\right]\right.}\end{array} minθGmaxθDEIHR∼pranin(IHR)[logDθD(IHR)]+EILR∼pG(ILR)[log(1−DθD(GθG(ILR))]
没有GAN基础的同学可能比较难理解上述公式,这里深入浅出的通俗解释下训练过程其实就是:
- 固定生成器G (参数为 θ G {\theta_{G}} θG), 训练判别器,使得其能够分辨 真实的图片和生成器生成的图片。
- 固定判别器, 训练生成器, 使得其能够让固定的判别器将其判别为真实的图片
如此迭代之后, 判别器再也无法分别真实和生成的图片,此时就说明生成器生成的图片已经足够以假乱真。这里真实的图片指的就是高精度的图片,训练完成后,我们期望生成器可以接收低精度图片,来生成高精度图片。
生成器作者主要使用了ResNet来实现。
判别器是使用了常规的卷积神经网络。
损失函数
与普通的GAN网络不同的是,这篇文章还考虑了content loss:
l V G G / i . j S R = 1 W i , j H i , j ∑ x = 1 W i , j H i , j ( ϕ i , j ( I H R ) x , y − ϕ i , j ( G θ G ( I L R ) ) x , y ) 2 \begin{array}{r}{l_{V G G / i . j}^{S R}=\frac{1}{W_{i, j} H_{i, j}} \sum_{x=1}^{W_{i, j} H_{i, j}}\left(\phi_{i, j}\left(I^{H R}\right)_{x, y}\right.} {-\phi_{i, j}\left(G_{\theta_{G}}\left(I^{L R}\right)\right)_{x, y} )^{2}}\end{array} lVGG/i.jSR=Wi,jHi,j1∑x=1Wi,jHi,j(ϕi,j(IHR)x,y−ϕi,j(GθG(ILR))x,y)2
意思就是,生成的图片会和准确的图片一起,输入到VGG网络中,然后得到特征图。 再将两者的特征图求MSE,并训练生成器缩小该MSE。这就是从内容的角度,让生成的图片和准确图片尽可能的接近。
结合上述的GAN网络,本文采用的loss是:
l S R = l X S R ⏟ content loss + 1 0 − 3 l G e n S R ⏟ adversarial loss l^{S R}=\underbrace{l_{\mathrm{X}}^{S R}}_{\text { content loss }}+\underbrace{10^{-3} l_{G e n}^{S R}}_{\text { adversarial loss }} lSR= content loss
lXSR+ adversarial loss
10−3lGenSR
也就是说在MSE损失的基础上,掺入了一点GAN的损失,作者指出这样会获得更好的性能。
实验
上述简单的概述应该很难让读者完全看懂,建议结合论文与代码一起融会贯通。这里说一下仿真细节:
数据集使用了数据集地址 人脸数据集,因此要恢复的图片也应该是人像图才会效果比较好。
笔者的配置是1080Ti + i9-9900k + 48G内存, 因此使用的batch_size为10。配置不够的同学可以先设为1,确保机器可以跑起来。
具体还可以参见基于keras的SRGAN实现中的readme,有具体的使用方法。
结束
这个Demo非常简单,但是效果很不错,适合课堂演示,Presentation之类的。
我给出了自己这边训练了2000次后的模型权重,可以从链接下载
提取码:su92
由于训练的模型固定了输出的尺寸,因此你自己想输入的图片也尽可能取正方形图片(裁剪一下就行)。