• pytorch 深度学习之线性代数


    标量

    包含一个数值的叫标量(scalar)。标量由只有一个元素的张量表示:

    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.))
    

    向量

    将向量视为标量值组成的列表。 我们将这些标量值称为向量的元素(element)或分量(component)。通过一维张量处理向量。一般来说,张量可以具有任意长度,取决于机器的内存限制,可以使用下标来引用向量的任一元素。

    \[\mathbf{A}=\left[\begin{array}{c}\mathbf{a}_{1}^{\top} \\ \mathbf{a}_{2}^{\top} \\ \vdots \\ \mathbf{a}_{m}^{\top}\end{array}\right] \]

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

    长度,维度和形状

    向量的长度通常称为向量的维度,可以通过调用 Python 的内置 len()函数来访问张量的长度。当用张量表示一个向量(只有一个轴)时,我们也可以通过.shape属性访问向量的长度。 形状(shape)是一个元素组,列出了张量沿每个轴的长度(维数)。 对于只有一个轴的张量,形状只有一个元素:

    len(x),x.shape
    
    (4, torch.Size([4]))
    

    矩阵

    正如向量将标量从零阶推广到一阶,矩阵将向量从一阶推广到二阶。

    \[\mathbf{A}=\left[\begin{array}{cccc}a_{11} & a_{12} & \cdots & a_{1 n} \\ a_{21} & a_{22} & \cdots & a_{2 n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m 1} & a_{m 2} & \cdots & a_{m n}\end{array}\right] \]

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

    当我们交换矩阵的行和列时,结果称为矩阵的转置(transpose):

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

    作为方阵的一种特殊类型,对称矩阵(symmetric matrix)\(\mathbf{A}\) 等于其转置:\(\mathbf{A}=\mathbf{A}^{\top}\),定义一个对称矩阵:

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

    张量

    就像向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构。 张量为我们提供了描述具有任意数量轴的 n 维数组的通用方法:

    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]]])
    

    张量算法的基本性质

    给定具有相同形状的任意两个张量,任何按元素二元运算的结果都将是相同形状的张量:

    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 = 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.))
    

    默认情况下,调用求和函数会沿所有的轴降低张量的维度,使它变为一个标量。 我们还可以指定张量沿哪一个轴来通过求和降低维度。 以矩阵为例,为了通过求和所有行的元素来降维(轴0),我们可以在调用函数时指定 axis=0。 由于输入矩阵沿0轴降维以生成输出向量,因此输入轴0的维数在输出形状中消失:

    A = torch.arange(20,dtype=torch.float32).reshape(5,4)
    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.]]),
     tensor([40., 45., 50., 55.]),
     torch.Size([4]))
    

    指定 axis=1 将通过汇总所有列的元素降维(轴1)。因此,输入轴1的维数在输出形状中消失:

    A = torch.arange(20,dtype=torch.float32).reshape(5,4)
    A_sum_axis1 = A.sum(axis=1)
    A,A_sum_axis1,A_sum_axis1.shape
    
    (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.]),
     torch.Size([5]))
    

    沿着行和列对矩阵求和,等价于对矩阵的所有元素进行求和:

    A.sum(axis=[0, 1])  # A.sum()
    
    tensor(190.)
    

    调用 mean 函数可以求平均值:

    A.mean(),A.sum()/A.numel(),A.mean(axis=0),A.sum(axis=0)/A.shape[0]
    
    (tensor(9.5000),
     tensor(9.5000),
     tensor([ 8.,  9., 10., 11.]),
     tensor([ 8.,  9., 10., 11.]))
    

    有时在调用函数来计算总和或均值时保持轴数不变会很有用:

    sum_A = A.sum(axis=1, keepdims=True)
    sum_A,A/sum_A
    
    (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]]))
    

    点积

    给定两个向量:\(\mathbf{x}, \mathbf{y} \in \mathbb{R}^{d}\),它们的点积(dot product):\(\mathbf{x}^{\top} \mathbf{y}\),或者记为:\(\langle\mathbf{x}, \mathbf{y}\rangle\),相同位置的按元素乘积的和:\(\mathbf{x}^{\top} \mathbf{y}=\sum_{i=1}^{d} x_{i} y_{i}\):

    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.))
    

    矩阵-向量积

    为矩阵 A 和向量 x 调用 torch.mv(A, x) 时,会执行矩阵-向量积。 注意,A 的列维数(沿轴1的长度)必须与 x 的维数(其长度)相同:

    \[\mathbf{A}=\left[\begin{array}{c}\mathbf{a}_{1}^{\top} \\ \mathbf{a}_{2}^{\top} \\ \vdots \\ \mathbf{a}_{m}^{\top}\end{array}\right] \]

    \[\mathbf{A}=\left[\begin{array}{cccc}a_{11} & a_{12} & \cdots & a_{1 n} \\ a_{21} & a_{22} & \cdots & a_{2 n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m 1} & a_{m 2} & \cdots & a_{m n}\end{array}\right] \]

    \[\mathbf{A} \mathbf{x}=\left[\begin{array}{c}\mathbf{a}_{1}^{\top} \\ \mathbf{a}_{2}^{\top} \\ \vdots \\ \mathbf{a}_{m}^{\top}\end{array}\right] \mathbf{x}=\left[\begin{array}{c}\mathbf{a}_{1}^{\top} \mathbf{x} \\ \mathbf{a}_{2}^{\top} \mathbf{x} \\ \vdots \\ \mathbf{a}_{m}^{\top} \mathbf{x}\end{array}\right] \]

    A.shape,x.shape,torch.mv(A,x)
    
    (torch.Size([5, 4]), torch.Size([4]), tensor([ 14.,  38.,  62.,  86., 110.]))
    

    矩阵-矩阵乘法

    假设有两个矩阵:\(\mathbf{A} \in \mathbb{R}^{n \times k}\)\(\mathbf{B} \in \mathbb{R}^{k \times m}\)

    \[\mathbf{A}=\left[\begin{array}{cccc}a_{11} & a_{12} & \cdots & a_{1 k} \\ a_{21} & a_{22} & \cdots & a_{2 k} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n 1} & a_{n 2} & \cdots & a_{n k}\end{array}\right], \quad \mathbf{B}=\left[\begin{array}{cccc}b_{11} & b_{12} & \cdots & b_{1 m} \\ b_{21} & b_{22} & \cdots & b_{2 m} \\ \vdots & \vdots & \ddots & \vdots \\ b_{k 1} & b_{k 2} & \cdots & b_{k m}\end{array}\right] \]

    则计算结果 \(\mathbf{C} \in \mathbb{R}^{n \times m}\):

    \[\mathbf{C}=\mathbf{A B}=\left[\begin{array}{c}\mathbf{a}_{1}^{\top} \\ \mathbf{a}_{2}^{\top} \\ \vdots \\ \mathbf{a}_{n}^{\top}\end{array}\right]\left[\begin{array}{llll}\mathbf{b}_{1} & \mathbf{b}_{2} & \cdots & \mathbf{b}_{m}\end{array}\right]=\left[\begin{array}{cccc}\mathbf{a}_{1}^{\top} \mathbf{b}_{1} & \mathbf{a}_{1}^{\top} \mathbf{b}_{2} & \cdots & \mathbf{a}_{1}^{\top} \mathbf{b}_{m} \\ \mathbf{a}_{2}^{\top} \mathbf{b}_{1} & \mathbf{a}_{2}^{\top} \mathbf{b}_{2} & \cdots & \mathbf{a}_{2}^{\top} \mathbf{b}_{m} \\ \vdots & \vdots & \ddots & \vdots \\ \mathbf{a}_{n}^{\top} \mathbf{b}_{1} & \mathbf{a}_{n}^{\top} \mathbf{b}_{2} & \cdots & \mathbf{a}_{n}^{\top} \mathbf{b}_{m}\end{array}\right] \]

    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.]])
    

    范数

    一个向量的范数告诉我们一个向量有多大。 这里考虑的大小(size)概念不涉及维度,而是分量的大小。
    在线性代数中,向量范数是将向量映射到标量的函数 \(f\) 。给定任意向量 \(\mathbf{X}\),向量范数要满足一些属性:

    • 第一个性质:如果我们按常数因子 \(Q\) 缩放向量的所有元素, 其范数也会按相同常数因子的绝对值缩放:\(f(\alpha \mathbf{x})=|\alpha| f(\mathbf{x})\)
    • 第二个性质:三角不等式:\(f(\mathbf{x}+\mathbf{y}) \leq f(\mathbf{x})+f(\mathbf{y})\)
    • 第三个性质:范数必须是非负的:\(f(\mathbf{x}) \geq 0\)
    • 最后一个性质要求范数最小为0,当且仅当向量全由0组成:\(\forall i,[\mathbf{x}]_{i}=0 \Leftrightarrow f(\mathbf{x})=0\)

    欧几里得距离是一个 \(L_{2}\) 范数:

    \[\|\mathbf{x}\|_{2}=\sqrt{\sum_{i=1}^{n} x_{i}^{2}} \]

    u = torch.tensor([3.0,-4.0])
    torch.norm(u)
    
    tensor(5.)
    

    \(L_{1}\) 范数,表示为向量元素的绝对值之和:

    \[\|\mathbf{x}\|_{1}=\sum_{i=1}^{n}\left|x_{i}\right| \]

    \(L_{2}\) 范数相比,\(L_{1}\) 范数受异常值的影响较小。

    torch.abs(u).sum()
    
    tensor(7.)
    

    \(L_{2}\) 范数和 \(L_{1}\) 范数都是更一般的范数的特例:

    \[\|\mathbf{x}\|_{p}=\left(\sum_{i=1}^{n}\left|x_{i}\right|^{p}\right)^{1 / p} \]

    类似于向量的 \(L_{2}\) 范数,矩阵 \(\mathbf{X} \in \mathbb{R}^{m \times n}\) 的Frobenius范数(Frobenius norm)是矩阵元素平方和的平方根:

    \[\|\mathbf{X}\|_{F}=\sqrt{\sum_{i=1}^{m} \sum_{j=1}^{n} x_{i j}^{2}} \]

    Frobenius 范数满足向量范数的所有性质,它就像是矩阵形向量的 \(L_{2}\) 范数。 调用以下函数将计算矩阵的 Frobenius 范数。

    torch.norm(torch.ones(4,9))
    
    tensor(6.)
    

    范数和目标

    经常试图解决优化问题: 最大化分配给观测数据的概率; 最小化预测和真实观测之间的距离。目标,或许是深度学习算法最重要的组成部分(除了数据),通常被表达为范数。

  • 相关阅读:
    java里面嵌套执行python脚本
    session的token令牌机制防止表单重复提交
    springIOC实现原理模拟(springIOC底层使用xml解析+反射实现)
    service层使用接口的好处
    javap -verbose输出结果详解
    skiplist
    Jmeter内存溢出解决方法
    Jmeter参数化设置的5种方法
    方法入参获取泛型类型
    并发编程笔记
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/16152580.html
Copyright © 2020-2023  润新知