2.2线性代数

深度学习关于线性代数相关知识

2.2.1标量

仅包含一个数值的叫标量,未知的标量值称为变量数学表示法,其中标量由普通小写字母表示(例如,x,y和z)。用R表示所有(连续)实数标量的空间。,表达式x ∈ R是表⽰x是⼀个实值标量的正式形式。标量由一个元素的张量组成。

  • 算术运算
import torch
x=torch.tensor([2.0])
y=torch.tensor([4])
print(x+y,"\n",x-y,"\n",x*y,"\n",x*y)
tensor([6.]) 
 tensor([-2.]) 
 tensor([8.]) 
 tensor([8.])

2.2.2向量

向量是标量值组成的列表。这些标量值称为向量的元素(element)或分量(component)。在数学表示法中,通常将向量记为粗体,小写的符号(例如,x,y和z)。

可以通过下标访问指定元素

import torch
x=torch.arange(4)
print(x)
print(x[2])
tensor([0, 1, 2, 3])
tensor(2)

大部分文献默认列向量是向量的默认方向。在数学中,向量x可以写为:
pytorch 张量加一个数_pytorch
一个向量x由n个实值标量组成,我们可以将其表示为
pytorch 张量加一个数_线性代数_02
向量的长度通常称为向量的纬度(dimension)。

可以调用python的内置len()函数来访问张量的长度,也快通过.shape属性访问向量的长度。

print(len(x))
print(x.shape)  # 轴为1,对于轴为1的张量,形状只有一个元素
4
torch.Size([4])

向量或轴的纬度被用来表示向量或轴的长度,即向量或轴的元素数量,然而,张量的纬度用来表示张良具有的轴数。在这个意义上,张量的某个轴的维数就是这个轴的长度。

2.2.3矩阵

正如向量从零阶推广到一阶,矩阵将向量从一阶推广到二阶。矩阵,我们通常用粗体,大写字母来表示(例如,XYZ),在代码中表示为具有两个轴的张量。

在数学表示发中,我们使用
pytorch 张量加一个数_深度学习_03
A的形状是(m,n)或者m*n。当矩阵具有相同数量的行和列时,其形状变为正方形;因此,他被称为方矩阵(square matrix)。

当调用函数来实例化张量时,我们可以通过指定两个分量m和n来创建一个形状为m*n的矩阵,使用reshape()函数

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

也可以通过下标进行访问
pytorch 张量加一个数_深度学习_04

print(X[1][1])
tensor(5)

也可进行翻转轴操作交换矩阵的行和列,这个操作的结果被称为矩阵的转置(transpose)。我们用
pytorch 张量加一个数_线性代数_05
来表示矩阵的转置。则对于任意i和j,都有
pytorch 张量加一个数_pytorch 张量加一个数_06
因此一个形状为m*n的矩阵转置为n *m的矩阵。

可以通过T函数来访问矩阵的转置

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

作为方矩阵的一种特殊类型,对称矩阵(symmetric matrix)A等于其转置:
pytorch 张量加一个数_线性代数_07

Y=torch.tensor([[1,2,3],[2,0,4],[3,4,5]])
print(Y)
print(Y==Y.T)
tensor([[1, 2, 3],
        [2, 0, 4],
        [3, 4, 5]])
tensor([[True, True, True],
        [True, True, True],
        [True, True, True]])

矩阵是有用的数据结构:它们允许我们组织具有不同变化模式的数据。

2.2.4张量

向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构。张量可以提供n维数组。向量是一阶张量,矩阵是二阶张量。张量的索引机制与矩阵类似。

处理图像时候,张量变得更加重要,图像以n维数组形式出现,其中3个轴对应于高度,宽度,一级有一个通道(channel)轴,用于堆叠颜色通道(红色,绿色和蓝色)。

import torch
x=torch.arange(24).reshape(2,3,4)
print(x)
sor([[[ 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.2.5张量算法的基本性质

按元素的二元运算,相同形状的张量,经过按元素的二元运算的结果将是想通过形状的张量。

A=torch.arange(20,dtype=torch.float32).reshape(5,4)
B=A.clone()
print(A)
print(A+B)
print(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.]])
tensor([[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]])

两个矩阵的按元素乘法称为哈达玛积(Hadamard product)(数学符号⊙)。对于矩阵
pytorch 张量加一个数_pytorch_08
其中第i⾏和第j列的元素是
pytorch 张量加一个数_线性代数_09
按元素相乘

print(A*B)
tensor([[  0.,   1.,   4.,   9.],
        [ 16.,  25.,  36.,  49.],
        [ 64.,  81., 100., 121.],
        [144., 169., 196., 225.],
        [256., 289., 324., 361.]])

将张量乘以或加上一个标量不会改变张良的形状,结果是张良的每个元素都与标量相加或相乘。

a=2
print(a+A)  #标量与矩阵相加
print(a*A)  #标量与矩阵相乘
tensor([[ 2.,  3.,  4.,  5.],
        [ 6.,  7.,  8.,  9.],
        [10., 11., 12., 13.],
        [14., 15., 16., 17.],
        [18., 19., 20., 21.]])
tensor([[ 0.,  2.,  4.,  6.],
        [ 8., 10., 12., 14.],
        [16., 18., 20., 22.],
        [24., 26., 28., 30.],
        [32., 34., 36., 38.]])

2.2.6 降维

使用sum函数可以对任意张量计算其元素的和。在数学表示法中,我们使用∑符号表⽰求和。为了表⽰⻓度为d的向量中元素的总和,可以记为
pytorch 张量加一个数_线性代数_10

import torch
x=torch.arange(4,dtype=torch.float32)
print(x)
print(x.sum())
tensor([0., 1., 2., 3.])
tensor(6.)

我们可以表示任意形状张量的元素和。例如,矩阵A中元素的和可以记为
pytorch 张量加一个数_pytorch 张量加一个数_11

y=torch.arange(12).reshape(3,4)
print(y.shape,'\n',y.sum())
torch.Size([3, 4]) 
tensor(66)

默认情况下,调用求和函数会沿所有的轴降低张量的维度,使它变为一个标量。我们还可以指定张量沿哪一个轴来通过求和降低维度。以矩阵为例,为了通过求和所有行的元素来降维(轴0),我们可以做调用函数时指定axis=0.由于输入矩阵沿着0轴降维以生成输出向量,因此输入的轴0的维数在输出形状中丢失。

y_sum_sxis0=y.sum(axis=0)
print(y_sum_sxis0)
print(y_sum_sxis0.shape)
y_sum_sxis0=y.sum(axis=0)
print(y_sum_sxis0)
print(y_sum_sxis0.shape)

指定axis=1将通过汇总所有列的元素降维(轴1),因此,输入的轴1的维数在输出形状中消失。

y_sum_axis1=y.sum(axis=1)
print(y_sum_axis1)
print(y_sum_axis1.shape)
tensor([ 6, 22, 38])
torch.Size([3])

沿着行和列求和,等价于对矩阵的所有元素求和。

print(y.sum(axis=[0,1]))
tensor(66)

求张量的平均数可以用(mean)。还可以通过将总和初一元素总数(numel)来计算平均值。在代码中,我们可以调用函数计算任意形状张量的平均值。也可以计算指定轴的平均值(axis)。

print(y.mean())   # 求平均值
print(y.numel())  # 求元素个数
print(y.sum()/float(y.numel()))
print(y.mean(axis=0))
print(y.sum(axis=0)/float(y.numel()))
tensor(5.5000)
12
tensor(5.5000)
tensor([4., 5., 6., 7.])
tensor([1.0000, 1.2500, 1.5000, 1.7500])
  • 非降维求和

有时调用函数来计算总和或均值时保持轴数不变会很有用。

import torch
x=torch.arange(20).reshape(4,5)
print(x)
sum_x=x.sum(axis=1,keepdim=True)   # axis=0,保留行  axis=1,保留列
print(sum_x)
tensor([[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]])
tensor([[10],
        [35],
        [60],
        [85]])

可以对列的和(sum_x)相除

print(x/sum_x)
tensor([[0.0000, 0.1000, 0.2000, 0.3000, 0.4000],
        [0.1429, 0.1714, 0.2000, 0.2286, 0.2571],
        [0.1667, 0.1833, 0.2000, 0.2167, 0.2333],
        [0.1765, 0.1882, 0.2000, 0.2118, 0.2235]])

沿着某个轴计算A元素的累计总和,比如axis=0,按行计算,我们可以调用cumsum函数。此函数不会沿着任何轴降低输入张量的纬度。

print(x.cumsum(axis=0))  #计算每列的累计和
tensor([[ 0,  1,  2,  3,  4],
        [ 5,  7,  9, 11, 13],
        [15, 18, 21, 24, 27],
        [30, 34, 38, 42, 46]])

2.2.7 点积(Dot Product)

给定两个向量
pytorch 张量加一个数_标量_12
它们的点积(dotproduct)就是对应下标元素相乘的和
pytorch 张量加一个数_pytorch_13

x=torch.arange(4,dtype=torch.float32)
y=torch.ones(4,dtype=torch.float32)
print(x,y,torch.dot(x,y))
tensor([0., 1., 2., 3.]) tensor([1., 1., 1., 1.]) tensor(6.)

通过执行元素乘法,进行求和来表示两个向量的点积:

print(torch.sum(x*y))
tensor(6.)

点积可以表示加权平均(weighted average)。。将两个向量归⼀化得到单位⻓度后,点积表⽰它们夹⻆的余弦。

2.2.8 矩阵-向量积

矩阵-向量积(matrix-vector product),矩阵的每列和向量的元素个数相同,矩阵的第一行和向量对应元素进行点乘相加求和后作为第一个元素,以此类推。

x=torch.arange(20).reshape(5,4)
y=torch.arange(4)
print(x,"\n",y)
print(torch.mv(x,y))
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])
tensor([ 14,  38,  62,  86, 110])

2.2.9 矩阵-矩阵乘法

矩阵-矩阵乘法(matrix-matrix multiplication),线代的矩阵A,B相乘,应满足A的列等于B的行,按照对应元素相乘求和作为第一个结果。

x=torch.arange(12).reshape(3,4)
y=torch.tensor([[2,2],[2,2],[2,2],[2,2]])
print(x)
print(y)
print(torch.mm(x,y) ) # 矩阵相乘函数  x 3*4 y 4*2 结果 3*2
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
tensor([[2, 2],
        [2, 2],
        [2, 2],
        [2, 2]])
tensor([[12, 12],
        [44, 44],
        [76, 76]])

2.2.10范数

一个向量的范数可以告诉我吗一个向量有多大。这里考虑的大小(size)概念不涉及维度,而是分量的大小。
pytorch 张量加一个数_标量_14
里面的元素的平方和再开根号

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

pytorch 张量加一个数_深度学习_15

表示为向量元素的绝对值之和

print(torch.abs(x).sum())
tensor(7.)

pytorch 张量加一个数_pytorch 张量加一个数_16

弗罗贝尼乌斯范数(Frobenius norn)是矩阵元素的平方根,类似于L2范数。

y=torch.ones((4,9))
print(y)
print(torch.norm(y))  #求弗罗贝尼乌斯范数
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.]])
tensor(6.)

范数一般用于解决优化问题,最大化分配给观测数据的概念;最小化预测和真实观测之间的距离。用向量表示实际的的东西(图片,价格),求出预测值和实际值的偏离(距离).