FSRCNN:加速超分辨率卷积神经网络

news/2025/3/25 18:27:15/文章来源:https://www.cnblogs.com/AshXir/p/18788250

FSRCNN:加速超分辨率卷积神经网络

Accelerating the Super-Resolution Convolutional Neural Network

加速超分辨率卷积神经网络

https://arxiv.org/abs/1608.00367

https://github.com/mrshao520/ReproductionCode/tree/main/FSRCNN/FSRCNN_torch

ECCV 2016

Abstract

  • 问题:高计算成本阻碍了SRCNN在需要实时性能(24fps)的实际应用中的应用
  • 方法:提出一种紧凑的沙漏形 CNN 结构,以实现更快、更好的 SR
    • 在网络的末端引入一个反卷积层,然后直接从原始的低分辨率图像学习到高分辨率图像的映射
    • 在映射之前缩小输入特征维度并在映射之后扩展来重新构建映射层
    • 采用更小的滤波器大小,但更多的映射层
  • 结果:所提出的模型实现了 40 倍以上的加速,甚至具有卓越的修复质量
  • 主要贡献
    • 我们制定了一个紧凑的沙漏形 CNN 结构,用于快速图像超分辨率。通过一组转置卷积过滤器的协作,网络可以学习原始 LR 和 HR 图像之间的端到端映射,而无需进行预处理。
    • 所提出的模型实现了比SRCNN快至少40倍的速度,同时保持卓越的性能。
    • 我们转移所提出网络的卷积层,以便跨不同的放大因子进行快速训练和测试,而不会损失恢复质量。

输入图像:\(n \times n\)

输出图像:\(o \times o\)

过滤器 :\(f \times f\)

padding :\(p \times p\)

step :\(s\)

卷积

\[o = \frac{n+2p-f}{s} + 1 \]

转置卷积:

\[o=s \times (n-1)-2p+f \]

1. 简介

限制运行速度的两种因素:

  1. 作为预处理步骤,需要使用双三次插值将原始 LR 图像上采样到所需的大小以形成输入。因此,SRCNN 的计算复杂度随着 HR 图像(而不是原始 LR 图像)的空间大小呈二次方增长。对于放大因子 \(n\) ,与插值 LR 图像进行卷积的计算成本将是原始 LR 图像的\(n^{2}\)倍。
  2. 第二个限制在于非线性映射步骤。在 SRCNN 中,输入图像块被投影到高维 LR 特征空间上,然后进行复杂的映射到另一个高维 HR 特征空间。
    • 通过采用更宽的映射层可以显着提高映射精度,但代价是运行时间。

解决方法:

  1. 对于第一个问题,在网络末端放置转置卷积层,则计算复杂度仅与原始LR图像的空间大小成正比。
  2. 对于第二个问题,我们在映射的开头和结尾分别添加收缩层和扩展层,以限制低维特征空间中的映射。此外,我们将单个宽映射层分解为具有具有固定过滤器大小 3 x 3 的多个层。新结构的整体形状像个沙漏,整体对称,两端厚,中间薄。

FSRCNN 还有另一个吸引人的特性,可以促进跨不同升级因素的快速训练和测试。具体来说,在FSRCNN中,所有卷积层(除转置卷积层之外)都可以由不同放大因子的网络共享。在训练过程中,使用训练有素的网络,我们只需针对另一个放大因子微调转置卷积层,几乎不会损失映射精度。在测试过程中,我们只需要进行一次卷积操作,并使用相应的转置卷积层将图像上采样到不同的尺度。

2. 相关工作

高级视觉问题(high-level problems):图像分类、目标检测

低级视觉问题(lower-level problems):SR

SR的深度模型不包含全连接层,卷积过滤器将严重影响性能。

3. Fast Super-Resolution by CNN(FSRCNN)

3.1 SRCNN

该图显示了SRCNN和FSRCNN的网络结构。所提出的 FSRCNN 与 SRCNN 主要在三个方面有所不同。首先,FSRCNN采用原始低分辨率图像作为输入,不进行双三次插值。在网络末端引入转置卷积层来执行上采样。其次,SRCNN 中的非线性映射步骤被 FSRCNN 中的三个步骤取代,即收缩、映射和扩展步骤。第三,FSRCNN采用更小的滤波器尺寸和更深的网络结构。这些改进为 FSRCNN 提供了比 SRCNN 更好的性能但计算成本更低。

3.2 FSRCNN

FSRCNN可以分解为五个部分—特征提取(feature extractions)、收缩(shrinking)、映射(mapping)、扩展(expending)和转置卷积(dconvolution)

  • 特征提取(feature extractions):通过与第一组过滤器进行卷积,输入的每个块(1像素重叠)被表示为高维特征向量。

    • \(nn.Conv2d(in\_channels=1, out\_channels=d, kernel\_size=5)\)
    • d:LR特征维度的数量
  • 收缩(shrinking):在特征提取层之后添加收缩层来降低LR特征维度 d,将过滤器的大小固定为 \(f_{2} = 1\)。收缩操作是为了提高计算效率而减少LR特征维数。

    • 通过采用较小的过滤器数量 \(n_{2}=s<<d\),LR特征维度从\(d\)减小到\(s\)
    • \(nn.Conv2d(in\_channels=d,out\_channels=s,kernel\_size=1)\)
    • s:收缩程度
  • 非线性映射(non-linear mapping):影响SR性能的最大因素是宽度(即第一层中的过滤器数量)和深度(即层数)的映射层。

    • \(m \times Conv2d(in\_channels=s,out\_channels=s,kernel\_size=3)\)
    • m:映射层数,决定了映射的精度和复杂性
    • 为了保持一致,所有映射层都包含相同数量的过滤去\(n_{3} = s\)
  • 扩展(expending):扩展层的作用类似于收缩层的逆过程。收缩操作是为了提高计算效率而减少LR特征维数。然而,如果我们直接从这些低维特征生成HR图像,最终的恢复质量会很差。因此,我们在映射部分之后添加一个扩展层来扩展HR特征维度。

    • \(Conv2d(in\_channels=s,out\_channels=d,kernel\_size=1)\)
  • 转置卷积(deconvolution):最后一部分是转置卷积层,它使用一组转置卷积过滤器对先前的特征进行上采样和聚合。转置卷积可以看作是卷积的逆操作。对于卷积,过滤器以步长\(k\)与图像进行卷积,输出是输入的\(\frac{1}{k}\)倍。相反,如果我们交换输入和输出的位置,输出将是输入的\(k\)倍。

    • \(nn.ConvTranspose2d(in\_channels=d,out\_channels=1,kernel\_size=9)\)
  • PReLU:对于每个卷积层之后的激活函数,我们建议使用参数整流线性单元(PReLU)而不是常用的整流线性单元(ReLU)。它们的负数部分的系数不同。对于ReLU和PReLU,我们可以将通用激活函数定义为\(f(x_{i})=max(x_{i},0)+a_{i}min(0,x_{i})\),其中 \(x_{i}\)\(i\) 为负数部分的系数。对于ReLU,参数 \(a_{i}\) 固定为0,但对于PReLU来说是可学习的。我们选择PReLU主要是为了避免ReLU中零梯度造成的死特征。实验表明,PReLU激活网络的性能更加稳定,可以看作是ReLU激活网络的上届。

  • 整体结构(Overall structure)

    • \(nn.Conv2d(in\_channels=1, out\_channels=d, kernel\_size=5)\)

    • PReLU

    • \(nn.Conv2d(in\_channels=d,out\_channels=s,kernel\_size=1)\)

    • PReLU

    • \(m \times Conv2d(in\_channels=s,out\_channels=s,kernel\_size=3)\)

    • PReLU

    • \(Conv2d(in\_channels=s,out\_channels=d,kernel\_size=1)\)

    • PReLU

    • \(nn.ConvTranspose2d(in\_channels=d,out\_channels=1,kernel\_size=9)\)

    • LR特征维度d、收缩过滤器的数量s和映射深度m控制性能和速度

    • 将FSRCNN网络表示为 FSRCNN(d, s, m)

计算复杂度可以计算为:

\[O\{(25d+sd+9ms^2+ds+81d)S_{LR}\} = O\{(9ms^2+2sd+106d)S_{LR}\} \]

  • 成本函数(Cost function):采用均方误差(MSE)作为成本函数

    \[\mathop{min}\limits_{\theta} \frac{1}{n} \sum_{i=1}^{n}{||F(Y^{i}_{s}; \theta) - X^{i}||^{2}_{2}} \]

    • \(Y^{i}_{s}\)\(X^{i}\) 是训练数据中的第 \(i\) 个LR和HR子图像对
    • \(F(Y^{i}_{S}; \theta)\) 是网络带有参数 \(\theta\)\(Y^{i}_{s}\) 的输出。
    • 所有参数均使用随机梯度下降和标准反向传播进行优化。

3.2.1 PReLU

torch.nn.PReLU(num_parameters=1, init=0.25, device=None, dtype=None)
  • 参数

    • num_parameters(int):要学习的 \(a\) 数量,只有两个合法值:输入的通道数 或 1。默认值为 1。
    • init(float):\(a\) 的初始值。默认值: 0,25
  • 变量

    • weight(Tensor):权重

\[PReLU(x) = \begin{cases}x & if\ x >= 0 \\ax & otherwise \end{cases} \]

  • 这里的\(a\)是一个可学习参数。当不带参数调用时,nn.PReLU() 在所有输入通道中使用单个参数 \(a\)。如果使用 nn.PReLU(nChannels)调用,则每个输入通道将使用单独的 \(a\)

![](src='https://img2024.cnblogs.com/blog/3623527/202503/3623527-20250323200534272-788712571.png' style="zoom:50%;")

Example:

m = nn.PReLU()
input = torch.randn(2)
output = m(input)

3.2.2 代码

import torch
import torch.nn as nn
import torch.nn.functional as Fclass FSRCNN(nn.Module):def __init__(self, upscale_factor, feature_dimension, shrinking, mapping_layers) -> None:"""feature_dimension: LR特征维度的数量shrinking: 收缩程度mapping_layers: 映射层数"""super().__init__()# feature_extractionsself.model_seq = nn.Sequential(nn.Conv2d(in_channels=1, out_channels=feature_dimension,kernel_size=5, padding=2),nn.PReLU(feature_dimension))# shrinkingself.model_seq.extend([nn.Conv2d(in_channels=feature_dimension,out_channels=shrinking, kernel_size=1),nn.PReLU(shrinking)])# non-linear mappingfor i in range(mapping_layers):self.model_seq.extend([nn.Conv2d(in_channels=shrinking, out_channels=shrinking,kernel_size=3, padding=1),nn.PReLU(shrinking)])# expendingself.model_seq.extend([nn.Conv2d(in_channels=shrinking, out_channels=feature_dimension, kernel_size=1),nn.PReLU(feature_dimension)])# deconvolutionself.last_seq = nn.Sequential(nn.ConvTranspose2d(in_channels=feature_dimension, out_channels=1, kernel_size=9, stride=upscale_factor, padding=4,output_padding=upscale_factor-1))def forward(self, x):x = self.model_seq(x)x = self.last_seq(x)return xif __name__ == '__main__':model = FSRCNN(3, 56, 12, 4)print(f'model ---------\n{model}')x = torch.randn((1, 1, 7, 7))x = model(x)print(f'x shape : {x.shape}')print(f'x : {x}')

3.3 与SRCNN的区别:从SRCNN到FSRCNN

  • upscale_factor = 3
  • 91个图像数据集上训练的性能
  • Set5 上的平均 PSNR

首先,我们用转置卷积层替换SRCNN-Ex的最后一个卷积层,然后整个网络将在原始LR图像上执行,计算复杂度与\(S_{LR}\)成正比。由于学习到的转置卷积核比单个双三次核更好,因此性能大约提高了 0.12 dB。其次,将单个映射层替换为收缩层、4个映射层和扩展层的组合。总体来说,多了5层,但参数从58,976减少到17,088。另外,这一步之后的加速度是最突出的 30.1 X 。人们普遍认为,深度是影响性能的关键因素。在这里,我们使用四个“窄”层来代替单个“宽”层,从而以更少的参数获得更好的结果(33.01 dB)。最后,我们采用更小的过滤器尺寸和更少的过滤器(例如,从 \(Conv(9,64,1)\)\(Conv(5,56,1)\) ),并获得 41.3X 的最终速度。当我们删除一些冗余参数时,网络的训练效率更高,并实现了另外 0.05 dB 的改进。

FSRCNN由卷积层和转置卷积层组成。可以针对不同的放大因子共享卷积层。针对不同的放大因子训练特定的转置卷积层。

3.4 不同的放大因子的SR

FSRCNN 的另一个优点是 FSRCNN 可以实现跨不同放大因素的快速训练和测试。具体来说,我们发现所有卷积层总体上都充当LR图像的复杂特征提取器,并且只有最后一个转置卷积层包含放大因子的信息。这也被实验证明了,其中对于不同的放大因子,卷积过滤器几乎是相同的 。利用这个特性,我们可以转移卷积过滤器以进行快速训练和测试。

在实践中,我们提前训练一个放大因子的模型。然后在训练过程中,我们仅针对另一个放大因子微调转置卷积层,并保持卷积层不变。微调速度很快,并且性能与从头开始训练一样好。在测试过程中,我们执行一次卷积运算,并使用相应的转置卷积层将图像上采样到不同的尺寸。

4. 实验

4.1 实施细节

数据集:

  • JPEG格式对于SR任务来说并不是最佳的
  • General-100数据集,其中包含100个bmp格式图像(无压缩)
    • 大小范围从710x704(大)到131x112(小)
    • 它们的质量都很好,边缘清晰,但平滑区域较少(例如天空和海洋),因此非常适合SR训练

为了充分利用数据集,采用数据增强:

  1. 缩放:每个图像按因子0.9、0.8、0.7和0.6缩小
  2. 旋转:每张图像旋转90°、180°和270°

测试和验证数据集:

使用Set5、Set14和BSD200数据集进行测试。从 BSD500 数据集的验证集中选择另外 20 个图像进行验证。

训练样本:

首先按需要的缩放因子 n 对原始训练图像进行下采样,以形成LR图像。然后,我们将LR训练图像裁剪为一组 \(f_{sub} \times f_{sub}\) 像素子图像,步幅为 \(k\) 。相应的HR子图像(大小为 \((n \times f_{sub})^2\) )也从真实有效的图像中裁剪出来。这些 LR/HR 子图像对是主要训练数据。

对于填充问题,我们凭经验发现填充输入或输出映射对最终性能影响不大。因此,我们根据过滤器的大小在所有层中采用零填充。这样,就不需要针对不同的网络设计改变子图像的大小。

影响子图像大小的另一个问题是反卷积层。当我们使用 Caffe 包 训练模型时,其转置卷积滤波器将生成大小为 \((nf_{sub}-n+1)^2\)而不是\((nf_{sub})^2\)的输出。因此,我们还裁剪 HR 子图像上的 \((n-1)\) 像素边框。最后,对于 x2, x3, x4,我们将LR/HR子图像对的大小设置为 \(10^2/19^2\)\(7^2/19^2\)\(6^2/21^2\)

训练策略:

当使用91张图像数据集进行训练时,卷积层的学习率为 \(10^{-3}\) ,转置卷积层的学习率为 \(10^{-4}\) 。然后在微调时,所有层的学习率都降低一半。

4.2 不同设置的调查

为了测试FSRCNN结构的性能,我们设计了一组具有不同值的三个敏感变量的控制实验——LR特征维度 d 、收缩滤波器的数量 s 、和映射深度 m 。具体来说,我们选择 d = 48 , 56 、 s = 12 , 16 和 m = 2 , 3 , 4 ,因此我们用不同的组合进行了总共 2 × 2 × 3 = 12 次实验。

这些实验在Set5数据集上的平均PSNR值如表所示。我们从表中的水平和垂直两个方向分析结果。首先,我们修复d , s 并检查 m 的影响。显然, m = 4 比 m = 2 和 m = 3 产生更好的结果。其次,我们修复 m 并检查 d 和 s 的影响。一般来说,更好的结果通常需要更多的参数(例如,更大的 d 或 s ),但更多的参数并不总是保证更好的结果。从所有结果中,我们找到了性能和参数之间的最佳权衡——FSRCNN (56,12,4),它以适度数量的参数实现了最高结果之一。

4.3 利用FSRCNN实现实时SR

4.4 不同放大因子的实现

与需要从头开始针对不同缩放因子训练网络的现有方法不同,所提出的 FSRCNN 通过传输卷积滤波器具有跨缩放因子学习和测试的灵活性。我们在本节中展示了这种灵活性。我们选择 FSRCNN (56,12,4) 作为默认网络。由于我们在放大因子 3 下获得了训练有素的模型,因此我们在 × 3 的基础上训练 × 2 的网络。具体来说,训练好的模型中所有卷积过滤器的参数都转移到 × 的网络中。 2.在训练过程中,我们只在91图像和General-100图像上微调转置卷积层 × 2 的数据集。为了进行比较,我们也为 × 2 训练另一个网络,但从头开始。这两个网络的收敛曲线如图所示。显然,通过传递参数,网络收敛得非常快(仅几个小时),并且具有与从头开始训练相同的良好性能。

4.5 与现有技术的比较

5. 结论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904349.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GNSS测量实习

实 习 报 告学院:建筑工程与空间信息学院 专业:地理信息科学 实习性质:校内实习 实习单位:建筑工程与空间信息学院 指导教师:冯建迪目录 一、实习的性质和目的要求 二、实习的任务和内容 三、静态测量 3.1 静态测量简介 3.2作业流程 3.3注意事项 3.4 GPS 控制网设计…

花束搭配

提取公式:Ai+Aj>Bi+Bj 变形得:Ai-Bi+Aj-Bj>0#include<bits/stdc++.h> using namespace std; #define int long long const int N = 1e6 + 10; int n, m, k, cnt, ans; string s;void solve() {cin >> n;vector<int> a(n), b(n), c(n);for (int i = 0…

题解:P11955 「ZHQOI R1」覆盖

https://www.luogu.com.cn/article/20vbz4zk对于一颗线段树,它的结构如图所示。一定是先有红色,再有绿色,再有蓝色,再有紫色。如果靠前的颜色没有那么靠后的颜色不可能出现。我们先考虑上一层(黑色)都已经处理完,新的一层会有什么影响,即已知 \(f_{2^j}\) 求 \(f_{2^j+…

sir.net,一个类似itdog/pingpe/chinaz的网络质量检测/监视工具

相信不少站长或主机爱好者都使用过itdog/pingpe/chinaz网络质量和ip质量检测这类工具,这其中最重要最常用的就是ping值检测工具了,如果你熟悉或接确过这方面的应用,那么现在,不防尝鲜下 sir.net(中文名:站长先生) ,它将不失作为你一个更有趣更稳定的选择。 1)类似google.…

原来不是喜欢原子化css,只不过是喜欢tailwind

前言 写css的时候,经常有某个控件只需要些许css样式,但是写行内样式又有优先级问题,从而需要为其单独定义一个class,然而某个控件只是用来布局,没有特定含义,连名称都不好命名。 因此,原子化css应运而生,早期的bootstrap,以及一些组件库中都有使用。 那时叫做工具类,…

c语言分支与循环基础

实验任务一 问题1:生成一个1到100的随机整数 问题2:使输出的整数宽度为4位,不足时在前面补0 问题3:循环生成五个1到100的随机整数,与固定前缀组合后输出类似学员编号的内容实验任务2 问题一:在一次购买流程结束后,清除本次购买的总价,下次运行能重新计算。去掉的话,总…

梯度方差的概念

梯度方差的概念 内容 在深度学习中,梯度方差(Gradient Variance) 是一个关键概念,它直接影响模型的训练稳定性和收敛速度。以下用通俗的语言和实际例子解释它的含义、作用及影响。1. 什么是梯度方差?定义: 梯度方差表示 不同批次数据计算出的梯度之间的波动程度。 如果每…

解决方案 | 如何安全可靠地更改win10的C盘用户名

有的朋友可能最开始由于不知道使用中文名在编程中的各种bug,从而将自己的系统用户名设置成了中文名或者各种奇怪符号的名字,导致在英文编程的时候或者使用英文软件的时候可能出错。为了解决这个问题,网上的文章写得又臭又长,生怕别人看懂学到了技术。本文目的:实现原用户名…