乐于分享
好东西不私藏

我的 AI 学习系列 | 第1篇——线性代数:AI 的母语

我的 AI 学习系列 | 第1篇——线性代数:AI 的母语
"不懂线性代数的人学 AI,就像不懂英语的人读莎士比亚——你能把书翻完,但你什么都没读懂。"

写在前面

我干了 18 年程序员。从 C++ 写到 Java,从 Java 写到 Python,从裸机部署搞到 Kubernetes,从虚拟化折腾到云原生。
2020 年,我决定 All in AI。
说实话,我 graduated 07 年,离校十几年了,数学早还给老师了。但我知道,搞 AI 不懂数学,永远只能在门口转悠。所以我做了个决定——把基础重新捡起来。
我让刚考上山大的表弟帮我淘了几本教材:高等数学、概率论、线性代数。然后从南大的西瓜书开始,配套南瓜书啃公式,再读清华出版的机器学习,李沐的《动手学深度学习》。从数学基础一路学到 Transformer、大模型、微调、Prompt Engineering、Agent 开发……
前后花了大半年,把整个链路打通了。后来带着团队做模型训练和微调,开发公司自有 AI 产品,拿到了国家大模型备案。
回头看,这条路最难的节点不是什么前沿技术,就是最开始的数学基础。
很多来咨询我的程序员朋友都说:"我也想学 AI,但一看公式就头大。"
我说,你不是数学差,你是没找到正确的入口。
程序员学数学和数学专业学数学,完全是两件事。数学专业追求严谨证明,程序员追求直觉和实用。你需要的是"这个概念在 AI 里干什么",而不是"这个定理怎么推导出来的"。
这个系列就是我当年的学习笔记——用代码讲故事,用直觉替代公式,用"为什么需要它"代替"它是什么"。
这是"我的 AI 学习系列"的第一篇。如果你也想从零开始搞懂 AI 背后的数学,我们开始吧。

一、那个让你永远在"调 API"的东西

先说个扎心的事实。
你用 LangChain 写了个 RAG 应用,调了 OpenAI 的接口,觉得 AI 不过如此。你用 HuggingFace 加载了个预训练模型,跑了推理,觉得自己已经"掌握"了大模型。
但你有没有想过:当模型在"推理"的时候,它到底在干什么?那些几十亿、几百亿的参数,到底是怎么组织起来的?为什么同样一个模型,用 GPU 跑比 CPU 快几十倍?
答案都指向同一个东西——线性代数
不是那种考研用的线性代数,不是让你算行列式和逆矩阵的那种。是另一种线性代数——理解数据如何表示、如何变换、如何压缩、如何比较相似的那一种。
线性代数是 AI 的母语。 不会它,你读不懂 AI 的"源码"。
就好比你是个全栈工程师,但你从来不理解 HTTP 协议。你也能写 Web 应用,框架帮你封装好了。但当性能出了问题、当请求莫名其妙失败、当你需要自己设计接口协议的时候,你就抓瞎了。
线性代数之于 AI,就是 HTTP 之于 Web 开发。它不是可选的加分项,它是你从"使用者"走向"理解者"的必经之路。
金句 #1:调 API 是手艺,懂数学才是本事。手艺会过时,本事不会。
那我们来看看,这门"AI 母语"到底长什么样。

二、向量——AI 世界的基本语言

从一个数组说起

如果你写过代码,你就已经见过向量了。
# 程序员眼中的"数组"user_ages = [25, 30, 28, 35, 22]# 数学家眼中的"向量"import numpy as npuser_vector = np.array([25, 30, 28, 35, 22])
就是这么简单。向量就是一个有序的数字列表。但在 AI 的世界里,向量不只是"存数据",它更像是给现实世界的东西分配了一个"坐标"。
想象你在描述一个人。你可以说"他 25 岁,月薪 2 万,身高 175cm,体重 70kg"。这四个数字 [25, 20000, 175, 70] 就构成了这个人的一个向量表示。
在 AI 的世界里,万物皆可向量化。 一段文字是一个向量,一张图片是一个向量,一首歌是一个向量,一个用户是一个向量,一件商品也是一个向量。
你可能会问:文字怎么变成向量?这个问题问得好,但暂时先别管。你只需要知道,AI 的第一步永远是"把东西变成数字",而向量就是这些数字的容器。

方向和长度——向量的几何直觉

光有数字还不够,向量最强大的地方在于它的几何含义。
在二维平面上画一个箭头,从原点指向某个点。这个箭头有方向,有长度。这就是向量的几何直觉。
import numpy as np# 两个向量v1 = np.array([3, 4])   # 指向右上v2 = np.array([-2, 3])  # 指向左上# 计算长度(模)print(f"v1 的长度: {np.linalg.norm(v1)}")  # 5.0(勾股定理:√(9+16)=5)print(f"v2 的长度: {np.linalg.norm(v2)}")  # ~3.61# 向量的方向(归一化 / 单位向量)v1_unit = v1 / np.linalg.norm(v1)print(f"v1 的单位向量: {v1_unit}")  # [0.6, 0.8]
为什么要关心方向和长度?因为在 AI 里,方向代表"是什么",长度代表"有多强"
一个用户的向量方向代表他的偏好类型(喜欢科技还是喜欢美食),长度代表他偏好的强烈程度。两段文字的向量方向越接近,说明内容越相似。

向量加法和数乘——组合与缩放

向量加法就是"叠加",数乘就是"缩放"。
import numpy as npv1 = np.array([1, 2])v2 = np.array([3, 1])# 加法:两个向量首尾相连,结果是从原点到终点的向量v_sum = v1 + v2  # [4, 3]# 数乘:等比例放大或缩小,方向不变v_scaled = 2 * v1  # [2, 4],长度翻倍,方向不变# 更有意思的:线性组合v_combo = 0.5 * v1 + 0.5 * v2  # 取两个向量的"中间点"print(f"线性组合: {v_combo}")  # [2.0, 1.5]
在 AI 里,向量加法最常见的场景是"组合特征"。比如一个词的向量 = 它本身的语义 + 位置信息 + 上下文信息。这就是 Transformer 里做的那些事儿。
数乘的场景更直接:学习率 × 梯度 = 参数更新量。每次训练,模型参数都在沿着梯度的方向调整一小步。

点积——AI 中最重要的运算

现在到了关键部分。
点积(Dot Product) 是整个 AI 中最核心的数学运算,没有之一。Transformer 的 Attention 机制,本质就是算点积。
import numpy as npa = np.array([1, 2, 3])b = np.array([4, 5, 6])# 点积:对应位置相乘再求和dot = np.dot(a, b)  # 1×4 + 2×5 + 3×6 = 32print(f"点积: {dot}")
点积的公式很简单:把对应位置的元素相乘,再全部加起来。但它的直觉非常深刻。
点积衡量的是两个向量"有多一致"。
想象两个向量是两根箭头。如果它们指向同一个方向,点积最大。如果互相垂直,点积为零。如果方向相反,点积为负。
import numpy as np# 方向接近a = np.array([1, 0])b = np.array([0.9, 0.1])print(f"方向接近,点积: {np.dot(a, b):.2f}")  # 0.9# 互相垂直c = np.array([1, 0])d = np.array([0, 1])print(f"互相垂直,点积: {np.dot(c, d):.2f}")  # 0.0# 方向相反e = np.array([1, 0])f = np.array([-1, 0])print(f"方向相反,点积: {np.dot(e, f):.2f}")  # -1.0
这意味着什么?点积天生就是一种"相似度度量"。
搜索引擎怎么知道哪些文档和你查询相关?算查询向量和文档向量的点积。推荐系统怎么知道该推什么商品?算用户向量和商品向量的点积。大语言模型怎么知道该"关注"输入中的哪些词?算 Query 向量和 Key 向量的点积。
金句 #2:点积是 AI 世界的"共鸣器"——两个向量越合拍,点积越大。

余弦相似度——忽略长度,只看方向

点积有个问题:它会被向量长度影响。一个很长的向量和一个很短的向量,即使方向一致,点积也可能很小。
所以 AI 中更常用的是余弦相似度——先把向量长度归一化为 1,再算点积。
import numpy as npdef cosine_similarity(a, b):    """余弦相似度 = 归一化后的点积"""    norm_a = np.linalg.norm(a)    norm_b = np.linalg.norm(b)    return np.dot(a, b) / (norm_a * norm_b)# 两段相似的文字text1_vec = np.array([0.8, 0.6, 0.1])   # 比如讲"机器学习"的文章text2_vec = np.array([0.7, 0.7, 0.05])  # 也是讲"机器学习"的文章# 两段不相关的文字text3_vec = np.array([0.1, 0.2, 0.9])   # 比如讲"烹饪"的文章print(f"相似文章的余弦相似度: {cosine_similarity(text1_vec, text2_vec):.4f}")# ~0.986print(f"不相关文章的余弦相似度: {cosine_similarity(text1_vec, text3_vec):.4f}")# ~0.227
余弦相似度的值域是 [-1, 1]。1 表示完全同向(最相似),0 表示无关,-1 表示完全反向。
你如果用过 LangChain 做向量检索,或者用 Milvus 做相似度搜索,背后的核心就是这个余弦相似度。现在你知道它不是什么黑魔法,就是归一化之后的点积。
到这里,向量部分就讲完了。我们认识了向量——AI 的基本数据单元,学会了加法、数乘这些操作,掌握了点积和余弦相似度这两个衡量"相似"的利器。
接下来,把一堆向量排成表格,我们就进入了矩阵的世界。

三、矩阵——数据的长相

从向量到矩阵:数据升级

向量是一维的数字列表。把它升一维,变成二维的表格,就是矩阵。
import numpy as np# 一个用户的行为数据(向量)user = np.array([1, 0, 1, 1, 0])  # 看了第1、3、4篇文章# 5个用户的行为数据(矩阵)users = np.array([    [1, 0, 1, 1, 0],  # 用户A    [0, 1, 1, 0, 1],  # 用户B    [1, 1, 0, 0, 1],  # 用户C    [0, 0, 1, 1, 1],  # 用户D    [1, 1, 1, 0, 0],  # 用户E])print(f"矩阵形状: {users.shape}")  # (5, 5) — 5个用户,5篇文章
矩阵就是一堆向量排在一起。在 AI 里,矩阵无处不在。
一张 28×28 的灰度图片,就是一个 28 行 28 列的矩阵,每个数字代表一个像素的亮度。一张 1080p 的高清图片,是一个 1080×1920 的矩阵。一个有 1 万用户、100 个特征的数据集,是一个 10000×100 的矩阵。
import numpy as np# 用矩阵表示一张 8×8 的灰度图# 每个数字代表一个像素的亮度(0=黑,1=白)image = np.array([    [0, 0, 1, 1, 1, 1, 0, 0],    [0, 1, 0, 0, 0, 0, 1, 0],    [1, 0, 1, 0, 0, 1, 0, 1],    [1, 0, 0, 0, 0, 0, 0, 1],    [1, 0, 1, 0, 0, 1, 0, 1],    [1, 0, 0, 1, 1, 0, 0, 1],    [0, 1, 0, 0, 0, 0, 1, 0],    [0, 0, 1, 1, 1, 1, 0, 0],])# 矩阵的每个元素就是一个像素print(f"图片矩阵形状: {image.shape}")  # (8, 8)print(f"左上角像素: {image[0, 0]}")    # 0(黑色)print(f"第一行像素: {image[0]}")# 矩阵运算:把图片变亮brighter = np.clip(image + 0.3, 0, 1)# 矩阵运算:水平翻转flipped = image[:, ::-1]  # 列反转# 矩阵运算:裁剪左上角 4×4cropped = image[:4, :4]
看到了吗?数据在 AI 里的"长相"就是矩阵。理解了矩阵,你就理解了 AI 看到的世界。

矩阵乘法——AI 最重要的操作

如果说点积是向量世界最重要的运算,那矩阵乘法就是整个 AI 最重要的操作。
矩阵乘法的本质是什么?线性变换。
想象你有一张照片。你可以旋转它、缩放它、拉伸它。这些操作都是"线性变换",都可以用矩阵乘法来表示。
import numpy as np# 一个简单的二维数据点point = np.array([1, 0])  # x 轴上的一个点# 旋转矩阵(逆时针旋转 90 度)rotation_90 = np.array([    [0, -1],    [1,  0],])# 矩阵乘法 = 做变换rotated = rotation_90 @ point  # [0, 1] — 旋转到了 y 轴上print(f"原始点: {point}")print(f"旋转 90° 后: {rotated}")# 缩放矩阵(x 方向放大 2 倍,y 方向缩小 0.5 倍)scale = np.array([    [2,  0],    [0, 0.5],])scaled = scale @ point  # [2, 0] — x 方向被拉长了print(f"缩放后: {scaled}")
矩阵乘法就是一个变换,把数据从一个"形状"变成另一个"形状"。
在神经网络里,每一层的运算核心就是矩阵乘法:
import numpy as np# 神经网络的一层,本质上就是矩阵运算# 输入:128维向量(比如一个词的表示)# 权重矩阵:128 × 64(这一层有64个神经元)# 输出:64维向量(变换后的表示)np.random.seed(42)input_vector = np.random.randn(128)        # 128维输入weight_matrix = np.random.randn(128, 64)   # 权重矩阵bias = np.random.randn(64)                 # 偏置# 这就是一层的全部运算!output = input_vector @ weight_matrix + biasprint(f"输入形状: {input_vector.shape}")    # (128,)print(f"权重形状: {weight_matrix.shape}")   # (128, 64)print(f"输出形状: {output.shape}")          # (64,)
输出 = 输入 × 权重矩阵 + 偏置。权重矩阵就是那个"变换",它把输入数据从一种表示变成另一种表示。训练的过程,就是在不断调整这个权重矩阵,让变换的结果越来越准确。
这就是为什么 GPU 对 AI 这么重要。GPU 天生就是为矩阵乘法设计的。一个 GPU 有几千个核心,可以同时计算几千个矩阵乘法的元素。CPU 需要一个一个算,GPU 可以一批算完。

为什么 AI 的每一步都是矩阵运算

让我们把视角拉高一点,看看整个深度学习的流程:
  • **数据输入**:图片 → 像素矩阵
  • **特征提取**:矩阵 × 权重矩阵 = 新矩阵(卷积操作本质上也是矩阵乘法)
  • **注意力计算**:Query 矩阵 × Key 矩阵的转置 = 注意力分数矩阵
  • **输出预测**:最终矩阵 × 输出权重矩阵 = 预测结果
从输入到输出,每一步都在做矩阵运算。这就是为什么线性代数是 AI 的母语——AI 说的是矩阵的语言
import numpy as np# 模拟一个简化版的 Transformer Attentionseq_len = 4       # 序列长度:4 个 tokend_model = 8       # 每个 token 用 8 维向量表示np.random.seed(42)X = np.random.randn(seq_len, d_model)  # 输入序列# 三个权重矩阵W_Q = np.random.randn(d_model, d_model)  # Query 权重W_K = np.random.randn(d_model, d_model)  # Key 权重W_V = np.random.randn(d_model, d_model)  # Value 权重# 矩阵乘法生成 Q、K、VQ = X @ W_Q  # (4, 8)K = X @ W_K  # (4, 8)V = X @ W_V  # (4, 8)# Attention 分数 = Q × K^T(还是矩阵乘法!)scores = Q @ K.T  # (4, 4)print(f"Attention 分数矩阵形状: {scores.shape}")# 4×4 — 每个 token 对其他所有 token 的关注程度# Softmax 归一化def softmax(x):    e_x = np.exp(x - x.max(axis=-1, keepdims=True))    return e_x / e_x.sum(axis=-1, keepdims=True)attention_weights = softmax(scores)# 加权求和(又是矩阵乘法)attention_output = attention_weights @ V  # (4, 8)print(f"Attention 输出形状: {attention_output.shape}")
看到了吧?Transformer 里最核心的 Attention 机制,从头到尾就是矩阵乘法。不会矩阵运算,你就永远看不懂 Attention 的代码。
金句 #3:神经网络的本质,就是一堆矩阵乘法,中间夹着非线性函数。

四、特征值与特征向量——找到数据的"主心骨"

一个变换中的"不变量"

这是一个听起来很吓人、但其实很直觉的概念。
想象你用手拉扯一块橡皮泥。大部分地方都被拉伸、扭曲了。但有些方向上的线条,只是变长或变短了,方向没有变
这些方向不变的向量,就是特征向量。变长或变短的比例,就是特征值
import numpy as np# 一个变换矩阵A = np.array([    [4, 1],    [2, 3],])# 求特征值和特征向量eigenvalues, eigenvectors = np.linalg.eig(A)print("特征值:", eigenvalues)  # 比如 [5, 2]print("特征向量:")print(eigenvectors)# 验证核心公式:A × v = λ × vfor i in range(len(eigenvalues)):    v = eigenvectors[:, i]    Av = A @ v    lambda_v = eigenvalues[i] * v    print(f"\n特征值 {eigenvalues[i]:.2f}: A×v ≈ λ×v? {np.allclose(Av, lambda_v)}")
A × v = λ × v,这就是特征值的定义。矩阵 A 作用在特征向量 v 上,效果就相当于一个数 λ 乘以 v——方向不变,只是拉伸或压缩了。

为什么特征值能衡量"重要性"

这个直觉非常关键。
特征值越大,说明这个方向上的变化越剧烈,包含的信息越多。 反过来,特征值越小的方向,信息越少,丢掉也无所谓。
想象你在拍一张全景照片。水平方向上信息很丰富(山、河、建筑),特征值大。垂直方向上大部分是天空,信息很少,特征值小。如果要做压缩,垂直方向的信息丢掉一些也看不出来。
这就是 PCA(主成分分析)的核心思想。

手写 PCA——把数据压缩到最重要的方向

PCA 做的事情很简单:找到数据变化最大的方向,把数据投影到这些方向上,丢掉不重要的方向。
import numpy as np# 生成一些二维数据(沿着某个方向分布)np.random.seed(42)n = 200# 原始数据:沿 45 度方向拉长X = np.random.randn(n, 2) @ np.array([[3, 1], [1, 1]]) + np.array([5, 3])print(f"原始数据形状: {X.shape}")  # (200, 2)# ---- 手写 PCA ----# 第一步:中心化(减去均值,让数据中心在原点)X_centered = X - X.mean(axis=0)# 第二步:计算协方差矩阵# 协方差矩阵衡量各个维度之间的相关性cov_matrix = (X_centered.T @ X_centered) / (n - 1)print(f"\n协方差矩阵:\n{np.round(cov_matrix, 2)}")# 第三步:求协方差矩阵的特征值和特征向量eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)# 第四步:按特征值从大到小排序(最重要的排前面)idx = np.argsort(eigenvalues)[::-1]eigenvalues = eigenvalues[idx]eigenvectors = eigenvectors[:, idx]print(f"\n特征值(从大到小): {np.round(eigenvalues, 2)}")print(f"每个特征值的信息占比: {np.round(eigenvalues / eigenvalues.sum(), 3)}")# 比如输出 [0.92, 0.08]# 说明第一个方向包含了 92% 的信息# 第五步:取前 k 个特征向量,做投影(降维)k = 1  # 只保留 1 个方向W = eigenvectors[:, :k]        # 投影矩阵 (2, 1)X_pca = X_centered @ W         # 降到 1 维 (200, 1)# 用降维后的数据重构回 2 维X_reconstructed = X_pca @ W.T + X.mean(axis=0)print(f"\n降维后形状: {X_pca.shape}")         # (200, 1)print(f"重构后形状: {X_reconstructed.shape}")  # (200, 2)# 计算重构误差error = np.mean((X - X_reconstructed) ** 2)print(f"重构均方误差: {error:.4f}")
这段代码你值得逐行读一遍。PCA 的整个流程就是:中心化 → 协方差矩阵 → 特征分解 → 排序 → 投影
PCA 在实际中很有用。假设你有 1000 维的特征数据,但大部分是噪声。PCA 可以帮你找到最重要的 50 个方向,把数据从 1000 维降到 50 维,还保留 95% 以上的信息。
在 AI 里,降维无处不在。Embedding 把高维词向量降到低维,Autoencoder 用神经网络做降维,t-SNE 把数据降到二维做可视化。它们的共同思想都是:找到数据的主心骨,丢掉细枝末节。

五、奇异值分解(SVD)——万能的矩阵分解术

把矩阵拆成三个有意义的部分

如果说特征分解是对"方阵"做的特殊手术,那 SVD 就是对"任意矩阵"都能做的通用手术。
任何矩阵 A(不管是不是方阵),都可以分解成三个矩阵的乘积:
A = U × Σ × V^T
  • **U**:左奇异矩阵,描述了"行"(比如用户)的特征
  • **Σ**:奇异值对角矩阵,每个值代表一个维度的重要性
  • **V^T**:右奇异矩阵的转置,描述了"列"(比如商品)的特征
import numpy as np# 一个评分矩阵:5 个用户对 4 部电影的评分# 行 = 用户,列 = 电影,值 = 评分(0 表示没看过)R = np.array([    [5, 5, 0, 0],   # 用户1:喜欢电影1和2    [5, 0, 3, 0],   # 用户2:喜欢电影1和3    [3, 4, 0, 0],   # 用户3:有点喜欢电影1和2    [0, 0, 5, 5],   # 用户4:喜欢电影3和4    [0, 0, 4, 4],   # 用户5:喜欢电影3和4])# SVD 分解U, S, Vt = np.linalg.svd(R, full_matrices=False)print(f"U 的形状: {U.shape}")    # (5, 4) — 用户的特征矩阵print(f"S 的形状: {S.shape}")    # (4,)  — 奇异值print(f"Vt 的形状: {Vt.shape}")  # (4, 4) — 电影的特征矩阵print(f"\n奇异值: {np.round(S, 2)}")print(f"奇异值占比: {np.round(S / S.sum(), 3)}")# 可能输出类似 [0.55, 0.32, 0.08, 0.05]# 前两个奇异值就占了 87% 的信息量
注意看奇异值的占比。前两个奇异值占了绝大部分。这意味着什么?4 部电影的全部信息,其实可以用 2 个维度来表示。

推荐系统——Netflix 竞赛背后的魔法

2006 年,Netflix 搞了一个百万美元的竞赛:谁能把他们的推荐算法提升 10%,奖金 100 万美元。最终的赢家用的就是矩阵分解(SVD 的变种)。
直觉是这样的:用户对电影的评分矩阵有很多空缺(大部分电影用户没看过)。矩阵分解能"填上"这些空缺。
import numpy as np# 接着上面的例子R = np.array([    [5, 5, 0, 0],    [5, 0, 3, 0],    [3, 4, 0, 0],    [0, 0, 5, 5],    [0, 0, 4, 4],])U, S, Vt = np.linalg.svd(R, full_matrices=False)# 只保留前 k 个奇异值(低秩近似)k = 2U_k = U[:, :k]           # (5, 2) — 用户在 2 个隐维度上的表示S_k = np.diag(S[:k])     # (2, 2) — 每个维度的重要性Vt_k = Vt[:k, :]         # (2, 4) — 电影在 2 个隐维度上的表示# 重构评分矩阵(这是"预测"的评分!)R_approx = U_k @ S_k @ Vt_kprint("原始评分矩阵:")print(R)print("\nSVD 预测评分矩阵(保留 2 个奇异值):")print(np.round(R_approx, 1))# 给用户 1 推荐他没看过的电影user1_predicted = R_approx[0]unwatched = R[0] == 0  # 没看过的电影recommendations = np.where(unwatched)[0]print(f"\n用户1没看过的电影: {recommendations}")print(f"预测评分: {np.round(user1_predicted[recommendations], 1)}")# 推荐预测评分最高的那部电影
SVD 把"用户-电影"矩阵分解成"用户-特征"和"特征-电影"两个矩阵。这里的"特征"是自动学出来的隐含维度,可能代表"动作片偏好"、"文艺片偏好"之类的含义。没人告诉它这些维度是什么,它自己从数据中发现了。
这就是推荐系统的基本原理。Netflix、抖音、淘宝的推荐,背后都有矩阵分解的影子。

用 SVD 做图像压缩

SVD 还有个非常直观的应用:图像压缩。
一张图片是一个矩阵。SVD 把它拆成三个部分。如果你只保留最大的几个奇异值,图片的主要信息还在,但存储空间大幅减少。
import numpy as np# 创建一张 64×64 的测试图片(波纹图案)x = np.linspace(0, 1, 64)y = np.linspace(0, 1, 64)X_grid, Y_grid = np.meshgrid(x, y)image = np.sin(2 * np.pi * X_grid) * np.cos(2 * np.pi * Y_grid)# SVD 分解U, S, Vt = np.linalg.svd(image, full_matrices=False)print(f"完整奇异值数量: {len(S)}")# 看看前几个奇异值包含了多少信息cumsum = np.cumsum(S) / S.sum()print(f"前 5 个奇异值的累计信息: {cumsum[4]:.2%}")print(f"前 10 个奇异值的累计信息: {cumsum[9]:.2%}")print(f"前 20 个奇异值的累计信息: {cumsum[19]:.2%}")# 用不同的 k 值重构图片for k in [5, 10, 20]:    U_k = U[:, :k]    S_k = np.diag(S[:k])    Vt_k = Vt[:k, :]    compressed = U_k @ S_k @ Vt_k    # 计算压缩率和误差    original_size = 64 * 64    compressed_size = 64 * k + k + k * 64  # U_k + S_k + Vt_k    ratio = compressed_size / original_size    error = np.mean((image - compressed) ** 2)    print(f"\nk={k}: 压缩率 {ratio:.1%}, 均方误差 {error:.6f}")    print(f"  存储对比: 原始 {original_size} 个数 → 压缩后 {compressed_size} 个数")
看看压缩效果。k=5 的时候可能只保留了不到 20% 的数据量,但图片的轮廓已经能看清了。k=20 的时候,肉眼几乎看不出和原图的区别。
金句 #4:SVD 就像一个翻译官,把矩阵翻译成"重要性排序"的语言。

SVD 和 PCA 的关系

你可能已经发现了,SVD 和 PCA 长得很像。没错,它们本质上是一回事。
PCA 的核心操作是对协方差矩阵做特征分解。而协方差矩阵的特征分解,等价于对中心化后的数据矩阵做 SVD。
import numpy as np# 用同一组数据验证np.random.seed(42)X = np.random.randn(200, 5) @ np.diag([3, 2, 1, 0.5, 0.1])# 方法1:PCA(通过协方差矩阵的特征分解)X_centered = X - X.mean(axis=0)cov = (X_centered.T @ X_centered) / (len(X) - 1)eigenvalues_pca = np.sort(np.linalg.eigvals(cov))[::-1]var_ratio_pca = eigenvalues_pca / eigenvalues_pca.sum()# 方法2:SVDU, S, Vt = np.linalg.svd(X_centered, full_matrices=False)# SVD 的奇异值² / (n-1) 就是 PCA 的特征值eigenvalues_svd = (S ** 2) / (len(X) - 1)var_ratio_svd = eigenvalues_svd / eigenvalues_svd.sum()print("PCA 的方差解释比:", np.round(var_ratio_pca, 3))print("SVD 的方差解释比:", np.round(var_ratio_svd, 3))# 两个结果一样!
记住这个结论:PCA 是 SVD 的特例,SVD 是更通用的矩阵分解工具。

六、张量——深度学习的数据容器

升维之路:标量 → 向量 → 矩阵 → 张量

还记得我们的升维之路吗?
  • **标量(0D)**:一个数,比如 `42`
  • **向量(1D)**:一列数,比如 `[1, 2, 3]`
  • **矩阵(2D)**:一个表格,比如 `[[1,2], [3,4]]`
  • **张量(3D+)**:更高维的数组
张量就是"更高维的矩阵"。或者反过来说,标量、向量、矩阵都是张量的特例。
import torch# 标量 — 0 维张量scalar = torch.tensor(42)print(f"标量: {scalar}, 维度: {scalar.dim()}")  # dim=0# 向量 — 1 维张量vector = torch.tensor([1, 2, 3, 4, 5])print(f"向量形状: {vector.shape}, 维度: {vector.dim()}")  # dim=1# 矩阵 — 2 维张量matrix = torch.tensor([[1, 2, 3],                        [4, 5, 6]])print(f"矩阵形状: {matrix.shape}, 维度: {matrix.dim()}")  # dim=2# 3 维张量(一张彩色图片)image = torch.randn(3, 224, 224)  # 3 通道, 224×224print(f"彩色图片形状: {image.shape}, 维度: {image.dim()}")  # dim=3# 4 维张量(一个 batch 的图片)batch_images = torch.randn(32, 3, 224, 224)  # 32 张图片print(f"Batch 形状: {batch_images.shape}, 维度: {batch_images.dim()}")  # dim=4# 5 维张量(一个 batch 的视频)batch_videos = torch.randn(8, 16, 3, 224, 224)  # 8个视频,每个16帧print(f"视频 Batch 形状: {batch_videos.shape}, 维度: {batch_videos.dim()}")  # dim=5
你可能注意到了,深度学习里张量的形状有个常见的约定:
  • **0D** 标量:`()` — 一个数
  • **1D** 向量:`(512,)` — 一个特征向量
  • **2D** 矩阵:`(batch, features)` — 表格数据
  • **3D** 序列/图片:`(batch, seq_len, hidden)` 或 `(channels, height, width)`
  • **4D** 图片 batch:`(batch, channels, height, width)`
  • **5D** 视频 batch:`(batch, frames, channels, height, width)`
在深度学习里,你处理的数据几乎都是 4 维或 5 维张量。 PyTorch 和 TensorFlow 就是为这种高维数据设计的。

为什么 GPU 能加速张量运算

CPU 的设计是"一个核心,什么都干"。GPU 的设计是"几千个简单核心,同时干同一件事"。
张量运算有一个特点:大量相同类型的计算,互相之间没有依赖。 矩阵乘法中,每个元素的计算都是独立的。这正好是 GPU 的强项。
import torchimport time# 创建两个大矩阵size = 2000A = torch.randn(size, size)B = torch.randn(size, size)# CPU 计算start = time.time()C_cpu = A @ Bcpu_time = time.time() - startprint(f"CPU 矩阵乘法 ({size}×{size}): {cpu_time:.4f} 秒")# GPU 计算(如果有 GPU 的话)if torch.cuda.is_available():    A_gpu = A.cuda()    B_gpu = B.cuda()    # 预热(第一次运行会慢,不计入时间)    _ = A_gpu @ B_gpu    torch.cuda.synchronize()    start = time.time()    C_gpu = A_gpu @ B_gpu    torch.cuda.synchronize()  # 等GPU算完    gpu_time = time.time() - start    print(f"GPU 矩阵乘法 ({size}×{size}): {gpu_time:.4f} 秒")    print(f"GPU 加速比: {cpu_time / gpu_time:.1f}x")else:    print("没有检测到 GPU,跳过 GPU 测试")
这就是为什么搞 AI 必须要 GPU。不是 GPU 多神秘,是矩阵乘法太适合并行了。一个 2000×2000 的矩阵乘法,有 40 亿次乘加运算,GPU 几千个核心同时开工,比 CPU 快几十倍。

PyTorch 张量基础操作

来看看在 PyTorch 里,张量到底怎么用。
import torch# ---- 创建张量 ----# 从列表创建t1 = torch.tensor([[1, 2], [3, 4]])# 创建全零、全一张量zeros = torch.zeros(3, 4)     # 3×4 全零ones = torch.ones(2, 3, 5)    # 2×3×5 全一# 随机初始化(最常用)randn = torch.randn(32, 3, 224, 224)  # 一个 batch 的图片print(f"随机张量形状: {randn.shape}")  # [32, 3, 224, 224]print(f"随机张量数据类型: {randn.dtype}")  # torch.float32# ---- 张量运算 ----a = torch.randn(3, 4)b = torch.randn(4, 2)# 矩阵乘法c = a @ b  # 或 torch.matmul(a, b)print(f"矩阵乘法结果形状: {c.shape}")  # (3, 2)# 逐元素运算d = torch.randn(3, 4)e = torch.randn(3, 4)sum_de = d + e          # 逐元素加法product_de = d * e      # 逐元素乘法(注意!不是矩阵乘法)# ---- 形状操作(非常常用)----x = torch.randn(32, 3, 224, 224)  # 图片 batch# 查看/改变形状print(f"原始形状: {x.shape}")flat = x.reshape(32, 3 * 224 * 224)    # 展平print(f"展平后: {flat.shape}")           # (32, 150528)restored = flat.reshape(32, 3, 224, 224)  # 恢复# 转置(交换维度)# 把 (batch, channels, H, W) 变成 (batch, H, W, channels)transposed = x.permute(0, 2, 3, 1)print(f"转置后: {transposed.shape}")  # (32, 224, 224, 3)# ---- 维度操作 ----# 添加维度x_unsqueezed = x.unsqueeze(1)  # 在第1维添加一个维度print(f"unsqueeze: {x.shape} → {x_unsqueezed.shape}")# 压缩维度(去掉大小为1的维度)x_squeezed = x_unsqueezed.squeeze(1)print(f"squeeze: {x_unsqueezed.shape} → {x_squeezed.shape}")# ---- 广播机制 ----# 不同形状的张量运算时,自动扩展batch = torch.randn(32, 64)   # 32个样本,每个64维bias = torch.randn(64)         # 64维偏置result = batch + bias          # 自动把 bias 扩展到 32×64print(f"广播结果: {result.shape}")  # (32, 64)
这些操作覆盖了你在 PyTorch 中 80% 以上的张量使用场景。创建、运算、变形、广播,掌握了这四类操作,你就能读懂大部分深度学习代码。

一张图片、一段视频——从 3D 到 5D

用实际的例子来感受张量的维度:
import torch# ---- 一张灰度图 ----gray_image = torch.randn(28, 28)  # 2D:28×28print(f"灰度图: {gray_image.shape}, 维度: {gray_image.dim()}")# ---- 一张彩色图 ----color_image = torch.randn(3, 224, 224)  # 3D:3通道×224×224print(f"彩色图: {color_image.shape}, 维度: {color_image.dim()}")# ---- 一个 batch 的彩色图 ----batch = torch.randn(32, 3, 224, 224)  # 4D:32张×3通道×224×224print(f"图片 batch: {batch.shape}, 维度: {batch.dim()}")# ---- 一段视频(50帧彩色图) ----video = torch.randn(50, 3, 224, 224)  # 4D:50帧×3通道×224×224print(f"一段视频: {video.shape}, 维度: {video.dim()}")# ---- 一个 batch 的视频 ----video_batch = torch.randn(8, 50, 3, 224, 224)  # 5D:8段×50帧×3通道×224×224print(f"视频 batch: {video_batch.shape}, 维度: {video_batch.dim()}")# 看看数据量num_elements = video_batch.numel()print(f"\n视频 batch 的总数据量: {num_elements:,} 个浮点数")print(f"占用内存(float32): {num_elements * 4 / 1024 / 1024:.1f} MB")
一个小小的 batch(8 段视频,每段 50 帧),数据量就接近 600 MB。这就是为什么深度学习需要大显存的 GPU。
金句 #5:张量是 AI 世界的集装箱——它不关心里面装的是图片、文字还是声音,它只关心形状和运算。

七、写在最后

我们来回顾一下今天学了什么。
向量是 AI 的基本语言。万物皆可向量化,万物皆可比较。点积和余弦相似度是衡量"相似"的利器,支撑着搜索、推荐、检索这些最核心的 AI 应用。
矩阵是数据的长相。图片是矩阵,权重是矩阵,每一步运算都是矩阵乘法。理解了矩阵乘法就是"线性变换",你就理解了神经网络在做什么。
特征值和特征向量帮我们找到数据的"主心骨"。PCA 用它们做降维,把 1000 维的数据压缩到 50 维,还能保留 95% 的信息。
SVD 是万能的矩阵分解术。推荐系统用它填空缺,图像压缩用它省空间,它和 PCA 是同一枚硬币的两面。
张量是深度学习的数据容器。从标量到 5 维张量,每一维都有明确的含义。GPU 天生适合张量运算,这就是为什么搞 AI 离不开 GPU。
五个概念,一条线索:用数字表示世界,用运算理解世界。

预告:下一篇——微积分:AI 的学习方式

如果说线性代数是 AI 的"语言",那微积分就是 AI 的"学习方式"。
神经网络是怎么"学会"东西的?梯度下降。梯度是什么?导数的推广。导数是什么?微积分的起点。
下一篇,我们聊聊微积分——从导数到梯度,从梯度下降到反向传播,看 AI 是怎么一步步"变聪明"的。

最后的最后

我经常跟来咨询的企业团队说一句话:
学 AI 的数学,不是为了当数学家,是为了不当"调参侠"。
你当然可以直接用 LangChain 搭应用,可以直接调 GPT 的 API。但当你遇到问题的时候——模型效果不好、推理太慢、需要自己设计架构——你能不能从原理出发去分析和解决?
能,还是不能,这就是区别。
数学不是障碍,是你的武器。拿起它,你会发现 AI 的世界远比你想象的清晰。
调 API 决定了你的起点,懂数学决定了你的天花板。
我们下篇见。

*这是"我的 AI 学习系列"第 1 篇。整个系列计划包含:线性代数、微积分、概率论与统计、信息论、优化理论等内容。如果你觉得有用,转发给同样在学 AI 的朋友吧。*
基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-09 11:07:17 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/592638.html
  2. 运行时间 : 0.119500s [ 吞吐率:8.37req/s ] 内存消耗:4,770.86kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=551aa2e1db7c16aefab6b702de131767
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000587s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000824s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000351s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000274s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000470s ]
  6. SELECT * FROM `set` [ RunTime:0.000192s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000566s ]
  8. SELECT * FROM `article` WHERE `id` = 592638 LIMIT 1 [ RunTime:0.000953s ]
  9. UPDATE `article` SET `lasttime` = 1778296037 WHERE `id` = 592638 [ RunTime:0.008137s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000345s ]
  11. SELECT * FROM `article` WHERE `id` < 592638 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000503s ]
  12. SELECT * FROM `article` WHERE `id` > 592638 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000443s ]
  13. SELECT * FROM `article` WHERE `id` < 592638 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000966s ]
  14. SELECT * FROM `article` WHERE `id` < 592638 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.003093s ]
  15. SELECT * FROM `article` WHERE `id` < 592638 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002579s ]
0.123778s