【深度学习】Pytorch 系列教程(四):PyTorch数据结构:2、张量的数学运算(2):矩阵运算及其数学原理(基础运算、转置、行列式、迹、伴随矩阵、逆、特征值和特征向量)

文章目录

  • 一、前言
  • 二、实验环境
  • 三、PyTorch数据结构
    • 1、Tensor(张量)
      • 1. 维度(Dimensions)
      • 2. 数据类型(Data Types)
      • 3. GPU加速(GPU Acceleration)
      • 2、张量的数学运算
        • 1. 向量运算
        • 2. 矩阵运算
          • 基础运算
          • 矩阵的转置
          • 矩阵的行列式
          • 求矩阵的迹
          • 矩阵的逆
            • 数学计算
            • 伴随矩阵
              • 数学计算
              • 计算矩阵的特征值和特征向量
                • 旧版
                • 新版
                • 数学计算

                  一、前言

                    本文将介绍PyTorch中张量的数学运算之矩阵运算,包括基础运算、转置、行列式、迹、伴随矩阵、逆、特征值和特征向量等。

                  二、实验环境

                    本系列实验使用如下环境

                  conda create -n DL python==3.11
                  
                  conda activate DL
                  
                  conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
                  

                  三、PyTorch数据结构

                  1、Tensor(张量)

                    Tensor(张量)是PyTorch中用于表示多维数据的主要数据结构,类似于多维数组,可以存储和操作数字数据。

                  1. 维度(Dimensions)

                    Tensor(张量)的维度(Dimensions)是指张量的轴数或阶数。在PyTorch中,可以使用size()方法获取张量的维度信息,使用dim()方法获取张量的轴数。

                  2. 数据类型(Data Types)

                    PyTorch中的张量可以具有不同的数据类型:

                  • torch.float32或torch.float:32位浮点数张量。
                  • torch.float64或torch.double:64位浮点数张量。
                  • torch.float16或torch.half:16位浮点数张量。
                  • torch.int8:8位整数张量。
                  • torch.int16或torch.short:16位整数张量。
                  • torch.int32或torch.int:32位整数张量。
                  • torch.int64或torch.long:64位整数张量。
                  • torch.bool:布尔张量,存储True或False。

                    【深度学习】Pytorch 系列教程(一):PyTorch数据结构:1、Tensor(张量)及其维度(Dimensions)、数据类型(Data Types)

                    3. GPU加速(GPU Acceleration)

                    【深度学习】Pytorch 系列教程(二):PyTorch数据结构:1、Tensor(张量): GPU加速(GPU Acceleration)

                    2、张量的数学运算

                      PyTorch提供了丰富的操作函数,用于对Tensor进行各种操作,如数学运算、统计计算、张量变形、索引和切片等。这些操作函数能够高效地利用GPU进行并行计算,加速模型训练过程。

                    1. 向量运算

                    【深度学习】Pytorch 系列教程(三):PyTorch数据结构:2、张量的数学运算(1):向量运算(加减乘除、数乘、内积、外积、范数、广播机制)

                    2. 矩阵运算

                    基础运算
                    import torch
                    # 定义两个矩阵
                    m1 = torch.tensor([[1, 2],
                                       [3, 4]])
                    m2 = torch.tensor([[5, 6],
                                       [7, 8]])
                    # 矩阵加法
                    addition_result = m1 + m2
                    print("Matrix addition result:\n", addition_result)
                    # 矩阵减法
                    subtraction_result = m1 - m2
                    print("Matrix subtraction result:\n", subtraction_result)
                    # 矩阵数乘
                    scalar = 2
                    scalar_multiplication_result = scalar * m1
                    print("Matrix scalar multiplication result:\n", scalar_multiplication_result)
                    # 矩阵乘法
                    matrix_multiplication_result = torch.matmul(m1, m2)
                    print("Matrix multiplication result:\n", matrix_multiplication_result)
                    
                    矩阵的转置

                      矩阵的转置是将矩阵的行和列进行交换,例如将第i行的元素变为第i列的元素。在实际中,转置在矩阵和向量的乘法、矩阵相似性、对称矩阵等方面具有重要的作用。

                    import torch
                    m = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
                    transposed_m = torch.transpose(m, 0, 1)
                    print("Transposed matrix:\n", transposed_m)
                    
                    tensor([[1., 3.],
                            [2., 4.]])
                    
                    矩阵的行列式

                      矩阵A的行列式是一个标量值,它可以从矩阵的元素中导出。在2x2矩阵的情况下,行列式ad-bc给出了一个变换面积的因子;在更高维度的情况下,它提供了矩阵表示的线性变换对体积的压缩或拉伸情况,因此在几何变换、求解线性方程组及求解微分方程等方面具有重要作用。

                    determinant_m = torch.det(m)
                    print("Determinant of matrix m3:", determinant_m)
                    

                    ∣ m ∣ = 1 ∗ 4 − 2 ∗ 3 = 4 − 6 = − 2 |m| = 1*4 - 2*3 = 4 - 6 = -2 ∣m∣=1∗4−2∗3=4−6=−2

                    eterminant of matrix m3: tensor(-2.)
                    
                    求矩阵的迹

                      矩阵的迹是矩阵对角元素的和,通常表示为Tr(A)。它在物理学和工程中用作描述动态系统稳定性和控制论上的重要特性,同时也在估计矩阵的模和矩阵相似性判别上应用广泛。

                    trace_m = torch.trace(m)
                    print("Trace of matrix m:", trace_m)
                    

                    T r ( m ) = 1 + 4 = 5 Tr(m) = 1 + 4= 5 Tr(m)=1+4=5

                    Trace of matrix m: tensor(5.)
                    
                    矩阵的逆

                      对于一个n×n的矩阵A,如果存在另一个n×n的矩阵B,使得AB和BA均为单位矩阵I,那么B就是A的逆矩阵。逆矩阵在线性代数中用于求解线性方程组和进行除法运算。

                    inverse_m = torch.inverse(m)
                    print("Inverse of matrix m:\n", inverse_m)
                    
                     tensor([[-2.0000,  1.0000],
                            [ 1.5000, -0.5000]])
                    
                    数学计算

                      由上述,已知矩阵m的行列式 ∣ m ∣ = − 2 |m| = -2 ∣m∣=−2,接下来,计算伴随矩阵(二阶矩阵的求法:主对角线元素互换,副对角线元素变号):

                    C = [ 4 − 2 − 3 1 ] C = \begin{bmatrix} 4 & -2 \\ -3 & 1 \end{bmatrix} C=[4−3​−21​]最后,计算逆矩阵:

                    m − 1 = ( 1 ∣ m ∣ ) ∗ C = [ − 2 1 1.5 − 0.5 ] m^{-1} = (\frac{1}{|m|}) *C = \begin{bmatrix} -2 & 1 \\ 1.5 & -0.5 \end{bmatrix} m−1=(∣m∣1​)∗C=[−21.5​1−0.5​]

                    伴随矩阵
                    数学计算
                    • 对于矩阵 A 中的每个元素 a i j a_{ij} aij​,计算出它的余子式 M i j M_{ij} Mij​。即将第 i 行和第 j 列的元素划去后剩下的元素构成的 n − 1 n-1 n−1阶子矩阵的行列式。

                    • 计算代数余子式 C i j = ( − 1 ) i + j M i j C_{ij} = (-1)^{i+j} M_{ij} Cij​=(−1)i+jMij​。其中 ( − 1 ) i + j (-1)^{i+j} (−1)i+j 是根据元素的位置来确定符号的规律,i、j 分别表示元素的行和列编号。

                    • 将代数余子式按照它们在原矩阵中的位置排列成一个新的矩阵再转置,这个新的矩阵称为伴随矩阵。

                    • 原矩阵A: A = [ 1 2 3 4 ] A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \\ \end{bmatrix} A=[13​24​]

                      • 对于元素 a 11 = 1 a_{11}=1 a11​=1,余子式 M 11 = 4 M_{11}=4 M11​=4, C 11 = 4 C_{11}=4 C11​=4
                        • M 11 M_{11} M11​ 是通过划去第一行和第一列的元素得到的子矩阵的行列式,即: M 11 = ∣ 4 ∣ = 4 M_{11} = |4| = 4 M11​=∣4∣=4,
                        • 对于元素 a 12 = 2 a_{12}=2 a12​=2,余子式 M 12 = − 3 M_{12}=-3 M12​=−3, C 12 = − 3 C_{12}=-3 C12​=−3
                        • 对于元素 a 21 = 3 a_{21}=3 a21​=3,余子式 M 21 = − 2 M_{21}=-2 M21​=−2, C 21 = − 2 C_{21}=-2 C21​=−2
                        • 对于元素 a 22 = 4 a_{22}=4 a22​=4,余子式 M 22 = 1 M_{22}=1 M22​=1, C 22 = 1 C_{22}=1 C22​=1
                        • 得到伴随矩阵:

                          C = [ 4 − 2 − 3 1 ] C = \begin{bmatrix} 4 & -2 \\ -3 & 1 \\ \end{bmatrix} C=[4−3​−21​]

                          import torch
                          A = torch.tensor([[1.0, 2.0],
                                            [3.0, 4.0]])
                          A_inv = torch.inverse(A)
                          # 计算行列式
                          det_A = torch.det(A)
                          # 计算伴随矩阵
                          adj_A = A_inv * det_A
                          

                            这里的adj_A并不是传统意义上的伴随矩阵,而是逆矩阵乘以行列式值的结果。传统意义上的伴随矩阵需要计算每个元素的代数余子式,这个步骤在PyTorch中没有直接的函数实现。

                          计算矩阵的特征值和特征向量

                            对于一个n×n的矩阵A,如果存在一个标量λ和一个非零的n维向量v,使得Av = λv,则λ称为A的特征值,v称为A对应于特征值λ的特征向量。特征值和特征向量在矩阵表示的线性变换中扮演重要的角色,在模式识别、信号处理和结构力学等领域有着广泛的应用。特征值和特征向量的计算对于矩阵的对角化、线性变换的分析和模式识别等方面具有重要意义。

                          旧版
                          eigenvalues, eigenvectors = torch.eig(m, eigenvectors=True)
                          print("Eigenvalues of matrix m:", eigenvalues)
                          print("Eigenvectors of matrix m:", eigenvectors)
                          

                          报错:

                          RuntimeError: This function was deprecated since version 1.9 and is now removed. `torch.linalg.eig` returns complex tensors of dtype `cfloat` or `cdouble` rather than real tensors mimicking complex tensors.
                          L, _ = torch.eig(A) should be replaced with:
                          L_complex = torch.linalg.eigvals(A)
                          and
                          L, V = torch.eig(A, eigenvectors=True) should be replaced with:
                          L_complex, V_complex = torch.linalg.eig(A)
                          
                          新版
                          # 求矩阵的特征值和特征向量
                          eigenvalues, eigenvectors = torch.linalg.eig(m)
                          print("Eigenvalues of matrix m:", eigenvalues)
                          print("Eigenvectors of matrix m:\n", eigenvectors)
                          
                          Eigenvalues of matrix m: tensor([-0.3723+0.j,  5.3723+0.j])
                          Eigenvectors of matrix m:
                           tensor([[-0.8246+0.j, -0.4160+0.j],
                                  [ 0.5658+0.j, -0.9094+0.j]])
                          
                          数学计算
                          1. 计算矩阵 A A A 的特征值:通过求解其特征多项式的根来获得,即 ∣ A − λ I ∣ = 0 |A - λI| = 0 ∣A−λI∣=0,其中 λ λ λ是特征值, I I I是单位矩阵。
                          2. 计算每个特征值对应的特征向量:对于每个特征值 λ λ λ,解方程组 ( A − λ I ) v = 0 (A - λI)v = 0 (A−λI)v=0,其中v是特征向量。
                          • 计算特征多项式:

                            ∣ A − λ I ∣ = ∣ 1 − λ 2 3 4 − λ ∣ |A - λI| = \begin{vmatrix} 1-λ & 2 \\ 3 & 4-λ \\ \end{vmatrix} ∣A−λI∣= ​1−λ3​24−λ​ ​

                          • 令 ∣ A − λ I ∣ = 0 |A - λI| = 0 ∣A−λI∣=0 可得

                            ( 1 − λ ) ( 4 − λ ) − 2 ∗ 3 = 0 (1-λ)(4-λ) - 2*3 = 0 (1−λ)(4−λ)−2∗3=0 λ 2 − 5 λ − 2 = 0 λ^2-5λ-2=0 λ2−5λ−2=0

                          • 得到特征值 : λ 1 = ( 5 + 33 ) 2 = 5.3723 , λ 2 = ( 5 − 33 ) 2 = − 0.3723 λ_1=\frac{(5 + \sqrt{33})}{2}=5.3723, λ_2=\frac{(5 - \sqrt{33})}{2}=-0.3723 λ1​=2(5+33 ​)​=5.3723,λ2​=2(5−33 ​)​=−0.3723

                          • 求解特征向量:

                            • 将 λ 1 = ( 5 + 33 ) 2 λ_1 =\frac{(5 + \sqrt{33})}{2} λ1​=2(5+33 ​)​代入得到:

                              ( A − λ 1 I ) v 1 = [ 1 − 5 + √ 33 2 2 3 4 − 5 + √ 33 2 ] v 1 = 0 (A - λ_1I)v_1 = \begin{bmatrix} 1-\frac{5 + √33}{2} & 2 \\ 3 & 4-\frac{5 + √33}{2} \\ \end{bmatrix}v_1 = 0 (A−λ1​I)v1​=[1−25+√33​3​24−25+√33​​]v1​=0

                              • 解得: