> 技术文档 > 李沐深度学习-2.3线性代数

李沐深度学习-2.3线性代数


2.3.1. 标量

import torchx = torch.tensor(3.0)y = torch.tensor(2.0)x + y, x * y, x / y, x**y#(tensor(5.), tensor(6.), tensor(1.5000), tensor(9.))

2.3.2. 向量

x = torch.arange(4)x#tensor([0, 1, 2, 3])
x[3]#通过下标访问#tensor(3)len(x)#4x.shape#torch.Size([4])

2.3.3. 矩阵

A = torch.arange(20).reshape(5, 4)Atensor([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]])
A.Ttensor([[ 0, 4, 8, 12, 16], [ 1, 5, 9, 13, 17], [ 2, 6, 10, 14, 18], [ 3, 7, 11, 15, 19]])

对称矩阵

B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])Btensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])B == B.Ttensor([[True, True, True], [True, True, True], [True, True, True]])

2.3.4. 张量

X = torch.arange(24).reshape(2, 3, 4)Xtensor([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]])

2.3.5. 张量算法的基本性质

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)B = A.clone() # 通过分配新内存,将A的一个副本分配给BA, A + B(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), tensor([[ 0., 2., 4., 6.], [ 8., 10., 12., 14.], [16., 18., 20., 22.], [24., 26., 28., 30.], [32., 34., 36., 38.]]))
A*B#对应位置元素相乘tensor([[ 0., 1., 4., 9.], [ 16., 25., 36., 49.], [ 64., 81., 100., 121.], [144., 169., 196., 225.], [256., 289., 324., 361.]])
#将张量乘以或加上一个标量不会改变张量的形状,其中张量的每个元素都将与标量相加或相乘a = 2X = torch.arange(24).reshape(2, 3, 4)a + X, (a * X).shape(tensor([[[ 2, 3, 4, 5], [ 6, 7, 8, 9], [10, 11, 12, 13]], [[14, 15, 16, 17], [18, 19, 20, 21], [22, 23, 24, 25]]]), torch.Size([2, 3, 4]))

2.3.6. 降维

# 降维x = torch.arange(4, dtype=torch.float32)x, x.sum()
(tensor([0., 1., 2., 3.]), tensor(6.))
A,A.shape, A.sum(),A.sum().shape
(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), torch.Size([5, 4]), tensor(190.), torch.Size([]))
A_sum_axis0 = A.sum(axis=0)#axis=0表示只保留所有列(按行降维)A_sum_axis0, A_sum_axis0.shape
(tensor([40., 45., 50., 55.]), torch.Size([4]))
B_sum_axis0 = B.sum(axis=1)#axis=1表示只保留所有行(按列降维)B,B_sum_axis0, B_sum_axis0.shape
(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), tensor([ 6., 22., 38., 54., 70.]), torch.Size([5]))
A.sum(axis=[0, 1]) # 结果和A.sum()相同
tensor(190.)
A.mean(), A.sum() / A.numel()# A.mean()表示求平均值,等价于A.sum() / A.numel()
(tensor(9.5000), tensor(9.5000))
A.mean(axis=0), A.sum(axis=0) / A.shape[0]
(tensor([ 8., 9., 10., 11.]), tensor([ 8., 9., 10., 11.]))

2.3.6.1. 非降维求和

sum_A = A.sum(axis=1, keepdims=True)#keepdims=True表示不去掉维度,而是降为1A,sum_A
(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), tensor([[ 6.], [22.], [38.], [54.], [70.]]))
A / sum_A#广播
tensor([[0.0000, 0.1667, 0.3333, 0.5000], [0.1818, 0.2273, 0.2727, 0.3182], [0.2105, 0.2368, 0.2632, 0.2895], [0.2222, 0.2407, 0.2593, 0.2778], [0.2286, 0.2429, 0.2571, 0.2714]])
A,A.cumsum(axis=0)#沿某个轴计算A元素的累积总和而不降低维度
(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), tensor([[ 0., 1., 2., 3.], [ 4., 6., 8., 10.], [12., 15., 18., 21.], [24., 28., 32., 36.], [40., 45., 50., 55.]]))

2.3.7. 点积(Dot Product)

y = torch.ones(4, dtype = torch.float32)x, y, torch.dot(x, y)#点积-----相同位置元素相乘后相加
(tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.))
# 可以通过执行按元素乘法,然后进行求和来表示两个向量的点积torch.sum(x * y)
tensor(6.)

2.3.8. 矩阵-向量积

# 使用张量表示矩阵-向量积,我们使用mv函数# 每一行乘以向量A,x,A.shape, x.shape, torch.mv(A, x)
(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), tensor([0., 1., 2., 3.]), torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.]))

2.3.9. 矩阵-矩阵乘法

# mm表示矩阵乘法B = torch.ones(4, 3)A,B,torch.mm(A, B)
(tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [12., 13., 14., 15.], [16., 17., 18., 19.]]), tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]), tensor([[ 6., 6., 6.], [22., 22., 22.], [38., 38., 38.], [54., 54., 54.], [70., 70., 70.]]))

2.3.10. 范数

# 计算L2范数u = torch.tensor([3.0, -4.0])torch.norm(u)
tensor(5.)
# 计算L1范数---为向量元素的绝对值之和torch.abs(u).sum()
tensor(7.)
# Frobenius范数-----是矩阵所有元素的平方和的平方根torch.norm(torch.ones((4, 9)))
tensor(6.)
a=torch.ones((2,5,4))a
tensor([[[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]], [[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]]])
a.sum(),a.sum(axis=0),a.sum(axis=1),a.sum(axis=2),a.sum(axis=0,keepdims=True)
(tensor(40.), tensor([[2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.]]), tensor([[5., 5., 5., 5.], [5., 5., 5., 5.]]), tensor([[4., 4., 4., 4., 4.], [4., 4., 4., 4., 4.]]), tensor([[[2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.]]]))