PyTorch中grid_sample的使用方法

grid_sample底层是应用双线性插值,把输入的tensor转换为指定大小。那它和interpolate有啥区别呢?
interpolate是规则采样(uniform),但是grid_sample的转换方式,内部采点的方式并不是规则的,是一种更为灵活的方式。

torch.nn.functional.grid_sample(input, grid, mode=‘bilinear’, padding_mode=‘zeros’)
  • input : 输入tensor, shape为 [N, C, H_in, W_in]
  • grid: 一个field flow, shape为[N, H_out, W_out, 2],最后一个维度是每个grid(H_out_i, W_out_i)在input的哪个位置的邻域去采点。数值范围被归一化到[-1,1]。

下面将介绍具体的例子。

import torch
from torch.nn import functional as F


inp = torch.ones(1, 1, 4, 4)

# 目的是得到一个 长宽为20的tensor
out_h = 20
out_w = 20
 # grid的生成方式等价于用mesh_grid
new_h = torch.linspace(-1, 1, out_h).view(-1, 1).repeat(1, out_w)
new_w = torch.linspace(-1, 1, out_w).repeat(out_h, 1)
grid = torch.cat((new_h.unsqueeze(2), new_w.unsqueeze(2)), dim=2)
grid = grid.unsqueeze(0)

outp = F.grid_sample(inp, grid=grid, mode='bilinear')
print(outp.shape)  #torch.Size([1, 1, 20, 20])

在上面的例子中,我们将一个大小为4x4的tensor 转换为了一个20x20的。grid的大小指定了输出大小,每个grid的位置是一个(x,y)坐标,其值来自于:输入input的(x,y)中 的四邻域插值得到的。

PyTorch中grid_sample的使用方法_第1张图片
图片来自于SFnet(eccv2020)。flow field是grid, low_resolution是input, high resolution是output。

至于grid的值是控制在-1,1的。那如何对应在input上呢。这个来看一下pytorch的底层源码
第66行到71行,获取到了grid的x和y,之后对其做了新的变换,变到input的坐标系下了。IW和IH是input的宽和高。

        real ix = THTensor_fastGet4d(grid, n, h, w, 0);
        real iy = THTensor_fastGet4d(grid, n, h, w, 1);

        // normalize ix, iy from [-1, 1] to [0, IH-1] & [0, IW-1]
        ix = ((ix + 1) / 2) * (IW-1);
        iy = ((iy + 1) / 2) * (IH-1);

你可能感兴趣的:(Pytorch)