srcnn fsrcnn espcn rdn超分网络的结构

article/2025/11/10 16:51:44

1.Srcnn

Code:

数据集制作方法:以x2为例
训练数据:一张原始图作为高分辨率图像(h, w),先下采样到(h/2, w/2),然后再cubic上采样到(h, w)得到低分辨率图像, 该网络只处理Y通道图像, 训练的时候patch_size 默认设为33。
事实上两者的分辨率是一样的,也就是网络的输入和输出尺寸是相同的,但是清晰度不同
在这里插入图片描述

评估和预测的时候网络输入是 整幅图像
在这里插入图片描述

网络模型:
参考论文和srcnn网络结构可视化

2.FSrcnn

相关code1

相关code2

1).是对srcnn的加速

主要看下图即可:
1)去掉bicubic interpolation,直接进入特征提取层,但是在网络最后加入反卷积层
2)特征映射层(mapping layer)替换为shrinking-mapping-expanding,达到加速目的
3)Fsrcnn更深的网络,更低的计算量
4)Fsrcnn除了反卷积层,其他层对于2x,3x,4x的训练参数是可以共享的,因此可以加速训练和测试
在这里插入图片描述

2).Srcnn和fsrcnn的一些对比

首先速度
在这里插入图片描述

其次结果
在这里插入图片描述

3).关于反卷积层

最后一层是反卷积层,进行图像尺寸的放大,因此前面层的训练参数可以共享,不同的分辨率放大倍数,只需要对 反卷积层微调即可,不同放大倍数反卷积层的stride有差异。
在这里插入图片描述

3).Espcn:Real-Time Single Image and Video Super-Resolution Using an Efficient

Sub-Pixel Convolutional Neural Network
1.Sub-pixel convolution layer
子像素卷积层 作为 扩大 图像尺寸的层, fsrcnn是用的反卷积层 扩大图像尺寸

就是 以放大二倍来说,倒数第二层 会有 4个通道, 然后4个通道重新排布扩大为4个像素。也就将倒数第二层的 size扩大了2倍在这里插入图片描述

2.网络架构
三个conv2d + 一个pixel shuffle
在这里插入图片描述
在这里插入图片描述

RDN:Residual Dense Network for Image Super-Resolution
1.网络架构
EDSR 利用了residual block
SRDenseNet 利用了 dense skip block
RDN将两者结合在一起,进一步提升特征提取和融合的能力,主要结构如下:
在这里插入图片描述

其中 residual dense block结构如下
在这里插入图片描述
RDN model

import argparseimport torch
from torch import nnclass DenseLayer(nn.Module):def __init__(self, in_channels, out_channels):super(DenseLayer, self).__init__()self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=3 // 2)self.relu = nn.ReLU(inplace=True)def forward(self, x):return torch.cat([x, self.relu(self.conv(x))], 1)class RDB(nn.Module):def __init__(self, in_channels, growth_rate, num_layers):super(RDB, self).__init__()self.layers = nn.Sequential(*[DenseLayer(in_channels + growth_rate * i, growth_rate) for i in range(num_layers)])# local feature fusionself.lff = nn.Conv2d(in_channels + growth_rate * num_layers, growth_rate, kernel_size=1)def forward(self, x):return x + self.lff(self.layers(x))  # local residual learningclass RDN(nn.Module):def __init__(self, scale_factor, num_channels, num_features, growth_rate, num_blocks, num_layers):super(RDN, self).__init__()self.G0 = num_featuresself.G = growth_rateself.D = num_blocksself.C = num_layers# shallow feature extractionself.sfe1 = nn.Conv2d(num_channels, num_features, kernel_size=3, padding=3 // 2)self.sfe2 = nn.Conv2d(num_features, num_features, kernel_size=3, padding=3 // 2)# residual dense blocksself.rdbs = nn.ModuleList([RDB(self.G0, self.G, self.C)])for _ in range(self.D - 1):self.rdbs.append(RDB(self.G, self.G, self.C))# global feature fusionself.gff = nn.Sequential(nn.Conv2d(self.G * self.D, self.G0, kernel_size=1),nn.Conv2d(self.G0, self.G0, kernel_size=3, padding=3 // 2))# up-samplingassert 2 <= scale_factor <= 4if scale_factor == 2 or scale_factor == 4:self.upscale = []for _ in range(scale_factor // 2):self.upscale.extend([nn.Conv2d(self.G0, self.G0 * (2 ** 2), kernel_size=3, padding=3 // 2),nn.PixelShuffle(2)])self.upscale = nn.Sequential(*self.upscale)else:self.upscale = nn.Sequential(nn.Conv2d(self.G0, self.G0 * (scale_factor ** 2), kernel_size=3, padding=3 // 2),nn.PixelShuffle(scale_factor))self.output = nn.Conv2d(self.G0, num_channels, kernel_size=3, padding=3 // 2)def forward(self, x):sfe1 = self.sfe1(x)sfe2 = self.sfe2(sfe1)x = sfe2local_features = []for i in range(self.D):x = self.rdbs[i](x)local_features.append(x)x = self.gff(torch.cat(local_features, 1)) + sfe1  # global residual learningx = self.upscale(x)x = self.output(x)return xfrom torchviz import make_dot
import tensorwatch as tw
from torchinfo import summary
import netron
if __name__ == "__main__":parser = argparse.ArgumentParser()parser.add_argument('--num-features', type=int, default=64)parser.add_argument('--growth-rate', type=int, default=64)parser.add_argument('--num-blocks', type=int, default=16)parser.add_argument('--num-layers', type=int, default=8)parser.add_argument('--scale', type=int, default=4)parser.add_argument('--patch-size', type=int, default=32)parser.add_argument('--lr', type=float, default=1e-4)parser.add_argument('--batch-size', type=int, default=16)parser.add_argument('--num-epochs', type=int, default=800)parser.add_argument('--num-workers', type=int, default=8)parser.add_argument('--seed', type=int, default=123)args = parser.parse_args()device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# device = 'cpu'modelviz = RDN(scale_factor=args.scale,num_channels=3,num_features=args.num_features,growth_rate=args.growth_rate,num_blocks=args.num_blocks,num_layers=args.num_layers).to(device)# 打印模型结构h, w, c = 20, 20, 3print(modelviz)summary(modelviz, input_size=(8, c, h, w), col_names=["kernel_size", "output_size", "num_params", "mult_adds"])for p in modelviz.parameters():if p.requires_grad:print(p.shape)# 创建输入, 看看输出结果input = torch.rand(8, c, h, w).to(device)out = modelviz(input)print(out.shape)# 1. 使用 torchviz 可视化g = make_dot(out)g.view()  # 直接在当前路径下保存 pdf 并打开# g.render(filename='netStructure/myNetModel', view=False, format='pdf')  # 保存 pdf 到指定路径不打开# 2. 保存成pt文件后进行可视化torch.save(modelviz, "modelviz.pt")modelData = 'modelviz.pt'netron.start(modelData)# 3. 使用tensorwatch可视化print(tw.model_stats(modelviz, (8, c, h, w)))# tw.draw_model(modelviz, input)```

http://chatgpt.dhexx.cn/article/70bxgFH1.shtml

相关文章

RDD

RDD <1> 概述一. 什么是RDD二. spark 编程模型1. DataSource2. SparkContext3. Diver&#xff08;1&#xff09;SparkConf&#xff08;2&#xff09;SparkEnv&#xff08;3&#xff09;DAGScheduler&#xff08;4&#xff09;TaskScheduler&#xff08;5&#xff09;Sche…

RDNet

RDNet&#xff1a;Density Map Regression Guided Detection Network for RGB-D Crowd Counting and Localization IntroductionMethodExperiments Introduction Motivation&#xff1a;Regression-based方法有局限性&#xff0c;希望还是使用detection-based可以估计出每个人…

【超分辨率】(RDN)Residual Dense Network for Image Super-Resolution论文翻译

机翻&#xff0c;我尽量调整了公式和图片的排版 发现机翻根本看不了&#xff0c;自己人工翻译了下&#xff0c;其中摘要、网络部分&#xff08;第三节&#xff09;为人工翻译。 自己翻译过程中难免会出错&#xff0c;希望各位海涵&#xff0c;同时也欢迎各位提出翻译过程中的错…

LIIF超分辨率之RDN(残差密集网络)

1. 背景 用PaddlePaddle复现论文LIIF&#xff0c;LIIF中使用的Encoder是RDN&#xff0c;本文介绍一下RDN。 RDN论文&#xff1a;https://arxiv.org/abs/1802.08797 Torch代码&#xff1a; https://github.com/yinboc/liif/blob/main/models/rdn.py 2. RDN的组成 RDN网络结…

图像超分辨之RDN(Residual Dense Network)

论文&#xff1a; Residual Dense Network for Image Super-Resolution Github&#xff1a; https://github.com/yulunzhang/RDN https://github.com/hengchuan/RDN-TensorFlow 整体结构&#xff1a; RDN&#xff08;Residual Dense Network&#xff09;主要包含4个模块。…

超分辨率-RDN

一、简介 RDN——Residual Dense Network—— 残差深度网络 RDN是基于深度学习的超分方法之一&#xff0c;发表于CVPR 2018 二、结构 RDN网络结构分为4个部分&#xff1a; 1、SFENet(Shallow Feature Extraction Net, 浅层特征提取网络) 2、RDBs( Residual Dense Blocks, 残…

【图像超分辨】RDN

RDN 网络结构实现细节讨论&#xff08;与其他网络的区别&#xff09;实验设置实验结果参考博客 RDN——Residual Dense Network—— 残差深度网络。RDN是基于深度学习的超分方法之一&#xff0c;发表于CVPR 2018。 网络结构 RDN网络结构分为4个部分&#xff1a; SFENet(Shall…

【图像复原】RDN论文详解(Residual Dense Network for Image Restoration)

这是CVPR2018的一篇文章&#xff0c;提出了针对图像复原任务的CNN模型RDN(residual dense network)。 RDN主要是提出了网络结构RDB(residual dense blocks)&#xff0c;它本质上就是残差网络结构与密集网络结构的结合。 1.残差网络&#xff08;resnet&#xff09;与密集网络&am…

超分之RDN

这篇文章提出了一种结合ResNet结构和DenseNet结构的深度超分网络——Residual Dense Network(后文简称RDN)。RDN基于Residual Dense Block(后文简称RDB)块以及全局残差连接来提取全局特征&#xff0c;而RDB块基于Dense结构和局部残差连接进一步提取局部特征。通过这种结构&…

Java线程中的用户态和内核态

内核态用户态是什么? 操作系统对程序的执行权限进行分级,分别为用户态和内核态。用户态相比内核态有较低的执行权限&#xff0c;很多操作是不被操作系统允许的&#xff0c;简单来说就是用户态只能访问内存,防止程序错误影响到其他程序&#xff0c;而内核态则是可以操作系统的…

「操作系统」什么是用户态和内核态?为什么要区分

「操作系统」什么是用户态和内核态&#xff1f;为什么要区分 参考&鸣谢 从根上理解用户态与内核态 程序员阿星 并发编程&#xff08;二十六&#xff09;内核态和用户态 Lovely小猫 操作系统之内核态与用户态 fimm 文章目录 「操作系统」什么是用户态和内核态&#xff1f;为…

用户态与内核态之间切换详解

用户空间和内核空间 用户程序有用户态和内核态两种状态。用户态就是执行在用户空间中&#xff0c;不能直接执行系统调用。必须先切换到内核态&#xff0c;也就是系统调用的相关数据信息必须存储在内核空间中&#xff0c;然后执行系统调用。 操作硬盘等资源属于敏感操作&#…

用户态和内核态 中断处理机制

操作系统 一、操作系统基础知识 1.1 用户态和内核态 1.1.1 定义&#xff1a;什么是用户态和内核态&#xff1f; Kernel 运行在超级权限模式&#xff08;Supervisor Mode&#xff09;下&#xff0c;所以拥有很高的权限。按照权限管理的原则&#xff0c;多数应用程序应该运行…

用户态和内核态:用户态线程和内核态线程有什么区别?

转载 文章来源于 拉钩教育 重学操作系统 林䭽 用户态和内核态&#xff1a;用户态线程和内核态线程有什么区别&#xff1f; 什么是用户态和内核态 Kernel 运行在超级权限模式&#xff08;Supervisor Mode&#xff09;下&#xff0c;所以拥有很高的权限。按照权限管理的原则&a…

什么是用户态和内核态

什么是用户态和内核态 从图上我们可以看出来通过系统调用将Linux整个体系分为用户态和内核态&#xff08;或者说内核空间和用户空间&#xff09;。 那内核态到底是什么呢&#xff1f;其实从本质上说就是我们所说的内核&#xff0c;它是一种特殊的软件程序&#xff0c;特殊在哪儿…

用户态和内核态之间的切换

用户态和内核态之间的切换 切换方式 从用户态到内核态切换可以通过三种方式&#xff0c;或者说会导致从用户态切换到内核态的操作&#xff1a; 系统调用&#xff0c;这个上面已经讲解过了&#xff0c;在我公众号之前的文章也有讲解过。其实系统调用本身就是中断&#xff0c;…

OS用户态和内核态

1、linux进程有4GB地址空间&#xff0c;如图所示&#xff1a; 3G-4G大部分是共享的&#xff0c;是内核态的地址空间。这里存放整个内核的代码和所有的内核模块以及内核所维护的数据。 2、特权级的概念&#xff1a; 对于任何操作系统来说&#xff0c;创建一个进程是核心功能。…

用户态和内核态区别

操作系统用户态和内核态之间的切换过程 1. 用户态和内核态的概念区别 究竟什么是用户态&#xff0c;什么是内核态&#xff0c;这两个基本概念以前一直理解得不是很清楚&#xff0c;根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能…

操作系统用户态和内核态之间的切换过程

操作系统用户态和内核态之间的切换过程 1. 用户态和内核态的概念区别 究竟什么是用户态&#xff0c;什么是内核态&#xff0c;这两个基本概念以前一直理解得不是很清楚&#xff0c;根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和…

用户态和内核态的内存管理

内核态&#xff1a;cpu可以访问内存的所有数据&#xff0c;包括外围设备&#xff0c;例如硬盘&#xff0c;网卡&#xff0c;cpu也可以将自己从一个程序切换到另一个程序。 用户态&#xff1a;只能受限的访问内存&#xff0c;且不允许访问外围设备&#xff0c;占用cpu的能力被剥…