张量的基本操作

一. 张量的基础概念

在学深度学习里,Tensor实际上就是一个多维数组(multidimensional array),是一种最基础的数据结构。

二. 张量常用操作

访问某一个元素(最后一个跳跃访问,每三行访问一个元素,每两列访问一个元素)

image-20241109210857386

构造一个张量:

1
2
import torch
a = torch.ones(3)

使用ndim查看张量的维度:

1
2
t1 = torch.tensor([1,2])
t1.ndim

输出:1

使用shape查看形状

1
2
t1 = torch.tensor([1,2])
t1.shape

由两个形状相同的二维数组创建一个三维的张量

1
2
3
a1 = np.array([[1,2,2],[3,4,4]])
a2 = np.array([[5,6,6],[7,8,8]])
t3 = torch.tensor([a1,a2])

输出:结果是一个三位向量

tensor([[[1, 2, 2],
[3, 4, 4]],
[[5, 6, 6],
[7, 8, 8]]], dtype=torch.int32)

flatten拉平,将任意维度张量转化为一维张量

1
2
t2 = torch.tensor([[1, 2],[3, 4]])
t2.flatten()

输出:

tensor([1, 2, 3, 4])

reshape方法,任意变形

1
2
t1 = torch.tensor([1,2])
t1.reshape(2,1)

输出:

tensor([[1],[2]])

torch.Size([2, 1])

特殊张量创建:****全零张量 .zeros()、全1张量 .ones()、单位矩阵 .eyes()、对角矩阵 .diag(一维张量)

1
2
3
torch.eye(5)
t1 = torch.tensor([1, 2])
torch.diag(t1)

输出:

tensor([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])

tensor([[1, 0],

[0, 2]])

服从0-1均匀分布的张量rand

1
torch.randn(2,3)#2行3列的随机数所构成的张量

输出:

tensor([[-0.8110, -1.1295, -0.2913],
[-1.1786, -0.8882, 0.2433]])

arange/linspace:生成数列

1
2
3
torch.arange(5)
torch.arange(1,5,0.5) #从1到5,每隔0.5取一个数
torch.linspace(1,5,3) #从1取到5,等距取三个数

empty,初始化指定形状矩阵

1
torch.full([2,4],2) #2行4列,数值为2

输出:

tensor([[2, 2, 2, 2],
[2, 2, 2, 2]])

创建指定形状的数组

1
2
torch.full_like(t1,2) #根据t1的形状,填充数值2
torch.randint_like(t2,1,10) #在1到10中随机抽取一些整数,并将其填充进t2的形状中去

张量与其它相关类型(数组、列表)之间转化方法

1
2
3
t1 = torch.tensor([1,2,3,4,5,6,7,8,9,10])
t1.numpy()
t1.tolist()

输出:

array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=int64)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

切片,一小点需要注意

1
t2[[0,2],1] # 第一行和第3行的第2列元素

分块

1
tc = torch.chunk(t2,4,dim=0) 

输出:
(tensor([[0, 1, 2]]),
tensor([[3, 4, 5]]),
tensor([[6, 7, 8]]),
tensor([[ 9, 10, 11]]))

拆分****:split函数

1
2
t2 = torch.arange(12).reshape(4,3)
torch.split(t2,2,0)

输出:

(tensor([[0, 1, 2],
[3, 4, 5]]),
tensor([[ 6, 7, 8],
[ 9, 10, 11]]))

torch.split(t2,[1,3],0)

[1,3]表示“第一块长度为1,第二块长度为3

torch.cat 的用法:多个张量合并在一起,默认按行(dim=0)【记住二维张量dim=0表示行】进行拼接,维度不匹配会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
z = torch.arange(12, dtype=torch.float32).reshape(3,4)
k = torch.tensor([[2,3,4,1],[4,5,6,1],[7,8,9,1]])
h = torch.cat((z,k), dim=0), torch.cat((z,k), dim=1)
print(h)

输出:
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 2., 3., 4., 1.],
[ 4., 5., 6., 1.],
[ 7., 8., 9., 1.]]),
tensor([[ 0., 1., 2., 3., 2., 3., 4., 1.],
[ 4., 5., 6., 7., 4., 5., 6., 1.],
[ 8., 9., 10., 11., 7., 8., 9., 1.]]))

【-1】访问最后一个元素,【1:3】选择第一行和第二行的元素(左闭右开)

张量的维度变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
x = torch.randn(3,4)
输出:
tensor([[ 0.6480, 1.5947, 0.6264, 0.6051],
[ 1.6784, 0.2768, -1.8780, -0.1133],
[-0.6442, 0.8570, 0.1677, 0.2378]])
mask = x.ge(0.5)
输出:
tensor([[ True, True, True, True],
[ True, False, False, False],
[False, True, False, False]])

torch.masked_select(x,mask)
输出:
tensor([0.6480, 1.5947, 0.6264, 0.6051, 1.6784, 0.8570])

删除不必要的维度

1
2
t = torch.zeros(1,1,3,1)
torch.squeeze(t).shape#剔除所有属性为1的维度

输出:

torch.Size([3])

1
2
3
b.squeeze(0).shape #挤压掉第0维
b.squeeze(-1).shape #挤压掉最后一维
b.squeeze(1).shape #挤压掉第一维

unsqueeze手动升维

调用方法1:torch.unsqueeze(t, dim=n)

1
2
3
t = torch.zeros(1,2,1,2)
# 在第0位索引上升高一个维度变成五维
torch.unsqueeze(t,dim=0).shape

输出:

torch.Size([1, 1, 2, 1, 2])

调用方法2:a.unsqueeze(dim=n)

1
2
3
4
# 在0索引前面插入了一个额外的维度
a.unsqueeze(0).shape
# 在末尾插入一个额外的维度,可以理解为像素的属性
a.unsqueeze(-1).shape

expand:broadcasting #只改变理解方式,不增加数据

1
2
b = torch.rand(1,32,1,1)
b.expand(4,32,14,14).shape

输出:

torch.Size([4, 32, 14, 14])

repeat的参数表示重复的次数

1
2
# 4表示对0维重复4次,32表示对1维重复32次
b.repeat(4,32,1,1).shape

输出:

torch.Size([4, 1024, 1, 1])

矩阵转置

1
2
3
a = torch.randn(3,4)
a.shape
a.t()

输出:

torch.Size([4, 3])

维度转换

1
2
3
# transpose实现维度两两交换
a = torch.rand(4,3,32,32)
2 = a.transpose(1,3).contiguous().view(4,3*32*32).view(4,32,32,3).transpose(1,3)

解释:

#transpose包含了要交换的两个维度[b,c,h,w]→[b,w,h,c]

#数据的维度顺序必须与存储顺序一致,用.contiguous把数据变成连续的

#.view(4,33232) [b,whc]

#.view(4,3,32,32) [b,w,h,c]

#.transpose(1,3) [b,c,g,w]

permute维度转换

1
2
b = torch.rand(4,3,28,32) 
b.permute(0,2,3,1).shape

输出:

torch.Size([4, 28, 32, 3])


张量的基本操作
http://example.com/2024/11/09/张量的基本操作/
作者
yzcabe
发布于
2024年11月9日
许可协议