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

本文介绍了深度学习中用于图像分割任务的上采样方法,包括线性插值(特别是双线性插值)和反池化。双线性插值通过在像素点周围生成新像素点来放大图像,而反池化则是池化的逆运算,可能丢失一些细节。此外,还提到了TransposeConv(转置卷积)作为上采样的一种方式,其本质是通过矩阵运算实现图像尺寸的扩大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三种上采样方法

在各种深度学习框架中,对于图像任务来说,数据格式通常为 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 × 16 4 \times 16 4×16的matrix其实就是kernel需要在原图上要进行所有运算的矩阵(卷积矩阵),然后把input也拉成一个一维的列向量,两者相乘就是最后的结果。

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

在这里插入图片描述

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

以上就是常用三种上采样方法 :)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值