上采样方法综述:线性插值,转置卷积,上池化

您所在的位置:网站首页 插值算法有哪些 上采样方法综述:线性插值,转置卷积,上池化

上采样方法综述:线性插值,转置卷积,上池化

2023-08-25 04:05| 来源: 网络整理| 查看: 265

1. 上采样的定义

上采样的技术是图像进行超分辨率的必要步骤,最近看到了CVPR2019有一些关于上采样的文章,所以想着把上采样的方法做一个简单的总结。

看了一些文章后,发现上采样大致被总结成了三个类别:

1、基于线性插值的上采样 2、基于深度学习的上采样(转置卷积) 3、Unpooling的方法

其实第三种只是做各种简单的补零或者扩充操作,下文将不对其进行涉及。

文章目录 1. 上采样的定义2. 线性插值1、最近邻算法1.9 单线性插值2、双线性插值算法2.2双线性插值优化的方向3、双三次插值算法(bicubic) 3. 深度学习1、转置卷积1.1 stride=1的非填充的反卷积1.2 stride>1, 扩大空间,然后反卷积 1.3扩大空间再用卷积填充2、PixelShuffle(亚像素卷积,CVPR2016)3、DUpsampling(亚像素卷积,CVPR2019)4、Meta-Upscale(任意尺度缩放,CVPR2019)5、CAPAFE(内容关注与核重组,思路新颖,ICCV2019) 4. 上池化—Unpooling参考附录1:full模式的卷积

2. 线性插值

参考:https://zhuanlan.zhihu.com/p/110754637

线性插值用的比较多的主要有三种:最近邻插值算法、双线性插值、双三次插值(BiCubic),当然还有各种其改进型。在如今SR中这些方法仍然广泛应用。这些方法各有优劣和劣势,主要在于处理效果和计算量的差别。

计算效果:最近邻插值算法 < 双线性插值 < 双三次插值计算速度:最近邻插值算法 > 双线性插值 > 双三次插值

最近邻法(Nearest Interpolation):计算速度最快,但是效果最差。 双线性插值(Bilinear Interpolation):双线性插值是用原图像中4(22)个点计算新图像中1个点,效果略逊于双三次插值,速度比双三次插值快,属于一种平衡美,在很多框架中属于默认算法。 双三次插值(Bicubic interpolation):双三次插值是用原图像中16(44)个点计算新图像中1个点,效果比较好,但是计算代价过大。

1、最近邻算法

最近邻插值算法是最简单的一种插值算法,当图片放大时,缺少的像素通过直接使用与之最近原有颜色生成(直接找到原图像中对应的点,将数值赋值给新图像矩阵中的点),也就是说照搬旁边的像素这样做结果产生了明显可见的锯齿。在待求像素的四邻像素中,将距离待求像素最近的邻灰度赋给待求像素。

找到原图像中的最近的点的公式:

在这里插入图片描述

总结

上图效果是最近邻法的计算过程示意图,由上图可见,最近邻法不需要计算只需要寻找原图中对应的点,所以最近邻法速度最快,但是会破坏原图像中像素的渐变关系,原图像中的像素点的值是渐变的,但是在新图像中局部破坏了这种渐变关系。

1.9 单线性插值

在这里插入图片描述

通式:

在这里插入图片描述

在这里插入图片描述

2、双线性插值算法

已知Q12,Q22,Q11,Q21,但是要插值的点为P点,这就要用双线性插值了(双线性插值就是做两次线性变换)

首先在 x 轴方向上,对R1和R2两个点进行插值 然后根据R1和R2对P点进行插值,这就是所谓的双线性插值。

双线性插值是分别在两个方向计算了共3次单线性插值,如图所示,先在x方向求2次单线性插值,获得R1(x, y1)、R2(x, y2)两个临时点,再在y方向计算1次单线性插值得出P(x, y)(实际上调换2次轴的方向先y后x也是一样的结果)。

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

可以把上式汇成所要计算的f(x,y)

在这里插入图片描述

通式: 在这里插入图片描述 f ( Q x x ) f(Q_{xx}) f(Qxx​)权重的表达式:每个点的权重都和待求点和对角点的距离有关

2.2双线性插值优化的方向 1、几何中心点重合。见我的另一篇文章《【上采样问题】双线性插值,几何中心点重合,align_corners》2、align_corners角点是否对齐。见我的另一篇文章《【上采样问题】双线性插值,几何中心点重合,align_corners》3、将浮点运算转换成整数运算(见我的另一篇文章见《【上采样问题】将浮点运算转换成整数运算》) 3、双三次插值算法(bicubic)

双三次插值在SR中引用的比较多,其计算也比较复杂速度较慢。它实际上也是一种插值的方式,但是并不是通过线性插值,而是通过邻近的4x4的像素做加权。

首先第一步是先构建作者所说的BiCubic函数

在这里插入图片描述

其中aij = W(x)* W(y),即我们要分别求取x,y方向的W,然后相乘作为权重。之后的计算就是对 4x4 值做加权,即可求出(u,v)的像素值。

至于x的取值访问如何理解,我简单把我的理解绘制成这张图,当要求的像素点为(u,v),则内圈的四个点权值计算选用|x|1, 扩大空间,然后反卷积

对于stride>1的反卷积过程:

步长大于1的反卷积在计算时,在其输入特征单元之间插入 ( s t r i d e r − 1 ) (strider-1) (strider−1)个0,插入0后把其看出是新的特征输入。

举个例子:

输入:2x2,卷积核:4x4,滑动步长:3,输出:7x7

在这里插入图片描述

在这里插入图片描述

1.输入图片每个像素进行一次反卷积(in=2, k=4, s=3, p=0),根据反卷积大小计算可以知道每个像素的卷积后大小为 1+4-1=4, 即4x4大小的特征图,输入有4个像素所以4个4x4的特征图 2.将4个特征图进行步长为3的fusion(即相加); 例如红色的特征图仍然是在原来输入位置(左上角),绿色还是在原来的位置(右上角),步长为3是指每隔3个像素进行fusion,重叠部分进行相加,即输出的第1行第4列是由红色特阵图的第一行第四列与绿色特征图的第一行第一列相加得到,其他如此类推。

可以看出full反卷积的大小是由卷积核大小与滑动步长决定, in是输入大小, k是卷积核大小, s是滑动步长, out是输出大小 得到 out = (in - 1) * s + k 上图过程就是, (2 - 1) * 3 + 4 = 7

等价于full的卷积模式(in=4, k=4, s=1, p=3)输出7×7,见1.3扩大空间再用卷积填充的解释

代码验证

import torch.nn as nn import torch ''' 测试卷积操作 ConvTranspose2d ''' X = torch.ones((1,1,2,2))#生成一个四维的数,其中第一维可以理解为batchsize,batchsize为1 print(X.shape) print(X) dconv = nn.ConvTranspose2d(1, 1, kernel_size=4, stride=3, padding=0,output_padding=0, bias= False) print(dconv(X))

结果:

tensor([[[[ 0.0872, -0.2410, 0.1025, -0.1363, -0.2410, 0.1025, -0.2235], [ 0.1666, 0.0411, -0.1581, 0.3365, 0.0411, -0.1581, 0.1699], [-0.0411, 0.2479, 0.0950, 0.1764, 0.2479, 0.0950, 0.2175], [ 0.0910, -0.0481, 0.0820, -0.1576, -0.0481, 0.0820, -0.2486], [ 0.1666, 0.0411, -0.1581, 0.3365, 0.0411, -0.1581, 0.1699], [-0.0411, 0.2479, 0.0950, 0.1764, 0.2479, 0.0950, 0.2175], [ 0.0039, 0.1929, -0.0205, -0.0213, 0.1929, -0.0205, -0.0252]]]], grad_fn=) import torch.nn as nn import torch X = torch.zeros((1,1,4,4))#生成一个四维的数,其中第一维可以理解为batchsize,batchsize为1 X[0][0][0][0]=1. X[0][0][0][3]=1. X[0][0][3][0]=1. X[0][0][3][3]=1. print(X.shape) print(X) conv = nn.Conv2d(1, 1, kernel_size=4, stride=1, padding=3,bias=False) print(conv(X)) tensor([[[[ 0.0651, 0.1391, -0.2263, 0.3148, 0.1391, -0.2263, 0.2497], [ 0.2020, 0.1740, 0.2184, 0.4468, 0.1740, 0.2184, 0.2448], [-0.1709, -0.1127, 0.2469, -0.4130, -0.1127, 0.2469, -0.2421], [ 0.2511, 0.1885, -0.4343, 0.6134, 0.1885, -0.4343, 0.3623], [ 0.2020, 0.1740, 0.2184, 0.4468, 0.1740, 0.2184, 0.2448], [-0.1709, -0.1127, 0.2469, -0.4130, -0.1127, 0.2469, -0.2421], [ 0.1860, 0.0494, -0.2081, 0.2986, 0.0494, -0.2081, 0.1126]]]], 1.3扩大空间再用卷积填充

来一个例子:

假设原图是3X3,首先使用上采样让图像变成7X7填充原始图像空白的像素点。使用一个3X3的卷积核对图像进行滑动步长为1的valid卷积,得到一个5X5的图像.结论: 1. 使用上采样扩大图片,2. 使用反卷积填充图像内容,使得图像内容变得丰富,这也是CNN输出end to end结果的一种方法。

在这里插入图片描述

除了以上这种单纯通过补零和unpooling来做输入的扩大的方法之外,近几年来,随着语义分割和超分辨率的发展,也出现了很多其他深度学习的方法来做上采样,取得了很好的效果。

2、PixelShuffle(亚像素卷积,CVPR2016)

PixelShuffle是在CVPR2016的Real-Time Single Image and Video Super-Resolution Using an Effificient Sub-Pixel Convolutional Neural Network一文中提出。

ESPCN的主要概念是关注于亚像素卷积层,通过三次卷积之后输出与原图一样尺寸的 r 2 r^2 r2通道的输出图,再通过如下图所示的reshape方法将 H × W × r 2 H×W×r^2 H×W×r2 的特征图转成 r H × r W rH×rW rH×rW 的输出图。而扩大的倍数刚刚好等同于通道数。这样的做法可以让网络去学习到一种插值方法,并存在于前面三层卷积层的参数中。

在这里插入图片描述这个方法的提出对超分辨率有两个与之前不同的贡献:

一个是不需要再通过一开始进行线性插值来扩大输入的尺寸了,从而可以用更小的卷积核就可以获得很好的效果,另一个是作者认为bicubic是一种卷积的特殊情况(即计算权重相乘求和),用卷积学习可以学会比手工设计更好的拟合方式。 3、DUpsampling(亚像素卷积,CVPR2019)

这个上采样方法是在CVPR2019中的Decoders Matter for Semantic Segmentation: Data-Dependent Decoding Enables Flexible Feature Aggregation∗中提出的,从下面的网络结构来看和PixelShuffle有点类似,它是通过卷积学习亚像素,并最后重组来获得更大的图像。

在这里插入图片描述 DUpsampling在对特征图的操作上有所不同,是先通过将单个像素所对应的C个通道reshape成一个 1 × C 1×C 1×C的向量,与 C × N C×N C×N的矩阵相乘得到 1 × N 1×N 1×N的向量,再reshape成为 2 × 2 × N / 4 2×2×N/4 2×2×N/4(2应该指的是放大倍数,即 r × r × N / r 2 r×r×N/r^2 r×r×N/r2)的扩大后的亚像素块,组合成放大后的特征图。

以上这两种算法都是基于数据去训练的,可以获得比线性插值更好的效果,但是与线性插值相比存在的问题是:

1、对于不同的放大倍数的图像需要训练不同的网络(因为通道数的改变);2、不容易进行连续的放大,比如1.1倍,1.2倍这样。说不容易而不是不能是因为可以适当放大输入图像或者对权重和步长进行调整后放缩,但是计算很复杂,效果没有整数倍好,线性插值却很容易办到。 4、Meta-Upscale(任意尺度缩放,CVPR2019)

在这里插入图片描述

先上一张图,这张图我觉得比较好的说明了原来的方法要如何做一次非整数尺度的放缩,这样方便进一步了解Meta-SR的思路。

Meta-SR中的Meta-Upscale是在CVPR2019上的Meta-SR: A Magnifification-Arbitrary Network for Super-Resolution一文中提出来的,作者提出了一种可以任意尺度缩放的方法,可以实现较好效果的非整数的放缩。

在这里插入图片描述

FLR 表示由特征学习模块提取的特征,并假定缩放因子是 r。对于 SR 图像上的每个像素(i, j),文中认为它由 ILR 图像上像素(i′,j′)的特征与一组相应卷积滤波器的权重所共同决定。从这一角度看,放大模块可视为从 FLR 到 ISR 的映射函数。

在这里插入图片描述

我对此的理解是,kxk应该是所设定的与ISR所相关的一个像素搜索范围。及这个范围内的所有像素都是和最后输出的像素是有关系的,需要对其计算相应的权重并加权计算。

HWx(InCxoutC)我的理解是图像最后输出的长x宽x输入的通道数(文中为64)x输出的通道数(文中为3)做为权值生成的输出的通道数。

对于一个像素的计算我们需要对64个通道上feature map上的对应9个值加权求和,就可以计算出输出的一个通道值,重复3次就是一个值的3个通道数的值,重复HW次就可以计算出整个输出。

那么知道最后如何计算输出之后,我们关心的是文中提到的是怎么来做对不同的放缩大小的权值计算的以及如何在任意尺度下完成输出像素和LR特征图上的对应。

作者把 Meta-Upscale 模块由三个重要的函数,即 Location Projection、Weight Prediction、Feature Mapping(这个就是上文讲的如何乘以权值得到最后的输出)。

先说下文中的Location Projection,如下图:

在这里插入图片描述 在这里插入图片描述

通过向下取整使得ISR中的每一个值都可以在ILR上找到一个对应的值。如放大1.5倍,那么ILR上的0对应ISR中的0和1(0/1.5



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3