Candlest 的博客

Back

你背负的今天已经无可挽救了吗-小杏LaylaBlur image

学了相关的东西,再来回顾 CS231N。

前期准备:作业环境#

cd /Volumes/lexar1t/learn/cs231n/assignment1
uv venv --python 3.9
source .venv/bin/activate
uv pip install numpy matplotlib future jupyterlab jupyterlab-lsp python-lsp-server
cd cs231n/datasets && ./get_datasets.sh && cd ../..
bash

Lec1 Intro#

训练动力学#

高容量算法需要靠海量数据驱动,模型才能学会泛化。这些泛化规则和过拟合背后,有着深层的数学原理。

L=1NiLidata loss(拟合数据)+λR(W)正则(压制容量,防过拟合)L = \underbrace{\frac{1}{N}\sum_i L_i}_{\text{data loss(拟合数据)}} + \underbrace{\lambda R(W)}_{\text{正则(压制容量,防过拟合)}}

CV 的最简单任务:图像分类#

2011 至今,ImageNet 见证了深度学习的再度繁荣。

imagenet

CV 的进阶任务:图像理解#

包括图像分割,目标检测……

CV 的未来:和生成式结合#

视觉不是全部。

Lec2 DL Basics#

计算机视觉的挑战#

以 RGB 图像为例:

平移旋转(位置及其关系)

RGB 变化(取决于表面材质、颜色和光源)

背景(高频和低频信息)

尺度变化(缩放)

图像尺寸(被归一化了,没那么重要)

遮挡

形变

类内差异

上下文

数据驱动的算法构建#

以图像识别为例

  1. 收集 (images, label) 对
  2. 用机器学习算法设计分类器,并使用数据训练
  3. 用保留数据测试分类器效果

最简单的两类分类器#

Nearest Neighbor Classifier#

算法设计#

distance_metric

曼哈顿距离(L1)和欧氏距离(L2):旋转敏感和旋转不敏感。(泛函)

距离

L1 距离对于旋转是不规则的,如果我们的特征是具体的,尺度不同的,推荐使用。

L2 距离是一个圆,如果我们的特征尺度相似,并不具体,可以使用。

超参数#

最近的 K 个邻居投票决定这个点是什么类别。

K 是我们接触的第一个超参数。

调参#

如何调参,寻找更好的超参数?

如何调参

也就是说,将我们能够得到的数据划分为三段:训练集、验证集和测试集。

我们在测试集上训练,选定对于验证集效果最好的超参,然后拿去给测试集测试。

还能更合理吗?交叉验证

交叉验证

但是太吃算力了,在大规模深度学习中是高成本的。人们往往依靠直觉调参,使用单一验证集。

Linear Classification#

原理:

f(x,W)=Wx+bf(x,W) = Wx + b

Linear Classification

现代深度学习模型的构建原语。

Linear_Classification2

局限性(单层)

局限性

损失函数 Loss#

L=1NiLi(f(xi,W),yi)\mathcal{L} = \frac{1}{N} \sum_i L_i (f(x_i,W), y_i)

反映预测的偏差程度。

在机器学习中,找到参数 w 使得损失函数 L 最小的过程称为优化(optimization)

Softmax 分类器#

归一化,选最大。

给定输入就是这第 ii 张图 xix_i 的前提下,标签 YY 等于第 kk 类的概率

P(Y=kX=xi)=eskjesjP(Y=k|X=x_i) = \frac{e^{s_k}}{\sum_j e^{s_j}}

交叉熵#

KL->MLE

计算理想分布 P(y)=(ABC100)P(y) = \begin{pmatrix} A & B & C\\1 & 0 & 0 \end{pmatrix} 和实际分布:P(y)=(ABCxaxbxc)P(y) = \begin{pmatrix} A & B & C\\ x_a & x_b & x_c \end{pmatrix} 的 KL 散度:

KL(P,Q)=P(y)logP(y)Q(y)=logP(xa)\text{KL}(P,Q) = \sum P(y) \log{\frac{P(y)}{Q(y)}} = - log P(x_a)

代入 Y=kX=xiY=k|X=x_i 也就是说:

L=KL(P,Q)=logP(Y=kX=xi)\mathcal{L} = \text{KL}(P,Q) = - log P(Y=k|X=x_i)

我们也叫这个为交叉熵(当理想分布为 One-Hot 编码时)

Lec3 Regularization & Optimization#

正则化#

L=1NiLi拟合训练数据+λR(W)避免模型在训练集上做的太好L = \underbrace{\frac{1}{N}\sum_i L_i}_{\text{拟合训练数据}} + \underbrace{\lambda R(W)}_{\text{避免模型在训练集上做的太好}}

对于 λR(W)\lambda R(W)λ\lambda 是正则化强度, R(W)R(W) 是正则化项。

L2 正则化(也叫 weight decay):

R(W)=klWk,l2R(W) = \sum_k \sum_l W_{k,l}^2

会让近 0 值被更多保留。

L1 正则化:

R(W)=klWk,lR(W) = \sum_k \sum_l| W_{k,l} |

会让权重更少近 0 项,保留少数非零项。

组合 L1 L2:

R(W)=klβWk,l2+Wk,lR(W) = \sum_k \sum_l \beta W_{k,l}^2 + | W_{k,l} |

正则化是一个不断发展的前沿课题。很多东西都能扯到正则化。

不要用网络大小来做正则化,应该用更强的正则化项。保持网络足够大、有足够的表达能力,然后通过正则化手段来控制模型的复杂度和泛化能力。

优化#

Loss Landscape

可微且凸函数。

海森矩阵#

我们用牛顿法引入海森矩阵。

高中我们学过,求 f(x)=0f(x) = 0 可以用:

x=xf(x)f(x)x' = x - \frac{f(x)}{f'(x)}

逐步逼近。

模型效果最好 \lrArr L(W)L(W) 取极小值 \lrArr L(W)=0L'(W) = 0。于是我们又回到了牛顿迭代法:

W=WL(W)L(2)(W)W' = W - \frac{L'(W)}{L^{(2)}(W)}

把一共有 nn 个参数的权重拉直为 W1WnW_1 \dots W_n

原来的一阶导 L(W)L'(W) 变成梯度 L(W)\nabla L(W)(雅可比矩阵退化)

原来的二阶导 L(2)(W)L^{(2)}(W) 变成海森矩阵:

H=(2LW1W12LW1W22LW1Wn2LW2W12LW2W22LW2Wn2LWnW12LWnWn)H= \begin{pmatrix} \frac{\partial^2 L}{\partial W_1 \partial W_1} & \frac{\partial^2 L}{\partial W_1 \partial W_2} & \cdots & \frac{\partial^2 L}{\partial W_1 \partial W_n}\\[4pt] \frac{\partial^2 L}{\partial W_2 \partial W_1} & \frac{\partial^2 L}{\partial W_2 \partial W_2} & \cdots & \frac{\partial^2 L}{\partial W_2 \partial W_n}\\[2pt] \vdots & \vdots & \ddots & \vdots\\[2pt] \frac{\partial^2 L}{\partial W_n \partial W_1} & \cdots & \cdots & \frac{\partial^2 L}{\partial W_n \partial W_n} \end{pmatrix}

不计成本的优化:

W=WLH=H1LW' = W - \frac{\nabla \mathcal{L}}{H} = H^{-1} \nabla \mathcal{L}

这就是牛顿法。现实里面的方法是做各种近似,然后以距离牛顿法的效果有多远为评价标准。

梯度下降(Gradient Descent, GD):

L=L+λWL(W,x,y)L' = L + \lambda \nabla_W L(W,x,y)
  1. 数值解,浮点运算
  2. 解析解,DAG 图链式发展

梯度下降遇到的问题#

局部最优解#

local minima 不等于 global minima

鞍点#

鞍点

鞍点和平原是优化要面临的主要挑战。

鞍点海森矩阵非正定。

随机梯度下降(Stochastic DG, SDG)#

x,yx,y 取 minibatch:

L=L+λWL(W,x,y)L' = L + \lambda \nabla_W L(W,x',y')

引入 Momentium#

优化器保存动量。

没动量时:

xt+1=xtαf(xi)x_{t+1} = x_t - \alpha \nabla f(x_i)

有动量时:

vt+1=ρ衰减系数vt+f(xi)xt+1=xtα学习率vt+1\begin{align*} v_{t+1} &= \overset{\text{衰减系数}}{\rho} v_t + \nabla f(x_i)\\ x_{t+1} &= x_t - \overset{学习率}{\alpha} v_{t+1} \end{align*}

RMSProp#

在平坦的地方加速,在陡峭的地方减速。

衰减系数 β\beta ,决定”过去的信息保留多久、当前值更新时新旧数据各占多少权重”,指数滑动平均(EMA) 一般能记住 11β\dfrac{1}{1-\beta} 步的信息。

st+1=βst+(1β)(f(xt))2xt+1=xtαst+1+ϵf(xt)\begin{align*} s_{t+1} &= \beta\, s_t + (1-\beta)\big(\nabla f(x_t)\big)^2\\ x_{t+1} &= x_t - \dfrac{\alpha}{\sqrt{s_{t+1}} + \epsilon}\, \nabla f(x_t) \end{align*}

ϵ=1e7\epsilon = 1e-7是一个防止除零的数值稳定性技巧。

这个自适应学习率是工程直觉 + 启发式设计(归一化)。

Adam#

Who is Adam ?

缝合怪。

mt+1=β1mt+(1β1)f(xt)st+1=β2st+(1β2)(f(xt))2xt+1=xtαst+1+ϵmt+1\begin{align*} m_{t+1} &= \beta_1 m_t + (1-\beta_1)\nabla f(x_t) \\ s_{t+1} &= \beta_2 s_t + (1-\beta_2)\big(\nabla f(x_t)\big)^2\\ x_{t+1} &= x_t - \dfrac{\alpha}{\sqrt{s_{t+1}}+\epsilon}\, m_{t+1} \end{align*}

AdamW:把权重衰减从梯度计算里移动到最后更新参数那一步,权重衰减不会被 Adam 的自适应缩放机制干扰。

lr衰减策略#

Cosine:

αt=12α0(1+cos(tπ/T))\alpha_t = \frac{1}{2}\alpha_0\left(1+\cos(t\pi/T)\right)

Linear:

αt=α0(1t/T)\alpha_t = \alpha_0(1-t/T)

Inverse sqrt:

αt=α0t\alpha_t = \frac{\alpha_0}{\sqrt{t}}

Warm-up:

αt={α0t/twarmupttwarmup(warmup 阶段:爬升)Cosine/Linear/Inverse sqrt 等t>twarmup(衰减阶段:下降)\alpha_t = \begin{cases} \alpha_0 \cdot t/t_{warmup} & t \le t_{warmup} \quad \text{(warmup 阶段:爬升)} \\ \text{Cosine/Linear/Inverse sqrt 等} & t > t_{warmup} \quad \text{(衰减阶段:下降)} \end{cases}

Lec4 NN & Backpropagation#

MLP#

上一节我们介绍了单层线性分类器,只要把它扩展到多层,就变成了 MLP 多层感知机。

f(x)=fn(x)=Wnσ(fn1(x))+bn,f1(x)=W1x+b1\begin{align*} f(x) = f_n(x) &= W_n \sigma(f_{n-1}(x)) + b_n,\\ f_1(x) &= W_1 x + b_1 \end{align*}

这里我们通过 σ()\sigma(\cdot) 引入了非线性。

激活函数#

全都是启发式设计,就悟去吧。

Sigmod#

σ(x)=11+ex\sigma(x) = \frac{1}{1+e^{-x}}

Tanh#

tanh(x)=exexex+ex\tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}

Tanh 和 Sigmod 有严重的梯度消失和过饱和问题,于是引入了 ReLU。

ReLU#

f(x)=max(0,x)f(x) = \max(0,x)

但是 ReLU 有死神经元问题。

Leaky ver:

f(x)=max(0.1x,x)f(x) = \max(0.1x,x)

缓解。

ELU#

f(x)={x,x>=0α(ex1),x<0f(x) = \begin{cases} x, \quad &x>=0\\ \alpha(e^x - 1), \quad &x < 0 \end{cases}

负区间用指数曲线代替线性,让负值饱和到 -α,既避免神经元死亡,又让输出均值更接近0(BatchNorm like),但计算量比 ReLU 大。

GeLU#

f(x)=xΦ(x)f(x) = x \Phi(x)

其中 Φ(x)\Phi(x) 是标准正态分布的累积概率。

Φ(x)=P(Xx)=x12πet22dt\Phi(x) = P(X \le x) = \int_{-\infty}^{x} \frac{1}{\sqrt{2\pi}} e^{-\frac{t^2}{2}}\, dt

按输入大小做随机丢弃。

SwiLU#

f(x)=xσ(x)f(x) = x \sigma(x)

把这个非初等函数 Φ(x)\Phi(x) 替换成 σ(x)\sigma(x),工程上更加廉价,效果相近。

雅可比矩阵与反向传播#

导数 Df(a)Df(a) 是函数在某一点附近,最好的逼近的线性部分。

f(a+h)=f(a)+Df(a)h仿射:最好的逼近+o(h)f(a+h) = \underbrace{f(a) + Df(a)h}_{\text{仿射:最好的逼近}} + o(|h|)

选定了两组基(函数的输入和输出),线性映射就能被矩阵表示:

Jij=fixj,J=(1f1nf11fmnfm)J_{ij} = \frac{\partial f_i}{\partial x_j}, \qquad J = \begin{pmatrix} \partial_1 f_1 & \cdots & \partial_n f_1 \\ \vdots & & \vdots \\ \partial_1 f_m & \cdots & \partial_n f_m\end{pmatrix}

自动微分:JVP 和 VJP#

考虑

(N×M)×(N×D)(N\times M)\times(N\times D)

取一个很普通的 Transformer 配置,N=64N=64D=M=4096D=M=4096

6440966440966.9×101064\cdot4096\cdot64\cdot4096 \approx 6.9\times10^{10}

现代深度学习反向传播通常采取 FP16,那么 6.9×10106.9\times10^{10} 是 132 GB+,是远远不可接受的。

所以我们引入 Vector-Jacobian Product 优化方法。我们根本不需要 JJ 本身,

u J JuJVP:我动了,下游会怎样v J yˉVJP:下游告诉我,我动一下值多少\underbrace{u \xrightarrow{\ J\ } Ju}_{\text{JVP:我动了,下游会怎样}} \qquad \underbrace{v \xleftarrow{\ J^\top\ } \bar y}_{\text{VJP:下游告诉我,我动一下值多少}}

Lec5-8 现代神经网络原语#

后续部分比较熟悉或者和我已经了解的部分重叠,所以过的比较快。

Lec5-6 CNN#

核心是两个算子在计算图被引入。

cnn

Yann LeCun 在 1998 提出 LeNet。

手工特征提取 + 线性分类器在 2000s 被大量使用,但是不够 Scaling 已经被扫入历史的垃圾桶。

2012 年 AlexNet 之后,CNN 用端到端训练把特征提取变成了机器可学习的参数。

Convolutional Layer#

核心是假设图像有平移不变性和局部性。

Pooling Layer#

感受野假设。

Lec7 RNN#

我已经了解 GRU 和 LSTM,所以跳过。

Lec8 Transformer#

注意力机制本身就是一种对神经网络非常强大的 primitive。

加性注意力

这一块主要在 CS336 上。

Lec9 图像高级任务#

对我来说,没啥价值。

Lec10 Videos#

不如去看 Qwen3-VL 的设计架构 Tech Report。

Lec11 大规模分布式训练#

已经过时了,我可以结合我自己的经历和开源模型的 report 自己总结。

Lec12 Self-Supervised Learning#

自监督学习:在没有人工标注的情况下,从数据本身构造出监督信号,先学到一个好的特征表示,再迁移到下游任务(分类、检测、分割)上。

Pretext Task#

强迫了解语义。

Contrastive Learning#

同一张图的不同增强视角应该在特征空间靠近,不同图的应该推远。InfoNCE loss。

Lec13-Lec14 生成任务#

不如阅读 VAE 论文和 Diffusion 论文。

Lec15 3D 视觉#

不是很感兴趣。

Lec16 多模态#

不如 CS336 和 Qwen-VL 报告。

Lec17 机器人学习#

Behavior-1K

tasks

CS231N 笔记
https://blog.candlest.cc/blog/course/cs231n
Author Candlest
Published at 2026年7月15日