tensor分为头信息区(Tensor)和存储区(Storage)

信息区主要保存着tensor的形状(size)、步长(stride)、数据类型(type)等信息,而真正的数据则保存成连续数组,存储在存储区

因为数据动辄成千上万,因此信息区元素占用内存较少,主要内存占用取决于tensor中元素的数目,即存储区的大小

一般来说,一个tensor有着与之相对应的storage,storage是在data之上封装的接口,便于使用

不同的tensor的头信息一般不同,但是可能使用相同的storage

生成a:

a = t.arange(0,6)
a.storage()

⚠️将这里改成a = t.arange(0,6).float(),用来保证得到的值的类型为FloatTensor

这跟下面遇见的一个问题相关,可以看到下面了解一下,然后再跟着操作

所以你的下面内容的值的类型应该为FloatTensor类型,我的仍是LongTensor,因为我没有改过来

返回:

012345
[torch.LongStorage of size 6]

生成b:

b = a.view(2,3)
b.storage()

返回:

 012345
[torch.LongStorage of size 6]

对比两者内存地址:

#一个对象的id值可以看作她的内存空间
#a,b storage的内存地址一样,即是同一个storage
id(a.storage()) == id(b.storage())

返回:

True

改变某个值查看是否共享内存:

#a改变,b也随之改变,因为他们共享storage,即内存
a[1] = 100
b

返回:

tensor([[  0, 100,   2],[  3,   4,   5]])

生成c:

#c从a的后两个元素取起
c = a[2:]
c.storage()#指向相同

返回:

 01002345
[torch.LongStorage of size 6]

查看其首元素内存地址:

c.data_ptr(), a.data_ptr() #data_ptr返回tensor首元素的内存地址
#从结果可以看出两者的地址相差16
#因为c是从a第二个元素选起的,每个元素占8个字节,因为a的值的类型是int64

返回:

(140707162378192, 140707162378176)

因为查看后a的类型为int64:

a.dtype

返回:

torch.int64

更改c:

c[0] = -100 #a,c也共享内存空间,c[0]的内存地址对应的是a[2]的内存地址
a

返回:

tensor([   0,  100, -100,    3,    4,    5])

使用storage来生成新tensor:

d = t.Tensor(c.storage())#这样a,b,c,d共享同样的内存空间
d[0] = 6666
b

⚠️报错:

RuntimeError: Expected object of data type 6 but got data type 4 for argument #2 'source'

这是因为Tensor期待得到的值的类型是FloatTensor(类型6),而不是其他类型LongTensor(data type 4)

因为如果生成:

dtypea = t.FloatTensor([[1, 2, 3], [4, 5, 6]])
dtypea.storage()

返回:

 1.02.03.04.05.06.0
[torch.FloatStorage of size 6]

再运行就成功了:

d = t.Tensor(dtypea.storage())#这样a,b,c,d共享同样的内存空间
d[0] = 6666
dtypea

返回:

tensor([[6.6660e+03, 2.0000e+00, 3.0000e+00],[4.0000e+00, 5.0000e+00, 6.0000e+00]])

如果使用的是IntTensor(data type 3),也会报错:

RuntimeError: Expected object of data type 6 but got data type 3 for argument #2 'source'

ShortTensor(data type 2),CharTensor(data type 1),ByteTensor(data type 0),DoubleTensor(data type 7)

下面的操作会在将上面的值改成FloatTensor的基础上进行,即在a = t.arange(0,6)后面添加.float(),然后从头执行了一遍

d = t.Tensor(c.storage())#这样a,b,c,d共享同样的内存空间
d[0] = 6666
b

返回:

tensor([[ 6.6660e+03,  1.0000e+02, -1.0000e+02],[ 3.0000e+00,  4.0000e+00,  5.0000e+00]])

判断是否共享内存:

#因此a,b,c,d这4个tensor共享storage
id(a.storage()) ==id(b.storage()) ==id(c.storage()) ==id(d.storage())#返回True

偏移量:

#获取首元素相对于storage地址的偏移量
a.storage_offset(), c.storage_offset(), d.storage_offset()

返回:

(0, 2, 0)

即使使用索引只获得一部分值,指向仍是storage:

#隔两行/列取元素来生成e
e = b[::2,::2]
print(e)
print(e.storage_offset())
id(e.storage()) ==id(a.storage()) #虽然值不相同,但是得到的storage是相同的

返回:

tensor([[6666., -100.]])
0
Out[44]:
True

步长信息:是有层次结构的步长

#获得步长信息
b.stride(), e.stride()

返回:

((3, 1), (6, 2))

查看空间是否连续:

#查看其值的内存空间是否连续
#因为e只取得了storage中的部分值,因此其是不连续的
b.is_contiguous(), e.is_contiguous()

返回:

(True, False)

从上面的操作中我们可以看出绝大多数的操作并不修改tensor的数据,即存储区的内容,只是修改了头信息区的内容

这种做法更节省内存,同时提升了处理速度

但是我们可以看见e的操作导致其不连续,这时候可以调用tensor.contiguous()方法将他们变成连续的数据。该方法是复制数据到新的内存中,不再与原来的数据共享storage,如:

e.contiguous().is_contiguous() #返回True

生成f:

print(e.data_ptr())
f = e.contiguous()
print(f.data_ptr()) #可见为f新分配了内存空间
print(f)
print(f.storage())#内存空间中只有两个值
print(f.size())
print(e.data_ptr()) #e指向的内存没有改变
f.is_contiguous() #这里的f的内存空间是连续的

返回:

140707203003760
140707160267104
tensor([[6666., -100.]])6666.0-100.0
[torch.FloatStorage of size 2]
torch.Size([1, 2])
140707203003760 Out[56]: True

是否为连续内存空间有什么影响?
比如当你想要使用.view()转换tensor的形状时,如果该tensor的内存空间不是连续的则会报错:

k = t.arange(0,6).view(2,3).float().t()#进行转置,转置后的k内存是不连续的
k.is_contiguous()
k.view(-1)

报错:

RuntimeError: invalid argument 2: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view(). at /Users/soumith/mc3build/conda-bld/pytorch_1549593514549/work/aten/src/TH/generic/THTensor.cpp:213

报错的意思也是要求在.view()之前调用.contiguous(),改后为:

k = t.arange(0,6).view(2,3).float().t()#进行转置,转置后的k内存是不连续的
k.is_contiguous()
k.contiguous().view(-1)

成功返回:

tensor([0., 3., 1., 4., 2., 5.])

转载于:https://www.cnblogs.com/wanghui-garcia/p/10623033.html

pytorch torch.Storage学习相关推荐

  1. PyTorch 1.0 中文文档:torch.Storage

    译者:yuange250 torch.Storage 跟绝大部分基于连续存储的数据结构类似,本质上是一个单一数据类型的一维连续数组(array). 每一个 torch.Tensor 都有一个与之相对应 ...

  2. PyTorch源码学习系列 - 1.初识

    本系列文章会优先发布于微信公众号和知乎,欢迎大家关注 微信公众号:小飞怪兽屋 知乎: PyTorch源码学习系列 - 1.初识 - 知乎 (zhihu.com) 目录 本系列的目的 PyTorch是什 ...

  3. PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx

    PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx 在写 PyTorch 代码时,我们会发现在 torch.nn.xxx 和 torch.nn.funct ...

  4. DL框架之PyTorch:深度学习框架PyTorch的简介、安装、使用方法之详细攻略

    DL框架之PyTorch:PyTorch的简介.安装.使用方法之详细攻略 DL框架之PyTorch:深度学习框架PyTorch的简介.安装.使用方法之详细攻略 目录 PyTorch的简介 1.pyto ...

  5. PyTorch入门-深度学习回顾和PyTorch简介

    一.神经网络的复习 1.深度学习 2.神经网络 3.激活函数 4.前向神经网络 5.卷积神经网络 6.循环神经网络 二.用PyTorch构建深度学习模型 深度学习模型框架 TensorFlow ay/ ...

  6. PyTorch | torch.linspace()创建均分数列张量 | torch.linspace()如何使用?| torch.linspace()使用方法 | torch.linspace例子

    公众号[计算机视觉联盟]后台回复[PyTorch]可以获得独家PyTorch学习教程pdf版 通过torch.linspace创建均分数列 张量 步长=(Start - end)/(Steps - 1 ...

  7. PyTorch | torch.full()使用方法 | torch.full()如何使用? torch.full()例子说明 | 通过torch.full创建全相同的张量

    公众号[计算机视觉联盟]后台回复[PyTorch]可以获得独家PyTorch学习教程pdf版 举例子说明torch.full()使用方法: t = torch.full((3,3),10)print( ...

  8. PyTorch | torch.zeros()如何使用?torch.zeros使用方法 | torch.zeros()例子

    公众号[计算机视觉联盟]后台回复[PyTorch]可以获得独家PyTorch学习教程pdf版 还是用实际例子比较明显 out_t = torch.tensor(([1]))t = torch.zero ...

  9. PyTorch | torch.randperm()使用方法

    公众号[计算机视觉联盟]后台回复[PyTorch]可以获得PyTorch学习教程pdf版 返回一个0~n-1的数组,随机打散的 t = torch.randperm(8) 结果: tensor([5, ...

最新文章

  1. 【力扣网练习题】罗马数字转整数
  2. SharePoint 2007 Web Content Management 性能优化系列 前言
  3. 趣学python3(37)-合并所有目录及子目录的文本文件为一个文件
  4. 细学PHP 09 MySql
  5. python struct pack解析_Python struct 详解
  6. LeetCode 6 - ZigZag Conversion
  7. 云智慧获 D 轮数 2500 万美元投资:全力推动智能运维落地
  8. JWT学习(二):Json Web Token JWT的Java使用 (JJWT)
  9. Linux下安装redis5.0.7
  10. 象棋 计算机配置,中国象棋电脑应用规范(五)
  11. 校园市场应该怎样做,看看小米有什么新招式
  12. 以太坊bloom和logs及代码解析
  13. 介质访问控制MAC以及ALOHA协议
  14. 区块链 - 展望2022年元宇宙会呈现哪些趋势?
  15. 为师生负重前行:记校园防疫中的故事
  16. AI模型神预测谁是卡塔尔世界杯冠军
  17. 流畅的python学习笔记
  18. C语言编程,给出三角形三个边的边长,判断是否能构成三角形。
  19. Unity技能编辑器(特效,音效)
  20. 知识创造的组织特征及过程

热门文章

  1. 【PhotoScan教程】Ps集群处理环境部署图文教程
  2. 最新阿里Java后端开发面试题100道(P6-P7)
  3. 水箱建模最小二乘法_幼儿园大班就能背出九九乘法表,和数学好真没什么关系……...
  4. 基于DDTBOX,使用线性支持向量回归(SVR)从ERP数据中解码连续变量
  5. c语言烟花程序视频,如何用c语言编写动态烟花
  6. PlantUML导出大图被截取和乱码
  7. 常用排序算法-----------JAVA实现
  8. Vue 跨页面#锚链接跳转
  9. php gmt文本转时间,PHP 使用gmdate将一个UNIX 时间格式化成 GMT 文本的简单示例
  10. mysql 关联删除_mysql如何删除关联表