Tensor存储结构如下,

如图所示,实际上很可能多个信息区对应于同一个存储区,也就是上一节我们说到的,初始化或者普通索引时经常会有这种情况。

一、几种共享内存的情况

view

a = t.arange(0,6)
print(a.storage())
b = a.view(2,3)
print(b.storage())
print(id(a.storage())==id(b.storage()))
a[1] = 10
print(b)

上面代码,我们通过.storage()可以查询到Tensor所对应的storage地址,可以看到view虽然不是inplace的,但也仅仅是更改了对同一片内存的检索方式而已,并没有开辟新的内存:

 0.0
1.0
2.0
3.0
4.0
5.0
[torch.FloatStorage of size 6]
0.0
1.0
2.0
3.0
4.0
5.0
[torch.FloatStorage of size 6]
True 0 10 2
3 4 5
[torch.FloatTensor of size 2x3]

简单索引

注意,id(a.storage())==id(c.storage()) != id(a[2])==id(a[0])==id(c[0]),id(a)!=id(c)

c = a[2:]
print(c.storage()) # c所属的storage也在这里
print(id(a[2]), id(a[0]),id(c[0])) # 指向了同一处
print(id(a),id(c))
print(id(a.storage()),id(c.storage()))
 0.0
10.0
2.0
3.0
4.0
5.0
[torch.FloatStorage of size 6]
2443616787576 2443616787576 2443616787576
2443617946696 2443591634888
2443617823496 2443617823496

通过Tensor初始化Tensor

d = t.Tensor(c.storage())
d[0] = 20
print(a)
print(id(a.storage())==id(b.storage())==id(c.storage())==id(d.storage()))
 20
10
2
3
4
5
[torch.FloatTensor of size 6] True

二、内存检索方式查看

storage_offset():偏移量
stride():步长,注意下面的代码,步长比我们通常理解的步长稍微麻烦一点,是有层次结构的步长

print(a.storage_offset(),b.storage_offset(),c.storage_offset(),d.storage_offset())
e = b[::2,::2]
print(id(b.storage())==id(e.storage()))
print(b.stride(),e.stride())
print(e.is_contiguous())
f = e.contiguous() # 对于内存不连续的张量,复制数据到新的连续内存中
print(id(f.storage())==id(e.storage()))
print(e.is_contiguous())
print(f.is_contiguous())
g = f.contiguous() # 对于内存连续的张量,这个操作什么都没做
print(id(f.storage())==id(g.storage()))

高级检索一般不共享stroage,这就是因为普通索引可以通过修改offset、stride、size实现,二高级检索出的结果坐标更加混乱,不方便这样修改,需要开辟新的内存进行存储。

三、其他有关Tensor

持久化

t.save和t.load,由于torch的为单独Tensor指定设备的特性,实际保存时会保存设备信息,但是load是通过特定参数可以加载到其他设备,详情help(torch.load),其他的同numpy类似

向量化计算

Tensor天生支持广播和矩阵运算,包含numpy等其他库在内,其矩阵计算效率远高于python内置的for循环,能少用for就少用,换句话说python的for循环实现的效率很低。

辅助功能

设置展示位数:t.set_printoptions(precision=n)

In [13]: a = t.randn(2,3)

In [14]: a
Out[14]:

1.1564  0.5561 -0.2968
-1.0205  0.8023  0.1582
[torch.FloatTensor of size 2x3]

In [15]: t.set_printoptions(precision=10)

In [16]: a
Out[16]:

1.1564352512 0.5561078787 -0.2968128324
-1.0205242634 0.8023245335 0.1582107395
[torch.FloatTensor of size 2x3]

out参数:

很多torch函数有out参数,这主要是因为torch没有tf.cast()这类的类型转换函数,也少有dtype参数指定输出类型,所以需要事先建立一个输出Tensor为LongTensor、IntTensor等等,再由out导入,如下:

In [3]: a = t.arange(0, 20000000)
In [4]: print(a[-1],a[-2])
16777216.0 16777216.0

可以看到溢出了数字,如果这样处理,

In [5]: b = t.LongTensor()
In [6]: b = t.arange(0,20000000)
In [7]: b[-2]
Out[7]: 16777216.0

还是不行,只能这样,

In [9]: b = t.LongTensor()

In [10]: t.arange(0,20000000,out=b)
Out[10]:

0.0000e+00
 1.0000e+00
 2.0000e+00
     ⋮
 2.0000e+07
 2.0000e+07
 2.0000e+07
[torch.LongTensor of size 20000000]

In [11]: b[-2]
Out[11]: 19999998

In [12]: b[-1]
Out[12]: 19999999

『PyTorch』第五弹_深入理解Tensor对象_下:从内存看Tensor的更多相关文章

  1. 『PyTorch』第五弹_深入理解autograd_下:函数扩展&高阶导数

    一.封装新的PyTorch函数 继承Function类 forward:输入Variable->中间计算Tensor->输出Variable backward:均使用Variable 线性 ...

  2. 『PyTorch』第五弹_深入理解autograd_上:Variable属性方法

    在PyTorch中计算图的特点可总结如下: autograd根据用户对variable的操作构建其计算图.对变量的操作抽象为Function. 对于那些不是任何函数(Function)的输出,由用户创 ...

  3. 『PyTorch』第五弹_深入理解autograd_中:Variable梯度探究

    查看非叶节点梯度的两种方法 在反向传播过程中非叶子节点的导数计算完之后即被清空.若想查看这些变量的梯度,有两种方法: 使用autograd.grad函数 使用hook autograd.grad和ho ...

  4. 『PyTorch』第五弹_深入理解Tensor对象_中下:数学计算以及numpy比较_&_广播原理简介

    一.简单数学操作 1.逐元素操作 t.clamp(a,min=2,max=4)近似于tf.clip_by_value(A, min, max),修剪值域. a = t.arange(0,6).view ...

  5. 『PyTorch』第五弹_深入理解Tensor对象_中上:索引

    一.普通索引 示例 a = t.Tensor(4,5) print(a) print(a[0:1,:2]) print(a[0,:2]) # 注意和前一种索引出来的值相同,shape不同 print( ...

  6. 『PyTorch』第五弹_深入理解Tensor对象_上:初始化以及尺寸调整

    一.创建Tensor 特殊方法: t.arange(1,6,2)t.linspace(1,10,3)t.randn(2,3) # 标准分布,*size t.randperm(5) # 随机排序,从0到 ...

  7. 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

    『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import t ...

  8. 『PyTorch』第三弹重置_Variable对象

    『PyTorch』第三弹_自动求导 torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现 Varibale包含三个属性: data ...

  9. 『PyTorch』第十弹_循环神经网络

    RNN基础: 『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练 TensorFlow RNN: 『TensotFlow』基础RNN网络分类问题 『TensotFlow』基础R ...

随机推荐

  1. ADG日志传输方式参数log_archive_dest_n详解

    主库的日志发送是由log_archive_dest_n参数设置(注意:同时还有一个和它相对应的开关参数log_archive_dest_state_n,用于指定该参数是否有效),下面简单介绍下该参数各 ...

  2. web前端,多语言切换,data-localize,

    demo: 链接:https://pan.baidu.com/s/1zhFHTv4P_epbBfpiggVDXg 提取码:aqts 要想有效果,必须发布在服务器上,可以在IIS上测试. 我只用到了中文 ...

  3. 【Python基础】zip函数的使用

    zip函数的使用 描述 zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表. 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同, ...

  4. java框架之SpringBoot(6)-Restful风格的CRUD示例

    准备 环境 IDE:Idea SpringBoot版本:1.5.19 UI:BootStrap 4 模板引擎:thymeleaf 3 效果:Restful 风格 CRUD 功能的 Demo 依赖 &l ...

  5. 非CI执行Allure2 trends空白问题

    问题描述 未使用CI工具集成Aluure运行测试用例并生成Allure报告,多次执行后,trends是空白的,未展示出期望的趋势图 问题原因非CI工具,是通过命令 allure serve 展示报告 ...

  6. 深入理解Java虚拟机6-chap8-9-斗者3星

    一.虚拟机字节码执行引擎 1.虚拟机执行引擎由自己实现,所以可以自行制定指令集与执行引擎的体系结构,并且可以执行那些不被硬件直接支持的指令集格式. 2.执行引擎 编译执行:通过JIT编译器产生本地代码 ...

  7. 51.webpack vue-cli创建项目

    在上两篇博文中已经安装了node.js.webpack.vue-cli,安装的版本为: 今天通过这篇博文创建项目. 1.选择路径 首先通过命令行进入想要创建项目的路径,例如: 通过e:命令进入盘幅,再 ...

  8. 关于绕过域名(ip)校验的一些小知识

    这篇文章最开始只是想写一个关于绕过referer的方法,写着写着发现和ssrf以及url跳转的一些手法类似,于是把这两种也加上了 对referer做校验一般是对csrf进行防范的手段之一,但是很多时候 ...

  9. CSS 字体效果

    text-shadow还没有出现时,大家在网页设计中阴影一般都是用photoshop做成图片,现在有了css3可以直接使用text-shadow属性来指定阴影.这个属性可以有两个作用,产生阴影和模糊主 ...

  10. DoubleDQN---tensorflow实现

    完整代码:https://github.com/zle1992/Reinforcement_Learning_Game 开山之作: <Playing Atari with Deep Reinfo ...