《智能系统与技术丛书 :基于浏览器的深度学习 》
智能系统与技术丛书
基于浏览器的深度学习
Deep Learning in the Browser
[ 法 ] 泽维尔·布里(Xavier Bourry)
[ 美 ] 佐佐木凯(Kai Sasaki)
[ 奥地利 ] 克里斯托夫·科纳( Christoph K.rner)
[ 日 ] 中野礼一郎(Reiichiro Nakano) 著
侠 天 易乐天 译
译者序
TensorFlow 已经成为工业界主流的深度学习框架,再加上 Keras 易用性的加持,越来 越多的从业者或者公司开始使用 TensorFlow 实现其深度学习的应用。一直以来缺乏客户端的深度学习框架,而且基于浏览器的 TensorFlow.js 则弥补了这一空白。基于浏览器的TensorFlow.js 可以跨平台、实时地进行推断,深受 JavaScript 开发者的喜爱,在 Github上的 Star 数也增长迅速。
本书是一本介绍 TensorFlow.js 的书,内容主要包括神经网络架构、主流的 JavaScript深度学习框架、深度学习的 JavaScript 基础、基于 WebGL 的 GPU 加速、浏览器上的数据抽取和操作,以及 TensorFlow.js 实践应用。每章都配有完整的代码示例以及可视化效果,轻松易学。书中还详细介绍了 TensorFlow.js 中的重要模块 tfjs-core、tfjs-layers、tfjs-node和 tfjs-converter 等。
本书虽然不难,但是对于新手或者渴望获得知识的读者来说,他们会从这本书学到有用的知识点。
本书大部分是在周末或乘坐高铁时翻译的。 虽然译书可以学到知识,却要消耗更多的时间。但只要在某个时间点某个人读到其中一段文字, 然后拍着桌子说“看了好多种表述,这次终于搞懂了”,我就知足了。
在此,也要感谢家人和朋友的帮助和支持。没有他们的支持完成本书的时间会更长。
其中部分纯前端的内容,由邀请的前端朋友易乐天翻译, 在这里表示感谢。由于水平有限,以及本书涉及知识点众多,难免会出现错误。为了方便读者反馈问题,给出本人公众号:神机喵算。 欢迎大家对本书的翻译纠错,对于发现的问题我一定会虚心接受批评并立即改正,并在公众号更新读者的问题,避免其他读者再入“坑”。
侠 天
前言
“一次编写,处处运行”是开发者们曾经的梦想。如果在所有环境,无论是什么样的机器、操作系统、屏幕分辨率或者计算能力,你都可以执行相同的软件,这个世界该是多么美好啊!这个美好的愿望首先导致了虚拟机的出现:模拟一个标准的计算机以供软件运行,在物理计算机和代码之间增加一个抽象层。因为在不同的架构中虚拟机是相同的,你只需编写和编译一次源代码。Java 虚拟机在 1994 年正式发布,是第一个真正意义上的跨平台虚拟机。
与此同时,万维网还在襁褓中。每个连接的用户能够使用相同的文件格式在网上读取和发布文档。HTML 语言迅速成为网上丰富的文本内容的标准。但它只是描述性的,不能满足网络用户的新需求。在 20 世纪 90 年代末,网络不再是一个共享的存储库:用户希望动态地与内容和其他用户进行交互。基于这个目的,浏览器上的 JavaScript 语言出现了,成为一个图灵机。通过使用 Java applet,Java 虚拟机也可以在浏览器上运行,并且大量使用,因为 JavaScript 功能弱且运行慢,不适合大型应用。
随着时间推移,JavaScript 变得越来越强大。JavaScript 第一次标准化是在 1997 年。在不使用 WebAssembly 或者 ASM.js 的情况下,它的速度增长到了比原生语言慢不到一个数量级的程度。Web 浏览器实现新的 API 提供访问以前预留给编译应用的接口:基于 WebGL 的 GPU、基于 WebRTC 的相机和 P2P 流、基于游戏手柄 API 的游戏机、基于 WebAudio 的音频卡以及基于 WebXR 的 VR 和 AR 设备。JavaScript 甚至发起新的挑战:基于 Node.js 的服务器端应用、基于 Electron 的桌面应用、基于渐进式网页程序(Progressive Web Application)的移动应用,甚至基于 Lisk 的分布式区块链应用。像 Re-act.js 或者 Angular 这样的大型框架和像 Node 包管理器这样的包管理器使得开发大型软件成为可能。JavaScript 势不可当,而它的竞争者 (比如 VBScript、Flash 或者 Silverlight,甚至 Java 虚拟机) 不断从 Web 浏览器中出局。角色发生了逆转:JavaScript 经常通过Webview 组件嵌入 Java 应用。在第一个虚拟机发布大约 25 年之后,“一次编写,处处运行”又怎么样了呢?
当 Web 浏览器使用新的 JavaScript 特征而越来越丰富时,由于作为计算支持的GPU 使用和像 Cuda 或者 OpenCL 这样的 GPU 并行计算库的出现,人工智能神经网络的能力得以释放。它们增加了新的功能,并在许多领域快速发展:自然语言处理、翻译、面部识别、给对象加标签、图片分割和聊天机器人。大型开源深度学习框架,比如Torch、Theano、TensorFlow 和云 GPU 计算的提供,让这种技术走出了实验室。
然而,深度学习的使用大部分仍然在服务器端,而不在客户端。造成这种情况的原因有三个:首先,为了高效地进行深度学习,你需要使用 GPU,而现在即使移动设备的平均 GPU 能力也足够好;其次,神经网络模型一般比较大,只有新移动网络技术 (比如5G) 能够足够快地传输这些数据;第三,你需要用 JavaScript 编写的、易构建的开源框架(比如 TensorFlow.js)运行神经网络模型。技术趋势也从完全的云计算转向边缘计算概念主导的更务实的方法:当用户有免费的强大计算终端时,为什么还要经过网络在昂贵的服务器端处理所有的计算?技术已经到位,所以你将看到许多在浏览器上的深度学习应用,这只是时间问题。
在客户端实现深度学习应用有很大的优势。你可以处理浏览器输入,这些在服务器端不可行,或者具有一些实时的限制 (比如来自麦克风的音频或者来自网络摄像头的视频)。客户端的深度学习使得应用扩展性更好,连接更健壮。软件可以享受 JavaScript 的所有便利:它能用 Node.js 在服务器端测试,使用渐进式网页程序封装的手机应用或者安装为桌面应用。用户可以在不安装任何东西的情况下安全地测试它。
本书是 Web 开发和深度学习的跨界。当这两种技术结合时,它们的“蜜月”将产生让人想象不到的新应用。你准备好开始冒险了吗?本书就是为你而写的:你可以学习到如何使用 JavaScript 的深度学习框架、抓取输入的 Web 编程以及 WebGL 的实现。
在不远的未来,计算机会与我们更密切。在 20 世纪 70 年代,它们远离主流,但是在20 世纪 80 年代桌面计算机出现时,它们开始贴近我们。它们逐渐进入笔记本电脑,最终进入智能手机。增强现实是下一步,为其准备了 Web 标准:WebXR。它使互联网更贴近我们,而且智能应用让我们更好地理解真实的世界。基于浏览器的深度学习当前还处于萌芽阶段,这是在其强大之前关注它的最佳时机。
开心地学习,开心地进行深度学习。
本书示例
本书所有源代码放在 https://github.com/backstopmedia/deep-learning-browser。你可以在 https://reiinakano.github.io/tfjs-rock-paper-scissors/访问石头剪刀布游戏示例,也可以在 https://reiinakano.github.io/tfjs-lstm-text-generation/访问文本生成模型的示例。
关于作者
2 Xavier Bourry 是创业公司 Jeeliz 的联合创始人和 CTO,专注于深度学习。
2 Kai Sasaki 是 Arm 公司的高级软件工程师,还是 Apache Hivemall Committer。
2 Christoph K.orner 在都柏林的微软公司处理 TSP 数据和 AI。
2 Reiichiro Nakano 是 Infostellar 公司的软件开发工程师,专注于机器学习。
目录
译者序
前言
第 1 章 深度学习. . . . . . . . . . . . . . . . . . . . . . .1
1.1 深度神经网络的数学基础 . . . . 1
1.1.1 感知机||门控线性回归 . . . . 2
1.1.2 多层感知机. . . . . . . . . . . . . . . . .5
1.1.3 卷积和池化. . . . . . . . . . . . . . . . .5
1.1.4 激活函数 . . . . . . . . . . . . . . . . . . . 7
1.2 深度神经网络的训练. . . . . . . .11
1.2.1 损失函数的重要性 . . . . . . . . . 12
1.2.2 正则化 . . . . . . . . . . . . . . . . . . . .12
1.2.3 反向传播算法 . . . . . . . . . . . . . 13
1.2.4 优化方法. . . . . . . . . . . . . . . . . .13
1.3 本章小结. . . . . . . . . . . . . . . . . . . .14
第 2 章 神经网络架构. . . . . . . . . . . . . . . . .15
2.1 卷积神经网络 . . . . . . . . . . . . . . . 15
2.1.1 AlexNet . . . . . . . . . . . . . . . . . . 16
2.1.2 GoogLeNet. . . . . . . . . . . . . . . .17
2.1.3 ResNet . . . . . . . . . . . . . . . . . . . 18
2.1.4 SqueezeNet . . . . . . . . . . . . . . . 19
2.2 循环神经网络 . . . . . . . . . . . . . . . 22
2.2.1 LSTM . . . . . . . . . . . . . . . . . . . 23
2.2.2 GRU . . . . . . . . . . . . . . . . . . . . .24
2.3 深度强化学习 . . . . . . . . . . . . . . . 25
2.4 本章小结. . . . . . . . . . . . . . . . . . . .28
第 3 章 JavaScript 深度学习框架 . . . . 29
3.1 TensorFlow.js . . . . . . . . . . . . . . .29
3.1.1 TensorFlow.js 介绍 . . . . . . . . 30
3.1.2 XOR 问题 . . . . . . . . . . . . . . . . 30
3.1.3 解决 XOR 问题 . . . . . . . . . . . 32
3.1.4 网络架构. . . . . . . . . . . . . . . . . .37
3.1.5 张量 . . . . . . . . . . . . . . . . . . . . . . 39
3.1.6 张量操作. . . . . . . . . . . . . . . . . .40
3.1.7 模型训练. . . . . . . . . . . . . . . . . .43
3.1.8 TensorFlow.js 的生态 . . . . . . 46
3.2 WebDNN . . . . . . . . . . . . . . . . . . . 48
3.3 Keras.js . . . . . . . . . . . . . . . . . . . . 51
3.4 本章小结. . . . . . . . . . . . . . . . . . . .52
第 4 章 深度学习的 JavaScript 基础 . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.1 JavaScript 中的TypedArray . . . . . . . . . . . . . . . . 53
4.1.1 ArrayBu.er . . . . . . . . . . . . . . 55
4.1.2 DataView . . . . . . . . . . . . . . . . 56
4.2 JavaScript 中的并发 . . . . . . . . 58
4.2.1 JavaScript 的事件循环 . . . . . 58
4.2.2 用 Promise 创建一个异步函数 . . . . . . . . . . . . . . . . . .59
4.2.3 使用新的async/await语法 . . . . . . . . . . . . . . . . . . . . . . 61
4.2.4 多线程使用 WebWorker . . . 64
4.2.5 深度学习应用程序的处理循环 . . . . . . . . . . . . . . . . . .66
4.3 在 CPU/GPU 上加载资源 . . . . . . . . . . . . . . . . . . . . . . . . 66
4.3.1 Fetch API . . . . . . . . . . . . . . . . 67
4.3.2 标签编码. . . . . . . . . . . . . . . . . .69
4.3.3 one-hot 编码 . . . . . . . . . . . . . . 69
4.4 本章小结. . . . . . . . . . . . . . . . . . . .70
第 5 章 基于 WebGL 的 GPU加速 . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.1 WebGL 基础 . . . . . . . . . . . . . . . . 74
5.1.1 WebGL 工作流程 . . . . . . . . . . 76
5.1.2 片段着色器渲染 . . . . . . . . . . . 78
5.2 WebGL 实现常规计算 . . . . . . 85
5.2.1 调试 WebGL . . . . . . . . . . . . . 86
5.2.2 渲染纹理. . . . . . . . . . . . . . . . . .87
5.2.3 精度重要性. . . . . . . . . . . . . . . .92
5.2.4 优化器 . . . . . . . . . . . . . . . . . . . .94
5.2.5 GLSL 开发. . . . . . . . . . . . . . . .95
5.2.6 浮点型的特殊性 . . . . . . . . . . . 95
5.2.7 从 CPU 流向 GPU,反之亦然 . . . . . . . . . . . . . . . . . .99
5.3 使用纹理和着色器的矩阵计算 . . . . . . . . . . . . . . . . . . 101
5.3.1 标准的矩阵加法 . . . . . . . . . . 101
5.3.2 标准的矩阵乘法 . . . . . . . . . . 102
5.3.3 激活函数应用 . . . . . . . . . . . . 103
5.3.4 运用WGLMatrix库 . . . . . . . . . 104
5.4 手写数字识别应用 . . . . . . . . . 105
5.4.1 数据编码 . . . . . . . . . . . . . . . . 105
5.4.2 内存优化 . . . . . . . . . . . . . . . . 105
5.4.3 前向传播 . . . . . . . . . . . . . . . . 107
5.4.4 第一次尝试 . . . . . . . . . . . . . . 107
5.4.5 优化性能 . . . . . . . . . . . . . . . . 108
5.5 本章小结 . . . . . . . . . . . . . . . . . . 109
第 6 章 从浏览器中提取数据 . . . . . . . . 111
6.1 加载图像数据. . . . . . . . . . . . . .112
6.1.1 从图像中提取像素 . . . . . . . . 112
6.1.2 加载远程资源 . . . . . . . . . . . . 114
6.1.3 获取二进制块 . . . . . . . . . . . . 116
6.2 将像素数据渲染到屏幕上 . . 117
6.2.1 显示图片 . . . . . . . . . . . . . . . . 118
6.2.2 将像素数据渲染到画布 . . . . 119
6.2.3 插值图像数据 . . . . . . . . . . . . 122
6.2.4 在画布上绘制形状 . . . . . . . . 124
6.3 访问相机、麦克风和扬声器. . . . . . . . . . . . . . . . . . . . .126
6.3.1 从网络摄像头捕获图像 . . . . 126
6.3.2 用麦克风录音 . . . . . . . . . . . . 128
6.3.3 加载、解码和播放声音 . . . . 130
6.4 深度学习框架中的实用工具. . . . . . . . . . . . . . . . . . .131
6.4.1 TensorFlow.js . . . . . . . . . . . 131
6.4.2 Keras.js . . . . . . . . . . . . . . . . . 133
6.4.3 WebDNN . . . . . . . . . . . . . . . 133
6.5 本章小结 . . . . . . . . . . . . . . . . . . 135
第 7 章 高级数据操作的方法 . . . . . . . . 137
7.1 反序列化 Protobuf . . . . . . . . 138
7.1.1 解析 Caffe 模型参数 . . . . . . 139
7.1.2 解析 TensorFlow 图. . . . . . .141
7.1.3 浮点精度的注意事项 . . . . . . 142
7.2 用 Chart.js 绘制图表. . . . . . .143
7.2.1 探索不同的图表类型 . . . . . . 144
7.2.2 配置数据集 . . . . . . . . . . . . . . 146
7.2.3 更新值. . . . . . . . . . . . . . . . . . .147
7.2.4 选项和配置概述 . . . . . . . . . . 150
7.3 用画布画草图. . . . . . . . . . . . . .153
7.3.1 在画布上绘图 . . . . . . . . . . . . 154
7.3.2 提取笔画 . . . . . . . . . . . . . . . . 158
7.4 从麦克风计算频谱图. . . . . . .159
7.5 人脸检测与跟踪 . . . . . . . . . . . 162
7.5.1 用 Jeeliz FaceFilter跟踪人脸. . . . . . . . . . . . . . . . .162
7.5.2 使用 tracking.js 跟踪人脸 . . . . . . . . . . . . . . . . . . . . . 163
7.5.3 Chrome 中人脸检测的原生支持. . . . . . . . . . . . . . . . .165
7.6 本章小结 . . . . . . . . . . . . . . . . . . 167
第 8 章 基于 TensorFlow.js构建应用 . . . . . . . . . . . . . . . . . . . . 169
8.1 TensorFlow.js 实现手势识别. . . . . . . . . . . . . . . . . . .169
8.1.1 算法解说 . . . . . . . . . . . . . . . . 170
8.1.2 TensorFlow.js 项目准备 . . . 171
8.1.3 实例化 KNN 图像分类器 . . . . . . . . . . . . . . . . . . . . . 172
8.1.4 TensorFlow.js 迭代训练 . . . 173
8.1.5 小结. . . . . . . . . . . . . . . . . . . . .176
8.2 TensorFlow.js 实现文本生成 . . . . . . . . . . . . . . . . . . . . . . . 176
8.2.1 算法解说 . . . . . . . . . . . . . . . . 176
8.2.2 Keras 模型 . . . . . . . . . . . . . . .177
8.2.3 将 Keras 模型转换为TensorFlow.js 模型 . . . . . . . 178
8.2.4 项目准备 . . . . . . . . . . . . . . . . 178
8.2.5 在 TensorFlow.js 中导入Keras 模型 . . . . . . . . . . . . . . 179
8.2.6 TensorFlow.js 迭代训练 . . . 179
8.2.7 构造模型输入 . . . . . . . . . . . . 181
8.2.8 模型预测 . . . . . . . . . . . . . . . . 183
8.2.9 模型输出抽样 . . . . . . . . . . . . 184
8.2.10 小结. . . . . . . . . . . . . . . . . . . .186
8.3 TensorFlow.js 实现图像降噪. . . . . . . . . . . . . . . . . . .186
8.3.1 算法解说 . . . . . . . . . . . . . . . . 187
8.3.2 将 Keras 模型转换为TensorFlow.js 模型 . . . . . . . 188
8.3.3 项目准备 . . . . . . . . . . . . . . . . 189
8.3.4 初始化. . . . . . . . . . . . . . . . . . .190
8.3.5 应用流程 . . . . . . . . . . . . . . . . 190
8.3.6 加载测试数字图片 . . . . . . . . 191
8.3.7 更新噪声 . . . . . . . . . . . . . . . . 193
8.3.8 生成变形图片 . . . . . . . . . . . . 194
8.3.9 图片降噪 . . . . . . . . . . . . . . . . 195
8.3.10 初始化函数 . . . . . . . . . . . . . 196
8.3.11 小结. . . . . . . . . . . . . . . . . . . .197
8.4 本章小结 . . . . . . . . . . . . . . . . . . 197
8.5 最后结论 . . . . . . . . . . . . . . . . . . 198
- 点赞
- 收藏
- 关注作者
评论(0)