pytorch线性代数

D2L线性代数

内容来自《D2L》,上课内容,加上我自己做的课后习题

标量

简单操作

c=a+b

c=a*b

c=sina

长度

|a|=a a>0,-a otherwise

|a+b|<=|a|+|b|

|a*b|=|a||b|

向量

在这里插入图片描述在这里插入图片描述

向量点积

img

几何意义:点积的结果是一个标量,等于向量大小与夹角的cos值的乘积。a•b = |a||b|cosθ

叉积:两个向量ab的叉积写作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)的张量Xlen(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)
计算得到的是一个标量,全部元素平方后相加,开根号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值