机器学习中的数学——线性空间与基

线性空间与基:机器学习背后的坐标系统

今天简单聊聊线性空间这两个概念。别看它们听起来很数学很抽象,其实这是整个机器学习大厦的地基------没有它们,神经网络就无法"看懂"数据,梯度下降也找不到方向。

你可能会想:不就是向量和坐标吗?我在高中就学过啊。等等,先别急。线性空间这个概念,远比你想象的要深刻。它不只是三维空间里的箭头,而是一个让数学家重新理解"空间"的革命性想法。今天我们就来聊聊,这个看似基础的概念,是怎么一步步演变成深度学习模型的核心语言的。

第一部分:线性空间的诞生------从具体到抽象的伟大跨越

历史溯源:数学家的"升维打击"

故事要从19世纪说起。

那时候,数学家们已经对三维空间里的几何驾轻就熟了------点、线、面、体,欧几里得几何玩了两千年。但问题来了:物理学家开始研究振动、波动、热传导,他们发现自己需要处理的不是三个数字,而是无穷多个数字

比如一根弦的振动,你不能只用三个坐标来描述它------弦上每一个点都在动,你需要一个函数来描述它。函数本身就成了一个"点",一个存在于某种"函数空间"里的点。

这时候,数学家们突然意识到:我们能不能把"空间"这个概念,从具体的三维世界里抽象出来?能不能定义一种更一般的空间,既包括普通的三维空间,也包括函数空间、矩阵空间,甚至更奇怪的东西?

1888年,意大利数学家Peano和德国数学家Hermann Grassmann(早在1844年就提出了雏形)给出了答案:线性空间(向量空间)的公理化定义。这是数学史上的一次"升维打击"------他们不再纠结于具体的几何图形,而是直接定义了"线性"这个本质。

为什么叫"线性"?因为它的核心特征就是:加法数乘。只要满足这两个运算的特定规则,不管你是三维向量、函数、矩阵还是多项式,都是线性空间的一员。

深层直觉:什么是"空间"?

好,定义先放一边,我们先建立直觉。

想象你在一个完全黑暗的房间里。你什么都看不见,但你可以:

  1. 向任意方向走(加法:从一个位置到另一个位置)
  2. 走得更远或更近(数乘:走2倍远,或走一半远)

只要你能做这两件事,并且它们满足一些"常识"(比如先走再走,顺序可以换;走2倍再走3倍,等于走5倍),那这个黑暗房间就是一个线性空间

关键洞察来了:你不需要知道这个房间到底长什么样。它可能是普通的三维房间,可能是四维时空,可能是无限维的函数海洋------都不重要。重要的是,只要"加法"和"数乘"的规则成立,所有线性代数的工具都能用。

这就是抽象数学的威力:一次证明,处处适用

换句话说,线性空间是数学家提炼出的"运动的本质"------不管你在什么样的空间里,只要能线性地移动和缩放,你就在玩同一个游戏。

第二部分:线性空间的定义------八条公理的美丽对称

正式定义(但别慌,我们慢慢讲)

一个线性空间 (或叫向量空间)VVV,是一个集合,它的元素叫向量,并且定义了两个运算:

  1. 加法 :u+v∈V\mathbf{u} + \mathbf{v} \in Vu+v∈V(两个向量相加还是向量)
  2. 数乘 :cv∈Vc\mathbf{v} \in Vcv∈V(向量乘以一个数还是向量,这里ccc来自某个数域,通常是实数R\mathbb{R}R或复数C\mathbb{C}C)

这两个运算需要满足八条公理

加法的性质(4条):

  1. 交换律 :u+v=v+u\mathbf{u} + \mathbf{v} = \mathbf{v} + \mathbf{u}u+v=v+u
  2. 结合律 :(u+v)+w=u+(v+w)(\mathbf{u} + \mathbf{v}) + \mathbf{w} = \mathbf{u} + (\mathbf{v} + \mathbf{w})(u+v)+w=u+(v+w)
  3. 零向量 :存在0\mathbf{0}0使得v+0=v\mathbf{v} + \mathbf{0} = \mathbf{v}v+0=v
  4. 逆元 :对每个v\mathbf{v}v,存在−v-\mathbf{v}−v使得v+(−v)=0\mathbf{v} + (-\mathbf{v}) = \mathbf{0}v+(−v)=0

数乘的性质(4条):

  1. 数乘结合律 :a(bv)=(ab)va(b\mathbf{v}) = (ab)\mathbf{v}a(bv)=(ab)v

  2. 单位元 :1v=v1\mathbf{v} = \mathbf{v}1v=v

  3. 分配律1 :(a+b)v=av+bv(a+b)\mathbf{v} = a\mathbf{v} + b\mathbf{v}(a+b)v=av+bv

  4. 分配律2 :a(u+v)=au+ava(\mathbf{u}+\mathbf{v}) = a\mathbf{u} + a\mathbf{v}a(u+v)=au+av

为什么是这八条?

看起来像在背法律条文?其实不是。这八条公理是数学家从无数具体例子中提炼出的最小约束------少一条都不行。

注意到没?这些公理都在说一件事:线性运算要"表现良好"。加法不能突然变得古怪(交换律、结合律),数乘不能跟加法打架(分配律)。

打个比方:如果你在玩一个游戏,游戏规则说"向北走2步再向东走3步"和"向东走3步再向北走2步"结果不一样,那这个游戏就不是"线性"的------它有某种奇怪的扭曲。线性空间就是要排除这种扭曲。

本质是什么?

线性空间的本质,是一个"可以自由组合"的世界。

在这个世界里,你可以把任意向量拿来"混搭"(线性组合),结果还是这个世界的居民。没有禁区,没有边界,一切都可以平滑地过渡。

这跟我们日常的物理世界很像:你可以往任意方向走(向量加法),可以走快走慢(数乘),不会突然掉进黑洞或撞墙(封闭性)。

第三部分:线性空间的具体例子------打开想象力

理论说完了,来点实在的。线性空间到底长什么样?

例子1:Rn\mathbb{R}^nRn ------ 最熟悉的陌生人

这是你最熟悉的:nnn维实数向量空间。

R3={[xyz]:x,y,z∈R}\mathbb{R}^3 = \left\{ \begin{bmatrix} x \\ y \\ z \end{bmatrix} : x,y,z \in \mathbb{R} \right\}R3=⎩ ⎨ ⎧ xyz :x,y,z∈R⎭ ⎬ ⎫

加法和数乘就是逐分量操作:

123\]+\[456\]=\[579\],2\[123\]=\[246\]\\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix} + \\begin{bmatrix} 4 \\\\ 5 \\\\ 6 \\end{bmatrix} = \\begin{bmatrix} 5 \\\\ 7 \\\\ 9 \\end{bmatrix}, \\quad 2\\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix} = \\begin{bmatrix} 2 \\\\ 4 \\\\ 6 \\end{bmatrix} 123 + 456 = 579 ,2 123 = 246 **本质** :这是"坐标空间",每个向量就是nnn个数字排成一队。机器学习里,一条数据(比如图片的像素、文本的embedding)通常就是Rn\\mathbb{R}\^nRn里的一个点。 ```python import numpy as np # 定义两个向量 v1 = np.array([1, 2, 3]) v2 = np.array([4, 5, 6]) # 加法 v_add = v1 + v2 print(f"加法: {v_add}") # [5 7 9] # 数乘 v_scale = 2 * v1 print(f"数乘: {v_scale}") # [2 4 6] # 线性组合 v_comb = 3*v1 + 0.5*v2 print(f"线性组合: {v_comb}") # [5. 8.5 12. ] ``` **一句话本质** :Rn\\mathbb{R}\^nRn是数字的直接排列,机器学习的"数据居住地"。 #### 例子2:函数空间 C\[0,1\]C\[0,1\]C\[0,1\] ------ 无限维的海洋 考虑所有在\[0,1\]\[0,1\]\[0,1\]区间上连续的函数: C\[0,1\]={f:\[0,1\]→R∣f 连续}C\[0,1\] = \\{ f: \[0,1\] \\to \\mathbb{R} \\mid f \\text{ 连续}\\}C\[0,1\]={f:\[0,1\]→R∣f 连续} 两个函数相加:(f+g)(x)=f(x)+g(x)(f+g)(x) = f(x) + g(x)(f+g)(x)=f(x)+g(x) 函数数乘:(cf)(x)=c⋅f(x)(cf)(x) = c \\cdot f(x)(cf)(x)=c⋅f(x) 验证一下:如果fff和ggg连续,那f+gf+gf+g和cfcfcf也连续。八条公理都满足。 **本质** :函数本身是"向量"!这个空间是**无限维**的------你需要无穷多个数字来完全描述一个连续函数(函数在每个点的值)。 ```python # 函数作为向量的例子 def f(x): return x**2 def g(x): return np.sin(x) # 函数加法 def f_plus_g(x): return f(x) + g(x) # 函数数乘 def scalar_times_f(x, c=2): return c * f(x) x_vals = np.linspace(0, 1, 100) print(f"f+g 在 x=0.5: {f_plus_g(0.5)}") # 0.25 + sin(0.5) print(f"2f 在 x=0.5: {scalar_times_f(0.5)}") # 2 * 0.25 = 0.5 ``` **一句话本质**:函数空间是无限维的向量空间,神经网络本质上在这个空间里"寻找函数"。 #### 例子3:矩阵空间 Mm×nM_{m \\times n}Mm×n ------ 神经网络的权重世界 所有m×nm \\times nm×n的实矩阵: M2×2={\[abcd\]:a,b,c,d∈R}M_{2 \\times 2} = \\left\\{ \\begin{bmatrix} a \& b \\\\ c \& d \\end{bmatrix} : a,b,c,d \\in \\mathbb{R} \\right\\}M2×2={\[acbd\]:a,b,c,d∈R} 矩阵加法和数乘就是逐元素操作。 **本质** :神经网络的每一层权重矩阵WWW就住在这个空间里。训练过程就是在这个空间里搜索"最优矩阵"。 ```python # 矩阵作为向量 A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) # 矩阵加法 C = A + B print(f"矩阵加法:\n{C}") # 矩阵数乘 D = 0.5 * A print(f"矩阵数乘:\n{D}") # 线性组合(权重更新的本质) learning_rate = 0.01 gradient = np.array([[0.1, 0.2], [0.3, 0.4]]) W_new = A - learning_rate * gradient # 梯度下降! print(f"权重更新:\n{W_new}") ``` **一句话本质**:矩阵空间是深度学习权重的栖息地,梯度下降在此空间中行走。 #### 例子4:多项式空间 PnP_nPn ------ 代数的乐园 所有次数不超过nnn的多项式: P2={a0+a1x+a2x2:a0,a1,a2∈R}P_2 = \\{ a_0 + a_1 x + a_2 x\^2 : a_0, a_1, a_2 \\in \\mathbb{R} \\}P2={a0+a1x+a2x2:a0,a1,a2∈R} 比如3+2x−x23 + 2x - x\^23+2x−x2和5−x+4x25 - x + 4x\^25−x+4x2都是P2P_2P2的元素。 加法:(3+2x−x2)+(5−x+4x2)=8+x+3x2(3+2x-x\^2) + (5-x+4x\^2) = 8+x+3x\^2(3+2x−x2)+(5−x+4x2)=8+x+3x2 数乘:2(3+2x−x2)=6+4x−2x22(3+2x-x\^2) = 6+4x-2x\^22(3+2x−x2)=6+4x−2x2 **本质**:多项式可以看作"特殊的函数",在机器学习的特征工程中(比如多项式回归),我们就在这个空间里工作。 ```python # 用numpy的poly1d表示多项式 p1 = np.poly1d([1, 2, 3]) # x^2 + 2x + 3 p2 = np.poly1d([4, 5, 6]) # 4x^2 + 5x + 6 # 多项式加法 p_add = p1 + p2 print(f"多项式加法: {p_add}") # 5x^2 + 7x + 9 # 多项式数乘 p_scale = 2 * p1 print(f"多项式数乘: {p_scale}") # 2x^2 + 4x + 6 ``` **一句话本质**:多项式空间让我们用"系数向量"来操作函数,特征工程的代数基础。 #### 为什么举这些例子? 注意到没?这些例子**表面上完全不同**------数字、函数、矩阵、多项式------但它们都遵守同样的八条公理。这意味着: **你在R3\\mathbb{R}\^3R3里学到的所有线性代数技巧,直接搬到函数空间、矩阵空间都能用!** 这就是抽象的威力。你不需要为每种空间重新发明轮子,所有"线性"的性质都是通用的。 ### 第四部分:基------空间的"身份证系统" 现在进入核心概念:**基**(basis)。 如果说线性空间是一个世界,那基就是这个世界的**坐标系统**,是我们用来"定位"每个向量的工具。 #### 历史溯源:坐标的革命 公元1637年,笛卡尔(Descartes)发明了**坐标系**------他把代数和几何统一了起来。突然间,几何问题可以用代数解决,代数问题可以用几何直观理解。 但笛卡尔的坐标系有个隐含假设:**你已经选好了xxx轴和yyy轴**。问题来了:为什么是这两个轴?能不能换成别的? 到了19世纪,数学家们意识到:坐标系的选择是**任意** 的。同一个向量,在不同的坐标系下,坐标完全不同。但向量本身没变------它还是它,只是我们**描述它的方式**变了。 这就引出了**基**的概念:基是一组特殊的向量,它们定义了坐标系的"轴"。选择不同的基,就是选择不同的观察角度。 #### 深层直觉:基是"测量尺" 想象你在一个平面上,手里有两把尺子(两个非零向量e1\\mathbf{e}_1e1和e2\\mathbf{e}_2e2)。现在给你一个点v\\mathbf{v}v,你要告诉我这个点的"位置"。 你可以这样描述: * 沿着e1\\mathbf{e}_1e1走aaa个单位 * 沿着e2\\mathbf{e}_2e2走bbb个单位 * 就到了v\\mathbf{v}v 数学上写成:v=ae1+be2\\mathbf{v} = a\\mathbf{e}_1 + b\\mathbf{e}_2v=ae1+be2 这里(a,b)(a, b)(a,b)就是v\\mathbf{v}v在基{e1,e2}\\{\\mathbf{e}_1, \\mathbf{e}_2\\}{e1,e2}下的**坐标**。 关键洞察:**基不是向量本身的属性,而是我们观察向量的方式**。 换个基,坐标就变了,但向量本身纹丝不动------就像你换了一把尺子测量房间,房间的大小没变,只是测出来的数字变了。 #### 正式定义:线性无关与张成 一组向量{v1,v2,...,vn}\\{\\mathbf{v}_1, \\mathbf{v}_2, \\ldots, \\mathbf{v}_n\\}{v1,v2,...,vn}是线性空间VVV的一组**基**,需要满足两个条件: **1. 线性无关(Linear Independence)** 没有任何一个向量能被其他向量的线性组合表示。数学上: c1v1+c2v2+⋯+cnvn=0  ⟹  c1=c2=⋯=cn=0c_1\\mathbf{v}_1 + c_2\\mathbf{v}_2 + \\cdots + c_n\\mathbf{v}_n = \\mathbf{0} \\implies c_1 = c_2 = \\cdots = c_n = 0c1v1+c2v2+⋯+cnvn=0⟹c1=c2=⋯=cn=0 **直觉**:每个基向量都提供了"新的方向",没有冗余信息。就像你用两把尺子测量平面,如果第二把尺子跟第一把平行,那它就没用------它没有提供新维度。 **2. 张成(Span)整个空间** 空间里的任意向量都能写成基向量的线性组合: ∀v∈V,∃c1,...,cn:v=c1v1+⋯+cnvn\\forall \\mathbf{v} \\in V, \\exists c_1, \\ldots, c_n: \\mathbf{v} = c_1\\mathbf{v}_1 + \\cdots + c_n\\mathbf{v}_n∀v∈V,∃c1,...,cn:v=c1v1+⋯+cnvn **直觉**:这组基"够用"了,能触及空间的每个角落。就像两把合适的尺子足以定位平面上的任意点,不需要第三把。 #### 为什么这两个条件? * **线性无关** 保证了坐标的**唯一性**:每个向量只有一种方式用基来表示。 * **张成** 保证了坐标的**完备性**:每个向量都能被表示。 缺一不可。如果基向量不是线性无关的,同一个向量可能有无数种坐标表示(坐标不唯一);如果不张成整个空间,有些向量就表示不出来(坐标不完备)。 #### 具体例子:R3\\mathbb{R}\^3R3的标准基 最常见的基是**标准基**: e1=\[100\],e2=\[010\],e3=\[001\]\\mathbf{e}_1 = \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\end{bmatrix}, \\quad \\mathbf{e}_2 = \\begin{bmatrix} 0 \\\\ 1 \\\\ 0 \\end{bmatrix}, \\quad \\mathbf{e}_3 = \\begin{bmatrix} 0 \\\\ 0 \\\\ 1 \\end{bmatrix}e1= 100 ,e2= 010 ,e3= 001 任何向量v=\[v1v2v3\]\\mathbf{v} = \\begin{bmatrix} v_1 \\\\ v_2 \\\\ v_3 \\end{bmatrix}v= v1v2v3 都可以写成: v=v1e1+v2e2+v3e3\\mathbf{v} = v_1\\mathbf{e}_1 + v_2\\mathbf{e}_2 + v_3\\mathbf{e}_3v=v1e1+v2e2+v3e3 **本质**:标准基下的坐标就是向量的"原始分量",这是最自然的选择------但不是唯一的选择! ```python # 标准基和坐标表示 e1 = np.array([1, 0, 0]) e2 = np.array([0, 1, 0]) e3 = np.array([0, 0, 1]) v = np.array([3, -2, 5]) # v在标准基下的坐标就是 [3, -2, 5] # 验证: v = 3*e1 + (-2)*e2 + 5*e3 v_reconstructed = 3*e1 + (-2)*e2 + 5*e3 print(f"重构向量: {v_reconstructed}") # [3 -2 5] print(f"是否相等: {np.allclose(v, v_reconstructed)}") # True ``` #### 例子2:换个基看看 考虑另一组基: b1=\[110\],b2=\[101\],b3=\[011\]\\mathbf{b}_1 = \\begin{bmatrix} 1 \\\\ 1 \\\\ 0 \\end{bmatrix}, \\quad \\mathbf{b}_2 = \\begin{bmatrix} 1 \\\\ 0 \\\\ 1 \\end{bmatrix}, \\quad \\mathbf{b}_3 = \\begin{bmatrix} 0 \\\\ 1 \\\\ 1 \\end{bmatrix}b1= 110 ,b2= 101 ,b3= 011 同一个向量v=\[3−25\]\\mathbf{v} = \\begin{bmatrix} 3 \\\\ -2 \\\\ 5 \\end{bmatrix}v= 3−25 在这组基下的坐标是什么? 需要解方程: c1b1+c2b2+c3b3=vc_1\\mathbf{b}_1 + c_2\\mathbf{b}_2 + c_3\\mathbf{b}_3 = \\mathbf{v}c1b1+c2b2+c3b3=v c1\[110\]+c2\[101\]+c3\[011\]=\[3−25\]c_1\\begin{bmatrix} 1 \\\\ 1 \\\\ 0 \\end{bmatrix} + c_2\\begin{bmatrix} 1 \\\\ 0 \\\\ 1 \\end{bmatrix} + c_3\\begin{bmatrix} 0 \\\\ 1 \\\\ 1 \\end{bmatrix} = \\begin{bmatrix} 3 \\\\ -2 \\\\ 5 \\end{bmatrix}c1 110 +c2 101 +c3 011 = 3−25 这是个线性方程组: {c1+c2=3c1+c3=−2c2+c3=5\\begin{cases} c_1 + c_2 = 3 \\\\ c_1 + c_3 = -2 \\\\ c_2 + c_3 = 5 \\end{cases}⎩ ⎨ ⎧c1+c2=3c1+c3=−2c2+c3=5 解得:c1=−2,c2=5,c3=0c_1 = -2, c_2 = 5, c_3 = 0c1=−2,c2=5,c3=0 所以v\\mathbf{v}v在新基下的坐标是\[−2,5,0\]\[-2, 5, 0\]\[−2,5,0\]! ```python # 新基 b1 = np.array([1, 1, 0]) b2 = np.array([1, 0, 1]) b3 = np.array([0, 1, 1]) # 构造基矩阵 (每列是一个基向量) B = np.column_stack([b1, b2, b3]) print(f"基矩阵 B:\n{B}") # 求解 B * c = v,得到新坐标 c v = np.array([3, -2, 5]) c = np.linalg.solve(B, v) print(f"新基下的坐标: {c}") # [-2. 5. 0.] # 验证 v_reconstructed = c[0]*b1 + c[1]*b2 + c[2]*b3 print(f"重构向量: {v_reconstructed}") # [ 3. -2. 5.] ``` **一句话本质**:换基就是换"观察角度",向量不变,坐标变。 ### 第五部分:维度------空间的"自由度" #### 维度的定义 一个线性空间VVV的**维度**,是它的任意一组基所包含的向量个数。 记作dim⁡(V)\\dim(V)dim(V)。 惊喜来了:**所有基的向量个数都一样**!这是线性代数的一个基本定理。 换句话说:不管你怎么选基,基向量的个数是固定的------这个数字刻画了空间的"自由度"。 #### 为什么维度是本质的? 维度告诉你:要完全描述这个空间里的一个向量,**最少需要几个数字**。 * R3\\mathbb{R}\^3R3是3维的:需要3个数字(x,y,z)(x, y, z)(x,y,z) * P2P_2P2(二次多项式)是3维的:需要3个系数(a0,a1,a2)(a_0, a_1, a_2)(a0,a1,a2) * M2×2M_{2 \\times 2}M2×2(2×2矩阵)是4维的:需要4个元素 但C\[0,1\]C\[0,1\]C\[0,1\](连续函数空间)是**无限维**的:需要无穷多个数字才能完全描述一个函数。 #### 例子:多项式空间的维度 P2={a0+a1x+a2x2:a0,a1,a2∈R}P_2 = \\{ a_0 + a_1 x + a_2 x\^2 : a_0, a_1, a_2 \\in \\mathbb{R} \\}P2={a0+a1x+a2x2:a0,a1,a2∈R} 一组自然的基是:{1,x,x2}\\{1, x, x\^2\\}{1,x,x2} 任何二次多项式都能写成: p(x)=a0⋅1+a1⋅x+a2⋅x2p(x) = a_0 \\cdot 1 + a_1 \\cdot x + a_2 \\cdot x\^2p(x)=a0⋅1+a1⋅x+a2⋅x2 这组基有3个元素,所以dim⁡(P2)=3\\dim(P_2) = 3dim(P2)=3。 但我们也可以选别的基!比如:{1,1+x,1+x+x2}\\{1, 1+x, 1+x+x\^2\\}{1,1+x,1+x+x2} 验证线性无关:假设c0⋅1+c1(1+x)+c2(1+x+x2)=0c_0 \\cdot 1 + c_1(1+x) + c_2(1+x+x\^2) = 0c0⋅1+c1(1+x)+c2(1+x+x2)=0 展开:(c0+c1+c2)+(c1+c2)x+c2x2=0(c_0+c_1+c_2) + (c_1+c_2)x + c_2 x\^2 = 0(c0+c1+c2)+(c1+c2)x+c2x2=0 这要求: {c0+c1+c2=0c1+c2=0c2=0\\begin{cases} c_0+c_1+c_2 = 0 \\\\ c_1+c_2 = 0 \\\\ c_2 = 0 \\end{cases}⎩ ⎨ ⎧c0+c1+c2=0c1+c2=0c2=0 解得c0=c1=c2=0c_0 = c_1 = c_2 = 0c0=c1=c2=0,所以线性无关!并且它们也张成P2P_2P2(可以验证)。 虽然基不同,但向量个数还是3------维度不变。 ```python # 多项式基的表示 # 标准基: {1, x, x^2} # 新基: {1, 1+x, 1+x+x^2} # 多项式 p(x) = 3 + 2x - x^2 在标准基下的坐标是 [3, 2, -1] # 在新基下的坐标是多少?需要解: # c0 * 1 + c1 * (1+x) + c2 * (1+x+x^2) = 3 + 2x - x^2 # 展开: (c0+c1+c2) + (c1+c2)x + c2*x^2 = 3 + 2x - x^2 # 得到方程组: # c0 + c1 + c2 = 3 # c1 + c2 = 2 # c2 = -1 # 解得: c2=-1, c1=3, c0=1 print("多项式 3 + 2x - x^2") print("标准基坐标: [3, 2, -1]") print("新基坐标: [1, 3, -1]") # 验证 c = np.array([1, 3, -1]) # 1*1 + 3*(1+x) + (-1)*(1+x+x^2) = 1 + 3 + 3x - 1 - x - x^2 = 3 + 2x - x^2 ✓ ``` **一句话本质**:维度是空间的"信息容量",基变坐标变但维度不变。 ### 第六部分:坐标系统------从向量到数字 #### 坐标的定义 给定线性空间VVV和一组基B={b1,...,bn}\\mathcal{B} = \\{\\mathbf{b}_1, \\ldots, \\mathbf{b}_n\\}B={b1,...,bn},任意向量v∈V\\mathbf{v} \\in Vv∈V都可以唯一地写成: v=c1b1+c2b2+⋯+cnbn\\mathbf{v} = c_1\\mathbf{b}_1 + c_2\\mathbf{b}_2 + \\cdots + c_n\\mathbf{b}_nv=c1b1+c2b2+⋯+cnbn 这些系数(c1,...,cn)(c_1, \\ldots, c_n)(c1,...,cn)组成的列向量: \[v\]B=\[c1c2⋮cn\]\[\\mathbf{v}\]_{\\mathcal{B}} = \\begin{bmatrix} c_1 \\\\ c_2 \\\\ \\vdots \\\\ c_n \\end{bmatrix}\[v\]B= c1c2⋮cn 叫做v\\mathbf{v}v在基B\\mathcal{B}B下的**坐标向量**。 #### 深层含义:从抽象到具体的桥梁 这是个极其重要的概念:**坐标向量让抽象的向量变成了具体的数字**。 * v\\mathbf{v}v本身可能是个函数、矩阵、多项式------很抽象 * \[v\]B\[\\mathbf{v}\]_{\\mathcal{B}}\[v\]B是Rn\\mathbb{R}\^nRn里的一个普通数组------很具体 一旦选定基B\\mathcal{B}B,整个抽象空间VVV就**同构** 于Rn\\mathbb{R}\^nRn------它们本质上是"同一个空间",只是换了件马甲。 这就是为什么计算机能处理各种抽象对象:**只要选好基,一切都变成数组**! #### 例子:函数的坐标表示 考虑P2P_2P2空间,选基B={1,x,x2}\\mathcal{B} = \\{1, x, x\^2\\}B={1,x,x2}。 函数p(x)=3+2x−x2p(x) = 3 + 2x - x\^2p(x)=3+2x−x2的坐标向量是: \[p\]B=\[32−1\]\[p\]_{\\mathcal{B}} = \\begin{bmatrix} 3 \\\\ 2 \\\\ -1 \\end{bmatrix}\[p\]B= 32−1 突然间,一个函数变成了三个数字!你可以用R3\\mathbb{R}\^3R3的所有工具来处理它。 ```python # 多项式作为向量 # 基: {1, x, x^2} # 多项式 p(x) = 3 + 2x - x^2 的坐标 p_coords = np.array([3, 2, -1]) # 多项式 q(x) = 1 - 2x + 3x^2 的坐标 q_coords = np.array([1, -2, 3]) # 多项式加法 -> 坐标加法 pq_coords = p_coords + q_coords print(f"(p+q)的坐标: {pq_coords}") # [4 0 2] -> 4 + 0x + 2x^2 # 数乘 -> 坐标数乘 scaled_p = 2 * p_coords print(f"(2p)的坐标: {scaled_p}") # [6 4 -2] -> 6 + 4x - 2x^2 # 内积 -> 坐标内积 (定义合适的内积) inner_prod = np.dot(p_coords, q_coords) print(f"坐标内积: {inner_prod}") # 3*1 + 2*(-2) + (-1)*3 = 3 - 4 - 3 = -4 ``` **一句话本质**:坐标是"抽象向量"的"数字身份证",让计算机能懂。 ### 第七部分:基变换------换个角度看世界 现在来到最精妙的部分:**基变换**(change of basis)。 同一个向量,在不同基下有不同坐标。那这些坐标之间有什么关系? #### 基变换矩阵 设有两组基: * 旧基B={b1,...,bn}\\mathcal{B} = \\{\\mathbf{b}_1, \\ldots, \\mathbf{b}_n\\}B={b1,...,bn} * 新基C={c1,...,cn}\\mathcal{C} = \\{\\mathbf{c}_1, \\ldots, \\mathbf{c}_n\\}C={c1,...,cn} 每个新基向量都能用旧基表示: cj=p1jb1+p2jb2+⋯+pnjbn\\mathbf{c}_j = p_{1j}\\mathbf{b}_1 + p_{2j}\\mathbf{b}_2 + \\cdots + p_{nj}\\mathbf{b}_ncj=p1jb1+p2jb2+⋯+pnjbn 把所有pijp_{ij}pij组成矩阵: P=\[p11p12⋯p1np21p22⋯p2n⋮⋮⋱⋮pn1pn2⋯pnn\]P = \\begin{bmatrix} p_{11} \& p_{12} \& \\cdots \& p_{1n} \\\\ p_{21} \& p_{22} \& \\cdots \& p_{2n} \\\\ \\vdots \& \\vdots \& \\ddots \& \\vdots \\\\ p_{n1} \& p_{n2} \& \\cdots \& p_{nn} \\end{bmatrix}P= p11p21⋮pn1p12p22⋮pn2⋯⋯⋱⋯p1np2n⋮pnn 这个PPP叫做从B\\mathcal{B}B到C\\mathcal{C}C的**基变换矩阵**(或过渡矩阵)。 神奇的公式来了: \[v\]B=P\[v\]C\[\\mathbf{v}\]_{\\mathcal{B}} = P \[\\mathbf{v}\]_{\\mathcal{C}}\[v\]B=P\[v\]C 或者反过来: \[v\]C=P−1\[v\]B\[\\mathbf{v}\]_{\\mathcal{C}} = P\^{-1} \[\\mathbf{v}\]_{\\mathcal{B}}\[v\]C=P−1\[v\]B #### 直觉解释 基变换矩阵PPP的第jjj列,就是新基的第jjj个向量cj\\mathbf{c}_jcj在旧基下的坐标。 当你把向量从新坐标系"翻译"成旧坐标系时,就是用PPP左乘;反之用P−1P\^{-1}P−1。 **本质**:基变换是"翻译",向量本身不动,只是换了描述方式。 #### 具体例子:R2\\mathbb{R}\^2R2的旋转基 标准基:E={\[10\],\[01\]}\\mathcal{E} = \\left\\{ \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}, \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\right\\}E={\[10\],\[01\]} 旋转45°45°45°的新基: B={\[cos⁡45°sin⁡45°\],\[−sin⁡45°cos⁡45°\]}={\[1212\],\[−1212\]}\\mathcal{B} = \\left\\{ \\begin{bmatrix} \\cos 45° \\\\ \\sin 45° \\end{bmatrix}, \\begin{bmatrix} -\\sin 45° \\\\ \\cos 45° \\end{bmatrix} \\right\\} = \\left\\{ \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix}, \\begin{bmatrix} -\\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\right\\}B={\[cos45°sin45°\],\[−sin45°cos45°\]}={\[2 12 1\],\[−2 12 1\]} 基变换矩阵(从B\\mathcal{B}B到E\\mathcal{E}E): P=\[12−121212\]P = \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \& -\\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \& \\frac{1}{\\sqrt{2}} \\end{bmatrix}P=\[2 12 1−2 12 1

向量v=[20]\mathbf{v} = \begin{bmatrix} 2 \\ 0 \end{bmatrix}v=[20]在标准基下的坐标是[2,0]T[2, 0]^T[2,0]T。

在新基下的坐标:

v\]B=P−1\[20\]=\[1212−1212\]\[20\]=\[2−2\]\[\\mathbf{v}\]_{\\mathcal{B}} = P\^{-1} \\begin{bmatrix} 2 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \& \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \& \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\begin{bmatrix} 2 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} \\sqrt{2} \\\\ -\\sqrt{2} \\end{bmatrix}\[v\]B=P−1\[20\]=\[2 1−2 12 12 1\]\[20\]=\[2 −2

python 复制代码
import numpy as np

# 标准基
e1 = np.array([1, 0])
e2 = np.array([0, 1])

# 旋转45度的新基
theta = np.pi / 4
b1 = np.array([np.cos(theta), np.sin(theta)])
b2 = np.array([-np.sin(theta), np.cos(theta)])

# 基变换矩阵 P (从新基到旧基)
# P的列是新基向量在旧基下的坐标
P = np.column_stack([b1, b2])
print(f"基变换矩阵 P:\n{P}")

# 向量 v = [2, 0] 在标准基下
v_std = np.array([2, 0])

# 转换到新基
v_new = np.linalg.inv(P) @ v_std
print(f"新基下的坐标: {v_new}")  # [ 1.41421356 -1.41421356]

# 验证:用新基重构
v_reconstructed = v_new[0]*b1 + v_new[1]*b2
print(f"重构向量: {v_reconstructed}")  # [2. 0.]
print(f"误差: {np.linalg.norm(v_std - v_reconstructed)}")  # 接近0

一句话本质:基变换矩阵是"坐标翻译器",连接不同观察视角。

第八部分:基的选择------为什么要换基?

你可能会想:标准基不就挺好的吗,为什么要费劲换基?

答案是:不同的基凸显不同的特性。选对基,复杂问题可以变简单。

应用1:对角化------让矩阵变简单

考虑矩阵A=[4123]A = \begin{bmatrix} 4 & 1 \\ 2 & 3 \end{bmatrix}A=[4213]。

在标准基下,计算A100A^{100}A100很麻烦。但如果我们找到一组特殊的基(特征向量),使得AAA在这组基下变成对角矩阵:

D=[λ100λ2]D = \begin{bmatrix} \lambda_1 & 0 \\ 0 & \lambda_2 \end{bmatrix}D=[λ100λ2]

那么D100D^{100}D100就超级简单:

D100=[λ110000λ2100]D^{100} = \begin{bmatrix} \lambda_1^{100} & 0 \\ 0 & \lambda_2^{100} \end{bmatrix}D100=[λ110000λ2100]

这就是特征值分解 的核心思想:换到特征向量基,矩阵变对角

python 复制代码
# 矩阵对角化
A = np.array([[4, 1], [2, 3]])

# 求特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f"特征值: {eigenvalues}")  # [5. 2.]
print(f"特征向量:\n{eigenvectors}")

# 对角化: A = P D P^(-1)
P = eigenvectors
D = np.diag(eigenvalues)

# 验证
A_reconstructed = P @ D @ np.linalg.inv(P)
print(f"重构矩阵:\n{A_reconstructed}")
print(f"误差: {np.linalg.norm(A - A_reconstructed)}")

# 计算 A^100
D_100 = np.diag(eigenvalues**100)
A_100 = P @ D_100 @ np.linalg.inv(P)
print(f"A^100 的一个元素: {A_100[0, 0]:.2e}")  # 巨大的数

应用意义:深度学习中的权重矩阵分析、图神经网络的谱方法,都基于这个思想。

应用2:主成分分析(PCA)------找最重要的方向

PCA的本质就是换基

  1. 原始数据在标准基下,特征之间可能有相关性
  2. 通过协方差矩阵的特征值分解,找到新的基(主成分)
  3. 在新基下,特征之间不相关,且按"重要性"排序

新基的第一个向量是数据方差最大的方向------最重要的特征!

python 复制代码
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris

# 加载数据
iris = load_iris()
X = iris.data  # 4维特征

# PCA降维到2维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

print(f"原始数据形状: {X.shape}")  # (150, 4)
print(f"PCA后形状: {X_pca.shape}")  # (150, 2)
print(f"主成分方向:\n{pca.components_}")  # 新基向量
print(f"解释方差比: {pca.explained_variance_ratio_}")  # 各主成分的重要性

# 本质:X_pca 就是 X 在新基(主成分)下的坐标

一句话本质:PCA换基到"数据方差最大"的方向,抓住主要信息。

应用3:傅里叶变换------时域到频域

信号处理中,时域信号f(t)f(t)f(t)可以看作函数空间里的向量。

傅里叶变换就是换基 :从"时间基"(δ(t−t0)\delta(t-t_0)δ(t−t0))换到"频率基"(eiωte^{i\omega t}eiωt)。

在频率基下,很多信号处理问题(如滤波)变得超级简单。

python 复制代码
# 傅里叶变换:换基到频率域
import matplotlib.pyplot as plt

# 生成时域信号: 混合两个频率
t = np.linspace(0, 1, 1000)
f = np.sin(2*np.pi*5*t) + 0.5*np.sin(2*np.pi*12*t)  # 5Hz + 12Hz

# 傅里叶变换
F = np.fft.fft(f)
freqs = np.fft.fftfreq(len(t), t[1]-t[0])

# F 就是信号在"频率基"下的坐标
# 可以看到两个峰值:5Hz 和 12Hz
plt.figure(figsize=(12, 4))
plt.subplot(121)
plt.plot(t[:100], f[:100])
plt.title("时域信号")
plt.subplot(122)
plt.plot(freqs[:500], np.abs(F)[:500])
plt.title("频域表示(新基下的坐标)")
plt.tight_layout()
# plt.show()

print("傅里叶变换找到的主要频率:", freqs[np.argsort(np.abs(F))[-4:-1]])

一句话本质:傅里叶变换换基到"振荡基",让频率特性一目了然。

应用4:神经网络的隐藏层------学习新基

这是个惊人的洞察:神经网络的每一层,都在隐式地学习一组新基

输入x\mathbf{x}x经过第一层h=σ(W1x+b1)\mathbf{h} = \sigma(W_1\mathbf{x} + \mathbf{b}_1)h=σ(W1x+b1),得到隐藏表示h\mathbf{h}h。

从线性代数角度看:

  • W1W_1W1定义了一组新基(权重矩阵的行向量)
  • h\mathbf{h}h是输入在这组"学习到的基"下的坐标(经过非线性激活)

深度网络就是逐层换基:每层找到更适合任务的表示空间。

python 复制代码
import torch
import torch.nn as nn

# 简单的两层神经网络
model = nn.Sequential(
    nn.Linear(10, 5),  # 第一层:从10维换基到5维
    nn.ReLU(),
    nn.Linear(5, 2)    # 第二层:从5维换基到2维
)

# 输入
x = torch.randn(1, 10)

# 提取中间表示
h1 = model[0](x)  # 第一层输出(新基下的坐标)
h1_act = model[1](h1)  # 激活后
output = model[2](h1_act)  # 最终输出

print(f"输入维度: {x.shape}")  # [1, 10]
print(f"第一层隐藏表示: {h1_act.shape}")  # [1, 5] - 5维基
print(f"输出维度: {output.shape}")  # [1, 2] - 2维基

# 解释:模型在学习最优的基变换
# 第一层的权重 W1 就是从输入空间到隐藏空间的基变换矩阵
print(f"第一层权重矩阵形状: {model[0].weight.shape}")  # [5, 10]
# 每一行定义了隐藏空间的一个基向量(在输入空间中的表示)

一句话本质:神经网络训练是在学习"任务最优基",让分类/回归变简单。

第九部分:正交基------最好用的基

不是所有基都是平等的。有一种基特别好用:正交基(orthogonal basis)。

什么是正交基?

如果基向量之间两两垂直(正交),就叫正交基。

数学上:bi⋅bj=0\mathbf{b}_i \cdot \mathbf{b}_j = 0bi⋅bj=0 当i≠ji \neq ji=j

如果基向量还都是单位长度(∥bi∥=1\|\mathbf{b}_i\| = 1∥bi∥=1),就叫标准正交基(orthonormal basis)。

为什么正交基好用?

1. 坐标计算超级简单

对于正交基{b1,...,bn}\{\mathbf{b}_1, \ldots, \mathbf{b}_n\}{b1,...,bn},向量v\mathbf{v}v的第iii个坐标直接是:

ci=v⋅bi∥bi∥2c_i = \frac{\mathbf{v} \cdot \mathbf{b}_i}{\|\mathbf{b}_i\|^2}ci=∥bi∥2v⋅bi

如果是标准正交基,更简单:ci=v⋅bic_i = \mathbf{v} \cdot \mathbf{b}_ici=v⋅bi

不需要解方程组!

2. 基变换矩阵是正交矩阵

如果两组基都是标准正交的,基变换矩阵PPP满足PTP=IP^T P = IPTP=I,即P−1=PTP^{-1} = P^TP−1=PT。

求逆变成了转置,计算超快!

3. 几何意义清晰

正交基就像标准的"坐标轴",互不干扰,最直观。

例子:R3\mathbb{R}^3R3的标准正交基

e1=[100],e2=[010],e3=[001]\mathbf{e}_1 = \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix}, \quad \mathbf{e}_2 = \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix}, \quad \mathbf{e}_3 = \begin{bmatrix} 0 \\ 0 \\ 1 \end{bmatrix}e1= 100 ,e2= 010 ,e3= 001

显然两两正交:ei⋅ej=0\mathbf{e}_i \cdot \mathbf{e}_j = 0ei⋅ej=0 当i≠ji \neq ji=j

单位长度:∥ei∥=1\|\mathbf{e}_i\| = 1∥ei∥=1

对于v=[3−25]\mathbf{v} = \begin{bmatrix} 3 \\ -2 \\ 5 \end{bmatrix}v= 3−25 ,坐标直接是:

c1=v⋅e1=3,c2=v⋅e2=−2,c3=v⋅e3=5c_1 = \mathbf{v} \cdot \mathbf{e}_1 = 3, \quad c_2 = \mathbf{v} \cdot \mathbf{e}_2 = -2, \quad c_3 = \mathbf{v} \cdot \mathbf{e}_3 = 5c1=v⋅e1=3,c2=v⋅e2=−2,c3=v⋅e3=5

python 复制代码
# 正交基的坐标计算
v = np.array([3, -2, 5])

e1 = np.array([1, 0, 0])
e2 = np.array([0, 1, 0])
e3 = np.array([0, 0, 1])

# 坐标就是内积
c1 = np.dot(v, e1)
c2 = np.dot(v, e2)
c3 = np.dot(v, e3)

print(f"坐标: [{c1}, {c2}, {c3}]")  # [3, -2, 5]

Gram-Schmidt正交化

给定任意一组线性无关的向量,可以通过Gram-Schmidt过程构造出正交基。

算法思路:

  1. 第一个向量u1=v1\mathbf{u}_1 = \mathbf{v}_1u1=v1保持不变
  2. 第二个向量v2\mathbf{v}_2v2减去它在u1\mathbf{u}_1u1上的投影:
    u2=v2−v2⋅u1u1⋅u1u1\mathbf{u}_2 = \mathbf{v}_2 - \frac{\mathbf{v}_2 \cdot \mathbf{u}_1}{\mathbf{u}_1 \cdot \mathbf{u}_1} \mathbf{u}_1u2=v2−u1⋅u1v2⋅u1u1
  3. 第三个向量依次减去在前两个上的投影...

最后把每个ui\mathbf{u}_iui单位化,得到标准正交基。

python 复制代码
def gram_schmidt(vectors):
    """Gram-Schmidt正交化"""
    basis = []
    for v in vectors:
        # 减去在已有基向量上的投影
        u = v.copy()
        for b in basis:
            u = u - (np.dot(v, b) / np.dot(b, b)) * b
        # 单位化
        u = u / np.linalg.norm(u)
        basis.append(u)
    return np.array(basis)

# 例子:三个线性无关但不正交的向量
v1 = np.array([1.0, 1.0, 0.0])
v2 = np.array([1.0, 0.0, 1.0])
v3 = np.array([0.0, 1.0, 1.0])

# 正交化
ortho_basis = gram_schmidt([v1, v2, v3])

print("正交化后的基:")
for i, b in enumerate(ortho_basis):
    print(f"b{i+1} = {b}")

# 验证正交性
print("\n验证正交性:")
for i in range(3):
    for j in range(i+1, 3):
        dot_prod = np.dot(ortho_basis[i], ortho_basis[j])
        print(f"b{i+1} · b{j+1} = {dot_prod:.10f}")  # 应该接近0

一句话本质:Gram-Schmidt是"强行拉正"向量的算法,让基变正交。

第十部分:深度学习中的基------实战应用

应用1:词嵌入空间的基

Word2Vec、GloVe等词嵌入方法,把每个词映射到高维向量空间(如300维)。

这个空间是R300\mathbb{R}^{300}R300,但并不是所有300个维度都同等重要

通过PCA或其他降维方法,可以找到"语义基"------最能区分词义的方向。

python 复制代码
# 词嵌入的降维可视化
from sklearn.manifold import TSNE

# 假设我们有词向量 (简化示例)
words = ['king', 'queen', 'man', 'woman', 'prince', 'princess']
# 在实际应用中,这些是300维向量
# 这里用随机向量模拟,但保持相似词靠近
np.random.seed(42)
word_vectors = np.random.randn(6, 50)  # 6个词,50维
word_vectors[0] += word_vectors[2] + 1  # king ≈ man + royal
word_vectors[1] += word_vectors[3] + 1  # queen ≈ woman + royal

# 用PCA找主要的"语义基"
pca = PCA(n_components=2)
word_vectors_2d = pca.fit_transform(word_vectors)

print("主成分(语义基)方向:")
print(pca.components_)
print(f"\n解释方差比: {pca.explained_variance_ratio_}")

# 在新基下,词的位置
for word, coord in zip(words, word_vectors_2d):
    print(f"{word}: {coord}")

洞察 :词嵌入空间的"基"不是人为定义的,而是通过训练学习出来的------每个维度捕捉某种语义特征(性别、时态、主题等)。

应用2:卷积层的滤波器基

CNN的卷积核本质上是在学习图像空间的基

每个滤波器检测一种特定模式(边缘、纹理、形状)------它们是图像特征空间的"基向量"。

python 复制代码
import torch.nn.functional as F

# 简单的边缘检测滤波器
edge_filter_h = torch.tensor([
    [[-1, -1, -1],
     [ 0,  0,  0],
     [ 1,  1,  1]]
], dtype=torch.float32).unsqueeze(0)  # 水平边缘

edge_filter_v = torch.tensor([
    [[-1, 0, 1],
     [-1, 0, 1],
     [-1, 0, 1]]
], dtype=torch.float32).unsqueeze(0)  # 垂直边缘

# 这些滤波器就是"边缘检测基"
# 图像的特征表示 = 在这些基上的投影(卷积)

# 模拟图像 (1x5x5)
image = torch.randn(1, 1, 5, 5)

# 应用滤波器(基变换)
feature_h = F.conv2d(image, edge_filter_h)
feature_v = F.conv2d(image, edge_filter_v)

print(f"水平边缘特征:\n{feature_h.squeeze()}")
print(f"\n垂直边缘特征:\n{feature_v.squeeze()}")

# 本质:CNN在学习最优的"视觉基"

洞察:CNN通过学习卷积核,自动发现图像的"最佳基表示"------不需要人工设计特征!

应用3:注意力机制的查询-键-值基

Transformer的自注意力机制,本质上是在学习三组基

  • WQW_QWQ:查询基(你想要什么?)
  • WKW_KWK:键基(我有什么?)
  • WVW_VWV:值基(我给你什么?)

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)VAttention(Q,K,V)=softmax(dk QKT)V

其中:
Q=XWQ,K=XWK,V=XWVQ = XW_Q, \quad K = XW_K, \quad V = XW_VQ=XWQ,K=XWK,V=XWV

这三个矩阵把输入XXX投影到不同的子空间(不同的基),然后通过内积计算"相关性"。

python 复制代码
class SelfAttention(nn.Module):
    def __init__(self, d_model, d_k):
        super().__init__()
        self.d_k = d_k
        # 三组基的变换矩阵
        self.W_Q = nn.Linear(d_model, d_k)
        self.W_K = nn.Linear(d_model, d_k)
        self.W_V = nn.Linear(d_k, d_model)
    
    def forward(self, X):
        # X: (batch, seq_len, d_model)
        # 投影到三组基
        Q = self.W_Q(X)  # 查询基
        K = self.W_K(X)  # 键基
        V = self.W_V(X)  # 值基
        
        # 计算注意力(在键空间中的相似度)
        scores = torch.matmul(Q, K.transpose(-2, -1)) / np.sqrt(self.d_k)
        attention = F.softmax(scores, dim=-1)
        
        # 加权组合值向量
        output = torch.matmul(attention, V)
        return output

# 使用
d_model, d_k = 512, 64
attn = SelfAttention(d_model, d_k)

X = torch.randn(2, 10, d_model)  # 2个句子,10个词,512维
output = attn(X)

print(f"输入形状: {X.shape}")
print(f"输出形状: {output.shape}")
print("\n注意力机制学习了三组基来捕捉词之间的关系")

洞察 :注意力机制的本质是学习相关性的最佳基------在这些基下,相关的词"靠得近"。

应用4:梯度下降在参数空间的基

神经网络的参数θ∈Rn\theta \in \mathbb{R}^nθ∈Rn(nnn可能是几百万)构成一个巨大的线性空间。

梯度∇L(θ)\nabla L(\theta)∇L(θ)指示了损失函数"下降最快"的方向------这是参数空间里的一个"特殊基向量"。

不同的优化器(SGD、Adam、RMSprop)本质上是在选择不同的基来表示梯度:

  • SGD:直接用梯度方向(标准基)
  • Momentum:加上历史梯度(指数衰减的时间基)
  • Adam:用梯度的一阶和二阶矩调整(自适应基)
python 复制代码
# 不同优化器 = 不同的基选择
model = nn.Linear(10, 1)
loss_fn = nn.MSELoss()

# SGD: 标准基(直接梯度)
optimizer_sgd = torch.optim.SGD(model.parameters(), lr=0.01)

# Adam: 自适应基(考虑历史统计)
optimizer_adam = torch.optim.Adam(model.parameters(), lr=0.01)

# 模拟一步训练
X = torch.randn(32, 10)
y = torch.randn(32, 1)

# SGD更新
optimizer_sgd.zero_grad()
loss = loss_fn(model(X), y)
loss.backward()
grad_sgd = model.weight.grad.clone()
optimizer_sgd.step()

# Adam更新(内部维护动量和二阶矩)
model.weight.grad = grad_sgd.clone()  # 使用相同的梯度
optimizer_adam.step()

print("两种优化器用不同的'基'来解释梯度")
print("SGD: 直接下降")
print("Adam: 自适应调整下降方向和步长")

洞察:优化算法的本质是选择参数空间中的"下降基"------Adam找到了更"聪明"的基。

第十一部分:基的哲学------表示的艺术

讲了这么多技术细节,我们退一步,思考一个深层问题:基到底意味着什么?

基是"视角"

同一个向量,在不同基下有不同坐标。这不是向量本身的改变,而是我们观察它的方式改变了。

就像一座山,从南面看是险峰,从北面看是缓坡------山没变,视角变了。

数学的美妙之处在于:有时候换个视角,难题迎刃而解

对角化就是最好的例子:同一个矩阵,在特征向量基下变成对角矩阵,高次幂计算变得trivial。

基是"语言"

不同的基是描述同一个对象的不同"语言"。

时域信号和频域信号是同一个函数的两种"说法"------时域语言强调"什么时候发生",频域语言强调"什么频率存在"。

机器学习中,原始像素是图像的"像素语言",CNN特征是图像的"语义语言"------后者对分类任务更有用。

基是"压缩"

好的基能用更少的坐标 表示更多的信息

PCA找到的主成分基,让我们可以丢掉不重要的维度而保留主要信息。

小波基(wavelet basis)让我们能压缩图像------大部分坐标接近零,只保留非零的。

JPEG压缩就是利用DCT(离散余弦变换)基------在这个基下,自然图像的能量集中在少数几个低频系数上。

基是"特征"

机器学习的核心任务是特征学习------找到数据的"好表示"。

从线性代数角度看,特征学习就是学习基

  • 传统机器学习:人工设计基(SIFT、HOG等手工特征)
  • 深度学习:自动学习基(神经网络权重)

深度学习的革命性在于:让机器自己发现最优基,而不是人类猜测。

第十二部分:关键洞察与总结

讲了这么多,让我们用几个"点睛之笔"来总结线性空间和基的本质。

核心隐喻

1. 线性空间是"可自由组合的宇宙"

只要加法和数乘的规则成立,你就在玩线性代数的游戏------无论是三维向量、函数、矩阵还是神经网络权重。

2. 基是"空间的身份证系统"

选定基,抽象向量变成具体数字;换个基,同一个向量换套"衣服",但本质不变。

3. 维度是"自由度的计数器"

nnn维空间需要nnn个数字来定位,nnn个独立方向来张成------这是空间的"信息容量"。

4. 坐标是"向量的数字化身"

计算机不懂抽象向量,但懂数字------坐标是抽象与计算的桥梁。

5. 基变换是"观察角度的切换"

同一个问题,换个基可能变简单------找对基是解决问题的关键。

6. 正交基是"最正直的坐标系"

互相垂直,计算简单,几何直观------数学中的"黄金标准"。

7. 机器学习是在"学习最优基"

从原始数据空间到特征空间,每一层变换都在寻找"任务友好"的表示------这就是表示学习。

机器学习视角的统一

我们可以用"基"的框架统一理解很多ML概念:

概念 本质(基的视角)
特征工程 手工设计数据空间的基
PCA降维 找方差最大的基,丢掉次要维度
自编码器 学习非线性的低维基(编码器)
卷积层 学习图像局部特征的基(滤波器)
词嵌入 学习语义空间的稠密基
注意力机制 学习查询-键-值三组关联基
梯度下降 在参数空间的"下降基"上行走
对抗样本 在某些基下,扰动很小但效果大

实践建议

当你在做深度学习项目时,可以这样思考:

1. 数据预处理:我在用什么"基"表示数据?(像素基?归一化后的标准基?)

2. 网络设计:每一层在学习什么样的"基变换"?这个基适合我的任务吗?

3. 可视化分析:用PCA/t-SNE换基到2D/3D,看看数据在新基下的分布。

4. 调试模型:检查中间层的表示(基变换后的坐标),看看信息是否保留/提取得当。

5. 迁移学习:预训练模型学到的"基"(特征提取器),能否迁移到我的任务?

延伸阅读方向

如果你对这些话题感兴趣,可以进一步学习:

  • 特征值与特征向量:对角化、谱定理、SVD分解
  • 内积空间:范数、正交性、投影定理
  • 矩阵分解:LU、QR、Cholesky、Jordan标准型
  • 泛函分析:无限维空间、Hilbert空间、再生核Hilbert空间(RKHS)
  • 流形学习:非线性降维、拓扑结构、局部线性嵌入
  • 表示学习理论:信息瓶颈、互信息最大化、对比学习

结语:从抽象到应用的旅程

线性空间和基,从19世纪的抽象数学概念,到今天深度学习的核心工具,走过了漫长的旅程。

数学家当初定义这些概念时,可能没想到它们会成为AI的语言------但这正是数学的魔力:一次抽象,终身受用

当你训练神经网络时,你在高维参数空间里搜索;当你做PCA降维时,你在寻找数据的主基;当你可视化词向量时,你在观察语义空间的基...

一切都是线性空间和基的故事。

下次当你看到"embedding"、"feature map"、"latent space"这些术语时,不妨想想:这些都是同一个数学结构------线性空间------的不同化身。你只是在用不同的"基"来观察和操作它们。

数学之美,在于用最简洁的语言,描述最广阔的世界。线性空间和基,就是这样的美。

希望这篇文章能让你对这个看似简单、实则深刻的概念有全新的理解。记住那个核心metaphor:

基是空间的坐标系统,换基是切换观察角度。找对基,问题变简单;学对基,模型更强大。

现在,去探索你自己的高维空间吧!

相关推荐
Ro Jace3 小时前
机器学习、深度学习、信号处理领域常用公式速查表
深度学习·机器学习·信号处理
电商API_180079052473 小时前
微店常用API:获取商品详情接口|关键字搜索商品接口|获取快递费接口-打通商品运营与用户体验的技术桥梁
大数据·服务器·人工智能·爬虫·数据挖掘
视***间3 小时前
AI智能相机未来应用
人工智能·数码相机
加油吧zkf4 小时前
卷积神经网络(CNN)
人工智能·深度学习·cnn
蓝博AI4 小时前
基于卷积神经网络的汽车类型识别系统,resnet50,vgg16,resnet34【pytorch框架,python代码】
人工智能·pytorch·python·神经网络·cnn
whaosoft-1434 小时前
51c大模型~合集43
人工智能
艾莉丝努力练剑4 小时前
【C++:继承和多态】多态加餐:面试常考——多态的常见问题11问
开发语言·c++·人工智能·面试·继承·c++进阶
TextIn智能文档云平台4 小时前
如何提高AI处理扫描文档的精度?
人工智能·自动化
lisw055 小时前
人和AI的分工模式!
人工智能·青少年编程