动手学深度学习 Aston Zhang Mu Li Zachary C. Lipton Alexander J. Smola 2019 年 06 月 27 日 本书稿为测试版本(生成日期: 2019 年 6 月 27 日) 。 访问 https://zh.d2l.ai ,获取本书的最新版本或正式版本。 i ii 目录 前言 1 如何使用本书 7 1 深度学习简介 13 1.1 起源 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.2 发展 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.3 成功案例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.4 特点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2 预备知识 25 2.1 获取和运行本书的代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.1.1 获取代码并安装运行环境 . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.1.2 更新代码和运行环境 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.1.3 使用 GPU 版的 MXNet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.2 数据操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 2.2.1 创建 NDArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 2.2.2 运算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.2.3 广播机制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.2.4 索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.2.5 运算的内存开销 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 iii 2.2.6 NDArray 和 NumPy 相互变换 . . . . . . . . . . . . . . . . . . . . . . . . 36 2.3 自动求梯度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.3.1 简单例子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.3.2 训练模式和预测模式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.3.3 对 Python 控制流求梯度 . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.4 查阅文档 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.4.1 查找模块里的所有函数和类 . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.4.2 查找特定函数和类的使用 . . . . . . . . . . . . . . . . . . . . . . . . . . 41 2.4.3 在 MXNet 网站上查阅 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3 深度学习基础 45 3.1 线性回归 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.1.1 线性回归的基本要素 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 3.1.2 线性回归的表示方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 3.2 线性回归的从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.2.1 生成数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.2.2 读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3.2.3 初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.2.4 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.2.5 定义损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.2.6 定义优化算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.2.7 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.3 线性回归的简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.3.1 生成数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.3.2 读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.3.3 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 3.3.4 初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.3.5 定义损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.3.6 定义优化算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.3.7 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 3.4 softmax 回归 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 3.4.1 分类问题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 3.4.2 softmax 回归模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 3.4.3 单样本分类的矢量计算表达式 . . . . . . . . . . . . . . . . . . . . . . . . 63 3.4.4 小批量样本分类的矢量计算表达式 . . . . . . . . . . . . . . . . . . . . . 64 iv 3.4.5 交叉熵损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 3.4.6 模型预测及评价 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 3.5 图像分类数据集( Fashion-MNIST ) . . . . . . . . . . . . . . . . . . . . . . . . 66 3.5.1 获取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 3.5.2 读取小批量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 3.6 softmax 回归的从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.6.1 获取和读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.6.2 初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.6.3 实现 softmax 运算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.6.4 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 3.6.5 定义损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 3.6.6 计算分类准确率 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 3.6.7 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 3.6.8 预测 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 3.7 softmax 回归的简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 3.7.1 获取和读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 3.7.2 定义和初始化模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 3.7.3 softmax 和交叉熵损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . 76 3.7.4 定义优化算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 3.7.5 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 3.8 多层感知机 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 3.8.1 隐藏层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 3.8.2 激活函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 3.8.3 多层感知机 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 3.9 多层感知机的从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.9.1 获取和读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.9.2 定义模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.9.3 定义激活函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.9.4 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 3.9.5 定义损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 3.9.6 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 3.10 多层感知机的简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 3.10.1 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 3.10.2 读取数据并训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 v 3.11 模型选择、欠拟合和过拟合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 3.11.1 训练误差和泛化误差 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 3.11.2 模型选择 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 3.11.3 欠拟合和过拟合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 3.11.4 多项式函数拟合实验 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 3.12 权重衰减 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 3.12.1 方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 3.12.2 高维线性回归实验 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 3.12.3 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 3.12.4 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 3.13 丢弃法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 3.13.1 方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 3.13.2 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 3.13.3 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 3.14 正向传播、反向传播和计算图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 3.14.1 正向传播 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 3.14.2 正向传播的计算图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 3.14.3 反向传播 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 3.14.4 训练深度学习模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 3.15 数值稳定性和模型初始化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 3.15.1 衰减和爆炸 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 3.15.2 随机初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 3.16 实战 Kaggle 比赛:房价预测 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 3.16.1 Kaggle 比赛 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 3.16.2 获取和读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 3.16.3 预处理数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 3.16.4 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 3.16.5 K 折交叉验证 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 3.16.6 模型选择 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 3.16.7 预测并在 Kaggle 提交结果 . . . . . . . . . . . . . . . . . . . . . . . . . . 121 4 深度学习计算 125 4.1 模型构造 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 4.1.1 继承 Block 类来构造模型 . . . . . . . . . . . . . . . . . . . . . . . . . . 126 4.1.2 Sequential 类继承自 Block 类 . . . . . . . . . . . . . . . . . . . . . . 127 vi 4.1.3 构造复杂的模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 4.2 模型参数的访问、初始化和共享 . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 4.2.1 访问模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 4.2.2 初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 4.2.3 自定义初始化方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 4.2.4 共享模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 4.3 模型参数的延后初始化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 4.3.1 延后初始化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 4.3.2 避免延后初始化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 4.4 自定义层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 4.4.1 不含模型参数的自定义层 . . . . . . . . . . . . . . . . . . . . . . . . . . 138 4.4.2 含模型参数的自定义层 . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 4.5 读取和存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 4.5.1 读写 NDArray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 4.5.2 读写 Gluon 模型的参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 4.6 GPU 计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 4.6.1 计算设备 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 4.6.2 NDArray 的 GPU 计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 4.6.3 Gluon 的 GPU 计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 5 卷积神经网络 149 5.1 二维卷积层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 5.1.1 二维互相关运算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 5.1.2 二维卷积层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 5.1.3 图像中物体边缘检测 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 5.1.4 通过数据学习核数组 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 5.1.5 互相关运算和卷积运算 . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 5.1.6 特征图和感受野 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 5.2 填充和步幅 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 5.2.1 填充 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 5.2.2 步幅 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 5.3 多输入通道和多输出通道 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 5.3.1 多输入通道 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 5.3.2 多输出通道 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 5.3.3 1 × 1 卷积层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 vii 5.4 池化层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 5.4.1 二维最大池化层和平均池化层 . . . . . . . . . . . . . . . . . . . . . . . . 164 5.4.2 填充和步幅 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 5.4.3 多通道 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 5.5 卷积神经网络( LeNet ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 5.5.1 LeNet 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 5.5.2 获取数据和训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 5.6 深度卷积神经网络( AlexNet ) . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 5.6.1 学习特征表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 5.6.2 AlexNet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 5.6.3 读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 5.6.4 训练 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 5.7 使用重复元素的网络( VGG ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 5.7.1 VGG 块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 5.7.2 VGG 网络 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 5.7.3 获取数据和训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 5.8 网络中的网络( NiN ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 5.8.1 NiN 块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 5.8.2 NiN 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 5.8.3 获取数据和训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 5.9 含并行连结的网络( GoogLeNet ) . . . . . . . . . . . . . . . . . . . . . . . . . . 185 5.9.1 Inception 块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 5.9.2 GoogLeNet 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 5.9.3 获取数据和训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 5.10 批量归一化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 5.10.1 批量归一化层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 5.10.2 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 5.10.3 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 5.11 残差网络( ResNet ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 5.11.1 残差块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 5.11.2 ResNet 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 5.11.3 获取数据和训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 5.12 稠密连接网络( DenseNet ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 5.12.1 稠密块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 viii 5.12.2 过渡层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 5.12.3 DenseNet 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 5.12.4 获取数据并训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 6 循环神经网络 207 6.1 语言模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 6.1.1 语言模型的计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 6.1.2 n 元语法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 6.2 循环神经网络 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 6.2.1 不含隐藏状态的神经网络 . . . . . . . . . . . . . . . . . . . . . . . . . . 210 6.2.2 含隐藏状态的循环神经网络 . . . . . . . . . . . . . . . . . . . . . . . . . 211 6.2.3 应用:基于字符级循环神经网络的语言模型 . . . . . . . . . . . . . . . . 213 6.3 语言模型数据集(周杰伦专辑歌词) . . . . . . . . . . . . . . . . . . . . . . . . 214 6.3.1 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 6.3.2 建立字符索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 6.3.3 时序数据的采样 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 6.4 循环神经网络的从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 6.4.1 one-hot 向量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 6.4.2 初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 6.4.3 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 6.4.4 定义预测函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 6.4.5 裁剪梯度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 6.4.6 困惑度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 6.4.7 定义模型训练函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 6.4.8 训练模型并创作歌词 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 6.5 循环神经网络的简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 6.5.1 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 6.5.2 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 6.6 通过时间反向传播 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 6.6.1 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 6.6.2 模型计算图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 6.6.3 方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 6.7 ⻔控循环单元( GRU ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 6.7.1 ⻔控循环单元 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 6.7.2 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 ix 6.7.3 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 6.7.4 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 6.8 ⻓短期记忆( LSTM ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 6.8.1 ⻓短期记忆 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 6.8.2 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 6.8.3 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 6.8.4 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 6.8.5 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 6.9 深度循环神经网络 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 6.10 双向循环神经网络 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 7 优化算法 253 7.1 优化与深度学习 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 7.1.1 优化与深度学习的关系 . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 7.1.2 优化在深度学习中的挑战 . . . . . . . . . . . . . . . . . . . . . . . . . . 254 7.2 梯度下降和随机梯度下降 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 7.2.1 一维梯度下降 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 7.2.2 学习率 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 7.2.3 多维梯度下降 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 7.2.4 随机梯度下降 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 7.3 小批量随机梯度下降 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 7.3.1 读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 7.3.2 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 7.3.3 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 7.4 动量法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 7.4.1 梯度下降的问题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 7.4.2 动量法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 7.4.3 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 7.4.4 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 7.5 AdaGrad 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 7.5.1 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 7.5.2 特点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 7.5.3 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 7.5.4 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 7.6 RMSProp 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 x 7.6.1 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 7.6.2 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 7.6.3 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 7.7 AdaDelta 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 7.7.1 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 7.7.2 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 7.7.3 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 7.8 Adam 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 7.8.1 算法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 7.8.2 从零开始实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 7.8.3 简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 8 计算性能 297 8.1 命令式和符号式混合编程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 8.1.1 混合式编程取两者之⻓ . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 8.1.2 使用 HybridSequential 类构造模型 . . . . . . . . . . . . . . . . . . . 300 8.1.3 使用 HybridBlock 类构造模型 . . . . . . . . . . . . . . . . . . . . . . . 302 8.2 异步计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 8.2.1 MXNet 中的异步计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 8.2.2 用同步函数让前端等待计算结果 . . . . . . . . . . . . . . . . . . . . . . 306 8.2.3 使用异步计算提升计算性能 . . . . . . . . . . . . . . . . . . . . . . . . . 307 8.2.4 异步计算对内存的影响 . . . . . . . . . . . . . . . . . . . . . . . . . . . 308 8.3 自动并行计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 8.3.1 CPU 和 GPU 的并行计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 8.3.2 计算和通信的并行计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 8.4 多 GPU 计算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 8.4.1 数据并行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 8.4.2 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 8.4.3 多 GPU 之间同步数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 8.4.4 单个小批量上的多 GPU 训练 . . . . . . . . . . . . . . . . . . . . . . . . . 319 8.4.5 定义训练函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 8.4.6 多 GPU 训练实验 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 8.5 多 GPU 计算的简洁实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 8.5.1 多 GPU 上初始化模型参数 . . . . . . . . . . . . . . . . . . . . . . . . . . 321 8.5.2 多 GPU 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 xi 9 计算机视觉 327 9.1 图像增广 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 9.1.1 常用的图像增广方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 9.1.2 使用图像增广训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 9.2 微调 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 9.2.1 热狗识别 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 9.3 目标检测和边界框 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 9.3.1 边界框 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 9.4 锚框 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 9.4.1 生成多个锚框 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 9.4.2 交并比 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 9.4.3 标注训练集的锚框 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 9.4.4 输出预测边界框 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 9.5 多尺度目标检测 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 9.6 目标检测数据集(皮卡丘) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 9.6.1 下载数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 9.6.2 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 9.6.3 图示数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 9.7 单发多框检测( SSD ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 9.7.1 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 9.7.2 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 9.7.3 预测 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 9.8 区域卷积神经网络( R-CNN )系列 . . . . . . . . . . . . . . . . . . . . . . . . . . 376 9.8.1 R-CNN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 9.8.2 Fast R-CNN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 9.8.3 Faster R-CNN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 9.8.4 Mask R-CNN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 9.9 语义分割和数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 9.9.1 图像分割和实例分割 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 9.9.2 Pascal VOC2012 语义分割数据集 . . . . . . . . . . . . . . . . . . . . . . 384 9.10 全卷积网络( FCN ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 9.10.1 转置卷积层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 9.10.2 构造模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 9.10.3 初始化转置卷积层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 xii 9.10.4 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 9.10.5 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 9.10.6 预测像素类别 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 9.11 样式迁移 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 9.11.1 方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 9.11.2 读取内容图像和样式图像 . . . . . . . . . . . . . . . . . . . . . . . . . . 401 9.11.3 预处理和后处理图像 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 9.11.4 抽取特征 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 9.11.5 定义损失函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 9.11.6 创建和初始化合成图像 . . . . . . . . . . . . . . . . . . . . . . . . . . . 405 9.11.7 训练 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 9.12 实战 Kaggle 比赛:图像分类( CIFAR-10 ) . . . . . . . . . . . . . . . . . . . . . . 409 9.12.1 获取和整理数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 9.12.2 图像增广 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 9.12.3 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 9.12.4 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 9.12.5 定义训练函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 9.12.6 训练并验证模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 9.12.7 对测试集分类并在 Kaggle 提交结果 . . . . . . . . . . . . . . . . . . . . . 417 9.13 实战 Kaggle 比赛:狗的品种识别( ImageNet Dogs ) . . . . . . . . . . . . . . . . 418 9.13.1 获取和整理数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 9.13.2 图像增广 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 9.13.3 读取数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 9.13.4 定义模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 9.13.5 定义训练函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 9.13.6 训练并验证模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 9.13.7 对测试集分类并在 Kaggle 提交结果 . . . . . . . . . . . . . . . . . . . . . 425 10 自然语言处理 427 10.1 词嵌入( word2vec ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 10.1.1 为何不采用 one-hot 向量 . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 10.1.2 跳字模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 10.1.3 连续词袋模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 10.2 近似训练 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 10.2.1 负采样 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 xiii 10.2.2 层序 softmax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 10.3 word2vec 的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436 10.3.1 处理数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437 10.3.2 负采样 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 10.3.3 读取数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 10.3.4 跳字模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442 10.3.5 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 10.3.6 应用词嵌入模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 10.4 子词嵌入( fastText ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 10.5 全局向量的词嵌入( GloVe ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448 10.5.1 GloVe 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 10.5.2 从条件概率比值理解 GloVe 模型 . . . . . . . . . . . . . . . . . . . . . . . 450 10.6 求近义词和类比词 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 10.6.1 使用预训练的词向量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 10.6.2 应用预训练词向量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 10.7 文本情感分类:使用循环神经网络 . . . . . . . . . . . . . . . . . . . . . . . . . . 456 10.7.1 文本情感分类数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 10.7.2 使用循环神经网络的模型 . . . . . . . . . . . . . . . . . . . . . . . . . . 459 10.8 文本情感分类:使用卷积神经网络( textCNN ) . . . . . . . . . . . . . . . . . . 462 10.8.1 一维卷积层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 10.8.2 时序最大池化层 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 10.8.3 读取和预处理 IMDb 数据集 . . . . . . . . . . . . . . . . . . . . . . . . . . 464 10.8.4 textCNN 模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 10.9 编码器—解码器( seq2seq ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 10.9.1 编码器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 10.9.2 解码器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 10.9.3 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 10.10 束搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 10.10.1 贪婪搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 10.10.2 穷举搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 10.10.3 束搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 10.11 注意力机制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 10.11.1 计算背景变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 10.11.2 更新隐藏状态 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 xiv 10.11.3 发展 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 10.12 机器翻译 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480 10.12.1 读取和预处理数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481 10.12.2 含注意力机制的编码器—解码器 . . . . . . . . . . . . . . . . . . . . . . . 482 10.12.3 训练模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 10.12.4 预测不定⻓的序列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 10.12.5 评价翻译结果 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 11 附录 491 11.1 主要符号一览 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 11.1.1 数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 11.1.2 集合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 11.1.3 操作符 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 11.1.4 函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 11.1.5 导数和梯度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 11.1.6 概率和统计 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 11.1.7 复杂度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 11.2 数学基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 11.2.1 线性代数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 11.2.2 微分 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496 11.2.3 概率 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 11.3 使用 Jupyter 记事本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500 11.3.1 在本地编辑和运行本书的代码 . . . . . . . . . . . . . . . . . . . . . . . . 501 11.3.2 高级选项 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 11.4 使用 AWS 运行代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 11.4.1 申请账号并登陆 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 11.4.2 创建并运行 EC2 实例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508 11.4.3 安装 CUDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513 11.4.4 获取本书的代码并安装 GPU 版的 MXNet . . . . . . . . . . . . . . . . . . . 515 11.4.5 运行 Jupyter 记事本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 11.4.6 关闭不使用的实例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 11.5 GPU 购买指南 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518 11.5.1 选择 GPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518 11.5.2 整机配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 11.6 如何为本书贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521 xv 11.7 d2lzh 包索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527 xvi 前言 就在几年前,不管在大公司还是创业公司,都鲜有工程师和科学家来将深度学习应用到智能产品 与服务中。 作为深度学习前身的神经网络, 才刚刚摆脱被机器学习学术界认为是过时工具的印象。 那个时候,即使是机器学习也非新闻头条的常客。它仅仅被看作是一⻔具有前瞻性,并拥有一系 列小范围实际应用的学科。在包含计算机视觉和自然语言处理在内的实际应用通常需要大量的相 关领域知识:这些实际应用被视为相互独立的领域,而机器学习只占其中一小部分。 然而仅仅在这几年之内,深度学习便令全世界大吃一惊。它非常有力地推动了计算机视觉、自然 语言处理、自动语音识别、强化学习和统计建模等多个领域的快速发展。随着这些领域的不断进 步,我们现在可以制造自动驾驶的汽⻋,基于短信、邮件甚至电话的自动回复系统,以及在围棋 中击败最优秀人类选手的软件。这些由深度学习带来的新工具也正产生着广泛的影响:它们改变 了电影制作和疾病诊断的方式,并在从天体物理学到生物学等各个基础科学中扮演越来越重要的 ⻆色。 与此同时,深度学习也给它的使用者们带来了独一无二的挑战:任何单一的应用都汇集了各学科 的知识。具体来说,应用深度学习需要同时理解: 1. 问题的动机和特点; 2. 将大量不同类型神经网络层通过特定方式组合在一起的模型背后的数学原理; 3. 在原始数据上拟合极复杂的深层模型的优化算法; 1 4. 有效训练模型、避免数值计算陷阱以及充分利用硬件性能所需的工程技能; 5. 为解决方案挑选合适的变量(超参数)组合的经验。 同样,我们几位作者也面临前所未有的挑战:我们需要在有限的篇幅里糅合深度学习的多方面知 识,从而使读者能够较快理解并应用深度学习技术。本书代表了我们的一种尝试:我们将教给读 者概念、背景知识和代码;我们将在同一个地方阐述剖析问题所需的批判性思维、解决问题所需 的数学知识,以及实现解决方案所需的工程技能。 包含代码、数学、网⻚、讨论的统一资源 我们在 2017 年 7 月启动了写作这本书的项目。 当时我们需要向用戶解释 Apache MXNet 在那时的新 接口 Gluon 。不幸的是,我们并没有找到任何一个资源可以同时满足以下几点需求: 1. 包含较新的方法和应用,并不断更新; 2. 广泛覆盖现代深度学习技术并具有一定的技术深度; 3. 既是严谨的教科书,又是包含可运行代码的生动的教程。 那时,我们在博客和 GitHub 上找到了大量的演示特定深度学习框架(例如用 TensorFlow 进行数 值计算)或实现特定模型(例如 AlexNet 、 ResNet 等)的示例代码。这些示例代码的一大价值在 于提供了教科书或论文往往省略的实现细节,比如数据的处理和运算的高效率实现。如果不了解 这些,即使能将算法倒背如流,也难以将算法应用到自己的项目中去。此外,这些示例代码还使 得用戶能通过观察修改代码所导致的结果变化而快速验证想法、积累经验。因此,我们坚信动手 实践对于学习深度学习的重要性。然而可惜的是, 这些示例代码通常侧重于如何实现给定的方法, 却忽略了有关算法设计的探究或者实现细节的解释。虽然在像 Distill 这样的网站和某些博客上出 现了一些有关算法设计和实现细节的讨论,但它们常常缺少示例代码,并通常仅覆盖深度学习的 一小部分。 另外,我们欣喜地看到了一些有关深度学习的教科书不断问世,其中最著名的要数 Goodfellow 、 Bengio 和 Courville 的《深度学习》 。该书梳理了深度学习背后的众多概念与方法,是一本极为优 秀的教材。然而,这类资源并没有将概念描述与实际代码相结合,以至于有时会令读者对如何实 现它们感到毫无头绪。除了这些以外,商业课程提供者们虽然制作了众多的优质资源,但它们的 付费⻔槛依然令不少用戶望而生畏。 正因为这样,深度学习用戶,尤其是初学者,往往不得不参考来源不同的多种资料。例如,通过 教科书或者论文来掌握算法及其相关数学知识,阅读线上文档学习深度学习框架的使用方法,然 后寻找感兴趣的算法在这个框架上的实现并摸索如何将它应用到自己的项目中去。如果你正亲身 2 目录