Pytorch之线性代数

作者: 陨星落云 | 来源:发表于2020-03-23 16:47 被阅读0次

    矩阵

    1. 矩阵初始化
    2. 矩阵元素运算
    3. 矩阵的乘法
    4. 矩阵的转置
    5. 矩阵对应列行的最大值,最小值,和
    6. 矩阵的其他操作:行列数、切片、复制、非0元素的下标
    7. 矩阵的行列式
    8. 矩阵的逆和伪逆
    9. 矩阵的对称
    10. 矩阵的秩、迹
    11. 矩阵求解
    12. 矩阵的特征值与特征向量(EVD)

    矩阵

    1. 矩阵初始化

    Tensor的初始化

    # 全零矩阵
    
    In [1]: import torch
    
    In [2]: myZero = torch.zeros(3,3)
    
    In [3]: myZero
    Out[3]: 
    tensor([[0., 0., 0.],
            [0., 0., 0.],
            [0., 0., 0.]])
    
    In [4]: type(myZero)
    Out[4]: torch.Tensor
    
    In [5]: myZero.dtype
    Out[5]: torch.float32
    
    # 全一矩阵
    
    In [6]: myOnes = torch.ones(3,3)
    
    In [8]: myOnes
    Out[8]: 
    tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]])
    
    # 单位矩阵
    
    In [9]: myEye = torch.eye(5)
    
    In [10]: myEye
    Out[10]: 
    tensor([[1., 0., 0., 0., 0.],
            [0., 1., 0., 0., 0.],
            [0., 0., 1., 0., 0.],
            [0., 0., 0., 1., 0.],
            [0., 0., 0., 0., 1.]])
    
    # 对称矩阵
    
    In [11]: a1 = [1,2,3,4,5]
    
    In [13]: a1 = torch.tensor(a1)
    
    In [14]: a1
    Out[14]: tensor([1, 2, 3, 4, 5])
    
    In [15]: myDiag = torch.diag(a1)
    
    In [16]: myDiag
    Out[16]: 
    tensor([[1, 0, 0, 0, 0],
            [0, 2, 0, 0, 0],
            [0, 0, 3, 0, 0],
            [0, 0, 0, 4, 0],
            [0, 0, 0, 0, 5]]) 
    
    # 随机矩阵
    
    In [17]: myRand = torch.rand(3,3)
    
    In [18]: myRand
    Out[18]: 
    tensor([[0.9588, 0.0139, 0.2303],
            [0.4332, 0.1916, 0.4152],
            [0.4848, 0.3361, 0.9799]])
    
    • 直接创建tensor
    In [19]: a = torch.tensor([[1,2,3],[4,5,6]])
    
    In [20]: a
    Out[20]: 
    tensor([[1, 2, 3],
            [4, 5, 6]])
    
    • 通过from_numpy() 函数将ndarray数据类型转化成矩阵(tensor)
    In [21]: import numpy as np
    
    In [22]: a = np.arange(12).reshape(3,4)
    
    In [23]: b = torch.from_numpy(a)
    
    In [24]: b
    Out[24]: 
    tensor([[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11]], dtype=torch.int32)
    
    2. 矩阵元素运算

    矩阵的元素运算是指矩阵在元素级别的加、减、乘、除运算。
    (1)元素相加和相减。
    条件:矩阵的行数和列数必须相同。
    数学公式:(A±B)_i,_j=A_i,_j±B_i,_j

    In [27]: myOnes = torch.ones(4,4)
    
    In [28]: myOnes
    Out[28]: 
    tensor([[1., 1., 1., 1.],
            [1., 1., 1., 1.],
            [1., 1., 1., 1.],
            [1., 1., 1., 1.]])
    
    In [29]: myEye = torch.eye(4)
    
    In [30]: myEye
    Out[30]: 
    tensor([[1., 0., 0., 0.],
            [0., 1., 0., 0.],
            [0., 0., 1., 0.],
            [0., 0., 0., 1.]])
    
    In [31]: myOnes + myEye
    Out[31]: 
    tensor([[2., 1., 1., 1.],
            [1., 2., 1., 1.],
            [1., 1., 2., 1.],
            [1., 1., 1., 2.]])
    
    In [32]: myOnes - myEye
    Out[32]: 
    tensor([[0., 1., 1., 1.],
            [1., 0., 1., 1.],
            [1., 1., 0., 1.],
            [1., 1., 1., 0.]])
    

    (2)矩阵数乘:一个数乘以一个矩阵。

    数学公式:(cA)_i,_j=c·A_i,_j

    In [37]: b 
    Out[37]: 
    tensor([[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11]], dtype=torch.int32)
    
    In [39]: b*10
    Out[39]: 
    tensor([[  0,  10,  20,  30],
            [ 40,  50,  60,  70],
            [ 80,  90, 100, 110]], dtype=torch.int32)
    

    (3)矩阵所有元素求和。
    数学公式:
    \operatorname{sum}(A)=\sum_{i=1}^{m} \sum_{j=1}^{n} A_{i, j}=1 其中, 1<i<m, 1<j<n

    In [40]: torch.sum(b)
    Out[40]: tensor(66)
    

    (4)矩阵所有元素之积

    数学公式:
    \operatorname{product}(A)=\prod_{i=1}^{m} \prod_{j=1}^{n} A_{i, j}=1 其中, 1<i<m, 1<j<n

    In [47]: a = torch.arange(4).reshape(2,2)+1
    
    In [48]: a
    Out[48]: 
    tensor([[1, 2],
            [3, 4]])
    
    In [49]: torch.prod(a)
    Out[49]: tensor(24)
    

    (5)矩阵各元素的n次幂:n=3。
    数学公式:
    A_{ij}^3=A_{ij}×A_{ij}×A_{ij}

    In [50]: a
    Out[50]: 
    tensor([[1, 2],
            [3, 4]])
    
    In [52]: torch.pow(a,3)
    Out[52]: 
    tensor([[ 1,  8],
            [27, 64]])
    
    3. 矩阵的乘法

    (1)矩阵各元素的积:矩阵的点乘同维对应元素的相乘。当矩阵的维度不同时,会根据一定的广播规则将维数扩充到一致的形式。
    数学公式:
    (A×B)_i,_j =A_i,_j×B_i,_j

    In [64]: a
    Out[64]: 
    tensor([[1, 2],
            [3, 4]])
    
    In [65]: b
    Out[65]: 
    tensor([[0, 1],
            [2, 3]])
    
    In [66]: torch.mul(a,b)
    Out[66]: 
    tensor([[ 0,  2],
            [ 6, 12]])
    

    (2)矩阵内积

    数学公式:
    [\boldsymbol{A}, \boldsymbol{B}]_{i, j}=\boldsymbol{A}_{i, 1} \boldsymbol{B}_{1, j}+\boldsymbol{A}_{i, 2} \boldsymbol{B}_{2, j}+\cdots+\boldsymbol{A}_{i n} \boldsymbol{B}_{n j}=\sum_{r=1}^{n} \boldsymbol{A}_{i, r} \boldsymbol{B}_{r, j^{\circ}}

    In [68]: a
    Out[68]: 
    tensor([[1, 2],
            [3, 4]])
    
    In [69]: b
    Out[69]: 
    tensor([[0, 1, 2],
            [3, 4, 5]])
    
    In [70]: torch.dot(a,b)
    Traceback (most recent call last):
    
      File "<ipython-input-70-5682e150e844>", line 1, in <module>
        torch.dot(a,b)
    # 报错,只允许一维的tensor,只适合向量内积
    RuntimeError: 1D tensors expected, got 2D, 2D tensors at C:\w\1\s\tmp_conda_3.6_045031\conda\conda-bld\pytorch_1565412750030\work\aten\src\TH/generic/THTensorEvenMoreMath.cpp:723
    
    #官方提示此功能不广播。有关广播的矩阵乘法,请参见torch.matmul()
    In [71]: torch.mm(a,b)
    Out[71]: 
    tensor([[ 6,  9, 12],
            [12, 19, 26]])
    
    In [72]: torch.matmul(a,b)
    Out[72]: 
    tensor([[ 6,  9, 12],
            [12, 19, 26]])
    

    (3)向量内积、外积

    x=\left(x_{1}, x_{1}, ...,x_{m}\right) y=\left(y_{1}, y_{2},...,y_{n}\right)

    向量内积:x y^{T}=\sum_{i=1}^{n} x_{i} y_{i}

    向量外积:x ^{T}y=\left(\begin{array}{ccc}{x_{1} y_{1}} & {\cdots} & {x_{1} y_{n}} \\ {\vdots} & {} & {\vdots} \\ {x_{m} y_{1}} & {\cdots} & {x_{m} y_{n}}\end{array}\right)

    In [73]: a1  = torch.tensor([2,1,0])
    
    In [74]: a2 = torch.tensor([-1,2,1])
    
    In [75]: a1
    Out[75]: tensor([2, 1, 0])
    
    In [76]: a2
    Out[76]: tensor([-1,  2,  1])
    
    In [77]: torch.dot(a1,a2)
    Out[77]: tensor(0)
    
    In [78]: torch.outer(a1,a2)
    Traceback (most recent call last):
    # 在pytorch中没有outer函数
      File "<ipython-input-78-cc115fea0111>", line 1, in <module>
        torch.outer(a1,a2)
    
    AttributeError: module 'torch' has no attribute 'outer'
    # 解决办法,先将一维的向量转换为二维,再利用矩阵内积方法计算
    In [86]: a1 = a1.reshape(1,3)
    
    In [87]: a2 = a2.reshape(1,3)
    # 转置
    In [88]: a1.T
    Out[88]: 
    tensor([[2],
            [1],
            [0]])
    
    In [89]: torch.mm(a1.T,a2)
    Out[89]: 
    tensor([[-2,  4,  2],
            [-1,  2,  1],
            [ 0,  0,  0]])
    

    (4)向量叉乘(叉积):运算结果是一个向量而不是一个标量。并且两个向量的叉积与这两个向量组成的坐标平面垂直。

    数学公式:

    a=\left(x_{1}, y_{1}, z_{1}\right) b=\left(x_{2}, y_{2}, z_{2}\right)
    a \times b=\left|\begin{array}{ccc}{\mathrm{i}} & {\mathrm{j}} & {\mathrm{k}} \\ {x_{1}} & {y_{1}} & {z_{1}} \\ {x_{2}} & {y_{2}} & {z_{2}}\end{array}\right|=\left(y_{1} z_{2}-y_{2} z_{1}\right) i-\left(x_{1} z_{2}-x_{2} z_{1}\right) j+\left(x_{1} y_{2}-x_{2} y_{1}\right) k
    其中
    i=(1,0,0) \quad j=(0,1,0) \quad \mathrm{k}=(0,0,1)
    根据i、j、k间关系,有:
    a \times b=\left(y_{1} z_{2}-y_{2} z_{1},-\left(x_{1} z_{2}-x_{2} z_{1}\right), x_{1} y_{2}-x_{2} y_{1}\right)

    例1、已知,a =(2,1,0),b =(-1,2,1),试求(1)a\times b(2)b\times a
    解:(1)a\times b =(1,-2,5):(2)b\times a =(-1,2,5)

    In [79]: torch.cross(a1,a2)
    Out[79]: tensor([ 1, -2,  5])
    
    In [80]: torch.cross(a2,a1)
    Out[80]: tensor([-1,  2, -5])
    
    4. 矩阵的转置

    数学公式:(A^T)_{ij} = A_{ij}

    In [90]: a
    Out[90]: 
    tensor([[1, 2],
            [3, 4]])
    
    In [91]: a.T
    Out[91]: 
    tensor([[1, 3],
            [2, 4]])
    
    In [92]: a.transpose(1,0)
    Out[92]: 
    tensor([[1, 3],
            [2, 4]])
    
    5. 矩阵对应列行的最大值,最小值,和
    In [99]: b 
    Out[99]: 
    tensor([[0, 1, 2],
            [3, 4, 5]])
    # 计算矩阵中最大值的对应索引
    In [100]: b.argmax()
    Out[100]: tensor(5)
    # 计算矩阵列中最大值对应的行索引
    In [101]: b.argmax(axis=0)
    Out[101]: tensor([1, 1, 1])
    # 计算矩阵行中最大值对应的列索引
    In [102]: b.argmax(axis=1)
    Out[102]: tensor([2, 2])
    # 矩阵中的最大值
    In [103]: b.max()
    Out[103]: tensor(5)
    # 矩阵列中的最小值
    In [104]: b.min()
    Out[104]: tensor(0)
    # 矩阵列求和
    In [105]: b.sum(axis=0)
    Out[105]: tensor([3, 5, 7])
    
    6. 矩阵的其他操作:行列数、切片、复制、非0元素的下标
    In [106]: a
    Out[106]: 
    tensor([[1, 2],
            [3, 4]])
    # 行列数
    In [107]: m,n = a.shape
    
    In [108]: m,n
    Out[108]: (2, 2)
    
    In [109]: b
    Out[109]: 
    tensor([[0, 1, 2],
            [3, 4, 5]])
    # 切片
    In [111]: b[1:]
    Out[111]: tensor([[3, 4, 5]])
    
    In [112]: b[:,1:]
    Out[112]: 
    tensor([[1, 2],
            [4, 5]])
    # 复制
    In [114]: c = torch.clone(b)
    
    In [115]: c
    Out[115]: 
    tensor([[0, 1, 2],
            [3, 4, 5]])
    # 随机生成0-8,大小4*4
    In [116]: d = torch.randint(0,9,(4,4))
    
    In [117]: d
    Out[117]: 
    tensor([[3, 1, 2, 2],
            [4, 8, 3, 6],
            [5, 4, 4, 6],
            [0, 3, 0, 5]])
    # 帅选出大于3的数
    In [118]: d[d>3]
    Out[118]: tensor([4, 8, 6, 5, 4, 4, 6, 5])
    
    In [119]: d
    Out[119]: 
    tensor([[3, 1, 2, 2],
            [4, 8, 3, 6],
            [5, 4, 4, 6],
            [0, 3, 0, 5]])
    # 非0元素的下标
    In [120]: torch.nonzero(d)
    Out[120]: 
    tensor([[0, 0],
            [0, 1],
            [0, 2],
            [0, 3],
            [1, 0],
            [1, 1],
            [1, 2],
            [1, 3],
            [2, 0],
            [2, 1],
            [2, 2],
            [2, 3],
            [3, 1],
            [3, 3]])
    
    7. 矩阵的行列式
    In [127]: a
    Out[127]: 
    tensor([[1, 2],
            [3, 4]])
    
    In [128]: a = a.float()
    
    In [129]: a
    Out[129]: 
    tensor([[1., 2.],
            [3., 4.]])
    # a必须为浮点型,否则会报错
    In [130]: torch.det(a)
    Out[130]: tensor(-2.0000)
        
    In [132]: d
    Out[132]: 
    tensor([[3, 1, 2, 2],
            [4, 8, 3, 6],
            [5, 4, 4, 6],
            [0, 3, 0, 5]])
    
    In [133]: torch.det(d.float())
    Out[133]: tensor(43.0000)
    
    8. 矩阵的逆和伪逆

    矩阵的逆

    In [134]: a
    Out[134]: 
    tensor([[1., 2.],
            [3., 4.]])
    # 矩阵的逆
    In [135]: torch.inverse(a)
    Out[135]: 
    tensor([[-2.0000,  1.0000],
            [ 1.5000, -0.5000]])
    

    注意:矩阵不满秩,则会报错

    矩阵的伪逆

    In [143]: e = e.double()
    # 最好使用float64,
    In [144]: e
    Out[144]: 
    tensor([[3., 3., 3.],
            [3., 3., 3.],
            [3., 3., 3.]], dtype=torch.float64)
    # 伪逆
    In [145]: torch.pinverse(e)
    Out[145]: 
    tensor([[0.0370, 0.0370, 0.0370],
            [0.0370, 0.0370, 0.0370],
            [0.0370, 0.0370, 0.0370]], dtype=torch.float64)
    
    In [146]: f = torch.ones((4,4),dtype=torch.float64)+3
    
    In [147]: f
    Out[147]: 
    tensor([[4., 4., 4., 4.],
            [4., 4., 4., 4.],
            [4., 4., 4., 4.],
            [4., 4., 4., 4.]], dtype=torch.float64)
    
    In [148]: torch.pinverse(f)
    Out[148]: 
    tensor([[0.0156, 0.0156, 0.0156, 0.0156],
            [0.0156, 0.0156, 0.0156, 0.0156],
            [0.0156, 0.0156, 0.0156, 0.0156],
            [0.0156, 0.0156, 0.0156, 0.0156]], dtype=torch.float64)
    
    9. 矩阵的对称
    In [149]: a
    Out[149]: 
    tensor([[1., 2.],
            [3., 4.]])
    
    In [150]: a*a.T
    Out[150]: 
    tensor([[ 1.,  6.],
            [ 6., 16.]])
    
    10. 矩阵的秩、迹

    矩阵的秩

    In [151]: a
    Out[151]: 
    tensor([[1., 2.],
            [3., 4.]])
    # 秩
    In [152]: torch.matrix_rank(a)
    Out[152]: tensor(2)
    
    In [153]: e
    Out[153]: 
    tensor([[3., 3., 3.],
            [3., 3., 3.],
            [3., 3., 3.]], dtype=torch.float64)
    
    In [154]: torch.matrix_rank(e)
    Out[154]: tensor(1)
    

    矩阵的迹

    In [156]: a
    Out[156]: 
    tensor([[1., 2.],
            [3., 4.]])
    # 迹
    In [157]: torch.trace(a)
    Out[157]: tensor(5.)
    
    In [158]: b
    Out[158]: 
    tensor([[0, 1, 2],
            [3, 4, 5]])
    
    In [159]: torch.trace(b)
    Out[159]: tensor(4)
    
    11. 矩阵求解

    可逆矩阵的求解
    AX=B

    In [174]: A = torch.randint(0,10,(4,4),dtype=torch.float64)
    
    In [175]: A
    Out[175]: 
    tensor([[1., 0., 9., 1.],
            [8., 5., 5., 6.],
            [9., 1., 0., 4.],
            [2., 0., 4., 0.]], dtype=torch.float64)
    
    In [177]: B = torch.tensor([[1,10,0,1]],dtype=torch.float64)
    
    In [178]: B
    Out[178]: tensor([[ 1., 10.,  0.,  1.]], dtype=torch.float64)
    # 求解
    In [180]: (X,LU) = torch.solve(B.T,A)
    
    In [181]: X
    Out[181]: 
    tensor([[ 0.0989],
            [ 2.7260],
            [ 0.2006],
            [-0.9040]], dtype=torch.float64)
    # 验证
    In [182]: torch.mm(A,X)
    Out[182]: 
    tensor([[ 1.0000],
            [10.0000],
            [ 0.0000],
            [ 1.0000]], dtype=torch.float64)
    
    
    12. 矩阵的特征值与特征向量(EVD)

    矩阵的特征向量和特征值:
    Av=\lambda v
    这里A是实对称矩阵,v是特征向量,\lambda是特征值。下面我们使用Pytorch求取矩阵的特征值和特征向量。

    In [200]: A = torch.tensor([[-1,1,0],[-4,3,0],[1,0,2]],dtype=torch.float64) 
    # 求解特征值与特征向量
    In [205]: (evals,evecs) = torch.eig(A,eigenvectors=True)
    # 特征值
    In [206]: evals
    Out[206]: 
    tensor([[2., 0.],
            [1., 0.],
            [1., 0.]], dtype=torch.float64)
    # 特征向量
    In [207]: evecs
    Out[207]: 
    tensor([[ 0.0000,  0.4082,  0.4082],
            [ 0.0000,  0.8165,  0.8165],
            [ 1.0000, -0.4082, -0.4082]], dtype=torch.float64)
    

    相关文章

      网友评论

        本文标题:Pytorch之线性代数

        本文链接:https://www.haomeiwen.com/subject/qkwwyhtx.html