超分辨率第二章-FSRCNN
FSRCNN是2016年提出的超分辨率模型,使用后端上采样(转置卷积的方法),在一定程度上解决了SRCNN的问题。
模型位置:F:\Github下载\FSRCNN-pytorch-master
一.模型介绍
FSRCNN改进了SRCNN在速度上存在的缺陷
SRCNN在将低分辨率图像送进网络之前,会先使用双三次插值法进行插值上采样操作,产生与groundtruth大小一致的低分辨率图像,这样会增加了计算复杂度,因为插值后的图像相比原始的低分辨率图像更大,于是在输入网络后各个卷积层的计算代价会增大,从而限制了网络的整体速度。
SRCNN非线性映射层的计算代价太高,参数过多(高维度下的映射)。
FSRCNN在SRCNN基础上做了如下改变:
FSRCNN直接采用低分辨的图像作为输入,不同于SRCNN需要先对低分辨率的图像进行双三次插值然后作为输入,FSRCNN在网络的最后采用反卷积层实现上采样,小尺寸的图像在映射学习阶段可以有效地提升运算速度
FSRCNN中没有非线性映射,相应地出现了收缩层、映射(多个卷积核为3*3的层)和扩展层,在低维空间中进行映射学习可以有效地提升运算速度
FSRCNN选择更小尺寸的滤波器和更深的网络结构。
所有卷积层(反卷积层除外)都可以由不同放大因子的网络共享,能够在保持恢复质量(即图像超分辨率重建后的质量)不降低的前提下,通过迁移(或共享)其卷积层来快速地对不同放大因子(upscaling factors)的图像进行训练和测试。
具体来说,我们可以从以下几个方面来理解这句话:
- 卷积层的迁移:在深度学习中,迁移学习是一种常见的技术,它允许将一个已经训练好的模型的部分(如网络层)用于另一个相关的任务中,以减少训练时间和提高模型性能。FSRCNN利用这一思想,将网络中用于特征提取的卷积层设计为与放大因子无关。这意味着,无论是将图像放大2倍、3倍还是4倍,这些卷积层都可以保持不变,而不需要为每个放大因子重新训练。
- 快速训练和测试:由于卷积层可以跨不同的放大因子进行迁移,因此FSRCNN在训练和测试时可以节省大量时间。对于一个新的放大因子,我们只需要重新训练或调整网络的反卷积层,该层直接负责根据给定的放大因子来重建图像。这种方式大大减少了训练成本,并加快了测试速度。
- 无损失的恢复质量:尽管FSRCNN通过迁移卷积层来简化训练和测试过程,但它并没有牺牲图像超分辨率重建的质量。这得益于其网络架构的精心设计,特别是反卷积层能够根据目标放大因子有效地重建图像细节。因此,无论是在哪个放大因子下,FSRCNN都能提供高质量的图像恢复结果。
对比
SRCNN结构(飞镖型维度变化:小-大-小,前端上采样)
1
2
3
4
5
6
7
8
9
10
11
12
13class 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 xFSRCNN结构(沙漏型维度变化:大-小-大,后端上采样)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def __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)])#进行m次s个通道到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()
图片:conv(卷积核大小,输出维度,输入维度)
二.数据集
以img-91作为训练集,Set5作为测试集。
三.模型搭建
1 | class FSRCNN(nn.Module): |
四.模型训练
代码与上一章内容相同
1
python train.py --train-file=data_set/train_set/91-image_x3.h5 --eval-file=data_set/eval_set/Set5_x3.h5 --outputs-dir=outputs #运行命令
结果:
五.模型测试
这里将低分辨率进行超分处理后的预测Y通道与双三次插值后图像的 Cb、Cr通道的结合的意义:
YCbCr色彩空间中的Y代表亮度信息,而Cb和Cr代表色度信息(蓝色和红色的色度差)。RGB色彩空间则直接由红(R)、绿(G)、蓝(B)三个颜色通道组成。
在图像处理中,由于人眼对亮度的敏感度高于对色度的敏感度,因此很多图像处理算法会选择在YCbCr色彩空间中进行处理,尤其是在超分辨率等任务中,可以独立地对亮度(Y通道)和色度(Cb、Cr通道)进行处理,以达到更好的视觉效果和计算效率。
在超分辨率任务中,由于亮度信息(Y通道)包含了图像的主要结构信息,因此通常会通过深度学习等算法对低分辨率图像的Y通道进行预测,以获得高分辨率的Y通道。而色度信息(Cb、Cr通道)则相对简单,可以通过传统的插值方法(如双三次插值)从低分辨率图像中直接获得高分辨率的版本。
将预测的Y通道与bicubic插值得到的Cb、Cr通道结合,实际上是在保持色度信息不变的同时,仅对亮度信息进行增强或修正。这样做的好处是可以在保持图像颜色自然性的同时,显著提高图像的清晰度和细节表现。
1 | cudnn.benchmark = True |