线性代数与向量

线性代数与向量

线性代数与向量

标量与向量

如何衡量一个人的健康程度?

在医学上,我们可以根据一个人的 身高、体重、年龄 来大致推算其健康程度。如果转换成数学语言的话,我们可以考虑写出这样一个公式,其中x表示身高,y表示体重,z表示年龄:(x+y)/z,公式的计算结果表示一个人的健康程度。

公式中的xyz可以是任何数字,我们将其称之为标量,多个标量组合在一起,产生了一个新的含义(一个人的健康程度),我们将这个组合称为向量

在代码中,我们可以使用一维数组来表示一个向量

importtorch x=torch.tensor([0,1,2,3])print(x)# tensor([0, 1, 2, 3])

一个只有一个元素的一维数组,可以表示一个标量

importtorch x=torch.tensor([1])print(x)# tensor([1])

矩阵

在使用数据的过程中,我们不可能只用一组数据(一个向量),例如医院必须要很多人的身体数据才能衡量出整体的健康指标。

当我们将多个向量组合在一起时,就形成了一个二维数组,称之为矩阵

importtorch x=torch.arange(12).reshape(3,-1)print(x)# tensor([[ 0, 1, 2, 3],# [ 4, 5, 6, 7],# [ 8, 9, 10, 11]])

如果我们将矩阵中的元素沿着斜对称轴互换的话(也就是将XijX_{ij}Xij变成XjiX_{ji}Xji),就可以得到数组的转置(数学表示为XTX^TXT):

importtorch x=torch.arange(12).reshape(3,-1)print(x)# tensor([[ 0, 1, 2, 3],# [ 4, 5, 6, 7],# [ 8, 9, 10, 11]])y=x.Tprint(y)# tensor([[ 0, 4, 8],# [ 1, 5, 9],# [ 2, 6, 10],# [ 3, 7, 11]])

如果X=XTX=X^TX=XT,我们称其为对称矩阵

importtorch x=torch.tensor([[1,2,3],[2,0,4],[3,4,5]])print(x)# tensor([[1, 2, 3],# [2, 0, 4],# [3, 4, 5]])y=x.Tprint(y)# tensor([[1, 2, 3],# [2, 0, 4],# [3, 4, 5]])print(x==y)# tensor([[True, True, True],# [True, True, True],# [True, True, True]])

当我们对一个矩阵(二维数组)或者更高维数组进行求和时,可以单独对某一维进行求和:

importtorch x=torch.ones(3,4)print(x)# tensor([[1., 1., 1., 1.],# [1., 1., 1., 1.],# [1., 1., 1., 1.]])print(x.sum())# tensor(12.)print(x.sum(axis=0))# tensor([3., 3., 3., 3.])print(x.sum(axis=1))# tensor([4., 4., 4.])

axis=0表示对第0维进行求和,对于一个矩阵(二维数组)来说,也就是将矩阵的高进行压缩,变成了一个一维数组(向量)。

同理,我们对一个矩阵(二维数组)或者更高维数组进行求平均值时,可以单独对某一维进行求平均值:

importtorch x=torch.arange(12,dtype=float).reshape(3,-1)print(x)# tensor([[1., 1., 1., 1.],# [1., 1., 1., 1.],# [1., 1., 1., 1.]])print(x.mean())# tensor(12.)print(x.mean(axis=0))# tensor([3., 3., 3., 3.])

不过,在某些操作中,我们可能不想降低数组的维度:

importtorch x=torch.ones(3,4)print(x)# tensor([[1., 1., 1., 1.],# [1., 1., 1., 1.],# [1., 1., 1., 1.]])print(x.sum())# tensor(12.)# 得到的依旧是一个二维数组,只不过第1维的数组长度为0print(x.sum(axis=0,keepdim=True))# tensor([[3., 3., 3., 3.]])

此外,还有个函数cumsum可以在某个维度上进行累计求和:

importtorch x=torch.ones(3,4)print(x)# tensor([[1., 1., 1., 1.],# [1., 1., 1., 1.],# [1., 1., 1., 1.]])print(x.sum())# tensor(12.)print(x.cumsum(axis=1))# tensor([[1., 2., 3., 4.],# [1., 2., 3., 4.],# [1., 2., 3., 4.]])

向量点积

对于两个相同形状的向量,将对应位置元素相乘,然后取和,可以得到这两个向量的点积(数学表示为XTYX^TYXTY或者<X,Y><X,Y><X,Y>):

importtorch x=torch.tensor([1,1,1])y=torch.tensor([2,2,2])print(torch.dot(x,y))# tensor(6)

矩阵-向量积

矩阵-向量积可以理解为向量点积的扩展,将向量与矩阵的每行向量进行点积,再将每个结果组合成一个向量,就得到了矩阵-向量积

importtorch x=torch.tensor([[1,1,1],[1,1,1],[1,1,1]])y=torch.tensor([2,2,2])# 用函数 mv 来得到矩阵-向量积print(torch.mv(x,y))# tensor([6, 6, 6])foriinrange(len(x)):print(torch.dot(y,x[i]))# tensor(6)# tensor(6)# tensor(6)

矩阵乘法

矩阵乘法也可以理解为向量点积的扩展,只需将一个矩阵的第i行,与另一个矩阵的第j列进行向量点积,就可以得到结果矩阵的第i行j列的元素:

importtorch x=torch.tensor([[1,1,1],[1,1,1],[1,1,1]])y=torch.tensor([[2,2,2],[2,2,2],[2,2,2]])# 用函数 mm 来得到矩阵乘法的结果print(torch.mm(x,y))# tensor([[6, 6, 6],# [6, 6, 6],# [6, 6, 6]])

范数

我们将一个向量的大小称为向量的范数

范数有多种计算方式。L2L_2L2范数的计算方式是将向量中所有元素的平方求和,然后求平方根:∥x∥2=∑i=1nxi2\|\mathbf{x}\|_2 = \sqrt{\sum_{i=1}^n x_i^2}x2=i=1nxi2,在PyTorch中可以通过norm函数获得:

importtorch x=torch.tensor([3.0,-4.0])print(x.norm())# tensor(5.)

L1L_1L1范数的计算方式是将向量中的所有元素的绝对值求和:∥x∥1=∑i=1n∣xi∣\|\mathbf{x}\|_1 = \sum_{i=1}^n \left|x_i \right|x1=i=1nxi,在PyTorch中可以通过这种方式获得:

importtorch x=torch.tensor([3.0,-4.0])print(torch.abs(x).sum())# tensor(7.)

范数的意义在于,我们可以衡量两个向量之间的差距

importtorch x=torch.tensor([2.,3.,2.])y=torch.tensor([1.,1.,1.])print(x.norm())# tensor(4.1231)print(y.norm())# tensor(1.7321)print((x-y).norm())# tensor(2.4495)