深度学习

深度学习简介

1.1 什么是深度学习

  • 定义:深度学习(Deep Learning)是机器学习的分支,是一种以人工神经网络为架构对数据进行特征学习的算法。其中的”深度”指网络中使用多层结构。
  • 核心思想:通过模仿人脑的神经网络来处理和分析复杂的数据,从大量数据中自动提取复杂特征,擅长处理高维数据(图像、语音、文本)。
  • 与机器学习/人工智能的关系:机器学习是实现人工智能的一种途径;深度学习是机器学习的一个子集,是实现机器学习的一种方法。

1.2 与传统机器学习的区别

对比项传统机器学习深度学习
特征提取依赖人工设计特征并进行特征提取不需要人工,依赖算法自动提取特征
网络结构一般无多层神经网络结构多层人工神经网络,逐层非线性变换
数据要求相对较小需要大量标注数据 + 强大计算资源(GPU)
可解释性较好差,被称为”黑箱”

1.3 深度学习四大特点

  1. 多层非线性变换:模型由多个层次组成,每层应用非线性激活函数对输入变换。低层捕捉简单特征(边缘、颜色),高层识别复杂模式(物体、面部)。
  2. 自动特征提取:无需人工特征工程,自动从原始数据学习特征。
  3. 大数据和计算能力:需要大量标注数据和 GPU 等计算资源。
  4. 可解释性差:内部机制不透明,被称为”黑箱”。

1.4 常见的深度学习模型

  • CNN(卷积神经网络):主要用于图像处理(图像分类、目标检测、图像分割);用卷积层自动提取局部特征,池化层减少参数提高效率。
  • RNN(循环神经网络):处理序列数据(NLP、语音识别);有记忆功能、可处理时间依赖性,但标准 RNN 难以捕捉长期依赖
  • 自编码器(Autoencoders):无监督学习模型,用于降维、特征学习、异常检测;由编码器(压缩为低维表示)和解码器(从低维重建原始输入)组成。
  • GAN(生成对抗网络):由生成器和判别器两个子网络组成;生成器创建逼真假样本,判别器区分真假;用于图像生成、视频合成。
  • Transformer:主要用于 NLP(机器翻译、文本生成);摒弃递归结构,采用自注意力机制(self-attention),可并行处理整个句子。
  • 其他(PPT 补充):深度强化学习(DRL)、图神经网络(GNN)。

1.5 应用场景

  • 计算机视觉:图像分类(人脸识别、医疗影像病变检测)、目标检测(自动驾驶行人检测、监控入侵检测)、面部识别(手机解锁)、图像生成(风格迁移、老照片修复)。
  • 自然语言处理:机器翻译(Google 翻译)、情感分析(社交媒体监控)、文本生成(写作助手)、语音识别(Siri/Alexa)、聊天机器人(客服机器人、GPT 类虚拟助手)。
  • 推荐系统:电影/音乐推荐(Netflix、Spotify)、电商推荐(亚马逊、淘宝)、社交媒体推荐(Facebook、Instagram)。
  • 其他:自动驾驶、医疗健康、工业与制造业、语音与音频处理。

1.6 发展历史与里程碑

人工智能三次浪潮(PPT):

  • 第一次浪潮(1950s–1970s 符号主义):1950 图灵设计国际象棋程序;1962 IBM Arthur Samuel 跳棋程序战胜人类高手。
  • 第二次浪潮(1980s–2000 统计主义):1993 Vapnik 提出 SVM;1997 IBM 深蓝战胜卡斯帕罗夫。
  • 第三次浪潮(2012–2016 神经网络):2012 AlexNet;2016 Google AlphaGo 战胜李世石(深度学习/深度强化学习进入公众视野)。
  • 大规模预训练模型(2017 至今):2017 Transformer;2018 BERT 和 GPT;2022 ChatGPT 进入大模型 AIGC 阶段。

深度学习自身发展史

  • 早期探索(1940s–1980s):20 世纪 40 年代皮茨(Walter Pitts)和麦卡洛克(Warren McCulloch)提出 McCulloch-Pitts 神经元;1958 罗森布拉特(Frank Rosenblatt)提出感知器(简单二分类);1960 年代末出现多层感知器(MLP),受限于计算能力和数据量。
  • 挑战与瓶颈(1980s–1990s):1986 年反向传播(Backpropagation)算法提出(Hinton、Rumelhart 等人),使多层网络可通过梯度下降优化参数解决非线性问题;但因计算资源限制,SVM、决策树成为主流。
  • 复兴与突破(2000s–2010s)
    • 2006 年 Hinton 团队提出深度信念网络(DBN),引入无监督预训练,标志深度学习复兴。
    • 2012 年 AlexNet(Alex Krizhevsky)在 ImageNet 图像分类竞赛显著提升精度(比传统方法提高 20% 以上),深度学习开山之作。
    • 2014 年 GANs(Ian Goodfellow 等人)提出,开启生成模型新时代。
    • 2015 年 ResNet(何凯明)提出,通过残差连接解决深层网络的梯度消失/爆炸,可训练 50/152 层极深网络。
  • 爆发期(2016 至今):2016 AlphaGo;2017 Transformer;2018 BERT/GPT;2022 ChatGPT。

1.7 容易考的点

  • 深度学习与传统机器学习的本质区别 → 自动特征提取 vs 人工特征工程
  • “深度”的含义 → 网络中使用多层(隐藏层数量决定深度)。
  • 深度学习被称为”黑箱”的原因 → 可解释性差。
  • 各里程碑人物/年份对应关系:1986 BP 算法、2006 DBN、2012 AlexNet、2014 GAN、2015 ResNet、2017 Transformer、2022 ChatGPT。
  • AlexNet 的意义 → 深度学习在计算机视觉领域的开山之作;ResNet 的意义 → 解决梯度消失/爆炸,允许训练极深网络。

二、PyTorch 框架

2.1 PyTorch 简介与特点

  • 定义:PyTorch 是基于 Python 语言的深度学习框架,将数据封装成张量(Tensor)处理;提供构建、训练、部署 ML/DL 模型的工具;广泛应用于 CV、NLP、强化学习。
  • 安装:pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple
  • 六大特点:
    1. 类似 NumPy 的张量计算:基本数据结构为 Tensor,具有 GPU 加速(CUDA) 能力。
    2. 自动微分系统(autograd):自动计算每个参数的梯度,支持动态计算图。
    3. 深度学习库 torch.nn:预构建层(全连接、卷积、RNN 等)、损失函数(交叉熵、MSE)、优化算法(SGD、Adam);nn.Module 是构建神经网络的基础类。
    4. 动态计算图:运行时构建和修改模型结构,灵活、易调试。
    5. GPU 加速tensor.to(device) 轻松在 CPU/GPU 间转移数据和模型。
    6. 跨平台支持:CPU/GPU/TPU、Linux/Windows/macOS、多 GPU/分布式训练。
  • 与 TensorFlow 对比:PyTorch 基于动态图,TensorFlow 1.x 基于静态计算图(TF 2.x 支持动态图);PyTorch 更灵活易调试,API 更贴近 Python,在学术界更流行。
  • 发展历史:Torch(Ronan Collobert 等人)→ Torch7(Lua)→ 2016 PyTorch 0.1.0(FAIR,Facebook 人工智能研究院)→ 0.2.0 引入动态图(制胜 TensorFlow 的关键)→ 2018 1.0(首个稳定版,Eager 模式)→ 2.0(torch.compile 加速、TorchDynamo 替换 torch.jit.trace/script)。
  • 课堂笔记补充:pytorch 已更新到 2.5 版本;可在 GPU/TPU/NPU 上运行。

2.2 张量(Tensor)基础

2.2.1 什么是张量

  • 张量 = 元素为同一种数据类型的多维矩阵(与 NumPy 数组类似),以”类”的形式封装运算方法。
  • 0 维=标量;1 维=向量/矢量;2 维=矩阵;多个二维张量组成三维张量,依此类推。
  • 默认数据类型:float32(torch.FloatTensor)

2.2.2 张量创建(核心 API)

API作用要点
torch.tensor(data=, dtype=)按指定数据创建numpy(float64) 传入则张量为 float64;列表默认 float32
torch.Tensor(size=)按形状创建(也可按数据)只给形状时内存未初始化(垃圾值)
torch.IntTensor/FloatTensor/DoubleTensor/ShortTensor/LongTensor()创建指定类型张量元素类型不正确会自动类型转换(如 2.5→2 截断)
torch.arange(start=, end=, step=)固定步长线性张量左闭右开 [start, end)
torch.linspace(start=, end=, steps=)固定元素数线性张量左闭右闭;step=(end-start)/(steps-1)
torch.rand/randn(size=)随机浮点张量randn 为标准正态
torch.randint(low=, high=, size=)随机整数张量左闭右开
torch.initial_seed() / torch.manual_seed(seed=)查看/设置随机种子保证实验可复现
torch.zeros/ones/full(size=, fill_value=)*_like(input=)全 0/全 1/全指定值张量like 版本按给定张量形状创建
tensor.type(dtype=)tensor.half/float/double/short/int/long()元素类型转换.double() 转 float64

2.2.3 张量类型转换

  • 张量 → NumPy:tensor.numpy()共享内存(改一个另一个跟着变),用 .numpy().copy() 避免共享。
  • NumPy → 张量:torch.from_numpy(ndarray) 共享内存torch.tensor(ndarray) 不共享内存
  • 提取数值:单元素张量用 .item()

2.2.4 数值计算

  • 基本运算:+ - * / -;函数形式 add/sub/mul/div/neg(不修改原数据);带下划线版本 add_()/sub_()/mul_()/div_()/neg_() 直接修改原数据
  • 点乘(Hadamard 积):相同形状张量对应位置元素相乘mul*
  • 矩阵乘法:要求 (n,m)×(m,p)→(n,p);运算符 @torch.matmul(input, other)(形状不同的张量只要最后几个维度符合矩阵乘法规则即可)。
  • 运算函数:mean(dim=)/sum(dim=)/min/max(dim=)/pow(exponent=)/sqrt()/exp()/log()/log2()/log10()dim=0 按列、dim=1 按行;mean 要求张量为 Float/Double 类型。

2.2.5 索引操作

  • 简单行列索引:data[0](第 0 行)、data[:, 0](第 0 列)。
  • 列表索引:data[[0,1],[1,2]] 取 (0,1)、(1,2) 两个位置;data[[[0],[1]],[1,2]] 取 0、1 行的 1、2 列共 4 个元素。
  • 范围索引(切片):data[:3, :2]data[2:, :2]
  • 布尔索引:data[data[:, 2] > 5](第 3 列大于 5 的行)、data[:, data[1] > 5]
  • 多维索引:data[0,:,:]data[:,0,:]data[:,:,0]

2.2.6 形状操作

函数作用要点
reshape(shape=)改变维度,数据不变可用 -1 自动计算某维度;连续/非连续均可
squeeze(dim=)删除形状为 1 的维度(降维不指定 dim 删除所有为 1 的维度;指定 dim 且该维不为 1 则不生效
unsqueeze(dim=)在指定位置加形状为 1 的维度(升维dim=-1 表示最后一维
transpose(dim0, dim1)交换两个指定维度如 (2,3,4) 交换 3、4 → (2,4,3)
permute(dims=)一次交换更多维度permute([1,2,0])
view(shape=)修改形状只能用于内存连续的张量;经 transpose/permute 后不连续,需先 .contiguous()
is_contiguous()判断张量是否内存连续返回 True/False

2.2.7 拼接操作

  • torch.cat([t1,t2], dim=):沿现有维度拼接,不改变维度数,除拼接维外其他维度必须匹配(拼接维数值相加)。
  • torch.stack([t1,t2], dim=):在新维度上堆叠,增加一个新维度,所有输入形状必须完全相同。

2.3 自动微分模块(autograd)

  • 概念:”梯度”= 对函数求导得到的值;”梯度下降法” = 求最优梯度值使损失函数最小的算法。
  • 梯度经典语录:
    • 对函数求导得到的值就是梯度(数值理解);没有点就无法求导。
    • 梯度就是上山下山最快的方向(方向理解)。
    • 在平面内,梯度就是某一点的斜率
    • 反向传播传播的是梯度(利用链式法则从后向前求导)。
    • 链式法则中梯度相乘,就是传说中的梯度传播
  • 训练中最常用算法是反向传播:参数根据损失函数关于参数的梯度进行调整;torch.autograd 支持任意计算图的自动梯度计算。
  • 三个关键规则
    1. PyTorch 不支持向量张量对向量张量求导,只支持标量张量对向量张量求导(y 必须是标量,向量需 y.sum() 后 backward)。
    2. 计算梯度:y.backward()(y 是标量);获取梯度:x.gradgrad 会累加上一次梯度值(默认累加,需手动清零)。
    3. requires_grad=True 才自动计算梯度并保存到 grad 中(默认为 False)。
  • 梯度下降更新公式:w = w - r * grad(r 是学习率);必须用 x.data = x.data - 0.01 * x.grad 更新(直接 x = x - 0.01*x.grad 会新建变量、破坏计算图)。
  • 梯度清零x.grad.zero_()(注意判断 grad 是否为 None)。
  • 注意点:不能将需要自动微分的张量转 numpy(报错 RuntimeError),需用 detach() 生成一个共享数据但不自动微分的新张量(x2 = x1.detach()x2.requires_grad=False,数据与 x1 共享同一内存)。

代码模式(梯度下降求最优解 y=x²+20 的极小值,迭代 1000 次)

x = torch.tensor(10, requires_grad=True, dtype=torch.float32)
y = x ** 2 + 20
for i in range(1, 1001):
y = x ** 2 + 20 # 3-1 前向传播
if x.grad is not None:
x.grad.zero_() # 3-2 梯度清零(默认累加)
y.sum().backward() # 3-3 反向传播
x.data = x.data - 0.01 * x.grad # 3-4 梯度更新 W=W-lr*grad

结果:x 从 10 收敛到 ≈0,y 最小值 ≈20。

自动微分应用(手写单层网络)

x = torch.ones(2, 5); y = torch.zeros(2, 3)
w = torch.randn(5, 3, requires_grad=True); b = torch.randn(3, requires_grad=True)
z = torch.matmul(x, w) + b
loss = torch.nn.MSELoss()(z, y)
loss.backward() # 梯度保存在 w.grad / b.grad

2.4 构建线性回归模型(完整流程,重要)

PyTorch 构建模型四步流程:① 准备训练集数据 → ② 构建模型 → ③ 设置损失函数和优化器 → ④ 模型训练

API 对照:nn.MSELoss() 代替平方损失;data.DataLoader 代替数据加载器;optim.SGD 代替优化器;nn.Linear 代替假设函数。

import torch
from torch.utils.data import TensorDataset, DataLoader
from torch import nn, optim
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt

def create_dataset():
x, y, coef = make_regression(n_samples=100, n_features=1, noise=10,
coef=True, bias=14.5, random_state=0)
return torch.tensor(x), torch.tensor(y), coef

def train():
x, y, coef = create_dataset()
dataset = TensorDataset(x, y)
dataloader = DataLoader(dataset=dataset, batch_size=16, shuffle=True) # 数据加载器
model = nn.Linear(in_features=1, out_features=1) # 假设函数(含 w、b)
criterion = nn.MSELoss() # 平方损失
optimizer = optim.SGD(params=model.parameters(), lr=1e-2) # 优化器
epochs = 100
epoch_loss, total_loss, train_sample = [], 0.0, 0.0
for _ in range(epochs):
for train_x, train_y in dataloader:
y_pred = model(train_x.type(torch.float32)) # 送入模型
loss = criterion(y_pred, train_y.reshape(-1, 1).type(torch.float32))
total_loss += loss.item(); train_sample += 1
optimizer.zero_grad() # 梯度清零
loss.backward() # 反向传播
optimizer.step() # 参数更新
epoch_loss.append(total_loss / train_sample)
# 绘制损失变化曲线 + 拟合直线(训练线 vs 真实线 y = coef*x + 14.5)

要点:in_features/out_features 是输入/输出张量第二维大小;model.weightmodel.bias 可查看参数;train_yreshape(-1,1) 与预测值形状对齐并统一 dtype。

2.5 PyTorch 常用 API 速查与易考点

  • 构建模型:继承 nn.Module__init__ 里定义层,forward 里定义前向传播(调用模型对象时自动执行)。
  • 训练四件套:optimizer.zero_grad()loss.backward()optimizer.step()(顺序固定)。
  • 数据流:Dataset(TensorDataset)→ DataLoader(batch_size=, shuffle=) → for 循环取 batch。
  • 模型保存/加载:torch.save(model.state_dict(), 'xxx.pth')model.load_state_dict(torch.load('xxx.pth'))
  • 训练/推理模式:model.train() / model.eval()(影响 Dropout/BN)。
  • 易考点:动态图 vs 静态图;tensor.numpy()from_numpy 共享内存;带下划线运算符就地修改;view 要求连续内存;detach() 用途;自动微分只支持标量对向量求导、梯度默认累加;为什么用 x.data 更新而非 x = x - lr*grad

三、神经网络基础

3.1 神经网络概念

  • 人工神经网络(ANN/NN):模仿生物神经网络结构和功能的计算模型,由多个互相连接的人工神经元(节点)构成,用于处理和学习复杂数据模式,尤其适合解决非线性问题
  • 生物类比:树突接收输入信号 → 细胞核聚集电荷 → 达到电位激活 → 轴突输出信号;人工神经元即”加权求和 + 激活函数”。
  • 神经网络结构三部分
    • 输入层:输入 x 的那一层,每个输入特征对应一个神经元。
    • 输出层:输出 y 的那一层,按任务(回归/分类)生成预测结果。
    • 隐藏层:输入层与输出层之间,网络的”深度”由隐藏层数量决定
  • 全连接神经网络(FCNN)特点:同一层神经元之间无连接;第 N 层每个神经元与第 N-1 层所有神经元相连(Fully Connected 的含义);接收的样本数据是二维的,数据在层间以二维形式传递;第 N-1 层输出就是第 N 层输入;每个连接有权重(w 和 b)。
  • 同一层的多个神经元并行处理相同输入,学习输入数据的不同特征。

3.2 神经元内部状态值与激活值

  • 前向传播:数据从输入到输出经过一层层神经元产生预测值的过程。每个神经元前向产生两个值:
    • 内部状态值(加权求和值)z = w·x + b(w 权重矩阵、x 输入、b 偏置)。
    • 激活值a = f(z)(f 为激活函数)。
  • 反向传播时产生激活值梯度与内部状态值梯度。
  • 控制每层内部状态值、激活值的方差可使网络工作得更好(引出激活函数与权重初始化)。

3.3 激活函数

3.3.1 为什么需要激活函数

  • 没有引入非线性因素的网络等价于线性模型,无法拟合复杂曲线;
  • 通过给网络输出增加激活函数引入非线性因素,使网络可以逼近任意函数,提升对复杂问题的拟合能力;
  • 反向传播(BP)要求激活函数必须可微

3.3.2 Sigmoid

  • 公式:f(x) = 1 / (1 + e^(-x));导数:f'(x) = f(x)·(1 - f(x))导数值域 (0, 0.25)
  • 将任意输入映射到 (0, 1);输入在 [-6, 6] 之间输出才有明显差异,[-3, 3] 之间效果较好;输入 <-6 或 >6 时激活值几乎相同(如输入 100 和 10000 激活值都≈1,丢失相差 100 倍的信息)。
  • 导数在 |x|>6 时接近 0 → 网络参数更新极其缓慢或无法更新
  • 缺点:
    1. 梯度消失:一般 sigmoid 网络 5 层之内就产生梯度消失(0.25^n 连乘)。
    2. 输出不以 0 为中心(恒为正),梯度更新只对某些特征产生同方向影响。
  • 使用场景:一般只用于二分类的输出层
  • PyTorch:torch.sigmoid(x)

3.3.3 Tanh(双曲正切)

  • 公式:f(x) = (e^x - e^(-x)) / (e^x + e^(-x));导数:f'(x) = 1 - f(x)²导数值域 (0, 1)
  • 将输入映射到 (-1, 1)以 0 为中心、0 点对称,可学习正负信号。
  • 与 Sigmoid 相比:以 0 为中心、梯度相对更大,收敛速度更快、迭代次数更少;但两侧导数也为 0,同样会造成梯度消失(输入 |x|>3 时导数≈0)。
  • 使用建议:隐藏层用 tanh,输出层用 sigmoid
  • PyTorch:torch.tanh(x)

3.3.4 ReLU

  • 公式:f(x) = max(0, x);导数:x>0 时为 1,x<0 时为 0(x=0 处不可导,一般取 0 或 1)。
  • 将小于 0 的值映射为 0,大于 0 的值保持不变:更重视正信号、忽略负信号;运算简单,提高训练效率。
  • 优点(与 sigmoid 相比,高频考点”ReLU 为什么好”):
    1. 计算量小:sigmoid 含指数运算,反向传播求梯度计算量大;ReLU 整个计算量节省很多。
    2. 缓解梯度消失:x>0 时梯度恒为 1,梯度不衰减,不会出现 sigmoid 那样的梯度消失,可训练深层网络。
    3. 稀疏性:使一部分神经元输出为 0,造成网络稀疏,减少参数相互依存,缓解过拟合
  • 缺点:神经元死亡(Dead ReLU)——随着训练推进,部分输入落入 <0 区域,导数恒为 0,对应权重无法更新。
  • 使用:目前最常用的激活函数
  • PyTorch:torch.relu(x);变体有 torch.leaky_relu()torch.prelu()(Leaky ReLU / PReLU)。

3.3.5 Softmax

  • 用于多分类,是 sigmoid 在多分类上的推广;把网络输出的 logits 映射成 (0,1) 的概率,且所有值累和为 1(满足概率性质),取概率最大的节点作为预测类别。
  • 公式:p_i = e^(z_i) / Σ_j e^(z_j)
  • PyTorch:torch.softmax(scores, dim=0)(dim=0 按行计算;dim=-1 每行数据相加为 1)。
  • 示例:scores=[0.2,0.02,0.15,0.15,1.3,0.5,0.06,1.1,0.05,3.75] → softmax 后最大概率 0.7392(对应 3.75)。

3.3.6 激活函数选择

  • 隐藏层:优先 ReLU;效果不好换 Leaky ReLU 等;用 ReLU 注意 Dead ReLU 问题;少用 sigmoid,可用 tanh。
  • 输出层:二分类 → sigmoid;多分类 → softmax;回归 → identity(恒等)。

3.4 参数初始化

  • 需要初始化的参数:权重和偏置(偏置一般初始化为 0 即可)。
  • 参数初始化三大作用:① 防止梯度消失或爆炸(初始权重过大/过小导致梯度指数级增大/缩小);② 提高收敛速度(激活值分布适中,梯度高效更新);③ 打破对称性(否则所有神经元更新方向相同,学习能力受限)。
初始化方法公式/规则优点缺点适用场景
随机初始化(均匀)默认区间 (0,1),可设为 (-1/√d, 1/√d),d=输入数量能有效打破对称性范围不当可能导致梯度问题浅层网络(隐藏层 1–3 层、总层数≤5)
随机初始化(正态)均值 0、标准差 1 的高斯分布取小值同上同上同上
全 0 初始化所有权重为 0实现简单无法打破对称性,无法有效训练几乎不使用,仅用于偏置初始化
全 1 初始化所有权重为 1实现简单无法打破对称性;激活值指数增长易梯度爆炸测试/调试、特殊稀疏网络
固定值初始化所有权重为某个固定值实现简单无法打破对称性;过大/过小导致梯度爆炸/消失测试/调试
kaiming(HE)初始化正态:std=√(2/fan_in);均匀:limit=√(6/fan_in)适合 ReLU,保持梯度稳定对非 ReLU 效果一般深度网络(10 层及以上)+ ReLU/Leaky ReLU
xavier(Glorot)初始化正态:std=√(2/(fan_in+fan_out));均匀:limit=√(6/(fan_in+fan_out))适用于 Sigmoid/Tanh,解决梯度消失对 ReLU 表现欠佳深度网络(10 层及以上)+ Sigmoid/Tanh
  • 术语:fan_in = 当前层接收的来自上一层的神经元数量(输入个数);fan_out = 当前层传给下一层的神经元数量(输出个数)。
  • 选择规则:Sigmoid/Tanh → xavier;ReLU/Leaky ReLU → kaiming;浅层 → 随机初始化;深层 → xavier/kaiming。
  • PyTorch 代码:nn.init.uniform_ / normal_ / constant_ / zeros_ / ones_ / kaiming_normal_(nonlinearity='relu') / kaiming_uniform_ / xavier_normal_ / xavier_uniform_(作用于 linear.weight 等)。

3.5 神经网络搭建与参数计算

  • 在 PyTorch 中定义网络 = 层堆叠:继承 nn.Module,实现两个方法:
    • __init__:定义网络层结构(主要是全连接层)并初始化;
    • forward:调用模型对象时自动执行,为各层传入数据做前向传播。
  • 示例模型(3-3-2-2):hidden1 用 xavier + sigmoid,hidden2 用 kaiming + relu,输出层线性 + softmax(dim=-1)。
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.linear1 = nn.Linear(3, 3)
nn.init.xavier_normal_(self.linear1.weight); nn.init.zeros_(self.linear1.bias)
self.linear2 = nn.Linear(3, 2)
nn.init.kaiming_normal_(self.linear2.weight, nonlinearity='relu'); nn.init.zeros_(self.linear2.bias)
self.out = nn.Linear(2, 2)
def forward(self, x):
x = torch.sigmoid(self.linear1(x))
x = torch.relu(self.linear2(x))
return torch.softmax(self.out(x), dim=-1)
  • 数据形状:输入 [batch_size, in_features] → 输出 [batch_size, out_features];例:5×3 输入 → 5×2 输出(softmax 后每行和为 1)。
  • 参数数量计算:以第一个隐层为例(3 个输入 → 3 个神经元),每个神经元参数 = w1,w2,w3,b 共 4 个,共 3×4=12 个。三层 (3→3, 3→2, 2→2) 总参数 = 12+8+6 = 26(可用 torchsummary.summary(model, input_size=(3,), batch_size=5) 查看)。
  • 查看可学习参数:for name, parameter in model.named_parameters(): print(name, parameter)
  • 注意:输入数据和网络权重是两回事,要分得清。

3.6 损失函数

  • 概念:损失函数用来衡量模型参数质量,即比较网络输出(预测值)与真实输出(真实值)的差异;模型通过最小化损失函数调整参数。别名:代价函数、目标函数、误差函数等。
  • 作用:① 评估性能;② 指导优化(梯度下降最小化损失)。

3.6.1 分类任务损失(交叉熵)

  • 多分类(softmax 损失)nn.CrossEntropyLoss() = softmax + 损失计算(PyTorch 中直接对网络输出 logits 计算,不需要手动加 softmax 层)。公式:L = -Σ_i y_i·log(S(f(x))_i),其中 y_i 为真实概率、f(x) 为预测分数、S 为 softmax。本质是最小化正确类别预测概率的对数的负值。注意 y_true 必须是 int64 类型;reduction='mean'(默认平均损失)/ 'sum'(总损失)。
  • 二分类:输出层用 sigmoid,损失用 nn.BCELoss(),公式 L = -[y·log(ŷ) + (1-y)·log(1-ŷ)],其中 y 为真实概率、ŷ 为预测概率(sigmoid 输出)。

3.6.2 回归任务损失

  • MAE(L1 Loss,平均绝对误差)nn.L1Loss(),以绝对误差作为距离。特点:具有稀疏性,常作为正则项;零点不可导、梯度不平滑,会跳过极小值;对异常值/离群点不敏感(线性惩罚)。
  • MSE(L2 Loss,均方误差/欧氏距离)nn.MSELoss(),误差平方和的均值。特点:任意位置可导,越接近底部导数越小,符合梯度下降套路;对离群点敏感(平方放大误差);预测与目标相差很大时梯度容易爆炸(层间梯度 >1 重复相乘导致指数级增长)。
  • Smooth L1nn.SmoothL1Loss()MSE 与 MAE 优点的结合。分段函数:|x|≤1 时为 0.5x²(L2,解决 L1 不光滑),|x|>1 时为 |x|-0.5(L1,解决离群点梯度爆炸)。对离群点更鲁棒、梯度更平滑。常用于目标检测等。

3.7 梯度下降与反向传播

3.7.1 梯度下降算法回顾

  • 梯度下降 = 寻找使损失函数最小化的方法;梯度的方向是函数增长最快的方向,梯度的反方向是函数减少最快的方向w = w - η·grad
  • 学习率 η:太小 → 收敛慢、训练时间成本增大;太大 → 可能直接跳过最优解、不收敛甚至震荡(梯度爆炸)。解决:学习率随训练变化(学习率衰减)。
  • 三个基础概念(高频考点):
    • Epoch:使用全部数据对模型进行的一次完整训练(训练轮次)。
    • Batch:每次反向传播参数更新使用的小部分样本(每批样本数量)。
    • Iteration:使用一个 Batch 数据对模型进行一次参数更新的过程。
    • 例:50000 样本、Batch Size=256 → 每 Epoch 训练 50000 张、Batch 个数=50000/256+1=196(未整除 +1)、每 Epoch Iteration=196、10 Epoch Iteration=1960。
  • 梯度下降三种方式的根本区别在 Batch Size:BGD(全部样本,计算量大)、SGD(随机一个样本,梯度可能不合理)、Mini-Batch(一批样本,计算量相对小、梯度更合理)。

3.7.2 反向传播(BP 算法)

  • 前向传播:数据输入网络,逐层向前传输,一直运算到输出层,得到预测值与真实值的误差 ERROR。
  • 反向传播:利用损失函数 ERROR,从后往前,结合梯度下降算法,依次求各参数的偏导(梯度),并更新参数
  • 核心:利用链式法则对神经网络各节点权重求梯度(如求 E 对 w5 的导数 = ∂E/∂out_o1 · ∂out_o1/∂net_o1 · ∂net_o1/∂w5;求 w1 时路径不止一条,各路径梯度相加)。“反向传播传播的是梯度”。
  • BP 算法不仅可用于多层前馈神经网络,也可用于其他类型网络;通常”BP 网络”指用 BP 算法训练的多层前馈网络。

3.7.3 梯度下降优化方法(重要对比)

  • 梯度下降可能遇到的问题:平缓区域(梯度小,优化变慢)、鞍点(梯度为 0,参数无法优化)、局部最小值(参数非最优)。
  • 优化方法:Momentum、AdaGrad、RMSprop、Adam。

① 指数移动加权平均(EWA,基础)

  • 公式:S_t = β·S_(t-1) + (1-β)·Y_t(S_t 指数加权平均值、Y_t 当前时刻值、β 权重系数)。
  • β 越大曲线越平缓(当前值影响越小),β 一般默认 0.9;用途:气温平滑曲线。

② Momentum(动量法)

  • 梯度公式:s_t = β·s_(t-1) + (1-β)·g_t;参数更新:w_t = w_(t-1) - η·s_t
  • 历史梯度的指数移动加权平均值代替当前梯度:平滑梯度变化,减小震荡,加快收敛;处于鞍点(当前梯度为 0)时因已积累历史梯度,可能跨过鞍点
  • PyTorch:optim.SGD([w], lr=0.01, momentum=0.9)

③ AdaGrad

  • 对不同参数分量用不同学习率,总体学习率逐渐减小(初期离目标远用大学习率,后期学习率下降)。
  • 步骤:累积平方梯度 s_t = s_(t-1) + g_t⊙g_t;学习率 η = η/(√s_t + σ)(σ=1e-10 防除 0);更新 w_t = w_(t-1) - η/(√s_t+σ)·g_t
  • 缺点:学习率过早、过量降低,后期学习率太小难找最优解。
  • PyTorch:optim.Adagrad([w], lr=0.01)

④ RMSProp

  • 对 AdaGrad 的优化:用指数加权平均梯度替换历史梯度平方和:s_t = β·s_(t-1) + (1-β)·g_t⊙g_t
  • 通过衰减系数 β 控制历史梯度信息的多少;避免学习率过早衰减,非凸条件下优化更好、学习率衰减更合理。
  • 注意:AdaGrad 和 RMSProp 都是对每个参数分量用不同学习率(梯度大的分量学习率小,反之大)。
  • PyTorch:optim.RMSprop([w], lr=0.01, alpha=0.9)(alpha 对应 β)。

⑤ Adam(自适应矩估计)

  • = Momentum + RMSProp:用梯度的一阶矩(均值)修正梯度,用梯度平方的二阶矩(方差)修正学习率。
  • 公式:m_t = β1·m_(t-1) + (1-β1)·g_ts_t = β2·s_(t-1) + (1-β2)·g_t²;偏差校正 m̂ = m/(1-β1^t)ŝ = s/(1-β2^t);更新 w_t = w_(t-1) - η/(√ŝ_t + ε)·m̂_t
  • PyTorch:optim.Adam([w], lr=0.01, betas=[0.9, 0.99])

优化器选择小结(表)

算法优点缺点适用
SGD简单易实现收敛慢、易震荡简单任务、数据分布稳定
Momentum加速收敛、减少震荡(高曲率区域)需调动量超参数非平稳优化、深度学习
AdaGrad自适应学习率,适合稀疏数据学习率过早衰减、早期停滞稀疏数据(NLP、推荐)
RMSProp解决 AdaGrad 过早衰减,适应性强需选好超参数、可能过于激进动态/非平稳目标
Adam结合两者优点,适应性强且稳定超参数多、可能较大波动广泛深度学习任务
  • 选择口诀:简单任务/小模型 → SGD 或 Momentum;复杂任务/大数据 → Adam;稀疏数据/文本 → AdaGrad 或 RMSProp。

3.8 学习率衰减

  • 为什么要衰减:训练后期学习率过高会造成 loss 振荡;减小过慢会造成收敛变慢。理想:前期收敛快、后期收敛慢。
  • 实验结论(y=4x²):小学习率下降慢;大学习率越过最小值点导致震荡、甚至不收敛(梯度爆炸);lr=0.125 时一步到最优点。
方法公式PyTorch API特点
等间隔衰减每 step_size 轮 lr = lr * gammaoptim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5)简单直观,适合大批量数据
指定间隔衰减在指定轮次 lr = lr * gammaoptim.lr_scheduler.MultiStepLR(optimizer, milestones=[50,125,160], gamma=0.5)按经验设定关键轮次
指数衰减lr = lr * gamma^epochoptim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)平滑、符合梯度下降规律(前期快中期慢后期更慢)
  • 使用套路:每 epoch 训练完调用 scheduler.step();用 scheduler.get_last_lr() 查看当前学习率。
  • 选择建议:优先指数衰减;按经验用指定间隔;简单模型用等间隔。

3.9 正则化方法

  • 正则化定义:为减小测试误差、提高泛化能力而采用的策略统称;神经网络表示能力强、易过拟合,需正则化。常用策略:范数惩罚、Dropout、特殊网络层(BN)等。

3.9.1 Dropout(随机失活)

  • 原理:训练时让神经元以超参数 p(丢弃概率)的概率停止工作(激活置为 0),未置 0 的进行缩放,缩放比例 1/(1-p);每次基于输入数据只更新子网络的参数(相当于训练很多子网络的集成)。
  • p 取值:通常 0.2–0.5;小模型/复杂任务可 0.3 或更小;很深网络用 0.5/0.6;通常加在全连接层激活函数之后
  • 训练 vs 测试
    • 训练:model.train(),随机失活并缩放 1/(1-p),使期望输出 E[x_dropout]=[(1-p)·x]/(1-p)=x,与测试期望一致。
    • 测试:随机失活不起作用,用所有神经元预测,model.eval()
  • 作用:防止过拟合(防止预测结果受某个神经元/特征影响过大)。
  • 代码:nn.Dropout(p=0.4);示例输入 [0,1.8033,1.4608,4.5189,6.9116] 失活后出现 0,未失活值 ×1/(1-0.4)。

3.9.2 批量归一化(Batch Normalization, BN)

  • 动机:流经网络的每个 batch 数据分布变化剧烈,网络参数频繁大幅调整、难以收敛;对每个 batch 数据标准化(均值≈0、方差≈1)后分布稳定,梯度变化稳定,加速收敛
  • 公式:先标准化 x̂ = (x - E(x)) / √(Var(x) + eps)(eps 通常 1e-5,防除 0),再重构 y = λ·x̂ + βλ、β 是可学习参数,对标准化值做线性变换,λ 为系数、β 为偏置)。
  • 步骤:① 在网络层(Conv2d/Linear)之后、激活函数之前添加 BN 层(Conv2d→BN→ReLU 或 Linear→BN→ReLU);② 训练时计算当前 batch 的 μ、σ² 并规范化,同时维护全局均值/方差的移动平均;③ 推理时(model.eval())用训练阶段的全局均值/方差,不再用当前 batch 统计量。
  • 作用(优点):
    1. 减少内部协方差偏移:输入分布稳定,加速训练、更稳定;
    2. 加速训练:避免每层输入分布不断变化导致学习慢;
    3. 起到正则化作用:不同批次统计量引入噪声,减少对其他正则化(如 Dropout)的依赖;
    4. 提升泛化能力
  • 使用场景:计算机视觉领域使用较多
  • 类别:nn.BatchNorm1d(全连接/一维,输入 (N, num_features))、nn.BatchNorm2d(CNN 图像,(N,C,H,W),对每个通道的特征图标准化)、nn.BatchNorm3d(3D CNN/视频,(N,C,D,H,W))。参数:num_features(通道数/特征数)、epsmomentumaffine(默认 True,使用可学习 γ、β)。
  • 注意:BatchNorm1d 要求每批样本至少 2 个,否则无法统计均值和方差。

3.9.3 正则化小结(课堂笔记补充)

  • L1 正则:需要手动写代码实现;L2 正则:SGD(weight_decay=...);此外还有 dropout、BN。(具体 L1/L2 公式资料未展开。)

3.10 神经网络优缺点(PPT)

  • 优点:精度高,性能优于其他机器学习方法甚至某些领域超过人类;可近似任意非线性函数;框架和库多。
  • 缺点:黑箱难解释;训练时间长、需大量算力;结构复杂、需调超参数;小数据集上表现不佳、易过拟合。

3.11 综合案例:手机价格分类(FCN 全连接网络)

  • 需求:根据 20 个手机性能特征预测价格区间(0/1/2/3 四类)→ 分类问题
  • 数据:共 2000 条,1600 训练 / 400 测试(train_test_split(x, y, train_size=0.8, random_state=88));特征数 20、类别数 4。
  • 模型:3 个全连接层 20→128→256→4,ReLU 激活(输出层不做 softmax,因为 nn.CrossEntropyLoss 内含 softmax)。
  • 训练:CrossEntropyLoss + optim.SGD(lr=1e-3),batch_size=8,50 epochs,torch.manual_seed(0);保存 torch.save(model.state_dict(), 'model/phone-price-model.pth')
  • 评估:加载权重 → model.eval()torch.argmax(output, dim=1) 取类别 → Acc = correct / len(valid_dataset)初始 Acc: 0.64250
  • 性能优化手段(高频考点):① 数据标准化(StandardScaler);② 优化方法 SGD→Adam;③ 学习率 1e-3→1e-4;④ 增加网络深度/参数量(20→128→256→512→128→4);⑤ 增加 BN 层;⑥ 增加训练轮数等。

四、卷积神经网络 CNN

4.1 图像基础知识

  • 图像由像素点组成,像素值范围 [0, 255]:越接近 0 越暗(黑),越接近 255 越亮(白)。
  • 四种图像类型:
    1. 二值图像:1 通道,取值 0/1(0 黑 1 白),用于 OCR、掩膜存储。
    2. 灰度图像:1 通道,[0,255],8 位无符号整型(int8);二值图像是灰度图像特例。
    3. 索引图像:1 通道,像素值作索引查颜色索引矩阵 MAP(MAP 大小如 256×3,MAP=[RGB])。
    4. 真彩色 RGB 图像3 通道(R、G、B 三个 M×N 二维矩阵),每个像素颜色直接存放,8 位无符号;注意:通道顺序是 BGR 而不是 RGB(OpenCV 惯例,资料原文如此)。
  • 深度学习中多用彩色图(RGB 3 通道);图像在 numpy/matplotlib 中形状为 (H, W, C)(高、宽、通道)。
  • 加载/显示:plt.imread("data/img.jpg")plt.imshow(img)plt.imsave(...);全 0 数组=黑色图像,全 255=白色(np.zeros([200,200,3]) / np.full([200,200,3], 255))。

4.2 CNN 概述

  • 定义:卷积神经网络 = 含有卷积层的神经网络,是深度学习在计算机视觉领域的突破性成果,专门处理图像、视频、语音等数据。卷积层的作用是自动学习、提取图像特征
  • 为什么不用全连接网络:图像大时全连接计算代价高,且难以保留原有特征、准确率不高。
  • CNN 三大部分
    1. 卷积层(CONV):提取图像中的局部特征(线性乘积求和)。
    2. 池化层(POOL)大幅降低参数量级(降维)(取区域平均值或最大值)。
    3. 全连接层(FC):类似 ANN 部分,接收二维数据,输出预测结果
  • 经典 CNN 结构流程:数据输入层(去均值/归一化/PCA,CNN 只对训练集做”去均值”)→ [卷积层 CONV → 激励层 ReLU → 池化层 POOL] 重复 → 全连接层 FC 输出。
  • 应用:图像分类、目标检测、图像分割、人脸识别、医学图像分析、自动驾驶。

4.3 卷积层(核心)

4.3.1 卷积计算原理

  • 卷积运算本质 = 卷积核(滤波器)与输入数据的局部区域做点积(等价于线性层加权求和)。
  • 术语:input=输入图像;filter=卷积核/滤波器(滤波矩阵),即一组固定权重的神经元(一个卷积核就是一个神经元),多个滤波器叠加成卷积层;输出=特征图(feature map)
  • 单点计算:w1x1 + w2x2 + ... + b(w 为卷积核权重,x 为局部像素值)。
  • 不同滤波器提取不同特征(颜色深浅、轮廓等),想提取什么特征就用什么滤波器。

4.3.2 Padding(填充)

  • 定义:在输入特征图边界周围添加额外像素(通常是 0)
  • 作用:① 保持空间维度(不 padding 特征图不断缩小,边缘信息丢失);② 保留边缘信息(边缘像素参与计算次数少,padding 增加其参与度);③ 提高性能。
  • 类型:Valid Padding(不填充,输出缩小)、Same Padding(输出与输入同尺寸)、Full Padding(尽可能多填,输出变大,较少用)。

4.3.3 Stride(步长)

  • 定义:卷积核在图像上滑动时的步伐大小(每次移动的像素数)。
  • 作用:① 降低计算复杂度(移动次数少);② 步长越大特征图越小(类似池化降维);③ 增大感受野(每个神经元捕捉更大范围输入)。
  • 选择:Stride=1 最常见(保留空间细节);Stride=2 或 4 用于快速降维、增大感受野。

4.3.4 多通道卷积

  • 卷积核通道数必须与输入图像通道数相同(RGB 三通道 → 每个卷积核也是 3 通道)。
  • 每个卷积核通道与输入对应通道卷积,各通道卷积结果按位相加得到最终特征图(1 个二维特征图)。
  • 多卷积核:有多少个卷积核(神经元)就提取多少张特征图(从不同视角/角度提取特征)。

4.3.5 特征图尺寸计算(高频考点)

  • 输入图像 W×W、卷积核 F×F、Stride=S、Padding=P → 输出 N×N: N = (W - F + 2P) / S + 1(除不尽则向下取整)。
  • 例:5×5 图像、3×3 卷积核、S=1、P=1 → (5-3+2)/1+1 = 5(Same 效果)。
  • 卷积核大小一般选奇数(1×1、3×3、5×5)。

4.3.6 PyTorch 卷积层 API

conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
# in_channels: 输入通道数(RGB 为 3)
# out_channels: 输出通道 = 卷积核(神经元)数量
# kernel_size: 卷积核大小,一般 3/5/7
# stride: 步长;可为整数(所有维度相同)或元组 (2,1)
# padding: 四周填充圈数,默认补 0;padding='same'(PyTorch 1.9+) 保持尺寸但 stride 必须为 1;padding=kernel_size-1 为 Full Padding
  • 使用流程(图像 → 卷积):读图 plt.imread(H,W,C)→ torch.tensor(img).permute(2,0,1) 变 (C,H,W) → unsqueeze(0) 变 (batch,C,H,W) → 送入卷积层。
  • 示例:640×640×3 图,nn.Conv2d(3, 4, kernel_size=3, stride=2, padding=0) → 输出 [1, 4, 319, 319]((640-3+0)/2+1=319.5 向下取整 319)。

4.4 池化层

  • 作用:对卷积层输出特征图下采样(降维):① 降维、减少计算量和内存;② 提高鲁棒性(对平移、旋转、噪声不敏感);③ 防止过拟合(减少模型复杂度);④ 提取更抽象高层特征。
  • 两种方式:
    • 最大池化(Max Pooling):取窗口内最大值作为输出。
    • 平均池化(Avg Pooling):取窗口内均值作为输出。
  • 多通道池化:对每个输入通道分别池化(不像卷积那样相加),所以池化前后通道数不变;池化只在宽高维度进行,通道维度不参与池化。
  • API:nn.MaxPool2d(kernel_size=2, stride=2, padding=1) / nn.AvgPool2d(kernel_size=2, stride=1, padding=0);参数同卷积(kernel_size 为窗口形状,池化层没有神经元参与)。
  • 示例:单通道 3×3 输入、kernel=2、stride=1 → 最大池化 [[4,5],[7,8]],平均池化 [[2,3],[5,6]]。

4.5 经典网络架构(按资料内容)

网络关键点意义
LeNet-5卷积层(提边缘、角点)+ 池化层(子采样,降维+鲁棒)+ 全连接层最早的 CNN 架构之一,证明 CNN 有效性,奠定基础
AlexNet更大的卷积核和更多卷积核;ReLU 激活最大池化Dropout 防过拟合;全连接分类ImageNet 大幅提升准确率,2012 开山之作,推动深度学习发展
VGGNet更小的 3×3 卷积核堆叠增加深度探索深度对性能的影响,深层提取更抽象特征
GoogLeNet (Inception)Inception 模块:并行不同大小卷积核与池化再拼接提高性能同时减少计算量,增加网络宽度
ResNet残差块:跳跃连接(Shortcut),允许梯度直接反向传播到浅层解决深度网络的梯度消失问题,可训练极深网络
DenseNet密集块:每层与之前所有层连接(特征重用)增强特征传递与梯度流动,避免梯度消失,提高参数效率

4.6 CNN 特性小结(易考点)

  • 局部连接:每个神经元只与输入的小局部区域(局部感受野)相连,符合图像空间结构,捕捉局部特征。
  • 权值共享:同一个卷积核在整个输入上共享权重 → 参数数量大大减少,减少计算量、提高训练效率。
  • 平移不变性:卷积是局部的且权重共享 → 物体出现在图像任何位置都能被检测到(空间不变性)。
  • 卷积层自动提取特征,无需人工特征工程。

4.7 综合案例:CIFAR10 图像分类(CNN)

  • CIFAR-10 数据集:5 万张训练图像 + 1 万张测试图像,10 个类别(airplane/automobile/bird/cat/deer/dog/frog/horse/ship/truck),每类 6k 张,图像大小 32×32×3。加载:CIFAR10(root='data', train=True, transform=ToTensor())(ToTensor 将 PIL 图像转 Tensor,自动归一化到 [0,1])。
  • 网络结构:输入 32×32 → conv1(3→6, k=3) → ReLU → pool1(2×2, s=2)(30→15)→ conv2(6→16, k=3) → ReLU → pool2(2×2, s=2)(13→6)→ 展平 16×6×6=576 → linear1(576→120) → linear2(120→84) → out(84→10)。
  • 展平关键代码x = x.reshape(x.size(0), -1)(最后一批可能不满 batch_size,不能写死;-1 自动计算 16×6×6=576)。
  • 训练:nn.CrossEntropyLoss() + optim.Adam(model.parameters(), lr=1e-3),batch_size=8,100 epochs;记录 loss、acc。
  • 评估:model.eval()(网络中有 dropout/BN 时评估阶段不执行相应操作);torch.argmax(output, dim=-1) == y 统计正确数。
  • 结果与过拟合:训练 100 轮训练集 acc≈0.90,测试集 Acc 只有 0.57过拟合
  • 模型优化(考点):学习率 1e-3→1e-4、增加参数量(conv1: 3→32,conv2: 32→128,全连接 576→2048→2048→10)、加 Dropout(p=0.5)(放在激活函数后/全连接层之间)→ 测试集 Acc 提升到 0.93

五、循环神经网络 RNN

5.1 RNN 概念与应用

  • 定义:循环神经网络(RNN)是专门处理序列数据的神经网络;具有”循环”结构,能处理和记住前面时间步的信息,适用于时间序列数据或有时序依赖的任务。
  • 序列数据:在不同时间点收集的数据(时间序列);也可以是文字序列。核心特点:后面的数据跟前面的数据有关系
  • 应用场景:NLP(文本生成、语言建模、机器翻译、情感分析);时间序列预测(股市、气象、传感器);语音识别;音乐生成。
  • 注意:标准 RNN 难以捕捉长期依赖关系(资料在简介章节明确指出)。

5.2 自然语言处理(NLP)概述

  • NLP 研究通过计算机算法理解自然语言(汉语、英语、法语等),该类数据不像结构化数据/图像那样方便数值化。
  • NLP 目标:让机器”听懂””读懂”自然语言并进行有效交流分析;涵盖语法分析、语义理解、情感分析、机器翻译等。

5.3 词嵌入层(Word Embedding)

  • 作用:把离散单词(词表索引)转换为连续、低维的稠密向量,让网络理解词汇语义;即将文本转换为向量。
  • 为什么不用 one-hot:one-hot 是高维稀疏向量,无法反映单词间相似性;词嵌入用低维稠密向量,能捕捉语义相似性(如”猫”与”狗”接近、”猫”与”汽车”遥远)。
  • 机制:按词数量构建词向量矩阵(如 100 个词、128 维 → 100×128 矩阵),每个词对应矩阵中一个向量。
  • 在 RNN 中的作用:① 输入表示(神经网络不能直接处理离散词索引);② 降低维度(高维稀疏→低维稠密);③ 捕捉语义相似性(训练学习词间关系)。
  • 工作流程:初始化词向量(随机或加载预训练 Word2Vec/GloVe)→ 分词、词转索引 → 查词向量 → 送入 RNN。
  • PyTorch APInn.Embedding(num_embeddings=词的数量, embedding_dim=词向量维度)。用法:jieba 分词 → 去重建词表 → embed(torch.tensor(i)) 取第 i 个词的向量。

5.4 循环网络层原理(核心公式)

  • 文本”我爱你”具有序列关系;RNN 实际是同一个神经元在不同时间步重复使用(展开图里画的 3 个神经元其实是同一个)。
  • 隐藏状态 h:保存序列数据中的历史信息并传给下一个时间步。三大作用:记忆功能(跨时间步传递信息)、上下文理解连接不同时间步(处理变长序列)。
  • 每次输入:上一个时间步的隐藏状态 + 当前输入 x;每次输出:当前隐藏状态 + 当前预测 y。
  • 文本生成例子:输入”我””爱”预测”你”——初始化 h0(一般全 0)→ 词嵌入”我”送第一个时间步得 h1 → h1+”爱”送第二个时间步得 h2 → h2 送全连接层得”你”的预测概率。
  • 计算隐藏状态(RNN 神经元内部): h_t = tanh(W_ih·x_t + b_ih + W_hh·h_(t-1) + b_hh)
    • W_ih 输入数据权重、b_ih 输入偏置、W_hh 隐藏状态权重、b_hh 隐藏状态偏置、h_(t-1) 输入隐藏状态、h_t 输出隐藏状态;最后用 tanh 激活。
  • 计算当前时刻输出y_t = W_hy·h_t + b_y(W_hy 隐藏到输出权重,b_y 输出偏置)。
  • 词汇表映射:y_t 是向量,经全连接层得到 y_pred,每个元素是词表中某个词的得分(softmax 转概率);词表有多少个词 y_pred 就有多少个元素,最大元素对应的词就是预测生成的词(本质是分类问题,每个词一个类别)。
  • 神经元工作机制总结:接收输入(x_t、h_(t-1))→ 更新隐藏状态 h_t(含过去记忆+当前输入)→ 基于 h_t 生成输出 y_t。
  • 文本生成预测流程:输入”m”→x1 → 初始化 h0=0 → 更新 h1 计算 y1 → 全连接+softmax 转概率 → 选概率最高的词(如”a”)→ 把”a”作为下一时间步输入继续,直到生成完整句子。

5.5 PyTorch RNN 层 API

RNN = nn.RNN(input_size, hidden_size, num_layers)
output, hn = RNN(x, h0)
  • 参数:input_size 输入维度(一般=词向量维度);hidden_size 隐藏层 h 维度(也是神经元输出维度);num_layers 隐藏层层数(默认 1)。
  • 输入:x 形状 [seq_len, batch, input_size](句长、批量、词向量维度);h0 形状 [num_layers, batch, hidden_size]
  • 输出:output 形状 [seq_len, batch, hidden_size](每个时间步的隐藏状态);hn 形状 [num_layers, batch, hidden_size](最后一层最终隐藏状态)。
  • 示例:rnn = nn.RNN(input_size=128, hidden_size=256)inputs = torch.randn(5, 32, 128)(5 个词、32 个句子);hn = torch.zeros(1, 32, 256) → output 形状 [5,32,256],hn 形状 [1,32,256]。

5.6 综合案例:周杰伦歌词生成(文本生成)

  • 数据集:周杰伦第一张专辑《Jay》到第十张《跨时代》歌词,5819 行文本
  • 任务:输入起始词,逐个预测下一个词,生成指定长度歌词(本质是多分类问题)。
  • 实现流程:构建词表 → 构建数据集对象 → 编写网络模型 → 编写训练函数 → 编写预测函数
    1. 构建词表:jieba 分词 → 去重得 unique_words → 建 word_to_index 映射 → 全文转索引 corpus_idx(每行词之间加空格索引分隔,消除行间语义关系)。
    2. 数据集(LyricsDataset):继承 torch.utils.data.Dataset,实现 __len____getitem__num_chars 个词为一个样本:x=corpus[start:end],y=corpus[start+1:end+1](预测下一个词,y 相对 x 后移一位);句子数=word_count//num_chars。
    3. 模型(TextGenerator)nn.Embedding(词数, 128)nn.RNN(128, 256, 1)nn.Linear(256, 词数);forward 中注意 embed.transpose(0, 1) 把 (batch, seq_len, dim) 换成 RNN 要求的 (seq_len, batch, dim);输出 reshape 成 (-1, 256) 送全连接;init_hidden(bs) 返回 torch.zeros(1, bs, 256)
    4. 训练nn.CrossEntropyLoss() + optim.Adam(lr=1e-3),num_chars=32、batch_size=5、10 epochs;y 需 torch.transpose(y,0,1).reshape(-1) 展平成与 output 对齐的一维索引。训练 10 轮 loss 从 1.84 降到 0.096;保存 lyrics_model_10.pth
    5. 预测:加载模型 → init_hidden(bs=1) → 起始词转索引 → 循环:model(torch.tensor([[word_idx]]), hidden) 输出 → torch.argmax(output) 取概率最大词 → 该词作为下一次输入,直到生成指定长度。示例:predict(‘分手’, 50) 生成的歌词通顺。

5.7 RNN 易考点

  • RNN 为什么适合序列数据(隐藏状态记忆);标准 RNN 的长期依赖问题(资料明确提及但未展开讲 LSTM/GRU,LSTM/GRU 门控结构在本资料中未涉及)。
  • h_t、y_t 公式;为什么展开图中”3 个神经元其实是 1 个”;隐藏状态的三大作用。
  • 词嵌入 vs one-hot;nn.Embedding 两个参数。
  • RNN 输入输出形状:x=[seq_len, batch, input_size]、h0=[num_layers, batch, hidden_size]、output=[seq_len, batch, hidden_size]。
  • 为什么 forward 中要 embed.transpose(0, 1);为什么 y 要展平成一维;为什么 reshape(x.size(0), -1) 不能写死 batch 数。
  • 文本生成 = 逐词分类(词表大小=类别数),选 softmax 概率最大的词。

六、笔记 day01–day06 实操细节整理

Day01:深度学习简介 + PyTorch 框架 + 张量基础

  • 深度学习=机器学习的一类算法,人工神经网络为结构、自动提取特征;特点:自动提取特征、解释性差、大量数据+高性能计算、非线性转换。
  • 模型归类:ANN(感知机)、CNN(图像/视频)、RNN(NLP)、Transformer(RNN 衍生出来的)、自编码器等。
  • PyTorch:python 第三方包,数据以张量类型存在;可在 GPU/TPU/NPU 上运行;当前更新到 2.5 版本
  • 张量维度认知:0 维=标量、1 维=[1 2 3 4 5]、2 维=[[…],[…]]、3 维…;张量是通过类创建的对象,提供方法和属性。
  • 实操踩坑
    • torch.tensor(list):Python 列表默认 float32torch.tensor(np.array) 继承 numpy 的 float64;int 标量创建 int 张量。
    • torch.Tensor(2, 3) 只给形状时是未初始化内存的垃圾值(不是 0)。
    • torch.IntTensor([2.5, 3.3]) 自动类型转换(截断为 2、3)。
    • torch.arange 左闭右开;torch.linspace 左闭右闭,step=(end-start)/(steps-1)。
    • 随机种子:torch.manual_seed(seed=66) 设置后,initial_seed() 显示设置的种子值。
    • zeros_like/ones_like/full_like 按给定张量的形状创建。
    • 类型转换:t1.type(dtype=torch.FloatTensor)t1.int()/float()/double()/half()
    • tensor.numpy() 共享内存(改 numpy 张量也变),torch.from_numpy() 也共享;torch.tensor(ndarray) 不共享;需要独立用 .copy()
    • .item():只要张量是单个元素(标量/一维/二维均可)就能取出数值。
    • 带下划线 neg_() 等就地修改原张量;点乘 */mul 要求形状相同;矩阵乘法 @/matmul 遵循 (n,m)×(m,p)→(n,p)。
    • mean(dim=0) 按列、dim=1 按行;mean 要求浮点类型。

Day02:张量索引、形状操作、拼接、自动微分

  • 索引:下标从 0 开始(右到左 -1);data[行, 列];列表索引 data[[1,3],[2,4]] 取对应位置元素;布尔索引 data[data[:,1]>6];切片 data[::2, 1::2];三维 data2[0,:,:] 等。
  • 形状操作reshape 可用 -1 自动计算((5,6)→(-1,3) → (10,3));squeeze 删除值为 1 的维度((3,1,2,1)(3,2),指定 dim=1 → (3,2,1),维度值不为 1 不生效);unsqueeze(dim=-1) 在最后加一维;permute 一次交换任意维顺序;transpose/permute 后张量不连续(is_contiguous()=False),view 会报错,需先 .contiguous()reshape 对连续/非连续都可用。
  • 拼接cat 不改变维度数(指定维数值相加,其他维必须相同);stack 新增一个维度(维度值=张量个数),所有张量形状必须相同。
  • 自动微分(重点实操)
    • requires_grad=True 且元素类型必须是浮点;loss 必须是标量loss.sum().backward())。
    • 梯度默认累加(上次+本次),更新前要 w.grad.zero_()
    • 更新必须 w.data = w.data - 0.01 * w.grad;直接 w = w - ... 会创建新张量导致问题。
    • 自动微分张量不能直接 .numpy(),用 w.detach() 剥离(共享数据、不自动微分)后再转。
    • 应用:y_pred = torch.matmul(x, w) + bnn.MSELoss()loss.sum().backward() → 看 w.gradb.grad

Day03:线性回归案例 + 神经网络概念 + 激活函数 + 参数初始化

  • 线性回归实操(make_regression 生成 100 个样本、1 特征、noise=10、bias=14.5):
    • TensorDataset(x, y) 构建数据集;DataLoader(batch_size=16, shuffle=True) 分批。
    • nn.Linear(1, 1) 含随机初始化的 w、b(model.weightmodel.biaslist(model.parameters()))。
    • 踩坑 1train_x 是 float64,模型 w 是 float32,需 train_x.type(torch.float32),否则类型不匹配报错。
    • 踩坑 2train_y 是一维,需 reshape(-1, 1) 成二维与 y_pred 对齐。
    • 训练循环:y_pred → loss(MSE)→ zero_grad → backward → step;100 epochs 后 w、b 逼近真实 coef、14.5;绘制损失曲线与拟合直线(训练线 vs 真实线)。
  • 激活函数实操结论
    • sigmoid:激活值范围 [0,1] 只有正信号;加权求和值在 [-6,6] 激活值才有差异(否则 0 或 1);导数范围 [0, 0.25],连乘 0.25×0.25×… 导致梯度消失;一般只在二分类输出层用,隐藏层 5 层内可考虑。
    • tanh:范围 [-1,1]、以 0 对称、有正负信号;加权求和值在 [-3,3] 导数才大,否则梯度消失;收敛比 sigmoid 快;隐藏层可用,浅层网络使用。
    • relu:范围 [0,x] 只有正信号;导数 0 或 1,线性输出大于 0 时导数为 1 不梯度消失、收敛最快;小于 0 神经元死亡(防过拟合),可换 leaky relu/prelu;优先选择、计算复杂度最小
    • softmax:多分类输出层把加权求和值转概率(torch.softmax(y, dim=1),dim=-1 按行)。
    • 绘图技巧:torch.linspace(-20, 20, 1000, requires_grad=True) + torch.sigmoid(x).sum().backward() 用 autograd 画导数图像(x.detach().numpy() 与 x.grad)。
  • 参数初始化实操nn.init.uniform_(linear.weight, a=-1/sqrt(5), b=1/sqrt(5)) 均匀区间可按 a/b 调整;正态 nn.init.normal_;其余 zeros/ones/constant/kaiming/xavier_。
  • 结论:浅层网络随机初始化;深层网络 tanh→xavier、relu→kaiming。

Day04:网络搭建 + 损失函数 + 优化方法 + 学习率衰减

  • nn.Module 搭建(ModelDemo)super().__init__() → 定义 self.linear1/linear2/output(nn.Linear)→ 在 __init__ 里用 nn.init.xavier_normal_(self.linear1.weight)nn.init.kaiming_normal_(self.linear2.weight, nonlinearity='relu') 初始化 → forward 里 sigmoid/relu/softmax(dim=-1);调用 my_model(data) 即执行 forward;summary(model, input_size=(5,3)) 统计参数;named_parameters() 查看各层 w/b。
  • 损失函数实操
    • 多分类:nn.CrossEntropyLoss(reduction='sum'),y_true 用类别索引(int64),y_pred 为 logits;reduction 默认 mean(平均损失),可改 sum(总损失)。
    • 二分类:nn.BCELoss(),y_pred 必须是 sigmoid 输出(概率)。
    • 回归:nn.L1Loss()(MAE,导数为 ±1、0 点不可导)、nn.MSELoss()(MSE,任意位置可导、越接近底部导数越小;有异常样本会放大误差易梯度爆炸)、nn.SmoothL1Loss()(MAE 与 MSE 中和:|w|>1 用 MAE、[-1,1] 用 MSE,不受异常值影响、任意位置可导)。
  • 优化方法实操结论
    • 指数加权平均:S100 = 0.1·Y100 + 0.1·0.9·Y99 + 0.1·0.9²·Y98 + …;β 越大受当前真实值影响越小,一般 0.9。
    • Momentum:optim.SGD([w], lr=0.01, momentum=0.9),计算的是当前时刻的指数移动加权平均梯度。
    • AdaGrad:optim.Adagrad([w], lr=0.01),学习率随训练次数越来越小(初期大后期小)。
    • RMSProp:optim.RMSprop([w], lr=0.01, alpha=0.9),对 adagrad 优化,用指数移动加权平均梯度代替历史累加梯度,避免学习率过快减小。
    • Adam:optim.Adam([w], lr=0.01, betas=(0.9, 0.99)),既优化学习率又优化梯度 = rmsprop + momentum。
    • 选择:SGD/momentum 用于简单任务或浅层模型;Adam 用于复杂任务或数据量大;AdaGrad/RMSProp 用于文本数据(NLP)。
  • 学习率衰减实操
    • 等间隔:optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5),每 50 轮 lr=lr*0.5。
    • 指定间隔:optim.lr_scheduler.MultiStepLR(optimizer, milestones=[50,100,160], gamma=0.5, last_epoch=-1),在指定轮次衰减。
    • 指数:optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9),lr=lr*gamma^epoch,更符合梯度下降规律(前期下降快中期慢后期更慢)。
    • 每轮训练完调 scheduler.step();用 get_last_lr() 取当前学习率;选择:优先指数、其次指定间隔、简单模型等间隔。

Day05:正则化 + 手机价格分类 + 图像基础 + CNN 卷积/池化

  • 正则化结论:防止过拟合(训练集好测试集差)、提高泛化能力;L1 正则需手动写代码实现,L2 正则用 SGD(weight_decay=);此外有 dropout、BN。
  • Dropout 实操nn.Dropout(p=0.4) 放在激活函数之后;每批次随机失活的神经元都不同,防止某个特征影响过大;不失活神经元 ÷(1-p),使训练与测试期望一致;训练 model.train()、测试 model.eval();p 取值 [0.2,0.5],简单模型概率低、复杂模型概率高。
  • BN 实操:计算每个 batch 的均值与标准差做标准化;不同 batch 统计量不同会引入噪声(防过拟合);可学习 γ、β 让每层分布不同;标准化后加权求和值落入激活函数合理区间(导数最大)加速收敛;训练时标准化、测试时不标准化nn.BatchNorm1d(一维样本,每批样本最少 2 个)、nn.BatchNorm2d(图像,按每通道二维矩阵计算)、nn.BatchNorm3d(视频);参数 num_features/eps/momentum/affine。
  • 手机价格分类:20 特征、4 类别;train_test_split(0.8, random_state=88);df 数据需 .values 取 numpy 再 torch.tensor 转张量;模型 20→128→256→4(输出层不做 softmax,CrossEntropyLoss 内含);optim.SGD(lr=1e-3)、batch=8、50 epochs;评估 model.eval() + torch.argmax(output, dim=1) + (y_pred==y).sum()/len(valid);优化手段:数据标准化、加深加宽网络、SGD→Adam、lr 1e-3→1e-4、正则化、增加轮数。
  • 图像基础:二值(1 通道 0/1)、灰度(1 通道 0-255)、索引(1 通道索引查 MAP)、RGB 真彩色(3 通道)四类;全黑/全白图 np.zeros/np.full((200,200,3))plt.imread/imsave/imshow;一张 200×200×3 的图放到全连接层就是 120000 个特征的一维向量(说明为什么需要卷积降维)。
  • 卷积层实操:卷积计算 = 带权重的卷积核与图像特征值点乘(w1x1+w2x2+…+b),卷积核=带权重参数的神经元;Padding 作用:保持形状一致、减少边缘信息丢失(未 padding 边缘只参与一次计算);Stride 默认 1(可 2/4),5×5 stride=1→3×3、stride=2→2×2;多通道卷积:卷积核通道数与图像通道数一致,各通道卷积结果加和得到新特征图的一个特征值(新特征图是 1 个二维矩阵);多卷积核 = 多少个神经元就提取多少张二维特征图;特征图公式 N=(W-F+2P)/S+1(小数向下取整);API nn.Conv2d(in_channels=3, out_channels=4, kernel_size=(3,3), stride=2, padding=0),图像先 permute(2,0,1) 变 (C,H,W) 再 unsqueeze(0) 变 (1,C,H,W)。
  • 池化层实操池化层没有神经元参与、只降维不提取特征;最大池化取窗口最大值、平均池化取均值;多通道池化各通道分别处理、通道数不变(只在高宽维度池化);nn.MaxPool2d(kernel_size=(2,2), stride=1, padding=0)nn.AvgPool2d(...)

Day06:CIFAR10 图像分类 + RNN 词嵌入 + 文本生成

  • CIFAR10 实操:torchvision 提供;训练 5 万、测试 1 万、10 类、单图 (32,32,3);CIFAR10(root='./data', train=True, transform=ToTensor())class_to_idx 查看类别映射;data.shapetargets
  • ImageModel 结构:conv1(3→6,k=3) → relu → pool1(2×2,s=2) → conv2(6→16,k=3) → relu → pool2 → linear1(16*6*6=576→120) → linear2(120→84) → out(84→10);展平 x.reshape(x.shape[0], -1)(最后一批不满 batch 不能写死)。
  • 训练:CrossEntropyLoss + Adam(1e-3),batch=8、10 epochs;model.train();统计 total_loss += loss.item()*len(y)total_correct += (torch.argmax(output, dim=-1)==y).sum();打印每轮 loss/acc/time;保存 state_dict。
  • 评估:model.eval();argmax dim=-1 取类别;Acc = correct/total。
  • 性能优化(过拟合):增加卷积核数量(3→32、6→128)、增加全连接神经元(2048)、减小学习率、加 Dropout(p=0.5)(训练集 acc 远高于测试集说明过拟合)。
  • RNN 部分:词嵌入 nn.Embedding(num_embeddings=词数量, embedding_dim=8),先 jieba 分词再查向量;RNN 层 nn.RNN(input_size=128, hidden_size=256, num_layers=1),x 形状 (5,32,128)(每句词数, 句子数, 词向量维度)、h0 (1,32,256)(层数, 句子数, 隐藏维度);h1 = relu(wh0+b+wx+b)、y1 = wh1+b(课堂笔记简化写法,正式公式为 tanh + W_hy·h_t + b_y);多层 RNN 做生成式 AI 只取最后一层隐藏状态与预测输出。
  • 歌词生成完整流程
    • build_vocab:jieba.lcut 分词 → 去重 unique_words → word_to_index → corpus_idx(行间插入空格索引分隔)。
    • LyricsDataset:__len__ 返回 word_count//num_chars;__getitem__ 返回 x=corpus[start:end]、y=corpus[start+1:end+1](-1 是因为 y 要后移一位)。
    • TextGenerator:Embedding(词数,128) → RNN(128,256,1) → Linear(256,词数);embed.transpose(0,1) 调整维度送 RNN;init_hidden(bs) 返回 zeros(1,bs,256)。
    • 训练:CrossEntropyLoss + Adam(1e-3),num_chars=32、batch_size=5、10 epochs;y 先 torch.transpose(y,0,1)reshape(-1) 与 output(seq_len*batch, 词数) 对齐;loss 从 ~1.84 降至 ~0.096。
    • 预测:predict('分手', 50),循环 argmax 取概率最大词索引作为下一输入,逐个生成。

七、大模型基础

7.1 语言模型

  • 定义:语言模型(Language Model)旨在建模词汇序列的生成概率;通俗理解就是计算一个句子概率的模型(判断一句话是否”像人话”)。
  • 标准定义:对句子 S=[W1,W2,…,Wn],语言模型计算 P(S);符合语用习惯的句子概率高。
  • 例:P(中国的首都是北京) > P(中国的首都是深圳)。
  • 概率链式法则P(S) = P(W1)·P(W2|W1)·...·P(Wn|W1,...,W(n-1))
  • 简化理解:语言模型 = 计算一个句子的概率,或预测下一个”词”的模型

7.2 语言模型发展四阶段

  1. 统计语言模型:统计学方法建模(N-gram)。
  2. 神经语言模型:简单浅层神经网络计算。
  3. 预训练语言模型:深层神经网络 + 大量无监督数据。
  4. 大语言模型:更大更深的网络 + 海量数据 + 预训练加多种后训练。

7.2.1 统计语言模型(N-gram)

  • 依据前面 N 个词预测下一个词;常见 1-gram、2-gram、3-gram;引入马尔科夫假设:一个词出现的概率只与它前面有限的几个词有关。
  • 1-gram(unigram):词与周围词独立,P(S)=P(W1)P(W2)...P(Wn);过于简单。
  • 2-gram(bigram):词仅依赖前一个词,P(S)=P(W1)P(W2|W1)...P(Wn|W(n-1))P(Wt|W(t-1)) = C(W(t-1),Wt)/C(W(t-1))(出现次数比)。
  • 3-gram(trigram):依赖前两个词,P(Wi|W(i-1),W(i-2)) = C(W(i-2)W(i-1)Wi)/C(W(i-2)W(i-1))
  • bigram 例子:P(想|我)=C(我,想)/C(我)=800/2100≈0.38;P(我想去打篮球)=P(想|我)·P(去|想)·P(打|去)·P(篮球|打)≈0.0022 > P(我想去打晚饭)≈0.00022 → 预测 [MASK]=篮球。
  • 两个缺陷:① 参数空间过大(可能性太多无法估算);② 数据稀疏严重(许多词对组合语料中没出现,最大似然估计概率为 0)。

7.2.2 神经语言模型

  • 结构:输入层 = 前 n-1 个词的词向量 C(w) 首尾拼接成 (n-1)·m 维向量 x → 隐藏层全连接 + tanh 激活 → 输出层 V 个节点(V=词汇量,全连接),y_i 表示下一个词为 i 的未归一化 log 概率 → softmax 归一化 → 取最大概率为预测。
  • 优点:神经网络建模当前词与前 n-1 个词的约束关系,泛化能力比 n-gram 好,词表征好可大幅降低数据稀疏问题。
  • 缺点:对长序列建模能力有限,可能出现长距离遗忘以及训练时梯度消失,难以稳定长文本输出。

7.2.3 预训练语言模型

  • Transformer 由编码器和解码器层组成,学习复杂语义能力强;主流预训练模型(GPT、BERT、T5)都用 Transformer 提取特征。
  • 使用方式:① 预训练:先在基础数据集/语料库上训练(无监督数据训练),学习数据普遍特征,构建基础模型(初始化参数);② 微调(Fine-tuning):在下游任务用预训练模型做迁移学习。
  • 优点:更强大的泛化能力、丰富语义表示、有效防止过拟合;缺点:计算资源需求大、可解释性差。

7.2.4 大语言模型

  • 扩展法则(Scaling Law):通过规模扩展(增加参数规模或数据规模)通常带来下游任务性能提升;预训练模型参数指数级提升,语言模型性能线性上升
  • 里程碑:2020 年 OpenAI 发布 GPT-3(1750 亿参数),首次展示大语言模型性能;对比:BERT-large 3.3 亿参数、GPT-2 17 亿参数。
  • 涌现能力:大模型具有而小模型不具有的能力(如 GPT-3 的上下文学习 In-Context Learning, ICL,可用少样本数据解决下游任务,GPT-2 不具备)。
  • 大语言模型特点:优点——具备一定智能、捕捉上下文语义、强大生成能力(文字/多模态)、可用插件自动信息检索;缺点——参数量大、算力要求高、可能生成有害/有偏见内容。

7.3 语言模型的评估指标

  • 生成类任务无确定答案,评估更复杂;开放领域有通用评测任务和数据集,垂直领域可能需自定标准。三个指标:BLEU、ROUGE、PPL。

7.3.1 BLEU(双语评估,机器翻译质量)

  • 思想:把”质量”定义为与人类翻译结果(reference)的一致性程度;分数范围 0~1,越接近 1 翻译质量越高。
  • 按 n-gram 分 BLEU-1~BLEU-4:BLEU-1 衡量单词级准确性,高阶衡量句子流畅性;实践中取 N=1~4 加权平均(权重默认各 0.25)。
  • 计算:匹配的 n-gram 个数 / candidate 中 n-gram 个数(基于精确率)。
  • 例:candidate “it is a nice day today” vs reference “today is a nice day”:1-gram 匹配 5/6、2-gram 3/5、3-gram 2/4、4-gram 1/3。
  • 综合公式:BLEU = bp · exp(Σ_(i=1..4) w_i·log(p_i))(bp 为长度惩罚系数,w_i 默认 0.25)。
  • 改进(防作弊):极端情况 candidate “the the the the” 按 1-gram 匹配度为 1 不合理 → 用词在译文中出现的最小次数 count_k = min(c_k, s_k)(c_k 在 candidate 出现次数、s_k 在 reference 出现次数),修正后 BLEU1=1/4。
  • 代码:from nltk.translate.bleu_score import sentence_bleusentence_bleu(reference, candidate, weights=(0.25,0.25,0.25,0.25))

7.3.2 ROUGE(摘要/问答评估)

  • ROUGE 分 ROUGE-N、ROUGE-L、ROUGE-W、ROUGE-S 四种;与 BLEU 类似,但 ROUGE 基于召回率,BLEU 更看重精确率
  • ROUGE-N:匹配的 n-gram 个数 / reference 中 n-gram 的个数(召回率视角)。例:同上面例句 ROUGE-1 = 5/5 = 1(生成内容完全覆盖参考文本)。
  • ROUGE-L:基于最长公共子序列(LCS),不要求匹配单词连续、只要求相对顺序一致,对词序变化鲁棒(子序列:删除若干字符不改变相对顺序,如 “ace” 是 “abcde” 的子序列)。依赖三个指标:精确率 P_LCS = LCS(X,Y)/n、召回率 R_LCS = LCS(X,Y)/m(m 参考句长、n 生成句长)、F1 = 2·P·R/(P+R)
  • 代码:from rouge import Rougerouge.get_scores(generated, reference) 返回 rouge-1/2/l 的 p、r、f。

7.3.3 PPL(困惑度)

  • 用来度量概率分布/概率模型预测样本的好坏程度;给测试集句子赋予较高概率的模型较好
  • 公式:PPL(S) = exp(-(1/N)·log p(w1,w2,...,wn));1-gram 下简化为 exp(-(1/N)·Σ log p(wi))
  • 结论:句子概率越大 → 语言模型越好 → 困惑度越小
  • 企业使用:评估微调前后模型在特定语料上的 PPL(如通用模型 qwen2.5-7B vs 垂直领域微调模型 qwen2.5-7B-SFT,微调后 PPL 应该越小)。

7.4 通用大模型评估任务 / 国内外大模型差异

  • 通用大模型评估任务;国内外大模型差异:SuperCLUE 中文大模型测评基准(superclueai.com 榜单)、OpenRouter 实际使用排名(openrouter.ai/rankings)等平台

八、15–20 个高频问题

  1. 深度学习和传统机器学习的区别? 深度学习以多层人工神经网络为架构、自动提取特征;传统机器学习依赖人工设计特征工程。深度学习需要更多数据与算力、可解释性差。
  2. 为什么神经网络需要激活函数? 没有激活函数时多层线性变换叠加仍是线性模型;激活函数引入非线性因素,使网络能逼近任意函数、拟合线性不可分问题;BP 要求激活函数可微。
  3. ReLU 为什么比 Sigmoid 好? ① 无指数运算,计算量小;② x>0 时导数为 1,梯度不衰减,缓解梯度消失,可训练深层网络;③ 输出为 0 形成稀疏性,减少参数相互依存,缓解过拟合。缺点是 x<0 导数恒 0 导致”神经元死亡”。
  4. 梯度消失的原因是什么? 反向传播用链式法则连乘各层梯度:sigmoid 导数最大 0.25、tanh 导数最大 1 且两侧趋 0,深层连乘使梯度指数级缩小趋 0(sigmoid 约 5 层即消失),浅层参数几乎不更新。解决方案:ReLU、合理初始化(xavier/kaiming)、BN、ResNet 残差连接等。
  5. Sigmoid 有哪些缺点? ① 饱和区导数≈0 → 梯度消失;② 输出不以 0 为中心(恒正),更新方向单一;③ 指数运算计算量大。一般只用于二分类输出层。
  6. 梯度爆炸是什么?如何产生? 网络层间梯度大于 1 时连乘导致指数级增长(如 MSE 损失在误差大时梯度大、初始权重过大)。缓解:合理初始化、梯度裁剪、BN、降低学习率。
  7. 全连接网络的参数数量怎么算? 每层参数 = 输入特征数 × 输出神经元数 + 输出神经元数(每个神经元 w 个数 + 1 个 b)。例 3→3 层为 3×4=12 个。
  8. Epoch、Batch、Iteration 的区别? Epoch=全部数据完整训练一次;Batch=每次参数更新用的样本数;Iteration=用 1 个 Batch 更新一次参数。50000 样本、batch=256 → 每 epoch 约 196 个 iteration。
  9. 反向传播(BP)的原理? 利用链式法则从输出层向输入层依次求损失对各参数的偏导(梯度),结合梯度下降更新权重:w = w – lr·grad。”反向传播传播的是梯度”。
  10. Momentum、AdaGrad、RMSProp、Adam 的区别? Momentum 用梯度的指数加权平均加速收敛、跨鞍点;AdaGrad 按历史梯度平方和自适应降学习率(易过早衰减);RMSProp 用指数加权平均替代平方和,解决过早衰减;Adam = Momentum + RMSProp,同时修正梯度与学习率,最常用。
  11. 为什么训练后期要减小学习率? 后期学习率过大会导致 loss 振荡、跳过最优点;过小又收敛慢。衰减方式:StepLR 等间隔、MultiStepLR 指定间隔、ExponentialLR 指数衰减(lr=lr·γ^epoch)。
  12. Dropout 的原理?训练和测试有什么区别? 训练时神经元以概率 p 随机置 0,未置 0 的缩放 1/(1-p)(保持期望不变),等价训练子网络集成、防过拟合;测试时 Dropout 不生效(model.eval() 用全部神经元)。
  13. Batch Normalization 的作用与训练/推理差异? 对每层输入标准化(均值 0 方差 1)再缩放平移(可学习 γ、β),减少内部协方差偏移、加速收敛、有正则化效果;放在激活函数之前。训练时用当前 batch 统计量并维护全局移动平均,推理时用全局统计量(model.eval())。
  14. 卷积核、步长、填充的作用?特征图尺寸怎么算? 卷积核提取局部特征(一个卷积核=一个神经元);步长控制滑动步伐(越大特征图越小);填充保持尺寸、保留边缘信息。公式:N = (W-F+2P)/S + 1(向下取整)。
  15. CNN 相比全连接网络的优势? 局部连接(局部感受野)+ 权值共享 → 参数大大减少、符合图像空间结构;具有平移不变性;自动提取层次化特征(低层边缘→高层物体)。
  16. 池化的作用?最大池化和平均池化的区别? 降维减少计算量与参数、提高鲁棒性、防过拟合、提取抽象特征;最大池化取窗口最大值(保留显著特征),平均池化取均值(保留整体信息);池化前后通道数不变。
  17. ResNet 解决什么问题? 通过残差块(跳跃连接)让梯度可直接反向传播到浅层,解决深度网络的梯度消失,可训练 50/152 层极深网络。
  18. RNN 的原理?为什么难以捕捉长期依赖? RNN 用隐藏状态 h_t=tanh(W_ih·x_t+W_hh·h_(t-1)+b) 循环传递信息,适合序列数据;但随时间步展开很深,梯度连乘导致梯度消失/爆炸,长距离信息丢失,故标准 RNN 难以捕捉长期依赖(资料未涉及 LSTM/GRU 门控细节)。
  19. 词嵌入(Embedding)相比 one-hot 的好处?nn.Embedding 参数含义? one-hot 高维稀疏、无法表达语义相似性;词嵌入低维稠密、能学习词间语义关系、降低维度。nn.Embedding(num_embeddings=词数量, embedding_dim=词向量维度)
  20. 文本生成为什么是分类问题?预测流程如何? 词表大小 = 类别数,每个时间步预测下一个词即对词表分类;流程:词嵌入 → RNN 更新隐藏状态 → 全连接输出每个词的得分 → softmax 转概率 → 取概率最大的词作为下一时间步输入,迭代生成。
  21. 语言模型是什么?N-gram 有什么缺陷? 语言模型计算句子序列概率 P(S)(或预测下一个词)。N-gram 依据前 N-1 个词预测,缺陷:参数空间过大数据稀疏(未出现组合概率为 0)。
  22. BLEU、ROUGE、PPL 分别是什么? BLEU:机器翻译与参考译文 n-gram 匹配(重精确率),0~1 越大越好;ROUGE:摘要/问答与参考答案匹配(重召回率),ROUGE-L 基于最长公共子序列;PPL:困惑度 = exp(-(1/N)Σlog p(w)),越小越好,用于评估语言模型在语料上的概率拟合。
  23. 什么是扩展法则(Scaling Law)与涌现能力? Scaling Law:模型参数/数据规模指数级提升时性能线性上升;涌现能力:大模型具有而小模型不具有的能力(如 GPT-3 的上下文学习 ICL),这也是”大语言模型”区别于小预训练模型的原因。
  24. PyTorch 中为什么梯度要清零?为什么用 x.data 更新而不是 x = x – lr·grad? 梯度默认累加(x.grad 是历史梯度之和),不清零会叠加错误梯度;x = x - lr·grad 会创建新张量、破坏计算图,需用 x.data = x.data - lr·x.grad 就地更新原始数据。
  25. 为什么 nn.CrossEntropyLoss 前不需要手动 softmax? PyTorch 的 CrossEntropyLoss = softmax + 交叉熵损失一体化实现,直接接收网络 logits 与类别索引(int64)即可;若自己加了 softmax 再用它会产生双重 softmax 错误。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇