MIT深度学习课程第四讲:卷积神经网络与迁移学习
本节课从上一节的 Fashion-MNIST 图像分类继续展开。
上一节中,单隐藏层神经网络可以在 Fashion-MNIST 上达到高 80% 的准确率,但它并不知道输入是图像。它只是把 28 x 28 的像素表格按行拼接成一个长向量,再送入 dense layer。
本节课的核心问题是:
图像不是任意向量。既然输入是图像,网络应当利用图像本身的结构。
课程依次讲解:
- 为什么直接 flatten 图像会有问题。
convolutional filter如何检测图像特征。convolutional layer如何处理灰度图和彩色图。pooling layer如何降低尺寸并提升抽象层次。- 基本
CNN架构如何组织。 - 如何用
Keras搭建Fashion-MNISTCNN。 - 如何处理小样本彩色图像分类。
- 如何用
ResNet做transfer learning。
一、本节课目标
老师开场说明,本节课内容非常密集。
目标是让学生从可能不了解 convolutions,到理解 convolutional networks 的工作方式,并实际搭建一个模型进行课堂演示。
老师提到,前一天发布的视频 walkthrough 会帮助本节课节省时间;本节的课堂 demo 属于 live demo,虽然过去几年通常运行良好,但现场演示本身仍有不确定性。
本节课会使用:
- PowerPoint
- 两个
Colab - 一个 Excel spreadsheet
- 可能还会用到手写说明文件
老师提醒,前半部分会比较概念密集,之后会进入 Colab 和 live demo。
二、Fashion-MNIST 回顾
上一节视频 walkthrough 中,普通神经网络处理 Fashion-MNIST 的方式是:
- 将每张
28 x 28图像 flatten。 - 把每一行像素拼接成一个长向量。
- 将向量送入 dense neural network。
这个方法可以得到高 80% 的准确率。
但问题是:
这个网络没有利用“输入是图像”这一事实。
它只是把图像看成一长串数字。
因此,本节课要讨论:图像数据有哪些结构,是任意向量没有的。
三、Flatten 图像的第一个问题:忽略空间邻接
学生首先指出,flatten 图像会丢失像素之间的邻近关系。
老师确认这是关键问题。
例如,一张图片中间有一个属于 T-shirt 的 pixel,那么它周围的 pixels 很可能也与同一个 T-shirt 概念有关。
这种信息称为:
spatial adjacency information图像中相邻像素之间的关系非常重要。直接 flatten 后,网络不再显式知道哪些像素原本相邻。
另一个学生提到,如果有关于图像的 metadata,例如 dimensions 或 resolution,也可能有帮助。老师承认这类 structured information 可能有用,但本节课暂时限定在只有 raw image、没有额外 metadata 的情况。
四、Flatten 图像的第二个问题:参数太多
老师用手机照片举例说明 dense layer 参数爆炸问题。
旧 iPhone 拍摄的彩色照片大约是:
3024 x 3024这约等于:
9 million pixels彩色图像有 3 个 channels,因此总输入数字约为:
27 million numbers每个数字都在 0 到 255 之间。
如果把这 27 million 个输入连接到一个只有 100 个 neurons 的 dense layer,仅这一层就大约有:
27 million * 100 = 2.7 billion parameters这里还暂时忽略了 biases。
问题包括:
- 计算量巨大。
- 需要非常多训练数据。
- 很容易 overfit。
老师用反问强调:很难获得 2.7 billion 张图片来训练这样一个简单部分,使其不过拟合。
五、Flatten 图像的第三个问题:缺少 Translation Invariance
第三个问题是同一个特征在不同位置会被重复学习。
例如:
- 图片左上角有一条 vertical line。
- 图片右下角也有一条 vertical line。
直接 flatten 后,dense layer 可能会分别学习:
- 如何检测左上角的 vertical line。
- 如何检测右下角的 vertical line。
这不合理,因为:
vertical line 无论在哪里,仍然是 vertical line。
理想的模型应该做到:
detect once, reuse everywhere这个性质叫:
translation invariance这里的 translation 是数学中的“平移”含义,即把对象移动到其他位置。
六、图像模型需要解决的三个问题
老师总结,处理图像时需要关注三件事:
- 避免简单 dense 连接带来的巨大参数量。
- 保留并利用
spatial adjacency。 - 让模型具备
translation invariance,即同一特征在不同位置都能被识别。
学生问:这些问题是否因为图像被压缩才出现?
老师回答:不是。
无论图像是否压缩,这些问题都会出现。问题来自图像作为二维或三维空间数据的结构,而不是压缩格式。
convolutional layers 正是为解决这些问题而发展出来的。
七、Convolutional Filter
convolutional layer 的基本构件是:
convolutional filter一个 convolutional filter 本质上是一个小矩阵。
例如:
3 x 3 matrix一个 convolutional layer 由一个或多个 filters 组成。
filter 的特殊之处在于:
如果 filter 中的数字选择得合适,并将它应用到图像上,它可以检测图像中的特征。
这些特征可以包括:
- lines
- curves
- color gradations
- circles
- edges
老师举例:
- 一个 filter 可以检测 horizontal lines。
- 另一个 filter 可以检测 vertical lines。
八、Apply Filter to Image:卷积操作
老师先用灰度图像解释如何将 filter 应用于图像。
假设图像是一个数字表:
- 每个数字在
0到255之间。 - filter 是一个
3 x 3小矩阵。
操作步骤是:
- 将 filter 放到图像左上角。
- filter 的
3 x 3数字与图像对应位置的3 x 3数字重叠。 - 得到
9对数字。 - 每一对数字相乘。
- 将所有乘积相加。
- 将结果送入
ReLU。 - 得到输出图像左上角的一个数字。
课堂示例中,第一次计算经过 ReLU 后得到 0,这个 0 就成为输出表左上角的值。
这个过程就是一次 convolution operation。
接着:
- filter 向右移动一格。
- 重复同样的乘法、求和、
ReLU。 - 得到输出中的下一个数字。
- 到达最右边后,移动到下一行。
- 一直重复到图像底部。
因此,apply filter 的过程可以理解为:
用同一个小矩阵在整张图像上滑动,每个位置生成一个输出值。
九、Padding 与 Stride
学生问:如果 filter 移动到边缘,不能完整匹配图像区域怎么办?
老师回答,本节课先用默认简单情况:
- 从左上角开始。
- 每次向右移动。
- 当 filter 右边缘与图像右边缘对齐时停止。
实际中还有一些细节:
9.1 Padding
可以在图像边缘外补一圈数值,使 filter 可以覆盖到原图边缘之外的位置。
这称为:
padding9.2 Stride
filter 不一定每次只移动一格。
也可以每次移动两格或更多。
这称为:
stride老师说明,这些是重要细节,但本节课先忽略。默认方法在很多情况下已经非常有效。
十、Excel 示例:用 Filter 检测数字 3 的边缘
老师切换到一个 Excel spreadsheet,说明 filter 如何工作。
这个 spreadsheet 来自 fast.ai 的相关材料。
表格中原始图像是一组数字:
- 大多数数字是
0。 - 部分数字接近
0.8、0.9等。 - 原始
0到255的像素值被除以255,转成0到1的小数。
Excel 使用 conditional formatting:
- 数字越接近
1,颜色越红。 - 因此数字
3的形状会在表格中显现出来。
老师展示:
- 一个 horizontal-line filter 应用后,数字
3的水平部分会亮起。 - 一个 vertical-line filter 应用后,数字
3的竖直部分会亮起。
在 Excel 中,单个输出单元的公式本质上是:
max(0, sum(matching image values * matching filter values))其中 max(0, ...) 对应 ReLU。
输出同样用 conditional formatting 显示,因此可以直观看到哪些位置被 filter 激活。
十一、为什么 Filter 能检测 Edge
老师解释 horizontal filter 的直觉。
filter 中可能包含:
- 一行正数,例如
1。 - 中间一行
0。 - 另一行负数,例如
-1。
当 filter 覆盖到图像中边缘位置时:
- 一侧有较大的像素值。
- 另一侧有较小或接近
0的像素值。 - 正数权重会放大亮的一侧。
- 负数权重会压低暗的一侧。
相乘并求和后,会得到较大的正数。
再经过 ReLU 后,这个位置就会“亮起来”。
因此,filter 可以检测特定方向的 edge。
老师建议课后使用 Excel 逐格追踪公式,理解为什么某些格子会被激活。
老师还提到有一个交互式网站,可以自己输入 filter 数字,观察它会检测出哪些 edges、curves 或其他图像结构。这个资源适合用来加深对 filter 数值和检测效果之间关系的理解。
十二、Filter 可以检测不同特征
老师总结:
通过选择不同的 filter 数字,并应用相同 convolution operation,可以检测不同图像特征。
每个 filter 可以看作一个 feature specialist。
例如它可能专门检测:
- vertical lines
- horizontal lines
- semicircles
- quarter circles
- color transitions
- curves
现代图像通常非常复杂,因此需要很多 filters。
关键是:
不需要人类预先指定每个 filter 检测什么。
系统会在训练中自己学习每个 filter 应该变成什么。
老师强调,这避免了深度学习出现之前计算机视觉中的人工特征工程瓶颈。
十三、多个 Filters 的输出
如果一个 convolutional layer 有两个 filters,就并行做两次 convolution operation。
流程是:
- filter 1 应用于同一张输入图像。
- 得到一张输出表。
- filter 2 也应用于同一张输入图像。
- 得到另一张输出表。
如果每个输出都是:
5 x 5那么两个输出可以打包成一个 tensor。
这个 tensor 的 shape 可以写成:
5 x 5 x 2也可以按另一种约定写成:
2 x 5 x 5哪种写法取决于框架或约定。
如果有 103 个 filters,则输出可以是:
5 x 5 x 103这说明为什么前面需要理解 tensors。
十四、彩色图像中的 Filter
灰度图像是二维表。
彩色图像通常有三个 channels:
- red
- green
- blue
因此,彩色图像可以看作:
height x width x 3课堂示例中,输入可以是:
6 x 6 x 3问题是:如何把一个 3 x 3 filter 应用到这种三通道图像上?
不能简单把同一个 2D filter 分别应用到 red、green、blue,然后把三者当作互不相关的东西处理。因为同一位置的 RGB 三个数共同描述同一个 underlying pixel concept。
十五、3D Filter:深度必须匹配输入深度
解决方法是:
将 filter 也变成 3D。
对于 RGB 图像,filter 不再是:
3 x 3而是:
3 x 3 x 3这样 filter 的 depth 与输入图像的 channel depth 匹配。
此时一个局部窗口中有:
3 * 3 * 3 = 27个输入数字,filter 中也有 27 个数字。
卷积操作仍然相同:
- 对应位置相乘。
- 所有乘积相加。
- 经过
ReLU。 - 得到一个输出数字。
如果输入 depth 是 10,那么 filter depth 也必须是 10。
老师强调:
filter 的 depth 匹配输入 depth。
课堂中老师还提到,他曾尝试让 ChatGPT 生成 3D filter 示意图,但效果不好,最后使用了 DeepLearning.ai 的一张更清楚的图来说明这个结构。
十六、彩色图像中多个 Filters 的输出
一个 3 x 3 x 3 filter 应用于输入后,仍然输出一张二维表。
例如输入是:
6 x 6 x 3使用一个 3 x 3 x 3 filter 后,可以得到:
4 x 4如果有 10 个 filters,就会得到 10 张 4 x 4 输出表。
它们打包后就是:
4 x 4 x 10老师特别强调:
不管输入是 2D、3D 还是更高 depth,一个 filter 在所有位置滑动后,单个 filter 的输出总是一张 2D number table。多个 filters 的多个 2D outputs 再被打包成一个 tensor。
老师补充,教材 Chapter 8.1 对这部分直觉有更多细节。卷积概念需要反复练习,通常不是一次听完就能完全内化。
十七、关于 3D Filter 的课堂问答
17.1 不同 Channel Depth 的 Filter 数值是否不同
学生问:如果 filter 在不同 depth 维度上放不同数字,是否就相当于做 color processing?
老师回答:是的。
对于 3 x 3 x 3 filter,确实有 27 个数。不同 channel depth 上可以有不同参数。
但老师暂时没有展开,因为更关键的问题是这些数字从哪里来。
17.2 是否可以先跨 Channel 做抽象再用低阶 Filter
学生问:是否可以先对不同 channels 做操作,形成中间层,再用低 rank filter?
老师回答:研究文献中确实有很多类似想法。
但本节课讲的是最基础的做法,并且这个基础做法已经非常强大。
很多研究会在基础方法之上做复杂改进,从 95% 提升到 95.1%,但对实践而言,基础方法已经足够重要。
17.3 一个 3D Filter 如何变成 2D 输出
学生问:3 x 3 x 3 filter 如何产生一个 4 x 4 输出?
老师解释:
- 一个
3 x 3 x 3filter 在输入上滑动。 - 每个位置都得到一个数字。
- 所有位置组合成一张
4 x 4表。 - 如果有多个 filters,就得到多张
4 x 4表。 - 多张表再组成一个更深的 tensor。
十八、Filter 参数从哪里来
老师提出关键问题:
这些 filter 中的数字从哪里来?
传统计算机视觉中,filters 通常由研究者手工设计。
例如,如果要从 MRI 图像中检测中风证据,研究者可能会:
- 设计特定 filters。
- 尝试很多数值。
- 找出适合特定任务的特征提取方式。
这种方式需要大量人工投入,是深度学习之前的典型特征工程。
十九、将 Filter 数值视为 Weights
深度学习带来的关键转变是:
将 filter 里的数字视为 weights,让模型通过 data 和 backprop 学习这些 weights。
一旦这样理解,convolutional filter 就不是手工规则,而是可训练参数。
老师指出,这个想法事后看起来很自然,但在当时并不显然。
它之所以可行,是因为前面已经具备了:
ReLU activationstochastic gradient descentGPUsbackprop- 训练深层网络的经验
老师强调,这是重要突破。
有学生问,不同应用或不同网络大小下是否会以不同方式初始化这些参数。老师说这是好问题,但会在后面讲 transfer learning 时再回到这个话题。
二十、Convolutional Filter 本质上是一种 Neuron
老师说明,convolutional filter 可以看作一种特殊的 neuron。
它的底层运算仍然是:
- 输入数字与参数相乘。
- 相加。
- 经过 activation function。
因此,前面关于 neural networks 的工具都可以继续使用:
- layers
- loss functions
- gradient descent
SGDbackprop- 参数学习
不需要为 convolutional filters 重新发明训练机制。
老师提到,appendix 中有一两页 slide 解释为什么 convolutional filter 可以看作 neuron。
二十一、AlexNet 与 2012 年突破
老师指出,学习 filter 参数是计算机视觉的重要转折点。
2012 年,AlexNet 使用这种技术在 ImageNet 比赛中显著超过竞争对手。
当时的误差率对比是:
- 之前最好结果:约
26%error rate。 AlexNet:约16%error rate。
这相当于一次性下降约 10%。
老师强调,过去每年提升往往只是 0.5% 或 1%,因此这个结果非常震撼。
二十二、Convolutional Layers 的层级理解
随着 convolutional layers 一层一层叠加,后面的 filter 实际上会看到原始图像中越来越大的区域。
直觉是:
- 第一层 filter 可能只看到局部的小区域,例如房子烟囱的一部分。
- 第二层的输入是第一层的输出。
- 第二层中一个位置对应原图中更大的区域。
- 层数越深,能综合的信息范围越大。
因此,CNN 逐层构建图像理解。
老师总结:
hierarchical learning 是 CNN 成功的重要原因。
二十三、网络内部可视化:从线条到人脸
老师展示了一个 face detection deep network 的可视化结果。
网络不同层学习到的内容大致是:
- 第一层:lines、edges 等基础形状。
- 第二层:把线条组合成更复杂的边缘。
- 更深层:组合出耳朵、脸部局部结构。
- 最后:组合出完整的人脸。
老师用这个例子说明,网络确实可能逐层学习越来越抽象的结构。
不过,这些内容通常是训练完成后通过 introspection 或 visualization 观察到的。
二十四、Pooling Layer
讲完 convolutional layer 后,老师介绍第二个构件:
pooling layerpooling layers 也称为:
subsampling layersdown-sampling layers
基本思想是:
convolutional layer 输出一个 tensor 后,pooling layer 将它稍微变小。
缩小 tensor 的作用是迫使网络总结输入中发生了什么,从而在更高层级上表示信息。
二十五、Max Pooling
老师用 4 x 4 的卷积输出表举例。
max pooling 的过程是:
- 在左上角覆盖一个
2 x 2空窗口。 - 找出这
4个数中的最大值。 - 将最大值放入输出表对应位置。
- 将窗口移动到下一个区域。
- 对每个区域重复。
示例中:
- 某个
2 x 2区域最大值是43。 - 另一个区域最大值是
109。 - 其他区域可能得到
105、35。
max pooling 没有需要学习的 weights。
它只是一个固定算术操作。
二十六、Average Pooling
另一种 pooling 是:
average pooling它不取最大值,而是计算窗口内数字的平均值。
例如:
- 某个
2 x 2区域平均值是22.2。 - 另一个区域平均值是
45.5。
老师强调,max pooling 和 average pooling 都会显著减少 entries 数量。
pooling 的输出会像普通 layer 输出一样传给下一层。
二十七、Max Pooling 的直觉:OR 条件
老师解释 max pooling 的直觉:
max pooling类似一个 OR condition。
如果卷积输出某个区域中有一个值很高,说明该区域中某处检测到了某个 feature。
max pooling 会保留这个高值,相当于回答:
这个区域中有没有东西亮起来?如果有,就认为该区域有该 feature。
如果没有,就认为该区域没有该 feature。
因此,max pooling 像 feature detector 的聚合器:
- top left 是否有 feature?
- top right 是否有 feature?
- bottom left 是否有 feature?
- bottom right 是否有 feature?
这让网络从单个 pixels 上升到更高层级的区域表示。
老师原本准备使用手写说明展示 pooling 的效果,但课堂设备没有顺利显示。他表示会录制一个 walkthrough 后发布,帮助学生理解 pooling 如何提升抽象层次。
二十八、Pooling 是否丢失空间信息
学生问:使用 pooling 后是否丢失了空间信息?
老师回答:不会以有害方式丢失,因为网络已经进入了更高层的抽象。
例如,模型不再关心某个眼睛像素的精确坐标,而是知道:
top-left 区域中有一个 eye-like feature 被激活。
也就是说,位置信息仍以较粗粒度保留。
这种抽象会逐层、缓慢、渐进地发生,所以需要深层网络。
二十九、多 Channel Tensor 上的 Pooling
老师补充:
如果 convolutional layer 输出 tensor 的 shape 是:
224 x 224 x 64这意味着有 64 张 224 x 224 的表。
pooling 会分别作用在每一张表上。
例如,经过 pooling 后:
224 x 224 x 64 → 112 x 112 x 64每张表的 height 和 width 变小,但 depth 不变。
也就是说:
pooling 缩小每个 channel 的空间尺寸,但不改变 channel 数量。
老师还提到,有一个来自 Stanford 课程的解释链接,对 convolution 和 pooling 有更复杂但很清楚的说明,可作为课后参考。
三十、Preprocessing 与网络结构的取舍
学生问:是否存在预处理和增加 convolutional layers 之间的取舍,例如视频是否先转成黑白静态序列,还是直接输入彩色视频。
老师回答:有取舍。
如果对数据有重要 domain knowledge,希望模型不浪费 capacity 学习某些必然成立的东西,可以在输入或网络设置中编码这些知识。
如果不确定,就让网络从数据中学习,只要最终目标是尽可能提高预测准确率。
三十一、基本 CNN 架构
老师总结基本 CNN 架构:
- 输入图像。
- 经过一系列 convolutional layers。
- 在若干位置插入 pooling layers。
- 形成多个 convolutional blocks。
- 最后 flatten。
- 接 dense layers。
- 接任务所需输出层,例如
softmax。
一个 convolutional block 通常是:
one or two convolutional layers + one pooling layer随着网络加深:
- height 和 width 通常变小。
- depth 通常变大。
经验上,这种“空间尺寸变小、通道深度变大”的结构在实践中效果很好。
三十二、ResNet 的尺寸示例
老师用 ResNet 举例说明尺寸变化。
输入彩色图像可以是:
224 x 224 x 3经过大量 convolution 和 pooling 后,ResNet 最后可能得到:
7 x 7 x 2048也就是说:
- height 从
224缩小到7。 - width 从
224缩小到7。 - depth 从
3增加到2048。
这体现了 CNN 中逐步变小、变深的特征表示。
三十三、为什么越深 Depth 越大
学生问:depth 变大是否因为每一层检测一个特征并堆叠起来?
老师回答,不能简单说每层只检测单个特征。
更好的直觉是:
- 基础特征数量可能不多,例如 lines、curves、color gradations。
- 但这些基础特征可以组合成大量现实世界对象。
- 就像少量原子可以组成大量分子。
因此,网络越往后,需要更多 filters 捕捉越来越多的组合模式。
depth 增加意味着有更多 filters,每个 filter 可以捕捉输入中的某种组合结构。
另一个学生追问 depth 具体如何增加。老师回答,depth 是由建模者在 convolutional layer 中选择 filter 数量决定的。类似 hidden layer 的 neuron 数量,filters 数量也是 design choice。layer 由 filters 组成,filters 越多,输出 tensor 的 depth 越大。
三十四、网络是否理解特征语义
学生问:模型学到 line、arc、eye 等特征后,是否知道这些特征的意义,例如知道某个 arc 是太阳还是眼睛?
老师回答:
我们不告诉网络要学什么,只告诉它最小化 loss function。
训练完成后,如果网络表现好,可以通过可视化或 introspection 查看它学到了什么。
有时可以看到它学到基础 lines、edges、复杂 shapes,最终组合成人脸。
但有时模型学到的表示不一定能被人类清楚解释。
老师提到,稍后会给一个早期可视化论文的参考,用于理解这些图像是如何生成的。
三十五、CNN 最后为什么要 Flatten
经过 convolutional 和 pooling 操作后,网络输出的是一个 tensor。
为了进入熟悉的 dense network 部分,需要将这个 tensor flatten 成一个长向量。
之后就可以接:
- dense layer
- final output layer
如果是多分类图像分类任务,最后可以接:
softmax老师强调,到了这一步又回到前面熟悉的 dense neural network territory。
三十六、Fashion-MNIST CNN Colab
接下来,老师进入 Fashion-MNIST 的 CNN Colab。
前置步骤包括:
- import packages
- set random seed
- load
Fashion-MNIST - create label names
- 准备绘制 accuracy 和 loss 的标准函数
图像像素仍然会除以 255,归一化到 0 到 1。
数据仍然是:
60,000张训练图像。- 每张
28 x 28。
三十七、为 CNN 增加 Channel 维度
Fashion-MNIST 是灰度图像。
概念上每张图片是:
28 x 28但 convolutional network 通常期待输入带有 channel 维度。
彩色图像有 3 个 channels。
灰度图像只有 1 个 channel。
因此,要把输入 shape 写成:
28 x 28 x 1老师使用类似:
expand_dimension的操作增加维度。
处理后,训练数据从:
60000 x 28 x 28变成:
60000 x 28 x 28 x 1三十八、用 Keras 定义第一个 CNN
模型输入仍然用:
keras.Input输入 shape 是:
28 x 28 x 138.1 Conv2D
在 Keras 中,二维卷积层使用:
layers.Conv2D老师提到,从名字也可以推断存在:
Conv1DConv3D
但图像处理通常用 Conv2D。
38.2 Filter 数量
第一个 convolutional layer 中,老师选择:
32 filtersfilter 数量是建模者决定的 design choice。
38.3 Kernel Size
filter 尺寸由:
kernel_size指定。
课堂示例使用:
kernel_size = 2 x 238.4 Activation
activation 使用:
ReLU第一层命名为 convolution 1,命名主要方便查看。
三十九、Fashion-MNIST CNN 的结构
第一个 convolutional block 是:
Conv2DMaxPool2D
第二个 convolutional block 由类似代码复制得到:
Conv2DMaxPool2D
老师说明,前面讲过越往后通常 depth 越大,但这个示例是简单起点,第二个 block 仍然使用 32 个 filters。
也可以尝试改成 64,让网络更深。
后续结构是:
- flatten 所有卷积输出。
- 接一个 dense layer。
- dense layer 有
256个 neurons。 - 最后接
10类softmax输出。
新的关键概念只有两个:
Conv2DMaxPool2D
四十、关于何时 Flatten 与是否总要用 CNN
学生问:什么时候 flatten?是否有时仍然使用上一节那种直接 flatten 的方法,而不用 CNN?
老师回答:
- 上一节已经试过直接 flatten,效果不差。
- 但对于图像,通常可以直接从 CNN 开始。
- 使用 CNN 不会放弃什么,反而能利用图像结构。
老师给出建模策略:
start simple. If it works, stop working on it. If it does not, add more layers.
也就是先用简单结构,够用就停止;不够再增加复杂度。
四十一、CNN 架构设计是否靠 Trial and Error
学生问:filters 数量、kernel size、layers 数量、convolution/pooling 架构是否主要靠 trial and error?
老师回答:通常是。
但后面会讲 transfer learning。
在实践中,与其从头设计和训练,通常更常见的做法是:
下载一个 pre-trained model,再为自己的问题进行适配。
老师之所以从头搭建,是为了让学生理解内部机制,而不是把模型当成黑箱。
四十二、Keras 中反复使用变量 x
学生问:代码中很多层都写成 x,是否是一种命名习惯?
老师解释:
- 这些 layer 不是都被命名为
x。 - 代码只是把当前层的输出重新赋值给变量
x。 Keras会在内部追踪计算图。
这样写可以避免:
x1x2x3x4
如果中间插入新层,就不必重新调整所有变量编号。
这是老师为了方便而使用的 notation。
四十三、Fashion-MNIST CNN 的参数与训练
老师运行:
model.summary这个 CNN 大约有:
302,000 parameters老师建议学生课后手动计算参数数量,确认能对上。
训练设置:
- optimizer:
Adam - compile:沿用前一节
Fashion-MNIST多分类模型的设置 - epochs:
10 - validation split:
20%
卷积网络计算更多,所以运行速度会比简单 dense 网络慢一些。
四十四、Image Classification 以外的任务如何输出
学生问:如果任务不是 image classification,例如 semantic segmentation,是否仍然 flatten?
老师回答:
本节课的结构适用于 image classification。
如果要做 semantic segmentation,输出端会更复杂,因为需要对每个 pixel 分类。
因此,输出 shape 需要与输入图像维度相匹配。
这类任务通常使用不同架构,例如:
U-Net老师说明,本节课不会深入 U-Net,但计划发布一个可选 walkthrough,展示如何用 Hugging Face Hub 快速构建 segmentation 等应用。
四十五、Fashion-MNIST CNN 的训练结果
训练曲线显示:
- training loss 下降良好。
- validation loss 大约在第
8个 epoch 附近开始 flatten。 - accuracy 达到
90%以上。
最终 test set accuracy 大约是:
90.5%老师提醒,从 88% 提升到 90% 不应被低估。
因为此类问题常常具有 diminishing returns:
- 原来剩余 error 大约
12%。 - 从中减少约
2%的 error,已经是有意义的进步。
老师提到,这个任务的 state of the art 大约是:
97%并鼓励学生尝试不同 filters 和设置,看是否能达到 mid 90s。
四十六、Epoch 与 Batch Size 的关系
学生问:epochs 是否与 batch 数量有关,因为模型设置了 batch size。
老师回答:
epoch是完整遍历训练数据的次数。- 在一个 epoch 内,
batch size决定要处理多少 batches。
计算方式仍是:
number_of_batches = ceil(number_of_training_examples / batch_size)本节课使用 10 epochs,主要是为了课堂演示速度。
老师说明,10 已经足够,因为模型已经开始 overfit。
四十七、Neural Network 是否总优于传统 Machine Learning
学生问:neural network 的准确率是否总是比传统 machine learning algorithm 更好,尤其是心脏病结构化数据问题。
老师回答:不是。
神经网络尤其适合:
- unstructured data
- images
- 这类图像输入
但如果是结构化数据,例如心脏病数据,传统方法有时表现很好。
老师特别提到:
- gradient boosting
XGBoost
对于 structured data,应该同时尝试神经网络和传统机器学习方法,而不是先验假设 DNN 一定最好。
四十八、改进模型的可选内容
老师提到,Colab 中有一节关于如何改进模型的 optional section。
本节课没有展开,建议学生自己查看。
随后课程从 Fashion-MNIST 转向彩色图像。
四十九、彩色图像小样本任务:Handbags vs Shoes
老师准备了一个小型彩色图像数据集。
数据来源:
- 老师 web scraped 图片。
- 大约
100张 handbags。 - 大约
100张 shoes。 - 总数约
200张彩色图片。
任务是:
判断一张图片是 handbag 还是 shoe。
老师强调,这个任务看起来很困难,因为:
200张图片很少。Fashion-MNIST有60,000张训练图像。- 即使在
Fashion-MNIST中,模型也会在5、6、7、8个 epochs 附近开始 overfit。
但本节课会展示仍然有办法做得很好。
五十、图像文件夹结构与 Keras
与 Fashion-MNIST 不同,handbags/shoes 数据来自老师自己的 web scraping,并放在 Dropbox folder 中。
流程是:
- 下载压缩包。
- 解压。
- 组织目录结构。
目录结构包括:
trainvalidationtest
每个 split 下又有:
handbagsshoes
老师说明,当处理图像时,可以把每个类别的图片放在一个 folder 中。
例如:
dogscats
然后把目录指给 Keras,Keras 会自动从 folder 名称推断 labels。
这是处理图像数据时很方便的方式。
五十一、读取 JPEG、Resize 与 Batch
处理彩色图像时,流程包括:
- 读取
JPEGs。 - 将图像转换成 tensors。
- 因为 web scraped 图片尺寸不同,需要 resize 到统一大小。
- 使用 batch size 进行 batching。
课堂中 batch size 使用:
32Keras utility 会自动完成很多步骤。
处理后数据量为:
- training data:
98images,属于2classes。 - validation data:
49images。 - test data:
38images。
输入图像被 resize 为:
224 x 224 x 3选择 224 x 224 x 3 的原因是后面要使用 ResNet,而 ResNet 期望这种输入尺寸。
五十二、从头训练一个彩色图像 CNN
老师先从头训练一个简单 CNN,用于 handbags vs shoes。
之前在 Fashion-MNIST 中,手动将像素值除以 255。
这里老师改用 Keras 内部的 preprocessing layer:
Rescaling这样可以直接在模型中完成:
0 to 255 → 0 to 1模型结构是:
- input
Rescaling- first convolutional block:
32filters - second convolutional block:
32filters MaxPoolFlatten- binary output with
sigmoid
因为任务只有两个类别:
- handbag
- shoe
所以这是 binary classification,输出层使用一个 sigmoid 即可。
模型大约有:
101,000 parameters编译设置:
- loss:
binary_crossentropy - optimizer:
Adam - metric:
accuracy
训练设置:
20epochs
五十三、Transfer Learning 的动机
从头训练彩色图像 CNN 后,老师转向问题:
数据只有每类约
100张,能否做得更好?
这引出:
transfer learning迁移学习利用两个趋势:
- 研究者设计了能利用输入类型结构的 architectures。
- 研究者用巨大数据集训练了大型模型,并公开发布这些模型供他人使用。
对于图像:
convolutional layers专门利用 image structure。
对于序列数据:
transformers专门利用 sequence structure。- 适用于 natural language、audio、video、gene sequence 等。
老师说明,后续会花很多时间讲 transformers。
五十四、Transfer Learning 的基本思想
transfer learning 的核心是:
不从头训练模型,而是拿一个别人已经训练好的 pre-trained network,针对自己的问题做定制。
对于 handbags vs shoes:
- 目标是输入任意图像,判断是 handbag 还是 shoe。
- handbags 和 shoes 都是 everyday objects。
因此,可以寻找已经在 everyday images 上训练过的模型。
老师说明,第一步也可以先查是否已经有人在 GitHub 上做过 handbag/shoe classifier。
如果没有,就使用迁移学习。
五十五、ImageNet
ImageNet 是一个包含大量 everyday objects 的图像数据库。
特点:
- millions of images
1000categories- 包含 furniture、animals、automobiles 等日常对象
因此,可以使用在 ImageNet 上训练好的网络。
这些网络的 weights 应该已经包含关于:
- lines
- shapes
- curves
- objects
等视觉特征的知识。
五十六、从头训练模型的结果
回到 Colab,从头训练的小型 CNN 出现了一些 overfitting。
观察结果:
- training accuracy 接近
100%。 - validation/test accuracy 大约在
80s。
最终评估约为:
87% accuracy老师强调,这已经不错,因为训练数据只有每类大约 100 个样本。
但这仍然是从头训练得到的结果。
五十七、Data Augmentation
老师接着介绍:
data augmentation核心直觉是:
对图像做小幅扰动,通常不会改变图像语义。
例如一张 handbag 图片:
- 轻微旋转
10degrees。 - 稍微 zoom in。
- 稍微 zoom out。
- 轻微 crop。
它仍然是 handbag。
因此,可以将这些轻微变化后的图像作为新的训练样本。
老师称这几乎是一个很好的 free lunch,尤其在数据较少时可以人工扩充训练集。
老师还提到,类似思想也可用于 text,后续课程会讲。
五十八、Keras 中的数据增强层
Keras 提供许多 data augmentation layers。
课堂示例包括:
- random horizontal flip
- random rotation
- random zoom
老师提到 random rotation 中的 0.1,他不确定是 degrees 还是 radians,需要查看 documentation。
这些增强不会对每张图都固定执行,而是随机发生。
这样可以让训练集中出现更多多样化版本。
老师展示随机抓取一张 handbag 图片,并产生多个增强版本:
- 有的略微旋转。
- 有的略微缩放。
- 有的方向有所变化。
五十九、Data Augmentation 的边界
老师强调:
数据增强不能改变图像的 underlying meaning。
例如:
- everyday images 中,horizontal flip 通常可以。
- vertical flip 通常不合适。
原因是很少需要识别倒立的 dog picture。
如果是 satellite data,也要非常谨慎,不能随意进行不合理的 flips。
数据增强应服务于真实任务分布,而不能生成语义错误或不现实的样本。
六十、在模型中插入 Data Augmentation
在 Keras 中,可以把 data augmentation layers 直接插入模型。
位置通常是:
right after the input其余网络结构可以保持不变。
老师说明,这个增强模型在 Colab 中可以训练,但由于时间限制,课堂不实际训练。
data augmentation 会在 homework 1 中出现,学生会获得更多练习。
六十一、ImageNet 模型学到了什么
老师回到 PowerPoint,说明在 ImageNet 上训练过的网络会在不同层学习到各种视觉特征。
可视化中可以看到:
- 第一层:color gradations、line-like features。
- 第二层:edges。
- 第三层:honeycomb-like shapes。
- 更深层:human torso-like shapes。
- 某些位置甚至像
Labrador retriever。
老师提到,之前关于“如何知道网络学到了什么”的问题,可以参考早期可视化论文。该论文是较早展示网络内部表示的工作之一。
六十二、多模态输入问题预告
学生问:如果输入是 email,其中既有 text,又有 image,还有 whitespace,这类输入如何表示?
老师回答,这个问题会在课程后面再认真讨论。
原因是答案较复杂,需要更充分的解释。
六十三、ResNet
ResNet 是一组在 ImageNet 上训练过的网络。
它们在与 ImageNet 相关的比赛中表现很好。
因为 ResNet 在 ImageNet 上训练过,所以它的 weights 和 parameters 应该已经包含许多关于图像的知识:
- lines
- shapes
- curves
- everyday objects
因此,可以尝试复用它。
六十四、为什么不能直接使用完整 ResNet
完整 ResNet 的最后一层用于:
1000-way classification因为 ImageNet 有 1000 类。
但本节课任务只有:
- handbag
- shoe
也就是 2 类。
因此,不能直接使用完整 ResNet 的原始输出层。
六十五、Headless ResNet
解决方法是:
去掉 ResNet 的最后分类层,只保留最后一层之前的部分。
老师称其为:
headless ResNet操作直觉是:
- 输入图像进入 ResNet。
- 图像经过 ResNet 的 convolutional blocks。
- 在最终
1000分类层之前停止。 - 取出此时的 tensor。
这个 tensor 可以看作图像的高层 representation。
它可能已经包含:
- objects
- shapes
- features
- 其他高级视觉结构
然后可以把这个 representation 接到一个小型网络上,例如:
- hidden layer
sigmoidoutput
用于 handbag vs shoe 分类。
六十六、Transfer Learning 的两种使用方式
老师介绍了基本方式和更高级方式。
66.1 Feature Extraction
先将所有图像通过 headless ResNet。
保存 ResNet 倒数第二部分输出的 tensors。
然后只训练一个小网络,将这些高层 representations 映射到 handbag/shoe。
因为输入已经不是原始像素,而是 ResNet 学出的高级表示,所以用很少样本也可能工作。
66.2 End-to-End Fine-Tuning
也可以把 headless ResNet 与自定义小网络连接起来,端到端训练。
关键是:
必须从下载的 ResNet weights 开始训练,因为这些 weights 是预训练模型的核心价值。
老师说明,homework 1 会做这类工作。
六十七、预训练模型来源
老师提到,pre-trained models 可以从多个平台获得:
TensorFlow HubPyTorch HubHugging Face Hub
老师在 13th 检查时,Hugging Face Hub 上已有超过:
half a million models他说上一年授课时大约是 50,000 个模型。
这说明预训练模型生态增长非常快。
六十八、关于 Adversarial Risk 的问答
学生问:如果所有人都知道模型 weights,是否会更容易受到 adversarial attacks?
老师回答:是的,存在一定 adversarial risk。
本节课没有展开,老师表示可以课后讨论。
六十九、Keras 中加载 ResNet
回到 Colab,老师使用 Keras 下载并加载 ResNet。
关键参数是:
include_top=False含义是:
不要 ResNet 最后的分类层,只保留到最后分类层之前的部分。
老师解释:
- 他习惯从左到右想象网络。
- 其他人有时从 bottom 到 top 想象网络。
top指最上面的最终分类层。
使用 include_top=False 后,就不需要手动删除最后一层。
ResNet 很大,大约有:
23 million parameters老师不打算画出完整结构,因为会非常长。
七十、ResNet 输出的 Representation
老师将所有 handbag/shoe 图像通过 headless ResNet。
ResNet 最后分类层之前输出的 representation 被保存下来。
输出结果中:
- training data 有
98examples。 - 每个 example 变成一个 tensor。
tensor shape 是:
7 x 7 x 2048这与前面讲 ResNet 时的尺寸示例对应。
七十一、在 ResNet Representation 上训练小模型
基于 ResNet 输出的 representation,老师搭建一个小模型:
- 输入 shape:
7 x 7 x 2048。 - 立即 flatten。
- 接一个 dense layer。
- dense layer 有
256个ReLUneurons。 - 使用
Dropout。 - 接一个
sigmoid输出。
老师说明,Dropout 还没有正式讲,会在下一周早些时候解释。本节课暂时不用担心这个细节。
训练设置:
10epochs。
模型训练很快,因为:
大型 ResNet 已经提前对所有图片算出高层 representations,后续训练不必每次重新跑完整 ResNet。
七十二、Transfer Learning 的结果
训练曲线中,第 10 个 epoch 似乎出现了问题,老师说也许应该在第 9 个 epoch 停止。
他也提到,这次结果与前一天运行时不完全一样,说明随机可复现性不总是完美。
最终在 test set 上得到:
100% accuracy老师表示这个结果非常惊人。
七十三、Live Demo:Webcam 分类鞋和包
最后,老师用 webcam 进行 live demo。
流程是:
- 使用一段代码从 webcam 捕捉图像。
- 将图像送入刚训练好的模型。
- 预测是 handbag 还是 shoe。
老师先在家试过,模型能判断 handbag。
课堂中他请学生提供:
- 一只 footwear。
- 一个 handbag 或类似物。
先测试鞋:
- 老师用 webcam 拍摄学生的 shoe。
- 模型预测为 shoe。
- demo 成功。
再测试包:
- 学生提供一个类似 backpack/handbag 的物品。
- 老师拍摄后模型预测为 handbag。
- demo 再次成功。
老师最后说明,每次做 live demo 都有失败风险,因此成功后松了一口气。
七十四、本节课核心总结
本节课的知识链条可以概括为:
- 直接 flatten 图像会忽略
spatial adjacency。 - dense layer 直接连接高分辨率图像会造成参数爆炸。
- 图像模型需要
translation invariance,即同一特征在不同位置都能识别。 convolutional filter是一个小矩阵,可以在图像上滑动并检测特征。- convolution operation 的核心是对应数字相乘、求和,再通过
ReLU。 padding和stride是控制 filter 移动与边界处理的重要细节。- 多个 filters 会生成多张输出表,并打包成更深的 tensor。
- 彩色图像需要 3D filters,filter depth 要匹配 input depth。
- filter 中的数字可以作为 weights,通过
backprop从数据中学习。 AlexNet在2012年通过 CNN 方法显著推动计算机视觉发展。- CNN 会逐层学习更抽象的图像表示。
pooling layer用于缩小空间尺寸,常见形式包括max pooling和average pooling。max pooling可以理解为检测某个区域中是否有 feature 激活。- 基本 CNN 由多个
convolutional blocks组成,最后 flatten 并接 dense/output layers。 Fashion-MNISTCNN 使用Conv2D、MaxPool2D、Flatten、dense layer 和softmax。Fashion-MNISTCNN test accuracy 约为90.5%,高于直接 flatten 的 dense 网络。- 对结构化数据,不应假设 DNN 一定优于传统机器学习方法。
- 小样本彩色图像分类可以先从头训练 CNN,但容易 overfit。
data augmentation可以通过合理扰动图像扩充训练数据。transfer learning使用 pre-trained models 的已有视觉表示来解决小样本任务。ResNet可通过include_top=False去掉最终1000分类层,作为 headless feature extractor。- headless ResNet 输出
7 x 7 x 2048representation。 - 基于 ResNet representation 的小模型在本节 demo 中达到
100%test accuracy,并成功完成 webcam 分类。
最核心的思想是:
CNN 将图像的空间结构、局部特征和参数共享纳入网络设计,而 transfer learning 则复用大模型在大规模数据上学到的视觉表示,让小样本任务也能取得很强效果。
理解这一点后,图像分类不再只是把 pixels 送入 dense layer,而是通过卷积、池化、层级表示和预训练知识共同完成的建模过程。