三种上采样方法 | 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的图像输出。