深度学习笔记(二)——对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(*size)直接从参数构造一个的张量,支持List,Numpy数组
eye(row, column)创建指定行数,列数的二维单位Tensor
linspace(start, end, steps)从start到end,均匀切分成steps份
logspace(start, end steps) 1 0 s t a r t 10^{start} 10start 1 0 e n d 10^{end} 10end,均分分成steps份
rand/randn(*size)生成 [ 0 , 1 ) [0,1) [0,1)均匀分布/标准正态分布数据
ones(*size)返回指定shape的张量,元素初始为1
zeros(*size)返回指定shape的张量,元素初始为0
ones_like(t)返回与T的shape相同的张量,且元素初始为1
zeros_like(t)返回与T的shape相同的张量,且元素初始为0
arange(start, end, step)在区间 [ s t a r t , e n d ) [start, end) [start,end)上一间隔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)

输出结果
在这里插入图片描述
经过实验,发现z1与z4等价(都是16),z2与z3等价(都是61)。这也不难记忆,因为根据函数使用规则,第二个参数只能取[-2, 1]四个整数值,按照大小排列:-2,-1,0,1,依次对应16、61、16、61,交替出现。

索引操作

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.


  1. 后面会有单独一篇文章对索引操作函数及其规则做出详细介绍,同时上述程序运行结果也会在该文章中给出。 ↩︎

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值