一、相关资料连接
二、代码及笔记(使用Jupyter Notebook)
(矩阵、张量、范数)
1. 矩阵乘法其实是空间扭曲,标量由只有一个元素的张量显示
import torch
x = torch.tensor([3.0])
y = torch.tensor([2.0])
x + y, x * y, x / y, x**y
3. 你可以将向量视为标量值组成的列表
x = torch.arange(4)
x
tensor([0, 1, 2, 3]) # 运行结果
4. 通过张量的索引来访问任一元素
x[3]
tensor(3) # 运行结果
5. 访问张量的长度
len(x)
4 # 运行结果
6. 只有一个轴的张量,形状只有一个元素
x.shape
torch.Size([4]) # 运行结果
7. 通过指定两个分量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]]) # 运行结果
8. 矩阵的转置
A.T
tensor([[ 0, 4, 8, 12, 16],
[ 1, 5, 9, 13, 17],
[ 2, 6, 10, 14, 18],
[ 3, 7, 11, 15, 19]]) # 运行结果
9. 对称矩阵(symmetric matrix)A等于其转置:A=A^T
B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
B
tensor([[1, 2, 3],
[2, 0, 4],
[3, 4, 5]]) # 运行结果
B == B.T
tensor([[True, True, True],
[True, True, True],
[True, True, True]]) # 运行结果
10. 就像向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构。(2,3,4)表示一共两个矩阵,每个矩阵是3行4列,可以以此类推,比如(2345),就是2个三维张量,每个三维张量是3个矩阵,每个矩阵是4行5列
X = torch.arange(24).reshape(2, 3, 4)
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]]]) # 运行结果
11. 给定具有相同形状的任意两个张量,任何按元素二元运算的结果都将是相同形状的张量
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone()
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和A+B的shape是一样的
12. 两个矩阵的按元素乘法称为哈达玛积(Hadamard product)(数学符号⊙)
A*B
tensor([[ 0., 1., 4., 9.],
[ 16., 25., 36., 49.],
[ 64., 81., 100., 121.],
[144., 169., 196., 225.],
[256., 289., 324., 361.]]) # 运行结果
13. a+X:是把X中的每一个数都加上a,a* X是把X中的每一个数都乘上a
a = 2
X = torch.arange(24).reshape(2, 3, 4)
X , a + X , (a * X).shape
(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]]]),
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])) # 运行结果
14. 计算其元素的和,不管x是什么样子的形状,他的sum永远都是一个标量
x = torch.arange(4, dtype=torch.float32)
x, x.sum()
(tensor([0., 1., 2., 3.]), tensor(6.)) # 运行结果
15. 表示任意形状张量的元素和
A = torch.arange(20).reshape(5,4)
A.shape, A.sum()
(torch.Size([5, 4]), tensor(190)) # 运行结果
A = torch.arange(20*2).reshape(2,5,4)
A,A.shape, A.sum()
(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]]]),
torch.Size([2, 5, 4]),
tensor(780)) # 运行结果
16. 指定张量沿哪一个轴来通过求和降低维度
A_sum_axis0 = A.sum(axis=0)
A,A_sum_axis0, A_sum_axis0.shape
(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]]]),
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)
A_sum_axis1, A_sum_axis1.shape
(tensor([[ 40, 45, 50, 55],
[140, 145, 150, 155]]),
torch.Size([2, 4])) # 运行结果
A_sum_axis2 = A.sum(axis=2)
A_sum_axis2, A_sum_axis2.shape
(tensor([[ 6, 22, 38, 54, 70],
[ 86, 102, 118, 134, 150]]),
torch.Size([2, 5])) # 运行结果
解释:A的shape是(2,5,4),axis0是对(2,5,4)中的2维度求和,axis1是对5的维度(按行求和),axis2是对4的维度(按列)求和。对某个维度求和时,保留其他的维度,保留的是哪些维度,则shape就是多少。eg: 一、 axis = 0,则按照2维度(2表示两个矩阵的对应位置相加求和),留下的是(5,4)则其结果的shape就是(5,4),即为5行4列的矩阵 二、 axis = 1,则按照5维度(5表示一个矩阵中有5行,则在行这个维度上相加求和,即纵向相加求和,40=0+4+8+12+16,45=1+5+9+13+17,等等),留下的是(2,4),则shape为(2,4)即2个矩阵,一个矩阵为4列 三、 axis = 2,则按照4维度(4表示一个矩阵中有4列,则在列这个维度上相加求和,即横向相加求和,6=0+1+2+3,22=4+5+6+7,等等),留下的是(2,5),则shape为(2,5)即2个矩阵,一个矩阵有5列
17. 按照两个维度求和
axis=[0,1],即按照2和5的维度求和,
180 = 0+4+8+12+16+20+24+28+32+36,
190 = 1+5+9+13+17+21+25+29+33+37。
剩下了4维度,则shape为4列
A,A.sum(axis=[0, 1])
(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]]]),
tensor([180, 190, 200, 210])) # 运行结果
A.sum(axis=[0, 1]).shape
torch.Size([4]) # 运行结果
18. 一个与求和相关的量是平均值(mean或average)
A =torch.arange(20,dtype=torch.float32).reshape(5,4)
A,A.mean(), A.sum() / A.numel()
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
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.])) # 运行结果
axis=0:表示纵向,(0+4+8+12+16)/5 = 8,(1+5+9+13+17)/5 = 9 等等,某一个维度算均值等价于,某一个维度求和在除以维度的形状是一样的
20. 计算总和或均值时保持轴数不变
sum_A = A.sum(axis=1, keepdims=True)
A,sum_A
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
tensor([[ 6.],
[22.],
[38.],
[54.],
[70.]])) # 运行结果
sum_A = A.sum(axis=1, keepdims=False)
A,sum_A
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
tensor([ 6., 22., 38., 54., 70.])) # 运行结果
解释:我们想在按照某一个维度求和的时候,不想吧这个维度丢掉若按照维度为1的维度求和则1维度就丢掉了。若是3维矩阵按照一个维度求和会变成一个2维的矩阵,如果是一个2维的矩阵按照一个维度求和则会变成一个一维的向量。当 keepidms=True,保持其二维或者三维的特性,(结果保持其原来维数) 默认为 False,不保持其二维或者三维的特性.(结果不保持其原来维数)。 eg:shape为[2,5,4],keepdims = True,若按照轴axis=1求和,其结果的shape应该为[2,1,4],即把5变成1,剩下的2,4还是保留,如果为False则shape结果为[2,4]。若按照1轴和2轴axis=[1,2]求和,那么结果shape为[2,1,1],这个变成1,数值没有改变,只是维度变成1维。
21. 通过广播将A除以sum_A
A / sum_A
此行报错原因是因为,广播机制一定得维度相同,由于上面keepdims = False,没有保持原来的维度,所以维度改变,应该使用keepdims = True的结果,如下:
sum_A = A.sum(axis=1, keepdims=True)
A,sum_A,A / sum_A
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]]),
tensor([[ 6.],
[22.],
[38.],
[54.],
[70.]]),
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]])) # 运行结果
axis = 1表示横向,0/6=0,1/6=0.1667,2/6=0.3333,3/6=0.5,4/22=0.1818,5/22=0.2273等等
22. 某个轴计算A元素的累积总和
A,A.cumsum(axis=0)
(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.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]])) # 运行结果
axis=0表示纵向,4=0+4,12=0+4+8,24=0+4+8+12,40=0+4+8+12+16,6+1+5,15=1+5=9,等等
23. 点积是相同位置的按元素乘积的和
x和y都是向量,dot表示是他们的点积:按元素相乘在求和,这是一个标量,torch.dot只能对一维向量做乘积
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.)) # 运行结果
24. 我们可以通过执行按元素乘法,然后进行求和来表示两个向量的点积
torch.sum(x * y)
tensor(6.) # 运行结果
25. 假设A是一个m * n的一个矩阵,x是一个n * 1的矩阵,则Ax是一个长度为m的一个列向量,它的第i个元素是A的第i行和x做点积。
A,x,A.shape, x.shape, torch.mv(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.]),
torch.Size([5, 4]),
torch.Size([4]),
tensor([ 14., 38., 62., 86., 110.])) # 运行结果
(5,4)* (4,1) = (5,1)是5行1列 torch.mv的mv是指matrix-vector multiplication,用矩阵A乘以x作为向量,mv是矩阵和向量的乘积。mm是矩阵与矩阵相乘(mm:Matrix-Matrix Multipliction)。一维向量是列向量(torch中一维向量是按照一维列向量参加运算,但是输出形式是行向量的形式)
26. 我们可以将矩阵-矩阵乘法AB看作是简单地执行m次矩阵-向量积,并将结果拼接在一起,形成一个n×m矩阵。A是一个5 * 4的矩阵,B是一个4 * 3的矩阵,那么AB做mm(即矩阵与矩阵的乘法)
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.]]) # 运行结果
结果是:(5,4)* (4,3) = (5,3)
27. 范数:是一个向量或者矩阵的长度。 L1 L2范数是针对向量而言的,F范数是针对矩阵而言的
(1)L2范数是向量元素平方和的平方根:
u是一个向量,则它的L2范数是,所有元素的做平方再求和再开根号,它的范数是用norm来定义,是一个标量
u = torch.tensor([3.0, -4.0])
torch.norm(u)
tensor(5.) # 运行结果
(2)L1范数,它表示向量每个元素的绝对值的和:
对u取绝对值再求和
torch.abs(u).sum()
tensor(7.) # 运行结果
28. 矩阵也有很对不也一样的范数,常用的是F范数。每个矩阵元素的平方,求和再开根号,等价于吧这个矩阵拉成一个向量,然后做一个向量的范数。矩阵 的弗罗贝尼乌斯范数(Frobenius norm)是矩阵元素平方和的平方根:
torch.norm(torch.ones((4, 9)))
tensor(6.) # 运行结果