提交 435eacd3 编写于 作者: W wizardforcel

2020-12-17 22:29:39

上级 25e823c5
......@@ -18,7 +18,7 @@
# 这本书适合谁
本书适用于希望构建现实人工智能应用的 Python 开发人员。 这本书对 Python 初学者很友好,但是熟悉 Python 对于玩弄代码很有帮助。 对于希望在现有技术栈中使用人工智能技术的经验丰富的 Python 程序员而言,它也将很有用。
本书适用于希望构建现实人工智能应用的 Python 开发人员。 这本书对 Python 初学者很友好,但是熟悉 Python 对于玩弄代码很有帮助。 对于希望在现有技术栈中使用人工智能技术的经验丰富的 Python 程序员而言,它也将很有用。
# 这本书涵盖的内容
......@@ -36,7 +36,7 @@
第 4 章,“特征选择和特征工程”
通过选择正确的尺寸传递给模型以及发现可以丰富输入数据集的新尺寸,可以提高模型表现。 本章将说明如何从现有特征以及外部资源创建新特征。 它还将介绍如何消除冗余或低值的特征。
通过选择正确的大小传递给模型以及发现可以丰富输入数据集的新大小,可以提高模型表现。 本章将说明如何从现有特征以及外部资源创建新特征。 它还将介绍如何消除冗余或低值的特征。
第 5 章,“使用监督学习的分类和回归”
......
......@@ -274,7 +274,7 @@ $ python3 --version
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
让我们更新程序包管理器:
让我们更新包管理器:
```py
$ brew update
......
......@@ -117,7 +117,7 @@ Uber 的**先进技术小组**(**ATG**)是 Uber 的子公司,致力于开
亚马逊的分拣设施是在人类,计算机和机器人之间形成的共生关系的最好例子之一。 计算机接受客户订单并决定将商品路由到何处,机器人充当搬运工,在仓库中搬运托盘和库存。 人们通过手动挑选进入每个订单的物品来解决“最后一英里”问题。 机器人熟练地无意识地重复执行多次任务,只要涉及到某种模式并且要进行一定程度的预训练就可以做到。 但是,让机器人捡起 20 磅重的包装,然后立即能够抓鸡蛋而不破鸡蛋,这是机器人技术难题之一。
机器人在处理不同大小,重量,形状和易碎性的物体时会遇到困难。 许多人可以轻松完成的任务。 因此,人们要处理机器人遇到的困难的任务。 这三种类型的不同演员之间的相互作用转化为一个经过微调的乐团,该乐团每天可以交付数百万个程序包而几乎没有错误。
机器人在处理不同大小,重量,形状和易碎性的物体时会遇到困难。 许多人可以轻松完成的任务。 因此,人们要处理机器人遇到的困难的任务。 这三种类型的不同演员之间的相互作用转化为一个经过微调的乐团,该乐团每天可以交付数百万个包而几乎没有错误。
甚至亚马逊机器人实现总监斯科特·安德森(Scott Anderson)在 2019 年 5 月都承认,距离全自动仓库至少有 10 年的路程。 因此,我们将继续在世界各地的仓库中看到这种配置一段时间。
......@@ -252,8 +252,8 @@ Pandora 是领先的音乐服务之一。 与 Apple 和 Amazon 等其他公司
Pandora 的推荐器基于多个层次:
* 首先,他们的音乐专家团队会根据流派,节奏和进度来注释歌曲。
* 这些注释被转换为用于比较歌曲相似度的向量。 这种方法促进了来自未知艺术家的“长尾巴”或晦涩音乐的呈现,尽管如此,它仍然可能适合个人听众。
* 首先,他们的音乐专家团队会根据流派,节奏和进度来标注歌曲。
* 这些标注被转换为用于比较歌曲相似度的向量。 这种方法促进了来自未知艺术家的“长尾巴”或晦涩音乐的呈现,尽管如此,它仍然可能适合个人听众。
* 该服务也高度依赖用户反馈,并使用它不断增强服务。 Pandora 收集了超过 750 亿个关于收听者偏好的反馈数据点。
* 然后,潘多拉(Pandora)推荐引擎可以使用收听者的先前选择,地理位置和其他人口统计数据,根据收听者的偏好执行个性化过滤。
......@@ -306,7 +306,7 @@ iRobot 于 1990 年由 Rodney Brooks,Colin Angle 和 Helen Greiner 在麻省
**收拾烂摊子**
正如我们在运输用途案例中了解到的一样,挑选具有不同重量,尺寸和形状的物体是最困难的自动化任务之一。 机器人可以在均匀的条件下(例如工厂车间,某些机器人专门从事某些任务)高效地执行任务。 然而,在拾起椅子之后拾起一双鞋可能是巨大的挑战,而且代价昂贵。 因此,不要指望机器很快就会以具有成本效益的方式普及这种家庭杂务。
正如我们在运输用途案例中了解到的一样,挑选具有不同重量,大小和形状的物体是最困难的自动化任务之一。 机器人可以在均匀的条件下(例如工厂车间,某些机器人专门从事某些任务)高效地执行任务。 然而,在拾起椅子之后拾起一双鞋可能是巨大的挑战,而且代价昂贵。 因此,不要指望机器很快就会以具有成本效益的方式普及这种家庭杂务。
**私人厨师**
......@@ -401,7 +401,7 @@ Google 的 AlphaZero 研究团队的科学家在 2017 年创建了一个系统
有一个强大的程序示例,它可以玩由 DeepMind 开发的名为 AlphaGo 的 Go 游戏。 AlphaGo 还有三个功能更强大的继任者,分别称为 AlphaGo Master,AlphaGo Zero 和 AlphaZero。
2015 年 10 月,原始的 AlphaGo 成为第一个在全尺寸 19 x 19 板上击败无障碍职业人类围棋选手的计算机围棋程序。 2016 年 3 月,它在五场比赛中击败了李·塞多尔。 这成为围棋程序第一次击败没有障碍的 9 杆专业运动员。 尽管 AlphaGo 在第四局中输给 Lee Sedol,但 Lee 在最后一场比赛中辞职,最终比分是 4 比 1。
2015 年 10 月,原始的 AlphaGo 成为第一个在全大小 19 x 19 板上击败无障碍职业人类围棋选手的计算机围棋程序。 2016 年 3 月,它在五场比赛中击败了李·塞多尔。 这成为围棋程序第一次击败没有障碍的 9 杆专业运动员。 尽管 AlphaGo 在第四局中输给 Lee Sedol,但 Lee 在最后一场比赛中辞职,最终比分是 4 比 1。
在 2017 年未来围棋峰会上,AlphaGo 的继任者 AlphaGo Master 在三场比赛中击败了大师 Kejie。 柯洁当时被评为世界排名第一的选手。 此后,AlphaGo 被中国围棋协会授予专业 9 段。
......
......@@ -157,7 +157,7 @@
* 合并
* 存储
云提供商已成为主要的数据科学平台。 一些最受欢迎的栈是围绕以下构建的:
云提供商已成为主要的数据科学平台。 一些最受欢迎的栈是围绕以下构建的:
* Azure ML 服务
* AWS SageMaker
......
# 4 特征选择和特征工程
特征选择(也称为变量选择,属性选择或变量子集选择)是一种用于从初始数据集中选择特征子集(变量,尺寸)的方法。 特征选择是构建机器学习模型过程中的关键步骤,并且可能对模型的表现产生巨大影响。 使用正确且相关的特征作为模型的输入还可以减少过拟合的机会,因为拥有更多相关的特征会减少模型使用不添加信号作为输入的嘈杂特征的机会。 最后,减少输入特征会减少训练模型所需的时间。 学习选择哪些特征是数据科学家开发的一项技能,通常仅来自数月和数年的经验,并且可以说是一门艺术,而不是一门科学。 特征选择很重要,因为它可以:
特征选择(也称为变量选择,属性选择或变量子集选择)是一种用于从初始数据集中选择特征子集(变量,大小)的方法。 特征选择是构建机器学习模型过程中的关键步骤,并且可能对模型的表现产生巨大影响。 使用正确且相关的特征作为模型的输入还可以减少过拟合的机会,因为拥有更多相关的特征会减少模型使用不添加信号作为输入的嘈杂特征的机会。 最后,减少输入特征会减少训练模型所需的时间。 学习选择哪些特征是数据科学家开发的一项技能,通常仅来自数月和数年的经验,并且可以说是一门艺术,而不是一门科学。 特征选择很重要,因为它可以:
* 缩短训练时间
* 简化模型并使它们更易于解释
......@@ -27,7 +27,7 @@
* 减少输入特征的多重共线性将使机器学习模型参数更易于解释。 *多重共线性*(也*共线性*)是在数据集中的特征中观察到的现象,在该数据集中可以从另一个模型的特征中线性预测另一个预测器特征,并且准确性很高。
* 减少运行模型所需的时间和模型所需的存储空间,将使我们能够运行模型的更多变体,从而带来更快更好的结果。
* 模型需要的输入特征越少,说明它就越容易。 当特征数量增加时,模型的可解释性下降。 减少输入要素的数量还可以简化为较小尺寸(例如 2D 或 3D)时可视化数据的过程。
* 模型需要的输入特征越少,说明它就越容易。 当特征数量增加时,模型的可解释性下降。 减少输入要素的数量还可以简化为较小大小(例如 2D 或 3D)时可视化数据的过程。
* 随着维数的增加,可能的配置呈指数增加,而观测值覆盖的配置数则减少。 随着您具有描述目标的更多特征,您也许可以更精确地描述数据,但是您的模型将不会使用新的数据点进行泛化-您的模型将过拟合数据。 这就是*维度诅咒*
让我们通过一个例子直观地思考一下。 美国有一个房地产网站,允许房地产经纪人和房主列出出租房屋或出售房屋。 Zillow 因其 Zestimate 而闻名。 Zestimate 是使用机器学习的估计价格。 Zillow 估计,如果今天将其投放市场,房屋将要出售的价格。 Zestimates 会不断更新和重新计算。 Zillow 如何得出这个数字? 如果您想了解更多,可以在 Kaggle 上进行一场比赛,该比赛在 Zestimate 上有很多资源。 [你可以在这里查询更多详情](https://www.kaggle.com/c/zillow-prize-1)
......
......@@ -621,11 +621,11 @@ plt.show()
targets = ['Class-0', 'Class-1', 'Class-2', 'Class-3', 'Class-4'] print('\n', classification_report(true_labels, pred_labels, target_names=targets))
```
分类报告打印每个班级的表现。 如果运行代码,您将看到以下屏幕截图:
分类报告打印每个类别的表现。 如果运行代码,您将看到以下屏幕截图:
![](img/B15441_05_07.png)
图 7:分类报告中每个班级的表现
图 7:分类报告中每个类别的表现
白色表示较高的值,而黑色表示较低的值,如在图像右侧的颜色图键上所示。 在理想情况下,对角正方形将全为白色,其他所有区域均为黑色。 这表示 100% 的准确性。
......
......@@ -877,7 +877,7 @@ print("Predicted traffic:", int(regressor.predict([test_datapoint_encoded])[0]))
在本章中,我们学习了集成学习及其在现实世界中的使用方式。 我们讨论了决策树以及如何基于决策树构建分类器。
我们了解了随机森林和极随机森林,它们是由多个决策树组成的。 我们讨论了如何基于它们构建分类器。 我们了解了如何估计预测的置信度。 我们还学习了如何处理班级失衡问题。
我们了解了随机森林和极随机森林,它们是由多个决策树组成的。 我们讨论了如何基于它们构建分类器。 我们了解了如何估计预测的置信度。 我们还学习了如何处理类别失衡问题。
我们讨论了如何找到最佳训练参数以使用网格搜索来构建模型。 我们学习了如何计算相对特征的重要性。 然后,我们将集成学习技术应用于一个实际问题,在该问题中,我们使用一个非常随机的森林回归量来预测流量。
......
......@@ -451,7 +451,7 @@ skf.get_n_splits(X, y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=0)
```
提取训练数据中的班级数量:
提取训练数据中的类别数量:
```
# Extract the number of classes
......
......@@ -223,7 +223,7 @@ import logpy.core as lc
from sympy.ntheory.generate import prime, isprime
```
接下来,定义一个函数,该函数根据数据类型检查给定数字是否为质数。 如果是数字,则很简单。 如果它是一个变量,那么我们必须运行顺序操作。 为了提供一些背景知识,方法`conde`是一个目标构造函数,提供逻辑 AND 和 OR 运算。
接下来,定义一个函数,该函数根据数据类型检查给定数字是否为质数。 如果是数字,则很简单。 如果它是一个变量,那么我们必须运行顺序操作。 为了提供一些背景知识,方法`conde`是一个目标构造,提供逻辑 AND 和 OR 运算。
方法`condeseq`类似于`conde`,但是它支持目标的通用迭代:
......
......@@ -27,7 +27,7 @@
通常,解决给定问题的选项太多,以至于无法开发单个算法来找到确定的最佳解决方案。 同样,不可能通过所有解决方案,因为这过于昂贵。 在这种情况下,我们依靠经验法则,通过消除明显错误的选项来帮助我们缩小搜索范围。 这个经验法则称为,称为**启发式**。 使用启发式搜索指导搜索的方法称为**启发式搜索**
启发式技术之所以强大,是因为它们可以加快过程。 即使启发式方法无法消除某些选项,也将有助于订购 t 软管选项,以便可能首先提出更好的解决方案。 如前所述,启发式搜索在计算上可能会很昂贵。 现在,我们将学习如何使用*快捷方式**修剪*搜索树。
启发式技术之所以强大,是因为它们可以加快过程。 即使启发式方法无法消除某些选项,也将有助于排序选项,以便可能首先提出更好的解决方案。 如前所述,启发式搜索在计算上可能会很昂贵。 现在,我们将学习如何使用*快捷方式**修剪*搜索树。
## 不知情或知情的搜索
......
......@@ -40,7 +40,7 @@
使用预定义的**适应度函数**确定个体的*适应度*。 短语*适者生存*发挥作用。
然后,我们选择这些选定的个体,并通过重组和突变创建下一代个体。 我们将在下一部分中讨论重组和突变的概念。 现在,让我们将这些技术视为通过将选定的个体视为父来创造下一代的机制。
然后,我们选择这些选定的个体,并通过重组和突变创建下一代个体。 我们将在下一部分中讨论重组和突变的概念。 现在,让我们将这些技术视为通过将选定的个体视为父来创造下一代的机制。
一旦执行重组和突变,我们将创建一组新的个体,这些个体将与旧个体竞争下一代的位置。 通过抛弃最弱的个体并用后代代替它们,我们正在提高总体的整体适应水平。 我们继续进行迭代,直到达到所需的总体适应性。
......@@ -60,7 +60,7 @@
*突变*是实现此目的的一种方法。 遗传算法对当前的一个或多个个体进行随机更改,以产生新的候选解。 这种变化称为突变。 现在,这种变化可能会使该个体变得比现有个体更好或更糟。
需要定义的下一个概念是*重组*,也称为*交叉*。 这与繁殖在进化过程中的作用直接相关。 GA 试图将当前一代的个体合并起来,以创建新的解决方案。 它结合了每个父个体的一些特征来创造这个后代。 此过程称为交叉。 目标是用总体中“钳工”个体产生的后代代替当前一代中的“较弱”个体。
需要定义的下一个概念是*重组*,也称为*交叉*。 这与繁殖在进化过程中的作用直接相关。 GA 试图将当前一代的个体合并起来,以创建新的解决方案。 它结合了每个父个体的一些特征来创造这个后代。 此过程称为交叉。 目标是用总体中“钳工”个体产生的后代代替当前一代中的“较弱”个体。
为了应用交叉和突变,我们需要选择标准。 *选择的概念*受自然选择理论的启发。 在每次迭代期间,GA 都会执行选择过程。 优胜劣汰的个体使用此选择过程进行选择,较弱的个体被终止。 优胜劣汰概念的生存就在这里发挥作用。 使用计算`i`个个体适应性的函数进行选择过程。
......
......@@ -58,13 +58,13 @@ AWS 还拥有一支由顾问组成的大军,致力于帮助其客户部署 AWS
微软的解决方案吸引托管旧式工作负载以及全新的云部署的客户,但出于不同的原因。
传统的工作负载通常由传统上是 Microsoft 客户的客户在 Azure 上运行,并试图利用他们以前在该技术栈中的投资。
传统的工作负载通常由传统上是 Microsoft 客户的客户在 Azure 上运行,并试图利用他们以前在该技术栈中的投资。
对于新的云部署,由于 Microsoft 为应用开发提供了强大的产品,专业的**平台即服务****PaaS**)功能,数据存储,机器学习和**物联网****IoT**)服务,Azure 云服务吸引人们。
在战略上致力于 Microsoft 技术栈的企业已经能够在生产中部署许多大型应用。 当开发人员完全致力于 Microsoft 产品套件(例如.NET 应用),然后将其部署在 Azure 上时,Azure 尤其有用。 微软之所以能够深入市场,是因为其经验丰富的销售人员和广泛的合作伙伴网络。
在战略上致力于 Microsoft 技术栈的企业已经能够在生产中部署许多大型应用。 当开发人员完全致力于 Microsoft 产品套件(例如.NET 应用),然后将其部署在 Azure 上时,Azure 尤其有用。 微软之所以能够深入市场,是因为其经验丰富的销售人员和广泛的合作伙伴网络。
此外,微软意识到,下一轮技术战将不会围绕操作系统展开,而是会围绕云进行,因此它们已越来越多地接受采用非微软操作系统。 为了证明这一点,到目前为止,大约一半的 Azure 工作负载运行在 Linux 或其他开源操作系统和技术栈上。
此外,微软意识到,下一轮技术战将不会围绕操作系统展开,而是会围绕云进行,因此它们已越来越多地接受采用非微软操作系统。 为了证明这一点,到目前为止,大约一半的 Azure 工作负载运行在 Linux 或其他开源操作系统和技术栈上。
Gartner 的一份报告指出:“*微软对未来具有独特的愿景,涉及通过本机的第一方产品(例如来自 VMware,NetApp,Red Hat,Cray 和 Databricks 的产品)引入技术合作伙伴。*
......@@ -220,7 +220,7 @@ SageMaker 部署支持一次性和批量预测。 批量预测对可以存储在
在前面的章节中,我们讨论了 Alexa 及其在家庭中越来越普遍的存在。 现在,我们将深入研究为 Alexa 提供支持的技术,并允许您创建自己的对话机器人。
Amazon Lex 是用于建立对话智能体的服务。 Amazon Lex 和其他聊天机器人是我们这一代人的尝试通过图灵测试,我们在前面的章节中已经进行了讨论。 任何人将与 Alexa 的对话与人类对话混淆都需要一段时间。 但是,亚马逊和其他公司在使这些对话越来越自然的过程中不断取得进步。 Amazon Lex,使用与 Amazon Alexa 相同的技术,使开发人员可以快速构建复杂的自然语言,会话智能体或“聊天机器人”。 对于简单的情况,无需任何编程就可以构建其中的一些聊天机器人。 但是,可以使用 AWS Lambda 作为集成技术将 Lex 与 AWS 栈中的其他服务集成。
Amazon Lex 是用于建立对话智能体的服务。 Amazon Lex 和其他聊天机器人是我们这一代人的尝试通过图灵测试,我们在前面的章节中已经进行了讨论。 任何人将与 Alexa 的对话与人类对话混淆都需要一段时间。 但是,亚马逊和其他公司在使这些对话越来越自然的过程中不断取得进步。 Amazon Lex,使用与 Amazon Alexa 相同的技术,使开发人员可以快速构建复杂的自然语言,会话智能体或“聊天机器人”。 对于简单的情况,无需任何编程就可以构建其中的一些聊天机器人。 但是,可以使用 AWS Lambda 作为集成技术将 Lex 与 AWS 栈中的其他服务集成。
稍后,我们将整整一章专门介绍如何创建聊天机器人,因此我们将在本节中简短介绍。
......
......@@ -20,7 +20,7 @@
没有对手的游戏比拥有对手的游戏更容易优化。 具有多个玩家的游戏,游戏玩法变得更加复杂。 让我们考虑一个两人游戏。 玩家为赢得比赛而进行的每一个举动,对方玩家都会采取行动以阻止该玩家获胜。 因此,当搜索算法从当前状态中找到最佳移动方式集时,它就不能不考虑对方玩家的反向移动而仅仅进行移动。 这意味着每次移动后都需要不断重新评估搜索算法。
让我们讨论一下计算机如何感知任何给定的游戏。 我们可以将游戏视为搜索树。 该树中的每个节点代表一个未来状态。 例如,如果您正在玩**井字棋**(圆圈和叉),则可以构造一棵树来表示所有可能的移动。 我们从树的根开始,这是游戏的起点。 该节点将具有几个代表各种可能动作的子代。 反过来,在对手进行更多移动之后,这些孩子将拥有更多代表游戏状态的孩子。 树的终端节点代表游戏的最终动作。 游戏将以平局结束,或者其中一名玩家将赢得比赛。搜索算法搜索该树以在游戏的每个步骤做出决策。 现在,我们将学习各种搜索技术,包括如何进行详尽的组合搜索,以帮助我们在井字棋中永不丢失,并解决许多其他问题。
让我们讨论一下计算机如何感知任何给定的游戏。 我们可以将游戏视为搜索树。 该树中的每个节点代表一个未来状态。 例如,如果您正在玩**井字棋**(圆圈和叉),则可以构造一棵树来表示所有可能的移动。 我们从树的根开始,这是游戏的起点。 该节点将具有几个代表各种可能动作的子代。 反过来,在对手进行更多移动之后,这些子项将拥有更多代表游戏状态的子项。 树的终端节点代表游戏的最终动作。 游戏将以平局结束,或者其中一名玩家将赢得比赛。搜索算法搜索该树以在游戏的每个步骤做出决策。 现在,我们将学习各种搜索技术,包括如何进行详尽的组合搜索,以帮助我们在井字棋中永不丢失,并解决许多其他问题。
# 组合搜索
......@@ -487,7 +487,7 @@ if __name__ == '__main__':
# 建立两个机器人来互相对抗 Hexapawn
**Hexapawn** 是一款两人游戏,尺寸`N×M`。 棋子存在于棋盘的两侧,目标是将棋子一直推进到棋盘的另一端。 国际象棋的标准典当规则适用。 这是`easyAI`库中提供的 Hexapawn 秘籍的变体。 将创建两个机器人,并使其相互对峙。 让我们创建代码。
**Hexapawn** 是一款两人游戏,大小`N×M`。 棋子存在于棋盘的两侧,目标是将棋子一直推进到棋盘的另一端。 国际象棋的标准典当规则适用。 这是`easyAI`库中提供的 Hexapawn 秘籍的变体。 将创建两个机器人,并使其相互对峙。 让我们创建代码。
创建一个新的 Python 文件并导入以下包:
......
......@@ -457,7 +457,7 @@ if __name__=='__main__':
为了从音频信号中提取频率特征,MFCC 首先提取功率谱。 然后,它使用滤波器组和**离散余弦变换****DCT**)提取特征。 如果您有兴趣进一步研究 MFCC,[请查看以下链接](http://practicalcryptography.com/miscellaneous/machine-learning/guide-mel-frequency-cepstral-coefficients-mfccs)
我们将使用一个名为`python_speech_features`程序包来提取 MFCC 特征。 [该包在这里可用](http://python-speech-features.readthedocs.org/en/latest)
我们将使用一个名为`python_speech_features`的包来提取 MFCC 特征。 [该包在这里可用](http://python-speech-features.readthedocs.org/en/latest)
为了易于使用,相关的文件夹已包含在代码包中。 您将在代码包中看到一个名为`features`的文件夹,其中包含使用此包所需的文件。 让我们看看如何提取 MFCC 特征。
......@@ -560,7 +560,7 @@ plt.show()
正如我们在上一章中讨论的那样,HMM 非常适合分析序列数据。 音频信号是时间序列信号,是序列数据的体现。 假定输出是由系统经过一系列隐藏状态生成的。 我们的目标是找出这些隐藏状态是什么,以便我们可以识别信号中的单词。 如果您有兴趣深入研究,[请查看以下链接](https://web.stanford.edu/~jurafsky/slp3/A.pdf)
我们将使用名为`hmmlearn`程序包来构建我们的语音识别系统。 [您可以在此处了解更多信息](http://hmmlearn.readthedocs.org/en/latest)
我们将使用名为`hmmlearn`的包来构建我们的语音识别系统。 [您可以在此处了解更多信息](http://hmmlearn.readthedocs.org/en/latest)
您可以通过运行以下命令来安装包:
......
......@@ -191,7 +191,7 @@ Webhook 是,HTTP 推送 API 或 Web 回调。 它也称为反向 API,因为
# 聊天机器人平台
一些使用最广泛的聊天机器人是由主要供应商(例如 Google,AWS 和 Microsoft)开发的平台实现的。 在为聊天机器人选择技术栈时,应仔细考虑他们的服务产品。 这三大供应商均提供可靠且可扩展的云计算服务,这些服务将帮助您根据需要实现和自定义聊天机器人。 到目前为止,可以轻松创建基于文本或语音的机器人的最著名平台如下:
一些使用最广泛的聊天机器人是由主要供应商(例如 Google,AWS 和 Microsoft)开发的平台实现的。 在为聊天机器人选择技术栈时,应仔细考虑他们的服务产品。 这三大供应商均提供可靠且可扩展的云计算服务,这些服务将帮助您根据需要实现和自定义聊天机器人。 到目前为止,可以轻松创建基于文本或语音的机器人的最著名平台如下:
* DialogFlow(Google,以前为 Api.ai)
* Azure Bot 服务(Microsoft)
......
......@@ -429,7 +429,7 @@ plt.show()
![](img/B15441_17_10.png)
图 10:最大和最小尺寸以及总体平均值
图 10:最大和最小大小以及总体平均值
如果向下滚动,则将看到按行平均值和打印出的相关系数:
......
# 18 图像识别
在本章中,我们将学习有关对象检测和跟踪的知识。 首先,我们将花费一些时间来理解为什么图像识别对于机器学习非常重要。 然后,我们将学习称为 OpenCV 的图像识别程序包,该程序包是计算机视觉的流行库。 我们还将学习如何安装 OpenCV 并讨论帧差异,以了解如何检测视频中的运动部分。 我们将学习如何使用色彩空间跟踪对象,以及如何使用背景减法来跟踪对象。 之后,我们将使用 CAMShift 算法构建交互式对象跟踪器,并学习如何构建基于光流的跟踪器。 我们将讨论人脸检测和相关概念,例如 Haar 级联和积分图像。 然后,我们将使用此技术来构建眼睛检测器和跟踪器。
在本章中,我们将学习有关对象检测和跟踪的知识。 首先,我们将花费一些时间来理解为什么图像识别对于机器学习非常重要。 然后,我们将学习称为 OpenCV 的图像识别包,该包是计算机视觉的流行库。 我们还将学习如何安装 OpenCV 并讨论帧差异,以了解如何检测视频中的运动部分。 我们将学习如何使用色彩空间跟踪对象,以及如何使用背景减法来跟踪对象。 之后,我们将使用 CAMShift 算法构建交互式对象跟踪器,并学习如何构建基于光流的跟踪器。 我们将讨论人脸检测和相关概念,例如 Haar 级联和积分图像。 然后,我们将使用此技术来构建眼睛检测器和跟踪器。
在本章结束时,您将了解:
......@@ -33,7 +33,7 @@
**MRI 和超声解释**:在识别癌症和其他疾病方面,某些工具的表现优于人类。
考虑了图像识别的一些实际应用后,让我们进入将要使用的程序包以亲自了解它。
考虑了图像识别的一些实际应用后,让我们进入将要使用的包以亲自了解它。
# OpenCV
......@@ -1057,7 +1057,7 @@ if __name__ == '__main__':
让我们看看如何使用它来执行人脸检测。 为了构建用于检测人脸的机器学习系统,我们首先需要构建特征提取器。 机器学习算法将使用这些特征来了解人脸。 这就是 Haar 特征变得相关的地方。
它们只是图像上补丁的简单总结和差异。 Haar 特征易于计算。 为了使其具有强大的缩放能力,我们在多种图像尺寸下执行此操作。 如果您想以教程格式了解更多信息,[可以查看以下链接](http://www.cs.ubc.ca/~lowe/425/slides/13-ViolaJones.pdf)
它们只是图像上补丁的简单总结和差异。 Haar 特征易于计算。 为了使其具有强大的缩放能力,我们在多种图像大小下执行此操作。 如果您想以教程格式了解更多信息,[可以查看以下链接](http://www.cs.ubc.ca/~lowe/425/slides/13-ViolaJones.pdf)
提取特征后,我们将其传递给简单分类器的增强级联。 我们检查图像中的各个矩形子区域,并继续丢弃不包含人脸的区域。 我们很高兴迅速得出最终答案。 为了高效地计算这些特征,他们使用了称为积分图像的概念。
......
......@@ -102,7 +102,7 @@ plt.ylabel('Dimension 2')
plt.title('Input data')
```
定义每个尺寸可以采用的最大值和最小值:
定义每个大小可以采用的最大值和最小值:
```py
# Define minimum and maximum values for each dimension
......@@ -412,7 +412,7 @@ import matplotlib.pyplot as plt
import neurolab as nl
```
从文件`data_vector_quantization.txt`加载输入数据。 该文件中的每一行都包含六个数字。 前两个数字形成数据点,后四个数字形成单热编码标签。 总体上有四个课程
从文件`data_vector_quantization.txt`加载输入数据。 该文件中的每一行都包含六个数字。 前两个数字形成数据点,后四个数字形成单热编码标签。 总体上有四个类别
```py
# Load input data
......
......@@ -27,7 +27,7 @@
**安全性**:ML 为许多行业提供了提升。 无论市场部门如何,网络安全始终是企业高管的“首要任务”。 某些安全供应商使用 GAN 来处理网络攻击。 简而言之,GAN 会创建伪造的入侵,然后使用这些入侵来训练模型以识别这些威胁,从而使我们能够阻止这些攻击的真实版本。
**数据操作**:GAN 可用于“伪样式迁移”,即,在不完全修改示例的情况下修改示例的某些尺寸
**数据操作**:GAN 可用于“伪样式迁移”,即,在不完全修改示例的情况下修改示例的某些大小
GAN 可用于语音应用。 给定语音,可以训练 GAN 来重现著名的声音。
......@@ -103,7 +103,7 @@ CNN 通常使用以下类型的层:
**整流线性单元层**:此层将激活函数应用于上一层的输出。 此函数通常类似于`max(0, x)`。 需要这一层来为网络增加非线性,以便可以很好地推广到任何类型的函数。
**合并层**:此层对上一层的输出进行采样,从而得到具有较小尺寸的结构。 池化有助于我们在网络发展过程中仅保留重要部分。 最大池化通常在池化层中使用,我们在给定的`KxK`窗口中选择最大值。
**合并层**:此层对上一层的输出进行采样,从而得到具有较小大小的结构。 池化有助于我们在网络发展过程中仅保留重要部分。 最大池化通常在池化层中使用,我们在给定的`KxK`窗口中选择最大值。
**全连接层**:此层计算最后一层的输出分数。 结果输出的大小为`1x1xL`,其中`L`是训练数据集中的类数。
......@@ -217,7 +217,7 @@ train = optimizer.minimize(loss)
init = tf.initialize_all_variables()
```
启动 TensorFlow 会话并使用初始化程序运行它:
启动 TensorFlow 会话并使用初始化运行它:
```py
# Start the tensorflow session and run it
......@@ -481,7 +481,7 @@ mnist = input_data.read_data_sets(args.input_dir, one_hot=True)
x = tf.placeholder(tf.float32, [None, 784])
```
我们将使用利用图像 2D 结构的卷积神经网络。 因此,让我们将`x`重塑为 4D 张量,其中第二维和第三维指定图像尺寸
我们将使用利用图像 2D 结构的卷积神经网络。 因此,让我们将`x`重塑为 4D 张量,其中第二维和第三维指定图像大小
```py
# Reshape 'x' into a 4D tensor
......@@ -533,7 +533,7 @@ h_conv2 = tf.nn.relu(convolution_2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pooling(h_conv2)
```
现在将图像尺寸减小为`7×7`。 用`1024`神经元创建一个完全连接的层:
现在将图像大小减小为`7×7`。 用`1024`神经元创建一个完全连接的层:
```py
# Define the fully connected layer
......
......@@ -45,7 +45,7 @@ RL 是指学习操作方法并将情况映射到某些动作以最大化回报
有关此主题的更多信息,请跳至第 2 章,“人工智能基本用例”中的“装运和仓库管理”部分。
**工业控制器**:考虑调度电梯的情况。 一个好的调度程序将花费最少的电量,并为最多的人员服务。 对于此类问题,RL 智能体可以学习如何在模拟环境中执行此操作。 然后,他们可以利用这些知识来制定最佳计划。
**工业控制器**:考虑调度电梯的情况。 一个好的调度将花费最少的电量,并为最多的人员服务。 对于此类问题,RL 智能体可以学习如何在模拟环境中执行此操作。 然后,他们可以利用这些知识来制定最佳计划。
**婴儿**:机器在使用 RL 方面没有垄断权; 刚开始的几个月里,新生儿经历了几乎相同的过程。 他们通过反复尝试来学习,直到学会平衡为止。 有趣的是,婴儿发现了走路(或跑步!)是最有效的方式之后,发现了不同的运动方法。
......@@ -73,7 +73,7 @@ RL 系统可以同时执行多个事情–通过执行试错搜索来学习,
# 创建环境
我们将使用名为 **OpenAI Gym**程序包来构建 RL 智能体。 [您可以在此处了解更多有关的信息](https://gym.openai.com)。 可以通过运行以下命令使用`pip`进行安装:
我们将使用名为 **OpenAI Gym** 的包来构建 RL 智能体。 [您可以在此处了解更多有关的信息](https://gym.openai.com)。 可以通过运行以下命令使用`pip`进行安装:
```py
$ pip3 install gym
......@@ -224,7 +224,7 @@ if __name__=='__main__':
input_env = args.input_env
```
在 OpenAI Gym 程序包中建立从输入参数到环境名称的映射:
在 OpenAI Gym 包中建立从输入参数到环境名称的映射:
```py
name_map = {'cartpole': 'CartPole-v0',
......
......@@ -213,7 +213,7 @@ Google 的工作方式与图书馆卡目录类似,不同之处在于 Google
在欺诈这个话题上,有趣的是,亚马逊在其 2019 年 re:Invent 会议上宣布了一项名为 **Fraud Detector** 的新服务。 它使用了与 Amazon 用来捕获欺诈的相同技术,并允许该服务的用户在自己的操作和交易中防止欺诈。 有关服务的更多信息,[可以在这里找到](https://aws.amazon.com/fraud-detector/)
在前面的部分中,我们了解了大数据技术本身是如何强大的。 本节的重点是要理解机器学习是大数据集群可以成功进行并以大规模并行方式处理的工作负载之一。 许多大数据堆栈(例如 Hadoop 堆栈)具有内置的机器学习组件(例如 Mahout),但是我们不限于仅使用这些组件来训练机器学习模型。 这些堆栈可以与其他同类最佳的 ML 库结合使用,例如 Scikit-Learn,Theano,Torch,Caffe 和 TensorFlow。 现在我们已经讨论了大数据如何帮助我们创建机器学习模型,让我们进一步了解一些当今最流行的大数据工具。
在前面的部分中,我们了解了大数据技术本身是如何强大的。 本节的重点是要理解机器学习是大数据集群可以成功进行并以大规模并行方式处理的工作负载之一。 许多大数据栈(例如 Hadoop 栈)具有内置的机器学习组件(例如 Mahout),但是我们不限于仅使用这些组件来训练机器学习模型。 这些栈可以与其他同类最佳的 ML 库结合使用,例如 Scikit-Learn,Theano,Torch,Caffe 和 TensorFlow。 现在我们已经讨论了大数据如何帮助我们创建机器学习模型,让我们进一步了解一些当今最流行的大数据工具。
## Apache Hadoop
......@@ -301,7 +301,7 @@ SparkSQL 无需修改即可运行 Hive 查询。 它重写了 Hive 前端和元
Impala 为 Hadoop 提供了可扩展的并行 SQL 数据库引擎,使开发人员可以对存储在 Apache HBase,Amazon S3 和 HDFS 中的数据创建并运行低延迟 SQL 查询,而无需在读取数据之前先进行移动或转换。
Impala 可以轻松与 Hadoop 集成,并支持 MapReduce,Apache Hive 和 Apache Pig 以及 Hadoop 栈中的其他工具所使用的相同文件和数据格式,元数据以及安全和资源管理框架。
Impala 可以轻松与 Hadoop 集成,并支持 MapReduce,Apache Hive 和 Apache Pig 以及 Hadoop 栈中的其他工具所使用的相同文件和数据格式,元数据以及安全和资源管理框架。
分析人员和数据科学家都使用 Impala。 人们通过 SQL,BI 工具以及机器学习库,包和工具对 Hadoop 中存储的数据进行分析。 结果是大规模数据处理(通过 MapReduce)。
......@@ -333,7 +333,7 @@ Impala 可以轻松与 Hadoop 集成,并支持 MapReduce,Apache Hive 和 Apa
## NoSQL 数据库的类型
**文档数据库**:文档数据库用于存储半结构化数据。 他们使用与复杂的数据结构(称为文档)配对的密钥。 文档可以包含许多类型的数据结构,例如原始值(如整数,布尔值和字符串),不同的键值对或键数组对,甚至是嵌套文档。
**文档数据库**:文档数据库用于存储半结构化数据。 他们使用与复杂的数据结构(称为文档)配对的。 文档可以包含许多类型的数据结构,例如原始值(如整数,布尔值和字符串),不同的键值对或键数组对,甚至是嵌套文档。
**图数据库**:图形数据库将图形结构用于具有节点,边和属性的语义查询,以表示和存储数据。 图形数据库的重点是数据中的关系。 一些示例使用图数据库的案例:
......
......@@ -252,7 +252,7 @@ GAN 的架构具有两个基本元素:生成器网络和判别器网络。 每
初始分数是 GAN 使用最广泛的评分算法。 它使用预训练的 Inception V3 网络(在 Imagenet 上进行训练)来提取生成图像和真实图像的特征。 由 Shane Barrat 和 Rishi Sharma 在其论文[《关于初始分数的注](https://arxiv.org/pdf/1801.01973.pdf)中提出。 初始分数或简称 IS,用于衡量所生成图像的质量和多样性。 让我们看一下`IS`的等式:
初始分数是 GAN 使用最广泛的评分算法。 它使用预训练的 Inception V3 网络(在 Imagenet 上进行训练)来提取生成图像和真实图像的特征。 由 Shane Barrat 和 Rishi Sharma 在其论文[《关于初始分数的注](https://arxiv.org/pdf/1801.01973.pdf)中提出。 初始分数或简称 IS,用于衡量所生成图像的质量和多样性。 让我们看一下`IS`的等式:
![](img/0d33c46a-0a5f-4027-919c-30b910e6d93b.png)
......
......@@ -200,7 +200,7 @@ pip install -r requirements.txt
在本章中,我们将使用 3D ShapeNets 数据集,该数据集可从[这个页面](http://3dshapenets.cs.princeton.edu/3DShapeNetsCode.zip)获得。 它由 Wu 和 Song 等人发行。 并包含 40 个对象类别的正确注释的 3D 形状。 我们将使用目录中可用的体积数据,我们将在本章稍后详细讨论。 在接下来的几节中,我们将下载,提取和浏览数据集。
在本章中,我们将使用 3D ShapeNets 数据集,该数据集可从[这个页面](http://3dshapenets.cs.princeton.edu/3DShapeNetsCode.zip)获得。 它由 Wu 和 Song 等人发行。 并包含 40 个对象类别的正确标注的 3D 形状。 我们将使用目录中可用的体积数据,我们将在本章稍后详细讨论。 在接下来的几节中,我们将下载,提取和浏览数据集。
3D ShapeNets 数据集仅用于学术用途。 如果您打算将数据集用于商业目的,请征求论文作者的许可,可以通过以下电子邮件地址与他们联系:`shurans@cs.princeton.edu`.
......@@ -271,7 +271,7 @@ import scipy.io as io
voxels = io.loadmat("path to .mat file")['instance']
```
2. 加载的 3D 图像的形状为`30x30x30`。 我们的网络需要形状为`64x64x64`的图像。 我们将使用 NumPy 的 `pad()`方法将 3D 图像的尺寸增加到`32x32x32`
2. 加载的 3D 图像的形状为`30x30x30`。 我们的网络需要形状为`64x64x64`的图像。 我们将使用 NumPy 的 `pad()`方法将 3D 图像的大小增加到`32x32x32`
```py
import numpy as np
......@@ -280,7 +280,7 @@ voxels = np.pad(voxels, (1, 1), 'constant', constant_values=(0, 0))
`pad()`方法采用四个参数,它们是实际体素的 N 维数组,需要填充到每个轴边缘的值的数量,模式值(`constant`)和`constant_values` 被填充。
3. 然后,使用`scipy.ndimage`模块中的`zoom()`函数将 3D 图像转换为尺寸`64x64x64`的 3D 图像。
3. 然后,使用`scipy.ndimage`模块中的`zoom()`函数将 3D 图像转换为大小`64x64x64`的 3D 图像。
```py
import scipy.ndimage as nd
......
......@@ -44,7 +44,7 @@ cGAN 的训练目标函数可以表示为:
![](img/115b5d5f-6623-46dc-bed1-e99a6aa5910c.png)
此处,`G`是生成器网络,`D`是判别器网络。 判别器的损失为`log D(x|y)`, 生成器的损失为`log(1 - D(G(z|y)))`。 我们可以说`G(z|y)`在给定`z``y`情况下建模我们数据的分布。 在此,`z`是从正态分布得出的尺寸为 100 的先验噪声分布。
此处,`G`是生成器网络,`D`是判别器网络。 判别器的损失为`log D(x|y)`, 生成器的损失为`log(1 - D(G(z|y)))`。 我们可以说`G(z|y)`在给定`z``y`情况下建模我们数据的分布。 在此,`z`是从正态分布得出的大小为 100 的先验噪声分布。
......@@ -66,7 +66,7 @@ cGAN 的问题在于它们无法学习将属性`y`的输入图像`x`逆映射到
编码器网络的主要目标是生成所提供图像的潜向量。 基本上,它会拍摄尺寸`(64, 64, 3)`的图像,并将其转换为 100 维向量。 编码器网络是一个深度卷积神经网络。 网络包含四个卷积块和两个密集层。 每个卷积块包含一个卷积层,一个批标准化层和一个激活函数。 在每个卷积块中,每个卷积层后面都有一个批量归一化层,但第一个卷积层除外。 Age-cGAN 部分的 “Keras 实现”将介绍编码器网络的配置。
编码器网络的主要目标是生成所提供图像的潜向量。 基本上,它会拍摄大小`(64, 64, 3)`的图像,并将其转换为 100 维向量。 编码器网络是一个深度卷积神经网络。 网络包含四个卷积块和两个密集层。 每个卷积块包含一个卷积层,一个批标准化层和一个激活函数。 在每个卷积块中,每个卷积层后面都有一个批量归一化层,但第一个卷积层除外。 Age-cGAN 部分的 “Keras 实现”将介绍编码器网络的配置。
......@@ -76,7 +76,7 @@ cGAN 的问题在于它们无法学习将属性`y`的输入图像`x`逆映射到
生成器的主要目标是生成尺寸`(64, 64, 3)`的图像。 它需要一个 100 维的潜向量和一些额外的信息`y`和尝试生成逼真的图像。 生成器网络也是一个深层卷积神经网络。 它由密集,上采样和卷积层组成。 它采用两个输入值:噪声向量和条件值。 条件值是提供给网络的附加信息。 对于 Age-cGAN,这就是年龄。 生成器网络的配置将在 Age-cGAN 部分的“Keras 实现”中进行介绍。
生成器的主要目标是生成大小`(64, 64, 3)`的图像。 它需要一个 100 维的潜向量和一些额外的信息`y`和尝试生成逼真的图像。 生成器网络也是一个深层卷积神经网络。 它由密集,上采样和卷积层组成。 它采用两个输入值:噪声向量和条件值。 条件值是提供给网络的附加信息。 对于 Age-cGAN,这就是年龄。 生成器网络的配置将在 Age-cGAN 部分的“Keras 实现”中进行介绍。
......@@ -480,7 +480,7 @@ def build_encoder():
生成器网络是一个 CNN,它采用 100 维向量`z`,并生成尺寸`(64, 64, 3)`的图像。 让我们在 Keras 框架中实现生成器网络。
生成器网络是一个 CNN,它采用 100 维向量`z`,并生成大小`(64, 64, 3)`的图像。 让我们在 Keras 框架中实现生成器网络。
执行以下步骤以实现生成器网络:
......@@ -505,7 +505,7 @@ x = concatenate([input_z_noise, input_label])
3. 接下来,添加具有以下配置的密集(完全连接)块:
* **单元(节点)**`2,048`
* **输入尺寸**:106
* **输入大小**:106
* **激活**`LeakyReLU``alpha`等于``0.2``
* **退出**`0.2`
......@@ -528,7 +528,7 @@ x = LeakyReLU(alpha=0.2)(x)
x = Dropout(0.2)(x)
```
5. 接下来,将最后一个密集层的输出重塑为尺寸`(8, 8, 256)`的三维张量:
5. 接下来,将最后一个密集层的输出重塑为大小`(8, 8, 256)`的三维张量:
```py
x = Reshape((8, 8, 256))(x)
......@@ -674,7 +674,7 @@ def expand_label_input(x):
return x
```
前面的函数会将尺寸为`(6, )`的张量转换为尺寸`(32, 32, 6)`的张量。
前面的函数会将大小为`(6, )`的张量转换为大小`(32, 32, 6)`的张量。
4. 接下来,沿着通道维度将变换后的标签张量和最后一个卷积层的输出连接起来,如下所示:
......
......@@ -95,7 +95,7 @@ L 等人研究了张量如何从第一层流到最后一层。 下图显示了
上图给出了生成器网络架构的顶层概述。
如前所述,判别器网络是一个包含 10 层的 CNN(您可以根据需要向网络添加更多层)。 基本上,它会拍摄尺寸`64 x 64 x 3`的图像,使用 2D 卷积层对其进行下采样,然后将其传递到完全连接的层进行分类。 它的输出是对给定图像是伪图像还是真实图像的预测。 可以为 0 或 1;可以为 0。 如果输出为 1,则传递到判别器的图像是真实的;如果输出为 0,则传递的图像是伪图像。
如前所述,判别器网络是一个包含 10 层的 CNN(您可以根据需要向网络添加更多层)。 基本上,它会拍摄大小`64 x 64 x 3`的图像,使用 2D 卷积层对其进行下采样,然后将其传递到完全连接的层进行分类。 它的输出是对给定图像是伪图像还是真实图像的预测。 可以为 0 或 1;可以为 0。 如果输出为 1,则传递到判别器的图像是真实的;如果输出为 0,则传递的图像是伪图像。
让我们看一下判别器网络中的各层:
......@@ -225,7 +225,7 @@ gallery-dl https://danbooru.donmai.us/posts?tags=face
![](img/503cd7f0-4105-49a5-9095-d400768e7eb9.png)
如您所见,有些图像还包含其他身体部位,我们在训练图像中不需要这些部位。 在下一部分中,我们将仅从这些图像中裁剪出人脸。 此外,我们会将所有图像调整为训练所需的尺寸
如您所见,有些图像还包含其他身体部位,我们在训练图像中不需要这些部位。 在下一部分中,我们将仅从这些图像中裁剪出人脸。 此外,我们会将所有图像调整为训练所需的大小
......@@ -297,7 +297,7 @@ for index, filename in
# Crop image cropped_image = im.crop(coordinates)
```
7. 接下来,将裁剪后的人脸图像调整为`(64, 64)`尺寸
7. 接下来,将裁剪后的人脸图像调整为`(64, 64)`大小
```py
# Resize image cropped_image = cropped_image.resize((64, 64), Image.ANTIALIAS)
......@@ -349,7 +349,7 @@ total_num_faces = 0 for index, filename in enumerate(glob.glob('/path/to/direc
print("Total number of faces:{}".format(total_num_faces))
```
前面的脚本将从包含下载图像的文件夹中加载所有图像,使用`python-animeface`库检测人脸,然后**从初始图像中裁剪出人脸**。 然后,裁切后的图像将被调整为`64 x 64`尺寸。如果要更改图像的尺寸,请相应地更改生成器和判别器的架构。 我们现在准备在我们的网络上工作。
前面的脚本将从包含下载图像的文件夹中加载所有图像,使用`python-animeface`库检测人脸,然后**从初始图像中裁剪出人脸**。 然后,裁切后的图像将被调整为`64 x 64`大小。如果要更改图像的大小,请相应地更改生成器和判别器的架构。 我们现在准备在我们的网络上工作。
......@@ -444,7 +444,7 @@ gen_model.add(Conv2D(3, (5, 5), padding='same'))
gen_model.add(Activation('tanh'))
```
生成器网络将输出`(batch_size, 64, 64, 3)`形状的张量。 这批张量中的一个图像张量类似于具有三个通道的尺寸`64 x 64`的图像: **红色,绿色****蓝色****RGB**)。
生成器网络将输出`(batch_size, 64, 64, 3)`形状的张量。 这批张量中的一个图像张量类似于具有三个通道的大小`64 x 64`的图像: **红色,绿色****蓝色****RGB**)。
用 Python 方法包装的生成器网络的完整代码如下所示:
......@@ -854,7 +854,7 @@ print("g_loss:", g_loss)
为了生成图像,我们需要一个从潜在空间采样的噪声向量。 Numpy 有一种称为`uniform()`的方法,可以根据均匀分布生成向量。 让我们看看如何在以下步骤中生成图像:
1. 通过添加以下代码行,创建尺寸`(batch_size, 100)`的噪声向量:
1. 通过添加以下代码行,创建大小`(batch_size, 100)`的噪声向量:
```py
z_noise = np.random.normal(0, 1, size=(batch_size, z_shape))
......
......@@ -25,7 +25,7 @@
与其他 GAN 一样,SRGAN 包含一个生成器网络和一个判别器网络。 两个网络都很深。 这两个网络的功能指定如下:
* **生成器**:生成器网络拍摄尺寸`64x64x3`的低分辨率图像,并且在一系列卷积和上采样层之后, 生成形状为`256x256x3`的超分辨率图片
* **生成器**:生成器网络拍摄大小`64x64x3`的低分辨率图像,并且在一系列卷积和上采样层之后, 生成形状为`256x256x3`的超分辨率图片
* **判别器**:判别器网络拍摄高分辨率图像,并尝试识别给定的图像是真实的(来自真实数据样本)还是(由生成器)伪造的
......@@ -1094,7 +1094,7 @@ d_loss_fake = discriminator.train_on_batch(generated_high_resolution_images, fak
这些图像将帮助您决定是继续训练还是尽早停止训练。 如果生成的高分辨率图像的质量良好,请停止训练。 或者,继续训练,直到您的模型变好为止。
我们现在已经成功地在`CelebA`数据集上训练了 SRGAN 网络。 训练完成后,生成高分辨率图像非常容易。 拍摄尺寸`64 x 64 x 3`的低分辨率图像,并将其传递给`generator.predict()`函数,该函数将生成高分辨率图像。
我们现在已经成功地在`CelebA`数据集上训练了 SRGAN 网络。 训练完成后,生成高分辨率图像非常容易。 拍摄大小`64 x 64 x 3`的低分辨率图像,并将其传递给`generator.predict()`函数,该函数将生成高分辨率图像。
......
......@@ -45,7 +45,7 @@ StackGAN 是一个两阶段的网络。 每个阶段都有两个生成器和两
来源:`arXiv:1612.03242 [cs.CV]`
上图是不言自明的。 它代表了 StackGAN 网络的两个阶段。 如您所见,第一步是生成尺寸为`64x64`的图像。 然后,第二阶段拍摄这些低分辨率图像,并生成尺寸`256x256`的高分辨率图像。 在接下来的几节中,我们将探讨 StackGAN 网络中的不同组件。 但是,在进行此操作之前,让我们熟悉本章中使用的符号:
上图是不言自明的。 它代表了 StackGAN 网络的两个阶段。 如您所见,第一步是生成大小为`64x64`的图像。 然后,第二阶段拍摄这些低分辨率图像,并生成大小`256x256`的高分辨率图像。 在接下来的几节中,我们将探讨 StackGAN 网络中的不同组件。 但是,在进行此操作之前,让我们熟悉本章中使用的符号:
| **表示法** | **说明** |
| --- | --- |
......@@ -62,7 +62,7 @@ StackGAN 是一个两阶段的网络。 每个阶段都有两个生成器和两
| `G1` | 这是第一阶段生成器。 |
| `D2` | 这是第二阶段的判别器。 |
| `G2` | 这是第二阶段生成器。 |
| `N2` | 这些是随机噪声变量的尺寸。 |
| `N2` | 这些是随机噪声变量的大小。 |
| `c_hat` | 这些是第二阶段 GAN 的高斯潜在变量。 |
......@@ -125,7 +125,7 @@ StackGAN 网络的主要组成部分是生成器网络和判别器网络。 在
第一阶段生成器网络是具有几个上采样层的深度卷积神经网络。 生成器网络是 CGAN ,其条件是处于`c_hat[0]`和随机变量`z`。 生成器网络采用高斯条件变量`c_hat[0]`和随机噪声变量`z`,并生成尺寸`64x64x3` 的图像。 生成的低分辨率图像可能具有原始形状和基本颜色,但会存在各种缺陷。 这里,`z`是从维数为`N[z]`的高斯分布`P[z]`采样的随机噪声变量。 生成器网络生成的图像可以表示为`s[0] = G[0](z, c_hat[0])`。 让我们看一下生成器网络的架构,如以下屏幕截图所示:
第一阶段生成器网络是具有几个上采样层的深度卷积神经网络。 生成器网络是 CGAN ,其条件是处于`c_hat[0]`和随机变量`z`。 生成器网络采用高斯条件变量`c_hat[0]`和随机噪声变量`z`,并生成大小`64x64x3` 的图像。 生成的低分辨率图像可能具有原始形状和基本颜色,但会存在各种缺陷。 这里,`z`是从维数为`N[z]`的高斯分布`P[z]`采样的随机噪声变量。 生成器网络生成的图像可以表示为`s[0] = G[0](z, c_hat[0])`。 让我们看一下生成器网络的架构,如以下屏幕截图所示:
![](img/04c840a1-a6ae-4b3d-a141-ed58f9dae21b.png)
......@@ -133,7 +133,7 @@ StackGAN 网络的主要组成部分是生成器网络和判别器网络。 在
第一阶段的生成器网络架构
如您所见,生成器网络包含几个卷积层,其中每个卷积层后跟一个批量规范化层或一个激活层。 它的唯一目的是生成尺寸`64x64x3`的图像。 现在我们有了生成器网络的基本概念,让我们探索判别器网络。
如您所见,生成器网络包含几个卷积层,其中每个卷积层后跟一个批量规范化层或一个激活层。 它的唯一目的是生成大小`64x64x3`的图像。 现在我们有了生成器网络的基本概念,让我们探索判别器网络。
......@@ -200,7 +200,7 @@ StackGAN 的第一阶段中使用了两个损失,如下所示:
生成器网络还是深层卷积神经网络。 第一阶段的结果是低分辨率图像,它经过几个下采样层以生成图像特征。 然后,将图像特征和文本条件变量沿通道尺寸连接在一起。 之后,将级联张量馈入一些残差块,这些残差块学习跨图像和文本特征的多峰表示。 最后,最后一个操作的输出被馈送到一组上采样层,这些上采样层生成尺寸`256x256x3`的高分辨率图像。 让我们看一下生成器网络的架构,如下图所示:
生成器网络还是深层卷积神经网络。 第一阶段的结果是低分辨率图像,它经过几个下采样层以生成图像特征。 然后,将图像特征和文本条件变量沿通道大小连接在一起。 之后,将级联张量馈入一些残差块,这些残差块学习跨图像和文本特征的多峰表示。 最后,最后一个操作的输出被馈送到一组上采样层,这些上采样层生成大小`256x256x3`的高分辨率图像。 让我们看一下生成器网络的架构,如下图所示:
![](img/028e54b4-8184-45bd-8edf-abc7b7e8de97.png)
......@@ -394,7 +394,7 @@ StackGAN 的 Keras 实现分为两部分:第一阶段和第二阶段。 我们
第一阶段 StackGAN 包含生成器网络和判别器网络。 它还具有一个文本编码器网络和一个条件增强网络(CA 网络),下面将对此进行详细说明。 生成器网络获取文本条件变量(`c_hat[0]`)以及噪声向量(`x`)。 经过一组上采样层后,它会生成尺寸`64x64x3`的低分辨率图像。 判别器网络拍摄此低分辨率图像,并尝试识别图像是真实的还是伪造的。 生成器网络是具有一组下采样层的网络,其后是连接,然后是分类层。 在以下各节中,我们将详细探讨 StackGAN 的架构。
第一阶段 StackGAN 包含生成器网络和判别器网络。 它还具有一个文本编码器网络和一个条件增强网络(CA 网络),下面将对此进行详细说明。 生成器网络获取文本条件变量(`c_hat[0]`)以及噪声向量(`x`)。 经过一组上采样层后,它会生成大小`64x64x3`的低分辨率图像。 判别器网络拍摄此低分辨率图像,并尝试识别图像是真实的还是伪造的。 生成器网络是具有一组下采样层的网络,其后是连接,然后是分类层。 在以下各节中,我们将详细探讨 StackGAN 的架构。
第一阶段 StackGAN 网络中使用的网络如下:
......@@ -536,7 +536,7 @@ x = Dense(128 * 8 * 4 * 4, use_bias=False)(gen_input)
x = ReLU()(x)
```
4. 之后,将最后一层的输出重塑为尺寸`(batch_size, 4, 4, 128*8)`的张量:
4. 之后,将最后一层的输出重塑为大小`(batch_size, 4, 4, 128*8)`的张量:
```py
x = Reshape((4, 4, 128 * 8), input_shape=(128 * 8 * 4 * 4,))(x)
......@@ -879,7 +879,7 @@ def build_adversarial_model(gen_model, dis_model):
该块从第一阶段的生成器获取尺寸`64x64x3`的低分辨率图像,并将其下采样以生成形状为`16x16x512`的张量。 图像经过一系列 2D 卷积块。
该块从第一阶段的生成器获取大小`64x64x3`的低分辨率图像,并将其下采样以生成形状为`16x16x512`的张量。 图像经过一系列 2D 卷积块。
在本节中,我们将为降采样模块编写实现。
......@@ -1009,7 +1009,7 @@ x = residual_block(x)
上采样块包含可提高图像空间分辨率并生成尺寸`256x256x3`的高分辨率图像的层。
上采样块包含可提高图像空间分辨率并生成大小`256x256x3`的高分辨率图像的层。
让我们为上采样块编写代码:
......@@ -1698,7 +1698,7 @@ stage1_gen.save_weights("stage1_gen.h5")
stage1_dis.save_weights("stage1_dis.h5")
```
恭喜,我们已经成功训练了 StackGAN 的第一阶段。 现在,我们拥有训练有素的生成器网络,可以生成尺寸`64x64x3`的图像。 这些图像将具有基本颜色和原始形状。 在下一部分中,我们将训练第二阶段 StackGAN。
恭喜,我们已经成功训练了 StackGAN 的第一阶段。 现在,我们拥有训练有素的生成器网络,可以生成大小`64x64x3`的图像。 这些图像将具有基本颜色和原始形状。 在下一部分中,我们将训练第二阶段 StackGAN。
......@@ -1853,7 +1853,7 @@ for epoch in range(epochs):
X_hr_train_batch = (X_hr_train_batch - 127.5) / 127.5
```
6. 接下来,使用生成器网络生成尺寸`256x256x2`的伪图像。 在此步骤中,我们首先使用第一阶段的生成器网络生成低分辨率的伪图像。 然后,我们在第二阶段中使用生成器网络生成以低分辨率图像为条件的高分辨率图像。
6. 接下来,使用生成器网络生成大小`256x256x2`的伪图像。 在此步骤中,我们首先使用第一阶段的生成器网络生成低分辨率的伪图像。 然后,我们在第二阶段中使用生成器网络生成以低分辨率图像为条件的高分辨率图像。
```py
lr_fake_images, _ = stage1_gen.predict([embedding_batch, z_noise], verbose=3)
......@@ -1926,7 +1926,7 @@ for epoch in range(epochs):
stage2_dis.save_weights("stage2_dis.h5")
```
恭喜,我们现在已经成功完成了第二阶段 StackGAN 的训练。 现在,我们有了一个生成器网络,可以生成尺寸 `256x256x3`的逼真的图像。 如果为生成器网络提供文本嵌入和噪声变量,它将生成 `256x256x3`分辨率图像。 让我们可视化网络的损失图。
恭喜,我们现在已经成功完成了第二阶段 StackGAN 的训练。 现在,我们有了一个生成器网络,可以生成大小 `256x256x3`的逼真的图像。 如果为生成器网络提供文本嵌入和噪声变量,它将生成 `256x256x3`分辨率图像。 让我们可视化网络的损失图。
......
......@@ -754,7 +754,7 @@ inputA = Input(shape=(128, 128, 3))
inputB = Input(shape=(128, 128, 3))
```
两个输入都将拍摄尺寸`(128, 128, 3)`的图像。 这些是符号输入变量,不包含实际值。 它们用于创建 Keras 模型(TensorFlow 图)。
两个输入都将拍摄大小`(128, 128, 3)`的图像。 这些是符号输入变量,不包含实际值。 它们用于创建 Keras 模型(TensorFlow 图)。
2. 接下来,使用生成器网络生成伪造图像,如下所示:
......
......@@ -155,7 +155,7 @@ Pix2pix 是条件 GAN 的变体。 我们已经在第 3 章,“使用条件 GA
连接沿着通道轴发生。 编码器网络的最后一层将张量传递到解码器网络的第一层。 在编码器网络的最后一块和解码器网络的最后一块没有连接。
生成器网络由这两个网络组成。 基本上,编码器网络是下采样器,而解码器网络是上采样器。 编码器网络将尺寸为`(256, 256, 1)`的图像采样为尺寸为`(1, 1, 1, 512)`的内部表示。 另一方面,解码器网络将尺寸为`(1, 1, 1, 512)`的内部表示采样为尺寸`(256, 256, 1)`的输出图像。
生成器网络由这两个网络组成。 基本上,编码器网络是下采样器,而解码器网络是上采样器。 编码器网络将大小为`(256, 256, 1)`的图像采样为大小为`(1, 1, 1, 512)`的内部表示。 另一方面,解码器网络将大小为`(1, 1, 1, 512)`的内部表示采样为大小`(256, 256, 1)`的输出图像。
在“pix2pix 的 Keras 实现”中,我们将详细介绍该架构。
......@@ -347,7 +347,7 @@ facade_photos = h5py.File(facade_photos_path, 'r')
facade_labels = h5py.File(facade_labels_path, 'r')
```
4. 接下来,将图像调整为所需的图像尺寸,如下所示:
4. 接下来,将图像调整为所需的图像大小,如下所示:
```py
# Resize and normalize images num_photos = facade_photos['data'].shape[0]
......@@ -478,7 +478,7 @@ from keras.optimizers import Adam
生成器网络从源域 A 拍摄尺寸为`(256, 256, 1)`的图像,并将其转换为目标域 B 中尺寸`(256, 256, 1)`的图像。 基本上,它将图像从源域 A 转换为目标域 B。让我们在 Keras 框架中实现生成器网络。
生成器网络从源域 A 拍摄大小为`(256, 256, 1)`的图像,并将其转换为目标域 B 中大小`(256, 256, 1)`的图像。 基本上,它将图像从源域 A 转换为目标域 B。让我们在 Keras 框架中实现生成器网络。
执行以下步骤来创建生成器网络:
......@@ -766,7 +766,7 @@ def build_unet_generator():
判别器网络受 PatchGAN 架构的启发。 它包含八个卷积块,一个密集层和一个展开层。 判别器网络获取从尺寸`(256, 256, 1)`的图像中提取的一组补丁,并预测给定补丁的概率。 让我们在 Keras 中实现判别器。
判别器网络受 PatchGAN 架构的启发。 它包含八个卷积块,一个密集层和一个展开层。 判别器网络获取从大小`(256, 256, 1)`的图像中提取的一组补丁,并预测给定补丁的概率。 让我们在 Keras 中实现判别器。
1. 首先初始化生成器网络所需的超参数:
......@@ -817,7 +817,7 @@ flatten_layer = Flatten()(des)
展开层将`n`维张量转换为一维张量。
7. 类似地,添加具有两个节点/神经元的密集层,并添加 `softmax` 作为激活函数。 这需要一个来自 `Flatten` 层的张量,并将其转换为尺寸`(batch_size, 2)`的张量:
7. 类似地,添加具有两个节点/神经元的密集层,并添加 `softmax` 作为激活函数。 这需要一个来自 `Flatten` 层的张量,并将其转换为大小`(batch_size, 2)`的张量:
```py
dense_layer = Dense(units=2, activation='softmax')(flatten_layer)
......@@ -1164,7 +1164,7 @@ test_facade_photos, test_facade_labels = load_dataset(data_dir=dataset_dir, data
validation_facade_photos, validation_facade_labels = load_dataset(data_dir=dataset_dir, data_type='validation',img_width=img_width, img_height=img_height)
```
`load_dataset`函数是“数据准备”部分中定义的 。 每一组包含所有图像的一组`ndarray`。 每组的尺寸将为`(#total_images, 256, 256, 1)`
`load_dataset`函数是“数据准备”部分中定义的 。 每一组包含所有图像的一组`ndarray`。 每组的大小将为`(#total_images, 256, 256, 1)`
7. 添加 `tensorboard` 以可视化训练损失并可视化网络图:
......
......@@ -904,7 +904,7 @@ idx = 0 for i in range(0, 192, square_fragment_size):
![](img/d3128ff0-f632-4a71-bd39-655c31928ff5.png)
用 24 个量量化的图片
用 24 个量量化的图片
结果显然是原始图像的有损压缩版本。 每个组都可以用一个索引来表示(例如,在我们的示例中,它可以是 8 位整数),该索引指向码本中的条目(`km.cluster_centers_`)。 因此,如果最初有`192×256×3 = 1,474,560`个 8 位值,则在量化之后,我们有 12,288 个 8 位索引(`2×2×3`块的数量),再加上 24 个 12 维量化向量。 为了了解 VQ 对图像的影响,绘制原始图像和处理后图像的 RGB 直方图非常有用,如以下直方图所示:
......
......@@ -244,7 +244,7 @@ MeanShift 在不同带宽下的聚类结果
所有具有`x[i]``x[j] ∈ X`将分配给同一群集`C[t]`。 此外,如果`x[k] ∈ C[t]`,则所有密度可达的点`x[p] ∈ X * x[k]`也将属于同一群集。 从任何其他点`x[i] ∈ X`不可达到密度的点`x[n]`被定义为**噪声点**。 因此,与其他算法相反,DBSCAN 输出`n`簇以及一个包含所有噪声点的附加集(不必将其视为离群值,而应视为不属于任何密集子区域的点)。 当然,由于噪声点没有标签,因此其数目应相当低; 因此,重要的是要调整参数`ε``n[min]`,以达到双重目的:最大化内聚和分离度,避免过多的点被标记为噪点 。 没有实现此目标的标准规则,因此,我建议在做出最终决定之前测试不同的值。
最后,重要的是要记住,DBSCAN 可以处理非凸几何形状,并且与均值移位相反,它假设存在由低密度区域包围的高密度区域。 而且,它的复杂性与所采用的 KNN 方法(强力,球树或 kd 树)严格相关。 通常,当数据集不太大时,平均性能大约为`O(N log N)`,但可能趋于`O(N^2)``N`非常大时。 要记住的另一个重要元素是样本的尺寸。 正如我们已经讨论的那样,高维度量可以减少两点的可分辨性,从而对 KNN 方法的表现产生负面影响。 因此,当维数很高时,应避免(或至少仔细分析)DBSCAN,因为生成的簇不能有效地表示实际的密集区域。
最后,重要的是要记住,DBSCAN 可以处理非凸几何形状,并且与均值移位相反,它假设存在由低密度区域包围的高密度区域。 而且,它的复杂性与所采用的 KNN 方法(强力,球树或 kd 树)严格相关。 通常,当数据集不太大时,平均性能大约为`O(N log N)`,但可能趋于`O(N^2)``N`非常大时。 要记住的另一个重要元素是样本的大小。 正如我们已经讨论的那样,高维度量可以减少两点的可分辨性,从而对 KNN 方法的表现产生负面影响。 因此,当维数很高时,应避免(或至少仔细分析)DBSCAN,因为生成的簇不能有效地表示实际的密集区域。
在显示具体示例之前,最好先介绍一种在未知的真实情况下可以采用的进一步评估方法。
......
......@@ -78,7 +78,7 @@
本章的主题是在没有任何监督的情况下自动检测异常。 由于模型不是基于标记样本提供的反馈,因此我们只能依靠整个数据集的属性来找出相似之处并突出显示不同之处。 特别是,我们从一个非常简单但有效的假设开始:常见事件为*正常*,而不太可能发生的事件通常被视为**异常**。 当然,此定义意味着我们正在监视的过程运行正常,并且大多数结果都被认为是有效的。 例如:一家硅加工厂必须将晶圆切成相等的块。 我们知道它们每个都是`0.2×0.2`英寸(约`0.5×0.5`厘米),每侧的标准差为 0.001 英寸。 此措施是在 1,000,000 个处理步骤后确定的。 我们是否被授权将`0.25×0.25`英寸芯片视为异常? 当然可以。 实际上,我们假设每边的长度都建模为高斯分布(一个非常合理的选择),其中`μ = 0.2``σ = 0.001`;在经过三个标准差后,概率下降到几乎为零。 因此,例如:`P(edge > 0.23)≈ 0`,具有这种尺寸的芯片必须清楚地视为异常。
本章的主题是在没有任何监督的情况下自动检测异常。 由于模型不是基于标记样本提供的反馈,因此我们只能依靠整个数据集的属性来找出相似之处并突出显示不同之处。 特别是,我们从一个非常简单但有效的假设开始:常见事件为*正常*,而不太可能发生的事件通常被视为**异常**。 当然,此定义意味着我们正在监视的过程运行正常,并且大多数结果都被认为是有效的。 例如:一家硅加工厂必须将晶圆切成相等的块。 我们知道它们每个都是`0.2×0.2`英寸(约`0.5×0.5`厘米),每侧的标准差为 0.001 英寸。 此措施是在 1,000,000 个处理步骤后确定的。 我们是否被授权将`0.25×0.25`英寸芯片视为异常? 当然可以。 实际上,我们假设每边的长度都建模为高斯分布(一个非常合理的选择),其中`μ = 0.2``σ = 0.001`;在经过三个标准差后,概率下降到几乎为零。 因此,例如:`P(edge > 0.23)≈ 0`,具有这种大小的芯片必须清楚地视为异常。
显然,这是一个非常简单的示例,不需要任何模型。 但是,在现实生活中,密度的结构可能非常复杂,几个高概率区域被低概率区域包围。 这就是为什么必须采用更通用的方法来对整个样本空间进行建模的原因。
......@@ -775,7 +775,7 @@ Liu FT,Ting KM 和 Zhou Z 在文章《隔离森林》中提出了一种非常
二叉决策树的通用结构
在有监督的任务中,选择元组(特征,阈值)是根据使孩子的杂质最小化的特定标准选择的。 这意味着目标通常是拆分节点,以使结果子集包含属于单个类的大多数样本。 当然,很容易理解,当所有叶子都是纯净的或达到最大深度时,该过程结束。 相反,在此特定上下文中,我们从一个非常特殊(但经过经验证明)的假设开始:如果属于**隔离森林**的树木每次都选择随机特征和随机阈值进行生长,则从根到包含任何异常值的叶子的路径的平均长度,比隔离异常值所需的路径更长。 通过考虑一个二维示例,可以很容易地理解这一假设的原因,如作者所示:
在有监督的任务中,选择元组(特征,阈值)是根据使子项的杂质最小化的特定标准选择的。 这意味着目标通常是拆分节点,以使结果子集包含属于单个类的大多数样本。 当然,很容易理解,当所有叶子都是纯净的或达到最大深度时,该过程结束。 相反,在此特定上下文中,我们从一个非常特殊(但经过经验证明)的假设开始:如果属于**隔离森林**的树木每次都选择随机特征和随机阈值进行生长,则从根到包含任何异常值的叶子的路径的平均长度,比隔离异常值所需的路径更长。 通过考虑一个二维示例,可以很容易地理解这一假设的原因,如作者所示:
![](img/7b91e898-5147-47c5-b273-a25e89bfe857.png)
......
......@@ -174,7 +174,7 @@ def whiten(X, correct=True):
return np.dot(Xc, W) * np.sqrt(X.shape[0]) if correct else 1.0
```
以下屏幕截图显示了应用于`X` 阵列的增白结果:
以下屏幕截图显示了应用于`X` 数组的增白结果:
![](img/96f5814c-722a-4892-aecb-e31d1b885cc7.png)
......@@ -799,7 +799,7 @@ print(Xl[200])
4. `Kurt(X) = 5`的分布适用于 ICA。 它是否正确?
5. 包含样本`(1, 2)``(0, -3)`的数据集`X`的 NNMF 是多少?
6. 一个 10 个文档的语料库与一个带有 10 个词的词典相关联。 我们知道每个文档的固定长度为 30 个字。 字典是否过于完整?
7. 核 PCA 与二次内核一起使用。 如果原始尺寸为 2,则执行 PCA 的新空间的尺寸是多少?
7. 核 PCA 与二次内核一起使用。 如果原始大小为 2,则执行 PCA 的新空间的大小是多少?
......
......@@ -298,7 +298,7 @@ Epoch 600) Average loss per sample: 0.4635812330245972 (Code mean: 0.42368677258
![](img/6b4e6663-04c2-47c6-af95-153f0cefa172.png)
在这种情况下,自编码器的目标是消除噪声项并恢复原始样本`x[i]`。 从数学角度来看,标准和**去噪自编码器**之间没有特别的区别; 但是,重要的是要考虑此类模型的容量需求。 由于他们必须恢复原始样本,因此在输入受损(其特征占用更大的样本空间)的情况下,层的数量和尺寸可能比标准自编码器要大。 当然,考虑到复杂性,没有一些测试就不可能有清晰的洞察力。 因此,我强烈建议从较小的模型开始,然后增加容量,直到最佳成本函数达到合适的值为止。 为了增加噪音,有几种可能的策略:
在这种情况下,自编码器的目标是消除噪声项并恢复原始样本`x[i]`。 从数学角度来看,标准和**去噪自编码器**之间没有特别的区别; 但是,重要的是要考虑此类模型的容量需求。 由于他们必须恢复原始样本,因此在输入受损(其特征占用更大的样本空间)的情况下,层的数量和大小可能比标准自编码器要大。 当然,考虑到复杂性,没有一些测试就不可能有清晰的洞察力。 因此,我强烈建议从较小的模型开始,然后增加容量,直到最佳成本函数达到合适的值为止。 为了增加噪音,有几种可能的策略:
* 破坏每个批量中的样本(贯穿整个时期)。
* 将噪声层用作编码器的输入 1。
......@@ -1088,7 +1088,7 @@ Y_train = Y_train[0:nb_samples]
3. 32 个 Sigmoid 神经元
4. 16 个 Sigmoid 神经元
因此,最后一个表示形式由 16 个值(原始尺寸的四分之一)组成。 我们将`η = 0.025`的学习速率设置为每批 16 个样本(当然,我们邀请您检查其他配置,以最大程度地减少重构误差)。 以下代码段初始化并训练模型:
因此,最后一个表示形式由 16 个值(原始大小的四分之一)组成。 我们将`η = 0.025`的学习速率设置为每批 16 个样本(当然,我们邀请您检查其他配置,以最大程度地减少重构误差)。 以下代码段初始化并训练模型:
```py
from dbn import UnsupervisedDBN
......@@ -1145,7 +1145,7 @@ Sanger 和 Rubner-Tavan 的网络是神经模型,能够在不进行任何统
2. 给定数据集`X`及其转换`Y`,根据自编码器产生的代码,可以在`Y`找到`X`中包含的所有信息。 它是否正确?
3. 代码`z[i] ∈ (0, 1)^128``sum(z[i]) = 36`。 稀疏吗?
4. 如果`std(z[i]) = 0.03`,代码是否稀疏?
5. Sanger 网络需要协方差矩阵列作为输入向量。 它是否正确?
5. Sanger 网络需要协方差矩数组作为输入向量。 它是否正确?
6. 我们如何确定 Rubner-Tavan 网络提取的每个成分的重要性?
7. 给定一个随机向量,`h[i] ∈ R^m``m`是 DBN 的输出维数),是否可以确定最可能对应的输入样本?
......
......@@ -662,7 +662,7 @@ with graph.as_default():
minimize(loss=loss_g, var_list=variables_g)
```
通常,第一步是声明占位符,该占位符与 DCGAN 相同。 但是,由于已经针对 64×64 图像优化了模型(特别是卷积或转置卷积的序列),因此我们将使用`tf.image.resize_images()`方法来调整原始样本的大小。 此操作将导致有限的质量损失; 因此,在生产应用中,我强烈建议您使用针对原始输入尺寸优化的模型。 在生成器和注释器都声明之后(如我们在上一个示例中讨论的那样,由于需要分别优化损失函数,因此我们需要两个实例共享相同的变量),我们可以设置损失。 在这种情况下,它们的计算非常简单且快速,但是我们为此付出了代价,并为此网络可以应用更小的校正。 实际上,在这种情况下,我们并没有直接最小化批评者损失函数; 相反,我们首先使用运算符`optimizer_c`计算并应用梯度,然后使用运算符`training_step_c`裁剪所有评论者变量。 因为我们只想调用此运算符,所以已在使用指令`tf.control_dependencies([optimizer_c])`定义的上下文中声明了它。 这样,当请求一个会话来计算`traning_step_c`时,TensorFlow 将注意首先运行`optimizer_c`,但是只有在结果准备好后,才会执行 main 命令(简单地裁剪变量)。 正如我们在理论中所解释的那样,此步骤对于保证评论者仍然具有 L-Lipschitz 函数是必要的,因此,允许使用从 Kantorovich-Rubinstein 定理得到的简化 Wasserstein 距离表达式。
通常,第一步是声明占位符,该占位符与 DCGAN 相同。 但是,由于已经针对 64×64 图像优化了模型(特别是卷积或转置卷积的序列),因此我们将使用`tf.image.resize_images()`方法来调整原始样本的大小。 此操作将导致有限的质量损失; 因此,在生产应用中,我强烈建议您使用针对原始输入大小优化的模型。 在生成器和标注器都声明之后(如我们在上一个示例中讨论的那样,由于需要分别优化损失函数,因此我们需要两个实例共享相同的变量),我们可以设置损失。 在这种情况下,它们的计算非常简单且快速,但是我们为此付出了代价,并为此网络可以应用更小的校正。 实际上,在这种情况下,我们并没有直接最小化批评者损失函数; 相反,我们首先使用运算符`optimizer_c`计算并应用梯度,然后使用运算符`training_step_c`裁剪所有评论者变量。 因为我们只想调用此运算符,所以已在使用指令`tf.control_dependencies([optimizer_c])`定义的上下文中声明了它。 这样,当请求一个会话来计算`traning_step_c`时,TensorFlow 将注意首先运行`optimizer_c`,但是只有在结果准备好后,才会执行 main 命令(简单地裁剪变量)。 正如我们在理论中所解释的那样,此步骤对于保证评论者仍然具有 L-Lipschitz 函数是必要的,因此,允许使用从 Kantorovich-Rubinstein 定理得到的简化 Wasserstein 距离表达式。
当图形完全定义后,可以创建一个会话并初始化所有变量,如下所示:
......@@ -673,7 +673,7 @@ session = tf.InteractiveSession(graph=graph)
tf.global_variables_initializer().run()
```
现在,所有组件都已设置好,我们准备开始训练过程,该过程分为注者训练步骤的`nb_critic`(在我们的情况下为五次)迭代和生成器训练步骤的一次执行,如下:
现在,所有组件都已设置好,我们准备开始训练过程,该过程分为注者训练步骤的`nb_critic`(在我们的情况下为五次)迭代和生成器训练步骤的一次执行,如下:
```py
import numpy as np
......@@ -736,7 +736,7 @@ Ys = np.squeeze((Ys[0] + 1.0) * 0.5 * 255.0).astype(np.uint8)
WGAN 生成的样本
可以看到,WGAN 已收敛到合理的最终配置。 图像质量受尺寸调整操作的强烈影响; 但是,有趣的是,生成的样本平均比原始样本要复杂。 例如,衣服的质地和形状受其他因素(例如,包和鞋子)的影响,结果是模型不规则,新颖样本数量增加。 但是,与 Olivetti 人脸数据集相反,在这种情况下,很难理解样本是否由异质属性的混合物组成,因为数据生成过程(例如标准 MNIST)具有至少 10 种原始的类。
可以看到,WGAN 已收敛到合理的最终配置。 图像质量受大小调整操作的强烈影响; 但是,有趣的是,生成的样本平均比原始样本要复杂。 例如,衣服的质地和形状受其他因素(例如,包和鞋子)的影响,结果是模型不规则,新颖样本数量增加。 但是,与 Olivetti 人脸数据集相反,在这种情况下,很难理解样本是否由异质属性的混合物组成,因为数据生成过程(例如标准 MNIST)具有至少 10 种原始的类。
WGAN 不会陷入模式崩溃,但是不同区域的强烈分离使模型无法轻松合并元素,正如我们在人脸观察到的那样。 作为练习,我邀请读者对 Olivetti 人脸数据集重复该示例,找到最佳的超参数配置,并将结果与​​标准 DCGAN 获得的结果进行比较。
......@@ -758,7 +758,7 @@ SOM 开发的墨西哥帽选择性
在初始步骤中,许多单元会响应相同的输入模式,但是我们已经可以观察到`x[i]`附近的优势。 但是,立即选择此设备可能会导致收敛过早,从而导致准确性下降。 这就是为什么获胜单位周围的半径逐渐减小的原因(观察到一种称为**墨西哥帽**的现象,因为其形状特殊)。 当然,在此过程中,最初的获胜单位无法保持稳定; 因此,重要的是要避免半径的快速减小,以免引起其他潜在单位被引出。 当呈现特定模式时,当神经元保持最活跃时,它将被略微转换为实际的赢家,因此,这将花费全部,因为不会再加强任何其他单元。
一些非常著名和有用的 SOM 是 **Kohonen 映射**(首次出现在《拓扑正确特征映射的自组织形成》)。 它们的结构像投影到由`N`神经元组成的二维流形(最经典的情况是平坦的二维区域)上的平面一样。 从现在开始,为简单起见,我们将考虑映射到包含`k×p`单位的矩阵的曲面,每个曲面均使用突触权重`w[ij] ∈ R^n`进行建模 (尺寸与输入模式相同,`x[i] ∈ R^n`)。 因此,权重矩阵变为`W(i, j) ∈ R^(k×p×n)`。 从实际的角度来看,在此模型中,由于不执行内部转换,因此神经元通过相应的权重向量表示。 当呈现模式`x[i]`时,获胜神经元`n[w]`(作为元组)的确定如下: 使用以下规则:*
一些非常著名和有用的 SOM 是 **Kohonen 映射**(首次出现在《拓扑正确特征映射的自组织形成》)。 它们的结构像投影到由`N`神经元组成的二维流形(最经典的情况是平坦的二维区域)上的平面一样。 从现在开始,为简单起见,我们将考虑映射到包含`k×p`单位的矩阵的曲面,每个曲面均使用突触权重`w[ij] ∈ R^n`进行建模 (大小与输入模式相同,`x[i] ∈ R^n`)。 因此,权重矩阵变为`W(i, j) ∈ R^(k×p×n)`。 从实际的角度来看,在此模型中,由于不执行内部转换,因此神经元通过相应的权重向量表示。 当呈现模式`x[i]`时,获胜神经元`n[w]`(作为元组)的确定如下: 使用以下规则:*
![](img/1d22e1e2-5d4d-472e-90eb-af603c0116eb.png)
......@@ -784,7 +784,7 @@ SOM 开发的墨西哥帽选择性
在此示例中,我们要训练一个 8×8 正方形 Kohonen 映射以接受 Olivetti 人脸数据集。 由于每个样本都是 64×64 灰度图像,因此我们需要分配一个形状等于(8,8,4,096)的权重矩阵。 训练过程可能会很长; 因此,我们会将地图限制为 100 个随机样本(当然,读者可以自由删除此限制,并使用整个数据集训练模型)。
在此示例中,我们要训练一个 8×8 正方形 Kohonen 映射以接受 Olivetti 人脸数据集。 由于每个样本都是 64×64 灰度图像,因此我们需要分配一个形状等于(8,8,4,096)的权重矩阵。 训练过程可能会很长; 因此,我们会将映射限制为 100 个随机样本(当然,读者可以自由删除此限制,并使用整个数据集训练模型)。
像往常一样,让我们​​开始加载并规范化数据集,如下所示:
......
......@@ -92,7 +92,7 @@ TensorFlow 是 Google 的开放源代码框架,用于构建机器学习 AI 应
另一个问题是 TensorFlow Mobile 和 TensorFlow Lite 之间的选择。 该书在大多数章节(1 至 10)中介绍了 TensorFlow Mobile。 TensorFlow Lite 可能是在移动设备上运行 TensorFlow 的未来,它在 Google I/O 2018 上仍处于开发人员预览版中,这就是 Google 希望您“使用 TensorFlow Mobile 覆盖生产案例”的原因。 即使在 TensorFlow Lite 正式发布后,根据 Google 的说法,“ TensorFlow Mobile 不会很快消失”-实际上,在本书出版之前我们测试了最新的 TensorFlow 1.8.0 版本,我们发现使用 TensorFlow Mobile 变得更加简单。
如果 TensorFlow Lite 在所有用例中完全取代 TensorFlow Mobile 的那一天(具有 Lite 更好的性能和更小的尺寸)终于到了,那么您从书本中学到的技能将只会为您做好准备。 同时,在那个不可预见的未来到来之前,您可以阅读这本书并了解如何使用 TensorFlow Mobile 这样的老大哥在您的移动应用中运行所有这些功能强大的 TensorFlow 模型。
如果 TensorFlow Lite 在所有用例中完全取代 TensorFlow Mobile 的那一天(具有 Lite 更好的性能和更小的大小)终于到了,那么您从书本中学到的技能将只会为您做好准备。 同时,在那个不可预见的未来到来之前,您可以阅读这本书并了解如何使用 TensorFlow Mobile 这样的老大哥在您的移动应用中运行所有这些功能强大的 TensorFlow 模型。
......
......@@ -235,7 +235,7 @@ Android Studio 是开发 Android 应用的最佳工具,并且 TensorFlow 对
在我们开始运行示例 TensorFlow iOS 和 Android 应用之前,让我们澄清一下。 TensorFlow 当前有两种在移动设备上开发和部署深度学习应用的方法:TensorFlow Mobile 和 TensorFlow Lite。 TensorFlow Mobile 从一开始就是 TensorFlow 的一部分,而 TensorFlow Lite 是开发和部署 TensorFlow 应用的较新方法,因为它具有更好的性能和更小的应用尺寸。 但是有一个关键因素可以让我们在本书中专注于 TensorFlow Mobile,同时仍在一个章节中介绍 TensorFlow Lite:从 TensorFlow 1.8 和 2018 年 5 月的 Google I/O 开始,TensorFlow Lite 仍在开发人员预览版中。 现在,准备投入生产的移动 TensorFlow 应用,您必须按照 Google 的建议使用 TensorFlow Mobile。
在我们开始运行示例 TensorFlow iOS 和 Android 应用之前,让我们澄清一下。 TensorFlow 当前有两种在移动设备上开发和部署深度学习应用的方法:TensorFlow Mobile 和 TensorFlow Lite。 TensorFlow Mobile 从一开始就是 TensorFlow 的一部分,而 TensorFlow Lite 是开发和部署 TensorFlow 应用的较新方法,因为它具有更好的性能和更小的应用大小。 但是有一个关键因素可以让我们在本书中专注于 TensorFlow Mobile,同时仍在一个章节中介绍 TensorFlow Lite:从 TensorFlow 1.8 和 2018 年 5 月的 Google I/O 开始,TensorFlow Lite 仍在开发人员预览版中。 现在,准备投入生产的移动 TensorFlow 应用,您必须按照 Google 的建议使用 TensorFlow Mobile。
我们决定现在专注于 TensorFlow Mobile 的另一个原因是,虽然 TensorFlow Lite 仅对模型运算符提供了有限的支持,但 TensorFlow Mobile 支持自定义以添加默认情况下 TensorFlow Mobile 不支持的新运算符,您会发现它经常发生在我们的各种模型中 AI 应用的模型。
......
......@@ -34,9 +34,9 @@
迁移学习的第二个主要好处是,我们只需要少量的训练数据就可以重新训练 CNN 的最后一层。 如果必须从头开始训练深层 CNN 的数百万个参数,则需要大量的训练数据。 例如,对于我们的狗品种再训练,我们只需要为每个狗品种提供 100 幅以上的图像,即可建立一个比原始图像分类模型更好的狗品种分类模型。
如果您不熟悉 CNN,请查看其中的最佳资源之一的视频和注释,这是 Stanford CS231n 课程[“用于视觉识别的 CNN”](http://cs231n.stanford.edu)。 CNN 的另一个很好的资源是 [Michael Nielsen 的在线书籍《神经网络和深度学习》的第 6 章](http://neuralnetworksanddeeplearning.com/chap6.html#introducing_convolutional_networks)
如果您不熟悉 CNN,请查看其中的最佳资源之一的视频和评论,这是 Stanford CS231n 课程[“用于视觉识别的 CNN”](http://cs231n.stanford.edu)。 CNN 的另一个很好的资源是 [Michael Nielsen 的在线书籍《神经网络和深度学习》的第 6 章](http://neuralnetworksanddeeplearning.com/chap6.html#introducing_convolutional_networks)
在接下来的两个部分中,我们将使用针对 TensorFlow 的两个最佳的经过预训练的 CNN 模型和一个犬种数据集来重新训练模型并生成更好的犬种识别模型。 第一个模型是 Inception v3,它是比 Inception v1 更准确的模型,已针对准确性进行了优化,但尺寸较大。 另一个模型是 MobileNet,它针对移动设备的大小和效率进行了优化。 TensorFlow 支持的预训练模型的详细列表位于[这里](https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models)
在接下来的两个部分中,我们将使用针对 TensorFlow 的两个最佳的经过预训练的 CNN 模型和一个犬种数据集来重新训练模型并生成更好的犬种识别模型。 第一个模型是 Inception v3,它是比 Inception v1 更准确的模型,已针对准确性进行了优化,但大小较大。 另一个模型是 MobileNet,它针对移动设备的大小和效率进行了优化。 TensorFlow 支持的预训练模型的详细列表位于[这里](https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models)
......@@ -46,7 +46,7 @@
在上一章中设置的 TensorFlow 源代码中,有一个 Python 脚本`tensorflow/examples/image_retraining/retrain.py`,可用于重新训练 Inception v3 或 MobileNet 模型。 在运行脚本以重新训练 Inception v3 模型以进行狗品种识别之前,我们需要首先下载[斯坦福狗数据集](http://vision.stanford.edu/aditya86/ImageNetDogs), 120 个犬种的图片(您只需要在链接中下载图片,而不是注释即可)。
在上一章中设置的 TensorFlow 源代码中,有一个 Python 脚本`tensorflow/examples/image_retraining/retrain.py`,可用于重新训练 Inception v3 或 MobileNet 模型。 在运行脚本以重新训练 Inception v3 模型以进行狗品种识别之前,我们需要首先下载[斯坦福狗数据集](http://vision.stanford.edu/aditya86/ImageNetDogs), 120 个犬种的图片(您只需要在链接中下载图片,而不是标注即可)。
`~/Downloads`中解压缩下载的狗`images.tar`文件,您应该在`~/Downloads/Images`中看到文件夹列表,如以下屏幕截图所示。 每个文件夹对应一个犬种,并且包含约 150 张图像(您无需为图像提供显式标签,因为文件夹名称用于标记文件夹中包含的图像):
......@@ -279,7 +279,7 @@ python tensorflow/examples/image_retraining/retrain.py
--architecture mobilenet_1.0_224
```
生成的标签文件`dog_retrained_labels_mobilenet.txt`实际上与使用 Inception v3 模型进行再训练期间生成的标签文件相同。 `--architecture`参数指定 16 个 MobileNet 模型之一,而值`mobilenet_1.0_224`表示使用模型大小为 1.0 的模型(对于其他参数,其他三个可能的值分别为 0.75、0.50 和 0.25 – 1.0,相反,准确但最大的尺寸为 0.25)和 224 作为图像输入尺寸(其他三个值分别为 192、160 和 128)。 如果将`_quantized`添加到架构值的末尾,即`--architecture mobilenet_1.0_224_quantized`,则模型也将被量化,从而导致重新训练的模型大小约为 5.1MB。 非量化模型的大小约为 17MB。
生成的标签文件`dog_retrained_labels_mobilenet.txt`实际上与使用 Inception v3 模型进行再训练期间生成的标签文件相同。 `--architecture`参数指定 16 个 MobileNet 模型之一,而值`mobilenet_1.0_224`表示使用模型大小为 1.0 的模型(对于其他参数,其他三个可能的值分别为 0.75、0.50 和 0.25 – 1.0,相反,准确但最大的大小为 0.25)和 224 作为图像输入大小(其他三个值分别为 192、160 和 128)。 如果将`_quantized`添加到架构值的末尾,即`--architecture mobilenet_1.0_224_quantized`,则模型也将被量化,从而导致重新训练的模型大小约为 5.1MB。 非量化模型的大小约为 17MB。
您可以按以下步骤测试先前使用`label_image`生成的模型:
......@@ -550,7 +550,7 @@ UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTar
[self.view addGestureRecognizer:recognizer];
```
9. 在轻敲处理程序中,我们首先创建两个`alert`操作,以允许用户选择重新训练的模型:
9. 在轻敲处理中,我们首先创建两个`alert`操作,以允许用户选择重新训练的模型:
```py
UIAlertAction* inceptionV3 = [UIAlertAction actionWithTitle:@"Inception v3 Retrained Model" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
......@@ -759,7 +759,7 @@ let recognizer = UITapGestureRecognizer(target: self, action: #selector(ViewCont
self.view.addGestureRecognizer(recognizer)
```
11. 在轻击处理程序中,我们首先添加`alert`动作,以允许用户选择 Inception v3 训练后的模型:
11. 在轻击处理中,我们首先添加`alert`动作,以允许用户选择 Inception v3 训练后的模型:
```py
let alert = UIAlertController(title: "Pick a Model", message: nil, preferredStyle: .actionSheet)
......@@ -866,7 +866,7 @@ Classifier classifier = TensorFlowImageClassifier.create(
OUTPUT_NAME);
```
然后从`assets`文件夹中读取我们的测试图像,根据模型指定的尺寸进行调整,然后调用推理方法`recognizeImage`
然后从`assets`文件夹中读取我们的测试图像,根据模型指定的大小进行调整,然后调用推理方法`recognizeImage`
```py
Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open(IMG_FILE));
......
......@@ -239,7 +239,7 @@ Found 4 possible outputs: (name=detection_boxes, op=Identity) (name=detection_sc
经过预训练的 TensorFlow 对象检测模型当然可以很好地解决某些问题。 但是有时候,您可能需要使用自己的带注释的数据集(在您特别感兴趣的对象或对象部分周围带有边界框)并重新训练现有模型,以便它可以更准确地检测不同的对象类别集合。
经过预训练的 TensorFlow 对象检测模型当然可以很好地解决某些问题。 但是有时候,您可能需要使用自己的带标注的数据集(在您特别感兴趣的对象或对象部分周围带有边界框)并重新训练现有模型,以便它可以更准确地检测不同的对象类别集合。
我们将使用 TensorFlow 对象检测 API 网站中记录的相同的 Oxford-IIIT Pets 数据集来重新训练本地计算机上的两个现有模型,而不是使用文档中介绍的 Google Cloud。 必要时,我们还将为每个步骤添加说明。 以下是有关如何使用 Oxford Oxford Pets 数据集重新训练 TensorFlow 对象检测模型的分步指南:
......@@ -485,7 +485,7 @@ tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a
-force_load $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/gen/protobuf_ios/lib/libprotobuf.a $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/gen/protobuf_ios/lib/libprotobuf-lite.a $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/downloads/nsync/builds/lipo.ios.c++11/nsync.a
```
需要第一个`–force_load`,因为它确保 TensorFlow 所需的 C++ 构造函数将被链接,否则,您仍可以构建和运行该应用,但会遇到有关未注册会话的错误。
需要第一个`–force_load`,因为它确保 TensorFlow 所需的 C++ 构造将被链接,否则,您仍可以构建和运行该应用,但会遇到有关未注册会话的错误。
最后一个库用于`nsync`,这是一个 C 库,[可导出互斥量和其他同步方法](https://github.com/google/nsync)。 在新的 TensorFlow 版本中引入。
......@@ -545,7 +545,7 @@ cd <TENSORFLOW_ROOT>/models/research/object_detection/protos
```
5. `protoc`编译器命令完成后,您将在项目的源目录中看到两个文件:`string_int_label_map.pb.cc``string_int_label_map.pb.h`。 将两个文件添加到 Xcode 项目中。
6. 在 Xcode 中,像在上一章中一样,将`ViewController.m`重命名为`ViewController.mm`,然后类似于第 2 章,“通过迁移学习对图像进行分类”的`HelloTensorFlow`应用的`ViewController.mm`,在点击的处理程序中为三个对象检测模型添加三个`UIAlertAction`,我们已将模型添加到项目中并将要测试。 现在,完整的项目文件应如图 3.7 所示:
6. 在 Xcode 中,像在上一章中一样,将`ViewController.m`重命名为`ViewController.mm`,然后类似于第 2 章,“通过迁移学习对图像进行分类”的`HelloTensorFlow`应用的`ViewController.mm`,在点击的处理中为三个对象检测模型添加三个`UIAlertAction`,我们已将模型添加到项目中并将要测试。 现在,完整的项目文件应如图 3.7 所示:
![](img/7023289e-ae57-4518-920e-140985314d13.png)
......@@ -564,7 +564,7 @@ void RunInferenceOnImage(NSString *model)
下一步之后,我们将解释这些函数的实现,您可以在该书的源代码仓库的`ch3/ios`文件夹中获取所有源代码。
8. 在 iOS 模拟器或设备中运行该应用。 首先,您会在屏幕上看到一张图片。 点按任意位置,您将看到一个对话框,要求您选择模型。 选择`SSD MobileNet`型号,在模拟器中花费大约一秒钟,在 iPhone 6 上花费五秒钟,以在图像上绘制检测结果。 Faster RCNN Inception V2 需要更长的时间(在模拟器中大约需要 5 秒,在 iPhone 6 上大约需要 20 秒); 该模型也比`SSD MobileNet`更精确,可以捕获`SSD MobileNet`模型遗漏的一个狗物体。 最后一个型号,更快的 RCNN Resnet 101,在 iOS 模拟器中花费了将近 20 秒,但由于其尺寸而在 iPhone 6 上崩溃。 图 3.8 总结了运行结果:
8. 在 iOS 模拟器或设备中运行该应用。 首先,您会在屏幕上看到一张图片。 点按任意位置,您将看到一个对话框,要求您选择模型。 选择`SSD MobileNet`型号,在模拟器中花费大约一秒钟,在 iPhone 6 上花费五秒钟,以在图像上绘制检测结果。 Faster RCNN Inception V2 需要更长的时间(在模拟器中大约需要 5 秒,在 iPhone 6 上大约需要 20 秒); 该模型也比`SSD MobileNet`更精确,可以捕获`SSD MobileNet`模型遗漏的一个狗物体。 最后一个型号,更快的 RCNN Resnet 101,在 iOS 模拟器中花费了将近 20 秒,但由于其大小而在 iPhone 6 上崩溃。 图 3.8 总结了运行结果:
![](img/411e68db-3026-4ba4-964a-3d9a174dce6f.png)
......
......@@ -340,7 +340,7 @@ try {
}
```
11. 类似地设置`mButton`并设置一个点击听器,以便在点击按钮时,创建并启动一个新线程,并调用`run`方法:
11. 类似地设置`mButton`并设置一个点击听器,以便在点击按钮时,创建并启动一个新线程,并调用`run`方法:
```py
mButton = findViewById(R.id.button);
......@@ -354,7 +354,7 @@ mButton.setOnClickListener(new View.OnClickListener() {
});
```
12. 在线程的`run`方法中,我们首先声明三个数组,并为其分配适当的内存:`intValues`数组保存测试图像的像素值,每个像素值代表 32 位 ARGB(Alpha,红,绿,蓝色)值; `floatValues`阵列如模型所预期的那样分别保存每个像素的红色,绿色和蓝色值,因此其大小是`intValues`的三倍,并且`outputValues`的大小与`floatValues`相同 ],但保留模型的输出值:
12. 在线程的`run`方法中,我们首先声明三个数组,并为其分配适当的内存:`intValues`数组保存测试图像的像素值,每个像素值代表 32 位 ARGB(Alpha,红,绿,蓝色)值; `floatValues`数组如模型所预期的那样分别保存每个像素的红色,绿色和蓝色值,因此其大小是`intValues`的三倍,并且`outputValues`的大小与`floatValues`相同 ],但保留模型的输出值:
```py
public void run() {
......@@ -378,9 +378,9 @@ for (int i = 0; i < intValues.length; i++) {
}
```
注意,`val``intValues`像素阵列的每个元素是一个 32 位整数,在其每个 8 位区域中均保留 ARGB。 我们使用向右移位(用于红色和绿色)和按位与运算来提取每个像素的红色,绿色和蓝色值,而忽略`intValues`元素中最左边的 8 位的 Alpha 值。 因此`floatValues[i*3]``floatValues[i*3+1]``floatValues[i*3+2]`分别保持像素的红色,绿色和蓝色值。
注意,`val``intValues`像素数组的每个元素是一个 32 位整数,在其每个 8 位区域中均保留 ARGB。 我们使用向右移位(用于红色和绿色)和按位与运算来提取每个像素的红色,绿色和蓝色值,而忽略`intValues`元素中最左边的 8 位的 Alpha 值。 因此`floatValues[i*3]``floatValues[i*3+1]``floatValues[i*3+2]`分别保持像素的红色,绿色和蓝色值。
现在,我们创建一个新的`TensorFlowInferenceInterface`实例,并在其中将`AssetManager`实例和模型文件名传递到`assets`文件夹中,然后使用 `TensorFlowInferenceInterface`实例将转换后的[ `floatValues`阵列。 如果模型需要多个输入节点,则可以调用多个`feed`方法。 然后,我们通过传递输出节点名称的字符串数组来运行模型。 在这里,对于我们的快速样式迁移模型,我们只有一个输入节点和一个输出节点。 最后,我们通过传递输出节点名称来获取模型的输出值。 如果希望接收多个输出节点,则可以调用多个访存:
现在,我们创建一个新的`TensorFlowInferenceInterface`实例,并在其中将`AssetManager`实例和模型文件名传递到`assets`文件夹中,然后使用 `TensorFlowInferenceInterface`实例将转换后的[ `floatValues`数组。 如果模型需要多个输入节点,则可以调用多个`feed`方法。 然后,我们通过传递输出节点名称的字符串数组来运行模型。 在这里,对于我们的快速样式迁移模型,我们只有一个输入节点和一个输出节点。 最后,我们通过传递输出节点名称来获取模型的输出值。 如果希望接收多个输出节点,则可以调用多个访存:
```py
AssetManager assetManager = getAssets();
......@@ -408,7 +408,7 @@ outputBitmap.setPixels(intValues, 0, outputBitmap.getWidth(), 0, 0, outputBitmap
mTransferredBitmap = Bitmap.createScaledBitmap(outputBitmap, bitmap.getWidth(), bitmap.getHeight(), true);
```
最后,我们向主线程的处理程序发送一条消息,以使其知道显示样式迁移图像的时间:
最后,我们向主线程的处理发送一条消息,以使其知道显示样式迁移图像的时间:
```py
Message msg = new Message();
......@@ -439,7 +439,7 @@ mHandler.sendMessage(msg);
在本章前面创建的 iOS 应用中,执行以下步骤来使用和运行多样式模型:
1.`stylize_quantized.pb`文件从`tensorflow/examples/android/assets`拖放到 Xcode 中的 iOS `apps`文件夹中。
2. 使用用于加载和处理快速传输样式模型的相同 `dispatch_async` ,向抽头处理程序中添加新的`UIAlertAction`
2. 使用用于加载和处理快速传输样式模型的相同 `dispatch_async` ,向抽头处理中添加新的`UIAlertAction`
```py
UIAlertAction* multi_style_transfer = [UIAlertAction actionWithTitle:@"Multistyle Transfer" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
......@@ -584,7 +584,7 @@ for (int i = 0; i < intValues.length; ++i) {
}
```
使用首先设置`styleVals`数组的代码段(如果对`styleVals`和如何设置数组的值感到困惑,请查看上一节第 5 步中的注):
使用首先设置`styleVals`数组的代码段(如果对`styleVals`和如何设置数组的值感到困惑,请查看上一节第 5 步中的注):
```py
final float[] styleVals = new float[NUM_STYLES];
......
......@@ -57,7 +57,7 @@ RNN 允许我们处理输入和/或输出的序列,因为根据设计,网络
语音命令数据集是从[开放语音记录站点](https://aiyprojects.withgoogle.com/open_speech_recording)收集的。您应该尝试一下,也许自己花些时间来录制自己的录音,以帮助改善录音效果,并在需要时了解如何收集自己的语音命令数据集。 关于使用数据集构建模型,[还有一个 Kaggle 竞赛](https://www.kaggle.com/c/tensorflow-speech-recognition-challenge),您可以在此处了解有关语音模型和提示的更多信息。
在移动应用中要训练和使用的模型基于纸质卷积神经网络,[用于小尺寸关键词发现](http://www.isca-speech.org/archive/interspeech_2015/papers/i15_1478.pdf),这与大多数其他基于 RNN 的大规模语音识别模型不同。 基于 CNN 的语音识别模型是可能的,但很有趣,因为对于简单的语音命令识别,我们可以在短时间内将音频信号转换为图像,或更准确地说,将频谱图转换为频率窗口期间音频信号的分布(有关使用`wav_to_spectrogram`脚本生成的示例频谱图图像,请参见本节开头的 TensorFlow 教程链接)。 换句话说,我们可以将音频信号从其原始时域表示转换为频域表示。 进行此转换的最佳算法是**离散傅立叶变换****DFT**),**快速傅立叶变换****FFT**)只是一种有效的选择 DFT 实现的算法。
在移动应用中要训练和使用的模型基于纸质卷积神经网络,[用于小大小关键词发现](http://www.isca-speech.org/archive/interspeech_2015/papers/i15_1478.pdf),这与大多数其他基于 RNN 的大规模语音识别模型不同。 基于 CNN 的语音识别模型是可能的,但很有趣,因为对于简单的语音命令识别,我们可以在短时间内将音频信号转换为图像,或更准确地说,将频谱图转换为频率窗口期间音频信号的分布(有关使用`wav_to_spectrogram`脚本生成的示例频谱图图像,请参见本节开头的 TensorFlow 教程链接)。 换句话说,我们可以将音频信号从其原始时域表示转换为频域表示。 进行此转换的最佳算法是**离散傅立叶变换****DFT**),**快速傅立叶变换****FFT**)只是一种有效的选择 DFT 实现的算法。
作为移动开发人员,您可能不需要了解 DFT 和 FFT。 但是,您最好了解所有这些模型训练在移动应用中使用时是如何工作的,因为我们知道我们将要介绍的 TensorFlow 简单语音命令模型训练的幕后花絮,这是 FFT 的使用,前十大模型之一。当然,除其他事项外,20 世纪的算法使基于 CNN 的语音命令识别模型训练成为可能。 有关 DFT 的有趣且直观的教程,您可以阅读[以下文章](http://practicalcryptography.com/miscellaneous/machine-learning/intuitive-guide-discrete-fourier-transform)
......@@ -262,7 +262,7 @@ private Button mButton;
private TextView mTextView;
```
7.`onCreate`方法中,我们首先实例化`mButton``mTextView`,然后设置按钮单击事件处理程序,该事件处理程序首先更改按钮标题,然后启动线程进行记录和识别:
7.`onCreate`方法中,我们首先实例化`mButton``mTextView`,然后设置按钮单击事件处理器,该事件处理器首先更改按钮标题,然后启动线程进行记录和识别:
```py
mButton = findViewById(R.id.button);
......@@ -465,7 +465,7 @@ std::string audioRecognition(float* floatInputBuffer, int length);
在此,我们不会显示以编程方式创建两个 UI 元素的代码段:一个按钮,当您点击该按钮时,它将开始录制 1 秒钟的音频,然后将音频发送到我们的模型以进行识别,以及一个显示识别结果的标签。 但是,我们将在下一部分中的 Swift 中展示一些 UI 代码以供复习。
4. 在按钮的`UIControlEventTouchUpInside`处理程序内,我们首先创建一个`AVAudioSession`实例,并将其类别设置为记录并将其激活:
4. 在按钮的`UIControlEventTouchUpInside`处理内,我们首先创建一个`AVAudioSession`实例,并将其类别设置为记录并将其激活:
```py
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
......@@ -496,7 +496,7 @@ NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];
```
最后,在按钮点击处理程序中,我们定义保存录制的音频的位置,创建`AVAudioRecorder`实例,设置其委托并开始录制 1 秒钟:
最后,在按钮点击处理中,我们定义保存录制的音频的位置,创建`AVAudioRecorder`实例,设置其委托并开始录制 1 秒钟:
```py
self.recorderFilePath = [NSString stringWithFormat:@"%@/recorded_file.wav", [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"]];
......@@ -696,7 +696,7 @@ override func viewDidLoad() {
self.view.addSubview(_lbl)
```
5. 添加一个按钮点击处理程序,并在其内部,首先请求用户的录制许可:
5. 添加一个按钮点击处理,并在其内部,首先请求用户的录制许可:
```py
@objc func btnTapped() {
......@@ -782,7 +782,7 @@ func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully f
}
```
如果您确实想将尽可能多的代码移植到 Swift,[则可以用 Swift 替换 C 中的音频文件转换代码](https://developer.apple.com/documentation/audiotoolbox/extended_audio_file_services)。 还有一些非官方的开源项目提供了官方 TensorFlow C++ API 的 Swift 包装器。 但是为了简单起见和达到适当的平衡,我们将保持 TensorFlow 模型的推论,在本示例中,还将保持音频文件的读取和转换,以及在 C++ 和 Objective-C 中与控制 UI 和录音,并启动呼叫以进行音频处理和识别。
如果您确实想将尽可能多的代码移植到 Swift,[则可以用 Swift 替换 C 中的音频文件转换代码](https://developer.apple.com/documentation/audiotoolbox/extended_audio_file_services)。 还有一些非官方的开源项目提供了官方 TensorFlow C++ API 的 Swift 包装器。 但是为了简单起见和达到适当的平衡,我们将保持 TensorFlow 模型的推论,在本示例中,还将保持音频文件的读取和转换,以及在 C++ 和 Objective-C 中与控制 UI 和录音,并启动调用来进行音频处理和识别。
这就是构建使用语音命令识别模型的 Swift iOS 应用所需的全部内容。 现在,您可以在 iOS 模拟器或实际设备上运行它,并看到与 Objective-C 版本完全相同的结果。
......
......@@ -721,7 +721,7 @@ bazel build //tensorflow/contrib/android:android_tensorflow_inference_java
请按照以下步骤使用 TensorFlow 库和我们先前构建的模型创建一个新的 Android 应用:
1. 在 Android Studio 中,创建一个名为 QuickDraw 的新 Android 应用,接受所有默认设置。 然后在应用的`build.gradle`中,将`compile files('libs/libandroid_tensorflow_inference_java.jar')`添加到依赖项的末尾。 像以前一样创建一个新的`assets`文件夹,并将`quickdraw_frozen_long_blacklist_strip_transformed.pb``classes.txt`拖放到该文件夹​​中。
2. 创建一个名为`QuickDrawView`的新 Java 类,该类扩展了`View`,并如下设置字段及其构造函数
2. 创建一个名为`QuickDrawView`的新 Java 类,该类扩展了`View`,并如下设置字段及其构造
```py
public class QuickDrawView extends View {
......@@ -865,7 +865,7 @@ public class MainActivity extends AppCompatActivity implements Runnable {
app:layout_constraintTop_toTopOf="parent"/>
```
8. 返回`MainActivity`; 在其`onCreate`方法中,将 UI 元素 ID 与字段绑定,为启动/重启按钮设置点击听器。 然后将`classes.txt`文件读入字符串数组:
8. 返回`MainActivity`; 在其`onCreate`方法中,将 UI 元素 ID 与字段绑定,为启动/重启按钮设置点击听器。 然后将`classes.txt`文件读入字符串数组:
```py
@Override
......
......@@ -522,7 +522,7 @@ plt.show()
图 8.2:使用 Keras 双向和堆叠 LSTM 层进行股价预测
很容易在栈中添加更多 LSTM 层,或者使用诸如学习率和丢弃率以及许多恒定设置之类的超参数。 但是,对于使用`pred_len``shift_pred`的不同设置,正确率的差异还没有发现。 也许我们现在应该对接近 60% 的正确率感到满意,并看看如何在 iOS 和 Android 上使用 TensorFlow 和 Keras 训练的模型-我们可以在以后继续尝试改进模型,但是,了解使用 TensorFlow 和 Keras 训练的 RNN 模型是否会遇到任何问题将非常有价值。
很容易在栈中添加更多 LSTM 层,或者使用诸如学习率和丢弃率以及许多恒定设置之类的超参数。 但是,对于使用`pred_len``shift_pred`的不同设置,正确率的差异还没有发现。 也许我们现在应该对接近 60% 的正确率感到满意,并看看如何在 iOS 和 Android 上使用 TensorFlow 和 Keras 训练的模型-我们可以在以后继续尝试改进模型,但是,了解使用 TensorFlow 和 Keras 训练的 RNN 模型是否会遇到任何问题将非常有价值。
正如 FrançoisChollet 指出的那样,“深度学习更多的是艺术而不是科学……每个问题都是独特的,您将不得不尝试并经验地评估不同的策略。目前尚无理论可以提前准确地告诉您应该做什么。 以最佳方式解决问题。您必须尝试并进行迭代。” 希望我们为您使用 TensorFlow 和 Keras API 改善股票价格预测模型提供了一个很好的起点。
......@@ -558,7 +558,7 @@ NSMutableArray *_closeprices;
const int SEQ_LEN = 20;
```
然后创建一个按钮点击处理程序,以使用户可以选择 TensorFlow 或 Keras 模型(该按钮在`viewDidLoad`方法中像以前一样创建):
然后创建一个按钮点击处理,以使用户可以选择 TensorFlow 或 Keras 模型(该按钮在`viewDidLoad`方法中像以前一样创建):
```py
- (IBAction)btnTapped:(id)sender {
......
......@@ -28,7 +28,7 @@ GAN 是学习生成类似于真实数据或训练集中数据的神经网络。
* 当以生成器的输出作为输入时,使其输出的可能性为实,尽可能接近 0.0,这恰好是生成器的相反目标
* 当输入真实数据作为输入时,使其输出的可能性为实数,尽可能接近 1.0
在下一节中,您将看到与生成器和鉴别器网络及其训练过程的给定描述相匹配的详细代码片段。 如果您想了解更多关于 GAN 的知识,除了这里的摘要概述之外,您还可以在 YouTube 上搜索“GAN 简介”,并观看 2016 年 NIPS(神经信息处理系统)和 ICCV(国际计算机视觉会议)2017 大会上的 Ian Goodfellow 的 GAN 入门和教程视频。 事实上,YouTube 上有 7 个 NIPS 2016 对抗训练讲习班视频和 12 个 ICCV 2017 GAN 指导视频,您可以自己投入其中。
在下一节中,您将看到与生成器和鉴别器网络及其训练过程的给定描述相匹配的详细代码片段。 如果您想了解更多关于 GAN 的知识,除了这里的摘要概述之外,您还可以在 YouTube 上搜索“GAN 简介”,并观看 2016 年 NIPS(神经信息处理系统)和 ICCV(国际计算机视觉会议)2017 大会上的 Ian Goodfellow 的 GAN 入门和教程视频。 事实上,YouTube 上有 7 个 NIPS 2016 对抗训练培训班视频和 12 个 ICCV 2017 GAN 指导视频,您可以自己投入其中。
在生成者和区分者两个参与者的竞争目标下,GAN 是一个寻求两个对手之间保持平衡的系统。 如果两个玩家都具有无限的能力并且可以进行最佳训练,那么纳什均衡(继 1994 年诺贝尔经济学奖得主约翰·纳什和电影主题《美丽心灵》之后) 一种状态,在这种状态下,任何玩家都无法通过仅更改其自己的策略来获利,这对应于生成器生成数据的状态,该数据看起来像真实数据,而判别器无法从假数据中分辨真实数据。
......@@ -605,7 +605,7 @@ protected void onCreate(Bundle savedInstanceState) {
}
```
然后,为两个按钮设置两个单击听器:
然后,为两个按钮设置两个单击听器:
```py
mButtonMNIST.setOnClickListener(new View.OnClickListener() {
......
......@@ -449,7 +449,7 @@ string playGame(bool withMCTS) {
else binary[PIECES_NUM+i] = 0;
```
例如,如果板阵列`[0 1 1 -1 1 -1 0 0 1 -1 -1 -1 -1 1 0 0 1 -1 1 -1 1 0 0 -1 -1 -1 1 -1 0 1 1 1 -1 -1 -1 -1 1 1 1 -1 1 1 -1]`,代表以下板状态(`X`表示 1,`O`表示 -1,`-`表示 0):
例如,如果板数组`[0 1 1 -1 1 -1 0 0 1 -1 -1 -1 -1 1 0 0 1 -1 1 -1 1 0 0 -1 -1 -1 1 -1 0 1 1 1 -1 -1 -1 -1 1 1 1 -1 1 1 -1]`,代表以下板状态(`X`表示 1,`O`表示 -1,`-`表示 0):
```py
['-', 'X', 'X', 'O', 'X', 'O', '-']
......@@ -484,7 +484,7 @@ string playGame(bool withMCTS) {
我们仅使用最大概率值来指导 AI 的移动,而不使用 MCTS,如果我们希望 AI 在象棋或围棋这样的复杂游戏中真正强大,这将是必要的。 如前所述,如果从经过训练的模型返回的策略是完美的,则无需使用 MCTS。 我们将在书的源代码存储库中保留 MCTS 实现,以供您参考,而不是显示 MCTS 的所有实现细节。
`playGame`方法中的其余代码根据模型返回的所有合法动作中的最大概率,以选定的动作来更新木板,将`printBoard` 辅助方法调用来在 Xcode 输出面板上打印板以进行更好的调试,将动作添加到 `aiMoves` 向量中,以便可以正确重绘板,并在游戏结束时返回正确的状态信息。 通过将 `aiTurn` 设置为 `false` ,您将很快看到的触摸事件处理程序将接受人类的触摸手势,作为人类打算采取的动作; 如果 `aiTurn``true` ,则触摸处理程序将忽略所有触摸手势:
`playGame`方法中的其余代码根据模型返回的所有合法动作中的最大概率,以选定的动作来更新木板,将`printBoard` 辅助方法调用来在 Xcode 输出面板上打印板以进行更好的调试,将动作添加到 `aiMoves` 向量中,以便可以正确重绘板,并在游戏结束时返回正确的状态信息。 通过将 `aiTurn` 设置为 `false` ,您将很快看到的触摸事件处理器将接受人类的触摸手势,作为人类打算采取的动作; 如果 `aiTurn``true` ,则触摸处理器将忽略所有触摸手势:
```py
board[action] = AI_PIECE;
......@@ -692,7 +692,7 @@ int winners[69][4] = {
{14,22,30,38}};
```
在触摸事件处理程序中,首先确保轮到人了。 然后检查触摸点值是否在面板区域内,根据触摸位置获取点击的列,并更新`board`数组和`humanMoves`向量:
在触摸事件处理中,首先确保轮到人了。 然后检查触摸点值是否在面板区域内,根据触摸位置获取点击的列,并更新`board`数组和`humanMoves`向量:
```py
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
......@@ -712,7 +712,7 @@ int winners[69][4] = {
}
```
其余触摸处理程序通过调用`createBoardImageInRect`来重绘`ImageView`,它使用`BezierPath`绘制或重绘棋盘和所有已玩过的棋子,检查游戏状态并在游戏结束时返回结果,或者继续玩游戏,如果没有:
其余触摸处理通过调用`createBoardImageInRect`来重绘`ImageView`,它使用`BezierPath`绘制或重绘棋盘和所有已玩过的棋子,检查游戏状态并在游戏结束时返回结果,或者继续玩游戏,如果没有:
```py
_iv.image = [self createBoardImageInRect:_iv.frame];
......@@ -1162,7 +1162,7 @@ public class MainActivity extends AppCompatActivity implements Runnable {
}
```
`onCreate`方法中,实例化三个 UI 元素,并设置按钮单击听器,以便它随机决定谁先采取行动。 当用户想要重玩游戏时,也会点击该按钮,因此我们需要在绘制面板和启动线程进行游戏之前重置`aiMoves``humanMoves`向量:
`onCreate`方法中,实例化三个 UI 元素,并设置按钮单击听器,以便它随机决定谁先采取行动。 当用户想要重玩游戏时,也会点击该按钮,因此我们需要在绘制面板和启动线程进行游戏之前重置`aiMoves``humanMoves`向量:
```py
protected void onCreate(Bundle savedInstanceState) {
......
......@@ -87,7 +87,7 @@ open simple.xcworkspace
如果在 iPhone 上安装并运行这两个应用,则从 iPhone 的设置中将看到 `tflite_camera_example`的应用大小约为 18.7MB,`tf_camera_example`的大小约为 44.2MB。
的确,Inception 3 模型的准确性比 MobileNet 模型要高,但是在许多使用情况下,可以忽略很小的准确性差异。 另外,不可否认,如今的移动应用很容易占用数十 MB 的空间,在某些用例中,应用大小相差 20 或 30MB 听起来并不大,但是在较小的嵌入式设备中,大小会更加敏感,如果我们可以以更快的速度和更小的尺寸获得几乎相同的精度,而不会遇到太多麻烦,对于用户而言,这永远是一件好事。
的确,Inception 3 模型的准确性比 MobileNet 模型要高,但是在许多使用情况下,可以忽略很小的准确性差异。 另外,不可否认,如今的移动应用很容易占用数十 MB 的空间,在某些用例中,应用大小相差 20 或 30MB 听起来并不大,但是在较小的嵌入式设备中,大小会更加敏感,如果我们可以以更快的速度和更小的大小获得几乎相同的精度,而不会遇到太多麻烦,对于用户而言,这永远是一件好事。
......@@ -333,7 +333,7 @@ bazel-bin/tensorflow/contrib/lite/toco/toco \
图 11.6:使用 TensorFlow Lite 和预构建的 MobileNet 图像分类模型的新 Android 应用
5. 像以前一样,在`activity_main.xml`中添加`ImageView``Button`,然后在`MainActivity.java``onCreate`方法中,将`ImageView`设置为测试图像的内容,然后单击 `Button`听器以启动新线程,并实例化名为`classifier``ImageClassifier`实例:
5. 像以前一样,在`activity_main.xml`中添加`ImageView``Button`,然后在`MainActivity.java``onCreate`方法中,将`ImageView`设置为测试图像的内容,然后单击 `Button`听器以启动新线程,并实例化名为`classifier``ImageClassifier`实例:
```py
private ImageClassifier classifier;
......
......@@ -185,7 +185,7 @@ gpg3_obj.turn_degrees(-30)
gpg3_obj.stop()
```
`drive_cm`根据其参数值是正值还是负值来向前或向后移动机器人。 `turn_degrees`顺时针或逆时针旋转机器人,取决于其参数值是正值还是负值。 因此,前面的示例代码将机器人向前移动 5 厘米,然后向后移动 5 厘米,顺时针旋转 30 度,然后逆时针旋转 30 度。 默认情况下,这些呼叫是阻止呼叫,因此直到机器人完成移动后它们才返回。 要进行非阻塞调用,请添加`False`参数,如下所示:
`drive_cm`根据其参数值是正值还是负值来向前或向后移动机器人。 `turn_degrees`顺时针或逆时针旋转机器人,取决于其参数值是正值还是负值。 因此,前面的示例代码将机器人向前移动 5 厘米,然后向后移动 5 厘米,顺时针旋转 30 度,然后逆时针旋转 30 度。 默认情况下,这些调用是阻塞调用,因此直到机器人完成移动后它们才返回。 要进行非阻塞调用,请添加`False`参数,如下所示:
```py
gpg3_obj.drive_cm(5, False)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册