开发者

PyTorch中grid_sample的使用及说明

目录
  • 关于grid_sample的使用
    • 下面将介绍具体的例子
  • torch.nn.functional.grid_sample() 注意点
    • 细节
  • 总结

    关于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的大小指定了输android开发者_开发入门出大小,每个grid的位置是一个(x,y)坐标,其值来自于:输入input的(x,y)中 的四邻域插值得到的。

    PyTorch中grid_sample的使用及说明

    图片来自于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);

    torch.nn.functional.grid_sample() 注意点

    用法: 主要用于采样,一般是使用bilinear根据grid的坐标采样

    F.grid_sample(img, grid, align_corners=True)
    • img是采样的空间,grid是生成的网格坐标。
    • grid通常由torch.meshgrid()生成,且要映射到(-1,1)之间,如:
    dx = torch.linspace(-1,1, 9)
    dy = torch.linspace(-1, 1,7)
    coords = torch.stack(torch.meshgrid(dy, dx), axis=-1)  #[dy*dx*2]

    输入输出情况:

    假如是4D 的input:

    img.shape : [B,C,H_in,W_in]
    grid.shape: [B,H_out,W_out,2]
    out: [B,C,编程H_out,W_out]

    细节

    1.为什么meshgrid生成坐标的时候,stack成coords时需要逆序(第一层是y,第二层是x)?

    Ans:采样的时候,在img上取点,坐标是根据grid来的,grid[:,:,0]是W维度的坐标,grid[:,:,1]是H维度的坐标,所以这个地方需要注意,是反过来的

    2.grid的形状仅仅影响output的形状,直接决定取点的还是坐标,所以尤其要注意grid坐标叠。

    总结

    以上为个人经验,编程客栈希望能给大家一个参考,也希望大家多多支持我们。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜