pytorch中的contiguous()

1 先看看官方中英文doc:

torch.Tensor.contiguous (Python method, in torch.Tensor)
torch.Tensor.is_contiguous (Python method, in torch.Tensor)

1.1 contiguous() → Tensor

Returns a contiguous tensor containing the same data as self tensor. If self tensor is contiguous, this function returns the self tensor.

1.2 contiguous() → Tensor

返回一个内存连续的有相同数据的tensor,如果原tensor内存连续,则返回原tensor;

2 pytorch contiguous的使用

contiguous一般与transpose,permute,view搭配使用:使用transpose或permute进行维度变换后,调用contiguous,然后方可使用view对维度进行变形(如:tensor_var.contiguous().view() ),示例如下:

x = torch.Tensor(2,3)
y = x.permute(1,0)         # permute:二维tensor的维度变换,此处功能相当于转置transpose
y.view(-1)                 # 报错,view使用前需调用contiguous()函数
y = x.permute(1,0).contiguous()
y.view(-1)                 # OK

具体原因有两种说法:

1 transpose、permute等维度变换操作后,tensor在内存中不再是连续存储的,而view操作要求tensor的内存连续存储,所以需要contiguous来返回一个contiguous copy;

2 维度变换后的变量是之前变量的浅拷贝,指向同一区域,即view操作会连带原来的变量一同变形,这是不合法的,所以也会报错;---- 这个解释有部分道理,也即contiguous返回了tensor的深拷贝contiguous copy数据;

3 contiguous函数分析,参考CSDN博客

在pytorch中,只有很少几个操作是不改变tensor的内容本身,而只是重新定义下标与元素的对应关系。换句话说,这种操作不进行数据拷贝和数据的改变,变的是元数据,这些操作是:

narrow(),view(),expand(),transpose();

举个栗子,在使用transpose()进行转置操作时,pytorch并不会创建新的、转置后的tensor,而是修改了tensor中的一些属性(也就是元数据),使得此时的offset和stride是与转置tensor相对应的,而转置的tensor和原tensor的内存是共享的

为了证明这一点,我们来看下面的代码:

x = torch.randn(3, 2)
y = x.transpose(x, 0, 1)
x[0, 0] = 233
print(y[0, 0])       # print 233

可以看到,改变了x的元素的值的同时,y的元素的值也发生了变化;也即,经过上述操作后得到的tensor,它内部数据的布局方式和从头开始创建一个常规的tensor的布局方式是不一样的!于是就有contiguous()的用武之地了。

在上面的例子中,x是contiguous的,但y不是(因为内部数据不是通常的布局方式)。注意:不要被contiguous的字面意思“连续的”误解,tensor中数据还是在内存中一块区域里,只是布局的问题

*当调用contiguous()时,会强制拷贝一份tensor,让它的布局和从头创建的一模一样;*

一般来说这一点不用太担心,如果你没在需要调用contiguous()的地方调用contiguous(),运行时会提示你:

RuntimeError: input is not contiguous

只要看到这个错误提示,加上contiguous()就好啦~

4 其他

4.1 is_contiguous()函数

is_contiguous() → bool

Returns True if self tensor is contiguous in memory in C order.

is_contiguous() → bool

如果该tensor在内存中是连续的则返回True;

pytorch里面的 contiguous() 是以 C 为顺序保存在内存里面,如果不是,则返回一个以 C 为顺序保存的tensor:

tensor_var.is_contiguous()           # 可以用来判断tensor是否以 C 为顺序保存的

一些可能导致不是以 C 为顺序保存的可能为:

import torch
x = torch.ones(10, 10)
x.is_contiguous()                                                   # True
x.transpose(0, 1).is_contiguous()                          # False,transpose会改变tensor变量内存的布局方式
x.transpose(0, 1).contiguous().is_contiguous()     # True

4.2 view()、reshape()函数的差异

在pytorch 0.4中,增加了torch.reshape(),与 numpy.reshape() 的功能类似,大致相当于 tensor.contiguous().view(),这样就省去了对tensor做view()变换前,调用contiguous()的麻烦;

pytorch中的contiguous()相关推荐

  1. PyTorch学习笔记(15) ——PyTorch中的contiguous

    本文转载自栩风在知乎上的文章<PyTorch中的contiguous>.我觉得很好,特此转载. 0. 前言 本文讲解了pytorch中contiguous的含义.定义.实现,以及conti ...

  2. Pytorch中的contiguous()函数

    这个函数主要是为了辅助pytorch中的一些其他函数,主要包含 在PyTorch中,有一些对Tensor的操作不会真正改变Tensor的内容,改变的仅仅是Tensor中字节位置的索引.这些操作有: n ...

  3. pytorch中的contiguous()函数的浅浅解释

    contiguous() 有些tensor并不是占用一整块内存,而是由不同的数据块组成. contiguous()函数的作用:把tensor变成在内存中连续分布的形式. 来自链接一 contiguou ...

  4. Pytorch中的contiguous理解

    最近遇到这个函数,但查的中文博客里的解释貌似不是很到位,这里翻译一下stackoverflow上的回答并加上自己的理解. 在pytorch中,只有很少几个操作是不改变tensor的内容本身,而只是重新 ...

  5. PyTorch中的contiguous解读

    本文讲解了pytorch中contiguous的含义.定义.实现,以及contiguous存在的原因,非contiguous时的解决办法.并对比了numpy中的contiguous. contiguo ...

  6. 详解PyTorch中的contiguous

    目录 前言 PyTorch中的is_contiguous是啥? 行优先 为什么需要 contiguous ? 为什么不在view 方法中默认调用contiguous方法? 前言 contiguous ...

  7. pytorch中的contiguous

    contigous 在英文中为 连续的意思,何为连续,就是语义相同的张量存储在连续的内存空间中, 为什么要使用contigous? 因为view()操作需要连续的tensor transpose.pe ...

  8. pytorch 中的 contiguous()

    if self.output_attention:return (V.contiguous(), A) #使用contiguous() # 如果想要断开这两个变量之间的依赖(x本身是contiguou ...

  9. pytorch笔记:contiguous tensor 存储知识

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

最新文章

  1. 3_ARM内核和架构都是什么意思,它们到底是什么关系?
  2. boost::histogram::axis::transform用法的测试程序
  3. Linux使用locate命令查找,Linux如何使用locate命令查找数据(2)
  4. 被除数是负数的话,为啥要加上偏移量?
  5. Rust: tokio,异步代码与运行速度初探
  6. python ip,python-IPy模块
  7. C#winform之自定义按钮形状(初级版)
  8. 即时通讯服务服务器 ejabberd、jabber、jabberd、xmpp简介
  9. int和long long有符号整形 负数比正数多一个
  10. nebula graph调研
  11. vs2010+opencv2.4.9配置========重点说明
  12. 微信小程序 星级评分 (带小数的评分/半星)
  13. 剪切caspase3_Caspase-3活性检测
  14. android 耳机检测,android 检测耳机是否插入方法
  15. No qualifying bean of type xxx found for dependency expected at least 1 bean which qualifies as ...
  16. CorelDRAW钢笔工具抠图教程
  17. Ghost 8.2 +GHOST使用教程(图+文)
  18. 浅谈NB_LOT和LTE CAT M1
  19. 周杰伦新歌《彩虹》mp3 在线试听|下载|歌词 在线播放,周杰伦新歌《彩虹》MV
  20. 2022年全球市场食用香精香料总体规模、主要生产商、主要地区、产品和应用细分研究报告

热门文章

  1. 点分十进制字符串IP和32位int整数互转Java实现
  2. spring boot之maven-wrapper
  3. 【python】代码换行的几种方法
  4. 美容行业如何制定网络营销方案,做好网络品牌推广?
  5. redis+mysql
  6. B3626 跳跃机器人
  7. 创建你的第一个Windows通用应用(UWP)
  8. Mac电脑 gitconfig 文件在哪里
  9. html怎么取消浮动,html css 中浮动的讲解和取消浮动的常见问题
  10. 一次替换多个字符串,批量替换多个字符串