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可以写为:
一个向量x由n个实值标量组成,我们可以将其表示为
向量的长度通常称为向量的纬度(dimension)。
可以调用python的内置len()函数来访问张量的长度,也快通过.shape属性访问向量的长度。
print(len(x))
print(x.shape) # 轴为1,对于轴为1的张量,形状只有一个元素
4
torch.Size([4])
向量或轴的纬度被用来表示向量或轴的长度,即向量或轴的元素数量,然而,张量的纬度用来表示张良具有的轴数。在这个意义上,张量的某个轴的维数就是这个轴的长度。
2.2.3矩阵
正如向量从零阶推广到一阶,矩阵将向量从一阶推广到二阶。矩阵,我们通常用粗体,大写字母来表示(例如,X,Y和Z),在代码中表示为具有两个轴的张量。
在数学表示发中,我们使用
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]])
也可以通过下标进行访问
print(X[1][1])
tensor(5)
也可进行翻转轴操作交换矩阵的行和列,这个操作的结果被称为矩阵的转置(transpose)。我们用
来表示矩阵的转置。则对于任意i和j,都有
因此一个形状为m*n的矩阵转置为n *m的矩阵。
可以通过T函数来访问矩阵的转置
print(X.T)
tensor([[ 0, 4, 8],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]])
作为方矩阵的一种特殊类型,对称矩阵(symmetric matrix)A等于其转置:
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)(数学符号⊙)。对于矩阵
其中第i⾏和第j列的元素是
按元素相乘
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的向量中元素的总和,可以记为
import torch
x=torch.arange(4,dtype=torch.float32)
print(x)
print(x.sum())
tensor([0., 1., 2., 3.])
tensor(6.)
我们可以表示任意形状张量的元素和。例如,矩阵A中元素的和可以记为
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)
给定两个向量
它们的点积(dotproduct)就是对应下标元素相乘的和
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)概念不涉及维度,而是分量的大小。
里面的元素的平方和再开根号
x=torch.tensor([-3.0,4.0])
print(torch.norm(x))
tensor(5.)
表示为向量元素的绝对值之和
print(torch.abs(x).sum())
tensor(7.)
弗罗贝尼乌斯范数(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.)
范数一般用于解决优化问题,最大化分配给观测数据的概念;最小化预测和真实观测之间的距离。用向量表示实际的的东西(图片,价格),求出预测值和实际值的偏离(距离).