Pytorch中的contiguous理解

最近在使用Pytorch搭建网络的时候,遇到一个错误,特来此记录一下,给路过的朋友设置踩坑预警。

报错信息

RuntimeError: input is not contiguous
按照常规操作,谷歌翻译搞起,得到结论:
RuntimeError:输入不连续
看到翻译结果,我…一脸懵,输入不连续是什么鬼。为了省时间,还是选择冲浪Debug。

报错原因

先补充一些基础知识:
我们知道一个张量tensor有shape和stride这些属性,那么这些属性之间的区别和联系是怎样的?以二维矩阵为例,shape = [row, column]是指矩阵有几行和列,stride = [stride1, stride2]分别是指从当前行起始位置遍历到矩阵下一行起始位置需要跳过几个元素,到下一列需要跳过几个元素。

摸索了一会儿,发现原因:
在pytorch中,只有很少几个操作[ narrow(), transpose(), view(), expand() ]是不改变tensor的内容本身,而只是重新定义下标与元素的对应关系的。即,这些操作并没有进行数据拷贝来改变数据,只是改变了原来数据中索引与值的对应关系,从而达到改变张量形状或形式的目的。
比如:

import torch

a = torch.randn(2, 3) # 随机定义一个2*3矩阵
a # 打印查看a
tensor([[-0.0861,  1.2402, -0.0422],
        [-0.5381, -1.2654, -0.2331]])
b = a.transpose(0, 1) # 对a进行转置,并赋值给b
b # 打印查看b
tensor([[-0.0861, -0.5381],
        [ 1.2402, -1.2654],
        [-0.0422, -0.2331]])
a[0, 0] = 10 # 修改a第一行第一列的元素
a # 打印查看a
tensor([[10.0000,  1.2402, -0.0422],
        [-0.5381, -1.2654, -0.2331]])
b # 打印查看b
tensor([[10.0000, -0.5381],
        [ 1.2402, -1.2654],
        [-0.0422, -0.2331]])

我们发现,修改矩阵a,矩阵b对应的元素也发生了同样的变化。这说明a和b在系统中是共享内存的。也就是说,经过transpose()方法操作后得到的tensor,它内部数据和transpose前是一样的,但是里边的布局方式发生了变化,transpose会改变a的stride,使得数据分块存储,变得不连续。但是很多方法需要处理的是连续的数据,比如view()。所以,这就有contiguous()的用武之地了。

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

当调用contiguous()时,会强制拷贝一份tensor,让它的布局和原来的数据一样。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值