[转载]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 底层数据指针不一致,说明确实重新开辟了内存空间。

最新文章

  1. Mac下安装GIT的坑
  2. flex4
  3. R&Rstudio安装各种包
  4. Python成长笔记 - 基础篇 (十三)--堡垒机
  5. Effective C++ -----条款43:学习处理模板化基类内的名称
  6. PAT乙级 1032. 挖掘机技术哪家强(20)
  7. 【转载】【Windows批处理IV】批量进行文件重命名
  8. 夺命雷公狗---微信开发62----所以memcache对access_token进行全局缓存优化
  9. js对cookie的操作,包括增,取,删
  10. GlassFish Server is a compliant implementation of the Java EE 7 platform
  11. iOS开发 - 一个天真的搜索控制器的独白
  12. ZigZag Conversion1
  13. su普通用户切换root用户失败
  14. Oracle安装oraInventory问题
  15. 面试题之python基础
  16. C#拷贝一个库的表到另外一个库中(的四种方式)
  17. kindedit编辑器和xxs攻击防护(BeautifulSoup)的简单使用
  18. RPM二进制包软件安装
  19. kafka---->kafka的使用(一)
  20. 使用Properties类和ResourceBundle类读取properties文件

热门文章

  1. FYI是什么意思?
  2. GradientDrawable
  3. 05-06 Flutter JSON和序列化反序列化、创建模型类转换Json数据、轮播图数据渲染:Flutter创建商品数据模型 、请求Api接口渲染热门商品 推荐商品
  4. phpcms前台无法退出无法清除cookie
  5. Android学习笔记之View
  6. 【AMAD】django-taggit -- 一个简单的,通用的django tagging模块
  7. 《剑指offer》Q01-12 (牛客10.11)
  8. NDK学习笔记-文件的拆分与合并
  9. Vue的作用域插槽
  10. Netty学习篇①