AI,全称人工智能(Artificial Intelligence)让机器从数据中学习规律并做出判断的技术,而数学是描述规律、刻画变化的精确语言。

AI 提出目标,数学提供实现路径——从数据表示到模型训练,每一步背后都是数学在起作用。

可以说,数学是 AI 的骨架,没有数学,AI 只是一个模糊的构想。有了数学,AI 才能被计算、被验证、被真正实现。

AI 数学基础相关内容包含以下几个板块:

  • 线性代数——描述数据的语言。一张图片、一段文字、一个用户画像,在计算机里最终都变成向量或矩阵。
  • 微积分——描述变化的语言。模型是怎么学会的?靠的是不断计算梯度、调整参数。
  • 概率与统计——描述不确定性的语言。世界是随机的,数据有噪声,模型的输出本质上是一种概率判断。
  • 信息论——描述信息量的语言。用来衡量预测和真实之间差了多少、模型学到了多少东西。
  • 优化理论——描述如何找到最优解的语言。训练一个模型,本质上就是在解一个优化问题。

这五个板块不是孤立的知识点,而是环环相扣的一条链路:

数据(线性代数)→ 建模(概率统计)→ 衡量误差(信息论)→ 求解(微积分+优化)

后面每一讲的内容,都会不断回到这条链路上,帮你把抽象的公式和具体的 AI 应用对应起来。

标量、向量、矩阵、张量

在 AI 的世界里,所有数据——无论是一张图片、一段文字、还是一段音频——最终都被组织成一种统一的形式:张量(Tensor)。

张量是一个统称,按照维度的不同,它有不同的名字。用维度(Dimension)理解数据的形状

标量(0 维):就是一个数。比如气温 26°C。在 NumPy 中 shape 显示为空元组 ()

向量(1 维):一串有序的数。比如一天中每小时的气温记录。Shape 为 (n,),n 是元素个数。

矩阵(2 维):一张表格,有行和列。比如一周七天、每天 24 小时的气温表。Shape 为 (行数, 列数)

张量(3 维及以上):多层数据叠放。比如全国 300 个城市、每个城市一周 7 天、每天 24 小时的气温。Shape 为 (城市数, 天数, 小时数) 即 (300, 7, 24)

维度可以简单理解为:你需要几个「坐标」才能锁定一个具体的数。

数学上的定义

标量 Scalar:标量是一个单独的数,记作 a=26,或者 x∈R(x 属于实数集)。

向量 Vector:向量是一组有序的数,通常竖着写(列向量):

v=\begin{bmatrix} v_{1}\\ v_{2}\\ \vdots \\ v_{n} \end{bmatrix} \in R^{n}

R^{n} 表示这是一个 n 维实数向量,v_{1}​ 是第 1 个分量,v_{n}​ 是第 n 个分量。

矩阵 Matrix:矩阵是一个 m 行 n 列的矩形数组:

A=\begin{bmatrix} a_{11} &a_{12} & \cdots & a_{1n}\\ a_{21} &a_{22} &\cdots & a_{2n}\\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} &a_{m2} &\cdots & a_{mn} \end{bmatrix} \in R^{m\times n}

记作 m×n 矩阵(m 行 n 列),a_{ij}​ 表示第 i 行第 j 列的元素。

张量 Tensor:张量是向量和矩阵向任意维度的推广。

一个 k 维张量的形状记作 (d_{1},d_{2},\cdots ,d_{k}),共 d_{1}\times d_2\times \cdots ×d_k 个元素。

名称 维度 Shape 示例 坐标数 数学记号
标量 0 () 0 x∈Rx∈R
向量 1 (n,) 1 v∈Rnv∈Rn
矩阵 2 (m, n) 2 A∈Rm×nA∈Rm×n
3D 张量 3 (d1, d2, d3) 3 T∈Rd1×d2×d3T∈Rd1​×d2​×d3​

Python 动手实践

下面用 NumPy 来创建和查看这些数据结构。shape 属性 是理解数据维度的关键。

import numpy as np

# 标量(0 维张量):shape = ()
scalar = np.array(26)
# 向量(1 维张量):shape = (n,)
vector = np.array([22, 23, 24, 26, 28, 30, 31, 29])
# 矩阵(2 维张量):shape = (行数, 列数)
matrix = np.array([[1, 2, 3], [4, 5, 6]])
# 3D 张量:shape = (层数, 行数, 列数)
tensor_3d = np.array([[[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]]])
# 4D 张量:模拟 3 张 2x2 像素的单通道图片
batch_images = np.array([
    [[[10],[20]],[[30],[40]]],
    [[[50],[60]],[[70],[80]]],
    [[[90],[100]],[[110],[120]]]
])

print("标量:    shape=", scalar.shape, "   ndim=", scalar.ndim)
print("向量:    shape=", vector.shape, "   ndim=", vector.ndim)
print("矩阵:    shape=", matrix.shape, "   ndim=", matrix.ndim)
print("3D 张量: shape=", tensor_3d.shape, "  ndim=", tensor_3d.ndim)
print("4D 张量: shape=", batch_images.shape, " ndim=", batch_images.ndim)

输出:

标量:    shape= ()        ndim= 0
向量:    shape= (8,)      ndim= 1
矩阵:    shape= (2, 3)    ndim= 2
3D 张量: shape= (2, 2, 3) ndim= 3
4D 张量: shape= (3, 2, 2, 1) ndim= 4

Shape 属性的规律

属性 含义 标量 向量(8个元素) 矩阵(2×3) 3D(2×2×3)
.shape 每个维度的大小 () (8,) (2, 3) (2, 2, 3)
.ndim 维度数量 = len(shape) 0 1 2 3
.size 元素总数 1 8 6 12

AI 中的应用场景

图像分类:从 3D 到 4D 张量

ImageNet 分类任务中,输入图片被统一缩放到 224×224 像素。单张彩色图片是 shape 为 (224, 224, 3) 的 3D 张量。

实际训练时,GPU 一次处理一个 batch(如 32 张图片),数据变为 4D 张量 (32, 224, 224, 3)

注意不同框架的通道位置约定不同:TensorFlow/Keras 使用 (N, H, W, C)(通道在最后),PyTorch 使用 (N, C, H, W)(通道在最前)。

当你看到报错 "shape mismatch: (32, 224, 224, 3) vs (32, 3, 224, 224)",就是通道位置不一致导致的——用 .permute() 或 .transpose() 调整即可。

自然语言处理:嵌入矩阵

BERT 模型的词表大小为 30522,隐藏维度为 768。它的词嵌入矩阵 shape 为 (30522, 768)——每行是一个词的 768 维向量。

GPT 系列也是如此:GPT-2 的词表 50257,嵌入维度 768(小模型)到 1600(大模型)。

当你输入一段文本,模型首先查表把每个词 ID 转成对应的嵌入向量,这就是「查表取行」——一个矩阵索引操作。

全连接层:矩阵乘法的核心地位

一个经典的 MNIST 手写数字识别网络:输入 784 维(28×28 像素展平),第一隐藏层 256 维。

权重矩阵 W₁ 的 shape 为 (256, 784)。每次前向传播计算 h = W₁ @ x,就是 256×784 矩阵乘 784 维向量。

整个神经网络的前向传播,本质上就是一层层的矩阵乘法和激活函数的交替。

视频数据:5D 张量

视频可以理解为多帧图片的序列。一段 16 帧的 224×224 彩色视频片段,shape 为 (16, 224, 224, 3)

加上 batch 维度后变成 5D 张量 (8, 16, 224, 224, 3)——这就是视频分类模型(如 3D-ResNet)的标准输入。

向量的加法与数乘

向量可以理解为从原点出发的一支箭——有长度、有方向。两个向量相加,就是把两段位移「拼接」在一起。

三角形法则:把第二个向量 b 的起点接到第一个向量 a 的终点。从 a 的起点到 b 的终点的连线,就是 a + b。直觉:「先走 a,再走 b」

平行四边形法则:以 a 和 b 为两条邻边,画一个平行四边形。从起点出发的对角线,就是 a + b。

数乘:拉伸或缩短向量

用一个标量(普通数字)去乘向量,结果是 改变向量的长度,但保持它所在的直线方向不变。

数乘只改变向量的「长度」,不改变它所在直线的方向(负数反转方向但仍在同一条直线上)。

这个性质叫做 共线性——数乘前后的两个向量总是在同一条直线上。

数学定义

向量加法

两个同维度的向量相加,就是对应位置的元素分别相加。两个向量维度必须相同,否则加法无意义。

a+b=\begin{bmatrix} a_1\\ a_2\\ \vdots \\ a_n \end{bmatrix} +\begin{bmatrix} b_1\\ b_2\\ \vdots \\ b_n \end{bmatrix}=\begin{bmatrix} a_1+b_1\\ a_2+b_2\\ \vdots \\ a_n+b_n \end{bmatrix}

向量减法

向量减法 = 加上反方向的向量:a−b=a+(−b)

向量数乘

一个标量 c 乘以一个向量,就是把向量的每个元素都乘以 c:

a\cdot v=c\cdot \begin{bmatrix} v_1\\ v_2\\ \vdots \\ v_n \end{bmatrix}=\begin{bmatrix} c\cdot v_1\\ c\cdot v_2\\ \vdots \\ c\cdot v_n \end{bmatrix}

运算性质速查

性质 公式 直觉
交换律 a+b=b+a 先走哪段都一样
结合律 (a+b)+c=a+(b+c) 怎么分组走都一样
分配律 c(a+b)=ca+cb 先加再拉伸 = 先拉伸再加

Python 动手实践

import numpy as np

# 创建两个向量
a = np.array([3, 1])    # a = (3, 1)
b = np.array([1, 2])    # b = (1, 2)

# 向量加法:对应位置相加
add = a + b
print("a + b =", add_result)    # [4, 3]

# 向量减法
sub_result = a - b
print("a - b =", sub_result)    # [2, -1]

# 数乘:每个元素乘以标量
c = 2.5
scale_result = c * a
print(f"{c} * a =", scale_result)  # [7.5, 2.5]

# 负向量:方向完全相反
neg = -a
print("-a =", neg)              # [-3, -1]

# NumPy 广播:标量与向量各元素直接运算
print("a + 10 =", a + 10)   # 每个元素都加 10
print("a * 3  =", a * 3)    # 每个元素都乘 3

输出:

a + b = [4 3]
a - b = [2 -1]
2.5 * a = [7.5 2.5]
-a = [-3 -1]
a + 10 = [13 11]
a * 3  = [9 3]

AI 中的应用场景

词向量的语义运算:Word2Vec 和 GloVe 等词嵌入模型最著名的发现:向量的加减法有语义含义。

vec(国王)−vec(男人)+vec(女人)≈vec(女王)

减法是去掉「男性」特征分量,加法是加上「女性」特征分量。结果向量在嵌入空间中距离「女王」最近。

这种语义运算不仅限于性别——「巴黎 - 法国 + 意大利 ≈ 罗马」也是同样的原理。向量的加法和减法在此起到了「特征编辑」的作用。(巴黎是法国的首都,罗马是意大利的首都)

神经网络中的偏置:每个神经元的计算 y=Wx+b 中,+b 就是向量加法——偏置将 wx 的结果整体平移。

如果没有偏置 b,模型在 x=0 时输出必定为 0,这严重限制了模型的表达能力。偏置相当于给每个神经元一个「默认激活值」。

梯度更新:训练时的参数更新 \theta_{new}=\theta_{old } - \eta \bigtriangledown J 就是数乘(学习率 × 梯度)与向量减法的组合。

数乘控制每步更新的大小(学习率越大步长越大),减法将参数向损失减小的方向移动。

数据预处理:均值中心化:在训练神经网络之前,通常会对数据做「减均值」操作:x_{norm}=x-\mu。这就是向量减法——将数据中心平移到原点,有助于梯度下降更快收敛。

向量的点积

点积(Dot Product)是 AI 中使用频率最高的向量运算。全连接层的计算、注意力机制的相似度匹配——它们的核心都是点积。点积有两种等价的视角,理解它们之间的桥梁是本章的核心收获。

视角一,代数计算:对应位置的元素相乘,然后求和。a\cdot b=\sum a_ib_i

例如:(2,3) · (4,1) = 2×4 + 3×1 = 11

视角二,几何直觉:将一个向量投影到另一个向量上,然后两段长度相乘。

a \cdot b = |a||b| cos\theta   夹角 θ 越小,点积越大。

两种算法得出的是同一个值——这是数学中一个极其优雅的等式。

数学定义

代数定义:a\cdot b=\sum a_ib_i=a_1b_1+a_2b_2+\cdots +a_nb_n

几何定义:a \cdot b = |a||b| cos\theta

两个定义的桥梁-——求夹角:cos\theta= \frac{a \cdot b }{|a||b| }

这意味着:给定两个向量的坐标,就能算出它们之间的夹角,不需要量角器。

运算性质

性质 公式 说明
交换律 a⋅b=b⋅a 顺序不影响
分配律 a⋅(b+c)=a⋅b+a⋅c 可先加再点积
自身点积 a⋅a=|a|^2 向量与自己的点积 = 长度的平方

Python 动手实践

import numpy as np

a = np.array([2, 3, 1])
b = np.array([4, 1, 2])

# 方法1:np.dot()
dot1 = np.dot(a, b)
# 方法2:@ 运算符(推荐)
dot2 = a @ b
# 方法3:手写验证
dot3 = sum(a[i] * b[i] for i in range(len(a)))

print("a · b =", dot1)   # 13
print("三种方法结果一致:", dot1 == dot2 == dot3)

# 用几何定义反推夹角
norm_a = np.linalg.norm(a)
norm_b = np.linalg.norm(b)
cos_theta = dot1 / (norm_a * norm_b)
theta_deg = np.degrees(np.arccos(cos_theta))
print(f"||a||={norm_a:.2f}, ||b||={norm_b:.2f}, cosθ={cos_theta:.4f}")
print(f"夹角 = {theta_deg:.1f}°")

# 验证几何公式
verify = norm_a * norm_b * cos_theta
print(f"||a||·||b||·cosθ = {verify:.4f} (与点积一致)")

# 不同夹角的演示
print("\n[1,0] · [0.8,0.6] =", np.array([1,0]) @ np.array([0.8,0.6]), " (锐角,正)")
print("[1,0] · [0,1] =", np.array([1,0]) @ np.array([0,1]), " (直角,零)")
print("[1,0] · [-1,0] =", np.array([1,0]) @ np.array([-1,0]), " (钝角,负)")

输出:

a · b = 13
三种方法结果一致: True
||a||=3.74, ||b||=4.58, cosθ=0.7582
夹角 = 40.7°
||a||·||b||·cosθ = 13.0000 (与点积一致)

[1,0] · [0.8,0.6] = 0.8  (锐角,正)
[1,0] · [0,1] = 0  (直角,零)
[1,0] · [-1,0] = -1  (钝角,负)

AI 中的应用场景

全连接层 = 点积的批量计算:一个神经元计算 y=w_1x_1+w_2x_2+\cdots +w_nx_n+b。加和部分就是权重向量 w 和输入向量 x 的点积。

当你看到一个全连接层 nn.Linear(784, 256),它在数学上做的事就是:256 个神经元,每个神经元拿自己的权重向量(784 维)与输入向量做点积,再加上偏置。256 个点积并行计算 = 矩阵乘法。

注意力机制 = 点积 + Softmax:Transformer 的核心操作:Query 向量与 Key 向量做点积,结果越大表示两者越「相关」。

Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{dk}})V

QK^T 是 seq_len × d_k 矩阵与 d_k × seq_len 矩阵的乘法,结果矩阵中位置 (i, j) 的值 = 第 i 个 Query 与第 j 个 Key 的点积。这个值越大,表示第 i 个位置对第 j 个位置的「注意力」越高。

除以 \sqrt{dk} 是为了防止点积值过大导致 Softmax 梯度消失。GPT、BERT、Claude 等所有现代大语言模型都基于这个点积注意力机制。

推荐系统中的相似度计算:用户向量与物品向量做点积,得到用户对该物品的「偏好分数」。这就是矩阵分解推荐算法的核心——评分矩阵 ≈ 用户隐向量矩阵 × 物品隐向量矩阵的转置。

向量的模长与余弦相似度

模长:向量有多长?

模长就是向量从原点到终点的「直线距离」——勾股定理在高维空间的推广。

 L1 范数:曼哈顿距离:v_{1}=\sum |v_i|。沿街道走 如:(3,4) 的 L1 = 7

 L2 范数(默认)v_2=\sqrt{\sum v_i^{2}}。直线距离:空中飞 (3,4) 的 L2 = 5

未特别说明时,「模长」默认指 L2 范数。

单位向量:扔掉长度,只留方向

任何非零向量除以自己的模长,得到长度为 1 的 单位向量:\hat{v} = \frac{v}{|v|},归一化后向量方向不变,但模长变为 1。

余弦相似度:只看方向,不看大小

余弦相似度 = 把两个向量都归一化为单位向量后,再做点积:cosineSim(a,b)=\frac{a \cdot b }{|a||b| }=cos\theta

(方向一致cos=1,方向垂直cos=0,方向相反cos=-1)

余弦相似度只关心方向,不关心长度。

v = (3,4) 和 w = (6,8)(w = 2v),长度差一倍,但余弦相似度 = 1——因为它们方向完全相同。

import numpy as np

v = np.array([3, 4, 0])
w = np.array([6, 8, 0])  # v 的 2 倍

# 模长
norm_v = np.linalg.norm(v)   # L2 默认
norm_w = np.linalg.norm(w)
print(f"||v|| = {norm_v:.1f}, ||w|| = {norm_w:.1f}")  # 5, 10

# 归一化
unit_v = v / norm_v
unit_w = w / norm_w
print("v 归一化:", unit_v)    # [0.6, 0.8, 0.]
print("w 归一化:", unit_w)    # [0.6, 0.8, 0.] 完全相同!

# 余弦相似度
cos_sim = np.dot(v, w) / (norm_v * norm_w)
print(f"余弦相似度 = {cos_sim:.4f}")  # 1.0

输出

||v|| = 5.0, ||w|| = 10.0
v 归一化: [0.6 0.8 0. ]
w 归一化: [0.6 0.8 0. ]
余弦相似度 = 1.0000
import numpy as np

# 批量计算余弦相似度矩阵
embeddings = np.array([
    [0.2, 0.5, 0.1, 0.8, 0.3],
    [0.3, 0.6, 0.2, 0.7, 0.4],
    [0.9, 0.1, 0.8, 0.1, 0.9],
])
norms = np.linalg.norm(embeddings, axis=1, keepdims=True)
normalized = embeddings / norms
sim_matrix = normalized @ normalized.T
print("\n余弦相似度矩阵:")
print(np.round(sim_matrix, 3))

输出:


余弦相似度矩阵:
[[1.    0.996 0.146]
 [0.996 1.    0.182]
 [0.146 0.182 1.   ]]

解释 normalized @ normalized.T

先把所有符号简化,抛弃抽象术语,只看结构

先定义数据

normalized.shape = (3, 5)

也就是 3 行 5 列:

normalized= \begin{bmatrix} \boldsymbol{v}_1 \\ \boldsymbol{v}_2 \\ \boldsymbol{v}_3 \end{bmatrix}

  • \boldsymbol{v}_1:第 1 个归一化向量,长度 5
  • \boldsymbol{v}_2:第 2 个归一化向量,长度 5
  • \boldsymbol{v}_3:第 3 个归一化向量,长度 5

2. normalized.T = 转置

转置之后行列互换,变成 5 行 3 列

normalized^\mathrm{T}= \Big[\boldsymbol{v}_1^\mathrm{T},\; \boldsymbol{v}_2^\mathrm{T},\; \boldsymbol{v}_3^\mathrm{T}\Big]

\boldsymbol{v}_1 是行向量:1\times5

\boldsymbol{v}_1^\mathrm{T} 变成列向量:5\times1

3. 矩阵乘法 A @ B 规则

如果 A 是 m\times k,B 是 k\times n 结果 = m\times n。元素 C_{ij} = A的第i行 \cdot B的第j列。

现在:A=normalized \quad(3,5)

B=normalized.T \quad(5,3)

输出矩阵:\boldsymbol{S} \quad(3,3)

\boldsymbol{S}= \begin{bmatrix} \boldsymbol{v}_1 \\ \boldsymbol{v}_2 \\ \boldsymbol{v}_3 \end{bmatrix} \quad @ \quad \Big[\boldsymbol{v}_1^\mathrm{T},\; \boldsymbol{v}_2^\mathrm{T},\; \boldsymbol{v}_3^\mathrm{T}\Big]

展开矩阵乘法!(重点!)

\boldsymbol{S}= \begin{bmatrix} \boldsymbol{v}_1\cdot\boldsymbol{v}_1^\mathrm{T} & \boldsymbol{v}_1\cdot\boldsymbol{v}_2^\mathrm{T} & \boldsymbol{v}_1\cdot\boldsymbol{v}_3^\mathrm{T} \\ \boldsymbol{v}_2\cdot\boldsymbol{v}_1^\mathrm{T} & \boldsymbol{v}_2\cdot\boldsymbol{v}_2^\mathrm{T} & \boldsymbol{v}_2\cdot\boldsymbol{v}_3^\mathrm{T} \\ \boldsymbol{v}_3\cdot\boldsymbol{v}_1^\mathrm{T} & \boldsymbol{v}_3\cdot\boldsymbol{v}_2^\mathrm{T} & \boldsymbol{v}_3\cdot\boldsymbol{v}_3^\mathrm{T} \end{bmatrix}

4. 和余弦相似度关联

之前做过:所有 v 都是 L2 归一化向量 余弦相似度公式:

\mathrm{sim}(\boldsymbol{a},\boldsymbol{b})=\frac{\boldsymbol{a}\cdot\boldsymbol{b}}{\|\boldsymbol{a}\|\|\boldsymbol{b}\|}

归一化后 \|\boldsymbol{a}\|=\|\boldsymbol{b}\|=1

\boldsymbol{v}_i \cdot \boldsymbol{v}_j^\mathrm{T} = \mathrm{sim}(i,j)

所以矩阵里面每一格含义:

  • \boldsymbol{S}[0,0] = \boldsymbol{v}_1 \cdot \boldsymbol{v}_1^\mathrm{T}:向量 1 和 向量 1 的相似度
  • \boldsymbol{S}[0,1] = \boldsymbol{v}_1 \cdot \boldsymbol{v}_2^\mathrm{T}:向量 1 和 向量 2 的相似度
  • \boldsymbol{S}[0,2] = \boldsymbol{v}_1 \cdot \boldsymbol{v}_3^\mathrm{T}:向量 1 和 向量 3 的相似度
  • \boldsymbol{S}[1,0] = \boldsymbol{v}_2 \cdot \boldsymbol{v}_1^\mathrm{T}:向量 2 和 向量 1 的相似度 以此类推。

✅ 最终得到完整两两相似度表格(相似度矩阵)

AI 中的应用场景

语义搜索与推荐系统:将查询词和文档分别编码为向量后,用余弦相似度排序——找最相关的文档。Google 的语义搜索、RAG(检索增强生成)中的向量检索都依赖余弦相似度。

相比点积,余弦相似度不受向量模长影响——一篇长文章的向量模长可能很大,但用余弦相似度能公平地与短查询比较方向一致性。

人脸识别:余弦相似度 > 欧氏距离:FaceNet 等面部识别模型将人脸映射为 128 维嵌入向量。两个人脸是否匹配,用余弦相似度判断——它对照明条件、照片亮度(影响向量模长)不敏感。

两张同一个人不同光照下的照片,嵌入向量方向几乎一致(cos ≈ 0.95+),但模长可能差很多。

L2 正则化防止过拟合:损失函数中加入 \lambda |w|2(权重衰减),惩罚权重模长过大。权重模长大意味着模型对某些特征过度信任,泛化能力差。L2 正则化将其拉向原点附近。

Batch Normalization 中的归一化:BN 对每层激活值做归一化:减均值后除以标准差,将数据变为模长稳定的分布。这用到了 L2 范数的概念来控制各层输出的尺度。

矩阵加法与矩阵乘法

矩阵乘法是理解神经网络前向传播的关键——全连接层的本质就是矩阵乘法。

矩阵加法:对应位置相加,两个形状相同的矩阵,把对应位置的元素加起来——和向量加法一样直观。

矩阵乘法:行与列的点积,矩阵乘法没有「对应位置乘」那么简单。为什么?

矩阵的深层含义是「线性变换」——它会把一个向量映射到另一个向量。

两个矩阵相乘 AB,在几何上的意思是:先做 B 变换,再做 A 变换。所以 AB 的运算法则必须反映「复合变换」的数学结构,而不是简单的逐元素相乘。

例如:A 表示「水平拉伸 2 倍」, B 表示「逆时针旋转 90°」。AB 表示「先旋转再拉伸」——这与 BA(先拉伸再旋转)完全不同,所以矩阵乘法不满足交换律。

运算法则是:左矩阵的第 i 行与右矩阵的第 j 列做点积 → 结果矩阵的 (i, j) 位置的值。

(m\times ×n)\times (n\times p)=(m\times p)   A 的列数 必须等于 B 的行数。两个标红的 n 必须相等。

结果的形状 = (A 的行数, B 的列数)

矩阵乘法 不满足交换律:AB ≠ BA(通常情况)。甚至维度可能不匹配导致 BA 无定义——这是初学者最容易出错的地方。

矩阵乘法的本质是线性变换的复合:乘以矩阵 A → 做完一次变换;再乘以矩阵 B → 做完第二次变换。两次变换复合 = 一次 (BA) 变换。这就是矩阵乘法这样定义的原因。

小卖部收入计算:三天的销量矩阵(行=日期,列=商品):

可乐 薯片 泡面
周一 10 5 3
周二 8 7 4
周三 12 4 6

价格矩阵(行=商品,列=店铺):

店铺1 店铺2
可乐 3 3.5
薯片 5 5.5
泡面 4 4.0

销量矩阵 (3×3) × 价格矩阵 (3×2) = 收入矩阵 (3×2)。结果的每一格 = 某天在某个店铺的总收入。

数学定义

矩阵加法:(A+B)_{ij}=a_{ij}+b_{ij}   前提:A 和 B 形状完全相同。

矩阵乘法:设 A 为 m×n,B 为 n×p,则 C = AB 为 m×p:c_{ij}=\sum_{k=1}^{n}a_{ik}b_{kj}

Python 动手实践

import numpy as np

A_runoob = np.array([[10, 5, 3], [8, 7, 4], [12, 4, 6]])
price = np.array([[3, 3.5], [5, 5.5], [4, 4.0]])

# 矩阵加法(同形状)
bonus = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
total = A_runoob + bonus
print("A + bonus:\n", total)

# 矩阵乘法:(3×3) @ (3×2) = (3×2)
revenue = A_runoob @ price
print("\n收入矩阵 A @ price:\n", revenue)
print("形状:", revenue.shape)

# 手动验证第(0,0)位置
manual = A_runoob[0,0]*price[0,0] + A_runoob[0,1]*price[1,0] + A_runoob[0,2]*price[2,0]
print(f"\n手动验证 [0,0]: {manual} == {revenue[0,0]}")

# 维度不匹配的陷阱
print(f"\nA 形状: {A_runoob.shape}")     # (3, 3)
print(f"price.T 形状: {price.T.shape}")   # (2, 3)
# A @ price.T → (3,3) @ (2,3) 不匹配!
# 正确:price.T @ A → (2,3) @ (3,3) = (2,3)
print(f"price.T @ A 形状: {(price.T @ A_runoob).shape}")  # (2, 3)

输出:

收入矩阵 A @ price:
 [[67.  72. ]
 [75.  79.5]
 [80.  88. ]]
形状: (3, 2)

A 形状: (3, 3)
price.T 形状: (2, 3)
price.T @ A 形状: (2, 3)

AI 中的应用场景

全连接层 = 矩阵乘法nn.Linear(d_in, d_out) 的本质:权重矩阵 W(d_out × d_in)乘以输入向量 x(d_in 维),得到输出(d_out 维)。

处理 batch 数据时,输入 X 是 (batch, d_in) 矩阵,计算 Y=XWTY=XWT 或 Y=WXTY=WXT,这是一次矩阵乘法完成整个 batch 的前向计算。GPU 对矩阵乘法有专门硬件加速(Tensor Core)。

注意力机制的 QK^T:Transformer 中 Q 和 K 都是 (seq_len, d_k) 矩阵。QK^T 是 seq_len×d_k 乘 d_k×seq_len,得到 (seq_len, seq_len) 的注意力分数矩阵。

GPT-4 级别的大模型中,seq_len 可达 128K,这个矩阵乘法的计算量占整个推理成本的很大一部分。FlashAttention 算法就是专门优化这个矩阵乘法的显存访问模式。

卷积的矩阵乘法实现(im2col):卷积操作可以展开为矩阵乘法:把输入图像按滑动窗口展开为一个大矩阵(im2col),然后把卷积核也展平为矩阵,两者相乘。这让卷积能利用高度优化的 GEMM(通用矩阵乘法)库来加速。

LoRA 微调中的矩阵分解:LoRA 在预训练权重旁加两个小矩阵 A 和 B 的乘积:W'=W+AB。这里的 AB 就是矩阵乘法——A 是 d×r,B 是 r×d,乘积是 d×d 的低秩矩阵。一个矩阵乘法实现了参数高效的微调。

矩阵的转置与逆矩阵

转置在注意力机制中频繁出现,逆矩阵帮助我们理解「可逆变换」——比如 PCA 中的坐标变换。

转置:行列互换:A (2\times 3)

1 2 3
4 5 6

A^T (3\times 2)

1 4
2 5
3 6

原来 (i, j) 位置的值,经过转置后到了 (j, i) 位置。 形状从 m×n 变成 n×m。

逆矩阵:撤销变换,矩阵 A 代表一个线性变换。A^-1 代表「撤销 A 的效果」。

数学表达:AA^{-1}=A^{-1}A=I(I 是单位矩阵,相当于数字 1)。

只有 方阵且满秩 的矩阵才有逆矩阵。非方阵或不满秩的方阵是「奇异矩阵」,没有逆——相当于一个不可逆的操作。

关键性质

  • 乘积转置反转顺序:(AB)^T=B^TA^T
  • 乘积逆也反转顺序:(AB)^{-1}=B^{-1}A^{-1}

逆矩阵:Ctrl+Z 撤销。你做了一个旋转 + 缩放操作(矩阵 A),想还原回去(A^{-1})。两次操作复合 = 什么都没变(AA^{-1} = I,恒等变换)。

数学定义

转置:(A^T)_{ij}=A_{ji}

逆矩阵:对于 n×n 方阵 A,如果存在 B 使得 AB=BA=I_n​,则 B = A^{-1}

import numpy as np

A = np.array([[1, 2, 3], [4, 5, 6]])
print("A (2x3):\n", A)
print("A.T (3x2):\n", A.T)
print()

# 验证 (AB)^T = B^T @ A^T
B = np.array([[1,2],[3,4],[5,6]])  # 3x2
AB = A @ B   # (2,3) @ (3,2) = (2,2)
print("(AB)^T:\n", AB.T)
print("B^T @ A^T:\n", B.T @ A.T)
print("相等:", np.allclose(AB.T, B.T @ A.T))
print()

# 逆矩阵
C = np.array([[2, 1], [5, 3]])  # 2x2 方阵
C_inv = np.linalg.inv(C)
print("C:\n", C)
print("C^{-1}:\n", C_inv)
print("C @ C^{-1} = I:\n", C @ C_inv)

# 奇异矩阵没有逆
D = np.array([[1, 2], [2, 4]])  # 第2行是第1行的2倍
try:
    np.linalg.inv(D)
except np.linalg.LinAlgError:
    print("\n奇异矩阵 D 没有逆矩阵(第2行=2×第1行)")

输出:

A (2x3):
 [[1 2 3]
 [4 5 6]]
A.T (3x2):
 [[1 4]
 [2 5]
 [3 6]]

C @ C^{-1} = I:
 [[1. 0.]
 [0. 1.]]

奇异矩阵 D 没有逆矩阵(第2行=2×第1行)

AI 中的应用场景

注意力机制的 K^T 操作QK^T 中 Key 矩阵的转置让 (seq_len, d_k) 的 Q 能与 (seq_len, d_k) 的 K 做矩阵乘法——转置将 K 变为 (d_k, seq_len),使内维匹配。这个 K^T 是所有 Transformer 模型注意力计算中最关键的维度变换。

线性回归的闭式解\hat{\beta }=(X^TX)^{-1}X^Ty——转置和逆矩阵同时出现。X^T X 保证结果是对称正定矩阵(可逆),然后求逆得到解析解。sklearn 的 LinearRegression 在不加正则化时底层就算这个。

梯度下降中的参数更新:在反向传播中,权重梯度矩阵的形状必须与权重矩阵匹配才能做减法更新。例如 W 是 (d_out, d_in),它的梯度 \nabla_W L 也是 (d_out, d_in)——转置在中间层帮助梯度在计算图中正确传导维度。

特殊矩阵

单位矩阵 I:主对角线全是 1,其余全是 0,乘以任何矩阵 = 不变,相当于数字中的「1」,对任意形状兼容的矩阵 A:IA=A,AI=A

I_n=\begin{bmatrix} 1 & & \cdots &0 \\ 0 & 1 & \cdots &0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 &0 & \cdots & 1 \end{bmatrix}

对角矩阵:独立缩放每个维度,对角矩阵乘以向量 = 对向量的每个分量独立施加不同的缩放系数。

D=diag(d_1,d_2,...,d_n)=\begin{bmatrix} d_1 & & \cdots &0 \\ 0 & d_2 & \cdots &0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 &0 & \cdots & d_n \end{bmatrix}

对称矩阵:转置后还是自己,对称矩阵有一个极重要的性质:特征值全是实数,特征向量相互正交。这使得对称矩阵在优化和统计中极其有用——协方差矩阵和 Hessian 矩阵都是对称矩阵。

A^T=A,即 a_{ij}=a_{ji}

矩阵的迹(trace):是线性代数中的基本概念,通常记作 tr(A)。对于一个 n×n 的方阵 A=[a_{ij}],其迹定义为主对角线元素之和:tr(A)=\sum_{i=1}^{n}a_{ii}。显然,只有方阵才有迹,标量的迹就是其本身。

import numpy as np

# 单位矩阵
I = np.eye(3)
A = np.array([[4,7,2],[3,5,1],[6,8,9]])
print("I @ A == A:", np.allclose(I @ A, A))

# 对角矩阵:独立缩放
D = np.diag([2, 3, 5])
v = np.array([1, 1, 1])
print("D @ [1,1,1] =", D @ v)  # [2, 3, 5]

# 对称矩阵
S = np.array([[1,4,5],[4,2,6],[5,6,3]])
print("S 对称:", np.allclose(S.T, S))
eigenvals = np.linalg.eigvals(S)
print("特征值全实数:", np.all(np.isreal(eigenvals)))

# 协方差矩阵天然对称
data = np.random.randn(100, 5)
cov = np.cov(data.T)
print("协方差矩阵对称:", np.allclose(cov, cov.T))

输出:

I @ A == A: True
D @ [1,1,1] = [2 3 5]
S 对称: True
特征值全实数: True
协方差矩阵对称: True

AI 中的应用场景

Adam 优化器 = 对角矩阵自适应缩放:Adam 为每个参数维护梯度平方的指数移动平均 v_t,更新时用 \theta_{t+1}=\theta_t - \eta \cdot \frac{m_t}{\sqrt{v_t}}。从数学上看,\frac{1}{\sqrt{v_t}}对每个参数分量独立缩放——这就是一个对角矩阵乘以梯度向量。活跃的梯度分量被缩小学习率,不活跃的梯度分量被放大。

协方差矩阵用于 PCA:PCA 降维的第一步:计算数据中心化后的协方差矩阵 \sum =X^TX/(n-1)。这是一个对称矩阵 \Sigma_{ij} = \Sigma_{ji},它的特征值全为实数。最大的 k 个特征值对应的特征向量就是主成分方向。sklearn 的 PCA 类底层就做这件事。

循环神经网络的恒等初始化:RNN 和 LSTM 的 recurrent 权重矩阵常初始化为单位矩阵。这确保训练初期,隐藏状态的信息能够「原封不动」地传递,避免梯度在时间步上过快衰减。这个技巧被称为 IRNN(Identity RNN)。

Xavier/Glorot 初始化:Xavier 初始化精心选择权重的方差使每层输出的方差保持一致:Var(W)=2/(n_{in}+n_{out})。这等价于从该方差的正态分布中对角矩阵(方差)的约束。

特征值、特征向量

设二阶方阵 A=\begin{bmatrix}a&b\\c&d\end{bmatrix}若存在非零向量 \boldsymbol{x}=\begin{bmatrix}x_1\\x_2\end{bmatrix} 和数 \lambda,满足: A\boldsymbol{x}=\lambda \boldsymbol{x} 则称 \lambda 为特征值\boldsymbol{x}为对应 \lambda 的特征向量

变形:(A-\lambda I)\boldsymbol{x}=\boldsymbol{0}

I=\begin{bmatrix}1&0\\0&1\end{bmatrix} 是二阶单位矩阵。

齐次方程组有非零解 $\iff$ 系数矩阵行列式为0:

\det(A-\lambda I)=0 该方程叫特征方程

第一步:求特征多项式、解特征值

A-\lambda I=\begin{bmatrix}a-\lambda&b\\c&d-\lambda\end{bmatrix}

行列式:

\det(A-\lambda I) =(a-\lambda)(d-\lambda)-bc \\ =\lambda^2-(a+d)\lambda +(ad-bc)

记:

  1. \mathrm{tr}(A)=a+d(主对角线和)
  2. 行列式 \det(A)=ad-bc

特征多项式简写:f(\lambda)=\lambda^2-\mathrm{tr}(A)\cdot\lambda + \det(A) 

解方程 \lambda^2-\mathrm{tr}(A)\lambda+\det(A)=0,得到两个特征值 \lambda_1,\lambda_2(实根/共轭复根/重根)。

求根公式: \lambda_{1,2}=\frac{\mathrm{tr}(A)\pm\sqrt{\mathrm{tr}^2(A)-4\det(A)}}{2}

判别式分类

  1. \Delta=\mathrm{tr}^2-4\det>0:两个不同实特征值
  2. \Delta=0:二重实特征值
  3. \Delta<0:一对共轭复特征值

第二步:对每个 \lambda 求特征向量

对单个特征值 \lambda_0,解齐次线性方程组: (A-\lambda_0 I)\begin{pmatrix}x_1\\x_2\end{pmatrix}=\begin{pmatrix}0\\0\end{pmatrix} 方程组有无穷多非零解,所有解都是 \lambda_0 的特征向量;通常取一个基础解系作为代表。

实操简化(二阶专用)

矩阵A-\lambda_0 I=\begin{bmatrix}a-\lambda_0 & b \\ c & d-\lambda_0\end{bmatrix},两行线性相关,只用一行列方程即可: (a-\lambda_0)x_1 + b x_2 = 0 自由设一个变量,解出另一个。

例1:二阶实矩阵,两个不同实特征值

A=\begin{bmatrix}3&1\\1&3\end{bmatrix}

计算迹、行列式 \mathrm{tr}(A)=3+3=6,\quad \det(A)=3\times3-1\times1=8

特征方程 \lambda^2-6\lambda+8=0 \Rightarrow (\lambda-2)(\lambda-4)=0 

特征值:$\lambda_1=2,\ \lambda_2=4$

$\lambda_1=2$ 的特征向量 A-2I=\begin{bmatrix}1&1\\1&1\end{bmatrix}

方程:$x_1+x_2=0 \Rightarrow x_2=-x_1$$x_1=1$,得基础特征向量: \boldsymbol{\xi}_1=\begin{bmatrix}1\\-1\end{bmatrix}

$\lambda_2=4$ 的特征向量A-4I=\begin{bmatrix}-1&1\\1&-1\end{bmatrix} 方程:$-x_1+x_2=0 \Rightarrow x_2=x_1$$x_1=1$\boldsymbol{\xi}_2=\begin{bmatrix}1\\1\end{bmatrix}

验证:A\boldsymbol{\xi}_1=2\boldsymbol{\xi}_1,\ A\boldsymbol{\xi}_2=4\boldsymbol{\xi}_2

例2:二重特征值(亏损矩阵示例)

A=\begin{bmatrix}2&1\\0&2\end{bmatrix}

\mathrm{tr}=4,\det=4,特征方程 $\lambda^2-4\lambda+4=0$$\lambda=2$(二重根)

A-2I=\begin{bmatrix}0&1\\0&0\end{bmatrix}

方程:$0\cdot x_1+1\cdot x_2=0 \Rightarrow x_2=0$

基础解系仅1个:\boldsymbol{\xi}=\begin{bmatrix}1\\0\end{bmatrix}

二重特征值只对应1个线性无关特征向量,矩阵不可对角化。

例3:共轭复特征值

A=\begin{bmatrix}0&-1\\1&0\end{bmatrix}

$\mathrm{tr}=0,\det=1$

\lambda^2+1=0 \Rightarrow \lambda_1=i,\ \lambda_2=-i

$\lambda=i$

A-iI=\begin{bmatrix}-i&-1\\1&-i\end{bmatrix},\quad -i x_1 -x_2=0 \Rightarrow x_2=-i x_1

$x_1=1$,复特征向量 $\boldsymbol{\xi}=\begin{bmatrix}1\\-i\end{bmatrix}$

 几何意义:矩阵代表线性变换,特征向量是变换中 “不跑偏” 的方向,特征值是拉伸 / 压缩程度。

import numpy as np
# 输入方阵A
A = np.array([[2, 1], [1, 2]])
# eigvals:只算特征值
vals = np.linalg.eigvals(A)
# eig:同时返回特征值、特征向量矩阵
vals, vecs = np.linalg.eig(A)
print(vals)
print(vecs)

    输出:

    [3. 1.]
    [[ 0.70710678 -0.70710678]
     [ 0.70710678  0.70710678]]
    • vecs[:,i]:第 i 个特征向量
    • vals[i]:对应第 i 个特征值

    验证公式 A\boldsymbol{v}=\lambda\boldsymbol{v}

    v = vecs[:,0]
    lam0 = vals[0]
    print(A @ v)
    print(lam0 * v) # 两者完全相等

    代码2:

    import numpy as np
    
    A = np.array([[2, 0], [0, 1]])  # 水平拉伸2倍,垂直不变
    eigenvalues, eigenvectors = np.linalg.eig(A)
    
    print("特征值:", eigenvalues)       # [2. 1.]
    print("特征向量 (列):\n", eigenvectors)
    
    # 验证 Av = λv
    for i in range(2):
        v = eigenvectors[:, i]
        lam = eigenvalues[i]
        print(f"\n验证特征向量{i+1}:")
        print(f"  A @ v = {A @ v}")
        print(f"  λ * v = {lam * v}")
        print(f"  相等: {np.allclose(A @ v, lam * v)}")
    
    # 对称矩阵的特征值全实数
    S = np.array([[1, 4], [4, 2]])
    print(f"\n对称矩阵 S 的特征值: {np.linalg.eigvals(S)}(全实数)")

    AI 中的应用场景

    PCA 降维:计算数据协方差矩阵的特征值和特征向量。最大的 k 个特征值对应的特征向量就是数据方差最大的 k 个方向(主成分)。将数据投影到这些方向上,方差小的方向被丢弃,实现降维。从 784 维的 MNIST 图像降到 50 维,仍能保留约 90% 的信息。

    谱归一化(Spectral Normalization):在 GAN 训练中,判别器的权重矩阵每步做谱归一化:W \leftarrow W / \sigma_{max}(W),其中 \sigma_{max} 是最大的奇异值(方阵时 = 最大特征值的绝对值)。这确保判别器是 1-Lipschitz 的,稳定训练、减少模式崩塌。

    图神经网络的谱方法:图拉普拉斯矩阵 L = D - A(D 是度对角矩阵,A 是邻接矩阵)的特征值和特征向量定义了图上的傅里叶变换。GCN(图卷积网络)就是在这个谱域上做卷积——虽然现代 GCN 更多用空间域方法,但谱方法是理论基础。

    矩阵的秩

    从鸡兔同笼到 AI 模型训练,线性方程组无处不在。矩阵的「秩」告诉我们方程组中真正有效的信息量有多少。

    任何线性方程组都可以写成 Ax = b

    A 是系数矩阵(m 个方程,n 个未知数),x 是未知数向量,b 是常数向量。例如鸡兔同笼:\left\{\begin{matrix} x+y=10 \\ 2x+4y=28 \end{matrix}\right.   ​ 写成矩阵形式:\begin{bmatrix} 1 & 1\\ 2 & 4 \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix}=\begin{bmatrix} 10\\ 28 \end{bmatrix}

    秩:独立信息的数量:秩(Rank)= 矩阵中真正「独立」的行数(或列数)。

    如果某个方程可以由其他方程乘以系数得到,它就是冗余的——不增加新信息。

    鸡兔同笼:满秩,唯一解

    头数 10 + 脚数 28 → 鸡 6 只、兔 4 只。两个方程提供两条独立信息,刚好解出两个未知数。

    冗余信息:欠秩,无穷多解

    方程一:x + y = 5。方程二:2x + 2y = 10(就是方程一的 2 倍)。两个方程其实是一条信息——有无穷多对 (x, y) 满足条件。

    秩的判定

    条件 解的情况
    rank(A) = rank([A|b]) = n 唯一解
    rank(A) = rank([A|b]) < n 无穷多解
    rank(A) < rank([A|b]) 无解

    其中 [A|b] 是把 b 拼在 A 右边的增广矩阵。

    import numpy as np
    
    # 鸡兔同笼:满秩
    A = np.array([[1,1],[2,4]])
    b = np.array([10,28])
    x = np.linalg.solve(A, b)
    print("解:", x, "→ 鸡=6, 兔=4")
    print("秩:", np.linalg.matrix_rank(A))  # 2(满秩)
    
    # 冗余方程
    A_red = np.array([[1,2],[2,4]])  # 第2行=2×第1行
    print("\n冗余矩阵的秩:", np.linalg.matrix_rank(A_red))  # 1
    
    # 随机大矩阵的秩
    big = np.random.randn(100, 50)
    print("100×50 随机矩阵的秩:", np.linalg.matrix_rank(big))  # 50

    输出:

    解: [6. 4.] → 鸡=6, 兔=4
    秩: 2(满秩)
    冗余矩阵的秩: 1
    100×50 随机矩阵的秩: 50

    AI 中的应用场景

    LoRA 微调 = 低秩假设:LoRA(Low-Rank Adaptation)的核心假设:预训练权重的微调更新量 \Delta W 是低秩的。因此可以用两个小矩阵 A(d×r)和 B(r×d)的乘积来近似完整更新量 \Delta W = AB,其中 r << d。

    例如对 GPT-3 的 12288 维权重矩阵,r 取 8 或 16 就够了——秩从 12288 降到 8,参数量减少上千倍。这就是利用「秩」的概念做参数高效微调。

    特征共线性检测:数据矩阵的秩远小于列数 → 特征之间存在高度共线性(多重共线性)→ 线性回归的 X^TX 不可逆或接近奇异 → 需要正则化(Ridge/Lasso)或降维(PCA)。在实际 ML 项目中,这表现为特征矩阵的条件数过大。

    推荐系统中的矩阵补全:用户-物品评分矩阵通常只有少数评分(稀疏),但假设它是由低秩结构生成的(相似用户有相似口味)。矩阵补全(Matrix Completion)利用秩的约束,通过已知评分推断缺失评分。这是 Netflix 推荐大赛获奖算法的核心思想。

    奇异值分解(SVD)

    \boldsymbol{A} 是 m\times n实矩阵,则奇异值分解:\boldsymbol{A}_{m\times n} = \boldsymbol{U}_{m\times m}\boldsymbol{\Sigma}_{m\times n}\boldsymbol{V}^T_{n\times n}

    各个矩阵含义

    \boldsymbol{U}左奇异向量矩阵,正交矩阵 \boldsymbol{U}^T\boldsymbol{U}=\boldsymbol{I}

    \boldsymbol{\Sigma}:奇异值对角矩阵,只有主对角线非零

    \boldsymbol{\Sigma}= \begin{pmatrix} \sigma_1 & & \\ & \sigma_2 & \\ & & \ddots \\ &&&\sigma_r\\ &&&&0 \end{pmatrix},\quad \boldsymbol{\sigma_1\ge \sigma_2\ge \dots \ge \sigma_r>0}

    \sigma_i 称为奇异值r=\mathrm{rank}(A)

    \boldsymbol{V}右奇异向量矩阵,正交矩阵 \boldsymbol{V}^T\boldsymbol{V}=\boldsymbol{I}

    import numpy as np
    
    A = np.array([[1,0,0,0,2],[0,0,3,0,0],[0,0,0,0,0],[0,4,0,0,0]])
    U, S, VT = np.linalg.svd(A)
    print("奇异值:", np.round(S, 2))  # [4. 3. 2.24 0.]
    print("非零奇异值个数 = 秩 =", np.sum(S > 1e-10))
    
    # 图像压缩演示:秩为1的图像
    img = np.outer(np.array([1,2,3,2,1]), np.array([2,4,6,4,2]))
    U_i, S_i, VT_i = np.linalg.svd(img)
    print("\n图像矩阵的奇异值:", np.round(S_i, 2))
    # 只用1个奇异值完美重建(因为秩=1)
    k = 1
    approx = U_i[:,:k] @ np.diag(S_i[:k]) @ VT_i[:k,:]
    print("k=1重建误差:", np.linalg.norm(img - approx))

    代码2:

    import numpy as np
    
    A = np.array([[1,2,3],[4,5,6]])
    U, s, Vt = np.linalg.svd(A)
    
    print("U:\n",U)
    print("奇异值s:",s)
    print("V转置:\n",Vt)
    
    # 构造Sigma
    Sigma = np.zeros_like(A, dtype=float)
    np.fill_diagonal(Sigma, s)
    
    # 还原A
    A_recon = U @ Sigma @ Vt
    print("重构误差",np.linalg.norm(A - A_recon))
    

    AI 中的应用场景

    LoRA 微调的数学基础:LoRA 假设 :ΔW是低秩的——这等价于假设 ΔW 的 SVD 中只有前 r 个奇异值显著,其余可以忽略。r 取得越小,可训练参数越少,但近似精度越低。实践中 r=8 或 16 常是效果与效率的最佳平衡点,这源于对权重矩阵奇异值衰减速度的经验观察。

    推荐系统:矩阵分解协同过滤:用户-物品评分矩阵 R(m×n)做截断 SVD:R\approx U_k\Sigma_kV_k^T​。U_k 的每行是用户的 k 维隐向量,V_k 的每行是物品的 k 维隐向量。用户 u 对物品 i 的预测评分 = u 的隐向量与 i 的隐向量的点积。

    模型压缩与蒸馏:全连接层的权重矩阵 W 做 SVD 后,用截断 SVD 近似:W\approx U_k\Sigma_kV_k^T。原矩阵 m×n 的参数量为 mn,分解后为 k(m+n+1)。当 k << min(m,n) 时,参数量大幅减少。这在移动端部署大模型时非常有用。

    PCA 的 SVD 实现:sklearn 的 PCA 底层不用特征分解而是用 SVD——对中心化后的数据矩阵直接做 SVD,右奇异向量 V 的列就是主成分方向。SVD 数值更稳定且不需要显式计算协方差矩阵。

    向量空间与基

    同一个位置,在 GPS 坐标系和北斗坐标系下的经纬度数值不同——但位置本身没变。向量也一样:同一个向量在不同基下有不同坐标。理解这一点,就理解了 PCA 降维和词嵌入空间的本质。

    向量空间 = 一个集合,其中的元素(向量)对加法和数乘封闭。

    封闭 = 空间内任意两个向量相加、或任意向量乘标量,结果仍在空间内。

    基:描述空间的坐标尺,基是一组向量,用它们的线性组合可以唯一地表示空间中任意向量。

    标准基:(1,0,0)、(0,1,0)、(0,0,1)——分别代表 x、y、z 轴方向。

    线性无关:没有冗余,

    一组向量线性无关 = 其中没有任何向量可以由其他向量线性组合表示。

    直觉:每个向量都带来真正的「新方向」,没有浪费。

    import numpy as np
    
    # 标准基
    e1, e2, e3 = np.array([1,0,0]), np.array([0,1,0]), np.array([0,0,1])
    v = np.array([4, 5, 6])
    print("v = 4*e1 + 5*e2 + 6*e3:", 4*e1 + 5*e2 + 6*e3)
    
    # 用秩判断线性无关
    v1, v2 = np.array([1,2]), np.array([2,4])  # v2 = 2*v1
    M = np.column_stack([v1, v2])
    print(f"{{v1, v2}} 的秩: {np.linalg.matrix_rank(M)} (< 2 → 线性相关)")
    
    # 换基:同一向量,不同基下的坐标不同
    v_std = np.array([3.0, 2.0])
    B_new = np.array([[2.0, 0], [0, 3.0]])  # 新基
    v_new = np.linalg.inv(B_new) @ v_std
    print(f"标准坐标: {v_std}, 新基下坐标: {v_new}")
    print(f"验证 B @ 新坐标 = {B_new @ v_new}")

    输出:

    v = 4*e1 + 5*e2 + 6*e3: [4 5 6]
    {v1, v2} 的秩: 1 (< 2 → 线性相关)
    标准坐标: [3. 2.], 新基下坐标: [1.5 0.67]
    验证 B @ 新坐标 = [3. 2.]

    AI 中的应用场景

    PCA 降维 = 换基:PCA 找到一组新的标准正交基(主成分方向),使数据在新基的前 k 个坐标上方差最大。降维 = 只保留前 k 个新基坐标,扔掉后方差小的方向。这本质上是坐标系变换——从一个 784 维的像素空间换到 50 维的主成分空间。

    词嵌入空间:Word2Vec 和 GloVe 将每个词映射到 300 维向量空间中的一个点。这个空间不是随意构造的——词与词之间的几何关系反映了语义关系。同义词距离近,反义词在某些方向上正好相反。向量空间中的线性运算(加减)对应语义操作。

    特征空间变换:神经网络的每一层都可以看作将输入映射到一个新的向量空间。原始空间中线性不可分的数据(如 XOR 问题),经过隐藏层变换到特征空间后变得线性可分。这就是深度学习的核心直觉——逐层变换,最终在特征空间中用简单分类器即可分开。

    导数/微分

    设函数 y=f(x) 在 x_0 邻域有定义,自变量增量 \Delta x = x - x_0,函数增量:

    \Delta y = f(x_0+\Delta x)-f(x_0) 若极限存在(函数连续不断裂),则称 f(x) 在 x_0 可导,导数记作 f'(x_0)

    \boldsymbol{f'(x_0) = \lim_{\Delta x \to 0}\frac{f(x_0+\Delta x)-f(x_0)}{\Delta x}}

    等价写法:

    f'(x)=\lim_{h\to0}\frac{f(x+h)-f(x)}{h}

    微分 dy

    dy = f'(x)dx,代表函数微小变化量,用直线(切线)近似一小段曲线,即以直代曲

    \frac{dy}{dx} = f'(x)= \lim_{h\to0}\frac{f(x+h)-f(x)}{h}

    平时大家说 “求微分”“求导” 经常混用,做题时不严格区分;

    导数几何意义 = 函数在该点切线斜率

    物理意义:瞬时变化率:速度、变化快慢。

    分类

    原函数f(x)

    导数结果f'(x)

    示例

    常数

    C

    0

    (3)' = 0

    幂函数

    x^n

    nx^{n-1}

    (x^2)'=2x,\ (x^3)'=3x^2,\ (\sqrt{x})'=\frac{1}{2\sqrt{x}}

    一次函数

    kx

    k

    (5x)'=5

    自然指数

    e^x

    e^x

    (e^x)'=e^x

    指数函数

    a^x

    a^x\ln a

    (2^x)'=2^x\ln 2

    自然对数

    \ln x

    \dfrac1x

    (\ln x)'=\dfrac1x

    对数函数

    \log_a x

    \dfrac{1}{x\ln a}

    (\log_3 x)'=\dfrac{1}{x\ln3}

    正弦

    \sin x

    \cos x

    (\sin x)'=\cos x

    余弦

    \cos x

    -\sin x

    (\cos x)'=-\sin x

    导数的四则运算

    公式 示例
    (f\pm g)'=f'\pm g' (e^{x}+4lnx)' =(e^{x})'+(4lnx)'=e^{x}+\frac{4}{x}
    (fg)'=f'g+fg' (sinx\cdot lnx)'=(sinx)'\cdot lnx+sinx\cdot (lnx)'=cosx\cdot lnx+sinx\cdot \frac{1}{x}
    (\frac{f}{g})'=\frac{f'g-fg'}{g^2} (\frac{e^{x}}{cosx})'=\frac{(e^{x})'\cdot cosx-e^{x}\cdot (cosx)'}{cos^{2}(x)}=\frac{e^{x}\cdot cosx-e^{x}\cdot (-sinx)}{cos^{2}(x)}
    \left \{ f\left [ g(x)\right ] \right \}'=f'(g)\cdot g'(x) (e^{2x})'=e^{2x}\cdot (2x)'=2e^{2x}\\\\(cos2x)'=(-sin2x)\cdot (2x)'=-2sin2x

    练习1:y = x^{3} - 2 x^{2} + sinx ,求f'(x)

    答案:3x^{2}-4x+cosx

    练习2:已知函数 y=sin2x ,求 \frac{dy}{dx}

    答案:2cos2x

    练习3:求函数 y=sinx\cdot lnx 的导数。

    答案:cosx\cdot lnx+sinx\cdot \frac{1}{x}

    练习4:已知 f(x)=e^{-ix}(\cos x+i\sin x),求 f'(x)

    f'(x) = -i e^{-ix}(\cos x+i\sin x)+e^{-ix}(-\sin x+i\cos x)\\\\ =e^{-ix}\left[-i\cos x+\sin x -\sin x+i\cos x\right]\\\\ =0

    代码1:

    import numpy as np
    
    def f(x):
        return (x**2 - 1) / (x - 1)
    
    print("=== lim_{x->1} (x^2-1)/(x-1) = 2 ===")
    # 从左右两边逼近
    for delta in [0.1, 0.01, 0.001, 0.0001]:
        print(f"x = {1-delta:.4f}, f(x) = {f(1-delta):.6f}")
        print(f"x = {1+delta:.4f}, f(x) = {f(1+delta):.6f}")
    print("→ 无论从哪边逼近,f(x)都趋近于 2")

    输出:

    === lim_{x->1} (x^2-1)/(x-1) = 2 ===
    x = 0.9000, f(x) = 1.900000
    x = 1.1000, f(x) = 2.100000
    x = 0.9900, f(x) = 1.990000
    x = 1.0100, f(x) = 2.010000
    → 无论从哪边逼近,f(x)都趋近于 2

    代码2:

    import numpy as np
    
    def numerical_derivative(f, x, h=1e-5):
        return (f(x + h) - f(x - h)) / (2 * h)
    
    f = lambda x: x**2
    
    # f'(2) = 2*2 = 4
    print(f"f'(2) 数值={numerical_derivative(f, 2):.6f}, 理论=4")
    
    # 各点的导数
    for x in [-2, -1, 0, 1, 2]:
        d = numerical_derivative(f, x)
        dir = "下降" if d < 0 else ("上升" if d > 0 else "水平")
        print(f"x={x:2d}, f'(x)={d:5.1f}, {dir}")

    输出:

    f'(2) 数值=4.000000, 理论=4
    x=-2, f'(x)= -4.0, 下降
    x=-1, f'(x)= -2.0, 下降
    x= 0, f'(x)=  0.0, 水平
    x= 1, f'(x)=  2.0, 上升
    x= 2, f'(x)=  4.0, 上升

    代码3

    import sympy as sp
    
    x = sp.Symbol('x')
    funcs = {'x^3': x**3, 'e^x': sp.exp(x), 'ln(x)': sp.log(x),
             'x^2 + 3x + 5': x**2 + 3*x + 5}
    
    print("=== 符号求导验证 ===")
    for name, f in funcs.items():
        print(f"f(x)={name:15s} → f'(x)={sp.diff(f, x)}")
    
    # 乘积法则
    f = x**2 * sp.exp(x)
    print(f"\n(x^2 · e^x)' = {sp.diff(f, x)}")
    # 链式法则:(2x+1)^3 的导数
    g = (2*x + 1)**3
    print(f"((2x+1)^3)' = {sp.diff(g, x)}")

    AI 中的应用场景

    梯度下降的一维原型:对于单变量函数,梯度下降退化为x_{new}=x_{old}-\eta \cdot f'(x_{old}) 。导数告诉你「往哪边走函数值会减小」——导数正就向左走,导数负就向右走。

    激活函数的导数决定反向传播效率:ReLU 的导数:x>0 时为 1,x≤0 时为 0。计算极快,且正半区梯度不衰减——这是 ReLU 比 Sigmoid 更适合深层网络的关键原因。Sigmoid 的导数最大只有 0.25,多层相乘后梯度指数级衰减(梯度消失)。

    损失函数在最优解处的导数为零:当模型收敛到局部最优时,损失函数关于所有参数的偏导都接近 0——梯度下降自然停止。这是训练收敛的信号:梯度范数 ||\nabla J|| \approx 0

    积分

    积分的核心思想:无限分割、微小量累加,求一段区间内的总累积量;微分是细分看变化率,积分是汇总算总量,二者互为逆运算。

    若函数 F(x) 的导数等于 f(x):即 F'(x) = f(x)

    则称 F(x)f(x) 的一个原函数

    例:(x^2)'=2x,所以 F(x)=x^2 是 f(x)=2x 的一个原函数。

    不定积分: \displaystyle\int f(x)dx=F(x)+C (求导逆运算,求解原函数)

    定积分: \displaystyle\int_{a}^{b}f(x)dx (区间[a,b]内曲线围成的净面积)

    牛顿-莱布尼兹公式

    \boldsymbol{\int_{a}^{b} f(x) dx = F(x)\big|_{a}^{b} = F(b)-F(a)}

    例题1:计算 \int_{0}^{2}2x\,dx 

    求解原函数 F(x)=x^2

    \int_{0}^{2}2x dx = F(2)-F(0)=2^2-0^2=4

    例题2:计算\int_{0}^{3}(2x+1)dx

    求解原函 (x^{2}+x)'=2x+1,取 F(x)=x^{2}+x

    \int_{0}^{3}(2x+1) dx = F(3)-F(0)=(x^{2}+x)|_{0}^{3}=(3^2+3)-(0^2-0)=12

    例题:用定积分求 y=\sin x 在[0,\pi]与 x 轴围成的面积。

    x\in[0,\pi] 时 \sin x\ge0,面积等于定积分: S=\int_{0}^{\pi}\sin x \,dx

    原函数:\int \sin x \,dx = -\cos x + C

    牛顿–莱布尼茨公式代入上下限

    \int_{0}^{\pi}\sin x \,dx = \big(-\cos x\big)\,\bigg|_{0}^{\pi} \\\\ = -\cos\pi - (-\cos 0) \\\\ = -(-1) - (-1) \\\\ = 1 + 1 \\\\ = 2

    结论:\sin x 在 0 到 \pi 之间与 x 轴围成的面积为 2。

    例题3:球的表面积公式为 S = 4πr²,体积公式为 V = (4/3)πr³。体积求导就是表面积。

    公式说明

    • 半径 r:球心到球面任意一点的距离
    • 直径 D:球的最大距离,D = 2r
    • 表面积 S:球表面所占的面积,S = 4πr² = πD² 
    • 体积 V:球内部空间的大小,V = (4/3)πr³ 

    公式推导概述

    微积分法:将球体沿半径方向分割成无数个薄壳层,每层厚度趋近于零时,薄壳体积除以厚度即为表面积,积分求和得到体积公式。

    梯度

    一元函数一阶导数就是该函数的梯度

    自动微分(Automatic Differentiation)TensorFlow 使用 GradientTape 来记录运算并自动计算梯度:函数:f(x) = 3x^2 + 2x + 1 解析导数:f'(x)=6x+2,验证 x=2 时导数 = 14

    x = tf.Variable(2.0)
    
    with tf.GradientTape() as tape:
        y = 3 * x**2 + 2 * x + 1
    
    # 求dy/dx
    dy_dx = tape.gradient(y, x)
    print(f"计算导数:{dy_dx.numpy()}")  # 输出14.0
    print(f"解析解验证:6*2+2 = {6*2+2}")

    多元函数梯度是各偏导组成的梯度向量

    二元函数:f(x,y) = x^2 + 3xy + y^3

    偏导数:

    \frac{\partial f}{\partial x}=2x+3y,\quad \frac{\partial f}{\partial y}=3x+3y^2

    梯度为[\frac{\partial f}{\partial x}=2x+3y,\quad \frac{\partial f}{\partial y}=3x+3y^2]

    取 x=1, y=2

    x = tf.Variable(1.0)
    y = tf.Variable(2.0)
    
    with tf.GradientTape() as tape:
        f = x**2 + 3*x*y + y**3
    
    # 一次性求多个梯度
    df_dx, df_dy = tape.gradient(f, [x, y])
    print(f"df/dx = {df_dx.numpy()}")  # 2*1+3*2=8
    print(f"df/dy = {df_dy.numpy()}")  # 3*1+3*(2^2)=15
    # 梯度向量 [8,15]
    import numpy as np
    
    def f(x, y):
        return x**2 + y**2  # 碗形函数
    
    def grad(x, y):
        return np.array([2*x, 2*y])
    
    pt = np.array([1.5, 1.0])
    g = grad(*pt)
    print(f"在 (1.5, 1.0): 梯度 = {g}")
    print(f"梯度模长 = {np.linalg.norm(g):.2f}")
    print(f"梯度指向远离原点(上升),负梯度指向原点(下降)")

    多元函数:J(\theta_0,\theta_1,...,\theta_n),参数向量\boldsymbol{\theta} = [\theta_0,\theta_1,...,\theta_n]^T

    梯度 \nabla J(\boldsymbol{\theta}) 是损失函数对所有参数的偏导数构成的向量:

    \nabla J(\boldsymbol{\theta}) = \begin{bmatrix} \frac{\partial J}{\partial \theta_0} \\\\ \frac{\partial J}{\partial \theta_1} \\\\ \vdots \\\\ \frac{\partial J}{\partial \theta_n} \end{bmatrix}

    代码:

    import sympy as sp
    
    x, y = sp.symbols('x y')
    f = x**2 + x*y + y**2
    print(f"f(x,y) = {f}")
    print(f"∂f/∂x = {sp.diff(f, x)}")  # 2x + y
    print(f"∂f/∂y = {sp.diff(f, y)}")  # x + 2y
    
    # 二阶偏导
    print(f"∂²f/∂x² = {sp.diff(f, x, 2)}")      # 2
    print(f"∂²f/∂x∂y = {sp.diff(f, x, y)}")     # 1
    
    # 线性模型损失对参数的偏导
    w, b, xi, yi = sp.symbols('w b x_i y_i')
    loss = (w*xi + b - yi)**2
    print(f"\nloss=(w·xi+b-yi)^2")
    print(f"∂L/∂w = {sp.diff(loss, w)}")
    print(f"∂L/∂b = {sp.diff(loss, b)}")

    输出:

    f(x,y) = x**2 + x*y + y**2
    ∂f/∂x = 2*x + y
    ∂f/∂y = x + 2*y
    ∂²f/∂x² = 2
    ∂²f/∂x∂y = 1
    
    loss=(w·xi+b-yi)^2
    ∂L/∂w = 2*x_i*(b + w*x_i - y_i)
    ∂L/∂b = 2*b + 2*w*x_i - 2*y_i

    AI 中的应用场景

    神经网络训练 = 百万次偏导计算:一个百万参数的模型,损失是关于百万个变量的多元函数。每轮训练,自动微分引擎对每一个参数求偏导,得到百万个偏导数值拼成梯度向量,沿负梯度方向更新所有参数。

    冻结参数的迁移学习:迁移学习中常「冻结」预训练层——这些层的参数不求偏导、不更新。PyTorch 中设置 requires_grad=False,对应参数的偏导计算被跳过,大幅节省显存和计算量。

    梯度下降算法

    梯度下降是最小化损失函数的迭代优化算法,广泛用于线性回归、逻辑回归、神经网络。

    一句话:沿着损失函数梯度的反方向,一步步更新参数,直到损失最小

    梯度方向 = 函数上升最快的方向,在一维平面函数中即为函数的导数,在二维或多维函数中为每个参数偏导数所构成的向量。

    目标:找到损失函数 f(x) = x^2 - 4x + 5 最小值。它的函数图像如下:

     f(x) = x^2 - 4x + 5 损失函数对应的导数为 {f}'(x) = 2x - 4,当然只需要调用 gradient 方法即可得到。

    通用梯度下降迭代公式:\boldsymbol{\theta} = \boldsymbol{\theta} - \alpha \cdot \nabla J(\boldsymbol{\theta}) ,\alpha学习率(learning rate),控制每一步走多大。(梯度/导数越大,说明此时前进的步子越大,为了防止迭代步子太大超过极值使用 \alpha 控制,梯度前加⼀个负号,就意味着朝着梯度相反的⽅向前进!我们在前⽂提到,梯度的⽅向实际就是函数在此点上升最快的⽅向!⽽我们需要朝着下降最快的⽅向⾛,⾃然就是负的梯度的⽅向,所以此处需要加上负号)

    学习率	效果
    太小	收敛极慢,需要很多步
    适中	平稳快速收敛
    太大	震荡甚至发散

    极小值点 x=2 手动利用梯度迭代更新参数

    x = tf.Variable(0.0) #从0开始找
    lr = 0.2  # 学习率
    epochs = 30 #迭代30次
    
    for i in range(epochs):
        with tf.GradientTape() as tape:
            y = x**2 - 4*x +5
        grad = tape.gradient(y, x)
        # 梯度下降更新:x = x - lr * grad
        x.assign_sub(lr * grad)
        if i % 5 == 0:
            print(f"迭代{i}, x={x.numpy():.3f}, loss={y.numpy():.3f}")

    输出会逐步收敛到 x≈2,loss≈1。

    迭代0, x=0.800, loss=5.000
    迭代5, x=1.907, loss=1.024
    迭代10, x=1.993, loss=1.000
    迭代15, x=1.999, loss=1.000
    迭代20, x=2.000, loss=1.000
    迭代25, x=2.000, loss=1.000
    import numpy as np
    
    # 生成数据 y = 3x + 2 + noise
    np.random.seed(42)
    X = np.linspace(0, 10, 100)
    y = 3 * X + 2 + np.random.normal(0, 2, 100)
    
    # 从零实现梯度下降
    w, b = 0.0, 0.0
    lr, n_iter = 0.01, 200
    losses = []
    
    for i in range(n_iter):
        y_pred = w * X + b
        loss = np.mean((y_pred - y) ** 2)
        losses.append(loss)
        # 梯度
        dw = 2 * np.mean((y_pred - y) * X)
        db = 2 * np.mean(y_pred - y)
        # 更新
        w -= lr * dw
        b -= lr * db
    
    print(f"RUNOOB 梯度下降结果:")
    print(f"真实: w=3.0, b=2.0")
    print(f"拟合: w={w:.4f}, b={b:.4f}")
    print(f"初始损失: {losses[0]:.2f} → 最终损失: {losses[-1]:.2f}")
    RUNOOB 梯度下降结果:
    真实: w=3.0, b=2.0
    拟合: w=2.9874, b=2.2835
    初始损失: 79.69 → 最终损失: 3.91

    链式法则

    2.复数乘法与欧拉公式

    虚数单位

    规定:\boldsymbol{i^2 = -1},i 叫虚数单位。 实数范围内负数不能开平方,引入 i 后可以计算 \sqrt{-a}=ia (a>0)

    复数标准形式

    任意复数写成:

    \boldsymbol{z = a + bi}

    • a:实部,记作 \mathrm{Re}(z)=a
    • b:虚部,记作 \mathrm{Im}(z)=b
    • a,b 都是实数

    举例:

    • 3+4i:实部 3,虚部 4
    • 5-2i=5+(-2)i:实部 5,虚部 - 2
    • 纯实数 7=7+0i,虚部为 0
    • 纯虚数 -6i=0-6i,实部为 0

    复平面(几何意义)

    每个复数 z=a+bi 对应平面上一个点 (a,b)

    • 横轴:实轴(实数)
    • 纵轴:虚轴(虚部) 这个平面叫复平面

    复数的模(到原点距离):|z|=\sqrt{a^2+b^2}

    复数乘法(代数形式)

    设两个复数:

    z_1=a+bi,\quad z_2=c+di 乘法直接按多项式展开,再代入 i^2=-1 化简:

    z_1 z_2 = (a+bi)(c+di)

    = ac + adi + bci + bdi^2

    = ac + (ad+bc)i + bd(-1)

    = \boldsymbol{(ac-bd) + (ad+bc)i}

    例题 1:计算 (2+3i)(1-4i)

    (2+3i)(1-4i)\\=2\times 1 - 3\times(-4) + \big(2\times(-4)+3\times1\big)i \\=2 + 12 + (-8+3)i \\=14 -5i

    例题 2 :纯虚数相乘

    i\cdot i = i^2 = -1

    2i\cdot 3i = 6i^2 = -6

    复数乘法的几何意义,极坐标形式

    复数写成极坐标:z=r(\cos\theta + i\sin\theta)

    • r=|z|:模长
    • \theta:辐角(与实轴夹角)

    乘法几何法则

    z_1=r_1(\cos\theta_1+i\sin\theta_1),\quad z_2=r_2(\cos\theta_2+i\sin\theta_2) 则

    .....用到公式:两角和差‌:sin(A±B)=sinAcosB±cosAsinB,cos(A±B)=cosAcosB∓sinAsinB。

    \boldsymbol{z_1 z_2 = r_1 r_2 \big[\cos(\theta_1+\theta_2)+i\sin(\theta_1+\theta_2)\big]}

    一句话总结几何意义:

    1. 模相乘:新模长 = 两个模长相乘
    2. 辐角相加:新角度 = 两个辐角相加

    直观例子

    乘以 i:i=1\cdot(\cos\frac{\pi}{2}+i\sin\frac{\pi}{2}) 任意复数乘 i:模不变,辐角加 90^\circ,相当于复平面上逆时针旋转 90°

    指数形式(欧拉公式)

    由于导数节我们对函数 f(x)=e^{-ix}(\cos x+i\sin x) 求导 f'(x)=0

    导数恒为 0,说明 f(x) 是常数。代入 x=0

    f(0)=e^{0}(\cos0+i\sin0)=1,因此 f(x)\equiv1,整理:

    e^{-ix}(\cos x+i\sin x)=1 \implies e^{ix}=\cos x+i\sin x

    e^{i\theta} = \cos\theta + i\sin\theta   左边 e^{i\theta}虚指数,不能用实数指数思维硬理解,它只是一个简写记号,等价于右边的三角函数复数。

    • e:自然常数,约 2.71828,和实数指数 e^x 是同一个底数;
    • i:虚数单位,i^2=-1
    • \theta:弧度制角度(复数的辐角),实数;

    举几个直观例子:

    1.\theta=0

    e^{i\cdot0}=\cos0+i\sin0=1+0i=1

    2.\theta=\pi(180°)

    e^{i\pi}=\cos\pi+i\sin\pi=-1+0i=-1

    这就是著名的欧拉恒等式:\boldsymbol{e^{i\pi}+1=0}(统一:e,\pi,i,1,0 五大基础常数。)

    3.\theta=\dfrac{\pi}{2}(90°)

    e^{i\frac{\pi}{2}}=\cos\frac{\pi}{2}+i\sin\frac{\pi}{2}=0+1i=i

    4.\theta=\dfrac{3\pi}{2}(270°) 

    e^{i\frac{3\pi}{2}}=\cos\frac{3\pi}{2}+i\sin\frac{3\pi}{2}=-i

    欧拉公式验证代码

    import os
    import tensorflow as tf
    
    # 统一 float64 精度
    pi = tf.math.acos(tf.constant(-1.0, dtype=tf.float64))
    x = pi
    
    # 实部、虚部全部强制 float64
    z = tf.complex(tf.constant(0.0, dtype=tf.float64), x)
    
    # e^(ix)
    left = tf.exp(z)
    # cosx + i sinx
    right = tf.complex(tf.cos(x), tf.sin(x))
    
    print("e^(iπ) =", left.numpy())
    print("cosπ + i sinπ =", right.numpy())

    复数的指数形式

    之前讲过复数三角形式: z=r(\cos\theta+i\sin\theta) 根据欧拉公式 \cos\theta+i\sin\theta=e^{i\theta},直接替换括号里的部分: \boldsymbol{z=re^{i\theta}}

    • r:复数的模(长度,实数≥0);
    • e^{i\theta}:只负责描述方向(旋转角度),模永远等于 1;

    举例: 复数 z=2+2i 模 r=\sqrt{2^2+2^2}=2\sqrt{2},辐角 \theta=\dfrac{\pi}{4} 指数形式: z=2\sqrt{2}\cdot e^{i\frac{\pi}{4}}

    指数形式下复数乘法

    公式:z_1 z_2 = r_1 r_2 e^{i(\theta_1+\theta_2)} 计算过程如下:

    设两个复数:z_1=r_1 e^{i\theta_1},\quad z_2=r_2 e^{i\theta_2}

    第一步:分开实数部分和指数部分

    z_1 z_2 = \big(r_1 \cdot e^{i\theta_1}\big) \cdot \big(r_2 \cdot e^{i\theta_2}\big)

    实数 r_1,r_2 可以交换位置,先相乘;指数项放一起: z_1 z_2 = (r_1 \cdot r_2) \cdot \big(e^{i\theta_1} \cdot e^{i\theta_2}\big)

    第二步:虚指数运算法则(和实数指数一样)

    实数指数公式:e^a \cdot e^b = e^{a+b} 虚指数完全沿用这条规则: e^{i\theta_1} \cdot e^{i\theta_2} = e^{i\theta_1+i\theta_2} = e^{i(\theta_1+\theta_2)}

    第三步:合并得到乘法公式

    \boldsymbol{z_1 z_2 = (r_1 r_2)\,e^{i(\theta_1+\theta_2)}}

    文字翻译(对应之前几何意义)

    1. 新模长 = 两个复数模相乘:r=r_1 r_2
    2. 新辐角 = 两个复数角度相加:\theta=\theta_1+\theta_2

    实操例题:设 z_1=2e^{i\frac{\pi}{3}},\quad z_2=3e^{i\frac{\pi}{6}} 求 z_1 z_2

    z_1 z_2 = (2\times 3)\cdot e^{i\left(\frac{\pi}{3}+\frac{\pi}{6}\right)} =6 e^{i\frac{\pi}{2}}

    再转回代数形式:6e^{i\frac{\pi}{2}}=6\left(\cos\frac{\pi}{2}+i\sin\frac{\pi}{2}\right)=6i

    乘法核心性质

    复数乘法五条性质与实数完全相同,有兴趣同学自行证明其过程。

    • 交换律:z_1 z_2 = z_2 z_1
    • 结合律:(z_1 z_2)z_3 = z_1(z_2 z_3)
    • 分配律:z_1(z_2+z_3)=z_1 z_2 + z_1 z_3
    • 零元:z\cdot 0 = 0
    • 单位元:z\cdot 1 = z

    补充一个关键用处:复数乘方(指数形式秒杀)

    z=re^{i\theta} \implies z^n = r^n e^{in\theta}

    模取 n 次方,角度乘 n,也就是棣莫弗公式,比三角函数展开简单很多。 例:(e^{i\theta})^3=e^{i3\theta}=\cos3\theta+i\sin3\theta

    余弦、正弦复指数展开

    欧拉公式:e^{i\theta} = \cos\theta + i\sin\theta

    对任意实数 \theta

    e^{i\theta} = \cos\theta + i\sin\theta  (式一)

    \theta 替换为-\theta,利用奇偶性: \cos(-\theta)=\cos\theta,\ \sin(-\theta)=-\sin\theta

    e^{-i\theta} = \cos\theta - i\sin\theta   (式二)

    式一 与 式二 相加/相减即可推出:余弦、正弦复指数展开(积分 / 傅里叶变换必备)

    \cos x = \frac{e^{ix}+e^{-ix}}{2} \\\\ \sin x = \frac{e^{ix}-e^{-ix}}{2i}

    欧拉分解:令余弦、正弦复指数展开中的x为 \omega t

    \cos(\omega t) = \frac{e^{j\omega t}+e^{-j\omega t}}{2},\quad \sin(\omega t) = \frac{e^{j\omega t}-e^{-j\omega t}}{2j}

    j 为虚数单位,时域三角函数等价正负频率复指数叠加

    基频 \omega_0 的含义

    T:信号周期,完成一次完整波形所需要的时间(单位:秒 s)如:T=0.5 s 则对应频率 2 Hz

    f频率,1 秒内完整波形重复多少次,f = \dfrac{1}{T},单位 Hz

    三角函数 \cos(\omega t)里的 \omega 叫角频率,表示每秒转过多少弧度。一圈圆周是 2\pi 弧度,所以:

    \omega = 2\pi f 。如:每秒转2圈说明频率 f =2 Hz,w=4\pi

    对于周期为 T 的周期信号:

    f_0 = \frac{1}{T},\quad \boldsymbol{\omega_0 = 2\pi f_0 = \frac{2\pi}{T}}

    \omega_0 是这个周期信号自身最慢、最基础的振荡频率,对应完整波形转一圈的角速度。

    傅里叶级数层面(最关键) 任何周期信号,都可以拆成:直流 + 基波 + 2 次谐波 + 3 次谐波 + …

    • 基波:频率 = \omega_0,和原信号周期完全相同的正弦 / 余弦波;
    • n 次谐波:频率 n\omega_0,速度是基波的 n 倍,周期 T/n

    举例:T=0.02\ \text{s}

    f_0=\frac{1}{0.02}=50\ \text{Hz},\quad \omega_0=\frac{2\pi}{0.02}=100\pi\ \text{rad/s}

    • 基波:50\ \text{Hz},周期 0.02\ \text{s}
    • 2 次谐波:100\ \text{Hz},周期 0.01\ \text{s}
    • 3 次谐波:150\ \text{Hz},周期 0.02/3\ \text{s}

    频谱层面 傅里叶级数的所有谱线频率只能是 (0,\pm\omega_0,\pm2\omega_0,\pm3\omega_0\cdots)\omega_0 是频谱上两根相邻谱线之间的间隔,所以叫 “基频”。

    实周期函数三角形式

    周期 T,基频 \omega_0=\dfrac{2\pi}{T}
    x(t) = a_0 + \sum_{n=1}^{\infty}\big[a_n\cos(n\omega_0 t)+b_n\sin(n\omega_0 t)\big]
    含义:周期信号 = 直流 + 无数倍频正余弦叠加。

    代入复指数展开,转复数傅里叶级数把 \cos,\sin全部换成 e^{jn\omega_0 t},e^{-jn\omega_0 t}
    a_n\cos(n\omega_0 t) = a_n \cdot \frac{e^{jn\omega_0 t}+e^{-jn\omega_0 t}}{2}\\\\\\ b_n\sin(n\omega_0 t) = b_n \cdot \frac{e^{jn\omega_0 t}-e^{-jn\omega_0 t}}{2j}
    合并同指数项:
    x(t) = \sum_{n=-\infty}^{+\infty} c_n \cdot e^{jn\omega_0 t}
    c_n是复傅里叶系数,对应频率 n\omega_0 的幅值相位,这就是复数形式傅里叶级数。

    周期延拓间隔无限大 → 傅里叶变换(连续频谱)

    傅里叶级数针对周期信号,频谱是一根根离散谱线; 令周期 T\to\infty,信号变为非周期信号,离散谱线间距 \omega_0\to0,离散频谱变成连续曲线,就推导出傅里叶变换。

    从级数系数过渡到傅里叶变换定义

    傅里叶级数系数:

    c_n = \frac{1}{T}\int_{-T/2}^{T/2} x(t) e^{-jn\omega_0 t} dt

    定义 X(j\omega) = \lim\limits_{T\to\infty} T\cdot c_n,替换 \omega=n\omega_0

    \boldsymbol{X(j\omega) = \int_{-\infty}^{+\infty} x(t)\,e^{-j\omega t}\,dt}

    这就是连续时间傅里叶变换 CTFT

    逆变换(还原时域信号)

    x(t) = \frac{1}{2\pi}\int_{-\infty}^{+\infty} X(j\omega)\,e^{j\omega t}\,d\omega

    物理意义: 任意时域非周期信号x(t),等价无穷多不同频率复指数 e^{j\omega t} 加权叠加,权重就是频谱 X(j\omega)

    Logo

    汇聚全球AI编程工具,助力开发者即刻编程。

    更多推荐