nn.ConvTranspose2d和nn.Upsample的区别

有参数可以训练

nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1,
                   padding=0, output_padding=0, groups=1, bias=True,
                   dilation=1, padding_mode=‘zeros’)

 

没有参数,速度更快,采取给定策略上采样

torch.nn.Upsample(size=None, scale_factor=None, mode=‘nearest’, align_corners=None)


对输入的多通道数据进行上采样
size (tuple ,optional)– 是输出矩阵大小([optional D_out], [optional H_out], W_out)的元组。
scale_factor (int / tuple of python:ints, optional) – 图像宽/高/深度的倍数
mode – (string, optional) – 上采样方法: 有nearest, linear, bilinear, bicubic and trilinear. 默认是: nearest
align_corners (bool, optional) – 如果为true,则输入和输入tensor的角点像素对齐,从而保留这些像素的像素值。 默认值: False

 

两者都是用来实现上采样,假设采样倍数为scale, 则把(H, W, C) -->变为(H*scale, W*scale,C)

下面以2倍上采样为例。

1.Upsample通过插值方法完成上采样。所以不需要训练参数

nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)

其中mode为选择的插值方法。

双线性插值原理及公式:

nn.ConvTranspose2d和nn.Upsample的区别_第1张图片

nn.ConvTranspose2d和nn.Upsample的区别_第2张图片

所以为了求P点需要根据P得到Q11,Q12,Q21以及Q22的坐标以及值!

步骤如下:

1)求P点坐标。对于目标图上的一个点Pdst,先求取对应的在源图上的点P,一般以像素中心为标准.(如果标准不同会导致最后的resize结果不同, 如opencv和matlab)

2)利用P点坐标求Q11,Q12,Q21以及Q22的坐标以及值。因为P点一般为小数,则对应的4个点就是相邻整数,如下图所示,则值也可以求出

3)套用公式,得到目标图上Pdst的值。

代码如下:

for n in range(3): # 对channel循环
        for dst_y in range(dst_h): # 对height循环
            for dst_x in range(dst_w): # 对width循环
                # 目标在源上的坐标
                src_x = (dst_x + 0.5) * scale_x - 0.5
                src_y = (dst_y + 0.5) * scale_y - 0.5
                # 计算在源图上四个近邻点的位置
                src_x_0 = int(np.floor(src_x))
                src_y_0 = int(np.floor(src_y))
                src_x_1 = min(src_x_0 + 1, src_w - 1)
                src_y_1 = min(src_y_0 + 1, src_h - 1)
 
                # 双线性插值
                value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, n] + (src_x - src_x_0) * src[src_y_0, src_x_1, n]
                value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, n] + (src_x - src_x_0) * src[src_y_1, src_x_1, n]
                dst[dst_y, dst_x, n] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)
    return dst

2.ConvTranspose2d可以理解为卷积的逆过程。所以可以训练参数

nn.ConvTranspose2d(mid_channels, mid_channels, kernel_size=4, stride=2, padding=1)

其中输出尺寸与输入关系如下,所以,k=4, s=2, p=1即2倍上采样。

具体执行过程为通过对原图插值0,扩大尺寸,然后改变卷积参数,对扩大尺寸后的进行卷积即nn.ConvTranspose2d:

1)原图插值,在两两元素之间插0。

2)改变参数。新的卷积核:Stride′=1, kernel的size′ = size  padding' 为Size−padding−1
3)卷积

如图所示:(3*3)--> (6*6)

在这里插入图片描述

 

你可能感兴趣的:(Python,Pytorch,python,pytorch)