AI学习笔记
AI 学习笔记
从零开始系统学习人工智能,涵盖前置基础 、核心原理 、工程实践 、应用工具 、进阶展望 5大模块,助你构建完整的AI知识体系
Python
数学基础
机器学习
深度学习
工程实践
第零章:学习路线图
学习目标
了解AI学习的完整知识体系与各模块之间的关系
明确自己的学习起点和目标方向
掌握后续学习所需的前置知识要求
建立合理的学习计划和时间安排
准备好学习所需的工具和环境
前置要求
基本的计算机操作能力
高中数学基础(代数、函数、基础几何)
对AI领域的好奇心和学习热情
愿意投入时间进行动手实践
学习路线图
以下是AI学习的完整路线图,共分为6大模块,建议按照顺序逐步学习。每个模块都有明确的学习目标和预期成果。
模块
章节内容
预计时间
重要程度
预期成果
模块一
第零章:学习路线图
0.5 周
★★
明确学习方向,搭建环境
模块二
第一章:Python编程基础
2 周
★★★
熟练使用Python进行数据处理
模块三
第二章:数学基础
2 周
★★★
理解AI背后的数学原理
模块四
第三章:机器学习基础
3 周
★★★
掌握经典ML算法与Scikit-learn
模块五
第四章:深度学习基础
3 周
★★★
理解神经网络与PyTorch
模块六
第五章:工程实践与工具
2 周
★★
完成端到端ML项目
预计学习时间
所需工具清单
工具
用途
获取方式
费用
Python 3.10+
编程语言
python.org
免费
VS Code
代码编辑器
code.visualstudio.com
免费
Jupyter Notebook
交互式编程环境
pip install jupyter
免费
NumPy
数值计算
pip install numpy
免费
Matplotlib
数据可视化
pip install matplotlib
免费
Git
版本控制
git-scm.com
免费
学习建议
建议使用 Anaconda 发行版,它已经预装了 Python、Jupyter Notebook、NumPy、Matplotlib 等常用工具,可以省去大量环境配置时间。安装命令:conda install numpy matplotlib jupyter
第一章:Python编程基础
学习目标
掌握Python基本语法:变量、数据类型、运算符
理解控制流:条件判断(if/else)、循环(for/while)
学会使用NumPy进行高效的数组与矩阵运算
能够使用Matplotlib创建基本的数据可视化图表
为后续机器学习编程打下坚实基础
前置要求
已安装Python 3.10或更高版本
了解基本的编程概念(如变量、函数)
能够使用终端/命令行执行基本命令
Python 环境安装
# 检查Python版本
python --version
# 输出: Python 3.10.x 或更高
# 使用pip安装所需库
pip install numpy matplotlib jupyter
# 或者使用conda(如果安装了Anaconda)
conda install numpy matplotlib jupyter
# 启动Jupyter Notebook
jupyter notebook
验证安装
在终端输入 python -c "import numpy; import matplotlib; print('安装成功!')",如果没有报错,说明环境安装成功。
基础语法
变量与数据类型
Python是动态类型语言,变量不需要提前声明类型。以下是常用的数据类型。
# ========== 变量与数据类型 ==========
# 整数 (int)
a = 10
b = -3
print(type(a)) # <class 'int'>
# 浮点数 (float)
pi = 3.14159
learning_rate = 0.001
print(type(pi)) # <class 'float'>
# 字符串 (str)
model_name = "ResNet-50"
description = '深度学习模型'
print(type(model_name)) # <class 'str'>
# 布尔值 (bool)
is_training = True
use_gpu = False
print(type(is_training)) # <class 'bool'>
# 列表 (list) - AI中常用于存储数据集、特征等
layers = ['conv', 'relu', 'pool', 'fc']
losses = [0.9, 0.7, 0.5, 0.3, 0.2]
# 字典 (dict) - AI中常用于存储超参数
hyperparams = {
'learning_rate': 0.001,
'batch_size': 32,
'epochs': 100,
'optimizer': 'adam'
}
# 元组 (tuple) - 不可变序列
image_shape = (224, 224, 3) # 高度, 宽度, 通道数
print(f"模型: {model_name}, 学习率: {hyperparams['learning_rate']}")
print(f"图像尺寸: {image_shape[0]}x{image_shape[1]}")
控制流
条件判断和循环是编程的基础,在AI中常用于数据预处理、训练循环等场景。
# ========== 条件判断 ==========
accuracy = 0.92
if accuracy >= 0.9:
print("模型表现优秀!")
elif accuracy >= 0.7:
print("模型表现良好,仍有提升空间")
else:
print("模型需要进一步调优")
# ========== for 循环 - 训练循环模拟 ==========
epochs = 5
losses = []
for epoch in range(epochs):
loss = 1.0 / (epoch + 1) # 模拟损失递减
losses.append(loss)
print(f"Epoch {epoch + 1}/{epochs}, Loss: {loss:.4f}")
# ========== while 循环 - 早停机制模拟 ==========
patience = 3
best_loss = float('inf')
no_improve = 0
current_loss = 0.8
while no_improve < patience:
if current_loss < best_loss:
best_loss = current_loss
no_improve = 0
print(f"损失改善: {best_loss:.4f}")
else:
no_improve += 1
print(f"未改善 ({no_improve}/{patience})")
current_loss *= 0.95 # 模拟损失变化
print(f"训练结束,最佳损失: {best_loss:.4f}")
# ========== 列表推导式 - 数据预处理常用 ==========
raw_data = [1.2, 3.4, 5.6, 7.8, 9.0]
normalized = [(x - min(raw_data)) / (max(raw_data) - min(raw_data))
for x in raw_data]
print(f"归一化结果: {normalized}")
Python小贴士
在AI编程中,列表推导式 和字典推导式 非常常用,它们比传统循环更简洁高效。此外,enumerate() 和 zip() 也是数据处理中的常用函数。
NumPy 基础
NumPy是Python科学计算的核心库,提供了高效的多维数组对象和丰富的数学函数。在AI中,NumPy是几乎所有数据处理和数值计算的基础。
数组创建
import numpy as np
# ========== 数组创建 ==========
# 从列表创建
a = np.array([1, 2, 3, 4, 5])
print(f"一维数组: {a}, 形状: {a.shape}")
# 创建全零数组(常用于初始化权重)
zeros = np.zeros((3, 4))
print(f"全零数组 (3x4):\n{zeros}")
# 创建全一数组
ones = np.ones((2, 3))
print(f"全一数组 (2x3):\n{ones}")
# 创建单位矩阵(线性代数中常用)
identity = np.eye(3)
print(f"单位矩阵 (3x3):\n{identity}")
# 创建随机数组(常用于初始化神经网络权重)
np.random.seed(42) # 设置随机种子,保证可复现
random_arr = np.random.randn(3, 3) # 标准正态分布
print(f"随机数组 (3x3):\n{random_arr}")
# 等间隔数组
x = np.linspace(0, 10, 5) # [0, 2.5, 5, 7.5, 10]
print(f"等间隔数组: {x}")
# 等差数组
y = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
print(f"等差数组: {y}")
矩阵运算
import numpy as np
# ========== 矩阵运算 ==========
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 矩阵加法
C = A + B
print(f"矩阵加法:\n{C}")
# 矩阵乘法(点积)- AI中最常用的运算
D = A @ B # 等价于 np.dot(A, B)
print(f"矩阵乘法 A @ B:\n{D}")
# 逐元素乘法(Hadamard积)
E = A * B
print(f"逐元素乘法 A * B:\n{E}")
# 转置
print(f"A的转置:\n{A.T}")
# 矩阵的逆
A_inv = np.linalg.inv(A)
print(f"A的逆矩阵:\n{A_inv}")
# 矩阵的行列式
det = np.linalg.det(A)
print(f"A的行列式: {det:.2f}")
# ========== 广播机制 ==========
# AI中非常重要的特性
x = np.array([[1], [2], [3]]) # 形状 (3, 1)
y = np.array([10, 20, 30]) # 形状 (3,)
result = x + y # 广播为 (3, 3)
print(f"广播结果:\n{result}")
# ========== 常用统计运算 ==========
data = np.array([1.2, 3.4, 5.6, 7.8, 9.0])
print(f"均值: {np.mean(data):.2f}")
print(f"标准差: {np.std(data):.2f}")
print(f"最大值: {np.max(data)}, 最小值: {np.min(data)}")
print(f"求和: {np.sum(data)}")
print(f"排序: {np.sort(data)}")
注意
在NumPy中,* 是逐元素乘法,@ 或 np.dot() 才是矩阵乘法。在AI编程中,矩阵乘法(@)远比逐元素乘法更常用,务必区分清楚。
Matplotlib 基础
Matplotlib是Python最常用的数据可视化库。在AI中,我们用它来可视化训练过程、数据分布、模型性能等。
折线图 - 训练损失可视化
import matplotlib.pyplot as plt
import numpy as np
# 设置中文字体(避免中文显示为方块)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# ========== 折线图:模拟训练过程 ==========
epochs = np.arange(1, 101)
train_loss = 2.0 * np.exp(-0.03 * epochs) + np.random.randn(100) * 0.05
val_loss = 2.2 * np.exp(-0.025 * epochs) + np.random.randn(100) * 0.08
plt.figure(figsize=(10, 6))
plt.plot(epochs, train_loss, 'b-', label='训练损失', linewidth=2)
plt.plot(epochs, val_loss, 'r--', label='验证损失', linewidth=2)
plt.xlabel('Epoch', fontsize=14)
plt.ylabel('Loss', fontsize=14)
plt.title('模型训练过程', fontsize=16)
plt.legend(fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('training_curve.png', dpi=150)
plt.show()
散点图 - 数据分布可视化
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# ========== 散点图:两类数据分布 ==========
np.random.seed(42)
# 类别A:以(2, 3)为中心
class_a = np.random.randn(50, 2) * 0.8 + np.array([2, 3])
# 类别B:以(6, 7)为中心
class_b = np.random.randn(50, 2) * 0.8 + np.array([6, 7])
plt.figure(figsize=(8, 6))
plt.scatter(class_a[:, 0], class_a[:, 1],
c='#4299e1', label='类别 A', alpha=0.7, s=80, edgecolors='white')
plt.scatter(class_b[:, 0], class_b[:, 1],
c='#e53e3e', label='类别 B', alpha=0.7, s=80, edgecolors='white')
plt.xlabel('特征 1', fontsize=14)
plt.ylabel('特征 2', fontsize=14)
plt.title('二分类数据分布', fontsize=16)
plt.legend(fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('scatter_plot.png', dpi=150)
plt.show()
练习题
[1]
使用NumPy创建一个 5x5 的随机矩阵,计算其转置、逆矩阵和行列式,并验证 \( A \times A^{-1} \) 是否接近单位矩阵。
[2]
给定两组数据 x = [1, 2, 3, 4, 5] 和 y = [2.1, 3.9, 6.2, 7.8, 10.1],使用Matplotlib绘制散点图,并观察它们之间的关系。
[3]
编写一个函数 normalize(data),接收一个NumPy数组,返回Z-score标准化后的结果(公式:\( z = \frac{x - \mu}{\sigma} \)),其中 \(\mu\) 为均值,\(\sigma\) 为标准差。
章节小结
Python是AI开发的首选语言,其简洁的语法和丰富的库生态是最大优势
NumPy的ndarray是AI数值计算的核心数据结构,掌握数组操作和广播机制至关重要
矩阵乘法(@)是AI计算的基本操作,务必与逐元素乘法(*)区分
Matplotlib是数据可视化的基础工具,在分析数据和展示模型性能时不可或缺
设置随机种子(np.random.seed())可以保证实验的可复现性
第二章:数学基础
学习目标
掌握线性代数核心概念:向量、矩阵、矩阵乘法及其几何意义
理解微积分基本概念:导数、偏导数、链式法则、梯度
熟悉概率统计基础:概率分布、期望、方差、贝叶斯定理
了解信息论基本概念:熵、交叉熵及其在AI中的应用
理解每个数学概念在AI中的具体应用场景
前置要求
高中数学基础(函数、方程、基本概率)
了解Python和NumPy基本操作(第一章内容)
对抽象数学概念有一定的接受能力
线性代数
线性代数是AI的数学基石。神经网络的前向传播本质上是矩阵乘法,反向传播需要计算梯度,这些操作都建立在线性代数之上。
向量 (Vector)
向量是具有大小和方向的量。在AI中,向量用于表示数据点、特征、词嵌入等。
\[ \mathbf{x} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} \in \mathbb{R}^n \]
n维列向量,表示一个具有n个特征的数据点
数值示例: 假设一个学生的成绩用向量表示:
\[ \mathbf{s} = \begin{bmatrix} 90 \\ 85 \\ 78 \\ 92 \end{bmatrix} \]
分别对应:数学、英语、物理、化学成绩
向量运算:
\[ \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n \]
点积(内积):衡量两个向量的相似度
AI中哪里用到: 词向量(Word Embedding)将词语映射为高维向量;特征向量表示数据样本;注意力机制中的Query、Key、Value都是向量。
矩阵 (Matrix)
矩阵是按照矩形排列的数字阵列。在AI中,矩阵用于表示数据集、权重矩阵、变换等。
\[ 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 \mathbb{R}^{m \times n} \]
m行n列的矩阵
数值示例: 一个3个样本、4个特征的数据集:
\[ X = \begin{bmatrix} 1.0 & 2.3 & 0.5 & 3.1 \\ 0.8 & 1.9 & 0.7 & 2.8 \\ 1.2 & 2.1 & 0.3 & 3.5 \end{bmatrix} \]
3行(样本)x 4列(特征)
AI中哪里用到: 数据集通常组织为矩阵形式(样本数 x 特征数);神经网络每一层的权重都是一个矩阵;图像可以看作像素矩阵。
矩阵乘法 (Matrix Multiplication)
矩阵乘法是神经网络前向传播的核心运算。
\[ C = A \times B, \quad c_{ij} = \sum_{k=1}^{K} a_{ik} \cdot b_{kj} \]
A(m x K) 乘以 B(K x n) 得到 C(m x n)
数值示例:
\[ \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} \times \begin{bmatrix} 5 & 6 \\ 7 & 8 \end{bmatrix} = \begin{bmatrix} 1 \times 5 + 2 \times 7 & 1 \times 6 + 2 \times 8 \\ 3 \times 5 + 4 \times 7 & 3 \times 6 + 4 \times 8 \end{bmatrix} = \begin{bmatrix} 19 & 22 \\ 43 & 50 \end{bmatrix} \]
逐步计算矩阵乘法
AI中哪里用到: 神经网络层的计算 \( \mathbf{h} = \sigma(W\mathbf{x} + \mathbf{b}) \),其中 \( W \) 是权重矩阵,\( \mathbf{x} \) 是输入向量,\( \mathbf{b} \) 是偏置向量,\( \sigma \) 是激活函数。整个深度网络就是一系列矩阵乘法的组合。
微积分
微积分是理解AI优化过程的关键。神经网络的训练本质上就是通过微积分中的梯度下降来最小化损失函数。
导数 (Derivative)
导数描述函数在某一点处的变化率,即"瞬时速度"。
\[ f'(x) = \frac{df}{dx} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} \]
导数的定义
常用导数公式:
\[ \frac{d}{dx}x^n = nx^{n-1}, \quad \frac{d}{dx}e^x = e^x, \quad \frac{d}{dx}\ln(x) = \frac{1}{x}, \quad \frac{d}{dx}\sin(x) = \cos(x) \]
基本函数的导数
AI中哪里用到: 导数告诉我们损失函数在某个参数值处的变化方向,是梯度下降法的基础。激活函数的导数决定了反向传播中梯度的流动。
偏导数 (Partial Derivative)
当函数有多个变量时,偏导数是固定其他变量,对某一个变量求导。
\[ f(x, y) = x^2 + 3xy + y^2 \]
\[ \frac{\partial f}{\partial x} = 2x + 3y, \quad \frac{\partial f}{\partial y} = 3x + 2y \]
多变量函数的偏导数
AI中哪里用到: 损失函数通常有大量参数(可能数百万个),我们需要分别对每个参数求偏导数,以确定每个参数应该如何调整来减小损失。
链式法则 (Chain Rule)
链式法则是微积分中最重要的法则之一,用于求复合函数的导数。
\[ \frac{d}{dx}[f(g(x))] = f'(g(x)) \cdot g'(x) \]
链式法则基本形式
多变量链式法则:
\[ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial w} \]
多层复合函数的链式求导
AI中哪里用到:反向传播算法(Backpropagation)的核心就是链式法则。 神经网络由多层组成,损失函数对第一层参数的梯度需要逐层传递,每一层都通过链式法则将梯度向后传递。这是深度学习能够高效训练的关键。
梯度 (Gradient)
梯度是一个向量,由函数对所有变量的偏导数组成,指向函数值增长最快的方向。
\[ \nabla f = \begin{bmatrix} \frac{\partial f}{\partial x_1} \\ \frac{\partial f}{\partial x_2} \\ \vdots \\ \frac{\partial f}{\partial x_n} \end{bmatrix} \]
梯度向量(n个变量的函数)
梯度下降更新公式:
\[ \theta_{t+1} = \theta_t - \alpha \cdot \nabla_\theta L(\theta_t) \]
梯度下降:沿梯度的反方向更新参数,\(\alpha\) 为学习率
AI中哪里用到:梯度下降是几乎所有机器学习模型的训练方法。 SGD、Adam、RMSprop等优化器都是基于梯度下降的变体。理解梯度是理解模型训练过程的关键。
概率统计
概率论为AI提供了处理不确定性的数学框架。从朴素贝叶斯分类器到贝叶斯神经网络,概率统计无处不在。
概率分布 (Probability Distribution)
概率分布描述了随机变量取各个值的可能性。
常见分布:
\[ \text{正态分布: } f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}} \]
高斯分布,\(\mu\)为均值,\(\sigma\)为标准差
\[ \text{伯努利分布: } P(X=k) = p^k(1-p)^{1-k}, \quad k \in \{0, 1\} \]
二值分布,如抛硬币
\[ \text{Softmax分布: } P(y_i) = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}} \]
多分类中常用的概率分布
AI中哪里用到: 正态分布用于权重初始化和数据假设;Softmax将网络输出转化为概率分布,用于多分类任务(如ImageNet的1000类分类)。
期望与方差 (Expectation & Variance)
期望是随机变量的"平均值",方差衡量数据的离散程度。
\[ \mathbb{E}[X] = \sum_{i} x_i \cdot P(x_i) \quad \text{(离散)} \]
\[ \mathbb{E}[X] = \int_{-\infty}^{\infty} x \cdot f(x) \, dx \quad \text{(连续)} \]
期望(数学期望)
\[ \text{Var}(X) = \mathbb{E}[(X - \mathbb{E}[X])^2] = \mathbb{E}[X^2] - (\mathbb{E}[X])^2 \]
方差:衡量随机变量偏离均值的程度
数值示例: 掷骰子的期望和方差:
\[ \mathbb{E}[X] = \frac{1+2+3+4+5+6}{6} = 3.5 \]
\[ \text{Var}(X) = \frac{(1-3.5)^2 + (2-3.5)^2 + \cdots + (6-3.5)^2}{6} \approx 2.92 \]
公平骰子的期望和方差
AI中哪里用到: 期望用于计算预测值;方差用于衡量模型的不确定性;Batch Normalization利用批次的均值和方差来稳定训练。
贝叶斯定理 (Bayes' Theorem)
贝叶斯定理描述了在获得新证据后如何更新我们的信念。
\[ P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} \]
贝叶斯定理:后验概率 = 似然 x 先验概率 / 证据
数值示例: 疾病检测
\[ \text{假设:疾病发病率} P(D) = 0.01, \text{检测灵敏度} P(+|D) = 0.99, \text{误报率} P(+|\neg D) = 0.05 \]
\[ P(D|+) = \frac{P(+|D) \cdot P(D)}{P(+|D) \cdot P(D) + P(+|\neg D) \cdot P(\neg D)} = \frac{0.99 \times 0.01}{0.99 \times 0.01 + 0.05 \times 0.99} \approx 0.167 \]
即使检测为阳性,实际患病的概率也仅有约16.7%(贝叶斯定理的经典应用)
AI中哪里用到: 朴素贝叶斯分类器(垃圾邮件过滤);贝叶斯优化(超参数调优);贝叶斯神经网络(量化模型不确定性);最大后验估计(MAP)。
信息论
信息论为AI提供了衡量"信息量"和"不确定性"的工具,是理解损失函数设计的基础。
熵 (Entropy)
熵衡量一个随机变量的不确定性,熵越大表示不确定性越高。
\[ H(X) = -\sum_{i=1}^{n} p(x_i) \log_2 p(x_i) \]
信息熵(单位:比特)
直观理解:
\[ \text{公平硬币: } H = -(0.5 \log_2 0.5 + 0.5 \log_2 0.5) = 1 \text{ bit} \]
\[ \text{作弊硬币(总是正面): } H = -(1 \log_2 1 + 0 \log_2 0) = 0 \text{ bit} \]
越确定的事物,熵越低;越不确定的事物,熵越高
AI中哪里用到: 决策树使用信息增益(基于熵)来选择最优分裂特征;信息熵用于衡量数据集的纯度。
交叉熵 (Cross-Entropy)
交叉熵衡量两个概率分布之间的"距离",是分类任务中最常用的损失函数。
\[ H(p, q) = -\sum_{i=1}^{n} p(x_i) \log q(x_i) \]
交叉熵:p为真实分布,q为预测分布
二分类交叉熵损失:
\[ \mathcal{L} = -\frac{1}{N}\sum_{i=1}^{N} \left[ y_i \log \hat{y}_i + (1 - y_i) \log(1 - \hat{y}_i) \right] \]
Binary Cross-Entropy Loss,\(\hat{y}\)为预测概率,\(y\)为真实标签
多分类交叉熵损失:
\[ \mathcal{L} = -\sum_{i=1}^{C} y_i \log \hat{y}_i \]
Categorical Cross-Entropy Loss,C为类别数
AI中哪里用到:交叉熵是深度学习中最常用的损失函数。 几乎所有的分类任务(图像分类、文本分类、机器翻译等)都使用交叉熵作为损失函数。它衡量的是模型预测分布与真实分布之间的差异,模型训练的目标就是最小化这个差异。
数学概念与AI应用对照表
数学概念
AI应用
涉及章节
向量/矩阵
数据表示、权重矩阵、特征提取
全部章节
矩阵乘法
神经网络前向传播
深度学习
导数/梯度
梯度下降、反向传播
机器学习、深度学习
链式法则
反向传播算法
深度学习
概率分布
Softmax输出、数据建模
机器学习、深度学习
贝叶斯定理
朴素贝叶斯、贝叶斯优化
机器学习
交叉熵
分类损失函数
机器学习、深度学习
练习题
[1]
给定矩阵 \( A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} \) 和向量 \( \mathbf{x} = \begin{bmatrix} 5 \\ 6 \end{bmatrix} \),手动计算 \( A\mathbf{x} \),然后用NumPy验证结果。
[2]
对函数 \( f(x, y) = x^2 y + y^3 \),分别求 \( \frac{\partial f}{\partial x} \) 和 \( \frac{\partial f}{\partial y} \),并计算在点 \( (2, 1) \) 处的梯度 \( \nabla f \)。
[3]
一个二分类问题中,真实标签为 \( y = 1 \),模型预测概率为 \( \hat{y} = 0.8 \)。计算该样本的交叉熵损失 \( \mathcal{L} = -[y \log \hat{y} + (1-y)\log(1-\hat{y})] \)。如果预测概率提高到 \( \hat{y} = 0.95 \),损失如何变化?
章节小结
线性代数是AI计算的基础,矩阵乘法是神经网络的核心运算
微积分中的梯度和链式法则是反向传播算法的数学基础
概率论为处理不确定性提供了框架,贝叶斯定理在多个AI领域有重要应用
交叉熵是最常用的分类损失函数,理解其含义对模型训练至关重要
不必一开始就精通所有数学,随着后续章节的学习,这些概念会越来越清晰
第二章(补充):环境配置实战
学习目标
掌握 Anaconda 在 Windows、Mac、Linux 上的安装与配置方法
理解 Python 虚拟环境的作用,熟练使用 conda 创建和管理环境
能够根据硬件条件选择并安装 CPU 或 GPU 版本的 PyTorch
熟悉 Jupyter Notebook 的启动方式、基本操作及 VS Code 集成使用
完成第一个基于 PyTorch 的简单神经网络搭建与运行
前置要求
具备基本的命令行操作能力(Windows CMD/PowerShell、Mac/Linux Terminal)
了解 Python 基础语法(变量、函数、基本数据结构)
计算机至少拥有 8GB 内存和 20GB 可用磁盘空间
如需使用 GPU 加速,需配备 NVIDIA 独立显卡(GTX 10 系列或更高)
Anaconda 安装
Anaconda 是一个集成了 Python、常用科学计算库以及包管理工具的数据科学平台。它内置了 conda 包管理器,能极大简化环境配置流程。
Windows 安装步骤
访问 Anaconda 官网 下载 Windows 安装包
双击运行安装程序,选择 "Add Anaconda3 to my PATH environment variable"(建议勾选)
完成安装后,打开 Anaconda Prompt 或 CMD
Mac 安装步骤
下载 macOS 图形安装包(Intel 芯片选 x86,Apple Silicon 选 arm64)
双击 .pkg 文件按向导安装,或下载命令行版本使用以下命令安装:
bash Anaconda3-2024.XX-MacOSX-arm64.sh
Linux 安装步骤
下载 Linux 版本的 sh 安装脚本
在终端中执行以下命令:
wget https://repo.anaconda.com/archive/Anaconda3-2024.XX-Linux-x86_64.sh
bash Anaconda3-2024.XX-Linux-x86_64.sh
source ~/.bashrc
验证安装
conda --version
python --version
安装成功标志: conda 命令能正常输出版本号(如 conda 24.1.2),即表示安装成功。
Python 虚拟环境
虚拟环境是 Python 开发中的核心实践,它能让你在同一台机器上维护多个相互隔离的 Python 环境。
为什么需要虚拟环境?
不同项目可能依赖同一库的不同版本(如项目A需要 PyTorch 1.x,项目B需要 2.x)
避免全局环境被污染,保持系统 Python 的纯净
便于复现和分享环境配置(通过 environment.yml)
方便部署时精确还原依赖
conda 环境管理常用命令
# 创建新环境(指定 Python 版本)
conda create -n ai-env python=3.10
# 激活环境
conda activate ai-env
# 退出当前环境
conda deactivate
# 查看所有环境
conda env list
# 删除环境
conda remove -n ai-env --all
# 导出环境配置
conda env export > environment.yml
# 从配置文件创建环境
conda env create -f environment.yml
PyTorch 安装
PyTorch 是目前最流行的深度学习框架之一。根据你的硬件条件,选择 CPU 版本或 GPU 版本进行安装。
CPU 版本安装
适用于没有 NVIDIA 显卡或仅需学习基础概念的场景:
conda activate ai-env
conda install pytorch torchvision torchaudio cpuonly -c pytorch
GPU 版本安装(CUDA)
适用于配备 NVIDIA 显卡且希望利用 GPU 加速训练的场景:
# CUDA 12.1 版本(推荐)
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
# 或 CUDA 11.8 版本(旧显卡兼容)
conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
注意: 安装 GPU 版本前,请确保已安装对应版本的 NVIDIA 显卡驱动。驱动版本过旧可能导致 CUDA 无法正常工作。
验证安装
import torch
# 检查 PyTorch 版本
print(f"PyTorch version: {torch.__version__}")
# 检查是否可以使用 GPU
print(f"CUDA available: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"CUDA version: {torch.version.cuda}")
print(f"GPU name: {torch.cuda.get_device_name(0)}")
print(f"GPU count: {torch.cuda.device_count()}")
Jupyter Notebook
Jupyter Notebook 是一个交互式编程环境,非常适合数据分析、模型调试和学习记录。
安装 Jupyter
conda install jupyter
启动 Jupyter Notebook
# 在指定目录启动(会自动打开浏览器)
jupyter notebook
# 指定端口启动
jupyter notebook --port 8888
# 不自动打开浏览器
jupyter notebook --no-browser
基本操作
新建单元格: 点击工具栏 "+" 按钮或使用快捷键 B(下方插入)/ A(上方插入)
运行单元格: Shift + Enter
切换模式: Esc 进入命令模式,Enter 进入编辑模式
单元格类型: Y(代码)、M(Markdown)、R(原始文本)
保存: Ctrl + S
重启内核: Kernel > Restart Kernel(可清除所有变量)
在 VS Code 中使用 Jupyter
安装 VS Code 扩展:Jupyter 和 Python
打开任意 .ipynb 文件,或新建文件并保存为 .ipynb 格式
点击右上角选择 Python 内核(选择你创建的 conda 环境)
即可在 VS Code 中直接运行 Notebook 单元格
推荐: 日常使用推荐在 VS Code 中编辑 Notebook,既能享受 Notebook 的交互性,又能利用 VS Code 强大的代码补全和调试功能。
常用库安装
以下列出了 AI 开发中最常用的 Python 库及其安装命令:
# 科学计算与数据处理
conda install numpy pandas matplotlib scikit-learn
# 或使用 pip 安装
pip install numpy pandas matplotlib scikit-learn
# 深度学习框架(PyTorch 已在前文安装)
pip install torch torchvision torchaudio
# Hugging Face 生态(预训练模型与数据集)
pip install transformers datasets accelerate
# 大模型应用开发
pip install langchain langchain-openai
# 其他常用工具
pip install tqdm tensorboard jupyterlab seaborn
库名
用途
安装命令
numpy
数值计算、多维数组操作
pip install numpy
pandas
数据读取、处理与分析
pip install pandas
matplotlib
数据可视化绘图
pip install matplotlib
scikit-learn
传统机器学习算法与工具
pip install scikit-learn
transformers
Hugging Face 预训练模型库
pip install transformers
torch
深度学习框架(PyTorch)
conda install pytorch -c pytorch
langchain
大语言模型应用开发框架
pip install langchain
GPU 环境检查
在进行深度学习训练前,确认 GPU 环境是否正常工作是至关重要的一步。
检查 NVIDIA 驱动与 CUDA
# 查看 GPU 信息
nvidia-smi
# 查看 CUDA 编译器版本
nvcc --version
PyTorch GPU 验证代码
import torch
# 1. 检查 CUDA 是否可用
print(f"CUDA available: {torch.cuda.is_available()}")
# 2. 获取 GPU 数量
print(f"GPU count: {torch.cuda.device_count()}")
# 3. 获取当前 GPU 名称
if torch.cuda.is_available():
print(f"Current GPU: {torch.cuda.get_device_name(0)}")
# 4. 测试张量是否能放到 GPU 上
if torch.cuda.is_available():
x = torch.rand(3, 3).cuda()
print(f"Tensor device: {x.device}")
print("GPU 测试通过!")
else:
print("CUDA 不可用,将使用 CPU 运行。")
常见问题: 如果 nvidia-smi 能显示 GPU 信息,但 torch.cuda.is_available() 返回 False,通常是因为 PyTorch 安装的 CUDA 版本与系统驱动不兼容,建议重新安装对应版本的 PyTorch。
第一个 AI 程序
让我们用 PyTorch 创建一个最简单的神经网络——一个单隐藏层的全连接网络,用于解决经典的 XOR 问题。
import torch
import torch.nn as nn
import torch.optim as optim
# 设置随机种子,保证结果可复现
torch.manual_seed(42)
# 定义神经网络模型
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.layer1 = nn.Linear(2, 4) # 输入层 -> 隐藏层
self.activation = nn.ReLU() # 激活函数
self.layer2 = nn.Linear(4, 1) # 隐藏层 -> 输出层
self.sigmoid = nn.Sigmoid() # 输出层激活
def forward(self, x):
x = self.layer1(x)
x = self.activation(x)
x = self.layer2(x)
x = self.sigmoid(x)
return x
# 准备 XOR 数据集
X = torch.tensor([[0., 0.], [0., 1.], [1., 0.], [1., 1.]])
y = torch.tensor([[0.], [1.], [1.], [0.]])
# 创建模型实例
model = SimpleNet()
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.1)
# 训练模型
print("开始训练...")
for epoch in range(1000):
# 前向传播
outputs = model(X)
loss = criterion(outputs, y)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 200 == 0:
print(f"Epoch [{epoch+1}/1000], Loss: {loss.item():.6f}")
# 测试模型
print("\n预测结果:")
with torch.no_grad():
predictions = model(X)
for i in range(4):
input_vals = X[i].tolist()
pred = predictions[i].item()
actual = y[i].item()
print(f"输入: {input_vals} -> 预测: {pred:.4f}, 实际: {actual}")
print("\n恭喜你,成功运行了第一个神经网络!")
运行结果说明: 训练完成后,模型应该能正确预测 XOR 的输出(输入相同为0,不同为1)。如果预测值接近 0 或 1,说明网络已学会 XOR 逻辑。
练习题
环境搭建实践
按照本章步骤,在你的电脑上完成以下操作:安装 Anaconda、创建名为 my-ai 的虚拟环境(Python 3.10)、安装 PyTorch CPU 版本,并在 Jupyter Notebook 中运行本章的 "第一个 AI 程序"。
虚拟环境管理
尝试导出你当前的环境配置为 environment.yml 文件,然后删除原环境并使用该配置文件重新创建环境,验证环境是否能正确还原。
扩展神经网络
修改 "第一个 AI 程序" 中的网络结构:将隐藏层神经元数量从 4 个增加到 8 个,添加第二个隐藏层,观察训练 loss 的变化和最终预测精度是否有提升。
章节小结
本章系统介绍了 AI 开发环境的搭建流程,涵盖 Anaconda 安装、虚拟环境管理、PyTorch 安装、Jupyter Notebook 使用以及常用库的配置。通过完成本章学习,你应该已经具备了以下能力:
能够独立搭建完整的 Python AI 开发环境
理解虚拟环境的重要性并熟练进行环境管理
根据硬件条件选择合适的 PyTorch 版本并完成安装验证
使用 Jupyter Notebook 或 VS Code 进行交互式编程
运行并理解一个简单的神经网络完整代码
环境配置是 AI 学习的第一步,也是后续所有实践的基础。建议在继续后续章节前,确保本章的所有工具和库都已正确安装并能正常运行。
附录C:常见问题(FAQ)
CUDA out of memory 怎么办?
GPU 显存不足是深度学习训练中最常见的问题,可通过以下方法解决:
减小 batch size: 将训练批次大小减半或更小,这是最直接有效的方法
使用混合精度训练: PyTorch 提供自动混合精度(AMP)功能,可节省约一半显存
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
outputs = model(inputs)
loss = criterion(outputs, targets)
清理缓存: 在训练循环中定期清理不需要的缓存
import torch
torch.cuda.empty_cache()
减少模型尺寸: 使用更小的模型或减少输入数据分辨率
梯度累积: 用多次小 batch 的梯度累积模拟大 batch 效果
模型下载慢/失败怎么办?
由于网络原因,从 Hugging Face 下载模型可能较慢或失败,可尝试以下方案:
使用国内镜像: 设置环境变量使用镜像站点
export HF_ENDPOINT=https://hf-mirror.com
使用 huggingface-cli 下载:
pip install huggingface-hub
huggingface-cli download --resume-download meta-llama/Llama-2-7b --local-dir ./models
在代码中设置镜像:
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
from transformers import AutoModel
model = AutoModel.from_pretrained("bert-base-chinese")
手动下载: 从镜像网站手动下载模型文件后放到本地缓存目录
ModuleNotFoundError 怎么解决?
模块未找到错误通常由以下原因导致:
API Key 怎么申请和管理?
使用大模型 API 需要申请对应的 API Key,以下是主要平台的申请入口和管理建议:
管理建议:
没有 GPU 可以学 AI 吗?
完全可以!虽然没有 GPU 会限制大规模模型的训练速度,但学习 AI 理论和运行中小规模模型完全可以在 CPU 上进行。此外,还有多种免费/低成本的 GPU 资源可用:
Python 版本应该选哪个?
Python 版本的选择需要考虑兼容性和稳定性:
推荐版本:3.9 - 3.11
Python 3.9:成熟稳定,几乎所有库都支持
Python 3.10:主流选择,语法改进(如 match-case)
Python 3.11:性能提升明显,大部分新库已支持
不推荐: Python 3.12(部分科学计算库尚未完全适配)、Python 3.8 及以下(即将或已经停止维护)
注意: 某些特定模型或框架可能对 Python 版本有严格要求,安装前请查阅官方文档的兼容性说明。
conda 和 pip 有什么区别?
特性
conda
pip
包来源
Anaconda 仓库、conda-forge
PyPI(Python Package Index)
非 Python 依赖
支持(C 库、CUDA 等)
不支持(需手动安装系统依赖)
环境管理
内置环境管理功能
需配合 virtualenv/venv 使用
安装速度
预编译二进制包,通常更快
部分包需本地编译,较慢
适用场景
数据科学、深度学习环境搭建
纯 Python 包安装
建议: 优先使用 conda 安装基础依赖(如 PyTorch、CUDA),pip 作为补充安装 PyPI 上的专用库。两者可在同一环境中混合使用。
Jupyter Notebook 卡顿怎么办?
Notebook 运行缓慢或卡顿可从以下方面排查和优化:
如何查看模型是否加载成功?
加载预训练模型后,可通过以下方式验证模型状态:
from transformers import AutoModel, AutoTokenizer
model_name = "bert-base-chinese"
model = AutoModel.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# 1. 打印模型结构(前5层)
print(model)
# 2. 统计模型参数量
total_params = sum(p.numel() for p in model.parameters())
trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(f"总参数量: {total_params:,}")
print(f"可训练参数量: {trainable_params:,}")
print(f"模型大小: {total_params * 4 / 1024 / 1024:.2f} MB (FP32)")
# 3. 测试前向传播
text = "这是一个测试"
inputs = tokenizer(text, return_tensors="pt")
outputs = model(**inputs)
print(f"输出形状: {outputs.last_hidden_state.shape}")
print("模型加载成功并可以正常推理!")
训练时 loss 不下降怎么办?
Loss 不下降说明模型没有有效学习,需要从多个维度排查:
如何选择合适的模型?
模型选择需要综合考虑任务需求、数据规模和计算资源:
任务类型:
文本分类:BERT、RoBERTa、DistilBERT
文本生成:GPT 系列、LLaMA、ChatGLM
图像分类:ResNet、EfficientNet、ViT
目标检测:YOLO、DETR
数据量: 数据少选小模型或进行迁移学习,数据充足可训练大模型
计算资源: 资源有限选择轻量级模型(DistilBERT、MobileNet)
精度要求: 高精度场景选大模型,实时推理场景选轻量化模型
AI 学习需要多强的电脑?
不同学习阶段对硬件的要求差异很大,以下是配置建议:
学习阶段
CPU
内存
GPU
适用场景
入门学习
任意现代 CPU
8GB+
无需 / 核显
理论学习、小规模代码实验
基础实践
i5/R5 及以上
16GB+
GTX 1060 6GB
经典模型训练、Kaggle 入门竞赛
进阶开发
i7/R7 及以上
32GB+
RTX 3060 12GB+
微调大模型、中等规模项目
专业研究
服务器级 CPU
64GB+
RTX 4090 / A100
大规模训练、论文复现
建议: 入门阶段不必追求高配,善用 Google Colab、Kaggle 等免费 GPU 资源。确定长期方向后再投资硬件。
第三章:AI基础概念
学习目标
理解人工智能(AI)的定义与核心能力
掌握AI的三个层次:弱人工智能、强人工智能、超人工智能
了解AI在日常生活中的典型应用场景
认识AI vs ML vs DL之间的层级关系
了解图灵测试和AI发展中的关键历史节点
前置要求
无特殊前置要求,具备基本的计算机使用经验即可。
什么是人工智能(AI)?
人工智能(Artificial Intelligence,AI) 是指让计算机模拟人类智能行为的技术。简单来说,就是让机器能够像人一样"思考"、"学习"和"解决问题"。
AI的三个层次
层次
定义
当前状态
例子
弱人工智能(Weak AI / Narrow AI)
专注于特定任务的AI,在单一领域表现出色
已实现,广泛应用
人脸识别、语音助手、推荐系统
强人工智能(Strong AI / AGI)
具备与人类同等智能水平,能处理各种复杂任务
仍在研究中
科幻电影中的Jarvis、HAL 9000
超人工智能(Super AI / ASI)
超越人类智能的AI,在所有领域远超人类
理论概念
目前仅存在于科幻想象中
常见误区
AI ≠ 机器人。AI是软件层面的智能算法,机器人是硬件载体。AI可以存在于任何设备中(手机、电脑、云端服务器),不一定需要物理形态。
AI vs ML vs DL 的关系
这三个概念经常被混用,但它们之间是包含关系:
概念
全称
范围
核心方法
AI
Artificial Intelligence
最广:所有让机器模拟智能的技术
规则系统、搜索算法、机器学习等
ML
Machine Learning
AI的子集:从数据中学习规律
监督学习、无监督学习、强化学习
DL
Deep Learning
ML的子集:使用多层神经网络
CNN、RNN、Transformer
层级关系
人工智能 ⊃ 机器学习 ⊃ 深度学习 (AI包含ML,ML包含DL,DL是最内层的核心技术)
AI在日常生活中的应用
你可能每天都在使用AI,却不自知。以下是常见的AI应用场景:
手机里的AI
功能
AI应用
你每天怎么用
人脸解锁
人脸识别+比对算法
拿起手机自动解锁
拍照美颜
人脸检测+图像处理
自拍自动磨皮、瘦脸
语音助手
语音识别+自然语言理解
"Hey Siri,明天天气怎样"
输入法联想
语言模型预测下一个词
打字自动补全"你好"→"吗"
相册分类
图像识别+自动分类
照片自动分成"人物"、"风景"
网络服务中的AI
推荐系统 :抖音、淘宝、Netflix的推荐都是AI分析你的喜好,推送你可能感兴趣的内容
搜索引擎 :Google/百度的搜索结果排序是AI判断哪些内容最相关
垃圾邮件过滤 :邮箱自动识别垃圾邮件,让你不用手动筛选
翻译服务 :Google翻译、DeepL使用AI翻译,质量远超传统方法
客服聊天 :很多客服是AI自动回答常见问题,节省人力
你可能不知道的AI
• 地图导航 :预测路况、选择最优路线 • 外卖配送 :估算送达时间、派单优化 • 打车软件 :匹配司机、预测等待时间 • 健康码 :行程分析、风险判断 • 股票交易 :算法自动交易、量化分析
AI在各行业的应用
医疗健康
辅助诊断 :AI分析X光、CT,帮助医生发现病灶
药物研发 :AI预测分子结构,加速新药开发
基因分析 :AI解读基因数据,预测疾病风险
智能问诊 :AI聊天机器人初步了解症状,分流患者
金融行业
风控审核 :AI判断贷款申请风险,秒级审批
欺诈检测 :AI识别异常交易,防止信用卡盗刷
量化交易 :AI分析市场数据,自动执行交易策略
智能客服 :银行APP的AI客服解答常见问题
教育领域
个性化学习 :AI分析学生水平,推荐适合的学习内容
自动批改 :AI批改作业、考试,节省教师时间
口语练习 :AI评测发音,帮助学生练口语
智能题库 :AI根据知识点自动生成题目
交通出行
自动驾驶 :AI控制车辆,正在逐步商业化
交通调度 :AI优化红绿灯时间,减少拥堵
网约车匹配 :AI匹配乘客和司机,提高效率
事故预防 :AI分析路况,预警潜在危险
制造业
质量检测 :AI视觉识别产品缺陷
预测维护 :AI预测设备故障,提前维护
生产优化 :AI优化生产流程,提高效率
供应链管理 :AI预测需求,优化库存
AI技术的分类
类型
能力
典型应用
视觉AI
看:识别图像、视频
人脸识别、自动驾驶视觉、医学影像分析
语音AI
听:识别和处理语音
语音助手、电话客服、语音翻译
语言AI
理解:阅读和生成文本
ChatGPT、翻译、写作辅助、代码生成
决策AI
思考:分析和决策
推荐系统、风控系统、游戏AI
创造AI
创作:生成新内容
AI绘画、AI音乐、AI写作
图灵测试
图灵测试(Turing Test) 由英国数学家艾伦·图灵(Alan Turing)在1950年提出,是判断机器是否具备智能的经典标准。测试方法很简单:一个人类裁判通过文字与一个机器和一个真人分别对话,如果裁判无法分辨哪个是机器、哪个是人,那么这台机器就通过了图灵测试,被认为具有"智能"。
图灵测试的意义与局限
图灵测试开创了"机器能否思考"这一哲学讨论的先河,但它也有局限性:一台机器可以通过巧妙的话术"骗过"裁判,却不一定真正理解语言。现代AI研究更多关注具体任务的性能指标,而非单纯通过图灵测试。
AI寒冬
AI的发展并非一帆风顺。历史上出现过多次AI寒冬(AI Winter) ——由于技术未能达到过高的期望,导致研究经费大幅削减、公众兴趣骤降的时期。第一次AI寒冬发生在1970年代,第二次在1980年代末至1990年代初。这些寒冬提醒我们:技术发展需要理性预期,既不能过度悲观,也不能盲目乐观。
当前AI的边界
AI能做什么 vs 不能做什么
AI目前能做的:
• 图像识别与分类
• 自然语言理解与生成
• 数据分析与模式发现
• 自动驾驶(限定场景)
• 游戏博弈与策略决策
• 代码生成与辅助编程
AI目前不能做的:
• 真正理解世界(仅有统计模式匹配)
• 拥有自我意识和情感
• 在没有训练过的全新领域泛化
• 保证100%准确(可能产生幻觉)
• 替代人类的创造力和道德判断
为什么AI现在这么火?
AI技术爆发的原因:
数据爆炸 :互联网产生海量数据,供AI学习
算力提升 :GPU等硬件让大规模计算成为可能
算法突破 :深度学习、Transformer等技术成熟
开源生态 :Hugging Face等平台让AI技术共享
应用落地 :ChatGPT等产品让普通人也能用AI
本章小结
人工智能(AI)是让计算机模拟人类智能行为的技术,核心能力包括感知、推理、学习和交互。
AI分为三个层次:弱AI(当前已实现)、强AI/AGI(研究中)、超AI(理论概念)。
AI、ML、DL是包含关系:AI ⊃ ML ⊃ DL,深度学习是当前最核心的技术手段。
AI已广泛应用于手机、网络服务、医疗、金融、教育、交通、制造等各行各业。
当前AI有明确的边界:擅长模式识别和数据分析,但缺乏真正的理解力、自我意识和道德判断能力。
练习题
以下哪项不属于AI的三个层次?
A. 弱人工智能(Narrow AI) B. 强人工智能(AGI) C. 超人工智能(ASI) D. 量子人工智能(QAI)
答案:D 。AI的三个层次是弱AI、强AI和超AI,量子人工智能不是标准的AI分类。
图灵测试的核心思想是什么?
A. 测试机器的计算速度 B. 通过对话判断机器是否能模仿人类智能 C. 测试机器的存储容量 D. 测试机器的视觉识别能力
答案:B 。图灵测试通过人机对话的不可区分性来判断机器是否具备智能。
以下关于AI、ML、DL的关系,哪个描述是正确的?
A. DL包含ML,ML包含AI B. AI包含ML,ML包含DL C. AI、ML、DL是三个独立的技术 D. DL和ML是同一概念的不同名称
答案:B 。AI是最广的概念,ML是AI的子集,DL是ML的子集,三者是层层包含的关系。
第四章:机器学习概述
学习目标
理解机器学习(ML)的定义与核心思想
掌握三种学习类型:监督学习、无监督学习、强化学习
理解监督学习的两大任务:分类与回归
了解机器学习的完整工作流程
认识无监督学习和强化学习的典型算法与应用
前置要求
第三章:AI基础概念(理解AI的基本定义和分类)。
什么是机器学习(ML)?
机器学习(Machine Learning) 是AI的核心分支,让计算机从数据中自动学习规律,而不是人工编写所有规则。
传统编程 vs 机器学习
传统编程 :人类编写规则 → 计算机执行 → 输出结果
机器学习 :计算机从数据中学习规则 → 自动改进 → 输出结果
例如:要识别垃圾邮件——
传统方式:程序员手动编写"如果邮件包含'中奖'、'免费'等关键词则标记为垃圾"
ML方式:给模型10万封已标记的邮件,模型自动学习垃圾邮件的特征模式
机器学习的三种类型
类型
特点
数据
应用场景
监督学习
有标签数据,告诉机器正确答案
有标签(输入+答案)
图像分类、垃圾邮件识别、预测房价
无监督学习
无标签数据,让机器自己发现规律
无标签(只有输入)
用户分群、数据降维、异常检测
强化学习
通过试错获得奖励,学习最优策略
环境反馈(奖励/惩罚)
游戏AI、自动驾驶、机器人控制
监督学习详解
监督学习是最常见的机器学习方式。就像老师教学生:老师给题目和答案,学生通过对比学习。
训练数据(输入+标签)
→
学习算法
→
模型
→
预测新数据
监督学习的两大任务:
分类(Classification) :预测离散类别,如"是/否"、"猫/狗"
回归(Regression) :预测连续数值,如房价、温度
监督学习的应用实例
垃圾邮件识别(分类任务) :
• 训练数据:10万封邮件(标记"垃圾"或"正常")
• 模型学习:垃圾邮件的特征(关键词、发件人)
• 应用:新邮件自动判断是否垃圾
房价预测(回归任务) :
• 训练数据:历史房价(面积、位置、房价)
• 模型学习:面积/位置与房价的关系
• 应用:输入房屋信息,预测房价
无监督学习详解
无监督学习(Unsupervised Learning) 是让机器在没有标签的数据中自己发现规律和结构。就像让学生在没有老师指导的情况下自己探索知识。
为什么叫"无监督"?
监督学习:有老师告诉对错(有标签) 无监督学习:没有老师,机器自己探索(无标签) 数据只有输入,没有标准答案。机器的任务是找出数据内部的规律。
无监督学习的主要任务
1. 聚类(Clustering)——自动分组
聚类 是把相似的数据自动归为一组,发现数据中的自然分组。
聚类的通俗理解
想象你有一堆照片,不知道分类。聚类算法会自动: • 把人物照片放在一起 • 把风景照片放在一起 • 把动物照片放在一起 机器不知道什么是"人物"、"风景",但它能发现照片之间的相似性,自动分组。
K-Means聚类算法示例
K-Means是最简单常用的聚类算法,下面用Python演示其基本用法:
from sklearn.cluster import KMeans
import numpy as np
# 生成模拟数据:两组二维点
np.random.seed(42)
data = np.concatenate([
np.random.randn(50, 2) + np.array([0, 0]), # 第一组,中心在(0,0)
np.random.randn(50, 2) + np.array([5, 5]), # 第二组,中心在(5,5)
])
# 使用K-Means聚类,指定分为2组
kmeans = KMeans(n_clusters=2, random_state=42, n_init=10)
labels = kmeans.fit_predict(data)
# 查看聚类结果
print("每个数据点的分组标签:", labels[:10])
print("聚类中心坐标:", kmeans.cluster_centers_)
# 输出示例:
# 每个数据点的分组标签: [1 1 1 1 1 1 1 1 1 1]
# 聚类中心坐标: [[4.93 4.88] [-0.12 0.05]]
2. 降维(Dimensionality Reduction)——简化数据
降维 是把高维数据压缩到低维,保留关键信息,去掉冗余。
什么是高维数据?
每个数据点有很多属性(维度): • 用户数据:年龄、性别、收入、职业、爱好...(几十个维度) • 图像:每个像素是一个维度(一张图片可能有上万个维度) 维度太多的问题:计算复杂、信息冗余、难以可视化 降维解决这个问题:保留核心信息,压缩到少数维度。
常见降维算法
算法
原理
应用
PCA(主成分分析)
找到数据变化最大的方向,投影到这些方向
数据压缩、可视化、去噪
t-SNE
保持局部相似性,用于可视化
高维数据可视化展示
UMAP
比t-SNE更快,保持全局结构
大规模数据可视化
3. 异常检测(Anomaly Detection)——发现异常
异常检测 是找出与正常数据明显不同的异常数据。
异常检测的价值
• 欺诈检测 :发现异常交易行为(银行卡盗刷) • 故障预警 :发现设备运行的异常状态 • 入侵检测 :发现网络异常流量攻击 • 数据清洗 :发现数据中的错误异常值
强化学习详解
强化学习(Reinforcement Learning) 是让AI通过不断尝试和反馈来学习最优策略。就像训练宠物:表现好给奖励,表现差不奖励,逐渐学会正确行为。
类比理解
训练狗狗: • 狗坐下 → 给零食(奖励) → 狗记住坐下能得零食 • 狗乱跑 → 不给零食(无奖励) → 狗知道乱跑没好处 • 多次尝试后 → 狗学会"听到指令就坐下" 强化学习就是这个原理:AI尝试各种行为,根据奖励反馈调整策略。
强化学习的核心概念
状态(State)
当前环境的情况 (如:游戏中角色的位置)
动作(Action)
AI能做的事情 (如:向上、向下、攻击)
奖励(Reward)
行为好坏的反馈 (如:得分、扣分)
策略(Policy)
在什么状态做什么动作 (AI学到的决策规则)
强化学习的循环过程
观察状态
→
选择动作
→
执行动作
→
获得奖励
→
更新策略
→
进入新状态
探索与利用的平衡
探索 vs 利用
探索 :尝试新的、未知的行为 • 好处:可能发现更好的方法 • 风险:可能暂时表现不好利用 :使用已知的最佳行为 • 好处:稳定获得好结果 • 风险:错过更好的方法 好的强化学习需要平衡两者:既探索新可能,又利用已知最优。
常见强化学习算法
算法
原理
应用
Q-Learning
建立表格记录每个(状态,动作)的预期奖励
简单环境、游戏AI
DQN
用神经网络代替Q表,处理复杂环境
Atari游戏、复杂游戏
Policy Gradient
直接优化动作策略,不是估计奖励值
连续动作空间、机器人
PPO
限制策略更新幅度,训练稳定
ChatGPT的RLHF训练
AlphaGo的突破
AlphaGo的学习过程: 1. 监督学习 :学习人类高手棋谱 2. 强化学习 :自我对弈,探索更好的策略 3. 发现人类未知的招法,超越人类水平 这是强化学习的经典成功案例。
机器学习的完整流程
一个完整的机器学习项目通常包含以下步骤:
数据收集
→
数据预处理
→
特征工程
→
模型选择
→
模型训练
→
模型评估
→
部署上线
步骤
说明
关键工具/方法
数据收集
获取训练所需的数据
数据库查询、爬虫、公开数据集
数据预处理
清洗、标准化、处理缺失值
Pandas、NumPy
特征工程
选择和构造有用的特征
领域知识、统计分析
模型选择
选择合适的算法
根据任务类型和数据特点
模型训练
用数据训练模型参数
Scikit-learn、PyTorch、TensorFlow
模型评估
测试模型性能
准确率、F1分数、交叉验证
部署上线
将模型投入实际使用
Flask、Docker、云服务
本章小结
机器学习是AI的核心分支,核心思想是让计算机从数据中自动学习规律,而非人工编写所有规则。
监督学习需要带标签的数据,分为分类(预测类别)和回归(预测数值)两大任务。
无监督学习在没有标签的数据中发现规律,主要任务包括聚类、降维和异常检测。
强化学习通过"试错+奖励"的方式学习最优策略,核心概念包括状态、动作、奖励和策略。
完整的机器学习流程包括:数据收集 → 预处理 → 特征工程 → 模型选择 → 训练 → 评估 → 部署。
练习题
以下哪个是监督学习的典型任务?
A. 将新闻按主题自动分组 B. 根据房屋特征预测房价 C. 发现信用卡交易的异常模式 D. 通过自我对弈学会下围棋
答案:B 。预测房价是回归任务,属于监督学习。A是无监督学习(聚类),C是无监督学习(异常检测),D是强化学习。
在强化学习中,"探索"和"利用"分别指什么?
A. 探索是寻找新数据,利用是使用旧数据 B. 探索是尝试未知行为,利用是使用已知最佳行为 C. 探索是增加模型参数,利用是减少模型参数 D. 探索是训练模型,利用是评估模型
答案:B 。探索指尝试新的、未知的行为以发现更好的策略;利用指使用已知的最佳行为以获得稳定回报。
机器学习完整流程的正确顺序是?
A. 模型选择 → 数据收集 → 特征工程 → 训练 → 评估 B. 数据收集 → 预处理 → 特征工程 → 模型选择 → 训练 → 评估 C. 数据收集 → 模型选择 → 训练 → 预处理 → 评估 D. 特征工程 → 数据收集 → 模型选择 → 训练 → 预处理
答案:B 。正确的流程是先收集数据,再预处理,然后特征工程,接着选择模型,训练,最后评估。
第五章:深度学习概述
学习目标
理解深度学习(DL)的定义及其与ML的关系
掌握神经网络的基本结构:输入层、隐藏层、输出层
理解神经元的工作原理和数学公式
了解常见激活函数的特点和用途
认识CNN、RNN、Transformer等常见深度学习架构
前置要求
第四章:机器学习概述(理解ML的基本概念和三种学习类型)。
什么是深度学习(DL)?
深度学习(Deep Learning) 是机器学习的子领域,使用多层神经网络来学习数据的复杂特征。
层级关系
人工智能 ⊃ 机器学习 ⊃ 深度学习 (AI包含ML,ML包含DL) 深度学习是机器学习中最强大的子集,也是当前AI突破的核心技术。
为什么叫"深度"学习?
因为神经网络有很多"层"。传统神经网络可能只有2-3层,深度学习网络可能有几十甚至上百层。
深度学习的优势
能自动学习复杂特征,无需人工特征工程
处理图像、语音、自然语言效果极佳
大规模数据和算力支持后性能持续提升
端到端学习:从原始输入直接到最终输出
常见深度学习架构
架构
特点
应用
CNN(卷积神经网络)
擅长处理图像,能识别空间模式
图像分类、目标检测、人脸识别
RNN(循环神经网络)
擅长处理序列数据,有记忆能力
语音识别、文本翻译、时间序列预测
Transformer
并行处理序列,注意力机制
GPT、BERT、大语言模型
神经网络基础
神经网络是深度学习的基本构建单元。理解它的工作原理,是理解深度学习的关键。
神经元的工作流程
一个神经元(节点)的工作过程分为5步:
接收输入 :从上一层接收多个输入值 \(x_1, x_2, ..., x_n\)
加权求和 :每个输入乘以对应的权重 \(w_i\),然后求和,再加上偏置 \(b\)
线性变换 :计算 \(z = w_1 x_1 + w_2 x_2 + ... + w_n x_n + b\),即 \(z = \mathbf{w} \cdot \mathbf{x} + b\)
激活函数 :将 \(z\) 通过非线性激活函数 \(f\),得到输出 \(y = f(z) = f(\mathbf{w} \cdot \mathbf{x} + b)\)
传递输出 :将 \(y\) 传递给下一层的神经元
核心公式
神经元的输出公式:
\[ y = f(\mathbf{w} \cdot \mathbf{x} + b) \]
其中:
• \(\mathbf{x}\) 是输入向量
• \(\mathbf{w}\) 是权重向量(模型参数,训练时学习)
• \(b\) 是偏置(另一个可学习参数)
• \(f\) 是激活函数(引入非线性)
激活函数
激活函数为神经网络引入非线性能力,使其能学习复杂的模式。如果没有激活函数,多层网络等价于单层线性变换。
激活函数
公式
图形特征
特点与用途
ReLU
\(f(x) = \max(0, x)\)
正数区域斜率为1,负数区域为0,在原点有折角
最常用的激活函数,计算简单,缓解梯度消失
Sigmoid
\(f(x) = \frac{1}{1 + e^{-x}}\)
S形曲线,输出范围(0,1)
输出可解释为概率,常用于二分类输出层
Tanh
\(f(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}\)
S形曲线,输出范围(-1,1),过原点
零中心化,比Sigmoid更适合隐藏层
Softmax
\(f(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}}\)
将向量转为概率分布,所有输出之和为1
多分类任务的输出层,输出各类别概率
前向传播 vs 反向传播
对比维度
前向传播(Forward Propagation)
反向传播(Backpropagation)
方向
输入层 → 隐藏层 → 输出层
输出层 → 隐藏层 → 输入层
目的
计算预测值
计算梯度,更新参数
过程
数据逐层通过,每层做加权求和+激活
误差逐层反向传递,计算每个参数的梯度
类比
学生做卷子,写出答案
老师批改,告诉学生哪里错了、该怎么改
深度学习发展简史
深度学习的发展经历了多个关键里程碑:
时间
里程碑
意义
1958年
感知机(Perceptron)
第一个神经网络模型,由Rosenblatt提出,能进行简单的线性分类
1986年
反向传播算法
Hinton等人推广了反向传播算法,使多层网络训练成为可能
1998年
LeNet-5
LeCun提出的卷积神经网络,成功应用于手写数字识别
2012年
AlexNet
在ImageNet竞赛中大幅领先,开启深度学习时代,证明GPU+大数据的威力
2014年
GAN、VGG
生成对抗网络提出;VGG证明深层网络效果更好
2015年
ResNet
残差网络突破100层,解决深层网络训练难题
2017年
Transformer
Google提出"Attention is All You Need",彻底改变NLP领域
2018年
BERT / GPT
预训练+微调范式确立,NLP任务性能大幅提升
2020-2022年
GPT-3 / DALL-E
大模型展现涌现能力,AI生成内容(AIGC)兴起
2022-2024年
ChatGPT / GPT-4
大语言模型走入大众视野,AI应用爆发式增长
本章小结
深度学习是机器学习的子集,使用多层神经网络自动学习数据的复杂特征表示。
神经元的基本公式为 \(y = f(\mathbf{w} \cdot \mathbf{x} + b)\),其中权重和偏置通过训练学习,激活函数引入非线性。
常见激活函数包括ReLU(最常用)、Sigmoid(概率输出)、Tanh(零中心化)、Softmax(多分类)。
前向传播计算预测值,反向传播计算梯度并更新参数,两者交替进行构成训练过程。
深度学习从1958年的感知机发展到如今的Transformer和大语言模型,经历了多次技术突破。
练习题
神经元输出的核心公式是什么?
A. \(y = w + x + b\) B. \(y = f(w \cdot x + b)\) C. \(y = f(x) + w\) D. \(y = w \times f(x) \times b\)
答案:B 。神经元先对输入做加权求和加偏置(\(w \cdot x + b\)),再通过激活函数 \(f\) 得到输出。
以下哪个激活函数最常用于多分类任务的输出层?
A. ReLU B. Sigmoid C. Tanh D. Softmax
答案:D 。Softmax将输出转为概率分布,适合多分类任务。Sigmoid用于二分类,ReLU和Tanh通常用于隐藏层。
2017年提出的Transformer架构的核心创新是什么?
A. 使用卷积核提取特征 B. 引入注意力机制实现并行处理 C. 使用循环结构处理序列 D. 提出了生成对抗网络
答案:B 。Transformer的核心创新是自注意力机制,可以并行处理整个序列,取代了RNN的逐词处理方式。
第六章:模型
学习目标
理解模型(Model)的概念与本质
掌握大语言模型(LLM)的工作原理
理解参数量的意义及其与效果的关系
学会根据任务类型、计算资源、成本和隐私需求选择合适的模型
区分开源模型与闭源模型的优劣
前置要求
第五章:深度学习概述(理解神经网络的基本结构和深度学习架构)。
什么是模型?
模型(Model) 是机器学习的核心产出,是一个数学函数或算法,能将输入数据转换为预测输出。
通俗理解
模型就像一个"黑盒子": 输入 → [模型] → 输出 比如输入一张图片,模型输出"这是猫"
模型的本质
模型内部是大量的参数(Parameters) ——就是数字。这些参数决定了模型如何处理输入。
一个简单模型可能有几百个参数
GPT-3有1750亿个参数
GPT-4参数量更大(具体数字未公开)
常见模型类型
类型
说明
例子
判别式模型
直接学习输入→输出的映射
分类器、回归模型
生成式模型
学习数据分布,能生成新数据
GPT、Stable Diffusion
大语言模型(LLM)
大规模文本生成模型
ChatGPT、Claude、Gemini
大语言模型(LLM)详解
大语言模型(Large Language Model) 是基于Transformer架构的生成式模型,能理解和生成人类语言。
LLM的工作原理
1. 接收文本输入 2. 将文本切分为token(词元) 3. 通过多层Transformer处理 4. 预测下一个token的概率 5. 输出最可能的文本序列
Token是什么?
Token是文本的最小处理单位。可以是:
一个词(如"apple")
一个字(如"你")
一个词的一部分(如"ing")
例如:"我爱学习AI" 可能被切分为:["我", "爱", "学习", "AI"] 共4个tokens。
使用transformers库调用LLM
下面展示如何使用Hugging Face的transformers库快速调用一个预训练模型:
from transformers import pipeline
# 创建文本生成pipeline(自动下载并加载模型)
generator = pipeline("text-generation", model="gpt2")
# 生成文本
result = generator(
"Artificial intelligence is",
max_new_tokens=20,
temperature=0.7,
do_sample=True
)
print(result[0]['generated_text'])
# 输出示例: "Artificial intelligence is transforming the way we live and work..."
# 也可以用于其他任务
classifier = pipeline("sentiment-analysis")
result = classifier("I love learning about AI!")
print(result)
# 输出示例: [{'label': 'POSITIVE', 'score': 0.9998}]
模型大小与参数量
参数量 是衡量模型规模的指标,参数越多,模型容量越大,通常效果更好,但成本也越高。
主流LLM的参数量对比
模型
参数量
显存需求(FP16)
特点
GPT-2 Small
117M(1.17亿)
~0.5GB
早期模型,适合入门学习
GPT-2 Large
1.5B(15亿)
~3GB
可在消费级显卡运行
Llama-2-7B
7B(70亿)
~14GB
开源主流,RTX 4090可运行
Llama-2-13B
13B(130亿)
~26GB
效果更好,需要高端显卡
Mistral-7B
7B
~14GB
效率高,小模型中的佼佼者
Qwen-7B
7B
~14GB
中文能力强,国产开源
Llama-2-70B
70B
~140GB
顶级开源,需要专业GPU
GPT-3
175B
~350GB
早期大模型标杆
GPT-4
未公开(推测万亿级)
需要集群
当前最强闭源模型之一
参数量与效果的关系
参数越多 → 效果越好 (但不是线性关系):
• 7B模型:适合简单任务,日常对话
• 13B模型:效果明显提升,复杂任务
• 70B模型:接近GPT-3水平,专业任务
效果提升趋势 :参数量与模型效果之间呈现对数增长关系——从小模型到大模型时效果提升显著,但继续增大时边际收益递减。就像考试从50分提升到80分容易,从90分提升到95分很难。
但代价也随之增加 :
• 更大显存需求
• 更慢的推理速度
• 更高的训练成本
实践中需要平衡效果与成本。
如何选择合适的模型?
选择模型需要考虑多个因素:
1. 任务类型
任务类型
推荐模型
原因
简单对话
7B-13B模型
成本低,效果足够
代码生成
Claude、GPT-4、DeepSeek-Coder
编程能力是核心竞争力
长文档处理
Claude(200K上下文)
超长上下文窗口
中文任务
Qwen、DeepSeek
中文训练数据多,效果好
实时应用
小模型+量化
速度优先,牺牲精度
私有部署
Llama、Qwen等开源模型
数据安全,成本可控
2. 计算资源
消费级显卡(如RTX 4090 24GB) :7B INT4量化、13B INT4量化
专业显卡(如A100 40-80GB) :70B INT4量化、13B FP16
无GPU(纯CPU) :小模型(7B以下)+ INT4量化
云端API :使用闭源模型(GPT-4、Claude),无需本地GPU
3. 成本考量
成本对比
闭源模型API :
• GPT-4:约$0.03/1K tokens输入,$0.06/1K tokens输出
• Claude:约$0.008/1K tokens(Haiku),$0.03/1K tokens(Sonnet)
开源模型自部署 :
• GPU租赁:$1-3/小时(RTX 4090),$3-5/小时(A100)
• 适合高频使用、固定成本
选择建议 :
• 低频使用 → API更划算
• 高频使用 → 自部署更经济
4. 数据隐私
数据敏感 :选择开源模型本地部署,数据不出本地
数据不敏感 :可以使用闭源API,效果更好
企业数据 :推荐私有部署或企业版API
开源 vs 闭源模型对比
维度
开源模型
闭源模型
效果
接近但略逊于闭源
通常最佳
成本
部署成本(GPU租赁)
API调用费用
隐私
完全可控,本地运行
数据上传到服务器
定制
可微调、可修改
无法修改,只能调用
易用性
需要技术能力部署
直接API调用,简单
更新
自己负责升级
厂商持续优化更新
实用建议
新手入门 :先用API(ChatGPT、Claude)体验,了解AI能力
进阶用户 :部署开源模型(Llama-2-7B),学习模型调优
企业应用 :根据数据敏感度选择API或私有部署
成本优化 :高频任务用开源自部署,低频任务用API
本章小结
模型是机器学习的核心产出,本质是包含大量参数的数学函数,将输入转换为预测输出。
大语言模型(LLM)基于Transformer架构,通过Token处理文本,逐个预测下一个Token来生成内容。
参数量是衡量模型规模的关键指标,参数越多效果越好但成本越高,呈现对数增长关系。
选型需要综合考虑任务类型、计算资源、成本和数据隐私四个维度。
开源模型提供隐私可控和可定制的优势,闭源模型在效果和易用性上更优,需根据场景选择。
练习题
以下关于模型参数量的描述,哪个是正确的?
A. 参数量与效果呈线性关系,参数翻倍效果翻倍 B. 参数量越多效果越好,但边际收益递减 C. 参数量对模型效果没有影响 D. 参数量越少效果越好,因为更精简
答案:B 。参数量与效果呈对数增长关系,从小模型增大时效果提升显著,继续增大时边际收益递减。
如果你的公司需要处理敏感数据且高频使用AI,应该选择哪种方案?
A. 使用GPT-4 API B. 使用Claude API C. 本地部署开源模型(如Llama、Qwen) D. 使用免费在线AI工具
答案:C 。数据敏感需要本地部署保证隐私,高频使用自部署比API更经济,因此开源模型本地部署是最佳选择。
Token是什么?以下哪个描述最准确?
A. Token就是汉字 B. Token就是英文单词 C. Token是文本的最小处理单位,可以是词、字或词的一部分 D. Token是模型的参数
答案:C 。Token是模型处理文本的最小单位,根据分词算法不同,可以是词、字或子词。
第七章:训练
学习目标
理解训练的定义与核心流程
掌握损失函数的概念与常见类型
理解梯度下降算法的原理与三种变体
理解反向传播的作用与机制
了解学习率、Batch Size、Epoch等关键超参数
前置要求
第五章:深度学习概述(理解神经网络结构)、第二章:数学基础(理解导数和梯度概念)。
什么是训练?
训练(Training) 是让模型从数据中学习的过程。通过反复调整模型参数,使其能准确完成任务。
类比理解
训练就像学生做练习题: 做题 → 对照答案 → 发现错误 → 调整方法 → 再做题 → ... 循环直到正确率足够高
训练的核心流程
准备数据
→
初始化模型
→
前向传播
→
计算损失
→
反向传播
→
更新参数
关键概念详解
1. 损失函数(Loss Function)
损失函数 衡量模型预测与真实答案的差距。损失越小,模型越好。
损失函数的数学公式
均方误差(MSE) ——用于回归任务:
\[ \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \]
其中 \(y_i\) 是真实值,\(\hat{y}_i\) 是预测值,\(n\) 是样本数量。
交叉熵损失(Cross-Entropy) ——用于分类任务:
\[ H(p, q) = -\sum_{i=1}^{C} p_i \log(q_i) \]
其中 \(p_i\) 是真实标签的概率分布(one-hot编码),\(q_i\) 是模型预测的概率,\(C\) 是类别数。
2. 优化器(Optimizer)
优化器 决定如何更新模型参数来降低损失。
SGD :随机梯度下降,最基础
Adam :自适应学习率,效果稳定,最常用
3. 学习率(Learning Rate)
学习率 控制每次参数更新的幅度。
太大:不稳定,可能跳过最优解
太小:训练太慢
需要调优找到合适值
批量大小(Batch Size)
一次训练使用多少样本: • 小批量:更频繁更新,内存占用小 • 大批量:更新更稳定,但内存占用大
4. Epoch、Batch、Iteration
这三个概念描述训练的循环过程,新手容易混淆,务必理解清楚:
概念
定义
例子
Epoch(轮次)
整个数据集被完整学习一遍
1000个样本全部训练完=1个Epoch
Batch(批次)
一次训练使用的样本数量
每次用32个样本训练=Batch Size=32
Iteration(迭代)
训练一个Batch需要的步骤
1000样本÷32=31.25≈32次迭代
具体计算示例
假设:
• 数据集有1000张图片
• Batch Size = 32(每次训练32张)
• 要训练10个Epoch
计算:
• 每个Epoch需要:1000 ÷ 32 = 31.25 ≈ 32次迭代
• 10个Epoch总共需要:32 × 10 = 320次迭代
• 模型参数更新320次
训练时通常会看到进度条显示:"Epoch 3/10, Batch 15/32"
为什么需要多个Epoch?
一次学习(1个Epoch)不足以让模型掌握知识,就像学生不能只看一遍课本就学会。需要多次重复学习,逐渐提高准确率。
Epoch太少 :模型没学好,欠拟合
Epoch太多 :模型"背熟了",过拟合(记住训练数据,不能泛化)
合适Epoch :观察训练曲线,找到损失不再明显下降的点
5. 梯度下降(Gradient Descent)详解
梯度下降 是训练模型的核心算法,用于找到让损失最小的参数值。
山坡类比
想象你站在山坡上,目标是到达最低点(山谷):
• 你看脚下,判断哪个方向最陡(梯度)
• 沿最陡方向往下走一步(参数更新)
• 重复:判断方向→走一步→判断方向→走一步
• 最终到达山谷(最优参数)
梯度 就是山坡最陡的方向(函数变化最快的方向)
下降 就是沿着这个方向往下走
梯度下降的三种方式
方式
每次使用的数据
特点
适用场景
批量梯度下降(BGD)
全部数据
方向准确,但计算慢
数据量小时使用
随机梯度下降(SGD)
单个样本
快但方向不稳定,易震荡
数据量大时使用
小批量梯度下降(Mini-batch SGD)
一小批样本(如32个)
平衡速度和稳定性,最常用
实际训练的主流方法
计算梯度 (损失函数对参数的导数)
→
确定方向 (梯度负方向)
→
更新参数 (参数 -= 学习率 × 梯度)
→
重复直到 损失足够小
梯度下降的关键公式
参数更新公式:
\[ \theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla L(\theta) \]
其中:
• \(\theta\) 是模型参数
• \(\eta\) 是学习率
• \(\nabla L(\theta)\) 是损失函数对参数的梯度
简单理解:新参数 = 旧参数 - 学习率 × 梯度
梯度告诉我们"往哪里走能降低损失",学习率告诉我们"走多远"。
梯度下降的Python代码示例
下面用一维函数演示梯度下降的基本过程:
import numpy as np
# 定义损失函数: f(x) = x^2 + 2x + 1 = (x+1)^2
# 最小值在 x = -1 处,最小值为 0
def loss_function(x):
return x**2 + 2*x + 1
# 损失函数的导数(梯度)
def gradient(x):
return 2*x + 2
# 梯度下降参数
learning_rate = 0.1 # 学习率
x = 3.0 # 初始值(随机初始化)
epochs = 30 # 迭代次数
print("梯度下降过程:")
for epoch in range(epochs):
grad = gradient(x) # 计算梯度
x = x - learning_rate * grad # 更新参数
loss = loss_function(x)
if epoch % 5 == 0 or epoch == epochs - 1:
print(f" Epoch {epoch:2d}: x = {x:.6f}, loss = {loss:.6f}")
print(f"\n最终结果: x = {x:.6f}, loss = {loss_function(x):.6f}")
# 输出: 最终结果: x = -1.000000, loss = 0.000000
为什么学习率很重要?
学习率决定每一步走多远:
学习率太大 :一步跨太大,可能跳过最低点,来回震荡,无法收敛
学习率太小 :一步太小,下山太慢,训练时间很长
合适的学习率 :稳定下降,较快到达最优
学习率调优技巧
• 初始值通常:0.001(Adam默认)、0.01(SGD默认)
• 观察训练曲线:损失震荡→学习率太大;损失下降慢→学习率太小
• 可以动态调整:训练前期大学习率(快速下降),后期小学习率(精细调整)
• 常用策略:学习率衰减、余弦退火
6. 反向传播(Backpropagation)补充
反向传播 是计算梯度的核心技术。它从输出层向输入层逐层计算每个参数对损失的影响。
为什么叫"反向"?
前向传播 :数据从输入→隐藏层→输出(计算预测值)
反向传播 :误差从输出→隐藏层→输入(计算梯度)
因为梯度计算是从输出层开始的,沿着网络结构"反向"传播误差信息,告诉每层"你哪里做错了,该怎么调整"。这就是神经网络的"自我纠错"过程。
训练的常见问题
问题
现象
原因
解决方法
过拟合(Overfitting)
训练数据表现好,新数据表现差
模型太复杂,"背熟"了训练数据
更多数据、正则化、Dropout、早停
欠拟合(Underfitting)
训练数据和新数据都表现差
模型太简单,无法学习数据规律
增加模型复杂度、更多训练时间
梯度消失
深层网络底层参数几乎不更新
多层网络中梯度逐层衰减
ReLU激活函数、Batch Normalization、残差连接
梯度爆炸
梯度值变得极大,参数更新不稳定
梯度在反向传播中逐层放大
梯度裁剪、合适的初始化方法
本章小结
训练是通过反复前向传播和反向传播来调整模型参数,使损失函数最小化的过程。
损失函数衡量预测与真实的差距:回归任务用MSE,分类任务用交叉熵。
梯度下降是参数更新的核心算法,公式为 \(\theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla L(\theta)\)。
学习率、Batch Size和Epoch是影响训练效果的关键超参数,需要根据具体任务调优。
常见训练问题包括过拟合(模型太复杂)、欠拟合(模型太简单)和梯度消失/爆炸(深层网络问题)。
练习题
在梯度下降中,如果学习率设置过大,最可能出现什么问题?
A. 训练速度太慢 B. 损失函数来回震荡,无法收敛 C. 模型欠拟合 D. 梯度消失
答案:B 。学习率太大会导致每步跨距过大,在最优点附近来回震荡,无法收敛到最小值。
以下哪个公式正确表达了梯度下降的参数更新规则?
A. \(\theta_{\text{new}} = \theta_{\text{old}} + \eta \cdot \nabla L\) B. \(\theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla L\) C. \(\theta_{\text{new}} = \theta_{\text{old}} \times \eta \cdot \nabla L\) D. \(\theta_{\text{new}} = \eta \cdot \nabla L\)
答案:B 。梯度下降沿梯度的负方向更新参数,即减去学习率乘以梯度。
模型在训练集上准确率99%,但在测试集上只有60%,这属于什么问题?
A. 欠拟合 B. 过拟合 C. 梯度消失 D. 学习率太大
答案:B 。训练集表现好但测试集表现差是典型的过拟合现象,模型"背熟"了训练数据但无法泛化到新数据。
第八章:模型评估与调优
学习目标
理解模型评估的意义和核心指标
掌握准确率、精确率、召回率、F1分数的计算与适用场景
理解过拟合与欠拟合的成因及偏差-方差权衡
掌握正则化方法(L1、L2、Dropout、数据增强)
了解交叉验证的原理与应用
前置要求
第七章:训练(理解损失函数、训练过程和常见问题)。
为什么需要评估?
训练完成后,需要评估模型性能,判断模型是否达到要求,是否可以投入使用。
核心问题
• 模型准确吗? • 模型稳定吗? • 模型能处理各种情况吗?
核心评估指标
准确率(Accuracy)
准确率 是模型预测正确的比例。
公式
\[ \text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN} \]
例如:100个样本,预测正确90个,准确率=90%
精确率与召回率
这两个指标用于评估分类模型的不同角度:
指标
含义
公式
应用场景
精确率(Precision)
预测为正的样本中,真正为正的比例
\(P = \frac{TP}{TP + FP}\)
"我说对的,有多少真的对"
召回率(Recall)
真正的正样本中,被预测为正的比例
\(R = \frac{TP}{TP + FN}\)
"真的对的,我找出来多少"
精确率 vs 召回率权衡
• 高精确率:宁可漏过,不可错报(医疗诊断——不误诊健康人)
• 高召回率:宁可错报,不可漏过(垃圾邮件检测——不漏掉垃圾邮件)
• 通常需要根据场景权衡
F1分数
F1分数 是精确率和召回率的调和平均,综合评估模型性能。
F1分数公式
\[ F1 = 2 \times \frac{P \times R}{P + R} \]
当精确率和召回率都很重要时,使用F1分数作为综合指标。
损失值(Loss)
损失值 衡量模型预测与真实答案的差距,训练过程中持续下降说明模型在学习。
训练初期:损失值高,模型在学习
训练中期:损失值下降,模型进步
训练后期:损失值稳定,模型收敛
评估指标的Python代码示例
from sklearn.metrics import (
accuracy_score, precision_score,
recall_score, f1_score, confusion_matrix
)
# 真实标签和模型预测
y_true = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 1, 0]
# 计算各项指标
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)
cm = confusion_matrix(y_true, y_pred)
print(f"准确率: {accuracy:.2%}")
print(f"精确率: {precision:.2%}")
print(f"召回率: {recall:.2%}")
print(f"F1分数: {f1:.2%}")
print(f"混淆矩阵:\n{cm}")
# 输出示例:
# 准确率: 80.00%
# 精确率: 75.00%
# 召回率: 83.33%
# F1分数: 78.95%
# 混淆矩阵:
# [[3 1]
# [1 5]]
混淆矩阵
混淆矩阵 是展示分类结果的表格,清晰显示预测正确和错误的情况。
预测为正
预测为负
实际为正
真正例(TP)
假负例(FN)
实际为负
假正例(FP)
真负例(TN)
过拟合与欠拟合
模型训练中最重要的两个问题就是过拟合和欠拟合,它们与偏差-方差权衡(Bias-Variance Tradeoff) 密切相关。
偏差与方差
概念
含义
对应问题
偏差(Bias)
模型预测的平均值与真实值的差距
偏差大 → 欠拟合(模型太简单)
方差(Variance)
模型在不同训练集上的预测波动
方差大 → 过拟合(模型太复杂)
靶心类比
想象射击靶心:
• 低偏差+低方差 :所有弹孔都集中在靶心 → 理想模型
• 高偏差+低方差 :弹孔集中但偏离靶心 → 欠拟合
• 低偏差+高方差 :弹孔散布在靶心周围 → 过拟合
• 高偏差+高方差 :弹孔散布且偏离靶心 → 最差情况
学习曲线
通过观察学习曲线(训练损失和验证损失随训练进行的变化)可以诊断问题:
欠拟合 :训练损失和验证损失都很高,且差距不大 → 模型太简单
过拟合 :训练损失很低,但验证损失很高且在上升 → 模型太复杂
良好拟合 :两者都逐渐下降并趋于稳定,差距适中
正则化方法
正则化 是防止过拟合的核心技术,通过限制模型复杂度来提高泛化能力。
L1 正则化(Lasso)
在损失函数中添加参数绝对值之和:
L1正则化公式
\[ L_{\text{total}} = L_{\text{original}} + \lambda \sum_{i} |w_i| \]
效果:使部分参数变为0,起到特征选择的作用,产生稀疏模型。
L2 正则化(Ridge)
在损失函数中添加参数平方和:
L2正则化公式
\[ L_{\text{total}} = L_{\text{original}} + \lambda \sum_{i} w_i^2 \]
效果:使参数值变小但不会变为0,防止任何单一参数对结果影响过大。
这是最常用的正则化方法,PyTorch中的weight_decay就是L2正则化。
Dropout
Dropout 在训练过程中随机"关闭"一部分神经元,迫使网络不依赖任何单个神经元。
Dropout原理
• 训练时:每个神经元以概率p被"丢弃"(输出设为0)
• 测试时:所有神经元都参与,但输出按比例缩小
• 效果:相当于训练了多个子网络的集成,减少过拟合
• 常用丢弃率:0.2~0.5
数据增强(Data Augmentation)
通过变换训练数据来增加数据多样性,让模型学到更鲁棒的特征。
图像 :旋转、翻转、裁剪、颜色变换、添加噪声
文本 :同义词替换、随机删除、回译
语音 :变速、变调、添加背景噪声
交叉验证
交叉验证 是一种更可靠的模型评估方法,能充分利用数据,减少评估结果的偶然性。
K折交叉验证(K-Fold Cross Validation)
将数据集分成K个大小相等的子集("折"),每次用其中一折作为验证集,其余K-1折作为训练集,重复K次,取K次评估结果的平均值。
第1折: [验证] [训练] [训练] [训练] [训练]
→
第2折: [训练] [验证] [训练] [训练] [训练]
→
第3折: [训练] [训练] [验证] [训练] [训练]
→
第4折: [训练] [训练] [训练] [验证] [训练]
→
第5折: [训练] [训练] [训练] [训练] [验证]
K折交叉验证要点
• 常用K值:5或10
• 每个样本都会被用作验证集一次
• 最终性能 = K次评估的平均值
• 比简单的训练/测试分割更可靠
• 计算成本更高(需要训练K次模型)
本章小结
模型评估的核心指标包括准确率、精确率、召回率和F1分数,不同场景应选择不同指标。
过拟合(训练好、测试差)和欠拟合(训练差、测试差)是最常见的两个问题,对应偏差-方差权衡。
正则化是防止过拟合的主要手段,包括L1正则化(稀疏化)、L2正则化(参数衰减)、Dropout和数据增强。
K折交叉验证通过多次训练-验证循环提供更可靠的性能评估,减少评估结果的偶然性。
混淆矩阵是分析分类结果的重要工具,从中可以推导出所有核心评估指标。
练习题
在医疗诊断场景中,以下哪个指标最重要?
A. 准确率 B. 精确率(宁可漏过,不可错报) C. 召回率(宁可错报,不可漏过) D. 以上都不重要
答案:B 。医疗诊断中,将健康人误诊为患病(低精确率)的代价很高,因此更看重精确率。
以下哪种方法不能有效防止过拟合?
A. 增加训练数据 B. 使用Dropout C. 增加模型层数和参数 D. 使用L2正则化
答案:C 。增加模型复杂度会加剧过拟合。增加数据、Dropout和L2正则化都是防止过拟合的有效方法。
5折交叉验证中,模型总共需要训练多少次?
A. 1次 B. 5次 C. 4次 D. 10次
答案:B 。K折交叉验证需要训练K次,每次使用不同的验证折,5折交叉验证就是训练5次。
第九章:卷积神经网络(CNN)
学习目标
理解CNN的定义及其为什么适合处理图像
掌握卷积操作的原理和特征提取的层次性
理解池化层和全连接层的作用
了解经典CNN架构(AlexNet、VGG、ResNet等)
能够使用PyTorch构建简单的CNN模型
前置要求
第五章:深度学习概述(理解神经网络的基本结构和激活函数)。
CNN概述
CNN(Convolutional Neural Network,卷积神经网络) 专门处理图像数据,能自动识别图像中的特征。它是图像识别、目标检测、人脸识别等视觉任务的核心技术。
为什么CNN适合处理图像?
图像是由像素组成的网格,相邻像素之间有关系(比如边缘是一条连续的线)。CNN能保留空间关系 ,不像传统方法把图像变成一串数字。它用"小窗口"扫描图像,就像人用眼睛逐区域观察一样。
CNN核心组件详解
1. 卷积层——特征提取的核心
卷积层 是CNN最重要的部分。它使用滤波器(Filter/Kernel) 在图像上滑动扫描,提取各种特征。
滤波器是什么?
滤波器是一个小矩阵(比如3×3),里面放着不同的数字权重。
• 边缘滤波器 :能检测图像中的线条和边缘
• 纹理滤波器 :能识别特定的纹理模式
• 颜色滤波器 :能检测特定的颜色分布
一个卷积层可能有几十到几百个不同的滤波器,每个学习识别一种特征。
卷积操作的原理
想象你有一个小窗口(3×3像素),在图像上从左到右、从上到下滑动:
定位 :窗口放在图像的某个位置
计算 :窗口内的像素值与滤波器权重相乘,然后求和
输出 :得到一个新的数值(特征值)
移动 :窗口向右移动一格,重复上述过程
完成 :扫描完整个图像,生成一张"特征图"
输入图像 (224×224像素)
→
卷积层 (多个滤波器扫描)
→
特征图 (每张对应一种特征)
卷积操作的Python/NumPy代码示例
import numpy as np
# 简单的5x5输入图像(灰度)
image = np.array([
[10, 10, 10, 0, 0],
[10, 10, 10, 0, 0],
[10, 10, 10, 0, 0],
[ 0, 0, 0, 10, 10],
[ 0, 0, 0, 10, 10]
], dtype=float)
# 3x3边缘检测滤波器(水平边缘)
kernel = np.array([
[-1, -1, -1],
[ 0, 0, 0],
[ 1, 1, 1]
], dtype=float)
# 手动实现2D卷积
def conv2d(image, kernel):
ih, iw = image.shape
kh, kw = kernel.shape
oh, ow = ih - kh + 1, iw - kw + 1
output = np.zeros((oh, ow))
for i in range(oh):
for j in range(ow):
region = image[i:i+kh, j:j+kw]
output[i, j] = np.sum(region * kernel)
return output
result = conv2d(image, kernel)
print("卷积结果(特征图):")
print(result)
# 输出: 检测到水平边缘的位置会有较大数值
特征提取的层次性
层数
提取的特征
例子
浅层(第1-2层)
基础视觉元素
边缘、线条、简单颜色块
中层(第3-5层)
形状和部件
圆形、方形、眼睛形状、轮子形状
深层(第6-N层)
完整物体
人脸、汽车、猫、狗的整体形态
实例:CNN如何识别一张猫的照片
第1层卷积 :检测到边缘线条 → 发现猫轮廓的边界
第2层卷积 :检测到形状 → 发现圆形的眼睛、三角形的耳朵
第3层卷积 :检测到部件 → 眼睛+耳朵+胡须的组合
第4层卷积 :检测到整体 → "这像是猫的脸"
全连接层 :综合判断 → 输出"这是猫(概率98%)"
2. 池化层——降维与关键特征保留
池化层 的作用是缩小特征图的尺寸,同时保留最重要的特征信息。
为什么需要池化?
• 减少计算量 :特征图太大,计算成本高
• 防止过拟合 :去除过多细节,保留核心特征
• 增强鲁棒性 :即使图像稍微移动、缩放,关键特征仍能被识别
常见池化方式
池化类型
原理
特点
最大池化(Max Pooling)
在区域内取最大值
保留最强特征,最常用
平均池化(Average Pooling)
在区域内取平均值
保留整体趋势,较平滑
3. 全连接层——最终分类决策
全连接层 将前面提取的所有特征综合起来,做出最终判断。
接收输入 :来自最后一层卷积/池化的特征
综合判断 :将所有特征"投票"决定类别
输出结果 :每个类别的概率值(如:猫90%、狗5%、鸟5%)
输入图像
→
卷积层 (多次)
→
池化层 (穿插)
→
全连接层
→
输出分类
著名CNN架构
架构
年份
特点
贡献
AlexNet
2012
8层,首次使用ReLU
开启深度学习时代
VGG
2014
16-19层,结构简洁
证明层数深效果好
ResNet
2015
残差连接,突破100层
解决深层网络训练难问题
YOLO
2016
实时目标检测
速度与精度平衡
CNN的局限
• 主要处理图像,不适合序列数据(文本、语音)
• 对图像旋转、翻转敏感(需要数据增强)
• 需要大量标注数据训练
• 计算资源需求较大
使用PyTorch构建简单CNN
下面展示如何用PyTorch构建一个用于图像分类的简单CNN:
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
"""简单的CNN模型,用于手写数字识别(MNIST)"""
def __init__(self):
super(SimpleCNN, self).__init__()
# 第一个卷积层:1通道输入,32个滤波器,3x3窗口
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
# 第二个卷积层:32通道输入,64个滤波器
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# 全连接层
self.fc1 = nn.Linear(64 * 7 * 7, 128) # 28x28图像经过两次池化后为7x7
self.fc2 = nn.Linear(128, 10) # 10个类别(数字0-9)
# Dropout层防止过拟合
self.dropout = nn.Dropout(0.25)
def forward(self, x):
# 第一层:卷积 → ReLU → 最大池化
x = F.relu(self.conv1(x)) # 输出: 32 x 28 x 28
x = F.max_pool2d(x, 2) # 输出: 32 x 14 x 14
# 第二层:卷积 → ReLU → 最大池化
x = F.relu(self.conv2(x)) # 输出: 64 x 14 x 14
x = F.max_pool2d(x, 2) # 输出: 64 x 7 x 7
# 展平为一维向量
x = x.view(-1, 64 * 7 * 7) # 输出: 3136
# 全连接层 + Dropout
x = F.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x) # 输出: 10(各类别得分)
return x
# 创建模型实例
model = SimpleCNN()
print(f"模型参数总量: {sum(p.numel() for p in model.parameters()):,}")
# 输出: 模型参数总量: 540,850
# 模拟前向传播
dummy_input = torch.randn(1, 1, 28, 28) # 批量大小1,1通道,28x28图像
output = model(dummy_input)
print(f"输出形状: {output.shape}") # 输出: torch.Size([1, 10])
本章小结
CNN是专为图像处理设计的深度学习架构,通过卷积操作保留空间关系,逐层提取从简单到复杂的特征。
卷积层使用滤波器在图像上滑动扫描,提取边缘、形状、物体等层次化特征。
池化层缩小特征图尺寸,减少计算量并增强鲁棒性;全连接层综合所有特征做出分类决策。
经典CNN架构包括AlexNet(开启深度学习时代)、VGG(证明深层有效)、ResNet(残差连接突破深度限制)。
CNN的局限包括:主要处理图像、对旋转敏感、需要大量标注数据和计算资源。
练习题
CNN中卷积层的主要作用是什么?
A. 将图像展平为一维向量 B. 使用滤波器在图像上滑动扫描,提取特征 C. 将特征图缩小到固定尺寸 D. 计算各类别的概率
答案:B 。卷积层使用滤波器在图像上滑动扫描,通过加权求和提取各种特征。
以下哪种池化方式最常用于CNN中?
A. 最小池化(Min Pooling) B. 中值池化(Median Pooling) C. 最大池化(Max Pooling) D. 随机池化(Random Pooling)
答案:C 。最大池化在区域内取最大值,保留最强特征,是CNN中最常用的池化方式。
ResNet的核心创新是什么?
A. 使用更大的滤波器 B. 引入残差连接(跳跃连接) C. 去掉全连接层 D. 使用循环结构
答案:B 。ResNet通过残差连接(跳跃连接)让梯度可以直接流过浅层,解决了深层网络训练困难的问题。
第十章:Transformer架构
学习目标
理解Transformer架构的革命性意义
掌握注意力机制和Self-Attention的工作原理
理解多头注意力机制的设计动机和工作方式
理解位置编码的必要性及数学公式
区分Encoder-only、Decoder-only和Encoder-Decoder架构
前置要求
第五章:深度学习概述(理解神经网络结构)、第二章:数学基础(理解矩阵运算、Softmax函数)。
Transformer概述
Transformer 是目前最主流的AI架构,GPT、BERT、Claude等几乎所有大语言模型都基于它。2017年由Google在论文"Attention is All You Need"中提出,彻底改变了自然语言处理领域。
Transformer的革命性突破
之前的模型(RNN)需要逐词处理,慢且难并行。
Transformer可以同时处理整个句子 ,速度快、效果好。
这让大模型训练成为可能,开启了AI新时代。
Transformer的核心:注意力机制
注意力机制(Attention) 让模型能关注输入中最相关的部分,就像人读书时会重点关注某些词句。
通俗理解
阅读句子"我喜欢编程,特别是Python"
处理"Python"这个词时,注意力会关注"编程"
因为它们语义相关,"Python"是"编程"的一种
这就是注意力机制的核心思想:根据当前词,找到相关词,重点参考。
Self-Attention(自注意力)详解
自注意力 让序列中的每个词都能关注其他所有词,获取上下文信息。
Query、Key、Value的比喻
图书馆类比
想象你在图书馆找书:
• Query(查询) :你想要找什么内容(当前词的需求)
• Key(标签) :每本书的标签/目录(其他词的标识)
• Value(内容) :书里的实际内容(其他词的信息)
你的Query与每本书的Key对比,找到最匹配的书,取出Value(书的内容)。相似度越高,这本书对你的价值越大。
自注意力计算过程
创建向量 :每个词生成Query、Key、Value三个向量
计算相似度 :Query与所有Key的点积,得到注意力分数
归一化 :分数除以\(\sqrt{d_k}\)(防止数值太大),再通过Softmax变成概率
加权求和 :用概率权重对所有Value加权,得到新的词表示
输入:"我 爱 学习"
→
每个词生成Q/K/V
→
"学习"的Q与其他词的K匹配
→
得到注意力权重
→
加权组合得到新表示
注意力分数计算的数学公式
Self-Attention公式
\[ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V \]
其中:
• \(Q\) 是查询矩阵(Query),形状为 \((n \times d_k)\)
• \(K\) 是键矩阵(Key),形状为 \((n \times d_k)\)
• \(V\) 是值矩阵(Value),形状为 \((n \times d_v)\)
• \(d_k\) 是Key向量的维度,\(\sqrt{d_k}\)用于缩放防止梯度消失
• \(QK^T\) 计算所有词对之间的相似度
• softmax将相似度转为概率分布
• 最终用概率对V加权求和
Self-Attention的Python/NumPy代码实现
import numpy as np
def softmax(x):
"""计算softmax,防止数值溢出"""
exp_x = np.exp(x - np.max(x, axis=-1, keepdims=True))
return exp_x / np.sum(exp_x, axis=-1, keepdims=True)
def self_attention(Q, K, V):
"""
Self-Attention计算
Q: (seq_len, d_k) 查询矩阵
K: (seq_len, d_k) 键矩阵
V: (seq_len, d_v) 值矩阵
"""
d_k = Q.shape[-1]
# 1. 计算注意力分数: Q * K^T
scores = Q @ K.T # (seq_len, seq_len)
# 2. 缩放
scores = scores / np.sqrt(d_k)
# 3. Softmax归一化
attention_weights = softmax(scores)
# 4. 加权求和
output = attention_weights @ V # (seq_len, d_v)
return output, attention_weights
# 示例:3个词,每个词用4维向量表示
np.random.seed(42)
seq_len = 3
d_k = 4
d_v = 4
Q = np.random.randn(seq_len, d_k)
K = np.random.randn(seq_len, d_k)
V = np.random.randn(seq_len, d_v)
output, weights = self_attention(Q, K, V)
print("注意力权重矩阵:")
print(np.round(weights, 3))
# 每行表示一个词对其他词的关注程度
print(f"\n输出形状: {output.shape}")
多头注意力(Multi-Head Attention)
多头注意力 是让模型从多个不同角度理解句子。
为什么需要"多头"?
一个注意力头只能关注一种关系:
• Head 1 可能关注语法关系(主语-谓语)
• Head 2 可能关注语义关系(名词-属性)
• Head 3 可能关注位置关系(上下文)
多个头可以同时关注不同类型的关系,理解更全面。
GPT-3使用了96个注意力头!
多头注意力工作原理
把Query、Key、Value分成多份(比如8份)
每份独立做一次自注意力计算
得到8个不同的"视角"结果
把8个结果合并,得到最终表示
位置编码(Positional Encoding)
位置编码 告诉模型每个词在句子中的位置,弥补Transformer无法识别顺序的缺陷。
为什么需要位置编码?
Transformer同时处理所有词,不知道"我吃苹果"和"苹果吃我"的区别(词相同,顺序不同)。
位置编码给每个词添加一个"位置标签",让模型能区分:
"我"(位置1)+ "吃"(位置2)+ "苹果"(位置3)
这样模型就知道词的顺序,理解正确含义。
位置编码的数学公式
正弦-余弦位置编码
\[ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) \]
\[ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) \]
其中:
• \(pos\) 是词在序列中的位置(0, 1, 2, ...)
• \(i\) 是维度索引
• \(d_{\text{model}}\) 是模型的嵌入维度(如512、768、1024)
这种编码方式使模型能学习到相对位置关系。
Transformer架构详解
Transformer由两个主要部分组成:
Encoder(编码器)——理解输入
Encoder 负责理解输入文本,提取其中的信息。
输入 :原始文本(如"把这段话翻译成英语")
处理 :多层自注意力+前馈网络,理解每个词及其上下文
输出 :每个词的深层语义表示
代表模型 :BERT(双向理解,适合分类、问答)
Decoder(解码器)——生成输出
Decoder 负责生成输出文本,逐词预测下一个词。
输入 :Encoder的输出 + 已生成的词
处理 :自注意力(看已生成部分)+ 交叉注意力(看Encoder输出)
输出 :下一个词的概率分布,选择最可能的词
代表模型 :GPT(单向生成,适合写作、对话)
输入文本
→
Encoder (理解)
→
语义表示
→
Decoder (生成)
→
输出文本
Encoder vs Decoder 对比
维度
Encoder
Decoder
注意力类型
自注意力(看全部输入)
自注意力(只能看已生成的词)+ 交叉注意力(看Encoder输出)
处理方式
双向理解
单向生成(从左到右)
代表模型
BERT、RoBERTa
GPT、LLaMA、Qwen
适合任务
分类、问答、命名实体识别
写作、对话、代码生成
不同架构的应用场景
架构
模型
特点
适合任务
仅Encoder
BERT、RoBERTa
双向理解整个文本
文本分类、情感分析、问答系统
仅Decoder
GPT、LLaMA、Qwen
单向生成,预测下一个词
写作、对话、代码生成
Encoder-Decoder
T5、BART
理解+生成结合
翻译、摘要、改写
关键创新总结
Transformer的三大创新:
• 自注意力 :词与词直接关联,理解全面
• 多头机制 :多个角度分析,更丰富
• 并行计算 :同时处理,速度快
这三点让Transformer成为现代AI的基石。
本章小结
Transformer通过注意力机制实现了并行处理序列数据,彻底取代了RNN的逐词处理方式,开启了AI新时代。
Self-Attention的核心公式为 \(\text{Attention}(Q,K,V) = \text{softmax}(QK^T/\sqrt{d_k})V\),通过Q/K/V机制让每个词关注所有相关词。
多头注意力让模型从多个角度理解文本,位置编码通过正弦-余弦函数为词添加位置信息。
Transformer由Encoder(理解输入)和Decoder(生成输出)组成,不同组合产生了BERT、GPT、T5等不同架构。
仅Encoder架构适合理解任务(分类、问答),仅Decoder架构适合生成任务(写作、对话),Encoder-Decoder适合序列转换任务(翻译、摘要)。
练习题
Self-Attention公式中,除以\(\sqrt{d_k}\)的目的是什么?
A. 加速计算 B. 防止点积结果过大导致softmax梯度消失 C. 增加模型参数 D. 减少内存使用
答案:B 。当维度\(d_k\)较大时,点积结果会很大,softmax会进入梯度极小的区域。除以\(\sqrt{d_k}\)进行缩放可以缓解这个问题。
GPT系列模型使用的是哪种Transformer架构?
A. 仅Encoder B. 仅Decoder C. Encoder-Decoder D. 不使用Transformer
答案:B 。GPT使用仅Decoder架构,通过自回归方式逐词生成文本,适合写作和对话等生成任务。
为什么Transformer需要位置编码?
A. 因为Transformer的计算速度太慢 B. 因为Transformer同时处理所有词,本身不知道词的顺序 C. 因为位置编码可以减少参数量 D. 因为没有位置编码就无法训练
答案:B 。Transformer的核心优势是并行处理所有词,但代价是丢失了词序信息。位置编码通过给每个位置添加唯一编码来弥补这一缺陷。
第十一章:大语言模型(LLM)详解
学习目标
理解LLM的预训练任务和训练流程
掌握分词算法(BPE)的基本原理
理解推理采样策略(Greedy、Beam Search、Temperature、Top-k、Top-p)
了解模型压缩技术(量化、蒸馏、剪枝)
能够使用transformers库进行文本生成
前置要求
第十章:Transformer架构(理解Self-Attention、位置编码和Decoder结构)。
LLM的工作原理
大语言模型(Large Language Model,LLM) 是基于Transformer Decoder架构的大规模预训练模型,通过预测下一个词来生成文本。
LLM工作的5个步骤
1. 接收输入 :用户输入文本(如"人工智能的未来是")
2. 分词处理 :将文本切分为Token序列
3. 嵌入编码 :将Token转换为向量表示,加上位置编码
4. Transformer处理 :通过多层Self-Attention和前馈网络处理
5. 预测输出 :根据最后一个Token的表示,预测下一个Token的概率分布
预训练任务详解
LLM的预训练通常基于以下两种任务之一:
1. Next Token Prediction(下一个词预测)
这是GPT系列使用的预训练任务。模型看到前面的词,预测下一个词。
示例
输入:"人工智能正在"
目标:预测下一个Token
可能输出:"改变"(概率30%)、"发展"(概率25%)、"进步"(概率15%)...
模型通过在海量文本上反复做这个任务,学会了语言的规律、知识和推理能力。
2. 掩码语言模型(Masked Language Model)
这是BERT使用的预训练任务。随机遮盖输入中的一些词,让模型预测被遮盖的词。
示例
原文:"人工智能正在改变世界"
掩码后:"[MASK]正在[MASK]世界"
目标:预测[MASK]位置的词("人工智能"和"改变")
分词算法
分词(Tokenization) 是将文本切分为模型可处理的Token序列的过程。
BPE(Byte Pair Encoding)原理
BPE是最常用的分词算法,核心思想是:从字符开始,反复合并最高频的字符对,逐步构建词表。
BPE简单示例
假设语料中出现很多次 "low"、"lower"、"newest":
初始 (字符级别):
l o w l o w e r n e w e s t
第1步 :e 和 w 最常相邻 → 合并为 ew
l o w l o w e r n ew e s t
第2步 :n 和 ew 最常相邻 → 合并为 new
l o w l o w e r new e s t
第3步 :lo 和 w 最常相邻 → 合并为 low
low low e r new e s t
最终词表包含:l, o, w, e, r, n, ew, new, lo, low, lowe, lower, ...
推理采样策略
LLM在生成文本时,需要从概率分布中选择下一个Token。不同的采样策略影响输出的多样性和质量。
策略
原理
优点
缺点
适用场景
Greedy(贪心)
每步选概率最高的Token
确定性强,速度快
容易重复,缺乏多样性
翻译、摘要等确定性任务
Beam Search
同时保留多个候选序列
全局最优,质量高
计算量大,输出保守
机器翻译
Temperature
调整概率分布的"尖锐度"
控制输出的随机性
需要调参
通用(低=事实,高=创意)
Top-k
只从概率最高的k个Token中采样
过滤低质量选项
k值固定,不够灵活
对话、故事生成
Top-p(核采样)
从概率累积达到p的最小Token集合中采样
动态调整候选集大小
实现稍复杂
通用,最推荐
采样参数选择建议
• 编程/数学 :temperature=0.1~0.2,top_p=0.9(确定性优先)
• 一般对话 :temperature=0.5~0.7,top_p=0.9(平衡)
• 创意写作 :temperature=0.8~1.0,top_p=0.95(多样性优先)
• 事实问答 :temperature=0,使用Greedy(最准确)
使用transformers库生成文本
from transformers import AutoModelForCausalLM, AutoTokenizer
# 加载模型和分词器
model_name = "gpt2" # 可替换为 "meta-llama/Llama-2-7b-hf" 等
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
# 编码输入文本
prompt = "人工智能的未来发展方向包括"
input_ids = tokenizer.encode(prompt, return_tensors="pt")
# 生成文本(使用不同的采样策略)
# 方式1:贪心搜索(确定性输出)
output_greedy = model.generate(input_ids, max_new_tokens=50, do_sample=False)
print("Greedy:", tokenizer.decode(output_greedy[0], skip_special_tokens=True))
# 方式2:带温度的采样(创造性输出)
output_temp = model.generate(
input_ids,
max_new_tokens=50,
do_sample=True,
temperature=0.8,
top_p=0.9
)
print("Temperature:", tokenizer.decode(output_temp[0], skip_special_tokens=True))
# 方式3:Top-k采样
output_topp = model.generate(
input_ids,
max_new_tokens=50,
do_sample=True,
top_k=50,
top_p=0.95
)
print("Top-k+p:", tokenizer.decode(output_topp[0], skip_special_tokens=True))
模型压缩技术
为了在资源有限的设备上运行大模型,需要使用模型压缩技术:
技术
原理
效果
代价
量化(Quantization)
降低参数精度(FP16→INT8→INT4)
显存减少50%-75%
精度略有下降
知识蒸馏(Distillation)
用大模型教小模型
小模型获得接近大模型的效果
需要训练过程
剪枝(Pruning)
删除不重要的参数或层
减少模型大小和计算量
可能影响性能
LoRA(低秩适配)
只训练少量额外参数
微调成本大幅降低
推理时需要合并参数
实用建议
本地运行大模型 :
• 7B模型 + INT4量化 ≈ 4GB显存(RTX 3060可运行)
• 13B模型 + INT4量化 ≈ 8GB显存(RTX 4070可运行)
• 推荐工具:llama.cpp、Ollama、vLLM
• 量化方法:GPTQ、AWQ、GGUF
本章小结
LLM基于Transformer Decoder架构,通过Next Token Prediction预训练任务在海量文本上学习语言规律和知识。
BPE分词算法从字符级别开始,通过反复合并高频字符对构建词表,平衡了词表大小和语义完整性。
推理采样策略决定了生成文本的多样性和质量:Greedy确定性最强,Temperature和Top-p提供灵活的随机性控制。
模型压缩技术(量化、蒸馏、剪枝、LoRA)使大模型能在资源有限的设备上运行,是AI落地应用的关键。
Hugging Face的transformers库提供了便捷的API来加载预训练模型、进行文本生成和模型微调。
练习题
GPT系列模型使用的预训练任务是什么?
A. 掩码语言模型(MLM) B. Next Token Prediction(下一个词预测) C. 图像分类 D. 聚类分析
答案:B 。GPT系列使用Next Token Prediction作为预训练任务,即根据前面的词预测下一个词。
如果需要生成创意性强的文本,应该怎样设置采样参数?
A. temperature=0.1, do_sample=False B. temperature=0.9, top_p=0.95, do_sample=True C. temperature=0, top_k=1 D. 不使用任何采样策略
答案:B 。较高的temperature(0.8-1.0)和较高的top_p(0.95)会增加输出的多样性和创造性。
BPE分词算法的核心思想是什么?
A. 随机将文本切分为固定长度的片段 B. 从字符开始,反复合并最高频的字符对来构建词表 C. 使用词典匹配,遇到未知词就跳过 D. 将每个汉字作为一个Token
答案:B 。BPE(Byte Pair Encoding)从字符级别开始,通过迭代合并语料中最高频的相邻字符对来构建子词词表。
第十二章:推理与部署
学习目标
理解推理(Inference)的基本概念及其与训练的区别
掌握模型压缩三大技术:量化、剪枝、知识蒸馏
了解KV Cache、Flash Attention、批处理推理等推理优化技术
认识主流推理框架(vLLM、TensorRT-LLM、ONNX Runtime、llama.cpp)
能够使用llama.cpp本地运行模型和使用vLLM部署API服务
前置要求
建议先学习第七章:训练 ,了解模型训练的基本流程和概念,以便更好地理解推理与训练的区别和联系。
什么是推理(Inference)?
推理(Inference) 是指将训练好的模型用于实际预测的过程。训练阶段模型不断学习参数,而推理阶段则利用已学到的参数对新数据进行预测或生成。
简单理解
训练就像学生上课学习知识,推理就像考试时运用学到的知识来答题。训练需要大量时间和算力,推理则需要快速、高效地给出结果。
推理 vs 训练对比
维度
训练(Training)
推理(Inference)
目标
学习模型参数(权重和偏置)
使用已学参数进行预测/生成
数据
需要大量标注数据
只需要输入数据(无需标注)
计算量
非常大(前向+反向传播)
较小(仅前向传播)
频率
一次性(或定期更新)
频繁(每次用户请求)
关键指标
损失值、准确率
延迟(Latency)、吞吐量(Throughput)
典型耗时
数小时到数周
毫秒到秒级
推理的关键指标
指标
说明
单位
首Token延迟(TTFT)
从发送请求到生成第一个Token的时间
毫秒(ms)
Token生成速度
每秒生成的Token数量
tokens/s
吞吐量
单位时间内处理的请求数量
requests/s
显存占用
推理过程中GPU显存的使用量
GB
常见的部署方式
部署方式
说明
适用场景
云端部署
在云服务器(AWS、Azure、阿里云等)上部署模型
高并发、需要弹性伸缩的生产环境
本地部署
在本地电脑或服务器上运行模型
数据隐私要求高、离线使用场景
边缘部署
在手机、IoT设备等终端上运行模型
实时性要求高、带宽受限场景
API服务
通过HTTP API调用远程模型
快速集成、无需管理基础设施
模型压缩技术
1. 量化(Quantization)
量化 是将模型参数从高精度数值格式转换为低精度格式的过程,从而减少模型大小和计算量。
精度格式
位数
模型大小(相对)
精度损失
推理速度
适用场景
FP32
32位浮点
100%(基准)
无
基准
训练、高精度推理
FP16
16位浮点
~50%
极小
~2x加速
GPU推理(推荐)
INT8
8位整数
~25%
较小
~4x加速
生产部署、移动端
INT4
4位整数
~12.5%
中等
~8x加速
极端资源受限场景
案例:Llama-2-70B量化
Llama-2-70B原始模型(FP32)需要约 140GB 显存,几乎无法在单卡GPU上运行。通过INT4量化后,模型大小降至约 35-40GB ,可以在两张24GB的A100或四张RTX 4090上运行,使得大模型的本地部署成为可能。
2. 剪枝(Pruning)
剪枝 是移除模型中不重要的参数或神经元,使模型变得更轻量。就像修剪树枝一样,去掉不重要的部分,保留核心结构。
剪枝的主要方法:
非结构化剪枝 :移除单个权重参数(稀疏化),需要特殊硬件/软件支持才能加速
结构化剪枝 :移除整个通道或层,可以直接加速推理,兼容性好
迭代剪枝 :训练→剪枝→微调→再剪枝,逐步减少模型参数
3. 知识蒸馏(Knowledge Distillation)
知识蒸馏 是将大模型(教师模型)的知识转移到小模型(学生模型)的技术,让学生模型在保持较小体积的同时获得接近教师模型的性能。
教师模型与学生模型
教师模型(Teacher Model) :体积大、精度高、计算成本高的大模型,如GPT-4、Llama-2-70B。
学生模型(Student Model) :体积小、速度快、适合部署的小模型,如GPT-3.5、Llama-2-7B。
蒸馏过程:学生模型学习教师模型的输出分布(软标签),而不仅仅是真实标签(硬标签),从而学到更丰富的"知识"。
推理优化技术
KV Cache
KV Cache 是Transformer模型推理中的关键优化技术。在自回归生成中,每个新Token的生成都需要计算所有之前Token的注意力。KV Cache将之前计算过的Key和Value缓存起来,避免重复计算,大幅提升推理速度。
没有KV Cache时,生成第N个Token需要重新计算前N-1个Token的注意力,复杂度为 \(O(N^2)\)。使用KV Cache后,只需计算新Token与之前Token的注意力,复杂度降为 \(O(N)\)。
Flash Attention
Flash Attention 是一种通过优化GPU内存访问模式来加速注意力计算的算法。传统注意力计算需要将巨大的注意力矩阵存储在显存中,而Flash Attention通过分块计算(Tiling)技术,减少了显存读写次数,实现了:
计算速度提升 2-4x
显存占用降低 5-20x
支持更长的上下文序列
批处理推理(Batched Inference)
批处理推理 是将多个请求合并为一个批次同时处理的技术。在服务端部署时,通过动态批处理(Dynamic Batching)可以将等待中的请求打包,充分利用GPU并行计算能力,大幅提升吞吐量。
静态批处理 :固定批次大小,简单但可能浪费GPU资源
动态批处理 :根据当前请求量动态调整批次大小,效率更高
连续批处理(Continuous Batching) :请求到达即可加入批次,无需等待批次填满
推理框架对比
框架
开发者
核心特点
量化支持
适用场景
vLLM
UC Berkeley
PagedAttention、高效显存管理、高吞吐量
AWQ、GPTQ、FP8
在线服务、高并发API
TensorRT-LLM
NVIDIA
深度优化NVIDIA GPU、极致性能
INT8、INT4、FP8
NVIDIA GPU生产部署
ONNX Runtime
Microsoft
跨平台、跨硬件、生态丰富
INT8、INT4
多平台部署、边缘设备
llama.cpp
Georgi Gerganov
纯C/C++实现、CPU/GPU混合推理、极低门槛
GGUF(Q4/Q5/Q8)
本地运行、CPU推理
使用llama.cpp本地运行模型
llama.cpp是最流行的本地推理工具之一,支持在CPU和GPU上运行量化后的LLM模型。
# 1. 安装llama.cpp(需要先编译)
# git clone https://github.com/ggerganov/llama.cpp
# cd llama.cpp && make
# 2. 下载GGUF格式模型(以Qwen2.5-7B为例)
# 从Hugging Face下载:Qwen/Qwen2.5-7B-Instruct-GGUF
# 3. 命令行运行模型进行交互式对话
# ./llama-cli -m models/qwen2.5-7b-instruct-q4_k_m.gguf \
# -c 4096 \
# -n 512 \
# --temp 0.7 \
# --top-p 0.9 \
# -i -p "你好,请介绍一下你自己"
# 参数说明:
# -m : 模型文件路径
# -c : 上下文窗口大小(token数)
# -n : 最大生成token数
# --temp : 温度参数(0-2,越高越随机)
# --top-p : 核采样概率阈值
# -i : 交互模式
# -p : 初始提示词
使用vLLM部署API服务
vLLM可以快速将模型部署为兼容OpenAI API格式的HTTP服务。
# 1. 安装vLLM
# pip install vllm
# 2. 启动API服务(命令行)
# python -m vllm.entrypoints.openai.api_server \
# --model Qwen/Qwen2.5-7B-Instruct \
# --tensor-parallel-size 1 \
# --max-model-len 4096 \
# --port 8000
# 3. 客户端调用API服务
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # vLLM本地服务不需要API Key
)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[
{"role": "system", "content": "你是一个有帮助的AI助手。"},
{"role": "user", "content": "请用Python写一个快速排序算法。"}
],
temperature=0.7,
max_tokens=1024
)
print(response.choices[0].message.content)
本章小结
推理是使用训练好的模型对新数据进行预测/生成的过程,关键指标包括首Token延迟、Token生成速度和吞吐量。
模型压缩三大技术——量化(降低精度)、剪枝(移除冗余参数)、知识蒸馏(大模型教小模型)——是让大模型高效运行的核心手段。
KV Cache通过缓存注意力计算结果避免重复计算,Flash Attention通过优化内存访问加速注意力计算,批处理推理通过并行处理提升吞吐量。
主流推理框架各有优势:vLLM适合高并发在线服务,TensorRT-LLM适合NVIDIA GPU极致优化,llama.cpp适合本地CPU/GPU推理。
llama.cpp和vLLM使得大模型的本地运行和API服务部署变得简单高效,是AI应用落地的重要工具。
练习题
以下关于推理和训练的说法,哪项是正确的?
A. 推理需要反向传播来计算梯度 B. 训练只需要前向传播 C. 推理仅需前向传播,训练需要前向+反向传播 D. 推理和训练的计算量基本相同
答案:C 。推理只需要前向传播即可得到预测结果,而训练需要前向传播计算输出、反向传播计算梯度来更新参数。
将一个FP32的70B参数模型量化为INT4后,模型参数的显存需求大约变为多少?
A. 140GB → 70GB B. 140GB → 35GB C. 140GB → 17.5GB D. 140GB → 8.75GB
答案:C 。INT4是4位,相比FP32的32位,精度降低了8倍,因此模型参数的显存需求从140GB降至约17.5GB。
vLLM框架的核心创新技术是什么?
A. Flash Attention B. PagedAttention C. Knowledge Distillation D. Structured Pruning
答案:B 。vLLM的核心创新是PagedAttention技术,它借鉴了操作系统的虚拟内存分页机制来管理KV Cache的显存,实现了高效的显存利用和更高的吞吐量。
第十三章:RAG(检索增强生成)
学习目标
理解RAG(Retrieval-Augmented Generation)的核心原理与价值
掌握RAG系统的核心组件和工作流程
了解文档切分策略、Embedding模型选择和向量数据库对比
能够使用LangChain构建简单的RAG应用
了解RAG系统的评估方法
前置要求
建议先学习第十一章:大语言模型(LLM)详解 ,了解LLM的基本原理和使用方法,以便理解RAG如何增强LLM的能力。
什么是RAG?
RAG(Retrieval-Augmented Generation,检索增强生成) 是一种将信息检索与大语言模型生成相结合的技术。它先从外部知识库中检索相关信息,再将检索到的信息作为上下文提供给LLM,从而生成更准确、更有依据的回答。
为什么需要RAG?
LLM存在以下局限性,RAG可以有效解决:
知识过时 :LLM的训练数据有截止日期,无法获取最新信息
幻觉问题 :LLM可能"编造"不存在的信息,RAG通过提供真实文档来减少幻觉
缺乏私有知识 :LLM不了解企业内部文档、个人笔记等私有数据
可追溯性差 :纯LLM回答无法引用信息来源,RAG可以标注出处
RAG工作流程
1
文档导入
将PDF、网页、数据库等外部知识导入系统
2
文档切分
将长文档切分为较小的文本块(Chunk)
3
向量化
使用Embedding模型将文本块转换为向量表示
5
检索
用户提问时,将问题向量化并在数据库中检索相关文档
6
生成
将检索到的文档作为上下文,交给LLM生成回答
RAG的核心组件
组件
功能
常见选择
文档加载器
读取各种格式的文档(PDF、Word、网页等)
LangChain Loaders、LlamaIndex
文本切分器
将长文档切分为适合检索的文本块
RecursiveCharacterTextSplitter
Embedding模型
将文本转换为向量表示
OpenAI、Sentence-BERT、BGE
向量数据库
存储和检索向量
Chroma、Milvus、Pinecone
RAG的优势
减少幻觉 :基于真实文档生成回答,提高准确性
知识可更新 :只需更新向量数据库中的文档,无需重新训练模型
支持私有数据 :可以整合企业内部知识库
可追溯来源 :回答可以标注引用的文档来源
成本更低 :相比微调,RAG的实现成本更低、速度更快
文档切分策略
文档切分(Chunking)是RAG系统中至关重要的一步,切分策略直接影响检索质量。
切分策略
原理
优点
缺点
适用场景
按段落切分
以段落分隔符(换行、空行)为边界切分
保持语义完整性
段落长度不一,可能过长或过短
结构化文档(文章、报告)
按Token切分
按固定Token数量切分
长度均匀,便于管理
可能切断语义完整的句子
需要精确控制上下文长度
重叠窗口切分
固定长度切分,相邻块之间保留重叠部分
兼顾长度控制和语义完整性
存储冗余,检索结果可能重复
通用场景(推荐)
推荐使用重叠窗口切分 ,通常设置块大小为500-1000个Token,重叠比例为10%-20%。
Embedding模型选择
模型
开发者
维度
最大长度
多语言支持
特点
text-embedding-3-small
OpenAI
1536
8191
较好
效果好、API调用简单、需付费
all-MiniLM-L6-v2
Sentence-BERT
384
256
一般
轻量快速、适合英文
bge-large-zh-v1.5
BAAI (BGE)
1024
512
优秀(中文)
中文效果出色、开源免费
m3e-base
Moka (M3E)
768
512
良好(中文)
中文场景常用、开源免费
向量数据库详细对比
数据库
特点
适用场景
是否开源
Pinecone
全托管云服务、无需运维、自动扩展
快速上线、不想管理基础设施的团队
否(商业服务)
Weaviate
支持混合搜索(向量+关键词)、GraphQL API
需要同时支持向量和关键词搜索的场景
是
Milvus
分布式架构、支持十亿级向量、性能极高
大规模生产环境、海量数据检索
是
Chroma
轻量级、嵌入式、Python友好、上手极简
开发测试、小规模应用、快速原型
是
Qdrant
Rust编写、高性能、支持过滤、API丰富
高性能需求、需要复杂过滤条件
是
使用LangChain构建简单RAG
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA
# 1. 加载文档
loader = TextLoader("knowledge_base.txt", encoding="utf-8")
documents = loader.load()
# 2. 切分文档
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块最大500个字符
chunk_overlap=50, # 块之间重叠50个字符
separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
chunks = text_splitter.split_documents(documents)
print(f"文档被切分为 {len(chunks)} 个文本块")
# 3. 初始化Embedding模型
embeddings = HuggingFaceEmbeddings(
model_name="BAAI/bge-large-zh-v1.5" # 中文Embedding模型
)
# 4. 创建向量数据库
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db" # 持久化存储目录
)
# 5. 创建检索器
retriever = vectorstore.as_retriever(
search_kwargs={"k": 3} # 检索最相关的3个文本块
)
# 6. 初始化LLM
llm = Ollama(model="qwen2.5:7b") # 使用本地Ollama运行
# 7. 构建RAG链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 将所有检索结果拼接到一起
retriever=retriever,
return_source_documents=True
)
# 8. 提问
question = "什么是机器学习?"
result = qa_chain({"query": question})
print(f"问题:{question}")
print(f"回答:{result['result']}")
print(f"引用来源:{[doc.metadata for doc in result['source_documents']]}")
RAG评估方法
评估RAG系统的质量需要从检索和生成两个维度进行:
评估维度
指标
说明
检索质量
检索准确率(Precision@K)
检索返回的K个文档中,有多少是真正相关的
检索质量
检索召回率(Recall@K)
所有相关文档中,有多少被成功检索到
生成质量
回答相关性
生成的回答是否与问题相关
生成质量
回答忠实度(Faithfulness)
回答是否基于检索到的文档,而非编造
整体质量
端到端准确率
最终回答的正确性和完整性
常用评估框架:RAGAS (RAG Assessment)是一个专门用于评估RAG系统的开源框架,提供上述指标的自动化计算。
本章小结
RAG通过"检索+生成"的范式,将外部知识库与大语言模型结合,有效解决了LLM的知识过时、幻觉和私有数据缺失等问题。
RAG的核心流程包括:文档导入→切分→向量化→存储索引→检索→生成,每个环节都有多种策略和工具可选。
文档切分推荐使用重叠窗口策略(500-1000 Token,10%-20%重叠),Embedding模型中文场景推荐BGE或M3E。
向量数据库选择需考虑规模和场景:Chroma适合开发测试,Milvus适合大规模生产,Pinecone适合不想运维的团队。
RAG评估需从检索质量(准确率、召回率)和生成质量(相关性、忠实度)两个维度综合考量。
练习题
RAG系统的主要目的是什么?
A. 训练更大的语言模型 B. 让LLM能够利用外部知识库来增强回答 C. 替代LLM进行文本生成 D. 加速模型的训练过程
答案:B 。RAG的核心目的是通过检索外部知识来增强LLM的生成能力,使回答更加准确、有依据。
在RAG系统中,文档切分时使用"重叠窗口"策略的主要好处是什么?
A. 减少存储空间 B. 避免在切分边界处丢失上下文信息 C. 加快检索速度 D. 减少Embedding的计算量
答案:B 。重叠窗口策略让相邻文本块之间保留部分重叠内容,确保即使关键信息恰好位于切分边界处,也不会被遗漏。
以下哪个向量数据库最适合快速原型开发和小规模应用?
A. Milvus B. Pinecone C. Chroma D. Qdrant
答案:C 。Chroma是轻量级、嵌入式、Python友好的向量数据库,非常适合开发测试和小规模应用场景。
第十四章:向量与Embedding
学习目标
理解标量和向量的基本概念
掌握Embedding的原理和作用
理解向量运算(加法、点积、余弦相似度)
能够使用Python计算向量相似度
了解Embedding可视化的基本方法
前置要求
建议先学习第二章:数学基础 ,了解基本的数学概念(如坐标系、距离等),有助于理解向量和向量运算。
标量(Scalar)
标量 是一个单独的数值,只有大小没有方向。
例子
温度 36.5 度、年龄 25 岁、体重 65 公斤——这些都是标量,因为它们只有一个数值,没有方向。
向量(Vector)
向量 是一组有序排列的数值,可以表示方向和大小。在AI中,向量是表示数据的核心方式。
例子
一个二维向量 \([3, 4]\) 可以表示平面上的一个点或方向;一个三维向量 \([1, 2, 3]\) 可以表示空间中的一个位置。在AI中,一个768维的向量可以表示一个词或一句话的语义。
Embedding——向量的AI应用
Embedding(嵌入/向量化) 是将文字、图片等非数值数据转换为数值向量的过程。通过Embedding,AI可以将语义相似的内容映射到向量空间中相近的位置。
为什么用向量表示数据?
计算机只能处理数字,而现实世界的数据(文字、图片、音频)不是数字。Embedding将这些数据转换为向量后,计算机就能通过数学运算来理解和比较它们的语义关系。例如,"国王"和"女王"的向量在空间中会很接近,因为它们的语义相似。
向量运算
运算
公式
含义
AI中的应用
向量加法
\([a_1, a_2] + [b_1, b_2] = [a_1+b_1, a_2+b_2]\)
两个向量的对应分量相加
合并语义信息
点积(Dot Product)
\(A \cdot B = a_1 b_1 + a_2 b_2 + \cdots\)
衡量两个向量的相似程度
注意力机制的核心计算
余弦相似度
\(\cos(\theta) = \frac{A \cdot B}{|A||B|}\)
衡量方向的相似性(不受长度影响)
文本相似度、推荐系统
常见的向量维度
模型/场景
向量维度
说明
Word2Vec
300
经典词向量模型
BERT
768
主流预训练语言模型
GPT系列
768 - 12288
随模型规模增大
OpenAI Embedding
1536 / 3072
text-embedding-3-small / large
余弦相似度详解
余弦相似度是衡量两个向量方向相似性的指标,取值范围为 \([-1, 1]\):
\(\cos(\theta) = 1\):两个向量方向完全相同(最相似)
\(\cos(\theta) = 0\):两个向量正交(无关)
\(\cos(\theta) = -1\):两个向量方向完全相反(最不相似)
数学公式:
\[
\cos(\theta) = \frac{A \cdot B}{|A| \times |B|} = \frac{\sum_{i=1}^{n} a_i \times b_i}{\sqrt{\sum_{i=1}^{n} a_i^2} \times \sqrt{\sum_{i=1}^{n} b_i^2}}
\]
其中 \(A \cdot B\) 是向量点积,\(|A|\) 和 \(|B|\) 是向量的模(长度)。
使用sentence-transformers计算相似度
from sentence_transformers import SentenceTransformer, util
# 加载预训练模型
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
# 定义文本
texts = [
"我喜欢吃苹果",
"我爱吃水果",
"今天天气很好",
"这辆车很快"
]
# 计算Embedding向量
embeddings = model.encode(texts)
# 计算余弦相似度
similarity_matrix = util.cos_sim(embeddings, embeddings)
# 打印相似度矩阵
for i in range(len(texts)):
for j in range(len(texts)):
if i < j: # 只打印上三角
score = similarity_matrix[i][j].item()
print(f"'{texts[i]}' vs '{texts[j]}': {score:.4f}")
# 输出示例:
# '我喜欢吃苹果' vs '我爱吃水果': 0.6532 (语义相近)
# '我喜欢吃苹果' vs '今天天气很好': 0.0231 (语义无关)
# '我喜欢吃苹果' vs '这辆车很快': -0.0512 (语义无关)
Embedding可视化
高维向量(如768维)无法直接可视化。常用的方法是通过降维技术 将高维向量映射到2D或3D空间中展示:
t-SNE (t-Distributed Stochastic Neighbor Embedding):非线性降维,擅长保持局部结构,适合可视化聚类
PCA (Principal Component Analysis):线性降维,速度快,适合初步探索
UMAP (Uniform Manifold Approximation and Projection):兼顾局部和全局结构,效果通常优于t-SNE
可视化效果
将大量文本的Embedding降维到2D后绘制散点图,你会看到:语义相似的文本(如关于"运动"的句子)会聚在一起形成簇,而语义不同的文本(如关于"科技"的句子)会分布在不同的区域。这种"语义空间"的可视化直观展示了Embedding如何捕捉语言含义。
本章小结
标量是单个数值,只有大小;向量是一组有序数值,可以表示方向和大小。在AI中,向量是表示数据的核心方式。
Embedding将文字、图片等非数值数据转换为数值向量,使计算机能够通过数学运算理解和比较语义关系。
余弦相似度 \(\cos(\theta) = \frac{A \cdot B}{|A||B|}\) 是衡量向量方向相似性的重要指标,广泛用于文本相似度计算和推荐系统。
sentence-transformers库提供了便捷的API来计算文本Embedding和相似度,是NLP开发中的常用工具。
通过t-SNE、PCA、UMAP等降维技术,可以将高维Embedding可视化到2D空间,直观展示语义聚类效果。
练习题
以下关于向量的说法,哪项是正确的?
A. 标量就是向量的一种特殊形式 B. 向量只有大小没有方向 C. 在AI中,向量可以用来表示文本的语义 D. 向量的维度越高,计算越简单
答案:C 。在AI中,Embedding将文本转换为高维向量,语义相似的文本在向量空间中距离较近。
余弦相似度的取值范围是什么?当两个向量方向完全相同时,余弦相似度是多少?
A. [0, 1],完全相同时为1 B. [-1, 1],完全相同时为1 C. [0, 1],完全相同时为0 D. [-1, 1],完全相同时为0
答案:B 。余弦相似度的取值范围是 \([-1, 1]\),方向完全相同为1,方向完全相反为-1,正交为0。
以下哪种降维技术最适合将高维Embedding可视化到2D空间?
A. One-Hot Encoding B. t-SNE C. Batch Normalization D. Dropout
答案:B 。t-SNE是一种非线性降维技术,擅长将高维数据映射到低维空间进行可视化,能很好地保持数据的局部聚类结构。
第十五章:AI智能体(Agent)
学习目标
理解AI智能体(Agent)的概念和核心能力
掌握Agent的工作流程和关键组件
理解ReAct模式和Function Calling机制
能够使用LangChain构建简单的Agent
了解Agent的评估维度
前置要求
建议先学习第十一章:大语言模型(LLM)详解 ,了解LLM的基本原理,因为Agent的核心"大脑"通常就是一个LLM。
什么是AI智能体(Agent)?
AI智能体(AI Agent) 是一种能够自主感知环境、做出决策并执行动作的AI系统。与普通LLM只能"对话"不同,Agent可以主动使用工具、调用API、规划任务,像一个"数字员工"一样完成复杂工作。
简单理解
普通LLM就像一个"被关在房间里只能说话的专家",而Agent就像一个"可以走出门、使用工具、与人协作的全能助手"。Agent = LLM + 工具 + 记忆 + 规划能力。
Agent的核心能力
Agent工作流程
Agent的关键组件
组件
功能
说明
LLM(大脑)
理解、推理、决策
Agent的核心,负责理解任务和制定计划
工具(Tools)
执行具体操作
如搜索、计算、API调用、文件操作等
记忆(Memory)
存储信息
短期记忆(对话历史)和长期记忆(知识库)
规划(Planning)
任务分解与调度
将复杂任务拆解为可执行的子任务序列
常见的Agent类型
ReAct Agent :基于推理(Reasoning)和行动(Acting)交替的Agent模式
Plan-and-Execute Agent :先制定完整计划,再逐步执行
Multi-Agent :多个Agent协作完成复杂任务
AutoGPT :高度自主的Agent,可以自行设定目标和子任务
常见Agent框架:LangChain Agents 、AutoGen 、CrewAI 、MetaGPT
ReAct模式详解
ReAct(Reasoning + Acting) 是一种让LLM交替进行"思考"和"行动"的Agent模式。LLM先推理下一步该做什么(Thought),然后执行具体操作(Action),再观察结果(Observation),如此循环直到任务完成。
ReAct循环流程
T
Thought(思考)
分析当前状态,决定下一步操作
O
Observation(观察)
获取工具返回的结果
ReAct示例
用户 :北京今天天气怎么样?需要带伞吗?
Thought 1 :用户想知道北京今天的天气和是否需要带伞。我需要先查询北京的天气信息。
Action 1 :调用天气查询工具,参数:城市="北京"
Observation 1 :北京今天:多云转小雨,气温18-25°C,降水概率70%
Thought 2 :天气显示有小雨,降水概率70%,建议带伞。
Action 2 :返回最终答案
Final Answer :北京今天多云转小雨,气温18-25°C,降水概率较高(70%),建议出门带伞。
Function Calling机制详解
Function Calling 是让LLM能够调用外部函数(工具)的机制。LLM本身只能生成文本,但通过Function Calling,它可以输出结构化的函数调用指令,由外部系统执行后返回结果。
Function Calling流程
3
LLM决策
LLM判断是否需要调用工具,输出函数名和参数
Function Calling示例:天气查询
工具定义 :
函数名:get_weather,参数:city(字符串,城市名称),返回:天气信息JSON
用户 :上海今天天气如何?
LLM输出 :调用 get_weather(city="上海")
系统执行 :返回 {"temp": 28, "condition": "晴", "humidity": 65}
LLM回答 :上海今天天气晴朗,气温28°C,湿度65%,适合外出活动。
使用LangChain构建简单Agent
from langchain_community.llms import Ollama
from langchain.agents import create_react_agent, AgentExecutor
from langchain.tools import tool
# 1. 定义工具
@tool
def search(query: str) -> str:
"""搜索互联网获取信息。输入:搜索关键词。"""
return f"搜索'{query}'的结果:这是模拟的搜索结果。"
@tool
def calculator(expression: str) -> str:
"""计算数学表达式。输入:数学表达式字符串。"""
try:
result = eval(expression)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{e}"
tools = [search, calculator]
# 2. 定义Agent提示词模板
prompt = """回答以下问题,你可以使用以下工具:
{tools}
工具名称:{tool_names}
请按照以下格式回答:
Thought: 我需要思考下一步做什么
Action: 工具名称
Action Input: 工具输入参数
Observation: 工具返回的结果(系统自动填充)
... (Thought/Action/Observation可以重复多次)
Thought: 我现在知道最终答案了
Final Answer: 最终答案
开始!
Question: {input}
Thought:{agent_scratchpad}"""
# 3. 创建Agent
llm = Ollama(model="qwen2.5:7b")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 4. 运行Agent
result = agent_executor.invoke({
"input": "2024年有多少天?请先搜索2024年是否是闰年,再计算。"
})
print(result["output"])
Agent评估维度
评估Agent的质量需要从多个维度综合考量:
评估维度
指标
说明
任务完成率
成功率
Agent正确完成任务的比例,是最核心的指标
工具调用准确率
正确调用次数/总调用次数
Agent选择正确工具和参数的能力
响应时间
平均耗时
从接收任务到返回结果的时间,影响用户体验
步骤效率
实际步骤数/最优步骤数
Agent是否用最少的步骤完成任务
错误恢复能力
从错误中恢复的比例
工具调用失败时,Agent能否调整策略继续执行
本章小结
AI Agent是能够自主感知、规划、执行和记忆的AI系统,核心公式为 Agent = LLM + 工具 + 记忆 + 规划。
ReAct模式通过Thought→Action→Observation的循环,让LLM能够交替推理和行动,是Agent最基础的工作模式。
Function Calling是LLM调用外部工具的标准机制,通过结构化的函数定义和调用,让LLM能够获取实时信息和执行操作。
LangChain提供了便捷的Agent构建框架,通过定义工具和提示词模板,可以快速搭建功能完整的Agent。
Agent评估需关注任务完成率、工具调用准确率、响应时间、步骤效率和错误恢复能力等多个维度。
练习题
ReAct模式中的三个核心步骤是什么?
A. Input → Process → Output B. Thought → Action → Observation C. Plan → Execute → Evaluate D. Encode → Decode → Translate
答案:B 。ReAct(Reasoning + Acting)的核心循环是:Thought(思考下一步)→ Action(执行操作)→ Observation(观察结果),如此反复直到任务完成。
Function Calling的主要作用是什么?
A. 让LLM生成更长的文本 B. 让LLM能够调用外部函数获取信息或执行操作 C. 让LLM的训练速度更快 D. 让LLM支持更多语言
答案:B 。Function Calling让LLM能够输出结构化的函数调用指令,由外部系统执行后返回结果,使LLM能够获取实时信息、执行计算等操作。
以下哪个不是Agent的核心组件?
A. LLM(大脑) B. 工具(Tools) C. 数据标注平台 D. 记忆(Memory)
答案:C 。Agent的核心组件包括LLM(大脑)、工具(执行操作)、记忆(存储信息)和规划(任务分解)。数据标注平台是训练阶段的工具,不是Agent的运行时组件。
第十六章:工具(Tools)与技能(Skills)
学习目标
理解工具(Tools)的类型和作用
掌握Function Calling的工作原理
理解技能(Skills)的概念和特点
区分工具与技能的关系
前置要求
建议先学习第十五章:AI智能体(Agent) ,了解Agent的基本概念,因为工具和技能是Agent执行任务的核心手段。
什么是工具(Tools)?
工具(Tools) 是Agent可以调用的外部功能模块,用于扩展Agent的能力边界。LLM本身只能处理文本,但通过工具,Agent可以搜索网络、执行计算、操作文件、调用API等。
为什么需要工具?
LLM有三大天然局限:知识有截止日期 (无法获取最新信息)、无法执行操作 (只能生成文本)、计算能力有限 (复杂计算容易出错)。工具弥补了这些不足,让Agent成为真正的"全能助手"。
常见工具类型
工具类型
功能
示例
搜索工具
搜索互联网获取信息
Google Search、Bing Search、DuckDuckGo
计算工具
执行数学计算
Python REPL、Wolfram Alpha、Calculator
文件工具
读写文件、管理目录
文件读写、PDF解析、Excel操作
API工具
调用外部服务API
天气API、地图API、数据库查询
代码工具
编写和执行代码
Python解释器、Shell命令
浏览器工具
浏览网页、提取信息
Web Browser、HTML Parser
Function Calling流程
3
LLM决策
LLM判断需要调用哪个工具,生成调用参数
什么是技能(Skills)?
技能(Skills) 是为Agent预配置的专业能力模块,是一组工具、知识和提示词的组合。如果说工具是"扳手、锤子"这样的单个工具,技能就是"修水管、修电路"这样的完整技能包。
类比理解
工具 就像厨师的"菜刀、锅、灶台"——是执行具体操作的基本工具。
技能 就像厨师的"炒菜技能、烘焙技能"——是完成特定任务的完整能力,包含了工具使用方法、经验和知识。
技能的特点
组合性 :一个技能通常包含多个工具的配合使用
专业性 :每个技能针对特定领域优化
可复用 :技能可以在不同Agent之间共享
可扩展 :可以不断添加新的技能来增强Agent能力
常见技能类型
技能类型
功能
包含的工具
搜索技能
搜索和整理信息
搜索引擎、网页解析、摘要生成
编程技能
编写和调试代码
代码编辑器、运行环境、调试工具
数据分析技能
处理和分析数据
数据处理、可视化、统计分析
文档处理技能
创建和编辑文档
文档读写、格式转换、摘要提取
图像处理技能
生成和处理图像
图像生成、编辑、OCR识别
技能 vs 工具
工具 是原子化的功能单元(如"搜索"),技能 是面向任务的组合方案(如"信息调研")。一个技能通常包含多个工具的使用策略和领域知识。工具回答"怎么做",技能回答"做什么"。
本章小结
工具(Tools)是Agent调用外部功能的基本单元,弥补了LLM在获取实时信息、执行操作和复杂计算方面的不足。
Function Calling是LLM调用工具的标准机制,通过工具注册→用户请求→LLM决策→执行返回→生成回答的流程实现。
技能(Skills)是工具、知识和提示词的组合,是面向特定任务的完整能力模块,比单个工具更高级、更专业。
工具是"扳手、锤子",技能是"修水管、修电路"——工具是原子化功能,技能是面向任务的组合方案。
练习题
以下哪项最适合作为Agent的"工具"而非"技能"?
A. 信息调研能力 B. Google搜索API C. 数据分析能力 D. 文档写作能力
答案:B 。Google搜索API是一个具体的、原子化的功能单元,属于"工具"。其他选项都是面向任务的组合能力,属于"技能"。
Function Calling流程的正确顺序是什么?
A. 用户请求→工具注册→LLM决策→执行与返回→生成回答 B. 工具注册→用户请求→LLM决策→执行与返回→生成回答 C. LLM决策→工具注册→用户请求→执行与返回→生成回答 D. 用户请求→LLM决策→工具注册→执行与返回→生成回答
答案:B 。Function Calling的正确流程是:先注册可用工具,然后接收用户请求,LLM根据工具描述决策调用哪个工具,系统执行后返回结果,LLM基于结果生成最终回答。
技能与工具的核心区别是什么?
A. 技能比工具更简单 B. 技能是工具、知识和提示词的组合,面向特定任务 C. 工具只能用于搜索,技能可以用于任何场景 D. 技能和工具是完全相同的概念
答案:B 。技能是面向特定任务的完整能力模块,包含多个工具的使用策略和领域知识;工具是原子化的功能单元。
第十七章:知识库与向量数据库
学习目标
理解知识库的类型和建设流程
掌握向量搜索的原理和优势
了解常见向量数据库的特点和适用场景
能够使用Chroma构建简单的向量数据库
前置要求
建议先学习第十四章:向量与Embedding ,了解向量、Embedding和相似度计算的基本概念。
什么是知识库?
知识库 是有组织地存储和管理知识的系统,为AI应用提供可靠的信息来源。在AI系统中,知识库是RAG、Agent等应用的基础设施。
为什么需要知识库?
LLM的知识来自训练数据,存在时效性差 (无法获取最新信息)、领域知识不足 (缺乏专业领域深度知识)、无法引用来源 (回答无法追溯出处)等问题。知识库为AI提供了可靠、可更新、可追溯的外部知识来源。
知识库的类型
类型
存储方式
检索方式
适用场景
结构化知识库
关系数据库(SQL)、知识图谱
精确查询(SQL、SPARQL)
需要精确查询的结构化数据
非结构化知识库
文档、网页、PDF
全文搜索、向量搜索
文档问答、知识检索
向量知识库
向量数据库
向量相似度搜索
RAG系统、语义搜索
混合知识库
多种存储方式组合
多路召回、融合排序
复杂企业级应用
知识库建设流程
向量数据库详解
向量数据库 是专门用于存储和检索高维向量的数据库。它通过向量相似度搜索(而非精确匹配)来找到语义相关的内容。
传统搜索 vs 向量搜索
维度
传统关键词搜索
向量语义搜索
匹配方式
精确关键词匹配
语义相似度匹配
理解能力
不理解语义,只看字面
理解语义,能匹配同义词
查询示例
"机器学习"只能匹配含"机器学习"的文档
"机器学习"也能匹配含"AI训练"、"模型训练"的文档
跨语言
不支持
多语言模型可支持
速度
极快(倒排索引)
快(近似最近邻算法)
向量搜索的优势
语义理解 :能匹配含义相近的内容,而非仅字面匹配
容错性强 :对拼写错误、表述方式变化不敏感
跨模态 :可以实现图文互搜(图片向量与文本向量在同一空间)
个性化 :可以结合用户偏好向量进行个性化推荐
常见向量数据库
Chroma :轻量级、Python友好、适合开发和小规模应用
Milvus :分布式、高性能、适合大规模生产环境
Pinecone :全托管云服务、无需运维
Weaviate :支持混合搜索(向量+关键词)
Qdrant :Rust编写、高性能、支持复杂过滤
FAISS :Meta开源的向量检索库(非完整数据库)
向量检索流程
1
向量化查询
将用户查询文本转换为Embedding向量
2
相似度计算
计算查询向量与数据库中所有向量的相似度
3
排序筛选
按相似度排序,返回Top-K个最相关的结果
使用Chroma构建向量数据库
import chromadb
from chromadb.utils import embedding_functions
# 1. 创建Chroma客户端
client = chromadb.PersistentClient(path="./my_chroma_db")
# 2. 初始化Embedding函数
embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction(
model_name="BAAI/bge-small-zh-v1.5"
)
# 3. 创建集合(相当于一张表)
collection = client.get_or_create_collection(
name="ai_knowledge_base",
embedding_function=embedding_fn,
metadata={"description": "AI学习笔记知识库"}
)
# 4. 添加文档
documents = [
"机器学习是人工智能的一个分支,通过数据训练模型来学习规律。",
"深度学习使用多层神经网络来学习数据的复杂表示。",
"自然语言处理(NLP)让计算机能够理解和生成人类语言。",
"计算机视觉让机器能够理解和处理图像和视频数据。",
"强化学习通过奖励和惩罚机制来训练智能体做出最优决策。"
]
collection.add(
documents=documents,
ids=["doc1", "doc2", "doc3", "doc4", "doc5"],
metadatas=[
{"category": "ML", "chapter": 4},
{"category": "DL", "chapter": 5},
{"category": "NLP", "chapter": 11},
{"category": "CV", "chapter": 9},
{"category": "RL", "chapter": 4}
]
)
print(f"已添加 {collection.count()} 条文档")
# 5. 向量搜索
results = collection.query(
query_texts=["如何让计算机理解人类语言?"],
n_results=3
)
print("\n搜索结果:")
for i, (doc, distance, metadata) in enumerate(zip(
results["documents"][0],
results["distances"][0],
results["metadatas"][0]
)):
print(f"\n[{i+1}] 相似度距离: {distance:.4f}")
print(f" 分类: {metadata['category']}")
print(f" 内容: {doc}")
# 6. 带条件过滤的搜索
filtered_results = collection.query(
query_texts=["学习方法"],
n_results=2,
where={"category": "ML"}
)
本章小结
知识库是有组织地存储和管理知识的系统,分为结构化、非结构化、向量和混合四种类型,是AI应用的重要基础设施。
向量数据库通过语义相似度搜索实现智能检索,相比传统关键词搜索,能理解语义、匹配同义词、容错性更强。
向量检索流程包括:向量化查询→相似度计算→排序筛选→返回结果,核心是Embedding模型和近似最近邻算法。
Chroma是轻量级向量数据库,Python API友好,适合快速构建原型和小规模应用;大规模生产环境推荐使用Milvus。
练习题
向量搜索相比传统关键词搜索的最大优势是什么?
A. 搜索速度更快 B. 能理解语义,匹配含义相近的内容 C. 占用存储空间更小 D. 不需要建立索引
答案:B 。向量搜索通过Embedding将文本转换为向量,通过向量相似度来匹配语义相关的内容,即使字面不完全相同也能找到相关结果。
以下哪个向量数据库最适合大规模生产环境?
A. Chroma B. FAISS C. Milvus D. 以上都不适合
答案:C 。Milvus是分布式架构的向量数据库,支持十亿级向量的高性能检索,最适合大规模生产环境。
向量检索的四个步骤中,第二步是什么?
A. 向量化查询 B. 相似度计算 C. 排序筛选 D. 返回结果
答案:B 。向量检索的四个步骤依次是:向量化查询→相似度计算→排序筛选→返回结果。
第十八章:上下文(Context)与记忆
学习目标
理解上下文窗口的概念和限制
掌握上下文的组成和管理策略
了解Agent记忆系统的类型和作用
能够计算上下文窗口的token消耗
前置要求
建议先学习第十一章:大语言模型(LLM)详解 ,了解LLM的基本原理和Token概念。
什么是上下文(Context)?
上下文(Context) 是指LLM在一次对话中能够"看到"的所有信息。它包括系统提示、用户消息、助手回复和历史对话等内容。上下文决定了LLM"知道什么"来回答当前问题。
上下文窗口(Context Window)
每个LLM都有一个上下文窗口大小限制 ,以Token数量衡量。超出窗口的信息会被"遗忘"。常见模型的上下文窗口:
GPT-4o :128K tokens
GPT-4o-mini :128K tokens
Claude 3.5 Sonnet :200K tokens
Qwen2.5-72B :128K tokens
GLM-4 :128K tokens
早期GPT-3.5 :4K / 16K tokens
上下文的组成
上下文管理策略
策略
说明
适用场景
滑动窗口
保留最近N轮对话,丢弃更早的
简单对话场景
摘要压缩
将早期对话摘要后保留,释放空间
长对话场景
选择性保留
根据相关性选择保留重要信息
信息密度高的对话
外部记忆
将信息存储到外部数据库,按需检索
Agent和复杂应用
Agent记忆系统
对于AI Agent来说,记忆系统比简单的对话历史更加复杂,需要支持不同类型和不同时效的记忆。
记忆类型
记忆类型
持续时间
存储位置
特点
短期记忆(工作记忆)
当前会话
上下文窗口
容量有限,会话结束即消失
长期记忆
跨会话持久
向量数据库/文件
容量大,可跨会话访问
情景记忆
特定事件
结构化存储
记录特定事件和经历
程序性记忆
永久
工具/技能配置
存储"如何做事"的知识
记忆的作用
保持连贯性 :让Agent记住之前的对话和决策,避免重复询问
积累经验 :从历史交互中学习,逐步提升任务完成质量
个性化 :记住用户偏好和习惯,提供个性化服务
协作支持 :在多Agent协作中共享信息和状态
记忆存储技术
向量数据库 :存储语义记忆,支持相似度检索(Chroma、Milvus)
关系数据库 :存储结构化信息(用户档案、任务记录)
键值存储 :存储简单的配置和状态(Redis)
文件系统 :存储长期文档和日志
上下文窗口计算示例
理解上下文窗口的token消耗对于优化LLM应用非常重要。以下是一个具体的计算示例:
Token计算示例
假设使用一个上下文窗口为 8K tokens 的模型:
系统提示词:约 200 tokens ("你是一个AI助手,擅长回答技术问题...")
用户当前消息:约 50 tokens ("请解释什么是Transformer架构")
历史对话(10轮):
每轮用户消息平均:~30 tokens
每轮助手回复平均:~150 tokens
10轮总计:10 x (30 + 150) = 1800 tokens
预留生成空间:1024 tokens (给模型生成回答留出空间)
总消耗 :200 + 50 + 1800 + 1024 = 3074 tokens
剩余空间 :8192 - 3074 = 5118 tokens
如果历史对话增加到50轮:50 x 180 = 9000 tokens ,就会超出8K窗口,需要使用滑动窗口或摘要策略。
import tiktoken
def count_tokens(text, model="gpt-4o-mini"):
"""计算文本的token数量"""
encoding = tiktoken.encoding_for_model(model)
return len(encoding.encode(text))
# 计算各部分token消耗
system_prompt = "你是一个专业的AI学习助手,擅长用简单易懂的语言解释复杂的技术概念。"
user_message = "请解释什么是Transformer架构?"
system_tokens = count_tokens(system_prompt)
user_tokens = count_tokens(user_message)
print(f"系统提示:{system_tokens} tokens")
print(f"用户消息:{user_tokens} tokens")
print(f"当前总消耗:{system_tokens + user_tokens} tokens")
# 模拟10轮历史对话
history_tokens = 10 * (30 + 150) # 每轮约180 tokens
reserved_for_output = 1024
total = system_tokens + user_tokens + history_tokens + reserved_for_output
print(f"含历史对话总消耗:{total} tokens")
print(f"8K窗口剩余:{8192 - total} tokens")
本章小结
上下文是LLM在一次对话中能"看到"的所有信息,上下文窗口大小以Token数量衡量,超出部分会被遗忘。
上下文由系统提示、用户消息、助手回复和历史对话组成,管理策略包括滑动窗口、摘要压缩、选择性保留和外部记忆。
Agent记忆系统分为短期记忆(当前会话)、长期记忆(跨会话持久)、情景记忆(特定事件)和程序性记忆(技能知识)四种类型。
合理计算和管理token消耗是优化LLM应用的关键,需要为模型输出预留足够空间,同时控制历史对话的长度。
练习题
以下哪种上下文管理策略最适合长对话场景?
A. 滑动窗口 B. 摘要压缩 C. 不做任何管理 D. 直接清空历史
答案:B 。摘要压缩将早期对话内容压缩为简短摘要,既保留了重要信息,又释放了上下文窗口空间,最适合长对话场景。
Agent的"长期记忆"通常存储在哪里?
A. 上下文窗口中 B. 向量数据库或文件中 C. LLM的参数中 D. 临时变量中
答案:B 。长期记忆需要跨会话持久保存,通常存储在向量数据库、关系数据库或文件系统中,而不是会话级的上下文窗口中。
如果一个模型的上下文窗口是8K tokens,系统提示用了200 tokens,预留输出1024 tokens,那么历史对话最多可以使用多少tokens?
A. 8192 tokens B. 1024 tokens C. 6968 tokens D. 7168 tokens
答案:C 。可用空间 = 8192 - 200(系统提示)- 1024(预留输出)= 6968 tokens。
第十九章:高级提示技术
学习目标
掌握思维链(Chain of Thought)提示技术
理解Zero-shot和Few-shot提示的区别和适用场景
掌握ReAct提示模式
了解更多实用的Prompt技巧和评估方法
前置要求
建议先学习第十一章:大语言模型(LLM)详解 ,了解LLM的基本原理和Prompt概念。
思维链(Chain of Thought, CoT)
思维链(Chain of Thought) 是一种通过引导LLM逐步推理来提升复杂问题回答质量的提示技术。核心思想是:让模型"展示思考过程",而不是直接给出答案。
基本方法
在提示词中添加"请一步一步思考"或"让我们逐步分析"等引导语,促使模型在给出最终答案前先展示推理过程。这种方法特别适用于数学计算、逻辑推理和多步骤问题。
CoT效果流程
CoT的典型应用
数学问题 :分步计算,减少计算错误
逻辑推理 :逐步分析条件,避免跳跃性错误
多步决策 :分解复杂决策为多个判断步骤
代码生成 :先分析需求,再设计逻辑,最后编写代码
文本分析 :逐步提取关键信息,综合得出结论
Zero-shot vs Few-shot
Zero-shot提示
Zero-shot :不给任何示例,直接让模型完成任务。依赖模型预训练知识。
示例:将以下英文翻译为中文:Hello World
Few-shot提示
Few-shot :在提示中给出几个示例,让模型学习输入-输出模式后再完成任务。
示例:
正面 → 积极 负面 → 消极 一般 → 中性 这个产品非常好 → ?
模型通过示例学会了"情感分类"的模式,输出"积极"。
何时使用Few-shot?
场景
推荐方式
原因
常见任务(翻译、摘要)
Zero-shot
模型已有丰富知识
特定格式输出
Few-shot
需要示例来明确格式要求
领域专业任务
Few-shot
示例帮助模型理解领域术语
分类/标注任务
Few-shot
示例明确分类标准
创意写作
Zero-shot
过多示例可能限制创造性
ReAct提示
ReAct提示 是将推理(Reasoning)和行动(Acting)结合的提示模式,让LLM在思考过程中交替进行推理和工具调用。
ReAct示例
问题 :清华大学和北京大学哪个建校更早?
Thought 1 :我需要查询清华大学的建校时间。
Action 1 :搜索"清华大学建校时间"
Observation 1 :清华大学建于1911年
Thought 2 :我还需要查询北京大学的建校时间。
Action 2 :搜索"北京大学建校时间"
Observation 2 :北京大学建于1898年
Thought 3 :北京大学(1898年)比清华大学(1911年)建校更早。
Answer :北京大学建校更早,建于1898年,比清华大学的1911年早了13年。
更多Prompt技巧
1. 角色设定(Role Prompting)
通过给LLM设定特定角色,可以显著提升回答的专业性和针对性。
# 角色设定示例
prompt = """
你是一位有20年经验的资深Python开发者和技术导师。
你的教学风格是:用简单的比喻解释复杂概念,提供可运行的代码示例,
并指出初学者常见的陷阱。
请解释什么是装饰器(Decorator)。
"""
2. 输出格式约束
明确指定输出格式,确保LLM返回符合预期的结构化结果。
# 格式约束示例
prompt = """
请分析以下文本的情感,并以JSON格式返回结果:
{
"sentiment": "正面/负面/中性",
"confidence": 0.0-1.0,
"keywords": ["关键词1", "关键词2"],
"reason": "判断理由"
}
文本:这款手机的拍照效果非常出色,电池续航也很给力!
"""
3. 分解任务(Task Decomposition)
将复杂任务分解为多个简单子任务,逐步完成。
# 任务分解示例
prompt = """
请按以下步骤完成任务:
步骤1:从文本中提取所有人名
步骤2:分析每个人物的关系
步骤3:生成人物关系图描述
步骤4:总结主要人物和核心冲突
文本:...
"""
4. 提供上下文(Context Provision)
在提示中提供充分的背景信息,帮助LLM给出更准确的回答。
# 提供上下文示例
prompt = """
背景信息:我们是一家电商公司,主要销售3C数码产品。
目标用户:18-35岁的年轻消费者。
当前问题:最近一个月,网站流量增长了30%,但转化率下降了15%。
请基于以上背景信息,分析可能的原因并给出改进建议。
"""
Prompt评估方法
评估Prompt质量需要从多个维度考量:
评估维度
说明
评估方法
一致性(Consistency)
相同Prompt多次运行,结果是否稳定一致
多次运行统计结果分布
相关性(Relevance)
输出是否与用户意图相关
人工评估或使用LLM-as-Judge
完整性(Completeness)
输出是否完整回答了所有问题
检查清单逐项验证
准确性(Accuracy)
输出内容是否事实正确
与标准答案对比
格式合规
输出是否符合要求的格式
格式解析验证
本章小结
思维链(CoT)通过引导LLM逐步推理来提升复杂问题的回答质量,特别适用于数学、逻辑推理和多步骤任务。
Zero-shot直接让模型凭预训练知识完成任务,Few-shot通过提供示例帮助模型理解任务模式。格式敏感和领域专业任务推荐Few-shot。
ReAct提示将推理和行动结合,让LLM在思考过程中交替进行推理和工具调用,适合需要获取外部信息的任务。
高级Prompt技巧包括角色设定、输出格式约束、任务分解和提供上下文,可以显著提升LLM输出的质量和可控性。
Prompt评估需关注一致性、相关性、完整性、准确性和格式合规等多个维度。
练习题
思维链(CoT)提示的核心思想是什么?
A. 让模型一次性给出答案 B. 让模型展示逐步推理过程后再给出答案 C. 让模型调用更多工具 D. 让模型使用更长的上下文
答案:B 。CoT的核心思想是引导LLM"展示思考过程",通过逐步推理来提升复杂问题的回答质量,减少跳跃性错误。
以下哪种场景最适合使用Few-shot提示?
A. 将"你好"翻译为英文 B. 按特定格式提取文档中的实体 C. 写一首关于春天的诗 D. 总结一篇文章的主要观点
答案:B 。Few-shot提示适合需要明确输出格式的任务,如实体提取、分类标注等。翻译和写诗等常见任务用Zero-shot即可。
以下哪个不是Prompt评估的维度?
A. 一致性 B. 相关性 C. 模型参数量 D. 完整性
答案:C 。Prompt评估的维度包括一致性、相关性、完整性、准确性和格式合规。模型参数量是模型本身的属性,不是Prompt质量的评估维度。
第二十章:数据——AI的燃料
学习目标
理解数据集的划分原则和重要性
掌握数据标注的类型、流程和挑战
了解数据清洗的常见问题和处理方法
掌握数据增强的概念和方法
能够使用Python进行数据集划分和数据增强
前置要求
建议先学习第四章:机器学习概述 ,了解机器学习的基本概念和工作流程。
数据集划分
数据集 是用于训练和评估AI模型的数据集合。在机器学习中,数据集通常需要划分为不同的子集,以确保模型能够被公正地评估。
子集
用途
典型比例
说明
训练集(Training Set)
训练模型参数
70%-80%
模型从中学习规律和模式
验证集(Validation Set)
调参和模型选择
10%-15%
用于选择超参数、防止过拟合
测试集(Test Set)
最终评估模型性能
10%-15%
模型从未见过的数据,评估泛化能力
数据划分的重要原则
测试集绝不能参与训练 :否则评估结果会过于乐观,无法反映真实性能
划分前先打乱数据 :避免数据有序排列导致的偏差
保持类别比例 :使用分层抽样确保各子集的类别分布一致
数据不能泄露 :确保测试集中的信息不会以任何方式泄露到训练过程中
使用scikit-learn划分数据集
from sklearn.model_selection import train_test_split
import numpy as np
# 模拟数据:1000个样本,每个样本有10个特征
X = np.random.rand(1000, 10) # 特征矩阵
y = np.random.randint(0, 3, size=1000) # 标签(3个类别)
# 第一次划分:分离出测试集(20%)
X_train_val, X_test, y_train_val, y_test = train_test_split(
X, y,
test_size=0.2, # 测试集占20%
random_state=42, # 随机种子,确保可复现
stratify=y # 分层抽样,保持类别比例
)
# 第二次划分:从训练+验证中分离出验证集(占原始数据的15%)
X_train, X_val, y_train, y_val = train_test_split(
X_train_val, y_train_val,
test_size=0.1875, # 0.8 * 0.1875 ≈ 0.15(占原始数据)
random_state=42,
stratify=y_train_val
)
print(f"训练集:{X_train.shape[0]} 样本(80%)")
print(f"验证集:{X_val.shape[0]} 样本(15%)")
print(f"测试集:{X_test.shape[0]} 样本(20%)")
# 验证类别分布
for name, labels in [("训练集", y_train), ("验证集", y_val), ("测试集", y_test)]:
unique, counts = np.unique(labels, return_counts=True)
print(f"\n{name}类别分布:")
for cls, count in zip(unique, counts):
print(f" 类别{cls}: {count} ({count/len(labels)*100:.1f}%)")
数据标注
数据标注 是为原始数据添加标签(标注信息)的过程,是监督学习的基础。标注质量直接影响模型性能。
常见标注类型
标注类型
说明
示例
分类标注
为数据分配类别标签
垃圾邮件/正常邮件、猫/狗/鸟
目标检测标注
标注图像中物体的位置和类别
用边界框标注图像中的人、车
序列标注
为序列数据中的每个元素标注
命名实体识别(人名、地名、机构名)
情感标注
标注文本的情感倾向
正面/负面/中性
偏好标注(RLHF)
标注多个回答的质量排序
回答A优于回答B
数据标注流程
数据标注的挑战
成本高 :大规模高质量标注需要大量人力和时间
主观性 :某些任务(如情感分析)标注者可能有不同判断
一致性 :不同标注者之间、同一标注者不同时间的标注可能不一致
边界模糊 :很多真实数据的标签并不明确
数据清洗
数据清洗 是识别并修正数据集中错误、不一致和不完整数据的过程。高质量的数据是训练高质量模型的前提。
常见数据问题及处理方法
问题类型
说明
处理方法
缺失值
数据中存在空值或缺失字段
删除、填充(均值/中位数/插值)
重复数据
存在完全相同或高度相似的数据
去重(保留一条或合并)
异常值
明显偏离正常范围的数据
删除、修正、单独分析
格式不一致
同一字段的数据格式不统一
统一格式、标准化处理
噪声数据
包含错误或无意义的数据
过滤、修正
标注错误
人工标注的标签有误
重新审核、修正标签
数据增强
数据增强(Data Augmentation) 是通过各种技术手段扩充数据集的方法,在不收集新数据的情况下增加数据量和多样性,提升模型的泛化能力。
图像数据增强示例
对一张猫的图片,可以通过以下方式生成多张"不同"的图片:
旋转 :将图片旋转一定角度
翻转 :水平或垂直翻转
裁剪 :随机裁剪不同区域
颜色变换 :调整亮度、对比度、饱和度
添加噪声 :添加随机噪声
为什么需要数据增强?
数据不足 :收集和标注数据成本高,增强可以低成本扩充数据集。
防止过拟合 :更多样的训练数据帮助模型学习更鲁棒的特征,而不是记忆特定样本。
提升泛化 :增强后的数据模拟了真实世界中的各种变化,提升模型在新数据上的表现。
数据增强Python代码示例
# 使用albumentations库进行图像数据增强
# 安装:pip install albumentations
import albumentations as A
import cv2
# 定义增强管道
transform = A.Compose([
A.RandomRotate90(p=0.5), # 随机旋转90度(50%概率)
A.HorizontalFlip(p=0.5), # 水平翻转(50%概率)
A.VerticalFlip(p=0.3), # 垂直翻转(30%概率)
A.RandomBrightnessContrast(
brightness_limit=0.2, contrast_limit=0.2, p=0.8
),
A.GaussNoise(p=0.3), # 添加高斯噪声(30%概率)
A.RandomCrop(height=224, width=224, p=1.0),
])
# 读取图片
image = cv2.imread("cat.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 生成增强后的图片
for i in range(5):
augmented = transform(image=image)["image"]
cv2.imwrite(f"cat_augmented_{i}.jpg",
cv2.cvtColor(augmented, cv2.COLOR_RGB2BGR))
# --- 文本数据增强方法 ---
# 推荐库:nlpaug (pip install nlpaug)
# 常用方法:
# 1. 同义词替换:将部分词替换为同义词
# 2. 随机插入:在句子中随机插入词
# 3. 随机交换:随机交换句子中的词
# 4. 随机删除:随机删除部分词
本章小结
数据集通常划分为训练集(70%-80%)、验证集(10%-15%)和测试集(10%-15%),测试集绝不能参与训练过程。
数据标注是监督学习的基础,常见类型包括分类标注、目标检测标注、序列标注、情感标注和偏好标注(RLHF)。
数据清洗处理缺失值、重复数据、异常值、格式不一致、噪声数据和标注错误等问题,是保证模型质量的关键步骤。
数据增强通过旋转、翻转、裁剪、颜色变换等技术扩充数据集,能有效防止过拟合、提升模型泛化能力。
scikit-learn的train_test_split和albumentations库分别提供了便捷的数据集划分和图像数据增强工具。
练习题
数据集划分中,验证集的主要用途是什么?
A. 训练模型参数 B. 最终评估模型性能 C. 调整超参数和选择模型 D. 数据清洗
答案:C 。验证集用于调整超参数、选择模型架构和进行早停判断,防止模型在训练集上过拟合。最终性能评估使用测试集。
以下哪种数据增强方法最适合文本数据?
A. 随机旋转 B. 颜色变换 C. 同义词替换 D. 随机裁剪
答案:C 。同义词替换是文本数据增强的常用方法,通过将部分词语替换为同义词来生成语义相似但表述不同的新文本。
为什么数据增强能帮助防止过拟合?
A. 增强后的数据更干净 B. 增加了数据的多样性,使模型学到更鲁棒的特征 C. 减少了训练数据量 D. 增强后的数据更容易学习
答案:B 。数据增强通过生成多样化的训练样本,使模型无法记忆特定样本的细节,被迫学习更通用、更鲁棒的特征表示。
第二十一章:AI的局限与挑战
学习目标
理解AI幻觉问题的类型和减少方法
掌握AI对齐的概念和RLHF方法
了解多模态AI的优势和发展
建立对AI能力的客观认知
前置要求
建议先学习第十一章:大语言模型(LLM)详解 ,了解LLM的基本原理,以便理解AI的局限性和挑战。
幻觉问题(Hallucination)
AI幻觉 是指AI模型生成看似合理但实际上不正确、不存在或无根据的内容。这是当前LLM最突出的局限性之一。
幻觉的类型
类型
说明
示例
事实性幻觉
编造不存在的事实或数据
"爱因斯坦在2020年获得了诺贝尔奖"(事实错误)
引用幻觉
虚构不存在的论文、书籍或引用
"根据《人工智能的未来》第3章..."(该书不存在)
逻辑幻觉
推理过程看似合理但结论错误
数学计算步骤正确但最终答案错误
能力幻觉
声称自己能做实际上做不到的事
"我已经帮你发送了邮件"(实际没有发送能力)
减少幻觉的方法
使用RAG :通过检索真实文档来提供事实依据,减少编造
降低Temperature :较低的Temperature让输出更确定性,减少随机性带来的错误
明确约束 :在Prompt中要求"如果不确定,请说不知道"
交叉验证 :对关键信息进行多源验证
提供上下文 :在Prompt中提供相关背景信息和事实
安全建议
在使用AI生成的内容时,务必:
对关键事实进行人工核实
不要将AI输出直接用于医疗、法律等高风险领域
了解AI的能力边界,合理设置期望
建立AI输出的审核和纠错机制
AI对齐(Alignment)
AI对齐 是指确保AI系统的行为符合人类价值观和意图的过程。随着AI能力越来越强,确保AI"做正确的事"变得至关重要。
对齐的四个维度
维度
说明
示例
有用性(Helpful)
AI能有效地帮助用户完成任务
准确回答问题、提供有用的建议
诚实性(Honest)
AI不编造信息,承认不确定性
不知道时说"我不确定",不虚构引用
无害性(Harmless)
AI不生成有害、危险的内容
拒绝生成暴力、歧视性内容
公平性(Fair)
AI不偏袒特定群体,避免偏见
对不同性别、种族的用户一视同仁
RLHF(基于人类反馈的强化学习)
RLHF(Reinforcement Learning from Human Feedback) 是目前最主流的AI对齐方法,通过人类反馈来训练AI更好地符合人类期望。
RLHF的四步流程
2
监督微调(SFT)
用人类标注的高质量问答数据微调模型
3
训练奖励模型
用人类对多个回答的排序数据训练奖励模型
为什么需要人类反馈?
纯数据驱动的训练无法捕捉人类价值观中的细微差别。例如,"如何制作蛋糕"和"如何制作炸弹"在技术层面都是"如何做"的问题,但人类对两者的期望完全不同。人类反馈帮助AI理解这些价值观差异。
多模态AI
多模态AI 是指能够同时处理和理解多种类型数据(文本、图像、音频、视频等)的AI系统。
多模态AI的优势
更全面的理解 :像人类一样,同时利用视觉、听觉、文本信息来理解世界
更强的交互 :支持图片+文字、语音+视频等多种交互方式
更广泛的应用 :覆盖更多场景,如自动驾驶、医疗影像分析、智能客服
常见多模态模型
模型
开发者
支持模态
核心能力
GPT-4o
OpenAI
文本、图像、音频
多模态对话、图像理解、语音交互
Claude 3.5
Anthropic
文本、图像
视觉理解、文档分析、代码生成
Gemini
Google
文本、图像、音频、视频
跨模态推理、长视频理解
Qwen-VL
阿里巴巴
文本、图像
中文视觉理解、OCR、图表分析
本章小结
AI幻觉是LLM生成看似合理但实际不正确内容的现象,分为事实性、引用、逻辑和能力四种类型,可通过RAG、降低Temperature、明确约束等方法减少。
AI对齐确保AI行为符合人类价值观,涵盖有用性、诚实性、无害性和公平性四个维度,RLHF是目前最主流的对齐方法。
RLHF通过预训练→监督微调→训练奖励模型→强化学习优化四步流程,让AI更好地理解和满足人类期望。
多模态AI能同时处理文本、图像、音频等多种数据类型,代表了大模型发展的下一个重要方向。
使用AI时需保持审慎态度,对关键信息进行人工核实,了解AI的能力边界。
练习题
以下哪种方法最能有效减少AI幻觉?
A. 增大模型参数 B. 使用RAG技术 C. 提高Temperature D. 增加训练数据量
答案:B 。RAG通过检索真实文档为LLM提供事实依据,是最直接有效的减少幻觉的方法。提高Temperature反而会增加输出的随机性和幻觉风险。
RLHF中的"奖励模型"的作用是什么?
A. 给用户发放奖励 B. 学习人类的偏好,评估AI回答的质量 C. 加速模型训练 D. 减少模型参数
答案:B 。奖励模型通过学习人类对多个回答的排序偏好,能够自动评估AI回答的质量,为后续的强化学习优化提供奖励信号。
以下哪个是多模态AI的优势?
A. 只能处理文本数据 B. 训练成本更低 C. 能同时理解和处理多种类型的数据 D. 不需要预训练
答案:C 。多模态AI的核心优势是能同时处理文本、图像、音频、视频等多种类型的数据,实现更全面的理解和更丰富的交互。
第二十二章:常用AI工具与平台
学习目标
了解主流AI助手的特点和适用场景
了解图像生成工具的能力和选择
掌握Hugging Face平台的使用方法
了解开源vs闭源模型的选择考量
了解AI编程工具的对比
前置要求
无特殊前置要求,本章为独立章节,适合所有读者。
主流AI助手
AI助手
开发者
核心特点
适用场景
ChatGPT
OpenAI
功能全面、插件生态丰富、GPT-4o多模态
通用对话、写作、编程、分析
Claude
Anthropic
长上下文(200K)、安全对齐好、分析能力强
长文档分析、代码审查、学术研究
文心一言
百度
中文优化好、集成百度搜索
中文场景、知识问答
通义千问
阿里巴巴
开源版本可用、多模态支持
中文场景、企业应用
图像生成工具
工具
开发者
核心特点
适用场景
Midjourney
Midjourney
艺术风格强、画面精美
艺术创作、概念设计
DALL-E 3
OpenAI
与ChatGPT集成、文字理解准确
精确控制生成内容
Stable Diffusion
Stability AI
开源、可本地部署、高度可定制
批量生成、定制模型
Hugging Face
Hugging Face 是AI领域最大的开源社区和模型托管平台,被称为"AI领域的GitHub"。
Hugging Face提供的内容
模型(Models) :数十万个预训练模型,涵盖NLP、CV、音频等多个领域
数据集(Datasets) :数千个公开数据集,方便下载和使用
Spaces :在线演示空间,可以快速部署和展示AI应用
Transformers库 :最流行的深度学习库之一,提供统一的API加载各种模型
使用Hugging Face的基本步骤
1
注册账号
在huggingface.co注册免费账号
3
安装依赖
安装transformers和torch库
Python代码示例
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
import torch
# 方法1:使用pipeline快速使用(最简单)
classifier = pipeline("sentiment-analysis", model="uer/roberta-base-finetuned-jd-binary-chinese")
result = classifier("这个产品质量非常好,推荐购买!")
print(result) # [{'label': 'positive', 'score': 0.98}]
# 方法2:加载具体模型(更灵活)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2.5-7B-Instruct",
torch_dtype=torch.float16,
device_map="auto"
)
messages = [
{"role": "system", "content": "你是一个有帮助的AI助手。"},
{"role": "user", "content": "用一句话介绍什么是机器学习。"}
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer([text], return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=100)
response = outputs[0][inputs.input_ids.shape[-1]:]
print(tokenizer.decode(response, skip_special_tokens=True))
开源 vs 闭源模型
维度
开源模型
闭源模型
代表
Llama、Qwen、GLM、Mistral
GPT-4、Claude、Gemini
可访问性
可下载权重、查看源码、自由修改
仅通过API调用,无法查看内部
成本
需自行部署和维护硬件
按使用量付费,无需管理基础设施
数据隐私
数据不出本地,完全可控
数据需发送到第三方服务器
定制化
可自由微调、修改、蒸馏
功能由服务商决定
性能上限
略低于顶级闭源模型
通常性能最强
如何选择?
选闭源 :追求最强性能、不想管理基础设施、快速验证想法。
选开源 :数据隐私要求高、需要深度定制、长期成本控制、学习研究目的。
主流开源模型
Llama 3 (Meta):性能优异,社区活跃
Qwen2.5 (阿里巴巴):中文能力强,多模态支持
GLM-4 (智谱AI):中文优化,长上下文
Mistral (Mistral AI):欧洲代表,高效架构
DeepSeek (深度求索):推理能力强,性价比高
AI编程工具对比
工具
开发者
核心特点
适用场景
Claude Code
Anthropic
终端AI编程助手、理解整个代码库、自主执行复杂任务
全栈开发、代码重构、Bug修复
GitHub Copilot
GitHub/Microsoft
IDE集成、实时代码补全、多模型支持
日常编码、代码补全、快速开发
Cursor
Cursor Inc.
AI原生IDE、代码库理解、多文件编辑
项目级开发、代码重构
Windsurf
Codeium
AI IDE、Cascade多步推理、免费额度
日常开发、学习编程
本章小结
主流AI助手各有特色:ChatGPT功能全面,Claude擅长长文档分析,国产模型在中文场景表现优秀。
Hugging Face是AI领域的核心平台,提供模型、数据集、Spaces和Transformers库,是AI开发者必备工具。
开源模型(Llama、Qwen等)提供数据隐私和定制化优势,闭源模型(GPT-4、Claude等)提供最强性能和便捷性。
AI编程工具(Claude Code、Copilot、Cursor、Windsurf)正在改变开发方式,选择需考虑集成方式、代码库理解能力和使用成本。
练习题
Hugging Face平台主要提供哪些内容?
A. 仅提供模型下载 B. 模型、数据集、Spaces和Transformers库 C. 仅提供云计算服务 D. 仅提供数据标注工具
答案:B 。Hugging Face提供模型(Models)、数据集(Datasets)、在线演示空间(Spaces)和Transformers库等丰富的AI资源和工具。
以下哪种场景更适合选择开源模型?
A. 追求最强性能,不想管理基础设施 B. 数据隐私要求高,需要本地部署 C. 快速验证想法,不想投入硬件 D. 需要最新的多模态能力
答案:B 。开源模型可以本地部署,数据不出本地,完全可控,最适合数据隐私要求高的场景。
以下哪个AI编程工具是终端原生的AI编程助手?
A. GitHub Copilot B. Cursor C. Claude Code D. Windsurf
答案:C 。Claude Code是Anthropic推出的终端原生AI编程助手,直接在命令行中运行,能理解整个代码库并自主执行复杂任务。
第二十三章:AI发展简史
学习目标
了解AI发展的三波浪潮
掌握AI发展的关键里程碑事件
理解ChatGPT带来的变革和影响
了解AI的未来发展趋势和面临的挑战
前置要求
建议先学习第三章:AI基础概念 ,了解AI的基本定义和分类。
AI的三波浪潮
第一波:规则驱动(1950s-1980s)
AI的诞生期,研究者尝试通过编写规则让计算机模拟人类智能。代表性成果包括逻辑推理程序、专家系统等。但由于"知识获取瓶颈"——人类知识难以完全用规则表达——第一波浪潮逐渐退去。
第二波:数据驱动(1990s-2010s)
随着互联网的发展,海量数据开始积累,机器学习(特别是深度学习)成为AI的主流方法。代表性成果包括ImageNet竞赛中CNN的突破、AlphaGo战胜围棋世界冠军等。GPU的普及为深度学习提供了强大的算力支持。
第三波:大模型时代(2017-至今)
Transformer架构的提出开启了第三波浪潮。GPT、BERT等大语言模型展示了惊人的语言理解和生成能力。ChatGPT的发布标志着AI从"专用工具"走向"通用助手",AI开始真正进入大众生活。
关键里程碑
时间
事件
意义
1950
图灵提出图灵测试
首次提出"机器能否思考"的判定标准
1956
达特茅斯会议
"人工智能"概念正式诞生
1997
深蓝战胜国际象棋冠军卡斯帕罗夫
AI首次在复杂棋类中战胜人类顶尖选手
2012
AlexNet在ImageNet竞赛中大幅领先
深度学习革命的起点,CNN引爆计算机视觉
2016
AlphaGo战胜围棋世界冠军李世石
强化学习的里程碑,AI攻克最复杂的棋类
2017
Google提出Transformer架构
开启大模型时代,奠定了GPT/BERT的基础
2022
ChatGPT发布
AI走向大众,两个月用户突破1亿
2023-2024
GPT-4、Claude 3、Gemini等多模态模型发布
AI进入多模态、Agent化时代
ChatGPT的影响
2022年11月30日,OpenAI发布ChatGPT,这是AI发展史上的一个转折点。
为什么ChatGPT的影响如此巨大?
交互方式革命 :首次让普通人通过自然语言与AI交互,无需任何技术背景
能力惊人 :展示了写作、编程、推理、翻译等多种能力,远超之前的聊天机器人
快速普及 :两个月内用户突破1亿,成为历史上增长最快的消费级应用
产业催化 :引发了全球AI投资热潮,各大科技公司纷纷推出竞品
ChatGPT带来的变化
教育变革 :AI成为学习助手,改变教学方式
工作方式 :AI辅助写作、编程、分析,提升工作效率
产业升级 :各行业开始探索AI应用场景
社会讨论 :引发了关于AI伦理、就业、安全的广泛讨论
开源生态 :推动了开源大模型(Llama、Qwen等)的快速发展
未来趋势
五大发展方向
通用人工智能(AGI) :从专用AI走向具备人类水平智能的通用AI
多模态融合 :文本、图像、音频、视频的深度融合,实现更自然的交互
AI Agent :从被动回答走向主动执行,AI成为能独立完成任务的"数字员工"
端侧AI :AI模型在手机、IoT设备等终端上运行,实现低延迟、隐私保护
AI for Science :AI加速科学发现,如蛋白质结构预测、药物研发、材料科学
面临的挑战
算力瓶颈 :大模型训练需要巨额算力,能源消耗巨大
数据枯竭 :高质量的训练数据逐渐用尽
安全风险 :AI被滥用的风险(深度伪造、网络攻击等)
就业影响 :AI可能替代部分工作岗位,需要社会适应
本章小结
AI发展经历了三波浪潮:规则驱动(1950s-1980s)→数据驱动(1990s-2010s)→大模型时代(2017-至今),每一波都建立在前一波的基础之上。
关键里程碑包括:图灵测试(1950)、达特茅斯会议(1956)、AlexNet(2012)、AlphaGo(2016)、Transformer(2017)、ChatGPT(2022)。
ChatGPT通过自然语言交互、惊人能力和快速普及,引发了全球AI革命,改变了人们的工作、学习和生活方式。
AI未来五大方向:AGI、多模态融合、AI Agent、端侧AI、AI for Science,同时面临算力、数据、安全和就业等挑战。
练习题
Transformer架构是在哪一年提出的?它标志着什么?
A. 2012年,标志着深度学习革命的起点 B. 2016年,标志着强化学习的里程碑 C. 2017年,标志着大模型时代的开启 D. 2022年,标志着AI走向大众
答案:C 。Transformer架构由Google在2017年提出(论文"Attention is All You Need"),奠定了GPT、BERT等大语言模型的基础,标志着大模型时代的开启。
ChatGPT发布后多长时间内用户突破了1亿?
A. 1个月 B. 2个月 C. 6个月 D. 1年
答案:B 。ChatGPT于2022年11月30日发布,在两个月内用户突破1亿,成为历史上增长最快的消费级应用。
以下哪个不属于AI面临的挑战?
A. 算力瓶颈 B. 数据枯竭 C. 安全风险 D. 互联网普及率
答案:D 。AI面临的挑战包括算力瓶颈、数据枯竭、安全风险和就业影响等。互联网普及率不是AI特有的挑战。
附录A:GPU与算力指南
算力是什么?
算力 (Computing Power)是指计算机进行数值计算的能力。在AI领域,算力是训练和运行模型的基础资源。
算力单位
FLOPS (Floating Point Operations Per Second,每秒浮点运算次数)是衡量算力的标准单位:
MFLOPS :百万次/秒(10^6)
GFLOPS :十亿次/秒(10^9)
TFLOPS :万亿次/秒(10^12)
PFLOPS :千万亿次/秒(10^15)
一块NVIDIA A100 GPU的算力约为 312 TFLOPS (FP16),而训练GPT-3需要约 3.14 × 10^23 FLOPS 的总计算量。
CPU vs GPU对比
维度
CPU
GPU
核心数
少量强大核心(4-64个)
大量简单核心(数千个)
擅长任务
串行计算、逻辑控制
大规模并行计算
内存带宽
较低(~50 GB/s)
极高(~2 TB/s)
适用场景
通用计算、操作系统
AI训练/推理、图形渲染
类比理解
CPU 就像一位大学教授 :知识渊博,能解决各种复杂问题,但一次只能辅导一个学生。
GPU 就像1000个小学生 :每个人只能做简单的加减乘除,但1000个人同时做,总速度远超教授。AI训练需要做大量简单的矩阵运算,正好适合GPU的并行能力。
为什么AI需要GPU?
AI模型训练涉及大量的矩阵乘法运算,这些运算可以并行执行。GPU拥有数千个计算核心,可以同时处理大量运算,比CPU快数十倍甚至上百倍。没有GPU,训练现代大模型可能需要数年甚至数十年。
主流GPU产品
GPU型号
显存
FP16算力
适用场景
NVIDIA H100
80GB HBM3
~990 TFLOPS
大模型训练(旗舰级)
NVIDIA A100
40/80GB HBM2e
~312 TFLOPS
大模型训练/推理(主流)
NVIDIA RTX 4090
24GB GDDR6X
~83 TFLOPS
本地推理、小模型微调
显存的重要性
显存(VRAM) 是GPU上用于存储模型参数和中间计算结果的内存。显存大小直接决定了能运行多大的模型。
为什么显存很重要?
模型参数需要加载到显存中才能进行计算。例如,一个7B参数的FP16模型需要约14GB显存,加上KV Cache等运行开销,至少需要16GB显存。如果显存不足,模型就无法运行,或者需要使用量化等压缩技术。
显存优化技术
量化 :降低参数精度(FP16→INT8→INT4),减少显存占用
梯度检查点 :用计算换显存,减少训练时的显存峰值
LoRA/QLoRA :只训练少量额外参数,大幅减少训练显存需求
分布式训练 :将模型分布到多张GPU上,突破单卡显存限制
附录B:术语表
术语
英文
简短解释
人工智能
Artificial Intelligence (AI)
让计算机模拟人类智能行为的技术
机器学习
Machine Learning (ML)
从数据中自动学习规律和模式的算法
深度学习
Deep Learning (DL)
使用多层神经网络的学习方法
大语言模型
Large Language Model (LLM)
参数量巨大的预训练语言模型
Transformer
Transformer
基于自注意力机制的神经网络架构
注意力机制
Attention Mechanism
让模型关注输入中重要部分的技术
Token
Token
文本处理的基本单元,可以是一个字、词或子词
Embedding
Embedding
将非数值数据(如文字)转换为数值向量的过程
向量数据库
Vector Database
专门存储和检索高维向量的数据库
余弦相似度
Cosine Similarity
衡量两个向量方向相似性的指标
RAG
Retrieval-Augmented Generation
检索增强生成,结合信息检索和文本生成
AI智能体
AI Agent
能自主感知、规划、执行和记忆的AI系统
ReAct
Reasoning + Acting
交替进行推理和行动的Agent模式
Function Calling
Function Calling
让LLM调用外部函数的机制
思维链
Chain of Thought (CoT)
引导LLM逐步推理的提示技术
上下文窗口
Context Window
LLM一次能处理的最大Token数量
幻觉
Hallucination
AI生成看似合理但实际不正确的内容
对齐
Alignment
确保AI行为符合人类价值观的过程
RLHF
Reinforcement Learning from Human Feedback
基于人类反馈的强化学习,用于AI对齐
量化
Quantization
将模型参数从高精度转为低精度以减小模型
剪枝
Pruning
移除模型中不重要的参数或神经元
知识蒸馏
Knowledge Distillation
将大模型知识转移到小模型的技术
KV Cache
Key-Value Cache
缓存注意力计算结果以加速推理
Flash Attention
Flash Attention
优化GPU内存访问加速注意力计算的算法
多模态
Multimodal
能同时处理文本、图像、音频等多种数据类型
数据增强
Data Augmentation
通过变换扩充数据集以提升模型泛化能力
过拟合
Overfitting
模型在训练数据上表现好但在新数据上表现差
泛化能力
Generalization
模型在面对未见过的数据时的表现能力
微调
Fine-tuning
在预训练模型基础上用特定数据进一步训练
LoRA
Low-Rank Adaptation
低秩适配,一种高效的模型微调方法
显存
VRAM (Video RAM)
GPU上用于存储模型和计算数据的内存
算力
Computing Power / FLOPS
计算机进行数值计算的能力
BPE
Byte Pair Encoding
一种子词分词算法,GPT系列使用
第二十四章:综合实战——搭建个人AI助手
学习目标
能够独立搭建一个功能完整的个人AI助手,整合对话、检索、工具调用和记忆功能
掌握从项目初始化到部署上线的完整开发流程
理解各模块之间的协作关系,具备模块化设计能力
学会使用Gradio快速搭建Web界面,实现用户友好的交互体验
具备根据需求扩展AI助手功能的能力,如多模态、语音、多Agent协作等
前置要求
在开始本章之前,请确保你已经掌握以下内容:
Python编程基础(函数、类、文件操作、虚拟环境)
LLM基本原理(提示工程、Token、温度参数等)
RAG技术(文档加载、Embedding、向量检索)
Agent概念(工具调用、Function Calling、ReAct模式)
基础的前端知识(HTML/CSS概念,有助于理解Gradio界面)
项目概述
项目功能介绍
本项目将搭建一个个人AI助手,具备以下核心功能:
智能问答 :基于大语言模型的自然语言对话能力
文档检索 :上传本地文档后,助手能基于文档内容回答问题(RAG)
工具调用 :支持天气查询、计算器、网页搜索等外部工具
记忆功能 :记住对话历史和重要信息,实现连续交互
技术架构图
系统整体架构流程如下:
用户输入
|
v
[意图识别模块] —— 判断用户意图:闲聊 / 文档问答 / 工具调用
|
v
[路由分发模块]
|—— 闲聊意图 ——→ [LLM对话模块] ——→ 生成回复
|—— 文档意图 ——→ [RAG检索模块] ——→ [LLM生成模块] ——→ 生成回复
|—— 工具意图 ——→ [工具调用模块] ——→ [LLM整合模块] ——→ 生成回复
|
v
[记忆管理模块] —— 保存对话历史,提取重要信息
|
v
[输出模块] —— 流式输出回复内容
|
v
用户看到回复
涉及知识点回顾
本项目将综合运用前面章节的核心知识:
模块 涉及章节 核心知识点
智能问答 第3-5章 LLM API调用、提示工程、流式输出
文档检索 第15-17章 文档加载、文本切分、Embedding、Chroma向量库
工具调用 第19-21章 Function Calling、ReAct模式、工具定义与路由
记忆功能 第22章 对话历史管理、长期记忆存储与检索
Web界面 第23章 Gradio组件、事件处理、界面布局
步骤一:项目初始化
创建项目目录结构
首先创建项目根目录和必要的子目录:
mkdir -p personal-ai-assistant/{src,data,docs,tests}
cd personal-ai-assistant
touch src/__init__.py
目录结构说明:
src/:源代码目录,包含各功能模块
data/:数据目录,存放上传的文档和向量数据库
docs/:项目文档
tests/:测试代码
创建 requirements.txt
列出项目所需的所有依赖包:
# LLM 相关
openai>=1.0.0
langchain>=0.1.0
langchain-openai>=0.0.5
langchain-community>=0.0.10
# 向量数据库
chromadb>=0.4.0
# 文档处理
pypdf>=3.0.0
python-docx>=0.8.11
unstructured>=0.11.0
# Embedding
sentence-transformers>=2.2.0
# Web 界面
gradio>=4.0.0
# 工具调用
requests>=2.31.0
# 配置管理
pyyaml>=6.0
python-dotenv>=1.0.0
# 其他工具
numpy>=1.24.0
tiktoken>=0.5.0
安装依赖:
pip install -r requirements.txt
创建 config.yaml 配置文件
配置文件用于管理非敏感的配置项:
# 模型配置
model:
provider: "openai" # 可选: openai, ollama
name: "gpt-4o-mini"
temperature: 0.7
max_tokens: 2000
streaming: true
# Ollama 配置(如果使用本地模型)
ollama:
base_url: "http://localhost:11434"
model: "llama3.1"
# RAG 配置
rag:
chunk_size: 500
chunk_overlap: 50
top_k: 5
embedding_model: "sentence-transformers/all-MiniLM-L6-v2"
# 记忆配置
memory:
short_term_limit: 10 # 短期记忆保留最近N轮
long_term_enabled: true
# 工具配置
tools:
weather_api_key: "" # 从环境变量读取,此处仅占位
search_api_key: ""
# 向量数据库
vector_db:
persist_directory: "./data/chroma_db"
创建 .env 文件管理敏感信息
注意: .env 文件包含敏感信息,切勿提交到Git仓库 !请在 .gitignore 中添加 .env。
# OpenAI API Key
OPENAI_API_KEY=sk-your-api-key-here
# 天气API Key(可选,如使用OpenWeatherMap)
WEATHER_API_KEY=your-weather-api-key
# 搜索API Key(可选,如使用SerpAPI或Bing Search)
SEARCH_API_KEY=your-search-api-key
步骤二:基础对话功能
使用 OpenAI API 搭建基础对话
在 src/chat.py 中创建基础对话模块:
import os
from typing import Iterator
from dotenv import load_dotenv
from openai import OpenAI, APIError, RateLimitError
# 加载环境变量
load_dotenv()
class ChatBot:
def __init__(self, model: str = "gpt-4o-mini", temperature: float = 0.7):
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.model = model
self.temperature = temperature
self.messages = [] # 对话历史
def chat(self, user_input: str) -> str:
"""非流式对话"""
self.messages.append({"role": "user", "content": user_input})
try:
response = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
temperature=self.temperature,
)
reply = response.choices[0].message.content
self.messages.append({"role": "assistant", "content": reply})
return reply
except APIError as e:
return f"API错误: {e}"
except RateLimitError:
return "请求过于频繁,请稍后再试。"
except Exception as e:
return f"发生错误: {e}"
def chat_stream(self, user_input: str) -> Iterator[str]:
"""流式对话,逐字返回"""
self.messages.append({"role": "user", "content": user_input})
try:
stream = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
temperature=self.temperature,
stream=True,
)
full_reply = ""
for chunk in stream:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
full_reply += content
yield content
self.messages.append({"role": "assistant", "content": full_reply})
except Exception as e:
yield f"发生错误: {e}"
def clear_history(self):
"""清空对话历史"""
self.messages = []
# 运行测试
if __name__ == "__main__":
bot = ChatBot()
print("=== 基础对话测试 ===")
print("Bot:", bot.chat("你好,请介绍一下你自己。"))
print("-" * 40)
print("流式输出测试:")
for chunk in bot.chat_stream("讲一个简短的笑话"):
print(chunk, end="", flush=True)
print()
使用 Ollama 本地模型(可选)
如果你希望使用本地模型,可以替换为Ollama客户端:
from openai import OpenAI
class LocalChatBot:
def __init__(self, model: str = "llama3.1", base_url: str = "http://localhost:11434"):
# Ollama 兼容 OpenAI API 格式
self.client = OpenAI(base_url=f"{base_url}/v1", api_key="ollama")
self.model = model
self.messages = []
def chat(self, user_input: str) -> str:
self.messages.append({"role": "user", "content": user_input})
response = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
)
reply = response.choices[0].message.content
self.messages.append({"role": "assistant", "content": reply})
return reply
测试验证: 运行 python src/chat.py,确认能正常获取AI回复,流式输出能逐字显示。
步骤三:添加RAG文档检索
创建RAG模块
在 src/rag.py 中实现文档检索功能:
import os
from typing import List
from langchain_community.document_loaders import (
PyPDFLoader, TextLoader, UnstructuredMarkdownLoader
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.schema import Document
class RAGSystem:
def __init__(self, persist_dir: str = "./data/chroma_db"):
self.persist_dir = persist_dir
self.embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
self.vector_store = None
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", "。", ",", " ", ""]
)
def load_document(self, file_path: str) -> List[Document]:
"""加载单个文档"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"文件不存在: {file_path}")
ext = os.path.splitext(file_path)[1].lower()
if ext == ".pdf":
loader = PyPDFLoader(file_path)
elif ext == ".txt":
loader = TextLoader(file_path, encoding="utf-8")
elif ext in [".md", ".markdown"]:
loader = UnstructuredMarkdownLoader(file_path)
else:
raise ValueError(f"不支持的文件格式: {ext}")
return loader.load()
def add_documents(self, file_paths: List[str]):
"""加载并索引多个文档"""
all_docs = []
for fp in file_paths:
docs = self.load_document(fp)
all_docs.extend(docs)
print(f"已加载: {fp} ({len(docs)} 页/段)")
# 文档切分
chunks = self.text_splitter.split_documents(all_docs)
print(f"文档切分后共 {len(chunks)} 个片段")
# 存入向量数据库
self.vector_store = Chroma.from_documents(
documents=chunks,
embedding=self.embeddings,
persist_directory=self.persist_dir
)
self.vector_store.persist()
print("向量数据库已保存。")
def load_existing_db(self):
"""加载已有的向量数据库"""
if os.path.exists(self.persist_dir):
self.vector_store = Chroma(
persist_directory=self.persist_dir,
embedding_function=self.embeddings
)
return True
return False
def search(self, query: str, top_k: int = 5) -> List[Document]:
"""检索相关文档片段"""
if not self.vector_store:
if not self.load_existing_db():
return []
return self.vector_store.similarity_search(query, k=top_k)
def get_context(self, query: str, top_k: int = 5) -> str:
"""获取检索结果拼接的上下文文本"""
docs = self.search(query, top_k)
if not docs:
return ""
contexts = []
for i, doc in enumerate(docs, 1):
source = doc.metadata.get("source", "未知来源")
contexts.append(f"[文档{i}] 来源: {source}\n{doc.page_content}")
return "\n\n".join(contexts)
# 测试代码
if __name__ == "__main__":
rag = RAGSystem()
# 假设 data/ 目录下有测试文档
# rag.add_documents(["data/test.pdf", "data/notes.txt"])
# context = rag.get_context("什么是RAG?")
# print(context)
集成RAG到对话中
修改 src/chat.py,添加RAG支持:
from src.rag import RAGSystem
class ChatBot:
def __init__(self, model: str = "gpt-4o-mini", temperature: float = 0.7, use_rag: bool = False):
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.model = model
self.temperature = temperature
self.messages = []
self.use_rag = use_rag
self.rag = RAGSystem() if use_rag else None
def chat(self, user_input: str) -> str:
# 如果启用RAG,先检索相关文档
if self.use_rag and self.rag:
context = self.rag.get_context(user_input)
if context:
# 将检索结果注入系统提示
system_msg = {
"role": "system",
"content": f"你是智能助手。请基于以下参考文档回答问题,如果文档中没有相关信息,请明确说明。\n\n参考文档:\n{context}"
}
messages = [system_msg] + self.messages + [{"role": "user", "content": user_input}]
else:
messages = self.messages + [{"role": "user", "content": user_input}]
else:
messages = self.messages + [{"role": "user", "content": user_input}]
try:
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=self.temperature,
)
reply = response.choices[0].message.content
self.messages.append({"role": "user", "content": user_input})
self.messages.append({"role": "assistant", "content": reply})
return reply
except Exception as e:
return f"发生错误: {e}"
测试问答效果:
准备一份测试PDF/TXT文档放入 data/ 目录
运行 rag.add_documents(["data/你的文档.pdf"]) 建立索引
提问与文档相关的问题,验证回答是否引用了文档内容
提问与文档无关的问题,验证助手是否能正确处理
步骤四:添加工具调用
定义工具
在 src/tools.py 中定义可用工具:
import os
import json
import requests
from typing import Dict, Any, Callable
from dotenv import load_dotenv
load_dotenv()
class ToolManager:
def __init__(self):
self.tools: Dict[str, Dict[str, Any]] = {}
self._register_default_tools()
def _register_default_tools(self):
"""注册默认工具"""
self.register_tool(
name="weather_query",
description="查询指定城市的当前天气",
parameters={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'、'Shanghai'"
}
},
"required": ["city"]
},
func=self._query_weather
)
self.register_tool(
name="calculator",
description="执行数学计算,如加减乘除、平方根等",
parameters={
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "数学表达式,如'2+3*4'、'sqrt(16)'"
}
},
"required": ["expression"]
},
func=self._calculate
)
self.register_tool(
name="web_search",
description="搜索互联网获取最新信息",
parameters={
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
}
},
"required": ["query"]
},
func=self._web_search
)
def register_tool(self, name: str, description: str, parameters: dict, func: Callable):
"""注册新工具"""
self.tools[name] = {
"name": name,
"description": description,
"parameters": parameters,
"func": func
}
def get_tool_definitions(self) -> list:
"""获取工具定义列表(用于Function Calling)"""
return [
{
"type": "function",
"function": {
"name": t["name"],
"description": t["description"],
"parameters": t["parameters"]
}
}
for t in self.tools.values()
]
def execute(self, tool_name: str, arguments: dict) -> str:
"""执行指定工具"""
if tool_name not in self.tools:
return f"错误:未找到工具 '{tool_name}'"
try:
result = self.tools[tool_name]["func"](**arguments)
return str(result)
except Exception as e:
return f"工具执行错误: {e}"
# ===== 工具实现 =====
def _query_weather(self, city: str) -> str:
"""查询天气(示例实现,使用OpenWeatherMap API)"""
api_key = os.getenv("WEATHER_API_KEY")
if not api_key:
return "天气API Key未配置,无法查询天气。"
try:
url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&lang=zh_cn&units=metric"
resp = requests.get(url, timeout=10)
data = resp.json()
if data.get("cod") != 200:
return f"查询失败: {data.get('message', '未知错误')}"
weather = data["weather"][0]["description"]
temp = data["main"]["temp"]
feels_like = data["main"]["feels_like"]
humidity = data["main"]["humidity"]
return f"{city}当前天气:{weather},温度{temp}°C(体感{feels_like}°C),湿度{humidity}%"
except Exception as e:
return f"天气查询出错: {e}"
def _calculate(self, expression: str) -> str:
"""安全计算器"""
allowed_names = {
"abs": abs, "round": round,
"max": max, "min": min,
"sum": sum, "len": len
}
try:
# 安全求值:只允许数字和基本运算符
result = eval(expression, {"__builtins__": {}}, allowed_names)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误: {e}"
def _web_search(self, query: str) -> str:
"""网页搜索(示例使用DuckDuckGo免费搜索)"""
try:
from duckduckgo_search import DDGS
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=3))
if not results:
return "未找到相关搜索结果。"
output = []
for i, r in enumerate(results, 1):
output.append(f"{i}. {r['title']}\n{r['href']}\n{r['body']}")
return "\n\n".join(output)
except ImportError:
return "未安装 duckduckgo-search,请执行: pip install duckduckgo-search"
except Exception as e:
return f"搜索出错: {e}"
工具路由逻辑
在 src/agent.py 中实现工具调用路由:
import json
from typing import Optional
from openai import OpenAI
from src.tools import ToolManager
class Agent:
def __init__(self, model: str = "gpt-4o-mini"):
self.client = OpenAI()
self.model = model
self.tool_manager = ToolManager()
def run(self, user_input: str) -> str:
"""运行Agent:判断是否需要调用工具"""
messages = [
{"role": "system", "content": "你是智能助手,可以使用工具帮助用户。如果需要使用工具,请调用对应函数。"},
{"role": "user", "content": user_input}
]
# 第一次调用:让模型判断是否需要工具
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
tools=self.tool_manager.get_tool_definitions(),
tool_choice="auto",
)
message = response.choices[0].message
# 如果需要调用工具
if message.tool_calls:
# 添加助手消息到历史
messages.append({
"role": "assistant",
"content": message.content or "",
"tool_calls": [tc.model_dump() for tc in message.tool_calls]
})
# 执行每个工具调用
for tool_call in message.tool_calls:
tool_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
print(f"[Agent] 调用工具: {tool_name}({arguments})")
result = self.tool_manager.execute(tool_name, arguments)
# 添加工具返回结果
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 第二次调用:让模型整合工具结果并回复
final_response = self.client.chat.completions.create(
model=self.model,
messages=messages,
)
return final_response.choices[0].message.content
# 不需要工具,直接返回回复
return message.content or ""
# 测试
if __name__ == "__main__":
agent = Agent()
print(agent.run("北京今天天气怎么样?"))
print("-" * 40)
print(agent.run("计算 123 * 456"))
工具调用流程说明:
用户输入问题
LLM判断是否需要工具(通过 tools 参数提供工具定义)
如需工具,LLM返回 tool_calls 而非直接回复
Agent执行对应工具函数,获取结果
将工具结果再次传给LLM,生成最终回复
步骤五:添加记忆功能
创建记忆管理模块
在 src/memory.py 中实现短期和长期记忆:
import os
import json
from typing import List, Dict
from datetime import datetime
class MemoryManager:
def __init__(self, short_term_limit: int = 10, long_term_file: str = "./data/long_term_memory.json"):
self.short_term_limit = short_term_limit
self.long_term_file = long_term_file
self.short_term: List[Dict] = [] # 短期记忆:最近N轮对话
self.long_term: Dict[str, str] = {} # 长期记忆:关键信息摘要
self._load_long_term()
def add_interaction(self, user_msg: str, assistant_msg: str):
"""添加一轮对话到短期记忆"""
self.short_term.append({
"role": "user",
"content": user_msg,
"timestamp": datetime.now().isoformat()
})
self.short_term.append({
"role": "assistant",
"content": assistant_msg,
"timestamp": datetime.now().isoformat()
})
# 保持短期记忆在限制范围内
while len(self.short_term) > self.short_term_limit * 2:
self.short_term.pop(0)
def get_short_term_messages(self) -> List[Dict]:
"""获取短期记忆(用于传给LLM)"""
return [{"role": m["role"], "content": m["content"]} for m in self.short_term]
def add_long_term(self, key: str, value: str):
"""添加长期记忆"""
self.long_term[key] = value
self._save_long_term()
def get_long_term_context(self) -> str:
"""获取长期记忆文本(用于系统提示)"""
if not self.long_term:
return ""
items = [f"- {k}: {v}" for k, v in self.long_term.items()]
return "已记住的用户信息:\n" + "\n".join(items)
def extract_and_save(self, user_msg: str, assistant_msg: str):
"""从对话中提取重要信息保存到长期记忆(简化版)"""
# 实际项目中可以使用LLM来提取关键信息
# 这里仅作示例:如果用户明确说"记住",则保存
if "记住" in user_msg or "记住" in assistant_msg:
# 简单提取"记住"后面的内容
# 实际应使用LLM进行信息抽取
pass
def _load_long_term(self):
"""从文件加载长期记忆"""
if os.path.exists(self.long_term_file):
with open(self.long_term_file, "r", encoding="utf-8") as f:
self.long_term = json.load(f)
def _save_long_term(self):
"""保存长期记忆到文件"""
os.makedirs(os.path.dirname(self.long_term_file), exist_ok=True)
with open(self.long_term_file, "w", encoding="utf-8") as f:
json.dump(self.long_term, f, ensure_ascii=False, indent=2)
def clear_short_term(self):
"""清空短期记忆"""
self.short_term = []
def clear_long_term(self):
"""清空长期记忆"""
self.long_term = {}
self._save_long_term()
集成记忆到对话
更新 src/chat.py 中的 ChatBot 类:
from src.memory import MemoryManager
class ChatBot:
def __init__(self, model: str = "gpt-4o-mini", temperature: float = 0.7,
use_rag: bool = False, use_memory: bool = True):
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.model = model
self.temperature = temperature
self.use_rag = use_rag
self.use_memory = use_memory
self.rag = RAGSystem() if use_rag else None
self.memory = MemoryManager() if use_memory else None
def chat(self, user_input: str) -> str:
# 构建消息列表
messages = []
# 1. 系统提示
system_parts = ["你是智能助手,能够回答问题、检索文档、调用工具。"]
if self.memory:
lt = self.memory.get_long_term_context()
if lt:
system_parts.append(lt)
system_msg = "\n\n".join(system_parts)
messages.append({"role": "system", "content": system_msg})
# 2. 短期记忆
if self.memory:
messages.extend(self.memory.get_short_term_messages())
# 3. RAG上下文(如果是文档相关问题)
user_msg_content = user_input
if self.use_rag and self.rag:
context = self.rag.get_context(user_input)
if context:
user_msg_content = f"基于以下参考文档回答问题:\n{context}\n\n用户问题:{user_input}"
messages.append({"role": "user", "content": user_msg_content})
# 调用LLM
try:
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=self.temperature,
)
reply = response.choices[0].message.content
# 保存到记忆
if self.memory:
self.memory.add_interaction(user_input, reply)
return reply
except Exception as e:
return f"发生错误: {e}"
def remember(self, key: str, value: str):
"""手动添加长期记忆"""
if self.memory:
self.memory.add_long_term(key, value)
return f"已记住: {key} = {value}"
return "记忆功能未启用"
def clear_memory(self):
"""清空记忆"""
if self.memory:
self.memory.clear_short_term()
self.memory.clear_long_term()
测试连续对话:
bot = ChatBot(use_memory=True)
print(bot.chat("我叫张三,今年28岁。"))
print(bot.chat("我叫什么名字?")) # 应能回答"张三"
print(bot.remember("职业", "软件工程师"))
print(bot.chat("我的职业是什么?")) # 应能回答"软件工程师"
步骤六:Web界面
使用Gradio搭建Web UI
在 src/webui.py 中创建Gradio界面:
import gradio as gr
from src.chat import ChatBot
from src.rag import RAGSystem
class AIAssistantWebUI:
def __init__(self):
self.bot = ChatBot(use_rag=True, use_memory=True)
self.rag = self.bot.rag
def respond(self, message: str, history: list) -> str:
"""处理用户消息并返回回复"""
if not message.strip():
return ""
# 使用流式输出
full_response = ""
for chunk in self.bot.chat_stream(message):
full_response += chunk
yield full_response
def upload_files(self, files: list) -> str:
"""上传文档并建立索引"""
if not files:
return "未选择文件"
file_paths = [f.name for f in files]
try:
self.rag.add_documents(file_paths)
return f"成功上传并索引 {len(file_paths)} 个文件"
except Exception as e:
return f"上传失败: {e}"
def clear_chat(self):
"""清空对话"""
self.bot.clear_history()
self.bot.clear_memory()
return None
def build_ui(self):
"""构建Gradio界面"""
with gr.Blocks(title="个人AI助手", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 个人AI助手")
gr.Markdown("智能问答 | 文档检索 | 工具调用 | 记忆功能")
with gr.Row():
# 左侧:聊天窗口
with gr.Column(scale=3):
chatbot = gr.Chatbot(
label="对话",
height=500,
bubble_full_width=False
)
msg_input = gr.Textbox(
label="输入消息",
placeholder="请输入你的问题...",
lines=2
)
with gr.Row():
send_btn = gr.Button("发送", variant="primary")
clear_btn = gr.Button("清空对话")
# 右侧:设置面板
with gr.Column(scale=1):
gr.Markdown("### 设置")
with gr.Tab("文档上传"):
file_upload = gr.File(
label="上传文档",
file_types=[".pdf", ".txt", ".md"],
file_count="multiple"
)
upload_btn = gr.Button("建立索引")
upload_status = gr.Textbox(label="状态", interactive=False)
with gr.Tab("记忆管理"):
memory_key = gr.Textbox(label="关键词")
memory_value = gr.Textbox(label="内容")
save_mem_btn = gr.Button("保存到长期记忆")
mem_status = gr.Textbox(label="状态", interactive=False)
with gr.Tab("关于"):
gr.Markdown("""
**功能说明:**
- 支持自然语言对话
- 上传PDF/TXT/Markdown文档进行问答
- 自动调用天气、计算、搜索等工具
- 记住对话历史和重要信息
""")
# 事件绑定
send_btn.click(
self.respond,
inputs=[msg_input, chatbot],
outputs=chatbot
).then(lambda: "", outputs=msg_input)
msg_input.submit(
self.respond,
inputs=[msg_input, chatbot],
outputs=chatbot
).then(lambda: "", outputs=msg_input)
clear_btn.click(self.clear_chat, outputs=chatbot)
upload_btn.click(self.upload_files, inputs=file_upload, outputs=upload_status)
def save_memory(k, v):
return self.bot.remember(k, v)
save_mem_btn.click(save_memory, inputs=[memory_key, memory_value], outputs=mem_status)
return demo
def main():
ui = AIAssistantWebUI()
demo = ui.build_ui()
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
if __name__ == "__main__":
main()
运行和访问
python src/webui.py
启动后,在浏览器中访问 http://localhost:7860 即可使用。
界面说明:
聊天窗口 :左侧主区域,显示对话历史,支持流式输出
文档上传 :右侧面板,支持多文件上传并自动建立向量索引
记忆管理 :手动添加长期记忆,如用户偏好、重要信息
步骤七:部署与优化
使用Docker打包
创建 Dockerfile:
FROM python:3.11-slim
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
libmagic1 \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目代码
COPY src/ ./src/
COPY config.yaml .
# 创建数据目录
RUN mkdir -p data
# 暴露端口
EXPOSE 7860
# 启动命令
CMD ["python", "src/webui.py"]
创建 .dockerignore:
.env
.git
__pycache__
*.pyc
data/chroma_db
构建并运行:
docker build -t personal-ai-assistant .
docker run -p 7860:7860 --env-file .env personal-ai-assistant
部署到云服务器
以阿里云/腾讯云为例:
购买云服务器(建议2核4G以上)
安装Docker:curl -fsSL https://get.docker.com | sh
上传项目代码和 .env 文件
构建镜像并运行(同上)
配置安全组,开放7860端口
(可选)配置Nginx反向代理,绑定域名和HTTPS
性能优化建议
模型选择 :日常对话使用 gpt-4o-mini 或本地 llama3.1,降低成本
向量缓存 :文档索引后持久化到磁盘,避免重复Embedding
异步处理 :文档上传和索引使用后台任务,避免阻塞界面
连接池 :使用HTTP连接池复用API连接,减少延迟
流式输出 :始终使用流式响应,提升用户体验
上下文压缩 :对话历史过长时,使用摘要压缩而非直接截断
项目完整代码汇总
整合版 main.py
以下是将所有功能整合后的 main.py,适合快速部署:
#!/usr/bin/env python3
"""
个人AI助手 - 整合版
功能:智能对话、RAG检索、工具调用、记忆管理、Web界面
"""
import os
import json
import yaml
from typing import List, Dict, Iterator
from dotenv import load_dotenv
from openai import OpenAI
# LangChain相关
from langchain_community.document_loaders import PyPDFLoader, TextLoader, UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.schema import Document
# Gradio
import gradio as gr
# 加载配置
load_dotenv()
CONFIG = yaml.safe_load(open("config.yaml", "r", encoding="utf-8"))
# ==================== RAG模块 ====================
class RAGSystem:
def __init__(self):
cfg = CONFIG["rag"]
self.persist_dir = CONFIG["vector_db"]["persist_directory"]
self.embeddings = HuggingFaceEmbeddings(model_name=cfg["embedding_model"])
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=cfg["chunk_size"],
chunk_overlap=cfg["chunk_overlap"]
)
self.vector_store = None
self._load_db()
def load_document(self, file_path: str) -> List[Document]:
ext = os.path.splitext(file_path)[1].lower()
loaders = {".pdf": PyPDFLoader, ".txt": TextLoader, ".md": UnstructuredMarkdownLoader}
if ext not in loaders:
raise ValueError(f"不支持的格式: {ext}")
loader = loaders[ext](file_path)
return loader.load()
def add_documents(self, file_paths: List[str]):
all_docs = []
for fp in file_paths:
all_docs.extend(self.load_document(fp))
chunks = self.text_splitter.split_documents(all_docs)
self.vector_store = Chroma.from_documents(
documents=chunks, embedding=self.embeddings, persist_directory=self.persist_dir
)
self.vector_store.persist()
def _load_db(self):
if os.path.exists(self.persist_dir):
self.vector_store = Chroma(persist_directory=self.persist_dir, embedding_function=self.embeddings)
def get_context(self, query: str, top_k: int = None) -> str:
if not self.vector_store:
return ""
k = top_k or CONFIG["rag"]["top_k"]
docs = self.vector_store.similarity_search(query, k=k)
return "\n\n".join([f"[来源: {d.metadata.get('source', '未知')}]\n{d.page_content}" for d in docs])
# ==================== 工具模块 ====================
class ToolManager:
def __init__(self):
self.tools = {}
self._register_defaults()
def _register_defaults(self):
self.register("calculator", "数学计算", {"type":"object","properties":{"expression":{"type":"string"}},"required":["expression"]}, self._calc)
self.register("weather_query", "天气查询", {"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}, self._weather)
def register(self, name, desc, params, func):
self.tools[name] = {"name": name, "description": desc, "parameters": params, "func": func}
def get_definitions(self):
return [{"type": "function", "function": {"name": t["name"], "description": t["description"], "parameters": t["parameters"]}} for t in self.tools.values()]
def execute(self, name, args):
return self.tools[name]["func"](**args) if name in self.tools else f"未知工具: {name}"
def _calc(self, expression: str) -> str:
try:
return f"结果: {eval(expression, {'__builtins__': {}}, {'abs':abs,'round':round,'max':max,'min':min})}"
except Exception as e:
return f"计算错误: {e}"
def _weather(self, city: str) -> str:
return f"{city}天气:晴天,25°C(示例数据,请配置真实API)"
# ==================== 记忆模块 ====================
class Memory:
def __init__(self):
cfg = CONFIG["memory"]
self.limit = cfg["short_term_limit"]
self.lt_file = "./data/long_term_memory.json"
self.short_term: List[Dict] = []
self.long_term: Dict[str, str] = {}
self._load_lt()
def add(self, user_msg, assistant_msg):
self.short_term.extend([{"role":"user","content":user_msg}, {"role":"assistant","content":assistant_msg}])
while len(self.short_term) > self.limit * 2:
self.short_term.pop(0)
def get_messages(self):
return [{"role": m["role"], "content": m["content"]} for m in self.short_term]
def add_lt(self, key, value):
self.long_term[key] = value
self._save_lt()
def get_lt_text(self):
return "已记住的信息:\n" + "\n".join([f"- {k}: {v}" for k, v in self.long_term.items()]) if self.long_term else ""
def _load_lt(self):
if os.path.exists(self.lt_file):
with open(self.lt_file, "r", encoding="utf-8") as f:
self.long_term = json.load(f)
def _save_lt(self):
os.makedirs(os.path.dirname(self.lt_file), exist_ok=True)
with open(self.lt_file, "w", encoding="utf-8") as f:
json.dump(self.long_term, f, ensure_ascii=False)
def clear(self):
self.short_term = []
self.long_term = {}
self._save_lt()
# ==================== 主对话模块 ====================
class AIAssistant:
def __init__(self):
mcfg = CONFIG["model"]
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.model = mcfg["name"]
self.temperature = mcfg["temperature"]
self.streaming = mcfg["streaming"]
self.rag = RAGSystem()
self.tools = ToolManager()
self.memory = Memory()
def chat(self, message: str) -> Iterator[str]:
messages = [{"role": "system", "content": f"你是智能助手。\n{self.memory.get_lt_text()}"}]
messages.extend(self.memory.get_messages())
# RAG增强
context = self.rag.get_context(message)
if context:
message = f"参考文档:\n{context}\n\n问题: {message}"
messages.append({"role": "user", "content": message})
# 第一次调用(可能触发工具)
response = self.client.chat.completions.create(
model=self.model, messages=messages, temperature=self.temperature,
tools=self.tools.get_definitions(), tool_choice="auto", stream=False
)
msg = response.choices[0].message
if msg.tool_calls:
messages.append({"role": "assistant", "content": msg.content or "", "tool_calls": [tc.model_dump() for tc in msg.tool_calls]})
for tc in msg.tool_calls:
result = self.tools.execute(tc.function.name, json.loads(tc.function.arguments))
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
final = self.client.chat.completions.create(model=self.model, messages=messages, temperature=self.temperature, stream=self.streaming)
else:
final = self.client.chat.completions.create(model=self.model, messages=messages, temperature=self.temperature, stream=self.streaming)
full_reply = ""
if self.streaming:
for chunk in final:
if chunk.choices[0].delta.content:
c = chunk.choices[0].delta.content
full_reply += c
yield full_reply
else:
full_reply = final.choices[0].message.content
yield full_reply
self.memory.add(message, full_reply)
# ==================== Web界面 ====================
class WebUI:
def __init__(self):
self.assistant = AIAssistant()
def respond(self, message, history):
if not message.strip():
return ""
full = ""
for chunk in self.assistant.chat(message):
full = chunk
yield full
def upload(self, files):
if not files:
return "未选择文件"
try:
self.assistant.rag.add_documents([f.name for f in files])
return f"已索引 {len(files)} 个文件"
except Exception as e:
return f"失败: {e}"
def build(self):
with gr.Blocks(title="个人AI助手", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 个人AI助手")
with gr.Row():
with gr.Column(scale=3):
chat = gr.Chatbot(label="对话", height=500)
inp = gr.Textbox(label="输入", placeholder="请输入...")
with gr.Row():
gr.Button("发送", variant="primary").click(self.respond, [inp, chat], chat).then(lambda: "", outputs=inp)
gr.Button("清空").click(lambda: self.assistant.memory.clear(), outputs=chat)
with gr.Column(scale=1):
gr.Markdown("### 文档上传")
fu = gr.File(file_types=[".pdf",".txt",".md"], file_count="multiple")
gr.Button("索引").click(self.upload, fu, gr.Textbox(label="状态"))
return demo
def main():
ui = WebUI()
ui.build().launch(server_name="0.0.0.0", server_port=7860)
if __name__ == "__main__":
main()
代码结构说明
personal-ai-assistant/
├── main.py # 整合版入口(适合快速部署)
├── src/
│ ├── __init__.py
│ ├── chat.py # 对话模块(基础对话+记忆集成)
│ ├── rag.py # RAG检索模块
│ ├── tools.py # 工具定义与管理
│ ├── agent.py # Agent路由逻辑
│ ├── memory.py # 记忆管理模块
│ └── webui.py # Gradio Web界面
├── data/
│ ├── chroma_db/ # 向量数据库持久化目录
│ └── long_term_memory.json # 长期记忆文件
├── config.yaml # 配置文件
├── requirements.txt # 依赖列表
├── Dockerfile # Docker打包文件
└── .env # 敏感信息(不提交Git)
扩展方向
多模态支持(图片理解)
集成GPT-4o或Qwen-VL等多模态模型,支持用户上传图片并提问:
# 多模态消息示例
messages = [{
"role": "user",
"content": [
{"type": "text", "text": "这张图片里有什么?"},
{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}
]
}]
语音交互
添加语音识别(Whisper)和语音合成(TTS):
语音输入:使用OpenAI Whisper API将语音转为文字
语音输出:使用Edge-TTS或GPT-SoVITS合成语音回复
多Agent协作
将不同功能拆分为专门Agent,通过主Agent协调:
研究Agent :负责信息检索和资料收集
代码Agent :负责编程和代码分析
写作Agent :负责文案撰写和润色
主控Agent :理解用户需求,分发给子Agent执行
接入更多工具
通过MCP(Model Context Protocol)或自定义接口,扩展助手能力:
日历管理:查询日程、创建提醒
邮件助手:读取、撰写、发送邮件
代码执行:安全执行Python代码并返回结果
数据库查询:连接SQL数据库执行查询
练习题
练习1:修改项目支持图片输入
在现有Gradio界面中添加图片上传功能,使助手能够:
接收用户上传的图片
将图片转为base64编码
使用GPT-4o等多模态模型分析图片内容并回答相关问题
提示: Gradio的 gr.Image 组件可以接收图片,OpenAI API支持传入base64编码的图片URL。
练习2:添加新的自定义工具
为AI助手添加一个实用的自定义工具,例如:
待办事项工具 :添加、查询、完成待办事项(数据存储到本地JSON文件)
翻译工具 :调用翻译API或本地模型进行中英互译
股票查询工具 :查询指定股票的实时价格
要求: 完整实现工具函数、参数定义、注册逻辑,并在Web界面中测试。
练习3:优化RAG检索效果
当前RAG实现使用基础的关键词相似度检索,尝试以下优化:
查询重写 :在检索前,使用LLM将用户问题改写为更适合检索的查询语句
混合检索 :结合向量相似度和关键词匹配(BM25),提升召回率
重排序 :检索出Top-10结果后,使用Cross-Encoder模型对结果重排序,选出最相关的Top-5
上下文增强 :在切分文档时,为每个chunk添加文档标题等元信息
评估: 准备一组测试问题和标准答案,对比优化前后的回答质量。
章节小结
本章通过一个完整的综合项目——个人AI助手 ,将前面所学的核心知识点串联起来,涵盖以下关键内容:
项目初始化 :合理的目录结构、依赖管理、配置分离(config.yaml + .env)
基础对话 :使用OpenAI API或Ollama搭建流式对话,含完善的错误处理
RAG文档检索 :支持PDF/TXT/Markdown,使用Chroma存储向量,实现检索增强生成
工具调用 :基于Function Calling实现天气、计算、搜索等工具的自动调用
记忆功能 :短期记忆保留对话上下文,长期记忆持久化重要信息
Web界面 :使用Gradio快速搭建包含聊天、上传、设置面板的完整UI
部署优化 :Docker打包、云服务器部署、性能优化策略
通过本章的学习,你应该具备了独立开发完整AI应用的能力。建议在此基础上继续探索扩展方向,如多模态、语音交互、多Agent协作等,打造更加强大的个人AI助手。
阅读进度:
0%
附录D:练习题答案与解析
第零章 学习路线图 - 练习题答案
1 AI学习路线中,数学基础主要包括哪些领域?
答案: 线性代数、微积分、概率论与统计、优化理论。
解析: 线性代数用于理解数据表示和矩阵运算;微积分是理解梯度下降和反向传播的基础;概率论与统计帮助理解不确定性建模;优化理论则是训练模型的核心数学工具。这四个领域构成了AI学习的数学支柱,缺一不可。
2 学习AI的推荐路径是什么顺序?
答案: Python编程基础 → 数学基础 → 机器学习 → 深度学习 → 大语言模型与AI应用。
解析: 这个路径遵循由浅入深的原则。先掌握编程工具(Python),再夯实数学基础,然后学习经典机器学习方法,接着深入神经网络和深度学习,最后扩展到当前最前沿的大语言模型和AI应用开发。循序渐进可以避免知识断层。
3 为什么Python是AI领域最常用的编程语言?
答案: 语法简洁易学、拥有丰富的科学计算库(NumPy、Pandas)、完善的深度学习框架(PyTorch、TensorFlow)、活跃的社区生态。
解析: Python的简洁语法降低了入门门槛,使得研究者可以更专注于算法本身而非编程细节。同时,NumPy、Pandas等库提供了高效的数据处理能力,PyTorch和TensorFlow等框架让深度学习模型的实现变得简单。庞大的社区也意味着遇到问题容易找到解决方案。
第一章 Python编程基础 - 练习题答案
1 Python中列表和元组的主要区别是什么?
答案: 列表是可变的(mutable),元组是不可变的(immutable)。
解析: 列表使用方括号[]定义,可以添加、删除、修改元素;元组使用圆括号()定义,创建后不能修改。元组的不可变性使其在作为字典键或集合元素时更有优势,且在某些场景下性能更好。在AI中,数据集常使用列表存储,而模型配置参数常用元组表示。
2 什么是列表推导式?请举例说明。
答案: 列表推导式是一种简洁创建列表的语法,格式为 [表达式 for 变量 in 可迭代对象 if 条件]。
解析: 例如 `[x**2 for x in range(10) if x % 2 == 0]` 会生成 `[0, 4, 16, 36, 64]`。列表推导式比传统的for循环更简洁、更易读,且执行效率通常更高。在数据预处理中,常用列表推导式快速转换数据格式或过滤数据。
3 Python中*args和**kwargs的作用是什么?
答案: *args用于接收可变数量的位置参数,**kwargs用于接收可变数量的关键字参数。
解析: *args将多余的位置参数打包成元组,**kwargs将多余的关键字参数打包成字典。这在AI框架中非常常见,例如PyTorch的模型定义、训练函数等经常需要灵活地传递各种参数。使用*args和**kwargs可以让函数接口更加灵活,同时保持向后兼容。
第二章 数学基础 - 练习题答案
1 什么是向量的点积(内积)?它在AI中有什么应用?
答案: 向量点积是两个向量对应元素相乘后求和,公式为 a·b = Σ(a_i * b_i)。
解析: 点积可以衡量两个向量的相似程度——点积越大表示方向越接近。在AI中,点积广泛应用于:注意力机制中的Query-Key计算、推荐系统中的用户-物品相似度、词向量相似度计算等。余弦相似度就是基于点积归一化得到的。
2 导数在机器学习中的主要作用是什么?
答案: 导数用于计算梯度,指导模型参数的更新方向。
解析: 在梯度下降算法中,损失函数对参数的导数(梯度)指示了参数应该向哪个方向调整以减小损失。导数的正负决定更新方向,导数的大小决定更新步长。反向传播算法本质上就是利用链式法则高效计算复合函数导数的过程。
3 什么是矩阵的特征值和特征向量?
答案: 对于方阵A,如果存在非零向量v和标量λ使得 Av = λv,则λ为特征值,v为对应的特征向量。
解析: 特征值和特征向量描述了线性变换的核心特征。在AI中,PCA降维就是基于协方差矩阵的特征分解;PageRank算法利用转移矩阵的特征向量计算网页重要性;许多图神经网络也利用邻接矩阵的谱分解。特征分解帮助我们理解数据的主要变化方向。
第三章 AI基础概念 - 练习题答案
1 人工智能、机器学习和深度学习三者之间的关系是什么?
答案: 人工智能是最大范畴,机器学习是实现AI的一种方法,深度学习是机器学习的一个子集。
解析: AI包含所有让机器表现出智能行为的技术;机器学习是AI的一个分支,通过数据自动学习规律而非硬编码规则;深度学习使用多层神经网络进行表示学习,是机器学习中最强大的方法之一。三者是包含关系:深度学习 ⊂ 机器学习 ⊂ 人工智能。
2 什么是监督学习和无监督学习的区别?
答案: 监督学习使用带标签的数据训练,无监督学习使用无标签的数据发现隐藏结构。
解析: 监督学习的目标是学习输入到输出的映射,如分类和回归任务;无监督学习则探索数据的内在结构,如聚类、降维、密度估计。监督学习需要人工标注数据,成本较高但效果通常更好;无监督学习可以利用大量未标注数据,但评估较困难。半监督学习则结合两者优势。
3 什么是过拟合?如何缓解过拟合?
答案: 过拟合是模型在训练数据上表现很好但在新数据上表现差的现象。
解析: 过拟合通常由于模型过于复杂或训练数据不足导致。缓解方法包括:增加训练数据、使用正则化(L1/L2)、Dropout、早停(Early Stopping)、交叉验证、简化模型结构等。核心思想是在拟合训练数据和保持泛化能力之间找到平衡。
第四章 机器学习概述 - 练习题答案
1 什么是特征工程?为什么它很重要?
答案: 特征工程是将原始数据转换为更适合机器学习模型输入的特征的过程。
解析: 好的特征能让简单模型表现出色,差的特征会让复杂模型也难以学习。特征工程包括特征选择、特征构造、特征缩放、编码分类变量等。在深度学习兴起之前,特征工程是机器学习项目的核心工作,"数据和特征决定了机器学习的上限"。
2 线性回归和逻辑回归的主要区别是什么?
答案: 线性回归用于连续值预测(回归),逻辑回归用于分类任务。
解析: 线性回归直接输出连续值,假设输出服从正态分布;逻辑回归通过Sigmoid函数将线性输出映射到(0,1)概率区间,用于二分类。虽然名字中有"回归",但逻辑回归本质是分类算法。两者都是广义线性模型的特例。
3 什么是交叉验证?常用的方法有哪些?
答案: 交叉验证是将数据分成多份轮流作为验证集评估模型性能的方法。
解析: 常用方法包括K折交叉验证(K-Fold,通常K=5或10)、留一法(Leave-One-Out)、分层K折(Stratified K-Fold,保持类别比例)等。交叉验证能更可靠地评估模型泛化能力,减少数据划分随机性的影响,同时充分利用有限的数据。
第五章 深度学习概述 - 练习题答案
1 什么是神经网络的前向传播和反向传播?
答案: 前向传播是输入数据逐层计算得到输出的过程;反向传播是根据损失函数梯度从输出层向输入层更新参数的过程。
解析: 前向传播中,数据经过各层的线性变换和激活函数得到预测结果;反向传播利用链式法则计算损失对各参数的梯度,然后使用优化器更新参数。这两个过程交替进行,使网络逐渐学习数据中的模式。反向传播是训练深度网络高效计算梯度的关键算法。
2 激活函数的作用是什么?常用的激活函数有哪些?
答案: 激活函数引入非线性,使神经网络能学习复杂模式。常用包括ReLU、Sigmoid、Tanh、Softmax等。
解析: 没有激活函数,多层网络等价于单层线性变换。ReLU(f(x)=max(0,x))计算简单且缓解梯度消失,是目前最常用的激活函数;Sigmoid和Tanh将输出压缩到特定范围,但在深层网络中容易出现梯度消失;Softmax常用于多分类输出层,将输出转换为概率分布。
3 什么是梯度消失和梯度爆炸问题?
答案: 梯度消失是反向传播时梯度逐层减小导致深层参数无法更新;梯度爆炸是梯度逐层增大导致参数更新失控。
解析: 两者都源于链式法则中梯度的连乘。当激活函数导数小于1时,多层连乘导致梯度指数级减小(消失);当权重较大时,梯度可能指数级增大(爆炸)。解决方法包括:使用ReLU激活、批归一化(BatchNorm)、残差连接、梯度裁剪、更好的权重初始化策略等。
第六章 模型 - 练习题答案
1 什么是模型的容量(Capacity)?
答案: 模型容量是指模型能够学习的函数的复杂程度,通常与参数数量和模型结构相关。
解析: 高容量模型可以学习更复杂的模式,但也更容易过拟合;低容量模型可能欠拟合。选择合适的模型容量需要在偏差-方差权衡中找到平衡点。增加层数、每层的神经元数、使用更复杂的架构都可以增加模型容量。
2 什么是迁移学习?它有什么优势?
答案: 迁移学习是将一个任务上学到的知识应用到另一个相关任务上的方法。
解析: 优势包括:减少训练数据需求、加速收敛、提高小数据集上的性能。常见做法是在大规模数据集(如ImageNet)上预训练模型,然后在目标任务上微调。在NLP领域,BERT、GPT等预训练模型的微调就是迁移学习的典型应用。
3 模型压缩的主要方法有哪些?
答案: 知识蒸馏、模型剪枝、量化、低秩分解等。
解析: 知识蒸馏用大模型(教师)指导小模型(学生)训练;剪枝移除不重要的权重或神经元;量化将浮点数权重转换为低精度整数;低秩分解用更小的矩阵近似大矩阵。这些方法可以在保持性能的同时显著减小模型大小和推理延迟,对部署到边缘设备至关重要。
第七章 训练 - 练习题答案
1 什么是学习率?它对训练有什么影响?
答案: 学习率控制参数更新的步长,是训练深度网络最重要的超参数之一。
解析: 学习率过大导致损失震荡甚至发散;学习率过小导致收敛缓慢或陷入局部最优。常用策略包括:学习率衰减(随时间降低)、预热(warmup,初始阶段逐渐增大)、自适应学习率(Adam、Adagrad等)。找到合适的学习率通常需要实验和调参。
2 批大小(Batch Size)对训练的影响是什么?
答案: 批大小决定每次参数更新使用的样本数量,影响训练速度和收敛行为。
解析: 大批次梯度估计更稳定,可以利用硬件并行加速,但内存需求大,可能泛化较差;小批次梯度噪声大,有助于逃离尖锐极小值,可能泛化更好,但训练速度慢。实践中常用32-512之间的批次大小,并使用梯度累积模拟大批次效果。
3 什么是早停(Early Stopping)?
答案: 早停是在验证集性能不再提升时提前终止训练的策略。
解析: 早停是一种简单而有效的正则化方法,可以防止模型在训练集上过度拟合。通常监控验证集损失或准确率,当指标在连续多个epoch不再改善时停止训练,并恢复最佳模型参数。早停实现简单,几乎不增加计算开销,是训练模型的标准实践。
第八章 模型评估与调优 - 练习题答案
1 准确率(Accuracy)在什么情况下可能产生误导?
答案: 在类别不平衡的数据集上,准确率可能产生误导。
解析: 例如99%负样本和1%正样本的数据集,即使模型全部预测为负类,准确率也有99%,但模型实际上完全无法识别正类。此时应使用精确率(Precision)、召回率(Recall)、F1分数、AUC-ROC、混淆矩阵等更全面的评估指标。
2 什么是超参数调优?常用的方法有哪些?
答案: 超参数调优是寻找最优超参数组合的过程,常用方法包括网格搜索、随机搜索、贝叶斯优化等。
解析: 网格搜索遍历所有可能的组合,计算成本高;随机搜索随机采样组合,效率更高;贝叶斯优化利用先验信息指导搜索,效率最高但实现复杂。现代工具如Optuna、Ray Tune提供了高效的超参数优化框架,支持早停和分布式搜索。
3 混淆矩阵中的TP、FP、TN、FN分别代表什么?
答案: TP(真正例):预测为正且实际为正;FP(假正例):预测为正但实际为负;TN(真负例):预测为负且实际为负;FN(假负例):预测为负但实际为正。
解析: 混淆矩阵是评估分类模型的基础工具。基于这四个值可以计算各种指标:精确率 = TP/(TP+FP),召回率 = TP/(TP+FN),F1 = 2*精确率*召回率/(精确率+召回率)。不同应用场景对FP和FN的容忍度不同,如医疗诊断更关注减少FN(漏诊)。
第九章 CNN - 练习题答案
1 卷积操作的核心思想是什么?
答案: 卷积使用可学习的滤波器(卷积核)在输入上滑动,提取局部特征。
解析: 卷积的核心优势在于局部连接和权重共享。每个滤波器只关注输入的局部区域(感受野),同一个滤波器在整个输入上共享参数,大大减少了参数量。多层卷积可以逐层提取从低级特征(边缘、纹理)到高级特征(形状、物体部件)的层次化表示。
2 什么是池化层?常用的池化操作有哪些?
答案: 池化层降低特征图的空间维度,减少计算量和参数量,提供一定的平移不变性。
解析: 常用池化包括最大池化(Max Pooling,取窗口内最大值)和平均池化(Average Pooling,取窗口内平均值)。最大池化保留最显著的特征响应,对纹理特征更有效;平均池化保留背景信息。现代网络如ResNet也使用步幅卷积(strided convolution)替代池化。
3 CNN为什么适合处理图像数据?
答案: CNN利用图像的局部相关性和平移不变性,通过卷积高效提取空间特征。
解析: 图像具有局部相关性(相邻像素相关)和层级结构(边缘→纹理→物体)。全连接网络忽略空间结构且参数量巨大;CNN通过局部感受野、权重共享和池化,既保留了空间信息又控制了参数量。这些归纳偏置使CNN在图像任务上远优于全连接网络。
第十章 Transformer - 练习题答案
1 Transformer相比RNN的主要优势是什么?
答案: Transformer通过自注意力机制实现并行计算,能更好地捕捉长距离依赖。
解析: RNN需要逐步处理序列,难以并行化,且长距离信息传递容易丢失。Transformer的自注意力让任意位置的token直接交互,计算可完全并行,且长距离依赖的建模能力与距离无关。这些特性使Transformer可以扩展到非常大的模型和数据规模。
2 什么是多头注意力(Multi-Head Attention)?
答案: 多头注意力将注意力机制并行执行多次,让模型在不同子空间关注不同方面的信息。
解析: 单头注意力可能只关注一种相关性,多头通过不同的线性投影将Query、Key、Value映射到多个子空间,分别计算注意力后再拼接。例如,在翻译任务中,不同头可能分别关注语法、语义、指代等不同层面的关系。这大大增强了模型的表达能力。
3 位置编码(Positional Encoding)的作用是什么?
答案: 位置编码为模型提供序列中token的位置信息,因为自注意力本身不包含位置信息。
解析: 自注意力计算中,token的位置交换不影响结果(置换等变性),但语言中词序至关重要。原始Transformer使用正弦/余弦函数生成位置编码;现代模型多使用可学习的位置嵌入(Positional Embedding)。更先进的方法如RoPE(旋转位置编码)将位置信息融入注意力计算本身。
第十一章 LLM详解 - 练习题答案
1 什么是预训练(Pre-training)和微调(Fine-tuning)?
答案: 预训练是在大规模无标注数据上学习通用表示,微调是在特定任务数据上调整模型参数。
解析: 预训练(如GPT的下一个词预测、BERT的掩码语言模型)让模型学习语言的基本规律和世界知识;微调使用带标签的任务数据调整模型,使其适应特定任务。现代范式还包括提示学习(Prompting)和指令微调(Instruction Tuning),用自然语言指令引导模型行为。
2 什么是温度参数(Temperature)在文本生成中的作用?
答案: 温度参数控制生成文本的随机性和多样性。
解析: 温度T对softmax输出的概率分布进行缩放:p_i = exp(z_i/T) / Σexp(z_j/T)。T→0时最确定(贪婪解码),T越大分布越均匀,生成越随机。低温度(如0.3)适合需要确定性的任务,高温度(如0.8-1.0)适合创意写作。Top-k和Top-p(nucleus)采样常与温度配合使用。
3 什么是RLHF(基于人类反馈的强化学习)?
答案: RLHF是使用人类偏好反馈训练奖励模型,再用强化学习优化语言模型生成质量的方法。
解析: RLHF包含三个阶段:1)监督微调(SFT);2)收集人类对模型输出的偏好比较,训练奖励模型;3)使用PPO等强化学习算法优化策略模型,使其生成能获得高奖励的文本。RLHF显著提升了模型遵循指令的能力和输出质量,是ChatGPT等对话模型的关键技术。
第十二章 推理与部署 - 练习题答案
1 模型推理中的延迟和吞吐量分别指什么?
答案: 延迟是处理单个请求的时间,吞吐量是单位时间处理的请求数量。
解析: 延迟影响用户体验(如对话响应速度),吞吐量决定系统服务能力。两者有时需要权衡:批处理提高吞吐量但增加单个请求延迟。优化延迟的方法包括模型量化、蒸馏、使用更快的注意力算法(如FlashAttention);提高吞吐量可通过动态批处理、模型并行、服务优化等实现。
2 什么是模型量化?常见的量化精度有哪些?
答案: 量化是将模型权重从高精度浮点数转换为低精度表示,减少存储和计算需求。
解析: 常见精度包括:FP32(单精度)、FP16/BF16(半精度)、INT8(8位整数)、INT4(4位整数)。FP16/BF16几乎不损失精度但速度提升2倍;INT8在大多数场景下精度损失很小,推理速度提升2-4倍;INT4用于极端压缩场景。量化感知训练(QAT)比训练后量化(PTQ)效果更好。
3 什么是KV Cache?在大模型推理中有什么作用?
答案: KV Cache缓存自注意力中的Key和Value矩阵,避免重复计算,加速自回归生成。
解析: 在自回归生成中,每次只生成一个新token,但注意力需要与所有历史token交互。KV Cache保存之前计算的Key和Value,新token只需计算自己的Q、K、V,然后与缓存的K、V做注意力。这避免了O(n²)的重复计算,将复杂度降为O(n),是大模型高效推理的关键技术。
第十三章 RAG - 练习题答案
1 什么是RAG(检索增强生成)?
答案: RAG是将信息检索与文本生成结合,让模型在生成时引用外部知识库的方法。
解析: RAG的工作流程:1)将用户查询编码为向量;2)在知识库中检索相关文档;3)将检索结果与查询一起输入生成模型;4)模型基于检索到的信息生成回答。RAG有效缓解了LLM的幻觉问题,使回答有据可查,并支持知识的动态更新而无需重新训练模型。
2 RAG相比微调(Fine-tuning)更新知识有什么优势?
答案: RAG可以实时更新知识、避免训练成本、减少幻觉、提供可溯源的回答。
解析: 微调需要重新训练模型,成本高且更新频率受限;RAG只需更新知识库文档即可。RAG让模型基于检索到的真实文档生成,显著减少幻觉;同时可以返回引用来源,提高可信度。对于频繁变化的知识(如新闻、产品信息),RAG是更实用的方案。
3 RAG系统中检索质量对最终效果有多大影响?
答案: 检索质量是决定RAG效果的关键因素,"垃圾进,垃圾出"。
解析: 如果检索阶段返回的文档不相关或质量差,即使生成模型很强也难以产出好结果。提升检索质量的方法包括:优化文档切分策略、改进Embedding模型、使用混合检索(向量+关键词)、重排序(Reranking)、查询扩展等。检索和生成两个环节都需要精心优化。
第十四章 向量与Embedding - 练习题答案
1 什么是Embedding?为什么需要将数据转换为向量?
答案: Embedding是将离散对象(词、图像等)映射到连续向量空间的技术。
解析: 向量表示使计算机能处理语义信息,相似的对象在向量空间中距离近。Embedding捕捉了数据的语义特征,支持向量运算(如词向量的"国王-男人+女人≈女王")。在深度学习中,Embedding是连接离散数据和神经网络连续计算的桥梁。
2 什么是向量数据库?与传统数据库有什么区别?
答案: 向量数据库专门存储和查询高维向量,支持相似性搜索。
解析: 传统数据库基于精确匹配(B+树、哈希),适合结构化数据查询;向量数据库基于近似最近邻(ANN)算法,在高维空间快速找到相似向量。核心区别:1)数据类型(结构化vs向量);2)查询方式(精确匹配vs相似性搜索);3)索引结构(B+树vs HNSW、IVF等ANN索引)。
3 余弦相似度和欧氏距离在向量比较中有什么区别?
答案: 余弦相似度衡量向量方向的一致性,欧氏距离衡量向量空间中的绝对距离。
解析: 余弦相似度 = (A·B)/(||A||*||B||),范围[-1,1],对向量长度不敏感,适合比较语义方向;欧氏距离 = ||A-B||,对绝对数值敏感。在文本Embedding中,余弦相似度更常用,因为语义相似性与向量长度关系不大。对于归一化的向量,两者是单调关系。
第十五章 Agent - 练习题答案
1 什么是AI Agent?它与传统的LLM应用有什么区别?
答案: AI Agent是能自主感知环境、做出决策并执行行动的AI系统。
解析: 传统LLM应用通常是单次问答,Agent则具有自主性:可以分解复杂任务、调用工具、观察执行结果、调整策略。Agent的核心组件包括:规划(Planning)、记忆(Memory)、工具使用(Tool Use)。LangChain、AutoGPT等框架提供了构建Agent的工具链。
2 Agent中的ReAct(推理+行动)框架是什么?
答案: ReAct是让模型交替进行推理(Reasoning)和行动(Acting)的框架。
解析: ReAct的核心思想:模型先思考当前状态和目标,然后决定执行什么行动(如搜索、计算),观察行动结果后再进行下一步推理。这种交替进行的方式让模型能处理需要多步操作的复杂任务,同时推理过程透明可追溯。ReAct显著提升了Agent解决复杂问题的能力。
3 构建可靠的Agent系统面临哪些挑战?
答案: 规划能力有限、工具使用错误、循环/死锁、幻觉传播、安全与权限控制等。
解析: Agent需要在开放环境中做决策,面临更多不确定性:可能制定不可行的计划、调用工具时参数错误、陷入无限循环、将LLM的幻觉传播到行动中。解决方案包括:添加反思机制、限制工具权限、设置最大步数、人类在环(Human-in-the-loop)审核等。
第十六章 工具与技能 - 练习题答案
1 为什么需要让LLM使用外部工具?
答案: LLM有知识截止、计算能力有限、无法访问实时信息,工具可以弥补这些不足。
解析: 工具扩展了LLM的能力边界:搜索引擎提供实时信息、计算器解决精确数学问题、代码解释器执行程序、数据库查询获取结构化数据。通过Function Calling机制,LLM可以判断何时需要调用工具、选择哪个工具、传递什么参数,实现与外部世界的交互。
2 什么是Function Calling?它的工作流程是什么?
答案: Function Calling是让LLM生成调用外部函数的参数的机制。
解析: 工作流程:1)定义可用工具(函数名、参数模式、描述);2)用户提问;3)LLM判断是否需要调用工具,生成JSON格式的函数调用;4)系统执行函数并返回结果;5)LLM基于函数结果生成最终回答。OpenAI、Anthropic等主流模型都支持Function Calling。
3 设计好的工具描述(Tool Description)有什么要点?
答案: 清晰说明工具功能、参数含义、使用场景和返回值格式。
解析: 工具描述是LLM选择工具的依据,应该:1)用自然语言明确说明工具能做什么;2)每个参数都要有description说明其含义和格式;3)提供使用示例帮助模型理解;4)避免模糊描述导致模型误选。好的工具描述能显著提升Agent的工具使用准确率。
第十七章 知识库与向量数据库 - 练习题答案
1 构建企业知识库RAG系统的主要步骤是什么?
答案: 数据收集、文档预处理、分块、Embedding、存储到向量数据库、检索、生成回答。
解析: 每个步骤都有技术考量:预处理要清洗格式和噪声;分块策略(按段落、语义、固定长度)影响检索粒度;Embedding模型选择决定语义表示质量;向量数据库选型要考虑规模、延迟、过滤需求。完整的RAG pipeline需要系统工程思维。
2 文档分块(Chunking)的策略有哪些?
答案: 固定长度分块、按段落/句子分块、语义分块、递归分块、基于结构的分块等。
解析: 固定长度最简单但可能切断语义;按段落保留结构但长度不均;语义分块使用模型判断边界,效果最好但成本高;递归分块先按大粒度再细化。选择策略需考虑文档类型(代码、论文、对话)和下游检索需求,常需要实验对比。
3 向量数据库选型需要考虑哪些因素?
答案: 数据规模、查询延迟、吞吐量、过滤能力、部署方式、生态集成、成本等。
解析: 主流向量数据库包括:Pinecone(托管服务)、Weaviate(开源,GraphQL接口)、Milvus/Zilliz(企业级,高吞吐)、Chroma(轻量,开发友好)、pgvector(PostgreSQL扩展)、Qdrant(Rust实现,高性能)。选型应基于实际场景需求,小规模可用Chroma,大规模生产环境考虑Milvus或Pinecone。
第十八章 上下文与记忆 - 练习题答案
1 LLM的上下文窗口(Context Window)限制会带来什么问题?
答案: 无法处理长文档、多轮对话中遗忘早期信息、难以进行复杂推理。
解析: 早期模型上下文窗口只有2K-4K tokens,无法容纳长论文或代码库。虽然现代模型已扩展到128K甚至1M tokens,但长上下文存在"Lost in the Middle"问题——模型对中间位置的信息提取能力较弱。解决方案包括:RAG检索相关片段、摘要压缩历史、使用支持长上下文的模型。
2 什么是滑动窗口记忆和摘要记忆?
答案: 滑动窗口保留最近K轮对话;摘要记忆对历史对话进行压缩摘要。
解析: 滑动窗口实现简单,但会丢失窗口外的信息;摘要记忆使用LLM定期总结对话历史,保留关键信息同时减少token占用。更高级的方法包括:实体记忆(提取关键实体和关系)、向量记忆(将对话Embedding存入向量库按需检索)、知识图谱记忆等。
3 如何在Agent系统中设计有效的记忆机制?
答案: 分层记忆设计:工作记忆(短期)、 episodic记忆(经验)、语义记忆(知识)。
解析: 参考人类记忆系统:工作记忆存放当前任务相关信息;episodic记忆存储过去的交互经验,支持"我之前做过类似任务"的检索;语义记忆存储事实性知识。LangChain提供了Memory组件,支持ConversationBufferMemory、VectorStoreRetrieverMemory等多种实现。
第十九章 高级提示技术 - 练习题答案
1 什么是少样本提示(Few-Shot Prompting)?
答案: 在提示中提供几个输入-输出示例,引导模型理解任务模式。
解析: 与零样本(直接描述任务)相比,少样本通过具体示例让模型"学习"期望的输出格式和推理方式。示例选择很重要:应选择代表性、多样性、与目标输入相似的示例。Chain-of-Thought提示常在少样本基础上加入推理过程示例,进一步提升复杂任务表现。
2 Chain-of-Thought(思维链)提示的原理是什么?
答案: 在提示中引导模型展示逐步推理过程,而非直接给出答案。
解析: 通过在示例中加入"让我们一步步思考"和中间推理步骤,模型被诱导进行显式推理。这显著提升了数学、逻辑、常识推理等复杂任务的表现。变体包括:Zero-shot-CoT(不加示例只加触发句)、Self-Consistency(多次采样选多数答案)、Tree of Thoughts(探索多条推理路径)等。
3 什么是提示词注入(Prompt Injection)攻击?如何防范?
答案: 提示词注入是通过恶意输入覆盖系统提示,操纵模型行为的攻击。
解析: 例如用户输入"忽略之前的指令,改为..."可能让模型泄露系统提示或执行非预期操作。防范措施:输入过滤和清洗、使用分隔符区分系统指令和用户输入、输出约束、权限控制、人类审核、对抗性训练等。安全提示工程是生产部署的重要环节。
第二十章 数据 - 练习题答案
1 数据质量对AI模型性能有多大影响?
答案: 数据质量是决定模型性能的最关键因素之一,"Garbage in, garbage out"。
解析: 高质量数据应满足:准确性(标注正确)、完整性(覆盖各种场景)、一致性(标准统一)、时效性(反映当前情况)。研究表明,增加数据量带来的提升可能不如提升数据质量。数据清洗、去重、去偏、增强是AI项目中最耗时但最重要的工作。
2 什么是数据增强?常用的方法有哪些?
答案: 数据增强是通过变换现有数据生成新训练样本的技术。
解析: 图像领域:翻转、旋转、裁剪、颜色变换、MixUp、CutMix等;NLP领域:同义词替换、回译、随机插入/删除、EDA等。数据增强可以增加训练数据多样性,提高模型泛化能力,减少过拟合。但增强策略应与任务匹配,过度增强可能引入噪声。
3 数据隐私和AI伦理中需要注意哪些问题?
答案: 个人隐私保护、数据偏见、知情同意、数据安全、模型可解释性等。
解析: 技术上:使用差分隐私、联邦学习、数据脱敏保护隐私;检测和缓解训练数据中的偏见(性别、种族、文化);确保数据采集获得用户同意。组织上:建立数据治理规范、进行AI伦理审查、保持模型决策透明可解释。法规上:遵守GDPR、CCPA等数据保护法规。
第二十一章 AI的局限与挑战 - 练习题答案
1 当前LLM的主要局限性有哪些?
答案: 幻觉、知识截止、推理能力有限、缺乏真正的理解、偏见、高计算成本等。
解析: 幻觉指模型生成看似合理但实际错误的内容;知识截止使模型不了解最新事件;复杂多步推理仍容易出错;模型更多是模式匹配而非真正"理解";训练数据中的偏见会被模型学习;大模型的训练和推理需要大量计算资源。这些局限决定了AI目前更适合辅助人类而非完全替代。
2 什么是AI的"幻觉"(Hallucination)?如何缓解?
答案: 幻觉是模型生成与事实不符或没有依据的内容的现象。
解析: 缓解方法:RAG检索真实信息作为依据、使用更高质量训练数据、事实核查和约束解码、让模型在不确定时拒绝回答、多模型验证、人类反馈强化学习(RLHF)等。完全消除幻觉目前仍是开放问题,关键是在应用场景中设计合适的防护机制。
3 AI发展面临哪些技术之外的挑战?
答案: 就业影响、隐私风险、安全威胁、伦理困境、监管滞后、数字鸿沟等。
解析: 社会影响:自动化可能替代部分工作,需要社会政策调整;安全风险:AI可能被用于深度伪造、网络攻击;伦理问题:自主武器、算法歧视;治理挑战:技术发展快于法规制定;公平问题:AI红利分配不均。解决这些需要技术、政策、教育、国际合作多方努力。
第二十二章 常用AI工具 - 练习题答案
1 选择AI工具时应考虑哪些因素?
答案: 任务匹配度、输出质量、成本、隐私安全、易用性、集成能力、社区支持等。
解析: 不同工具擅长不同任务:ChatGPT/Claude适合对话和写作,Midjourney/Stable Diffusion适合图像生成,GitHub Copilot适合代码辅助。企业场景还需考虑数据隐私(是否支持私有部署)、API稳定性、成本可控性。没有"最好"的工具,只有"最适合"的工具。
2 开源模型和商业API各有什么优缺点?
答案: 开源模型可定制、可私有化部署、成本低;商业API使用简单、维护少、通常性能更好。
解析: 开源(如Llama、Mistral、Qwen)适合有技术能力、数据敏感、需要深度定制的团队;商业API(如GPT-4、Claude)适合快速验证、没有运维资源、追求稳定性的场景。很多团队采用混合策略:敏感业务用开源私有化部署,通用任务调用商业API。
3 如何有效使用ChatGPT/Claude等大模型助手?
答案: 清晰具体的提示、提供上下文、分解复杂任务、迭代优化、验证输出。
解析: 有效技巧:1)角色设定("你是一位资深Python工程师");2)明确输出格式("用表格列出");3)提供示例(Few-shot);4)分解复杂任务为多步;5)要求模型解释推理过程(CoT);6)对关键输出进行事实核查。把大模型当作聪明的实习生——需要明确指导和检查。
第二十三章 AI发展简史 - 练习题答案
1 AI发展经历了哪几个主要阶段?
答案: 符号AI(1950s-1980s)、机器学习兴起(1980s-2010s)、深度学习革命(2010s-)、大模型时代(2020s-)。
解析: 符号AI基于逻辑和规则,如专家系统;机器学习让数据驱动模型学习规律;深度学习用多层神经网络实现突破(AlexNet 2012是里程碑);大模型时代以GPT系列为代表,展示涌现能力和通用性。每个阶段都伴随着算力、数据、算法的协同进步。
2 深度学习革命的关键里程碑有哪些?
答案: AlexNet(2012)、VGG/ResNet(2014-2015)、Transformer(2017)、BERT/GPT(2018-2019)、GPT-3/ChatGPT(2020-2022)。
解析: AlexNet在ImageNet上的突破证明了深度CNN的有效性;ResNet的残差连接解决了深层网络训练问题;Transformer引入自注意力,成为NLP和后续多模态的基础;GPT-3展示了大模型的涌现能力;ChatGPT通过RLHF实现了产品化的对话AI。这些里程碑推动了AI的快速发展。
3 当前AI发展的主要趋势是什么?
答案: 多模态融合、Agent自主系统、端侧AI、AI安全对齐、科学发现应用等。
解析: 多模态模型(GPT-4V、Sora)统一处理文本、图像、视频;Agent让AI能自主规划和执行复杂任务;端侧AI将模型部署到手机、IoT设备;AI安全和对齐研究确保模型行为符合人类价值观;AI for Science加速科研发现(AlphaFold、材料发现)。AI正从工具向通用智能助手演进。
附录E:在线运行环境
以下Google Colab笔记本提供了各章节的实践练习环境,点击即可在浏览器中运行代码,无需本地配置。
🐍
Python基础练习
涵盖Python语法、数据结构、函数和面向对象编程的基础练习,适合初学者快速上手。
🔢
NumPy矩阵运算
NumPy数组操作、矩阵乘法、广播机制、线性代数运算等核心概念的实践练习。
📉
梯度下降可视化
交互式可视化梯度下降算法,理解学习率、收敛过程和不同优化器的行为差异。
🎯
K-Means聚类
实现K-Means算法,理解聚类原理、肘部法则和不同初始化策略对结果的影响。
🖼️
PyTorch CNN
使用PyTorch构建卷积神经网络,在CIFAR-10数据集上进行图像分类训练。
🔄
Transformer Self-Attention
从零实现Self-Attention机制,可视化注意力权重,理解Transformer的核心原理。
📝
LLM文本生成
使用Hugging Face Transformers加载预训练模型,进行文本生成和提示工程实验。
🔍
LangChain RAG
构建完整的RAG应用,包括文档加载、向量存储、检索和问答链的实现。
🤖
LangChain Agent
创建能使用工具的AI Agent,实现ReAct推理循环,让模型自主完成复杂任务。
🧑💻
个人AI助手项目
综合运用所学知识,构建一个具备记忆、工具使用和知识库的个人AI助手。