- ML 2022 Spring
- ML 2025 Spring
- GitHub - datawhalechina/leedl-tutorial
- 《动手学深度学习》 — 动手学深度学习 2.0.0 documentation
- 本文是datawhale苹果书、李宏毅教授2021-2025ML课程、李沐动手学深度学习的笔记
机器学习基础

数学基础
标量函数关于向量的导数
在机器学习中,标量函数对向量求导数的结果是一个梯度向量。梯度向量包含了函数对向量中每个分量的偏导数。
梯度的定义
梯度 实际上是由所有偏导数组成的向量:
实例
我们展开:
对每个分量 求导:
所以整体梯度就是:
b = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
print(f"向量 b = {b}")
print(f"b 的维度: {b.shape}")
# 计算 z = ||b||² = b^T b
z = torch.dot(b, b) # 这是一个标量
print(f"z = ||b||² = {z}")
print(f"z 的维度: {z.shape} (标量)")
# 计算梯度
z.backward()
print(f"∂z/∂b = {b.grad}")
print(f"梯度的维度: {b.grad.shape}")
# 梯度应该是 2b
ML Framework
target: looking for function
- function with unknown
- define loss
- optimization
具体可以分为 5 步:
- 读取数据:分 batch
- 初始化参数:给出事的权重 w 偏置 b
- 前向传播:计算出预测值
- 计算损失
- 反向传播,更新参数
function with unknown
Hard Sigmoid 是常见的目标 function。
- 可以用 Sigmoid Function 逼近 Hard Sigmoid

多个 sigmoid 合成 red curve

最终的 function with unknown

loss

最常见的损失函数是平方误差 square error:预测值与实际值的差的平方。
optimize
不断更新 gradient

总的数据集会分成很多 batch:
- 遍历所有batch称为一次epoch
- update指更新一次batch

more layers
可以把模型进一步改成多层:

每一层都是一个 Sigmoid 或 ReLU 的 function,称为神经元(neuron),很多的神经元称为神经网络 (neural network)。
神经网络不是新的技术,80、90 年代就已经用过了,后来为了要重振神经网络的雄风,所以需要新的名字。每一层,称为隐藏层(hidden layer),很多的隐藏层就“深”,这套技术称为深度学习。
但是层数不一定越深越好,可能会出现过拟合 overfitting 的问题:

常见的机器学习问题
- 监督学习
- 回归
- 分类
- 标记问题
- 搜索
- 推荐系统
- 序列学习
- 无监督学习
- 聚类 clustering :没有标签的情况下,给数据分类/聚类
- 主成分分析 principal component analysis:找到少量的参数来准确地捕捉数据的线性相关属性,比如,一个球的运动轨迹可以用球的速度、直径和质量来描述。
- 因果关系 causality 和 概率图模型 probabilistic graphical models 问题:描述观察到的许多数据的根本原因。
- 生成对抗性网络 generative adversarial networks :为我们提供一种合成数据的方法,甚至像图像和音频这样复杂的非结构化数据。
- 离线学习:与环境交互学习
- 强化学习
是否监督的核心区别是有无标签数据,但这背后反映的是更本质的差异。
- 监督学习有标签,模型学的是输入→输出的映射关系
- 目标明确,e.g. 给你一张图,告诉你是猫还是狗,模型就去学这个判断规则
- 无监督学习没有标签,模型只有输入数据
- 目标是自己发现数据内部的结构、规律或分布,比如聚类、降维、密度估计
Model Bias
假设模型过于简单,一个有未知参数的函数代 θ1 得到一个函数 fθ1(x),同理可得到另一个函数 fθ2(x),把所有的函数集合起来得到一个函数的集合。但是该函数的集合太小了,没有包含任何一个函数,可以让损失变低的函数不在模 型可以描述的范围内。在这种情况下,就算找出了一个 θ∗ ,虽然它是这些蓝色的函数里面最好的一个,但损失还是不够低。

Optimization
一般只会用到梯度下降进行优化,这种优化的方法很多的问题。比如(a)可能会卡在局部最小值的地方,无法找到一个真的可以让损失很低的参数。

Overfitting
过拟合的表现为:训练数据上面的损失小,测试数据上的损失大。
例子:模型过于灵活
在这 3 个蓝点(训练数据)上面,要让损失低,所以模型的这个曲线会通过这 3 个点,但是其它没有训练集做为限制的地方,因为它的灵活性很大,所以模型可以变成各式各样的函数,没有给它数据做为训练,可以产生各式各样奇怪的结果(“随意”)。
最终,表现为训练数据loss为0,测试数据loss很大。

可以用数据增强和限制模型的方法,降低 overfitting
data augmentation
根据问题的理解创造出新的数据。举个例子,在做图像识别的时候,常做的 一个招式是,假设训练集里面有某一张图片,把它左右翻转,或者是把它其中一块截出来放大 等等。
limitation
限制模型,让模型不要有过大的灵活性。
- 减少模型参数:对于神经网络,可以减少每层的参数
- 减少数据特征值
- 早停(early stopping)、正则化(regularization)和丢弃法(dropout method)
Cross Validation
交叉验证 Cross Validation 是为了避免在测试集上面过拟合。
k 折交叉验证就是先把训练集切成 k 等份。在这个例子,训练集被切成 3 等份,切完以后,拿其中一份当作验证集,另外两份当训练集。
- 这件事情要重复 3 次:第一份第 2 份当训练,第 3 份当验证;第一份第 3 份当训练,第 2 份当验证;第 1 份当验证,第 2 份第 3 份当训练。

Mismatch
不匹配,简单理解就是一种反常的情况发生了。

而且,增加数据也不能让模型做得更好,到底有没有mismatch,要看人对数据本身的理解。
Local Minima and Saddle Point
- local minima 是局部极小值
- saddle point 是鞍点,不是极小,可以向其他方向 escape
这两者一般统称为 critical point 临界点。

determining the types of critical point
损失函数可由于泰勒级数近似为:
其中,H 里面放的是 L 的二次微分,可以通过 的正负判断是否是极小值。
batch size
大的批量往往在训练的时候结果比较差,小的批量优化的结果是比较好的,这个是优化的问题。
local minima 也分好坏,如下图:
- flat minima 是好的
- sharp minima 是坏的

评价 local minima 好坏的根本在于:
- train 和 test 的 loss 一般有一些差别
- 两者的 flat minima 往往很接近
- 但是 sharp minima 很有可能会有很大差别
批量大小对梯度下降法的影响的直观理解:
大的批量大小会让我们倾向于走到“峡谷”里面,而小的批量大小倾向于让我们走到“盆地” 里面。小的批量有很多的损失,其更新方向比较随机,其每次更新的方向都不太一样。即使 “峡谷”非常窄,它也可以跳出去,之后如果有一个非常宽的“盆地”,它才会停下来。
momentum method
- 动量法是另一种可以对抗 local minima 和 saddle point 的方法
假设误差表面就是真正的斜坡,参数是一个球,把球从斜坡上滚下来,如果使用梯度下降,球走到或鞍点就停住了。
但是在物理的世界里,一个球如果从高处滚下来,就算滚到鞍点或局部最小值点,因为惯性的关系它还是会继续往前走。如果球的动量足够大,其甚至翻过小坡继续往前走,它并不一定会被鞍点或局部最小值点卡住,如果将其应用到梯度下降中,这就是动量。
引入动量后,可以从两个角度来理解动量法:
- 一个角度是动量是梯度的反方向加上前一次移动的方向
- 另外一个角度是当加上动量的时候,更新的方向不是只考虑现在的梯度,而是考虑过去所有梯度的总和

- 其中 η 是学习率, λ 是前一个方向的权重参数,是需要调的。
Adaptive Learning Rate
不同学习率:

- 图中误差表面的最低点在叉号处
- 学习率太大会导致训练时参数不断震荡,如图a
- 学习率变小可以解决震荡的问题,但是在左拐以后,BC 段的坡度已经非常平坦了(指梯度很小),这种小的学习率无法再让参数前进到目标位置,如图b
AdaGrad
AdaGrad(Adaptive Gradient)是典型的自适应学习率方法,其能够根据梯度大小自动调整学习率。AdaGrad 可以做到梯度比较大的时候,学习率就减小,梯度比较小的时候,学习率就放大。
原始的梯度下降更新某个参数 θ 的过程为(学习率固定):
AdaGrad 的更新过程,学习率不再固定:
新引入的符号的说明,要点就是学习率就变得参数相关(parameter dependent):

最终自适应的效果如下:

RMSProp
RMSprop(Root Mean Squared propagation)是 Geoffrey Hinton 在 Coursera 上的深度学习的课程中提到的,没有论文,属于黑科技了...
RMSProp 第一步跟 Adagrad 的方法是相同的,即
第二步更新过程为
- 这里额外引入了一个超参数 α,且 0 < α < 1。
通过 α 可以在计算算均方根的时候,调整现在这个梯度的重要性。如果 α 设很大趋近于 1,代表 g1i 比较不重要,之前算出来的梯度比较重要。
而上一节的 Adagrad 则是每一个梯度都有同等的重要性,不够灵活。
Adam
- Adam(Adaptive moment estimation)是最常用的优化策略/优化器 optimizer
Adam 可以看作 RMSprop 加上动量,其使用动量作为参数更新方向,并且能够自适应调整学习率。PyTorch 里面已经写好了 Adam 优化器,这个优化器里面有一些超参数需 要人为决定,但是往往用 PyTorch 预设的参数就足够好了。
Learning Rate Scheduling
学习率调度(learning rate scheduling)中 η 跟时间有关,最常见的策略是学习率衰减(learning rate decay)。

还有一种策略是 warmup,即先上升一小段,到达一定值再下降。
BERT 和 Transformer 的训练都使用了 warmup,但 warmup 比较像一个 trick,没有人严谨解释为什么,一个可能的原因是:统计的结果需要足够多的数据才精准,一开始统计结果 σ 是不精准的,所以需要先上升一段时间,以收集有关 σ 的统计数据。
神经网络的两个核心
线性和非线性交替
线性和非线性处理单元的交替(称为“层”)。
神经网络的每一层通常由两种处理单元构成:
线性变换:例如矩阵乘法
y=Wx+by = Wx + b
这一步是对输入进行线性组合,本质上相当于传统的线性模型,比如线性回归、感知机。非线性激活函数:例如 ReLU、Sigmoid、Tanh 等
a=σ(y)a = \sigma(y)
非线性激活函数用于打破线性限制,让网络能够逼近复杂的非线性函数。
链式法则
一句话总结,链式法则的本质是 --- 复合函数求导,逐层相乘。

链式法则(反向传播)用于一次性调整全部参数。
- 神经网络训练的目标是最小化一个损失函数(loss function),如分类任务中的交叉熵。
- 但网络中的参数成百上千,分布在多层中,如何计算它们对 loss 的影响?
这就用到了链式法则(Chain Rule):在复合函数中,整体导数是各层导数的乘积。
例如:
反向传播(backpropagation)正是利用链式法则:
- 从输出层开始,逐层向后传播梯度
- 每层根据自身的输入、输出和激活函数,计算梯度
- 所有参数的梯度在一次前向-反向传播中完成计算
NOTE
梯度为什么是向后传的 因为损失 L 是在最后一层算出来的,我们只知道"输出错了多少"。
要知道第一层的参数该怎么调,必须把这个"错误信号"一层层往回传,从数学上看,就是从后往前求损失函数对于每一层的参数的导数(梯度)。
为什么必须要回传,其实是复合函数求导法则(链式法则)可以通过函数套函数来理解,我们所说的从最后一层开始算导数,最后一层就是最外层的函数,复合函数求导要求我们从最外层开始链式求导,所以如果想知道最内层的导数(第一层),必须先求出最外层的导数,一层层求出来。
总结
| 原则 | 内容 | 作用 |
|---|---|---|
| 线性 + 非线性层交替 | + 激活函数 | 提升表达能力,逼近复杂函数 |
| 链式法则 / 反向传播 | 用链式求导法一次性计算所有参数的梯度 | 高效训练整个网络 |
分类与回归
分类与回归是深度学习最常见的两种问题。

回归
最基础的单层线性回归:
from torch import nn
# Sequential = the list of layers
net = nn.Sequential(nn.Linear(2, 1))
线性回归原理
在机器学习领域,我们通常使用的是高维数据集,建模时采用线性代数表示法会比较方便。 当我们的输入包含个特征时,我们将预测结果表示为:
将所有特征放到向量中,并将所有权重放到向量中,我们可以用点积形式来简洁地表达模型:
- 向量对应于单个数据样本的特征。
用符号表示的矩阵可以很方便地引用我们整个数据集的个样本。其中,的每一行是一个样本,每一列是一种特征。
对于特征集合,预测值可以通过矩阵-向量乘法表示为:
- 其中是特征矩阵,是权重向量,是偏置项。
- 假如把矩阵向量乘法的式子看成
线性方程组求解,那么是需要求的解。
分类
分类的核心在于 Class as one-hot vector 。
使用 one-hot vector (独热编码)每个 vector 的距离是一样的,直接用数字 1 2 3 的话,三者之间的距离不同。

Softmax
Softmax 回归可以看作是线性回归在分类问题上的扩展。
Softmax 函数的作用是将未规范化的预测变换为非负数并且总和为1,同时让模型保持可导的性质。
公式省流:
- 归一化:对每个未规范化的预测求幂,这样可以确保输出非负。
- 保证概率和是1:每个求幂后的结果除以它们的总和。
对数似然
对数似然是似然函数的对数。
- 似然可以理解为概率,区别是似然的思维是固定数据,变化参数,概率相反。
在多分类问题中,每个样本服从多项式分布,其概率质量函数为:
在softmax回归中:
似然函数:表示给定所有特征 ,观测到所有标签 的概率
对数似然:取似然函数的对数
另外,由于概率总小于 1 ,概率的对数总是负的,所以一般 loss 都要用负对数似然,这样 loss 负负得正,是一个正值,这时候就是最小化 loss 就是最小化负对数似然。
交叉熵损失
交叉熵损失是分类问题最常用的损失函数,衡量的是两个概率分布 p(真实标签)和 q(模型预测)之间的距离。
交叉熵公式:
注意,交叉熵损失在独热编码的情况下退化为负对数似然:
- 由于 是一个长度为 的独热编码向量,所以除了一个值为1项以外,其他所有项都为0
梯度计算:
Pytorch 的交叉熵计算函数内部使用了 LogSumExp 技巧,避免原始公式容易出现的溢出问题。
loss = nn.CrossEntropyLoss(reduction='none')
多层感知机
多层感知机由多层神经元组成, 每一层与它的上一层相连,从中接收输入; 同时每一层也与它的下一层相连,影响当前层的神经元。 当我们训练容量较大的模型时,我们面临着过拟合的风险。
全连接网络

加入隐藏层
直接的输入到输出的线性模型往往难以符合实际,所以我们需要在网络中加入隐藏层,最简单的做法是多层全连接网络:

非线性的激活函数
为了发挥多层架构的潜力,我们还需要在仿射变换之后对每个隐藏单元应用非线性的激活函数(activation function)。
一般每个隐藏层之后都会加一层激活函数。
CNN
RNN
REF

On this page
- 机器学习基础
- 数学基础
- 标量函数关于向量的导数
- 梯度的定义
- 实例
- ML Framework
- function with unknown
- loss
- optimize
- more layers
- 常见的机器学习问题
- Model Bias
- Optimization
- Overfitting
- data augmentation
- limitation
- Cross Validation
- Mismatch
- Local Minima and Saddle Point
- determining the types of critical point
- batch size
- momentum method
- Adaptive Learning Rate
- AdaGrad
- RMSProp
- Adam
- Learning Rate Scheduling
- 神经网络的两个核心
- 线性和非线性交替
- 链式法则
- 总结
- 分类与回归
- 回归
- 线性回归原理
- 分类
- Softmax
- 对数似然
- 交叉熵损失
- 多层感知机
- 全连接网络
- 加入隐藏层
- 非线性的激活函数
- CNN
- RNN
- REF
