文章目录
0. 前言
按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解及成果,但是内容可能存在不准确的地方。如果发现文中错误,希望批评指正,共同进步。
在深度学习中,线性代数是最基础数学工具,它为构建和理解神经网络提供了必要的数学框架。这门课程虽然是我们大学中的必修课,但是由于其内容的晦涩、抽象以及缺少实际应用说明,是最容易还给老师的学科。
本文将汇总在深度学习中常用的、又是非常容易被忘记的线性代数知识点,并结合PyTorch代码以及深度学习中的实际应用加以说明。本文适用于任何想认真研究深度学习的新手,而对于老手同样也推荐再学习一下线性代数以夯实基础,并能激发出更深层次的思考。
这是一个系列文章,相关文章链接如下:
- 第一篇:基础概念、秩、奇异值(本篇)
- 第二篇:行列式、逆矩阵、特征值与特征向量
- 第三篇:协方差矩阵、主成分分析、正交性与正定性
1. 基础概念
这一章是基础中的基础,也都非常好理解,大多数人可以跳过此章节~
-
向量:一个向量可以用一个列向量来表示:
v = ( 1 2 3 ) \mathbf{v} = \begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix} v= 123 -
矩阵:一个简单的 2x3 矩阵可以写作:
A = ( 1 2 3 4 5 6 ) A = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} A=(142536) -
标量:一个标量就是一个单独的数字:
s = 3 s = 3 s=3 -
向量加法:假设我们有两个向量 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) -
向量标量乘法:如果用标量 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} 2⋅v=2⋅ 123 = 2⋅12⋅22⋅3 = 246 -
矩阵加法:如果有两个同维度的矩阵 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) -
矩阵标量乘法:如果用标量 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} 3⋅A=3⋅(1324)=(3⋅13⋅33⋅23⋅4)=(39612) -
矩阵乘法(点乘):假设有两个矩阵 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=((1⋅7+2⋅9+3⋅11)(4⋅7+5⋅9+6⋅11)(1⋅8+2⋅10+3⋅12)(4⋅8+5⋅10+6⋅12))=(5813964154) -
转置:矩阵 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 -
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=A∘B 将会是:
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=(1⋅53⋅72⋅64⋅8)=(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 秩的计算方法
计算矩阵的秩有多种方法,以下种常见的计算方法:
- 行阶梯形形式(Row Echelon Form, REF)
- 行最简形(Reduced Row Echelon Form, RREF)
- 高斯消元法(Gaussian Elimination)
- 高斯-若尔当消元法(Gauss-Jordan Elimination)
- 奇异值分解(Singular Value Decomposition, SVD)
- QR 分解(QR Decomposition)
- LU 分解(LU Decomposition)
- 列空间和零空间(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 秩在深度学习中的应用
- 低秩近似:通过将高维的权重矩阵分解为低秩矩阵的乘积,可以显著减少模型的参数数量,从而实现模型压缩。这不仅减少了模型的存储需求,还能加速模型的训练和推理过程。
- 特征选择:通过对权重矩阵的秩进行分析,可以识别出哪些特征是冗余的(联想下上面说的“没有用”的方程),从而帮助进行特征选择,进一步减少模型复杂度。
- 正则化:通过正则化技术(如 L1 或 L2 正则化)来惩罚权重矩阵的范数,间接控制矩阵的秩(简单来说,正则化惩罚会鼓励权重矩阵中的元素变为0,如果矩阵中有多个零向量,那么矩阵的秩就会下降。),从而减少模型的复杂度,防止过拟合。
- 模型泛化能力:适当的矩阵秩有助于提升模型的泛化能力。如果矩阵的秩过高,可能导致模型过于复杂而过拟合;如果秩过低,则可能使模型过于简单而欠拟合。
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 奇异值的性质
- 非负性:奇异值是非负实数,即 σ i ≥ 0 \sigma_i \geq 0 σi≥0。
- 排序:通常情况下,奇异值按从大到小的顺序排列,即 σ 1 ≥ σ 2 ≥ … ≥ σ r > 0 \sigma_1 \geq \sigma_2 \geq \ldots \geq \sigma_r > 0 σ1≥σ2≥…≥σr>0。
- 秩:矩阵的秩等于非零奇异值的数量。
- 范数:最大奇异值是矩阵的谱范数(spectral norm),即 ∥ A ∥ 2 = σ 1 \|A\|_2 = \sigma_1 ∥A∥2=σ1。
- 伪逆:奇异值分解可以用于计算矩阵的伪逆(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 奇异值在深度学习中的应用
权重的奇异值在深度学习中具有重要的意义,因为它们反映了权重矩阵的结构和性质。可以提供关于模型复杂度、稳定性以及潜在的优化方向的信息。
-
矩阵的秩与模型复杂度:非零奇异值较高意味着秩较大,这通常意味着模型有更多的自由度来拟合数据。如果秩过高,模型可能会过拟合;如果秩过低,则可能导致欠拟合。
-
模型的稳定性:条件数是矩阵的最大奇异值与最小非零奇异值的比值。条件数越大,矩阵越接近奇异,这意味着模型可能对输入数据的变化更加敏感。条件数较大的矩阵在数值计算中容易出现问题,如梯度消失或梯度爆炸。通过观察权重矩阵的奇异值分布,可以评估模型的数值稳定性。
-
模型的可解释性:奇异值分解不仅提供了奇异值,还提供了左奇异向量和右奇异向量。这些向量可以解释为模型中的重要特征或模式。通过分析奇异向量,可以识别哪些特征对于模型的决策最重要,从而帮助进行特征选择或特征工程。
-
模型压缩与加速:通过保留权重矩阵的最大几个奇异值及其对应的奇异向量,可以构建低秩近似矩阵。这种方法可以显著减少模型的参数数量,从而实现模型压缩。低秩近似不仅可以减少参数数量,还可以减少计算复杂度,从而提高模型的推理速度。
-
正则化与防止过拟合:通过正则化技术(如 L2 正则化)惩罚权重矩阵的范数,可以间接地控制奇异值的大小,从而控制矩阵的秩。通过限制奇异值的大小,可以减少模型的复杂度,从而防止过拟合现象的发生。