D2L线性代数
内容来自《D2L》,上课内容,加上我自己做的课后习题
标量
简单操作
c=a+b
c=a*b
c=sina
长度
|a|=a a>0,-a otherwise
|a+b|<=|a|+|b|
|a*b|=|a||b|
向量
向量点积 :
几何意义:点积的结果是一个标量,等于向量大小与夹角的cos值的乘积。a•b = |a||b|cosθ
叉积:两个向量a和b的叉积写作a×b ,运算结果是一个向量,与原来的两个向量垂直。
c =a×b =(x1,y1,z1)×(x2,y2,z2)=(y1z2 - y2z1, z1x2 - z2x1, x1y2 - x2y1)
矩阵乘法:矩阵乘向量(矩阵第一行和列向量相乘求和,写输出第一个位置),矩阵乘矩阵书上有
扭曲空间:向量通过一个矩阵乘法变成另一个向量
矩阵长度:范数
F范数:每个元素平方相加开根号
正定矩阵:该矩阵乘任意一个列向量/行向量大于等于0
正交矩阵:
所有行都相互正交
所有行都有单位长度
可以写成UUT=1(等于对角线全为1的单位矩阵)
置换矩阵:是正交矩阵
特征向量和特征值:不被矩阵改变方向的向量 Ax=λx
#标量由只有一个元素的张量表示
import torch
x=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.]))
#可以将向量视为标量值组成的列表
x=torch.arange(4)
x
tensor([0, 1, 2, 3])
#通过张量的索引访问任意元素
x[3]
tensor(3)
#访问张量长度
len(x)
4
#只有一个轴的张量,形状只有一个元素
x.shape
torch.Size([4])
#通过指定两个分量m和n来创建一个形状为m*n的矩阵
a=torch.arange(20).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.T#转置
tensor([[ 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]])
print(b)
b==b.T
tensor([[1, 2, 3],
[2, 0, 4],
[3, 4, 5]])
tensor([[True, True, True],
[True, True, True],
[True, True, True]])
#就像向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构
x=torch.arange(24).reshape(2,3,4)
x
tensor([[[ 0, 1, 2, 3],#行最后一维,4
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],#列第二维,2是第三维
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
#给定具有相同形状的任何两个张量,任何元素二元运算的结果都将是相同形状的张量
a=torch.arange(20,dtype=torch.float32).reshape(5,4)
b=a.clone()#同过分配新内存,将a的副本分配给b
a,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=2
X=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]))
#计算其元素的和
x=torch.arange(4,dtype=torch.float32)
x,x.sum()
(tensor([0., 1., 2., 3.]), tensor(6.))
#表示任意形状张量的和
a.shape,a.sum()#sum是标量
(torch.Size([5, 4]), tensor(190.))
a=torch.arange(20*2).reshape(2,5,4)
a.shape,a.sum()
(torch.Size([2, 5, 4]), tensor(780))#0,1,2维
#指定维度求和汇总张量的轴(对哪个维度求和,哪个维度发生改变,维度会消失,)
a_sum_axis0=a.sum(axis=0)#对0
a_sum_axis0,a_sum_axis0.shape
(tensor([[20, 22, 24, 26],
[28, 30, 32, 34],
[36, 38, 40, 42],
[44, 46, 48, 50],
[52, 54, 56, 58]]),
torch.Size([5, 4]))
a_sum_axis1=a.sum(axis=1)#对1
a_sum_axis1,a_sum_axis1.shape
(tensor([[ 40, 45, 50, 55],
[140, 145, 150, 155]]),
torch.Size([2, 4]))
a.sum(axis=[0,1]) tensor([180, 190, 200, 210])
a.sum(axis=[0,1]).shape torch.Size([4])
#相当于把某一维降维,三位的话就是把矩阵拍扁,对应的元素相加,剩下来的就是没被拍扁的维度
#均值
a.mean()#要float才能求
a.mean(axis=0)
#计算总和或均值时保持数轴不变,不丢掉维度,对应维度=1
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
sum_A=A.sum(axis=0,keepdims=True)
sum_A
tensor([[ 0., 1., 2., 3.],#A
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
tensor([[40., 45., 50., 55.]])
#通过广播将A除以sum_A(A的维度和sum_A维度一样)#形状不一,维度一样,但可以复制维度再运算
A/sum_A
tensor([[0.0000, 0.0222, 0.0400, 0.0545],
[0.1000, 0.1111, 0.1200, 0.1273],
[0.2000, 0.2000, 0.2000, 0.2000],
[0.3000, 0.2889, 0.2800, 0.2727],
[0.4000, 0.3778, 0.3600, 0.3455]])
#某个轴计算A元素的累计总和
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.]])#第0列一直往下累加
#点积是相同位置的按元素乘积的和(哈达玛积 ⊙)
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.)
#矩阵向量积Ax是一个长度为m的列向量(python中虽然是列向量但还是横着表示,x也是一个列向量,默认是列向量),其第i个元素是点积aiTx
A.shape,x.shape,torch.mv(A,x)
(torch.Size([5, 4]), torch.Size([4]), tensor([ 14., 38., 62., 86., 110.]))
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.]))
#可以将矩阵-矩阵乘法AB看作是简单地执行m次矩阵-向量积,并将结果拼到一起,形成一个n*m矩阵
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.]])
#L2范数是向量元素平方和的平方根:
u=torch.tensor([3.0,-4.0])
torch.norm(u)
tensor(5.)
#L1范数是向量元素绝对值之和
torch.abs(u).sum()#abs是绝对值
tensor(7.)
#矩阵的佛罗贝尼乌斯范数(Forbenius norm)是矩阵元素平方后全部加起来的平方根,计算简单
torch.norm(torch.ones(4,9))
tensor(6.)
5*4的矩阵:
shape:[5,4]
维度:2
axis:0,1
按axis=0做sum,第一列求sum,第二列sum。。。。相当于拍扁,得到长为4的向量
axis=1做sum,降维后得到长为5的向量
keepdims=True
shape=[2,5,4]axis=1,那么结果=[2,1,4]
axis=[1,2],[2,1,1]
a.sum(axis=[0,1],keepdims=True).shape#shape没有括号
torch.Size([1, 1, 4])
torch:一维张量一定是行向量
列向量是矩阵,计算机中向量是一位的,内存中是一个数组,没有行列之分。
练习:
1.我们在本节中定义了形状(2,3,4)的张量X
。len(X)
的输出结果是什么?
x=torch.arange(24).reshape(2,3,4)#三维
print(x,len(x))
tensor([[[ 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.对于任意形状的张量X
,len(X)
是否总是对应于X
特定轴的长度?这个轴是什么?
#就像向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构
x=torch.arange(24*5).reshape(5,3,4,2)
print(x,len(x))
tensor([[[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[ 10, 11],
[ 12, 13],
[ 14, 15]],
[[ 16, 17],
[ 18, 19],
[ 20, 21],
[ 22, 23]]],
[[[ 24, 25],
[ 26, 27],
[ 28, 29],
[ 30, 31]],
[[ 32, 33],
[ 34, 35],
[ 36, 37],
[ 38, 39]],
[[ 40, 41],
[ 42, 43],
[ 44, 45],
[ 46, 47]]],
[[[ 48, 49],
[ 50, 51],
[ 52, 53],
[ 54, 55]],
[[ 56, 57],
[ 58, 59],
[ 60, 61],
[ 62, 63]],
[[ 64, 65],
[ 66, 67],
[ 68, 69],
[ 70, 71]]],
[[[ 72, 73],
[ 74, 75],
[ 76, 77],
[ 78, 79]],
[[ 80, 81],
[ 82, 83],
[ 84, 85],
[ 86, 87]],
[[ 88, 89],
[ 90, 91],
[ 92, 93],
[ 94, 95]]],
[[[ 96, 97],
[ 98, 99],
[100, 101],
[102, 103]],
[[104, 105],
[106, 107],
[108, 109],
[110, 111]],
[[112, 113],
[114, 115],
[116, 117],
[118, 119]]]]) 5
len()对应的是第0轴上的长度
3.运行A/A.sum(axis=1)
,看看会发生什么。你能分析原因吗?
报错,The size of tensor a (4) must match the size of tensor b (5) at non-singleton dimension 1
因为A是二维的,后面的值变成一维,无法除
4.考虑一个具有形状(2,3,4)的张量,在轴0、1、2上的求和输出是什么形状?
[3,4]、[2,4]、[2,3]
5.为linalg.norm
函数提供3个或更多轴的张量,并观察其输出。对于任意形状的张量这个函数计算得到什么?
X=torch.ones(2,3,4)
Y=torch.ones(2,3,4,5)
print(torch.norm(X))
print(torch.norm(Y))
tensor(4.8990)
tensor(10.9545)
计算得到的是一个标量,全部元素平方后相加,开根号
6.为linalg.norm
函数提供3个或更多轴的张量,并观察其输出。对于任意形状的张量这个函数计算得到什么?
X=torch.ones(2,3,4)
Y=torch.ones(2,3,4,5)
print(torch.norm(X))
print(torch.norm(Y))
tensor(4.8990)
tensor(10.9545)
计算得到的是一个标量,全部元素平方后相加,开根号