第19讲 · EECS 189:反向传播(续)与卷积神经网络

UC Berkeley EECS 189/289A《机器学习导论》2026 春季 · 课堂实录重构

原始标题 Backpropagation (cont.) & Convolutional Neural Networks
视频 https://www.youtube.com/watch?v=-4PpBUsB_S4
课程主页 https://eecs189.org/sp26/
官方讲义/笔记(Lecture 19) Google Drive 文件夹
图片来源 书中幻灯片插图为官方 PDF 高清渲染图

对应讲次:第19讲(UC Berkeley EECS 189 机器学习导论)

制作模型:deepseek-flash(coding-agent / pi;据 ~/.pi/agent/settings.json)

说明:课程材料版权归 UC Berkeley 及授课教师所有,本书仅供学习

本讲路线图

(参考时间: 00:00)

  1. 反向传播收尾:为什么需要前向传播、有限差分 / 符号微分的代价、自动微分;
  2. 训练神经网络的注意事项:激活函数的梯度问题、初始化、Batch Normalization、数据归一化;
  3. 卷积神经网络(CNN):从「全局模板」到「局部特征共享」;
  4. 卷积细节:stride、padding、滤波器组、特征图;
  5. 池化与网络堆叠、训练、架构选择。
标题页

📷 标题页
回到原视频 (00:00:20)

整体设定与之前相同

📷 整体设定与之前相同
回到原视频 (00:01:33)


一、反向传播的补充

1.1 为什么需要前向传播?

问题:计算梯度时不是只需要误差信号吗,为什么还要先做完整的前向传播?

答案:反向遍历图时,每一步都需要前向中间变量的值($y$ 就是 $v_4$、$z$ 就是 $v_3$……)。所以必须先把所有中间值算出来并保存,反向时再乘上这些值。这也意味着训练时应监控训练/验证损失,确认它整体在下降(SGD 会小幅波动)。

用计算图系统化导数(一)

📷 用计算图系统化导数(一)
回到原视频 (00:02:46)

用计算图系统化导数(二)

📷 用计算图系统化导数(二)
回到原视频 (00:03:59)

1.2 三种求梯度方式的代价

用数值微分计算梯度

📷 用数值微分计算梯度
回到原视频 (00:05:12)

SymPy 等计算机代数系统

📷 SymPy 等计算机代数系统
回到原视频 (00:06:25)

过去我们这样应用反向传播

📷 过去我们这样应用反向传播
回到原视频 (00:07:38)

CS 189/289

📷 CS 189/289
回到原视频 (00:08:51)


二、训练注意事项:梯度、初始化、归一化

2.1 激活函数的梯度问题

为什么深度网络这么好? 讲师引用 David Donoho 的调侃:每个研究神经网络的理论家都只看到自己想看到的东西——目前没有单一、公认的理论,但经验上它们统治了现实世界。「全基展开的线性回归」也有通用逼近定理,但神经网络能边训练边决定需要哪些基函数,从而更紧凑。

Sigmoid/tanh 的共同问题

📷 Sigmoid/tanh 的共同问题
回到原视频 (00:10:04)

ReLU 解决了一半问题

📷 ReLU 解决了一半问题
回到原视频 (00:11:17)

为什么深度网络这么好?(一)

📷 为什么深度网络这么好?(一)
回到原视频 (00:12:30)

为什么深度网络这么好?(二)

📷 为什么深度网络这么好?(二)
回到原视频 (00:13:43)

2.2 参数初始化

线性回归是凸的,初值无所谓;但神经网络高度非凸,有大量局部极小/极大/鞍点 ⇒ 初始化至关重要,是活跃的研究方向。

核心思想:让预激活处在非线性函数的「甜点区」(梯度大的地方)。

反复出现的主题:深度网络里几乎所有创新,都是在想办法让梯度不要消失、持续可学。

初始参数的选择很重要

📷 初始参数的选择很重要
回到原视频 (00:14:56)

非线性函数的「甜点区」

📷 非线性函数的「甜点区」
回到原视频 (00:16:09)

从零权重开始

📷 从零权重开始
回到原视频 (00:17:22)

从接近零的权重开始

📷 从接近零的权重开始
回到原视频 (00:18:35)

如何保持梯度流动?

📷 如何保持梯度流动?
回到原视频 (00:19:48)

2.3 Batch Normalization

做法:对每个单元的预激活,在一个小批量内做标准化:

$$ \hat a = \frac{a-\mu_{\text{batch}}}{\sqrt{\sigma^2_{\text{batch}}+\epsilon}} $$

把预激活强制拉回甜点区。然后(通常)再学习一个缩放/平移,恢复表达能力。

它理论支撑薄弱、常被称为「异端」,但实践效果很好、至今流行。

Batch Normalization

📷 Batch Normalization
回到原视频 (00:21:01)

用 Batch Norm 训练与预测

📷 用 Batch Norm 训练与预测
回到原视频 (00:22:14)

通常还要归一化训练数据

📷 通常还要归一化训练数据
回到原视频 (00:23:27)

2.4 数据归一化

变量量纲不同(身高 40–100 英寸 vs 血小板计数 1000–100000)会让梯度下降在某些方向移动过快、没有好理由。预处理:对数据(不是参数)计算均值/方差并标准化,训练前做一次并固定,然后对验证/测试集施加完全相同的变换。注意与 Batch Norm 的区别:BN 作用在参数/预激活上、每个小批量都做;数据归一化作用在数据上、只做一次。

CS 189/289

📷 CS 189/289
回到原视频 (00:24:40)

(要点)

📷 (要点)
回到原视频 (00:25:53)

全连接层无法复用「特征」(一)

📷 全连接层无法复用「特征」(一)
回到原视频 (00:27:06)

(要点)

📷 (要点)
回到原视频 (00:28:19)

(要点)

📷 (要点)
回到原视频 (00:29:32)

(要点)

📷 (要点)
回到原视频 (00:30:45)

(要点)

📷 (要点)
回到原视频 (00:31:58)

全连接:全局模板匹配

📷 全连接:全局模板匹配
回到原视频 (00:33:11)

可以想象使用分层的「局部特征」

📷 可以想象使用分层的「局部特征」
回到原视频 (00:34:24)


三、卷积神经网络(CNN)

3.1 动机:从全局模板到局部共享

全连接层的问题:它是一个固定的全局模板——为识别「眼睛」需要一整个权重矩阵,为每个类别/位置都要重复学。但图像里「眼睛」出现在哪里都应该算眼睛。我们想要的是参数库:一个小滤波器/卷积核(filter/kernel/template) 在整幅图上滑动,到处问「这里有没有这个特征?」——参数共享 + 局部连接。

自然的特征层次:浅层学边缘/方向,中层组合成车轮/车窗/眼睛/鼻子,高层才判「有没有车/人脸」。滤波器的值由梯度下降自动学习(不是像基展开那样预先指定)。

卷积神经网络(CNN)

📷 卷积神经网络(CNN)
回到原视频 (00:35:37)

(要点)

📷 (要点)
回到原视频 (00:36:50)

这将如何工作?(一)

📷 这将如何工作?(一)
回到原视频 (00:38:03)

(引文)

📷 (引文)
回到原视频 (00:39:16)

这将如何工作?(二)

📷 这将如何工作?(二)
回到原视频 (00:40:29)

这将如何工作?(三)

📷 这将如何工作?(三)
回到原视频 (00:41:42)

输出体积的深度 = 滤波器数 = 特征图数

📷 输出体积的深度 = 滤波器数 = 特征图数
回到原视频 (00:42:55)

(引文)

📷 (引文)
回到原视频 (00:44:08)

CNN 开始赢得竞赛

📷 CNN 开始赢得竞赛
回到原视频 (00:45:21)

3.2 卷积细节

(参考时间: 01:02)

2D 卷积:用一个 $3\times3$ 的核在图像上滑动,每次做逐元素点积得到一个标量(响应)。所有响应排成特征图(feature map)。

多个滤波器:一层里有 $F$ 个核 ⇒ 产生 $F$ 张特征图,堆成深度为 $F$ 的输出体积。这些旋钮(几个核、核多大、stride、padding)都要靠验证集经验性地调。

注:传统图像处理里「卷积」会先翻转核;机器学习中核是学出来的,翻转与否等价(会学成翻转版),所以直接做点积即可。经典手写核(模糊核、水平/垂直边缘检测器)有助于直觉理解网络可能学到什么。

回到卷积的细节

📷 回到卷积的细节
回到原视频 (00:46:34)

2D 卷积的示例计算

📷 2D 卷积的示例计算
回到原视频 (00:47:47)

Stride = 1(帧 1)

📷 Stride = 1(帧 1)
回到原视频 (00:49:00)

Stride = 1(帧 2)

📷 Stride = 1(帧 2)
回到原视频 (00:50:13)

Stride = 1(帧 3)

📷 Stride = 1(帧 3)
回到原视频 (00:51:26)

Stride = 1(帧 4)

📷 Stride = 1(帧 4)
回到原视频 (00:52:39)

Stride = 1(帧 5)

📷 Stride = 1(帧 5)
回到原视频 (00:53:52)

Stride = 1(帧 6)

📷 Stride = 1(帧 6)
回到原视频 (00:55:05)

响应 -1(帧 1)

📷 响应 -1(帧 1)
回到原视频 (00:56:18)

响应 -1(帧 2)

📷 响应 -1(帧 2)
回到原视频 (00:57:31)

响应 -1(帧 3)

📷 响应 -1(帧 3)
回到原视频 (00:58:44)

响应 -1(帧 4)

📷 响应 -1(帧 4)
回到原视频 (00:59:57)

响应 -1(帧 5)

📷 响应 -1(帧 5)
回到原视频 (01:01:10)

响应 -1(帧 6)

📷 响应 -1(帧 6)
回到原视频 (01:02:23)

响应 -1(帧 7)

📷 响应 -1(帧 7)
回到原视频 (01:03:36)

响应 -1(帧 8)

📷 响应 -1(帧 8)
回到原视频 (01:04:49)

响应 -1(帧 9)

📷 响应 -1(帧 9)
回到原视频 (01:06:02)

响应 -1(帧 10)

📷 响应 -1(帧 10)
回到原视频 (01:07:15)

响应 -1(帧 11)

📷 响应 -1(帧 11)
回到原视频 (01:08:28)

3.3 1D → 2D 卷积

数学定义(1D 连续):$(f*g)(t)=\int f(\tau)g(t-\tau)\,d\tau$;离散版是求和。严格定义里核是翻转的,但在机器学习里无所谓。

从 1D 到 2D:二维核在两个方向翻转后做点积;实践中就是滑动 + 点积。

数学上:1D 卷积

📷 数学上:1D 卷积
回到原视频 (01:09:41)

1D 卷积(一)

📷 1D 卷积(一)
回到原视频 (01:10:54)

1D 卷积(二)

📷 1D 卷积(二)
回到原视频 (01:12:07)

(引文)

📷 (引文)
回到原视频 (01:13:20)

从 1D 到 2D 卷积

📷 从 1D 到 2D 卷积
回到原视频 (01:14:33)

卷积动画(引文 1)

📷 卷积动画(引文 1)
回到原视频 (01:15:46)

卷积动画(引文 2)

📷 卷积动画(引文 2)
回到原视频 (01:16:59)

卷积动画(引文 3)

📷 卷积动画(引文 3)
回到原视频 (01:18:12)

卷积动画(引文 4)

📷 卷积动画(引文 4)
回到原视频 (01:19:25)

卷积动画(引文 5)

📷 卷积动画(引文 5)
回到原视频 (01:20:38)

卷积动画(引文 6)

📷 卷积动画(引文 6)
回到原视频 (01:21:51)

卷积动画(引文 7)

📷 卷积动画(引文 7)
回到原视频 (01:23:04)

卷积动画(引文 8)

📷 卷积动画(引文 8)
回到原视频 (01:24:17)

卷积算术(动画 1)

📷 卷积算术(动画 1)
回到原视频 (01:25:30)

卷积算术(动画 2)

📷 卷积算术(动画 2)
回到原视频 (01:26:43)

$F$ 个 $M\times M$ 的滤波器

📷 $F$ 个 $M\times M$ 的滤波器
回到原视频 (01:27:56)

一个尺寸为 …… 的图像

📷 一个尺寸为 …… 的图像
回到原视频 (01:29:09)

$F$ 个 $M\times M$ 的滤波器(续)

📷 $F$ 个 $M\times M$ 的滤波器(续)
回到原视频 (01:30:22)

一个图像(续)

📷 一个图像(续)
回到原视频 (01:31:35)

如果我们想保持图像尺寸不变?(一)

📷 如果我们想保持图像尺寸不变?(一)
回到原视频 (01:32:48)

如果我们想保持图像尺寸不变?(二)

📷 如果我们想保持图像尺寸不变?(二)
回到原视频 (01:34:01)

3.4 池化与堆叠

池化(pooling):对特征图做下采样(如每个 $2\times2$ 区域取最大值/平均值),减小尺寸、增强平移不变性、降低计算量。

堆叠:(conv + ReLU) + pooling 作为基本积木,反复堆叠(乐高式组合),中间穿插全连接层。

ConvNets 的「池化」层

📷 ConvNets 的「池化」层
回到原视频 (01:35:14)

池化层减小卷积输出尺寸

📷 池化层减小卷积输出尺寸
回到原视频 (01:36:27)

池化:下采样特征图

📷 池化:下采样特征图
回到原视频 (01:37:40)

池化(帧 1)

📷 池化(帧 1)
回到原视频 (01:38:53)

池化(帧 2)

📷 池化(帧 2)
回到原视频 (01:40:06)

池化(帧 3)

📷 池化(帧 3)
回到原视频 (01:41:19)

池化(帧 4)

📷 池化(帧 4)
回到原视频 (01:42:32)

池化(帧 5)

📷 池化(帧 5)
回到原视频 (01:43:45)

池化(帧 6)

📷 池化(帧 6)
回到原视频 (01:44:58)

池化(帧 7)

📷 池化(帧 7)
回到原视频 (01:46:11)

池化(帧 8)

📷 池化(帧 8)
回到原视频 (01:47:24)

池化(帧 9)

📷 池化(帧 9)
回到原视频 (01:48:37)

ConvNets:堆叠不同的层

📷 ConvNets:堆叠不同的层
回到原视频 (01:49:50)

卷积神经网络(ConvNets)

📷 卷积神经网络(ConvNets)
回到原视频 (01:51:03)

ConvNets 也需要非线性(激活)

📷 ConvNets 也需要非线性(激活)
回到原视频 (01:52:16)

ConvNets:(conv + ReLU) + pooling

📷 ConvNets:(conv + ReLU) + pooling
回到原视频 (01:53:29)

(引文)

📷 (引文)
回到原视频 (01:54:42)

ConvNets:训练

📷 ConvNets:训练
回到原视频 (01:55:55)

我们应该用什么架构?(一)

📷 我们应该用什么架构?(一)
回到原视频 (01:57:08)

我们应该用什么架构?(二)

📷 我们应该用什么架构?(二)
回到原视频 (01:58:21)

我们应该用什么架构?(三)

📷 我们应该用什么架构?(三)
回到原视频 (01:59:34)


总结(Takeaways)


附:参考与延伸阅读

主题 链接
本讲视频 https://www.youtube.com/watch?v=-4PpBUsB_S4
课程主页 https://eecs189.org/sp26/
官方讲义/笔记(Lecture 19) Google Drive 文件夹
Roger Grosse, CSC321 讲义(CNN) http://www.cs.toronto.edu/~rgrosse/courses/csc321_2017/slides/lec11.pdf
Dumoulin & Visin, A guide to convolution arithmetic https://github.com/vdumoulin/conv_arithmetic
Bishop, Pattern Recognition and Machine Learning 第 5 章 · https://www.microsoft.com/en-us/research/publication/pattern-recognition-machine-learning/

版权说明:本讲视频、幻灯片与课程材料版权归 UC Berkeley EECS 189/289A 课程团队所有。本书为课堂内容的学习性中文重构,仅供学习交流。