深度学习笔记(二)——对Tensor创建、修改、索引操作的整理

Tensor的创建、修改、索引操作

Tensor概述

对Tensor的操作很多,从接口角度来划分,可以分为两类:
(1)torch.function;(2)tensor.function
这些操作对大部分Tensor都是等价的,如:torch.add(x,y)与x.add(y)等价。
如果从修改方式的角度来划分,可以分为以下两类。
(1)不修改自身数据,如x.add(y),x的数据不变,返回一个新的Tensor。
(2)修改自身数据,如x.add_(y)(运行符带下划线后缀),运算结果存在x中,x被修改。

import torch
x = torch.tensor([1, 2])
y = torch.tensor([3, 4])
z = x.add(y)
print(z)
print(x)
x.add_(y)
print(x)

输出结果

深度学习笔记(二)——对Tensor创建、修改、索引操作的整理

创建Tensor

函数功能Tensor(*size)直接从参数构造一个的张量,支持List,Numpy数组eye(row, column)创建指定行数,列数的二维单位Tensorlinspace(start, end, steps)从start到end,均匀切分成steps份logspace(start, end steps)从
1 0 s t a r t 10^{start}1 0 s t a r t 1 0 e n d 10^{end}1 0 e n d

,均分分成steps份rand/randn(*size)生成
[ 0 , 1 ) [0,1)[0 ,1 )

均匀分布/标准正态分布数据ones(size)返回指定shape的张量,元素初始为1zeros(size)返回指定shape的张量,元素初始为0ones_like(t)返回与T的shape相同的张量,且元素初始为1zeros_like(t)返回与T的shape相同的张量,且元素初始为0arange(start, end, step)在区间
[ s t a r t , e n d ) [start, end)[s t a r t ,e n d )

上一间隔step生成一个序列张量from_Numpy(ndarry)从ndarry创建一个Tensor

这里不再给出示例,只说明有关torch.Tensor与torch.tensor的几点区别:
(1)torch.Tensor是torch.empty和torch.tensor之间的一种混合,但是当传入数据时,torch.Tensor使用全局默认dtype(FloatTensor),而torch.tensor是从数据中推断数据类型。
(2)torch.tensor(1)返回一个固定值1,而torch.Tensor(1)返回一个大小为1的张量,它是随机初始化的值。

修改Tensor形状

函数说明size()返回张量的shape属性值,与函数shape(0.4版新增)等价numel(input)计算Tensor元素个数view(*shape)修改Tensor的shape,与reshape类似,但view返回的对象与源Tensor共享内存,修改一个,另一个同时修改。Reshape将生成新的Tensor,而且不要求源Tensor是连续的。view(-1)展平数组resize类似于view,但在size超出时会重新分配内存空间item若Tensor为单元素,则返回python的标量unsqueeze在指定维度增加一个”1″squeeze在指定维度压缩一个”1″

这里说明两个问题

torch.view与torch.reshape的异同

(1)reshape()可以有torch.reshape(),也可由torch.Tensor.reshape()调用。但view()只可由torch.Tensor.view()来调用。
(2)对于一个将要被view的Tensor,新的size必须与原来的size与stride兼容。否则在view之前必须调用contiguous()方法。
(3)同样也是返回与input数据量相同,但形状不同的Tensor。若满足view的条件,则不会copy,若不满足,则会copy。
(4)如果你只想重塑张量,请使用torch.reshape。如果你还关注内存使用情况并希望确保两个张量共享相同的数据,请使用torch.view。

unsqueeze函数的参数

import torch
x = torch.randn(2, 3)
y = x.view(-1)
z1 = torch.unsqueeze(y, 0)
z2 = torch.unsqueeze(y, 1)
z3 = torch.unsqueeze(y, -1)
z4 = torch.unsqueeze(y, -2)

输出结果

深度学习笔记(二)——对Tensor创建、修改、索引操作的整理
经过实验,发现z1与z4等价(都是1 _6),z2与z3等价(都是6_1)。这也不难记忆,因为根据函数使用规则,第二个参数只能取[-2, 1]四个整数值,按照大小排列:-2,-1,0,1,依次对应1 _6、6_1、1 _6、6_1,交替出现。

索引操作

Tensor的索引操作与Numpy类似,一般情况下索引结果与源数据共享内存。从Tensor获取元素除了可以通过索引,也可以借助于一些函数。

函数说明index_select(input,dim, index)在指定维度上选择一些行或列nonzero(input)获取非0元素的下标masked_select(input, mask)使用二元值进行选择gather(input,dim,index)在指定维度上选择数据,输出的形状与index(index的类型必须是LongTensor类型的)一致scatter_(input,dim, index, src)为gather的反操作,根据指定索引补充数据

import torch
设置一个随机种子
torch.manual_seed(100)
生成一个形状为2*3的矩阵
x = torch.randn(2, 3)
根据索引获取第1行,所有数据
x[0, :]
获取最后一列数据
x[:, -1]
生成是否大于0的Byter张量
mask = x> 0
获取大于0的值
torch.masked_select(x, mask)
获取非0下标,即行,列索引
torch.nonzero(mask)
获取指定索引对应的值
index = torch.LongTensor([[0, 1, 1]])
torch.gather(x, 0, index)
index = torch.LongTensor([[0, 1, 1], [1, 1, 1]])
a = torch.gather(x, 1, index)
把a的值返回到一个2*3的0矩阵中
z = torch.zeros(2, 3)
z.scatter_(1, index, a)

因为时间原因😅,这里没能详细介绍有关1:index_select、gather函数及其中index参数的用法(也是花了点时间才想明白😅),这里先强调一点:index参数要求是torch.LongTensor类型的。

参考文献

吴茂贵,郁明敏,杨本法,李涛,张粤磊. Python深度学习(基于Pytorch). 北京:机械工业出版社,2019.

Original: https://blog.csdn.net/weixin_45813658/article/details/121659537
Author: 小白成长之旅
Title: 深度学习笔记(二)——对Tensor创建、修改、索引操作的整理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/763061/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球