FSRCNN论文学习笔记

       SRCNN作为卷积神经网络应用于SR领域0到1的突破,与传统的图像重建方法相比取得了较好的性能。在此基础上,Chao Dong等人针对其存在的问题进行了改进,进一步提出了更为轻量型的FSRCNN网络,在保证性能的基础上大大提升了网络速度。

SRCNN网络存在两个显著的不足:

①在图像预处理阶段通过双三次插值将原始LR图像放大至目标HR图像,后续操作均在插值放大后的图像上进行,计算复杂度为o(n^{2})

②复杂的非线性映射步骤,使用了大量的参数,从而导致网络收敛速度较慢。

FSRCNN的主要改进:

①直接将不经任何预处理操作的原始图像送入网络,在低维空间进行重建操作,并在网络最后添加反卷积层来代替双三次插值,以实现上采样操作,放大图像尺寸。此时网络的计算复杂度仅与原始LR图像的空间大小成比例o(n)

②将原有的非线性映射层替换为一个由收缩层,低维非线性映射层、扩展层组成的沙漏型网络结构(中间厚,两端薄)。

③不同的放大因子可共享网络参数,仅需针对一个放大因子对模型进行预训练,在使用另一个放大因子时微调反卷积层的参数即可,大大提高了网络的训练速度与鲁棒性。

FSRCNN网络结构

FSRCNN论文学习笔记_第1张图片

       训练集同样采用91-images(额外增加General-100 dataset),测试集使用set5数据集,FSRCNN的超参数为d,s,m,网络表示为FSRCNN(d,s,m)。

输入图像: 首先根据缩放因子k对原始图像进行下采样形成LR图像,然后将LR图像切割成大小为n×n(n=patches)的子图像,LR子图像与对应的HR子图像作为labels同时输入网络中作为训练集(prepare→h5文件)。

特征提取层(提取特征):d个大小为1×5×5的卷积核,输出特征图大小为n×n×d(使用padding);

收缩层(减小特征维度):s(s<

非线性映射层(m个):s个大小为s×3×3的卷积核,中间特征图大小为n×n×s,输出特征图大小同样为n×n×s;

扩展层(恢复特征维度):d个大小为s×1×1的卷积核,输出特征图大小为n×n×d;

反卷积层(放大因子为k):1个大小为d×9×9的卷积核,padding=k-1,stride=k,输出放大后的HR图像大小为nk×nk×1。

损失函数:MSE均方误差

       与SRCNN不同的是,此时的输入数据准备无需经过双三次放大步骤,直接输入原图像:

hr_width = (hr.width // args.scale) * args.scale
hr_height = (hr.height // args.scale) * args.scale
hr = hr.resize((hr_width, hr_height), resample=pil_image.BICUBIC)
lr = hr.resize((hr.width // args.scale, hr_height // args.scale), resample=pil_image.BICUBIC)
# lr = hr.resize((hr.width * args.scale, hr_height * args.scale), resample=pil_image.BICUBIC)  无需放大

       网络的实现也较为容易:(使用PReLU激活函数防止特征失活)

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()

       FSRCNN(56,12,4)取得了速度与质量上的最佳性能,小型FSRCNN(32,5,1)在减少参数的同时也满足了质量和速度的要求。

重建结果:(PSNR=35.53)

FSRCNN论文学习笔记_第2张图片

PS:反卷积

FSRCNN论文学习笔记_第3张图片

stride:生成图像上移动的步长;

padding:卷积核周围填充像素;

输出矩阵大小:

        output=(input-1)*stride+2*(padding+1)+kernel_size-2(无output_padding)

        output=(input-1)*stride+output_padding–2*padding+kernel_size(有output_padding)

pytorch中的nn.ConvTranspose2d函数:

nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1)
'''
in_channels(int) – 输入信号的通道数
out_channels(int) – 卷积产生的通道数
kerner_size(int or tuple) - 卷积核的大小
stride(int or tuple,optional) - 卷积步长,即要将输入扩大的倍数。
padding(int or tuple, optional) - 输入的每一条边补充0的层数,高宽都增加2*padding
output_padding(int or tuple, optional) - 输出边补充0的层数,高宽都增加padding
groups(int, optional) – 从输入通道到输出通道的阻塞连接数
bias(bool, optional) - 如果bias=True,添加偏置
dilation(int or tuple, optional) – 卷积核元素之间的间距
'''

你可能感兴趣的:(深度学习,超分辨率重建,计算机视觉)