3.线性代数
(1)向量维数和张量维数的区别:
(2)普通矩阵乘法:
要求左矩阵的列数等于右矩阵的行数
import torch
# 创建两个矩阵
A = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
B = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)
# 使用 torch.matmul() 进行矩阵乘法
result1 = torch.matmul(A, B)
print("使用 torch.matmul() 的结果:")
print(result1)
# 使用 @ 运算符进行矩阵乘法
result2 = A @ B
print("使用 @ 运算符的结果:")
print(result2)
>>> B = torch.ones(4, 3)
>>> torch.mm(A,B)
tensor([[ 6., 6., 6.],
[22., 22., 22.],
[38., 38., 38.],
[54., 54., 54.],
[70., 70., 70.]])
>>> B
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
>>> A
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
-
torch.mm
只能处理二维张量的矩阵乘法。 -
torch.matmul
更加灵活,它可以处理多种情况,包括二维矩阵乘法、批量矩阵乘法等。例如,当输入是三维张量时,torch.matmul
会按照批量矩阵乘法的规则进行计算,而torch.mm
则会报错。
(3)逐元素乘法(Hadamard 积)
要求两个矩阵的形状完全相同,对应位置的元素相乘.
用*号,就像加法一样,加法也是逐元素加法
import torch
# 创建两个矩阵
A = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
B = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)
# 逐元素乘法
result = A * B
print("逐元素乘法的结果:")
print(result)
(4)范数:
一个向量空间 V 上的范数是一个函数 ∥⋅∥:V→R,它满足以下性质:
-
非负性:对于所有 v∈V,有 ∥v∥≥0,且 ∥v∥=0 当且仅当 v=0。
-
齐次性:对于所有 v∈V 和所有标量 c,有 ∥cv∥=∣c∣∥v∥。
-
三角不等式:对于所有 u,v∈V,有 ∥u+v∥≤∥u∥+∥v∥。
(5)降维:
# 创建一个二维张量
A = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
A
tensor([[1., 2.],
[3., 4.]])
# 沿着第 0 维(列方向,垂直方向)求和
sum_along_dim0 = torch.sum(A, dim=0)
print("沿着第 0 维求和的结果:", sum_along_dim0)
#沿着第 0 维求和的结果: tensor([4., 6.])
# 沿着第 1 维(行方向,水平方向)求和
sum_along_dim1 = torch.sum(A, dim=1)
print("沿着第 1 维求和的结果:", sum_along_dim1)
#沿着第 1 维求和的结果: tensor([3., 7.])
# 对于更高维度的张量,例如三维张量
B = torch.tensor([
[[1, 2], [3, 4]],
[[5, 6], [7, 8]]
], dtype=torch.float32)
B
tensor([[[1., 2.],
[3., 4.]],
[[5., 6.],
[7., 8.]]])
# 沿着第 0 维(这里是堆叠维度)求和
sum_B_along_dim0 = torch.sum(B, dim=0)
print("三维张量沿着第 0 维求和的结果形状:", sum_B_along_dim0.shape)
#三维张量沿着第 0 维求和的结果形状: torch.Size([2, 2])
实际应用场景:
-
图像数据处理:在处理图像数据时,图像通常表示为三维张量(高度、宽度、通道数)。如果我们想将图像的颜色通道信息进行合并,可以沿着通道维度求和,将三维图像张量降为二维。
-
序列数据处理:在处理序列数据(如文本)时,序列通常表示为二维或更高维的张量。沿着序列长度维度求和,可以将序列信息进行聚合,得到整个序列的综合表示。
还可以通过求平均数进行降维:
>>> A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
>>> A
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
>>> A_sum_axis0 = A.sum(axis=0)
>>> A_sum_axis0,A_sum_axis0.shape
(tensor([40., 45., 50., 55.]), torch.Size([4]))
>>> A_sum_axis1 = A.sum(axis=1)
>>> A_sum_axis1,A_sum_axis1.shape
(tensor([ 6., 22., 38., 54., 70.]), torch.Size([5]))
>>> A.sum(axis=[0,1])
tensor(190.)
>>> 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.]))
>>>
非降维求和:
>>> sum_A=A.sum(axis=1,keepdims=True)
>>> sum_A
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 的第 0 维(通常对应列方向,垂直方向)进行累积求和操作
>>> A.cumsum(axis=0)
tensor([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])
>>>
cumsum累积求和的过程: