0. 前言

在深度学习中,线性代数是最基础数学工具,它为构建和理解神经网络提供了必要的数学框架。这门课程虽然是我们大学中的必修课,但是由于其内容的晦涩、抽象以及缺少实际应用说明,是最容易还给老师的学科。

本文将汇总在深度学习中常用的、又是非常容易被忘记的线性代数知识点,并结合PyTorch代码以及深度学习中的实际应用加以说明。本文适用于任何想认真研究深度学习的新手,而对于老手同样也推荐再学习一下线性代数以夯实基础,并能激发出更深层次的思考。

这是一个系列文章,相关文章链接如下:

1. 基础概念

  1. 向量:一个向量可以用一个列向量来表示:
    v = ( 1 2 3 ) \mathbf{v} = \begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} v= 123

  2. 矩阵:一个简单的 2x3 矩阵可以写作:
    A = ( 1 2 3 4 5 6 ) A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} A=(142536)

  3. 标量:一个标量就是一个单独的数字:
    s = 3 s = 3 s=3

  4. 向量加法:假设我们有两个向量 u \mathbf{u} u v \mathbf{v} v
    u = ( 1 2 ) , v = ( 3 4 ) \mathbf{u} = \begin{pmatrix} 1 \\ 2 \end{pmatrix}, \quad \mathbf{v} = \begin{pmatrix} 3 \\ 4 \end{pmatrix} u=(12),v=(34)
    它们的和为:
    u + v = ( 1 + 3 2 + 4 ) = ( 4 6 ) \mathbf{u} + \mathbf{v} = \begin{pmatrix} 1 + 3 \\ 2 + 4 \end{pmatrix} = \begin{pmatrix} 4 \\ 6 \end{pmatrix} u+v=(1+32+4)=(46)

  5. 向量标量乘法:如果用标量 s = 2 s = 2 s=2 乘以向量 v = ( 1 2 3 ) \mathbf{v} = \begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} v= 123
    2 ⋅ v = 2 ⋅ ( 1 2 3 ) = ( 2 ⋅ 1 2 ⋅ 2 2 ⋅ 3 ) = ( 2 4 6 ) 2 \cdot \mathbf{v} = 2 \cdot \begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} = \begin{pmatrix} 2 \cdot 1 \\ 2 \cdot 2 \\ 2 \cdot 3 \end{pmatrix} = \begin{pmatrix} 2 \\ 4 \\ 6 \end{pmatrix} 2v=2 123 = 212223 = 246

  6. 矩阵加法:如果有两个同维度的矩阵 A A A B B B
    A = ( 1 2 3 4 ) , B = ( 5 6 7 8 ) A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}, \quad B = \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} A=(1324),B=(5768)
    它们的和为:
    A + B = ( 1 + 5 2 + 6 3 + 7 4 + 8 ) = ( 6 8 10 12 ) A + B = \begin{pmatrix} 1 + 5 & 2 + 6 \\ 3 + 7 & 4 + 8 \end{pmatrix} = \begin{pmatrix} 6 & 8 \\ 10 & 12 \end{pmatrix} A+B=(1+53+72+64+8)=(610812)

  7. 矩阵标量乘法:如果用标量 s = 3 s = 3 s=3乘以矩阵 A = ( 1 2 3 4 ) A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} A=(1324)
    3 ⋅ A = 3 ⋅ ( 1 2 3 4 ) = ( 3 ⋅ 1 3 ⋅ 2 3 ⋅ 3 3 ⋅ 4 ) = ( 3 6 9 12 ) 3 \cdot A = 3 \cdot \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} = \begin{pmatrix} 3 \cdot 1 & 3 \cdot 2 \\ 3 \cdot 3 & 3 \cdot 4 \end{pmatrix} = \begin{pmatrix} 3 & 6 \\ 9 & 12 \end{pmatrix} 3A=3(1324)=(31333234)=(39612)

  8. 矩阵乘法(点乘):假设有两个矩阵 A A A B B B,其中 A A A是 2x3 矩阵, B B B 是 3x2 矩阵:
    A = ( 1 2 3 4 5 6 ) , B = ( 7 8 9 10 11 12 ) A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix}, \quad B = \begin{pmatrix} 7 & 8 \\ 9 & 10 \\ 11 & 12 \end{pmatrix} A=(142536),B= 791181012
    它们的乘积为:
    A B = ( ( 1 ⋅ 7 + 2 ⋅ 9 + 3 ⋅ 11 ) ( 1 ⋅ 8 + 2 ⋅ 10 + 3 ⋅ 12 ) ( 4 ⋅ 7 + 5 ⋅ 9 + 6 ⋅ 11 ) ( 4 ⋅ 8 + 5 ⋅ 10 + 6 ⋅ 12 ) ) = ( 58 64 139 154 ) AB = \begin{pmatrix} (1\cdot7 + 2\cdot9 + 3\cdot11) & (1\cdot8 + 2\cdot10 + 3\cdot12) \\ (4\cdot7 + 5\cdot9 + 6\cdot11) & (4\cdot8 + 5\cdot10 + 6\cdot12) \end{pmatrix} = \begin{pmatrix} 58 & 64 \\ 139 & 154 \end{pmatrix} AB=((17+29+311)(47+59+611)(18+210+312)(48+510+612))=(5813964154)

  9. 转置:矩阵 A = ( 1 2 3 4 5 6 ) A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} A=(142536) 的转置 A T A^T AT是:
    A T = ( 1 4 2 5 3 6 ) A^T = \begin{pmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{pmatrix} AT= 123456

  10. Hadamard 乘积:假设我们有两个 2x2 矩阵 A A A B B B

A = ( 1 2 3 4 ) , B = ( 5 6 7 8 ) A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}, \quad B = \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} A=(1324),B=(5768)

那么 A A A B B B的 Hadamard 乘积 C = A ∘ B C = A \circ B C=AB 将会是:

C = ( 1 ⋅ 5 2 ⋅ 6 3 ⋅ 7 4 ⋅ 8 ) = ( 5 12 21 32 ) C = \begin{pmatrix} 1 \cdot 5 & 2 \cdot 6 \\ 3 \cdot 7 & 4 \cdot 8 \end{pmatrix} = \begin{pmatrix} 5 & 12 \\ 21 & 32 \end{pmatrix} C=(15372648)=(5211232)

这就是通过对应元素相乘得到的矩阵。

2. 矩阵的秩

2.1 秩的定义

矩阵的秩定义为:矩阵中非零子式的最高阶数。具体来说,如果矩阵 A A A中存在一个 r r r阶非零子式,且所有 r + 1 r+1 r+1阶及更高阶的子式都为零,则称 r r r为矩阵 A A A的秩,记作 r a n k ( A ) = r rank(A) = r rank(A)=r R ( A ) = r R(A) = r R(A)=r

看到上面这段定义,你头皮发麻了吗?我也明白了当年为什么学不好线性代数了。

秩,可以理解为矩阵中线性独立列(或行)的最大数量,这样理解就简单多了,但是可能仍然比较抽象,这里可以举一个简单的例子:

如果一个人让你帮忙解一个方程组:

x + y + z = 1 x + 2 y + 2 z = 5 \begin{align*} x+y+z=1\\ x+2y+2z=5 \end{align*} x+y+z=1x+2y+2z=5

上过初中的我们都知道,要想解出这里的 x x x y y y z z z至少还需要一个方程,于是他又给了:

2 x + 3 y + 3 z = 6 2x+3y+3z=6 2x+3y+3z=6

看到这,你会不会给他一个大大的白眼,因为第三个方程它“没有用”啊!它就是第一个和第二个方程的左右分别加合而已,第三个方程的引入并没有新的信息量。如果我们把上面的系数写成矩阵的形式:

( 1 1 1 1 2 2 2 3 3 ) \begin{pmatrix} 1 & 1 &1 \\ 1 & 2 & 2 \\ 2&3&3 \end{pmatrix} 112123123

我们也可以发现:这个矩阵中的任意一行,是可以通过其他两行进行线性组合计算出来(例如:第二行 = -1×第一行+1×第三行)的,即这个矩阵的线性独立行为2,那么这个矩阵的行秩即为2。(列秩也是同样的道理)

2.2 秩的计算方法

计算矩阵的秩有多种方法,以下种常见的计算方法:

  1. 行阶梯形形式(Row Echelon Form, REF)
  2. 行最简形(Reduced Row Echelon Form, RREF)
  3. 高斯消元法(Gaussian Elimination)
  4. 高斯-若尔当消元法(Gauss-Jordan Elimination)
  5. 奇异值分解(Singular Value Decomposition, SVD)
  6. QR 分解(QR Decomposition)
  7. LU 分解(LU Decomposition)
  8. 列空间和零空间(Column Space and Null Space)分析

这些方法都可以用来确定矩阵的秩,每种方法都有其适用场景和特点。这块不是本文的介绍重点,后面仅详细介绍奇异值分解SVD方法,其他方法有需要可以自行百度。

也可以使用PyTorch中的.matrix_rank()方法求解矩阵的秩,示例代码如下:

import torch

# 创建一个矩阵
matrix = torch.tensor([[1,1,1],[1,2,2],[2,3,3]],dtype=torch.float32)
# 计算矩阵的秩
rank = torch.linalg.matrix_rank(matrix)
print("Matrix:\n", matrix)
print("Rank of the matrix:", rank)

输出为:

Matrix:
 tensor([[1., 1., 1.],
        [1., 2., 2.],
        [2., 3., 3.]])
Rank of the matrix: tensor(2)
2.3 秩在深度学习中的应用
  1. 低秩近似:通过将高维的权重矩阵分解为低秩矩阵的乘积,可以显著减少模型的参数数量,从而实现模型压缩。这不仅减少了模型的存储需求,还能加速模型的训练和推理过程。
  2. 特征选择:通过对权重矩阵的秩进行分析,可以识别出哪些特征是冗余的(联想下上面说的“没有用”的方程),从而帮助进行特征选择,进一步减少模型复杂度。
  3. 正则化:通过正则化技术(如 L1 或 L2 正则化)来惩罚权重矩阵的范数,间接控制矩阵的秩(简单来说,正则化惩罚会鼓励权重矩阵中的元素变为0,如果矩阵中有多个零向量,那么矩阵的秩就会下降。),从而减少模型的复杂度,防止过拟合。
  4. 模型泛化能力:适当的矩阵秩有助于提升模型的泛化能力。如果矩阵的秩过高,可能导致模型过于复杂而过拟合;如果秩过低,则可能使模型过于简单而欠拟合。

3. 矩阵的奇异值

矩阵的奇异值是矩阵的一个重要属性,它们出现在矩阵的奇异值分解(Singular Value Decomposition, SVD)中。奇异值分解是线性代数中的一个重要工具,广泛应用于数据分析、信号处理、机器学习等领域。下面详细介绍矩阵的奇异值及其相关概念。

3.1 奇异值分解(SVD)

对于任何一个 m × n m \times n m×n的矩阵 A A A,都可以将其分解为三个矩阵的乘积:
A = U Σ V T A = U \Sigma V^T A=UΣVT
其中:

  • U U U是一个 m × m m \times m m×m的酉矩阵(orthogonal matrix),它的列向量是 A A A的左奇异向量。
  • Σ \Sigma Σ是一个 m × n m \times n m×n 的对角矩阵,对角线上是矩阵 A A A的奇异值,通常按从大到小的顺序排列。
  • V V V是一个 n × n n \times n n×n的酉矩阵,它的列向量是 A A A 的右奇异向量。
3.2 奇异值的定义

奇异值是对角矩阵 Σ \Sigma Σ中的非负实数对角元素。如果矩阵 A A A的秩为 r r r,那么它有 r r r个非零奇异值。其余的奇异值均为零。

3.3 奇异值的性质
  1. 非负性:奇异值是非负实数,即 σ i ≥ 0 \sigma_i \geq 0 σi0
  2. 排序:通常情况下,奇异值按从大到小的顺序排列,即 σ 1 ≥ σ 2 ≥ … ≥ σ r > 0 \sigma_1 \geq \sigma_2 \geq \ldots \geq \sigma_r > 0 σ1σ2σr>0
  3. :矩阵的秩等于非零奇异值的数量。
  4. 范数:最大奇异值是矩阵的谱范数(spectral norm),即 ∥ A ∥ 2 = σ 1 \|A\|_2 = \sigma_1 A2=σ1
  5. 伪逆:奇异值分解可以用于计算矩阵的伪逆(Moore-Penrose pseudoinverse),即 A † = V Σ † U T A^\dagger = V \Sigma^\dagger U^T A=VΣUT,其中 Σ † \Sigma^\dagger Σ Σ \Sigma Σ的对角矩阵,其非零对角元素替换为各自的倒数。
3.4 奇异值的意义

奇异值提供了矩阵的重要信息,包括但不限于:

  • 矩阵的秩:矩阵的秩等于非零奇异值的数量。
  • 矩阵的稳定性:奇异值的分布可以反映矩阵的稳定性。如果奇异值差距很大,矩阵可能是病态的(ill-conditioned),这意味着它对数值计算中的微小变化很敏感。
  • 特征向量:奇异值分解提供了矩阵的特征向量(后续文章会讲),这些向量可以用于数据的降维和特征提取。
  • 低秩近似:通过保留最大的几个奇异值及其对应的奇异向量,可以构造矩阵的低秩近似,这对于数据压缩和降维很有用。(即2.3节中的第1点)
3.5 实例说明

假设我们有一个 3x2 的矩阵 A A A

A = ( 1 2 3 4 5 6 ) A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \end{pmatrix} A= 135246

对其进行 SVD 分解,得到:

A = U Σ V T A = U \Sigma V^T A=UΣVT

其中 U U U V V V 是酉矩阵, Σ \Sigma Σ 是对角矩阵,包含奇异值。例如:

U = ( u 11 u 12 u 13 u 21 u 22 u 23 u 31 u 32 u 33 ) , Σ = ( σ 1 0 0 σ 2 0 0 ) , V = ( v 11 v 12 v 21 v 22 ) U = \begin{pmatrix} u_{11} & u_{12} & u_{13} \\ u_{21} & u_{22} & u_{23} \\ u_{31} & u_{32} & u_{33} \end{pmatrix}, \quad \Sigma = \begin{pmatrix} \sigma_1 & 0 \\ 0 & \sigma_2 \\ 0 & 0 \end{pmatrix}, \quad V = \begin{pmatrix} v_{11} & v_{12} \\ v_{21} & v_{22} \end{pmatrix} U= u11u21u31u12u22u32u13u23u33 ,Σ= σ1000σ20 ,V=(v11v21v12v22)

这里的 σ 1 \sigma_1 σ1 σ 2 \sigma_2 σ2就是矩阵 A A A 的奇异值。而奇异值的求解我们仍可以借助PyTorch:

import torch

# 创建一个随机矩阵
A = torch.tensor([[1,2],[3,4],[5,6]],dtype=torch.float32)

# 使用 torch.svd 进行奇异值分解
U, S, Vt = torch.svd(A)

print("Left singular vectors (U):")
print(U)
print("Singular values (S):")
print(S)
print("Right singular vectors (V^T):")
print(Vt)

输出为:

Left singular vectors (U):
tensor([[-0.2298,  0.8835],
        [-0.5247,  0.2408],
        [-0.8196, -0.4019]])
Singular values (S):
tensor([9.5255, 0.5143])
Right singular vectors (V^T):
tensor([[-0.6196, -0.7849],
        [-0.7849,  0.6196]])

我们可以反过来通过重构 A A A来验算下过程的正确性:

import numpy as np
# 重构矩阵 A
Sigma = np.zeros((3, 2),dtype=np.float32)
Sigma[:2, :2] = np.diag(S)

A_reconstructed = U @ Sigma @ Vt
print(A_reconstructed)

输出为:

tensor([[1.0000, 2.0000],
        [3.0000, 4.0000],
        [5.0000, 6.0000]])
3.6 奇异值在深度学习中的应用

权重的奇异值在深度学习中具有重要的意义,因为它们反映了权重矩阵的结构和性质。可以提供关于模型复杂度、稳定性以及潜在的优化方向的信息。

  1. 矩阵的秩与模型复杂度:非零奇异值较高意味着秩较大,这通常意味着模型有更多的自由度来拟合数据。如果秩过高,模型可能会过拟合;如果秩过低,则可能导致欠拟合。

  2. 模型的稳定性:条件数是矩阵的最大奇异值与最小非零奇异值的比值。条件数越大,矩阵越接近奇异,这意味着模型可能对输入数据的变化更加敏感。条件数较大的矩阵在数值计算中容易出现问题,如梯度消失或梯度爆炸。通过观察权重矩阵的奇异值分布,可以评估模型的数值稳定性。

  3. 模型的可解释性:奇异值分解不仅提供了奇异值,还提供了左奇异向量和右奇异向量。这些向量可以解释为模型中的重要特征或模式。通过分析奇异向量,可以识别哪些特征对于模型的决策最重要,从而帮助进行特征选择或特征工程。

  4. 模型压缩与加速:通过保留权重矩阵的最大几个奇异值及其对应的奇异向量,可以构建低秩近似矩阵。这种方法可以显著减少模型的参数数量,从而实现模型压缩。低秩近似不仅可以减少参数数量,还可以减少计算复杂度,从而提高模型的推理速度。

  5. 正则化与防止过拟合:通过正则化技术(如 L2 正则化)惩罚权重矩阵的范数,可以间接地控制奇异值的大小,从而控制矩阵的秩。通过限制奇异值的大小,可以减少模型的复杂度,从而防止过拟合现象的发生。

09-10 09:57