TowardsDataScience 博客中文翻译 2016~2018(一百五十二)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何使用云 ML 引擎在云端训练机器学习模型

原文:https://towardsdatascience.com/how-to-train-machine-learning-models-in-the-cloud-using-cloud-ml-engine-3f0d935294b3?source=collection_archive---------1-----------------------

以及如何使用 docopt 包巧妙地编写一个task.py

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在云中训练 ML 模型很有意义。为什么?在许多原因中,它允许你用大量的计算训练大量的数据,并且可能并行训练许多模型。加上也不难做!在 Google 云平台上,可以使用 Cloud ML Engine 在 TensorFlow 和其他 Python ML 库中(如 scikit-learn)训练机器学习模型,而无需管理任何基础设施。为了做到这一点,你需要将你的代码放入一个 Python 包中(即添加setup.py__init__.py文件)。此外,将您的代码组织成一个model.pytask.py是一个最佳实践。在这篇博文中,我将带你一步一步地了解这涉及到什么。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Submitting a job to ML Engine. The file *task.py* is the file actually executed by ML Engine and it references the model logic located in *model.py*.

**task.py**文件

作为一名教师,我看到学生,尤其是那些刚接触 Python 的学生,最先遇到的事情之一就是创建一个task.py文件。虽然这在技术上是可选的(见下文),但强烈推荐,因为它允许你将超参数从模型逻辑中分离出来(位于model.py)。它通常是由 ML 引擎调用的实际文件,其目的有两个:

  1. 读取和解析模型参数,如训练数据和输出模型的位置、隐藏层数、批量大小等。
  2. 用所述参数调用位于model.py中的模型训练逻辑

An example task.py file that parses command line arguments for training data location, batch size, hidden units, and the output location of the final model.

有许多不同的方法可以编写一个task.py文件——你甚至可以给它起不同的名字。事实上task.pymodel.py约定仅仅是一个约定。我们本来可以称之为task.py aReallyCoolArgument_parser.pymodel.py very_deeeep_model.py

我们甚至可以将这两个实体合并到一个文件中,进行参数解析和训练模型。只要你把你的代码安排到一个 Python 包中(即它必须包含 setup.py__init__.py),ML 引擎就不会在意。但是,坚持在一个 trainer 文件夹中命名为task.pymodel.py的两个文件的惯例(更多细节在下面),这两个文件分别存放您的参数解析和模型逻辑。

查看云 ML 示例云 ML 培训报告,了解使用云 ML 引擎的完整示例以及model.pytask.py 文件的示例。

使用 docopt 编写干净 **task.py** 文件

尽管许多人使用 argparse,这是用于解析命令行参数的标准 Python 库,但我更喜欢使用 docopt 包来编写我的task.py文件。为什么?因为这是写一个记载 task.py最简洁的方法。事实上,几乎你唯一需要写的就是你的程序的使用信息(即帮助信息),而 docopt 会处理剩下的事情。基于您在模块的 doc 字符串中编写的用法消息(Python 将调用这个__doc__),您调用docopt(__doc__),它根据您在 doc 字符串中指定的格式为您生成一个参数解析器。以下是上面使用 docopt 的示例:

很不错,对吧?让我来分解一下。第一块代码是您的task.py的用法。如果您不带参数调用它或者错误地调用task.py,这将显示给用户。

arguments = docopt(__doc__)行从帮助字符串中解析用法模式(“用法:…”)和选项描述(以破折号“-”开头的行),并确保程序调用与用法模式匹配。

最后一部分将这些参数分配给model.py变量,然后执行训练和评估。

让我们运行一个任务。记住task.py是称为 Python 包的文件家族的一部分。在实践中,您将花大部分时间编写model.py文件,花一点时间创建task.py file,其余的基本上是样板文件。

training_example # root directory
   setup.py # says how to install your package
   trainer # package name, “trainer” is convention
      model.py
      task.py
      __init__.py # Python convention indicating this is a package

因为我们使用的是 docopt,它不是标准库的一部分,我们必须将它添加到setup.py,所以我们在setup.py中插入了一个额外的行:

这将告诉 Cloud ML Engine 在我们向云提交作业时通过运行pip install docopt来安装 docopt。

最后,一旦我们有了以上结构的文件,我们就可以向 ML 引擎提交一个作业。在我们这样做之前,让我们首先使用python -mml-engine local predict在本地测试我们的包。这两个步骤虽然是可选的,但可以帮助您在提交到云之前调试和测试包的功能。你通常在一个很小的数据集或非常有限的训练步骤上这样做。

Before you train on the cloud, test your package locally to make sure there are no syntactic or semantic errors.

一旦我们在本地测试了我们的模型,我们将使用gcloud ml-engine jobs submit training向 ML 引擎提交我们的作业

这两行与我们的讨论相关:

— package-path=$(pwd)/my_model_package/trainer \
— module-name trainer.task

第一行表示我们包名的位置,我们总是称之为trainer(一个约定)。第二行表示,在培训师包中,我们将调用培训师包中的任务模块(task.py)。

结论

通过构建task.py,我们可以将超参数作为命令行参数来处理,这允许我们将模型逻辑从超参数中分离出来。一个重要的好处是,这使我们能够使用不同的参数轻松地并行启动多个作业,以确定最佳超参数集(我们甚至可以使用内置的超参数调整服务!).最后,docopt 包根据用户编写的用法字符串自动为我们的task.py文件生成一个解析器。

就是这样!我希望这能清楚地说明如何提交一个 ML 引擎作业并构建一个task.py。如果你觉得这很有帮助,请留下你的掌声,让其他人也能发现。

附加资源

如何用优化器更快的训练神经网络?

原文:https://towardsdatascience.com/how-to-train-neural-network-faster-with-optimizers-d297730b3713?source=collection_archive---------6-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

神经网络的秘密第四部分

当我在写最后一篇文章时,我有机会只用 Numpy 创建自己的神经网络。这是一项非常具有挑战性的任务,但同时它极大地拓宽了我对神经网络内部发生的过程的理解。其中,这次经历让我真正意识到有多少因素影响神经网络的性能。所选的架构、适当的超参数值,甚至参数的正确初始化,只是其中的一部分…然而,这一次,我们将关注对学习过程速度有巨大影响的决策,以及获得的预测的准确性——优化策略的选择。我们将深入了解许多流行的优化器,研究它们是如何工作的,并将它们相互比较。

**注意:**由于我想涵盖的内容范围相当广,所以我决定不在本文中包含任何代码片段。但是请记住,像往常一样,您可以在 GitHub 上找到所有用于创建可视化效果的代码。我还准备了一些笔记本,可以让你更好地理解讨论的问题。

机器学习算法的优化

O 优化是一个寻找使我们的功能最小化或最大化的参数的过程。当我们训练机器学习模型时,我们通常使用间接优化。我们选择某种度量标准,如准确度、精确度或召回率,这表明我们的模型解决给定问题的效果如何。然而,我们正在优化一个不同的成本函数 J(θ) ,并希望最小化其值将改善我们关心的度量。当然,成本函数的选择通常与我们要解决的特定问题有关。本质上,它是故意设计来表明我们离理想的解决方案有多远。可以想象,这个话题相当复杂,是一篇单独文章的绝佳话题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1. Examples of points which are a problem for optimization algorithms.

一路上的陷阱

然而事实证明,找到非凸成本函数的最小值通常并不容易,我们必须使用高级优化策略来定位它们。如果你学过微分学,你肯定知道局部最小值的概念——这是我们的优化器可能陷入的一些最大的陷阱。对于那些还没有接触过数学中这一奇妙部分的人,我只能说,这些是函数取最小值的点,但只是在给定的区域内。上图的左侧显示了这种情况的一个示例。我们可以清楚地看到,优化器定位的点并不是整体最优解。

克服所谓的鞍点通常被认为更具挑战性。这些是平台,其中成本函数值几乎是恒定的。这种情况显示在同一图的右侧。在这些点上,所有方向上的梯度几乎为零,使得不可能逃脱。

有时,特别是在多层网络的情况下,我们可能不得不处理成本函数非常陡峭的区域。在这些地方,渐变的值急剧增加——爆炸渐变——这导致采取巨大的步骤,经常破坏整个先前的优化。然而,这个问题可以通过渐变裁剪轻松避免——定义最大允许渐变值。

梯度下降

在我们了解更高级的算法之前,让我们先来看看一些基本策略。可能最直接的方法之一就是简单地沿着与梯度相反的方向前进。这种策略可以用下面的等式来描述。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中,α是一个称为学习率的超参数,它转化为我们在每次迭代中将要采取的步长。它的选择在一定程度上表达了学习速度和可以获得的结果的准确性之间的折衷。选择太小的步长会导致繁琐的计算,并且需要执行更多的迭代。然而,另一方面,选择太高的值会有效地阻止我们找到最小值。这种情况如图 2 所示——我们可以看到在随后的迭代中,我们如何来回跳动,无法稳定下来。同时,模型中适当的步骤被定义,几乎立即找到最小值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2. Visualization of gradient descent behavior for small and large learning rate values. In order to avoid obscuring the image, only the last ten steps are visible at any time.

此外,该算法易受先前描述的鞍点问题的影响。由于在随后的迭代中执行的校正的大小与计算的梯度成比例,我们将无法逃离平台。

最后,最重要的是,该算法是无效的——它需要在每次迭代中使用整个训练集。这意味着,在每个时期,我们必须查看所有示例,以便执行下一个优化步骤。当训练集由几千个例子组成时,这可能不是问题,但正如我在我的一篇文章中提到的那样——当神经网络拥有数百万条记录时,它们工作得最好。在这种情况下,很难想象在每次迭代中我们都使用整个集合。这会浪费时间和计算机内存。所有这些因素导致梯度下降,以其最纯粹的形式,在大多数情况下不起作用。

小批量梯度下降

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3. Comparison of gradient descent and mini-batch gradient descent.

L et 首先尝试解决上一章提到的最后一个问题——效率低下。虽然矢量化允许我们通过一次处理许多训练示例来加速计算,但当数据集有数百万条记录时,整个过程仍然需要很长时间才能完成**。**。让我们尝试使用一个相当简单的解决方案——将整个数据集划分为更小的批次,并在后续迭代中使用它们进行训练。我们的新策略已经在上面的动画中形象化了。想象一下,画在左边的等高线象征着我们想要优化的成本函数。我们可以看到,由于我们需要处理的数据量更少,我们的新算法做出决策的速度更快。再来关注一下对比车型在运动上的对比。梯度下降采取罕见的,相对较大的步骤,几乎没有噪音。另一方面,批量梯度下降需要更多的步骤,但是由于分析数据集中可能的多样性,我们有更多的噪音。甚至有可能在一次迭代中,我们会朝着与预期相反的方向前进。然而,平均来说,我们向最小值移动。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 4. Splitting the dataset into batchs.

我知道你在想什么…如何选择批量?正如深度学习中经常出现的情况一样,答案不是确定的,取决于具体的情况。如果我们批处理的大小等于整个数据集,那么我们本质上是在处理一个普通的梯度下降。另一方面,如果大小为 1,那么在每次迭代中,我们只使用数据集中的一个例子,因此失去了矢量化的好处。这种方法有时是合理的,使用它的策略的一个例子是随机梯度下降。这是通过选择随机数据集记录并在后续迭代中将其用作训练集来完成的。然而,如果我们决定使用小批量,我们通常选择一个中间值—通常从 64 到 512 个示例中选择。

指数加权平均值

T 他的想法被用在很多领域,比如统计学、经济学甚至深度学习。许多先进的神经网络优化算法使用这个概念,因为它允许我们继续优化,即使在给定点计算的梯度为零。让我们花一些时间来理解这个算法。作为一个例子,我们将使用去年最大的科技公司的股票价值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 5. Visualization showing Exponentially weighted averages calculated for different β values.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EWA 本质上是平均许多以前的值,以便独立于局部波动,专注于整体趋势。它的值是使用上面显示的递归公式计算的,其中β是用于控制要平均的值的范围的参数。我们可以说,在随后的迭代中,我们考虑了 1/(1 - β)个例子。对于较大的β值,我们得到的图形要平滑得多,因为我们对许多记录进行了平均。另一方面,我们的图表越来越向右移动,因为当我们在很长一段时间内平均时,EWA 适应新趋势的速度更慢。这可以从图 5 中看出,我们在图 5 中展示了收盘时的实际股票价值,以及 4 个显示为不同 beta 参数计算的指数加权平均值的图表。

动量梯度下降

这种策略利用指数加权平均值来避免成本函数的梯度接近于零的点的麻烦。简而言之,我们允许我们的算法获得动量,这样即使局部梯度为零,我们仍然依靠先前计算的值向前移动。由于这个原因,它几乎总是比纯梯度下降更好的选择。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

像往常一样,我们使用反向传播来计算网络每层的 dWdb 的值。然而,这次不是直接使用计算的梯度来更新我们的 NN 参数值,而是首先计算 VdWVdb 的中间值。这些值实际上是成本函数关于单个参数的导数的 EWA。最后,我们将在梯度下降中使用 VdWVdb 。整个过程可以用下面的等式来描述。还值得注意的是,该方法的实现需要存储迭代之间的 EWA 值。您可以在我的存储库上的一个笔记本中看到详细信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 6. Gradient descent with momentum.

现在,让我们尝试对 EWA 对我们的模型行为的影响有一个直观的认识。再一次,让我们想象下面画的等高线象征着我们优化的成本函数。上面的可视化显示了标准梯度下降和带有动量的 GD 之间的比较。我们可以看到,成本函数的图形形状迫使采用非常缓慢的优化方式。就像在股票市场价格的例子中一样,指数加权平均值的使用让我们关注领先的趋势而不是噪音。指示最小值的分量被放大,导致振荡的分量被慢慢消除。此外,如果我们在后续更新中获得指向相似方向的梯度,学习率将会提高。这导致更快的收敛和减少的振荡。然而,这种方法有一个缺点—当您接近最小值时,动量值会增加,并可能变得如此之大,以至于算法将无法在正确的位置停止。

RMSProp

另一种提高梯度下降性能的方法是应用 RMSProp 策略——均方根传播,这是最常用的优化器之一。这是另一种使用指数加权平均值的算法。此外,它是自适应的——它允许对模型的每个参数的学习速率进行单独调整。后续参数值基于为特定参数计算的先前梯度值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用图 6 中的例子。和上面的等式,让我们考虑这个策略背后的逻辑。根据名称,在每次迭代中,我们计算关于相应参数的成本函数的导数的逐元素平方。此外,我们使用 EWA 来平均最近迭代中获得的值。最后,在我们更新网络参数值之前,相应的梯度分量除以平方和的平方根。这意味着对于梯度大的参数,学习速率降低得更快,而对于梯度小的参数,学习速率降低得更慢。这样,我们的算法减少了振荡,并防止噪声控制信号。为了避免被零除(数值稳定性),我们还为分母增加了一个非常小的值,在引用的公式中标记为ɛ.

我必须承认,在写这篇文章的时候,我有两个惊叹的时刻——我被我分析的优化器之间的质量飞跃震惊了。第一个是当我看到标准梯度下降和小批量之间的训练时间的差异。第二,当我将 RMSprop 与我们目前所见的一切进行比较时。然而,这种方法也有缺点。随着上述方程的分母在每次迭代中增加,我们的学习速率变小。因此,这可能会导致我们的模型完全停止。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 7. Optimizers comparison.

圣经》和《古兰经》传统中)亚当(人类第一人的名字

L 快速但同样重要的是,让我告诉你关于自适应矩估计。与 RMSProp 一样,这是一种在广泛的应用中运行良好的算法。它利用了 RMSProp 的最大优点,并将它们与动量优化的思想相结合。结果是一个允许快速有效优化的策略。上图显示了讨论得很好的优化器如何处理函数中困难部分的优化。你可以立即看到亚当在这种情况下做得很好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不幸的是,随着我们方法的有效性增加,计算的复杂性也增加了。是真的…以上,我写了十个矩阵方程,描述优化过程的单次迭代。根据经验,我知道你们中的一些人——尤其是那些不太熟悉数学家的人——现在会心情沉重。**别担心!请注意,这里没有什么新内容。**这些等式与之前为 momentum 和 RMSProp 优化器编写的等式相同。这一次我们将简单地同时使用这两种想法。

结论

我希望我已经设法以透明的方式解释了这些难题。这篇文章让我明白了选择正确的优化器有多重要。理解这些算法可以有意识地使用它们,理解单个超参数的变化如何影响整个模型的性能。

如果你设法来到这里,恭喜你。这当然不是最容易的阅读。如果你喜欢这篇文章,请在 TwitterMedium 上关注我,并在 GitHubKaggle 上查看我正在进行的其他项目。本文是“神经网络的奥秘”系列的第四部分,如果你还没有机会,请阅读其他文章。如果你对接下来的帖子有什么有趣的想法,请写在评论里。保持好奇!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何训练你的模型(大大加快)

原文:https://towardsdatascience.com/how-to-train-your-model-dramatically-faster-9ad063f0f718?source=collection_archive---------6-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

学习使用迁移学习,用 Python 编码的例子。

我在Unbox Research——Tyler ney lon的新 ML 研发工作室担任机器学习工程师。我刚刚完成了一个项目,为一个客户实现了一个定制的图像分类器 iOS 应用程序——在这种情况下,迁移学习是一个强大的工具。

迁移学习是一种有效地、部分地重新训练神经网络的技术。为此,我们重用先前构建的模型架构和大部分学习到的权重,然后使用标准训练方法来学习剩余的、未重用的参数。

迁移学习 vs 非迁移学习

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1: Model architecture for a standard neural network model, with green color indicating the training of all weights and biases.

经过充分训练的神经网络在初始层中获取输入值,然后顺序地将该信息向前馈送(同时对其进行转换),直到关键的是,某个倒数第二层已经构建了可以更容易地转换为最终输出的输入的高级表示。该模型的完整训练包括在每个连接中使用的权重和偏差项的优化,用绿色标记。

倒数第二层被称为瓶颈层**层*。瓶颈层将回归模型中的值或分类模型中的 softmax 概率推送到我们的最终网络层。*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2: Model architecture for a transfer-learning neural network model, with red color indicating fixed weights and biases, and green color indicating the training of just the final layer’s weights and biases.

在迁移学习中,我们从整个网络的预训练权重开始。然后,我们将权重固定到最后一层,并让该层中的权重随着我们对新数据的训练而变化。如图所示,我们保持红色连接不变,现在只重新训练最后一层绿色连接。

传输效率

迁移学习有两大好处:

  1. 对新数据的训练比从头开始更快。
  2. 如果我们从零开始,我们通常可以用比我们需要的更少的训练数据来解决问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3: A high level overview of the InceptionV3 model, which we use to demonstrate a transfer learning example. The fancy flowchart nature of the image has to do with Inception being a convolutional neural net.

在这里,我们考虑迁移学习为什么如此有效。

通过只重新训练我们的最后一层,我们正在执行一个计算成本低得多的优化(学习数百或数千个参数,而不是数百万个)。

这与像 Inception v3 这样的开源模型形成了鲜明对比,后者包含 2500 万个参数,并使用一流的硬件进行了训练。因此,这些网络具有非常合适的参数和瓶颈层,具有高度优化的输入数据表示。虽然您可能会发现很难用自己有限的计算和数据资源从头开始训练一个高性能的模型,但您可以使用迁移学习来利用他人的工作,并强制倍增您的性能。

样本代码

让我们看一些 Python 代码,稍微深入一些(但不要太深入——不要在那里迷路!).

首先,我们需要从一个预训练模型开始。Keras 有一堆预训练的模型;我们将使用 InceptionV3 模型。

*# Keras and TensorFlow must be (pip) installed.
from keras.applications import InceptionV3
from keras.models       import Model*

InceptionV3 已经在 ImageNet 数据上进行了训练,该数据包含 1000 个不同的对象,其中许多我觉得非常古怪。例如,924 类是guacamole

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 4: mmm….

事实上,预训练的概念 3 承认这一点。

preds = InceptionV3().predict(guacamole_img)返回一个 1000 维的数组(其中guacamole_img是一个 224x224x3 维的 np 数组)。

preds.max()返回 0.99999,而preds.argmax(-1)返回指数 924——盗梦空间模型非常确定这个鳄梨色拉酱就是那个!(例如,我们预测guacamole_img是 99.999%置信度的 Imagenet 图像#924。这里有一个可复制的代码的链接。

既然我们知道 InceptionV3 至少可以确认我当前吃的是什么,那么让我们看看是否可以使用底层数据表示来重新训练和学习一个新的分类方案。

如上所述,我们希望冻结模型的前n-1层,只重新训练最后一层。

下面,我们加载预训练模型;然后,我们使用 TensorFlow 的.get_layer() 方法从原始模型中获取输入和倒数第二个(瓶颈)层名称,并使用这两个层作为输入和输出来构建新模型。

*original_model    = InceptionV3()
bottleneck_input  = original_model.get_layer(index=0).input
bottleneck_output = original_model.get_layer(index=-2).output
bottleneck_model  = Model(inputs=bottleneck_input,           outputs=bottleneck_output)*

这里,我们从初始模型的第一层(index = 0)获得输入。如果我们print(model.get_layer(index=0).input),我们会看到Tensor("input_1:0", shape=(?,?,?,3), dtype=float32)——这表明我们的模型期望一些不确定数量的图像作为输入,具有未指定的高度和宽度,具有 3 个 RBG 通道。这也是我们希望作为瓶颈层输入的内容。

我们将Tensor("avg_pool/Mean:0",shape=(?, 2048), dtype=float32)视为瓶颈的输出,我们通过引用倒数第二个模型层来访问它。在这种情况下,Inception 模型已经学习了任何图像输入的 2048 维表示,其中我们可以认为这些 2048 维表示对于分类来说必不可少的图像的关键组成部分。

最后,我们用原始图像输入和瓶颈层输出实例化一个新模型:Model(inputs=bottleneck_input, outputs=bottleneck_output).

接下来,我们需要将预训练模型中的每一层设置为不可训练的*——本质上,我们冻结了这些层的权重和偏差,并保留了已经通过 Inception 原始、费力的训练学习到的信息。*

*for layer in bottleneck_model.layers:
    layer.trainable = False*

现在,我们制作一个新的Sequential()模型,从我们之前的构建模块开始,然后做一个小的添加。

*new_model = Sequential()
new_model.add(bottleneck_model)
new_model.add(Dense(2, activation=‘softmax’, input_dim=2048))*

上面的代码用于构建一个复合模型,该模型将我们的初始架构与一个包含两个节点的最终层相结合。我们使用 2,因为我们要重新训练一个新的模型来学习区分猫和狗——所以我们只有 2 个图像类。用你希望分类的类别来代替它。

如前所述,瓶颈输出的大小是 2048,所以这是我们对Dense层的 input_dim。最后,我们插入一个 softmax 激活,以确保我们的图像类输出可以被解释为概率。

我在这篇文章的最后附上了整个网络的一个非常高的网络布局图——一定要看看!。

最后,我们只需要几个标准的张量流步骤:

*# For a binary classification problem
new_model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])one_hot_labels = keras.utils.to_categorical(labels, num_classes=2)new_model.fit(processed_imgs_array, 
              one_hot_labels, 
              epochs=2, 
              batch_size=32)*

这里,processed_ims_array是一个大小为(number_images_in_training_set, 224, 224, 3)的数组,labels是地面真实图像类的 Python 列表。这些标量对应于训练数据中的图像类别。num_classes=2,所以labels只是一个包含 0 和 1 的长度number_of_images_in_training_set的列表。

最后,当我们在我们的第一个猫训练图像上运行这个模型时(使用 Tensorflow 非常方便的内置双线性 重缩放函数):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 6: A cute cat…is good for you!

该模型以 94%的置信度预测cat。考虑到我只使用了 20 张训练图像,并且只训练了 2 个时期,这已经很不错了!

外卖

通过利用预先构建的模型架构和预先学习的权重,迁移学习允许您使用学习到的给定数据结构的高级表示,并将其应用于您自己的新训练数据。

概括地说,使用迁移学习需要 3 个要素:

  1. 预训练模型
  2. 相似的训练数据-您需要输入与预训练模型的输入“足够相似”。足够相似意味着输入必须是相同的格式(如输入张量的形状、数据类型……)和相似的解释。例如,如果您使用一个为图像分类而预先训练的模型,图像将作为输入!然而,一些聪明的人将格式的音频通过一个预先训练的图像分类器运行,得到了一些很酷的结果。一如既往,财富偏爱有创造力的人。
  3. 培训标签

查看完整的工作示例点击查看使用本地文件的迁移学习演示。

如果你有任何问题/发现这个有价值,请在下面留下评论和掌声。如果你有任何想要讨论的机器学习项目,请随时联系我!will@unboxresearch.com。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于纽约市的读者,我们将于 2019 年 1 月举办一场关于 TensorFlow 的研讨会— 在这里 获取门票。

附录:

用 Netron 创建的我们网络的完整图形表示。你不庆幸我们不用完全构建自己吗?!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何用 Keras 和 Apache Spark 并行训练你的神经网络

原文:https://towardsdatascience.com/how-to-train-your-neural-networks-in-parallel-with-keras-and-apache-spark-ea8a3f48cae6?source=collection_archive---------5-----------------------

Github 链接到项目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“Time-lapse photography of spark (not the kind we address) from a firecracker” Photo by Ethan Hoover on Unsplash

作为一名数据科学家,你肯定遇到过“Apache Spark”一词被抛出的冷场讨论,通常后面是“computational clusters”、“JVM”等其他词,有时还有“你有没有再次尝试重启内核?”。你知道,只是标准的行业术语。理想情况下,您可能至少知道 Spark 与扩展您的数据科学项目有关。或者,通过管理海量数据并从中产生任何可操作的见解的第一手经验,您可能特别了解 SystemML 的强大威力。所以让我们开始吧!

Apache Spark 上的集群计算

在大多数真实世界的机器学习候选场景中,数据本身是从物联网传感器或多媒体平台实时生成的,并使用从 HDFS、ObjectStore、NoSQL 或 SQL 数据库等云解决方案以适当的格式存储。对于许多用例来说,在本地节点(Java 虚拟机在本地节点上运行 iPython 笔记本)提供的有限资源上运行您的分析工作流可能无法满足要求。快速、健壮和可靠的机器学习工作流可以利用大型计算集群,而无需费力地编辑代码并使其适应并行处理。你怎么问?这就是著名的 Hadoop 分布式文件系统的秘方,它可以让你将所有磁盘的存储容量合并为一个大型虚拟文件系统。

HDFS 主要做的是将数据分成大小相等的块,并将它们分布在物理磁盘上,同时在这些块上创建一个虚拟视图,以便它可以被视为跨整个集群的单个大文件。该技术的一个主要优势来自于数据局部性的概念。由于 HDFS 跟踪文件各个块的位置,因此可以使用驻留在同一物理工作节点上的 CPU 或 GPU 并行执行计算。在这一点上,你们中的一些人可能会问,为什么要这样做?嗯,这个问题的简单答案可以通过一个小测验来证明:

您有一个很好的计算集群,拥有 256 个节点,每个节点 8 个 CPU,每个 CPU 有 16 个 CPU 内核,每个内核有 4 个超线程。并发运行的并行线程的最大可能数量是多少?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image retrieved from : https://systemml.apache.org/

这个问题的答案当然是, <在这里打鼓> : 131 072 同时运行并行线程,各自做自己的一部分工作!(= 256 个节点*每个节点 8 个 CPU 每个 CPU 16 个 CPU 核心每个核心 4 个超线程)。因此,通过这种方式,Apache spark 提供了一个开源的分布式通用集群计算框架,它允许你操作数据并并行执行计算。

永远有弹性

ApacheSpark 中的主要数据抽象是古老的弹性 分布式数据集 ( RDD) 。这是一个分布式不可变的集合或列表数据,可以用字符串或双精度值编写,可以使用各种数据存储解决方案伪造,从开源的 MongoDB 数据库到更具排他性的 SQL 和 NoSQL 解决方案。您甚至可以从本地文件系统创建 rdd。创建后,RDD 分布在不同工作节点的主内存中。最后,你会发现 rdd 相当懒。这意味着,只有在执行特定计算确实需要数据时,才会从底层存储系统中读取数据。默认情况下,应用于数据框的任何变换(如删除变量或归一化要素)都不会立即执行。相反,你的选择会被记住,只有当一个动作要求一个结果返回给驱动程序时才会被计算。事实证明,这根本不是一个坏主意,并为即将到来的真正的大规模行动节省了相当多的计算资源。

Apache Spark 的三个杀手级特性使其成为强大的数据科学和机器学习工具:

1.结构化数据检索:Spark SQL

无数的数据科学家、分析师和普通商业智能用户依靠 interactive SQL 查询来探索数据。令人欣慰的是,Spark 很好地意识到了这一点,并附带了用于结构化数据处理的 Spark 模块,称为 Spark SQL。它提供了我们都非常珍视的编程抽象,即数据框架。Spark SQL 还可以充当分布式 SQL 查询引擎,并使未修改的 Hadoop Hive 查询在现有部署和数据上的运行速度提高 100 倍。它还提供了与 Spark 生态系统其余部分的强大集成(例如,将 SQL 查询处理与机器学习集成)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Spark Open source ecosystem

2.机器学习:MLlib

机器学习已经迅速成为挖掘大数据以获得可操作见解的关键部分。建立在 Spark 之上的 MLlib 是一个可扩展的机器学习库,它提供了高质量的算法和“闪电般”的速度,如果他们说自己做的话(比 MapReduce 快 100 倍)。该库可作为 Spark 应用程序的一部分在 Java、Scala 和 Python 中使用,因此您可以将其包含在完整的工作流中。

它的伟大之处在于,Apache SystemML 为使用大量数据的机器学习提供了一个最佳的工作场所,因为它不仅提供了使用大量定制算法的方法,还允许您使用一些伟大的预实现算法(如梯度提升树、K-最近邻,仅举几例)。更好的是,它与各种著名的深度学习框架(如 Keras 和 Caffe)相接口,我们将在后面看到。

3.流分析:火花流

最后,如今许多应用程序不仅需要处理和分析批量数据,还需要实时处理和分析新数据流。Spark Streaming 运行在 Spark 之上,支持跨流和历史数据的强大交互和分析应用,同时继承了 Spark 的易用性和容错特性。它很容易与各种流行的数据源集成,包括 HDFS、Flume、Kafka 和 Twitter。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有些人可能会说,在这里只命名 3 个特性并不能体现 Apache Spark 的公正。钨加速器和语法执行树等操作特性也非常出色,同样有利于当今忙碌的数据科学家。当然,我可以详细介绍 Apache Spark、Hadoop 分布式文件系统和 mllib 库。可以说是“引擎盖下”的旅行。但是也许下一篇文章。对于本文的目的,我们理解 Apache Spark 的 SystemML 可以在可嵌入、独立和集群模式下运行,支持 Scala、Python 和 Java 中的各种 API,并且是扩展深度学习模型的理想选择就足够了。你怎么问?

用 SystemML 扩展机器学习

进入大数据世界七大奇迹之一的 SystemML。这个灵活的机器学习系统能够自动扩展到 SparkHadoop 集群。事实上,根据数据大小、稀疏性、计算集群大小以及本地机器的内存配置,SystemML 将决定是编译单节点计划,还是 Hadoop 或 Spark 计划。它附带了一种类似 R 的函数式编程语言,称为声明式机器学习,可以让您实现您喜欢的机器学习算法,或者更好的是,从头设计一个自定义算法。据说 SystemML 有一个低成本的编译器,可以自动生成混合运行时执行计划,这些计划由单个节点和分布式操作组成。它可以在 Apache Spark 上运行,在 Apache Spark 上,它可以自动逐行缩放您的数据,确定您的代码应该在驱动程序上运行还是在 Apache Spark 集群上运行。

在 SystemML 上实现深度学习模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 SystemML 中实现深度学习模型有三种不同的方式:

  1. 使用DML-体神经网络库:这个库允许用户充分利用 DML 语言的灵活性来实现你的神经网络。
  2. 使用实验性的 Caffe2DML API :这个 API 允许用 Caffe 的 proto 格式表示的模型被导入到 SystemML 中。这个 API 不要求 Caffe 安装在你的 SystemML 上。
    • 使用实验性的 Keras2DML API :这个 API 允许用 Keras 的 API 表示的模型导入到 SystemML 中。但是,这个 API 要求 Keras 安装在您的驱动程序上。*

SystemML 的开发包括额外的具有 GPU 功能的深度学习,例如导入和运行神经网络架构和用于训练的预训练模型。本文的下一部分将展示如何使用 MLContext API 序列化和训练 Keras 模型。我也鼓励你查看一些由 Apache Spark 发布的关于如何开始使用 DML 的详细教程,并行化诸如自动编码器的算法,并尝试一些不错的旧图像分类

IBM Watson Studio 上的 Apache Spark

现在,我们将最终使用实验性的 Keras2DML API 来训练我们的 Keras 模型。为了能够执行以下代码,您需要在 IBM cloud 帐户上创建一个免费 tier 帐户,并登录以激活 Watson studio。

(IBM cloud 上的分步 Spark 设置 教程此处 ,IBM cloud 上的 spark 更多信息此处 )。

一旦你有了一个激活星火计划的 Watson studio 账号,你就可以在平台上创建一个 Jupyter 笔记本,选择一个云机配置(CPU 和 RAM 的数量)和一个星火计划,就可以开始了!

沃森工作室附带一个免费的星火计划,包括 2 个星火工作者。虽然这对于现在这样的演示目的来说已经足够了,但是对于真实世界的场景来说,强烈建议购买付费的 Spark 计划。更多的 Spark workers 基本上意味着更多的线程可以并行处理计算,因此更少像僵尸一样在屏幕前等待结果。最后,在我们开始之前,我还将注意到其他替代方案,如深度认知,具有同样有趣的功能和说明性的媒体文章,它们是存在的,并且同样值得探索。

SystemML 上的手写数字识别

啊,MNIST。如此标志性,它可以被认为是机器学习数据集的“hello world”。事实上,它甚至是 Keras 安装自带的六个标准数据集之一。请放心,无论您想到什么算法,从线性分类器到卷积神经网络,都已经在这个数据集上进行了尝试和测试,在过去 20 年的某个时间。都是为了手写数字识别的任务。一些我们人类自己毫不费力就能做到的事情(如此之多,以至于不得不把它作为一项工作来做肯定是非常令人沮丧的)。

事实上,这项任务是相当多的机器学习起源项目的理想候选,因为缺乏当时存在的全面的大型数据集……嗯,任何真正的东西。尽管现在情况已经不同了,互联网上充斥着从鳄梨价格到金星火山的数据集。今天,我们通过扩大我们的手写数字识别项目来纪念 MNIST 的传统。我们通过在计算集群上训练我们的机器学习算法来做到这一点,并有可能大大减少我们的训练时间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Convolutional neural network on MNIST dataset

1。我们从导入一些库开始:

import keras
from keras.models import Sequential
from keras.layers import Input, Dense, Conv2D
from keras.layers import MaxPooling2D, Dropout,Flatten
from keras import backend as K
from keras.models import Model
import numpy as np
import matplotlib.pyplot as plt

2.加载数据

我们现在可以从 Keras 加载 MNIST 数据集,使用下面的简单代码行。

from keras.datasets import mnist(X_train, y_train), (X_test, y_test) = mnist.load_data()# Expect to see a numpy n-dimentional array of (60000, 28, 28)type(X_train), X_train.shape, type(X_train)

3.塑造您的数据

在这里,我们做一些最适合我们的神经网络重塑。我们将每个 28×28 的图像重新排列成一个 784 像素值的向量。

#Flatten each of our 28 X 28 images to a vector of 1, 784X_train = X_train.reshape(-1, 784)
X_test = X_test.reshape(-1, 784)#Check shape
X_train.shape, X_test.shape

4.标准化您的数据

然后,我们使用 Scikit-Learn 的 MinMaxScaler 来归一化我们的像素数据,其范围通常为 0–255。归一化后,值的范围将从 0 到 1,这大大改善了结果。

from sklearn.preprocessing import MinMaxScalerdef scaleData(data):       
    scaler = MinMaxScaler(feature_range=(0, 1))
    return scaler.fit_transform(data) X_train = scaleData(X_train)
X_test = scaleData(X_test)

5.建立网络

接下来,我们用 Keras 构建我们的网络,定义一个适当的输入形状,然后堆叠一些卷积最大汇集密集和丢弃层,如下所示。(一些神经网络基础:确保你的最后一层和你的输出类有相同数量的神经元。因为我们预测的是手写数字,范围从 0 到 9,所以我们有一个由 10 个神经元组成的密集层作为最后一层。)

input_shape = (1,28,28) if K.image_data_format() == 'channels_first' else (28,28, 1)keras_model = Sequential()
keras_model.add(Conv2D(32, kernel_size=(5, 5), activation='relu', input_shape=input_shape, padding='same'))
keras_model.add(MaxPooling2D(pool_size=(2, 2)))
keras_model.add(Conv2D(64, (5, 5), activation='relu', padding='same'))
keras_model.add(MaxPooling2D(pool_size=(2, 2)))
keras_model.add(Flatten())
keras_model.add(Dense(512, activation='relu'))
keras_model.add(Dropout(0.5))
keras_model.add(Dense(10, activation='softmax'))
keras_model.summary()

如果你看到下面这个 Keras 模型的总结,那么到目前为止你都是好的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.创建一个 SystemML 模型

使用 Keras2DML 包装器,并将其输入我们新构建的 Keras 网络。这是通过调用 Keras2DML 方法并向其提供您的 spark 会话、Keras 模型、其输入形状和预定义变量来完成的。变量’ epoch 表示您的算法在数据上迭代的次数。接下来,我们有’ batch_size ',它表示我们的网络将在每个学习批次中看到的训练示例的数量。最后,‘samples’只是对我们训练集中的样本数量进行编码。我们还要求每 10 次迭代显示一次训练结果。

然后,我们在新定义的 SystemML 模型上使用fit参数,并向其传递训练数组和标签来启动我们的训练会话。**

**from systemml.mllearn import Keras2DMLepochs = 5
batch_size = 100
samples = 60000
max_iter = int(epochs*math.ceil(samples/batch_size))sysml_model = Keras2DML(spark, keras_model, input_shape=(1,28,28), weights='weights_dir', batch_size=batch_size, max_iter=max_iter, test_interval=0, display=10) sysml_model.fit(X_train, y_train)**

现在,您应该会在屏幕上看到类似这样的内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6.得分时间到了!我们只需在我们训练好的 SystemML 模型上调用 score 参数,就可以做到这一点,就像这样:

**sysml_model.score(X_test, y_test)**

等待 spark 作业执行,然后,瞧!您应该看到您在测试集上的准确性出现。你可以在下面看到,我们取得了 98.76 的成绩,不算太差。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

请注意,我们能够通过 SystemML 的 Keras2DML 包装器部署 Keras 模型,该包装器实际上将您的模型序列化为 Caffe 模型,然后将该模型转换为声明性的机器学习脚本。如果您选择用 Keras 来训练相同的 Keras 模型,那么该模型将会受到单个 JVM 的资源的限制,而不会为了并行处理而对代码进行重大调整。整洁,不是吗?你现在可以在本地 GPU 上训练你的神经网络,或者像我们在 Watson studio 上做的那样使用云机器。

虽然在处理方面配备一些本地火力总感觉不错,但没有什么能打败云。你真的可以扩大你的项目,选择合适的机器配置和 spark 计划,而成本只是硬件替代品的一小部分。这是处理不同环境和高度多样化需求的用例的理想选择,从小规模数据可视化到需要实时分析 Pb 级数据的大数据项目。也许你只是试图分析来自你的分布式仓库网络(如沃尔玛)的大量物联网数据。或者也许你到达了亚原子深度,试图确定我们宇宙的结构,就像欧洲粒子物理研究所一样。在这些大不相同的用例中,任何一个都可以从将计算迁移到云中受益,而且很可能已经这样做了。

谢谢你的时间

我希望你觉得这篇文章内容丰富,令人愉快。我真的很喜欢研究这篇文章的内容和编写相关的代码。这里有一个到我的库的链接,里面有的完整代码,以及一个不使用 SystemML 的脚本版本。如果您对所涉及的内容或所提供的源代码有任何问题或反馈,请在评论中告诉我。下次见!

参考

****1。星火入门:https://databricks.com/product/getting-started-guide-2

****2。SystemML 网页:http://systemml.apache.org/

****3。Spark ML 上下文编程指南:https://system ML . Apache . org/docs/0 . 15 . 0/spark-ML context-Programming-guide

4. Keras2DML 指南:https://system ml . Apache . org/docs/1 . 0 . 0/初学者-指南-keras2dml

5。喀拉斯:https://keras.io/

6。Github 资源库代码:https://gist . github . com/NiloyPurkait/1c 6 c 44 f 329 f 2255 f 5 de 2 b 0d 498 C3 f 238

如何用 TensorFlow 的物体检测器 API 训练自己的物体检测器

原文:https://towardsdatascience.com/how-to-train-your-own-object-detector-with-tensorflows-object-detector-api-bec72ecfe1d9?source=collection_archive---------0-----------------------

这是关于“用 Tensorflow 和 OpenCV 构建实时物体识别应用”的后续帖子,在这里我重点训练自己的类。具体来说,我在自己收集和标记的数据集上训练了自己的浣熊检测器。完整的数据集可在我的 Github repo 上获得。

顺便说一下,这是浣熊探测器在工作:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Raccoon detector.

想了解详情,还是继续看下去吧!

动机

在我的上一篇帖子之后,许多人要求我写一份指南,介绍他们如何使用 TensorFlow 的新对象检测器 API 用他们自己的数据集训练对象检测器。我找到时间做这件事。在这篇文章中,我将解释训练你自己的探测器的所有必要步骤。特别是,我创建了一个对象检测器,能够识别浣熊,结果相对较好。

搞什么鬼?为什么说浣熊 🐼 ????

没有什么特别😄它们是我最喜欢的动物之一,不知何故它们也是我的邻居!我发誓,浣熊探测器有很多潜在的用途。例如,现在你可以检测到当你不在家时,是否有浣熊在敲你的门。该系统可以向您的手机发送一条推送消息,让您知道有访客。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Full video: https://youtu.be/Bl-QY84hojs

创建数据集

所以我们认真点!我需要做的第一件事是创建自己的数据集:

  • Tensorflow 对象检测 API 使用 TFRecord 文件格式,所以最后我们需要将数据集转换成这种文件格式
  • 有几个选项可以生成 TFRecord 文件。要么你有一个与 PASCAL VOC 数据集Oxford Pet 数据集结构相似的数据集,然后他们有现成的脚本用于这种情况(参见[create_pascal_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pascal_tf_record.py)[create_pet_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pet_tf_record.py))。如果您没有这些结构中的一个,您需要编写自己的脚本来生成 TFRecords(它们也为这个提供了解释)。这就是我做的!
  • 要为 API 准备输入文件,您需要考虑两件事。首先,您需要一个编码为 jpeg 或 png 的 RGB 图像,其次,您需要一个图像的边界框列表(xmin, ymin, xmax, ymax)和边界框中的对象类别。对我来说,这很简单,因为我只有一门课。
  • 我从 Google ImagesPixabay 中搜集了 200 张浣熊图片(主要是 jpegs 和一些 png ),确保这些图片在比例、姿势和光照方面有很大的变化。这是我收集的浣熊图像数据集的一个子集:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Subset of the Raccoon image dataset.

  • 之后,我用标签手工给它们贴上标签。LabelImg 是一个用 Python 编写的图形图像注释工具,使用 Qt 作为图形界面。它支持 Python 2 和 3,但我用 Python 2 和 Qt4 从源代码中构建了它,因为我用 Python 3 和 Qt5 时遇到了问题。它非常容易使用,注释以 PASCAL VOC 格式保存为 XML 文件,这意味着我也可以使用[create_pascal_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pascal_tf_record.py)脚本,但我没有这样做,因为我想创建自己的脚本。
  • 不知何故,LabelImg 在 MAC OSX 上打开 JPEG 有问题,所以我不得不把它们转换成 png,然后再转换回 JPEG。实际上,我可以将它们保存在 png 中,API 也应该支持这一点。我发现的时候已经太晚了。这是我下次要做的。
  • 最后,在标记图像之后,我编写了一个脚本,将 XML 文件转换为 csv 文件,然后创建 TFRecords。我用了 160 张图片进行训练(train.records),40 张图片进行测试(test.records)。该脚本也可以在我的回购上获得

备注:

  • 我发现了另一个叫做 FIAT(快速图像数据注释工具)的注释工具,看起来也不错。将来,我可能会尝试这样做。
  • 对于命令行上的图像处理,如将多个图像转换成不同的文件格式, ImageMagick 是一个非常好的工具。万一,你没用过,值得一试。
  • 通常,创建数据集是最痛苦的部分。我花了 2 个小时来整理这些图片并给它们贴上标签。这只是一堂课。
  • 确保图像大小为中等(参见 Google images,了解中等是什么意思)。如果图像太大,您可能会在训练过程中遇到内存不足的错误,尤其是在您没有更改默认批处理大小设置的情况下。

训练模型

在我为 API 创建了所需的输入文件之后,我现在可以训练我的模型了。

对于培训,您需要以下内容:

  • 一个物体检测训练管道。他们还在回购上提供了样本配置文件。对于我的训练,我使用ssd_mobilenet_v1_pets.config作为基础。我需要将num_classes调整为 1,并为模型检查点、训练和测试数据文件以及标签地图设置路径(PATH_TO_BE_CONFIGURED)。至于其他配置,比如学习率、批量大小等等,我使用了它们的默认设置。

注意:data_augmentation_option非常有趣,如果你的数据集没有太多的可变性,比如不同的比例、姿势等…完整的选项列表可以在这里找到(见PREPROCESSING_FUNCTION_MAP)。

  • 数据集(TFRecord 文件)及其相应的标签映射。如何创建标签地图的例子可以在这里找到。这也是我的标注图,非常简单,因为我只有一个类:
item {
  id: 1
  name: 'raccoon'
}

**注意:**你的标签映射应该总是从 id 1 开始,这一点很重要。索引 0 是一个占位符索引(关于这个主题的更多信息,也参见这个讨论)。

  • (可选) 预先训练好的模型检查点。建议使用检查点,因为从预先训练的模型开始总是更好,因为从头开始训练可能需要几天才能得到好结果。他们在回购协议上提供了几个模型检查点。在我的例子中,我使用了 ssd_mobilenet_v1_coco 模型,因为模型速度对我来说比准确性更重要。

现在你可以开始训练了:

  • 培训可以在本地进行,也可以在 (AWS、谷歌云等)上进行。).如果你家里有 GPU(至少 2 GB 以上),那么你可以在本地完成,否则我会建议你使用云。就我而言,这次我使用了谷歌云,基本上遵循了他们文档中描述的所有步骤。
  • 对于谷歌云,你需要定义一个 YAML 配置文件。还提供了一个样本文件,我基本上只是采用了默认值。
  • 还建议在培训期间开始评估工作。然后,您可以通过在本地机器上运行 Tensorboard 来监控培训和评估工作的进程。
tensorboard — logdir=gs://${YOUR_CLOUD_BUCKET}

以下是我的培训和评估工作的结果。总的来说,我用 24 个批量运行了大约一个小时/22k 步,但是我已经在大约 40 分钟内取得了很好的结果。

总损失是这样演变的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Total loss decreased pretty fast due to the pre-trained model.

因为我只有一个类,所以只看总地图(平均精度)就足够了:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The mAP hit 0.8 at around 20k steps which is quite good.

下面是一个在训练模型时评估一幅图像的示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The detected box around the Raccoon got much better over time.

输出模型

  • 完成训练后,我将训练好的模型导出到一个文件中(Tensorflow graph proto ),这样我就可以用它进行推理。
  • 在我的例子中,我必须将模型检查点从 Google Cloud bucket 复制到我的本地机器上,然后使用提供的脚本来导出模型。型号可以在我的回购上找到,以防万一如果真的要用在生产上;)

奖金:

I applied the trained model on a video that I found on YouTube.

  • 如果你看过视频,你会发现并不是每只浣熊都被检测到,或者有一些错误的分类。这是合乎逻辑的,因为我们只在一个小数据集上训练模型。要创建一个更通用、更强大的浣熊检测器,例如,它还能够检测地球上最著名的浣熊,即来自银河护卫队的火箭浣熊,我们只需要更多的数据。这只是目前人工智能的局限性之一!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Most famous raccoon on earth.

结论

我希望你喜欢这篇文章。如果你有,给我一个❤️。希望你现在可以训练你自己的物体探测器。在本文中,我只使用了一个类,因为我懒得标记更多的数据。有一些服务,如crowd Lower、 CrowdAI亚马逊的 Mechanical Turk 提供数据标签服务,但这对于本文来说太多了。

我在如此短的训练时间内获得了相当不错的结果,但这是因为检测器只在一个班中训练过。对于更多的职业,总地图不会像我得到的那样好,而且肯定需要更长的训练时间才能得到好的结果。事实上,我还在 Udacity 提供的带注释的驾驶数据集(数据集 1)上训练了一个对象检测器。我花了很长时间来训练一个模型,它能够很好地识别汽车、卡车和行人。在许多其他情况下,即使我使用的模型也过于简单,无法捕捉多个类之间的所有可变性,因此必须使用更复杂的模型。还必须考虑模型速度和模型精度之间的权衡。然而,这是一个不同的故事,实际上可以是另一个独立的文章。

在 Medium Dat Tran 或 twitter @datitran 上关注我,了解我的最新作品。

如何训练你的自动驾驶汽车转向

原文:https://towardsdatascience.com/how-to-train-your-self-driving-car-to-steer-68c3d24bbcb7?source=collection_archive---------1-----------------------

一步一步的指导使用小而有效的神经网络和一点魔法。

神经网络,特别是深度学习研究,最近在计算机视觉领域和计算机科学的其他重要领域取得了许多突破。在许多不同的应用中,目前正在兴起的一项技术是自动驾驶汽车。每个人都听说过他们,所有的大公司似乎都在这个新千年的淘金热中投入巨资。人工智能驱动的汽车可以带你去任何地方,而你的时间,嗯,不开车。在这篇文章中,我将向你展示如何训练一个神经网络,仅使用前方道路的图像来自主驾驶。你可以在这个 Jupyter 笔记本中找到所有的代码,一步一步地解释。你也可以在这里找到更详细的论文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

深度神经网络,尤其是在计算机视觉、物体识别等领域,往往参数很多,有几百万个。这意味着它们的计算量和运行它们的设备的内存都很大。如果你是一个学术实验室或一家大公司,你有你的数据中心和大量的 GPU,这不是一个问题。但是,如果你只有一辆应该实时驾驶的汽车上的嵌入式系统,这可能是一个问题。这就是为什么我将重点放在非常纤薄、快速和高效的特定**架构上。我使用的主要模型是SqueezeNet**架构。这是一个相当新的模型,它用很少的参数,仅几兆字节的重量,就在对象识别任务上取得了显著的性能。我建议阅读这个故事和代码,它已经非常详细,以进一步理解概念。

我们首先需要的是一个数据集**,这是大多数深度学习项目的核心。幸运的是,有几个数据集对我们有用。我们最需要的是在不同环境下(高速公路、城市)驾驶数小时所拍摄的图像。你可以在笔记本里找到一本。有了数据集之后,我们需要对数据进行预处理,以使我们的算法更好地工作。例如,我们当然不能将整个数据集加载到 RAM 中,因此我们需要设计一个生成器,,这是 Python 中一种特别有用的函数,它允许动态加载一小批数据,对其进行预处理,然后将其直接输出到我们的神经网络中。为了帮助网络更好地概括每一种可能的天气和光线条件,我们可以随机修改图像的亮度。此外,我们可以裁剪图像的顶部,因为它主要包含天空和其他对驾驶无用的信息。这有助于使整个计算更快。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

NVIDIA model.

在预处理之后,我们可以开始设计我们的网络。为此,我使用了 Keras,使其可读性更好。第一款是 NVIDIA 型号,相当经典的 CNN。在一些卷积层之后,从我们的图像中提取视觉特征,我们有一个展平层,然后是完全连接的层,它输出一个单一的实数值:我们的转向角。你可以在代码中看到网络的细节。

如果你在笔记本电脑上训练这个网络,特别是在没有 GPU 加速的情况下,你可能需要一整天来训练它。(但是努力是值得的。大概吧。)在这个相对较小的训练之后,你可以看到验证损失是如何显著减少的,因此网络确实在学习如何驾驶。

这种架构可以在笔记本电脑上实时工作,大约有 500,000 个参数。但是我们可以做得更好,建立一个更小的网络。这就是 SqueezeNet 出现的原因。这种特殊的架构已经很小了,我通过减少卷积特性的数量进一步缩小了它。这个架构的核心是 Fire 模块,这是一个非常巧妙的过滤器块,可以使用很少的参数提取语义上重要的特征,并且输出很少。您可以在代码中看到网络实现的细节。最终的层也被修改,因为我们的任务是图像空间中的回归,而网络最初是为对象识别而设计的。****

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Fire Module.

使用与之前相同的训练设置,我们可以看到训练是如何更快的,并且在大约 10 个时期之后,网络达到甚至更好的性能。

你可能会说,我们在这里预测的转向角仅仅基于当前帧,而驾驶是一项动态任务,也依赖于先前的帧。这就是为什么我在这里展示的最后一个模型是一个循环模型。我在 SqueezeNet 的第一个密集连接层的输出中添加了一个递归层:网络现在将 5 个连续帧作为输入,然后递归层输出一个单一的实数值,即转向角。令人惊讶的是,这种新架构的性能,即使它更接近人类决定如何驾驶的方式,也不比以前看到的架构更好。因此,无记忆和无状态架构可以很好地驱动,从单个帧计算转向角度,独立于其他帧。****

现在,最后,我们网络运行的一个小视频。剧本是从这个非常酷的资料库中截取的。它显示汽车的实时驾驶,转向完全由网络根据它看到的街道来控制。很好,对吧?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Our self-driving car in action.

我们已经用非常简单的架构和技术训练我们的自动驾驶汽车转向,取得了显著的效果。我希望你已经从这篇文章、代码和论文中学到了一两个技巧。欢迎评论或联系!

如何训练张量流模型

原文:https://towardsdatascience.com/how-to-traine-tensorflow-models-79426dabd304?source=collection_archive---------0-----------------------

使用 GPU

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

近年来,机器学习领域取得了重大进展。这种进步很大程度上可以归功于图形处理单元(GPU)的使用越来越多,以加速机器学习模型的训练。特别是,额外的计算能力导致了深度学习的普及——使用复杂的多层神经网络来创建模型,能够从大量未标记的训练数据中进行特征检测。

GPU 简介

GPU 非常适合深度学习,因为它们被设计来处理的计算类型恰好与深度学习中遇到的计算类型相同。图像、视频和其他图形都表示为矩阵,因此当您执行任何操作(如放大效果或相机旋转)时,您所做的只是对矩阵应用一些数学变换。

实际上,这意味着与中央处理器(CPU)相比,GPU 更擅长执行矩阵运算和其他几种高级数学转换。这使得深度学习算法在 GPU 上的运行速度比 CPU 快好几倍。学习时间通常可以从几天缩短到几个小时。

机器学习中的 GPU

那么,如何使用 GPU 来完成机器学习任务呢?在这篇文章中,我们将探索一个支持 GPU 的 AWS 实例的设置,以在 Tensorflow 中训练神经网络。

首先,在 AWS 控制面板中创建一个新的 EC2 实例。

我们将使用 Ubuntu Server 16.04 LTS (HVM)作为操作系统,但是这个过程在任何 64 位 Linux 发行版上都应该是相似的。

对于实例类型,选择 g2.2xlarge 这些是通过 NVIDIA GRID GPU 启用的。也有几个这样的 GPU 的实例,但利用一个以上需要额外的设置,这将在本文稍后讨论。

使用您首选的安全设置完成设置。

一旦设置和创建完成,SSH 进入您的实例。

Python 应该已经存在于系统中,所以安装所需的库:

sudo apt-get update
sudo apt-get install python-pip python-dev

接下来,安装启用 GPU 支持的 Tensorflow。最简单的方法是:

pip install tensorflow-gpu

但是,对于某些安装,这可能会失败。如果发生这种情况,还有一个替代方案:

export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-0.12.1-cp27-none-linux_x86_64.whl
sudo pip install --upgrade $TF_BINARY_URL

如果在 TF 安装过程中得到一个locale.Error: unsupported locale setting,请输入:

export LC_ALL=C

然后,重复安装过程。

如果不再出现错误,TF 安装就结束了。然而,为了让 GPU 加速正常工作,我们仍然必须安装 Cuda 工具包和 cuDNN。

首先,让我们安装 Cuda 工具包。

开始之前,请注意安装过程将下载大约 3gb 的数据。

wget "http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.44-1_amd64.deb"
sudo dpkg -i cuda-repo-ubuntu1604_8.0.44-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda

安装 CUDA 工具包后,下载 cuDNN Library for Linux (注意,您需要注册加速计算开发者计划)并将其复制到您的 EC2 实例中。

sudo tar -xvf cudnn-8.0-linux-x64-v5.1.tgz -C /usr/local
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64"
export CUDA_HOME=/usr/local/cuda

最后,设置过程已经结束,我们可以测试安装了:

python
>>> import tensorflow as tf
>>> sess = tf.Session()

你应该看到Found device 0 with properties: name: GRID K520

>>> hello_world = tf.constant("Hello, world!")
>>> print sess.run(hello_world)

将显示Hello, world!

>>> print sess.run(tf.constant(123)*tf.constant(456))

56088是正确答案。

系统现在准备好利用带有 Tensorflow 的 GPU。

对 Tensorflow 代码的更改应该是最小的。如果 TensorFlow 操作同时具有 CPU 和 GPU 实现,则将操作分配给设备时,GPU 设备将优先。

如果您想在自己选择的设备上运行一个特定的操作,而不是使用默认的,您可以使用with tf.device创建一个设备上下文。这将强制该上下文中的所有操作具有相同的设备分配。

# Creates a graph.
with tf.device('/gpu:0'):
 a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
 b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
 c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print sess.run©

如果您想在多个 GPU 上运行 TensorFlow,可以以多塔的方式构建一个模型,并将每个塔分配给不同的 GPU。例如:

# Creates a graph.
c = []
for d in ['/gpu:2', '/gpu:3']:
 with tf.device(d):
 a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
 b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2])
 c.append(tf.matmul(a, b))
with tf.device('/cpu:0'):
 sum = tf.add_n(c)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print sess.run(sum)

利用 GPU 的优势

出于基准测试的目的,我们将使用卷积神经网络(CNN)来识别图像,这是作为 Tensorflow 教程的一部分提供的。CIFAR-10 分类是机器学习中常见的基准问题。任务是将 RGB 32x32 像素图像分为 10 类。

让我们比较在几种流行的配置上训练该模型的性能:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果

如结果所示,在这个特定示例中,16 个 CPU 的能力与 1 个 GPU 的能力相当。在撰写本文时,同样的训练时间,使用 GPU 也要便宜 18%。

data art的高级建筑师尼古拉·哈巴罗夫撰写。

如何用数据可视化改造枯燥乏味的报表

原文:https://towardsdatascience.com/how-to-transform-boring-and-dry-reports-with-data-visualization-81fd908bcc62?source=collection_archive---------6-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

研究表明,帮助当今人们应对信息过载的最基本方法之一是将其可视化。通俗地说,这意味着将其绘制成图表,在地图上绘制,甚至使用数据创建交互式图表。

通过可视化地绘制出数据,不仅可以更容易地消化和理解重要信息,还可以更容易地发现关键模式、重要趋势和令人信服的相关性,否则这些可能很难揭示。一句话:你不仅要明白 发生了什么 发生了什么,还要明白 为什么

你想讲什么故事?

在创建图表之前,首先理解 为什么 你需要一个图表是至关重要的。请记住,您正在创建一个可视化工具来帮助人们理解复杂的数据,发现模式,识别趋势,并最终实现目标。

您还必须遵循图表最佳实践。首先,这些数字需要相加,你需要相应地调整你的图表。此外,考虑你想要说明多少变量,你想要显示多少数据点,以及你想要如何缩放你的轴。

以下是可以从最新的数据可视化工具中受益的传统商务智能报告/实践类型:

对于会计部门

费用报告

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

假设您想要生成一份每月支出报告,比较不同类别的支出数据,如差旅、办公用品等。—甚至跨部门。如何快速、轻松地判断某个特定领域何时会增加支出,从而发现节约的机会?

虽然这种趋势在电子表格中很容易被忽略,但条形图可以将数据可视化。这是一种比较信息的简单方法,因为它一眼就能发现高点和低点。会计部门可以向领导或部门主管提供信息,并立即了解面临的挑战。(当他们的打印费用明显高于另一个部门的技术成本时,谁会对他们过度使用复印机犹豫不决呢?)

财务仪表板

随着越来越多的组织将透明度作为员工参与和保留的一种战略,每月一次的“市政厅”变得越来越普遍,在那里共享关键数据。

虽然这是一项勇敢的努力,但简单地向那些可能不会经常与如此大数量的数据打交道的人展示枯燥的收入/利润/支出数据,只会导致每个人都对此视而不见。更糟糕的是,缺乏理解可能会导致员工在没有问题的地方假设有问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image Source

数据可视化使任何人都可以理解这样的报告,而不管分析的舒适度如何。你可以清楚地展示成功的领域和改进的机会。此外,你可以提出多种观点,让员工明白,虽然利润比上个月有所下降,但实际上比去年同月有所上升。

使用数据可视化软件,您还可以使图表和图形具有交互性和可访问性。您可以创建一个仪表板,供员工随时登录,而不是在每月 30 分钟的会议中显示一组数字。这样,他们可以更好地了解公司的日常表现,以及他们的工作对整体的影响。

对于营销和销售团队来说

参与趋势

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

又到了一年中的这个时候:你那位对营销持怀疑态度的首席执行官希望你写一份报告,反映你的网站在三个月内的页面浏览量。他希望它与收入相对应,以证明你的参与努力的价值。

在折线图中尝试一下。这是一种连接单个数字数据点的简单方法,可以简单直观地显示趋势,以及它们在一段时间内的对应关系。与收入增长相比,您的网站浏览量、电子邮件参与率或广告点击率之间的关系如何?正相关可能表明这种努力是成功的,可以很快让你买入进一步的投资。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CRM 快照

销售线索挖掘可能是一个支离破碎的过程。你观察漏斗的每一步,衡量参与度和转化率,但很难看到全貌。

数据可视化会有所帮助。映射图表可以显示销售线索的每一步,以便轻松发现和解决潜在的障碍。与此同时,您可以注意到加速领域,即销售线索可能转化的领域,并从这些案例中学习最佳实践。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此外,你可以创建买家旅程。随着您将数据可视化工具与您的 CRM 集成,最常见的购买途径将会出现。利用这些趋势来创建旅程和人物角色,为你的未来战略提供信息。

对于人力资源

学习管理报告

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

学习管理系统 (LMS)正越来越多地被企业用于从合规培训到入职培训、拓展机会和绩效评估的方方面面。一个使用良好的 LMS 可以是关于您最重要的资产——您的员工——的大量数据。然而,如果你不了解这些数据,或者如果个别经理对他们的直接下属有看法,但领导层缺乏全局观念,这些数据可能会被浪费掉。

使用数据可视化,您可以获得员工进展快照,这将有助于您确定表现最佳的员工(可能准备好升职)以及那些发展停滞或落后的员工。

招聘来源报告

许多组织都有分散的招聘流程,由各个经理负责职位发布和候选人招聘。这种支离破碎的过程可能会导致重新创建车轮,关注那些要么不起作用要么导致候选人不合格的招聘策略。

您可以使用数据可视化创建图表,集中了解招聘流程。例如,创建一个饼图,显示您可能使用的各种媒体(社交媒体、电子邮件、招聘信息板等)的招聘来源。您可以为组织创建一个总体图表,还可以为每个部门创建单独的版本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

利用这些信息,你会很快注意到招聘信息板最适合招聘 IT 人员,而你的营销团队中的大多数人都是直接推荐来的。有了这些数据,你就可以了解哪些领域有助于改善你的候选人库,缩短每个职位的招聘时间。

对于技术团队来说

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无论您的组织规模如何,您都有机会使用故障单系统向您的 IT 团队报告问题,确定问题的重要性,并跟踪问题直到解决。这些票务工具通常提供易于理解的门票数量和每张门票花费时间的指标,但这并不能说明太多问题。

讲述故事的是事件级别。这些票都是从哪里来的?哪些设备、产品或用户是最大的罪魁祸首?你的组织越大,就越难注意到这种趋势。当 IT 团队可以制定防火计划时,他们却以救火告终。

使用数据可视化,您可以轻松地注意到事件的最大原因,并主动解决它们,以减少整体票证数量。

争夺领导权

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image Source

投资者和顾问委员会希望不断了解他们所支持的企业。对于业务领导来说,定期向他们传达指标可能是一个挑战,他们已经很忙,很难创建可消化的数据,然后有时间回答问题。

数据可视化工具带来了变化。正如您可以创建仅供员工访问的自定义仪表板一样,您也可以为投资者创建仪表板。使用它以视觉上引人注目的方式展示他们最关心的数据,无需指导即可理解。这样,投资者可以在自己的时间登录来检查进展,而你的季度会议可以用来根据这些数据制定战略,而不是在数字中摸索。

眼见为实

由于我们这个社会的注意力持续下降——8 秒钟——并且因为我们不断暴露在海量信息中,所以快速、直观地传达我们的数据至关重要。

数据可视化使我们能够快速理解信息,并调整不同的变量来观察它们的效果。

一张图片真的抵得上一千个字。作为企业所有者或团队经理,你不能只使用原始数据来教育你的利益相关者。

当您将数据可视化时,人们就更容易消化引人注目的见解,因此您可以全面提高关注度、保留率和参与度。

本帖 原版 最早出现在 Visme 的 视觉学习中心

如何调优 BigQuery ML 分类模型以达到期望的精度或召回率

原文:https://towardsdatascience.com/how-to-tune-a-bigquery-ml-classification-model-to-achieve-a-desired-precision-or-recall-e4d40b93016a?source=collection_archive---------15-----------------------

基于 ROC 曲线选择概率阈值

BigQuery 为在大型结构化数据集上训练机器学习模型提供了一种令人难以置信的便捷方式。在之前的一篇文章中,我向您展示了如何训练一个分类模型来预测航班延误。以下是预测航班是否会晚点 15 分钟或更久的 SQL 查询:

CREATE OR REPLACE MODEL flights.delayedOPTIONS (model_type='logistic_reg', input_label_cols=['late'], 
         data_split_method='custom', data_split_col='is_train_row') ASSELECT
  IF(arr_delay < 15, 0, 1) AS late,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance,
  is_train_day = 'True' AS is_train_row
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL

这将在名为 flights 的数据集中创建一个名为 delayed 的模型。该模型将使用载体、原点等列。作为模型的输入,并预测航班是否会晚点。地面实况来自美国航班到达延误的历史数据。请注意,我已经按天将数据预拆分为一行是训练数据(is_train_day=True)还是应该用于独立评估(is_train_day=False)。这很重要,因为同一天的航班延误往往高度相关。

当训练完成时,BigQuery 报告训练统计数据,但是我们应该查看保留数据集的评估统计数据(is_train_day=False):

SELECT * from ML.EVALUATE(MODEL flights.delayed,
(
SELECT
  IF(arr_delay < 15, 0, 1) AS late,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL
  AND is_train_day = 'False'
))

这给了我们:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Evaluation statistics for flight delay model

航班延误数据是一个不平衡的数据集——只有 18%的航班晚点(这是我通过实践发现的):

SELECT
  SUM(IF(arr_delay < 15, 0, 1))/COUNT(arr_delay) AS fraction_late
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL
  AND is_train_day = 'True'

在这样一个不平衡的数据集中,准确性并不那么有用,通常有一个业务目标来满足期望的精度(如果 1 更常见)或召回(如果 0 更常见)。

受试者工作特征曲线

一个分类模型实际上返回的是航班晚点的概率;上表中的评估统计数据是通过将该概率阈值设定为 0.5 来计算的。我们可以改变这个阈值,并在不同的阈值下获得精度和召回率。这被称为 ROC 曲线(这是一个可以追溯到雷达时代的首字母缩写词),我们可以让 BigQuery 使用以下方法生成这条曲线:

SELECT * from ML.ROC_CURVE(MODEL flights.delayed,
(
SELECT
  IF(arr_delay < 15, 0, 1) AS late,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL
  AND is_train_day = 'True'
))

本质上,它和 ML 是一样的。评估查询,除了您使用 ML。ROC _ CURVE 因为我们要调整阈值,所以我们应该对训练数据进行调整(is_train_day=True)。该表返回 101 行,每个阈值都有一个误报率(1 精度)和召回率。默认情况下,阈值基于对训练数据集的百分位数的计算:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Recall, false positive rate, etc. as the probability threshold of the classification model is changed

我们可以点击 BigQuery UI 中的“Explore in Data Studio”链接,得到一个图(设置 false_positive_rate 为维度,recall 为度量):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ROC curve in Data Studio

更有用的观点是将阈值作为维度,将另外两个统计数据作为维度:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Graph the variation of recall and false_positive_rate by threshold in Data Studio and choose the threshold that gives you a recall close to 70%.

我们可以调整阈值来实现一定的回忆(然后你将生活在你得到的任何精度)。假设我们想要确保识别至少 70%的晚点航班,即我们想要 0.7 的召回率。从上图可以看出,概率阈值需要为 0.335。这意味着我们会错误地将 1%的准点航班识别为晚点。

SQL 中的优化概率阈值

下面是一个查询,它将返回阈值,而无需绘制图形并将鼠标悬停在其上:

WITH roc AS (SELECT * from ML.ROC_CURVE(MODEL flights.delayed,
(
SELECT
  IF(arr_delay < 15, 0, 1) AS late,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL
  AND is_train_day = 'True'
)))SELECT 
threshold, recall, false_positive_rate,
**ABS(recall - 0.7) AS from_desired_recall**
FROM roc
**ORDER BY from_desired_recall ASC**
LIMIT 1

这给了我们获得 0.7 召回所需的阈值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Choosing the threshold that gives us a recall of 0.7.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Nicely tuned! Photo by Ali Morshedlou on Unsplash

用新的概率阈值进行评估和预测

我们可以(对保留的数据集)进行评估,看看我们是否达到了预期的召回率:

SELECT * from ML.EVALUATE(MODEL flights.delayed,
(
SELECT
  IF(arr_delay < 15, 0, 1) AS late,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL
  AND is_train_day = 'False'
), **STRUCT(0.3348 AS threshold)**)

这给了我们:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

We get the hoped-for recall of 70% on the independent evaluation dataset!

万岁!我们在独立评估数据集上也获得了 70%的召回率,所以看起来我们没有过度拟合。

和 ML 一样。评估,当我们进行最大似然预测时,我们可以指定概率的期望阈值:

SELECT * from ML.PREDICT(MODEL flights.delayed,
(
SELECT
  IF(arr_delay < 15, 0, 1) AS late,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance
FROM
  `cloud-training-demos.flights.tzcorr` as f
JOIN `cloud-training-demos.flights.trainday` as t
USING(FL_DATE)
WHERE
  arr_delay IS NOT NULL
  AND is_train_day = 'False'
LIMIT 10
), **STRUCT(0.3348 AS threshold)**)

尽情享受吧!

如何使用 Core ML 在 iOS 11 上使用机器学习模型

原文:https://towardsdatascience.com/how-to-use-a-machine-learning-model-on-ios-11-using-core-ml-24a9d8654df6?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

iOS 11 的发布给开发者带来了很多新功能,比如 ARKitCore NFC 等等。对我来说真正突出的一点是增加了核心 ML

Core ML 可以让你将任何机器学习模型集成到你的 iOS 应用中。

在本教程中,我将使用一个预先训练好的深度卷积神经网络来确定一张图片是否包含一只猫或一只狗。这是我在学习 DL 时建立的一个非常简单的模型。

先决条件

要完成本教程,您需要:

  1. 运行 iOS 11 的设备
  2. Xcode 9
  3. 受过训练的模特

获取核心 ML 模型

要将您的模型转换为 Core ML ,您需要安装 Apple 提供的命令行工具。

pip install coremltools

接下来,在与模型相同的文件夹中创建一个 python 文件,并添加下面的代码。 image_input_names 和 is_bgr 告诉转换器我们的输入参数将是一个图像。

注意:如果您的模型不是用 Keras 构建的,或者如果您需要关于可用参数的更多信息,您可以查看 Apple 文档。https://apple . github . io/coremltools/coremltools . converters . html

创建后,执行 python 文件来转换您的模型。

python your_file_name.py

将新模型添加到您的应用中

首先,将模型拖到项目导航器中,将模型添加到 Xcode 项目中。将自动生成一个带有模型名称及其属性的新对象。

您可以通过在 Xcode 中打开它来查看有关模型的信息。在查看 mine 时,我们可以看到模型类型和我们在转换模型时配置的输入/输出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

给你的模型拍照

首先实现本地相机来拍摄照片,为我们的模型提供素材。

在 UIImagePickerController 的委托中,我们将进行预测,并提供一个简单的警告来显示我们模型的输出。预测方法将在稍后实现。

调整照片大小

如果你仔细看了我的模型的描述,你会注意到我的输入图像的大小是 64x64。由于我的模型是用特定大小的图像训练的,我们需要将相机中的照片调整到与它们相同的大小。

将 UIImage 转换为 CVPixelBuffer

遗憾的是 Core ML 不允许我们将 UIImage 直接输入到模型中。而是需要转换成支持的类型CVPixelBuffer。我创建了一个简单的扩展来将 UIImage 转换成 CVPixelBuffer。

做预测

现在是有趣的部分!我们将使用我们之前创建的方法来格式化我们的 UIImage,然后将它提供给我们的模型。一旦格式化,我们简单地调用预测方法来获得我们的预测。

Tada!现在,您应该可以从您的模型中获得预测。

你可以在 Github 上找到完整的项目:https://github.com/francoismarceau29/CoreMLCNNDemo

如果你喜欢这篇文章,请一定留下你的关注,你也可以在 twitter 上联系我。

如何使用人工智能检测非数据科学家的开放式问题

原文:https://towardsdatascience.com/how-to-use-ai-to-detect-open-ended-questions-for-non-datascientists-e2ef02427422?source=collection_archive---------6-----------------------

这是一个快速指南,任何人都可以按照它来训练机器学习模型,以检测文本中的开放式问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

开放式问题的能力非常重要,无论你是在产品管理、教育、咨询/治疗、销售还是新闻业。从表面上看,区分开放式问题(“你感觉如何?”)与封闭式问题(“你喜欢你的工作吗?”).

人工智能和机器学习

想到聊天机器人、消息服务和其他与人类互动的机器用例,我清楚地意识到,能够问(或至少能够检测)开放式问题将是重要的。这可以帮助指导学生和教师、辅导员和被辅导者、面试官和被面试者(名单还在继续)在网上和机器互动。

但是现在让我们只关注单一的用例;正在检测问题类型。我做的第一件事是在谷歌上搜索一个合适的问题和答案的数据集,上面有问题类型的标签。幸运的是,我发现了这个非常大的亚马逊问答数据集。

观点问答系统中的歧义性、主观性和分歧观点建模
【孟婷】万,朱利安·麦考利
数据挖掘国际会议(ICDM) ,2016
pdf

通过客户评论解决复杂主观的产品相关查询
朱利安·麦考利,杨顺清
环球网(WWW) ,2016
pdf

下载和了解数据集

数据集被分解为亚马逊产品类别,所以我只是随机选择了一个并下载了它。不幸的是,它本质上是一个文本文件,其中每一行都是一个 JSON 对象,并且格式不正确。

这是机器学习的第一个问题。干净的数据集。

我经历了手动清理这些数据的过程,这实际上意味着运行一个 Python 脚本(幸运的是网站的作者提供了这个脚本)来将文件转换成一个格式正确的 JSON 对象列表。

接下来,我需要更改封闭式问题的问题类型标签,因为在字段名中使用“/”会在以后出现问题。我简单地对“是/否”到“是 _ 否”进行了查找和替换。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Some grammar errors

手动检查这些数据,你会发现它并不完美。不是数据集作者的错,主要是问题作者的错。有大量的语法错误、标点符号问题等。

但是没关系。还是看看能不能得到显著的结果吧。

文本类

我最喜欢的训练机器学习模型的方法是从将数据集转换成文本文件开始,然后将它们放入标签为“开放式”和“yes_no”的文件夹中。这不是唯一的方法,或者可能是最好的/最有效的方法,但是因为我不是一个很好的开发人员,我试图通过使用现有的工具来使事情变得简单。我最喜欢的一个是它的文本类。它使用机器框分类框使用文件夹中的文本文件构建模型。

为了做到这一点,我编写了这个 Go 代码(请—不要评判)来将 JSONs 转换成文件夹中的文本文件。

训练模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

When you run Classificationbox you can visit localhost on port 8080 to see a console

下一步是挑选你最喜欢的机器学习模型创建工具。我的明明是机盒。下载并运行分类框,然后在你所有文本文件所在的文件夹上运行 Textclass 工具。

它将很快对成千上万个例子进行训练(对我来说不到一分钟),然后经历一个验证过程(它将已知的答案与模型预测的进行核对)。

在我第一次运行时,我得到了84%的准确度。不惊人,但它绝对有资格作为重要的。80%以上的准确率意味着您正在做一些事情,而这种优化很可能会让您获得更高的准确率。这种优化通常意味着进行更多的数据清理、平衡,或者只是有更多的样本。

我首先进行了平衡数据的步骤,这提高了几个点的准确性,然后我回到源位置,下载了几个数据集添加到第一个数据集。经过两轮添加数据和平衡,我能够获得高达87%的精度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Textclass CLI output

在这上面只花了一个小时,我感到非常满意,使用机器学习来检测文本中的开放式问题是完全可行的。我强烈建议大家自己试一试,看看会有什么发现。

如何用 API 做一个深度学习卫星图片库?

原文:https://towardsdatascience.com/how-to-use-api-to-make-a-deep-learning-satellite-image-repository-818a5ae2a5fa?source=collection_archive---------2-----------------------

进行任何深度学习实验的最重要的部分之一是从不同的来源提取或收集数据,以获得真实/接近实际的训练样本。现在,在缺乏已经可用的深度学习研究存储库或 kaggle 数据集的情况下,有时我们可能会在尝试我们在特定用例中学习的方法时遇到障碍。这就是神奇的 API 世界来拯救我们的地方。

什么是 API?

以下是维基百科的内容:

在计算机编程中,应用编程接口(API)是一组用于构建应用软件的子例程定义、协议和工具。一般来说,它是各种软件组件之间的一组明确定义的通信方法。一个好的 API 通过提供所有的构建模块,让开发一个计算机程序变得更加容易,然后由程序员把这些模块组合在一起。API 可以用于基于网络的系统、操作系统、数据库系统、计算机硬件或软件库。API 规范可以有多种形式,但通常包括例程、数据结构、对象类、变量或远程调用的规范。POSIX、Windows API 和 ASPI 是不同形式的 API 的例子。 通常提供 API 的文档以方便使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

from -https://shareurcodes.com/blog/creating%20a%20simple%20rest%20api%20in%20php

简而言之:API 是一种接口或协议,它允许用户/开发人员从开发的应用程序(如 web 服务器/web 实用工具等)中提取实用程序,而无需理解底层代码或系统。API 可用于获取数据以及更新数据源中的数据。我们在这里将涉及或使用的是 GET 请求,因为我们对数据源感兴趣。

手里的问题是什么?

现在考虑深度学习的图像分类问题,我需要的是一组卫星图像,这些图像被标记为对应的灾难类型。我瞄准的门户网站是https://earthobservatory.nasa.gov/NaturalHazards/

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://earthobservatory.nasa.gov/NaturalHazards/

现在地球观测站是一个门户网站,将有 100 多张图片,现在我需要搜索一个 API 端点,它允许我获取继续分析所需的图片。API 端点是一个 URL,根据 API 文档中提供的规范,可以查询它来搜索您需要的数据。

在浩如烟海的网络世界里搜索了一下,我找到了 https://eonet.sci.gsfc.nasa.gov/。它是关于自然事件的元数据的储存库。这个存储库支持的 API 有一个很好的端点文档。

下面是大多数 API 文档的样子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://eonet.sci.gsfc.nasa.gov/docs/v2.1

现在我需要从表格中了解的是:

1)自然事件跟踪器的 API 端点是https://eonet.sci.gsfc.nasa.gov/api/v2.1/events。这就是我对图像元数据的所有查询,都将通过这个 URL 获得。

2)我可以根据来源、状态、限制、天数来查询存储库

3)示例查询-【https://eonet.sci.gsfc.nasa.gov/api/v2.1/events?limit=5 &天数=20 &来源=InciWeb &状态=未结。这给了我下面的 JSON 结果,关于过去 5 天的自然事件,来自 InciWeb 并且仍然开放。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何有效地编码和获取信息?

现在我们知道了信息存在于何处,但我们仍然需要找到一种最佳方法来做到这一点:

Step-1 使用 python 中的请求来访问 eonet API 端点并获得所需的 json 响应

import requests
parameters={"limit":1000,"days":5000}
response=requests.get('[https://eonet.sci.gsfc.nasa.gov/api/v2/events?status=closed&source=EO'](https://eonet.sci.gsfc.nasa.gov/api/v2/events?status=closed&source=EO'))
print(response.status_code)

代码应该得到 json 响应,您可以使用任何在线可用的 json 到 csv 转换器将其转换为 csv。从 csv 中过滤出您希望作为训练数据一部分保留的图像 URL

步骤 2 现在,当你有了所有你需要下载图片的图片网址。您可以使用以下代码将图像下载到您的硬盘或虚拟机上。

import csv
import urllib
import lxml.html
import requestsconnection = urllib.urlopen(url)with open('location/urls_to_download_2.csv') as csvfile:
    csvrows = csv.reader(csvfile, delimiter=',', quotechar='"')
    for row in csvrows:
      if 'view.php' in row[0]:
        filename = row[1]
        url = row[0]
        locn=row[2]
        print (locn)

是的。现在,您已经具备了图像形式的所有必需数据,可以征服卫星图像的深度学习了。只管去做吧!

tf.keras 和 TensorFlow:批量规范化以更快地训练深度神经网络

原文:https://towardsdatascience.com/how-to-use-batch-normalization-with-tensorflow-and-tf-keras-to-train-deep-neural-networks-faster-60ba4d054b73?source=collection_archive---------5-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练深度神经网络可能很耗时。特别是,当网络由于梯度(尤其是早期图层中的梯度)已接近零值而停止更新时,梯度消失会严重阻碍训练。合并 Xavier 权重初始化和 ReLu 激活函数有助于解决消失梯度问题。这些技术也有助于解决相反但密切相关的爆炸梯度问题,即梯度变得非常大,从而阻止模型更新。

也许对付渐变消失和爆炸问题的最有力的工具是批量标准化。批量标准化的工作方式如下:对于给定图层中的每个单元,首先计算 z 得分,然后使用两个经过训练的变量𝛾和𝛽.应用线性变换批量标准化通常在非线性激活函数之前完成(见下图),但是在激活函数之后应用也是有益的。查看这堂课了解更多关于这项技术如何工作的细节。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

During backpropagation gradients tend to get smaller at lower layers, slowing down weight updates and thus training. Batch Normalization helps combat the so-called vanishing gradients.

在 TensorFlow 中可以通过三种方式实现批量规范化。使用:

  1. tf.keras.layers.BatchNormalization
  2. tf.layers.batch_normalization
  3. tf.nn.batch_normalization

08/18/2018 更新:dnn classifierdnn regressor现在有了一个 *batch_norm* 参数,这使得用一个固定的估计器进行批量归一化变得可能和容易。

2019 年 11 月 12 日更新:使用 tf.keras,这变得更加容易,你可以简单地添加一个 *BatchNormalization* 层,而不需要担心 control_dependencies。

tf.keras模块在 1.4 版本中成为核心 TensorFlow API 的一部分。并且提供了用于构建张量流模型的高级 API 所以我会告诉你如何在 Keras 做到这一点。tf.layers.batch_normalization函数具有类似的功能,但是 Keras 通常被证明是在 TensorFlow 中编写模型函数的更简单的方法。

Note the training variable in the Batch Normalization function. This is required because Batch Normalization operates differently during training vs. the application stage– during training the z score is computed using the batch mean and variance, while in inference, it’s computed using a mean and variance estimated from the entire training set.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

In TensorFlow, Batch Normalization can be implemented as an additional layer using tf.keras.layers.

带有tf.GraphKeys.UPDATE_OPS的第二个代码块很重要。对于网络中的每个单元,TensorFlow 使用tf.keras.layers.BatchNormalization不断估计训练数据集中权重的平均值和方差。这些然后被存储在tf.GraphKeys.UPDATE_OPS变量中。训练后,这些存储的值用于在预测时应用批处理规范化。每个单元的训练集平均值和方差可以通过打印extra_ops来观察,它包含网络中每个层的列表:

print(extra_ops)[<tf.Tensor ‘batch_normalization/AssignMovingAvg:0’ shape=(500,) dtype=float32_ref>, # layer 1 mean values
 <tf.Tensor ‘batch_normalization/AssignMovingAvg_1:0’ shape=(500,) dtype=float32_ref>, # layer 1 variances ...]

虽然在tf.nn模块中也可以使用批量标准化,但是它需要额外的簿记,因为均值和方差是函数的必需参数。因此,用户必须在批处理级别和训练集级别手动计算均值和方差。因此,它是比tf.keras.layerstf.layers更低的抽象层次;避免tf.nn实现。

MNIST 上的批处理规范化

下面,我使用 TensorFlow 对突出的 MNIST 数据集应用批量归一化。点击查看代码。MNIST 是一个易于分析的数据集,不需要很多图层就可以实现低分类错误。但是,我们仍然可以建立一个深度网络,观察批处理规范化如何影响收敛。

让我们使用[tf.estimator](https://www.tensorflow.org/get_started/custom_estimators) API 构建一个定制的评估器。首先,我们建立模型:

定义模型函数后,让我们构建定制的估计器,并训练和评估我们的模型:

让我们测试一下批量标准化如何影响不同深度的模型。在我们将代码打包成 Python 包之后,我们可以使用 Cloud ML Engine 并行启动多个实验:

下图显示了达到 90%测试准确度(一个简单的目标)所需的训练迭代次数(1 次迭代包含 500 个批量),作为网络深度的函数。很明显,批量标准化大大加快了深层网络的训练速度。如果没有批标准化,训练步骤的数量会随着每个后续层的增加而增加,但有了批标准化,训练步骤的数量几乎保持不变。实际上,在更复杂的数据集上,更多的图层是成功的先决条件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Without Batch Normalization the number of training iterations required to hit 90% accuracy increases with the number of layers, likely due to the vanishing gradient effect.

同样,如下图所示,对于一个有 7 个隐层的全连通网络,没有批量归一化的收敛时间明显变慢。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上实验利用了常用的 ReLu 激活函数。尽管显然不能避免消失梯度效应,如上所示,ReLu 激活比 sigmoid 或 tanh 激活函数要好得多。sigmoid 激活函数对消失梯度的脆弱性是很容易理解的。在较大幅度(非常正或非常负)值时,sigmoid 函数“饱和”,即 sigmoid 函数的导数接近零。当许多节点饱和时,更新次数减少,网络停止训练。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相同的 7 层网络在使用 sigmoid 激活函数而不使用批量标准化的情况下训练明显较慢。当使用 ReLu 时,通过批处理规范化,网络以相似的迭代次数收敛。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

另一方面,其他激活函数,如指数 ReLu 或泄漏 ReLu 函数,可以帮助解决消失梯度问题,因为它们对于正大数和负大数都具有非零导数。

最后,值得注意的是,批量标准化会导致额外的培训时间成本。虽然批量标准化通常减少了达到收敛的训练步骤的数量,但是它带来了额外的时间成本,因为它引入了额外的操作,并且还引入了每个单元两个新的训练参数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

For the MNIST classification problem (using a 1080 GTX GPU), Batch Normalization converges in (top) fewer iterations, however the time per iteration is slower. Ultimately, the Batch Normalization version still converges faster (bottom), but the improvement is less pronounced when incorporating total training time.

XLA 和融合批处理规范化(tf.layers.batch_normalization中的融合参数)合并到一个内核中,可以帮助加速批处理规范化操作。

无论如何,批处理规范化对于加速深度神经网络的训练是一个非常有价值的工具。和训练深度神经网络一样,判断一种方法是否对你的问题有帮助的最好方法就是去尝试!

如何利用企业邮件分析揭示隐藏的明星,确保机会均等!

原文:https://towardsdatascience.com/how-to-use-corporate-e-mail-analysis-to-reveal-hidden-stars-and-ensure-equal-opportunities-90bb77d61a7f?source=collection_archive---------13-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

unsplash.com

组织网络分析和沟通内容分析系列文章

1736 年,莱昂哈德·欧拉写了一篇关于柯尼斯堡七座桥的论文。这篇论文被认为是图论史上的第一篇。最近,图论被用于组织沟通领域,它被称为组织网络分析(ONA),基本上是“谁跟谁”。

在遍布全球的大型组织中,寻找领域专家、话题影响者或有效沟通者是一项挑战。意识到这些挑战,我们开始了探索之旅。

本系列文章的重点是电子邮件分析。简单来说,电子邮件包含:发件人、收件人、时间戳、主题和正文。但是,还有更多的字段可用。例如,MS Outlook 定义了关于字段的更多细节,这开启了一个应用 ONA 和数据科学的机会新世界。TrustSphere 也就主题写了一篇很棒的文章。

从某种意义上说,公司的电子邮件交流代表了同事之间的工作关系——这正是 ONA 的意义所在。通过各种分析,我们希望了解并推进人员培养、人才发现和整体组织沟通改善。我们区分了电子邮件网络和内容,以缓解隐私和道德话题。同样的原则也适用于组织中任何形式的现代交流,无论是即时消息、评论还是反馈系统。

基于电子邮件网络的分析

这种方法不使用电子邮件内容。它只关注电子邮件的“发件人”、“收件人”和“时间戳”字段。给某人发送电子邮件会在网络中创建一个边缘。很明显,仅通过分析“已发送”的电子邮件就可以构建整个组织网络(“已发送”的电子邮件将总是进入某人的收件箱)。在我们的实验数据集中,我们排除了邮件列表和外部电子邮件域,同时保留了 CC 和 BCC 收件人,它们在图中可能具有不同的权重。为简单起见,我们暂时将所有权重相同的电子邮件设为 1。我们的方法基于借用图论的 11 个网络度量,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们提出两个最有趣的观点:

  1. 内部继任计划
  2. 如果员工离职怎么办

有关这些见解的技术实现的更多信息,请参见第 2 部分

此外,我们还结合了各种衡量标准,以建议的形式向员工提供进一步的见解,包括如何改善他们的沟通和协作,以及向谁寻求建议和支持。

我们的建议有助于员工实现他们的潜力,并在您的组织中更加引人注目。

这些是我们已经实施的一些建议,但不是最终建议:

  1. 为了增加你在组织中的影响力,请联系 <用户>
  2. 改善与 <用户> 的沟通与协作。
  3. 要提高电子邮件沟通技巧,请联系 <用户>
  4. 改善与您的直接下属 <用户> 的沟通。

假设 <用户> 已经同意被推荐。

以下是这些建议的样子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有关技术实施和指标组合的更多信息,请参见第 3 部分,其中我们重点介绍前两个推荐器示例。

基于电子邮件内容的分析

电子邮件内容是电子邮件分析的另一个来源,但是它意味着更多的隐私问题。我们不断努力改进我们的概念,以解决与隐私相关的话题。如果你想了解更多,请参阅我们的文章《如何利用趋势发现隐藏的明星并致力于一个完美的项目?《人物分析会让你成为明星》,第四部分。

技术实现请参见第五部分


最后,使用 ONA 和 NLP 实现类似的电子邮件分析需要尽早解决以下问题:

  • 职业道德
  • 设计的数据隐私
  • 机器学习用例
  • 产品管理
  • 员工接受度

这些话题密切相关,相互依存。例如,今天,如果隐私问题没有在早期得到解决,就很难获得员工的认可,尤其是那些属于 GDPR 领域的产品。在这方面,我们定义了一种解决隐私和 GDPR 的方法,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

类似地,除非数据隐私和伦理没有得到很好的考虑和整合,否则产品管理无法开发出好的产品。例如,经理可以使用 ONA 指标来惩罚(甚至解雇)员工,而不是做正确的事情。因此,产品管理必须通过他们的解决方案关注员工的改进和能力,同时最小化误用见解和建议的空间。

成功的 ONA 产品实施取决于组织和员工如何跟进,以及公司文化如何处理这些见解。对于组织来说,理解、计划和实施洞察后阶段和过程是至关重要的——这只有在组织领导层的支持下才能实现。这种支持的主要原因与您的组织如何利用获得的信息有关。整个组织必须有向未来组织发展和转型的意愿和支持,在未来组织中,员工是组织发展的焦点。

本文是 ONA @豪夫系列文章的一部分


  1. 如何利用企业邮件分析揭示隐藏的明星,确保机会均等(Part 1)
  2. 基于电子邮件网络的见解的技术概述(第 2 部分)
  3. 深入探讨基于电子邮件网络的推荐(第 3 部分)
  4. 如何利用趋势发现隐藏的明星,并致力于一个完美的项目?人物分析会让你成为明星
  5. 如何实现基于电子邮件内容的分析(第 5 部分)

如何在 TensorFlow 中使用数据集

原文:https://towardsdatascience.com/how-to-use-dataset-in-tensorflow-c758ef9e4428?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我在LinkedIn,快来打个招呼 👋

内置的输入管道。再也不用“feed-dict”了

16/02/2020:我已经换成 PyTorch 😍

29/05/2019:我会把教程更新到 tf 2.0😎(我正在完成我的硕士论文)

2018 年 2 月 6 日更新:添加了第二个完整示例,将 csv 直接读入数据集

2018 年 5 月 25 日更新:添加了第二个完整示例,带有一个 可重新初始化的迭代器

更新至 TensorFlow 1.8

您应该知道,feed-dict是向 TensorFlow 传递信息的最慢方式,必须避免使用。将数据输入模型的正确方法是使用输入管道来确保 GPU 永远不会等待新的东西进来。

幸运的是,TensorFlow 有一个内置的 API,名为 Dataset ,可以更容易地完成这项任务。在本教程中,我们将了解如何创建输入管道,以及如何高效地将数据输入模型。

本文将解释数据集的基本机制,涵盖最常见的用例。

你可以在这里找到 jupyter 笔记本的所有代码:

https://github . com/FrancescoSaverioZuppichini/tensor flow-Dataset-Tutorial/blob/master/Dataset _ Tutorial . ipynb

一般概述

为了使用数据集,我们需要三个步骤:

  • 导入数据。从一些数据创建数据集实例
  • 创建一个迭代器。通过使用创建的数据集来制作迭代器实例来遍历数据集
  • 消费数据。通过使用创建的迭代器,我们可以从数据集中获取元素,以提供给模型

导入数据

我们首先需要一些数据放入我们的数据集

来自 numpy

这是常见的情况,我们有一个 numpy 数组,我们想把它传递给 tensorflow。

# create a random vector of shape (100,2)
x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)

我们也可以传递不止一个 numpy 数组,一个经典的例子是当我们将一些数据分成特征和标签时

features, labels = (np.random.sample((100,2)), np.random.sample((100,1)))
dataset = tf.data.Dataset.from_tensor_slices((features,labels))

来自张量

当然,我们可以用一些张量初始化我们的数据集

# using a tensor
dataset = tf.data.Dataset.from_tensor_slices(tf.random_uniform([100, 2]))

从占位符

当我们想要动态地改变数据集中的数据时,这是很有用的,我们将在后面看到如何改变。

x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)

来自发电机

我们也可以从生成器初始化一个数据集,当我们有一个不同元素长度的数组(例如一个序列)时,这很有用:

# from generator
sequence = np.array([[[1]],[[2],[3]],[[3],[4],[5]]])def generator():
    for el in sequence:
        yield eldataset = tf.data.Dataset().batch(1).from_generator(generator,
                                           output_types= tf.int64, 
                                           output_shapes=(tf.TensorShape([None, 1])))iter = dataset.make_initializable_iterator()
el = iter.get_next()with tf.Session() as sess:
    sess.run(iter.initializer)
    print(sess.run(el))
    print(sess.run(el))
    print(sess.run(el))

输出:

[[1]]
[[2]
 [3]]
[[3]
 [4]
 [5]]

在这种情况下,您还需要指定将用于创建正确张量的数据的类型和形状。

从 csv 文件

您可以直接将 csv 文件读入数据集。例如,我有一个 csv 文件,里面有推文和他们的情绪。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

tweets.csv

我现在可以通过调用tf.contrib.data.make_csv_dataset轻松地从它创建一个Dataset。请注意,迭代器将创建一个字典,以 key 作为列名,以张量的形式使用正确的行值。

# load a csv
CSV_PATH = './tweets.csv'
dataset = tf.contrib.data.make_csv_dataset(CSV_PATH, batch_size=32)
iter = dataset.make_one_shot_iterator()
next = iter.get_next()
print(next) # next is a dict with key=columns names and value=column data
inputs, labels = next['text'], next['sentiment']with  tf.Session() as sess:
    sess.run([inputs, labels])

next在哪里

{'sentiment': <tf.Tensor 'IteratorGetNext_15:0' shape=(?,) dtype=int32>, 'text': <tf.Tensor 'IteratorGetNext_15:1' shape=(?,) dtype=string>}

创建迭代器

我们已经看到了如何创建数据集,但是如何取回我们的数据呢?我们必须使用一个Iterator,这将使我们能够遍历数据集并检索数据的真实值。有四种类型的迭代器。

  • 一针。它可以遍历一次数据集,你不能给它任何值。
  • 可初始化:可以动态改变调用它的initializer操作,用feed_dict传递新数据。它基本上是一个可以装满东西的桶。
  • 可重新初始化:它可以从不同的Dataset.初始化,当你有一个训练数据集需要一些额外的变换,例如 shuffle,和一个测试数据集时非常有用。这就像使用塔式起重机来选择不同的容器。
  • Feedable : 可以用迭代器选择使用。按照前面的例子,就像一个塔吊选择用哪个塔吊来选择拿哪个集装箱。在我看来是没用的。

一次性迭代器

这是最简单的迭代器。使用第一个例子

x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)# create the iterator
iter = dataset.make_one_shot_iterator()

然后你需要调用get_next()来获取包含你的数据的张量

...
# create the iterator
iter = dataset.make_one_shot_iterator()
el = iter.get_next()

我们可以运行el来查看它的值

with tf.Session() as sess:
    print(sess.run(el)) # output: [ 0.42116176  0.40666069]

可初始化迭代器

如果我们想要构建一个动态数据集,可以在运行时改变数据源,我们可以创建一个带有占位符的数据集。然后我们可以使用通用的feed-dict机制初始化占位符。这是通过一个可初始化的迭代器完成的。使用上一节中的示例三

# using a placeholder
x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)data = np.random.sample((100,2))iter = dataset.make_initializable_iterator() # create the iterator
el = iter.get_next()with tf.Session() as sess:
    # feed the placeholder with data
    sess.run(iter.initializer, feed_dict={ x: data }) 
    print(sess.run(el)) # output [ 0.52374458  0.71968478]

这次我们叫make_initializable_iterator。然后,在sess范围内,我们运行initializer操作来传递我们的数据,在本例中是一个随机的 numpy 数组。。

想象一下,现在我们有一个训练集和一个测试集,这是一个真实的常见场景:

train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.array([[1,2]]), np.array([[0]]))

然后,我们将训练模型,然后在测试数据集上评估它,这可以通过在训练后再次初始化迭代器来完成

# initializable iterator to switch between dataset
EPOCHS = 10x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
dataset = tf.data.Dataset.from_tensor_slices((x, y))train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.array([[1,2]]), np.array([[0]]))iter = dataset.make_initializable_iterator()
features, labels = iter.get_next()with tf.Session() as sess:
#     initialise iterator with train data
    sess.run(iter.initializer, feed_dict={ x: train_data[0], y: train_data[1]})
    for _ in range(EPOCHS):
        sess.run([features, labels])
#     switch to test data
    sess.run(iter.initializer, feed_dict={ x: test_data[0], y: test_data[1]})
    print(sess.run([features, labels]))

可重新初始化的迭代器

这个概念类似于以前,我们要在数据之间动态切换。但是,我们不是向同一个数据集提供新数据,而是切换数据集。和以前一样,我们希望有一个训练数据集和一个测试数据集

# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))

我们可以创建两个数据集

# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices(train_data)
test_dataset = tf.data.Dataset.from_tensor_slices(test_data)

这就是诀窍,我们创建一个泛型迭代器

# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
                                           train_dataset.output_shapes)

然后是两个初始化操作:

# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)

我们像以前一样得到下一个元素

features, labels = iter.get_next()

现在,我们可以使用我们的会话直接运行两个初始化操作。综上所述,我们得到:

# Reinitializable iterator to switch between Datasets
EPOCHS = 10
# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))
# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices(train_data)
test_dataset = tf.data.Dataset.from_tensor_slices(test_data)
# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
                                           train_dataset.output_shapes)
features, labels = iter.get_next()
# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)with tf.Session() as sess:
    sess.run(train_init_op) # switch to train dataset
    for _ in range(EPOCHS):
        sess.run([features, labels])
    sess.run(test_init_op) # switch to val dataset
    print(sess.run([features, labels]))

可馈送迭代器

这非常类似于reinitializable迭代器,但是它不是在数据集之间切换,而是在迭代器之间切换。在我们创建了两个数据集之后

train_dataset = tf.data.Dataset.from_tensor_slices((x,y))
test_dataset = tf.data.Dataset.from_tensor_slices((x,y))

一个用于培训,一个用于测试。然后,我们可以创建我们的迭代器,在这种情况下我们使用initializable迭代器,但是你也可以使用one shot迭代器

train_iterator = train_dataset.make_initializable_iterator()
test_iterator = test_dataset.make_initializable_iterator()

现在,我们需要定义和handle,这将是一个可以动态改变的占位符。

handle = tf.placeholder(tf.string, shape=[])

然后,与之前类似,我们使用数据集的形状定义一个泛型迭代器

iter = tf.data.Iterator.from_string_handle(
    handle, train_dataset.output_types, train_dataset.output_shapes)

然后,我们得到下一个元素

next_elements = iter.get_next()

为了在迭代器之间切换,我们只需调用next_elemenents操作,并在 feed_dict 中传递正确的handle。例如,要从训练集中获取一个元素:

sess.run(next_elements, feed_dict = {handle: train_handle})

如果你正在使用initializable迭代器,就像我们正在做的那样,记得在开始之前初始化它们

sess.run(train_iterator.initializer, feed_dict={ x: train_data[0], y: train_data[1]})
    sess.run(test_iterator.initializer, feed_dict={ x: test_data[0], y: test_data[1]})

综上所述,我们得到:

# feedable iterator to switch between iterators
EPOCHS = 10
# making fake data using numpy
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((10,2)), np.random.sample((10,1)))
# create placeholder
x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
# create two datasets, one for training and one for test
train_dataset = tf.data.Dataset.from_tensor_slices((x,y))
test_dataset = tf.data.Dataset.from_tensor_slices((x,y))
# create the iterators from the dataset
train_iterator = train_dataset.make_initializable_iterator()
test_iterator = test_dataset.make_initializable_iterator()
# same as in the doc [https://www.tensorflow.org/programmers_guide/datasets#creating_an_iterator](https://www.tensorflow.org/programmers_guide/datasets#creating_an_iterator)
handle = tf.placeholder(tf.string, shape=[])
iter = tf.data.Iterator.from_string_handle(
    handle, train_dataset.output_types, train_dataset.output_shapes)
next_elements = iter.get_next()with tf.Session() as sess:
    train_handle = sess.run(train_iterator.string_handle())
    test_handle = sess.run(test_iterator.string_handle())

    # initialise iterators. 
    sess.run(train_iterator.initializer, feed_dict={ x: train_data[0], y: train_data[1]})
    sess.run(test_iterator.initializer, feed_dict={ x: test_data[0], y: test_data[1]})

    for _ in range(EPOCHS):
        x,y = sess.run(next_elements, feed_dict = {handle: train_handle})
        print(x, y)

    x,y = sess.run(next_elements, feed_dict = {handle: test_handle})
    print(x,y)

消费数据

在前面的例子中,我们使用了会话来打印数据集中next元素的值。

...
next_el = iter.get_next()
...
print(sess.run(next_el)) # will output the current element

为了将数据传递给模型,我们必须传递从get_next()生成的张量

在下面的代码片段中,我们有一个包含两个 numpy 数组的数据集,使用了第一部分中的相同示例。注意,我们需要将.random.sample包装在另一个 numpy 数组中,以添加一个维度,我们需要这个维度来批量处理数据

# using two numpy arrays
features, labels = (np.array([np.random.sample((100,2))]), 
                    np.array([np.random.sample((100,1))]))dataset = tf.data.Dataset.from_tensor_slices((features,labels)).repeat().batch(BATCH_SIZE)

然后像往常一样,我们创建一个迭代器

iter = dataset.make_one_shot_iterator()
x, y = iter.get_next()

我们制作一个模型,一个简单的神经网络

# make a simple model
net = tf.layers.dense(x, 8) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8)
prediction = tf.layers.dense(net, 1)loss = tf.losses.mean_squared_error(prediction, y) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)

我们直接使用来自iter.get_next()的张量作为第一层的输入,并作为损失函数的标签。包装在一起:

EPOCHS = 10
BATCH_SIZE = 16
# using two numpy arrays
features, labels = (np.array([np.random.sample((100,2))]), 
                    np.array([np.random.sample((100,1))]))dataset = tf.data.Dataset.from_tensor_slices((features,labels)).repeat().batch(BATCH_SIZE)iter = dataset.make_one_shot_iterator()
x, y = iter.get_next()# make a simple model
net = tf.layers.dense(x, 8, activation=tf.tanh) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)loss = tf.losses.mean_squared_error(prediction, y) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(EPOCHS):
        _, loss_value = sess.run([train_op, loss])
        print("Iter: {}, Loss: {:.4f}".format(i, loss_value))

输出:

Iter: 0, Loss: 0.1328 
Iter: 1, Loss: 0.1312 
Iter: 2, Loss: 0.1296 
Iter: 3, Loss: 0.1281 
Iter: 4, Loss: 0.1267 
Iter: 5, Loss: 0.1254 
Iter: 6, Loss: 0.1242 
Iter: 7, Loss: 0.1231 
Iter: 8, Loss: 0.1220 
Iter: 9, Loss: 0.1210

有用的东西

一批

通常批处理数据是一件痛苦的事情,有了Dataset API,我们可以使用方法batch(BATCH_SIZE)以提供的大小自动批处理数据集。默认值为 1。在下面的例子中,我们使用的批量大小为 4

# BATCHING
BATCH_SIZE = 4
x = np.random.sample((100,2))
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x).batch(BATCH_SIZE)iter = dataset.make_one_shot_iterator()
el = iter.get_next()with tf.Session() as sess:
    print(sess.run(el)) 

输出:

[[ 0.65686128  0.99373963]
 [ 0.69690451  0.32446826]
 [ 0.57148422  0.68688242]
 [ 0.20335116  0.82473219]]

重复

使用.repeat(),我们可以指定数据集迭代的次数。如果没有传递参数,它将永远循环下去,通常最好是永远循环下去,用标准循环直接控制历元数。

洗牌

我们可以通过使用方法shuffle()来打乱数据集,默认情况下,每个时期都会打乱数据集。

记住:打乱数据集对于避免过度适应非常重要。

我们还可以设置参数buffer_size,一个固定大小的缓冲区,下一个元素将从其中统一选择。示例:

# BATCHING
BATCH_SIZE = 4
x = np.array([[1],[2],[3],[4]])
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(BATCH_SIZE)iter = dataset.make_one_shot_iterator()
el = iter.get_next()with tf.Session() as sess:
    print(sess.run(el))

首次运行输出:

[[4]
 [2]
 [3]
 [1]]

第二轮输出:

[[3]
 [1]
 [2]
 [4]]

没错。它被洗牌了。如果您愿意,也可以设置seed参数。

地图

您可以使用map方法将自定义函数应用于数据集的每个成员。在下面的例子中,我们将每个元素乘以 2:

# MAP
x = np.array([[1],[2],[3],[4]])
# make a dataset from a numpy array
dataset = tf.data.Dataset.from_tensor_slices(x)
dataset = dataset.map(lambda x: x*2)iter = dataset.make_one_shot_iterator()
el = iter.get_next()with tf.Session() as sess:
#     this will run forever
        for _ in range(len(x)):
            print(sess.run(el))

输出:

[2]
[4]
[6]
[8]

完整示例

可初始化的迭代器

在下面的例子中,我们使用批处理来训练一个简单的模型,并且我们使用一个可初始化的迭代器在训练和测试数据集之间切换

# Wrapping all together -> Switch between train and test set using Initializable iterator
EPOCHS = 10
# create a placeholder to dynamically switch between batch sizes
batch_size = tf.placeholder(tf.int64)x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
dataset = tf.data.Dataset.from_tensor_slices((x, y)).batch(batch_size).repeat()# using two numpy arrays
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((20,2)), np.random.sample((20,1)))iter = dataset.make_initializable_iterator()
features, labels = iter.get_next()
# make a simple model
net = tf.layers.dense(features, 8, activation=tf.tanh) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)loss = tf.losses.mean_squared_error(prediction, labels) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # initialise iterator with train data
    sess.run(iter.initializer, feed_dict={ x: train_data[0], y: train_data[1], batch_size: BATCH_SIZE})
    print('Training...')
    for i in range(EPOCHS):
        tot_loss = 0
        for _ in range(n_batches):
            _, loss_value = sess.run([train_op, loss])
            tot_loss += loss_value
        print("Iter: {}, Loss: {:.4f}".format(i, tot_loss / n_batches))
    # initialise iterator with test data
    sess.run(iter.initializer, feed_dict={ x: test_data[0], y: test_data[1], batch_size: test_data[0].shape[0]})
    print('Test Loss: {:4f}'.format(sess.run(loss)))

注意,我们使用了一个批量大小的占位符,以便在训练后动态切换它

输出

Training...
Iter: 0, Loss: 0.2977
Iter: 1, Loss: 0.2152
Iter: 2, Loss: 0.1787
Iter: 3, Loss: 0.1597
Iter: 4, Loss: 0.1277
Iter: 5, Loss: 0.1334
Iter: 6, Loss: 0.1000
Iter: 7, Loss: 0.1154
Iter: 8, Loss: 0.0989
Iter: 9, Loss: 0.0948
Test Loss: 0.082150

可重新初始化的迭代器

在下面的例子中,我们使用批处理训练一个简单的模型,并且我们使用可重新初始化的迭代器在训练和测试数据集之间切换

# Wrapping all together -> Switch between train and test set using Reinitializable iterator
EPOCHS = 10
# create a placeholder to dynamically switch between batch sizes
batch_size = tf.placeholder(tf.int64)x, y = tf.placeholder(tf.float32, shape=[None,2]), tf.placeholder(tf.float32, shape=[None,1])
train_dataset = tf.data.Dataset.from_tensor_slices((x,y)).batch(batch_size).repeat()
test_dataset = tf.data.Dataset.from_tensor_slices((x,y)).batch(batch_size) # always batch even if you want to one shot it
# using two numpy arrays
train_data = (np.random.sample((100,2)), np.random.sample((100,1)))
test_data = (np.random.sample((20,2)), np.random.sample((20,1)))# create a iterator of the correct shape and type
iter = tf.data.Iterator.from_structure(train_dataset.output_types,
                                           train_dataset.output_shapes)
features, labels = iter.get_next()
# create the initialisation operations
train_init_op = iter.make_initializer(train_dataset)
test_init_op = iter.make_initializer(test_dataset)# make a simple model
net = tf.layers.dense(features, 8, activation=tf.tanh) # pass the first value from iter.get_next() as input
net = tf.layers.dense(net, 8, activation=tf.tanh)
prediction = tf.layers.dense(net, 1, activation=tf.tanh)loss = tf.losses.mean_squared_error(prediction, labels) # pass the second value from iter.get_net() as label
train_op = tf.train.AdamOptimizer().minimize(loss)with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # initialise iterator with train data
    sess.run(train_init_op, feed_dict = {x : train_data[0], y: train_data[1], batch_size: 16})
    print('Training...')
    for i in range(EPOCHS):
        tot_loss = 0
        for _ in range(n_batches):
            _, loss_value = sess.run([train_op, loss])
            tot_loss += loss_value
        print("Iter: {}, Loss: {:.4f}".format(i, tot_loss / n_batches))
    # initialise iterator with test data
    sess.run(test_init_op, feed_dict = {x : test_data[0], y: test_data[1], batch_size:len(test_data[0])})
    print('Test Loss: {:4f}'.format(sess.run(loss)))

其他资源

张量流数据集教程:https://www.tensorflow.org/programmers_guide/datasets

数据集文档:

https://www.tensorflow.org/api_docs/python/tf/data/Dataset

结论

Dataset API 为我们提供了一种快速而健壮的方式来创建优化的输入管道,以训练、评估和测试我们的模型。在本文中,我们已经看到了可以用它们进行的大多数常见操作。

你可以用我为这篇文章做的笔记本作为参考。

感谢您的阅读,

弗朗西斯科·萨维里奥

如何使用深度学习来量化传粉者的行为

原文:https://towardsdatascience.com/how-to-use-deep-learning-to-quantify-pollinator-behavior-i-5fc8000a9bde?source=collection_archive---------7-----------------------

在过去的几年里,关于两个看似不相关的话题的新闻变得相当模糊:蜜蜂和其他授粉者的减少,同时,人工智能和数据科学的增加。读了一些关于授粉和授粉如何工作的研究,我意识到尽管已经知道了很多,但是像所有科学一样,还有更多未知的东西。这引发了我的好奇心,难道没有可能将 AI 用于传粉者的研究吗?在这篇文章中,我解释了一个简单的方法。我写了一些代码,可以在我的 github 上找到。(https://github.com/jnnkl/bees_on_dahlia)。但作为一个引子:我想量化这部电影中花的访问量。

获取数据
要做的第一件事是收集数据。我的目标是做一些便宜的东西,所以我买了我能在当地电子商店找到的最便宜的网络摄像机。去年 9 月,我把它带到一个公园,收集了大约 1.5 个小时的一束大丽花的第二组延时照片。这产生了大约 4500 张图片的数据集。我的目标是使用深度学习方法来计算访问每朵花的传粉者的数量。我决定去监督学习,因为这是最容易的。为此,我需要一个带标签的数据集,为此我使用了前 1500 张图像。也就是说,我确实在有昆虫访客和没有昆虫访客的主花中间剪出了正方形。我做了不同大小的方块,并把每只蜜蜂剪了几次。用这种方法,我收集了 635 张有蜜蜂的花的照片,因为花更经常不被访问,而不是被访问,所以有更多没有昆虫的照片。事实证明,花更经常不被参观,而不是参观。为了使数据集平衡,我使用了相似数量的空花图片。

构建网络
我想构建一个包含两类的分类器 1)有昆虫存在,2)没有昆虫存在。我为此使用了卷积神经网络,因为这对图像识别非常有用。由于数据量不多,我选择了迁移学习。因为 VGG16 是安装在我电脑上的 keras 发行版中最小的网络,所以我使用了它。我使用了 keras 的这篇(https://blog . keras . io/building-powerful-image-classification-models-using-very-little-data . html)博文中讨论的技术。在 VGG16 网络之上,我放了一个小的卷积神经网络,训练这个小网络并保存它。接下来,我把整个网络,使前 15 层不可训练,然后用非常小的训练率训练其余部分,以防止过度拟合。我很快得到了超过 92%的准确率。我很幸运能够访问 GPU 集群来进行培训,否则这将需要相当长的时间。

制作电影
现在我可以对有蜜蜂或没有蜜蜂的正方形图像进行分类,是时候用它来检查我的电影中两种主要花卉的昆虫访客数量了。幸运的是,我在一个无风的日子做了延时记录,所以图像相当稳定。所以我简单地确定了两朵花的位置,取了每张照片的这些部分,通过神经网络运行,得到了一个表格,显示了这两朵花的每张照片上是否有昆虫。由于准确性很高,但不太高,我决定只计算那些昆虫的实例,如果至少有两个昆虫的后续实例,类似地,如果它消失的时间短于一秒钟,那么我将其重新分类为。我在我看的地方画了方框,如果没有昆虫就画红色,如果有昆虫就画绿色。这导致了下面的电影:

量化结果和一些讨论
现在我有了一个很好的可视化,这并不是真正的量化让我们来看一些图。在这个图中,花 1 是左上角的花,花 2 是只能看到一半的大花。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它们表明,较大的花得到更多的访问,访问之间的间隔似乎更小。当然,这个简短的测量并不支持任何关于传粉者行为的严肃主张,但这不是我想要的。这个实验的目标是表明深度学习技术可以帮助研究授粉行为,也是以定量的方式。当然,这也可以用经典的图像分析方法来完成。或许,人们可以相对容易地提出一种算法,自动识别昆虫对这些大丽花的访问。然而,他们并不推广到其他花卉。我检查了这个网络是否也适用于其他花的延时。如果是这样的话,我会很幸运,事实上我不得不得出结论,这个网络只为这些花工作。其他花的结构通常比这种特殊的大丽花更多样化,要建立一个网络来检测所有种类的花上的昆虫实际上是相当棘手的。所以如何为其他花和更多背景获得一个好的昆虫检测网络将是后面帖子的一个话题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A nice picture of a bumblebee on a Rubus flower.

如何使用 ELMo 词向量进行垃圾邮件分类

原文:https://towardsdatascience.com/how-to-use-elmo-word-vectors-for-spam-classification-1891c0da8f1d?source=collection_archive---------10-----------------------

自然语言处理的 Keras 教程

数据集:https://www . ka ggle . com/UC IML/SMS-spam-collection-dataset/version/1 # _ = _

代码:http://hunterheidenreich . com/blog/elmo-word-vectors-in-keras/

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何使用脸书图形 API 和使用 Python 提取数据!

原文:https://towardsdatascience.com/how-to-use-facebook-graph-api-and-extract-data-using-python-1839e19d6999?source=collection_archive---------0-----------------------

大家好,

这是我关于 Medium.com 的第二篇报道。自从第一个故事以来,我已经从挣扎着写代码变成了有点舒服。我写了一个 Python 代码来提取脸书的公开数据。让我们深入研究一下。

获取接入令牌:

为了能够使用 python 代码从脸书提取数据,您需要在脸书上注册为开发人员,然后拥有一个访问令牌。下面是它的步骤。

  1. 去 developers.facebook.com 链接,在那里创建一个账户。
  2. 转到链接developers.facebook.com/tools/explorer
  3. 转到右上角的“我的应用程序”下拉菜单,选择“添加新应用程序”。选择显示名称和类别,然后“创建应用 ID”。
  4. 再次回到同一环节developers.facebook.com/tools/explorer。您将在右上角的“我的应用程序”下方看到“图形应用程序资源管理器”。从“图形 API 浏览器”下拉列表中,选择您的应用程序。
  5. 然后,选择“获取令牌”。从该下拉列表中,选择“获取用户访问令牌”。从出现的菜单中选择“权限”,然后选择“获取访问令牌”
  6. 转到链接developers.facebook.com/tools/accesstoken。选择“用户令牌”对应的“调试”。转到“扩展令牌访问”。这将确保您的令牌不会每两小时过期一次。

访问脸书公共数据的 Python 代码:

如果你想收集任何公开的数据,请点击链接https://developers.facebook.com/docs/graph-api。参见https://developers . Facebook . com/docs/graph-API/reference/v 2.7/。从这个文档中,选择您想要从中提取数据的任何字段,如“组”或“页”等。在选择了这些代码之后,去看看代码的例子,然后选择“facebook graph api ”,你会得到如何提取信息的提示。这个博客主要是关于获取事件数据。

首先,导入’ urllib3 ‘,’ facebook ‘,’ requests ',如果它们已经可用的话。如果没有,请下载这些库。定义一个变量令牌,并将其值设置为上面得到的“用户访问令牌”。

token= ‘aiufniqaefncqiuhfencioaeusKJBNfljabicnlkjshniuwnscslkjjndfi’

获取事件列表:

现在,要查找任何搜索词“诗歌”的事件信息,并将这些事件的数量限制为 10000 个:

graph = facebook.GraphAPI(access_token=token, version = 2.7)
events = graph.request(‘/search?q=Poetry&type=event&limit=10000’)

这将给出一个在脸书上创建的所有事件的字典,并且其名称中有字符串“诗歌”。要获取事件列表,请执行以下操作:

eventList = events[‘data’]

从上面提取的事件列表中提取事件的所有信息:

通过以下方式获取列表中第一个事件的 EventID

eventid = eventList[1][‘id’]

对于此 EventID,获取所有信息并设置一些变量,这些变量将在以后由以下人员使用:

event1 = graph.get_object(id=eventid,
 fields=’attending_count,can_guests_invite,category,cover,declined_count,description,end_time,guest_list_enabled,interested_count,is_canceled,is_page_owned,is_viewer_admin,maybe_count,noreply_count,owner,parent_group,place,ticket_uri,timezone,type,updated_time’)
attenderscount = event1[‘attending_count’]
declinerscount = event1[‘declined_count’]
interestedcount = event1[‘interested_count’]
maybecount = event1[‘maybe_count’]
noreplycount = event1[‘noreply_count’]

获取所有参加活动的人的列表,并将响应转换成 json 格式:

attenders = requests.get(“[https://graph.facebook.com/v2.7/](https://graph.facebook.com/v2.7/)"+eventid+"/attending?access_token="+token+”&limit=”+str(attenderscount)) attenders_json = attenders.json()

获取事件的管理员:

admins = requests.get(“[https://graph.facebook.com/v2.7/](https://graph.facebook.com/v2.7/)"+eventid+"/admins?access_token="+token)admins_json = admins.json()

同样,如果您愿意,您可以提取其他信息,如该活动的照片/视频/提要。

进入https://developers . Facebook . com/docs/graph-API/reference/event/查看文档中的“Edges”部分。见图片

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,让我们说,你想有一个对这个事件感兴趣的所有人的名单,点击“感兴趣的”绿色单词在这里。这将打开新的一页:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在此选择“图形 API 浏览器”。这将打开新的一页:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里,输入事件的 id 来代替{event-id},如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击提交。此外,在同一页面上,你会发现下面的’获取代码’选项

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

选择它以查看代码。在出现的弹出窗口中选择“curl ”,然后在 python 代码中获得相同的输出,用 requests.get 编写它,如上面的示例所示。

希望这对那些开始使用 facebook graph API 的人有所帮助。我将很高兴听到你的建议/问题/反馈。

如果你发现这个博客对你有任何价值,如果你对加密货币感兴趣,如果你很慷慨,考虑发送一些涟漪到以下地址:

目的地标签:5973413

钱包地址:rld inlq 5 cjood 9 wdjy 9 zcdgyck 8 kgevkuj

上面的语句中有太多的如果。只有三个都是真的才发送!加密货币 FTW!

如何使用 flickr api 为深度学习实验收集数据?

原文:https://towardsdatascience.com/how-to-use-flickr-api-to-collect-data-for-deep-learning-experiments-209b55a09628?source=collection_archive---------6-----------------------

一旦你踏上了深度学习的旅程,并通过了基本的玩具示例,如在 MNIST 数据集上对手写数字进行分类,下一个合乎逻辑的步骤就是开始从事自己的定制项目。人们遇到的第一个障碍是他们想要做的定制项目的数据可能不可用。如果你知道如何清理网站,你可以很容易地收集到你想要的图片,但是清理网站有两个陷阱:

1.刮一些网站是不合法也不道德的

2.即使你不关心法律或道德,大规模报废也是具有挑战性的,特别是如果有适当的保护措施来阻止报废的话。

除了废弃网络,还有其他选择。以下是您可以在自己的项目中使用图像数据的资源列表:

1.Yelp 公开了大量的数据,他们公开了 20 万张图片的数据集,你可以点击这里查看https://www.yelp.com/dataset

2.这里也有亚马逊评论数据托管在 http://jmcauley.ucsd.edu/data/amazon/也包括预处理的图像特征

3.此外,还有一些数据集,如学术界非常常用的 MS COCO、Imagenet 和 CIFAR 10。

如果这些数据集似乎也不能满足您的目的,那么您可以使用 flickr 作为您的数据收集来源。Flickr 有一个 api 可以用来收集图片。您可以使用这个 api 通过标签搜索图像。例如,您可以搜索日常物品/地点和建筑物的图像,如灯柱、披萨、教堂等。我能够使用这个 api 轻松地为一个给定的标签获取大约 600 多张图片。我能够创建一个脚本,通过标签获取图像,并存储在计算机上的一个文件夹中,该文件夹以被搜索的标签命名。我创建了两个脚本,一个获取给定标记的 url,并将其存储在 csv 文件中。另一个脚本从 url 文件中读取链接,获取图像并将它们存储在一个文件夹中。

下面是通过标签获取 Url 的脚本代码, flickrGetUrl.py (你可以在这里注册获得密钥和应用程序秘密令牌https://www.flickr.com/services/apps/create/

要使用上面的脚本,您可以在终端中运行以下命令:

python flickrGetUrl.py pizza 500

这将在工作目录中创建一个新文件,其中将有指向 pizza 图像的链接,这将是一个名为 pizza.csv 的. csv 文件。第一个参数是您想要其图像的标记,第二个参数是要尝试的 URL 获取的数量。

第二个文件, get_images.py 从 url 获取图片并将图片存储在一个文件夹中,下面是它的代码:

要使用第二个文件,请在终端中键入以下内容:

python get_images.py pizza.csv

这将从存储在 pizza.csv 中的 URL 获取图像,并将它们存储在一个名为 pizza 的文件夹中。

这些是一些常见的方法,人们可以通过这些方法获取图像数据来运行深度学习实验。请记住,上面的脚本可能需要一些时间来下载图像,您可以通过向它们添加多处理功能并在多核机器上运行它们来加速这些脚本。

如何使用机器学习进行异常检测和状态监控

原文:https://towardsdatascience.com/how-to-use-machine-learning-for-anomaly-detection-and-condition-monitoring-6742f82900d7?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

机器学习和统计分析的具体用例

在本文中,我将介绍机器学习和统计分析的几种不同技术和应用,然后展示如何应用这些方法来解决异常检测和状态监控的特定用例。

数字化转型,数字化,工业 4.0 等。

这些都是你以前可能听说过或读到过的术语。然而,在所有这些时髦词汇的背后,主要目标是利用技术和数据来提高生产率和效率。设备和传感器之间的信息和数据的连接和流动允许大量的可用数据。关键的促成因素是能够使用这些大量的可用数据并实际提取有用的信息,从而有可能降低成本、优化容量并将停机时间降至最低。这就是最近围绕机器学习和数据分析的讨论发挥作用的地方。

异常检测

异常检测(或异常值检测)是对罕见项目、事件或观察结果的识别,这些项目、事件或观察结果因与大多数数据显著不同而引起怀疑。通常,异常数据可能与某种问题或罕见事件有关,例如银行欺诈、医疗问题、结构缺陷、设备故障等。这种联系使得挑选出哪些数据点可以被视为异常变得非常有趣,因为从业务角度来看,识别这些事件通常非常有趣。

这给我们带来了一个关键目标:我们如何识别数据点是正常的还是异常的?在一些简单的情况下,如下图所示,数据可视化可以给我们重要的信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1 : Anomaly detection for two variables

在二维数据( XY )的情况下,通过位于典型分布之外的数据点直观地识别异常变得非常容易。然而,看右边的图,不可能通过调查当时的一个变量直接识别异常值:X 和 Y 变量的组合使我们能够容易地识别异常值。当我们从两个变量扩大到 10-100 个变量时,事情变得非常复杂,这在异常检测的实际应用中是常见的情况。

连接到状态监控

任何机器,无论是旋转机器(泵、压缩机、燃气轮机或蒸汽轮机等。)或非旋转机器(热交换器、蒸馏塔、阀门等)。)最终会达到健康不佳的地步。该点可能不是实际故障或停机的点,而是设备不再以最佳状态运行的点。这表明可能需要一些维护活动来恢复全部运行潜力。简单来说,识别我们设备的“健康状态”是状态监控的领域。

执行状态监控的最常见方法是查看机器的每个传感器测量值,并对其施加最小和最大值限制。如果当前值在界限内,那么机器是健康的。如果当前值超出界限,则机器不健康,并发出警报。

众所周知,这种强加硬编码警报限值的程序会发送大量错误警报,即针对机器实际健康状态的警报。还有漏报警,即有问题但没有报警的情况。第一个问题不仅浪费时间和精力,而且浪费设备的可用性。第二个问题更为关键,因为它会导致真正的损失,以及相关的维修费用和生产损失。

这两个问题都是由同一个原因引起的:一个复杂设备的健康状况无法根据对每个测量值的分析而可靠地判断出来(正如上一节异常检测中的图 1 所示)。我们必须考虑各种测量的组合来获得情况的真实指示

技术部分:

如果不深入一些更技术性的方面,很难涵盖异常检测的机器学习和统计分析主题。我还是会避免太深入理论背景(但是提供一些链接,可以更详细的描述)。如果您对机器学习和统计分析的实际应用更感兴趣,例如状态监控,请直接跳到“状态监控用例”部分。

方法 1:多元统计分析

使用主成分分析的维数减少:PCA

由于处理高维数据通常具有挑战性,有几种技术可以减少变量的数量(维度缩减)。其中一个主要技术是主成分分析 (PCA),它执行数据到低维空间的线性映射,使得低维表示中数据的方差最大化。在实践中,构建数据的协方差矩阵,并计算该矩阵的特征向量。对应于最大特征值(主成分)的特征向量现在可以用于重构原始数据的方差的大部分。原始的特征空间现在已经减少到由几个特征向量跨越的空间(丢失了一些数据,但是希望保留最重要的方差)。

多元异常检测

正如我们上面提到的,为了在处理一两个变量时识别异常,数据可视化通常是一个很好的起点。然而,当将其扩展到高维数据时(实际应用中经常出现这种情况),这种方法变得越来越困难。幸运的是,多元统计学在这方面发挥了作用。

当处理一组数据点时,它们通常具有某种分布(例如高斯分布)。为了以更定量的方式检测异常,我们首先从数据点计算概率分布 p (x)。然后当一个新的例子 *x,*进来时,我们将 p (x)与一个阈值 r 进行比较。如果 p (x) < r ,则认为是异常。这是因为正常示例倾向于具有大的 p (x ),而异常示例倾向于具有小的 p (x)

在状态监控的情况下,这是很有趣的,因为异常可以告诉我们一些关于被监控设备的“健康状态”的信息:当设备接近故障或次优操作时,生成的数据通常与来自“健康”设备的数据具有不同的分布。

马哈拉诺比斯距离

如上所述,考虑估计数据点属于分布的概率的问题。我们的第一步是找到样本点的质心或质心。直觉上,问题点离这个质心越近,就越有可能属于集合。然而,我们还需要知道这个集合是分布在一个大的范围还是一个小的范围,这样我们就可以决定一个给定的距离中心的距离是否值得注意。最简单的方法是估计样本点到质心距离的标准偏差。通过将其代入正态分布,我们可以推导出数据点属于同一分布的概率。

上述方法的缺点是,我们假设样本点以球形方式围绕质心分布。如果分布确实是非球形的,例如椭球形,那么我们可以预期测试点属于该集合的概率不仅取决于离质心的距离,还取决于方向。在椭球具有短轴的方向上,测试点必须更近,而在长轴的方向上,测试点可以离中心更远。在数学基础上,可以通过计算样本的协方差矩阵来估计最能代表集合概率分布的椭球。 Mahalanobis 距离 (MD)是测试点距离质心的距离除以椭球体在测试点方向的宽度。

为了使用 MD 将测试点分类为属于 N 个类别之一,首先估计每个类别的协方差矩阵,通常基于已知属于每个类别的样本。在我们的例子中,由于我们只对“正常”与“异常”的分类感兴趣,我们使用只包含正常操作条件的训练数据来计算协方差矩阵。然后,给定一个测试样本,我们计算“正常”类别的 MD,如果距离高于某个阈值,则将测试点分类为“异常”。

**注意:**MD 的使用意味着可以通过均值和协方差矩阵进行推断——这是正态分布独有的特性。在我们的情况下,这个标准不一定满足,因为输入变量可能不是正态分布的。然而,我们还是试了一下,看看效果如何!

方法 2:人工神经网络

自动编码器网络

第二种方法是基于使用自动编码器神经网络。它基于与上述统计分析相似的原理,但略有不同。

自动编码器是一种人工神经网络,用于以无监督的方式学习高效的数据编码。自动编码器的目的是学习一组数据的表示(编码),通常用于维度缩减。随着缩减侧,学习重构侧,其中自动编码器试图从缩减的编码中生成尽可能接近其原始输入的表示。

在架构上,自动编码器的最简单形式是一个前馈,非递归神经网络,非常类似于许多单层感知器,这使得多层感知器(MLP)——具有一个输入层、一个输出层和一个或多个连接它们的隐藏层——但是输出层具有与输入层相同数量的节点,并且目的是重建它自己的输入。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2: Autoencoder network

在异常检测和状态监控的背景下,基本思想是使用自动编码器网络将传感器读数“压缩”到一个较低维度的表示,该表示捕获各种变量之间的相关性和相互作用。(基本上与 PCA 模型的原理相同,但是这里我们也允许变量之间的非线性相互作用)。

然后,自动编码器网络根据代表“正常”操作状态的数据进行训练,目标是首先压缩,然后重构输入变量。在降维过程中,网络学习各种变量之间的相互作用,并且应该能够在输出端将它们重构回原始变量。主要思想是,随着被监控设备的退化,这将影响变量之间的相互作用(例如,温度、压力、振动等的变化)。).当这种情况发生时,人们将开始看到输入变量的网络重构中的误差增加。通过监控重建误差,可以得到被监控设备的“健康”的指示,因为该误差将随着设备退化而增加。类似于使用马氏距离的第一种方法,我们这里使用重建误差的概率分布来识别数据点是正常还是异常。

状态监控用例:齿轮轴承故障

在本节中,我将介绍一个使用上述两种不同方法进行状态监控的实际用例。由于我们与客户合作的大部分数据都不是公开可用的,我选择用 NASA 提供的数据来演示这两种方法,这些数据可以在这里下载。

对于此用例,目标是检测发动机上的齿轮轴承退化,并发出警告,允许采取预测措施,以避免齿轮故障(例如,可能是设备的计划维护/修理)。

实验细节和数据准备:

三组数据,每组由四个轴承组成,在恒定负载和运行条件下运行至失效。振动测量信号是在轴承的整个寿命期间为数据集提供的,直到发生故障。失败发生在 1 亿次循环后,外环出现裂纹(参见下载页面的自述文件,了解更多关于实验的信息)。由于设备一直运行到发生故障,前两天运行的数据被用作训练数据,以代表正常和“健康”的设备。然后将轴承故障发生前的数据集的剩余部分用作测试数据,以评估不同方法是否能够在故障发生前检测到轴承退化。

方法 1 : PCA + Mahalanobis 距离

正如在本文的“技术部分”中更详细解释的,第一种方法包括首先执行主成分分析,然后计算马氏距离 (MD)以识别数据点是正常还是异常(设备退化的迹象)。代表“健康”设备的训练数据的 MD 分布如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3: Distribution of Mahalanobis distance for “healthy” equipment

使用“健康”设备的 MD 分布,我们可以定义一个阈值来判断什么是异常。根据上述分布,我们可以将 MD > 3 定义为异常。检测设备退化的这种方法的评估现在包括计算测试集中所有数据点的 MD,并将其与定义的阈值进行比较,以将其标记为异常。

测试数据的模型评估:

使用上述方法,我们计算了轴承失效前的测试数据的 MD,如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 4: Predicting bearing failure using approach 1

在上图中,绿点对应于计算的 MD,而红线代表用于标记异常的定义阈值。轴承故障发生在数据集的末端,由黑色虚线表示。这说明第一种建模方法能够在实际故障(MD 超过阈值)前大约 3 天检测到即将到来的设备故障。

我们现在可以使用第二种建模方法进行类似的练习,以评估哪种方法比另一种方法性能更好。

方法 2:人工神经网络

正如在论文的“技术部分”中更详细解释的,第二种方法包括使用自动编码器神经网络来寻找异常(通过网络中增加的重建损失来识别)。类似于第一种方法,我们在这里也使用代表“健康”设备的训练数据的模型输出的分布来检测异常。训练数据的重建损失(平均绝对误差)分布如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 5 : Distribution of reconstruction loss for “healthy” equipment.

使用“健康”设备的重建损失分布,我们现在可以定义一个阈值来确定什么是异常。根据上述分布,我们可以将大于 0.25 的损失定义为异常。检测设备退化的方法的评估现在包括计算测试集中所有数据点的重建损失,并将该损失与定义的阈值进行比较,以将其标记为异常。

测试数据的模型评估:

使用上述方法,我们计算了轴承失效前的测试数据的重建损失,如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 6: Predicting bearing failure using approach 2

在上图中,蓝点对应于重建损失,而红线代表用于标记异常的定义阈值。轴承故障发生在数据集的末端,由黑色虚线表示。这说明这种建模方法也能够在实际故障(其中重建损失超过阈值)之前大约 3 天检测到即将到来的设备故障。

结果摘要:

如以上关于两种不同异常检测方法的章节所示,两种方法都能够在实际故障发生前几天成功检测到即将发生的设备故障。在现实生活中,这将允许在故障之前采取预测措施(维护/修理),这意味着节约成本以及设备故障对 HSE 方面的潜在重要性。

展望:

随着通过传感器捕获数据的成本降低,以及设备之间的连接性增加,能够从数据中提取有价值的信息变得越来越重要。在大量数据中寻找模式是机器学习和统计学的领域,在我看来,利用隐藏在这些数据中的信息来提高几个不同领域的性能有巨大的可能性。本文中提到的异常检测和状态监控只是许多可能性中的一种。(此处也可用)

在未来,我相信机器学习将会被用在比我们今天所能想象的更多的地方。你认为它会对各个行业产生什么影响?我很想在下面的评论中听到你的想法。

编辑:这篇关于异常检测和状态监控的文章收到了很多反馈。我收到的许多问题涉及技术方面以及如何建立模型等。由于这个原因,我决定写一篇后续文章,详细介绍所有必要的步骤,从预处理数据到构建模型和可视化结果。

如果你有兴趣了解更多与人工智能/机器学习和数据科学相关的主题,你也可以看看我写的其他一些文章。你会发现他们都列在我的中型作者简介,中,你可以在这里找到。

而且,如果你想成为一个媒体会员,免费访问平台上的所有资料,你也可以使用下面我的推荐链接。(注意:如果您使用此链接注册,我也会收到一部分会员费)

* [## 通过我的推荐链接加入媒体- Vegard Flovik

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@vflovik/membership)

更多来自 Vegard Flovik 媒体:

  1. 蒙特卡洛方法简介
  2. 从物理学到数据科学的转变
  3. 什么是图论,为什么要关心?
  4. 用于图像分类的深度迁移学习
  5. 建造一个能读懂你思想的人工智能
  6. 机器学习:从炒作到现实应用
  7. 人工智能和大数据隐藏的风险
  8. 供应链管理的人工智能:预测分析和需求预测
  9. 如何(不)使用机器学习进行时间序列预测:避免陷阱
  10. 如何利用机器学习进行生产优化:利用数据提高绩效
  11. 如何向 AI 系统教授物理?
  12. 我们能否利用纳米级磁铁构建人工大脑网络?

人工智能研讨会——从宣传到现实应用*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值