线性代数

发布时间 2023-07-21 15:21:58作者: mostimali




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

一些简单的属性




A = torch.arange(20).reshape(5,4)
print(A)
print(A.T)
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [16, 17, 18, 19]]) 
tensor([[ 0,  4,  8, 12, 16],
        [ 1,  5,  9, 13, 17],
        [ 2,  6, 10, 14, 18],
        [ 3,  7, 11, 15, 19]])

A.T: 矩阵A的转置, 可以理解为矩阵沿着左上-右下的对角线翻转

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

如果矩阵B等于它的转置矩阵, 则称矩阵B为对称矩阵




A = torch.arange(40).reshape(2, 5, 4)
print(A, "\n")
print(A.sum(), "\n")
A_sum0 = A.sum(axis=0)
A_sum1 = A.sum(axis=1)
print(A_sum0, "\n")
print(A_sum1, "\n")
A_sum02= A.sum(axis=[0, 2])
print(A_sum02, "\n")
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(780) 

tensor([[20, 22, 24, 26],
        [28, 30, 32, 34],
        [36, 38, 40, 42],
        [44, 46, 48, 50],
        [52, 54, 56, 58]]) 

tensor([[ 40,  45,  50,  55],
        [140, 145, 150, 155]]) 

tensor([ 92, 124, 156, 188, 220]) 

sum(axis= x)顾名思义是求和函数, 但是注意函数的返回值是张量而不是数值;
如果括号里什么都不写则是返回一个标量, 值是所有元素的和
如果axis=0即对A的第一个维度也就是2这个维度进行求和, 返回值就是一个大小为5x4的张量
如果axis=1即对A的第二个维度也就是5这个维度进行求和, 返回值就是一个大小为2x4的张量
如果axis=[0, 2]即对A的第一和第三个维度进行求和, 返回值就是一个大小为5的张量
可以理解为对哪些维度求和就要消除哪些维度

A_sum0T = A.sum(axis=0, keepdims=True)
print(A_sum0T, "\n")
print(A_sum0T.shape)
tensor([[[20., 22., 24., 26.],
         [28., 30., 32., 34.],
         [36., 38., 40., 42.],
         [44., 46., 48., 50.],
         [52., 54., 56., 58.]]]) 

torch.Size([1, 5, 4])

如果说不想损失维度的话可以加上keepdims=True, 例如A_sum0T就是一个1x5x4的张量, 保留了第一个维度
这样可以方便做广播机制

广播机制

广播机制是一种补全机制, 现给定两个矩阵进行运算, 在特定情况下两个矩阵会扩充为相同维度且各个维度大小相等的两个矩阵
特定情况如下: 对于矩阵的维度我们从后往前看, 如果相同则往前看; 如果不同且其中一个为1, 则把1扩展为另一个矩阵当前维度的大小;
如果两个矩阵的维度不同, 且从后往前一直都满足特定情况, 那么对于维度小的矩阵会自动补全为另一个矩阵的维度

A = torch.ones(4, 3, 2)
B = torch.ones(4, 1, 2) # B的1扩充为3
print((A+B).shape)
torch.Size([4, 3, 2])
A = torch.ones(4, 1, 3, 2) # A的1扩充为5
B = torch.ones(5, 1, 2) # B的1扩充为3, 并补全了4这个维度
print((A+B).shape)
torch.Size([4, 5, 3, 2])
A = torch.ones(4, 1, 3, 3)
B = torch.ones(5, 1, 2)
print((A+B).shape) # 2!=3, 不满足特定情况, 报错

注意: 广播机制只是在运算过程中改变了原矩阵的维度, 运算结束后矩阵的维度还是原来的样子




A = torch.arange(40, dtype=torch.float32).reshape(2, 5, 4)
print(A.mean())
print(A.sum()/A.numel(), "\n")

print(A.mean(axis=0))
print(A.sum(axis=0)/A.shape[0], "\n")
tensor(19.5000)
tensor(19.5000) 

tensor([[10., 11., 12., 13.],
        [14., 15., 16., 17.],
        [18., 19., 20., 21.],
        [22., 23., 24., 25.],
        [26., 27., 28., 29.]])
tensor([[10., 11., 12., 13.],
        [14., 15., 16., 17.],
        [18., 19., 20., 21.],
        [22., 23., 24., 25.],
        [26., 27., 28., 29.]]) 

和sum()相似, 对于求平均值函数mean()来说也是如此, 返回值也是张量
求平均值除了用mean()函数外还可以用sum()/个数, 这样的返回值依旧是张量; (求单独某一维的元素个数要用shape[])
注意求平均值的前提是张量的数值类型是float




A = torch.arange(20).reshape(5, 4)
print(A)
print(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]])

cumsum(axis= x): 累加求和, 与sum()不同, cumsum的返回值维度不变, 和原张量相同; 元素的值类似于第x维上的前缀和




x = torch.arange(4, dtype=torch.float32)
y = torch.ones(4, dtype=torch.float32)
print(torch.dot(x, y))
print(torch.sum(x*y))
tensor(6.)
tensor(6.)

dot(x, y): 求两个向量的点积, 也就是相同位置元素乘积的和; 效果等同于sum(x*y)

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = torch.ones(4, 3)
print(torch.mm(A, B))
tensor([[ 6.,  6.,  6.],
        [22., 22., 22.],
        [38., 38., 38.],
        [54., 54., 54.],
        [70., 70., 70.]])

mm(A, B): 指的就是矩阵乘法, 而之前的A*B只是点乘




A = torch.tensor([3.0, -4.0])
print(torch.abs(A).sum())
print(torch.norm(A))

A = torch.ones(4, 9)
print(torch.norm(A))
tensor(7.)
tensor(5.)

tensor(6.)

abs(向量).sum(): 求向量的L1范数, 就是把所有元素的绝对值加起来
norm(向量): 求向量的L2范数, 就是把所有元素的平方加起来再开根号, 可以理解为向量的模

norm(矩阵): 求矩阵的F范数, 也是把所有元素的平方加起来再开根号