文章目录
- 1、张量的数据存储
- 2、张量的连续性:contiguous
- 3、.view() 和 .reshape()
- 4、.permute() 和 .transpose()
- 5、总结
1、张量的数据存储
- 在pytorch中,张量的存储实际上分为两个部分,一部分是张量的头信息,包括张量的shape,stride等。另一部分就是张量数据的实际存储空间,可以使用张量.storage() 方法来得到张量存储的数据,sorage() 是在data之上封装的一个接口。
2、张量的连续性:contiguous
- 我们可以通过张量的is_contiguous()方法来判断张量是否连续。
- is_contiguous直观的解释是Tensor底层一维数组元素的存储顺序与Tensor按行优先一维展开的元素顺序是否一致。
3、.view() 和 .reshape()
-
view() 只能对连续张量进行,其实质是将张量先展开成一维,然后再按照给定的shape进行排列,view()不会创建新的内存空间,我们可以理解为view() 是在原始数据上修改了张量的头文件,所以view() 其实是对张量的浅拷贝(这里把张量数据的存储相当于列表中的列表)
-
reshape() = view() 或者 contiguous() + view(),reshape可以作用于非连续的张量,其本质是先进行contiguous,再执行view。当张量是连续的时候reshape = view,也就是产生的还是浅拷贝,但是如果是不连续的张量,则reshape() = contiguous() + view(),而contiguous是对数据按照其shape进行深拷贝,此时reshape前后的张量不再共享内存中的数据。
4、.permute() 和 .transpose()
-
可以理解为,没有改变张量的结构,只是改变了我们观察张量的角度,比如一个1224的图,转置以后变成2412,整个图片是没有改变的,只是改变了我们观察的角度
-
permute()和transpose() 也是浅拷贝,只改变张量的头元信息,而与原张量共享数据,但是通过这两者操作之后的张量不再满足连续性,因为此时张量在内存中的存储位置是没有变化的,但是张量头文件中的stride,shape发生了变化,使得张量按行展开以后不再与其在内存中的存储顺序一样了。所以这个时候只能先使用contiguous对转置后的数据进行深拷贝,并按照转置后的stride在内存中对数据进行重排。变成连续的,之后才可以使用view()
5、总结
- permute()和transpose()是按照张量的数组坐标进行转置的,可以理解为我们只是换个角度观察张量,再换一种理解,张量中的维度实际上是数据排列的先后顺序,我们换维度,也就是换数据排列的先后顺序。
😄感觉一般用reshape就好了,反正它等于.contiguous()+.view(),省事
参考链接:https://blog.csdn.net/xx_xjm/article/details/123301266