TensorFlow2 神经网络应用指南(一)
一、简介
在本书中,我们深入到深度学习(DL)的领域,并涵盖了几个深度学习概念以及几个案例研究。这些案例研究的范围从图像识别到推荐系统,从艺术生成到对象聚类。深度学习是更广泛的机器学习(ML)方法家族的一部分,基于具有表示学习的人工神经网络(ann)。这些神经网络模仿人类的脑细胞,或神经元,进行算法学习,它们的学习速度比人类的学习速度快得多。几种深度学习方法为不同类型的机器学习问题提供了解决方案:(I)监督学习,(ii)非监督学习,(iii)半监督学习,以及(iv)强化学习。
这本书的结构也包括机器学习学科的介绍,这样读者可以熟悉机器学习的一般规则和概念。然后,提供深度学习的详细介绍,让读者熟悉深度学习的子学科。
在涵盖了深度学习的基础知识之后,这本书涵盖了不同类型的人工神经网络及其潜在的现实生活应用(即案例研究)。因此,在每一章,这本书(I)介绍了一个特定的神经网络结构的概念,并详细介绍了它的组成部分,然后(ii)提供了一个如何应用这种网络结构来解决一个特定的人工智能(AI)问题的教程。
由于本书的目标是为深度学习应用程序提供案例研究,因此寻求几种技术和库的能力以获得满意的学习体验。
在深入机器学习和深度学习之前,我们先介绍一下本书中使用的技术。这个介绍包括最新的发展和为什么选择这些技术的理由。最后,本章还介绍了如何安装这些技术,并以最少的麻烦为您的环境做准备。本书的核心技术如下:
-
我们选择的编程语言: Python 3.x
-
我们选择的深度学习框架: TensorFlow 2.x
-
我们的开发环境: Google Colab ( 用 Jupyter 笔记本替代)
Note
显示如何使用 TensorFlow 的 TensorFlow 流水线指南可在第五章中找到,而与 TensorFlow 一起使用的相关库在第四章中介绍。
请注意,本书假设您使用 Google Colab,这几乎不需要环境设置。如果您喜欢本地环境,本章还包括本地 Jupyter 笔记本安装指南。如果你决定使用 Google Colab,你可以跳过 Jupyter 笔记本安装部分。
Note
当学习一门新的编程学科或技术时,最令人沮丧的任务之一是环境设置过程。因此,尽可能简化这一过程非常重要。因此,本章的设计考虑到了这一原则。
Python 作为编程语言
Python 是一种编程语言,由吉多·范·罗苏姆作为附带项目创建,最初发布于 1991 年。Python 支持面向对象编程(OOP),这是一种基于对象概念的范式,可以包含字段形式的数据。Python 优先考虑程序员的体验。因此,程序员可以为小型和大型项目编写清晰的逻辑代码。它还包含对函数式编程的支持。Python 是动态类型化的,是垃圾回收的。
Python 也被认为是一种解释语言,因为它通过一个解释器,将你写的代码转换成你的计算机处理器可以理解的语言。解释器“一条一条”地执行代码语句。另一方面,在编译语言中,编译器完全执行代码并一次列出所有可能的错误。就速度和性能而言,编译的代码比解释的代码更有效。然而,脚本语言(如 Python)只显示一条错误消息,即使您的代码有多个错误。这个特性可以帮助程序员快速清除错误,提高开发速度。
Python 的时间轴
我们来看看 Python 的时间轴:
-
在 20 世纪 80 年代末,Python 被认为是 ABC 语言的继承者。
-
1989 年 12 月,吉多·范·罗苏姆开始实施 Python。
-
1994 年 1 月,Python 版发布。包括的主要新特性是函数式编程工具 lambda、map、filter 和 reduce。
-
2000 年 10 月,Python 2.0 发布了主要的新特性,包括循环检测垃圾收集器和对 Unicode 的支持。
-
Python 3.0 于 2008 年 12 月 3 日发布。这是该语言的一个主要修订版,只是部分向后兼容。它的许多主要特性被移植到 Python 2.6.x 和 2.7.x 版本系列。Python 3 的发行版包括 2 到 3 实用程序,它自动(至少部分地)将 Python 2 代码翻译成 Python 3。
-
截至 2020 年 1 月 1 日,Python 2 没有新的 bug 报告、修复或更改,不再支持Python 2。
Python 2 对 Python 3
一个新的深度学习程序员可能会有一个常见的问题,就是使用 Python 2.x 还是 Python 3.x,因为有许多过时的博客帖子和网络文章比较两个主要版本。截至 2020 年,可以肯定地说,这些比较是不相关的。正如您在前面的时间表中看到的,Python 2.x 的延迟弃用最终发生在 2020 年 1 月 1 日。因此,程序员可能再也找不到对 Python 2.x 版本的官方支持了。
程序员的一项基本技能是掌握最新技术,因此,本书仅使用 Python 3.x 版本。对于只熟悉 Python 2.x 版本的读者来说,这种偏好应该不会造成问题,因为本书中针对 Python 2.x 和 Python 3.x 使用的语法之间的差异并不明显。因此,Python 2.x 程序员可能会立即熟悉本书中的源代码。
为什么是 Python?
与其他编程语言相比,Python 在数据科学家和机器学习工程师中受欢迎有几个原因。2019 年 Kaggle 机器学习和数据科学调查显示,Python 是迄今为止最受数据科学和机器学习欢迎的编程语言;见图 1-1 。
图 1-1
2019 年 Kaggle 机器学习和数据科学调查
与其他语言相比,Python 受欢迎有几个原因。下面是 Python 的一个非详尽的优点列表。
易于学习
新手选择 Python 作为主要编程语言的主要原因之一是它的易学性。与其他编程语言相比,Python 提供了更短的学习曲线,因此程序员可以在短时间内达到良好的能力水平。与其他流行的编程语言相比,Python 的语法更容易学习,代码可读性更好。显示这一点的一个常见例子是不同编程语言打印“Hello,World!”所需的代码量。例如,能够打印出 Hello,World!在 Java 中,您需要以下代码:
你好,世界!在 Java 中
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
使用 Python 中的一行代码也可以获得相同的结果:
Hello, World! in Python
print("Hello, World!")
各种可用的数据科学库
与其他编程语言相比,Python 的另一个强大特性是它的各种各样的数据科学库。Pandas、NumPy、SciPy 和 scikit-learn 等数据科学库通过其标准化的函数和逻辑与数学运算模块,减少了为模型训练准备数据的时间。此外,由于 Python 开发人员的活跃社区,一旦开发人员检测到一个常见问题,就会立即设计并发布一个新的库来解决这个问题。
社区支持
强大的社区支持是 Python 相对于其他编程语言的另一个优势。越来越多的志愿者正在发布 Python 库,这种实践使 Python 成为具有现代和强大库的语言。此外,大量经验丰富的 Python 程序员随时准备帮助其他程序员解决在线社区渠道上的问题,如堆栈溢出。
可视化选项
数据可视化是从原始数据中提取洞察力的重要学科,Python 提供了几个有用的可视化选项。优秀的 Matplotlib 总是有最可定制的选项。此外,Seaborn 和 Pandas Plot API 是强大的库,可以简化数据科学家使用的最常见的可视化任务。此外,Plotly 和 Dash 等库允许用户创建交互式绘图和复杂的仪表板,并在 Web 上提供服务。有了这些库,数据科学家可以轻松地创建图表,绘制图形,并促进特征提取。
既然我们讨论了为什么数据科学家最喜欢的语言是 Python,我们可以继续讨论为什么我们使用 TensorFlow 作为我们的机器学习框架。
TensorFlow 作为深度学习框架
TensorFlow 是一个开源的机器学习平台,特别关注神经网络,由谷歌大脑团队开发。尽管最初用于内部目的,但谷歌在 2015 年 11 月发布了 Apache License 2.0 下的库,这使其成为一个开源库。 1 虽然 TensorFlow 的用例并不局限于机器学习应用,但是机器学习才是我们看到 TensorFlow 实力的领域。
具有稳定和官方 TensorFlow APIs 的两种编程语言是 Python 和 C。此外,C++、Java、JavaScript、Go 和 Swift 是开发人员可能会发现有限到广泛 TensorFlow 兼容性的其他编程语言。最后,还有 C#、Haskell、Julia、MATLAB、R、Scala、Rust、OCaml、Crystal 的第三方 TensorFlow APIs。
TensorFlow 时间线
虽然这本书重点介绍了使用 Python API 的 TensorFlow 2.x,但是 Google 也发布了几个补充的 TensorFlow 库。了解 TensorFlow 平台的发展对于了解全貌至关重要。作为 TensorFlow 项目的一部分,Google 实现的里程碑的时间表可以总结如下:
-
2011 年,Google Brain 使用深度学习神经网络构建了一个名为 DistBelief 的机器学习系统。
-
2015 年 11 月,谷歌在 Apache License 2.0 下发布了 TensorFlow 库,并将其开源,以加速人工智能的进步。
-
2016 年 5 月,谷歌公布了一款为机器学习打造、为 TensorFlow 量身定制的专用集成电路(ASIC),名为张量处理单元(TPU) 。
-
2017 年 2 月,谷歌发布了 TensorFlow 1.0.0 。
-
2017 年 5 月,谷歌宣布 TensorFlow Lite **,**一个用于移动设备中机器学习开发的库。
-
2017 年 12 月,谷歌推出了 Kubeflow ,允许在 Kubernetes 上运行和部署 TensorFlow。
-
2018 年 3 月,谷歌公布了用 JavaScript 进行机器学习的tensor flow . js1.0 版本。
-
2018 年 7 月,谷歌公布了 Edge TPU 。Edge TPU 是谷歌专门打造的 ASIC 芯片,旨在智能手机上运行 TensorFlow Lite 机器学习(ML)模型。
-
2019 年 1 月,谷歌宣布 TensorFlow 2.0 将于 2019 年 9 月正式上市。
-
2019 年 5 月,谷歌公布了用于计算机图形学深度学习的 TensorFlow Graphics 。
-
2019 年 9 月,TensorFlow 团队发布了 TensorFlow 2.0 ,库的新主要版本。
这个时间线表明 TensorFlow 平台正在走向成熟。特别是随着 TensorFlow 2.0 的发布,Google 显著提高了 TensorFlow APIs 的用户友好性。此外,TensorFlow 团队宣布,他们不打算引入任何其他重大变化。因此,可以有把握地假设,本书中包含的方法和语法将长期保持其相关性。
为什么选择 TensorFlow?
由科技巨头、科技基金会和学术机构开发的二十多个深度学习库对公众开放。虽然每个框架在深度学习的特定子学科中都有其优势,但这本书主要关注带有 Keras API 的 TensorFlow。选择 TensorFlow 而不是其他深度学习框架的主要原因是它的受欢迎程度。另一方面,这种说法并不意味着其他框架比 TensorFlow 更好–,也没有 tensor flow 受欢迎–。特别是随着 2.0 版本的推出,TensorFlow 通过解决深度学习社区提出的问题加强了自己的力量。今天,TensorFlow 可能被视为最受欢迎的深度学习框架,它非常强大且易于使用,并具有出色的社区支持。
TensorFlow 2.x 中的新增功能
自 2015 年推出以来,TensorFlow 已经发展成为市场上最先进的机器学习平台之一。研究人员、开发人员和公司广泛采用了 TensorFlow 团队引入的技术。2019 年 9 月,TensorFlow 2.0 在 4 岁生日前后发布。TensorFlow 团队通过清理废弃的 API 和减少重复来简化 API。TensorFlow 团队引入了几项更新,以实现 TensorFlow 2.0 的简单易用。这些更新可能如下所列:
-
使用 Keras 和热切的执行轻松构建模型
-
在任何平台上的生产级别中实现强大的模型部署
-
强大的研究实验
-
由于清理和减少重复,简化了 API
使用 Keras 和热切的执行轻松构建模型
TensorFlow 团队进一步简化了模型构建体验,通过新的或改进的模块(如tf.data、tf.keras、tf.estimators和Distribution Strategy API)来响应预期。
使用 tf.data 加载数据
在 TensorFlow 2.0 中,使用通过tf.data模块创建的输入流水线读取训练数据。tf.feature_column模块用于定义特征特性。对新来者有用的是新的数据集模块。TensorFlow 2.0 提供了一个单独的数据集模块,该模块提供了一系列流行的数据集,并允许开发人员试验这些数据集。
使用 tf.keras 构建、训练和验证您的模型,或者使用预制的估计器
在 TensorFlow 1.x 中,开发人员可以使用之前版本的tf.contrib、tf.layers、tf.keras和tf.estimators来构建模型。为同一个问题提供四种不同的选择让新来者感到困惑,并赶走了其中一些人,尤其是 PyTorch。TensorFlow 2.0 通过将选项限制为两个改进的模块来简化模型构建:tf.keras (TensorFlow Keras API)和tf.estimators (Estimator API)。TensorFlow Keras API 提供了一个高级接口,使模型构建变得简单,这对于概念验证(POC) 尤其有用。另一方面,Estimator API 更适合需要扩展服务和增加定制能力的生产级模型。
以急切的执行方式运行和调试,然后使用 AutoGraph API 获得图形的好处
TensorFlow 1.x 版本对 TensorFlow 图进行了优先排序,这对新来者并不友好。尽管 TensorFlow 2.0 保留了这种复杂的方法,但急切执行–对比概念–被默认。谷歌用以下声明解释了这一变化的最初原因:
急切执行是一个命令性的、由运行定义的接口,当从 Python 中调用操作时,立即执行操作。这样更容易上手 TensorFlow,可以让研发更直观。 2
热切的执行使模型建立更容易。它提供了快速调试功能,可以立即处理运行时错误,并与 Python 工具集成,这使得 TensorFlow 对初学者更加友好。另一方面,图执行对于分布式培训、性能优化和生产部署具有优势。为了填补这一空白,TensorFlow 引入了名为 via tf.function decorator 的 AutoGraph API。这本书将急切执行优先于图形执行,为读者提供了一个陡峭的学习曲线。
使用分布式策略进行分布式培训
使用大型数据集的模型训练需要使用多个处理器(如 CPU、GPU 或 TPU)进行分布式训练。尽管 TensorFlow 1.x 支持分布式训练,但分布式策略 API 优化并简化了跨多个 GPU、多台机器或 TPU 的分布式训练。TensorFlow 还提供了在本地或云环境中的 Kubernetes 集群上部署培训的模板,这使得培训更具成本效益。
导出到保存模型
训练模型后,开发人员可以导出到 SavedModel。API 可用于构建一个完整的带权重和计算的 TensorFlow 程序。这种标准化的 SavedModel 可以在不同的 TensorFlow 部署库中互换使用,例如(i) TensorFlow Serving,(ii) TensorFlow Lite,(iii) TensorFlow.js,以及(iv) TensorFlow Hub。
在任何平台上的生产中实现强大的模型部署
TensorFlow 一直致力于在不同设备上提供直接的生产路径。已经有几个库可以用来在专用环境中为训练好的模型提供服务。
TensorFlow 服务
TensorFlow Serving 是一个灵活的高性能 TensorFlow 库,允许通过 HTTP/REST 或 gRPC/协议缓冲区为模型提供服务。这个平台是平台和语言中立的,因为您可以使用任何编程语言进行 HTTP 调用。
TensorFlow Lite
TensorFlow Lite 是一个轻量级深度学习框架,用于将模型部署到移动设备(iOS 和 Android)或嵌入式设备(Raspberry Pi 或 Edge TPUs)。开发人员可能会选择一个经过训练的模型,将该模型转换为压缩的 fat 缓冲区,并使用 TensorFlow Lite 部署到移动或嵌入式设备上。
TensorFlow.js
TensorFlow.js 使开发人员能够将其模型部署到 web 浏览器或 Node.js 环境中。开发人员还可以使用类似 Keras 的 API 在浏览器中用 JavaScript 构建和训练模型。
在 TensorFlow 2.0 中,通过标准化的交换格式和一致的 API,跨平台和组件的能力和奇偶校验得到了极大的提高。TensorFlow 团队在图 1-2 中展示了 TensorFlow 2.0 新的简化架构。
图 1-2
TensorFlow 2.0 架构的简化图 3
改善研究人员的实验体验
研究人员通常需要一个易于使用的工具来将他们的研究想法从概念转化为代码。一个概念的证明可能只有在几次迭代之后才能实现,而这个概念可能在几次实验之后才能发表。TensorFlow 2.0 旨在让这一过程更容易实现。Keras Functional API –与模型子类 API –配合使用,提供了构建复杂模型的足够能力。tf.GradientTape和tf.custom_gradient是生成自定义训练逻辑的关键。
任何机器学习项目都始于概念证明(POC)。开发人员需要采用敏捷的方法,并使用易于使用的工具来将新想法从概念转化为有证据支持的出版物。最后,TensorFlow 2.0 提供了强大的扩展,如参差张量、TensorFlow Probability 和 Tensor2Tensor,以确保灵活性和增强的实验能力。
TensorFlow 竞争对手
尽管这本书使用 TensorFlow 作为主要的深度学习框架,但对竞争的深度学习框架和库进行简要介绍是必不可少的。虽然深度学习框架的总数超过 20 个,但其中许多框架目前都不是由其设计者维护的。因此,我们只能谈一谈极少数积极可靠的深度学习框架,涵盖如下。
硬
Keras 是一个用 Python 编写的开源神经网络库,可以运行在 TensorFlow、微软认知工具包(CNTK)、Theano、R 和 PlaidML 之上。谷歌工程师弗朗索瓦·乔莱(Franç ois Chollet)设计了 Keras,以实现神经网络的快速实验。它非常用户友好,模块化,可扩展。Keras 还以简单、灵活和强大而自豪。由于这些特性,Keras 被新人视为首选的深度学习库。
Keras 应该被视为 TensorFlow 的补充选项,而不是竞争对手的库,因为它依赖于现有的深度学习框架。2017 年,谷歌的 TensorFlow 团队同意在其核心库中支持 Keras。有了 TensorFlow 2.0,Keras API 变得更加精简和集成。这本书利用了 TensorFlow Keras API,这使得创建神经网络变得容易得多。
Keras 官网: www.keras.io
PyTorch
PyTorch 是一个开源神经网络库,主要由脸书的人工智能研究实验室(FAIR)开发和维护,最初于 2016 年 10 月发布。FAIR 在 Torch library 的基础上构建了 PyTorch,这是另一个开源机器学习库,一个科学计算框架,以及一个基于 Lua 编程语言的脚本语言,最初由 Ronan Collobert,Samy Bengio 和 Johnny Mariéthoz 设计。
由于 PyTorch 是由脸书开发的,并提供了一个易于使用的界面,它的流行程度在最近几年有所增加,特别是在学术界。PyTorch 是 TensorFlow 的主要竞争对手。在 TensorFlow 2.0 之前,尽管其 API 的易用性存在问题,但由于其社区支持、生产性能和额外的用例解决方案,TensorFlow 一直保持着流行。此外,TensorFlow 2.0 的最新改进引入了对 TensorFlow 1.x 缺点的补救措施。因此,尽管 PyTorch 越来越受欢迎,TensorFlow 很可能会保持其地位。
PyTorch 官网: www.pytorch.org
Apache MXNet
MXNet 是 Apache 基金会推出的开源深度学习框架。这是一个灵活、可扩展、快速的深度学习框架。它支持多种编程语言(包括 C++、Python、Java、Julia、MATLAB、JavaScript、Go、R、Scala、Perl 和 Wolfram 语言)。
MXNet 由亚马逊、英特尔、百度、微软、Wolfram Research、卡内基梅隆大学、麻省理工学院和华盛顿大学使用和支持。虽然一些受尊敬的机构和技术公司支持 MXNet,但 MXNet 的社区支持是有限的。因此,与 TensorFlow、Keras 和 PyTorch 相比,它仍然不太受欢迎。
MXNet 官网:mxnet.apache.org
微软认知工具包
微软于 2016 年 1 月发布了作为其开源深度学习框架的 CNTK。CNTK 也称为微软认知工具包,支持 Python、C++、C#和 Java 等流行编程语言。微软在其流行的应用程序和产品(如 Skype、Xbox 和 Cortana)中使用了 CNTK,特别是在语音、手写和图像识别方面。然而,截至 2019 年 1 月,微软停止发布微软认知工具包的新更新。因此,CNTK 被认为是不推荐使用的。
微软认知工具包官网: www.cntk.ai
最终评估
上述深度学习框架的设计者和维护者明显显示了深度学习框架开发的转变。深度学习最初是大学里的一个学术研究领域,很少甚至没有现实生活中的应用。然而,随着计算能力的提高、处理成本的降低以及互联网的兴起,这种情况已经发生了变化。越来越多的深度学习应用的现实生活用例一直在满足大型科技公司的胃口。Torch、Caffe 和 Theano 等早期的学术项目为 TensorFlow、Keras 和 PyTorch 等深度学习库的开发铺平了道路。谷歌、亚马逊和脸书等行业参与者已经为他们自己的开源深度学习框架雇佣了这些早期项目的维护者。因此,对早期项目的支持非常有限,而新一代框架变得越来越强大。
截至 2020 年,可以肯定地说,TensorFlow 和 PyTorch 之间正在进行真正的竞争。由于其成熟性、对多种编程语言的广泛支持、在就业市场中的受欢迎程度、广泛的社区支持和支持技术,TensorFlow 占据了上风。2018 年,Jeff Hale 为市场上的深度学习框架开发了一个权力排名。他权衡了在网上工作列表、相关文章和博客帖子以及 GitHub 上发现的提及。他的结果也支持前面的评估;参见图 1-3 。
图 1-3
深度学习框架 Power Scores 2018 作者杰夫·黑尔 4
因此,由于其技术进步和在技术社区中的受欢迎程度,TensorFlow 是本书中使用的单一深度学习框架。在下一节中,我们将了解 TensorFlow 2.0 引入的新功能。
最终考虑
提供 PyTorch 等易用模块的竞争对手库越来越受欢迎,这表明 TensorFlow 1.x 没有走上正轨。Keras library 的兴起(其唯一目的是促进 TensorFlow –以及其他一些–的使用)是另一个迹象,表明 TensorFlow 必须简化其工作流程以保持其现有的用户群。TensorFlow 2.0 的引入是为了缓解这个问题,看起来大多数批评都是通过新引入的 API 和改进的现有 API 来解决的。
安装和环境设置
既然我们解决了为什么 TensorFlow 是本书选择的深度学习框架,为什么 Python 是选择的编程语言的问题,那么是时候为深度学习建立一个编程环境了。
机器学习任务需要持续的测试和概念验证工作。传统的 Python 运行环境可能会阻碍测试的速度。因此,开发人员通常求助于交互式运行环境来进行数据清理、模型构建和训练。使用交互式环境有几个优点:
-
在交互式运行环境中,开发人员可以运行部分代码,而输出仍然保存在内存中。
-
代码的下一部分可能仍然使用代码的前一部分的输出。
-
代码的一部分中出现的错误可能会被修复,而代码的其余部分可能仍会运行。
-
一个大的代码文件可能被分成几个部分,这使得调试变得非常简单。
我们几乎可以说,使用交互式编程环境已经成为深度学习研究的行业标准。因此,对于贯穿本书的深度学习项目,我们也将遵循这种做法。
对于 Python TensorFlow 程序员来说,在交互式编程环境中构建和训练模型有几种可行的选择。然而,我们将深入探讨为用户提供不同好处的最受欢迎的选项:(i) Jupyter Notebook 和(ii) Google Colab 。
交互式编程环境:IPython、Jupyter Notebook 和 Google Colab
Python 交互式编程环境中使用了多种工具。使交互成为可能的核心技术是 IPython。IPython 是 Python 的一个改进的 shell 和 read–eval–print 循环(REPL)。“IPython Notebook”是使用 IPython 开发的产品,可通过网络浏览器作为“笔记本”访问。IPython 处理两个基本角色:
-
作为 REPL 的终端 IPython
-
IPython 内核,提供计算和与前端接口(如 IPython Notebook)的通信
开发人员可以编写代码,做笔记,并将媒体上传到他们的 IPython 笔记本上。IPython Notebook 项目的发展导致了 Project Jupyter 的创建,它包含了 Notebook 工具和其他用于多种语言(Julia、Python 和 R)的交互式工具。Jupyter Notebook 及其灵活的界面将笔记本从代码扩展到可视化、多媒体、协作和许多其他功能,为数据科学家和机器学习专家创造了一个舒适的环境。
如果你想让你的开发体验更上一层楼,谷歌云,这是一个基于云的 Jupyter 笔记本环境,是一个终极工具。此外,Google Colab 还提供协作选项、使用 Google 的计算能力和基于云的托管功能。IPython、Jupyter Notebook、Google Colab 之间的关系如图 1-4 所示。
图 1-4
IPython、Jupyter Notebook 和 Google Colab 之间的关系
在接下来的部分,我们将深入 IPython、Jupyter Notebook 和 Google Colab 的细节。我们还将(I)安装带有 Anaconda 发行版的 Jupyter 笔记本,以及(ii)安装 Google Colab。
伊普提洪伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁伊普提翁
IPython 是一个命令外壳和一个内核,它支持交互式 Python 笔记本。IPython 允许程序员在笔记本环境中快速运行他们的代码。IPython 提供了几个特性:
-
交互式外壳(终端和 Qt 控制台)
-
基于 web 的笔记本界面,支持代码、文本和媒体
-
支持交互式数据可视化和 GUI 工具包
-
灵活和可嵌入的解释器加载到项目中
-
并行计算工具包
IPython 项目已经超越了运行 Python 脚本的范畴,正在成为一个语言无关的工具。从 IPython 4.0 开始,与语言无关的部分被收集在一个新项目下,名为 Project Jupyter。Jupyter 这个名字是对 Jupyter 支持的核心编程语言的引用,这些语言是 Julia、Python 和 r。截至这个分拆决定的实施,IPython 现在只专注于交互式 Python,Jupyter 专注于笔记本格式、消息协议、QT 控制台和笔记本 web 应用程序等工具。
Jupyter 笔记型电脑
Project Jupyter 是 2014 年脱胎于 IPython 项目的一个分拆开源项目。Jupyter 永远免费供所有人使用,它是通过 Jupyter 社区的共识开发的。作为 Jupyter 项目的一部分,发布了几个有用的工具,如 Jupyter Notebook、JupyterLab、Jupyter Hub 和 Voilà。虽然所有这些工具可以同时用于附带目的,但安装 Jupyter Notebook 足以满足本书的环境要求。
另一方面,作为一个开源项目,Jupyter 工具可以集成到不同的工具集和捆绑包中。我们将使用 Anaconda 发行版在本地机器上安装环境,而不是通过终端(对于 macOS 和 Linux)或命令提示符(对于 Windows)安装 Jupyter Notebook。
蟒蛇分布
Anaconda 是用于科学计算的 Python 和 R 编程语言的免费开源发行版,旨在简化包的管理和部署
环境设置是编程的繁琐任务之一。开发人员经常遇到独特的问题,主要是由于他们的操作系统及其版本。使用 Anaconda 发行版,可以轻松安装 Jupyter Notebook 和其他有用的数据科学库。
在 Windows 上安装
- 选择 Python 3.x 的 64 位图形安装程序,在
www.anaconda.com/products/individual下载 Anaconda 安装程序;见图 1-5 。
图 1-5
Anaconda 安装程式页面
图 1-6
Windows 操作系统的 Anaconda 安装窗口
-
双击安装程序启动。
-
单击“下一步”按钮。
-
阅读许可协议,然后单击“我同意”
-
为“仅我”选择一个安装,然后单击“下一步”按钮。
-
选择安装 Anaconda 的目标文件夹,然后单击“下一步”按钮(确保您的目标路径不包含空格或 Unicode 字符)。
-
确保(I)“将 Anaconda3 添加到您的路径环境变量”选项未选中,并且(ii)“将 Anaconda3 注册为我的默认 Python 3.x”选项已选中,如图 1-6 所示。
-
单击“安装”按钮,等待安装完成。
-
单击“下一步”按钮。
-
单击“下一步”按钮跳过安装 PyCharm IDE。
-
成功安装后,您将看到“感谢您安装 Anaconda 个人版”消息。单击“完成”按钮。
-
你现在可以在开始菜单中找到“巨蟒导航”应用程序来打开 Jupyter 笔记本。只需打开应用程序,点击 Jupyter 笔记本卡中的“启动”按钮。这一步将在本地主机上提示一个 web 浏览器:8888。
在 Mac 上安装
- 选择 Python 3.x 的 64 位图形安装程序,在
www.anaconda.com/products/individual下载 Anaconda 安装程序;见图 1-7 。
图 1-7
Anaconda 安装程式页面
-
双击下载的文件,然后单击“继续”按钮开始安装。
-
单击简介、自述文件和许可证屏幕上的“继续”按钮。
-
单击提示窗口上的“同意”按钮,同意软件许可协议的条款。
-
确保在目的地选择屏幕中选择了“仅为我安装”选项,然后单击“继续”按钮。
-
单击 Install 按钮安装 Anaconda,并等待安装完成。
-
单击“继续”按钮跳过 PyCharm IDE 的安装。
图 1-9
创建新的 Jupyter 笔记本
-
Click the “Close” button, as shown in Figure 1-8, to close the installer.
图 1-8
macOS 的 Anaconda 安装窗口
-
你现在可以打开 Jupyter 笔记本,在你的 Launchpad 下找到“Anaconda-Navigator”应用程序。只需打开应用程序,点击 Jupyter 笔记本卡中的“启动”按钮。这一步将提示本地主机上的终端和 web 浏览器:8888。
-
点击新建➤ Python3 可以新建一个 IPython 笔记本,如图 1-9 所示。
Jupyter Notebook 附带了重要的数据科学库,如 Pandas、NumPy 和 Matplotlib。但是,如果你决定使用 Jupyter 笔记本进行深度学习,还是要安装 TensorFlow。TensorFlow 的安装可以用 Python 的“pip”包管理器来实现,因为我们已经用 Anaconda 发行版安装了 Python。您可以按照以下方法之一将 TensorFlow 安装到您的本地计算机上。
|操作系统
|
安装 TensorFlow 的替代方法
|
| --- | --- |
| 苹果 | 对于 Mac,只需从 Launchpad 的其他文件夹下打开一个终端窗口,然后粘贴以下脚本:pip install --upgrade tensorflow |
| Windows 操作系统 | 对于 Windows,转到 Windows 机器上的“开始”菜单,搜索“cmd”,右键单击它并选择“以管理员身份运行”,然后粘贴前面提到的相同脚本:pip install --upgrade tensorflow |
| macOS/Windows | 对于 macOS 和 Windows,创建一个新的 IPython 笔记本,如前面所示。将以下代码复制并粘贴到一个空单元格中,然后单击页面顶部的“运行”按钮:!pip install --upgrade tensorflow注意小心感叹号! |
另一方面,如果你想使用谷歌 Colab,你不必安装 TensorFlow,因为谷歌 Colab 笔记本电脑预装了 TensorFlow。
Google Colab
Colaboratory,简称 Colab,是谷歌的产品,它允许开发者通过浏览器编写和执行 Python 代码。Google Colab 是深度学习任务的优秀工具。Google Colab 是一个托管的 Jupyter 笔记本,不需要设置,有一个优秀的免费版本,可以免费访问 GPU 等 Google 计算资源。
与 Anaconda 发行版一样,Google Colab 附带了重要的数据科学库,如 Pandas、NumPy、Matplotlib,以及更重要的 TensorFlow。Colab 还允许与其他开发者共享笔记本,并将你的文件保存到 Google Drive。您可以从任何地方访问和运行 Colab 笔记本中的代码。
综上所述,Colab 只是 Jupyter 笔记本的一个专门版本,运行在云上,提供免费的计算资源。
Caution
作为读者,您可以选择使用本地设备并安装前面显示的 Anaconda 发行版。使用 Jupyter Notebook,只要熟悉 Jupyter Notebook 就不会出现任何问题。另一方面,为了能够使这本书和代码保持最新,我将故意使用 Google Colab,以便我可以重新访问代码并进行更新。因此,您将始终可以访问最新版本的代码。所以,这本书我推荐你用 Google Colab。
Google Colab 设置
谷歌设置过程相对简单,可以通过以下步骤在所有设备上完成:
-
访问 colab.research.google.com,这将引导你到谷歌联合实验室的欢迎页面;参见图 1-10 。
-
Click the “Sign in” button on the right top.
图 1-10
谷歌 Colab 欢迎笔记本截图
-
Sign in with your Gmail account. Create one if you don’t have a Gmail account; see Figure 1-11.
图 1-11
Google 登录页面
-
一旦完成登录过程,您就可以使用 Google Colab 了。
-
You may easily create a new Colab Notebook on this page by clicking File ➤ New notebook. You can see an example Colab notebook in Figure 1-12.
图 1-12
空的 Google Colab 笔记本的截图
硬件选项和要求
深度学习是计算非常密集的,大型深度学习项目需要多台机器同时进行分布式计算。CPU、GPU 和 TPU 等处理单元、RAM、HDD 和 SSD 等硬盘驱动器以及电源单元是影响计算机整体训练性能的重要硬件单元。
对于使用大量数据集进行训练的项目来说,拥有强大的计算能力和合适的硬件是极其重要的。使用大型数据集进行模型定型的最关键组件是处理单元。当任务太大时,开发人员通常使用 GPU 和 TPU,而 CPU 对于中小型的训练任务可能就足够了。
这本书不包含计算量大的项目,因为这样的项目可能会使读者气馁和失去动力。因此,普通计算机足以满足本书的计算能力要求。此外,如果你按照建议使用 Google Colab 的教程,Google Colab 中提供的资源——也包括 GPUs 对于本书中的项目来说绰绰有余。因此,您完全不必担心您的硬件。
Footnotes 1谷歌刚刚开源了 TensorFlow,它的人工智能引擎| WIRED, www.wired.com/2015/11/google-open-sources-its-artificial-intelligence-engine/ (最后一次访问是在 2020 年 6 月 5 日)
2
谷歌人工智能博客:渴望执行:TensorFlow 的命令式运行定义界面,https://ai.googleblog.com/2017/10/eager-execution-imperative-define-by.html(2020 年 6 月 8 日最后一次访问)
3
TensorFlow 2.0 即将推出的内容- TensorFlow - Medium,https://medium.com/tensorflow/whats-coming-in-tensorflow-2-0-d3663832e9b8(2020 年 6 月 8 日最后一次访问)
4
深度学习框架 Power Scores 2018 走向数据科学, https://towardsdatascience.com/deep-learning-framework-power-scores-2018-23607ddf297a (最后一次访问 2020 年 6 月 6 日)
二、机器学习导论
本章旨在对机器学习领域进行介绍,并阐明类似领域的范围,尤其是深度学习。它还旨在比较不同的机器学习方法,介绍一些流行的机器学习模型,提及重要的机器学习概念,并引导您完成机器学习的步骤。这一章非常重要,因为深度学习是机器学习的一个子部分,因此,大多数解释也适用于深度学习。
什么是机器学习?
众所周知,计算机不具备认知能力,无法自主推理。然而,它们在处理数据方面非常完美,它们可以在少量时间内完成高难度的计算任务。只要我们向他们提供详细的、一步一步的逻辑和数学指导,他们就能处理任何事情。因此,如果我们可以用逻辑运算来代表人类的认知能力,计算机就可以发展认知技能。
意识是人工智能热议的话题之一:*计算机能变得有意识吗?*虽然这次讨论的范围是机器是否可以完全模仿人类意识(通用 AI ),但在本书中,我们专注于模仿特定任务的特定人类技能(狭义 AI )。这就是机器学习的用武之地。
“机器学习”一词最早是由 IBM 科学家、计算机游戏和人工智能领域的先驱亚瑟·塞缪尔(Arthur Samuel)在 1959 年提出的。在 20 世纪 50 年代、60 年代和 70 年代,神经网络的早期工作是以模仿人脑为目标的。然而,由于计算机技术的限制,神经网络的实际应用在很长一段时间内是不可行的。对其他 ML 技术(即,需要较少计算机资源的非深度学习技术)的基础机器学习研究在 20 世纪 80 年代和 90 年代普及。这一时期计算机技术的进步部分地允许在现实生活中采用机器学习应用。随着时间的推移,由于不成熟的计算机技术造成的限制大多被消除了,尤其是在最近几年。虽然我们总是在争取更好更高效的计算能力和存储,但现在,我们至少可以快速地建立模型,进行测试,甚至部署在互联网上,供全世界使用。今天,由于大量的数据、高效的数据存储技术以及更快更便宜的处理能力,机器学习领域非常活跃。图 2-1 总结了人工智能的时间轴。
图 2-1
人工智能时间轴
机器学习被认为是人工智能领域下的一个子学科。机器学习(ML)研究旨在根据经验自动提高为特定任务设计的计算机算法的性能。在机器学习研究中,经验来自训练数据,训练数据可以被定义为根据先前记录的观察收集的样本数据。通过这种体验,机器学习算法可以学习和建立数学模型来进行预测和决策。学习过程从将包含隐含模式的训练数据(例如,例子、直接经验、基本指令)输入模型开始。由于计算机比人类具有更强的处理能力,它们可以在短时间内从数据中找到这些有价值的模式。这些模式–然后–被用来对相关事件做出预测和决策。如果开发者构建了允许连续训练的合适的机器学习系统,则即使在部署之后,学习也可以继续。
以前,我们可能会在系统的几个子组件中使用机器学习。现在,我们实际上使用机器学习来取代整套系统,而不是试图为每一部分建立一个更好的机器学习模型。
—杰夫·迪恩
机器学习应用在不同领域的使用越来越多。这些现实生活中的应用在很大程度上有所不同。下面列出了一些使用案例:
-
**医疗保健:**针对患者症状的医疗诊断
-
电子商务:预测预期需求
-
法律:审查法律文件,提醒律师注意有问题的条款
-
社交网络:根据用户在约会应用上的偏好找到一个好的匹配
-
金融:根据历史数据预测股票的未来价格
这显然是一个非详尽的列表,有数百个,如果不是数千个,潜在的机器学习用例。取决于你的目标是什么,有许多不同的方法来创建机器学习模型。这些方法通常分为四种主要方法:(I)监督学习,(ii)半监督学习,(iii)非监督学习,和(iv)强化学习。
每种方法在设计上都有明显的不同,但它们都遵循相同的基本原则,并符合相同的理论背景。在接下来的章节中,我们将更详细地介绍这些不同的方法。但首先,我们将简单谈谈相邻领域的范围:(一)人工智能,(二)深度学习,(三)大数据,(四)数据科学。
机器学习的范围及其与相邻领域的关系
一旦你开始消费书籍、文章、视频课程、博客文章等机器学习内容,你会经常看到人工智能、机器学习、深度学习、大数据、数据科学等术语。这些术语之间的区别有一点模糊。在本节中,我们将澄清这种模糊性并说明其区别。
人工智能
人工智能(AI)是一个宽泛的术语,它的定义在不同的教科书中有所不同。人工智能一词通常用于描述模拟人类智能和模仿人类与人类思维相关的“认知”能力的计算机。解决问题和学习是这些认知能力的例子。人工智能领域包含机器学习研究,因为人工智能系统能够从经验中学习。一般来说,具有人工智能的机器能够
-
理解和解释数据
-
从数据中学习
-
基于从数据中提取的见解和模式做出“智能”决策
这些术语与机器学习高度相关。由于机器学习,人工智能系统可以在意识水平上学习和超越。机器学习用于训练 AI 系统,让它们变得更聪明。
深度学习
深度学习(DL)是机器学习的一个子领域,专门使用多层神经元从原始数据中提取模式和特征。这些多层相互连接的神经元创建了人工神经网络(ANNs 参见图 2-2 。人工神经网络是一种特殊的机器学习算法,旨在模拟人脑的工作机制。有许多不同类型的人工神经网络用于多种目的。总之,深度学习算法是机器学习算法的一个子集。
图 2-2
人工神经网络
正如在机器学习中一样,所有四种方法(监督、半监督、非监督和强化学习)都可以在深度学习中使用。当有大量数据和足够的计算能力时,深度学习几乎总是优于其他机器学习算法。深度学习算法在图像处理、语音识别和机器翻译中特别有用。
数据科学
数据科学是一个跨学科领域,位于人工智能、特定领域知识、信息科学和统计学的交叉点。数据科学家使用各种科学方法、流程和算法来获取知识,并从观察到的数据中获得洞察力。
与机器学习相比,数据科学研究的目标不一定是模型训练。数据科学研究通常旨在提取知识和洞察力,以支持人类决策过程,而不是创建人工智能系统。因此,尽管数据科学和其他相邻领域之间存在交叉,但数据科学领域与它们不同,因为它不需要提供智能系统或训练有素的模型。
大数据
大数据是一个旨在高效分析无法用传统数据处理方法和应用处理的大量数据的领域。更多观察的数据通常会带来更高的准确性,而高复杂性可能会增加错误发现率。大数据领域研究当数据集非常大时,如何高效地捕获、存储、分析、搜索、共享、可视化和更新数据。大数据研究可以用于人工智能(及其子领域)和数据科学。大数据位于前面提到的所有其他领域的交叉点,因为它的方法对所有这些领域都至关重要。
分类图
这些相邻术语之间的关系可以在下面的分类图中可视化,如图 2-3 所示。
图 2-3
人工智能和数据科学的分类
这种分类法几乎是模糊背后原因的清晰证据。每当我们在谈论深度学习的时候,我们也在谈论机器学习和人工智能。当我们在进行深度学习项目时,有些人可能会称之为数据科学项目或大数据项目。这些命名方法不一定是不正确的,但是它们很容易混淆。因此,了解这些场的交集和减法是至关重要的。
机器学习方法和模型
顶级机器学习方法根据其学习反馈机制的性质进行分类。这些不同的方法可以列举如下:
-
监督学习
-
无监督学习
-
半监督学习
-
强化学习
大多数机器学习问题可以通过采用这些方法中的一种来解决。然而,我们可能仍然会遇到不适合这些方法之一的复杂的机器学习解决方案。在本节中,我们将简要介绍这四种主要机器学习方法的范围,以及它们的应用示例。这种分类法至关重要,因为它将帮助您快速发现将来可能遇到的问题的本质,分析您的资源,并开发合适的解决方案。让我们从监督学习方法开始。
监督学习
当存在包含响应变量值(或标签)记录的数据集时,可以采用监督学习方法。根据上下文,这些带有标签的数据通常被称为“标签数据”和“训练数据”例如,当我们试图使用一个人的体重、年龄和性别来预测其身高时,我们需要包含其体重、年龄和性别信息以及实际身高的训练数据。这些数据允许机器学习算法发现身高和其他变量之间的关系。然后,使用这些知识,该模型可以预测给定人的身高。
例如,我们可以根据以前看到的垃圾邮件和非垃圾邮件的区别特征(如电子邮件的长度和电子邮件中特定关键字的使用)将电子邮件标记为“垃圾邮件”或“非垃圾邮件”。从训练数据的学习持续进行,直到机器学习模型在训练数据上达到高水平的准确度。
有两个主要的监督学习问题:(I)分类问题和(ii)回归问题。在分类问题中,模型学习根据它们的变量值对观察值进行分类。在学习过程中,模型会接触到大量带有标签的观察结果。例如,在看到数千名客户的购物习惯和性别信息后,模型可能会根据他们的购物习惯成功预测新客户的性别。二元分类是用于在两个标签下分组的术语,例如男性和女性。另一个二元分类的例子可能是预测图片中的动物是“猫”还是“不是猫”,如图 2-4 所示。
图 2-4
监督学习中的分类问题1
另一方面,当有两个以上的标签时,使用多标签分类。识别和预测图像上的手写字母和数字是多标签分类的一个例子。
在回归问题中,目标是通过利用其他变量(即自变量、解释变量或特征)和目标变量(即因变量、响应变量或标签)之间的关系来计算值。我们的目标变量和其他变量之间的关系强度是预测值的一个关键决定因素,此外还有用于观察的解释变量的值。根据客户的历史数据预测客户会花多少钱是一个回归问题。
有几十种不同的机器学习算法适合监督学习。由于这本书的重点是深度学习,我们只涵盖一些更受欢迎的,而不深入他们的细节。
-
线性和逻辑回归:线性回归是一种建模数字响应变量(Y)和一个或多个解释变量(Xs)之间关系的线性方法。另一方面,逻辑回归是一种略有不同的方法,用于模拟特定类别或事件存在的概率,如男性/女性代表性别。因此,线性回归用于回归问题,而逻辑回归大多用于分类问题。
-
决策树和集成方法:决策树是一种类似流程图的结构和决策支持工具,它将潜在决策和不确定事件与其概率联系起来,以创建一个预测可能结果的模型。我们还可以集成多个决策树来创建更高级的机器学习算法,如随机森林算法。
-
支持向量机:支持向量机构建一个超平面来分离一个空间,该空间可用于分类、回归或离群点检测。例如,三维空间(例如,立方体)可以用二维超平面(例如,正方形)分成更小的块。这将有助于将观察结果分成两个不同的类别。潜在的应用可能比这个例子复杂得多。支持向量机是一种流行的机器学习算法,由于其高精度性能和相对低水平的计算资源要求。
-
K-最近邻:K-最近邻算法是一种机器学习算法,可用于分类和回归问题。k 是用户定义的常数,表示算法中包含的邻居观测值的数量。在分类问题中,新的未标记观察的邻居被用于基于邻居的标签来预测该新观察的标签。
-
神经网络 (多层感知器,MLP) :仅前馈神经网络、卷积神经网络(CNN)、循环神经网络(RNNs)经常用于监督学习问题,这些将在后面的章节中介绍。
无监督学习
无监督学习是机器学习算法中使用的一种方法,用于从不包含标签的数据集进行推断。无监督学习主要用于聚类分析。聚类分析是一种分组工作,其中一个组(即一个聚类)的成员比其他聚类的成员彼此更相似。有许多不同的聚类方法可用。它们通常利用一种基于选定度量的相似性度量,例如欧几里德距离或概率距离。生物信息学序列分析、遗传聚类、模式挖掘和对象识别是可以用无监督学习方法解决的一些聚类问题。
无监督学习的另一个用例是降维。维度相当于数据集中使用的要素数量。在某些数据集中,您可能会发现存储在各个列中的数百个潜在要素。在大多数数据集中,这些列中有几个是高度相关的。因此,我们要么选择最好的,特征选择,要么结合已有特征提取新的特征,特征提取。这就是无监督学习发挥作用的地方。降维方法帮助我们创建更整洁的模型,没有噪音和不必要的特征。
无监督学习也可以用于异常检测问题和生成系统。我将简要提及一些流行的无监督机器学习模型,如下所示:
-
层次聚类:层次聚类是一种无监督的机器学习算法,用于对具有相似特征的未标记观察值进行增量分组。层次聚类可以是聚集的(自下而上的方法)或分裂的(自上而下的方法)。聚类的层次结构被表示为树或树状图。
-
K-Means 聚类 : K-means 聚类是一种流行的无监督机器学习算法。k 是用户指定的常数,表示要创建的簇的数量。k-均值聚类根据到聚类中心的距离将观察值分组到 k 个不同的聚类中。
-
主成分分析(PCA) : PCA 广泛用于降维。PCA 找到两个或多个变量的线性组合,称为主成分。该过程降低了模型的维度复杂度,使得问题可以被更快地可视化和分析,同时模型也更容易被训练。
-
神经网络:自编码器、深度信念网络、Hebbian 学习、生成对抗网络(GANs)和自组织映射是用于无监督学习的一些神经网络。这些网络结构的细节和应用将在接下来的章节中介绍。
半监督学习
半监督学习是一种结合了监督学习和非监督学习特点的机器学习方法。当我们有少量标记数据和大量未标记数据可用于训练时,半监督学习方法特别有用。监督学习特征有助于利用少量的标签数据。相比之下,无监督学习特征对于利用大量未标记数据是有用的。
嗯,你可能会想,如果半监督学习有实用的现实应用。虽然监督学习是一种强大的方法,但标记数据——用于监督学习——是一个昂贵而耗时的过程。另一方面,大量数据也可能是有益的,即使它们没有被标记。因此,在现实生活中,如果做得正确,半监督学习可能会成为最合适和最有成效的机器学习方法。
在半监督学习中,我们通常从聚类未标记的数据开始。然后,我们使用标记数据来标记聚类的未标记数据。最后,大量现在标记的数据用于训练机器学习模型。半监督学习模型可能非常强大,因为它们可以利用大量的数据。
半监督学习模型通常是监督和非监督学习中使用的现有机器学习算法的转换和调整版本的组合。这种方法成功地应用于语音分析、内容分类和蛋白质序列分类等领域。这些领域的相似之处在于,它们提供了丰富的未标记数据,而只有少量的标记数据。
强化学习
强化学习是机器学习的主要方法之一,它涉及在特定的环境中寻找最优的代理行为来最大化回报。代理人学习完善自己的行动,以获得尽可能高的累积回报。强化学习有四个主要元素:
-
代理:执行分配给它的任务的可训练程序
-
环境:代理完成其任务的真实或虚拟世界
-
动作:导致环境中状态改变的代理的移动
-
报酬:基于行动的消极或积极的报酬
强化学习既可以用于现实世界,也可以用于虚拟世界。例如,您可以创建一个不断发展的广告投放系统,根据不同设置产生的广告收入来决定向网站投放多少广告。广告投放系统将是现实世界应用的一个很好的例子。另一方面,你可以用强化学习在视频游戏中训练一个代理人来与其他玩家竞争,这些玩家通常被称为机器人。最后,用强化学习的方法对机器人的运动进行虚拟和真实的训练。一些流行的强化学习模型可以列举如下:
-
q 学习
-
国家-行动-奖励-国家-行动
-
深 Q 网(DQN)
-
深度确定性政策梯度(DDPG)
现有深度学习框架的一个缺点是缺乏对强化学习的全面模块支持,TensorFlow 也不例外。深度强化学习只能用构建在现有深度学习库之上的扩展库来完成,比如 Keras-RL,TF。代理,以及 Tensorforce 或专用强化学习库,如开放 AI 基线和稳定基线。因此,我们将无法在本书中深入探讨强化学习。
不同方法的评估
我们简要介绍了四种主要的机器学习方法:(I)监督学习,(ii)非监督学习,(iii)半监督学习,以及(v)强化学习。这些方法被应用于具有几种潜在算法的机器学习问题。监督学习解决分类和回归问题,而非监督学习处理维度减少和聚类。半监督学习结合了监督学习和非监督学习方法,以利用未标记的数据进行分类任务,而强化学习用于寻找最佳的行动集,以获得最高的回报。图 2-5 总结了这些方法的特点。
图 2-5
机器学习方法的特征概述
机器学习的步骤
由于多年的机器学习研究,我们现在已经完善了机器学习流程,可以准确地构建和训练模型。尽管您可能会在其他来源中看到稍微改变的流程,但是基本原理是相同的。机器学习过程的步骤可以列举如下:
-
收集数据
-
准备数据
-
型号选择
-
培养
-
估价
-
超参数调谐
-
预报
让我们深入每一个步骤,看看它们内部发生了什么。
收集数据
数据是机器学习模型的燃料。没有适当的数据,我们就无法达到预期的目的:高精度。这些数据必须是高质量和大容量的。因此,收集的数据的质量和数量对于成功的机器学习项目都非常重要。事实上,收集数据是机器学习项目中最具挑战性的部分之一。但是不要害怕。感谢 Kaggle 和 UC Irvine 的 Repository 等平台,我们可以跳过“收集数据”这一步,至少是出于教育目的。这一步的结果是数据的表示,例如保存为 CSV ( 逗号分隔值)文件的表格。
准备数据
现在我们已经收集了数据,我们需要为模型构建和训练准备数据。
首先,我们对数据进行初步的清理和转换。这一部分可能包括几项任务,包括但不限于处理缺失值、删除重复项、纠正错误、将字符串转换为浮点数、规范化数据以及生成虚拟变量。
然后,我们将数据随机化,以消除由于数据收集的时间而导致的任何不必要的相关性。在清理和随机化我们的数据后,我们使用数据可视化工具来发现变量之间的关系,这可能在模型构建过程中对我们有所帮助。我们还可以通过数据可视化来检测类不平衡和离群值。
最后,我们将准备好的数据集分成训练和评估(即测试)数据集。
型号选择
根据我们的问题,我们尝试不同的机器学习算法来找到最佳性能的模型。如果没有机器学习和深度学习库,对整个模型算法进行编码将是极其耗时的。但多亏了这些库,我们可以在几个机器学习模型中快速建立我们的模型,并在轻松训练后找到表现最好的一个。
培养
既然我们已经选择了一个(或多个)算法,构建了我们的(或多个)模型,并准备了我们的数据,我们可以将这些数据输入到模型中,并观察它(它们)优化方程变量。训练的目标是做出最高数量的正确预测或最低数量的错误。例如,如果我们使用线性回归,我们使用的方程如下:
y = m*x + b
-
符号:
-
y:响应变量
-
x:解释变量
-
男:坡度
-
拦截
我们的线性回归模型试图找到完美的斜率( m )和截距( b )值,这样我们可能以实际 y 值和 y 预测值之间的最低差异结束。完善我们的模型的过程是在几个训练步骤中反复进行的,直到在所选的性能度量上观察不到进一步的性能提高。
估价
在使用训练数据训练我们的模型之后,我们应该立即使用我们的模型从未见过的评估数据集来测试我们训练的模型。这种以前看不到的数据为我们提供了一个客观的表现得分。数据集的理想训练/测试拆分比率通常是 80/20、90/10 或 70/30,具体取决于领域。在某些情况下,数据科学家还会留出一个验证数据集。
尤其是当我们的数据有限时,数据科学家使用的一种有用的评估技术是交叉验证。请记住,我们将经常应用交叉验证进行评估。
Cross-Validation
是一种用于评估的替代重采样技术。在 k 倍交叉验证中,数据集被分成 k 个组。一组留作测试数据,该组切换 k 次。因此,每组用于测试一次。最终,我们有了一个更加可靠的性能评估。
评估是检查过拟合的一个特别重要的步骤。机器学习模型在优化方面过于急切。他们倾向于创建一组非常复杂的变量值来捕捉我们数据中的所有变化。然而,当我们在现实生活中部署模型时,这可能会导致问题,因为使用有限的训练数据来完善模型会产生短暂的视觉效果。
Overfitting
是一个机器学习问题,当模型过于接近观察值时就会出现。当模型存在过拟合问题时,它往往对训练数据表现良好,但对测试数据和现实世界表现不佳。
我们的模型应该高度准确,但也要灵活。在机器学习研究中,我们总是观察偏差和方差的权衡。引入系统的偏差水平和观察到的方差水平之间必须有一个平衡,这样我们的模型才能在现实生活中提供有意义和可靠的预测。
Bias and Variance Trade-Off
是机器学习模型的属性。偏差是模型为简化优化过程而做出的假设。方差是对目标函数可以输出的值的分布的度量。虽然偏差给模型带来了简单性,但你可能离可靠的预测还差得很远。另一方面,高方差会损害获得有意义结果的能力。
这些是评估机器学习模型时要注意的一些属性。假设我们对偏差和方差的权衡和过拟合非常小心,并且我们使用交叉验证来训练我们的模型。但是我们如何衡量我们的模型的成功呢?这是我们根据问题选择性能术语的地方。
Performance Terms for Classification
我们通常参考混淆矩阵(见图 2-6 )来理解我们的模型表现如何。混淆矩阵不仅允许我们计算模型的精确度,还允许我们计算模型性能的召回、精确度和 F1 得分。
图 2-6
分类问题的混淆矩阵
Performance Terms for Regression
我们通常使用基于错误的度量来度量模型性能。实际观察和预测之间的差异称为误差。通过综合计算,我们可能会找到诸如**【RMSE】**平均绝对误差(MSE) 等度量标准。这些度量值有助于衡量模型在特定回归中的成功程度。
**### 超参数调谐
既然我们在训练和测试数据集上都有了性能指标结果,我们可以调整模型超参数来进一步提高我们的性能。学习率、训练步骤数、初始化值、时期大小、批量大小和分布类型是一些可以随意使用的超参数。超参数调谐通常被称为艺术作品,而不是科学。数据科学家利用他们的直觉来尝试超参数的不同组合,以实现最高的性能。
预报
至此,我们已经完成了使用优化的超参数的初始训练。现在,我们可以用训练好的模型进行预测。预测步骤不应被视为学习过程的结束。在收到真实世界的反馈后,我们可以回过头来进一步训练、评估和调整我们的模型,以解决数据科学问题不断变化的本质。
最终评估
在这一章中,我们介绍了机器学习,其中也包括深度学习的子领域。我们对比了人工智能、机器学习、深度学习、数据科学和大数据等领域。
我们访问了主要的机器学习方法,(I)监督学习,(ii)非监督学习,(iii)半监督学习,和(iv)强化学习,并介绍了一些与这些方法一起使用的流行的机器学习模型。
然后,我们讲述了机器学习的步骤。本节解释了使用我们收集和清理的数据成功构建和训练机器学习模型的必要步骤。
在下一章,我们将对深度学习进行介绍。机器学习的介绍将帮助你掌握我们将在下一章看到的概念。
Footnotes 1Freepik 制作的图标,那些图标,桉树来自 www.flaticon.com
**
三、深度学习和神经网络概述
既然你正在读这本书,那么可以有把握地假设你知道深度学习是如何在最近几年流行起来的。深度学习越来越受欢迎有一个非常好的原因:它不可思议的准确性表现。尤其是当有丰富的数据和可用的处理能力时,深度学习是机器学习专家的选择。深度学习与传统机器学习算法的性能对比如图 3-1 所示。
图 3-1
深度学习与传统 ML 在准确性上的比较
深度学习是机器学习的一个子领域,它模仿人脑的数据处理和模式生成能力,用于自动决策。与其他机器学习算法相比,深度学习的独特准确性曲线有助于它被机器学习专家广泛使用和采用。由于人工神经网络,深度学习成为可能。人工神经网络是模拟人脑中神经元的网络结构,以便可以进行深度学习。在图 3-2 中,你可能会发现一个具有深度学习能力的人工神经网络(ANN)的例子。
图 3-2
具有两个隐层的人工神经网络的描述
你可能会认为深度学习是一个新发明的领域,最近推翻了其他机器学习算法。很多人都这样想。然而,人工神经网络和深度学习领域可以追溯到 20 世纪 40 年代。最近深度学习的兴起主要是因为大量的可用数据,更重要的是因为廉价而丰富的处理能力。
这是深度学习的概述章节。我们将看看我们在深度学习中经常使用的关键概念,包括(I)激活函数,(ii)损失函数,(iii)优化器和反向传播,(iv)正则化,以及(v)特征缩放。但是,首先,我们将深入研究人工神经网络和深度学习的历史,以便您对本书中经常看到的深度学习概念的根源有所了解。
神经网络和深度学习研究的时间线
神经网络和深度学习研究的时间轴并不是由一系列不间断的进步组成的。事实上,人工智能领域经历了几次失败,这些失败被称为 AI winters。让我们深入研究神经网络和深度学习的历史,它始于 1943 年。
人工神经元**的开发——1943 年,先驱学者沃尔特·皮茨和沃伦·麦卡洛克发表了论文【神经活动中内在思想的逻辑演算】,在那里他们提出了一个生物神经元的数学模型,称为 麦卡洛克-皮茨神经元 。麦卡洛克皮茨神经元的能力是最小的,它没有学习机制。麦卡洛克·皮茨神经元的重要性在于,它为深度学习奠定了基础。1957 年,Frank Rosenblatt 发表了另一篇论文,题为“感知器:感知和识别自动机”,其中他介绍了具有学习和二进制分类功能的感知器**。革命性的感知机模型——在麦克库洛奇·皮茨神经元之后崛起——激励了许多从事人工神经网络研究的研究人员。**
**反向传播——1960 年,亨利·j·凯利发表了一篇题为《最佳飞行路径的梯度理论》的论文,他在论文中展示了一个连续反向传播的例子。反向传播是一个重要的深度学习概念,我们将在本章中讨论。1962 年,Stuart Dreyfus 在他的论文“变分问题的数值解”中用链式法则改进了反向传播。反向传播这个术语是由 Rumelhart、Hinton 和 Williams 在 1986 年创造的,这些研究人员已经将其应用于人工神经网络。
训练和计算机化–1965 年,通常被称为“深度学习之父”的阿列克谢·伊瓦赫年科(Alexey Ivakhnenko)建立了一个神经网络的分层表示,并通过使用多项式激活函数成功训练了这个模型。1970 年,Seppo Linnainmaa 发现了反向传播的自动微分,并能够编写第一个反向传播程序。这一发展可能标志着深度学习计算机化的开始。1971 年,Ivakhnenko 创建了一个八层神经网络,由于其多层结构,它被认为是一个深度学习网络。
1969 年,马文·明斯基和西蒙·派珀特写了《感知机》一书,他在书中猛烈抨击了感知机弗兰克·罗森布拉特的工作。这本书对人工智能项目资金造成了毁灭性的破坏,引发了从 1974 年持续到 1980 年的人工智能冬天。
卷积神经网络——1980 年,Kunihiko Fukushima 推出了 neocognitron,这是第一个卷积神经网络(CNN),可以识别视觉模式。1982 年,Paul Werbos 提出了在神经网络中使用反向传播来最小化误差,并且 AI 社区已经广泛采用了这个提议。1989 年,Yann LeCun 使用反向传播来训练 CNN 识别 MNIST(改进的国家标准和技术研究所)数据集中的手写数字。在本书中,我们在第七章中有一个类似的案例研究。
循环神经网络–1982 年,John Hopfield 介绍了 Hopfield 网络,这是循环神经网络(RNNs)的早期实现。循环神经网络是革命性的算法,最适用于顺序数据。1985 年,Geoffrey Hinton、David H. Ackley 和 Terrence Sejnowski 提出了玻尔兹曼机,这是一种没有输出层的随机 RNN。1986 年,Paul Smolensky 开发了一种新的玻尔兹曼机变体,它在输入层和隐藏层中没有层内连接,这种机器被称为受限玻尔兹曼机。受限玻尔兹曼机在推荐系统中尤其成功。1997 年,Sepp Hochreiter 和 Jürgen Schmidhuber 发表了一篇关于改进的 RNN 模型——长短期记忆(LSTM)的论文,我们也将在第八章中涉及。2006 年,Geoffrey Hinton、Simon Osindero 和 Yee Whye Teh 组合了几个受限玻尔兹曼机(RBM)并创建了深度信念网络,这提高了 RBM 的能力。
深度学习的能力–1986 年,Terry Sejnowski 开发了 NETtalk,这是一个基于神经网络的文本到语音转换系统,可以对英语文本进行发音。1989 年,George Cybenko 在他的论文“Sigmoidal 函数的叠加近似”中指出,具有单个隐藏层 的前馈神经网络可以求解任何连续函数 。
消失梯度问题——1991 年,Sepp Hochreiter 发现并证明了消失梯度问题,它减缓了深度学习过程,使其变得不切实际。20 年后,在 2011 年,Yoshua Bengio、Antoine Bordes 和 Xavier Glorot 表明,使用校正线性单位(ReLU)作为激活函数可以防止消失梯度问题。
用于深度学习的 GPU——2009 年,吴恩达、拉杰特·刘冰和阿南德·马德哈万在他们的论文《使用图形处理器的大规模深度无监督学习》中建议使用 GPU 进行深度学习,因为在 GPU 中发现的核心数量比在 CPU 中发现的要多得多。这种转换减少了神经网络的训练时间,使它们的应用更加可行。随着 GPU 制造商推出的官方并行计算平台(如 Nvidia 的 CUDA 和 AMD 的 ROCm),GPU 在深度学习中的使用越来越多,导致了深度学习专用 ASICS 的发展(如谷歌的 TPU)。
ImageNet 和****AlexNet——2009 年,费-李非推出了一个拥有 1400 万张标注图片的数据库,名为 ImageNet。ImageNet 数据库的创建有助于图像处理神经网络的发展,因为深度学习的一个重要组成部分是丰富的数据。自从 ImageNet 数据库创建以来,每年都举行竞赛以改进图像处理研究。2012 年,Alex Krizhevsky 设计了一个经过 GPU 训练的 CNN,AlexNet,与早期的模型相比,模型精度提高了 75%。
生成对抗网络——2014 年,伊恩·古德菲勒(Ian Goodfellow)在当地一家酒吧和朋友聊天时,想到了一个新的神经网络模型的想法。这个革命性的模型是在一夜之间设计出来的,现在被称为生成对抗性神经网络(GANs),它能够生成艺术,文本和诗歌,它可以完成许多其他创造性任务。在第十二章中,我们有一个关于 GANs 实施的案例研究。
力量 强化学习——2016 年,DeepMind 训练了一个深度强化学习模型 AlphaGo,它可以玩围棋,围棋被认为是比象棋复杂得多的游戏。AlphaGo 在 2017 年击败了围棋世界冠军柯洁。
图灵奖授予深度学习的先驱——2019 年,人工智能领域的三位先驱 Yann LeCun、Geoffrey Hinton 和 Yoshua Bengio 分享了图灵奖。这个奖项证明了深度学习对于计算机科学界的重要性。
人工神经网络的结构
在深入研究基本的深度学习概念之前,让我们看看当今现代深度神经网络的发展历程。今天,我们可以很容易地找到具有数百层和数千个神经元的神经网络的例子,但在二十世纪中期之前,人工神经网络这个术语甚至不存在。这一切始于 1943 年的一个简单的人工神经元——麦卡洛克·皮茨神经元——它只能进行简单的数学计算,没有学习能力。
麦卡洛克-皮茨神经元
麦卡洛克·皮茨神经元于 1943 年问世,它只能进行基本的数学运算。每个事件被赋予一个布尔值(0 或 1),如果事件结果(0 和 1)的总和超过一个阈值,那么人工神经元就会触发。图 3-3 显示了麦卡洛克皮茨神经元的 or 和 and 运算的可视化示例。
图 3-3
用于“或”与“与”运算的麦卡洛克·皮茨神经元
由于来自麦卡洛克皮茨神经元事件的输入只能是布尔值(0 或 1),它的能力是最小的。随着线性阈值单元(LTU)的发展,这种限制得到了解决。
线性阈值单位(LTU)
在麦卡洛克·皮茨神经元中,每个事件的重要性是相等的,这是有问题的,因为大多数真实世界的事件不符合这种简单的设置。为了解决这个问题,1957 年引入了线性阈值单元(LTU)。在 LTU 中,权重被分配给每个事件,这些权重可以是负的或正的。每个事件的结果仍被赋予一个布尔值(0 或 1),但随后乘以指定的权重。只有当这些加权事件结果的总和为正时,才会激活 LTU。在图 3-4 中,你可能会发现 LTU 的可视化,它是今天人工神经网络的基础。
图 3-4
线性阈值单元(LTU)可视化
感知器
感知器是一种用于监督学习的二进制分类算法,由一层 ltu 组成。在感知器中,ltu 使用相同的事件输出作为输入。感知器算法可以调整权重,以校正经过训练的神经网络的行为。此外,可以添加偏置项来提高网络的精度性能。
当感知器只有一层时,称为单层感知器。有一个输出层和一个接收输入的输入层。当隐藏层被添加到单层感知器时,我们最终得到一个多层感知器(MLP)。MLP 被认为是一种深度神经网络,我们为日常问题建立的人工神经网络就是 MLP 的例子。在图 3-5 中,你可能会发现一个单层感知器的可视化例子。
图 3-5
单层感知器图的例子
现代深度神经网络
我们今天遇到的深度神经网络是多层感知器(MLP)的改进版本。我们经常使用比阶跃函数(0 或 1)更复杂的激活函数,如 ReLU、Sigmoid、Tanh 和 Softmax。现代深度神经网络通常利用一种梯度下降方法进行优化。现代深度神经网络示例如图 3-6 所示。
图 3-6
一个现代深度神经网络的例子
现在,您已经了解了更多关于开发今天的现代深度神经网络的旅程,这是从麦卡洛克·皮茨神经元开始的,我们可以深入研究我们在应用中使用的基本深度学习概念。
激活功能
激活函数是用于帮助人工神经网络从数据中学习复杂模式的函数。通常在每个神经元的末端添加一个激活函数,它会影响下一个神经元触发什么。换句话说,如图 3-7 所示,一个神经元的激活函数是在给定一个输入或一组输入后,给出该神经元的输出。
图 3-7
最后是一个带有激活函数的 LTU 图的例子
激活函数引入了最终的计算步骤,这给人工神经网络增加了额外的复杂性。因此,它们增加了所需的训练时间和处理能力。那么,我们为什么要在神经网络中使用激活函数呢?答案很简单:激活函数提高了神经网络使用相关信息和抑制不相关数据点的能力。如果没有激活函数,我们的神经网络将只能执行线性转换。尽管避免激活函数使得神经网络模型更简单,但是该模型的功能将更弱,并且不能收敛于复杂的模式结构。没有激活函数的神经网络本质上只是一个线性回归模型。
我们可以在神经网络中使用许多不同的激活函数。激活功能的非详尽列表可在此处找到:
-
二进制步骤
-
线性的
-
乙状结肠(逻辑激活功能)
-
双曲正切
-
整流线性单位
-
Softmax(软件最大值)
-
李奇注意到了
-
参数化 ReLU
-
指数线性单位
-
嗖嗖
在这些激活函数中,Tanh、ReLU 和 Sigmoid 激活函数广泛用于单个神经元激活。还有,Softmax 函数在图层之后被广泛使用。您可以在图 3-8 中找到 Tanh、ReLU 和 Sigmoid 函数的 X-Y 图。
图 3-8
Tanh、ReLU 和 Sigmoid 函数图
根据问题的性质,一个激活功能可能比另一个执行得更好。尽管 ReLU、Tanh 和 Sigmoid 函数通常在深度学习中收敛得很好,但我们应该尝试所有可能的函数,并优化我们的训练,以尽可能实现最高的精度性能。可以通过以下要点对 ReLU、Tanh 和 Sigmoid 进行简单的比较:
-
ReLU 函数是一个广泛使用的通用激活函数。应该用在隐藏层。如果有死亡的神经元,泄漏的 ReLU 可能会修复潜在的问题。
-
Sigmoid 函数在分类任务中工作得最好。
-
Sigmoid 和 Tanh 函数可能会导致消失梯度问题。
优化训练实践的最佳策略是从 ReLU 开始,尝试其他激活功能,看看性能是否有所提高。
损失(成本或误差)函数
损失函数是用于测量深度学习模型对于给定数据的性能的函数。它通常基于误差项,误差项被计算为真实(测量)值和训练模型的预测值之间的距离。
误差=测量值-预测值
因此,我们每次预测都会有一个误差项。假设您正在处理数百万个数据点。为了能够从这些单独的误差项中获得洞察力,我们需要一个聚合函数,以便我们能够得出一个性能评估的单一值。这个函数被称为损失函数、 成本函数 ,或者 误差函数 ,视上下文而定。
几个损失函数用于性能评估,选择正确的函数是建模的一个组成部分。这种选择必须基于问题的性质。虽然均方根误差(RMSE)函数对于我们想要惩罚大误差的回归问题是正确的损失函数,但是多类交叉熵应该被选择用于多类分类问题。
此外,为了被用于生成聚合误差项的单个值,损失函数也可以被用于强化学习中的奖励。在本书中,我们将主要使用带有误差项的损失函数,但请注意,使用损失函数作为奖励措施是可能的。
深度学习任务中使用了几个损失函数。均方根误差(RMSE)、均方误差(MSE)、平均绝对误差(MAE)和平均绝对百分比误差(MAPE)是回归问题的一些合适的损失函数。对于二元和多类分类问题,我们可以使用交叉熵的变体(即对数)函数。
深度学习中的优化
既然我们已经讨论了激活和损失函数,是时候继续讨论权重和偏差优化了。神经元和层中使用的激活函数对从权重和偏差项导出的线性结果进行最终调整。我们可以使用这些参数(权重和偏差)进行预测。实际值和预测值之间的距离被记录为误差项。这些误差项通过损失函数聚集成单个值。除了这个过程,优化函数对权重和偏差进行小的改变,并用损失函数测量这些改变的影响。该过程有助于找到最佳权重和偏差值,以最小化误差并最大化模型的准确性。这个训练周期如图 3-9 所示。
图 3-9
具有成本函数、激活函数和优化器的深度学习模型训练
在优化过程中会遇到一些优化算法和挑战。在本节中,我们将简要介绍这些功能和挑战。但首先,我们来看看一个必不可少的优化概念:反向传播。
反向传播
反向传播算法是用于与优化器并行迭代的神经网络架构中的基本组件。它是神经网络学习的中心机制。这个名字本身就说明了问题,因为单词 propagate 的意思是传送某物。所以一词 backpropagation 的意思是将信息传回。“这正是反向传播算法所要做的:它将计算出的损失返回给系统,由优化器用来调整权重和偏差。这个过程可以一步一步地解释,如下所示:
-
步骤 1 :训练好的神经网络用当前的权重和偏差进行预测。
-
步骤 2 :用损失函数作为单一误差度量来测量神经网络的性能。
-
步骤 3 :这个误差度量被反向传播到优化器,以便它可以重新调整权重和偏差。
-
重复
通过使用反向传播算法提供的信息,优化算法可以完善神经网络中使用的权重和偏差。让我们来看看优化算法(即优化器),它们与反向传播机制并行使用。
优化算法
优化算法可以被定义为帮助另一个算法无延迟地最大化其性能的算法。深度学习是优化算法被广泛使用的一个领域。深度学习任务中最常用的优化算法如下:
-
圣经》和《古兰经》传统中)亚当(人类第一人的名字
-
随机梯度下降
-
阿达德尔塔
-
Rmsprop
-
阿达玛斯
-
阿达格拉德
-
那达慕
请注意,所有这些优化器以及前面提到的损失和激活函数在 TensorFlow 中都很容易找到。实际应用中最常用的是 Adam 优化器和随机梯度下降(SGD)优化器。让我们看看所有优化器之母,梯度下降和 SGD,以便更好地理解优化算法是如何工作的。
梯度下降和随机梯度下降(SGD)–随机梯度下降是梯度下降方法的一种变体。SGD 是深度学习中广泛使用的一种迭代优化方法。SGD 的根源可以追溯到 20 世纪 50 年代,它是最古老的——但也是最成功的——优化算法之一。
梯度下降法是一系列优化算法,用于最小化神经网络中的总损失(或成本)。有几种梯度下降实现:原始梯度下降或批量梯度下降算法使用每个时期的全部训练数据。随机(随机)梯度下降(SGD)选择随机观察来测量由于权重和偏差的变化而导致的总损失(或成本)的变化。最后,小批量梯度下降使用小批量,因此训练可能仍然是快速和可靠的。
Epoch
是超参数,表示使用定型数据集调整神经网络值的次数。
图 3-10
显示梯度下降的失重图
图 3-10 显示了梯度下降算法的工作原理。当机器学习专家选择更快的学习速率时,采取更大的增量步骤。
Learning Rate
是优化算法中的参数,它调节每次迭代时的步长,同时向前移动损失/成本函数的最小值。学习速度越快,模型越快地收敛到最小值附近,但它可能会超过实际的最小值点。如果学习速度慢,优化可能会花费太多时间。因此,一个机器学习专家必须选择最优的学习速率,它允许模型在合理的时间内找到期望的最小点。
亚当优化器–什么是亚当?
我不会深入其他优化算法的细节,因为它们大多是梯度下降法的修改或改进实现。所以暂时了解一下梯度下降算法就够了。
在下一节中,我们将看到在培训过程中对优化过程产生负面影响的优化挑战。如前所述,开发了一些优化算法来缓解这些挑战。
优化挑战
我们在深度学习中经常会遇到三个优化挑战。这些挑战是(I)局部最小值,(ii)鞍点,和(iii)消失梯度。我们简单讨论一下它们是什么。
局部最小值**–**在神经网络训练中,具有单个最小值的简单减肥图可能有助于可视化体重和计算出的体重之间的关系,以用于教育目的。然而,在现实世界的问题中,这个图可能包含许多局部最小值,并且我们的优化算法可能收敛于一个局部最小值而不是全局最小值点。图 3-11 显示了我们的模型是如何陷入局部最小值的。
图 3-11
具有两个局部最小值和一个全局最小值的减重图
**鞍点—**鞍点是图中的稳定点,算法无法判断它是局部最小值还是局部最大值。鞍点的两边斜率为零。使用多个观测值进行损失计算的优化器可能会陷入鞍点。因此,随机梯度下降是鞍点的一个合适的解决方案。图 3-12 为带有鞍点的简化图形。
图 3-12
具有两个局部最小值和一个全局最小值的减重图
消失梯度**–**过度使用某些激活函数(如 Sigmoid)可能会对优化算法产生负面影响。由于损失函数的梯度接近于零,所以降低损失函数的输出变得困难。消失梯度问题的一个有效解决方案是在隐藏层中使用 ReLU 作为激活函数。Sigmoid 激活函数——消失梯度问题的主要原因——及其导数如图 3-13 所示。
图 3-13
Sigmoid 函数及其导数
为了能够解决这种常见的优化挑战,我们应该尝试并找到激活函数和优化函数的最佳组合,以便我们的模型正确收敛并找到理想的最小点。
过拟合和正则化
深度学习和机器学习的另一个重要概念是过拟合。在本节中,我们将讨论过拟合问题以及如何用正则化方法解决过拟合问题。
过拟合
在第二章中,我们已经简单解释了机器学习的过拟合概念。过拟合也是深度学习中的一个挑战。我们不希望我们的神经网络过于紧密地拟合有限的一组数据点,这会危及它在现实世界中的性能。我们也不希望我们的模型欠拟合,因为它不会给我们一个好的精度水平。欠配合和过配合问题如图 3-14 所示。
图 3-14
X-Y 图中的欠拟合和过拟合
解决拟合不足问题的方法是建立一个具有有意义特征的好模型,输入足够的数据,进行足够的训练。另一方面,更多的数据、去除过多的特征和交叉验证是解决过拟合问题的适当方法。此外,我们有一组复杂的方法来克服过拟合问题,即正则化方法。
正规化
正则化是一种对抗过拟合的技术。有许多可能的正则化方法,可列举如下:
-
提前停止
-
拒绝传统社会的人
-
L1 和 L2 正规化
-
日期增加
提前停止–提前停止是一种非常简单但有效的防止过拟合的策略。设置足够数量的历元(训练步骤)对于实现高水平的准确性至关重要。但是,您可能很容易走极端,将您的模型训练得与您的训练数据过于吻合。使用早期停止,如果模型在一定数量的时期内没有显示出显著的性能改善,则学习算法停止。
辍学–辍学是另一种简单但有效的正规化方法。启用 dropout 后,我们的模型会暂时从网络中删除一些神经元或层,这会给神经网络增加额外的噪声。这种噪声防止模型与训练数据过于接近,并使模型更加灵活。
L1 和 L2 正则化–这两种方法在损失函数中增加了一个额外的惩罚项,对误差的惩罚力度更大。对于 L1 正则化,这一项是套索回归,而对于 L2 正则化,这是岭回归。处理大量要素时,L1 和 L2 正则化尤其有用。
数据扩充–数据扩充是一种增加训练数据量的方法。通过对现有数据进行小的转换,我们可以生成更多的观察值,并将它们添加到原始数据集中。数据扩充增加了训练数据的总量,这有助于防止过拟合问题。
特征缩放
深度学习的另一个关键概念是特征缩放。特征缩放是一种标准化特征范围的方法,以便神经网络更准确地执行。当特征值的范围变化很大时,一些目标函数可能无法在机器学习模型中正确工作。例如,分类器通常计算两个数据点之间的距离。当一个特征的值的方差很大时,这个特征决定了这个计算的距离,这意味着这个特定特征对结果的夸大影响。缩放每个特性的值范围有助于消除这个问题。下面列出了几种特征缩放方法:
-
标准化:调整各特征值,使均值和单位方差为零。
-
最小-最大归一化(重新缩放):在[0,1]和[-1,1]之间缩放每个特性的值。
-
均值归一化:从每个数据点中扣除均值,并将结果除以最大-最小差。它是最小-最大归一化的一个稍有改变且不太流行的版本。
-
缩放到单位长度:将特征的每个分量除以该特征向量的欧几里德长度。
在深度学习中使用特征缩放有两个好处:
-
它确保每个特征对预测算法的贡献成比例。
-
它加速了梯度下降算法的收敛,从而减少了训练模型所需的时间。
最终评估
在这一章中,我们讨论了人工神经网络和深度学习的时间线。经过多年的研究,它帮助我们理解了我们在职业生活中使用的概念是如何变成现实的。好消息是,由于 TensorFlow,我们能够在几秒钟内将这些组件添加到我们的神经网络中。
沿着深度学习时间线,我们详细分析了神经网络和人工神经元的结构。此外,我们涵盖了基本的深度学习概念,包括(I)优化函数,(ii)激活函数,(iii)损失函数,(iv)过拟合和正则化,以及(v)特征缩放。
这一章是上一章的延续,上一章我们讲述了机器学习的基础知识。在下一章中,我们将了解深度学习研究中最常用的补充技术:(i) NumPy,(ii) SciPy,(iii) Matplotlib,(iii) Pandas,(iv) scikit-learn,以及(v) Flask。**
四、TensorFlow 2.x 的补充库
现在我们已经讨论了机器学习和深度学习的基础知识,我们可以慢慢转向深度学习的应用方面。如你所知,每个机器学习应用,包括深度学习应用,都有一个由几个步骤组成的流水线。TensorFlow 为所有这些步骤提供了几个模块。即使 TensorFlow 在建模、训练、评估和预测方面非常强大,我们仍然需要其他补充库来完成某些任务,尤其是数据准备。尽管您可能在深度学习流水线中使用的潜在库可能在很大程度上有所不同,但最受欢迎的补充库如下:
| NumPySciPy 熊猫 | • Matplotlib• 科学学习烧瓶 |特别是在 TensorFlow 2.x 之后,我们开始看到越来越多的数据准备、可视化以及其他相关功能添加到 TensorFlow 中。然而,这些功能还不能与这些专用库所提供的相提并论。表 4-1 列出了这些库及其核心功能。
表 4-1
TensorFlow 的补充库及其主要用例
|图书馆
|
核心能力
| | --- | --- | | NumPy | 阵列处理 | | 我的天啊 | 科学计算 | | 熊猫 | 阵列处理和数据分析,包括数据可视化 | | Matplotlib | 数据可视化 | | Scikit-learn | 机器学习 | | 瓶 | 用于部署的 Web 框架 |
让我们看看如何使用 pip(我们的 Python 包安装程序)将它们安装在一起。
使用 Pip 安装
Pip 是 Python 事实上的标准包管理系统,已经包含在 Python 安装包中。用 pip 可以轻松安装和管理 Python 库。
*最初使用 pip 的环境是 macOS 的终端和 Windows OS 的命令提示符。不过你也可以用 Jupyter 笔记本里面的 pip 和 Google Colab 稍微调整一下。这两个选项的区别只有一个感叹号(!).
|终端和命令提示符
|
Jupyter 笔记本和 Google Colab
|
| --- | --- |
| pip install package-name | !pip install package-name |
如果您决定在本地 Jupyter 笔记本上安装本书,我们必须确保您的系统上安装了 pip。
Use of Pip in Google Colab
如果你使用的是推荐的 Google Colab,你就不用担心你的系统上有没有 pip。你可以在你的 Google Colab 笔记本中使用带有感叹号的 pip。
Pip 安装,或其 确认分三步完成:
-
打开 macOS 的终端 Windows OS 的命令提示符:
-
您可以从“其他”文件夹下的 Launchpad 打开终端窗口。
-
您可以打开命令行窗口,方法是(I)按 Windows+X 打开超级用户菜单,然后(ii)单击“命令提示符”或“命令提示符(管理)”
-
-
检查是否安装了 pip ,并使用以下脚本查看系统上安装的当前版本:
pip --version
- 如果终端/命令行没有返回版本信息,请使用以下命令安装 pip:
python -m pip install -U pip
如果它返回版本信息,那么您确认您的系统上安装了 pip。
- 关闭终端/命令行窗口。
安装 库——现在我们确认您的系统上已经安装了 pip,您可以使用表 4-2 中的以下脚本安装本章中提到的所有库。
表 4-2
Pip 安装脚本的补充库
|图书馆
|
安装脚本
|
| --- | --- |
| NumPy | pip install numpy |
| 我的天啊 | pip install scipy |
| 熊猫 | pip install pandas |
| Matplotlib | pip install matplotlib |
| Scikit-learn | pip install scikit-learn |
| 瓶 | pip install flask |
Beware of Already Installed Packages
Google Colab 笔记本和 Jupyter 笔记本都已经预装了这些库。只需运行前面提到的脚本一次,以确保您已经安装了它们,这样在案例研究期间,万一它们中的一些丢失了,您就不会受到干扰。
现在我们确信您的系统中已经安装了这些库(Google Colab 或 Jupyter Notebook),我们可以深入了解这些库的细节了。
NumPy–数组处理
NumPy(数值 Python)是一个非常流行的开源数值 Python 库,由 Travis Oliphant 创建。NumPy 提供了多维数组以及大量用于数学运算的有用函数。
NumPy 充当 C 中实现的相应库的包装器。因此,它提供了两个世界的最佳状态:(I)C 的效率和(ii)Python 的易用性。NumPy 数组是易于创建的高效对象,用于(I)存储数据和(ii)快速矩阵运算。使用 NumPy,您可以快速生成包含随机数的数组,这对于增强学习体验和概念验证任务来说是完美的。此外,我们将在后面介绍的 Pandas 库严重依赖于 NumPy 对象,并且几乎是作为 NumPy 扩展来工作的。
多亏了 NumPy 阵列,我们可以轻松地处理大量数据和进行高级数学运算。与内置的 Python 序列相比,NumPy 的ndarray对象用更少的代码执行起来更快更有效。越来越多的库依赖 NumPy 数组来处理数据,这显示了 NumPy 的强大。由于深度学习模型通常是用数百万个数据点训练的,NumPy 阵列的大小和速度优势对于机器学习专家来说至关重要。
关于 NumPy 的有用信息
-
网站 :
www.numpy.org/ -
文档网址 :
https://numpy.org/doc/ -
安装命令 : pip
install numpy -
导入的首选别名:
import numpy as np
科学计算
SciPy 是一个开源的 Python 库,它包含一组用于数学、科学和工程研究的函数。SciPy 函数建立在 NumPy 库的基础上。SciPy 允许用户使用易于使用的语法来操作和可视化他们的数据。SciPy 是一个库,它提高了开发人员的数据处理和系统原型能力,并使 Python 与竞争系统如 MATLAB、IDL、Octave、R-Lab 和 SciLab 一样有效。因此,SciPy 的数据处理和原型函数集合进一步加强了 Python 作为通用编程语言已经确立的优势。
SciPy 的大量函数集合被组织到基于域的子包中。SciPy 子包必须与母 SciPy 库分开调用,例如
from scipy import stats, special
在表 4-3 中,您可以找到 SciPy 子包的列表。
表 4-3
SciPy 子包
|子包
|
描述
|
子包
|
描述
|
| --- | --- | --- | --- |
| stats | 统计函数和分布 | linalg | 线性代数 |
| special | 特殊功能 | io | 输入和输出 |
| spatial | 空间数据结构和算法 | interpolate | 插值和平滑样条 |
| sparse | 稀疏矩阵和相关例程 | integrate | 积分和方程求解 |
| signal | 信号处理 | fftpack | 快速傅立叶变换例程 |
| optimize | 优化和求根例程 | constants | 物理和数学常数 |
| odr | 正交距离回归 | cluster | 聚类算法 |
| ndimage | n 维图像处理 | | |
关于 的有用信息 SciPy
-
文档网址 :
https://docs.scipy.org/doc/ -
安装命令 :
pip install scipy -
导入首选别名 :
from scipy importsub-package-name
pandas–阵列处理和数据分析
Pandas 是一个 Python 库,它提供了灵活且富于表现力的数据结构,适合执行快速的数学运算。Python 是一个全面且易于使用的数据分析库,它的目标是成为领先的开源语言中立的数据分析工具。
一维序列和二维数据帧是 pandas 中的两种主要数据结构。因为它扩展了 NumPy 的功能,并且是建立在 NumPy 之上的,Pandas 几乎像 NumPy 的扩展一样运行。Pandas 还提供了几种数据可视化方法,这对于从数据集中获得洞察力非常有用。
您可以使用 Pandas 分析您的数据并执行多项计算任务。以下是你可以对熊猫做的事情的非详尽列表:
-
通过填充和删除来处理缺失数据
-
由于允许可变性,数据插入和删除
-
自动和显式数据对齐
-
分组依据和排序依据功能
-
轻松地将无组织的对象转换为数据帧
-
切片、索引和子集操作
-
合并、连接和联接操作
-
重塑和透视操作
-
分级和多重标记
-
时序和序列数据的特定操作
-
强大的输入和输出操作,支持广泛的文件格式(包括 CSV、XLSX、HTML、HDF5)
由于 Pandas 是 NumPy 的事实上的扩展,提高了它的能力,我们比 NumPy 更经常地利用 Pandas。但是在某些情况下,由于其他补充库的限制,我们不得不依赖 NumPy。
关于熊猫的有用信息
-
安装命令 :
pip install pandas -
导入首选别名:
import pandas as pd
Matplotlib 和 Seaborn–数据可视化
Matplotlib 是一个 Python 数据可视化库,用于创建静态的、动态的和交互式的图形和绘图。您可以为学术出版物、博客和书籍制作高质量的绘图,还可以使用 Matplotlib 从大型数据集获得见解。
除了使用 Google Colab 笔记本获得洞察力,您还可以使用 Matplotlib 的面向对象 API 将绘图嵌入到应用程序中。Matplotlib 的三个主要功能如下:
-
创建:使用 Matplotlib,您可以用最少的代码创建高质量的绘图。Matplotlib 提供的图形类型总数超过数百种——从直方图到热度图,从条形图到曲面图。
-
自定义 : Matplotlib 绘图非常灵活,您可以自定义线型、字体属性、颜色和轴信息。您可以从图中导出并将数据嵌入到图中。
-
Extend :你可以利用大量的第三方库来扩展 Matplotlib。其中一些库也极其有用,比如 Seaborn 。
您可以使用 Matplotlib 做的事情如下所示:
-
使用 PyPlot 模块并创建交互式绘图。
-
使用线条、条形图、标记和其他对象创建数百种不同的图形和绘图。
-
创建独特的图,如曲面图和等高线图。
-
向图中添加图像和字段。
-
在一个图形下创建多个支线剧情。
-
灵活编辑绘图中的文本、轴、颜色、标签和注释。
-
使用 Matplotlib 创建一个或多个形状。
-
创建展示图。
-
利用动画支持。
关于 Matplotlib 的有用信息
-
文档网址 :
https://matplotlib.org/3.2.1/contents.html(确保输入最新版本) -
安装命令: pip
install matplotlib -
导入首选别名:
import matplotlib.pyplot as plt
除了普通的 Matplotlib,第三方软件包也被广泛用于增加 Matplotlib 的功能。在 Matplotlib 之上构建的一个有用的数据可视化库是 Seaborn。Seaborn 是一个基于 Matplotlib 的数据可视化库。它为扩展 Matplotlib 的功能提供了一个高级接口。使用 Seaborn,您可以减少生成有洞察力的图表所需的时间。
关于 Seaborn 的有用信息
-
安装命令: pip
install seaborn -
导入首选别名:
import seaborn as sns
sci kit-learn–机器学习
Scikit-learn 是一个强大的开源 Python 机器学习库,最初由 David Cournapeau 开发,作为谷歌代码之夏项目。你可以使用 scikit-learn 作为一个独立的机器学习库,并成功构建各种传统的机器学习模型。除了能够创建机器学习模型,scikit-learn 构建在 NumPy、SciPy 和 Matplotlib 之上,为预测数据分析提供了简单高效的工具。scikit-learn 有六个主要功能,如下所示:
-
分类 : Scikit-learn 提供了几种算法来识别一个对象属于哪个类别,比如支持向量机、逻辑回归、k 近邻、决策树等等。
-
回归:scikit-learn 提供的几种算法可以预测与对象相关联的连续值响应变量,例如线性回归、梯度推进、随机森林、决策树等等。
-
聚类 : Scikit-learn 还提供聚类算法,用于将相似的对象自动分组到聚类中,比如 k-means 聚类、谱聚类、均值漂移等等。
-
降维 : Scikit-learn 提供了几种算法来减少要考虑的解释变量的数量,比如 PCA、特征选择、非负矩阵分解等等。
-
模型选择 : Scikit-learn 可以帮助模型验证和比较,也可以帮助选择参数和模型。你可以将你的 TensorFlow 模型与 scikit-learn 的传统机器学习模型进行比较。网格搜索、交叉验证和指标是用于模型选择和验证功能的一些工具。
-
预处理:通过预处理、特征提取和特征缩放选项,您可以在 TensorFlow 不足的地方转换您的数据。
当我们想要将我们的深度学习模型与其他机器学习算法进行比较时,Scikit-learn 特别有用。此外,通过 scikit-learn,我们可以在将数据输入深度学习流水线之前对其进行预处理。
关于 Scikit 的有用信息-了解
-
安装命令 : pip
install scikit-learn -
导入首选别名:
from scikit-learn import *
烧瓶-部署
与前面提到的库不同,Flask 不是一个数据科学库,但它是 Python 的一个微型 web 框架。它被认为是一个微框架,因为它没有和其他 web 框架认为必不可少的组件打包在一起,比如数据库抽象层和表单验证。这些组件可以嵌入带有强大的第三方扩展的 Flask 应用程序中。这一特性使得 Flask 变得简单和轻量,并减少了开发时间。如果你想为你训练好的深度学习模型服务,又不想花太多时间在 web 编程上,Flask 是一个完美的选择。
与 Django 相反,Flask 易于学习和实现。Django 是一个非常完善的、流行的 Python web 框架。但是由于它的体积很大,内置了很多扩展包,Django 对于大型项目来说是一个更好的选择。目前,Flask 在其 GitHub repo 上的星级比 Python 的任何其他 web 框架都多,并在 2018 年 Python 开发者调查中被评为最受欢迎的 web 框架。
关于烧瓶的有用信息
-
安装命令 :
pip install flask -
导入的首选别名:
from flask import Flask, *
最终评估
在这一章中,我们将介绍 TensorFlow 最常用的补充库。我们主要使用 TensorFlow,因为它有越来越多的模块可以满足开发人员在开发过程中每一步的需求。但是,仍然有一些操作我们不得不依赖这些库。
虽然 NumPy 和 Pandas 是非常强大的数据处理库,但 Matplotlib 和 Seaborn 对于数据可视化非常有用。虽然 SciPy 帮助我们进行复杂的数学运算,但 scikit-learn 对高级预处理操作和验证任务特别有用。最后,Flask 是我们选择的 web 框架,可以快速为我们训练好的模型提供服务。
在下一章中,我们将通过实际的代码示例深入研究 TensorFlow 模块。*
五、TensorFlow 2.0 和深度学习流水线指南
在前面的章节中,我们在深入研究深度学习应用之前介绍了基础知识。
-
第一章有助于理解选择 Python 和 TensorFlow 等技术背后的原因。它还帮助我们建立了我们的环境。
-
第二章对机器学习做了一个简单的介绍,因为深度学习是机器学习的一个子领域。
-
在第三章,我们终于涵盖了深度学习的基础知识。这三章是概念性和介绍性的章节。
-
第四章总结了我们在深度学习流水线中使用的所有技术,除了一项:TensorFlow。
在本章中,我们将介绍 TensorFlow 的基础知识以及本书中使用的 API 参考。
TensorFlow Basics
本章的主要重点是我们如何将 TensorFlow 用于神经网络和模型训练,但首先,我们需要涵盖 TensorFlow 基础知识下的几个主题,它们是
-
急切执行与图形执行
-
张量洛常数
-
tensorflow 变量
急切的执行
TensorFlow 2.0 带来的一个新特性是将急切执行作为默认选项。通过快速执行,TensorFlow 计算代码中出现的张量值。急切执行简化了 TensorFlow 中的模型构建体验,您可以立即看到 TensorFlow 操作的结果。
这种转变背后的主要动机是 PyTorch 的动态计算图形能力。借助动态计算图形功能,PyTorch 用户能够遵循通过运行定义的方法,在这种方法中,您可以立即看到操作的结果。
然而,对于图形执行,TensorFlow 1.x 遵循了一种定义并运行的方法,在这种方法中,只有在我们用tf.Session包装了代码之后才会进行评估。图形执行在分布式培训、性能优化和生产部署方面具有优势。但是由于实现的困难,图形执行也把新来者驱赶到 PyTorch。因此,新来者的这一困难导致 TensorFlow 团队采用急切执行,即 TensorFlow 的按运行定义的方法,作为默认的执行方法。
在本书中,我们只使用默认的急切执行进行模型构建和训练。
张量
张量是 TensorFlow 内置的统一类型的多维数组。它们非常类似于 NumPy 数组,并且它们是不可变的,这意味着一旦创建,它们就不能被更改,并且您只能用编辑创建一个新的副本。
张量根据其维数进行分类:
-
秩-0(标量)张量:包含单个值且没有轴的张量
-
秩 1 张量:一个包含单轴中一系列值的张量
-
秩 2 张量:包含两个轴的张量
-
秩 N 张量:包含 N 轴的张量
例如,可以创建一个秩为 3 的张量,并打印出以下几行:
rank_3_tensor = tf.constant([
[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]],
[[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]],
[[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]],])
print(rank_3_tensor)
您可以使用以下功能访问关于tf.Tensor对象的详细信息:
print("Type of every element:", rank_3_tensor.dtype)
print("Number of dimensions:", rank_3_tensor.ndim)
print("Shape of tensor:", rank_3_tensor.shape)
print("Elements along axis 0 of tensor:", rank_3_tensor.shape[0])
print("Elements along the last axis of tensor:", rank_3_tensor.shape[-1])
print("Total number of elements (3*2*5): ", tf.size(rank_3_tensor).numpy())
Output:
Type of every element: <dtype: 'int32'>
Number of dimensions: 3
Shape of tensor: (3, 2, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*5): 30
有几个函数可以创建张量对象。除了tf.Constant(),我们经常使用tf.ones()和tf.zeros()函数来创建给定大小的只有 1 或 0 的张量。以下几行提供了两者的示例:
zeros = tf.zeros(shape=[2,3])
print(zeros)
Output:
tf.Tensor(
[[0\. 0\. 0.]
[0\. 0\. 0.]], shape=(2, 3), dtype=float32)
ones = tf.ones(shape=[2,3])
print(ones)
Output:
tf.Tensor(
[[1\. 1\. 1.]
[1\. 1\. 1.]], shape=(2, 3), dtype=float32)
基本的tf.Tensor类要求张量是矩形的,这意味着沿着每个轴,每个元素都有相同的大小。然而,有一些特殊类型的张量可以处理不同的形状:
-
不规则张量:沿某轴具有可变数量元素的张量
-
稀疏张量:一种数据稀疏的张量,就像一个非常宽的嵌入空间
可变的
TensorFlow 变量是表示共享的持久状态的推荐方法,您可以使用模型来操作该状态。TensorFlow 变量被记录为一个tf.Variable对象。一个tf.Variable对象代表一个值可以改变的张量,与普通的 TensorFlow 常数相反。tf.Variable对象用于存储模型参数。
TensorFlow 变量与 TensorFlow 常量非常相似,但有一个显著的区别:变量是可变的。因此,可变对象的值可以改变(例如,用assign()函数)以及可变对象的形状也可以改变(例如,用reshape()函数)。
您可以使用以下代码创建一个基本变量:
a = tf.Variable([2.0, 3.0])
您也可以使用现有的常数来创建变量:
my_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])
my_variable = tf.Variable(my_tensor)
print(my_variable)
Output:
<tf.Variable 'Variable:0' shape=(2, 2) dtype=float32, numpy=
array([[1., 2.],
[3., 4.]], dtype=float32)>
您可以使用tensor.numpy()函数将 TensorFlow 变量对象或 TensorFlow 张量对象转换为 NumPy 数组,如下所示:
my_variable.numpy()
my_tensor.numpy()
这些是 TensorFlow 中的一些基本概念。现在,我们可以继续使用 TensorFlow 进行模型构建和数据处理。
TensorFlow 深度学习流水线
在第二章的最后一节,我们列出了一个完整的机器学习流水线的步骤(即获得经过训练的机器学习模型的步骤)。在深度学习模型中,我们几乎只使用相同的流水线,其中有大量 TensorFlow 的工作。图 5-1 显示了我们的流水线是如何工作的(请注意,您可能会遇到不同来源的细微变化)。
图 5-1
用 TensorFlow 构建的深度学习流水线
在接下来的部分中,我们将通过代码示例来介绍这些步骤。请注意,数据收集步骤将被省略,因为它通常被视为一项单独的任务,通常不由机器学习专家来执行。
数据加载和准备
在建立和训练神经网络之前,深度学习的第一步是加载你的数据,处理它,并将其馈送给神经网络。我们在下一章讨论的所有神经网络都需要数据,为此,我们需要以正确的格式输入数据。我们的 TensorFlow 模型接受几种对象类型,如下所示:
-
TensorFlow 数据集对象
-
TensorFlow 数据集目录
-
NumPy 数组对象
-
熊猫数据帧对象
让我们深入了解如何使用它们。
数据集对象(tf.data.Dataset)
TensorFlow 数据集对象表示一大组元素(即数据集)。tf.data.Dataset API 是 TensorFlow 接受的模型输入对象之一,用于训练并专门为输入流水线设计。
您可以将数据集 API 用于以下目的:
-
根据给定的数据创建数据集。
-
使用集合函数(如地图)转换数据集。
-
迭代数据集并处理单个元素。
Dataset API 支持各种文件格式和 Python 对象,可以用来创建tf.data.Dataset对象。让我们来看看这些受支持的文件格式和对象:
-
来自 Python 列表、NumPy 数组、Pandas DataFrame 和
from_tensor_slices函数的数据集 -
使用
TextLineDataset函数从文本文件中获取数据集
ds = tf.data.Dataset.from_tensor_slices([1, 2, 3])
ds = tf.data.Dataset.from_tensor_slices(numpy_array)
ds = tf.data.Dataset.from_tensor_slices(df.values)
- 来自 TensorFlow 的 TFRecord 格式的数据集,带有
TFRecordDataset函数
ds = tf.data.TextLineDataset("file.txt")
- 包含以下内容的 CSV 文件中的数据集
ds = tf.data.TFRecordDataset("file.tfrecord")
- 来自 TensorFlow 数据集目录的数据集:这将在下一节中介绍。
ds = tf.data.experimental.make_csv_dataset( "file.csv", batch_size=5)
TensorFlow 数据集目录
TensorFlow 数据集是由 TensorFlow 维护的流行数据集的集合。他们通常是干净的,随时可以使用。
装置
TensorFlow 数据集存在于两个包中:
-
稳定版,每几个月更新一次
-
tfds-nightly:每夜发布的版本,包含数据集的最新版本
正如您从名称中可以理解的那样,您可以使用稳定版本,它更新的频率较低,但更可靠,也可以使用每夜发布的版本,它提供对数据集最新版本的访问。但是请注意,由于频繁的发布,tfds-nightly更容易崩溃,因此不建议在生产级项目中使用。
如果您的系统上没有,您可以使用以下命令行脚本安装这些软件包:
pip install tensorflow_datasets
pip install tfds-nightly
进口
这些包是通过tensorflow_datasets加载的,通常缩写为tfds。为了能够导入这些包,您只需运行一行代码,如下所示:
import tensorflow_datasets as tfds
数据集目录
导入主库后,我们可以使用加载功能导入 TensorFlow 数据集目录页面中列出的常用库之一,该页面可在上访问
www.tensorflow.org/datasets/catalog/overview
在此目录下,您可能会找到几十个数据集,它们属于以下列出的组之一:
-
声音的
-
图像
-
图像分类
-
目标检测
-
问题回答
-
结构化的
-
摘要
-
文本
-
翻译
-
录像
加载数据集
从 TensorFlow 数据集目录加载数据集的最简单方法是使用加载函数。该功能将
-
下载数据集。
-
将其保存为
TFRecord文件。 -
将
TFRecord文件加载到您的笔记本上。 -
创建一个
tf.data.Dataset对象,可以用来训练一个模型。
以下示例显示了如何使用 load 函数加载数据集:
mnist_dataset = tfds.load(‘mnist’, split=‘train’)
您可以通过设置加载函数的特定参数来自定义加载过程:
-
split :控制加载数据集的哪一部分
-
shuffle_files :控制是否在每个历元之间对文件进行洗牌
-
data_dir :控制数据集保存的位置
-
with_info :控制是否加载
DatasetInfo对象
在接下来的章节中,我们将在很大程度上利用这个目录。
硬数据集
除了 TensorFlow 数据集目录,Keras 还提供对其目录中列出的有限数量的数据集的访问,可通过 https://keras.io/api/datasets/ 访问。该目录下可访问的数据集有
-
梦妮丝
-
CIFAR10
-
cifar 100 足球俱乐部
-
IMDB 电影评论
-
路透社通讯社
-
时尚 MNIST
-
波士顿住房公司
如你所见,这个目录非常有限,但在你的研究项目中会派上用场。
您可以使用load_data()函数从 Keras API 加载数据集,如下所示:
(x_train, y_train), (x_test, y_test)= tf.keras.datasets.mnist.load_data( path="mnist.npz" )
Keras 数据集与 TensorFlow 数据集的一个重要区别是,它们是作为 NumPy 数组对象导入的。
NumPy 阵列
TensorFlow 接受作为输入数据的数据类型之一是 NumPy 数组。如前一章所述,您可以用下面一行导入 NumPy 库:
import numpy as np
可以用np.array()函数创建一个 NumPy 数组,可以馈入 TensorFlow 模型。您还可以使用一个函数,比如np.genfromtxt(),从 CSV 文件中加载数据集。
实际上,我们很少使用 NumPy 函数来加载数据。对于这个任务,我们经常利用 Pandas 库,它几乎是一个 NumPy 扩展。
熊猫数据框
TensorFlow 和 NumPy 数组也接受 Pandas 数据帧和系列对象。熊猫和熊猫之间有很强的联系。为了处理和清理我们的数据,熊猫经常提供更强大的功能。然而,NumPy 数组通常更有效,并在更大程度上被其他库所识别。例如,您可能需要使用 scikit-learn 来预处理您的数据。Scikit-learn 将接受 Pandas 数据帧和 NumPy 数组,但只返回 NumPy 数组。因此,一个机器学习专家必须学会使用这两个库。
您可以导入 Pandas 库,如下所示:
import pandas as pd
您可以轻松地从 CSV、Excel 和 text 等不同格式的文件中加载数据集,如下所示:
-
CSV 文件 :
pd.read_csv("path/xyz.csv") -
Excel 文件 :
pd.read_excel("path/xyz.xlsx") -
文本文件 :
pd.read_csv("path/xyz.txt") -
HTML 文件 :
pd.read_html("path/xyz.html")或pd.read_html('URL')
从这些不同的文件格式中加载数据集后,Pandas 为您提供了大量不同的功能,您还可以使用pandas.DataFrame.head()或pandas.DataFrame.tail()函数检查数据处理操作的结果。
其他对象
随着 TensorFlow 新版本的推出,支持的文件格式数量也在增加。此外,TensorFlow I/O 是一个扩展库,通过其 API 进一步扩展了受支持库的数量。虽然我们前面提到的受支持的对象和文件格式已经足够了,但是如果您对其他格式感兴趣,可以访问 TensorFlow I/O 的官方 GitHub 存储库
TensorFlow I/O: https://github.com/tensorflow/io#tensorflow-io
模型结构
在加载和处理数据集之后,下一步是建立深度学习模型进行训练。我们有两个主要选项来构建模型:
-
响亮的接口
-
估计器 API
在本书中,我们只使用 Keras API,因此,重点放在用 Keras API 构建模型的不同方式上。
响亮的接口
如前几章所述,Keras 是 TensorFlow 的补充库。此外,tensor flow–2.0 版–采用 Keras 作为内置 API 来构建模型和实现附加功能。
TensorFlow 2.x 下的 Keras API 提供了三种不同的方法来实现神经网络模型:
-
顺序 API
-
功能 API
-
模型子类化
下面我们来看看每种方法。
顺序 API
Keras Sequential API 允许您逐步构建神经网络。您可以创建一个Sequential()模型对象,并且可以在每一行添加一个层。
使用 Keras Sequential API 是构建模型的最简单的方法,但需要付出代价:有限定制。尽管您可以在几秒钟内构建一个顺序模型,但是顺序模型不提供某些功能,例如(I)层共享,(ii)多个分支,(iii)多个输入,以及(iv)多个输出。当我们有一个带有一个输入张量和一个输出张量的简单层叠时,顺序模型是最佳选择。
使用 Keras Sequential API 是构建神经网络的最基本的方法,这对于接下来的许多章节来说已经足够了。但是,要构建更复杂的模型,我们需要使用 Keras Functional API 和模型子类化选项。
使用 Keras Sequential API 构建一个基本的前馈神经网络可以通过以下代码实现:
model = Sequential()
model.add(Flatten(input_shape=(28, 28)))
model.add(Dense(128,'relu'))
model.add(Dense(10, "softmax"))
或者,我们可以将一个层列表传递给顺序构造函数:
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(128,'relu'),
Dense(10, "softmax"),
])
一旦构建了顺序模型,它的行为就像一个功能 API 模型,为每一层提供一个输入属性和一个输出属性。
在我们的案例研究中,我们利用其他属性和函数,如model.layers和model.summary()来理解我们的神经网络的结构。
功能 API
Keras Functional API 是一个更健壮且稍微复杂的 API,用于使用 TensorFlow 构建强大的神经网络。我们用 Keras Functional API 创建的模型比我们用 Keras Sequential API 创建的模型更灵活。它们可以处理非线性拓扑、共享层,并且可以有多个分支、输入和输出。
Keras Functional API 方法源于这样一个事实,即大多数神经网络是层的有向无环图(DAG)。因此,Keras 团队开发了 Keras Functional API 来设计这种结构。Keras Functional API 是构建图层图表的好方法。
为了用 Keras Functional API 创建一个神经网络,我们创建一个输入层并将其连接到第一层。下一层与上一层相连,以此类推。最后,Model对象将输入和连接的层堆栈作为参数。
Keras 顺序 API 中的示例模型可以使用 Keras 功能 API 来构建,如下所示:
inputs = tf.keras.Input(shape=(28, 28))
x = Flatten()(inputs)
x = Dense(128, "relu")(x)
outputs = Dense(10, "softmax")(x)
model = tf.keras.Model(inputs=inputs,
outputs=outputs,
name="mnist_model")
就像在 Keras Sequential API 中一样,我们可以使用 layers 属性,summary()函数。此外,我们还可以用下面这条线将模型绘制成图形:
tf.keras.utils.plot_model(model)
模型和层子类化
模型子类化是最先进的 Keras 方法,它给了我们无限的灵活性,可以从零开始构建神经网络。您也可以使用层子类化来构建自定义层(即模型的构建块),您可以在神经网络模型中使用这些自定义层。
通过模型子类化,我们可以构建定制的神经网络来进行训练。Keras 模型类内部是用于定义模型架构的根类。
模型子类化的好处是它是完全可定制的,而它的缺点是实现困难。因此,如果您试图构建奇异的神经网络或进行研究级别的研究,那么模型子类化方法是一条可行之路。但是,如果您可以使用 Keras 顺序 API 或 Keras 功能 API 来完成您的项目,您就不应该为模型子类化而烦恼。
您看到的前面的例子可以用模型子类化来重写,如下所示:
class CustomModel(tf.keras.Model):
def __init__(self, **kwargs):
super(CustomModel, self).__init__(**kwargs)
self.layer_1 = Flatten()
self.layer_2 = Dense(128, "relu")
self.layer_3 = Dense(10, "softmax")
def call(self, inputs):
x = self.layer_1(inputs)
x = self.layer_2(x)
x = self.layer_3(x)
return x
model = CustomModel(name=' mnist_model')
模型子类化有两个关键功能:
-
__init__函数作为一个构造函数。多亏了__init__,我们可以初始化模型的属性(例如,层)。 -
super函数用于调用父构造函数(tf.keras.Model)。 -
self对象用于引用实例属性(如层)。 -
call功能是在__init__功能中定义层后定义操作的地方。
在前面的示例中,我们在 init 函数下定义了密集层,然后将它们创建为对象,并构建了我们的模型,类似于我们使用 Keras Functional API 构建神经网络的方式。但是请注意,您可以在模型子类化中构建您的模型。
我们可以通过使用自定义类(自定义模型)生成一个对象来完成我们的模型构建,如下所示:
model = CustomModel(name='mnist_model')
我们在第 10 和 11 章中使用模型子类化。
估计器 API
Estimator API 是一个高级 TensorFlow API,它封装了以下功能:
-
培养
-
估价
-
预报
-
出口供食用
我们可以利用各种预制的估算器,也可以用估算器 API 编写自己的模型。Estimator API 比 Keras APIs 有一些优势,比如基于参数服务器的训练和完全的 TFX 集成。然而,Keras APIs 将很快具备这些功能,这使得 Estimator API 成为可选的。
这本书不包括案例研究中的评估者 API。因此,我们不赘述。但是,如果您有兴趣了解有关估算器 API 的更多信息,请访问位于 www.tensorflow.org/guide/estimator 的 TensorFlow 估算器 API 指南。
编译、训练和评估模型并进行预测
编译是深度学习模型训练的重要部分,其中我们定义了我们的(I)优化器,(ii)损失函数,以及其他参数,例如(iii)回调。另一方面,训练是我们开始将输入数据输入到模型中的步骤,以便模型可以学习推断隐藏在数据集中的模式。评估是我们检查我们的模型的常见深度学习问题(如过拟合)的步骤。
有两种方法来编译、训练和评估我们的模型:
-
使用标准方法
-
编写自定义训练循环
标准方法
当我们遵循标准训练方法时,我们可以受益于以下功能:
-
model.compile() -
model.fit() -
model.evaluate() -
model.predict()
模型.编译( )
model.compile()是我们在训练之前设置优化器、损失函数和性能指标的函数。这是一个非常简单的步骤,只用一行代码就可以完成。另外,请注意,有两种方法可以在model.compile()函数中传递损失函数和优化器参数,举例如下:
-
选项 1 :将参数作为字符串传递
-
选项 2 :将参数作为 TensorFlow 对象传递
model.compile(
optimizer='adam',
loss=mse,
metrics=['accuracy'])
model.compile(
optimizer=tf.keras.optimizers.Adam() ,
loss=tf.keras.losses.MSE(),
metrics=[tf.keras.metrics.Accuracy()])
将损失函数、指标和优化器作为对象传递比选项 1 更灵活,因为我们还可以在对象中设置参数。
【计算机】优化程序
TensorFlow 支持的优化器算法如下:
-
阿达德尔塔
-
阿达格拉德
-
圣经》和《古兰经》传统中)亚当(人类第一人的名字
-
阿达玛斯
-
稀疏性
-
那达慕
-
RMSProp
-
签名于
最新列表可在以下网址找到:
www.tensorflow.org/api_docs/python/tf/keras/optimizers
您可以通过tf.keras.optimizers模块选择一个优化器。
损失函数
在开始训练之前,必须设置的另一个重要参数是损失函数。tf.keras.losses模块支持许多适用于分类和回归任务的损失函数。完整列表可在以下网址找到:
www.tensorflow.org/api_docs/python/tf/keras/losses
model.fit()
model.fit()为固定数量的历元(数据集上的迭代)训练模型。它需要几个参数,比如 epochs、callbacks 和 shuffle,但是它还必须接受另一个参数:我们的数据。根据问题的不同,这些数据可能是(I)仅要素或(ii)要素和标签。model.fit()功能的使用示例如下:
model.fit(train_x, train_y, epochs=50)
模型.评估( )
model.evaluate()函数使用测试数据集返回模型的损失值和度量值。它返回的内容和接受的参数类似于model.fit()函数,但是它不再进一步训练模型。
model.evaluate(test_x, test_y)
模型.预测( )
model.predict()是我们用来做单项预测的函数。model.evaluate()功能需要标签,而model.predict()功能不需要标签。它只是使用训练好的模型进行预测,如下所示:
model.evaluate(sample_x)
定制培训
您可以完全定制该流程,而不是遵循允许您使用model.compile()、model.fit()、model.evaluate()和model.predict()等功能的标准培训选项。
为了能够定义一个定制的训练循环,你必须使用一个tf.GradientTape()。tf.GradientTape()记录自动微分的操作,这对于训练时实现反向传播等机器学习算法非常有用。换句话说,tf.GradientTape()允许我们追踪 TensorFlow 计算和计算梯度。
对于定制培训,我们遵循以下步骤:
-
设置优化器、损失函数和指标。
-
运行一个 for 循环来计算历元数。
-
对每个时期的每个批次运行嵌套循环:
-
与
tf.GradientTape()一起计算和记录损失,并进行反向传播。 -
运行优化程序。
-
计算、记录和打印指标结果。
-
以下几行显示了标准培训方法的示例。只需两行代码,您就可以配置和训练您的模型。
model.compile(optimizer=Adam(), loss=SCC(from_logits=True), metrics=[SCA()])
model.fit(x_train, y_train, epochs=epochs)
另一方面,下面几行显示了如何使用定制的训练循环获得相同的结果。
# Instantiate optimizer, loss, and metric
optimizer, loss_fn, accuracy = Adam(), SCC(from_logits=True), SCA()
# Convert NumPy to TF Dataset object
train_dataset = (Dataset.from_tensor_slices((x_train, y_train)).shuffle(buffer_size=1024).batch(batch_size=64))
for epoch in range(epochs):
# Iterate over the batches of the dataset.
for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
# Open a GradientTape to record the operations, which enables auto-differentiation.
with tf.GradientTape() as tape:
# The operations that the layer applies to its inputs are going to be recorded
logits = model(x_batch_train, training=True)
loss_value = loss_fn(y_batch_train, logits)
# Use the tape to automatically retrieve the gradients of the trainable variables
grads = tape.gradient(loss_value, model.trainable_weights)
# Run one step of gradient descent by updating
# the value of the variables to minimize the loss.
optimizer.apply_gradients(zip(grads, model.trainable_weights))
# Metrics related part
accuracy.update_state(y_batch_train, logits)
if step % int(len(train_dataset)/5) == 0: #Print out
print(step, "/", len(train_dataset)," | ",end="")
print("\rFor Epoch %.0f, Accuracy: %.4f" % (epoch+1, float(accuracy.result()),))
accuracy.reset_states()
如您所见,这要复杂得多,因此,您应该只在绝对必要时使用定制培训。您也可以自定义个人训练步骤、model.evaluate()功能,甚至model.predict()功能。因此,TensorFlow 几乎总是为研究人员和定制模型开发人员提供足够的灵活性。在本书中,我们利用了第十二章中的定制培训。
保存和加载模型
我们刚刚学习了如何建立一个神经网络,这些信息对于接下来章节的案例研究至关重要。但是我们也想在现实世界的应用中使用我们训练的模型。因此,我们需要保存我们的模型,以便它可以被重用。
我们可以将整个模型保存到一个工件中。当我们保存整个模型时,它包含
-
模型的架构和配置数据
-
模型的优化权重
-
模型的编译信息(
model.compile()info) -
优化程序及其最新状态
TensorFlow 提供了两种保存模型的格式:
-
tensorflow 存储模型格式
-
Keras HDF5(或 H5)格式
虽然以前旧的 HDF5 格式非常流行,但 SavedModel 已经成为 TensorFlow 中保存模型的推荐格式。HDF5 和 SavedModel 的关键区别在于,HDF5 使用对象配置来保存模型架构,而 SavedModel 保存执行图。这种差异的实际后果是显著的。SavedModels 可以保存定制对象,例如用模型子类化构建的模型或没有原始代码的定制层。为了能够以 HDF5 格式保存自定义对象,需要额外的步骤,这使得 HDF5 不那么吸引人。
保存模型
以其中一种格式保存模型非常容易。可以通过在model.save()函数中传递一个参数(save_format)来选择所需的格式。
要以 SavedModel 格式保存模型,我们可以使用下面一行:
model.save("My_SavedModel")
如果您想以 HDF5 格式保存您的模型,我们可以简单地使用带有save_format参数的相同函数:
model.save("My_H5Model", save_format="h5")
对于 HDF5 格式,您也可以使用 Keras 的save_model()函数,如下所示:
tf.keras.models.save_model("My_H5Model")
保存模型后,包含模型的文件可以在您的临时 Google Colab 目录中找到。
加载模型
保存模型文件后,您可以轻松地加载和重建之前保存的模型。为了加载我们的模型,我们使用 Keras API 提供的load_model()函数。以下代码行可用于加载以任一格式保存的模型:
import tensorflow as tf
reconstructed_model = tf.keras.models.load_model( 'My_SavedModel' )
您可以使用加载的模型,就像使用您训练的模型一样。以下几行是用于新训练模型的model.evaluate()函数的精确副本:
test_loss, test_acc = reconstructed_model.evaluate( x_test, y_test, verbose=2)
print('\nTest accuracy:', test_acc)
结论
既然我们已经介绍了如何将 TensorFlow 用于我们的深度学习流水线以及一些 TensorFlow 基础知识,我们可以开始介绍不同类型的神经网络概念及其相应的案例研究。我们的第一个神经网络类型是前馈神经网络,或者换句话说,多层感知器。