获取分辨率函数是什么_深度学习应用“Zero Shot”超分辨率重构图像

超分辨率(SR)是一种提高图像分辨率的技术。

这些方法是从低分辨率(LR)图像中获得高分辨率(HR)输出。执行单图像超分辨率(SISR)的目的是在增加图像尺寸的同时使其质量下降的最小。应用范围很广,如医学成像,压缩,农业分析,自动驾驶到卫星图像、侦察等等。

超分辨率领域正在经历一段复兴时期。卷积神经网络和生成性对抗网络等深度学习模型的最新进展引发了各种新方法,并为基于特征工程的经典方法无法解决的问题带来了最新的研究成果。

在本文中,我们将讨论该领域的主要方法,并将深入探讨一种名为Zero Shot Super Resolution的特殊方法。

472116febd0ca7e3d1472ef49d93641f.png

图1. ZSSR VS EDSR性能比较

目前,在深度学习领域SR主要有两种方法。

第一种方法:使用各种卷积神经网络,最好使用跳过连接(深度神经网络),并尝试将L1或L2损失最小化,从低分辨率对重建高分辨率图像。

第二种方法:生成性对抗神经网络,也称为GAN。

可以训练GAN架构以生成类似于特定数据集的分布。GAN拥有两个主要部分:生成器和判别器。

生成器学习如何从随机噪声中创建数据集分布,判别器学习如何区分数据集中的实际样本与从生成器合成创建的样本。通过以对抗性方式将它们一起训练,每个部分都经过迭代改进,最终的结果是得到一个强大的样本生成器和一个用于真实与合成样本的强大的判别器。

例如:通过向GAN提供MNIST数据集,其生成器学习如何创建手写数字,并且其判别器学习如何区分真实和合成数字。

cc647609cff4f1e59920e2146e850756.png

图2.手写数字(MNIST)的GAN示意图

我们采用这种架构并将GAN/对抗性损失降至最低。

SR的GAN模型的生成器部分通常使用L2损失(也称为MSE或均方误差)或更现代的感知损失,即均方误差(MSE),但是其来自于预先在Imagenet上训练的更深层的模型(通常是VGG-16或VGG-19)作为重构损失。预训练模型的输出为我们提供了高质量的特征,而无需任何耗时的特征工程。我们比较了网络输出的特征图和HR图像。

所有这些都归结为这样一个事实,即大多数超分辨率系统的核心都有L1或L2指标。这是有道理的,因为图像重建的标准指标是PSNR(峰值信噪比)具有内置的MSE(L2损失):

PSNR = 10 * log10((data_range ** 2)/ mse),在sci-kit图像中所定义。

Data_range是数据类型中的像素范围。通常为255或1。

MSE的值越低意味着误差越小,从MSE和PSNR之间的反比关系可以看出,MSE的值越小,PSNR值越大。从逻辑上讲,PSNR值越高越好,因为它意味着信噪比更高。

bae503657e9755c8cf1bbd2f380d137f.png

图3.创建高分辨率图像

限制

在Technion研究员Yochai Blau 最近的一篇论文中,经研究证据被证实表明这两种方法都受到内在权衡特性的约束。它的效果是显而易见的,因为现有的许多SR方法难以同时提高噪声(失真)和感知(质量)指标的性能。简单来说,超分辨率图像出现得越真实,它所具有的人造噪声或伪影越多,并且超分辨率图像中的失真和噪声越少,图像看起来就越模糊。

323ec779045c8dbc194ceeeed214c3e5.png

图4.失真和感知权衡

目前的超分辨率(SR)方法的问题在于它们中的大多数都受到监督。这意味着通过对成对数据集的优化来学习算法参数。通过将低分辨率图像重建为其高分辨率图像时的损失函数最小化。

虽然已经有人进行了一些尝试来生成具有本质上不同分辨率特征的数码相机拍摄的数据集,但大多数数据集是通过使用插值方法(通常是双三次)对图像进行下采样而生成的。这可能是非常有效且经济的,但这也意味着大多数数据集不包括室外LR图像。这具有非常深刻的含义,综合创建的数据集并不代表真正的伪影和常见的低级图像现象。这导致SR模型无法学习如何对抗源于光学或数字问题的缺陷,而主要是通过综合创建低分辨率(LR)图像而生成的伪影。最麻烦的是模型可能只学会逆转下采样机制本身。

要学习图像的超分辨率,首先要使用GAN学习如何进行图像退化来试图解决这种成对数据创建的错误方法。

28b13e27cf5a97f434cff4eac6bac111.png

图5.低质量图像放大

Zero Shot Super-Resolution(Zssr)

在Weizmann研究所的Assaf Shocher撰写的论文中,我们发现了一种新颖,简单而优雅的方法来实现单图像超分辨率。他们使用小型(~100K可训练参数)全卷积神经网络(FCN ),而不是在大型数据集上训练大型网络(EDSR ~43M参数),并对目标数据本身及其许多扩展进行训练。以生成最终更高分辨率输出。它们通过先创建原始图像的缩小副本,并对其进行裁剪、翻转和旋转,从而动态生成数据增强,并生成LR-HR对。然后,他们模拟一个特定的预定义的超分辨率比例,通过先向下采样,然后向上采样,将增强效果模糊到原来的大小(等于其父级HR的大小)。导致模糊和非模糊的一对增强,两者都从原始图像按相同的随机因素缩小比例,子级LR模糊的方式模拟预先确定的比例。

图6是我们的ZSSR版本。子级LR图像经过FCNN并最终添加到其未更改的副本(输出= LR + FCN(LR))。然后我们计算关于父级HR输出的L1损失:

然后将这些对输入到FCN网络进行训练,目的是将LR图像重建的L1损失降到最小,使其与HR匹配。使用具有ReLU激活函数,深度为8层和64个滤波器的神经网络的简单架构(对于所有层,只有最后一个是线性的)。设置从输入到输出的skip connection,因此我们只需要学习从模糊LR到HR源的残差图像。

cb347dfcda3555b4186418c30d26a688.png

图6. ZSSR算法的图示。

原始图像I被许多不同的比例因子下采样。每一个缩小的副本都是通过先缩小再放大来模糊的。通过比较网络输出的f(LR)和匹配的HR,我们可以训练出一个LR-HR对。

最后,我们在原始图像上进行测试(model.predict)以生成超分辨率输出。

存在真实高质量图像的情况下,可以使用PSNR和SSIM指标将其与网络输出进行比较。

关于这种架构的事实是,我们在没有验证集的情况下进行训练,并且只在原始样本上进行测试。虽然一开始这可能有点违反直觉,但它符合我们的目标,并明显减少了运行时间。

神经网络学习重新缩放(或映射)函数:

527b7dc2f620df4d48294618b0162168.png

关于全卷积神经网络(FCN)的另一个重要事实是我们可以使用不同的输入大小。因此,每组样本具有不同的大小。通过仔细选择正确地超参数:内核大小为3 * 3,步幅为1和填充'same',我们得到了与输入大小完全相同的输出大小,使我们能够计算它们的相对误差。我们只通过改变双三次插值来改进这个体系结构,调整大小的因素本身就是一个预定义的参数。

对这种架构的科学解释是在图像中存在重复的内部特征。在Weizmann研究所的同一组研究中显示,尺寸为5 * 5和7 * 7的小图像块在不同的位置(在一张图像中)重复它们的原始大小和跨尺度。在同一组的另一项工作中研究显示,单个图像与大图像数据集相比具有较低的内部熵。这与内部图像块和自相似性原则是一致的。针对所讨论的特定图像的神经网络进行训练,然后在其上进行测试。

b144676148cf8dae341d784a04939e77.png

图7. CSI 提高SOTA。

尽管神经网络接受域小,但神经网络能够捕获图像中对象的非局部递归。这源于特定图像的训练过程。通过使学习独立于图像大小来进一步加速学习。这是通过合并裁剪机制实现的。只从每个图像对中获取固定大小的裁剪,不过这个超参数会对运行时间和性能产生很大影响。

特定于图像的神经网络可能听起来是一个笨拙的解决方案,但现实是,尽管监督SISR方法可以得到令人印象深刻的结果,它们的性能在现实生活中的低质量图像上大大减少。学习如何对抗真实的噪声和人为干预需要创建一个非常深的神经网络,每个神经网络都经过训练并专门针对特定的问题进行处理,并且针对该特定任务需要数天甚至数周的处理。

Zero Shot Super resolution确实优于大型监督SISR模型,在具有噪声,压缩、伪影等影响较大的低分辨率图像。诸如降尺度内核,比例因子附加,噪声水平及其在训练增强上的类型等参数可供选择,从而能够更好地适应图像的特征(添加噪声有助于改善低质量LR图像的效果)。选择这些参数需要重新训练,因此不适合大型架构。

现在,我们看一下代码,讨论它是如何工作的,并强调修改它以供将来实验的方法。我们将突出强调main.py文件中的特定代码块,以更好地解释底层的内容。我们将深入研究代码实现并解释主要函数和评估指标。

导入必要的库

import argparseimport numpy as npimport cv2import osimport kerasfrom keras.callbacks import LearningRateScheduler, ModelCheckpointfrom keras.models import Modelfrom keras.layers import Conv2D, Inputfrom skimage.measure import compare_ssim as ssimfrom skimage.measure import compare_psnrimport globimport missinglink
7400879b346a3c9d9f382a9e3127d4c5.png

这里我么还使用了包括NumPy,cv2,Keras和MissingLink , MissingLink.ai SDK,它是深度学习工作流程自动化的平台,SDK通过消除管理大量实验,大型数据集,本地和外部机器以及代码版本控制的痛苦,实现了复杂深度学习模型的快速高效开发。我们将利用它来跟踪我们实验的实时值,然后,对于更高级的用户,我们将深入研究MissingLink的数据管理功能。

主程序编译

在主程序内部,我们设置了一个参数解析器,用于从CLI配置参数,获取输出目录和目标映像的路径,然后加载它。我们还将TensorFlow定义为后端,并将图像维度排序为通道最后。不同的Keras后端库(TensorFlow,Theano)以相反的方式设置这些,即通道首先分别对应于通道。通过确保设置是这样的,我们可以避免错误来为我们的神经网络提供错误的数据形状。

# mainif __name__ == '__main__': np.random.seed(0) if keras.backend == 'tensorflow': keras.backend.set_image_dim_ordering('tf') # Provide an alternative to provide MissingLinkAI credential parser = argparse.ArgumentParser() parser.add_argument('--srFactor', type=int) parser.add_argument('--epochs', type=int, default=EPOCHS) #parser.add_argument('--filepath', type=str) parser.add_argument('--subdir', type=str, default='067') parser.add_argument('--filters', type=int, default=FILTERS) parser.add_argument('--activation', default=ACTIVATION) parser.add_argument('--shuffle', default=SHUFFLE) parser.add_argument('--batch', type=int, default=BATCH_SIZE) parser.add_argument('--layers', type=int, default=LAYERS_NUM) parser.add_argument('--sortOrder', default=SORT_ORDER) parser.add_argument('--scalingSteps', type=int, default=NB_SCALING_STEPS) parser.add_argument('--groundTruth', default=GROUND_TRUTH) parser.add_argument('--baseline', default=BASELINE) parser.add_argument('--flip', default=FLIP_FLAG) parser.add_argument('--noiseFlag', default=False) parser.add_argument('--noiseSTD', type = int, default=30) parser.add_argument('--project') # Override credential values if provided as arguments args = parser.parse_args() #file_name = args.filepath or file_name subdir = args.subdir SR_FACTOR = args.srFactor or SR_FACTOR FILTERS = args.filters or FILTERS EPOCHS = args.epochs or EPOCHS ACTIVATION = args.activation or ACTIVATION SHUFFLE = args.shuffle or SHUFFLE BATCH_SIZE = args.batch or BATCH_SIZE LAYERS_NUM = args.layers or LAYERS_NUM SORT_ORDER = args.sortOrder or SORT_ORDER NB_SCALING_STEPS = args.scalingSteps or NB_SCALING_STEPS GROUND_TRUTH = args.groundTruth or GROUND_TRUTH BASELINE = args.baseline or BASELINE FLIP_FLAG = args.flip or FLIP_FLAG NOISE_FLAG = args.noiseFlag or NOISE_FLAG NOISY_PIXELS_STD = args.noiseSTD or NOISY_PIXELS_STD # We're making sure These parameters are equal, in case of an update from the parser. NB_PAIRS = EPOCHS EPOCHS_DROP = np.ceil((NB_STEPS * EPOCHS) / NB_SCALING_STEPS) psnr_score = None ssim_score = None metrics_ratio = None # Path for Data and Output directories on Docker # save to disk if os.environ.get('ML'): output_paths = '/output' else: output_paths = os.path.join(os.getcwd(), 'output') if not os.path.exists(output_paths): os.makedirs(output_paths) print (output_paths) # output_paths = select_first_dir('/output', './output') # if (output_paths == './output'): # mk_dir(dir_name='./output') file_name = select_file(ORIGIN_IMAGE, subdir) print(file_name) # Load image from data volumes image = load_img(file_name) cv2.imwrite(output_paths + '/' + 'image.png', cv2.cvtColor(image, cv2.COLOR_RGB2BGR), params=[CV_IMWRITE_PNG_COMPRESSION])
53a1d494667436cb0c63e68ef3f83b6e.png

构建模型

我们使用Keras函数模型API创建模型。这使我们能够创建比常见的Sequential模型更复杂的架构。

build_model()

build_model() 函数是我们定义和编译模型的地方。

def build_model(): # model filters = FILTERS # 64 kernel_size = 3 # Highly important to keep image size the same through layer strides = 1 # Highly important to keep image size the same through layer padding = "same" # Highly important to keep image size the same through layer inp = Input(shape=(None, None, NB_CHANNELS)) # seq_model = Sequential() z = (Conv2D( filters=NB_CHANNELS, kernel_size=kernel_size, activation="relu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值