原文出处:Introduction to Frameworks 原作者:Microsoft · 许可证:MIT License 中文译本由诸葛AI学院整理,仅供学习参考,版权归原作者与微软所有。
神经网络框架
前面我们已经学过,要高效地训练神经网络,得做到两件事:
- 能对张量(tensor)做运算,比如乘、加,以及计算 sigmoid、softmax 这类函数
- 能算出所有表达式的梯度(gradient),好执行梯度下降(gradient descent)优化
课前小测
第一件,numpy 库就能办到;算梯度则还需要一套机制。在上一节我们自己搭的框架里,负责反向传播(backpropagation)的 backward 方法中,每个导数函数都得手动编程实现。一个理想的框架(framework),应该能对我们定义的任意表达式自动计算梯度。
还有一个同样要紧的点:计算要能放到 GPU 或其他专用计算单元(比如 TPU)上跑。深度神经网络的训练需要大量计算,能不能把这些计算并行化到 GPU 上,非常重要。
"并行化"(parallelize)这个词,指的是把计算分发到多个设备上执行。
目前最流行的两个神经网络框架是 TensorFlow 和 PyTorch。两者都提供在 CPU 和 GPU 上操作张量的低层 API(low-level API)。低层 API 之上还有高层 API(high-level API),分别是 Keras 和 PyTorch Lightning。
| TensorFlow | PyTorch | |
|---|---|---|
| 低层 API | TensorFlow | PyTorch |
| 高层 API | Keras | PyTorch Lightning |
两个框架的低层 API 都能用来构建所谓的计算图(computational graph)。这张图描述如何用给定的输入参数算出输出(通常是损失函数),可以推送给 GPU(如果有)去计算。框架还提供对这张计算图求导、算出梯度的函数,算出来的梯度用于优化模型参数。
高层 API 基本把神经网络看成一层层的序列,搭建大多数网络因此轻松得多。训练模型通常只要准备好数据,再调用一个 fit 函数,活儿就干完了。
用高层 API,你能很快搭出典型的神经网络,不用操心一堆细节;用低层 API,你对训练过程的控制力强得多,所以科研中用得很多,尤其是在处理新的神经网络架构时。
还有一点要弄清楚:两套 API 可以混着用。比如用低层 API 开发自己的网络层结构,再把它嵌进用高层 API 搭建、训练的大网络里;或者反过来,用高层 API 把网络定义成一串层,再用自己写的低层训练循环做优化。两套 API 用的是同一套底层概念,本来就是设计成配合使用的。
学习路径
这门课的大部分内容都同时提供 PyTorch 和 TensorFlow 两个版本。你可以选定自己喜欢的框架,只学对应的 notebook。拿不定主意的话,去网上看看关于 PyTorch vs. TensorFlow 的讨论,也可以两个框架都上手感受一下,理解会更清楚。
只要条件允许,我们会优先用高层 API,图个简洁。不过我们认为,从头到尾弄明白神经网络是怎么工作的很重要,所以开头部分会先从低层 API 和张量讲起。如果你想尽快上手、不想在这些细节上花太多时间,可以跳过这部分,直接学高层 API 的 notebook。
练习:框架
接着在下面的 notebook 里继续学习:
| TensorFlow | PyTorch | |
|---|---|---|
| 低层 API | TensorFlow + Keras Notebook | PyTorch Notebook |
| 高层 API | Keras Notebook | PyTorch Lightning |
框架练熟之后,我们来回顾一个重要概念:过拟合(overfitting)。
过拟合
过拟合是机器学习里极其重要的一个概念,必须把它弄明白!
来看一个拟合 5 个点的问题(图中用 x 标出这 5 个点)。原文此处有两张图,左边是线性模型的拟合结果,右边是非线性模型的拟合结果,两组数据对照如下:
| 线性模型,2 个参数 | 非线性模型,7 个参数 | |
|---|---|---|
| 训练误差 | 5.3 | 0 |
| 验证误差 | 5.1 | 20 |
- 左图是一条恰到好处的直线拟合。参数数量合适,模型把握住了这组点分布背后的思路。
- 右图的模型太强了。只有 5 个点,模型却有 7 个参数,它可以调成穿过所有点,把训练误差压到 0。但正因如此,模型没能理解数据背后的正确规律,验证误差非常高。
要在模型的丰富程度(参数数量)和训练样本的数量之间找到正确的平衡,这一点非常重要。
过拟合为什么会发生
- 训练数据不够多
- 模型太强
- 输入数据里噪声太大
怎么发现过拟合
从上面两张图就能看出来:训练误差非常低、验证误差很高,就是过拟合。正常训练时,训练误差和验证误差会一起下降,到某个点上,验证误差可能不再下降、反而开始上升。这就是过拟合的信号,也是提醒我们该在这一处停止训练了(至少要把模型存个快照)。原文此处有一张图,画的就是这种曲线:训练误差一路下降,验证误差先降后升。
怎么预防过拟合
如果发现过拟合了,可以下面挑一条来做:
过拟合与偏差-方差权衡
过拟合其实是统计学里一个更普遍问题的特例,叫偏差-方差权衡(bias-variance tradeoff)。把模型可能的误差来源摆出来看,有两种误差:
- 偏差误差(bias error):算法没能正确捕捉训练数据之间的关系。常见原因是模型不够强,也就是欠拟合(underfitting)。
- 方差误差(variance error):模型拟合的不是有意义的规律,而是输入数据里的噪声,也就是过拟合。
训练过程中,偏差误差会下降(模型逐渐学会逼近数据),方差误差则会上升。必须及时停止训练:要么手动停(发现过拟合信号时),要么自动停(引入正则化),以此防止过拟合。
小结
这节课我们讲了两大热门 AI 框架 TensorFlow 和 PyTorch 各自 API 的区别,还重点学了过拟合这个重要主题。
挑战任务
配套的 notebook 末尾都列着 'task',把 notebook 逐个过一遍,完成这些任务。
课后小测
复习与自学
围绕下面几个主题做点功课:
- TensorFlow
- PyTorch
- 过拟合
再问自己两个问题:
- TensorFlow 和 PyTorch 有什么区别?
- 过拟合和欠拟合有什么区别?
作业
这个实验要求你用 PyTorch 或 TensorFlow,通过单层和多层全连接网络,解决两个分类问题。