SRGAN——使用与超分辨率重建的GAN

本文详细介绍了超分辨率重建技术,特别是SRGAN和ESPCN在网络结构和优化方法上的应用。首先,讨论了超分辨率的基本概念和分类,包括基于深度学习的SISR方法,如SRCNN、ESPCN和实时方法。接着,通过TensorFlow实现ESPCN网络在MNIST和flowers数据集上的超分辨率重建,对比了不同插值方法和模型的性能。进一步,文章探讨了残差网络在ESPCN基础上的改进,提高了4倍分辨率的重建效果。最后,引入了SRGAN,利用对抗网络在高分辨率图像生成中考虑了图像的细节和整体风格,以提高重建质量。整个过程包含了损失函数、优化器的选择以及训练过程中的检查点保存和恢复。

  SRGAN数据GAN理论在超分辨率重建(SR)方面的应用。

一、超分辨率技术

1.SR技术介绍

  SR技术,是指从观测到的低分辨率图像重建出相对应的高分辨率图像,在监控设备、卫星图像和医学影像等领域都有重要的应用价值,也可以应用于马赛克图片的恢复应用场景。
  SR可分为两类:从多张低分辨率图像重建出高分辨率图像;从单张低分辨率图像重建出高分辨率图像。基于深度学习的SR,主要是基于单张低分辨率的重建方法,即Single Image Super-Resolution(SISR)。
  SISR是一个逆问题。对于一个低分辨率图像,可能存在许多不同的高分辨率图像与之对应,为了让逆向的结果更加接近真实图片,则需要让模型在一定约束下,指定某个领域中进行可逆训练。这个约束,就是指现有的低分辨率像素的色度信息与位置信息。为了让模型更好的学习并利用这个信息,基于深度学习的SR通过神经网络直接通过优化低分辨率图像道高分辨率图像的loss来进行端到端的训练。

2.深度学习中的SR方法

  在GAN出现之前,通常采用SRCNN、DRCN。该方法的大体思路是将低分辨率像素先扩展到高分辨率的像素大小,然后通过卷积方式训练网络,优化其与真实高分辨率图片的loss,最终形成模型。
  后面出现了另一种高效的方法ESPCN(实时的基于卷积神经网络的图像超分辨率方法)。ESPCN的核心概念是亚像素卷积层,即先在原有的低像素图像上做卷积操作,最终输出一个含有多个feature map的结果,保证总像素点与高分辨率的像素点总是一致的,然后将多张低分辨率图像合并成一张高分辨率的图像。
  例如,假设需要将低分辨率图片的像素扩大2倍(从128×128扩大到256×256),就直接将其进行卷积操作,最终输出放大倍数的平方4个feature map。以灰度图为例,将4个图片中的第一个像素取出成为重构图中的4个像素,依次类推,在重构图中的每2×2区域都是有这4幅图对应位置的像素组成,最终形成[batch_size,2×W,2×H,1]大小的高分辨率图像,这个变换陈伟亚像素卷积。
在这里插入图片描述

3.TensorFlow中的图片变换函数

def resize_image(images, size, method=ResizeMethod.BILINEAR, align_corners=False):
  前两个参数分别是输入的图片及要变换的尺寸,图片的形状为[batch, height, width, channels]或[height, width, channels]。第3个参数的取值。

  • ResizeMethod.BLINEAR:表示使用双线性茶汁算法变化图片。
  • ResizeMethod.NEAREST_NEIGHBOR:表示使用邻近插值算法变化图片。
  • ResizeMethod.BICUBIC:表示使双立方插值算法变化图片。
  • ResizeMethod.AREA:表示使用面积插值算法变化图片

二、实例93:ESPCN实现MNIST数据集的超分辨重建

实例描述

  通过使用ESPCN网络,在MNIST数据集上将低分辨率图片复原成高分辨率图片,并与其他复原函数的生成结果进行比较。

1.引入头文件,构建低分辨率样本

  在头文件部分导入slim库,使用resize_bicubic来构建缩小的4倍低分辨率样本,将28×28的像素变成14×14(缩小2倍)

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import tensorflow.contrib.slim as slim
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/data/", one_hot=True)


batch_size = 30   # 获取样本的批次大小
n_input = 784 # MNIST data 输入 (img shape: 28*28)
n_classes = 10  # MNIST 列别 (0-9 ,一共10类)

x = tf.placeholder("float", [None, n_input])
img = tf.reshape(x,[-1,28,28,1])
x_small = tf.image.resize_bicubic(img, (14, 14))#  缩小2倍

2.通过TensorFlow函数实现超分辨率

  分别使用bicubic、nearest_neighbor和bilinear方法将分辨率还原。

x_bicubic = tf.image.resize_bicubic(x_small, (28, 28))#双立方插值算法变化
x_nearest = tf.image.resize_nearest_neighbor(x_small, (28, 28))
x_bilin = tf.image.resize_bilinear(x_small, (28, 28))

3.建立ESPCN网络结构

  建立一个简单的三层卷积网络:第1层使用5×5的卷积核,输出64通道的图片,slim卷积函数使用的是默认激活函数Relu;第2层使用3×3的卷积核,输出是32通道;最后一层使用3×3卷积核,生成4通道图片。这个4通道需要和恢复超分辨率缩放范围对应,4代表长、宽各放大2倍。接着使用tf.depth_to_space函数,将多张图片合并成一张图片。
tf.depth_to_space函数的意思是将深度数据按照块的模式展开重新排列,第一个输入是原始数据,第二个输入是块的尺寸,输入2则代表尺寸为2×2的块。而深度就是生成图片的通道数,即每个通道对应的像素值填充到指定大小的块中。

#espcn
net = slim.conv2d(x_small, 64, 5)
net =slim.conv2d(net, 32, 3)
net = slim.conv2d(net, 4, 3)
net = tf.depth_to_space(net,2)

4.构建loss及优化器

  将图片重新调整形状(reshape)为(batch_size, 784)的形状,通过平方差来计算loss,设定学习率为0.01。

y_pred = tf.reshape(net,[-1,784])

cost = tf.reduce_mean(tf.pow(x - y_pred, 2))
optimizer = tf.train.AdamOptimizer(0.01 ).minimize(cost)

5.建立session,运行

training_epochs =100
display_step =20

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    total_batch = int(mnist.train.num_examples/batch_size)
    # 启动循环开始训练
    for epoch in range(training_epochs):
        # 遍历全部数据集
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)  
            _, c = sess.run([optimizer, cost], feed_dict={
   
   x: batch_xs})
        # 显示训练中的详细信息
        if epoch % display_step == 0:
            print("Epoch:", '%04d' % (epoch+1),
                  "cost=", "{:.9f}".format(c))

    print("完成!")

6.图示结果

  为了比较效果,将原始图片、低分辨率图片、各种算法的变换图片及模型恢复图片一起显示。

 show_num = 10
    encode_s,encode_b,encode_n ,encode_bi,y_predv= sess.run(
        [x_small,x_bicubic,x_nearest,x_bilin,y_pred], feed_dict={
   
   x: mnist.test.images[:show_num]})
    
    f, a = plt.subplots(6, 10, figsize=(10, 6))
    for i in range(show_num):
        a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
        a[1][i].imshow(np.reshape(encode_s[i], (14, 14)))
        a[2][i].imshow(np.reshape(encode_b[i], (28, 28)))
        a[3][i].imshow(np.reshape(encode_n[i], (28, 28)))
        a[4][i].imshow(np.reshape(encode_bi[i], (28, 28)))
        a[5][i].imshow(np.reshape(y_predv[i], (28, 28)))
    plt.show()

在这里插入图片描述

三、实例94:ESPCN实现flowers数据集的超分辨率重建

  下面对彩色图片进行超分辨率的重构。彩色图片与MNIST样本不同的地方主要是,图片变成3通道,并且像素点更多,而MNIST像素点更稀疏。所以应用在训练模型上,会有一些细节进行调节。
  本例主要实现对flowers数据集的图片处理。本例同样还是使用slim模块进行数据的操作。另外flowers是尺寸不一样的数据样本,所以本例需要借鉴统一尺寸处理的方法。

实例描述

  通过使用ESPCN网络,在flowers数据集上将低分辨率图片复原成高分辨率图片并与其他复原函数生成结果进行比较。

1.引入头文件,创建样本数据源

  同样使用slim,这次使用的数据源是flowers,将代码文件建立在models下的slim中。

放在slim文件外的话datasets模块会导入失败
slim文件中tf_slim更改一下,应该是TensorFlow1.×版本的问题。

在这里插入图片描述

height = width = 200
batch_size = 4

DATA_DIR="flowers"

#选择数据集validation
dataset = flowers.get_split('validation', DATA_DIR)
#创建一个provider
provider = slim.dataset_data_provider.DatasetDataProvider(dataset,num_readers = 2)
#通过provider的get拿到内容
[image, label] = provider.get(['image', 'label'])
print(image.shape)

这里自己做数据集时没做到存入不同大小图片,先剪辑相同大小再存入数据集,slim中的是将数据集导出再剪辑。

2.获取批次样本并通过TensorFlow函数实现超分辨率

  通过resize_image_with_crop_or_pad函数统一样本大小,大的减掉,不够的加0填充。使用tf.train.batch函数获得指定批次数据image和labels


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值