三种上采样方法 | Three up sampling methods

三种上采样方法 | Three up sampling methods

目录

    • 三种上采样方法
      • 线性插值 | liner interpolate
        • 代码实现
      • 反池化 | Un - Pooling
      • Transpose Conv
        • 对Transport Conv更加细致的理解

三种上采样方法

在各种深度学习框架中,对于图像任务来说,数据格式通常为 NCHW,因为当数据是以这种格式排列的时候,在利用 intel GPU 加速的情况下,GPU希望读取同一个channel的图像像素是连续的,NCHW的排布正好满足需求,在访问内存的时候就是连续的了,比较方便。

在做图像分割的时候,要求对图像做像素级分类。对于常见的FCN分割网络来说,在网络的最后需要把经过卷积、池化的图像数据进行放大,放大到输入图像的Size后进行输出,这个过程不改变数据的N 和 C ,只改变 W 、H

放大的过程被称为上采样

线性插值 | liner interpolate

在线性插值的几种方法,例如双线性插值、三线性插值、最近邻插值、双三次插值,最常用的是双线性插值。

  • 最近邻插值是在输入张量的高度和宽度上进行最近邻插值。
  • 双线性插值是线性插值的扩展,用于在直线2D网格上插值两个变量(例如,该操作中的H方向和W方向)的函数。 关键思想是首先在一个方向上执行线性插值,然后在另一个方向上再次执行线性插值。
  • 三线插值是线性插值的一种扩展,是3参数的插值方程(比如op里的D,H,W方向),在三个方向上进行线性插值。
  • 双三次插值是在二维网格上对数据点进行插值的三次插值的扩展,它能创造出比双线性和最近临插值更为光滑的图像边缘。

此处用双线性插值举例

结论简述:双线性插值就是在几个像素点围成的矩阵内部,根据计算方法生成一些与临近像素点的数值相差不大的新像素点,以此来对图像进行放大。

代码实现

环境: paddle 1.8.5、 python3.6+

import paddle.fluid as fluid
import numpy as np

def main():
    with fluid.dygraph.guard(fluid.CPUPlace()):
        data = np.array([[1,2],
                         [6,9]]).astype('float32')
        print(data)
        data = data[np.newaxis,np.newaxis,:,:]
        data = fluid.dygraph.to_variable(data)
        data = fluid.layers.interpolate(data,out_shape=(4,4),align_corners=True)
        out = data.numpy()
        print(out)

if __name__ == "__main__":
    main()

#---------------------------------------------------------------------------#
OUTPUT:
[[1. 2.]
 [6. 9.]]
 
[[[[1.        1.3333333 1.6666667 2.       ]
   [2.6666665 3.222222  3.7777777 4.333333 ]
   [4.3333335 5.1111107 5.888889  6.6666665]
   [6.        7.        8.        9.       ]]]]

反池化 | Un - Pooling

显而易见,反池化就是池化的逆运算,现在基本不用这种方法了。

上图就是Max-pooling的逆过程,不同的是经过反池化后,生成的图像可能会丢失一些细节,例如图中的0,但是可以表现图像特征的像素值会保留,例如图像里面的20,30,112,37这些像素点。

Transpose Conv

如图,左边是一个正常的卷积过程,而右边则是Cnov的逆过程,下面这张图会更清楚一点,大概过程就是把得到的特征图也就是feature map 进行一个padding,再和旋转180°的卷积核进行正常的卷积过程,得到一张扩张的output。

上述过程可以说是一个结论,其中对底层来说,并不存在我们脑子里这么抽象的东西,例如卷积核的滑动啊,对于底层来说,其实本质还是在做矩阵的运算

对Transport Conv更加细致的理解

对于不想理解原理的朋友来说,这部分可以跳过。

对于正常的卷积操作来说,其实质性的操作其实是把整个过程(卷积核在原图上的滑动以及像素点的相乘相加)要进行的步骤具体化为一个矩阵matrix,下图kernel下方的4 \times 16的matrix其实就是kernel需要在原图上要进行所有运算的矩阵(卷积矩阵),然后把input也拉成一个一维的列向量,两者相乘就是最后的结果。

根据基本的现代知识,4 \times 16 的matrix和一个 16 \times 1 的matrix相乘最后得到一个4 \times 1的列向量,再把列向量reshape成我们需要的输出size,其实这就是底层所做的,整个卷积的过程。

为什么第三种方法被称为transport conv,就是因为它其实是把卷积矩阵(上面谈到的),进行一个transport操作,再和输入需要做上采样的图像数据进行卷积操作,得到最后需要的与原图相同size的图像输出。

发布于 2021-01-14 20:16