当前位置:   article > 正文

Pytorch之contiguous函数_pytorch contiguous()

pytorch contiguous()

转载自:https://zhuanlan.zhihu.com/p/64376950,本文只做个人记录学习使用,版权归原作者所有。

contiguous()->Tensor返回一个内存连续的有相同数据的tensor,如果原tensor内存连续,则返回原tensor。

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

  1. x=torch.Tensor(2,3)
  2. y=x.permute(1,0)
  3. y.view(-1) #报错,view使用前需要调用contiguous()函数
  4. y=x.permute(1,0).contiguous()
  5. y.view(-1)

具体原因有两种说法:

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

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

contiguous函数分析,参考CSDN博客

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

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

举个例子,在使用transpose()进行转置操作时,pytorch并不会创建新的转置后的tensor,而是修改了tensor中的一些属性(元数据),使得此时的offset和stride是与转置tensor相对应的,而转置的tensor和原tensor的内存是共享的!为了证明这一点,请看下面的代码:

  1. import torch
  2. x=torch.randn(3,2)
  3. print(x)
  4. y=x.transpose(0,1)
  5. print(y)
  6. x[0,0]=233
  7. print(x)
  8. print(y)

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

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

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

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

RunTimeError: input is not contiguous

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/350738
推荐阅读
相关标签
  

闽ICP备14008679号