所谓上采样,实则是一个插值过程。所以上采样对象在初始化时,需要指定一个插值类型,Upsample是torch.nn中最基础的上采样类,初始化参数如下
Upsample(size=None, scale_factor=None, mode='nearest', align_corners=None)
其中,scale_factor为上采样的倍数,align_corners为True时,输出的角像素将与输出张量对齐。
插值模式可选值包括
记scale_factor为 k k k,则输入和输出数组形状的关系如下
1D | 2D | 3D | |
---|---|---|---|
输入 | [ N , C , W ] [N,C,W] [N,C,W] | [ N , C , H , W ] [N,C,H,W] [N,C,H,W] | [ N , C , D , H , W ] [N,C,D,H,W] [N,C,D,H,W] |
输出 | [ N , C , k W ] [N,C,kW] [N,C,kW] | [ N , C , k H , k W ] [N,C,kH,kW] [N,C,kH,kW] | [ N , C , k D , k H , k W ] [N,C,kD,kH,kW] [N,C,kD,kH,kW] |
下面针对一维数组测试一下
import torch
from torch import nn
x = torch.arange(1, 5, dtype=torch.float32).view(1, 1, 4)
up = nn.Upsample(scale_factor=2, mode='linear')
up(x)
# tensor([[[1.00, 1.25, 1.75, 2.25, 2.75, 3.25, 3.75, 4.00]]])
可见,up将 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4变成了 1.00 , 1.25 , 1.75 , 2.25 , 2.75 , 3.25 , 3.75 , 4.00 1.00, 1.25, 1.75, 2.25, 2.75, 3.25, 3.75, 4.00 1.00,1.25,1.75,2.25,2.75,3.25,3.75,4.00。
可能是针对二维图像的上采样操作比较多,故而pytorch专门为这种情况封装了两个类,并且分别提供了邻近插值和双线性插值,其初始化参数如下
UpsamplingNearest2d(size=None, scale_factor=None)
UpsamplingBilinear2d(size=None, scale_factor=None)
二者的输入均为 N , C , H , W N,C,H,W N,C,H,W,输出均为 N , C , k H , k W N,C,kH,kW N,C,kH,kW,与UpSample的二维情况一致。
x0 = torch.arange(1, 17, dtype=torch.float32).view(1, 1, 4, 4)
upNearest = nn.UpsamplingNearest2d(scale_factor=2)
upBilinear = nn.UpsamplingBilinear2d(scale_factor=2)
xN = upNearest(x0)
xB = upBilinear(x0)
下面可以画一下二者的区别
import matplotlib.pyplot as plt
fig = plt.figure()
for i, x in enumerate([x0, xN, xB],1):
ax = fig.add_subplot(1,3,i)
plt.imshow(torch.squeeze(x))
plt.show()
效果如下
第二个图像为邻近插值,即插入值等于某个附近点的值,所以从结果来看,尽管像素尺寸从 4 × 4 4\times4 4×4变成了 8 × 8 8\times8 8×8,但相邻的 2 × 2 2\times2 2×2的像素格子中,灰度值是一致的。