ESPCN的核心概念是亚像素卷积层(sub-pixel convolutional layer)。网络的输入是原始低分辨率图像,通过三个卷积层以后,得到的特征为r^2WH ,其中WH与输入图像大小相同,再将特征图像每个像素的 r^2个通道重新排列成一个 r*r 的区域,即将r^2WH特征经过重排得到rW*rH的输出,实现了图像r倍上采样。
pixel_shuffle = torch.nn.PixelShuffle(r)
output = pixel_shuffle(input)
其中r为上采样倍率。输入输出如下:
比如input的shape是(1, 64, 20, 30), r = 2,
而这个shape对应的是(1, r2C, H, W), 也就是r2C = 2x2xC = 64, 所以C=16,
所以output应该是(1, C, rH, rW),也就是(1, 16, 40, 60)
例如,有r2个channel, 把这些channel铺成 r x r的一个大像素,假如r = 3,那么output中一个pixel有9个channel,它对应右边SR图像中一个3x3的大像素(注意看颜色的对应)。回到r,每个pixel有r2个channel,把它铺平,成为一个r x r的SR大像素,所以(r2C, H x W)就成了(C, r x r x H x W), 也就是(C, rH, rW)
ConvTranspose2d是其中一个扩大图像尺寸的方法(逆卷积)
self.last_part = nn.ConvTranspose2d(d, num_channels, kernel_size=9,
stride=scale_factor, padding=9//2,output_padding=scale_factor-1)
当给一个特征图a, 以及给定的卷积核设置,我们分为三步进行逆卷积操作:
第一步:对输入的特征图a进行一些变换,得到新的特征图a’
第二步:求新的卷积核设置,得到新的卷积核设置,后面都会用右上角加撇点的方式区分
第三步:用新的卷积核在新的特征图上做常规的卷积,得到的结果就是逆卷积的结果,就是我们要求的结果。
(1)新的特征图通过插值得到,插在原先高度方向的每两个相邻中间插上" Stride-1"列0。我们知道对于输入为 Height 的特征图来说有 Height-1个位置,所以,最终我们的特征图在原先的基础上加上 (Stride−1)∗(Height−1)。即 Height'=Height+(Stride-1)*(Height-1)
对图的说明:
输入特征图A: 3*3
输入卷积核K:kernel为 3*3, stride为2, padding为1
新的特征图A’: 3 + (3-1)*(2-1) = 3+2 = 5 注意加上padding之后才是7。
新的卷积核设置K’: kernel不变,stride为1,padding= 3-1-1=1
最终结果: (5+2-3)/1+1=5