FSRCNN:加速超分辨率卷积神经网络,SRCNN的加速版

paper:https://arxiv.org/pdf/1608.00367

code: https://github.com/yjn870/FSRCNN-pytorch/tree/master

目录

1. 动机

2. 方法

3. 代码对比

 4. 实验结果


1. 动机

        作者此前提出的SRCNN证明了CNN在图像超分领域的有效性。然而,SRCNN计算效率较低,不能达到实时性能。因此,该作者重新设计了SRCNN的网络,以提升推理速度。

改进点包括三个方面:

  • 1)在网络末端引入了一个反卷积层,用于将原始分辨率的feature map映射到高分辨率图像;
  • 2) 引入了沙漏型body网络,输入特征的通道维度先缩小再扩大,以降低计算量;
  • 3) 采用更小的卷积核,但层次更深了;

所提出的网络能够提速40倍,同时SR质量也更好。

2. 方法

        原始SRCNN有一个预处理步骤,即先将原图上采样,然后再送入网络,这无疑增加了计算量。在FSRCNN中,去掉了这个步骤,直接从原始分辨率开始,最终得到高分辨率结果。此外,如何缩小计算量也是FSRCNN重点考虑的问题,原始SRCNN虽然层数较少,但卷积核较大(9*9),因此FSRCNN探索了更小的卷积核,同时增加网络深度,整体的计算量能够降低不少。

        根据上述观察,我们研究了一种更简洁、更高效的网络结构,用于快速准确的图像SR。为了解决第一个问题,我们采用反卷积层来代替双三次插值。为了进一步减轻计算负担,我们在网络的末端放置了反卷积层1,那么计算复杂度仅与原始LR图像的空间大小成正比。值得注意的是,反褶积层不等于传统插值核的简单替代,如FCN[13],或像[14]这样的“unpooling+convolution”。相反,它由各种自动学习的上采样核(见图3)组成,它们共同工作生成最终的HR输出,并用均匀插值核替换这些反卷积滤波器将导致PSNR急剧下降(例如,对于×3,Set5数据集[15]上至少0.9 dB)。

        对于第二个问题,我们分别在映射层的开头和结尾添加一个收缩层和扩展层,以限制低维特征空间中的映射。此外,我们将单个宽映射层分解为几个具有固定滤波器大小为 3 × 3 的层。

        FSRCNN整体网络结构如下:

        FSRCNN可以分解为特征提取、收缩、映射、扩展和反卷积五个部分。前四个部分是卷积层,最后一个是反卷积层。为了更好地理解,我们将卷积层表示为 Conv(fi, ni, ci),将反卷积层表示为 DeConv(fi, ni, ci),其中变量 fi, ni, ci 分别表示滤波器大小、滤波器数量和通道数。

  • Feature extraction: 这部分类似于 SRCNN 的第一部分,但在输入图像上不同。FSRCNN 在原始 LR 图像上执行特征提取,无需插值;而且,卷积核大小从9变成了5。
  • Shrinking:使用1*1卷积将通道数降低;
  • Non-linear mapping:使用3*3卷积进行特征映射;
  • Expanding: 将通道维度再恢复回去;
  • Deconvolution:反卷积层,这一层用于对先前的特征进行上采样和聚合,得到高分辨率结果。

3. 代码对比

        首先看看SRCNN的代码:

from torch import nn
 
 
class SRCNN(nn.Module):
    def __init__(self, num_channels=1):
        super(SRCNN, self).__init__()
        self.conv1 = nn.Conv2d(num_channels, 64, kernel_size=9, padding=9 // 2)
        self.conv2 = nn.Conv2d(64, 32, kernel_size=5, padding=5 // 2)
        self.conv3 = nn.Conv2d(32, num_channels, kernel_size=5, padding=5 // 2)
        self.relu = nn.ReLU(inplace=True)
 
    def forward(self, x):
        x = self.relu(self.conv1(x))
        x = self.relu(self.conv2(x))
        x = self.conv3(x)
        return x

        再来看FSRCNN的代码:

import math
from torch import nn


class FSRCNN(nn.Module):
    def __init__(self, scale_factor, num_channels=1, d=56, s=12, m=4):
        super(FSRCNN, self).__init__()
        self.first_part = nn.Sequential(
            nn.Conv2d(num_channels, d, kernel_size=5, padding=5//2),
            nn.PReLU(d)
        )
        self.mid_part = [nn.Conv2d(d, s, kernel_size=1), nn.PReLU(s)]
        for _ in range(m):
            self.mid_part.extend([nn.Conv2d(s, s, kernel_size=3, padding=3//2), nn.PReLU(s)])
        self.mid_part.extend([nn.Conv2d(s, d, kernel_size=1), nn.PReLU(d)])
        self.mid_part = nn.Sequential(*self.mid_part)
        self.last_part = nn.ConvTranspose2d(d, num_channels, kernel_size=9, stride=scale_factor, padding=9//2,
                                            output_padding=scale_factor-1)

        self._initialize_weights()

    def _initialize_weights(self):
        for m in self.first_part:
            if isinstance(m, nn.Conv2d):
                nn.init.normal_(m.weight.data, mean=0.0, std=math.sqrt(2/(m.out_channels*m.weight.data[0][0].numel())))
                nn.init.zeros_(m.bias.data)
        for m in self.mid_part:
            if isinstance(m, nn.Conv2d):
                nn.init.normal_(m.weight.data, mean=0.0, std=math.sqrt(2/(m.out_channels*m.weight.data[0][0].numel())))
                nn.init.zeros_(m.bias.data)
        nn.init.normal_(self.last_part.weight.data, mean=0.0, std=0.001)
        nn.init.zeros_(self.last_part.bias.data)

    def forward(self, x):
        x = self.first_part(x)
        x = self.mid_part(x)
        x = self.last_part(x)
        return x

        可以看出,FSRCNN网络结构更复杂了,但通过去掉预处理过程中的上采样、缩小卷积核、收缩映射过程中的通道数,最终可以得到更深却更轻量的网络,从而达到速度更快、效果更好的结果。

        下表展示了从SRCNN到FSRCNN的变化过程:

 4. 实验结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux报错处理:‘abrt-cli status’ timed out

最近登录服务器时出现报错,后来查阅资料发现是因为ssh登录时间很久,登录后出现abrt-cli status timed out 的报错。 1.问题分析 abrt-cli是ABRT(Automated Bug Reporting Tool)的命令行接口,用于在Linux系统中处理和报告程序崩溃。 如果abr…

C语言实现扫雷游戏完整实现(上)

文章目录 前言一、新建好头文件和源文件二、实现游戏菜单选择功能三、定义游戏函数四、初始化棋盘五、 打印棋盘函数六、布置雷函数七、玩家排雷菜单八、标记功能的菜单九、标记功能菜单的实现总结 前言 C语言从新建文件到游戏菜单,游戏函数,初始化棋盘…

ElasticSearch笔记一

随着这个业务的发展,我们的数据量越来越庞大。那么传统的这种mysql的数据库就渐渐的难以满足我们复杂的业务需求了。 所以在微服务架构下一般都会用到一种分布式搜索的技术。那么今天呢我们就会带着大家去学习分布搜索当中最流行的一种ElasticSearch,Ela…

【折半处理 二分查找】1755. 最接近目标值的子序列和

本文涉及知识点 折半处理 二分查找算法合集 LeetCode1755. 最接近目标值的子序列和 给你一个整数数组 nums 和一个目标值 goal 。 你需要从 nums 中选出一个子序列,使子序列元素总和最接近 goal 。也就是说,如果子序列元素和为 sum ,你需要…

关于Java的三个小题目(很容易错!)

第一题 char运算后的数据类型 最后输出的是什么类型? 答案:int char与byte的联系和区别 char是无符号型的,能够表示一个整数,不能表示负数(0~65535);而byte是有符号型的,能够表示…

elasticsearch-8.1.0安装记录

目录 零、版本说明一、安装二、使用客户端访问 零、版本说明 centos [rootnode1 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)elasticsearch elasticsearch-8.1.0-linux-x86_64一、安装 systemctl stop firewalld.servicesystemctl disable firewal…

笔记本电脑耗电和发热比较厉害怎么处理

工作中会遇到有同事反馈笔记本电脑耗电和发热比较厉害,主要检查以下几个地方 1、CPU频率 很多人觉得是cpu使用率高就代表电脑跑得快,发热量就大,其实不是的,主要是看的cpu频率,频率越高,电脑发热量越大。如…

Laravel 6 - 第十一章 中间件

​ 文章目录 Laravel 6 - 第一章 简介 Laravel 6 - 第二章 项目搭建 Laravel 6 - 第三章 文件夹结构 Laravel 6 - 第四章 生命周期 Laravel 6 - 第五章 控制反转和依赖注入 Laravel 6 - 第六章 服务容器 Laravel 6 - 第七章 服务提供者 Laravel 6 - 第八章 门面 Laravel 6 - …

如何在 Flutter 中制作多种颜色的 TextField

TextField widget 本身并不施加任何样式。相反,它会要求 TextEditingController 生成一个样式化的 TextSpan 对象,即一段带有样式的文本。 TextField 将其样式传递给 TextEditingController ,默认实现只是将其放入 TextSpan 对象中&#xff0…

C#通过Qt使用VTK

需求: 一个项目,界面是C# 开发的,但是业务上有三维可视化的需求,VTK基于C#的绑定版本需要收费,并且资料很少。因此将VTK嵌入到Qt里,并封装成一个dll,通过接口提供给C#访问。 实现:…

HTTP慢连接攻击的原理和防范措施

随着互联网的快速发展,网络安全问题日益凸显,网络攻击事件频繁发生。其中,HTTP慢速攻击作为一种隐蔽且高效的攻击方式,近年来逐渐出现的越来越多。 为了防范这些网络攻击,我们需要先了解这些攻击情况,这样…

贪吃蛇(C语言版)

在我们学习完C语言 和单链表知识点后 我们开始写个贪吃蛇的代码 目标:使用C语言在Windows环境的控制台模拟实现经典小游戏贪吃蛇 贪吃蛇代码实现的基本功能: 地图的绘制 蛇、食物的创建 蛇的状态(正常 撞墙 撞到自己 正常退出&#xf…

vscode将本地服务转发到外网地址访问

示例中将本地的5500端口,用vscode进行端口转发,在外网地址访问服务 要转发的端口 转发端口 点击转发端口 输入要转发的端口,按下回车 Enter 点击允许,弹出确认界面后点击打开 转发端口已经成功配置上,右键可见性…

Git和Github绑定

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

爬虫中怎么判断一个网页是否包含ajax请求

1、前言 在用爬虫抓取数据的时候,如果一个网页包含ajax请求,由于数据时动态加载的,直接根据网址是不能获取到想要的数据。因此,在爬虫需要首先判断一个网页是否包含ajax请求数据。 2、ajax请求 2.1 什么是ajax请求 AJAX Asynch…

20240424codeforces刷题题解

240424刷题题解 Walk on Matrix CodeForces - 1332D 思路 构造题,每个 d p i , j dp_{i,j} dpi,j​​​都是由其左上方向中的按位与最大值决定的。 我们需要从使得贪心解与正确解的差值为 k k k。 为了方便获得 k k k,可以考虑构造一个贪心解为 0…

社交媒体数据恢复:Facebook

在使用Facebook的过程中,可能会出现数据丢失的情况,如误删了重要的帖子、照片或其他文件。在这种情况下,你可以尝试以下方法来恢复Facebook的数据。 首先,确保你备份了Facebook的数据。如果你定期备份数据,那么恢复起…

第26天:安全开发-PHP应用模版引用Smarty渲染MVC模型数据联动RCE安全

第二十六天 一、PHP新闻显示-数据库操作读取显示 1.新闻列表 数据库创建新闻存储代码连接数据库读取页面进行自定义显示 二、PHP模版引用-自写模版&Smarty渲染 1.自写模版引用 页面显示样式编排显示数据插入页面引用模版调用触发 2.Smarty模版引用 1.下载&#xff1a…

【C语言回顾】操作符详解

前言1. 操作符分类2. 二进制和进制转换2.1 二进制2.2 进制转换2.2.1 二进制转十进制2.2.2 二进制转八进制2.2.3 二进制转十六进制 3. 原码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符6. 单目操作符7. 逗号表达式8. 下标引用操作符9. 函数调用操作符10.…

Linux:进程与计划任务

文章目录 Linux:进程与计划任务一、进程1、进程是什么2、进程状态 二、列出进程命令1、查看静态的进程统计信息——“ps”Play1:“ps aux”Play2:ps -elf 2、查看静态的进程统计信息——“top”段首解析进程信息区解释 三、运行与终止进程3.1、运行进程3…