zoukankan      html  css  js  c++  java
  • [转载]PyTorch上的contiguous

    [转载]PyTorch上的contiguous

    来源:https://zhuanlan.zhihu.com/p/64551412

    这篇文章写的非常好,我这里就不复制粘贴了,有兴趣的同学可以去看原文,我这里只摘录一些结论过来以便查询:

    PyTorch 提供了is_contiguouscontiguous(形容词动用)两个方法 ,分别用于判定Tensor是否是 contiguous 的,以及保证Tensor是contiguous的。

    is_contiguous直观的解释是Tensor底层一维数组元素的存储顺序与Tensor按行优先一维展开的元素顺序是否一致

    为什么需要 contiguous

    torch.view等方法操作需要连续的Tensor。

    transpose、permute 操作虽然没有修改底层一维数组,但是新建了一份Tensor元信息,并在新的元信息中的 重新指定 stride。torch.view 方法约定了不修改数组本身,只是使用新的形状查看数据。如果我们在 transpose、permute 操作后执行 view,Pytorch 会抛出错误.

    原文中举了一个例子来说明:transpose、permute不修改底层数组,而view是直接访问底层数组的,所以在执行transpose、permute之后如果直接调用view,返回的是内存中存储的底层数组的顺序,而非transpose、permute操作之后看起来的顺序

    >>>t = torch.arange(12).reshape(3,4)
    >>>t
    tensor([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>>t.stride()
    (4, 1)
    >>>t2 = t.transpose(0,1)
    >>>t2
    tensor([[ 0,  4,  8],
           [ 1,  5,  9],
           [ 2,  6, 10],
           [ 3,  7, 11]])
    >>>t2.stride()
    (1, 4)
    >>>t.data_ptr() == t2.data_ptr() # 底层数据是同一个一维数组
    True
    >>>t.is_contiguous(),t2.is_contiguous() # t连续,t2不连续
    (True, False)
    

    t2 与 t 引用同一份底层数据 a,如下:

    [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]
    

    ,两者仅是stride、shape不同。如果执行 t2.view(-1) ,期望返回以下数据 b(但实际会报错):

    [ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11]
    

    a 的基础上使用一个新的 stride 无法直接得到 b ,需要先使用 t2 的 stride (1, 4) 转换到 t2 的结构,再基于 t2 的结构使用 stride (1,) 转换为形状为 (12,)的 b但这不是view工作的方式view 仅在底层数组上使用指定的形状进行变形,即使 view 不报错,它返回的数据是:

    [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]
    

    这是不满足预期的。使用contiguous方法后返回新Tensor t3,重新开辟了一块内存,并使用照 t2 的按行优先一维展开的顺序存储底层数据。

    >>>t3 = t2.contiguous()
    >>>t3
    tensor([[ 0,  4,  8],
           [ 1,  5,  9],
           [ 2,  6, 10],
           [ 3,  7, 11]])
    >>>t3.data_ptr() == t2.data_ptr() # 底层数据不是同一个一维数组
    False
    

    可以发现 t与t2 底层数据指针一致,t3 与 t2 底层数据指针不一致,说明确实重新开辟了内存空间。

  • 相关阅读:
    python 发送邮件
    java 获取两个时间之前所有的日期
    java 子线程定时去更改主线程的变量
    post 两种方式 application/x-www-form-urlencoded和multipart/form-data
    aws 社交媒体技术大会 部分总结
    java操作Mongodb数据库
    实体类注解 @entity
    spring security 部分注解讲解
    @Column
    阿里云搭建服务器
  • 原文地址:https://www.cnblogs.com/jiading/p/11982023.html
Copyright © 2011-2022 走看看