深度学习开发框架PyTorch(2)-- Tensor

Tensor(张量)是神经网络框架中重要的基础数据类型,可以简单理解为N维数组的容器对象。Tensor之间的通过运算进行连接,从而形成计算图。几乎所有的深度学习框架都是基于张量和计算图的,PyTorch也不例外。

一、创建Tensor

在PyTorch里创建Tensor的方法很多。

方法名 说明
Tensor(*sizes) 基础构造函数
ones(*sizes) 全1的Tensor
zeros(*sizes) 全0的Tensor
rand/randn(*sizes) 均匀/标准分布
eye(*sizes) 对角线为1,其他为0
arange(s,e,sep) 从s到e,步长为step
linspace(s,e,count) 从s到e,均匀切分成count份
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import torch as t

# 使用基础构造函数
a = t.Tensor(2,3)
b = t.Tensor([[1,2,3], [4,5,6]])
print(a)
print(b)
print(b.shape)
print(b.numel()) # b中元素总个数

# 使用全1构造函数
c = t.ones(3,3)
print(c)

# 使用全0构造函数
d = t.zeros(3,3)
print(d)

# 用均匀分布、标准分布构造函数
e = t.randn(3,2)
f = t.randn(3,2)
print(e)
print(f)

# 使用单位矩阵构造函数
g = t.eye(3,4)
print(g)

# 用步长和区间构造函数
h = t.arange(1, 6, 2)
print(h)

# 用个数和区间构造函数
i = t.linspace(1, 6, 2)
print(i)

二、常用Tensor操作

1、改变形状

通过tensor.view方法可以调整tensor的形状,但是必须保证调整前后元素总数一致。

1
2
3
4
5
import torch as t

a = t.arange(0, 6)
a.view(-1, 2)
print(a)

通过tensor.resize_方法也可以调整tensor的形状,与view不同的是它可以修改tensor的元素总数。

1
2
3
4
5
6
7
8
import torch as t

a = t.arange(0, 6)
a.resize_(2, 3)
print(a)

a.resize_(1, 10)
print(a)

2、分割与合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import torch as t

a = t.arange(0, 9).view(3, 3)
b = t.arange(0, 9).view(3, 3)

# 按照横向分割成3个
print(t.chunk(a, 3, 0))
# 按照纵向分割成3个
print(t.chunk(a, 3, 1))

# 横向堆叠
print(t.cat([a, b], 0))
# 纵向堆叠
print(t.cat([a, b], 1))

3、逐元素操作

这部分操作会对tensor的每一个元素进行操作,此类操作的输入和输出形状一致。

方法名 说明
add/sub/mul/div 加/减/乘/除
abs/reciprocal/neg 绝对值/倒数/相反数
sqrt/pow/fmod 平方根/求幂/求余
cos/sin/tan/acos/asin/atan 三角函数
ceil/round/floor/trunc/frac 上取整/四舍五入/下取整/只保留整数部分/只保留小数部分
clamp(input,min,max) 超过min和max的部分截断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import torch as t

a = t.arange(0, 6).view(2, 3).float()

# 算术运算
print(t.add(a, 2))
print(t.sub(a, 2))
print(t.mul(a, 2))
print(t.div(a, 2))

print(t.abs(a))
print(t.reciprocal(a))
print(t.neg(a))

print(t.pow(a, 2))
print(t.sqrt(a))
print(t.fmod(a, 3))

# 三角函数
print(t.cos(a))
print(t.sin(a))
print(t.tan(a))
print(t.acos(a))
print(t.asin(a))
print(t.atan(a))

# 取整运算
print(t.ceil(a))
print(t.round(a))
print(t.floor(a))
print(t.trunc(a))

# 截断
print(t.clamp(a, 2, 4))

4、统计运算

这部分操作会让输出形状小于输入形状,并可以沿着某一维度进行制定操作。

方法名 说明
max/min/mean/sum/median/mode 最大/最小/均值/求和/中位数/众数
norm 范数
std/var 标准差/方差
cumsum/cumprod 累加和/累乘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import torch as t

a = t.arange(0, 9).view(3, 3).float()

print(a)
print(a.max()) # 最大值
print(a.min()) # 最小值
print(a.mean()) # 均值
print(a.mean(0)) # 列均值
print(a.sum(0)) # 列求和
print(a.sum(1)) # 行求和
print(a.median(0)) # 列中位数
print(a.mode(0)) # 列众数

print(a.norm(2)) # a的n阶范数

print(a.std()) # 标准差
print(a.var()) # 方差

print(a.cumsum(0)) # 累加和
print(a.cumprod(0)) # 累乘

5、比较运算

方法名 说明
gt/lt/ge/le/eq/ne 大于/小于/大于等于/小于等于/等于/不等
topk 最大的k个数
sort 排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import torch as t

a = t.arange(0, 9).view(3, 3).float()

print(a.gt(3))
print(a.eq(3))
print(a.ne(3))

print(a.topk(1, 0)[0]) # 纵向最大的1个
print(a.topk(1, 1)[0]) # 横向最大的1个
print(t.topk(a, 1, 1)[0]) # 横向最大的1个

print(a.sort(0, descending=False)[1]) # descending控制升降
print(a.sort(1, descending=True)[1])

6、线性代数

方法名 说明
diag 矩阵的对角线元素
trace 矩阵的对角线元素之和(矩阵的迹)
triu/tril 矩阵的上三角元素/下三角元素
t 矩阵转置
inverse 求逆矩阵
eig 求方阵的特征值和特征向量
svd 奇异值分解
dot 两个张量的内积
mm 两个矩阵的乘法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import torch as t

a = t.arange(1, 10).view(3, 3).float()
print(a)

# 对角线元素
print(t.diag(a))
# 对角线元素之和
print(t.trace(a))

# 矩阵上三角元素
print(t.triu(a))
# 矩阵下三角元素
print(t.tril(a))

# 转置,contiguous()使存储空间连续
print(t.t(a).contiguous())
# 求逆矩阵
print(t.inverse(a))
# 求方阵的特征值和特征向量
print(t.eig(a, eigenvectors=True))
# 奇异值分解
print(t.svd(a))

# 两个张量的点积
print(t.dot(t.Tensor([2, 3]), t.Tensor([2, 1])))
# 两个矩阵的乘法
c = t.randn(3, 3)
d = t.arange(0, 12).view(3, 4).float()
print(t.mm(c, d))

三、Tensor与NumPy的转换

Tensor和NumPy数组之间具有很高的相似性,彼此之间的互操作也非常简单高效。

1、从NumPy转Tensor

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
import torch as t

a = np.ones([2, 3])
# 方法一
b1 = t.from_numpy(a)
print(type(b1))

# 方法二
b2 = t.Tensor(a)
print(type(b2))

2、从Tensor转NumPy

1
2
3
4
5
6
import numpy as np
import torch as t

b = t.Tensor([2, 3])
a = b.numpy()
print(type(a))

四、Tensor的持久化

1、使用CPU模式

1
2
3
4
5
6
7
8
9
import torch as t

a = t.Tensor([2, 3])
# 保存
t.save(a, 'a.pth')

# 加载
b = t.load('a.pth')
print(b)

2、使用GPU模式

在保存和加载过程中可以制定具体使用哪个设备。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch as t

a = t.Tensor([2, 3])

if t.cuda.is_available():
a = a.cuda(0) # 将a转为GPU0上的tensor
# 保存
t.save(a, 'a.pth')

# 加载为b, b加载进GPU0(因为保存时候tensor就在GPU0上)
b = t.load('a.pth')
# 加载为c, 指定新位置
c = t.load('a.pth', map_location={'cuda:1':'cuda:0'})

print(b)
print(c)
0%