TowardsDataScience-博客中文翻译-2020-三十九-

TowardsDataScience 博客中文翻译 2020(三十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

语义文本匹配的深度学习

原文:https://towardsdatascience.com/deep-learning-for-semantic-text-matching-d4df6c2cf4c5?source=collection_archive---------5-----------------------

卡韦蒂·纳文库马尔舒拉滕德拉·哈索拉撰写

在本文中,我们将讨论语义文本匹配问题,它在信息检索(网络搜索)、问题回答、推荐系统等领域都有应用。

语义文本匹配是估计源文本和目标文本之间语义相似度的任务。让我们用下面这个寻找最接近问题的例子来理解这一点。我们得到了一个大的问题语料库,对于任何提出或搜索的新问题,目标是从这个语料库中找到最相似的问题。语义是这项任务的一个重要方面。例如,在给定的图中,问题“投资房地产市场的逐步指南是什么”与源问题并不十分相关,但仍然与源问题有很高的句法重叠。而这里的句法重叠指的是两者之间的常用词数量。

我们将讨论如何为这样的任务建立一个机器学习系统。

来源:作者图片

下表列出了语义文本匹配在网络搜索、赞助搜索、问题回答和产品推荐领域的一些应用。

来源:作者图片

在本文的剩余部分中,我们将把重点放在新闻搜索上,作为一个说明性的例子,目标是为给定的输入查询找到相关的新闻文章。尽管我们将要讨论的技术适用于任何语义文本匹配任务。

来源:作者图片

下图描述了新闻搜索 IR 系统的高级流程:

IR 系统(新闻搜索)(来源:作者图片)

基线方法

首先,让我们看一个简单的二进制分类方法来构建这样一个检索和排序系统。本质上,我们希望建立一个模型,该模型将查询和文档作为输入,并预测文档与查询相关的概率。

为了训练这个模型,首先我们需要生成带有查询和文档对以及 0/1 标签的训练数据。这种训练数据可以基于人类标记来收集。但是人工标记非常昂贵,而且只能产生有限的数据。这就是为什么通常使用基于历史点击数据的代理标签生成方法。

因此,如果对于给定的查询,当向用户显示文档时,该文档已经接收了最小数量的点击和最小点击率,则查询-文档对被标记为 1。并且对于同一查询,从语料库中随机采样的少量文档被标记为 0,并用于训练模型。

一旦我们收集了这些数据,我们就可以从查询和文档中提取一些特征,并训练一个二元分类模型(SVM/提升树/神经网络),然后将其用于我们的 IR 系统。

对于任何类似“银行存款利率”的查询,我们都会根据语料库中的文档逐一进行评估。首先,我们将查询和文档 1 传递给模型,这将给出该文档与查询相关的概率。然后,我们将传递查询和文档 2,并获得文档 2 的概率,我们将对语料库中的所有文档进行预测。一旦我们有了所有文档的概率,我们就可以根据概率对它们进行排序,并将排名靠前的文档返回给用户。

但是正如您可能已经观察到的,这种方法是不可伸缩的,因为文档语料库可能非常庞大,并且逐个对文档进行评分是不可行的。

来源:作者图片

大规模系统的两步法;

为了平衡规模和质量,大规模语义文本匹配系统通常遵循两步方法:

步骤 1 —候选人生成:

第一步是候选人生成。候选生成步骤的目标是快速检索与输入查询相关的文档子集。这一步有一些假阳性是可以的,如果这有助于使这一步更快。有多种方法可以构建候选生成模块。我们将在本文中讨论两种方法。

候选人生成(来源:作者图片)

步骤 2 —重新分级:

一旦我们有了 100 个候选文档,下一步就是重新排序。重新排序步骤的目标是相对于输入查询对候选文档进行排序,从而可以向用户显示排名靠前的文档。有多种方法可以构建重新排序模块。我们将在本文中讨论两个模型。

重新排名(来源:作者图片)

候选人生成:

基于倒排索引的候选生成:

传统上,基于令牌的倒排索引用于候选生成。倒排索引本质上是一个哈希映射,它将标记或单词映射到包含该标记的文档列表。这种索引构建可以离线完成。

然后,当查询到来时,首先我们将把查询分成标记,然后对于每个标记,我们将查找索引以获得包含该标记的文档列表。这些单个列表与 BM25 得分的联合可用作下一步重新分级的候选文档。

基于倒排索引的候选生成(来源:作者图片)

但是这种基于标记的检索具有局限性,因为它不能捕获单词之间的语义关系。例如,该方法为查询“银行存款利率”检索新闻文章“由于非法采矿在河岸沉积沙子”,因为没有办法区分“金融”银行和“河流”银行。

基于嵌入的候选生成:

最近,使用 DNN 嵌入的候选生成变得流行,因为它们可以更好地捕获查询和文档语义。在深入研究嵌入如何用于候选生成之前,让我们先简要介绍一下嵌入

单词嵌入:文献中提出了许多密集嵌入技术,如 word2vec、Glove、fasttext 等。这些技术的目的是通过几个 100 维实数密集向量来表示单词,使得语义相似单词的向量在 n 维空间中是邻近的。预先训练的单词嵌入可从各种 NLP 组下载。

Word2vec CBoW 和 Skip-gram 是两个早期的单词嵌入模型,它们围绕密集单词嵌入产生了很多兴趣。CBoW 将单词周围的上下文作为输入,并试图预测单词,而 skip-gram 将单词作为输入,并试图预测世界各地的上下文。这两种架构的目标都是提取单词共现模式,从而捕获单词之间的语义关系

来源:【word 2 矢量模型的 CBoW 和 Skip-gram 架构

句子嵌入:一种生成句子嵌入的方法可以是直接对句子中的单词向量进行平均,但是这种平均嵌入对于像语义匹配这样的下游任务来说执行得不是很好。已经提出了许多模型来学习更好的句子嵌入。BERT 就是这样一个基于 transformer 架构的流行深度学习模型。各种 NLP 小组都提供了在大量文本数据(如维基百科和图书语料库)上训练的预训练 BERT 模型。这些预先训练的模型可以用于为语料库中的文档生成嵌入

来源: BERT:用于语言理解的深度双向转换器的预训练

有了这个关于嵌入的快速背景,让我们看看如何使用嵌入来生成候选项。首先,我们可以使用像 BERT 这样的技术生成语料库中所有文档的嵌入。现在,当新的查询出现时,我们可以使用相同的 BERT 预训练模型将其转换为数字向量。然后可以基于查询嵌入和每个文档嵌入之间的余弦相似性来检索候选文档。

来源:作者图片

但是计算所有文档嵌入的查询嵌入的余弦相似度是非常昂贵的。这就是类似 FAISS 的相似性搜索库发挥作用的地方。这些库允许在嵌入空间中非常有效的 top-k 检索。本质上,文档向量可以使用像 FAISS 这样的库进行离线索引。现在,当新的查询出现时,我们可以使用相同的 BERT 预训练模型将其转换为数字向量。然后,使用查询嵌入对文档的向量索引运行最近邻搜索,并在嵌入空间中检索前 k 个最近的文档。

密集向量的高效相似性搜索(来源:作者图片)

重新分级:

一旦我们检索到前 k 个候选文档,下一步就是根据查询对这些文档进行排序,这样就可以向用户呈现排名靠前的结果。

为什么我们需要重新排名?

一种方法可以是完全取消重新排序步骤,直接使用由候选生成步骤提供的排序来选择最高的结果。但是这种方法不是最佳的,因为候选生成具有局限性:

  • 首先,对于候选生成步骤,需要离线预计算文档嵌入,这意味着只能使用独立于查询和基于嵌入的模型。此外,任何在查询和文档之间使用交叉特征的模型都不能用于候选生成步骤。
  • 第二,重新排序模型可用于优化特定任务目标,如赞助搜索中的点击率或产品推荐中的转化率,而通用预训练模型可用于候选生成。

让我们来看看重新排序任务的几个深度学习模型。

二重奏模型

巴斯卡尔·米特拉等人。艾尔。提出了深度学习模型 Duet 用于重排序任务。该模型将查询和文档对中的单词嵌入作为输入,然后是交互层和密集层,以计算给定查询的文档的概率。这个模型可以在查询文档训练数据上进行训练,如基线方法一节中所讨论的。

来源:学习使用本地和分布式文本表示进行网络搜索

伯特为排名

戴等。艾尔。提出扩展 BERT 模型进行任务重排序。它建议采用预先训练的 BERT 模型,并在查询文档训练数据上微调该模型。此微调模型可用于重新分级任务。

来源:使用上下文神经语言建模进行更深入的文本理解

结论

我们讨论了一种用于处理大规模语义文本匹配问题的端到端深度学习方法。我们还使用了 Kaggle 的识别 Quora 重复问题问题来说明本文讨论的技术的样本代码。

带代码的笔记本在 GitHub 有售。

我们还就此主题举办了一场网络研讨会。同样的录像可以在 youtube 上观看

供应链优化的深度学习|使用自动化机器人分拣包裹

原文:https://towardsdatascience.com/deep-learning-for-supply-chain-optimization-using-automated-robots-to-sort-packages-f29123d889de?source=collection_archive---------37-----------------------

我是如何制造一个自主机器人来帮助你更快地获得在线订单的

自动化是过去几年的主要趋势。现在,随着电子商务需求的不断增长,亚马逊每天处理 576 万份订单(仅在美国!),供应链行业面临一个新的优化问题。

分拣是交付过程中的一个重要步骤,传统上,这一过程是手工进行的。在谷歌上简单搜索“包裹分拣工作,你会看到成千上万家公司为此招聘人力。不用说,手工分拣速度慢,效率低,还会导致延误。在像供应链这样快节奏的行业中,每一分钟的延迟都会导致公司收入的损失。

来源:“ UPS 的 200 亿美元问题:运营停滞在 20 世纪

因此,公司正在寻找更快、更有效和更可靠的系统。这个问题可以用机器学习来解决。

因此,在冠状病毒封锁期间,我无法进入电子产品和五金店,我决定用我在家里能找到的任何废料制作自己的“自动分拣机”。这台机器能够根据包裹的最终目的地将它们分类。

该视频展示了项目的运作。

它是如何工作的!

  • 传送带上方放置了一个摄像头。
  • 照相机将包裹的快照发送到计算机。
  • 计算机处理输入,并对图像运行深度学习算法(更快的 RCNN)。
  • 深度学习模型确定包裹的合适目的地,并自动分拣。

技术方面的东西

  • 我用 Tensorflow 对象检测 API 训练了一个基于更快 RCNN 架构的深度学习模型。

更快的 RCNN 架构

  • 我在自己的数据集上通过点击数百张要分类的包裹照片来训练它。
  • 在使用 Tensorflow 对象检测 API 训练模型之后,OpenCV 使用训练期间生成的推理图和 labelmap 执行分类任务。

从网络摄像头获取视频输入的 OpenCV 脚本

作者照片-深度学习模型对包的分类

  • 这就是模型对包进行分类的方式。
  • 一旦被识别,算法就向 Arduino 微控制器发送信号。
  • 微控制器向适当的伺服电机发出信号,使其迅速进入,并将包裹分拣到所需的目的地。

结论

为了提高速度和效率,减少对手工劳动的依赖并最大限度地提高利润,各行业都在寻求供应链中每一步的自动化。随着世界变得越来越依赖在线服务,机器人,自动驾驶卡车,增强现实,仓库自动化,只是未来技术的一部分,这些技术将改变我们所知的电子商务的面貌。

参考资料:

Tensorflow 对象检测 API

使用 PyTorch 对表格数据进行深度学习

原文:https://towardsdatascience.com/deep-learning-for-tabular-data-using-pytorch-1807f2858320?source=collection_archive---------3-----------------------

关于多类分类问题

信号源

深度学习已被证明在计算机视觉、自然语言处理、信号处理等许多领域具有开创性。然而,当涉及到由分类或数字变量组成的更结构化的表格数据时,传统的机器学习方法(如随机森林,XGBoost)被认为表现更好。正如所料,神经网络已经赶上来了,并且在许多情况下表现得一样好,有时甚至更好。

用表格数据执行深度学习的最简单方法是通过 fast-ai 库,它给出了非常好的结果,但对于试图了解幕后真正发生了什么的人来说,它可能有点太抽象了。因此,在本文中,我介绍了如何构建一个简单的深度学习模型来处理 Pytorch 中关于多类分类问题的表格数据。

Pytorch 的一点背景

Pytorch 是一个流行的开源机器库。它和 Python 一样使用和学习简单。使用 PyTorch 的其他一些优势是它的多 GPU 支持和自定义数据加载器。如果你对基础知识不熟悉或者需要复习,这里是一个很好的起点:

密码

如果你想遵循代码,这是我的 Jupyter 笔记本:

[## 动物 _ 庇护所 _ 结果

使用 jovian.ml 共享](https://jovian.ml/aakanksha-ns/shelter-outcome)

资料组

我使用了收容所动物结果 Kaggle 竞赛数据:

[## 收容所动物结果

帮助改善收容所动物的结果

www.kaggle.com](https://www.kaggle.com/c/shelter-animal-outcomes/data)

这是一个表格数据集,在训练集中包含大约 26k 行和 10 列。除了DateTime之外的所有列都是分类的。

来自训练集的样本数据

问题陈述

给定庇护所动物的某些特征(如年龄、性别、颜色、品种),预测其结果。

有 5 种可能的结果:Return_to_owner, Euthanasia, Adoption, Transfer, Died。我们期望找到一个动物的结果属于 5 个类别中的每一个的概率。

数据预处理

尽管这一步骤很大程度上取决于特定的数据和问题,但仍有两个必要的步骤需要遵循:

摆脱Nan价值观:

Nan(非数字)表示数据集中缺少值。该模型不接受Nan值,因此它们必须被删除或替换。

对于数字列,处理这些值的一种流行方法是用 0、均值、中值、众数或其他剩余数据的函数来估算它们。缺失值有时可能表示数据集中的基础要素,因此人们通常会创建一个与缺失值列相对应的新二进制列来记录数据是否缺失。

对于分类列,Nan值可以认为是自己的类别!

编码所有分类列的标签:

因为我们的模型只能接受数字输入,所以我们将所有的分类元素转换成数字。这意味着我们不用字符串来表示类别,而是用数字。选择代表类别的数字应在 0 到该列中不同类别总数(包括Nan)的范围内。这是为了当我们为该列创建分类嵌入时,我们希望能够索引到我们的嵌入矩阵中,该矩阵对于每个类别都有一个条目。下面是一个简单的标签编码示例:

我使用了 scikit-learn 库中的[LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html)类来编码分类列。您可以定义一个定制的类来完成这项工作,并跟踪类别标签,因为您也需要它们来编码测试数据。

编码目标的标签:

如果目标有字符串条目,我们还需要对其进行标签编码。此外,确保维护一个将编码映射到原始值的字典,因为您将需要它来计算模型的最终输出。

庇护所结果问题的特殊数据处理:

除了上述步骤,我还对示例问题做了一些处理。

  1. 删除了AnimalID栏,因为它很独特,对训练没有帮助。
  2. 删除了OutcomeSubtype列,因为它是目标的一部分,但我们没有被要求预测它。
  3. 删除了DateTime列,因为记录输入时的确切时间戳似乎不是一个重要的特性。事实上,我最初试图将它拆分成单独的月和年列,但后来意识到将该列一起删除会得到更好的结果!
  4. 删除了Name列,因为它有太多的Nan值(缺少 10k 以上)。此外,它似乎不是决定动物结果的一个非常重要的特征。

注意:在我的笔记本中,我堆叠了训练和测试列,然后进行了预处理,以避免必须根据测试集上的训练集标签进行标签编码(因为这将涉及到维护一个编码标签到实际值的字典)。在这里进行堆叠和处理是没问题的,因为没有数字列(因此没有进行输入),并且每列的类别数量是固定的。在实践中,我们绝不能这样做,因为这可能会将测试/验证集中的一些数据泄露给训练数据,并导致对模型的不准确评估。例如,如果您在类似age的数字列中有缺失值,并决定用平均值对其进行估算,则平均值应仅在训练集(非堆叠训练-测试-有效集)上计算,并且该值也应用于估算验证和测试集中的缺失值。

范畴嵌入

分类嵌入与自然语言处理中常用的单词嵌入非常相似。基本思想是让列中的每个类别都有一个固定长度的向量表示。这与一次性编码的不同之处在于,我们不是使用稀疏矩阵,而是使用嵌入,为每个类别获得密集矩阵,其中相似类别在嵌入空间中具有彼此接近的值。因此,这个过程不仅节省了内存(因为对包含太多类别的列进行一键编码确实会破坏输入矩阵,而且它是一个非常稀疏的矩阵),而且还揭示了分类变量的内在属性。

例如,如果我们有一列颜色,我们为它找到嵌入,我们可以期望redpink在嵌入空间中比redblue更近

分类嵌入层相当于每个独热编码输入之上的额外层:

来源:分类变量的实体嵌入研究论文

对于我们的 shelter outcome 问题,我们只有分类列,但我会将值少于 3 的列视为连续列。为了决定每列嵌入向量的长度,我从 fast-ai 库中取了一个简单的函数:

Pytorch 数据集和数据加载器

我们扩展了 Pytorch 提供的[Dataset](https://pytorch.org/docs/stable/_modules/torch/utils/data/dataset.html#TensorDataset)(抽象)类,以便在训练时更容易访问我们的数据集,并有效地使用DataLoader模块来管理批处理。这包括根据我们的特定数据集覆盖__len____getitem__方法。

因为我们只需要嵌入分类列,所以我们将输入分成两部分:数字和分类。

然后,我们选择批量大小,并将其与数据集一起提供给数据加载器。深度学习一般是批量进行的。DataLoader帮助我们有效地管理这些批次,并在训练前重组数据。

要进行健全性检查,您可以遍历创建的数据加载器来查看每个批处理:

模型

我们的数据被分成连续的和分类的部分。我们首先根据之前确定的大小将分类部分转换为嵌入向量,并将它们与连续部分连接起来,以馈送到网络的其余部分。这张图片展示了我使用的模型:

住房结果模型

培养

现在我们在训练集上训练模型。我已经使用了 Adam 优化器来优化交叉熵损失。训练非常简单:迭代每一批,向前传递,计算梯度,梯度下降,根据需要重复这个过程。可以看看我的笔记本了解代码。

测试输出

由于我们对找到测试输入的每个类的概率感兴趣,所以我们对模型输出应用了 Softmax 函数。我还提交了一个 Kaggle 来看看这个模型的表现如何:

我们做了很少的功能工程和数据探索,并使用了非常基本的深度学习架构,但我们的模型比大约 50%的解决方案做得更好。这表明这种使用神经网络对表格数据建模的方法非常强大!

参考文献:

  1. https://www . usfca . edu/data-institute/certificates/fundamentals-deep-learning—第 2 课
  2. https://jovian.ml/aakashns/04-feedforward-nn

时间序列分类的深度学习(InceptionTime)

原文:https://towardsdatascience.com/deep-learning-for-time-series-classification-inceptiontime-245703f422db?source=collection_archive---------1-----------------------

用于时间序列分类的新深度学习(类 GoogleNet)模型。

图 InceptionTime 的初始模块。

索引

  1. 动机
  2. 用于时间序列分类的机器学习
  3. 时间序列分类的最佳深度学习实践:InceptionTime
  4. 了解初始时间
  5. 结论

1。动机

时间序列数据一直是金融服务的主要兴趣,现在随着实时应用的兴起,零售和编程广告等其他领域正在将注意力转向时间序列数据驱动的应用。在过去几年中,云服务的几个主要参与者,如 Apache Kafka 和 Apache Spark,已经发布了处理时间序列数据的新产品。因此,理解机器学习(ML)在这个新兴领域中的作用和潜力是非常有趣的。

在这篇文章中,我通过跟踪[ 2 作者的一系列出版物,讨论了关于深度学习的时间序列分类(TSC)的(非常)最新发现。

2。用于时间序列分类的机器学习

定义问题:

TSC 是 ML 对学习如何给时间序列分配标签感兴趣的领域。更具体地说,我们对训练 ML 模型感兴趣,当输入一系列按时间顺序索引的数据点(例如,金融资产的历史数据)时,它输出标签(例如,资产的行业部门)。

更正式的说法是,让【t8(x,y)】成为一个训练实例,带有 T 观察值 (X,… ,Xᵀ)≡ X (时间序列)和一个离散类变量 y ,它取 k 个可能值(标签)。一个数据集 S 就是一组 n 这样的训练实例: S= { (X₍₁₎,y₍₁₎),…,(X₍ n₎,y₍ n₎)) } 。对时间序列数据进行分类的任务包括在 S 上学习分类器,以便从可能的输入空间 {X} 映射到标签 {y,…,yᵏ} 上的概率分布。

我们真的需要 DL 吗?

提醒我们自己 DL 只不过是一套解决问题的工具,这一点很重要,尽管 DL 可能非常强大,但这并不意味着我们应该盲目地将 DL 技术应用于每一个问题。毕竟,训练和调整神经网络可能非常耗时,所以测试其他 ML 模型的性能,然后寻找任何潜在的缺点总是一个好的做法。

通常,问题的性质是由数据本身决定的;在我们的例子中,选择处理和分类时间序列的方式高度依赖于数据的长度和统计。也就是说,让我们运行一个快速量纲分析来估计我们问题的复杂性。

假设我们希望为我们的 TSC 问题学习一个最近邻分类器(这在文献中很常见)。现在给定一个长度为 Tn 时间序列的数据集,我们必须为 ⁿC₂=n(n-1)/2 唯一对计算某种距离度量。此外,为了找到两个时间序列 X₍₁₎X₍₂₎ 之间的“最佳距离”,我们必须为每一对唯一的训练实例计算 T×T 逐点距离矩阵mʲᵏ=(x₍₁₎ʲ-x₍₂₎ᵏ),然后寻找优化我们的目标函数的路径。正如在[ 3 中所解释的,文献中有几种针对这种设置的优化算法,它们都具有复杂度 O(n ⋅ Tᶜ) ,其中 c=3 或 4 。显然,时间序列的长度真的会损害计算速度。然而,对于某些类型的数据,这个问题可以在不挖掘复杂的机器学习模型(如深度神经网络)的情况下得到缓解。

在信号处理中,通过将信号分解成一系列“基本”信号来分析复杂信号,称为傅立叶模式。例如,下面的方波可以用三个不同频率的正弦信号 (f₁、f₂、f₃)=(ω、3ω、5ω) 来近似,对于某个恒定角频率 ω

图 2:方波的傅立叶级数展开(红线)。这里我只介绍前三种模式(蓝色虚线)和它们的加法(绿线)。希望不难看出,通过增加下一个模式,级数很快收敛到方波。

通过对这些信号进行线性求和,我们可以重建原始信号:

方波(t)= w⋅sin(f₁t)+w⋅sin(f₂t)+w⋅sin(f₃t)+…

其中系数 (W,W,W ) = (1,1/3,1/5) 指定每个模式对方波贡献的权重

现在考虑一个数据集,在该数据集内,最初由一系列 T 时间有序数据点表示的任何时间序列也可以由三个基本频率模式所跨越的空间中的权重向量来表示:

X=(X,…,Xᵀ )W = (W,w,w,…)。

从我们的时间序列数据的“时间”表示到“频率”表示被称为傅立叶变换,虽然傅立叶空间在理论上是无限维的(而不是三维的),但我们可以应用各种近似技术将傅立叶级数截断到有限维。最重要的是,我们可以将时间序列数据的 T 维表示减少到多个维度(在傅立叶空间),这使得我们的分类问题在计算上是可跟踪的。总的来说,我们可以在数据预处理阶段应用傅立叶变换,以将输入时间序列转换成权重向量,然后继续构建我们的分类模型(例如,1-最近邻分类器)。使用这种“行为良好”的时间序列,我们可以在不使用 DL 的情况下实现高性能。

现在,前述处理方法假设任何输入信号都可以用基本(谐波)函数的傅立叶级数来近似。然而,许多现实世界的时间序列数据是如此嘈杂(如金融数据),不允许这样一个优雅的分解(或任何形式的数学预处理)。正是针对这种类型的数据,DL 前来救援:在处理非结构化噪声数据时,让模型自己学习如何处理时间序列数据是一个更有前途的解决方案。

3。TSC 的最佳 DL 实践:开始时间

迄今为止,TSC 有两种最先进的 DL 型号。最古老的模型称为 HIVE-COTE [ 4 ],它基于最近邻算法和动态时间弯曲相似性度量。尽管该算法在基准数据集[ 5 ]上取得了优异的性能,但其时间复杂度为 O(n ⋅ T ⁴) 。最近[ 6 ]的作者介绍了一种深度卷积神经网络(CNN),称为 InceptionTime,它不仅比 HIVE-COTE 的精度更高,而且速度也快得多。InceptionTime 的高精度及其可扩展性使其成为产品开发的完美候选!

为此,让我们介绍一下 InceptionTime 最重要的组件,以及这些组件是如何在 Keras 中实现的。

3.1 输入层

一般来说,时间序列 X 的每个数据观测值 Xʲ (j=1,…,T) 可以是一个或多个数据测量值的列表,即 Xʲ = ( X₁ʲ,…,X_m ʲ ) 对于 m 数据测量值,都是在第 j 时刻进行的。例如,一个质点在三维空间中运动的速度由三个空间分量组成: V =(V₁,V₂,V₃) 。跟踪粒子的速度达 T 秒,每秒一次观测,相当于收集一系列数据:( V ,…,vᵀ)。

定义 1:-维多元时间序列【MTS】x =(x,…,x【ᵀ】T 有序元素 X

定义二:一个长度为 T 的单变量时间序列 X 简单来说就是一个 m=1 的 MTS,即xʲ∈ℝ和 X**

就像在图像分类问题中一样,我们可以将输入 MTS 视为一个形状数组( 1,T,m) ,其中 m 表示通道的数量(深度)。事实上,抑制输入的宽度并直接使用 input_shape = (T,m)是很方便的。

3.2 初始模块

InceptionTime 的主要构件是初始模块,如下图所示:

图 InceptionTime 的初始模块。框中的第一个数字表示内核大小,而第二个数字表示步幅大小。“(S)”指定填充类型,即“相同”。

这包括以下几层:

  • 一个瓶颈层,用于减少输入的维度(即深度)。这减少了计算成本和参数数量,加快了训练速度,提高了泛化能力。
  • 瓶颈的输出被馈送到核大小为 10、20 和 40 的三个一维卷积层
  • 初始模块的输入也通过大小为 3 的最大池层,并依次通过瓶颈层
  • 最后一层是深度级联层,其中步骤 2 的四个卷积层的输出沿着深度维度被级联。

所有层(不包括连接层)都有步距 1 和【相同】填充。此外,所有的卷积层都有 32 个 T4 过滤器。

Keras 实现

3.3 盗梦空间网络

InceptionTime 的网络架构与 GoogleNet 的[ 7 ]高度相似。具体而言,该网络由一系列初始模块组成,其后是一个全局平均池层和一个具有 softmax 激活功能的密集层。

图 4:用于时间序列分类的初始网络。

然而,InceptionTime 在其网络层中引入了一个额外的元素:剩余连接在每三个初始模块中。

图 5:初始网络中的剩余连接。

Keras 实施

3.4 初始时间:用于 TSC 的神经网络集成

正如[ 6 ]中所解释的,事实证明,单个初始网络在准确性方面表现出很大的差异。这可能是因为与随机权重初始化以及随机优化过程本身相关联的可变性。为了克服这种不稳定性,提出的最先进的 InceptionTime 模型实际上是由 5 个初始网络组成的,每个预测都被赋予一个均匀的权重(有关 TSC 的深度神经网络集成的更多信息,请参见[ 8 )。模型的完整实现可以在 Github 上找到。

4。了解开始时间

正如前面提到的,InceptionTime 主要是受计算机视觉问题的 CNN 的启发,因此,我们希望我们的模型以类似的方式学习功能。例如,在图像分类中,底层的神经元学习识别低级(局部)特征,如线条,而高层的神经元学习检测高级(全局)特征,如形状(如眼睛)。同样,我们期望 InceptionTime 的底层神经元能够捕捉到一个时间序列的局部结构,比如直线和曲线,顶层神经元能够识别各种形状模式,比如“山谷”和“山丘”。

图 6:过滤器中神经元的感受野。

神经元所依赖的输入信号区域被称为该特定神经元的感受野。在物体识别中,更大的感受野用于捕捉更多的上下文。因此,在处理非常长的时间序列数据时,选择更大的感受域是很自然的,这样我们的认知时间将学会检测更大的模式。

5.结论

TSC 的一个重要方面是时间序列的长度,因为这可能会降低训练速度。虽然有各种数学处理方案可以用来解决这样的问题,但 InceptionTime 是 TSC 的主要算法,特别是对于长时间的噪声时间序列数据。

InceptionTime 是一组 CNN,它学习识别时间序列数据集中的局部和全局形状模式(即低级和高级特征)。不同的实验 6 表明 InceptionTime 的时间复杂度与训练集大小和时间序列长度均呈线性增长,即 O(n ⋅ T)!总的来说,InceptionTime 将 TSC 问题与图像分类问题放在了同一立足点上,因此探索其在工业领域的不同应用是令人兴奋的。

在接下来的一篇文章中,我将讨论我如何使用 InceptionTime 根据不同的属性(如行业/类别、位置和绩效)对金融资产进行分类和聚类。

参考

[ 1 ] 通过错误传播学习内部表示

2时间序列分类的深度学习:综述

[ 3 ] 伟大的时间序列分类烘焙:对最近提出的算法的实验评估。扩展版

[ 4 ] HIVE-COTE:用于时间序列分类的基于变换的集成的层次投票集合

5UCR 时间序列分类存档

[ 6 ] 开始时间:寻找 AlexNet 进行时间序列分类

[ 7 ] 用卷积更深入(GoogleNet)

[ 8 ] 用于时间序列分类的深度神经网络集成

(深入)从 Kaggle 竞赛中学习

原文:https://towardsdatascience.com/deep-learning-from-kaggle-competitions-e0992fd4352e?source=collection_archive---------56-----------------------

为什么是 Kaggle?

几个月前,当我参加 SIIM-ISIC 黑素瘤分类竞赛时,我开始认真使用 Kaggle

我认为,最初的原因是我想要一种严肃的方式来测试我的机器学习(ML)和深度学习(DL)技能。当时,我正在为 Coursera 医学专业学习,我对将 DL 应用于医学能够实现什么很感兴趣(现在仍然如此)。我还在读埃里克·托普写的美丽的书:《深度医学》,书中充满了有趣的想法。

几年前,我开了一个 Kaggle 账户,但还没做过什么大事。然后,我发现了黑色素瘤挑战,这似乎是一个用真实数据开始一项艰巨任务的好方法。

因此,我开始致力于比赛,我陷入了比赛。我认为这更容易。

我所学内容的总结。

我学会掌握的第一件事是如何高效地读取许多图像,而不需要 GPU(或 TPU)等待。

事实上,在一开始,我试图在 2-GPU 机器上训练我的第一个模型,训练似乎太。GPU 利用率非常低,大约 20%。为什么?

因为我正在使用 Keras ImageDataGenerator ,从目录中读取图像。看了 Kaggle 上的几个讨论(是的,这是一个重要的建议:看讨论)我发现一个非常有效的方法是将图片(最终经过预处理,调整大小)打包成 TFRecord 格式 的文件。通过这种方式,我已经能够将 GPU 利用率提高到 90%以上。

是的,我知道随着 TF 2.3 的到来,预处理和数据加载功能将会有所改进(参见:imagedatasetfromdirect),但是如果您需要进行大量的图像(或数据)预处理,那么您应该考虑将结果打包成 TFRecord 格式。

第二件重要的事情是使用一个现代预训练的 ConvNet

再次,从 Kaggle 的讨论中,我发现了效率网家族。这些是卷积网络,在 Imagenet 上预先训练,由谷歌研究人员在 2019 年提出。这些 CNN 非常高效,如果与旧 CNN 相比,你可以用更少的计算能力获得更高的精确度。令人惊讶的是,你可以简单地使用一个高效网络作为卷积层(特征提取器)来提高精确度。

(来源:谷歌 AI 博客,https://AI . Google blog . com/2019/05/efficient net-improving-accuracy-and . html)

第三件事是开发一种健壮的交叉验证方法。像往常一样,你希望有一个尽可能大的训练集。但是,与此同时,您需要足够大的验证集,以便对训练模型在看不见的数据上的性能(准确性、AUC 等)有一个公平的想法。如果验证集太小,您对分数的估计很大程度上取决于您在训练集和验证集之间划分的方式。唯一可行的方法是采用健壮的交叉验证(CV)模式。例如,我经常使用具有 5 个折叠的 CV:训练集被分成 5 个折叠,并且我重复训练(对于整个历元数)五次,每次取训练集的五分之一进行验证。对于每一次折叠,我估计最终的准确度(或者你选择的任何度量标准),最好的估计(在验证阶段)是平均值。如果训练集和测试集中的分布是相同的,你应该得到一个 CV 分数,这是对公开分数 LB 的一个很好的估计(你也希望得到最终的私有 LB 分数)。

第四:学会使用 TPU 。TPU 是由 Google 专门设计和开发的专用(ASIC)处理器,用于处理神经网络。如果你知道怎么做,你可以在 TPU 上使用 Tensorflow,以比使用 2-GPU 机器快十倍的速度训练你的模型。更好的是能够在 1/10 的时间内测试模型中的变化,以及它们在准确性方面的结果。这样你就不会因为等太久而感到无聊,也可以做更多的检查。在 Kaggle 上,你每周有 30 个小时的 TPU 时间是免费的(目前唯一的缺点是他们还不支持 TF 2.3,但我相信不会花太长时间来支持它)。

一般来说,你应该知道如何在多 GPU 和 TPU 机器上训练。这并不困难,即使乍一看配置代码看起来有点晦涩。

第五:温柔对待自己的学习速度。

学习率(LR)可能是最重要的超参数。但是,如果你阅读一本关于深度学习的介绍性书籍,你不会找到任何关于你可以采用的策略的详细描述,以使用 LR 来充分利用你的数据。

一些快速的考虑:如果你正在进行迁移学习(参见 EfficientNet ),你可以在不冻结卷积层的情况下开始训练,但之后你应该非常小心地采用非常小的学习速率,以避免来自“未训练的”分类尾部的梯度破坏预训练卷积头的权重。然后你应该随着时代逐渐提高学习速度。但是,当损失的改善开始减少时,你应该开始降低学习率。很难把它做好。通常,在 Kaggle 比赛中,我看到它采用了时变学习率,使用 Keras LearningRateScheduler。

更多细节请见https://www.jeremyjordan.me/nn-learning-rate/

我一直在使用的代码示例可以在这里找到:

https://github . com/luigisaetta/Diabetic-Retinopathy/blob/master/Diabetic-Retinopathy-512-Classification-copy 6 . ipynb

完整的例子。

我已经准备了一个相当完整的例子,使用的数据来自一个旧的竞争:糖尿病视网膜病变检测。你可以在我的 Github 仓库中找到代码:https://github.com/luigisaetta/diabetic-retinopathy

我有:

  • 预处理所有图像,将尺寸缩小到 512x512
  • 应用一个过滤器,高斯模糊,增强细节显示博士的迹象
  • 将处理后的图像打包到 TFRecord 文件中
  • 开发了一个 CNN 模型,使用高效的网络 B4 进行五级分类(根据比赛要求)
  • 应用前面详述的所有内容

您可以在 Github 存储库中找到重现结果的所有细节,数据集(带有 TFRecord 文件)可在 ka ggle:https://www.kaggle.com/luigisaetta/tfrecord512上找到。

一些结论。

经过大约 24 小时的训练,我的最佳模型显示出了 0.856 的 CV 精度。

下图显示了其中一个 CV 折叠的准确度随着时期的增加而增加(对于其他折叠,情况类似)。

图:acc。vs 时代(按作者)。

但是,有趣的是,最终的提交(你可以在 Kaggle 的封闭比赛中使用延迟提交)获得了 0.79369 的私人 LB 分数。这个分数会让我排在第 14 位。

(作者)。

嗯,这并不意味着我已经是一个大师,但可以肯定的是,这是一个证明,与今天的技术和技巧,这是更容易得到的结果,需要几个月的辛勤工作五年前。关于这一说法,仅给出一个细节:五年前,效率网不可用(它们已在 2019 年发表)。

这就是我们所说的:进步。

ai4 医学。

我真的认为人工智能和人工智能可以为发展一个更美好的世界做出巨大贡献的一个领域是医学。它不仅应用了计算机视觉领域的结果(人工智能支持的诊断)。特别是在最不发达国家,那里仍然有太多的人遭受疾病之苦,如果及时正确诊断,这些疾病是可以治愈的。

正如我所说,这并不容易。超过 3000 名参与者,最后一个惊喜是:私立学校与公立学校非常不同。

我以前 20%的成绩结束了比赛,这对于一个 Kaggle 初学者来说已经不错了。

原载于 2020 年 8 月 24 日https://luigisaeta . it

深度学习的硬件:了解你的选择

原文:https://towardsdatascience.com/deep-learning-hardware-know-your-options-9e95026b5d5e?source=collection_archive---------1-----------------------

在部署神经网络时,GPU(图形处理单元)之外还有选项,即 FPGA (现场可编程门阵列)。在深入研究 FPGAs 及其实现之前,最好先了解一下 GPU 架构,以及为什么 GPU 是神经网络的主要组成部分。

Tensorflow 等流行的库使用 CUDA(计算统一设备架构)在 GPU 上处理数据,利用它们的并行计算能力。这项工作被称为 GPGPU(通用 GPU)编程。它已经适应了需要至少数千次算术运算的深度学习模型。

如下所示,深度卷积神经网络要求滤波器在像素区域上滑动,同时在每次迭代时输出加权和。对于每一层,这一过程重复数千次,不同的过滤器大小相同。从逻辑上讲,深度模型计算量变大,GPU 派上了用场。

来源:Hinton G.E .等人通过研究论文;第一层包含 253,440 个权重,因此至少有那么多计算

Tensorflow 可以构建在 CUDA 的基础上,这使得最终用户无需实施并行代码和理解其芯片的架构。它的便利性和高度优化使它非常适合广泛使用。

FPGAs 早期没有提供这样一个方便的解决方案,使用它们需要对硬件如何工作有深入的理解。但是最近的进展使它们变得更容易接近,以后还会有更多的进展。

概观

本文的内容假设对不同的硬件模型如何工作知之甚少或一无所知。它包括以下内容:

  • GPU、CPU 和 CUDA
  • FPGAs 的优势与设计
  • HDL 作为一种 FPGA 部署方法
  • HLS 作为一种 FPGA 部署方法
  • 使用 LeFlow 的 FPGA 部署
  • LeFlow 的优化特性

为什么 GPU 有时候比 CPU 好?

CPU(中央处理器)设计用于串行操作并支持高级逻辑。这反映在他们的设计中,包含更少的内核和更多的高速缓存以快速获取复杂的指令。

资料来源:Elkaduwe 等人。via 研究论文;一个字母决定一切

GPU、拥有数百个更小的内核用于简单计算,因此与 CPU 相比具有更高的吞吐量。

来源:自我内核< < <网格,1 > > > () 符号表示并行进程运行的数量,等于变量网格的大小。运行名为内核的函数。

CUDA 通过将 GPU 的众多内核抽象成块来访问它们。每个块包含多达 512 个可访问的线程,可能有 65 535 个块能够同时运行。每个线程执行一个短程序,问题是它可以与其他线程并行运行。 Tensorflow 利用这种模式来提高处理能力,通常会同时运行数百到数千个线程

要了解更多关于使用 CUDA 的信息,请访问 Nvidia 的开发者博客 或查阅《CUDA 示例》一书。

神经网络硬件

Tensorflow 分为两个部分:库和运行时。

库是计算图(神经网络)的创建,运行时是它在某个硬件平台上的执行。

首选平台是 GPU,但也有一个替代方案:FPGAs。

为什么要用 FPGAs?

FPGAs 可以产生具有数千个存储单元的电路来进行计算,因此它们的工作方式类似于 CUDA 中的 GPU 及其线程。FPGAs 具有自适应架构,支持额外优化以提高吞吐量。因此,可能的计算量使 FPGAs 成为 GPU 的可行解决方案。

相比之下,FPGAs 功耗较低,最适合嵌入式应用。它们也是汽车 ADAS(高级驾驶辅助系统)等安全关键操作的公认标准。

来源:福特汽车公司 via 维基媒体(CC);FPGAs 安全关键任务的理想应用:碰撞报警系统

此外,FPGAs 可以实现自定义数据类型,而 GPU 受到架构的限制。随着神经网络以多种方式转变并延伸到更多行业,FPGAs 提供的自适应能力非常有用。

现在你一定想知道,什么是 FPGAs?

FPGA(现场可编程门阵列)是一种可定制的硬件设备。它可以被认为是浮动逻辑门的海洋。一个设计师走过来,用一种硬件描述语言* (HDL),比如 Verilog 或 VHDL,写下一个程序。该程序规定了连接方式以及如何使用数字元件实现连接。HDL 的另一个词是 RTL (寄存器传输级)语言。***

FPGAs 很容易被发现,找一个超大的 Arduino。

来源:保罗马蒂亚斯 via 维基媒体(CC);altera DE2–115 板,可使用的众多 FPGAs 之一

开玩笑,它们有各种形状和大小。

使用类似于编译器的软件,HDL 被合成(找出使用什么门),然后被路由(将部件连接在一起)以形成优化的数字电路。这些工具(HDL、综合、路由、时序分析、测试)都包含在一个软件套件中,有些包括 Xilinx 设计工具和 Quartus Prime。

目前,模型使用 GPU 进行训练,但随后部署在 FPGA 上进行实时处理

那我们为什么不用 FPGAs 来代替呢?

对于 FPGAs 来说,棘手的部分是实现用 Python 等高级语言编写的 ML 框架。 HDL 本身并不是一个编程平台,它是用来定义硬件组件(如寄存器和计数器)的代码。一些 HDL 语言包括:Verilog,VHDL。

下面显示的是用于创建串行位检测器的一些代码片段。

如果你不熟悉它,试着猜猜它是做什么的。

来源:Self

完成了吗?即使你盯着它看一会儿,它也不明显。

大多数情况下,FSM(有限状态机)用于将任务分解成具有输入相关转换的状态。所有这些都是在编程之前完成的,以确定每个时钟周期电路将如何工作。然后这个图,如下所示,被转换成 HDL 代码块。

来源:Maggyero via 维基媒体(CC);可能的 FSM 图

回到主题:主要的一点是,没有直接的翻译将 Python 中的一个循环转换成 Verilog 中的一束电线。

考虑到设计的复杂性,很难对其进行进一步的优化调试。没有像 CUDA 中那样的抽象来简化过程,在 CUDA 中可以选择和修改线程。

那么我们应该坚持使用 GPU 吗?

不,FPGAs 并非一无是处。

解决编程问题的一种方法是使用 HLS (高级综合)工具,如 LegUp 来在 Verilog 中生成程序进行部署。HLS 工具允许设计者避免从头开始编写 HDL,而是使用更加直观的算法式编程语言(C)。

HLS 工具抽象出硬件级设计;类似于模型运行时 CUDA 如何自动设置并发块和线程。**

HLS 工具需要 C 代码作为输入,该输入将映射LLVM IR (中间表示)以供执行。这些工具用于将程序描述转换成硬件实现。**

它们在 FPGA 设计中的作用如下所示。

来源:Greg S. via 佛罗里达大学幻灯片HLS 工具产生 HDL* ,允许寄存器传输(RT)合成成数字电路,最终部署在 FPGA 上***

关于 LLVM IRs 的更多信息

LLVM 不是首字母缩写,是构造* 类汇编指令 (IRs)的。这些程序对于 HLS 工具来说更容易处理,并可用于为 FPGA 创建可综合的代码。***

IRs 用于通用格式描述源代码,允许各种程序使用。**

要了解更多关于 LLVM 和 IRs 的信息,请参考Chisnall 博士的幻灯片

来源:戴维斯·奇斯纳尔博士 via 讲稿;从 LLVM IR 到 x86 架构汇编指令的转换,显然两种格式非常相似证明 IR 的适应性****

回到 FPGAs 的问题

主要的问题是将程序和为 Python 编写的库转换成 C 语言,以便 HLS 工具运行。目前 C 语言不支持 Tensorflow,所以这个解决方案非常困难。显然,布局和创建硬件的要求是在深度学习中使用 FPGAs 的一大障碍**

我们的英雄勒弗洛

来源:Daniel H.N .等人通过研究论文LeFlow pipeline 显示它是 LLVM IR 和 HLS 之间的中介

LeFlow Toolkit 允许工程师使用 Python 设计、训练和测试他们的模型,然后将其直接部署到 FPGA 中使用。 LeFlow 通过允许 HLS 工具与 PythonTensorflow 兼容来简化设计过程,充当适配器****

该软件由不列颠哥伦比亚大学 ECE(电气和计算机工程)系的研究人员 T21 设计,他们是丹尼尔·h·诺罗尼亚和史蒂文 J.E 威尔逊。

以下部分详细介绍了 LeFlow 如何与 Tensorflow 和 FPGA 集成,如果您只对实现中的感兴趣,请跳过到:调优时间******

LeFlow 工具包如何与 Tensorflow 一起工作

为 Tensorflow 设计的 XLA(加速线性代数)编译器输出一个 LLVM IR。LeFlow 重组IR 和优化与 HLS 工具配合使用。****

在此基础上,HLS 工具完成了将 IR 转换为部署到 FPGAs 上的程序的所有工作,如部分所述:我们应该坚持使用 GPU 吗?

勒弗洛投入产出模型

LeFlow 将 IR 作为输入。算法 1 是 Tensorflow 加载两个浮点数的 IR。

来源:Daniel H.N .等人通过研究论文;输入到 LeFlow,需要重组。获取指向每个 float 的元素指针(第 5、6 行),解引用它们并加载(第 7、8 行)。

这个节目很难跟上,而且看起来很乱。勒弗洛会把它清理干净,然后换掉。

它的目标是创建全局变量,然后将它们映射为硬件接口的输入和输出。下图概述了 LeFlow 重新格式化并将 IR 通过 LegUp 后的合成电路。****

来源:Daniel H.N .等人通过研究论文;硬件实施所需的变量和设置由 LegUp、LeFlow 生产,必须易于识别变量

显然,硬件接口需要额外的模块和信号,如时钟、复位、内存和内存控制器。 LegUp 处理这些部件的创建,包括时钟的计时规范。****

转换 IR 以实现最佳执行

LeFlow 为 FPGA 寄存器设置了一个可变负载。这允许变量访问,以及当高级代码改变时自动电路修改变化主要在线 1、6、7* 明显。*****

来源:Daniel H.N .等人通过研究论文重组 LLVM IR ,为 HLS 合成做准备****

如算法 2 的改进 IR 所示,LeFlow 完成了它的工作,剩下的由 HLS 工具处理!

调音时间!

LeFlow 的一个有趣的特性是可以更换硬件。LeFlow 提供了展开和内存分区参数,这些参数在正确使用时会加速计算。这与 FPGAs 固有的低延迟相结合,使它们能够以极高的效率工作。****

最棒的是,这些参数可以在 Python 中指定,指令可以直接传递到电路级。

展开还是不展开

展开用于循环,是一种小心的平衡行为。想法是在每次迭代中进行多次计算(或复制)并采取更大的步骤。

这看起来与常规的 for 循环相同,但在硬件级别添加了更多组件,以在每个时钟周期(或循环迭代)执行更多计算。有关展开的更多信息,请参见 Keil 的用户指南

*****int sum = 0;for(int i = 0; i < 10; i+=2) sum += a[i]; sum += a[i+1];*****

从上面看,我们可以展开两倍,这意味着一次进行两次迭代,循环增加两步。

来源:Daniel H.N .等人通过研究论文将 32×32 输入图像上的 3×3 卷积的简化循环展开为 5 个 32×32 输出****

这利用了 FPGA 的并行性,工作起来更像 GPU ,显然每个示例的周期减少了 13%。

请记住,额外添加的硬件可能会导致效率低下或尺寸受限。

用内存分区分割它

LeFlow 管道中使用的 HLS 需要一个双端口 RAM(随机存取存储器)来存储值。

这是有问题的,因为 RAM 被设计成存储大量数据,但代价是非常慢。从其中提取值可能需要十倍的时钟周期。

幸运的是,FPGAs 包含许多其他独立的存储单元,因此 LeFlow 可以将其数据划分到多个唯一的存储点。在某种意义上,这类似于在处理器中添加更多的内核。它通过允许更多的指令同时执行来减少时钟周期****

假设任务是将两个大小为 8 的数组的元素相乘。在并行计算中,任务被分成组同时执行。循环分解意味着某一组步骤同时重复。****

使用内存分区可以提高 FPGAs 的运行效率。以下计划已经运行了八个时钟周期。

来源:Daniel H.N .等人通过研究论文加载两个数组的时钟周期分解****

在(a)中,没有内存分区,所以每个周期从每个数组中加载、相乘并存储一个元素。该过程继续,并花费八个周期*直到完成。*******

在(b)中,数组被循环划分到两个独立的存储器中。每个数组中的两个元素在每个周期被加载、相乘并存储。较大的块表示进程同时发生,尽管是在硬件的不同部分。这将其减少到六个周期****

在 c)中,数组被循环划分到四个独立的存储器中,并且减少到五个周期。每个周期加载、相乘并存储来自每个数组的四个元素**

在 Python 中使用 LeFlow

来源:Daniel H.N .等人通过研究论文实现一个 CNN* 。输入被分配为单个 32×32 图像(第 4 行),并且网络输出五个图像(每个图像应用了 3×3 滤波器;第 5 行)。***

一旦 LeFlow 设置正确,它只需运行一个设备选择行,无需任何额外的配置(如展开):

***with tf.device("device:XLA_CPU:0")***

它表示 XLA 编译器将用于生成 LLVM 并启动 LeFlow 转换过程。

尝试一下!

现在你是了解 LeFlow 工作原理的专家,也许 FPGAs 适合你。

Github 上有很多 LeFlow 及其具体安装的例子。丹尼尔·霍兰达(合著者之一)有关于 MNIST 数字识别源代码,所以拿起 FPGA 试一试吧!****

【深度学习】如何建立一个有情感的聊天机器人

原文:https://towardsdatascience.com/deep-learning-how-to-build-an-emotional-chatbot-part-1-bert-sentiment-predictor-3deebdb7ea30?source=collection_archive---------26-----------------------

实践教程

第 1 部分:伯特情绪预测器

《卫报》:一个机器人写了整篇文章。你害怕了吗,人类?

随着如今对话系统的成熟,我们可以下载并应用经过高级训练的聊天机器人,如 GPT-3DialoGPTPlatoOpenNMT 等。然而,与传统的聊天机器人不同,建立一个能够产生情感和积极反应的聊天机器人仍然是一个热门的研究领域。(类似于新闻中提到的人工智能,我们希望人工智能说一些积极的东西(例如,我的创造者告诉我说‘我为和平而来’))

此外,一个有情感的聊天机器人在商业中是非常可取的,例如改善客户服务。

在这两篇文章中,我将基于 HKUST 的论文 HappyBot:通过改善用户体验前瞻生成移情对话响应和我的尝试,介绍如何构建一个情感聊天机器人(基于深度神经网络的对话系统)。

这个想法是建立一个结合强化学习的对话系统,奖励积极的反应,惩罚消极的反应。

从技术上来说,这个任务涉及到建立深度学习模型,迁移学习(BERT),情感分析,强化学习,以及它们的实现(在 PyTorch 中),这些都是机器学习的热门话题。

用于情感分析的微调预训练 BERT 模型

在第 1 部分中,我们将以一种现代的方式构建一个情感预测器(使用来自预训练的 BERT 模型的迁移学习)。

回想一下,我们的目标是:建立一个结合强化学习的对话系统,奖励产生的积极响应,惩罚产生的消极响应。 有些我们需要一个“判官”来决定每个生成的句子的一个情感得分。 ( 感情分析 )

BERT 目前是 Google 在 2018 年发布的 NLP 任务中的显著模型之一。BERT 的关键思想是通过使用具有变换器架构的双向深度神经网络来构建自然语言的表示。BERT 模型经常被用作其他 NLP 任务的预训练模型。

要构建一个 BERT 情感预测器(PyTorch ),可以遵循这里的文章:第 2 部分:在语言可接受性(COLA)数据集的语料库上使用 PyTorch 进行文本分类的 BERT 微调教程。

斯坦福情感树库 v2 (SST2)

我们在任务中使用了斯坦福情感树库 v2 (SST2)数据集,可以在这里下载。SST2 数据集提供了 239,232 个句子,其中每个句子包含从 1 到 25(从最负面到最正面)的最多 6 个情感标签。我们计算了每个句子的平均情绪得分,并将其分为“负面”(得分≤10)、“中性”(得分≤10<和“正面”(得分> 16)。最终的训练/验证/试验数据分成 50/25/25。

构建 BERT 情感分类器

每个句子都将被分词,长度大于 160 个单词的句子将被删减。我们使用包装变压器中准备好的记号赋予器。

然后,我们从预训练的 BERT 模型建立多类(正面、中性和负面)分类模型(softmax 函数),损失函数作为交叉熵。注意,我们采用渐变裁剪来避免渐变爆炸。以下是训练/有效数据的结果:

模型训练表明一个历元已经足够,而更多的历元仅提高训练精度,但有效精度保持不变。

在模型训练之后,我们将我们的模型应用于具有 75.2%准确度的测试数据(类似于我们的模型训练) :

因为我们的预测是获得“正面”、“自然”和“负面”标签的概率,所以我们需要将其转换为 0-1 的情感分数作为奖励:

情绪得分= 1P(正)+ 0.5P(自然)+ 0*P(负)

其中输出 1 =高度正,0 =高度负)

以下是一些例子:

这一结果将在下一部分的情感对话系统中得到应用。

参考

  • Devlin,j .,Chang,M. W .,Lee,k .,& Toutanova,K. (2018 年)。Bert:用于语言理解的深度双向转换器的预训练。arXiv 预印本 arXiv:1810.04805。
  • 申洁敏、徐鹏、安德里亚·马多托和帕斯卡尔·冯。Happybot:通过提高用户体验前瞻性来产生移情对话响应。arXiv 预印本 arXiv:1906.08487,2019。
  • 理查德·索彻、亚历克斯·佩雷金、让·吴、贾森·庄、克里斯托弗·曼宁、和克里斯托弗·波茨。2013.情感树库语义合成的递归深度模型。2013 年自然语言处理经验方法会议论文集,第 1631-1642 页。

【深度学习】如何建立一个有情感的聊天机器人

原文:https://towardsdatascience.com/deep-learning-how-to-build-an-emotional-chatbot-part-2-the-dialogue-system-4932afe6545c?source=collection_archive---------29-----------------------

情感聊天机器人

第二部分:基于深度学习和强化学习的对话系统

第一部分,我们已经建立了伯特情绪预测器。我们现在开始结合它,建立情感对话系统。在进入细节之前,让我们先介绍一些先决条件。(但我仍然无法解释这里的所有术语……)

深度学习的先决条件

  • seq 2 seq model
    seq 2 seq model是一种高级神经网络,旨在将一个序列变成另一个序列。Seq2seq 由两个神经网络组成:EncoderRNN(为了避免消失梯度问题,更常被称为 LSTM 或 GRU )对源句子进行编码,为解码器 RNN 提供隐藏状态。另一方面,解码器生成目标句子。

用于机器翻译的编码器-解码器架构

  • 注意力是你需要的全部 尽管 Seq2Seq 模型在 NLP 中带来了巨大的突破,但一个普通的 Seq2Seq 模型仍然遭受瓶颈和消失梯度问题。注意力模型是 Seq2Seq 之上的一项著名技术,它允许解码器直接专注于源的某些部分,这通过提供到遥远状态的捷径来缓解消失梯度问题。

    更多详情可以参考 NLP 从无到有:带序列到序列网络的翻译及注意

注意力模型(变压器)架构

Texar 包

移情对话数据集

来自 ParlAI 的 EmpatheticDialogues 数据集包含大约 33090 个对话,其中每个对话包含几个句子,并被分类为不同的情绪情况。为简单起见,没有应用验证数据集。训练/测试被分割为 90/10%(跳过了验证数据集)。

下面是一个守恒的例子(转换成一对源句和目标句):

我们准备的数据如下:

  1. 5 个字以内 30 个字以上的句子去掉。
  2. 标记数据,包括符号。英语中的许多缩写形式也被替换了。例如,“不能”将被转换为“不能”
  3. 构建所有单词的词汇表。词汇表的大小是 24,408,完全基于训练数据。

对话系统设计(编码器和损失函数)

基于 HKUST 的论文“ HappyBot:通过改善用户体验前瞻产生移情对话响应”,现在让我们来关注最有趣的部分。

结合情感预测器的网络结构

  • MLE 损失
    模型结构如下。左边是注意力模型的结构,正常的对话系统。目标是嵌入每个句子输入(长度为 T ),然后从 vocab 列表生成输出概率分布(w_t)。响应生成中的训练目标是最大化单词 y*的可能性,并且其损失函数被写为:

  • 线性回归损失
    在我们结合情感的强化学习(RL)部分之前,我们引入另一个线性回归作为基线回报模型,估计每个句子的情感得分 R 如下:

其中 m_t 是编码器在步骤 t 的隐藏状态,R 是该句子的情感得分(奖励),W_r 和 b_r 是可训练参数。这种线性回归的目的是减少报酬 r 的方差。

  • 强化学习损失 我们通过贪婪解码来解码我们预测的句子(我们这样做是为了时间有效性。我们将在下一节介绍“解码策略”)。之后,BERT 模型将预测该句子的情感得分 R。RL 损耗计算如下:

其中 w_t 是在步骤 t 单词的预测概率分布

RL 的含义:线性回归的输出(Rˇt)作为 R 的一个均值,当涉及到一个很大的情绪得分(即 R>Rˇt)时,最小化 L_RL 就是最大化 w_t,也就是说我们要增加获得一个很大奖励的机会。另一方面,当 R<Rˇt 时,需要最小化 wt 以减少损耗。这就是强化学习的原理:你想获得奖励的几率更高。(就像心理学中的操作性条件反射一样)

最后,这三个损失函数组合如下:

MLE、RL 和 B 的λ(权重)是决定权重的三个超参数。

对话系统设计(解码策略)

在用损失函数训练模型之后。为了从 w_t 的概率分布生成预测的句子,我们需要解码部分。这里我们将应用并比较两种解码策略:

  1. 贪婪解码 每一步都取最可能的单词(由 argmax)而不回溯。
    • 优点:快速
      -缺点:无法追溯生成过程,可能会引起一些奇怪的反应。(生成:我爱……,哦其实“爱”这个词不是我想要的!)
  2. 前 K 个采样解码
    从 w_t 中随机采样,仅限于前 K 个最可能的单词。使用 top-k 采样,尤其是使用较大的 k,响应将更加通用和多样。(注意,如果你想用 AI 写诗或小说,你需要 top-k 采样,而不是贪婪解码)

有关解码策略的更多信息,可以阅读下面的文章“您需要了解的响应生成解码策略

如果您采用 Texar 包的解码,您可以通过“助手”实例轻松实现不同的解码策略。

模特培训

培训期间采用了几种策略:

  • 稍后启用强化学习部分的训练 刚开始的时候,生成的句子不够精细,无法进行情感评分。所以我们在第 19 纪元开始 RL 部分。换句话说,聊天机器人通常在开始时学习,然后再考虑情感。
  • RL 的最小权重
    注意到 loss_RL 的斜率较高(因为当输入为负时对数函数的斜率较高,因此其梯度下降)。我们采用了 RL 和 B 的一个极小的 lambda(权重)来平衡它们与 MLE 的 lambda。

b 损失和 RL 损失将在训练中占主导地位。

  • 提前停止
    由于 loss_RL 占优势,模型可能会以 loss_MLE 为代价降低它。因此,在我们的模型中采用了提前停止。如果 loss_MLE 大于其在添加 loss_RL 之前的平均值,则模型训练将终止。我们的模特训练在 20 世纪就结束了。

以下是模型 20 个时期的最终训练历史:

模型评估

为了评估我们的方法,我们将构建另一个基线模型(没有强化学习部分)进行比较。我们将在回应生成中使用两个标准指标:

r 是基础真实响应,r^是系统响应,k 索引所有可能的长度为 n 的 n 元文法,h(k,r)是 r 中 n 元文法的数量。选择 BLEU-1(单元文法)和 BLEU-2(双元文法)用于我们的评估。

  • Distinct metric Distinct metric 衡量生成句子的多样性,定义为不同 n 元语法的数量除以生成单词的总量。我们选择 Distinct-1 (uni-gram)进行评估。

  • 基于指标的评估 我们已经训练了两组模型,基线模型(带有我们的强化学习部分)和非基线模型。对于解码策略,我们还评估了贪婪和 top-k (k=5)来测试解码策略的影响。

    在下表中,发现我们的非基线模型通过在训练和测试数据集中具有最高的情感分数 BLEU-1/2 和独特分数(略好于基线模型)而胜过基线模型。

对训练/测试数据的 BLEU、独特和平均情感评分评估

  • 生成实例

括号内的分数是伯特的情感分数。

结论

与基线模型相比,我们的方法在保持高语言性能的同时,成功地生成了更多的积极响应。

令人惊讶的是,我们发现贪婪方法不仅在语言性能方面与 top-k 采样(k=5)表现相似,而且由于 top-k 采样更有利于通用响应,因此它还产生了更多的正面响应。

参考

  • Ashish Vaswani、Noam Shazeer、Niki Parmar、Jakob Uszkoreit、Llion Jones、AidanNGomez、Lukasz Kaiser 和 Illia Polosukhin。2017.你需要的只是关注。神经信息处理系统进展,6000-6010 页。
  • H.拉什金,E. M .史密斯,m .李,y .布鲁走向共情的开放领域对话模式:一个新的基准和数据集
  • 申洁敏、徐鹏、安德里亚·马多托和帕斯卡尔·冯。Happybot:通过提高用户体验前瞻性来产生移情对话响应。arXiv 预印本 arXiv:1906.08487,2019。
  • K.Papineni、S. Roukos、T. Ward 和 W. J. Zhu。BLEU:一种自动评估机器翻译的方法。在 ACL,2002 年。
  • Sutskever,I .,Vinyals,o .,和 Le,Q. (2014 年)。用神经网络进行序列间学习。神经信息处理系统进展(NIPS 2014)。

基于 Fastai 的深度学习图像分类

原文:https://towardsdatascience.com/deep-learning-image-classification-with-fast-ai-fc4dc9052106?source=collection_archive---------10-----------------------

精疲力尽地学习复杂的机器学习概念和复杂的术语?通过构建一个简单的图像分类器来检测 x 射线中的肺炎,重新点燃您的热情!

瓦迪姆·萨多夫斯基在 Unsplash 上拍摄的照片

TL;速度三角形定位法(dead reckoning)

如果你开始对学习一门学科感到筋疲力尽,走出杂草通常是有益的。我喜欢做一些有趣又容易的事情,以便在我的学习旅程中重新获得积极的动力。这个项目让我的创造力再次迸发。将我的笔记本从我的 GitHub 库加载到 Google Colab,并上传 Kaggle 数据集来学习如何使用 fastai 软件构建图像分类器!别忘了把硬件加速器设置成 GPU!

P.S .进入文件→上传笔记本→GitHub Tab→BSA maha/Chest-x ray-FastAI 直接上传笔记本到 Colab

如何轻松将 GitHub 笔记本上传到 Google Colab

介绍

邓宁-克鲁格效应

你设定了一个目标,比如想成为一名数据科学家或数据工程师。当你浏览你能找到的关于这个主题的所有材料时,你的热情和精力会达到顶点。也许你甚至开办了一个编码训练营或 Coursera 课程,作为你掌握数据之路的向导。当你快速赢得胜利时,你的大脑会充满多巴胺。首先,这是基本的 python 编程。然后你用 sci-kit learn 做了你的第一个线性回归——机器学习毕竟没那么差!你很快吸收了扔给你的所有信息。没有什么能阻止你。

我去过那里,现在仍然去那里。我毕竟是人。我指的是邓宁-克鲁格效应中“愚笨山”的顶峰。有了完美的数据集合,线性回归很容易,但这并不现实。最后,在轻松地浏览了一两个月之后,你碰到了一堵名为统计的墙。你苦苦思索,几乎无法理解——除非你觉得自己没有保留任何东西。人们还记得所有这些分发的东西吗?剧透警告:是的,你会被问到关于他们的问题。当你继续学习的时候,你会意识到你的 python 技能远没有达到应有的水平。你决定看几个招聘启事,然后突然想到。你没有计算机科学的高级研究生学位,你不知道该工作的一些要求如何发音,更不知道它们是什么——Hadoop?欢迎来到绝望之谷。你想退出,继续你的生活。

邓宁-克鲁格效应

解药

我的教官,上士·里维拉,在 T2 的海军陆战队新兵训练营——曾经说过,

“动力就像咖啡因一样,最终会消失。你真正寻找的是灵感。”

每当我发现自己在新的学习旅程中走向绝望之谷时,我都会记得这句话。回到游戏中的最好方法是记住最初是什么让你兴奋。给自己找一个速战速决的机会,重新获得一些积极的动力。

这个项目是我的速赢之作。它让我重新认识到机器学习的惊人力量,以及它可以多么简单。我的想象力开始变得天马行空,想到了我可以制造的所有工具来帮助世界上的其他人。我再次找到了灵感,激情重燃。我希望这对你也一样。

是时候建造了

这篇博文的目标并不是高度技术性的,并教你关于深度学习的一切。我希望你去跟大师本人学习,杰瑞米·霍华德在 Fast.ai。我目前正在学习这门课程,我怎么推荐都不为过。我喜欢他自上而下的教学理念和他让深度学习对每个人都可用的目标。最棒的是它是免费的!

[## 程序员实用深度学习,v3

欢迎光临!如果你是所有这些深度学习的新手,那么不要担心-我们将带你一步一步地完成它…

course.fast.ai](https://course.fast.ai/)

这篇文章的目标是通过快速构建一个具有非常明显的用例的深度学习模型来激励你。这个项目将需要大约 10 分钟的编码。 然而,由于数据集较大以及您的硬件,我们的卷积神经网络(CNN)学习器的训练可能需要 30 分钟。

平台:Google Colab

我强烈推荐 Google Colab 用于所有需要 GPU 的任务——这就是其中一个例子。如果你熟悉 Jupyter 笔记本,那么你会很快意识到它几乎是一个复制品。如果你不熟悉这些,那么请做谷歌 Colab 的教程。

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/notebooks/welcome.ipynb)

在 Colab 中,确保进入运行时→更改运行时类型→将硬件加速器设置为 GPU。

数据集:Kaggle 胸部 x 光肺炎数据集

我在这个项目中使用的数据集是在 Kaggle 上找到的。它有 1 GB 多一点,所以我把它下载到我的本地驱动器,然后上传到我的谷歌驱动器。这允许我从本地硬盘上删除文件。

[## 胸部 x 光图像(肺炎)

5,863 张图片,2 个类别

www.kaggle.com](https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia)

数据集是超过 5,800 JPGs 的胸部 x 光片。这些照片由文件夹标注,分别是“肺炎”和“正常”。这将在以后证明是有益的。

这个数据集有点独特。通常,对于 Kaggle 比赛,一个验证数据集测量你的模型在整个训练中的表现。当你准备好了,你就可以使用测试数据集来做出你的预测,并提交给竞赛评分。对于这个特例,我们将使用我们的测试数据集作为我们的验证数据集来衡量我们的模型表现如何。该数据集没有竞争,验证集只有 16 幅图像,太小了。

密码

首先,你可能需要在谷歌 Colab 笔记本中安装 fastai 软件。在第一个单元格中运行下面的代码,如果它说已经安装了,我们就可以开始了。

!pip install fastai

现在我们需要导入所有必要的库和一些附加功能。下面的代码将导入运行代码所需的所有库。最后两行是可选的。

如果你已经将数据集上传到 Google drive 文件夹中,我推荐你只运行最后两行。您必须执行一个身份验证操作,才能将您的 Google Drive 安装到 Colab。

from fastai.vision import *
from fastai.metrics import error_rate, accuracyimport warnings
warnings.filterwarnings('ignore')from google.colab import drive
drive.mount('/content/drive')

数据集应该是一组父文件夹和子文件夹,如下图所示。非常重要的是,你的文件结构反映了我的。整个项目最困难的部分是组织你的数据。我假设从现在开始你已经把数据上传到 Google Colab 了。

我的项目 Google Drive 根目录中的数据集文件夹

每个测试、训练和评估文件夹子文件夹

一旦你把所有的数据组织好了,乐趣就可以开始了。我们将设置存储您数据的根目录。这是 test、train 和 val 文件夹所在的文件夹路径。当我们稍后保存我们的训练模型时,它们将被保存在这个目录中。

# Set path to root directory
path = Path('/content/drive/My Drive/Colab Notebooks/chest_xray')# View all files in directory
path.ls()

然后我们必须创建一个针对 fastai 软件的 "ImageDataBunch" 对象。这个对象汇集了我们所有的训练数据、测试数据和验证数据,并对图像执行必要的转换。ds _ tfms 正在指定超出本博客范围的转换,要了解更多相关信息,我建议完成 Fast.ai 课程。

# We are creating a fastai DataBunch from our dataset
# Preprocessing takes place when creating the databunch
# May need to decrease batch size and num_workers depending on GPUdata = ImageDataBunch.from_folder(path, train='train', valid='test', ds_tfms=get_transforms(do_flip=False), size=224, bs=64, num_workers=8)

现在你可以明白为什么像我们之前做的那样组织文件夹是重要的。这允许我们使用 from_folder 方法来正确标记所有的图像,同时保持我们的数据集分离,因此没有数据泄漏所有图像都被标准化为 224 像素乘 224 像素的大小。“bs”代表批量大小,即同时向模型显示的图像数量。如果您的 GPU 没有足够的内存,您可能需要减少“bs”——尝试 32 或 16。

使用下面的代码块来查看图像,并了解 ImageDataBunch 是如何对它们进行更改的。

# Show what the data looks like after being transformed
data.show_batch()# See the classes and count of classes in your dataset
print(data.classes,data.c)# See the number of images in each data set
print(len(data.train_ds), len(data.valid_ds)

上面代码的输出应该类似于我下面的输出。

show_batch 代码单元格的输出

现在我们将建立我们的神经网络。在 fastai 中,被训练的模型被称为“学习者”。学习者是一个可以学习适应模型的一般概念。我们正在使用 cnn_learner,它将使用 ResNet34 架构。如果你好奇,这里有一篇描述 ResNet34 的好文章。

[## 理解和可视化资源

这个帖子可以在这里找到 PDF 格式。

towardsdatascience.com](/understanding-and-visualizing-resnets-442284831be8)

创建我们的学习器的代码是一个简单的一行程序。一旦我们创建了学习者,我们将使用 fit_one_cycle 方法在我们的数据集上训练模型。resnet 34 模型是一个预先训练好的模型,我们正在对其数据进行微调。这被称为迁移学习,也是 fastai 建立的前提。

# Build the CNN model with the pretrained resnet34
# Error rate = 1 - accuracy
learn = cnn_learner(data, models.resnet34, metrics = [accuracy])# Train the model on 4 epochs of data at the default learning rate
learn.fit_one_cycle(4)

学习者的培训结果

因为我们用我们的测试数据集替换了我们的验证数据集,所以我们可以确切地看到我们的模型在每个时期结束时有多精确。结果显示,我们可能在 2 个时期后停止训练。在第二个历元之后,您可以看到有效损失增加,精度降低。然而,列车损失在每个时期都在减少。这是过度拟合训练数据的一个很好的例子。我们的结果显示准确率为 87.6%!更令人惊奇的是,这里的编码是如此简单!

# Save the model
learn.save('stage-1')# Load the Model
learn.load('stage-1')

不要忘记保存您的模型。这样,如果你在不影响模型的“第一阶段”部分的情况下进行修正,你可以重新加载它,而不用浪费时间重新训练它。当你重新加载你的模型时,你会看到一个很长的输出,详细描述了 CNN 的内部工作,这是正常的。

现在,除了最后一层,所有的层都被冻结了。当我们在这些冻结层上调用 fit_one_cycle 时,我们只训练了最后一层,这是将 x 射线图像分类为“正常”或“肺炎”的部分。

现在我们将解冻 CNN 中的所有图层,并对其进行更多的重新训练。这将改变模型评估图像的方式,而不仅仅是分类图像的方式。在我们进行更多的训练之前,让我们来看看什么是好的训练学习率。

# Unfreeze all layers of the CNN
learn.unfreeze()# Find the optimal learning rate and plot a visual
learn.lr_find()
learn.recorder.plot(suggestion=True)

学习与损失函数图

该图显示了学习率如何影响模型的准确性。我们可以看到,随着学习率的增加,我们的模型的损失也在增加。现在,我们已经解冻了学习者中的所有层,我们将使用这些最佳学习率进行重新培训。我们使用的 slice()函数输入学习率。选择一个好的学习率似乎是一门艺术而不是科学,Fastai 课程帮助你学习经验法则。

既然我们对自己的学习速度有了一个概念,让我们根据我们的数据再次训练我们学习者的所有层次。

# Fit the model over 2 epochs
learn.fit_one_cycle(2, max_lr=slice(3e-7, 3e-6))

阶段 2 的模型输出

我们现在已经将准确率提高到了 89.1% 。换句话说,我们每检查 10 次,只能预测 1 次不正确的 x 射线。它并不完美,但对于我们投入的工作量来说已经很不错了!我们再多训练几次,看看能不能多挤出几个百分点。

第三阶段的模型输出

太好了!我们从模型中又挤出了 2%的精确度!现在,让我们来探究一下这个模型出了什么问题。在许多情况下,这允许您更好地理解您的数据,这可能导致使用不同的预处理技术或架构。

解释

首先,我们需要创建一个解释器对象。从这个“interp”对象,我们可以调用 plot_confusion_matrix 和 plot _ top _ losses 等方法。

# Rebuild interpreter and replot confusion matrix
interp = ClassificationInterpretation.from_learner(learn)interp.plot_confusion_matrix(figsize=(12,12), dpi=60)

上面的混淆矩阵显示我们错误地预测了总共 53 幅图像。50 个图像我们错误地预测为肺炎,3 个图像我们预测正常有肺炎。他的图也适用于多标签分类。如果你有很多职业,混淆矩阵通常很难解释。幸运的是,fastai 有一个混淆矩阵的文本版本,可以使用 most_confused 方法访问

most _ 混淆方法输出(预测/实际/总和)

另一个非常有用的方法是 plot _ top _ losses。这允许您检查您的模型最有信心预测正确,但模型是错误的图像。这通常可以显示数据集中的错误。例如,如果图像被错误地贴错标签,您应该正确地给图像贴标签。

show _ top _ losses 方法的输出

现在你有了如何使用强大的 fastai 软件构建图像分类器的框架!我希望这个模型能启发你使用这些技术来创建各种工具。Fast.ai 小组正在整理一个很棒的程序,我强烈建议你去看看!

现在,将这个模型部署为一个 web 应用程序,允许人们为您的模型上传 x 光片,以预测诊断结果!如果有,当然请不要用这种模式代替咨询医生。如果你有兴趣了解如何将这个模型部署为一个 web 应用程序,请告诉我!如果有人对关于部署的后续帖子感兴趣,我会试一试!

谢谢你花时间阅读我的博客。如果您有任何问题或有建设性的批评,请随时联系我!

领英:

www.linkedin.com/in/blakesamaha

个人网站:

aggressiontothemean.com

推特:

@ Mean _ Agression

深度学习图像增强对损失函数工程的见解

原文:https://towardsdatascience.com/deep-learning-image-enhancement-insights-on-loss-function-engineering-f57ccbb585d7?source=collection_archive---------3-----------------------

对超分辨率、色彩和风格转换的技术和损失函数工程的见解。

这些是我从使用深度学习进行各种图像处理技术的实验中获得的关于损失函数工程和深度神经网络架构的一些见解,这些技术包括超分辨率、着色(将颜色修补到黑白图像中)和风格转换。

这篇文章扩展了我的文章中描述的损失函数基于特征激活和风格损失的损失函数,我在我的研究中使用了基于深度学习的图像增强,用于超分辨率和黑白图像的着色。事实证明,这些文章比我预想的要受欢迎得多,尤其是在过去的几个月里,我的文章在谷歌搜索“超级分辨率”的结果中名列前茅。

我在过去一年的研究中发现了一些有趣的发现和见解。有效损失函数在训练有效模型中是重要的,在某些情况下,它们可能比模型的架构更重要。

理论上,损失函数也可以申请专利。随着深度学习的成长和兴起,未来看到损失函数工程师这样的工作成为角色也就不足为奇了。

在本文的后半部分,有一些使用这些损失函数技术生成图像的例子,用于超分辨率、着色和风格转换。

用于训练图像增强的深度学习模型的损失函数中的常见评估度量

对于图像增强,损失函数旨在评估模型的预测/生成输出离目标/地面真实图像有多远,以训练模型来最小化该损失。

传统上,在学术和研究论文中,通常使用基于均方误差(MSE)、均方根误差(RMSE)或峰值信噪比(PSNR)的像素损失来对此进行评估。

像素损失本质上是目标图像的像素距离预测/生成图像的像素有多远的度量。

峰值信噪比(PSNR)

来自维基百科:PSNR 最容易通过均方差(MSE)来定义。给定无噪声的 m×n 单色图像 I 及其有噪声的近似 K,MSE 定义如下。

均方差(MSE)/ L2 损耗

这里的数学让这比看起来更复杂。

均方误差

这是在 RGB 图像中的三个通道之间进行比较。MSE 用于比较目标图像的像素距离预测/生成图像的像素有多远。取每个像素差值的平均值,然后平方。

对于 L2 损失,目标是最小平方偏差,以最小化地面真实和预测/生成图像之间的平方差之和。

如果取均方误差的平方根,这允许考虑所生成的图像和待评估的地面真实图像之间的距离。

峰值信噪比定义(PSNR)

峰值信噪比

峰值信噪比定义(PSNR)最常用于对不同编解码器和图像压缩造成的质量损失进行质量评估,其中信号是原始图像,噪声是压缩图像产生的误差。

PSNR 非常常用于评估图像增强技术,例如超分辨率,其中信号是原始/地面真实图像,噪声是模型无法恢复的误差。

尽管 PSNR 是基于对数的指标,但它是基于 MSE 的。

MSE 不是图像增强质量的良好指示。

为什么均方误差(MSE)不是图像增强质量的良好指标。

使用 MSE 或基于 MSE 的度量可能导致训练找到基于深度学习的模糊滤波器,因为这可能具有最低的损失和最容易收敛到最小化损失的解决方案。

最小化 MSE 的损失函数鼓励寻找通常过度平滑的似乎合理的解决方案的像素平均值,并且尽管最小化了损失,但是从吸引人类观察者的角度来看,所生成的图像将具有较差的感知质量。

考虑具有盐和胡椒噪声的图像将导致比许多其他可能生成的图像更低的损失,这些图像从人类感知来看将更接近地面真实。

椒盐噪声。来源:维基百科

平均绝对误差/ L1 损耗

对于 L1 损失,目标是最小绝对偏差(LAD ),以最小化地面真实和预测/生成图像之间的绝对差异之和。

MAE 减少了平均误差,而 MSE 没有。相反,MSE 非常容易受到异常值的影响。

对于图像增强,MAE 将可能产生从人类观察者的角度看起来质量更高的图像。

PSNR 基于 MAE 而非 MSE

如果使用 MSE 的上述 PSNR 的类似等式被改变为使用 MAE,则在我的实验中,这产生了比 PSNR 更吸引人的增强图像,尽管不如以下度量有效。

结构相似指数(SSIM)

结构相似性指数(SSIM)是一个感知指标。SSIM 是基于图像中可见的结构。使用 SSIM 进行图像增强评估是因为对于一些研究人员来说,PSNR 不再被认为是图像质量退化的可靠指标。这是一个感知指标,用于量化由处理导致的图像质量下降。

我的实验再次使用 SSIM 作为损失函数的度量,结果得到比 PSNR 更吸引人的增强图像

特征损失(感知损失)

如果使用差异固定的预训练模型,则通过在模型内放置回调,可以在感兴趣的层在地面真实图像和预测图像之间比较来自该模型的激活。感兴趣的图层是那些紧接在提取信息的平均或最大池图层之前的图层。

这些有趣的层是模型对特征的感知。

可以比较来自这些感兴趣层的激活的平均绝对误差(MAE ),然后这可以是构成损失函数一部分的度量。

如果生成的图像可以具有更清晰的特征,则从人类观察者对图像质量的观点来看,其余的像素通常不太重要。

这在我的文章基于特征激活和风格损失的损失函数中有更详细的描述

对于超分辨率,我相信这是感知图像质量最重要的指标。然而,这种类型的损失度量在许多研究论文中并不流行,因为它不容易与其他研究进行比较。

克矩阵损失

很少使用的是 Gram 矩阵损失,它本质上是一种风格损失的评估形式。

向量集的格拉姆矩阵是这些向量所有可能的内积的矩阵。

可以获取来自每个通道的激活,将每个激活展平成一维向量,然后获取这些向量彼此的点积以形成格拉姆矩阵。点积表示每个通道组合的相关程度。如果一个通道指示纹理,而另一个通道指示明亮的颜色,则高点积将指示具有纹理的单元也倾向于具有明亮的颜色。

这已被有效地用于评估风格损失。如果两幅图像具有相同的风格,那么它们将具有相似的 gram 矩阵。激活的展平从比较中移除了它们的空间信息。这是克矩阵损失对风格转移如此有效的原因之一。

如果损失函数使用不同的固定预训练模型,来自该预训练模型的激活可以在地面真实图像和感兴趣层的预测图像之间进行比较。同样,感兴趣的图层是那些位于平均或最大汇集图层之前的图层,在这些图层中提取信息。不是查看特征/感知损失,而是可以比较激活的 gram 矩阵的平均绝对误差(MAE ),然后构成作为损失函数一部分的度量。

同样,与前面提到的特征损失一样,这种损失度量在许多研究论文中并不流行,因为它不容易与其他研究进行比较。

如果与损失函数中的其他损失指标一起使用,则需要一个适当的乘数,以将其作为一个类似或适当的尺度。

进一步在下面,这种损失度量在着色中的有效性被显示为非常令人印象深刻。

重量标准化与批次标准化

批量归一化是用于训练深度神经网络的常见实践,包括用于图像生成的深度神经网络,包括生成对抗网络(GANs)。

在论文 关于生成对抗网络 【司涛祥,郝丽】中批量和权重归一化的影响中,发现批量归一化会对训练模型的质量和训练过程的稳定性产生负面影响。最近的技术,重量标准化,被发现可以改善重建,训练速度,特别是 GANs 的稳定性。

在我的实验中,我发现在训练超分辨率和着色的两个模型的情况下,权重归一化是有效的,不限于使用 GANs 进行训练。

自我关注

在论文 自我注意生成对抗网络 (张寒、伊恩·古德菲勒、迪米特里斯·梅塔克萨斯、奥登纳)中,自我注意的思想是基于自然语言处理中用于图像生成的注意机制来实现的

自我关注模块。来源:https://arxiv.org/pdf/1805.08318.pdf

自我注意允许使用来自所有特征位置的线索来生成细节。它有助于确保图像的远处部分彼此一致,而传统上这是卷积神经网络(CNN)的一个缺点。

在我的没有 GANs 的深度学习超分辨率和着色的实验中,我发现自我关注提高了模型基于损失标准和从人类评估角度生成图像的性能。这在着色时更加明显,图像不同部分的相似特征具有更好的一致性。

超分辨率

光谱归一化

在论文**(Takeru Miyato,Toshiki Kataoka,Masanori Koyama,Yuichi Yoshida)* 中,提出了一种称为谱归一化的新的权重归一化技术来稳定鉴别器的训练。克里斯蒂安·科斯格罗维的一篇文章解释了什么是光谱归一化,通过限制权重的李普希兹常数来控制梯度。*

在论文**(张寒,伊恩·古德菲勒,迪米特里斯·梅塔克萨斯,奥登纳)中,鉴别器和生成器都使用了谱归一化。**

在我最近对基于深度学习的超分辨率进行的实验(没有 GANs)中,我发现光谱归一化比重量归一化和批量归一化更有效地提高了模型生成图像的性能——基于损失标准和从人类评估的角度。

在我对黑白图像进行基于深度学习的着色(颜色修复)的实验中(同样没有 GANs),我发现光谱归一化 不如 批量归一化有效。

2 倍超分辨率:基于 ResNet 34 的编码器和基于 U-Net 架构的解码器的改进型号

该模型的目标是生成更大的高保真图像,其高度和宽度是输入图像的两倍,像素是输入图像的四倍。对于一个训练有素的模特来说,这是一项艰巨的任务。

生成这些超分辨率图像的模型在 U-Net 架构中具有基于 ResNet34 的编码器和解码器。在我过去的实验中,这个改进的模型被训练用于使用损失函数的超分辨率,该损失函数组合了 SSIM(结构相似性指数)、来自固定预训练的 VGG16 模型的特征/感知损失和来自固定预训练的 VGG16 模型的 gram 矩阵(风格)损失,以及小部分 MAE(平均绝对误差)损失。

这也在模型的训练中使用了光谱归一化和自我注意。

在下面的例子中,低分辨率输入图像在左边,生成的预测在中间,地面真实/目标图像在右边。

2 倍的超分辨率源于一个改进的超分辨率模型,该模型采用 U-Net 架构和基于 ResNet34 的编码器/解码器。低分辨率图像(左),生成的预测(中),地面实况(右)

如果你仔细观察第一排冲浪板上的岩石和手臂,这些特征清晰而鲜明。如果你仔细观察屋顶、窗户和悬挂在上面的纺织品,同样的情况也可以在最下面一排的图片中看到——房屋。图像底部中心的栅栏线清晰可见。

着色/将颜色修补成黑白图像。

这里的着色实验使用了比我之前的实验小得多的 U-Net 架构,基于基于 ResNet18 的编码器和解码器,而不是使用基于 ResNet34 的编码器和解码器。

改进的基于 ResNet18 的编码器和解码器 U-Net。

与我过去的实验相比,这个改进的模型被训练用于使用损失函数的图像着色,该损失函数结合了 SSIM(结构相似性指数)、来自固定的预训练 VGG16 模型的少量特征/感知损失和来自固定的预训练 VGG16 模型的 gram 矩阵(风格)损失,以及非常小比例的 MAE(平均绝对误差)损失。

这个模型的训练使用了体重标准化和自我关注。此外,以 16 位浮点精度进行训练有助于进一步减少损失。与此结合的组合或混合损失函数允许模型最小化不同因素的损失,从而产生有吸引力的结果。

在下面的例子中,低分辨率输入图像在左边,生成的预测在中间,地面真实/目标图像在右边。

色彩化产生于具有 U-Net 架构的模型,该 U-Net 架构具有利用混合损失函数训练的基于 ResNet18 的编码器/解码器。低分辨率图像(左),生成的预测(中),地面实况(右)

在最后一个例子中,生成的熊的图像比地面的真实情况更具视觉吸引力。

Gram (style)损失函数用于训练具有基于 ResNet18 的编码器和解码器 U-Net 架构的模型

这一模型的结果令人惊讶地有效。用于训练该模型的损失函数不使用 MSE 或 MAE 像素损失。损失函数也没有使用 PSNR、SSIM 或特征损失。损失函数仅将感兴趣特征的 gram 矩阵与 ImageNet 预先训练的固定模型进行比较。

结果,虽然不如一个模型训练有素的其他损失,在我看来,是相当了不起的,修复了纯粹来自训练的颜色,以尽量减少风格的损失。

在下面的例子中,低分辨率输入图像在左边,生成的预测在中间,地面真实/目标图像在右边。

在我看来,一部分生成的图像看起来比真实的地面更具视觉吸引力。

4 倍超分辨率实验

该模型的目标是生成更大的高保真图像,其高度和宽度是输入图像的四倍,像素是输入图像的 16 倍。对于一个模特来说,这是一个很难完成的任务。

训练使用了与本文前面描述的 2x 超分辨率实验相似的损失函数度量。

在下图中,低分辨率输入图像位于左侧,生成的预测位于中间,地面真实/目标图像位于右侧。考虑到输入图像的低质量,该模型正在执行一项令人印象深刻的任务来提高图像的质量。

在上面的图像中,灌木、波浪和岩石明显更清晰,图像中的两个人也是如此。在下图中,建筑线条和屋顶的质量再次明显提高。

4 倍超分辨率源于采用 U-Net 架构和基于 ResNet34 的编码器/解码器的超分辨率模型。低分辨率图像(左),生成的预测(中),地面实况(右)

基于 U-Net 的风格迁移实验

我最近做了一些实验,试图评估上述技术是否可以应用于风格转换。这些实验给出了一些有趣的结果,使用了 U-Net 架构、特征损失和风格损失度量。

风格转移是一个有趣的、不同的并且难以解决的问题,因为与其他图像增强训练不同,在训练期间没有单一的基础事实/目标可以用来与生成的模型进行比较。

这些实验训练了基于 ResNet34 编码器和解码器的具有 U-Net 架构的模型。网络的编码器部分基于在 ImageNet 上预先训练的模型。

损失函数使用特征损失和 gram 矩阵损失的度量的组合,比较原始和生成/风格化图像的固定预训练 VGG-16 模型内感兴趣层的激活。

我一直在试验的 U-Net 架构的身份/跳过连接可以允许学习一种不寻常的算法,该算法使用图像的一组高度样式化的部分,而图像的大部分保持不样式化。这是模型发现在损失函数度量中最有效地最小化误差。与特征/感知损失相比,需要对 gram 矩阵/风格损失进行仔细加权,以产生吸引人的结果。

风格转移实验——好结果

这些风格转移实验的例子试图转移文森特·梵高的疯人院花园的风格,这是我最喜欢的画作之一,我今年早些时候在阿姆斯特丹有幸看到过。

文森特·梵高的疯人院花园

在花了相当多的时间调整损失函数并对其进行微调后,经过训练的模型学会了生成有趣的图像,并将梵高画作的风格转移到这些图像上。

基于文森特·梵高的疯人院花园的风格转变的一个较好的例子。原始图像在左侧,样式化/生成的图像在右侧

来自同一个训练过的模型的另一个非常有趣的例子是这个生成的狼的图像,模型决定给它发光的眼睛,我认为这可能总结了原画中的情绪,它的不祥的人潜伏在树上。发光的眼睛是模型特征检测的结果。

另一个更好的风格转变的例子基于文森特·梵高的疯人院花园——一只眼睛发光的狼。原始图像在左侧,样式化/生成的图像在右侧

风格转移实验—其他结果

这些例子试图传达文森特·梵高的《星夜》的风格。

文森特·梵高的《星夜》

来自训练模型的风格化生成的图像具有绘画的风格和图像,尽管结果似乎过度使用了某些风格。如果对损失函数进行调整,我敢肯定会发现不同的更有吸引力的结果。我怀疑这种风格的图像是 U-Net 的跳过/身份连接的结果。

基于文森特·梵高的疯人院花园的风格转换示例。原始图像在左侧,样式化/生成的图像在右侧

同样,从训练模型生成的风格化图像既有绘画风格也有图像。风格化的效果非常有趣,如果对损失函数进行更多的调整和重新训练,我相信会产生更吸引人的结果。

基于文森特·梵高疯人院花园的风格转移示例。原始图像在左侧,样式化/生成的图像在右侧

风格转移实验——最糟糕的结果

这些实验部分是由于损失函数的风格损失部分权重太大。我也相信这个模型被训练了太长时间和/或学习率太高。

如果你仔细观察,你仍然可以在图像中看到蝴蝶的轮廓,尽管它和它的特征已经大部分丢失了。左侧和顶部有丰富的样式信息。

基于文森特·梵高的疯人院花园的风格转移的失败例子。原始图像在左侧,样式化/生成的图像在右侧

如果你非常仔细地看,你仍然可以看到图像中一些特征的轮廓,尽管几乎看不到。同样,左侧和顶部生成了丰富的样式信息。

基于文森特·梵高的疯人院花园的风格转移的失败例子。原始图像在左侧,样式化/生成的图像在右侧

这些例子说明了训练一个有效的模型有多困难,尤其是当没有单一目标或基础事实来评估每个训练图像的模型时。

结论

与深度学习图像增强研究中传统使用的度量相比,存在可以产生视觉上更吸引人的生成图像的损失函数。作为损失函数度量的一部分,使用和比较来自单独的固定预训练模型的激活非常有效。

我希望有更多的时间来重温这篇文章,以提供更好的图像生成结果,更多的例子和这里概述的技术和结果的扩展解释。此外,当时间允许时,我会将这些模型中最好的放入生产环境中使用。

我也希望能找到一个我能与之合作的出版物或学术机构,来撰写和发表一篇详细介绍这些实验和结果的论文。

最后,我要感谢杰瑞米·霍华德和杰森·安蒂奇的灵感,他们试图训练基于深度学习的模型来执行这些超级分辨率和着色任务。

云中的深度学习。如何入门 Google Colab,为什么?

原文:https://towardsdatascience.com/deep-learning-in-a-cloud-how-to-get-started-with-google-colab-and-why-d07874c5e833?source=collection_archive---------37-----------------------

如何开始使用 Google Colab……

图片由皮克斯巴伊费利克斯米特迈尔拍摄

简介

在本文中,我将向您介绍 Google Colab,它是一个类似于 Jupyter notebook 的工具,允许您在云端运行代码。我将向您介绍:

Google Colab 是什么,为什么你应该开始使用它?

如何安装 Google Colab?

在 Google Colab 中编写你的第一个函数。

在 Google Colab 中加载数据文件。

如何在 Google Colab 中打开 GPU 和 TPU,以及如何使用它进行深度学习。

阅读完本文后,您应该已经准备好开始将 Google Colab 用于您的数据科学项目,利用在云中运行代码的优势,并使用该工具提供的免费 GPU /TPU。

我们开始吧!

Google Colab 是什么,为什么你应该开始使用它?

轻松协作

顾名思义,Google Colab 是由 Google 发布的一个工具,与其他 Google 产品类似,它可以在云中使用,并允许协作编辑。这意味着您可以轻松地与其他人共享笔记本,允许他们查看代码,或者使他们成为协作者。

预装的数据科学库

Google Colab 允许你像 Jupyter Notebook 一样交互式地编写和运行 python 代码。此外,它预装了大多数数据科学库,这使它成为想要立即开始机器学习项目的初学者的理想工具。像 pandas,numpy,Tensorflow,Keras,OpenCV 这样的库已经安装好了,所以不需要运行‘pip install’和本地环境安装。

自由图形处理器/ TPU

此外,它还提供免费的 GPU /TPU!这意味着训练神经网络将更快,并且可以由没有非常强大的机器的人访问。即使你有一台强大的机器,Google Colab 也能让你把机器从繁重的工作中解放出来,并把它委托给云。

如何安装 Google Colab?

为了开始使用 Google Colab,请遵循以下简单步骤。

  1. 导航至您的 Google Drive 页面

2.在 Google Drive 中,点击’+New按钮。

3.从 '+新建'下拉菜单中选择'更多',然后从附加下拉菜单中选择“ +连接更多应用”。

4.现在你应该可以看到一个带有 G Suite Marketplace 的窗口。在搜索框中输入合作实验室并按回车键确认选择。

5.现在,您应该能够看到 Google Colab 程序作为一个可能的选择。

6.现在点击图标选择的【合作实验室】,系统会提示您安装按钮。按照屏幕上显示的安装指南操作,之后你就可以使用 Google Colab 了。

在 Google Colab 中编写你的第一个函数

一旦您安装了 Google Colab,当您从 Google Drive 中选择“+ New”按钮时,它将出现在您的下拉列表中。

通过点击“谷歌实验室”,系统将在一个新窗口中打开一个谷歌实验室文件。现在,您可以像使用普通 Jupyter 笔记本一样使用该文件了。你可以用一个简单的 hello world 函数来测试它。

def hello_world(): print ('hello world')

经过测试后,您可以像使用 Jupyter 笔记本一样开始使用。您可以使用普通导入来导入库,运行 python 代码,并添加带文本的 markdown,就像它是普通的 Jupyter 笔记本文件一样。

现在我将向您展示如何在 Google Colab 中加载数据文件,因为它与您在 Jupyter Notebook 中使用的略有不同。

在 Google Colab 中加载数据文件

从 Google Colab 加载文件有两个选项。您可以从本地文件系统加载它,或者将文件添加到 Google Drive 并连接 Google Colab 以使用存储在驱动器中的文件。我建议你做后者。

为了连接 Google Drives 和 Colab,请在其中一个 Colab 文件中运行此代码。

from google.colab import drivedrive.mount('/content/drive')

您将被提示打开链接,在那里您将被要求允许 Google Drive 文件流。

点击“允许”按钮,您将获得授权码。使用此代码,并将其粘贴到 Google Colab 文件中您已经安装驱动器的位置。这需要一段时间,你的 Google Drive 应该可以使用了。您应该能够看到“安装在/content/drive ”消息。

现在你可以从你的硬盘上开始使用你的 Google Colab 笔记本中的文件了。让我们看一个例子。我的谷歌硬盘里有一个名为“数字”的文件。我可以使用下面的代码将它加载到 pandas 数据框中。

import pandas as pddf = pd.read_csv('/content/drive/My Drive/numbers.csv')

为了访问 Google Drive 中的任何文件,您只需使用“/content/Drive/My Drive/”+filename 作为路径。

如何开启 GPU / TPU 并用于深度学习

让我们以我认为的谷歌协作工具的最大优势来结束本教程:使用免费的 GPU 或 TPU。此外,这不会比使用另一个下拉菜单更简单。

导航至'运行时',并选择“更改运行时类型”。

现在你会看到一个对话框,里面有三个选项:无、TPU 和 GPU。选择您希望用于神经网络训练的一个。

一旦你选择了这个选项,就像平常一样运行你的 Keras 或者 Tensorflow 代码。如果你的人工神经网络和数据集足够大,当使用 GPU 或 TPU 时,你应该会看到每个历元训练时间的显著减少。

总结

您已经准备好开始使用 Google Colab 进行您的数据科学项目。我希望你会喜欢它的功能,并利用它的协作性质和免费的 GPU。如果您正在寻找一些项目想法,请查看我在本文中列出的数据资源:

[## 机器学习数据集

为数据科学项目寻找第一批数据的最佳资源

towardsdatascience.com](/machine-learning-data-sets-8c73825a17f9)

原载于 aboutdatablog.com: 云端深度学习。如何入门 Google Colab,为什么?2020 年 4 月 22 日。

PS:我正在 Medium 和aboutdatablog.com上写文章,深入浅出地解释基本的数据科学概念。你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。如果你还不是中等会员,你可以在这里加入

下面还有一些你可能喜欢的帖子

* [## python 中的 lambda 函数是什么,为什么你现在就应该开始使用它们

初学者在 python 和 pandas 中开始使用 lambda 函数的快速指南。

towardsdatascience.com](/what-are-lambda-functions-in-python-and-why-you-should-start-using-them-right-now-75ab85655dc6) [## Jupyter 笔记本自动完成

数据科学家的最佳生产力工具,如果您还没有使用它,您应该使用它…

towardsdatascience.com](/jupyter-notebook-autocompletion-f291008c66c) [## 当你开始与图书馆合作时,7 个实用的熊猫提示

解释一些乍一看不那么明显的东西…

towardsdatascience.com](/7-practical-pandas-tips-when-you-start-working-with-the-library-e4a9205eb443)*

脑-机接口中的深度学习

原文:https://towardsdatascience.com/deep-learning-in-brain-computer-interface-f650d00268d0?source=collection_archive---------23-----------------------

推动该领域发展的现状和挑战

Robina Weermeijer 在 Unsplash 上的照片

什么是脑机接口?

脑机接口(Brain-Computer Interface,BCI)是一种提取对象(人或动物)的大脑活动模式并将其转换为交互式应用的消息或命令的系统。大脑活动模式是用脑电图(EEG)获得的信号。

完全用我们的思想控制设备的概念并不新鲜。众所周知,科幻小说和好莱坞电影描绘了这一点。已经进行了几项研究和实验,如猴子控制机械臂自己进食、控制轮椅控制光标每分钟打大约八个字。

除了控制设备,脑机接口的不同应用和研究包括:

  • 睡眠模式
  • 癫痫
  • 注意缺陷多动障碍
  • 意识障碍
  • 麻醉深度
  • 疲劳和精神负荷
  • 情绪
  • 情感

BCI 应用的挑战

BCI 系统的工作依赖于破译大脑活动的能力。但是单个 EEG 数据可能包含伪像、来自电力线的干扰、测量和环境噪声。它也包含受试者正在进行的思想的干扰。这些假象/噪声掩盖了实际的目标信号。

在实验过程中,由于疲劳、情绪甚至是眨眼等细微的身体动作,我们的大脑都会产生不同的信号。因此,针对特定用户训练的分类器可能很难概括同一个人在不同时间记录的数据。

EEG 信号是高度用户特定的,因此,大多数 BCI 系统是为每个用户校准的。在佐治亚理工学院的研究中,他们在看不见的对象(不属于训练数据集的一部分)上获得了 38%的准确率,在看得见的对象上获得了 75%的准确率。

Hajinoroozi 等人对被试内和跨被试预测都进行了测试,结果显示跨被试模型的表现总是比被试内模型差。

在数据收集中,基本事实通常取决于主体必须执行的操作。因此,这可能是棘手的,因为不可能知道受试者在想什么,或者受试者准确地聚焦在哪里。

BCI 尤其具有挑战性,因为该理论涉及多个学科:

  • 神经系统科学
  • 信号处理
  • 机器学习
  • 计算智能
  • 认知科学
  • 物理学

这些挑战表明,为什么向大众市场推出 BCI 系统是一个巨大的挑战。

为什么深度学习适用于 BCI 应用

近年来,深度学习在各种任务中表现显著;事实证明,它优于使用手工制作功能的“传统”机器学习方法。

将具有高度可变性和非平稳噪声的脑电活动解码成有意义的信号是困难的。这些困难导致使用机器学习算法来解决 BCI 应用。

深度学习具有从高维数据的分层表示中提取特征和学习的能力,并且已经在计算机视觉和自然语言处理领域中导致了许多真实世界的应用。鉴于其在其他领域的有效性,深度学习似乎有望从原始脑电图数据中学习,以提取更好的特征,从而提高性能和鲁棒性。

EEG 数据集是高维的,具有大量参数的深度学习模型可能能够直接学习生鸡蛋信号。

常见的深度学习架构

为了解决 BCI 应用中的挑战,研究人员致力于改善从 EEG 信号中提取基本特征,并建立能够更好地概括的模型。

受限玻尔兹曼机

受限玻尔兹曼机器(RBM)基于训练数据的对数似然的梯度上升来学习输入数据的概率分布。深度信念网络(DBN)由三个 RBM 组成,其中 RBM 可以以深度学习的方式堆叠和训练。

递归神经网络

鉴于脑电图数据具有时间结构,频率随时间变化,递归神经网络(RNN)是合适的。通过递归的 RNN 模型序列数据,这是在时间上展开 RNN 以形成前馈神经网络来应用反向传播。

长短期存储器(LSTM)是一种 RNN 架构,由使用带自连接存储单元的门控单元的存储块组成。LSTM 解决了传统递归神经网络的梯度消失问题。

卷积神经网络

最近的发现显示了卷积神经网络(CNN)处理时间序列的有效性,因为它们能够从原始数据中学习最相关的特征。CNN 可以扩展到更高维度来学习任务所需的特征。卷积层通常由卷积、非线性激活和池化组成。

CNN 在多项任务上超越了之前的 BCI 竞赛获胜者。然而,支持向量机的集合获得了比 CNN 方法稍好的性能。几项研究探讨了将 DBN 与 CNN 以及 RNN 与 CNN 合并的想法。DBN 和 CNN 的结合产生了有希望的结果。

Schirrmeister 等人探究了浅层和深层 CNN 模型的效果。他们表明,较浅(5 层)的全卷积模型比深度模型性能更好。

张等从准确度、精度、F-measure 和 G-mean 等方面评估了范围从 2 到 10 深度优于更深的模型。

由于可用于 BCI 的训练样本数量很少,许多研究工作表明,那些具有更少参数的较浅架构被证明更有用。

规范化

正如在 BCI 应用的挑战中提到的,EEG 信号是高度可变的。由于 EEG 包含来自正在进行的大脑活动和测量噪声的干扰,所以在受试者之间甚至在同一受试者中,EEG 信号可能有很大不同。

这些类型的噪声建议使用正则化,以保持网络的权重较小,从而减少过拟合。神经网络的常见正则化方法是 L1 和 L2,它们根据权重的大小和符号对权重进行惩罚。辍学技术也是非常常用的。

这些正则化技术通常会略微提高性能,大多数研究至少使用了一种正则化技术。

当前最先进的模型

深度学习模型目前的性能尚不清楚它是否能胜过传统的处理技术。这是因为与自然图像不同,在自然图像中有 ImageNet 数据集作为基准数据集,EEG 没有基准数据集。

在 BCI,研究中使用了许多不同的任务和不同的数据集,报告的结果高度偏向于特定数据集的个体研究。每项研究的报告绩效指标和方法各不相同,缺乏标准化的报告方法。

再现性对于推动一个领域的发展至关重要;这在技术发展非常迅速的计算机视觉领域已经看到了。随着开源数据集的可用性和代码的共享,计算机视觉社区实现了适合现实世界应用的最先进的性能。

不幸的是,对于 BCI 研究,许多研究人员使用私人数据集,他们不公开发布他们的代码。获取数据更加昂贵,带注释的数据需要主题专家的贡献。

深度学习在 BCI 应用中的问题

因为训练深度学习模型通常需要大的训练数据集。不像计算机视觉研究社区,那里有大量的数据可用;有限的可用 BCI 数据对推进该领域提出了挑战。高质量的数据也很难获得,可以采用扩充数据集或使用生成性对抗网络。

深度学习模型在记忆数据集方面很棒,但鉴于脑电图的信噪比较低,模型可能会记忆噪声数据。因此,即使使用各种正则化技术,性能也会受到很大影响。

张等强调深度学习模型容易受到对抗性攻击。后果可能从仅仅是用户困惑和沮丧,到显著降低用户的生活质量,甚至到故意伤害用户使其陷入危险。

通常,深度学习模型被视为黑盒,其中它不提供对决策背后的神经生理现象的洞察。这让临床医生和最终用户感到不舒服,特别是当理解模型如何以及为什么产生输出可能对做出明智的临床选择至关重要时。由 Sturm 等人进行的一项研究使用逐层相关性传播将决策转换为热图,指示每个数据点与决策结果的相关性。

深度学习模型可能需要很长时间来训练;因此,在新用户和每次使用之前,需要很长时间来校准。我们不能指望新用户花几个小时记录他们在不同任务上的大脑模式,也不能让 BCI 用户每次想使用系统时都要等待。

结论

研究人员需要开发更强大和一致的算法,以便于训练和部署。算法必须能够处理小的训练样本,处理有噪声的信号,很好地概括不同时间的用户以及不同用户的情绪和概括。

许多研究是在少数对象上离线评估的,但对于实际的 BCI 应用来说,机器学习需要实时工作。

深度学习推进因缺乏数据和代码共享而滞后;当研究人员公开共享数据集和代码时,进展会快得多。

在将 BCI 应用程序推广到大众市场之前,有许多问题需要解决。

感谢阅读!当我开始我的博士之旅,研究脑机接口的时候。如果你有兴趣阅读更多关于脑机接口的内容,请关注我。我将会写下我所学到的和我将要做的事情。

[## 人工智能和神经科学之间的迷人关系

他们如何相互激励、共同进步、相互受益

towardsdatascience.com](/the-fascinating-relationship-between-ai-and-neuroscience-89189218bb05) [## 数据科学家:21 世纪最肮脏的工作

40%的吸尘器,40%的看门人,20%的算命师。

towardsdatascience.com](/data-scientist-the-dirtiest-job-of-the-21st-century-7f0c8215e845)

金融深度学习:这是金融业的未来吗?

原文:https://towardsdatascience.com/deep-learning-in-finance-is-this-the-future-of-the-financial-industry-a29b561031e9?source=collection_archive---------13-----------------------

使用深度学习加速金融行业的增长

深度学习现在引领着金融创新的潮流吗?计算金融、机器学习和深度学习多年来一直是金融部门的重要组成部分。这些技巧、技术和技能的发展使得金融业在过去几十年里实现了爆炸性增长,并变得更加高效、敏锐,对其参与者来说利润丰厚。这将继续成为金融业未来的驱动力吗?

来源

深度学习怎么用在金融上?

金融深度学习是在金融部门的各个部分使用神经网络方法的艺术,例如:

  • 客户服务
  • 价格预测
  • 证券管理
  • 欺诈检测
  • 算法交易
  • 高性能计算
  • 风险管理
  • 信用评估
  • 和操作

随着新的深度学习焦点的出现,推动金融行业的人们不得不通过从理论金融知识的理解中分支出来适应。他们现在被迫学习如何使用 Python、云计算、数学和统计学,还采用了 GPU(图形处理单元)的使用,以便更快地处理数据。

在本帖中,我们将重点介绍:

  • 金融中的算法交易
  • 金融中的价格预测
  • 金融领域的欺诈检测

每个部分还包括一个有用的教程链接。

金融中的算法交易

算法交易是创建一个计算模型来实现金融市场中的买卖决策的过程。除了基于数学模型,交易者还可以使用深度学习技术,使用近似模型来实现买卖交易。

来源

算法交易策略

  • 趋势跟随
  • 这是最常见的策略类型,投资者将跟踪价格变动、移动平均线、突破等模式。没有对价格的预测,相反,目标是根据投资者提供的逻辑指令执行买卖策略。
  • 套利机会
  • 从金融资产的差价中获利被称为“金融套利”。这基本上是当你购买一个更便宜的资产,并在不同的市场以更高的价格出售,从而在没有任何净现金流的情况下获利。如果投资者能够成功执行利用差价的策略,就有机会进行有利可图的交易。
  • 数学建模
  • 均值回归——这是基于一种观点,即资产的高低价格将回归到其平均价值。一旦价格低于平均值,就被视为买入资产的机会,希望价格高于平均值。资产的平均价值不断变化,因此需要持续监控。
  • 成交量加权平均价格(VWAP) —该策略分解大订单,并使用特定股票的历史成交量曲线向市场发布动态确定的较小订单块。目的是在 VWAP 附近执行订单,从而从平均价格中获益。
  • 时间加权平均价格(TWAP) —时间加权平均价格策略分解一个大订单,并使用在开始和结束时间之间平均划分的时间段向市场发布动态确定的较小订单块。目标是在开始和结束时间之间以接近平均价格的价格执行订单,从而将市场影响降至最低。

参见本教程用 Python Python、Zipline 和 Quantopian 进行金融编程,学习如何用 Python 进行量化交易。

金融中的价格预测

几十年来,金融行业的交易员和专家一直严重依赖计算机,但借助运行 GPU 的高性能计算(HPC ),他们已经能够将计算机提升到一个新的水平。这些新的工作站和服务器为海量数据集提供了大量存储选项。这些系统还允许人们执行复杂的、占用大量内存的算法,这些算法需要在本地机器上使用数百万甚至数十亿个数据点来执行金融交易策略,以及使用深度学习技术进行价格预测。

来源

用于深度学习价格预测的技术

  • 递归神经网络(RNN) —短时间范围
  • RNN 用于具有连续顺序的数据,如时序数据库。
  • 长短期记忆模型(LSTM)——与 RNN 相比,时间跨度更长
  • LSTM 是 RNN 的变体,增加了参数以支持更长的记忆,因此预测的时间范围可以更长。
  • 多层感知器(MLP)
  • MLP 是一类前馈神经网络,由输入层、隐含层和输出层组成。这也适用于时间序列预测,因为它:
  • 对异常值、噪声数据和缺失值具有鲁棒性
  • 非线性建模
  • 支持多元预测
  • 多步预测

本教程可以带你通过使用 Python 和 TensorFlow 2 和 Keras 进行金融资产价格预测

金融领域的欺诈检测

金融界充斥着欺诈和欺骗。黑客和骗子总是试图窃取机密的个人信息和公司内部信息来出售。世界各地的政府都在对公司进行严格审查,以升级他们的网络安全和欺诈检测系统。网络安全也是2020 年就业市场上最受欢迎的职位之一。

机器学习和深度学习现在被用于自动化搜索数据流以发现可能是安全威胁的异常的过程。

自动编码器

用于异常检测的深度学习算法是自动编码器。自动编码器神经网络是一种无监督的学习算法,它应用反向传播,将目标值设置为等于输入值,这实质上是对数据进行编码和压缩,并将数据重构为尽可能接近原始数据的表示。

自动编码器由两部分组成:

  • 编码器 —获取输入数据并将其压缩成一个数量向量。
  • 解码器 —从编码器获取数据并重建原始输入。

来源

本教程将带您了解带有 Keras、TensorFlow 和深度学习的自动编码器

对深度学习在金融领域的潜力略知一二

金融行业是受 AI(人工智能)新发现影响最大的行业之一。由于近年来市场波动性增加和网络犯罪威胁增加,预测增加回报的机会和使用人工智能保护数据是两个增长的领域。

该行业产生了数万亿个数据点,需要创新的解决方案来处理和分析这些数据。更严格的监管以及来自政府、行业和消费者的越来越大的压力迫使金融行业的参与者在保护数据的同时仍然增加投资者的回报。

谁来运营你的深度学习项目?

金融行业曾经被世界上最著名学校的 MBA 们所主宰。现在,焦点转移到了拥有编程语言知识的技术人才身上,如 Python、以及云计算和深度学习。

工程师在设置和管理 GPU 驱动的硬件以应对新挑战方面也发挥着重要作用。了解你在处理什么数据,你需要使用的深度学习应用和框架,你想要得到的结果,这些都需要大家共同努力。如果您的团队中缺少工程师,寻找像 Exxact 这样的公司可以帮助您了解您的需求,并提供预先配置、设置好的解决方案,一插上电源即可投入使用。你只需要确保你手头有技术人员来使用它,或者获得必要的知识来自己运行它。

几何中的深度学习:弧长学习

原文:https://towardsdatascience.com/deep-learning-in-geomtry-arclentgh-learning-119d347231ce?source=collection_archive---------23-----------------------

入门

使用深度神经网络(DNN)解决了几何中的一个基本问题。我们从监督学习方法的例子中学到了一个几何性质。由于最简单的几何对象是曲线,我们重点学习平面曲线的长度。为此,重构了基本长度公理,建立了弧长网

介绍

曲线长度的计算是许多现代和古典问题中最主要的组成部分之一。例如,手写签名涉及计算沿曲线的长度(Ooi 等人)。当一个人在现实生活中处理长度计算的挑战时,他面临着几个约束,如加性噪声、离散化误差和部分信息。在本帖中,我们回顾了我们的工作,预印本可在线获得:

https://www . researchgate . net/publication/345435009 _ Length _ Learning _ for _ Planar _ Euclidean _ Curves

在目前的工作中,我们解决了几何领域中的一个基本问题,我们的目标是使用 DNN 重建一个基本属性。最简单的几何对象是曲线,评估曲线的简单度量是长度。在经典文献(Kimmel,2003)中有许多用于计算长度和其他几何性质的封闭形式的表达式。然而,由于我们知道 DNN 的强大功能,我们非常有动力通过设计 DNN 来重构曲线长度(弧长)属性。为简单起见,我们将重点放在二维欧几里得域上。

一点几何学

因此,在我们深入研究机器学习公式之前,让我们简要回顾一下长度属性。2D 曲线的欧几里德长度的一般方程由下式给出

(1)

主长度的公理是可加性、不变性、单调性和非负性。关于连接的长度相加,关于旋转和平移不变,它是单调的,并且根据定义,任何曲线的长度都是非负的。

为了求一条连续曲线的长度,应该把它离散化。离散化过程包含误差。例如,让我们看看蓝色曲线。该曲线的粗略离散化可以导致橙色离散化曲线。显然,将曲线划分成许多无穷小的线可以使离散化误差最小化。

作者图片

在离散化误差中,我们可以发现由于长度方程(1)中涉及的非线性和导数而出现的附加噪声、部分信息和许多其他误差。

那么,我们如何把它表述为一项学习任务呢?

学习方法

我们用一种监督学习方法解决了这个问题,该方法具有满足长度公理的独特损失函数。得到的训练模型称为 ArcLengthNet。它获得一个 2D 向量作为输入,表示平面欧几里得采样曲线,并输出它们各自的长度。我们创建了一个包含 20,000 个示例的数据集,以完全支持 DNN 培训。这些大量的例子旨在涵盖曲线转换并满足不同的模式。我们数据中的一般曲线如下所示

其中 R 为旋转矩阵, T 为平移向量, a 为振幅,φ为相位。

按作者分列的数字

设计了一个独特的损失函数:

其中 s1、s2s3 是保持等式L(S1)=L(S2)+L(S3)O是通过模型传递示例可以调整权重:

架构:设计了一个简化的基于 CNN 的架构。它包括一个卷积层和两个只有一个激活功能的全连接层。每条曲线由 N = 200 个点表示。该表示被插入到具有大小为 3 的小内核的卷积层中。它被处理成一个全连接层,该层通过一个整流线性单元(ReLU)激活函数向另一个最终输出长度的全连接层仅输出 10 个权重。

通过用反向传播方法小批量传递许多示例来训练 DNN。训练过程以 200 个样本为一批进行 100 个时期。我们使用的优化器是动量和重量衰减的随机梯度下降(SGD)。

作者图片

作者图片

经过 100 个时代后,模型得到了很好的训练。定义了一个维持集来测试这些体系结构在看不见的数据上的性能。该集合包含 5,000 个没有在训练集或测试集中使用的示例。ArcLengthNet 获得的最小均方误差为 0.17。在此维持集上测试了 ArcLengthNet 的单调属性,其中在真实长度和 ArcLengthNet 之间建立了线性关系:

作者图片

摘要

提出了一种基于学习的曲线长度重构方法。深度神经网络重构基本公理的能力得到了证明。所得结果可进一步用于改进手写签名和重构更多的微分几何性质和定理。如需更多信息,请随时给我发电子邮件。

鸣谢 一年前,我在以色列理工学院(Technion)上了一堂名为“几何计算机视觉”的课,由 Ron Kimmel 教授主讲。他向我介绍了微分几何领域的一个基本问题,并要求我使用深度学习方法重建弧长。我要感谢基梅尔教授向我介绍了这个迷人而富有挑战性的问题。

— — — — — — — — — — — — — — — — — — — — — — — — —

关于作者

Barak 获得了以色列理工学院的航空工程学士学位(2016 年)、硕士学位(2018 年)以及经济和管理学士学位(2016 年,成绩优异)。他曾在高通工作(2019-2020),在那里他主要研究机器学习和信号处理算法。巴拉克目前正在海法大学攻读博士学位。他的研究兴趣包括传感器融合、导航、深度学习和估计理论。

访问我的个人网站:www.Barakor.com

领英https://www.linkedin.com/in/barakor/

推特:巴拉克 2

— — — — — — — — — — — — — — — — — — — — — — — — —

参考

[1]j .伯格,纽约证券交易所,2018 年。复杂几何形状中偏微分方程的统一深度人工神经网络方法。神经计算 317,28–41。

[2]布朗斯坦,M.M .,布鲁纳,j .,勒村,y .,斯拉姆,a .,范德盖恩斯特,p .,2017。几何深度学习:超越欧几里得数据。IEEE 信号处理杂志 34,18–42。

[3] Do Carmo,议员,2016。曲线和曲面的微分几何:修订和更新第二版。多佛信使出版公司。

[4] Graves,a .,Liwicki,m .,Fern andez,s .,Bertolami,r .,Bunke,h .,Schmidhuber,j .,2008 年。一种新的用于无约束手写识别的连接主义系统。IEEE 模式分析与机器智能汇刊 31,855–868。

[5]君特,b,《父母研究报告》, 1990 年。计算参数曲线的弧长。IEEE 计算机图形与应用 10,72–78。

[6]黑尔韦格,H.B .,克里斯菲尔德,m .,1998 年。处理急剧骤回的新弧长法。计算机与结构 66,704–709。

[7]r .基梅尔,2003 年。图像的数值几何:理论、算法和应用。斯普林格科学与商业媒体。

[8]派,g .,韦茨勒,a .,基梅尔,r .,2016 年。学习平面曲线的不变表示。arXiv 预印本 arXiv:1611.07807。

深度学习和医疗保健:闪光的不一定是金子

原文:https://towardsdatascience.com/deep-learning-in-healthcare-all-the-glitters-aint-gold-4913eec32687?source=collection_archive---------28-----------------------

(莎伦·麦卡琴 / Unsplash )

深度学习和医疗保健之间复杂关系的概述。

全部登上人工智能列车

虽然这种流行趋势对我们这些在这个领域工作的人来说肯定是令人愉快和兴奋的,但它同时也带有危险的因素。信息论确实是一个有价值的工具,并将继续发展[……],但它肯定不是通信工程师或其他任何人的灵丹妙药。[……]当人们意识到使用一些令人兴奋的词汇,如信息、熵、冗余,并不能解决我们所有的问题时,我们多少有些人为的繁荣很容易在一夜之间崩溃。

——克劳德·e·香农《赶时髦》,1956 年

从最早的时候起,人工智能 (AI) 就经常被过分看好,但却表现不佳。五十多年后,香农的关注仍然非常及时:只要将'信息论'与'机器学习'和'信息、熵、冗余'与'深度学习、神经网络、人工智能'切换,你就会突然被投射到 1950 年到 2020 年。

如今, 大家都想造艾 。大型科技公司每年都推出更复杂、资源需求更大的神经网络。资金流动,炒作上升,甚至像医疗保健这样相当保守的分支机构也开始随波逐流,而没有足够担心其影响。

关于人工智能,深度学习 (DL) 是这十年来真正的最有价值的技术,最近在不同的科学领域成为一项真正的增值技术,并作为最接近人类推理的东西而受到关注。

只不过我们还没到那一步。

在此,我们将讨论为什么即使****炒作驱动的深度学习潮流不能也不应该被阻止,医疗保健提供商也应该更多地关注谁可能真正受益于这种新方法

跳上深度学习列车的数据科学家(naz mul Hasan Khan/Caters News)

人工智能和医疗保健:比《暮光之城》更好的爱情故事

医学和人工智能之间的关系和人工智能领域本身一样古老。从这个意义上来说,我们可以说艾发现了医疗保健中的第一个,【大】粉碎了它的青春。

早期和第一次分手

最早的医学专家系统(即由硬编码 if-else 语句组成的计算机化问题解决程序)实际上可以追溯到 1960 年初。正如每个青少年的爱情故事一样,最初的时刻令人难忘,热情也达到了顶峰,但事情很快开始变得有点复杂:由于硬件限制,缺乏基础,以及来自学术界和新闻界的大量悲观情绪,医疗保健——以及其他许多科学分支——对人工智能及其应用逐渐失去了兴趣。第一次分手是在空气中。****

恢复

所谓的艾冬一直持续到 1990 年。与此同时,研究人员专注于如何利用专家知识实现基于演绎学习的患者护理临床建议。也是在这几年,朱迪亚·珀尔和理查德·尤金·那不勒斯提出了贝叶斯网络的想法,这是最有魅力的统计模型之一,开创了临床推理,即使在它诞生 45 年后仍然有很多话要说。
贝叶斯分类器和贝叶斯理论很快成为一种成熟的实践,与古老的
回归模型相结合,在至少二十年的时间里,在医学研究的许多领域带来了巨大的进步。然后互联网发生了。

复合了

从 90 年代中期开始,随着计算机硬件和计算能力的显著提高,收集的数据量开始呈指数级增长。十年后,随着 EHRs(电子健康记录)的普及,医疗领域也开始有大量的数据可用。很快,医疗保健研究人员开始从知识驱动的方法转向数据驱动的方法:浪漫又开始了。

近二十年在 PubMed 发表的 ML 论文[ Valliani et al. 2019 ]

直到数据把我们分开

快进到 2010 年代和大数据革命,一种“新的”奇特的人工智能技术以其令人印象深刻的成就震撼了科学界。深度学习算法开始一个接一个地打破记录,逐渐将各种口味的人工神经网络** (ANNs)作为最先进的技术应用在自然语言处理计算机视觉语音识别等领域,导致医学成像也取得了重要进展。**

医疗保健中数据和深度学习的指数级增长[ 方等 2016 (R)、比尔斯等 2018 (L)]

深度学习的两个方面

为什么大家都爱深度学习?

与传统的机器学习(ML)算法相反,深度学习由海量数据推动,需要配备强大 GPU 的高端机器在合理的时间框架内运行。这两个要求都很昂贵,那么为什么公司和研究实验室认为果汁值得压榨呢?

在传统的机器学习技术中,大多数应用的 特征需要由领域专家来识别,以降低数据的复杂性,并使模式对学习算法的工作更加可见。深度学习算法最大的优势是尝试自己从数据中学习高级特征。这在理论上消除了对领域专业知识和核心特征提取的需求

放射学中模式分类的一个例子。与传统的 ML 算法相反,DL 框架将琐碎的特征提取步骤封装在学习过程本身中。(艾时代杂志)

在需要高度自动化缺乏对特征工程领域理解的复杂问题中(例如图像分类、自然语言处理、机器人技术)深度学习技术正在飞速发展,达到前所未有的精确度水平。

深度学习在医疗保健中的应用

通过处理来自各种来源的大量数据,如放射图像、基因组数据和电子健康记录,深度学习可以帮助医生分析信息和检测多种情况,试图解决许多必要的医疗保健问题,如降低误诊率和预测手术结果。以下是深度学习目前正在展示的一些知名医疗领域:

  • 【肿瘤检测】:卷积神经网络(CNN)的采用显著提高了癌症的早期检测,在筛查乳腺钼靶摄影中的乳腺癌检测等问题上达到了非常高的准确率[ 沈等 2019 ]。在该领域,当在诊断成像研究中识别重要特征时,DL 算法正在接近甚至超过人类诊断医生的准确性[ Haenssle et al. 2018 ]。
  • 医院再入院、住院时间和住院死亡率预测 : DL-powered 算法可以访问每个患者的数万个预测值,包括自由文本注释,并自动识别哪些数据对特定预测很重要,而无需手动选择专家认为重要的变量 Rajkomar 等人 2018
  • ****药物发现和精准医疗:一种新药的发现总是被学术界和普通大众的兴奋所包围,但药物开发周期非常缓慢且昂贵,只有不到 10%进入市场。DL 可用于自动产生指纹和更有效的特征或用于从头药物设计,降低过程成本[ 徐等 2018 ]。
  • 自然语言处理:电子病历在世界各地医疗中心的引入为医疗服务提供者打开了一个新的信息来源:自由文本。从非结构化数据中提取有用的可操作信息有助于医疗保健的许多方面,如摘要、自动报告、问题回答,当然还有决策。然而,的临床文本 往往支离破碎, 不合语法,电报式并且大量使用首字母缩写缩写,这甚至能难倒最聪明的 NLP 算法。

然而——如题——即使是深度学习,也不是所有闪光的都是金子。数据科学家一直在上述所有应用中投入大量精力,但其中一些应用暴露出在实际用例场景中难以克服的局限性,迫使基于 DL 的方法停留在仅供研究的隔离区。但是,为什么这些方法在某些领域表现出色,而在另一些领域却举步维艰呢?为什么我们努力在真实用例场景中取得重大进展?****

在这里,我们将重点关注医疗保健中深度学习的两个最重要的概念问题。

深度学习和医疗保健问题:可解释性和因果关系

应对医疗保健意味着应对人们的生活。这意味着细心、自信、透明、谨慎、敏感和解释为什么以及如何得出某种诊断的能力。同样,我们希望在内科医生和外科医生身上找到这些品质,我们也应该在我们的算法中寻找它们。这就是深度学习显示其局限性的地方。****

让我们以自然语言处理为例。如今,医疗保健领域中由人类生成的书面/口头数据量非常庞大。据估计,近 80%的医疗保健数据在创建后仍处于非结构化和未开发状态。临床记录可能是医疗保健中最被忽视的输入,发生这种情况不是因为它们不提供信息,而是因为很难处理这种类型的数据。
我们已经提到了利用这种信息如何能够显著提高模型的准确性,但是
性能才是最重要的吗

在医疗保健中,一种非常流行的处理文本进行预测的方法是使用单词嵌入,这是一种由各种类型的神经网络驱动的多维、密集、数字表示的单词。
患者的临床记录可以以不同的方式组合,检索
文档嵌入患者嵌入。由于我们现在处理的是数字向量而不是文本,我们可以简单地将它们输入我们最喜欢的分类算法。

患者嵌入管道的示例:收集患者 P1 的临床笔记句子 S,并将其分解为单词 W。然后使用深度学习将这些单词 W 转换为数字向量 W,然后将这些向量组合两次以检索患者嵌入 p,这些嵌入 p 也是向量。这种嵌入现在可以成为我们想要的每个分类算法的输入的一部分。

让我们假设现在我们开发了一个癌症早期检测模型,当我们通过 300 维患者嵌入包括非结构化数据时,它看到了惊人的 30%的准确性提升。我们合理地猜测我们的模型正在使用临床记录** 中的一些非常相关的信息来评估患者的状况。**

但是 这是什么 相关信息?

正如我们所说,嵌入只是密集的数字向量。使用深度学习将单词转换为向量,并将它们合并在一起,完全打乱了桌子上的卡片,使得无法猜测负责患者分类的单词/句子的组合。**
注意机制和系数只能告诉我们哪些成分与预测结果最相关,但是由于我们失去了单词和嵌入成分之间的联系,我们无法真正理解** 为什么这些成分如此重要

准确性与可解释性的权衡(数据科学忍者)

即使模型达到了更好的精确度,我们也不能仅仅因为组件#217 这样说就诊断出一种疾病。使用降维是好的,但是如果我们需要理解决策的来源并在一个更大的(人类)知识框架内评估它,我们必须能够还原这个过程。
这就引出了
因果关系问题

因果(哈佛大学)

人工智能先驱 Yoshua Bengio 因对深度学习的发展做出的贡献而获得图灵奖,他最近表示 DL 必须学习更多关于因果关系的知识才能实现其全部潜力。
换句话说,他说,
深度学习需要开始问为什么事情会发生

****深度学习从根本上是盲目的因果与真正的医生不同,深度学习算法无法解释为什么特定的图像或临床记录可能暗示疾病。理解因果关系,特别是在医疗保健领域,将使现有的人工智能系统更加智能和高效:一个深入了解因果关系的机器人可以制定假设,想象场景,并学习如何在它们实际发生之前解决它们

****这种心态是人类天性所特有的,认知科学实验表明,理解因果关系是人类发展和智力的基础,尽管我们仍然不清楚我们是如何形成这种知识的。另一方面,深度学习算法不太擅长概括,无法将它们从一个上下文学到的东西应用到另一个上下文。这在医学上是非常有限的,因为每一项诊断和预后任务都是基于一个非常复杂的因果联系网络。

在机器人的肩膀上(Newsparent.com)

结论

目前为止我们得到了什么

深度学习 在过去十年里已经成为游戏规则的改变者,我们已经看到了它可以在医疗领域实现的许多方式。然而,我们必须指出,当我们处理涉及患者生命的非常复杂和微妙的情况时,它的阴暗和狭隘的性质是一个问题。如果我们不能解开它以理解它得到结论的方式,那么拥有一个极其精确的模式识别工具在临床决策中是无用的。

这就是为什么简单的线性回归仍然在许多真实的医疗用例场景中战胜复杂的神经网络。我们不能相信无法完全解释的伪黑箱,同样,如果因果关系是该学科的基石,我们也不能依赖能够掌握相关性但不能掌握因果关系的高度特定的模型。

未来会怎样

加里·马库斯在他的新书《重塑人工智能》的后记中写道:

“由深度理解驱动的人工智能将是第一个能够像孩子一样学习的人工智能,容易、强大、不断扩展其对世界的知识,通常只需要一两个新概念或新情况的例子,就可以创建一个有效的模型。”

这可以说是我们应该指出的下一个重大成就,但这并不容易。创造一种超越人类水平的智能远比我们被引导去相信的要复杂得多。这个世界是复杂和开放的,我们今天拥有的高度专业化的狭窄机器还不能完全被信任来完成这种复杂性得到充分展示的任务,如个性化医疗。

参考资料和进一步讲座

在这里,你可以找到我的主要资料来源,以及一些非常有趣的阅读材料,如果你有兴趣深入挖掘深度学习和医疗保健之间的复杂关系,我建议你看一看。

希望这篇博客文章能够给你一个关于在医学中使用深度学习的许多含义的概述。如果你觉得有帮助,请在评论区留下你的想法并分享!

** [## Tommaso Buonocore -作者-走向数据科学| LinkedIn

查看世界上最大的职业社区 LinkedIn 上 Tommaso Buonocore 的个人资料。托马索列出了 5 项工作…

www.linkedin.com](https://www.linkedin.com/in/tbuonocore/)**

医疗保健中的深度学习— X 射线成像(第 1 部分—X 射线的基础知识)

原文:https://towardsdatascience.com/deep-learning-in-healthcare-x-ray-imaging-part-1-basics-of-x-rays-f8e6bad1e421?source=collection_archive---------67-----------------------

这是关于深度学习使用的系列文章的第 1 部分,重点是 X 射线成像(胸部 X 射线)。在这里,我们将讨论 X 射线的基础知识,从它的历史,工作原理到成像。

x 射线成像是最古老的医学成像方法之一,也是最流行的医学成像方法之一。x 光是拯救生命的技术,实际上是偶然发明的。德国物理学家威廉·伦琴在气体放电管中进行电子束实验时发现了这项技术。在做这个实验时,他注意到当电子束运行时,他实验室的荧光屏开始发绿光。现在,这并不是一个不寻常的现象,但是伦琴的屏幕被厚纸板挡住了,他认为厚纸板可以阻挡辐射。他的发现有趣的一面是,他发现这是某种穿透性的辐射,但不能确切地指出它实际上是什么。

当一只手放在光束前面时,神奇的事情发生了,它在屏幕上产生了骨头的图像。这一突破使得 X 射线在发现后立即得到了完美的应用。这一双重发现(X 射线及其应用)标志着人类历史上医学成像领域最大的发现之一。

它让专业人员有机会在不需要任何侵入性手术的情况下观察人体内部的疾病。它甚至允许他们看到轻微修改的软组织。

图一。第一张 x 光照片(威廉·伦琴。— [1],公共领域,【https://commons.wikimedia.org/w/index.php?curid=5059748】

那么什么是 X 射线呢?

你可以把 X 射线想象成光线。两者都是光子以波的形式携带的电磁能量。这两种波的主要区别是射线的能级或波长。我们人类有能力感知可见光波长的光线。但是越来越长的波长不在我们的可见光谱范围内。x 射线是更短更高能量的波。

图二。光谱(作者 Ulflund——该图是维基共享资源不同图片的汇编。上面的图是我自己做的,最初是作为我自己的作品上传的。结晶学图像来自文件:Lysozym diffraction.png,用户:Del45。乳房 x 线照片来自 Nevit Dilmen 的 40F MLO DMMG.png 文件。CT 图像来自文件:Ct-workstation-neck.jpg,作者:ChumpusRex。行李扫描仪图像来自文件:用户在 VTBS.JPG 行李检查用户:Mattes。、CC BY-SA 3.0、【https://commons.wikimedia.org/w/index.php?curid=22545004】T4

X 射线是如何工作的?

x 射线是由原子内电子的运动产生的。给定 X 射线的具体能级取决于原子中电子在轨道间下落的距离。

当任何给定的光子与另一个原子碰撞时,原子可以吸收光子的能量,并将电子提升到更高的水平。在这种情况下,光子的能量必须与两个电子之间的能量差相匹配。如果这没有发生,那么光子就不能引起轨道之间的移动。

这意味着当 X 射线的光子穿过身体时,每个组织的原子对光子的吸收或反应是不同的。软组织由更小的原子组成,因此由于光子的高能量,它们不能很好地吸收 X 射线。

另一方面,骨骼中的钙原子要大得多,因此它们会吸收 X 射线光子,从而导致 X 射线图像上的不同视图。

在 x 光机内:

图 3。在 x 光机里(作者丹尼尔·w·里奇——自己的作品,CC BY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=16622562)

在 x 光机内部,有一对电极,一个阴极和一个阳极。该仪器被放置在通常由玻璃制成的真空管内。阴极通常是加热的灯丝,阳极是由钨制成的平圆盘。当阴极被加热时,在高电位差下,电子从阴极喷出并向阳极移动。由于电极对上的高电压,电子以极高的速度向阳极移动。电子最终撞击阳极的钨原子,并撞击原子较低轨道中的松散电子。随着电子从较高的轨道落到这些较低的能级,额外的能量以光子或 X 射线的形式释放出来。X 射线就是这样产生的。

但是在需要检查软组织的情况下,需要添加造影剂。造影剂通常是对 X 射线不透明并聚集在软组织中的液体。为了检查血管,医生将这种介质注入静脉。通常这些图像是用荧光显微镜实时观察的。

图 4。胆囊切除术中观察软组织(由 HenrikP 医用 x 射线(荧光镜),公共领域,【https://commons.wikimedia.org/w/index.php?curid=318366)

x 射线成像:

为了从 x 光机获得图像,医生在病人的另一侧使用胶片或传感器。当 X 射线穿过人体时,它们会与沿途的许多原子相互作用。最终记录在胶片或探测器上的是所有这些相互作用的总和。

图 5。x 射线成像(BruceBlaus —自己的作品,CC BY-SA 4.0,https://commons.wikimedia.org/w/index.php?curid=44921292)

图 6。胸部 x 光片(作者 Diego Grez—radio grafía _ lupules _ Francis ca _ lor ca . jpg,抄送 BY-SA 3.0,【https://commons.wikimedia.org/w/index.php?curid=10302947】T2

参考资料:

  1. 《x 光片》。科学任务理事会。 NASA
  2. 罗伯特·诺韦林(1997)。斯夸尔放射学基础。哈佛大学出版社。第五版。国际标准书号0–674–83339–2。
  3. 【x 光】牛津英语词典 (第 3 版。).牛津大学出版社。2005 年 9 月。

医疗保健中的深度学习— X 射线成像(第 2 部分—了解 X 射线图像)

原文:https://towardsdatascience.com/deep-learning-in-healthcare-x-ray-imaging-part-2-understanding-x-ray-images-b8c6155cd51d?source=collection_archive---------27-----------------------

这是深度学习在 X 射线成像上的应用的第二部分。这里的重点是理解 X 射线图像,特别是胸部 X 射线。

解读胸部 x 光片:

图一。胸部 x 光——1)肺部,2)右半膈肌,3)左半膈肌,4)右心房,5)左心房(作者迭戈·格雷兹——radiografía _ pulmonaes _ Francis ca _ lor ca . jpg,CC BY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=10302947。作者编辑)

x 射线图像是灰度图像,即图像具有一些暗的像素和一些亮的像素。在医学成像术语中,这些图像具有范围从 0 到 255 的值,其中 0 对应于完全暗的像素,255 对应于完全白的像素。

图二。灰度条

X 射线图像上的不同值对应不同的密度区域:

  1. 深色-身体上充满空气的位置将显示为黑色。
  2. 深灰色——皮下组织或脂肪
  3. 浅灰色——像心脏和血管这样的软组织
  4. 灰白色——像肋骨这样的骨头
  5. 亮白色——存在金属物体,如起搏器或除颤器

医生解读图像的方式是通过观察不同密度之间的边界。如图 1 所示,肋骨呈灰白色,因为它们是致密的组织,但由于肺部充满空气,因此肺部呈黑色。类似地,肺下面是半膈,它也是软组织,因此呈现浅灰色。这有助于我们清楚地了解肺部的位置和范围。

因此,如果两个具有不同密度的物体彼此靠近,它们可以在 X 射线图像中被区分开来。

现在,如果肺部发生了什么事情,比如肺炎,那么,空气密度大的肺部会变成水密度大的肺部。这将导致分界线褪色,因为像素密度将开始接近灰度条。

进行胸部 X 射线检查时,通常要求患者站立,并从前到后(前-后)或从后到前(后-前)拍摄 X 射线。

使用胸部 x 光可以区分的各种解剖结构:

图二。解剖气道— 1)气管,2)右主支气管,3)左主支气管(作者 Diego Grez—radiografía _ pulmones _ Francis ca _ lor ca . jpg,CC BY-SA 3.0,【https://commons.wikimedia.org/w/index.php?curid=10302947】T2,作者编辑)

图 3。解剖膈肌和胸膜——1)胸膜,2)右半膈肌,3)左半膈肌(作者迭戈·格雷兹(Diego Grez——radiografía _ pulme es _ Francis ca _ lor ca . jpg,CC BY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=10302947,作者编辑)

图 4。解剖骨骼——1)锁骨,2)后肋,3)前肋,4)椎体(作者 Diego Grez——radiografía _ pulme es _ Francis ca _ lor ca . jpg,CC BY-SA 3.0,【https://commons.wikimedia.org/w/index.php?curid=10302947】,作者编辑)

图 5。胸部 x 光片上的心脏解剖(作者 Mikael hgg strm,M.D.-作者信息-重复使用图片使用 ZooFari、Stillwaterising 和 Gray's Anatomy creators 的源图片-编辑文件:ZooFari 的 Heart diagram-en . SVG(attribute-Share like 3.0 un ported license)。文件:气管(透明)。png(来自《实习医生格蕾》,公共领域)文件:Chest _ x ray _ PA _ 3–8–2010 . png by Stillwaterising(公共领域)静脉系统的进一步概述:(2011)。"一篇绘画性文章:重症监护室的导管放射学"。印度放射学和成像杂志 21 (3): 182。DOI:10.4103/0971–3026.85365。ISSN 0971–3026。合成:米凯尔·海格斯特伦,CC BY-SA 3.0,【https://commons.wikimedia.org/w/index.php?curid=55155319】T4

以上图像的目的是显示对于一个没有受过训练的医生来说,从胸部 x 光图像中解释不同的解剖结构是多么困难,更不用说任何异常了。

这正是深度学习派上用场的地方。通过深度学习,即使是对身体的不同异常或解剖结构一无所知的人,也可以在预测各种异常时得出令人满意的结果。当然,如果没有庞大的数据集或来自训练有素的医生的地面真实数据,这些都是不可能的,但尽管如此,自我训练算法甚至可以得出这样的结果这一事实令人困惑。

在接下来的几个部分中,我们将使用 Python、卷积神经网络深入研究 X 射线图像可视化,并研究它们如何训练,并得出预测。

参考资料:

  1. Fred A. Mettler、Walter Huda、Terry T. Yoshizumi、Mahadevappa Mahesh:“放射学和诊断核医学中的有效剂量:目录”——放射学 2008 年;248:254–263
  2. “胸部 X 线质量—投影”放射学大师级。检索于 2016 年 1 月 27 日。
  3. 胸透,OB-GYN 101:产科入门&妇科。2003 年、2004 年、2005 年、2008 年 Brookside Associates 有限公司医学教育部门,2010 年 2 月 9 日检索。

医疗保健中的深度学习— X 射线成像(第 3 部分—使用 Python 分析图像)

原文:https://towardsdatascience.com/deep-learning-in-healthcare-x-ray-imaging-part-3-analyzing-images-using-python-915a98fbf14c?source=collection_archive---------26-----------------------

这是深度学习在 X 射线成像上的应用的第 3 部分。这里的重点是使用 Python 查看和分析 X 射线图像。

既然我们已经了解了未经培训的专业人员解读 X 射线图像有多么困难,那么让我们来看看一些查看和分析图像及其直方图的技术,以及一种使用 Python 编程将图像和标签相加的技术。

图像数据集:

图像数据集(胸部 x 光片)从 Kaggle 获得。数据集可通过以下链接获得—https://www . ka ggle . com/paultimothymooney/chest-x ray-pneumonia/data

图一。不同肺炎情况下的胸部 x 光检查(资料来源- Kaggle 公共数据集,详情见参考文献 1)

关于数据集—直接引用自 Kaggle challenge —数据集分为 3 个文件夹(train、test、val ),并包含每个图像类别(肺炎/正常)的子文件夹。有 5,863 个 x 光图像(JPEG)和 2 个类别(肺炎/正常)。胸部 X 线图像(前-后)选自广州市妇女儿童医疗中心 1-5 岁的儿童患者的回顾性队列。所有的胸部 x 光成像都是作为患者常规临床护理的一部分进行的。对于胸部 x 射线图像的分析,最初通过去除所有低质量或不可读的扫描对所有胸部射线照片进行质量控制筛选。图像的诊断然后由两名专家医生进行评级,然后被批准用于训练人工智能系统。为了解决任何评分错误,评估集也由第三方专家检查。

正如内容中明确指出的那样,挑战中共有 5863 幅图像可用,这些图像被分为肺炎和正常两类,并进一步分为训练/测试和验证集。为了使挑战更加困难,我们将数据分为三类,正常、细菌性肺炎和病毒性肺炎。在这一部分中,我们将只关注图像——用 python 加载它们,从医学成像的角度分析图像的各个重要方面,并将图像和标签一起加载。让我们直入主题吧。

导入必要的库

*#importing all the necessary libraries*

**import** **numpy** **as** **np**                     
**import** **matplotlib.pyplot** **as** **plt**
**import** **os**
**import** **cv2** **as** **cv**
**import** **random**

Numpy — Numpy 是 Python 中最常用的库之一。它用于对多维数组和矩阵进行运算,并执行高级数学函数来对这些数组进行运算。

matplotlib——用于在 python 中创建静态和动态可视化的库。

OS——python 内置的一个模块。它提供了与操作系统交互的功能。

cv2 — OpenCV(开源计算机视觉库)—一个非常重要的库,主要用于计算机视觉。其他类似的库有 SimpleITK 和 Pillow (Python 图像库)。

random —生成伪随机数的模块。

研究数据集中的单个图像:

*#load a single image from the bacteria folder*

**def** load_image(path):
    **for** img **in** os.listdir(bacteria_path):
        print('Image name =',img)
        image = cv.imread(os.path.join(bacteria_path, img))
        **break**

    **return** image

如前所述,数据集中的图像被分成三类。1-正常,2-细菌(细菌性肺炎),3-病毒(病毒性肺炎)。

上面的代码片段创建了一个函数 load_image,它将用于从训练集的细菌文件夹中加载一个图像。os.listdir 用于列出该目录中的所有文件。在这种情况下,它可以用来访问细菌文件夹中的所有图像。接下来,它将打印图像的名称。最后,使用 OpenCV 库读取图像。

Break-在这里是必要的,这样只访问第一个图像,否则函数将遍历细菌文件夹中的所有图像。

*# Investigate a single image*

bacteria_path = 'H:/All Files/Kaggle/chest_xray/train/2_BACTERIA/'

image = load_image(bacteria_path)
plt.imshow(image, cmap='gray')
plt.colorbar()
plt.title('Raw Chest X Ray Image')
print(f"The dimensions are **{image.shape[0]}** pixels height and **{image.shape[1]}** pixels width")
print(f"The maximum pixel value is {image.max():.4f}")
print(f"The minimum pixel value is {image.min():.4f}")
print(f"The mean value of the pixels is {image.mean():.4f}")
print(f"The standard deviation is {image.std():.4f}")

输出-

在这个代码片段中,首先定义了图像的路径。然后,通过调用函数 load_image,将文件夹中的第一幅图像加载到变量“image”中。然后使用 matplotlib.imshow 查看图像。之后,打印图像尺寸、灰度栏中的最大像素值和最小像素值。还计算图像像素的平均值和标准偏差。

接下来,我们绘制图像所有像素的直方图。直方图是用不同高度的条来显示数据的图形。

# plot a histogramplt.hist(image.ravel(),256,[0,256]) 
plt.show()

输出-

Matplotlib.hist 用于绘制直方图。由于图像大部分是暗的,我们在灰度条的零位置上看到一个巨大的像素簇。

这些是可以使用 OpenCV 和 matplotlib 在图像上执行的一些基本功能。我们将在后面的部分看到 OpenCV 的更多用途。

一起加载图像和标签并调整图像大小

*# loading the path of the train images*

path = 'H:/All Files/Kaggle/chest_xray/train/'
train = os.listdir(path)

定义了训练集的路径,路径下的目录保存在‘train’中。在这种情况下,有三个文件夹,1_Normal、2_Bacteria 和 3_Virus。

folders=[]
folders = [f **for** f **in** sorted(os.listdir(path))]
print(folders)

输出-

[' 1 _ 正常',' 2 _ 细菌',' 3 _ 病毒']

我们创建一个空列表——文件夹。然后,使用 os.listdir 遍历路径,将文件夹名排序并存储在列表中——“folders”。

labels = folders
print (f'The labels are **{labels}**')

*# setting the size of images that we want*

image_size = 256
print(f'All images to be resized into **{image_size}*****{image_size}** pixels')

输出-

文件夹名称被设置为图像的标签,并且图像尺寸被选择为 256256。也就是说,所有图像的大小都将调整为 256256。如果我们浏览数据集,我们会看到所有的图像都有不同的维度,为了将图像输入到卷积神经网络(CNN)中,有必要将图像调整到相同的维度。

*# defining a function to load images and labels together*
*# this function will also resize the images*

**def** load_train(path):

    images = []

    **for** label **in** labels:
        direc = os.path.join(path, label)
        class_num = labels.index(label)

        **for** image **in** os.listdir(direc):
            image_read = cv.imread(os.path.join(direc,image),cv.IMREAD_GRAYSCALE)
            image_resized = cv.resize(image_read,(image_size,image_size))
            images.append([image_resized,class_num])

    **return** np.array(images)

这里我们定义了一个函数,根据标签名称加载所有图像,将它们的大小调整为 256*256 像素,并返回图像数组。

创建一个空列表来保存所有图像。然后运行“for”循环,从所有三个文件夹中提取所有图像。os.path.join 用于合并目录中的路径。简历。im read _ gray 将所有图像转换为灰度格式。cv.resize 用于将图像大小调整为 256*256 像素。。“append”用于将所有图像追加到一个列表中,该列表最终被转换为一个数组并使用 return 语句返回。

*#load all the training images to train_images*

train_images = load_train(path)

print(f'Shape of the training images = **{train_images.shape}**')

训练图像的输出形状= (5208,2)

然后调用函数“load_train ”,所有训练图像都作为数组保存在 train_images 中。训练图像的形状为(5208,2)

*#loading the images and labels seperately in X and y, to be used later for training*X = []
y = []

**for** feature, label **in** train_images:
    X.append(feature)
    y.append(label)

print (f'Length of X = {len(X)}')
print (f'Length of y = {len(y)}')

输出-

为了训练神经网络,需要分离图像和标签,并且通过在 train_images 上循环,并且通过提取图像和它们相应的标签来完成。

*# checking the number of images of each class*

a = 0
b = 0
c = 0

**for** label **in** y:
    **if** label == 0:
        a += 1
    **if** label == 1:
        b += 1
    **if** label == 2:
        c += 1

print (f'Number of Normal images = **{a}**')
print (f'Number of Bacteria images = **{b}**')
print (f'Number of Virus images = **{c}**')

*# plotting the data*

x_pos = [i **for** i, _ **in** enumerate(labels)]
numbers = [a,b,c]
plt.bar(x_pos,numbers,color = 'green')
plt.xlabel("Labels")
plt.ylabel("No. of images")
plt.title("Images for each label")

plt.xticks(x_pos, labels)

plt.show()

输出-

为了检查每个类中的图像数量,运行了一个 for 循环。然后使用用于创建条形图的 matplotlib.bar 绘制结果。

从数据中可以清楚地看出,属于每个标签的图像数量有很大的差异。如果用这些数量的图像训练网络,它可能会偏向具有最多标签的类。这就是所谓的阶级不平衡问题。因此,每个类有相似数量的图像是必要的,我们将在下一部分讨论这一点。

*# Displays images* 
*# Extract 9 random images*
print('Display Random Images')

*# Adjust the size of your images*
plt.figure(figsize=(20,10))

**for** i **in** range(9):
    num = random.randint(0,len(X)-1)
    plt.subplot(3, 3, i + 1)

    plt.imshow(X[num],cmap='gray')
    plt.axis('off')

*# Adjust subplot parameters to give specified padding*
plt.tight_layout()

最后,我们使用随机模块从训练集中生成九幅随机图像,然后使用 matplotlib 绘制这些图像。

这是这部分的结尾。正如我们所见,对于医学成像分析来说,正确理解数据集是非常重要的,在本例中是 X 射线图像。在下一部分中,我们将使用 matplotlib 和 OpenCV 处理类不平衡问题和更多操作。

参考资料:

  1. 从丹尼尔-克马尼获得的数据集;张、康;Goldbaum,Michael (2018),“用于分类的标记光学相干断层扫描(OCT)和胸部 X 射线图像”,Mendeley Data,v2 http://dx . doi . org/10.17632/rscb jbr 9 SJ。
  2. 通过基于图像的深度学习识别医学诊断和可治疗的疾病- (2018),作者:Daniel S. Kermany,Michael Goldbaum,Cai,Carolina C.S. Valentim,Huiying Liang,Sally L. Baxter,Alex McKeown,Ge Yang,Xiaokang Wu,Yan,Justin Dong,Made K. Prasadha,Jacqueline Pei,Magdalene Y.L. Ting,,Christina Li,Sierra Hewett 等,出版物:Cell Publisher。

医疗保健中的深度学习——X 射线成像(第 4 部分——类别失衡问题)

原文:https://towardsdatascience.com/deep-learning-in-healthcare-x-ray-imaging-part-4-the-class-imbalance-problem-364eff4d47bb?source=collection_archive---------22-----------------------

这是深度学习在 X 射线成像上的应用的第 4 部分。这里的重点是解决阶级不平衡问题的各种方法。

正如我们在上一部分—第三部分—(https://towards data science . com/deep-learning-in-health care-x-ray-imaging-Part-3-analyzing-images-using-python-915 a 98 fbf 14 c)中看到的,胸部 x 光数据集存在图像的不平衡。这是我们在上一部分看到的每个类的图像的条形图。

图一。各个阶层形象的不平衡(作者图片)

在医学成像数据集中,这是一个非常常见的问题。由于大多数情况下,数据是从各种不同的来源收集的,并且不是所有的疾病都像其他疾病一样流行,所以数据集往往是不平衡的。

那么,如果我们在不平衡的数据集上训练神经网络,会出现什么问题呢?答案是,与图像较少的班级相比,网络倾向于从图像较多的班级学到更多东西。也就是说,在这种情况下,该模型可能预测更多的图像是“细菌性肺炎”,即使这些图像可能来自其他两个类别,这在处理医学图像时是不期望的结果。

此外,应该注意,在处理医学图像时,模型的最终精度(训练精度或验证精度)不是模型性能所基于的正确参数。因为,即使模型在特定类别上表现不佳,但是在具有最大图像的类别上表现良好,准确度仍然会很高。实际上,我们希望模型在所有的类中都表现良好。因此,还有其他参数,如灵敏度(召回率/真阳性率(TPR))、特异性(真阴性率(TNR))、精确度或阳性预测值(PPV)和 F 值,这些参数应该被考虑来分析训练模型的性能。我们将在后面讨论混淆矩阵的部分详细讨论这些。

还必须维护一组单独的图像,在这些图像上,模型既没有被训练也没有被验证,以便检查模型如何在它以前从未见过的图像上执行。这也是分析模型性能的必修步骤。

解决阶级不平衡的各种方法:

有各种各样的方法来解决阶级不平衡的问题。最好的方法是为少数民族阶层收集更多的图像。但是在某些情况下这是不可能的。在这种情况下,通常这三种方法是有益的:a. 加权损失 b. 欠采样 c. 过采样

我们将详细介绍每种方法:

  1. 更新损失函数—加权损失

假设我们用的是 二元交叉熵损失函数 。损失函数看起来像这样-

L(X,y) = - log P(Y =1 |X)如果 Y =1 和-log P(Y=0 |X)如果 y=0

这测量分类模型的输出,其输出在 0 和 1 之间。(这个损失函数只有在我们做二元分类问题的时候才起作用。对于多个类别,我们使用分类交叉熵损失或稀疏分类交叉熵损失。我们将在后面的部分讨论基本的损失函数)。

示例-如果图像的标签为 1,并且神经网络算法预测标签为 1 的概率为 0.2。

让我们应用损失函数来计算本例的损失。请注意,我们对标签 1 感兴趣。所以,我们要用损失函数 L 的第一部分,损失 L 是-

L =-log 0.2 = 0.70

这是算法在这个例子中得到的损失。

对于另一个标签为 0 的图像,如果算法预测该图像为标签 0 的概率为 0.7,那么我们使用损失函数的第二部分,但实际上不能直接使用。相反,我们使用不同的方法。我们知道最大概率可以是 1,所以我们计算标签的概率是 1。

在这种情况下,L =-log(1–0.7)=-log(0.3)= 0.52

现在我们来看多个例子,关于阶级不平衡。

图一。阶级不平衡,概率和计算损失(来源:图片由作者创建)

在图 1 中,我们看到总共有 10 个图像,但是其中 8 个属于类标签 1,只有两个属于类标签 0。因此,这是一个典型的阶级不平衡问题。假设所有预测的概率都是 0.5,

标签 1 的损耗 L =-log(0.5)= 0.3,

标签 0 的损耗 L =-log(1–0.5)=-log(0.5)= 0.3

因此,标签 1 的总损耗= 0.3 x 8 = 2.4

而标签 0 的总损耗= 0.3 x 2 = 0.6

因此,损失的大部分来源于标签为 1 的类。因此,与标签为 0 的图像的权重相比,更新权重时的算法更倾向于更新标签为 1 的图像的权重。这并不能产生一个非常好的分类器,这就是类不平衡问题

类别不平衡问题的解决方案是修改损失函数,以不同地加权 1 和 0 类别

w1 是我们分配给标签 1 示例的权重,w0 是分配给标签 0 示例的权重。新的损失函数,

如果 Y =1,L = w1 x -log(Y =1 |X ),并且,

如果 Y=0,L = w0 x -log P(Y=0 |X)

我们希望给予图像较少的类比图像较多的类更多的权重。因此,在这种情况下,我们给 8 个例子中的类 1 的权重为 2/10 = 0.2,给 2 个例子中的类 0 的权重为 8/10 = 0.8。

通常,使用下面的公式计算权重,

w1 =标签为 0 的图像数/图像总数= 2/10

w0 =标签为 1 的图像数量/图像总数= 8/10

下面是使用加权损失的更新损失表。

图二。更新的加权损失(来源:图片由作者创建)

因此,对于新的计算,我们只需将损失与各个类别的权重相乘。如果我们计算总损失,

标签 1 的总损耗= 0.06×8 = 0.48

标签 0 的总损耗= 0.24 x 2 = 0.48

现在这两类都有相同的总损失。因此,即使两个类别具有不同数量的图像,该算法现在也会平等地对待这两个类别,并且分类器会正确地对具有非常少图像的类别的图像进行分类。

2。缩减采样

缩减像素采样是从包含最多图像的类中移除图像,以使其与包含较少图像的类具有可比性的过程。

例如,在肺炎分类问题中,我们看到,与 1341 个正常肺炎图像和 1337 个病毒性肺炎图像相比,有 2530 个细菌性肺炎图像。因此,我们可以从细菌性肺炎类中删除大约 1200 幅图像,这样所有类都有相似数量的图像。

这对于具有属于每个类的大量图像的数据集是可能的,并且移除一些图像不会损害神经网络的性能。

3。过采样

过采样是将更多图像添加到少数类以使少数类中的图像数量与多数类中的图像数量相似的过程。

这可以通过简单地复制少数类中的图像来实现。直接复制同一个图像两次,会导致网络过载。因此,为了减少过度拟合,我们可以使用一些人工数据增强来为少数民族创建更多的图像。(这也确实会导致一些过度拟合,但这是一种比直接复制原始图像两到三次好得多的技术)

这是我们在肺炎分类任务中使用的技术,网络工作得相当好。

接下来,我们看一下生成人工数据集的 python 代码。

**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **cv2** **as** **cv**
**import** **matplotlib.pyplot** **as** **plt**
**import** **os**
**import** **random**

**from** **sklearn.model_selection** **import** train_test_split

我们之前看过所有的库,除了 sklearn。

sklearn — Scikit-learn(又名sklearn)是一个针对 python 的机器学习库。包含了分类、回归、支持向量机、随机森林等所有著名的机器学习算法。它也是一个非常重要的机器学习数据预处理库。

image_size = 256

labels = ['1_NORMAL', '2_BACTERIA','3_VIRUS']

**def** create_training_data(paths):

    images = []

    **for** label **in** labels:
        dir = os.path.join(paths,label)
        class_num = labels.index(label)

        **for** image **in** os.listdir(dir):
            image_read = cv.imread(os.path.join(dir,image))
            image_resized = cv.resize(image_read,(image_size,image_size),cv.IMREAD_GRAYSCALE)
            images.append([image_resized,class_num])

    **return** np.array(images)train = create_training_data('D:/Kaggle datasets/chest_xray_tf/train')X = []
y = []

**for** feature, label **in** train:
    X.append(feature)
    y.append(label)

X= np.array(X)
y = np.array(y)
y = np.expand_dims(y, axis=1)

上面的代码调用训练数据集并加载 X 中的图像和 y 中的标签。第 3 部分已经提到了详细信息—(https://towardsdatascience . com/deep-learning-in-health care-X-ray-imaging-Part-3-analyzing-images-using-python-915 a 98 fbf 14 c)。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state = 32, stratify=y)

因为我们只有训练和验证数据,没有测试数据,所以我们使用 sklearn 的 train_test_split 创建测试数据。它用于将整个数据分割成训练和测试图像和标签。我们将整个数据的 20%分配给测试集,因此设置“test_size = 0.2”,random_state 在第一次混洗数据,但在下一次运行时保持它们不变,并用于在每次运行 train_test_split 时不混洗图像,分层在这里很重要,因为数据是不平衡的,因为分层确保在训练和测试集中每个类别的图像有相等的分割。

重要说明—过采样应在训练数据上进行,而不是在测试数据上进行。如果测试数据包含人工生成的图像,我们将看到的分类器结果将不会正确解释网络实际学习了多少。因此,更好的方法是首先拆分训练和测试数据,然后只对训练数据进行过采样。

*# checking the number of images of each class*

a = 0
b = 0
c = 0

**for** label **in** y_train:
    **if** label == 0:
        a += 1
    **if** label == 1:
        b += 1
    **if** label == 2:
        c += 1

print (f'Number of Normal images = **{a}**')
print (f'Number of Bacteria images = **{b}**')
print (f'Number of Virus images = **{c}**')

*# plotting the data*

xe = [i **for** i, _ **in** enumerate(labels)]

numbers = [a,b,c]
plt.bar(xe,numbers,color = 'green')
plt.xlabel("Labels")
plt.ylabel("No. of images")
plt.title("Images for each label")

plt.xticks(xe, labels)

plt.show()

输出-

所以现在我们看到了。训练集具有 1226 幅正常图像、2184 幅细菌性肺炎图像和 1154 幅病毒性肺炎图像。

#check the difference from the majority classdifference_normal = b-a
difference_virus = b-c

print(difference_normal)
print(difference_virus)

输出—

958

1030

解决不平衡—

**def** rotate_images(image, scale =1.0, h=256, w = 256):

    center = (h/2,w/2)

    angle = random.randint(-25,25)
    M = cv.getRotationMatrix2D(center, angle, scale)
    rotated = cv.warpAffine(image, M, (h,w))
    **return** rotated

**def** flip (image):

    flipped = np.fliplr(image)
    **return** flipped

**def** translation (image):

    x= random.randint(-50,50)
    y = random.randint(-50,50)
    rows,cols,z = image.shape
    M = np.float32([[1,0,x],[0,1,y]])
    translate = cv.warpAffine(image,M,(cols,rows))

    **return** translate

**def** blur (image):

    x = random.randrange(1,5,2)
    blur = cv.GaussianBlur(image,(x,x),cv.BORDER_DEFAULT)
    **return** blur

我们将使用 4 种类型的数据扩充方法,使用 OpenCV 库-1。旋转-从-25 度到+25 度任意旋转,2。水平翻转图像,3。平移,x 轴和 y 轴随机设置,4。高斯模糊随机。

有关如何使用 OpenCV 实现数据增强的详细信息,请访问以下链接—https://opencv.org

**def** apply_aug (image):

    number = random.randint(1,4)

    **if** number == 1:
        image= rotate_images(image, scale =1.0, h=256, w = 256)

    **if** number == 2:
        image= flip(image)

    **if** number ==3:
        image= translation(image)

    **if** number ==4:
        image= blur(image)

    **return** image

接下来,我们定义另一个函数,这样所有的扩充都是完全随机应用的。

**def** oversample_images (difference_normal,difference_virus, X_train, y_train):

    normal_counter = 0
    virus_counter= 0
    new_normal = []
    new_virus = []
    label_normal = []
    label_virus = []

    **for** i,item **in** enumerate (X_train):

        **if** y_train[i] == 0 **and** normal_counter < difference_normal:

            image = apply_aug(item)

            normal_counter = normal_counter+1
            label = 0

            new_normal.append(image)
            label_normal.append(label)

        **if** y_train[i] == 2 **and** virus_counter < difference_virus:

            image = apply_aug(item)

            virus_counter = virus_counter+1
            label =2

            new_virus.append(image)
            label_virus.append(label)

    new_normal = np.array(new_normal)
    label_normal = np.array(label_normal)
    new_virus= np.array(new_virus)
    label_virus = np.array(label_virus)

    **return** new_normal, label_normal, new_virus, label_virus

该功能为正常和病毒性肺炎图像创建所有人工增强图像,直到它们达到与总细菌性肺炎图像的差值。然后,它返回新创建的正常和病毒性肺炎图像和标签。

n_images,n_labels,v_images,v_labels =oversample_images(difference_normal,difference_virus,X_train,y_train)print(n_images.shape)
print(n_labels.shape)
print(v_images.shape)
print(v_labels.shape)

输出—

我们看到,正如预期的那样,创建了 958 幅正常图像和 1030 幅病毒性肺炎图像。

让我们想象一些人造的正常图像,

*# Extract 9 random images*
print('Display Random Images')

*# Adjust the size of your images*
plt.figure(figsize=(20,10))

**for** i **in** range(9):
    num = random.randint(0,len(n_images)-1)
    plt.subplot(3, 3, i + 1)

    plt.imshow(n_images[num],cmap='gray')
    plt.axis('off')

*# Adjust subplot parameters to give specified padding*
plt.tight_layout()

输出-

接下来,让我们想象一些人造病毒性肺炎的图像,

*# Displays 9 generated viral images* 
*# Extract 9 random images*
print('Display Random Images')

*# Adjust the size of your images*
plt.figure(figsize=(20,10))

**for** i **in** range(9):
    num = random.randint(0,len(v_images)-1)
    plt.subplot(3, 3, i + 1)

    plt.imshow(v_images[num],cmap='gray')
    plt.axis('off')

*# Adjust subplot parameters to give specified padding*
plt.tight_layout()

输出-

上面生成的每张图像都有某种程度的增强——旋转、平移、翻转或模糊,所有这些都是随机应用的。

接下来,我们将这些人工图像及其标签与原始训练数据集合并。

new_labels = np.append(n_labels,v_labels)
y_new_labels = np.expand_dims(new_labels, axis=1)
x_new_images = np.append(n_images,v_images,axis=0)

X_train1 = np.append(X_train,x_new_images,axis=0)
y_train1 = np.append(y_train,y_new_labels)

print(X_train1.shape)
print(y_train1.shape)

输出—

现在,训练数据集有 6552 幅图像。

bacteria_new=0
virus_new=0
normal_new =0

**for** i **in** y_train1:

    **if** i==0:
        normal_new = normal_new+1
    **elif** i==1 :
        bacteria_new = bacteria_new+1
    **else**:
        virus_new=virus_new+1    

print ('Number of Normal images =',normal_new)
print ('Number of Bacteria images = ',bacteria_new)
print ('Number of Virus images =',virus_new)

*# plotting the data*

xe = [i **for** i, _ **in** enumerate(labels)]

numbers = [normal_new, bacteria_new, virus_new]
plt.bar(xe,numbers,color = 'green')
plt.xlabel("Labels")
plt.ylabel("No. of images")
plt.title("Images for each label")

plt.xticks(xe, labels)

plt.show()

输出—

最后,我们在训练数据集中取得了平衡。我们在所有三个类中有 2184 个图像。

这就是我们解决阶级不平衡问题的方法。请随意尝试其他方法,并与最终结果进行比较。

既然在下一部分中处理了类不平衡问题,我们将研究使用 Keras 和 TensorFlow 的图像规范化和数据增强。

医疗保健中的深度学习——X 射线成像(第 5 部分——数据扩充和图像标准化)

原文:https://towardsdatascience.com/deep-learning-in-healthcare-x-ray-imaging-part-5-data-augmentation-and-image-normalization-1ead1c02cfe3?source=collection_archive---------25-----------------------

这是深度学习在 X 射线成像上的应用的第 5 部分。这里的重点是实现数据扩充的各种方法。

我们在上一部分—第四部分—https://towards data science . com/deep-learning-in-health care-x-ray-imaging-Part-4-the-Class-distribution-Problem-364 eff 4d 47 bb中看到了如何解决阶层失衡问题。在本节中,我们将重点关注图像规范化和数据扩充。

在解决了类不平衡问题之后,接下来我们来看看如何提高神经网络的性能并使其更快。在训练数据的三个类中,我们已经有了相似数量的图像— 1。正常(无感染),2。细菌性肺炎,3。病毒性肺炎。

每一类中图片数量的条形图——图片来自第四部分(来源:图片由作者创建)

图像缩放/归一化:

当所有特征都在同一尺度上时,神经网络工作得最好。类似地,当特征以平均值零为中心,标准偏差为 1时,梯度下降等优化算法工作得非常好,即数据具有标准正态分布的属性。

这可以通过如下所示的几种方式来实现。

案例 1:不推荐

scaled_dataset = (dataset - dataset_mean) / dataset_std_deviation

train, test = split(scaled_dataset)

整个数据集被缩放,然后分成训练集和测试集。

案例 2:不推荐

train, test = split(dataset)

scaled_train =  (train - train_mean) / train_std_deviation

scaled_test = (test - test_mean) / test_std_deviation

数据集被分成训练集和测试集,然后分别对训练集和测试集进行缩放。

案例三:推荐

train, test = split(dataset)scaled_train =  (train - train_mean) / train_std_deviation

scaled_test = (test - train_mean) / train_std_deviation

数据集被分成训练集和测试集。然后对训练图像进行缩放。为了缩放测试图像,我们使用训练集的平均值和标准偏差,而不是测试图像的平均值和标准偏差。

使用训练集的均值和标准差来衡量测试集可能看起来很奇怪,但是案例 3 是遵循的最佳方法。原因是:

测试数据是模型的“看不见的数据”,我们使用测试数据来检查模型在看不见的数据下的表现,也就是说,它给出了一个很好的估计,即模型是否可以在现实世界中使用。

现在,在真实的场景中,我们可能没有一批测试图像来测试我们的模型,而是只有一个图像。在这种情况下,不可能在单个图像上计算平均值和标准偏差。此外,在多个图像的情况下,知道每批测试数据的平均值将有效地给我们的模型带来优势,并且我们不希望模型具有关于测试数据的任何信息。

因此,解决这个问题的最佳方式是使用案例 3,并使用从训练集计算的统计数据来规范化传入的测试数据。然后,我们将使用这些统计数据来转换我们的测试数据和以后的任何数据。

数据扩充:

数据扩充是一种策略,使从业者能够显著增加可用于训练模型的数据的多样性,而无需实际收集新数据。[1]

在第 4 部分(https://towards data science . com/deep-learning-in-health care-x-ray-imaging-part-4-the-class-unbalancy-problem-364 eff 4d 47 bb)中,我们已经看到了如何通过使用数据增强来创建人工图像。我们使用 OpenCV 来旋转、平移、翻转和模糊图像。在这里,我们研究如何在 Keras 中进行数据扩充。

数据增强的优势:

  1. 改进模型结果
  2. 防止过度拟合

为了实现这一点,我们将使用 Keras 框架中的 ImageDataGenerator 类。ImageDataGenerator 通过实时数据扩充帮助生成批量张量图像数据。也就是说,它可以执行所有这些操作:

  1. 生成数据框中指定的批量图像。
  2. 允许基本的数据扩充技术,如翻转、缩放、缩放、旋转等。
  3. 转换每批中的值,使它们的平均值为 1,标准偏差为 1。这通过标准化输入分布来帮助模型训练。
  4. 它还通过在所有通道上重复图像中的值,将单通道 X 射线图像(灰度)转换为三通道格式。我们需要这样做,因为我们稍后将用来训练模型的预训练模型需要三通道输入。

实现 ImageDataGenerator:

下面的代码是第 3 部分和第 4 部分代码的延续:

第三部分链接—https://towards data science . com/deep-learning-in-health care-x-ray-imaging-part-3-analyzing-images-using-python-915 a 98 fbf 14 c

第四部分链接—https://towards data science . com/deep-learning-in-health care-x-ray-imaging-part-4-the-class-unbalancy-problem-364 eff 4d 47 bb

**def** get_train_generator(X_train,y_train, batch_size = 32, shuffle = **True**, seed = 1):

    print("getting train generator...") 
    *# normalize and augment images*
    image_generator = ImageDataGenerator(
        samplewise_center=**True**,
        samplewise_std_normalization= **True**,
        rotation_range = 15,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        fill_mode="nearest",
        cval=0.0,
        rescale = 0.2)

    generator = image_generator.flow(
            X_train,
            y=y_train,
            shuffle=shuffle,
            batch_size=batch_size,
            seed=seed
            )

    **return** generator

上面的代码片段为训练集实现了 ImageDataGenerator。ImageDataGenerator 成批接受图像。这里,批量大小设置为 32,因此它将一次生成 32 个图像。

samplewise_center=**True**,
samplewise_std_normalization= **True**

这实现了图像标准化。它将图像像素居中到平均值 0,标准偏差为 1。

这就是 Keras 在不需要使用任何公式的情况下进行图像规范化/标准化/缩放的方式。

可视化 ImageDataGenerator 如何工作:

通过一张猫的图片,我们可以看到 ImageDataGenerator 中的各种增强功能是如何工作的

#importing the necessary libraries**import** **cv2** **as** **cv**
**import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**

**from** **tensorflow.keras.preprocessing.image** **import** load_img
**from** **tensorflow.keras.preprocessing.image** **import** img_to_array
**from** **tensorflow.keras.preprocessing.image** **import** ImageDataGenerator#define a function to display 9 augmented images**def** show_image(iterator):

    *# generate samples and plot*
    **for** i **in** range(9):
        plt.subplot(330 + 1 + i)
        batch = iterator.next()
        image = batch[0].astype('uint8')
        plt.imshow(image)
    plt.show()#load and display the original imageimg = load_img('cat.jpg') 
plt.imshow (img) 
data = img_to_array(img) 
samples = np.expand_dims(data, 0)

***# height_shift_range***datagen = ImageDataGenerator(height_shift_range=0.5)
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

***# width_shift_range***datagen = ImageDataGenerator(width_shift_range=0.5)
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

***# rotation_range*** datagen = ImageDataGenerator(rotation_range = 50)
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

***# shear_range*** datagen = ImageDataGenerator(shear_range = 50)
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

***# brightness_range*** datagen = ImageDataGenerator(brightness_range = [0.3,1.9])
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

***# zoom_range***datagen = ImageDataGenerator(zoom_range = [0.5,1.5])
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

***# flip***datagen =ImageDataGenerator(horizontal_flip=**True**,vertical_flip=**True**)
iterator = datagen.flow(samples, batch_size=1)

show_image(iterator)

从图片来看,我相信 ImgaeDataGenerator 中每个函数的作用是可以理解的。更多详情请访问以下链接—【https://keras.io/api/preprocessing/image/

回到 X 射线图像,我们已经看到了如何在训练集上实现 ImageDataGenerator。但是我们不应该直接在测试集上实现,就像在案例 3 的图像缩放/归一化中看到的那样(如上所述)。因此,我们为测试和验证集构建了一个单独的生成器。

**def** get_test_val_generator(X_train,y_train,X_test,y_test,X_val,y_val,
                      batch_size=32, seed=1, sample_size=100):

    raw_train_generator = ImageDataGenerator().flow(
        X_train,y_train, 
        batch_size=sample_size, 
        shuffle=**False**)

    *# get data sample*
    batch = raw_train_generator.next()
    data_sample = batch[0]

    *# use sample to fit mean and std for test set generator*
    image_generator = ImageDataGenerator(
        featurewise_center=**True**,
        featurewise_std_normalization= **True**)

    *# fit generator to sample from training data*
    image_generator.fit(data_sample)

    *# get test generator*
    test_generator = image_generator.flow(
            X_test,
            y=y_test,
            batch_size=batch_size,
            shuffle=**False**,
            seed=seed)

    *#get validation generator*
    val_generator = image_generator.flow(
            X_val,
            y=y_val,
            batch_size=batch_size,
            shuffle=**False**,
            seed=seed)

    **return** test_generator,val_generator

在这个实现中,我们使用训练集的统计数据,并将其应用于测试和验证集。理想情况下,我们希望使用整个训练集来计算样本均值和标准差。
然而,由于这非常大,这将非常耗时。
因此,我们随机抽取数据集样本(在本例中为 100 张图像),并计算样本均值和样本标准差。

接下来,我们创建训练、测试和验证生成器。

***#create the train, test and validation generator* ** train_generator = get_train_generator(X_train,y_train) test_generator,valid_generator = get_test_val_generator(X_train,y_train,X_test,y_test,X_val,y_val)

在生成器被创建之后,我们可视化一些来自训练和测试生成器的图像,看看它们看起来如何。

***# Displays 9 generated train_generator images*** 

print('Display Random Images')

*# Adjust the size of your images*
plt.figure(figsize=(20,10))

**for** i **in** range(12):
    num = random.randint(1,30)
    plt.subplot(3,4, i + 1)

    x,y = train_generator.__getitem__(num)

    plt.imshow(x[num],cmap='gray')
    plt.axis('off')

*# Adjust subplot parameters to give specified padding*
plt.tight_layout()

***# Displays 9 generated test_generator images * ** print('Display Random Images') *# Adjust the size of your images* plt.figure(figsize=(20,10))  
   **for** i **in** range(12):     
   num = random.randint(1,17)     
   plt.subplot(3,4, i + 1)          
   x,y = test_generator.__getitem__(num)
   plt.imshow(x[num],cmap='gray')     
   plt.axis('off')    

*# Adjust subplot parameters to give specified padding* plt.tight_layout()

我们看到图像现在在训练和测试生成器中都被归一化了,但是我们仅在训练生成器上应用了增强,因为神经网络仅在训练图像上训练,并且我们不想干扰测试或验证图像。

图像被标准化和增强,现在可以输入神经网络。在下一部分中,我们将设计一个神经网络,看看它在将 X 射线图像适当分类到所有三个类别中的效果如何。在后面的部分,我们还将看到如何使用迁移学习进一步改善这些结果。

参考资料:

  1. https://bair.berkeley.edu/blog/2019/06/07/data_aug

组织病理学中的深度学习(下)

原文:https://towardsdatascience.com/deep-learning-in-histopathology-35c0294d38eb?source=collection_archive---------40-----------------------

计算机视觉/深度学习/医学成像

文献综述

在最后一部分的中,我们开始了关于深度学习在组织病理学中的现状的介绍性讨论,我们讨论了组织病理学、数字组织病理学、机器学习在该领域的可能性以及各种应用,随后详细讨论了处理数字显微切片图像以及将深度学习算法应用于这些图像所涉及的挑战。

在这篇博客中,我们将从方法论的角度更详细地讨论深度学习对组织病理学的适用性,以及它使用相关工作进行说明来帮助完成的任务。

深度学习的适用性可以根据它执行的任务或学习范式来研究,这是我们将在这篇文章中使用的分类。不同的学习算法,即用于组织病理学的深度学习,以及任务在以下概述中进行了可视化。

图:这里看到的是计算组织病理学中的深度神经网络模型、各种应用和任务的概述。来源: 斯里尼迪等人

基于这些,在文献中已经提出了许多 DL 模型,这些模型传统上基于卷积神经网络(CNN)、递归神经网络(RNNs)、生成对抗网络(GANs)、自动编码器(AEs)和其他变体。

监督学习

在监督学习技术中,我们根据数字组织病理学中解决的任务的性质确定了三种主要的规范深度学习模型:分类、回归和分割。

监督分类法

它可以进一步细分为局部和全球一级的分类。 局部级别分类 需要识别整个载玻片图像的小块中的细胞或细胞核。深度学习已被证明在通过滑动窗口方法对图像补片进行逐像素预测方面非常成功,病理学家将这些图像补片标注为包含感兴趣对象(细胞/细胞核)或背景的区域。
局部分类中最突出的工作之一出现在 2019 年,当时 Qaiser 等人在其论文中使用轮廓作为区分特征,以便通过将斑块分类为肿瘤区域或正常区域来分割结肠肿瘤区域。持续同源性分布图是一个区域的紧凑的数学特征表示,对于输入数据、维度和坐标中的规模、扰动具有独特性和鲁棒性。
他们将训练数据集的 PHP 与使用 CNN 提取的特征结合起来使用,然后对它们分别使用随机森林回归,随后使用多阶段集成策略进行最终分类。这种混合方法被证明是既准确又高效的 wrt 推理速度。
全局水平分类 中,大部分已发表的工作都集中在一种基于面片的分类方法上,用于全切片水平的疾病预测任务。它可以包括小块水平的定位以及整个载玻片水平的疾病分类或分级。这些方法的主要缺点是在整个 WSI 上进行密集的逐块预测需要相对较长的计算时间。不同的作品以不同的方式处理这个问题,一些使用
启发式采样策略到最近的使用基于任务驱动 视觉注意 的粗处理。**

图:基于视觉注意力的观察、调查和分类模型的流程。来源: 徐等(2019)

【徐】在他们的工作中,通过硬视觉注意算法自适应地从原始图像中选择一系列粗糙区域,然后对于每个这样的区域,能够基于软注意机制来调查异常部分。然后,在顶部构建一个递归网络以对图像区域进行分类,并且还预测在下一时间步要研究的图像区域的位置。这样,分类只需要调查一小部分像素

将基于视觉注意力的模型用于整个幻灯片图像全局分类任务的优点是:

  • 该模型试图只学习对疾病预测最相关的诊断有用的区域,因为它实施了区域选择机制。
  • 模型的复杂度与 WSI 的大小无关。

哈利切克、马丁等人 进行的另一项全球分类的近期工作使用 CNN 使用完全不同的方法对鳞状细胞癌【SCC】甲状腺细胞癌进行基于补丁的定位和全切片分类。
从每个概述的组织学载玻片产生癌症区域的地面实况二元掩模。使用 最近邻插值 将 WSIs 和相应的地面实况向下采样四倍。然后将降采样后的载玻片分成大小为 101 x 101 的小块。为了确保通用性,通过应用 90 度旋转和反射,图像补片的数量增加了 8x ,以开发一种更强大的诊断方法。此外,为了建立颜色特征不变性和对载玻片之间的 H & E 染色 的差异的容忍度的水平,在馈送到用于检测头颈癌的 Inception-v4 模型之前,随机操纵每个块的色调、饱和度、亮度和对比度,以形成更严格的训练范例。

监督回归

在这种方法中,我们集中于直接回归像素作为对象中心的可能性,以检测或定位对象。与分类不同,回归给我们一个连续的值,通常是概率分数,而不是简单的作为输出的类别标签。回归有助于通过加强拓扑约束进行更好的检测,例如为靠近对象中心的像素分配更高的概率值。
回归也有助于应对细胞/细胞核检测中面临的挑战,这些挑战是由于高度不规则的外观以及它们作为重叠的团块出现而导致分离它们的问题而引起的。文献中提出的深度回归模型主要基于 CNN 或 全卷积网络(FCN) 架构。

格雷厄姆等人HoVer-Net 上发表的论文是整个研究领域中最具开创性的作品之一。它提出了一个统一的 FCN 模型,同时核实例分割和分类。它利用核像素到其质心的垂直和水平距离内编码的丰富实例信息。然后利用这些距离来分离成簇的细胞核,从而产生精确的分割,特别是在具有重叠实例的区域中。
然后,对于每个分割的实例,网络通过专用的上采样分支预测细胞核的类型。该网络由用于三种不同任务的三个平行分支组成。对于三个分支中的每一个,我们都有相应的数据基础事实注释。

  • 细胞核像素(NP) 分支预测像素是否属于细胞核或背景,
  • 水平-垂直(悬停)分支预测核像素到其质心的水平和垂直距离。这里,颜色表示每个核像素到质心的距离的等级。
  • 蓝色代表最大+1 的正距离,表示像素在水平贴图的情况下位于 COM 的左侧,在垂直贴图的情况下位于 COM 的上方。类似地,红色表示负距离,最大为-1,意味着像素相应地位于 COM 的右侧/底部。
  • 然后,细胞核分类(NC) 分支(可选)预测每个像素的细胞核类型。

图:由一个编码器和三个并行解码器组成的 HoVernet 架构 FCN 网络。来源: 格雷厄姆等人

具体来说, NPHoVer 分支通过先从背景中分离出细胞核像素(NP 分支),再分离出接触细胞核( HoVer 分支)共同实现细胞核实例分割。这是用于组织的定位和聚类步骤的相同模型,用于将整个载玻片图像建模为图形,以便使用 图形神经网络 进行后续学习,如前一篇文章中所述。

在我们关于组织病理学深度学习讨论的下一个也是最后一个部分,我们将讨论数字组织病理学背景下的监督分割、弱监督和非监督学习方法,以及适当的应用和相关文献。

PS:我已经将技术上重要的术语链接到解释它们的相应资源。

参考

  1. Qaiser,Tsang,Y.W .,Taniyama,d .,Sakamoto,n .,Nakane,k .,Epstein,d .,Rajpoot,n .,2019b .利用持续同源性和深度卷积特征快速准确地分割组织学图像中的肿瘤。医学图像分析 55,1–14。
  2. 徐,b,刘,j,侯,x,刘,b,加里波第,j,埃利斯,国际组织,格林,a,沈,l,邱,g,2019。看,调查,分类:乳腺癌分类的深度混合注意方法,载于:2019 IEEE 第 16 届国际生物医学成像研讨会(ISBI 2019),第 914–918 页。
  3. 使用卷积神经网络进行数字化全切片组织学中的头颈癌检测。科学报告9.1(2019):1–11。
  4. Graham,s .,Vu,Q.D .,Raza,S.E.A .,Azam,a .,Tsang,Y.W .,Kwak,J.T .,Rajpoot,n . 2019 b .Hover-net:多组织组织学图像中细胞核的同时分割和分类。医学图像分析 58,101563。
  5. 斯里尼迪,切坦 l,奥赞西加和安妮 l 马特尔。"用于计算组织病理学的深度神经网络模型:综述." arXiv 预印本 arXiv:1912.12378 (2019)。

Java 中的深度学习

原文:https://towardsdatascience.com/deep-learning-in-java-d9b54ae1423a?source=collection_archive---------10-----------------------

乌列尔 SCUnsplash 上拍摄的照片

DeepJavaLibrary 简介:一个开源的、与引擎无关的、用于训练和推理的深度学习 Java 库

长久以来,Java 一直是企业中[最受欢迎的编程语言之一,拥有一个庞大的库、框架和开发人员社区的生态系统。然而,Java 为深度学习应用程序提供的选项非常有限。目前,大多数深度学习模型都是用 Python 编写和训练的。这为想要进入这一领域的 Java 开发人员带来了额外的进入壁垒,因为他们必须学习一种新的编程语言和复杂的深度学习领域。

为了降低 Java 开发者进入深度学习的门槛,AWS 构建了](https://www.cloudfoundry.org/wp-content/uploads/Developer-Language-Report_FINAL.pdf) Deep Java Library (DJL) ,这是一个开源的 Java 深度学习框架,通过支持任何深度学习引擎,如 Apache MXNet、PyTorch 或 TensorFlow,在 Java 中原生运行训练和推理,为 Java 开发者搭建桥梁。它还包含一个强大的 ModelZoo 设计,允许您管理经过训练的模型,并在一行代码中加载它们。内置的 ModelZoo 目前支持来自 GluonCV、HuggingFace、TorchHub 和 Keras 的 70 多个预训练和随时可用的模型。如果你是一名 Java 开发人员,并且对探索深度学习感兴趣, Deep Java Library (DJL) 是一个很好的起点。

在本教程中,我们将通过在流行的 MNIST 数据集上训练一个简单模型来演示 DJL 的训练能力。

什么是深度学习?

机器学习是通过使用各种统计技术,让计算机从数据中学习给定任务的规范的过程。这种学习任务特征的能力允许计算机执行复杂的任务,例如检测图像中的对象,这些任务通常被认为超出了计算机的范围,因为很难为每种可能的情况提供准确的规范。

深度学习是基于人工神经网络的机器学习分支。人工神经网络是一种受人脑启发的编程范式,它帮助计算机基于观察数据学习和执行任务。深度学习是一组强大的技术,可以用来帮助训练大型人工神经网络来执行复杂的任务。深度学习技术已被证明在解决复杂任务方面非常有效,如对象检测、动作识别、机器翻译、自然语言理解等。

和 DJL 一起训练 MNIST

设置项目

您可以在 gradle 项目中使用以下配置来导入所需的依赖项。在这个例子中,我们使用了包含 DJL 项目核心 API 的api包,以及包含 DJL 一些基本数据集的basicdataset包。因为我们用 MXNet 引擎训练,我们也将导入mxnet-engine包和mxnet-native-auto包。

plugins {
    id 'java'
}
repositories {                           
    jcenter()
}
dependencies {
    implementation "ai.djl:api:0.8.0"
    implementation "ai.djl:basicdataset:0.8.0"
    // MXNet
    runtimeOnly "ai.djl.mxnet:mxnet-engine:0.8.0"
    runtimeOnly "ai.djl.mxnet:mxnet-native-auto:1.7.0-backport"
}

NDArray 和 NDManager

NDArray 是 DJL 所有数学计算的核心数据结构。NDArray 表示一个多维、固定大小的同构数组。NDArray 的行为类似于 python 程序 numpy。

NDManagerNDArray 的管理者。NDManager 管理 NDArray 的生命周期,是 DJL 内存管理的重要组成部分。一旦 NDManager 关闭,由 NDManager 实例创建的每个 NDArray 都将关闭。NDManager 和 NDArray 都扩展了AutoCloseable。为了更好的了解和理解 NDArray 和 NDManager 的用法,请看这篇博文

模型

在 DJL,训练和推理以Model开始。在本文中,我们将集中讨论培训过程。为了开始训练过程,我们创建了一个Model类的新实例。Model类也扩展了AutoCloseable。所以,它是用 try-with-resources 创建的。

try (Model model = Model.newInstance()) {
    ...
    // training process takes place here
    ...
}

准备数据

MNIST 数据库(改进的国家标准和技术研究所数据库)是一个手写数字的大型数据库,通常用于训练各种图像处理系统。MNIST数据集在 DJL 随处可见。来自 DJL MNIST 数据集的单个图像的形状为(28,28)。如果您希望在自己的数据集上训练模型,您可以按照这里的说明添加自己的数据集。

来自 MNIST 数据集的随机图像集合,由克尔森·瓦斯特拍摄

为了训练您的模型,您首先需要加载数据集。

int batchSize = 32;
Mnist trainingDataset = Mnist.builder()
        .optUsage(Usage.TRAIN)
        .setSampling(batchSize, true)
        .build();
Mnist validationDataset = Mnist.builder()
        .optUsage(Usage.TEST)
        .setSampling(batchSize, true)
        .build();

这段代码创建了训练和验证数据集。数据集还被配置为对数据集进行随机采样。对数据集进行了进一步的配置,如对图像应用变换,或限制数据集的大小。

构建模型(构建模块)

一旦数据准备好了,你需要构建你想要训练的神经网络。在 DJL,神经网络用一个Block来表示。块是形成神经网络的可组合函数。它们可以代表单个操作、神经网络的一部分,甚至整个神经网络。一个Block可以有参数和子块。在训练过程中,参数被更新,并且子块也被训练。这也递归地更新了它所有子节点的参数。

在构建这些块函数时,最简单的方法就是使用 composition。积木可以由其他积木组合而成。我们将包含块称为父块,将子块称为子块。

我们提供了几个助手,让构建通用的块组合结构变得容易。SequentialBlock是一个容器块,它的子块形成了一个块链,每个子块将其输出提供给序列中的下一个子块。ParallelBlock 是一个容器块,其子块并行执行,块的输出根据指定的组合函数进行组合。block 是一个具有操作功能的模块,必须由用户指定。

可用于构建神经网络的模块类型(非穷举),keer than Vasist 的图像

我们将建立一个简单的 MLP(多层感知器)。多层感知器(MLP)是一种前馈人工神经网络,它从一组输入生成一组输出。MLP 的特征在于若干层输入结点在输入层和输出层之间连接成一个有向图。它可以通过在一个SequentialBlock内使用多个LinearBlock来构建。

int input = 768;
int output = 10;
int[] hidden = new int[] {128, 64};
SequentialBlock sequentialBlock = new SequentialBlock();
sequentialBlock.add(Blocks.batchFlattenBlock(input));
for (int hiddenSize : hidden) {
    sequentialBlock.add(Linear.builder().setUnits(hiddenSize).build());
    sequentialBlock.add(activation);
}
sequentialBlock.add(Linear.builder().setUnits(output).build());

DJL 还提供了一个预制的Mlp模块,我们可以直接使用。

Block block = new Mlp(
        Mnist.IMAGE_HEIGHT * Mnist.IMAGE_WIDTH,
        Mnist.NUM_CLASSES,
        new int[] {128, 64});

培养

现在,您已经创建了模型的一个新实例,准备了数据集,并构造了一个块,您可以开始训练了。在深度学习中,训练包括以下步骤:

  • 初始化:该步骤初始化模块,并根据指定的Initializer方案创建相应的参数。
  • Forward:该步骤执行由Block表示的计算,并生成输出。
  • 损失计算:在这一步中,通过将指定的Loss函数应用于输出和提供的标签来计算损失。
  • 向后:在此步骤中,使用损失,并沿神经网络反向传播梯度。
  • 步骤:在该步骤中,根据指定的Optimizer更新程序块的参数值。

然而,DJL 通过Trainer抽象了所有这些步骤。可以通过指定InitializerLossOptimizer等训练配置来创建Trainer。使用TrainingConfig可以设置这些配置和更多配置。可以设置的其他一些配置有:

  • Device -必须进行培训的设备
  • TrainingListeners -监听器监听训练过程中的各个阶段,并执行特定的功能,如记录和评估。用户可以根据需要实现自定义TrainingListener
DefaultTrainingConfig config = new DefaultTrainingConfig(Loss.softmaxCrossEntropyLoss())
                .addEvaluator(new Accuracy())
                .optDevices(Device.getDevices(arguments.getMaxGpus()))
                .addTrainingListeners(TrainingListener.Defaults.logging(arguments.getOutputDir()));
try (Trainer trainer = model.newTrainer(config)){
    // training happens here
}

一旦创建了训练器,必须用输入的Shape对其进行初始化。然后,你调用fit()方法开始训练。fit()方法对数据集上的模型进行指定数量的历元训练,运行验证,并将模型保存在文件系统的指定目录中。

/*
* MNIST is 28x28 grayscale image and pre processed into 28 * 28 NDArray.
* 1st axis is batch axis, we can use 1 for initialization.
*/
Shape inputShape = new Shape(1, Mnist.IMAGE_HEIGHT * Mnist.IMAGE_WIDTH);
int numEpoch = 5;
String outputDir = "/build/model";// initialize trainer with proper input shape
trainer.initialize(inputShape);TrainingUtils.fit(trainer, numEpoch, trainingSet, validateSet, outputDir, "mlp");

就是这样。恭喜你!你已经使用 DJL 训练了你的第一个深度学习模型!您可以在控制台上监视训练过程,也可以监视监听器的实现。如果您使用默认侦听器,您的输出应该类似于以下内容。

[INFO ] - Downloading libmxnet.dylib ...
[INFO ] - Training on: cpu().
[INFO ] - Load MXNet Engine Version 1.7.0 in 0.131 ms.
Training:    100% |████████████████████████████████████████| Accuracy: 0.93, SoftmaxCrossEntropyLoss: 0.24, speed: 1235.20 items/sec
Validating:  100% |████████████████████████████████████████|
[INFO ] - Epoch 1 finished.
[INFO ] - Train: Accuracy: 0.93, SoftmaxCrossEntropyLoss: 0.24
[INFO ] - Validate: Accuracy: 0.95, SoftmaxCrossEntropyLoss: 0.14
Training:    100% |████████████████████████████████████████| Accuracy: 0.97, SoftmaxCrossEntropyLoss: 0.10, speed: 2851.06 items/sec
Validating:  100% |████████████████████████████████████████|
[INFO ] - Epoch 2 finished.NG [1m 41s]
[INFO ] - Train: Accuracy: 0.97, SoftmaxCrossEntropyLoss: 0.10
[INFO ] - Validate: Accuracy: 0.97, SoftmaxCrossEntropyLoss: 0.09
[INFO ] - train P50: 12.756 ms, P90: 21.044 ms
[INFO ] - forward P50: 0.375 ms, P90: 0.607 ms
[INFO ] - training-metrics P50: 0.021 ms, P90: 0.034 ms
[INFO ] - backward P50: 0.608 ms, P90: 0.973 ms
[INFO ] - step P50: 0.543 ms, P90: 0.869 ms
[INFO ] - epoch P50: 35.989 s, P90: 35.989 s

一旦训练完成,我们就可以使用训练好的模型进行推理来获得预测。您可以使用您的 model jupyter 笔记本按照推理,在保存的模型上运行推理。您也可以按照使用多层感知器(MLP)模型训练手写数字识别中的说明直接运行完整的代码。

摘要

在本文中,我们向您介绍了深度学习,并使用 DJL 完成了一个简单的训练示例。虽然这个例子是一个简单的例子,但 DJL 为更复杂的深度学习模型提供了相同的抽象。

关注我们的 GitHub演示库Slack channelTwitter 获取更多关于 DJL 的文档和示例!

宏观经济学中的深度学习——国债

原文:https://towardsdatascience.com/deep-learning-in-macroeconomics-treasury-bonds-fbc1b37fe4c8?source=collection_archive---------15-----------------------

预测 10 年期美国国债利率

照片由像素上的能量史诗拍摄

未来一年,美国国债利率将如何变动?下个财政季度?下个月怎么样?这些问题在金融市场投资者和政策制定者的决策中都起着至关重要的作用。投资者的目标是寻求更高的投资回报,估计长期回报,并模拟风险溢价。政策制定者试图预测未来的利率,以帮助推动适当的货币和财政措施,从而维持健康的市场和宏观经济。

在本文中,我将卷积 LSTM 神经网络的预测性能与费城美联储专业预测者调查的总体预测性能进行了比较。这个模型和方法类似于我在《T4》上一篇关于预测美国通胀率的文章中使用的方法。历史上,这种调查汇总的预测方法已经被用于通过汇总许多经济学家模型的结果和对未来表现的预测来提高表现。这与蓝筹股经济指标预测以及道琼斯/华尔街日报经济预测调查等所使用的方法类似。我发现,通过使用神经网络预测算法,预测性能可以在所有测试时间范围内得到改善。

国债的重要性

美国国债收益率不仅在显示股市和整体经济状况方面非常重要,也是许多其他利率和证券定价的驱动因素。

10 年期美国国债实际上是美国债务的一部分。通过购买债券,你可以向美国联邦政府提供小额贷款。10 年期债券是美国财政部发行的 10 年后到期的债券。这些债券由美国财政部拍卖,其价格在一定程度上由需求决定。

这些债券通常被视为无风险债务工具。也就是说,它们决定了无违约风险的债务回报率。这是因为所有的美国国债都是由美国经济担保的。相对于许多国家而言,人们认为美国债务违约的风险很小。

这种将美国国债视为无风险投资的观点,是推动美国国债在理解经济观点方面的重要性以及推动美国国债对其他债务工具的影响力的部分原因。

当经济表现良好且对未来表现的预期较高时,投资者将寻求投资的最高回报率,对美国国债的需求将会减少。在商业周期的这种扩张时期,有许多其他投资工具可以产生比国债更高的回报。结果,需求下降,购买者只愿意以低于面值的价格购买债券。随着市场平衡,与其他投资工具竞争,这将推高收益率。

在经济收缩时期或有衰退风险时,情况正好相反。投资者将资产从被认为风险较高的工具中转移出来,寻找安全稳定的投资,比如国债。这种高需求推高了债券价格,降低了收益率。投资者愿意接受这种较低的回报,以换取他们投资安全的知识。这就是为什么在经济扩张时期,我们会看到国债利率下降,而在经济收缩时期,我们会看到利率上升。

在紧缩时期,这种无风险利率的下降导致银行贷款利率和其他利率也下降,以便在市场上竞争。抵押贷款等安全性较低的投资必须降低利率,以吸引投资者。这为市场提供了额外的流动性。较低的抵押贷款和贷款利率通过降低购房和举债成本而推高了借贷。

通过更好地了解债券利率的未来走势,个人、政策制定者和市场参与者可以改善他们的决策。投资者可以获得更高的回报,并在市场波动之前采取行动,而不是对其做出反应。同样,政策制定者可以在经济陷入危机之前就货币政策和流动性做出决定。或许最重要的是,通过预测债券利率的变动,我们可以更好地理解更广泛的经济情绪。一段时间内利率的大幅变动可以表明风险认知的变化,并作为衰退的指标。

数据

对于数据,我使用来自 FRED-MD 数据库的 GS10 系列。FRED-MD 是一个由圣路易斯美联储委员会维护的数据库,旨在对大数据进行“实证分析”。“数据通过 FRED 数据库实时更新。

GS10 变量代表 10 年期美国国债月底的固定到期收益率。该利率是根据美国财政部提供的信息计算的。数据也可以从弗雷德这里获得。

为了这个分析,我预测了每个月的债券利率。由于债券是每天交易的,这相当于每个月末计算的利率。首先对该序列进行差分以产生平稳性,然后用具有单一特征的滚动 24 个月周期的张量来构造。虽然数据在用于非线性预测模型之前是否必须是稳定的还存在争议,但在这种情况下,我发现差分后的结果得到了改善。滚动平均输入的结构类似。在对序列进行差分后,计算移动平均值,然后将其构建为滚动 24 个月周期的张量,其中三个移动平均值中的每一个都作为一个特征。

时间序列数据的卷积 LSTM 建模

我开发了一个卷积 LSTM 神经网络(CNN-LSTM)来预测未来 12 个月每个月的债券利率。

卷积神经网络是一系列深度学习算法,最初是为图像分类而设计的。该网络获取一幅图像,将该图像通过一组对该图像的不同方面应用权重的过滤器,并最终提供预测。这就像一个特征工程系统,随着时间的推移,网络“学习”什么样的特征过滤器在图像分类中最重要。

类似的方法可以应用于时间序列。虽然时间序列不像图像那样具有“物理”特征,但时间序列数据确实包含时间维度特征。如果我们将时间序列数据想象成一幅图像,我们可以将卷积网络想象成一盏聚光灯或一扇窗户,它扫描整个时间段,照亮该时间段内序列的形状,然后对其进行过滤,以找到它最能代表的特征形状。这种模式的简单说明如下:

时间序列卷积网络的说明性示例(权重是固定的)-十年期国债利率

这个卷积模型可以扩展为一个长短长短期记忆(LSTM)层集,以便更好地了解这些历史时间维度特征中的哪一个在何时影响比率。LSTM 是一种用于深度学习的人工递归神经网络(RNN)架构。与其他前馈神经网络不同,LSTM 网络具有反馈连接。这些反馈连接允许网络学习哪些过去的信息是重要的,而忘记哪些是不重要的。

该单元由几个门函数组成,这些门函数决定新信息对预测问题是否重要,以及旧信息是否仍然相关。该存储器被称为单元状态,并且可以保存所有先前学习的相关信息,用于时序序列的完整处理。这允许在整个处理过程中保持序列中更早学习到的信息。

当信息通过 LSTM 处理时,它通过一系列的门,这些门决定了信息是被保留、更新还是被完全遗忘。这就是 LSTM 建筑优于其他 RNN 建筑的好处。LSTM 能够将信息从处理的早期一直传送到末端,而其他 RNN 网络只是用序列中的每个附加输入来更新它们的理解。这使得 LSTM 网络对于像时间序列这样的序列数据的分析非常强大。

模型架构

我用来分析的 CNN-LSTM 网络如下图所示。首先,我们从两个输入开始,原始时间序列和三个移动平均平滑序列。每个平滑系列代表任何给定观测值的前三个月、六个月和一年的移动平均值。

这些输入然后被馈送到单独的卷积层,以提取每个输入序列的相对重要的特征权重。这些结果然后被合并在一起,并传递到一系列 LSTM 网络,然后最终传递到一组完全连接的块。全连接块堆栈中的每个后续块包含的节点比前一堆栈中的少。在每个块之间,使用剩余或跳过连接,允许模型使用在早期层中学习的信息来继续训练后面的层。这防止了从卷积层输出的信息太快丢失或被模型的后续层模糊。这也有助于防止渐变消失的问题,并允许在模型结构中进一步保留原始序列中的一些较小的细节。最后,在输出最终预测之前,将对最终图层应用一个丢弃。

模型架构图

结果

在对数据进行差分后,我将数据集分成训练集和测试集(70/30 分割)。数据在截至 2001 年 6 月的所有月份中进行训练,然后对 2001 年 7 月到 2019 年 9 月进行预测。我使用一步滚动预测。对于测试集中的每个月,预测对应于接下来 12 个月的每个月末的债券利率,然后使用观察到的债券利率来预测接下来 12 个月的集合。预测以多元方式进行,同时预测随后 12 个月中的每个月,并在系列中每 10 次观察时进行验证。

这是一个相当现实的方法,因为在预测下一期的债券利率时,分析师可以使用所有以前观察到的利率。通过使用一步预测,我们保持这种不断增长的建模信息。通过使用有状态 LSTM 模型,模型权重随着每次新的预测迭代而调整。这使得模型能够拾取序列中可能随时间发生的任何结构变化。该模型的误差率以年度百分比表示。

作为模型的基准,我给出了专业预测者调查(SPF)和费城美联储 DARM 模型(SPF 的最高表现基准)测试期间的误差率。SPF 是美国持续时间最长的宏观经济指标预测调查。这些基准的错误率是根据 SPF 官方错误率文档计算的。

下面是模型结果的总结:

模型和基准误差结果

我们可以看到,多元卷积 LSTM 模型远远优于直接自回归模型和调查汇总预测。虽然在这些预测如何运行以及误差如何表现方面存在一些差异,但我们可以看到卷积模型在每个时间段都优于这些更传统的方法。SPF 预测按季度在每个季度的中期进行,然后在当前季度末和随后的季度进行预测,而不是按月进行。仍然可以通过将每个季度预测视为三个月的预测,将当前季度预测视为大约一个月的预测来进行比较。

下面,我们可以看到模型在整个时间序列中的表现。总的来说,我们可以看到模型与数据拟合得很好,只是在方差较大的时期或趋势变化很快的时候,误差会稍微大一些。在 1980 年代的最高历史汇率值时,情况尤其如此。

如果我们更仔细地观察测试期间,我们可以看到模型几乎完全符合实际债券利率。这部分是由于模型在每次后续预测中获得了额外的信息。自 1984 年的峰值以来,国债利率一直在稳步下降。最近的经济理论表明,债券利率可能已经发生结构性变化,进入一个较低的稳定状态。考虑到美国国债收益率曲线,这一点尤其有趣。然而,该模型似乎很容易适应这种结构上的变化。

虽然在误差方面比基准测试有明显的改进,但可以看到的另一个主要好处是模型的预测能力没有滞后。典型的计量经济学模型预测通常显示出其预测的滞后性,并且难以快速适应趋势的变化。在查看下面的附加基准预测时,我们可以看到,特别是对于中长期预测,预测率存在明显的滞后。我们还可以在基准预测中看到我所说的模型粘性。在这种情况下,长期预测往往会高估系列趋势变化的幅度,并且对方向逆转的适应速度较慢。这在 20 世纪 80 年代 DARM T+12 预测中最为明显。我们可以看到,模型在峰值后反转方向很慢。

10 年期国债利率预测

结论

这为使用神经网络预测债券利率提供了有力的证据。这种神经网络结构可以极大地改善预测,并能更快地对趋势变化做出反应。这种预测方法也可能具有更好的性能,因为它同时预测所有 12 个未来期间。与其他典型的递归生成预测的基准模型(即预测 T+2 基于预测 T+1)不同,神经网络仅使用时间 T 的信息来预测所有 12 个时段。这基本上允许模型优化其权重,就好像使用了 12 个独立的模型一样。

这项分析只使用了一个单一的预测变量,通货膨胀的历史,以预测未来的通货膨胀率。有可能通过增加额外的预测因子来提高模型的性能。也可以使用不同的平滑方法,例如指数平滑,这可以允许改进预测。债券利率数据也可以在每日序列中获得,这可能是预测挑战的有趣补充,并提供额外的数据。

我的分析代码可以在我的 GitHub 上找到。我将继续更新代码和完善模型,因此结果可能会略有变化。

[## acertainKnight/FRED _ 预测 _ 最终

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/acertainKnight/FRED_Forecasting_Final) [## 10 年期国债固定到期利率

资料来源:美联储系统(美国)理事会发布:H.15 选定利率单位:频率…

fred.stlouisfed.org](https://fred.stlouisfed.org/series/GS10)

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

自动驾驶地图中的深度学习

原文:https://towardsdatascience.com/deep-learning-in-mapping-for-autonomous-driving-9e33ee951a44?source=collection_archive---------11-----------------------

更新:自本文撰写以来,有几篇关于深度学习的高清地图构建的新论文。当我有机会的时候,我会更新这个帖子

深度学习的应用已经在自动驾驶栈的各个组件中进行了探索,例如,在感知、预测和规划中。深度学习还可以用于映射,这是更高级自动驾驶的关键组件。

拥有准确的地图对于自动驾驶在路线选择、定位以及轻松感知方面的成功至关重要。可以通过订购商业地图服务来获得具有不同程度信息的地图。然而,在没有地图的地区,自动驾驶车辆需要依靠自己的地图构建能力来确保自动驾驶的功能性和安全性。

离线映射与在线映射

在离线绘图场景中,传感器数据被聚集在一个集中的位置。这些数据可能是卫星图像,也可能是相机或激光雷达等机载传感器收集的数据。它可能来自同一辆车在同一地点的多次通行,也可能来自一个车队的众包。地图的渲染是离线构建的,需要人工注释者在地图上注释语义结构并检查最终结果。传统的地图服务以这种离线方式工作,然后将经过注释和管理的地图提供给路上的车辆。

高清地图注释的用户界面示例(来源)

在线地图是在车辆上进行的,因此不能让人类参与其中。典型的例子是用于同步定位和绘图的 SLAM 系统。最近,语义 SLAM 专注于道路上的表面标记的几何和语义含义,被探索作为映射的轻量级解决方案。此外,单目语义在线映射(monoSOM) 是一个趋势性主题,其中使用神经网络将来自多个相机的单目图像的时间序列融合成语义鸟瞰图。这些话题超出了本文的范围,将在其他地方讨论。

标清地图与高清地图

根据输入分辨率的不同,深度学习在映射中的应用大致有两种类型。第一行工作集中于地图拓扑的发现,例如道路网络,并且通常不包含车道级别信息。他们只需要一张分辨率相对较低、精度大约为米级的图像。另一类应用侧重于提取车道级别信息,如车道线、路面箭头和其他语义标记。这需要更高分辨率的图像,具有厘米级的精度。相应地,这两种类型的地图在本文的其余部分将被统称为标清地图和高清地图。

深度学习在 SD 地图上的应用(左, DeepRoadMapper )和 HD 地图上的应用(右, DAGMapper )

这篇文章主要关注高清地图的离线生成。请注意,其中一些方法也可以应用于在线制图,我们将专门针对 SD 制图的一些相关工作进行一个简短的回顾。

注释者友好的映射

在离线映射中,有一个人类评审员来评审深度学习的结果是负担得起的,也是必不可少的。因此,不仅整体的准确性很重要,而且结果的表示也很重要,因为结果应该很容易被人类注释者修改。

由于大多数运动规划者只能处理结构化的并表示正确拓扑的车道图,映射算法的输出通常是一个 结构化表示(车道线的折线等)。幸运的是,这种表示有助于人工注释者的有效修改。

SD 映射(道路拓扑发现)

深度学习在地图绘制上的早期应用侧重于从相对低分辨率的航空图像中提取道路级拓扑。深度学习为 SD 映射创建了一个大覆盖范围的负担得起的解决方案。SD 地图中生成的道路拓扑的主要用途在自动驾驶环境中相对有限,用于路线选择和导航。然而,其中一些研究中提出的方法与后来的高清地图工作高度相关,因此在此进行回顾。

deep road mapper(ICCV 2017)接收从卫星获得的航空图像,并创建结构化的道路网络。它首先执行语义分割,并在生成的道路图上运行细化和修剪算法。由于语义分割的不准确性(被树、建筑物等遮挡),许多道路是断开的。为了解决这个问题,DeepRoadMapper 使用 A*搜索算法来生成连接假设以弥合差距。

road tracer(CVPR 2018)也注意到了不可靠的语义分割结果,将其作为中间表示进行了剔除。它使用迭代图构造来直接获得道路的拓扑。该算法需要做出决定,朝着某个方向前进一定的距离,类似于强化学习设置中的代理。

“代理”在 RoadTracer 中提取道路拓扑

poly mapper(ICCV 2019)可能受到 RoadTracer 的启发,它也消除了中间表示。它显式地统一了不同类型对象的形状表示,包括道路和街道建筑物,并将它们表述为封闭的多边形。公式非常巧妙和简洁,遵循迷宫墙跟随器算法。

PolyMapper 中使用迷宫墙跟随器对道路拓扑进行顺序化

PolyMapper 使用 Mask RCNN 架构提取建筑物和道路的边界遮罩。基于遮罩,它提取顶点,找到起始顶点,并使用 RNN 自回归迭代所有顶点以形成闭合多边形。

聚合地图的网络架构

RoadTracerpoly mapper中,地图结构化表示的自回归生成与高清制图中使用的非常相似。****

高清制图(车道等级信息提取)

SD 地图缺乏自主汽车安全定位和运动规划所需的细节和准确性。带有车道等级信息的高清地图是自动驾驶所必需的。高清地图生成通常采用更高分辨率的鸟瞰(BEV)图像,通过拼接机载相机图像和/或激光雷达扫描生成。

【结构化在线地图的分层递归注意网络,CVPR 2018】取道路的稀疏点云扫掠,输出包含车道边界实例的道路网络的结构化表示。它首先迭代地找到每条车道线的起点,然后对于每条车道线,沿着这条线迭代地绘制下一个顶点。这两个 rnn 以分层的方式组织起来,因此被命名为 HRAN——分层递归注意网络。********

分层循环注意力网络(来源)

它提出了折线损失的思想,以鼓励神经网络输出结构化折线。折线损失测量地面真实折线的边与其预测值的偏差。这比顶点上的距离更合适,因为有许多方法可以绘制等效的折线。****

折线损失(又名倒角距离损失)关注的是形状而不是顶点位置()

HRAN 使用每像素 5 厘米的分辨率,并在 20 厘米的精度内实现 0.91 召回。主要的失效模式来自于缺失或额外的车道线。注意,100%的准确性不一定是最终目标,因为注释者仍然需要手动检查这些图像并修复它们。这些故障案例可以相对容易地修复。后期作品深度边界提取器中使用的高度渐变图或许可以修复护栏被误认为车道线的 FP 情况。

来自 HRAN 的定性结果

深度结构化人行横道 (绘制人行横道的端到端深度结构化模型,ECCV 2018)从 Lidar 点和相机图像(lidar + RGB = 4 通道)产生的 BEV 图像中提取结构化人行横道。该网络生成三个独特的特征地图——语义分割、轮廓检测以及根据直接监控定义人行横道方向的角度。

天真地说,等高线图和角度/对齐图仅在人行横道边界处具有非零值。这类似于一键编码,并且提供了过于稀疏的监督。为了解决这一问题,等值线图采用了反距离变换(DT)的形式,并且角度图还将非零区域扩展到扩大的等值线带。另一种方法是使用高斯模糊来处理几乎是一个热点的地面真相,就像在 CenterNet 中一样。

这项工作在某种意义上不完全是端到端的,因为管道的最终目标是生成人行横道的两个结构化的、定向的边界。为了获得结构化的边界,三个中间特征地图连同一个粗地图(OpenStreetMaps,其提供道路中心线和交叉多边形)被输入到能量最大化管道中,以找到人行横道的最佳边界和方向角。

深层结构人行横道总体管线

BEV 输入分辨率为 4cm/像素,整体精度达到 0.96。主要故障模式是油漆质量差,导致不正确的距离变换和分割预测。

以上结果由几次行驶产生的输入离线得出。该模型还可以在同一位置单程运行在线,并可以实现类似的性能,在线生成图像质量差的附加故障模式。

来自深层结构人行横道的定性结果

深度边界提取器 (道路边界提取卷积递归网络,CVPR 2019)用折线提取道路边界。它受深度结构化人行横道的启发,使用卷积 RNN(卷积蛇,或 cSnake)以自回归方式进行预测。通过增加一个额外的激光雷达高度梯度通道,输入扩展了深层结构人行横道的输入,该通道通过获取 Sobel 滤波激光雷达 BEV 图的幅值生成。

cSnake 网络迭代地关注旋转的 ROI,并输出对应于道路边界的折线的顶点。它首先预测终点。基于每个端点,它裁剪和旋转以该端点为中心的特征地图,并定位下一个点的位置。上述过程自回归运行。

深边界提取器整体管线

Deep Boundary Extractor 以 4 cm/pixel 的输入分辨率运行,并实现约 0.90 逐点 F1 分数和 0.993 拓扑精度。

来自深边界提取器的定性结果

Dag mapper(通过发现车道拓扑来学习地图,ICCV 2019)将 HRAN 的结构化车道线提取工作向前推进了一步,并专注于分叉和合并等更难的情况。它接收激光雷达强度图并输出 DAG(有向无环图),而不是 HRAN 中的简单折线。

DAGMapper 的核心还有一个递归卷积头,它迭代地关注以最后预测点为中心的裁剪后的特征地图补丁,并预测下一个点的位置。变化在于它还预测点的状态是合并、分叉还是继续。

DAGMapper 的整体管线

输入分辨率为 5 厘米/像素。精确度/召回率/F1 在 2 像素(10 厘米)阈值处约为 0.76,在 10 像素(50 厘米)处约为 0.96。拓扑精度约为 0.89。

来自 DAGMapper 的定性结果

外卖食品

  • 用于离线绘图的深度学习有一个人在循环中。深度学习的结果需要被结构化,以便能够被自动驾驶堆栈使用,并且能够被人类注释者容易地修改。
  • 当前的高清制图应用主要集中在道路边界、车道线(包括合并和分叉拓扑)和人行横道边界的提取上。
  • 所有 HD 制图研究的核心构建模块是递归卷积网络,它迭代地获取以当前注释点为中心的裁剪后的特征地图,并预测下一个注释点。

参考

实践中的深度学习:思维导图备忘单

原文:https://towardsdatascience.com/deep-learning-in-practice-mental-map-cheat-sheet-6647b1767e5c?source=collection_archive---------43-----------------------

做深度学习需要什么?

一旦你理解了深度学习背后的理论,琐碎的下一步就是实践你所学到的东西。在这篇文章中,我试图在一个心理地图备忘单中收集所有与实践中的深度学习相关的内容。这对于深度学习初学者来说非常有用,这些初学者通常要么不知道要使用的工具或数据集,要么对一两个市场领导者的知识很肤浅,因为他们在几乎所有与深度学习相关的文档中都遇到过他们。如果你打算从事这个领域,你应该有一个更全面的看法。

Unsplash 上由 Tevarak Phanduang 拍摄的照片

思维导图的中心主题是“实践中的深度学习”,从中衍生出 5 个主要分支,即(1)编程语言,(2)框架和库,(3)ide、笔记本和源代码编辑器,(4)数据集和(5)实现。它们中的每一个都将在下面介绍。以下是所提议的思维导图备忘单的不同分支的摘录。每个工具和数据集前面都有一个指向下载页面的链接。最常用的工具用红色标出。

思维导图备忘单不同分支的摘录

你可以点击下面的按钮下载备忘单。由于思维导图非常大,请考虑将其下载到您的设备上,然后在 PDF 文档中缩放感兴趣的项目。

分支 1:编程语言

Python 是最著名的语言之一,甚至可能是最流行的。下面的利率随时间变化图就是很好的证明。根据过去 12 个月的谷歌全球趋势,它显示了 Python 与其潜在候选人 R、Julia 和 Scala 相比的趋势。你可以在思维导图中找到其他用于深度学习的语言,比如 java、javascript、Go……

分支 2:框架和库

我在思维导图中提到的一些框架和库只致力于深度学习,例如 M xNetDeepLearning。Scala 。其他的不仅仅是深度学习。它们是更大的机器学习,具有很大的深度学习焦点,例如 TensorFlowPyTorch 。此外,我收集到的框架和库类型多样: BigDLPaddlePaddle 用于分布式深度学习, PaddleFL 用于联邦学习, PyTorch MobileTensorFlow Lite 用于移动和物联网设备上的深度学习,…

在下面的图表中,我展示了 GitHub 上最受欢迎的框架在提交、贡献者、明星、分叉和观察方面的近期活动。除了明星类别,TensorFlow 在其他类别中拥有最多的 GitHub 活动。Fastai 显示了更多的恒星。事实上,当我写这篇文章时,它是 GitHub 上第二大热门知识库。你可以在这里找到理解 GitHub 类别所需的一切。

分支 3:ide、笔记本和源代码编辑器

我将这个分支细分为 3 个主要部分:

(1)IDE:IDE,集成开发环境的首字母缩略词,使程序员能够整合编写计算机程序的不同方面。它通过将编写软件的常见活动(如编辑源代码、编译、构建可执行文件和调试)合并到一个应用程序中,提高了程序员的工作效率。在下表中,我展示了一些在思维导图中唤起的 ide。

(2)源代码编辑器:是 ide 的简化版本,因为它们提供的工具更少。它们是对编程语言敏感的,因此它们突出了程序的语法元素;并提供许多有助于程序开发的特性,如自动完成、编译、构建和运行。

(3)笔记本电脑:适合初学者,因为它们结合了 IDE 功能和人体工程学、交互式和易于使用的教育工具。他们还结合了实时代码、叙述性文本、等式、结果可视化、图像和其他几种媒体。在下表中,我根据自己选择的 6 个特性展示了 5 款开源笔记本电脑:

支持的内核:内核是执行笔记本中包含的代码的计算引擎/后端。我所说的支持的内核是指笔记本环境所支持的语言范围。

类型:此功能表示笔记本是基于网络的应用程序还是基于桌面的应用程序。web 应用程序的一个非常简单的定义是,它存储在一个远程服务器上,该服务器需要一个 web 浏览器作为客户端来运行,并且需要互联网来传输数据和资源。桌面应用程序旨在为不需要互联网的独立机器提供服务。如果安装了适当的软件包(例如,nteract),基于桌面应用程序的笔记本电脑可以用作基于网络的笔记本电脑。

多语言:是在一个笔记本中创建多语言支持的能力,以便允许不同语言执行的代码之间的互操作性。相反,单一语言笔记本允许您同时以其支持的语言之一创建笔记本。

多用户:表示允许多个用户同时编辑笔记本,而不会互相冲突、碰撞和覆盖。一些笔记本电脑可以与多个用户共享,但它们不具备多用户功能。Jupyter 本质上是一个单用户应用程序。但是,您可以使用 JupyterHub 来创建多用户 Hub,它管理和代理单用户 Jupyter 笔记本服务器的多个实例。

云平台支持:可以在个人电脑上工作。然而,管理需要大量数据的实际问题变得很困难。为了从 GPU 等更高的物质资源中受益,有必要向更高的计算规模转移。我之所以选择这个功能,是因为了解大型云平台是否支持笔记本电脑环境非常重要,也就是说,您创建笔记本电脑所需的一切都已预装在云上。

社区:如果您开始使用某个特定的笔记本电脑,您会希望与其他开发人员和专家建立联系。他们可以加快你的进度,帮助你解决一些遇到的问题。此外,文档应该基本可用。

分支 4:数据集

深度学习获得更好模型的关键是数据。这就是为什么我在建议的思维导图中专门为数据集设计了一个分支。所有诱发的数据集都是开放的,并且大量用于众多深度学习项目。其中一些甚至在市场领导者框架内实现了特定的类和功能;并且在全球比赛中非常常用,如 KaggleCodalabDataDriven 。我选择添加到我的思维导图中的数据集属于不同的上下文,即图像处理(例如 MNIST 和 ImageNet)、自然语言处理(NLP)(例如 Yelp 和 WordNet)和语音识别(例如 LibriSpeech 和 AudioSet)

用于图像处理的开放深度学习数据集的样本

面对新型冠状病毒引起的新冠肺炎疫情,世界各地的研究人员正试图找到耗时的 RT-PCR 的其他诊断替代方法。深度学习应用于阳性新冠肺炎病例的胸部射线照相图像,例如胸部 X 射线(CXR)和计算机断层扫描(CT),已经显示出对冠状病毒诊断的很大希望。在这种情况下,我注意到很多人,特别是那些深度学习从业者,但不是医学成像专家,询问可用的新冠肺炎 CXR 和 CT 图像。因此,我列举了目前在这种情况下使用的开放数据集以及它们的 GitHub 链接。我还提到了现有的 CXR 和 CT 图像数据集,例如 RSNA 和 ChestX-ray14,它们已经被用于肺部疾病的检测和分类。这将帮助您将它们与新的新冠肺炎数据集合并,以便(1)将其与其他类型的肺炎区分开来,(2)决定谁应该优先接受新冠肺炎病例的 PCR 检测,以及(3)选择治疗方法,因为新冠肺炎和非新冠肺炎感染需要不同的治疗方案。

来自开放深度学习新冠肺炎和非新冠肺炎数据集的胸部 x 光图像

在此,我必须指出,我没有指出新冠肺炎数据库中的图像数量,因为它们变化很大。他们正在被科学界和医学协会扩大。随着新数据的出现,后者正在不断努力扩大这些基础。此外,新冠肺炎数据集仍处于初期阶段,有限且不成熟。你可以求助于一些技术,比如迁移学习和数据扩充,来改进训练过程。你可以在 AI 对抗新冠肺炎特别工作组和世界卫生组织(世卫组织)的网站上寻找其他数据集、挑战、项目和论文,其中大部分是预印本。希望这一切都会过去!

第五分部:实施

深度学习正在多个领域兴起,包括但不限于计算机视觉、在线推荐引擎、语音助手、医疗诊断、聊天机器人、预测营销分析、物理机器人和自动驾驶汽车。我在思维导图中提到的实现是说明性的,而不是详尽的。这些仅仅是举几个例子。我为您挑选了下面的链接,这些链接展示了与医学成像处理、NLP 和语音识别相关的深度学习的 3 个现实世界实现:

派&人工智能:现实世界中人工智能在医学上的应用

自然语言处理和机器学习的用例

现实世界应用的自动语音识别

嗯!就是这个!

请注意,我并不要求列举与深度学习相关的所有工具、数据集和用例。我试图在一个单一的思维地图中收集这些后者的大部分。这仍有待讨论。我欢迎并重视您在这方面可能提出的任何问题和意见。此外,本文的目的不是判断哪种工具比其他工具更好。我不知道你是否注意到没有个人意见形成。它只是对主要深度学习工具及其特征的客观列举。

如果你错过了我以前的文章:

[## 学习率常见问题

学习率问题和答案

towardsdatascience.com](/frequently-asked-questions-on-learning-rate-6defb4e45d2e) [## 全面综合了主要激活函数的优缺点

激活函数:神经网络最重要的超参数之一,必须仔细选择…

medium.com](https://medium.com/analytics-vidhya/comprehensive-synthesis-of-the-main-activation-functions-pros-and-cons-dab105fe4b3b)

宇宙中的深度学习:排名 3 机器学习(ML)应用

原文:https://towardsdatascience.com/deep-learning-in-the-cosmos-ranking-3-machine-learning-ml-applications-f45c2ae74432?source=collection_archive---------26-----------------------

在过去十年中,深度学习帮助推动了多个领域的最新发展,科学研究也不例外。我们之前已经讨论过 Deepmind 在蛋白质折叠预测方面令人印象深刻的首次亮相,以及斯坦福学生研究蛋白质复合物结合操作的项目,这两个都是利用深度学习研究非常小的事情的例子。

来源

深度学习同样也在科学研究中得到了应用,而这与规模光谱正好相反。在这篇文章中,我们将讨论深度学习用于研究宇宙学的一些最新应用,也就是对宇宙的研究。正如您所想象的,这个主题包含了各种各样的子类别。我们将从机器学习和基础科学的角度对这些项目的炒作和影响进行评级,尽管我们将根据趣味性而不是依赖引用指标来判断这一点。如果可能的话,我们还会提供每个项目公共资源库的链接,这样你就可以自己查看了。

大肆宣传是为了什么?人工智能解决了宇宙学中的三体问题

(格林等 2019) 一览:

TL;一个多层感知器被训练来预测一个简化的三体问题模拟中的未来位置。

炒作: 4/3 三倍浓咖啡。该项目的报道范围从人工智能可以解决难住牛顿的三体到神经网络解决三体的速度快一亿倍。媒体的大肆宣传遵循了研究论文中的描述性方法,这似乎是为了让专业领域之外的读者惊叹而精确设计的。由于深度学习和n-身体轨道力学方面的共同专业知识将是稀有的平方,很容易陷入不熟悉的细节而错过重点。

冲击(ML): 3/10 致密层。有趣的是,在这个大 conv 网络无处不在的时代,看到一个深度多层感知器被使用。

撞击(物理学): 3/ n 巨大的天体。

模型:具有 ReLU 激活的 10 层全连接神经网络。

输入数据:三体之一的起始位置和目标时间 t

输出:时间 t 三个粒子中的两个粒子的位置。坐标参考系统暗示了第三个粒子的位置。

代码:https://github.com/pgbreen/NVM(仅使用预先训练的模型权重进行推断)

解开人工智能如何解决宇宙学中的三体问题的细节

在经典轨道力学中,预测一个孤立的两个引力体系统的未来位置是相对容易的。再增加一个物体,我们就有了臭名昭著的三体问题,这是一个经典的例子,说明在一个看似简单的系统的动态相互作用中,混沌是如何出现的。混沌系统的一个标志是它们对初始条件极其敏感,它们的行为看起来是随机的。这些状态很难预测,混沌系统演化的时间越长,预测就变得越困难,因为过去的错误会不断增加。这就是为什么对于一个特工来说,学会摆动一根实心的杆子要比一根多节的杆子容易得多的原因之一:

像这种双摆的混沌系统很难预测和控制

就像强化学习代理努力控制双摆一样,科学家也发现很难预测像三体问题这样的混沌系统的未来状态。没有解析解,所以计算物理学家依靠他们的老朋友蛮力计算。这是可行的,但是并不总是清楚需要多少数值精度,并且会消耗大量资源。

这篇文章的作者使用了一个 10 层的多层感知器来预测三体轨道问题的未来状态。训练数据由名为 Brutus 的强力数值模拟器计算。我很喜欢看到一个“老式”的多层感知器,如果看看代码,用不同的训练超参数和不同的体系结构进行试验,会很有趣。不幸的是,可用的公共代码不包括任何培训实用程序。

我同意最近的怀疑态度,因为这篇论文的主张是由一个非常狭窄和简化的用例支持的,不太可能轻易地推广到更复杂的情况。我要补充的是,结果并不像宣传的那样令人印象深刻。当被训练来预测更远的未来时,性能显著下降,范围从大约 0.01 到 0.2 的平均绝对误差。当所讨论的无单位数几乎总是在-1 和+1 之间时,这些误差就很大。训练网络来预测未来还会导致训练集更大的过度拟合,这个问题在讨论中没有涉及。

在宇宙学中使用机器学习(ML)最有价值的领域是什么?用深度学习发现更多系外行星

艺术家对由马丁·科恩梅瑟创作的 K2–18b 的印象。图片来源美国宇航局

(Dattilo et al. 2019)

机器学习如何帮助发现新行星一览

TL;博士:开普勒太空望远镜在 2013 年发生故障,导致了大量的噪音数据。研究人员将 AstroNet-K2 训练为先前模型 AstroNet 的修改版本,以处理新的噪声数据,并发现了两颗新的系外行星。这些行星通过后续观测得到了验证。

炒作: 1/3 三倍浓咖啡。麻省理工学院技术评论的报道经过了合理的衡量,没有对该项目做出夸大或不切实际的声明,但有时忽略了提及 AstroNet-K2 是基于一年前发布的前一个项目 AstroNet。

影响(ML): 4/8 卷积滤波器。AstroNet 和 AstroNet-K2 的区别似乎在于超参数搜索和不同的数据集。

Impact(系外行星天文学):2/1076 个已知的【超级地球】(https://en . Wikipedia . org/wiki/File:Size _ of _ Kepler _ Planet _ candidates . jpg)由 AstroNet-K2 发现,并用额外的观测数据验证。我认为这是作为一个本科生研究项目开始的一个非常有益的成果。

模型:两个独立的卷积臂从输入数据中提取特征。这些卷积层的输出被结合并馈入输出最终预测的 4 个完全连接的层。

输入数据:开普勒望远镜 K2 运行的 1D 光变曲线。

输出:给定信号由凌日系外行星引起的概率。

代号:https://github.com/aedattilo/models_K2

解开机器学习如何发现新行星的细节

开普勒仪器是一个基于太空的望远镜,旨在研究太阳系以外的行星,也就是外行星。1995 年,迪迪埃·奎洛兹和米歇尔·马约尔描述了第一颗围绕像我们这样的恒星运行的系外行星,这两人获得了 2019 年诺贝尔物理学奖。十多年后,当开普勒于 2009 年发射时,已知的系外行星总数不到 400 颗。现在处于休眠状态的望远镜于 2009 年开始运行,在 2013 年用于精确指向的部件反应轮出现故障之前,发现了 1000 多颗新的系外行星。这结束了任务的第一阶段。

一些巧妙的工程改变让望远镜开始了第二阶段的数据采集,称为 K2。来自 K2 的数据更嘈杂,而且仅限于 80 天或更少的连续观测。这些限制给在成千上万个假定的行星信号中识别有前途的行星候选者带来了挑战,这项任务以前由卷积神经网络(AstroNet)处理开普勒初级数据收集阶段的数据处理得很好。德克萨斯大学奥斯汀分校的研究人员决定尝试相同的方法,并从 AstroNet 的架构中派生出 AstroNet-K2 来对 K2 行星信号进行排序。

经过训练,AstroNet-K2 在测试集中识别确认的系外行星的准确率达到 98%,假阳性率很低。作者认为这种性能足以用作分析工具,而不是完全自动化,需要人工跟踪。来自报纸:

虽然我们网络的性能还没有达到生成全自动且统一的
行星候选星表所需的
水平,但它可以作为
概念的证明。——
(达蒂洛等 2019)

AstroNet-K2 获得了这篇博文梦寐以求的“最佳价值”奖,因为它实现了一项物有所值的重大科学发现。与列表中的其他两个项目不同,这两个项目更多的是概念性的演示,这个项目导致了实际的科学进步,为已知系外行星的目录增加了两个新的确认条目:EPIC 246151543 b 和 EPIC 246078672 b。

除了 K2 数据的内在挑战之外,行星的信号还因火星穿过观测窗口和与安全模式事件相关的 5 天数据缺失而进一步混淆。这是一个很好的有效的机器学习的例子:作者采用了一个现有的有良好记录的 conv 网络,并对其进行了修改,以在给定的数据上表现良好,添加了一些从困难的观察运行中获得的新发现,而没有重新发明轮子。

值得注意的是,这项研究的主要作者安妮·达蒂洛在研究完成时还是一名大学生。对于一个本科生研究项目来说,这是一个非常好的结果。开源软件的使用和基于以前开发的架构的构建强调了一个事实,即深度学习正处于高级准备阶段。这项技术还没有完全成熟到无处不在的地步,但工具都在货架上,随时可以应用。

CosmoGAN:引力透镜的生成对抗网络方法

(穆斯塔法等人 2019 )一览

柴郡猫星系团的引力透镜效应。图片来源 NASA

TL;博士:宇宙中有一堆缺失的物质,我们称之为暗物质。这种丢失质量的重力会弯曲光,宇宙学家可以根据光的扭曲来猜测暗物质的位置。深度卷积生成对抗网络擅长制作逼真的图像,这些研究人员训练了一个网络来制作看起来像与暗物质分布相关联的数据的图像。

炒作: 1/3 三倍浓咖啡。基本上我能找到的这篇论文的所有新闻报道都是从劳伦斯柏克莱国家实验室的新闻稿中抄袭来的。这样的报道并不过分夸张或古怪,尽管我会说对 CosmoGAN 实际上做了什么的描述是模糊的(但这篇论文在这方面也不是很清楚)。我最喜欢的标题是宇宙科学家利用神经网络以简单的方式构建暗物质地图

影响(ML): 6/64 潜在空间随机变量。这是一个普通的 DCGAN,被训练来模拟引力弱透镜数据。

撞击(宇宙学):10 个中有 1 个不可观测的质量。

型号: CosmoGAN 是一款 DCGAN 。每个网络有 4 层,但由于具有较少的卷积滤波器,发生器的参数(1230 万)比鉴别器(440 万)多 3 倍。参数不一致是为了稳定训练,防止鉴别器脱离生成器。

输入数据: 64 单位潜向量(生成器),生成(由 CosmoGAN)和模拟(数值物理模拟器)弱透镜会聚图的 2D 图像,可以对应暗物质分布(鉴别器)。

输出:似是而非的会聚图(生成器),或给定图像是真实(模拟)会聚图的概率(鉴别器)

代号:https://github.com/MustafaMustafa/cosmoGAN

解开关于生成对抗网络如何导致引力透镜化的更好方法的细节

暗物质是一种相对神秘的物质形式,占(我们认为)宇宙质量的很大一部分(大约 85%)。“黑暗”的绰号指的是这样一个事实,即这种形式的物质在正常观测中是不可见的,而是只能从引力效应中推断出来,比如 20 世纪 60 年代由薇拉·鲁宾观测到的星系旋转速度的差异。研究暗物质的一个基本可观测现象是引力透镜,其中大质量物体扭曲了来自更远物体的光线。当透镜效应是由不可见的暗物质引起时,这就变成了一个困难的逆问题,需要密集的模拟来克服。

“如果你希望从零开始做一个苹果派,你必须首先发明宇宙”(卡尔·萨根,宇宙)。这同样适用于研究暗物质的存在:基于引力透镜的观察建立暗物质地图的黄金标准方法是创建一个(虚拟)宇宙。众所周知,宇宙的创造在计算上是昂贵的,旋转一个高保真度的宇宙来检查它是否与观察结果一致,这给可以完成的科学数量带来了实质性的限制。

当数据丰富而分析数据的计算不足时,科学家会寻找方法来开发替代模型,这些模型可以解释数据,而不必每次都构建一个全新的宇宙。CosmoGAN 就是这样一种方法,利用现代深度学习生成网络来估计引力透镜数据的收敛图。

自 Goodfellow 等人在 2014 年描述了生成性对抗网络以来,它们已经走过了漫长的道路。GAN 框架是一个(现在相当多样化的)生成模型的利基,它将生成网络与鉴别网络或伪造检测网络对立起来。这两个网络相互作用,产生越来越真实的合成数据,而鉴别器在检测假货方面越来越好。这种相互作用提供了纯 GAN 训练环路中唯一必需的训练信号(尽管像条件 GAN 这样的变体可以利用额外的数据),因此在 GAN 训练中平衡两个网络是一种艺术,众所周知,当这种平衡不均衡时,GAN 容易不稳定。

考虑到他们难以训练和解释的名声,甘斯在计算宇宙学家中找到了 从业者中的 可能会有点令人惊讶。然而,CosmoGAN 的范围相当有限。生成器学习模仿收敛图的统计现实图像,但这些图像与潜在空间中的随机输入无关。在这种情况下,像古老的 edges2cats 演示中的 pix2pix 方案这样的条件 GAN 会更有意义。也就是说,生成一个似乎可以解释给定天文图像中透镜现象的会聚图将是有用的,这可以通过额外的观测来验证。

此外,由发生器产生的会聚图是 2D,但暗物质实际上将分布在三维空间。作者暗示,其中一些限制将在未来的工作中得到解决。例如,提到“可控的 gan”听起来类似于上面提到的条件 gan,他们确实打算制作一个 3D 版本的体积暗物质分布。如果是这样的话,这个项目中 85%的工作现在仍然是不可观察的。

这 3 个机器学习(ML)应用程序正在允许宇宙学中不可思议的发现和突破

我们刚刚开始看到它在宇宙学中的潜力。这篇文章强调了一个事实,即在太空研究中取得新的发现并不需要大胆地去科学家没有去过的地方。更确切地说,正如我们在系外行星项目中看到的那样,一种经过验证的技术的巧妙实现,可以适应并应用于一个新的数据集,从而产生新的发现。另一方面,这个列表中的另外两个项目,虽然拥有更高的期望和更闪亮的描述,但只是使用模拟数据的概念性探索。

我们还可以注意到,这些例子中非专业媒体报道的炒作因素与研究论文描述中使用的夸张程度相关。这表明研究人员不能将夸大的新闻报道完全归咎于科学记者,这个问题困扰着大多数研究领域,而不仅仅是 AI/ML。过度炒作会导致无效的反馈循环,导致经济/技术泡沫和研究资源的低效配置。这就是为什么我们更喜欢仔细看看新的深度学习应用的明星声明,无论它们是研究宇宙还是更世俗的东西。

【深度学习】引入生成对抗网络(GANs)

原文:https://towardsdatascience.com/deep-learning-introduction-of-generative-adversarial-networks-gans-ae22c4350b1f?source=collection_archive---------26-----------------------

甘斯的直觉和客观功能

生成对抗网络(GANs)形成于 2014 年[1],是一种先进的深度神经网络,具有许多应用。与无监督学习中的传统机器学习(它不需要目标标签)不同,GANs 是一种通过给定数据生成新内容的生成模型。

有趣的是,GANs 首先从原始论文的右侧看到了 MNIST(手写数字数据库)的生成图像:

MNIST GANs 从原纸生成的图像

直觉

GANs 的类比被认为是伪钞制造者和警察之间的假币检测游戏[1]。根据 Goodfellow [2]对 GANs 的教程,GANs 由两个角色组成,分别是生成者(造假者)和鉴别者(警察)。

伪造者试图制造假币,并通过查看真钞来欺骗警察(鉴别者)。鉴别器的工作就是鉴别给定的钱是不是真的。首先,伪造者制造的货币太粗糙,很容易辨别。基于这些失败,现在伪造者努力生产更复杂的货币。与此同时,警察现在更有经验来辨别真假钱。

随着这一过程重复多次,双方都向对方学习(这就是它被称为“对抗性”的原因),因此变得足够成熟和老练。现在,造假者生产的假币对除了警察以外的其他人来说都是非常逼真的。

打假人与警察博弈的类比。图片由作者提供。

GANs 的目标函数

回想一下,目标函数是在训练时要优化的函数(通常是最大化它,如果我们要最小化它,通常它被称为损失函数)。寻找目标函数的最优点有几种方法,如最大似然估计(MLE)和不同的梯度下降法等。

GANs 由两个深度神经网络组成,生成器网络(表示为 G)和鉴别器网络(表示为 D)。G 的目的是从分布 p_data 中输出假数据 G(z)来欺骗 D。另一方面,鉴别器网络 D 输出真实数据的概率,其目标是最大化真实标签的概率和最小化虚假标签的概率(分布为 p_z)。

在训练期间,G 和 D 基于下面的最小-最大目标函数 V(G;d):

等式 1。作者图片

鉴别器应该给真实图像(D_θd(x))一个高值,这与对它取逻辑函数((logD_θd(x)))是一样的。它还应该给假图像(G_θg(z))一个低值,这与减去它并取逻辑函数(log(1- D_θd(x))是一样的。简而言之,可以通过上述目标函数 V(G;d)为 d。

对于生成器来说,最好是愚弄生成器,如果 D_θd(x)接近 1,就可以实现,这与最小化 log(1- D_θd(x))相同。对于生成器来说是有区别的,也就是说,最小-最大函数 V(G;d)不依赖于发电机。(在打假人与警察的博弈类比中,警察能否识别真钱与打假人无关。)简而言之,它与最小化目标函数 V(G;d)对于θg。

训练甘斯

由于训练中的实际原因,对发生器部分进行了修改,而不是原来的目标函数:

等式 2。作者图片

原因是在训练开始时,生成的伪图像太明显(即 D_θd(x)接近于零),因此损失几乎为零并且具有零梯度。

对于新的目标函数,当 D_θd(x)较小时,梯度比原来的高:

等式 3。作者图片

但是对于一个梯度:

等式 4。作者图片

当 D_θd(x)较小时,等式 3 中的分母比等式 4 中的分母小得多。

原始论文陈述了鉴别器 D 的最佳点和训练过程,这里跳过这些以避免数学细节和直接复制,但是这里提供了用于说明的非正式想法:

  • 训练在小批量的噪声样本和真实例子中进行。minibatch 的目标是加快训练过程,因为通过所有数据训练 DNN 是非常繁重的。
  • 发电机的原始随机梯度下降通常被方程 2 的随机梯度上升代替。

参考资料:

  1. 古德费勒、j .普热-阿巴迪、m .米尔扎、b .徐、d .沃德-法利、s .奥泽尔、a .库维尔和 y .本吉奥。生成对抗网络。在 NIPS,2014。
  2. 好家伙。Nips 2016 教程:生成性对抗网络。arXiv 预印本 arXiv:1701.00160,2016。

深度学习:张量和张量流简介

原文:https://towardsdatascience.com/deep-learning-introduction-to-tensors-tensorflow-36ce3663528f?source=collection_archive---------10-----------------------

了解最受欢迎的深度学习库!

图片来自 Unsplash

介绍

本文的目标是涵盖以下主题:

  • 张量介绍
  • 图表、变量和操作
  • 使用 TensorFlow 解决问题

什么是张量流

TensorFlow 是由 Google 开发和维护的一个框架,它使数学运算能够在 CPU 或 GPU 上以优化的方式执行。我们将专注于 GPU,因为这是我们训练深度神经网络的最快方法。

为什么是 Tensorflow?

  • 因为它的灵活性和可伸缩性
  • 因为它受欢迎

按作者分列的数字

使 TensorFlow 成为最受欢迎的深度学习库的关键功能是:

  • TensorFlow 使用张量来执行操作。
  • 在 TensorFlow 中,首先定义要执行的活动(构建图),然后执行它们(执行图)。这允许该过程被优化到手边的任务,大大减少了计算时间。
  • TensorFlow 支持代码并行运行或在一个或多个 GPU 上运行。

好吧,但是张量是什么?

虽然张量是物理学家发明的,用来描述相互作用,但在人工智能领域,张量可以简单地理解为数字的容器。

按作者分列的数字

让我们现在就把这一切付诸实践。我们将使用 python 编写一些张量代码,以便更好地理解它们是什么以及它们是如何工作的。

实践中的张量

假设我们想存储一个学生的平均成绩。我们将使用一个 0D 张量,它只是一个简单的数或标量。

import numpy as nptensor_0D = np.array(5)
print("Average grade: \n{}".format(tensor_0D))
print("Tensor dimensions: \n{}".format(tensor_0D.ndim))

现在让我们尝试存储该学生所学的每门课程的分数。我们可以用 1D 张量来做到这一点:

tensor_1D = np.array([4,6,8])
print("Subject grades: \n{}".format(tensor_1D))
print("Tensor dimensions: \n{}".format(tensor_0D.ndim))

但是,等等……如果我们想存储学生每门学科的每次考试的分数,该怎么办呢?如果每个科目有 3 次考试,我们该怎么做呢?

通过使用 2D 张量!正如我们之前看到的,它是一个矩阵。

**# 2D Tensor (matrix)**
tensor_2D = np.array([[0, 1, 1],  # Subject 1
                      [2, 3, 3],  # Subject 2
                      [1, 3, 2]])  # Subject 3
print("Exam grades are:\n{}".format(tensor_2D))print("Subject 1:\n{}".format(tensor_2D[0]))print("Subject 2:\n{}".format(tensor_2D[1]))print("Subject 3:\n{}".format(tensor_2D[2]))print("Tensor dimensions: \n{}".format(tensor_2D.ndim))

我们现在希望存储四个季度的科目成绩(每年一次),这样将来需要时就可以更容易地访问它们,你不这样认为吗?你认为我们该如何组织他们?

如果我们给 2D 张量增加一个维度来表示四分之一会怎么样?

我们会得到一个三维张量(三维矩阵或立方体)。

tensor_3D = np.array([[[0, 1, 1],  # First quarter
                      [2, 3, 3],
                      [1, 3, 2]],
                     [[1, 3, 2],  # Second quarter
                      [2, 4, 2],
                      [0, 1, 1]]])
print("Exam grades per quarter are:\n{}".format(tensor_3D))print("First quarter:\n{}".format(tensor_3D[0]))print("Second quarter:\n{}".format(tensor_3D[1]))print("Tensor dimensions: \n{}".format(tensor_3D.ndim))

如果我们在张量中增加一个维度,这样我们就可以得到每个学生每门学科每学期的成绩,会怎么样?

它将是一个 4D 张量(3D 矩阵向量或立方体向量)。

tensor_4D = np.array([[[[0, 1, 1], # Jacob
                      [2, 3, 3],
                      [1, 3, 2]],
                     [[1, 3, 2],
                      [2, 4, 2],
                      [0, 1, 1]]],
                      [[[0, 3, 1], # Christian
                      [2, 4, 1],
                      [1, 3, 2]],
                     [[1, 1, 1],
                      [2, 3, 4],
                      [1, 3, 2]]],
                     [[[2, 2, 4], # Sofia
                      [2, 1, 3],
                      [0, 4, 2]],
                     [[2, 4, 1],
                      [2, 3, 0],
                      [1, 3, 3]]]])
print("The grades of each student are:\n{}".format(tensor_4D))print("Jacob's grades:\n{}".format(tensor_4D[0]))print("Christian's grades:\n{}".format(tensor_4D[1]))print("Sofia's grades:\n{}".format(tensor_4D[2]))print("Tensor dimensions: \n{}".format(tensor_4D.ndim))

所以我们可以无限地增加张量的维数,来存储更多的数据。

为了让您了解张量在深度学习领域的使用频率,最常见的张量类型有:

  • 三维张量:用于时间序列。
  • 4D 张量:用于图像。
  • 5D 张紧器:与视频一起使用。

通常,其中一个维度将用于存储每种数据类型的样本。例如,对于图像:

如果我们想要存储 224x224 像素的 64 幅 RGB 图像,我们将需要一个 3D 矩阵向量,或者同样的,一个 4D 张量。我们需要多少维度?

我们有 64 幅 224 像素 x 224 像素 x 3 通道(R、G、B)的图像。

因此:(64,224,224,3)

如果你想更深入地了解张量或更多的例子,这里有一个非常好的资源:用猫说明的张量

我们之前说过,在 TensorFlow 中,首先定义要执行的操作,然后执行它们。为了做到这一点,你使用一个图表。

什么是图形?

a + b 求和的一个简单例子。

按作者分列的数字

这是一个更复杂的例子,现在,你不需要完全理解,但这只是其中的一小部分。

张量流付诸实践

首先我们需要定义和理解 TensorFlow 的一些基本概念(从现在开始 TF):

  • tf。图:表示一组 tf。操作
  • tf。运算:运算是由我们定义的方程式决定的吗
  • tf。张量:我们存储 tf 结果的地方。操作

一开始,tf。图形对我们来说是透明的,因为有一个默认的图形,其中添加了我们定义的所有操作。它被称为 tf.get_default_graph()。

**# We import the Tensorflow package and matplotlib for the charts** import tensorflow as tf
import matplotlib.pyplot as plt 
%matplotlib inline

先说一些很简单的,仅仅是 Tensorflow 中的一个简单乘法。

**# Variables definition**
x = tf.constant(6)  
y = tf.constant(8)**# Operations definition**
result = tf.multiply(x, y)
print(result)

如你所见,它没有给我们返回结果。到目前为止,它所做的就是创建网络。

举个例子,就像坐车一样。现在我们已经把它组装好了,但是它仍然没有完成它的设计,移动。为此,我们应该打开它。为此,我们将使用 tf。会话()。

sess = tf.Session() 
output = sess.run(result)  
print(output)

为了能够可视化该图,我们应该定义几个函数。

from IPython.display import clear_output, Image, display, HTMLdef strip_consts(graph_def, max_const_size=32):
    """Strip large constant values from graph_def."""
    strip_def = tf.GraphDef()
    for n0 in graph_def.node:
        n = strip_def.node.add() 
        n.MergeFrom(n0)
        if n.op == 'Const':
            tensor = n.attr['value'].tensor
            size = len(tensor.tensor_content)
            if size > max_const_size:
                tensor.tensor_content = "<stripped %d bytes>"%size
    return strip_defdef show_graph(graph_def, max_const_size=32):
    """Visualize TensorFlow graph."""
    if hasattr(graph_def, 'as_graph_def'):
        graph_def = graph_def.as_graph_def()
    strip_def = strip_consts(graph_def, max_const_size=max_const_size)
    code = """
        <script>
          function load() {{
            document.getElementById("{id}").pbtxt = {data};
          }}
        </script>
        <link rel="import" href="[https://tensorboard.appspot.com/tf-graph-basic.build.html](https://tensorboard.appspot.com/tf-graph-basic.build.html)" onload=load()>
        <div style="height:600px">
          <tf-graph-basic id="{id}"></tf-graph-basic>
        </div>
    """.format(data=repr(str(strip_def)), id='graph'+str(np.random.rand()))iframe = """
        <iframe seamless style="width:1200px;height:620px;border:0" srcdoc="{}"></iframe>
    """.format(code.replace('"', '&quot;'))
    display(HTML(iframe)

现在我们将展示之前定义的图表:

正如我们所见,该图由两个常量类型的节点和一个运算符类型(乘法)的节点组成。然而,他们的名字并不十分具有指示性。让我们改变这一点:

x2 = tf.constant(5.0, name='x2')
y2 = tf.constant(6.0, name='y2')result = tf.multiply(x2, y2)# Let's see what it looks like now:
show_graph(tf.get_default_graph().as_graph_def())

一旦我们执行了操作,我们应该关闭会话,用 sess.close()释放资源。

最后,我们还可以向 the GPU 表明我们希望它执行操作。为此,我们可以打印可用设备的列表:

from tensorflow.python.client import device_libdef get_available_devices():
    local_device_protos = device_lib.list_local_devices()
    return [x.name for x in local_device_protos]print(get_available_devices())

我们将选择 GPU:0,并执行[3 ^ 3]乘以[2 ^ 2]的乘法运算,结果可能是 3x3 +2x2 = 12。让我们来看看:

通过使用 with ___ as __:我们让 python 自己释放 TF 会话的资源:

with tf.Session() as sess:
  with tf.device("/GPU:0"):
    matrix1 = tf.constant([[3., 3.]])
    matrix2 = tf.constant([[2.],[2.]])
    product = tf.matmul(matrix1, matrix2)

  output = sess.run(product)
  print(output)

现在让我们创建一个在-5 和 5 之间平均稀疏的 32 个值的 1D 张量:

n_values = 64
x = tf.linspace(-5.0, 5.0, n_values)sess = tf.Session()
result = sess.run(x)print(result)

除了 sess.run(_)之外,还有其他评价张量的方法

x.eval(session=sess)

我们需要始终记住结束会议:

sess.close()

我们还可以使用交互式会话,这可以帮助我们不必不断地调用。运行()以执行结果:

sess = tf.InteractiveSession()
x.eval()

现在我们来看一个 tf。操作,为此,我们将使用“x”来创建和可视化高斯分布。它的公式是:

sigma = 1.0
mean = 0**# To implement the gaussian distributio formula**:
g1d = (tf.exp(tf.negative(tf.pow(x - mean, 2.0) / (2.0 * tf.pow(sigma, 2.0)))) *
     (1.0 / (sigma * tf.sqrt(2.0 * 3.1415))))**# to check that this operation has been succesuflly included in our tf.Graph**
if g1d.graph is tf.get_default_graph():
  print('All good')

plt.plot(g1d.eval())

# to see the dimensions
print(g1d.get_shape())
print(type(g1d.get_shape()))print(g1d.get_shape().as_list())print(type(g1d.get_shape().as_list()))

有时候,在执行返回变量值的操作之前,我们不知道变量的维数。对于这些情况,我们可以使用 tf.shape(variable ),它返回一个张量,在运行时计算结果的维数。

这被称为“静态形状”和“动态形状”,其中静态形状的计算考虑了张量的维度和所涉及的操作,以及执行时的动态。

如果我们将 x 定义为“占位符”会发生什么?一个占位符就像一个储备,它表明那里会有一个张量,但没有必要在那个时刻定义它。例如,通过定义:

x = tf.placeholder(tf.int32, shape=[5])

我们知道 x 将持有一个 1D 五维张量,这一点由 x.get_shape()所证实:

print(x.get_shape())

但是我们不知道什么价值观会形成它,直到我们告诉它。

占位符和变量的区别:

变数

它们用于容纳在培训过程中学习到的参数。

因此,这些值是从训练中获得的-它们需要分配一个初始值(可以是随机的)

占位符

为数据保留空间(例如,为图像中的像素)

它们不需要为 start 赋值(尽管它们可以)

获得的值 5 是 x 维度的静态值。但是,如果我们对 x 应用一个 tf.unique()会发生什么呢?

y, _ = tf.unique(x)
print(y.get_shape())

所发生的是 tf.unique()返回 x 的唯一值,这些值最初是未知的,因为 x 被定义为一个占位符,占位符直到执行时才需要定义,正如我们之前所说的。事实上,让我们看看如果我们给“x”输入两个不同的值会发生什么:

with tf.Session() as sess:
 print(sess.run(y, feed_dict={x: [0, 1, 2, 3, 4]}).shape)
 print(sess.run(y, feed_dict={x: [0, 0, 0, 0, 1]}).shape)

看那个!y 的大小根据 tf.unique()返回的内容而变化。这叫做“动态形状”,它总是被定义的,它永远不会通过回答返回一个问题。因此,TensorFlow 支持类似 tf.unique()的操作,这些操作可能会产生大小可变的结果。

现在你知道了,每次你使用输出变量的运算,你都需要使用 tf.shape(变量)来计算张量的动态形状。

sy = tf.shape(y)**# Returns a list with the dimensions**
print(sy.eval(feed_dict={x: [0, 1, 2, 3, 4]}))
print(sy.eval(feed_dict={x: [0, 0, 0, 0, 1]}))**# We access the dimension of interest**
print(sy.eval(feed_dict={x: [0, 1, 2, 3, 4]})[0])
print(sy.eval(feed_dict={x: [0, 0, 0, 0, 1]})[0])

现在,我们可以在考虑操作的输出大小之后执行操作,我们在第一个实例中并不知道输出的大小。

print(tf.shape(y).eval(feed_dict={x: [0, 1, 4, 1, 0]}))
print(type(tf.shape(y).eval(feed_dict={x: [0, 1, 4, 1, 0]})))print(tf.stack([y, y[::-1], tf.range(tf.shape(y)[0])]).eval(feed_dict={x: [0, 1, 4, 1, 0]}))

现在让我们看看 2D 的高斯分布

g1d_r = tf.reshape(g1d, [n_values, 1])
print(g1d.get_shape().as_list())
print(g1d_r.get_shape().as_list())# We multiply the row vector of the 1D Gaussian by the column to obtain the 2D version
g2d = tf.matmul(tf.reshape(g1d, [n_values, 1]), tf.reshape(g1d, [1, n_values]))# To visualize it
plt.imshow(g2d.eval())

查看我们的 tf 中包含的操作列表。图表

ops = tf.get_default_graph().get_operations()
print([op.name for op in ops])

结论

一如既往,我希望你喜欢这篇文章,并且你已经学习了张量和张量流的基础知识以及它们是如何使用的

如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里

如果你想了解更多关于机器学习和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!

深度学习很容易

原文:https://towardsdatascience.com/deep-learning-is-easy-a048afd50c81?source=collection_archive---------59-----------------------

意见

企业通过深度学习创造价值有多容易

很长一段时间以来,深度学习一直是新闻中的热门话题。这有很好的理由——最重要的理由是它通过软件提供的附加值。今天,我们将探索这些年来深度学习变得多么容易,以及这对就业市场意味着什么。

丹尼尔·明戈金在 Unsplash 上的照片

让我先做一个大胆的免责声明——这篇文章不适用于深度学习的研究部分。然而,这篇文章确实适用于实际的深度学习。我所说的“实用”是指利用深度学习库来解决特定的业务问题。

今天,我们将探索在没有雇用任何深度学习工程师的情况下,这些公司可以在深度学习方面做些什么。所有的工作都可以由软件开发人员或领域专家来完成——归结起来就是点击几下鼠标。

这里的目的是测试深度学习工程师是否变得过时,并测试入门级深度学习工作所需的技能水平——所有这些都是根据 2020 年的标准。

但是我们如何测试呢?好问题。让我们在下一节看一个具体的例子。

具体的例子

“没有数据,你只是另一个有观点的人”——威廉·爱德华·戴明说,我非常同意。我不指望你相信你读到的一切——我知道我不会。这就是为什么我准备了一个具体的、简单易懂的展示,让你无可争议。

让我把你介绍给乔。

乔在一家医院的一个部门工作,该部门处理肺部疾病和一般肺部疾病。缺少医学专家,工作不断出现。医务人员超负荷工作,疲惫不堪,因此容易出错。

我不是医学专家,所以如果我在这里说错了什么,请原谅我——这是最重要的整体概念。

为了减轻团队的负担,Joe 决定使用深度学习来“外包”重复的任务,比如说,肺部图像分类。最终的结果是,Joe 的医疗团队应该有更多的时间从事这项工作的人的方面。唯一的问题是——乔对深度学习一无所知。

Joe 在网上搜索并找到了一些 AutoML 工具——比如苹果的 CreateML。碰巧他也有一台 Mac 电脑。太好了!

经过进一步的研究,Joe 发现 CreateML 对很多任务都很有用——图像分类就是其中之一:

太棒了。Joe 在医院工作,所以获取数据不成问题。他的团队已经收集并标记了几千张图片,准备插入到 CreateML 中。

现在我无法访问他们的图像,所以我将使用肺炎肺部图像数据集进行演示。该数据集包含超过 5000 张(非常)不同大小的肺部图像——这对深度学习实践者来说是一个问题,但对 CreateML 来说不是问题。

Joe 的下一步是开发一个预测模型。在阅读了一两篇文章之后,他熟悉了训练/测试/验证分割的概念,所以他以那种方式组织数据。结果是 CreateML 以同样的方式工作:

只需拖放即可——其他一切都是自动处理的

乔现在可以点击那个大而醒目的 Run 按钮,开始训练过程。在我的机器上花了大约 1 个小时完成,但结果是在测试集上产生了 85%的准确率(以前看不到的数据):

我不知道医学专家的分类有多少次是错的,但 85%肯定是一个很好的起点!

我以前在这个 Pneuomina 数据集上工作过(用 PyTorch ),在测试集上只获得了 83.5%的准确率。这里的召回值非常高,大约为 99.5%,这意味着如果图像被分类为受感染,我们可以 99.5%确定它确实被感染了。

简单来说,这个模型不太可能对阳性病例进行错误分类。该数据集的问题是类别不平衡-负面案例比正面案例多约 2 倍-这影响了模型的整体预测能力(准确性)。

然而,85%是坚如磐石的,至少一开始是这样。当然,乔和他的医疗团队是一个虚构的人,但我希望你能明白。

这对就业市场意味着什么?

这是否意味着深度学习工作将成为过去?一点也不,但你还是应该有所顾虑。

试着像做生意一样思考一下。如果一个免费工具可以胜过新手深度学习实践者,你会雇佣他们吗?我知道我不会。还有, CreateML 模型很容易将模型部署到 iOS 和 macOS 上,但是通过一些手工操作,模型可以部署到任何地方。

CreateML 这样的工具是为软件开发人员设计的——让他们更容易在应用程序中使用机器学习。这并不意味着取代人,但人们只能假设,除了这些工具可以提供的解决方案之外,很大一部分公司并不需要更复杂的解决方案。

另外,你能指望新手知道如何处理模型部署吗?没有,但是您的软件开发和 DevOps 团队可以轻松处理这项任务。

那么深度学习实践者的目的是什么呢?嗯,通过专业知识和领域知识来超越像这样的工具。初级从业者可能做不到这一点。这也是为什么领域内大部分职位都是资深的原因。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

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

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

如何让深度学习使用逻辑

原文:https://towardsdatascience.com/deep-learning-is-not-logical-ce0941b74f0a?source=collection_archive---------31-----------------------

理解大脑如何导航环境可以帮助人工智能解决复杂的问题

亚历山德鲁-波格丹一世·吉塔在 Unsplash 上拍摄的照片

在这篇文章中,我将展示深度学习无法理解逻辑和结构,并指出由神经科学启发的潜在解决方案。这很重要,因为世界上大多数有价值的问题都需要逻辑地解决,但现代深度学习在这方面很大程度上失败了。

合乎逻辑是什么意思?

从统计学的角度来说,逻辑类似于在给定一组观察值的情况下对预测的极端信心。在纯粹的逻辑世界中,1 + 1 = 2 总是正确的,而在更随机的非逻辑系统中,1 + 1 = 2 可能只在 90%的情况下是正确的。

有些逻辑产生于我们对世界结构的理解,比如物理定律。举个例子,如果你丢了一个球,然后你希望它会掉到地上。然而,在一个非结构化的世界中,一切皆有可能,这使得预测未来变得困难。例如,股票市场是一个非结构化的世界。我父亲从 5 月份就开始关注 Novax Pharma,但他不可能预测到首席执行官会卖掉他的股票,使其价格暴跌。

统计学家可能会说,我们生活在一个随机和无组织的世界,但宇宙中也有许多方面是可预测和符合逻辑的,如物理、数学和科学。逻辑性让我们能够规划未来,并形成具体的路径来帮助我们达到目标。几乎所有值得解决的难题都需要运用推理和逻辑。

纯深度学习是学不到逻辑的

深度学习能否实现逻辑的圣杯? DeepMind 在他们 2019 年的论文中提出了这个问题,他们在论文中实现了一个变压器模型来解决数学问题[1]。他们的结果令人印象深刻;该模型在简单的加法、减法、除法和乘法中达到了 90%以上的准确率。但是当混合操作时,性能下降到 50%,这表明该模型只是猜测解决方案,而不是一步一步地解决问题。

在深度学习中还有其他例子,模型或代理人非常擅长他们的任务,以至于他们产生了逻辑和推理的幻觉。

OpenAI 的 GPT-2 语言模型可以生成类似人类的文章,但更仔细的检查表明,它的输出没有逻辑结构,只是模仿它在训练数据中被训练的内容。例如,该模型有时会写到水下发生的火灾。

DeepMind 和 OpenAI 开发的分别用于玩星际争霸 2 和 DotA 2 的视频游戏代理在各自的游戏中击败了顶级职业游戏玩家,但大多使用纯粹的机械技能和执行良好的攻击,而不是策略。例如在 DotA 2 中,如果目标的生命值低于阈值,玩家可以采取一个动作立即杀死另一个玩家,否则伤害很小甚至没有。不可否认,在阈值以上使用它是一个错误,但 OpenAI 的 DotA 2 bot 一直在这样做。当人类对手使用仅靠机械技能无法克服的模糊策略时,DeepMind 为《星际争霸 2》开发的 AlphaStar 会持续倾斜并输掉比赛。

一些人认为,如果接受更长时间的训练,这些特工可能会克服上述缺陷。这可能是真的,但是这些问题通常不会出现在普通玩家身上。很明显,这些智能体缺少一种使它们像人类一样聪明的成分。

神经科学给了我们答案

早在二月份,我偶然发现了莱克斯·弗里德曼对理论神经科学家杰弗瑞·霍金的采访。在采访中,霍金斯描述说,神经科学家正在假设人类空间导航的神经机制也可能是人类导航抽象概念的能力的原因。我是说,为什么不呢?从逻辑上来说,解决问题与空间导航使用相同的原理,因为两者都需要规划从起点到终点的路线。

2018 年,DeepMind 恰好实现了世界上第一个使用神经基底进行空间导航的智能体(称为网格细胞)[2]。代理的任务是在迷宫般的环境中导航,网格细胞的参与教会了代理始终选择捷径并在原始捷径受阻后创建新的捷径。这是一个令人难以置信的壮举,网格细胞的最初发现者评论说这是“机器人学中众所周知的困难”。然而,最重要的是,他们的实验发现,智能体中使用的神经网络通过仅让网络估计智能体每次移动时在迷宫中的位置和朝向,发展了类似网格细胞的属性。简而言之,他们的发现表明自我意识(在这种情况下是空间自我意识)是解决任何导航问题的关键因素。对于我们大多数人来说,这不应该是一个惊喜,因为评估我们相对于目标的位置对于实现目标是至关重要的。**

这是这篇文章的惊人想法。我们一直在通过最小化预测误差来训练深度学习模型(例如,分类图像是猫还是狗等等),但如果我们最小化其自我意识误差,模型是否有可能理解这个世界的结构并导航抽象概念?

实现自我感知的人工智能

假设自我意识是人工智能逻辑解决问题的必要成分之一,我们将如何实现它?网格细胞论文中有一些要点:

  1. “自我意识”的错误是真实情况和代理人自己预测的位置和方向之间的差异。
  2. 基本事实的位置和方向(代理的自我意识)由神经激活信号表示,当代理处于唯一的位置和方向时,每个单元都会触发。
  3. 网格单元相对于代理的位置和它的方向以规则的间隔被激活
  4. 当模型训练以最小化自我意识的损失时,网格单元激活正好在最终线性层之前出现。

总之,只要我们确定它所处的环境,并尽量减少对其坐标和方向预测的误差,“自我意识”就会完全脱离训练。不幸的是,涉及网格单元的实验只在空间导航上进行过,所以还不清楚它是否适用于非空间系统。

但我心里确实有一个实验。自然语言处理中的一个研究热点是理解如何教授一个模型来捕捉因果关系。我之前提到的关于 GPT-2 写的关于水下发生火灾的例子是一个混淆因果关系和相关性的例子。仅仅因为有句子说水经常灭火并不意味着火影响水。学会在单词嵌入的向量空间中导航的网格细胞会更好地捕捉这种关系吗?

结论

虽然上面的实验是推测性的,这篇文章可能完全是一场虚惊,但不可否认的是深度学习已经撞上了一堵墙,对于研究社区来说,一个值得前进的方式是探索新的想法(哎呀,感谢明显队长!).在我的计算机科学论文项目期间,我探索了知识图在赋予神经网络推理能力方面的潜力。这是一个很酷的概念,但由于图形的内在限制,这个项目失败了。

在写这篇文章的时候,我正暂停深度学习,专注于我最后一年的教育,所以我将火炬传递给你。对于那些厌倦了优化现有架构或被这一想法吸引的人,我强烈建议你看看 DeepMind 关于 grid cell 的论文,并将其应用于非空间应用。谁知道呢,你可能会发现一个比现有架构性能更好的新架构。但是如果你是,记住你是从这里听到的。

[1] D. Saxton,E. Grefenstette,F. Hill,和 P . Kohli,分析神经模型的数学推理能力 (2019),ICLR 2019

[2] A. Banino 等人工智能体中使用网格状表示的矢量导航 (2018),Nature 26,1。

深度学习不是解开奇点的钥匙

原文:https://towardsdatascience.com/deep-learning-is-not-the-key-to-unlocking-the-singularity-913f960ac345?source=collection_archive---------14-----------------------

深度学习改变了人工智能领域,但它不会给我们人工通用智能——下面是原因。

D eep 学习是使用神经网络来解决近似、回归或分类任务。这个工具已经成为展示智能代理的突出设备,但它并不具备结构化推理的明显潜力。这篇文章强调了深度学习的惊人的优势,将其放在我们试图解决的的背景下。

神经网络的规范图像。来源—作者。

神经网络是使人工智能实用化的第一个工具——它们现在被用于许多领域(见这篇impact 综述)。上一次单一技术试图在行业中引起引人注目的变化是 专家系统 ,在那里,计算机科学家和专业人士的协同作用将他们的知识提取到树状搜索算法中,以供重复使用。这种方法的问题在于,它无法解读训练集的言外之意——它只是重复给定的内容,因此公司不再花钱制作它们。它给了我们第一个艾的冬天

机器学习:人工智能的子领域,任务是从状态空间的部分观察中对新数据做出决策。

关于 AI 的状态,神经网络改变了什么?他们有能力概括(或记忆)一个状态空间到适度概括的程度。你问什么是神经网络?逼近任何有限的输入数据集都是一个长时间的非线性函数和矩阵运算的交织过程。如果你想知道更多,我会让你观看这个由格兰特·桑德森制作的神奇的* 视频和系列。有许多方法来描述它,但是在本文的上下文中,仅仅把它想成一个高维函数近似器就足够了。*

在讨论神经网络时,记住机器学习的目标是什么是很重要的。 机器学习是关于做决策,人工智能是关于做推理能力。 做第一件事可以启用第二件事,但这不是一个充分的准则。

奇点是什么?

Vernor Vinge 在 1993 年的一篇文章 中创造了“奇点”,即将到来的技术奇点 ,它标志着人类从占主导地位的超级智能时代的结束。现在,人工智能领域的顶尖科学家在争论它何时会出现,我暂时弃权。最终,问题是,需要什么工具或发现来让计算机绕过人类智能。答案不是深层网络。

来源——作者 CS188 课程,http://ai.berkeley.edu

反对深度学习的理由

为什么深度学习不会超越人类的智力——缺乏真正的概括?最近的研究已经讨论了神经网络是如何简单地记忆训练集的,其间有轻微的插值。这解释了转换数据的困难、分布变化的困难以及增加数据集大小的好处。深度网络是最好的近似工具,因为它们可以跨越有限数据的任何领域:计算机视觉、动态系统、音频处理等等。他们无法准确预测系统何时在复杂的习性中扩展,如身体智能或抽象造句,这是人类大脑的奇迹。

把神经网络的预测能力看作是解决人类水平智能的必要组成部分,但是对于是否足以证明超级智能的存在并没有说什么。

将深度学习与符号人工智能相结合

人脑是一个 20W 的通用智能系统的存在。计算机最终可以做到(也许在更高的功率下)。象征性人工智能的经典领域试图使用更高级的数学和基于推理的构造来创造智能系统。符号人工智能旨在使计算机能够推理和提取知识,而不是记忆和预测。也就是说,深度学习已经实现了如此多的自动化任务(图像识别、时间序列预测等),因此这些推理系统可以采取非常不同的方法。在深度学习浪潮之外获得资金要困难得多,但正是研究人员展示了下一个平台(可能利用深度学习),这将通过建设性的推理能力彻底改变该领域

人工智能社区需要记住有时会偏离正道。来源—作者。

强化学习是深度学习的展示

强化学习近年来已经成为深度学习能力的一个戏剧性展示——在各种游戏中展示戏剧性的概括和发现能力( 123 、…)。它如此成功的原因是它们是游戏。它们是不同比例的玩具样品。RL 的进步表明,我们可以将一个报酬近似问题框架化为一个回归问题。

[GAE-舒尔曼,莫里茨,莱文,约旦,阿比勒,ICLR 2016]

这是如此令人兴奋的原因——潜力。当我们将更多真实世界的问题公式化为复杂的近似问题时,deep-RL 任务将会更出色。现在的障碍是系统和数据科学。

考虑一下新上市的初创公司 Covariant.ai他们正在用深度学习进行物流革命(当然,也在幕后尝试 RL——伯克利的 source friends。)

Lex Friedman 对深度学习的位置做了一个很好的总结——学习专家在互联网上的人数越来越多,请欣赏!

更多?订阅我关于机器人、人工智能和社会的时事通讯!

[## 自动化大众化

一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…

robotic.substack.com](https://robotic.substack.com/)

深度学习,认识聪明的汉斯

原文:https://towardsdatascience.com/deep-learning-meet-clever-hans-3576144dc5a9?source=collection_archive---------26-----------------------

一篇关于 DNNs 犯下的隐藏错误,为什么它们真的不是错误的文章,还有一匹德国马。

基拉·奥德·海德在 Unsplash 拍摄的照片

【1900 年左右,一位德国农民做出了一个惊人的声明:他教会了一匹马基本的算术,甚至识字和拼写!事实上,在公开演示中,这匹名为“聪明的汉斯”的马能够通过一连串的蹄子敲击正确地回答主人的所有问题。

当时柏林大学的心理学家 Oskar Pfungst 不太相信这种动物真的拥有类似人类的能力,他设计了一系列实验来证明这位农民的说法是错误的。1907 年,他发表了关于这个问题的著名报告,做出了令人惊讶的观察:只有当提问的实验者知道答案时,聪明的汉斯才会给出正确的答案!

这匹马实际上并没有学会通过计算或阅读来解决问题,而是通过识别实验者身体语言中的微妙线索来判断出它所期望的答案。

时至今日,心理学研究中(人或动物)测试对象的行为受实验者预期影响的现象被称为“聪明的汉斯现象”。通常,要特别注意防止受试者在没有解决实际问题的情况下给出正确的答案。

等等。我以为这篇文章是关于深度学习的?

事实上,在现代尖端的深度学习系统(甚至是简单回归)中,我们遇到了同样的问题!当数据中存在与正确结果高度相关的特征(如实验者的肢体语言)时,可能会出现聪明的汉斯现象,或传统统计学文献中的虚假相关性,但不是答案正确(如正确计算)的原因

Lapuschkin 等人最近在《自然》杂志上发表的一篇文章漂亮地说明了这种效应确实发生在现代深度学习模型中,例如图像识别或玩雅达利游戏。(更多示例见下文。)

那么,我们为什么要关心模型使用什么信息呢?模型终究是在输出正确的答案。

对你的训练和测试数据来说是这样的。

但是它在部署时仍然正确吗?它会因为依赖错误的特性而轻易被愚弄吗?

例如,想象你有一个区分狼和哈士奇的算法,但它主要是通过图像中出现的雪来区分狼和哈士奇。或者,想象一下你想要识别火车和船只(例如,给定 PASCAL VOC 2012 数据集),但是你的算法实际上学会了识别水和铁轨。这对任何严肃的应用程序来说都是灾难。如果你注意的话,你可以在文献中找到很多例子:

现在,你仍然可以争辩说,它并没有那么糟糕;毕竟网络正确地解决了任务,只是问题没有以好的方式提出——只是修复数据!如果你这样做了,你是在一个很好的公司。莱昂·博图(Léon Bottou)是目前在脸书人工智能公司工作的著名研究员,他认为修正我们的问题陈述可以走很长的路。

这有什么大不了的?为什么聪明的汉斯类型的错误如此糟糕,以至于我们必须独立于典型的分类错误来关心它们?

事实是,发现你的网络是否犯了聪明的汉斯类型的错误真的不容易,准确地说是,因为它们没有反映在分类错误中。基本上,你必须依赖于一个无偏差的数据集或者一个足够高质量的测试集。从上面的例子来看,不太令人放心。

如果你正在使用可解释性方法,并且知道要寻找什么,你可能通过查看网络实际使用的功能来发现聪明的汉斯类型的错误。但是对于大数据集,这是不可行的。研究人员开始以可扩展的方式解决这个问题,但是还有很长的路要走。

作为研究人员和实践者,重要的是要意识到聪明的汉斯类型的错误,并知道从哪里开始(试图)发现它们。除此之外,祝你好运!

希望你学到了有用的东西!

物体检测的深度学习方法:R-CNN 解释

原文:https://towardsdatascience.com/deep-learning-method-for-object-detection-r-cnn-explained-ecdadd751d22?source=collection_archive---------6-----------------------

R-CNN 目标检测算法,从原始论文一步一步讲解

来源:Matthijs Hollemans 的博客

介绍

CNN 已经被广泛用于图像分类。但是检测图像中的对象并在它们周围绘制边界框是一个很难解决的问题。为了解决这个问题,2014 年发表了 R-CNN 算法。在 R-CNN 之后,它的许多变体如 Fast-R-CNNFast-R-CNNMask-R-CNN 出现了,它们即兴完成了对象检测的任务。要了解最新的 R-CNN 变种,对 R-CNN 有一个清晰的认识是很重要的。一旦理解了这一点,那么所有其他的变化就很容易理解了。

这篇文章将假设读者熟悉 SVM,使用 CNN 和线性回归的图像分类。

概观

R-CNN 论文【1】发表于 2014 年。这是第一篇表明 CNN 可以在对象检测中产生高性能的论文。该算法以下列方式进行对象检测:

来源:原创论文

  1. 该方法将图像作为输入,并从图像中提取大约 2000 个区域提议(上图中的步骤 2)。
  2. 然后,每个区域提议被扭曲(整形)成固定大小,作为 CNN 的输入。
  3. CNN 为每个区域提议提取一个固定长度的特征向量(上图中的步骤 3)。
  4. 这些特征用于使用类别特定的线性 SVM 对区域方案进行分类(上图中的步骤 4)。
  5. 使用边界框回归来细化边界框,使得对象被该框正确地捕捉。

现在这篇文章将深入解释模型如何被训练以及它如何预测边界框的细节。

计算区域建议

地区提案|来源:作者图片

区域建议是可能包含对象的边界框。这些由 4 个数字(x,y,h,w)的元组表示。(x,y)是边界框中心的坐标,( h,w)分别是边界框的高度和宽度。这些区域建议由一种叫做选择性搜索【2】的算法计算。对于一幅图像,提取大约 2000 个区域提议。

训练 CNN 特征提取器;

基于 CNN(VGG 16 台)的特征提取器|来源: Pinterest |由作者编辑

预训练网络:为了训练 CNN 进行特征提取,像 VGG-16 这样的架构用来自 imagenet 数据的预训练权重初始化。具有 1000 个类别的输出层被切断。因此,当一个区域提议图像(扭曲到 224x224 大小)被传递到网络时,我们得到一个 4096 维的特征向量,如上图所示。这样,每个区域提议由 4096 维特征向量表示。

下一步是用区域建议图像微调网络的权重。为了理解这一点,我们将引入一个称为交集/并集或 IoU 得分的新指标。

并集上的交集

为了衡量分类模型的性能,我们通常使用准确度、召回率、精确度等指标。但是如何衡量物体检测的性能。在对象检测中,我们必须评估两件事:

  1. 边界框在图像中定位对象的能力。换句话说,预测的边界框有多接近地面真实。
  2. 边界框是否正确分类了被包围的对象

来源:阿德里安·罗斯布鲁克的博客

IoU 分数衡量预测框与实际情况的接近程度。它是地面真实值和预测框的公共面积与这两个框所包围的总面积的比率。

来源: Gitbook

在最左边的图像中,可以看到预测框不接近真实情况,因此 IoU 得分仅为 35%,而在最右边的图像中,预测框与真实情况框完全重叠,因此获得了 95%的非常高的值。IoU 值从 0 到 1 不等。

微调网络:为了微调模型,用 N+1 个类(softmax 层)替换具有 1000 个类的输出层,模型的其余部分保持不变。n 是对象被分类的不同类别的数量,加上背景类别的 1。

接下来,微调需要数据。IoU > 50%的区域提案被视为该目标的积极类别,其余被视为背景。在上面的球图像中,IoU 分数为 35%的区域提案将被标记为背景,而其余的方框将被标记为球。这些图像(区域提议)被扭曲(调整大小)到与 CNN 兼容的尺寸,在 VGG 16 的情况下是 224x224。使用这些图像,网络的权重被微调。

特定于培训班的 SVM

一旦获得了每个区域建议的 4096 维特征,下一个任务是为每个类别训练一个二元 SVM。例如,如果检测模型要检测三个不同的对象——猫、狗和人,那么需要为每个类训练三个 SVM。

数据准备:属于特定类别的所有对象提议被分离。该类别的手动标记的地面实况图像被认为是正类别,而对于该类别具有 IoU < 30%的对象提议被认为是负类别。对每个类别做同样的事情,并且训练 N 个 SVM 模型以将每个区域提议分类成 N 个类别。

包围盒回归

来源:我的起点网站 |作者编辑

由选择性搜索[2]算法预测的区域提议边界框可能无法捕获整个对象。为了微调预测的边界框,使用边界框回归。

通过选择性搜索[2]算法考虑地面真实区域建议 G 和预测区域建议 P。

为了使 G 比例不变的预测,进行以下变换,使得回归的目标是 t.

转换方程

来源: Pinterest |作者编辑

回归模型的输入是来自 CNN 的最后一个池层的特征。我们每类训练 4 个回归模型,目标为 t ,输入特征为 CNN 的最后一个池层特征,以学习回归参数 w。

回归方程式

这里*是(x,y,w,h)的占位符,phi(P)是对应于方案 P 的最后一个池化图层要素。因此,要预测地面实况 G,我们可以使用回归方程根据区域方案 P 计算 t,然后将 t 和 P 的值代入变换方程以获得 G。

预言;预测;预告

一旦 R-CNN 的不同部分被训练,接下来的部分是进行对象检测。

来源:作者图片

  1. 拍摄输入图像,并使用选择性搜索[2]算法,为图像获得大约 2000 个区域提议。
  2. 每个区域建议图像被扭曲成 224x224 的固定大小。
  3. 这些区域提议图像然后被传递到训练的 CNN 以获得所有 2000 个区域提议的 4096 维特征向量,这导致 2000×4096 维矩阵。

来源:作者图片

3.每个区域的提案都使用每个类别的 SVM 进行分类。通常对于 N 个类,SVM 权重(4096 维)以矩阵的形式堆叠,并与特征矩阵相乘。这将产生一个矩阵,该矩阵为区域提案所属的每个类别分配一个分数。

4.该建议被分配到得分最高的类别。因此,图像中的所有 2000 个区域提议或边界框都标有类别标签。

5.在那些众多的边界框中,许多是多余的和重叠的边界框,需要被移除。为了实现这一点,使用了非最大抑制算法。

非最大抑制算法:

来源:非最大压制博客

非最大抑制是一种贪婪算法。它一次只对一个类有效。对于一个特定的类,它选择使用 SVM 获得最高分数的盒子。然后,它计算属于该类的所有其他边界框的 IoU 分数。IoU 分数大于 70%的框被移除。换句话说,具有非常高重叠的边界框被移除。然后选择下一个最高得分框,依此类推,直到该类别的所有重叠边界框都被移除。对所有的类都这样做,以获得如上所示的结果。

6.一旦获得标记的边界框,下一个任务是使用回归来微调框的位置。

通过回归微调区域建议|来源:作者图片

在训练期间,为每个类训练 4 个回归模型。因此,对于特定的包围盒,区域建议图像通过 CNN 以获得要传递给回归模型的特征 P。回归模型输出比例不变的坐标(dx(P),dy(P),dw(P),dh(P))。这些坐标与区域建议坐标(Px,Py,Pw,Ph)相结合,使用以下公式获得调整后的最终坐标(Gx,Gy,Gw,Gh)。

原始论文的结果

R-CNN 物体探测结果|来源:原创论文

结论

R-CNN 虽然擅长检测对象,但也有不足之处。

  1. 这种算法很慢,在图像上执行对象检测大约需要 47 秒。
  2. 训练不是一步到位的。不同的部分有不同的模式,这使得培训过程非常耗时。

这些缺点在 R-CNN 后来的改进中得到解决,这些改进是 Fast-RCNN、Fast-RCNN 和 Mask-RCNN。对 R-CNN 有很好的理解,有助于轻松直观地理解 R-CNN 的其他变种。

参考

  1. R.吉希克、j .多纳休、t .达雷尔和 j .马利克。丰富的特征层次,用于精确的对象检测和语义分割。2014 年在 CVPR。
  2. Uijlings,Jasper & Sande,K. & Gevers,T. & Smeulders,Arnold。(2013).物体识别的选择性搜索。国际计算机视觉杂志。104.154–171.10.1007/s 11263–013–0620–5。

深度学习模型实现:分类变量的嵌入

原文:https://towardsdatascience.com/deep-learning-model-implementation-embeddings-for-categorical-variables-1f12df30fcc8?source=collection_archive---------26-----------------------

利用嵌入探索美国房价和移民模式

对于许多复杂的预测问题,深度学习(DL)方法(如 CNN、NLP 和全连接网络)提供了最高水平的性能。这通常以理解解释特征在预测结果中的作用为代价。虽然基于统计方法的机器学习(ML)方法提供了多种技术,包括变量选择、相对重要性和某些情况下的模型系数,以了解预测器的作用(如本系列的第 1 部分中所讨论的),但在 DL 方面实现类似见解的潜力还没有得到充分探索。而且,由于所涉及的复杂性,这种情况很可能会持续下去。然而,有一些方法可以获得一些关于众所周知的黑盒中发生了什么的线索。例如,在图像的 CNN 分析中,类别激活地图是一种识别图片的哪些区域在其分类中最活跃或最有影响力的方法。

嵌入

对于时间序列或其他结构化数据,嵌入为分类特征提供了标准的一键编码或“虚拟”变量表示的替代方法,可以洞察它们对因变量的影响模式(郭和 Berkhahn2016 )。嵌入矩阵与模型拟合一起被估计,并且它们的维数通常被选择为稍微小于变量的基数,例如,表示一周中各天的嵌入矩阵可以具有 7×4 的维数,从而允许每一天由 4 维嵌入向量来表示。这允许沿着 4 个维度来捕捉模式和各天之间的相似性或差异。

一个例子:房地产时间序列

我想看看我是否能从 DL 模型中估计嵌入,以及产生的模式是否是可解释的。当美国经济分析局(BEA)最近开始发布美国各县的 GDP 数据时,我开始对在这种地理粒度级别上还能找到什么类型的数据感兴趣。我热爱所有与房地产有关的事情,当时我还不是一个能接触到 MLS 信息的活跃的代理人。幸运的是,有 Zillow 研究公司。尽管 Zillow 在该网站上提供的信息会随着时间的推移而变化,但去年他们提供了从 2010 年 1 月 1 日到 2018 年 1 月 1 日期间约 1260 个美国县的调整后销售价格数据。各县提供的其他房地产数据包括销售计数、降价百分比、Zillow 房屋价值指数(ZHVI)、Zillow 天数、每月房源和以前止赎房屋的销售百分比。所有这些功能每月都有。我收集了美国各县的其他数据,包括 GDP(2015-2018,BEA),人口模式,失业和贫困,家庭收入,县商业模式和美国人口普查地区和部门(2010-2018,美国人口普查局)。这些数据每年记录一次。我还从美联储经济数据(2010-2018,FRED)中获得了月度优惠利率。

我的目标是使用 fastai 库来预测美国各县的年度月度调整销售价格。我拟合了一个具有两个完全连接层的 DL 模型,其中分类变量使用嵌入来表示。最终模型在预测下一年的调整后销售价格时实现了 8%的验证均方根百分比误差。你可以在这里看到适合和如何提取嵌入的代码。一旦提取,嵌入矩阵与原始数据合并回计算主成分(PCs)。地理变量的前两个 PCs 的图表如下,从最细到最细:州、部门和地区。这些会引出我们可以解读的东西吗?让我们来了解一下!

状态

作者图片

状态嵌入沿 PC1 的布局显示了一些我们可能预期的聚类(例如 CT 和 RI、NY 和 NJ)和异常值(例如 CA、HI),但在其他方面显得相当复杂。让我们使用美国人口普查部门和地区来进行更高层次的分组(你可以在这里看到这些)。

美国人口普查部门

作者图片

这里事情变得有趣了!沿着 PC1,除了南大西洋分部之外,其它地方都相当不错。沿着 PC2,我们有一些最初看起来不协调的分组,至少从地理角度考虑。东/北/中南部以及南大西洋与山区划分在一起,新英格兰/中大西洋与它们的海岸相对,太平洋。这些领域有什么共同点?

从供求及其对价格的影响来考虑,让我们看看美国的移民模式。虽然人口普查局也有这种类型的信息,但我发现了一个有趣的来源(来自应该知道的人!)是北美搬家服务。你可以在这里查看他们过去十年的互动迁徙地图。在美国大选的前一个月,我有点希望他们选择不同的颜色而不是红色和蓝色来区分各州是主要向外还是向内(!)但这是一张迷人的地图。在他们的网站上,你可以滑动滚动条来查看 2011 年至 2019 年每年的数据,并将鼠标悬停在每个州上来查看其出境和入境统计数据,以及财产税百分比。

有趣的是,我们看到了与上述嵌入描述的模式的一致性,美国人口普查部门东南中、南大西洋和山地有更多的向内迁移,新英格兰(至少是 CT)、中大西洋和太平洋部门经历了更多的向外迁移。该模式的一个例外是东北中心区,虽然与其他入境区组合在一起,但似乎有更多的出境移民。

还有一个最小的美国人口普查分组需要考虑:地区。

美国人口普查地区

作者图片

如上图所示,美国的四个人口普查区域将人口普查划分折叠起来。根据我们已经研究过的迁移模式,PC1 可能会根据迁移模式及其对房价的影响对这些地区进行排序。在过去的十年中,美国南部地区的房价涨幅无疑是最大的。真正有意思的是 PC2!虽然其他三个地区基本上在这个轴上一起崩溃,但西方与其他地区截然不同。虽然在过去十年中,南部、东北部和中西部地区的入境或出境移民模式在内部相当一致,但西部人口普查区合并了太平洋地区和山区的不同移民动态。

最后

通过一点额外的工作,分类变量的嵌入可以从 DL 模型拟合中提取出来,并且可以提供一些关于预测变量影响我们预测结果的能力的方式的见解。嵌入还可以被提取并用作其他类型的建模的协变量,例如 ML 策略,并且可以提供比传统虚拟或一个热编码参数化更小的基数。

用于自动摘要的深度学习模型

原文:https://towardsdatascience.com/deep-learning-models-for-automatic-summarization-4c2b89f2a9ea?source=collection_archive---------15-----------------------

NLP 的下一件大事?

来源:作者

arXiv 上的 PDF 版本

也许是所有 NLP 任务中最有帮助的

超过四分之一世纪以来,我们已经能够通过使用几个相关的关键字查询搜索引擎来搜索网络。如果没有这样的工具,互联网将只是无用的数据垃圾场。1998 年,谷歌的 PageRank 算法 重新定义了我们对搜索结果相关性的预期。最近一些 语义处理 已经被添加到这个魔法中,帮助引擎解释用简单语言表达的查询。在不太遥远的将来,我们也许可以通过与搜索引擎进行简短的对话来确定文档,就像我们与书商进行对话一样。尽管在书商和搜索引擎之间有一个重要的区别。如果你犹豫应该读哪本书,你可以试着让书商用几句话给你总结一下。

在传统的基于规则的 NLP 方法中,这种摘要任务看起来已经完全遥不可及,并且在可预见的将来,它也被认为是不现实的。但是,随着 NLP 深度学习模型的最新进展,事情正在慢慢发生变化。现在想象一下,在你最喜欢的搜索引擎的输入框旁边有一个下拉列表,可以让你设置给定文档的自动摘要的长度。比如说,1 句话,10 句话或者一页纸的总结。那会有帮助吗?事实上,它很有可能很快被证明是如此有用,以至于可能变得无处不在。除了改进文档搜索,它还可以帮助许多其他任务。例如,它可以帮助科学家跟上医学或人工智能等领域令人眼花缭乱的出版物。更通俗地说,它可以帮助为网上商店制作 简短的产品描述 ,这些商店的商品目录太大,人工无法处理。自动摘要应用的更多例子在这里描述为

对于像小说这样有几百页的大文档,这种通用的摘要工具仍然属于科幻小说的范畴。然而,由于深度学习模型令人惊讶的灵活性,对可以用几句话概括一两页文档的工具的等待可能不会太长,至少在特定的知识领域内。本文的目的是描述最近的数据集** [ 12深度学习架构 [ 345 ,它们让我们更接近目标。**

困难的任务

总结任务很困难,原因有很多,其中一些与其他 NLP 任务相同,例如翻译:

  • 对于给定的文档,不存在客观上最好的摘要。一般来说,他们中的许多人会认为同样好。
  • 很难准确定义什么是好的总结,以及我们应该用什么分数来评估它。
  • 好的训练资料早就被稀缺的昂贵的给收集了。

人类对摘要的评价是主观的,包括对风格、连贯性、完整性和可读性的判断。不幸的是,目前还不知道既容易计算又忠实于人类判断的分数。胭脂分数是我们所拥有的最好的分数,但是我们将会看到它有明显的缺点。ROUGE 只是计算机器生成的摘要和人类编写的参考摘要共有的字数,即 n 克。更准确地说,它报告了相应的召回的组合:

精度:

ROUGE- n 中报道的组合是他们的几何平均值(称为 F1 分数)。尽管 ROUGE 分数没有如实地反映人类的判断,但是它具有计算简单的优点,并且它考虑了与多个摘要相关联的一些灵活性,这可以通过重新排列有效摘要中的单词来产生。

有两种类型的摘要系统:

  • ****摘录摘要系统从源文档中选择多个片段来组成摘要。这种方法的优点是保证了生成的摘要在语法上是正确的。总的来说,提取系统的 ROUGE 得分较高,比我们接下来讨论的选项更可靠。
  • 另一方面,抽象概括系统生成自己的单词和句子来重新表达原文的意思,就像人类作家会做的那样。它们可以被视为试图保留意义的压缩系统。后一种系统显然更难开发,因为它涉及到解释信息和包含外部知识的能力。

我们将在下面描述这两种情况。

更多更好的数据

**直到最近,用于训练摘要模型的主要数据集是 CNN /每日邮报数据集 ,它包含 300,000 个新闻文章的例子和它们的多行摘要。然而,一项详细的检查[ 1 ]揭示了这个数据集中的各种限制,这些限制可能会对系统执行文本摘要的能力的评估产生偏见。例如,结果表明有用的信息在数据源中分布不均匀,即大部分在文档的开头。此外,许多摘要包含源代码的大片段。这当然不是教系统如何产生好的抽象摘要的最好方法。

但最近事情发生了变化。例如, 大专利数据集 [ 1 ]包含 130 万个专利文档及其摘要,缓解了上述大部分缺点。**

一种为训练摘要模型产生不断增长的数据集的新方法使用了在国际科学会议上给出的谈话的视频记录。这里的基本假设是,这些抄本为产生高质量的科学论文摘要提供了一个良好的起点。成绩单本身并不直接是一篇论文的总结。相反, TalkSumm 方法2】的作者提出通过从演讲中呈现的论文中检索一系列相关句子来创建摘要。一个句子被认为是相关的,取决于说话者在她的谈话中使用了多少单词来描述它,假设她在任何给定的时间点脑子里都有论文的给定句子。

巧妙的架构和改进的成本函数

在本节中,我们将描述最近为摘要任务开发的 3 个神经网络模型。这里的目的当然不是完整的,而仅仅是为了说明为解决这个基本的自然语言处理问题而提出的各种想法。

使学习这种任务成为可能的基本神经网络架构是 Seq2Seq 架构LSTM 递归神经网络 (RNN)、 BERT变压器 模型以及 注意机制

图 1 :基本 Seq2Seq 编解码架构,注意。 x _i 是输入令牌嵌入,a_i^t 是步骤 t 的注意力权重, h _ i 是上下文向量, h ^t 是通过用注意力权重对上下文向量进行加权得到的步骤 t 的句子嵌入, s i 是解码器状态, x ' i 最后,p^t_vocab 是固定词汇在时间 t 的概率分布,(来源:作者)。

对于不熟悉这些话题的读者,我们推荐上面的链接,这些链接将为他们提供很好的介绍。图 1 显示了 Seq2Seq 架构,它将一个令牌序列转换成另一个长度可能不同的序列。它定义了我们在讨论 Seq2Seq 时要参考的向量。

图 2 : BERT 作为变压器架构的编码器部分。转换器背后的核心思想是注意力机制的智能实现,允许计算在 GPU 上高效并行化,这是经典 RNN 无法实现的。每个输入向量 x _ j 是一个令牌嵌入和一个位置嵌入的和。输出 h _ i 是上下文感知令牌嵌入(来源:作者)。

图 2 描绘了一个变压器网络,在嵌入和隐藏向量之间具有自我关注依赖性。粗略地说,转换器将令牌嵌入序列 x _ i 转换成另一个上下文感知嵌入序列 h _ i 。输入向量 x _ i 通常也包括位置信息。与 RNN 网络相比,这是必需的,因为变压器中的输入具有排列对称性。

不结巴地总结

我们提出的第一个架构解决了抽象的摘要任务[ 3 ]。将普通 Seq2Seq 架构应用于总结的早期尝试揭示了这种简单方法的许多问题:

  • 原始文档中的事实细节,如日期、地点或电话号码,在摘要中经常被错误地复制。
  • 一个有限的词汇表阻止了一些像专有名词这样的词被考虑进去。
  • ****源片段的不必要重复经常发生,换句话说模型倾向于口吃

图 3 显示了这些不想要的行为的例子。[ 3 中的作者提出了两个对普通 Seq2Seq 的改进来缓解这些缺点。

图 3 :最后一节“Pointer-Gen + Coverage”包含了[3]中提出的系统的输出。摘要中使用的片段用蓝色表示,事实错误用红色表示,不必要的重复用绿色表示(来源)。

首先,为了克服有限的词汇限制,他们允许网络直接从源中复制一个单词,并在需要时在摘要中使用。做到这一点的精确机制被称为指针网络。请记住,在普通的 Seq2Seq 网络中,解码器在每个时间步长 t 计算固定有限词汇中的单词 w 的概率分布p^t_ vocab(w)。像往常一样, p ^ t _vocab 通过 softmax 层计算,该层将注意力上下文向量 h ^ t 和解码器状态 s _ t 作为输入。在指针网络中,计算一个附加的复制概率** p _copy,它表示一个字应该从源复制而不是由解码器生成的概率。使用具有 h ^ ts _ tx _ t 矢量作为输入的 s 形层来计算概率 p copy(参见图 1)。哪个单词实际上应该被复制是由解码器在时间 t 对源中的每个单词wII^t确定的。将所有这些放在一起,模型产生单词 w 的全部概率由以下混合给出:**

第二,为了避免重复相同的片段,作者在每个时间步 t 定义了一个覆盖向量** c ^ t ,该覆盖向量估计直到时间 t 源中的每个单词从解码器接收到的关注量:**

这个覆盖向量然后被用在网络内的两个不同的地方。首先,它用于通知负责计算注意力权重 a ^ t _ i 的注意力机制(除了通常对字 w _ i 和解码器状态 s _ t 的编码器上下文向量 h _ i 。解码器因此知道它已经注意的单词。其次,它用于校正损失函数。请记住,在时间步长 t 时,权重a^tI是放在单词 w _ i 上的注意力,而c^tI是这个单词在过去受到的注意力。如果单词 w _ i 在时间 t 比它在过去已经受到的关注更多,也就是说,如果a*t*_*I*>*c*t_I,那么成本函数应该惩罚 c 的大值为了惩罚对重复单词的注意,在时间步长 t 时,在损失函数中定义一个附加项作为输入标记的总和:

这然后被添加到(用附加的超参数)训练集中目标词 w ^*_ t 的通常负对数似然中:

使用和不使用这些额外技巧的结果如图 3 所示。

作为语境化句子序列的文档

我们的下一个例子展示了为提取摘要任务定义新 SOTA 的最新想法。它直接基于导致 2018 年
BERT 模型 的一个关键思想,即基于一个 变压器 编码器的巧妙预训练任务的迁移学习。让我们再深入一点,总结一下文档摘要的 HIBERT 架构[ 4 ]。

基本的观察是,抽取分类可以铸为一个句子标注问题:简单训练一个模型,识别文档中的哪个句子应该保留,组成摘要!为此,HIBERT 架构使用两个嵌套的编码器转换器,如图 4 所示。

****图 4:HIBERT 架构包含两个 Transformer 编码器的层次结构,用于将文档中的每个句子分类为摘要的一部分或不是摘要的一部分(来源:作者)。

底部的第一个 Transformer 编码器是一个经典的句子编码器,它将组成文档第 k 句的单词序列( w _0^ kw 1^ k ,…,wj^k)转换为嵌入h的句子该向量通常被识别为句尾标记< EOS >上方的上下文向量。****

位于顶部的第二个 Transformer 编码器是一个文档编码器,它将句子嵌入序列( h _1、 h _2、…、 h _ D) 转换为一个文档感知句子嵌入序列** ( d _1、 d _2、…、D*这些嵌入又被转换成概率序列( p _1、 p _2、…、 p _ D ),其中 p _ j 是第 j 句应该是摘要的一部分的概率。***

从头开始训练这样一个复杂的层次网络是不切实际的,因为它需要大量不切实际的文档摘要对。众所周知,训练这样一个数据量有限的复杂网络的最佳策略是使用迁移学习。为此,首先在辅助任务上对 HIBERT 体系结构进行预训练,该辅助任务包括预测在大型文档语料库中随机屏蔽(15%)的句子:

掩蔽句子预测任务的一个例子。

图 5 显示了用于这个屏蔽句子预测任务的架构。它在 HIBERT 架构之上添加了一个 Transformer 解码器,以便将嵌入了 d _ k 的文档感知语句转换为被屏蔽的第 k 个语句的单词序列( w _0^ kw 2^ k 、…、w j ^ k )。为了在步骤 i 生成单词,解码器使用其上下文 h _ i 和来自文档编码器的嵌入 d _ k 的文档感知语句。

图 5 :用于屏蔽语句预测任务的架构。在 HIBERT 架构的顶部添加了一个句子转换解码器,以使用其文档感知嵌入 d _ k 中封装的信息来恢复被屏蔽句子的单词(来源:作者)。

以这种方式训练的网络收集了大量的语义知识,而不需要任何扩展的标记过程。在第二阶段,利用它在预训练任务中学习到的内容,网络在实际的目标任务上进行微调,即作为句子二进制标记任务的摘要,如图 4 所示。

这个屏蔽句子预测任务显然在句子层面上让人想起用于预训练原始 BERT 模型的屏蔽语言模型** (MLM)。请记住,MLM 的任务在于恢复句子中随机屏蔽的单词。**

强化学习来拯救

正如我们前面所解释的,总结任务的一个核心问题是缺少唯一的最佳总结。ROUGE score 在某种程度上考虑到了这一点,因为它忽略了生成的摘要中单词的顺序(或 n -grams)。因此,我们实际上希望最小化的成本函数应该类似于这个胭脂分数,或者至少最终的损失函数应该包括这样一个项。这就是我们在这里展示的上一部作品[ 5 中遵循的策略,同样涉及抽象概括。

像 ROUGE 这样的分数的问题是,对于解码器生成的任何单词序列( w _1,…, w _ j ),它相对于网络的参数θ是恒定的,因此使得反向传播不可能。这种情况并不是没有希望的,因为从生成器*定义的联合概率分布 p_theta ( w _1、…, w _ j )中采样的句子( w _1、…, w _ j 的胭脂分数的期望值实际上是一个可微的接下来的路就很清楚了。只要将期望值定义的损失最小化:*

实际上,我们可以将 Seq2Seq 模型的生成器视为一个强化学习** (RL)代理,其在时间步 t 的动作是根据内部状态 s _ t 生成一个字 w _ t ,该字封装了来自先前动作的历史。从现在开始,我们只需要打开一本关于 RL [ 13 ]的书,学习如何最小化 L _RL。RL 中的一个基本结果,被称为政策梯度定理,陈述了 L _RL 的梯度:**

在哪里

最后一个索引 j 是< EOS >令牌的索引。加强算法用生成器计算的分布pθ(w 1,…,w_ 1,…, w _j】)的单个样本来近似上述期望:

实际上,像 ROUGE 这样的分数可能具有大的方差,这阻碍了梯度下降的收敛。好在我们可以通过比较 ROUGE( w _1、…、 w _ j )和一个独立于( w _1、…、 w _ j )的基线** b 来提升收敛速度。这不会改变 L _RL 的梯度,这一点很容易验证,但它可以显著降低方差[ 13 ],从而显著提高收敛性:**

因此,主要问题是找到一个适当的基线。我们正在讨论的工作中的想法是,让基线 b 等于生成器在推理时实际生成的单词序列的 ROUGE 分数。请记住,这是由解码器的 softmax 在每一步 t 计算的连续最大化条件概率的单词序列:

基线 b 的这种选择称为自我临界序列训练** (SCST)。因此,总的来说,钢筋损失项为:**

在哪里

我们可以看到,这个损失项促使p_θ生成单词序列( w _1、…, w _ j ),其胭脂分数大于解码器当前生成的序列的胭脂分数。

在损失函数中包括这样的 SCST 强化学习项有两个好处。首先,促使构造 L _RL 的原因是,它使得在随机梯度下降训练过程中使用像 ROUGE 这样的不可微分数成为可能。第二个好处是,它还可以治疗所谓的曝光偏差。暴露偏差来自典型的教师强制*程序,该程序通常用于训练 Seq2Seq 模型。该过程使用来自训练集的基础真值字( w 1,…, w * j )来训练解码器 RNN,而在推断时间,解码器当然必须使用其自己生成的令牌,这可能因此导致错误的累积。基线 b 的 SCST 选择相当于使用在推断时间实际看到的分布来训练解码器。

使用的最终损失函数是强化学习** 损失 L _RL 和标准最大似然 目标 L _ML 的加权和。前者考虑到了摘要的非唯一性,至少在某种程度上是这样,但它本身肯定不是模型产生可读消息的动机。另一方面,后者更喜欢可读的句子,因为它基本上定义了一个语言模型。**

为了避免重复,作者还使用了一种增强的注意力机制,这种机制涉及到一个指针网络,类似于我们在第一个例子[ 3 中描述的那个。

下一步是什么?

我们在上一节中描述的三个模型都使用深度学习,因此实现了一种纯粹的统计方法来完成摘要任务。最近的研究也试图找到更好的损失函数。例如, 朗诵会 的研究人员探索了一个有趣的想法,即一个好的总结应该在原文允许的范围内回答问题。总的来说,这些模型对于短文档确实出奇地有效。但是,我们可以合理地期望建立一个系统,使用仅仅依赖于处理大量文本数据的技术,在一页中总结 300 页的小说吗?这远非显而易见。原则上,摘要应该能够利用真实世界的知识来理解要摘要的文档或书籍。尽管语言模型本身不太可能捕捉到这样的常识,而这些常识更有可能是由感官经验收集的。建立有用的摘要工具的一个短期可能性是将它们的范围缩小到已经有知识基础或本体的特定专业领域。一个更激进的步骤是建立一个具有更好的“真实世界理解”的系统,这个步骤可能来自于多模态学习器,它被设计来聚合音频、视频和文本模态,例如电影。沿着这条道路已经取得了可喜的成果。

感谢

在此,我要感谢 Thomas Scialom ,他是朗诵会的研究员,他好心地与我分享了他的知识,让我注意到他在 GitHub [ 16 上的总结摘要页面。这帮助我启动了对深度学习摘要模型的探索。

参考

  1. E.Sharma,C. Li,L. Wang, BIGPATENT:一个用于抽象和连贯摘要的大规模数据集 (2019),arXiv:1906.03741。
  2. G.Lev,m . shmu Eli-朔伊尔,J. Herzig,A. Jerbi,D. Konopnicki, TalkSumm:一种基于会议会谈的科学论文摘要的数据集和可扩展标注方法 (2019),arXiv:1906.01351。
  3. A.见 Peter J. Liu,Ch。d .曼宁,直奔主题:用指针生成器网络进行总结 (2017),arXiv:1704.04368。
  4. X.张,魏,周,【面向文档摘要的层次双向变换器文档级预训练】 (2019),arXiv:1905.06566 .
  5. R.保卢斯,c .熊,R. Socher,抽象概括的深度强化模型 (2017),arXiv:1705.04304。
  6. C.林胭脂一包自动评价总结**
  7. 南 J. Rennie,E. Marcheret,Y. Mroueh,J. Ross,V. Goel,用于图像字幕的自我临界序列训练 (2016),arXiv:1612.00563。
  8. G.Genthial, Seq2Seq 带关注和光束搜索 (2017),博客。
  9. C.Olah 了解 LSTM 网络 (2015),博客。
  10. J.Alammar, The Illustrated BERT,ELMo and Co. ,博客。
  11. J.Alammar,图文并茂的变形金刚,博客。
  12. D.Bahdanau,K. Cho,Y. Bengio,联合学习对齐和翻译的神经机器翻译 (2016),arXiv:1409.0473。
  13. R.萨顿和 a .巴尔托,强化学习:导论 (2018),麻省理工学院出版社,麻省剑桥。
  14. T.Scialom,S. Lamprier,B. Piwowarski,J. Staiano,答案联合起来!增强摘要模型的无监督度量 (2019),arXiv:1909.01610。
  15. 南 Palaskar,J. Libovick,S. Gella,F. Metze,【How2 视频的多模态抽象摘要 (2019),arXiv:1906.07901。
  16. T.Scialom,总结概括 (2019),GitHub。

深度学习——不仅仅是大公司

原文:https://towardsdatascience.com/deep-learning-not-only-for-the-big-ones-bd16b019d5e8?source=collection_archive---------62-----------------------

如何使用深度学习,即使是小数据集

弗兰基·查马基在 Unsplash 上拍摄的照片

当你在研究深度学习算法时,你几乎总是需要大量的数据来训练你的模型。这是不可避免的,因为像 RNN 或 GRU 这样的深度学习算法需要数据,为了收敛,它们需要公平的数据份额。但是如果没有足够的数据呢?这种情况并不罕见,事实上,在研究工作中,你可能每天都要处理它,或者即使你正在研究一个新的领域/产品,那里还没有很多可用的数据。你怎么处理这个?我能应用机器学习吗?我能利用深度学习的最新进展吗?

有两种可能的路径可供我们选择,我将在下一节中介绍它们——数据路径和模型路径。

数据分支

这听起来可能有点显而易见,但有时我们会错过这种解决方案解决小数据问题的能力——我说的是数据增强。数据扩充背后的想法是——某个点(在超空间中)附近的点代表类似的行为。例如:一个狗的图像增加了对比度或亮度仍然是一个狗的图像。

要对表格数据集使用数据扩充,有多种方法可用,例如:

再来详细说说 SMOTE。为了简化,我们可以将 SMOTE 背后的概念定义为“物以类聚”,这在数据方面的减少意味着在多维空间中彼此接近的数据点表示相似的行为,因此它们可以被近似为数据集的新数据点。

当从一个较大的集合中合成几个样本时,这种技术最有效。但是,一旦你超过了某个近似合成样本的阈值,样本的可能性就开始发散。因此,在实现这一点时,你必须记住这一点。

但是,一旦你超过了某个近似合成样本的阈值,样本的可能性就开始发散。

再来说说图像中的数据增强。看下面的图片,它们都代表一只鹦鹉,但它们都不同,因为图像的人口统计数据,如对比度、亮度等。,从单个图像变为 12 个图像,数据量增加了 12 倍。

演职员表:【https://github.com/albumentations-team/albumentations

当然,我们还可以应用旋转、镜像和裁剪来增加可用的图像数据集。为此,有几个可用的库,如 OpenCV、PyTorch 和 TensorFlow。另一个也很有趣的是蛋白,你可以在这个 Colab 笔记本上看到它的运行。

数据扩充的生成模型

生成模型已经证明了对数据分布的超级有用的理解,以至于今天这些模型是数据扩充任务的主要工具。

用于数据扩充的生成模型的一些最广为人知的应用可以恢复如下:

LSTM 的文本生成——除了用于预测模型,RNN 和 LSTM 的能够学习问题的序列,然后为文本生成等问题领域生成新的完全合理的序列。但它们在地理位置数据生成方面也非常强大。

用于图像生成的可变自动编码器(VAE)—深度生成模型越来越受欢迎。VAE 架构非常直观且易于理解,由两个神经网络组成——一个编码器和一个解码器,其中编码器将每个记录映射到 z 维标准分布。

用于表格数据生成的生成对抗模型 —由两个网络组成——一个鉴别器和一个生成器,GANs 已被证明在学习数据集分布和复制数据增强方面非常强大。它们的应用相当广泛,从图像到规则数据生成,从表格数据到时间序列

模型路径

到目前为止,我们研究了调整我们的数据量本身,但是,如果我们调整模型本身,我们也可以通过小数据集获得更好的结果。有几种方法可以实现这一点,接下来我将描述它们。

迁移学习

迁移学习已经成为研究者甚至业界人士的首选策略。你在 Kaggle 上看到的几乎所有模型都以这样或那样的方式利用迁移学习。它不仅减少了训练次数,而且在小数据集上也工作得很好。

例如,您可以使用像 ResNet、InceptionV3 这样的预训练模型,只训练最后一层(冻结其余部分),而不是在图像分类任务中从头开始训练您的 CNN 模型,这样您的任务将只需原来训练时间的一半即可完成。

迁移学习过程中需要微调,这将涉及超参数优化和多层冻结(根据需要)。这里是一个使用 Tensorflow2.0 的预训练 CNN 的transfer learning 实现。

余弦损失

另一种已被证明有效的技术是将损失函数从交叉熵改为一种称为余弦损失的新方法。

什么是余弦损失? 余弦损失是通过考虑余弦相似性和

  • f_theta(x)代表模型参数
  • Psi(y)表示类别标签的独热码编码向量
  • σ_cos 表示两个向量之间的余弦相似度。

这个在这篇论文里有详细解释。在分类过程中使用余弦损失代替了传统的交叉熵等方法,模型的准确性有了很大的提高。在所有小数据集上,使用余弦损失获得的分类精度大大优于 softmax 后的交叉熵,在 CUBNAB 数据集上,最大相对改进为 30%和 21%。

虽然小数据集是一个现实,并且对大多数研究人员和组织来说是一个明显的问题,但是为了解决这个问题,在这个领域已经做了很多改进。在这里,我给你留下一些在这个领域已经完成的最惊人的研究:

最后但并非最不重要的一点是,由于 COVID 已经存在并长期存在,研究人员正在寻找利用现有基础设施检测它们的更好方法。COVID 是一种相当新的疾病,这使得被感染和检测的人的数据集非常小

他们在 4000 张病毒性和细菌性肺炎的胸部 x 光片上使用了预先训练好的 CNN 模型,其中 122 张属于新冠肺炎。这证明了小数据集的用例以及在这种情况下利用预训练模型的合理性。他们报告的 AUC 分数约为 0.997,令人印象深刻。

本文解释了生成模型的使用,该模型通过针对胸部 X 射线的有限数据集的微调深度迁移学习来扩充数据。这里使用的预训练模型包括 ResNet、GoogLeNet、AlexNet 和 SqueezeNet,数据集为 5863 张胸部 x 光片。该论文的结论是,ResNet 的性能优于其他达到约 99%准确率的产品。

结论

我们在这篇文章中看到,有两种主要方法可以解决小数据集问题,一种是通过调整数据部分,另一种是利用模型固有的功能和使用不同的损失函数。不同的策略可以很容易地应用,并提高整体 ML 模型的质量,同时使其有可能受益于深度学习算法的力量。然而,如果我们想要产生有价值的 ML 模型,我们不应该忘记与每一种方法相关的权衡。

法比亚娜·克莱门特 y Data的首席数据官。

我们帮助人工智能的早期采用者改进和生成高质量的数据,以便他们能够成为明天的行业领导者

深度学习预算:450 美元 eGPU vs 谷歌 Colab

原文:https://towardsdatascience.com/deep-learning-on-a-budget-450-egpu-vs-google-colab-494f9a2ff0db?source=collection_archive---------5-----------------------

Colab 对于开始深度学习来说是非凡的,但它如何与 eGPU +超极本相抗衡?

Unsplash 上由娜娜杜瓦拍摄的照片

深度学习很贵。即使是最简单的任务,GPU 也是必不可少的。对于希望获得最佳按需处理能力的人来说,一台新电脑的价格将超过 1500 美元,而借用云计算服务的处理能力,在大量使用的情况下,每个月的费用很容易超过 100 美元。这对企业来说绝对没问题,但对普通个人来说,这意味着更多。

正因为如此,2 个月前,我进行了第一次重大采购,以给自己合理的计算能力。我已经有了一台配有小 GPU 的旧 XPS 15(GTX 960m,只是不合适),所以我决定买一台 Razer core + NVIDIA GTX 1080,我立即拥有了大约 4 倍于我以前的处理能力,价格不到 450 美元(我买的都是二手的)。这是一个如此巨大的转变,以至于我写了一篇中型文章详细描述了整个过程和结果(你可以在这里看到)。

这篇文章很受欢迎,但是我的许多读者和同事问我一个问题,“这和 colab 相比如何?”对于所有这些,我会回答说,我听说有人喜欢它,但我从来没有考虑过。毕竟,一个免费的 GPU 能有多好?

在我进入结果之前,我将给出一个关于 Colab 本身的小背景。Colab 是谷歌研究院开发的一款产品,让任何人都能执行 Python 代码。它完全在浏览器中运行,并使用 google drive 作为其主要文件存储。这使得它很容易被共享,并且完全在云中。(你可以点击查看 colab 的精彩介绍)

问题是计算资源没有保证,这意味着你基本上得到了谷歌目前没有使用的东西。Colab 表示,大多数时候,这意味着分配的 GPU 将从 Nvidia K80s、T4s、P4s 和 P100s 中选择。另一个问题是,如果您暂时不使用 Colab,它会将这些资源分配给其他人。在我的测试中,这不是很宽容。甚至在我带我的狗去洗手间的时候,我也经历了超时。如果您让某个东西运行,做其他事情,并且在完成时没有保存结果,这可能会很烦人。最后一个缺点是运行时间有 12 小时的限制。大多数人不应该担心这一点,但是对于大型项目,调优可能需要一段时间,这可能会很麻烦。

现在我已经解释了什么是 Colab,我可以解释我是如何测试它的。与我在上一篇文章中用来测试我的 eGPU 的类似,我使用了 AI 基准,这是一个非常简单但功能强大的 python 库,它利用 Tensorflow 在 19 个不同的部分上运行 42 个测试,为 GPU 提供了很好的通用 AI 分数。接下来,我初始化了一个运行时 15 次,每次都运行 AI benchmark,记录结果以及分配的 GPU——我得到了 K80 10 次,P100 4 次,T4 1 次(我从未得到 P4,但它的性能应该比 T4 略差)——下面是速度结果!

Colab 结果

正如你所看到的,结果有很大的差异,顶级 GPU 比他们可以指定的最慢的 GPU 快近 4 倍,但对于一个免费的 GPU 来说,它们都是惊人的。我很惊讶这些都是免费的。它们都提供 12g 以上的内存,对于大多数项目来说足够了,当 P100 被分配时,它的速度接近全新的 RTX 2070。即使是最慢、最常见的 K80,其性能也比 GTX 1050 Ti 略差,后者仍然是一款 150 美元的 GPU。

这与我的 eGPU 相比如何?老实说,它堆叠得非常好。下面是我的 1080 设置绘制在旁边时的相同图形!

科 lab vs GTX 1080 eGPU

在中等情况下,Colab 将为用户分配一个 K80,GTX 1080 的速度大约是它的两倍,这对 Colab 来说不是特别好。然而,有时,当 P100 被分配时,P100 是绝对的杀手级 GPU(再次为免费)。因为 P100 是如此之大,当比较一般情况时,您可以看到两个结果没有太大的不同,我的 eGPU 平均只提高了 15%左右。

eGPU 与 Colab 平均值

因此,如果你想进入机器学习领域(或者想升级你目前的设置),你应该怎么做?我个人的建议是,如果你只是想涉足机器学习(至少是开始),参加一个初级的机器学习课程,或者并不总是需要计算资源,Colab 绝对是一个不用动脑筋的人。它免费提供计算机是巨大的。

然而,如果您觉得受到 Colab 产品的限制,可能需要更快的速度,随时了解您的资源,需要长时间的训练,想要使用非 python 语言,或者计划使用 GPU 来完成机器学习任务以外的任务,eGPU(或专用 GPU)可能会更适合您!

我也不想在结束这篇文章时不提到 Colab Pro。每月支付 10 美元,您就可以获得更高的使用限制,并优先使用速度更快的处理器。如果你喜欢 Colab,但担心它的速度和使用限制,它是云计算的一个很好的替代品,价格也很实惠!

如果你喜欢这篇文章,请随时关注我,阅读我写的更多内容,或者请将我作为推荐人,这样我就可以继续制作我喜欢的内容。

[## 我是如何用 eGPU 将我的旧笔记本电脑变成机器学习超级明星的

以新电脑的零头成本改造超极本的惊人简单之旅

towardsdatascience.com](/how-i-turned-my-older-laptop-into-a-machine-learning-superstar-with-an-egpu-66679aa27a7c) [## 为什么雷电 3 如此重要?(以及苹果为什么喜欢它们)

无论您是将它用于 eGPU 和机器学习、游戏,还是用于外部显示器…没有它的生活可能…

towardsdatascience.com](/why-is-thunderbolt-3-such-a-huge-deal-and-why-apple-loves-them-614542d32dc2) [## 合并/连接熊猫数据帧的最有效方法

为什么几乎每个人都写得很低效

towardsdatascience.com](/the-most-efficient-way-to-merge-join-pandas-dataframes-7576e8b6c5c)

编辑:2011 年 11 月 25 日——在的这篇文章中,我使用一台连接速度更快的新笔记本电脑测试了我的 eGPU,看到了更好的 AI 成绩,使它与 Colab 相比更具竞争力。

结合时间序列和表格数据的深度学习。

原文:https://towardsdatascience.com/deep-learning-on-a-combination-of-time-series-and-tabular-data-b8c062ff1907?source=collection_archive---------37-----------------------

图片来源:取消快照

我们经常发现自己处于这样一种情况,即我们想要在模型中利用不同特性的组合。模型的输入数据是时间序列和表格数据的混合。在这种情况下,设计一个深度学习模型是一个有趣的问题。

一个示例场景是:您有来自 fitbit 等设备的数据,并且您想要预测任何给定时刻的睡眠阶段:

你混合了:

时间序列输入:

  • 心率序列
  • 呼吸频率序列

表格特征:

  • 睡眠开始后的时间
  • 代表这种用户睡眠模式的个性化嵌入

和许多其他功能。

解决这个问题的一种方法是将其视为多模态深度学习。

多模态学习——在研究之门上的照片

在谷歌研究这里引入了“广泛和深度学习”

广泛而深入的学习——谷歌博客上的照片

那么我们该如何着手呢?

  1. 通过 RNN 或 LSTM 或 1D CNN 传递时间序列序列,并捕获隐藏状态或 CNN 嵌入作为序列的表示。
  2. 将每个序列的嵌入与其他表格特征连接起来。

一些有趣的决定需要考虑:

对于多个时间序列输入序列:

  • 你是否将序列视为独立的,并在后期融合/连接表示(后期融合)?
  • 还是把它们当做多通道输入,每个时间序列作为一个通道(早期融合)?

一般来说,晚期融合似乎比早期融合工作得更好,并且当不同的输入序列长度不同时,也不需要填充输入。然而,它确实依赖于问题空间和输入序列的相关性。

一般来说,RNN 似乎更适合较短的序列,双向 LSTM 更适合较长的序列。在后期融合中,你可以混合搭配 RNN/LSTM/1d 有线电视新闻网的不同序列。

下面是一个示例模型实现(用 pytorch 编写):

该实施例使用具有后期融合的 2 层比迪 LSTM。

对于每个时间序列特征(特征 1 和特征 2 ),我们也有基线值,因此我们有融合层,其中我们融合了序列的表示(LSTM 的隐藏状态)和基线值。然而,该融合层不是必需的,并且在没有基线值的情况下不是必需的。

class TestModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.input_size = 70
        self.hidden_size = 8
        self.num_layers = 2
        self.output_dim = 2
        self.lstm_feature_1 = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True,
                                      bidirectional=True)
        self.lstm_feature_2 = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True,
                                      bidirectional=True)
        self.fc_feature_1 = nn.Linear((self.hidden_size * 2) + 1, 1)
        self.fc_feature_2 = nn.Linear((self.hidden_size * 2) + 1, 1)

        self.fc = nn.Linear(4, self.output_dim)

    def forward(self, f, device=None):
        if not device:
            device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

        x_f1, f1, x_f2, f2, f3, f4 = f

        # x_f1 is feature_1_seq
        # f1 is feature_1_baseline
        # x_f2 is feature_2_seq
        # f2 is feature_2_baseline

        # f3 and f4 are tabular features

        x_f1 = x_f1.view(x_f1.shape[0], 1, -1)
        h0_f1, c0_f1 = self.init_hidden(x_f1, device)
        h_t_f1, c_t_f1 = self.lstm_feature_1(x_f1, (h0_f1, c0_f1))
        x_f1 = h_t_f1
        x_f1 = x_f1.view(x_f1.shape[0], -1)

        x_f2 = x_f2.view(x_f2.shape[0], 1, -1)
        h0_f2, c0_f2 = self.init_hidden(x_f2, device)
        h_t_f2, c_t_f2 = self.lstm_feature_2(x_f2, (h0_f2, c0_f2))
        x_f2 = h_t_f2
        x_f2 = x_f2.view(x_f2.shape[0], -1)

        x_f1 = torch.cat((x_f1, f1), 1)
        x_f1 = self.fc_feature_1(x_f1)

        x_f2 = torch.cat((x_f2, f2), 1)
        x_f2 = self.fc_feature_2(x_f2)

        x = torch.cat((x_f1, x_f2, f3, f4), 1)
        x = self.fc(x)
        x = F.log_softmax(x, dim=1)
        return x

    def init_hidden(self, x, device):
        batch_size = x.size(0)
        h0 = torch.zeros(self.num_layers * 2, batch_size, self.hidden_size).to(device)
        c0 = torch.zeros(self.num_layers * 2, batch_size, self.hidden_size).to(device)
        return h0, c0

如果你曾处理过一个涉及类似输入方式的问题:我很想听听你对你有用的东西或者你尝试过的其他方法。

动态图上的深度学习

原文:https://towardsdatascience.com/deep-learning-on-dynamic-graphs-1b97c2fab0ab?source=collection_archive---------61-----------------------

时态图网络

迈克尔布朗斯坦 — 8 分钟阅读

许多现实世界的问题涉及各种性质的交易网络以及社会互动和参与,这些问题是动态的,可以建模为图表,其中节点和边随着时间的推移而出现。在这篇文章中,我们描述了时态图网络,这是一个在动态图上进行深度学习的通用框架。

用合成数据改善机器学习中的大规模不平衡数据集

亚历山大·沃森 — 6 分钟阅读

我们将使用合成数据和 SMOTE 中的一些概念来提高欺诈、网络安全或任何极少数类别分类的模型准确性

照片由 Florian Olivo 在 Unsplash 上拍摄

用人工智能玩毁灭:深度 Q 学习的多目标优化

阿德里安·许 — 13 分钟读完

在线学习方法是一个动态的算法家族,为过去十年强化学习的许多最新成就提供了动力。在线学习方法属于强化学习方法的基于样本的学习类别,允许简单地通过重复观察来确定状态值,消除了对显式转换动态的需要。

丹·史沫特莱在 Unsplash 上的照片

让你的机器学习模型进入现实世界

保罗调 — 10 分钟读出

过去几年中一个令人兴奋的发展是产品中机器学习的扩散。我们现在看到最先进的计算机视觉模型被部署在手机上。最先进的自然语言处理模型正被用来改进搜索。

巨型图上的深度学习

原文:https://towardsdatascience.com/deep-learning-on-giant-graphs-6b20b033b4a0?source=collection_archive---------63-----------------------

简单可扩展图形神经网络

迈克尔·布朗斯坦 — 12 分钟阅读

迄今为止,阻碍图形神经网络在工业应用中广泛采用的挑战之一是难以将它们扩展到大型图形,如 Twitter follow graph。节点之间的相互依赖性使得将损失函数分解成单个节点的贡献具有挑战性。在这篇文章中,我们描述了一个在 Twitter 上开发的简单的图形神经网络架构,它可以处理非常大的图形。

夏琳·钱布利斯:从心理学到自然语言处理和应用研究

通过琥珀色滕 — 18 分钟读取

在过去的十年中,人们对数据科学的兴趣呈指数级增长,越来越多的人开始转向该领域。2020 年,关于转入数据科学职业的文章和 YouTube 视频比比皆是。然而,对于许多人来说,关于这种转变的许多关键问题仍然存在:你如何从社会科学背景进入数据科学?心理学等领域中哪些最重要的技能可以应用于数据科学?

Opte 项目发布的一个图形可视化,一个互联网的试验性地图

什么是图论,为什么要关心?

通过 Vegard Flovik — 13 分钟读取

对你来说,图论可能听起来像一个令人生畏的抽象话题,那么你为什么还要花时间去读一篇关于它的文章呢?然而,尽管听起来可能不太适用,但图论实际上有大量有用和重要的应用!在这篇文章中,我将试着简单解释一下这些应用程序是什么。在这样做的时候,我会尽我所能让你相信,至少对这个话题有一些基本的了解,对于解决你可能遇到的一些有趣的问题是有用的。

Feliphe Schiarolli 在 Unsplash 上拍摄的照片

视频通话数十亿无互联网

P.K .米什拉 — 11 分钟阅读

过去的这个周末,我看到一篇新闻文章,提到数百万印度学生被困在家里,无法使用互联网或在线教育。事实上,超过一半的世界人口仍然没有任何互联网连接。虽然这种数字鸿沟已经在美国显现出来,特别是在冠状病毒疫情封锁期间的儿童教育方面,但这个问题在亚洲和非洲要严重得多,那里只有不到五分之一的人连接到互联网。

照片由 Unsplash 上的 66 north 拍摄

知识表示和推理用答案集编程

由娜塔莉·库斯特——8 分钟读完

在工业和科学领域,计算问题的数量似乎是无限的。对来自大量可用数据的新见解有着巨大的需求。为了获得这些知识,专门的人使用各种编程语言来设计和实现算法。

图形的深度学习:卷积是你所需要的

原文:https://towardsdatascience.com/deep-learning-on-graphs-convolution-is-all-you-need-3c1cf8f1e715?source=collection_archive---------8-----------------------

图卷积网络及其应用介绍

0.动机

你有没有想过为什么深度神经网络(DNNs)比传统的机器学习模型(嗯,有时候)更好?当然也有很多例外,在表格数据上,梯度推进机器优于全连接神经网络。在 DNNs 的独特特征中,我不认为非线性变换使它们从传统的 ML 模型中脱颖而出。许多传统的 ML 模型,如决策树和 SVM,也能够处理数据空间中的非线性。我很少遇到一个简单的全连接 DNN 在任何基准上都达到了最先进的性能。

真正使 DNNs 区别于传统 ML 模型的是那些支持参数共享的专用神经网络层,例如时间的递归层和空间的卷积层。有了这些专门的神经元层,DNN 作为自动特征提取器蓬勃发展,以取代手工设计的特征。LSTM 和 GRU 等递归层利用数据的时间依赖性,非常适合文本和语音,而卷积层利用空间平移不变性,适用于文本(Conv1D)、图像(Conv2D)和 3D 图像(Conv3D)。

但是没有时间或空间结构的数据怎么办?许多类型的数据实际上都有底层的图形结构,包括:

  • 社交:社交媒体如脸书、推特以及引文网络等。
  • 知识:知识可以组织成图, Google 的知识图可以更好的检索相关搜索结果;维基百科的文章也可以通过超链接连接成图。
  • 生物学:蛋白质和基因可以分别根据它们的物理或调控相互作用组织成图,如蛋白质-蛋白质相互作用网络和基因调控网络。

鉴于图的普遍性,我们是否可以开发神经网络层,利用图的拓扑来更好地表示和推断图中的节点?

1.图形的深度学习

2019 年,图形神经网络(GNNs)正式成为 NeurIPS 2019 的热门研究课题。但是它的起源要追溯到更早。

一些将深度学习应用于图表的早期尝试受到了开创性的 Word2vec 模型的启发(米科洛夫等人)。2013) 在文字嵌入。我们知道,Word2vec 通过使用向量表示预测大型语料库中任何给定单词的上下文,来学习低维空间中的单词嵌入。与图中的节点不同,单词是按顺序出现的,因此每个单词只有两个邻居。但在某种意义上,一个句子可以被认为是一个以单个单词为节点的路径图。如果我们能把一个图形转换成一个序列,或者多个序列,我们就可以采用自然语言处理的模型。

为此, DeepWalk(佩罗齐等人。2014) 使用随机漫步将图展平为序列,随机漫步是一种随机过程,随机漫步通过沿着相邻节点移动来遍历图。更具体地,DeepWalk 使用从截断的随机行走获得的局部信息,通过将随机行走访问的节点视为句子的等价物来学习潜在表示。同样,node 2 vec(Grover&lesko vec 2016)模拟有偏随机游走,可以高效地探索多样的邻域。

由 node2vec 生成的 les missérables 同现网络,标签颜色反映同质性(图 3 来自Grover&lesko vec 2016

DeepWalk 和 Node2vec 都以智能方式将图转换为序列,以应用神经方法对序列进行建模,但是没有开发神经机制来直接使用图中的局部邻域信息。

2.图上的卷积

也许研究人员的动机是与图中的相邻节点共享参数,而不是采用递归,图像中常用的卷积现在在图上也是可能的。

根据定义,卷积是对两个函数( fg )的数学运算,产生第三个函数,表示一个函数的形状如何被另一个函数修改。直观地说,你可以把卷积想象成沿着一个函数移动另一个函数,它们重叠的区域就是最终的卷积函数。

显然,根据一位深度学习大师和他的拙劣描述,卷积比你想象的要常见得多:

玩笑归玩笑,我们如何将卷积应用于图形呢?

理论上,卷积运算可以在空间(欧几里德)域或频谱(频率)域中进行。图的局部邻域信息不容易在空间域表示,图的卷积是在谱域进行的。

根据卷积定理,全图卷积包括对图的拉普拉斯矩阵()𝐿进行特征分解,然后对图进行傅立叶变换:

全图形卷积正向传递

这里,上标(I)表示神经网络层, H 是𝑁× F_i 特征矩阵( N :图中的节点数; F_i :图层特征数量I);W(F _ I×F _ { I+1 })为权重矩阵;U(N×N)是 L. 的特征向量

然而,计算全图卷积代价太大,于是研究人员开发了局部卷积方法来近似全图卷积。图形卷积的一般正向传递可以写成:

局部图形卷积正向传递

其中前向传递函数 f 采用来自前一层的特征和图邻接矩阵(通常是归一化的或变换的)来表示图的邻域信息,然后应用诸如 ReLU 的非线性激活函数𝜎(⋅来传播到下一层。

在这里,我们重点关注两种早期开发的近似方法:

切比雪夫多项式基滤波器的前向传递

,其中 T_k (⋅)是切比雪夫多项式函数,𝑘定义了 k 阶邻域,𝐿̃是由其最大特征值归一化的拉普拉斯矩阵。

图卷积网络的正向传递

,其中𝐴̂是对称归一化邻接矩阵。

3.图卷积网的应用

由于图在许多类型的真实世界数据中普遍存在,GCNs 也可以用于解决各种问题。这些应用程序可以分为以节点为中心的问题和以图形为中心的问题。

3.1.GCNs 的以节点为中心的应用(学习图中节点的标签或表示):

  • 半监督节点分类:利用图结构和节点特征来预测未标记节点的标签。示例包括在文档的引用网络上预测文档分类,其中仅标注引用网络中的文档子集(节点)。
  • 节点表示学习:给定一个图和一个节点的特征矩阵,学习图中节点的低维表示。前面提到的 DeepWalk 和 Node2vec 都是为此应用程序开发的。

3.2.GCNs 的以图形为中心的应用(学习给定节点特征和图形结构的图形的标签或表示)

  • 图形信号处理(分类/回归):给定一个具有 N 个节点的固定图形( G ,以及一个特征矩阵X(M*个实例由 N 个特征构成),目标是学习一个函数 f 来对那些 M 个实例做出预测: y = 这本质上是监督学习的一个特例,可以将特征组织成一个图。这也是图像分类的图等价:其中像素被组织成二维网格,并且卷积(CNN)被应用于空间域。图形信号处理的一个实例,由 Dutil 等人演示。2018 ,将 GCNs 应用于基因表达数据(由 N 个基因组成的 M 个样本的矩阵),连同基因网络(由 N 个基因组成的代表调控关系的图)一起预测单个基因的表达水平。*
  • 图的表征学习:给定一组图,目标是学习图的潜在表征: f ( G )。小分子化合物的化学结构可以被视为图形,其中原子是节点,键是边。GCNs 可用于学习分子指纹( Duvenaud et al )。,2015 ),这样的分子图表示也可以用来预测分子性质( Ryu )。,2018 )。

有机化合物可以表示为由化学键(边)连接的原子(节点)的图形

4.GCN 对 MNIST 在图形信号处理问题上的实验

Defferrard 等人(2016) 在优秀的老 MNIST 手写数字分类数据集上设计了一个有趣的实验,以展示 GCNs 的效用。他们没有在原始空间中组织像素,而是创建了一个网格图,使用最近邻将像素连接到原始欧几里得空间中的邻居。然后,该 2D 网格图可以用于表示 gcn 的那些像素的相同空间信息。在这里,我复制了他们的 2D 网格,并对图做了一些可视化处理,以及它的邻接矩阵 A 和度矩阵 D 。请注意,网格图的四个角有一些伪像。

GCN 使用的全网格图

他们的实验发现,在对数字进行分类时,GCN 利用 2D 网格图获得了与经典 CNN 相当的性能。受此实验的启发,我非常好奇潜在的图形结构是否会影响 GCN 的预测性能。具体来说,我们是否可以从数据集本身创建一些有意义的图表来为标注的预测提供信息?

训练集中的平均数字和数字特定的图形(第 2 行:修剪的网格;第 3 行:相关图)

因此,我创建了 20 个上面可视化的像素图:第一行绘制了来自训练集的平均位数;第二行是通过使用平均信号修整完整的 2D 网格图创建的图(数字特定的修整网格图);第三行是根据来自各个数字的像素之间的相关性构建的图(特定于数字的像素相关性图)。

为了设置我的实验,我使用了来自speck tral的 GCN 层来实现我的简单 GCN,它有 10 个图形卷积滤波器,后面是输出层。首先,我用完全相同的 2D 网格和没有任何图形的 GCN 获得了 GCN 的基线性能,以显示我的 GCN 模型确实在工作,并且与没有图形卷积机制的模型相比,实现了更好的性能:

基线模式 MNIST 分类任务的测试集精度:全网格、空图的 GCN 模式;和全连接(FC)网络

接下来,我将完整的 2D 网格切换到不同数字形状的修剪网格。从下表中可以看出,与全网格(0.932)相比,GCNs 的性能下降了一点点(平均为 0.920),这有点出乎意料,因为神经网络现在只能看到组织成网格的像素的子集,其余的是分散的。也许让我有点惊讶的是,虽然 2D 网格被修剪成单个数字的形状,但 GCNs 并没有获得识别相应数字的卓越能力。

用修剪网格和相关图对 20 个 GCN 模式的 MNIST 分类的测试集精确度

我没有修剪网格图,而是考虑从数据本身构建要素(像素)的相似度图,看看这是否能提高性能。对于任何数据集来说,这可能是一种更通用的方法,即使要素之间没有基础的图表结构。通过连接训练集中各个数字实例中具有高相关性的像素,我创建了那些特定于数字的相关图,并发现它们有助于提高 GCN 模型的预测精度(跨数字平均为 0.935)。然而,这些数字特定的相关图也没有更好地识别它们各自的数字。

结论:

GCNs 对于图形信号处理问题非常有用,并且当与特征图结合时,可以潜在地提高神经网络对表格数据的适用性。

感谢阅读!如果你有兴趣,这篇文章中描述的实验的 Jupyter 笔记本可以在这里找到:【https://github.com/wangz10/gcn-playground

主要参考文献:

图的深度学习:成功、挑战和下一步

原文:https://towardsdatascience.com/deep-learning-on-graphs-successes-challenges-and-next-steps-7d9ec220ba8?source=collection_archive---------15-----------------------

图形神经网络的下一步是什么?

这是 系列帖子 中的第一篇,我将在这里讨论图形深度学习领域的演变和未来趋势。

图的深度学习,也称为几何深度学习(GDL) [1],图表示学习(GRL),或关系归纳偏差[2],最近已经成为机器学习中最热门的话题之一。虽然图形学习的早期工作可以追溯到至少十年[3]如果不是二十年[4],但毫无疑问,过去几年的进展使这些方法从一个小众领域成为了 ML 社区 T11 的焦点,甚至成为了大众科学出版社的焦点(其中Quanta Magazine为流形 T15、T16 药物发现 T17 和 T18 蛋白质科学 T19 的研究发表了一系列关于几何深度学习的优秀文章)。

图形是强大的数学抽象,可以描述从生物学和高能物理学到社会科学和经济学等领域的复杂关系和相互作用系统。由于如今这些领域中的一些领域产生的图形结构数据量非常巨大(突出的例子是 Twitter 和脸书等社交网络),尝试应用在其他数据丰富的环境中非常成功的深度学习技术是非常诱人的。

很大程度上依赖于应用程序的图形学习问题有多种风格。一个二分法是在节点方式的图方式的问题之间,其中前者试图预测图中各个节点的属性(例如识别社交网络中的恶意用户),而后者试图对整个图进行预测(例如预测分子的溶解度)。再者,和传统的 ML 问题一样,我们可以区分监督非监督(或自监督)设置,以及直推式归纳式问题。

与图像分析和计算机视觉中使用的卷积神经网络类似,在图上有效学习的关键是设计具有共享权重的局部操作,在每个节点和它的邻居之间传递消息。与处理网格结构数据的经典深度神经网络相比,一个主要区别在于,在图形上,这种操作是置换不变的,即独立于相邻节点的顺序,因为通常没有对它们进行排序的规范方式。

尽管他们做出了承诺,也有一系列图形表示学习的成功故事(其中我可以自私地列举出 Twitter 收购了我和我的学生一起创立的基于图形的假新闻检测初创公司 Fabula AI 的),但迄今为止,我们还没有看到卷积网络在计算机视觉方面取得的巨大成功。在下文中,我将尝试概述我对可能原因的看法,以及该领域在未来几年将如何发展。

像 ImageNet 这样的标准化基准无疑是计算机视觉中深度学习的关键成功因素之一,有些人甚至认为对于深度学习革命来说,数据比算法更重要。在图形学习社区中,我们还没有和 ImageNet 在规模和复杂性上类似的东西。2019 年推出的 Open Graph Benchmark 可能是朝着这个目标的第一次尝试,试图在有趣的真实世界图结构数据集上引入具有挑战性的图学习任务。障碍之一是,从用户活动中产生多样化和丰富图表的科技公司不愿意分享这些数据,因为担心隐私法,如 GDPR。一个值得注意的例外是 Twitter,作为 RecSys 挑战赛的一部分,它在某些隐私保护限制下向研究社区提供了 1.6 亿条推文的数据集以及相应的用户参与度图。希望以后有很多公司效仿。

在公共领域可用的软件库在深度学习的“民主化”和使其成为一种流行工具方面发挥了至关重要的作用。如果说直到最近,图形学习实现主要是一堆写得很差且很少测试的代码,那么现在已经有了像 PyTorch GeometricDeep Graph Library (DGL) 这样的库,它们是在行业赞助的帮助下专业编写和维护的。在 arxiv 上出现一个新的图形深度学习架构几周后,看到它的实现并不罕见。

可扩展性是限制工业应用的关键因素之一,这些工业应用通常需要处理非常大的图(想想拥有数亿个节点和数十亿条边的 Twitter 社交网络)和低延迟约束。直到最近,学术研究团体几乎忽略了这一方面,文献中描述的许多模型完全不适用于大规模设置。此外,图形硬件(GPU)与经典深度学习架构的幸福婚姻是推动它们共同成功的主要力量之一,但它不一定最适合图形结构数据。从长远来看,我们可能需要专门的图形硬件[7]。

动态图是文献中很少涉及的另一个方面。虽然图是对复杂系统建模的一种常见方式,但这种抽象往往过于简单,因为现实世界的系统是动态的,会随着时间的推移而演变。有时是时间行为提供了关于系统的关键见解。尽管最近取得了一些进展,设计能够有效处理连续时间图的图神经网络模型仍然是一个开放的研究问题。

已知更高级的结构如基序、graphlets 或单纯复合物在复杂网络中很重要,例如在生物学应用中描述蛋白质-蛋白质相互作用。然而,大多数图形神经网络仅限于节点和边。将这样的结构结合到消息传递机制中可以给基于图的模型带来更大的表达能力。

对图形神经网络表达能力的理论理解相当有限。常见的情况是,在某些设置中使用图形神经网络可以显著提高性能,而在其他设置中几乎没有差异。目前还不完全清楚图形神经网络何时以及为什么工作良好或失败。这个问题很困难,因为人们既要考虑底层图的结构,又要考虑图上的数据。对于只涉及图连通性的图分类问题,最近的工作表明,图神经网络等价于 Weisfeiler-Lehman 图同构测试【8】(一种启发式方法,用于解决图论中的一个经典问题,即确定两个图在其节点排列上是否相同)。这种形式主义揭示了为什么,例如,图神经网络在不能通过这种简单测试来区分的非同构图的实例上失败。超越 Weisfeiler-Lehman 等级测试,同时保持使图形神经网络如此有吸引力的低线性复杂度是一个开放的研究问题。

图神经网络在存在噪声数据或遭受敌对攻击时的鲁棒性和有保证的性能[9]是另一个有趣且基本上未开发的研究领域。

应用程序也许是这个领域最令人满意的部分。从事图形学习多年后,我已经和粒子物理学家[10]、临床医生[11]、生物学家和化学家[12]交了朋友——如果我们没有在他们各自的领域进行应用研究,我是不可能认识这些人的。如果我要打赌图形深度学习在未来几年可能产生最大影响的一个领域,我会指出结构生物学和化学。在这些领域中,基于图的模型既可以用作分子的低级模型[5],也可以用作它们之间相互作用的高级模型[13,11]。将这些结合起来可能是达到对制药行业有用的水平的关键——我们看到了这方面的初步迹象,今年早些时候,图形神经网络被用于发现一种新的抗生素[14]或预测蛋白质之间的相互作用[12]。如果图形深度学习实现了它的承诺,那么传统上非常漫长且极其昂贵的发现、开发和测试新药的过程可能永远不会变了。

[1] M. M. Bronstein 等人几何深度学习:超越欧几里德数据 (2017),IEEE 信号处理杂志 34(4):18–42。

[2] P .巴塔格利亚等人,关系归纳偏差、深度学习和图网络 (2018),arXiv:1806.01261。

[3] F. Scarselli 等.图形神经网络模型(2008),IEEE 神经网络汇刊 20(1):61–80 .

[4] A .屈希勒尔,c .戈勒(1996 年)。使用结构驱动的递归神经网络在符号域中进行归纳学习。Künstliche Intelligenz。

[5] J. Gilmer 等人,量子化学的神经信息传递 (2017),ICML。

[6] A. Wissner-Gross,数据集超过算法 (2016)。

[7] C.-Y .桂等..关于图形处理加速器的调查:挑战与机遇 (2019),arXiv:1902.10130。

[8] K. Xu 等图神经网络到底有多强大? (2019),ICLR。

[9] D. Zügner 等人,图数据对神经网络的对抗性攻击 (2018),Proc .KDD。

[10] N. Choma 等人ice cube 信号分类的图形神经网络 (2018),Proc .ICMLA。

[11] K. Veselkov 等人 HyperFoods:食品中抗癌分子的机器智能图谱 (2019),科学报告 9。

[12] P .盖恩萨等人利用几何深度学习从蛋白质分子表面破译相互作用指纹 (2020),自然方法 17:184–192。

[13] M. Zitnik 等人用图卷积网络建模多药副作用 (2018),生物信息学 34(13):457–466。

[14] J. Stokes 等.抗生素发现的深度学习方法(2020),细胞,180(4)。

A 中文翻译 本帖由 刘止庸 提供。另见 丹麦语版 。对图形深度学习感兴趣?参见我的 博客 关于走向数据科学, 订阅我的 帖子,获取 中等会员 ,或者关注我的 推特

点云深度学习:在 Google Colab 中实现 PointNet

原文:https://towardsdatascience.com/deep-learning-on-point-clouds-implementing-pointnet-in-google-colab-1fd65cd3a263?source=collection_archive---------2-----------------------

点网是一种简单有效的点云识别神经网络。在本教程中,我们将使用 PyTorch 实现它。

1.介绍

3D 数据对于自动驾驶汽车、自主机器人、虚拟和增强现实至关重要。与用像素阵列表示的 2D 图像不同,它可以表示为多边形网格体积像素网格点云等。

图片来自:用 PyTorch 中的一张 2D 图片创建 3D 模型

在今天的计算机视觉和机器学习中, 90%的进步只处理二维图像

1.1.点云

点云是一种广泛使用的 3D 数据形式,可以由深度传感器产生,如激光雷达RGB-D 相机。

它是 3D 物体最简单的表示:仅点于 3D 空间无连通性。点云也可以包含点的法线。

几乎所有的 3d 扫描设备都会产生点云。

可以捕捉点云的设备(Iphone 11、华硕 Zenfone AR、索尼 Xperia XZ1)。图片来自:本课程

此外,最近苹果推出了带有激光雷达扫描仪的 Ipad Pro,可以测量 5 米以外的周围物体的距离。

1.2.点云深度学习

所以,让我们想想如何处理点云。CNN 对图像非常有用。我们能把它们用于 3D 吗?

想法:将 2D 卷积推广到规则三维网格

图片来自: arxiv 论文

这个其实管用

主要的问题低效表示:大小为 100 的立方体素网格将有 1,000,000 个体素。

1.3.点网

但是如果我们尝试处理点云呢?

有三个主要的约束:

  • 点云是无序的。算法必须对输入集的排列不变。
  • 如果我们旋转椅子,它还是椅子,对吗?网络必须是不变的 刚性变换
  • 网络应该捕捉点之间的相互作用。

PointNet 的作者介绍了一种考虑了所有这些特性的神经网络。它设法解决分类,部件和语义分割任务。来实施吧!

图片来自: arxiv 论文

2.履行

在本节中,我们将使用 PyTorch 从 Google Colab 中的原始论文重新实现分类模型

你可以在https://github . com/nikitakaraevv/pointnet/blob/master/nbs/pointnet class . ipynb找到完整笔记本

2.1.资料组

在原始论文中,作者在 ModelNet40 形状分类基准上评估了 PointNet。它包含来自 40 个对象类别的 12,311 个模型,分为 9,843 个训练模型和 2,468 个测试模型。

为了简单起见,让我们使用同一个数据集的较小版本: ModelNet10。它由来自 10 个类别的对象、3991 个用于训练的模型和 908 个用于测试的模型组成。

[## 3D 形状网:体积形状的深层表示

在物体识别中,3D 形状是一个至关重要但严重未被充分利用的线索,主要是因为缺乏一个好的通用…

3dvision.princeton.edu](http://3dvision.princeton.edu/projects/2014/3DShapeNets/)

想直接开始训练别忘了打开 GPU

让我们导入必要的库:

我们可以将数据集直接下载到 Google Colab 运行时:

这个数据集由组成。关闭包含由顶点和三角面表示的网格文件。顶点只是三维空间中的点,每个三角形由 3 个顶点索引组成。

我们将需要一个函数来读取。关闭文件:

完整网格看起来是这样的:

啮合其中一个。关闭文件。使用创建 plotly

如你所见,这是一张🛏床

但是如果我们去掉人脸,只保留 3D 点,它看起来就不再像一张床了!

网格顶点

实际上,曲面的平坦部分不需要任何点来构建网格。这就是为什么点主要位于床的角度和圆形部分。

2.2.点取样

因此,由于点不是均匀分布在物体表面的,我们的点网很难对它们进行分类。(尤其是知道这个点云看起来连床都不像)。

这个问题的解决方案可能非常简单:让我们在物体的表面上均匀地采样点。

我们不应该忘记脸可以有不同的区域。

因此,我们可以将选择特定面的概率与其面积成比例分配。这是可以做到的:

我们的网络架构中将会有密集层。这就是为什么我们希望点云中有固定数量的点。让我们从构建的分布中抽取人脸样本。之后,我们在每个选择的面上采样一个点:

一些面可以有多个采样点,而另一些面根本没有采样点。

由网格曲面上的采样点创建的点云

这个点云看起来更像一张床!🛏

2.3.增加

让我们想想其他可能的问题。我们知道物体可以有不同的大小,可以放在我们坐标系的不同部分。

因此,让我们物体平移到原点,从其所有点中减去平均值,并将的点归一化到一个单位球。为了在训练期间增加数据,我们围绕 Z 轴随机旋转对象,并添加高斯噪声,如本文所述:

这是标准化的同一张床,带有旋转噪音:

添加噪声的旋转点云

2.4.模型

好了,我们已经完成了数据集和预处理。让我们考虑一下模型架构。该架构及其背后的关键思想已经得到了很好的解释,例如,在本文中:

[## 深入了解 PointNet

PointNet 是 3D 感知领域的开创性论文,将深度学习应用于点云,用于对象分类和…

medium.com](https://medium.com/@luis_gonzales/an-in-depth-look-at-pointnet-111d7efdaa1a)

我们记得结果应该是对输入点的不变排列和几何变换,比如刚性变换

图片来自: arxiv 论文

让我们在 PyTorch 中开始实现它:

首先,我们的张量会有大小(batch_size, num_of_points, 3)。在这种情况下,具有共享权重MLP 只是具有大小为 1 的内核的 1-dim 卷积

为了确保对变换的不变性,我们将 T-Net 预测的 3x3 变换矩阵应用于输入点的坐标。有趣的是,我们不能通过三维矩阵对 3D 空间中的翻译进行编码。无论如何,我们已经在预处理中将点云平移到原点。

这里重要的一点是输出矩阵的初始化。我们希望它默认为 identity,开始训练时没有任何转换。因此,我们只需在输出中添加一个单位矩阵:

在应用 MLP 后,我们将使用相同但 64 维的 T 网来对齐提取的点特征。

为了提供置换不变性,我们将对称函数(max pooling)应用于提取和转换的特征,因此结果不再依赖于输入点的顺序。

让我们把它们结合在一起:

然后,让我们用输出端的最后一个 MLPLogSoftmax将它们打包在一个类中:**

最后我们将定义损失函数。正如我们使用 LogSoftmax 获得稳定性 一样,我们应该使用 NLLLoss 而不是 CrossEntropyLoss。此外,我们将添加两个正则化项,以使变换矩阵接近正交( AAᵀ = I ) :

2.5.培养

****最后一步!我们可以用一个经典的 PyTorch 训练循环。这肯定不是最有趣的部分,所以让我们省略它。

同样,带有训练循环的完整 Google Colab 笔记本可以在此链接 后找到

我们就来看看在 GPU 上训练 15 个纪元后的结果吧。培训本身大约需要 3 个小时,但是根据 Colab 分配给当前会话的 GPU 类型,培训时间可能会有所不同

通过一个简单的训练循环,在 13 个时期后可以达到 85% 的总体验证准确度,相比之下,在原始作品中对于 40 个类,该准确度为 89%。这里的要点是实现完整的模型,而不是真的获得最好的分数。因此,我们将把调整训练循环和其他实验作为练习。****

有趣的是,我们的模型有时会混淆梳妆台和床头柜,厕所和椅子,书桌和桌子,这很容易理解(厕所除外):

3.最后的话

你做到了!🎉🎊👏

你实现了 PointNet ,这是一个深度学习架构,可以用于各种 3D 识别任务。尽管我们在这里实现了分类模型,但是分割正常评估或其他任务只需要对模型和数据集类进行微小的修改。

完整的笔记本可在https://github . com/nikitakaraevv/point net/blob/master/nbs/point net class . ipynb获得。

感谢您的阅读!我希望这篇教程对你有用。如果是这样,请在评论中告诉我。顺便说一句,这是我的第一篇媒体文章,所以我将非常感谢您的评论或私信反馈!

参考资料:

[1] Charles R. Qi,,Kaichun Mo,Leonidas J. Guibas, PointNet:用于三维分类和分割的点集深度学习 (2017),CVPR 2017

[2]亚当·康纳-西蒙斯,点云深度学习 (2019),麻省理工学院计算机科学&人工智能实验室

[2] Loic Landrieu,3D 点云的语义分割 (2019),巴黎东方大学—机器学习与优化工作组

[4] Charles R. Qi 等,用于 3D 数据上对象分类的体积和多视图 CNN(2016),

深度学习优化器——难?不是。[1]

原文:https://towardsdatascience.com/deep-learning-optimizers-hard-not-3f5c4f7b4e96?source=collection_archive---------34-----------------------

让优化器更容易理解

Unsplash 上由 Franck V. 拍摄的照片

你说优化?—哇,伙计,那是一些超级复杂的数学;对吗?对吗?不对!大多数人回避优化算法,因为它们大多是通过在 PyTorch 或 TensorFlow 中编写一行代码来实现的。然而,对于神经网络训练来说,优化算法通常是训练模型中最有影响力的因素。他们对如何更新权重、模型学习什么和丢弃什么有完全的发言权。

深度学习是当今最先进的技术之一。这真的不难理解为什么这么多人对人工智能或神经网络感兴趣。互联网上大量的课程材料使得新手很难选择一种正确的教学方法。因此,大量对人工智能感兴趣的人很少知道基础知识。

深入主题,深度学习涉及许多方式和上下文的优化。深度学习中最难的优化问题之一是神经网络训练。与神经网络训练相关联的优化围绕寻找减小损失函数 J(θ)的参数 θ

在数学优化和决策理论中,损失函数或成本函数是一个函数,它将一个事件或一个或多个变量的值映射到一个实数上,直观地表示与该事件相关的一些“成本”——https://en.wikipedia.org/wiki/Loss_function

人们最常犯的一个错误是他们不能区分优化和反向传播。这确实令人困惑,所以让我给你解释一下。在反向传播中,我们计算梯度,并且不基于这些梯度更新权重。我们只是计算梯度。在优化过程中,我们根据计算的梯度和我们选择的优化算法来更新权重。因此,优化算法因网络而异,但反向传播保持不变。

神经网络中的优化不同于在各种机器学习模型中观察到的优化。在最大似然模型中,我们已经能够仔细地设计目标函数,使得损失函数是凸的,从而优化问题变得相当容易。然而,在训练神经网络时,由于以下普遍面临的问题,事情变得复杂和失控:

  1. 神经网络具有高维凸优化问题。结果,我们经常遇到零梯度的鞍点。鞍点的问题是,当从一个横截面观察它们时,我们得到一个局部最小值,而从另一个横截面,我们得到一个全局最大值。

鞍点 v/s Minima—https://commons . wikimedia . org/wiki/File:Minima _ and _ Saddle _ point . png

2.最优化的问题并不以鞍点结束。目标函数导数中的悬崖是与训练相关联的另一个优化问题。由于几个重量相乘,我们有陡峭的区域,称为悬崖。当算法在这样的悬崖之前时,它可能采取太大的步骤,并且可能跳下悬崖,从而扰乱算法的正常流程。

3.如果局部表面不指向全局最小值,则基于局部梯度计算的优化失败。当成本函数导数包含某个“悬崖”并且不能穿越它时,可能会发生这种情况。它可能在更高维度的空间中穿行,但是在训练期间花费的过多时间会使网络太慢。

4.在神经网络中也观察到“消失”和“爆炸”梯度的问题。当神经网络涉及相同矩阵的重复乘法(如在 RNNs 中)导致具有高指数的矩阵时,出现消失和爆炸梯度。当执行矩阵的特征分解以获得特征值时,任何不接近 1 的特征值将爆炸(如果大于 1)或消失(如果小于 1 ),产生消失和爆炸梯度的问题。

因此,我们可以看到,如果我们试图优化和训练一个神经网络,我们可能会面临许多问题。幸运的是,我们已经准备好了一些优化算法,这些算法是研究人员经过数月甚至数年的工作后留给我们的。我将讨论非常流行的 SGD 优化算法。(随机梯度下降)

签名于

随机梯度下降可能是深度学习中最常用的优化算法之一。要理解随机梯度下降,就必须理解什么是梯度下降。梯度下降意味着沿着梯度的斜坡移动。你是如何“移动”的?

梯度下降算法首先决定斜率指向哪个方向。然后它向降低斜率迈出了一步。这背后的直觉是,我们最终寻求最小化成本函数,我们可以在斜率为零的地方得到最小值。但是,嘿——一个最大值也有零斜率!这就是为什么我们使用海森矩阵。海森矩阵存储了成本函数的二阶导数,帮助我们区分最大值和最小值。

现在,主要有三种类型的梯度下降—

  1. 批量梯度下降:在这种类型的梯度下降中,在评估所有训练样本之后更新权重。
  2. 在线训练:在这种类型的梯度下降中,一旦一个训练样本被评估,权重就被更新。训练样本是随机选择的。
  3. 小批量梯度下降(SGD):小批量梯度下降结合了两个世界的优点。在这种情况下,我们从训练样本中随机抽取一小批样本,并在评估后更新权重。然后我们对另一个小批量样品进行取样,这个过程一次又一次地重复。

现在,我们知道权重是根据我们定义的学习率更新的。然而,在编写 SGD 优化算法时,我们必须记住的一个最重要的因素(你通常不会)是,学习速率必须随着时间的推移而降低。

需要降低学习率,因为 SGD 使用小批量。从训练数据中采样小批量,并且这种数据采样导致噪声的存在。即使我们到达最低限度,噪音也不会消失。因此,我们需要密切监控学习率,以使模型收敛。

为什么用 SGD 而不用梯度下降(批量)?

神经网络需要大量数据才能正常工作。与机器学习模型相比,即使在简单的分类器中也需要更多的训练数据。对大量的训练样本使用梯度下降在计算上将是非常昂贵的,并且将成倍地增加学习时间。SGD 和使用基于小批量的模型的主要特征之一是每次更新的学习时间不会随着训练数据的增加而增加。这是非常有用的,因为我们最终可以突破梯度下降对我们可以使用的训练数据大小的限制。

我希望这篇文章有助于打破优化算法的概念及其在深度学习领域的必要性。如果有任何问题,请在评论区告诉我:)

参考:深度学习作者:伊恩·古德菲勒、约舒阿·本吉奥、亚伦·库维尔(2017)

自然语言处理(NLP)的深度学习管道

原文:https://towardsdatascience.com/deep-learning-pipeline-for-natural-language-processing-nlp-c6f4074897bb?source=collection_archive---------10-----------------------

NLP、无监督机器学习和深度学习概念在无标签文本数据上的实际实现。

照片由 Unsplash 上的 h heyerlein 拍摄

在本文中,我将探索自然语言处理(NLP)的基础知识,并演示如何实现一个管道,该管道将传统的无监督学习算法与深度学习算法相结合,以训练无标签的大型文本数据。因此,主要目标是演示如何建立管道,以促进原始文本数据的收集和创建,预处理和分类未标记的文本数据,最终在 Keras 中训练和评估深度学习模型。

阅读完本教程后,您将能够执行以下操作:

  1. 如何通过 Twitter API 和 Tweepy Python 包从 Twitter 收集数据
  2. 如何用 pandas 高效地读取和清理大型文本数据集
  3. 如何使用基本的自然语言处理技术预处理文本数据并生成特征
  4. 如何对未标记的文本数据进行分类
  5. 如何在 Keras 中训练、编译、拟合和评估深度学习模型

在我的 GitHub 中找到我的带有 Python 代码的 Jupyter 笔记本。

卷起袖子,我们有很多工作要做,让我们开始吧…..

数据

在做这个项目的时候,美国 2020 年大选即将到来,对与即将到来的选举相关的推文进行情感分析,以了解在选举日之前大约两周 Twitter 世界中正在讨论的观点和话题是有意义的。Twitter 是一个未经过滤的意见的伟大来源,而不是我们从主要媒体渠道看到的典型的过滤新闻。因此,我们将通过使用 Twitter API 和 python 包 Tweepy 从 Twitter 收集 tweets 来构建我们自己的数据集。

步骤 1:数据收集

先决条件

在开始使用来自 Twitter 的流数据之前,您必须具备以下条件:

  1. Twitter 帐户和 Twitter API 消费者密钥(访问令牌密钥、访问令牌秘密密钥、消费者密钥和消费者秘密密钥)
  2. 安装在您的 Jupyter 笔记本中的 Tweepy 软件包

设置 Twitter 帐户和检索您的 Twitter API 消费者密钥超出了本文的范围。如果你在这些方面需要帮助,看看这个帖子

Tweepy 可以通过 Jupyter 笔记本中的 pip install 进行安装,下面一行代码就可以完成。

# Install Tweepy
!pip install tweepy

安装完成后,继续将软件包导入您的笔记本电脑。

1.1 设置数据流管道

在这一节中,我将向您展示如何使用 Twitter API、Tweepy 和一个自定义函数来设置您的数据流管道。我们可以通过三个步骤实现这一目标:

  1. 设置您的 Twitter API 消费者密钥
  2. 设置 Twitter API 授权处理程序
  3. 编写一个自定义函数来监听和流式传输实时推文
# Twitter API consumer keys
access_token = "  insert your key here  "
access_token_secret = "  insert your key here  "
consumer_key = "  insert your key here  "
consumer_secret = "  insert your key here  "# Twitter API authorization
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)# Custom function that streams data from Twitter (20,000 tweets at most per instance)
class MyStreamListener(tweepy.StreamListener):
    """Function to listen and stream Twitter data"""
    def __init__(self, api=None):
        super(MyStreamListener, self).__init__()
        self.num_tweets = 0
        self.file = open("tweets.txt", "w")def on_status(self, status):
        tweet = status._json
        self.file.write( json.dumps(tweet) + '\n' )
        self.num_tweets += 1
        if self.num_tweets < 20000: 
            return True
        else:
            return False
        self.file.close()def on_error(self, status):
        print(status)

1.2 开始直播推文

既然环境已经设置好了,您就可以开始从 Twitter 流式传输实时推文了。在此之前,确定一些你想用来收集你感兴趣的相关推文的关键词。由于我将发布与美国大选相关的推文,我选择了一些相关的关键词,如“美国大选”、“特朗普”、“拜登”等。

我们的目标是收集至少 400,000 条推文,使其成为足够大的文本数据,一次性收集所有这些数据的计算量很大。因此,我将建立一个管道,以高效地传输数据。请注意上面的自定义函数,它将在每个块中最多监听和传输 20,000 条 tweets。因此,为了收集超过 40 万条推文,我们需要运行至少 20 个区块。

下面是代码如何寻找用于监听和流式传输实时推文到熊猫数据帧的块:

# Listen and stream live tweets
listener = MyStreamListener()
stream = tweepy.Stream(auth, listener)
stream.filter(track = ['US Election', 'election', 'trump', 'Mike Pence', 'biden', 'Kamala Harris', 'Donald Trump', 'Joe Biden'])# Read the tweets into a list
tweets_data_path = 'tweets.txt'
tweets_data=[]
tweets_file_1 = open(tweets_data_path, 'r')# Read in tweets and store in list: tweets_data
for line in tweets_file_1:
    tweet = json.loads(line)
    tweets_data.append(tweet)# Close connection to file
tweets_file_1.close()# Print the keys of the first tweet dict
print(tweets_data[0].keys())# Read the data into a pandas DataFrame
names = tweets_data[0].keys()
df1 = pd.DataFrame(tweets_data, columns= names)

如上所述,为了收集 400,000 条推文,您必须运行上述代码至少 20 次,并将收集的推文保存在单独的 pandas dataframe 中,该 dataframe 将在以后连接起来,以将所有推文整合到单个数据集。

1.3 将所有数据块组合成一个数据集

# Concatenate dataframes into a single pandas dataframe
list_of_dataChunks = [df1, df2, df3, df4, df5, df6, df7, df8, df9, df10, df11, df12, df13, df14, df15, df16, df17, df18, df19, df20]
df = pd.concat(list_of_dataChunks, ignore_index=True)# Export the dataset into a CSV file
df.to_csv('tweets.csv', index=False)

现在,您已经将组合数据集导出到 CSV 文件中,您可以在接下来的数据清理和可视化步骤中使用它。

我已经捐赠了我创建的数据集,并在 Kaggle 中公开。

第二步:数据争论

在本节中,我们将清理刚刚收集的数据。在可视化数据之前,必须清理数据集并将其转换为可以高效可视化的格式。给定具有 440,000 行的数据集,必须找到一种有效的方法来读取和清理它。为此,pandas chunksize 属性可用于将 CSV 文件中的数据以块的形式读入 pandas 数据帧。此外,我们可以指定感兴趣的列的名称,而不是读取包含所有列的数据集。使用 chunksize 和更少量的感兴趣的列,大型数据集可以非常高效和快速地读入数据帧,而不需要其他替代方案,例如在集群上使用 PySpark 的分布式计算。

为了将数据集转换成可视化所需的形状,将应用以下基本 NLP 技术:

  1. 提取仅有的英语推特
  2. 删除重复项(如果有)
  3. 删除丢失的值(如果有)
  4. 标记化(将推文分成单个单词)
  5. 将单词转换成小写
  6. 删除标点符号
  7. 删除停用词
  8. 删除网址,“twitter”和其他缩写词

我将遵循以下方法来实现上述步骤:

  1. 编写一个自定义函数来标记推文
  2. 编写另一个自定义函数,对数据应用上述所有清理步骤。
  3. 最后,读取数据块,并在读取数据块时,通过自定义函数将这些争论步骤应用于每个数据块。

让我们看看所有这些都在起作用…

# Function to tokenize the tweets
def custom_tokenize(text):
    """Function that tokenizes text"""
    from nltk.tokenize import word_tokenize
    if not text:
        print('The text to be tokenized is a None type. Defaulting to blank string.')
        text = ''
    return word_tokenize(text)# Function that applies the cleaning steps
def clean_up(data):
    """Function that cleans up the data into a shape that can be further used for modeling"""
    english = data[data['lang']=='en'] # extract only tweets in english language
    english.drop_duplicates() # drop duplicate tweets
    english['text'].dropna(inplace=True) # drop any rows with missing tweets
    tokenized = english['text'].apply(custom_tokenize) # Tokenize tweets
    lower_tokens = tokenized.apply(lambda x: [t.lower() for t in x]) # Convert tokens into lower case
    alpha_only = lower_tokens.apply(lambda x: [t for t in x if t.isalpha()]) # Remove punctuations
    no_stops = alpha_only.apply(lambda x: [t for t in x if t not in stopwords.words('english')]) # remove stop words
    no_stops.apply(lambda x: [x.remove(t) for t in x if t=='rt']) # remove acronym "rt"
    no_stops.apply(lambda x: [x.remove(t) for t in x if t=='https']) # remove acronym "https"
    no_stops.apply(lambda x: [x.remove(t) for t in x if t=='twitter']) # remove the word "twitter"
    no_stops.apply(lambda x: [x.remove(t) for t in x if t=='retweet']) # remove the word "retweet"
    return no_stops# Read and clean the data
warnings.filterwarnings("ignore")
use_cols = ['text', 'lang'] # specify the columns
path = 'tweets.csv' # path to the raw dataset
data_iterator = pd.read_csv(path, usecols=use_cols, chunksize=50000)
chunk_list = []
for data_chunk in data_iterator:
    filtered_chunk = clean_up(data_chunk)
    chunk_list.append(filtered_chunk)
tidy_data = pd.concat(chunk_list)

在这种情况下,块大小是 50,000,这就是熊猫如何读取每个块中的 50,000 条推文,并在读取下一批推文之前对它们应用清理步骤,等等。

在此过程之后,数据集将变得干净,并为可视化做好准备。为了避免每次打开笔记本时执行数据争论步骤,您可以简单地将整齐的数据导出到一个外部文件中,以便将来使用。对于大型数据集,将其导出到 JSON 文件比导出到 CSV 文件更有效。

# Explort the tidy data to json file for ease of use in the next steps
tidy_data.to_json('tidy_tweets.json', orient='table')

这些整洁的数据看起来是这样的:

步骤 3:探索性数据分析(可视化)

既然数据是干净的,让我们可视化并理解我们的数据的本质。我们可以关注的几个明显的事情如下:

  1. 每条推文的字数
  2. 一条推文中单词的平均长度
  3. Unigram
  4. 二元模型
  5. 三元模型
  6. Wordcloud

似乎每条推文的字数在 1 到 19 个词之间,平均在 10 到 12 个词之间。

推特中一个单词的平均字符数似乎在 3 到 14 个字符之间,平均出现在 5 到 7 个字符之间。人们可能会在 Twitter 设定的 280 个字符的限制内,选择简短的词语来以最佳方式表达自己的观点。

Unigram

正如所料,“特朗普”和“拜登”这两个词主导了 10 月 15 日至 10 月 16 日期间发布的 2020 年美国大选相关推文。

二元模型(最常出现的一对连续单词)

三元模型(三个单词的最常见序列)

Wordcloud

通过可视化数据,注意单词没有被词条化。词汇化是将单词转换成基本形式或词典形式的过程。这是 NLP 和机器学习中常用的技术。因此,在下一步中,我们将使用以下代码对令牌进行符号化。

# Convert tokens into format required for lemmatization
from nltk.corpus import wordnet
def get_wordnet_pos(word):
    """Map POS tag to first character lemmatize() accepts"""
    tag = nltk.pos_tag([word])[0][1][0].upper()
    tag_dict = {"J": wordnet.ADJ,
                "N": wordnet.NOUN,
                "V": wordnet.VERB,
                "R": wordnet.ADV}return tag_dict.get(tag, wordnet.NOUN)# Lemmatize tokens
lemmatizer = WordNetLemmatizer()
tidy_tweets['lemmatized'] = tidy_tweets['text'].apply(lambda x: [lemmatizer.lemmatize(word, get_wordnet_pos(word)) for word in x])# Convert the lemmatized words back to the text format
tidy_tweets['tokens_back_to_text'] = [' '.join(map(str, l)) for l in tidy_tweets['lemmatized']]

现在,让我们将符号化的标记保存到另一个 JSON 文件中,以便在管道的下一步中使用。

# Explort the lemmatized data to json file for ease of use in the next steps
tidy_tweets.to_json('lemmatized.json', orient='table')

方法

在进行预处理和建模的步骤之前,让我们回顾并明确我们在管道中的下一个步骤的方法。在我们可以预测一条推文属于哪个类别之前,我们必须首先用类别来标记原始推文。请记住,我们从 Twitter 上以原始推文的形式传输我们的数据,因此数据并没有标记出来。因此,实施以下方法是合适的:

  1. 用 k-means 聚类算法标记数据集
  2. 训练深度学习模型来预测推文的类别
  3. 评估模型并确定潜在的改进

步骤 4:标记未标记的文本数据并预处理

在这一部分,我们的目标是给推文贴上两个标签,分别对应积极或消极的情绪。然后进一步预处理,将标注后的文本数据转换成可以进一步用于训练深度学习模型的格式。

有许多不同的方法来对未标记的文本数据进行分类,这些方法包括但不限于使用 SVM、分层聚类、余弦相似度甚至亚马逊 Mechanical Turk。在这个例子中,我将向您展示另一种更简单的,也许不是最准确的,对文本数据进行分类的快速而又麻烦的方法。为此,我将首先对 VADER 进行情绪分析,以确定推文是积极的、消极的还是中立的。接下来,我将使用一个简单的 k-means 聚类算法,根据从推文的积极、消极和中立程度得出的计算复合值对推文进行聚类。

4.1 创造情绪

让我们先来看看数据集

列“tokens_back_to_text”是转换回文本格式的词汇化标记,我将使用 tidy 数据集中的此列来创建 VADER 包中的 SenitmentIntensityAnalyzer 情感。

# Extract lemmatized text into a list
tweets = list(df['tokens_back_to_text'])# Create sentiments with SentimentIntensityAnalyzer
**from** **vaderSentiment.vaderSentiment** **import** SentimentIntensityAnalyzer 
sid = SentimentIntensityAnalyzer()
sentiment = [sid.polarity_scores(tweet) **for** tweet **in** tweets]

下面是情绪的前 5 行

4.2 用 k-means 聚类对未标记数据进行标记

现在,我将使用上述数据帧中的“复合”列,并将其输入 k-means 聚类算法,以 0 或 1 分别代表“消极”或“积极”情绪。也就是说,我会将相应复合值大于或等于 0.05 的推文标记为积极情绪,而小于 0.05 的值将被标记为消极情绪。这里没有硬性规定,只是我如何设置我的实验。

下面是如何用 python 中的 scikit-learn 中的 k-means 聚类算法实现文本标注工作。记住,给标签和原始数据框都指定相同的索引,在那里你有你的推文/文本。

*# Tag the tweets with labels using k-means clustering algorithm*
**from** **sklearn.cluster** **import** KMeans
kmeans = KMeans(n_clusters=2, random_state=0).fit(compound)
labels = pd.DataFrame(kmeans.labels_, columns=['label'], index=df.index)

标签计数

查看 0 和 1 的标签计数,注意数据集是不平衡的,其中超过两倍的推文被标记为 1。这将影响模型的性能,因此我们必须在训练模型之前平衡数据集。

此外,我们还可以借助一种称为“潜在狄利克雷分配”的强大 NLP 算法,从每个类别中识别推文的主题,这种算法可以提供负面和正面推文中主题的直觉。稍后,我将在另一篇文章中展示这一点。现在,为了这个练习,让我们使用类别 0 和 1。所以现在,我们已经成功地将我们的问题转化为监督学习问题,接下来我们将继续使用我们现在标记的文本数据来训练深度学习模型。

第五步:建模

我们有一个相当大的数据集,有超过 400,000 条推文,超过 60,000 个独特的单词。在如此大的数据集上训练具有多个隐藏层的 rnn 在计算上是繁重的,如果你试图在 CPU 上训练它们,可能需要几天(如果不是几周的话)。训练深度学习模型的一种常见方法是使用 GPU 优化的机器来获得更高的训练性能。在本练习中,我们将使用预装了 TensorFlow 后端和 CUDA 的 Amazon SageMaker p2.xlarge 实例。我们将使用 Keras 接口到张量流。

让我们开始吧,我们将应用以下步骤。

培训步骤

  1. 对数据集进行标记化、填充和排序
  2. 用 SMOTE 平衡数据集
  3. 将数据集分成训练集和测试集
  4. 训练简单神经网络和 LSTM 模型
  5. 评估模型

数据集必须转换成数字格式,因为机器学习算法不理解自然语言。在对数据进行矢量化之前,我们先来看看数据的文本格式。

tweets.head()

5.1 对数据集进行标记化、填充和排序

*# prepare tokenizer* tokenizer = Tokenizer() tokenizer.fit_on_texts(tweets)*# integer encode the documents*
sequences = tokenizer.texts_to_sequences(tweets)*# pad documents to a max length of 14 words* maxlen = 14 X = pad_sequences(sequences, maxlen=maxlen)

5.2 用 SMOTE 平衡不平衡的数据

**from** **imblearn.over_sampling** **import** SMOTE
**from** **imblearn.under_sampling** **import** RandomUnderSampler
**from** **imblearn.pipeline** **import** Pipeline*# define pipeline*
over = SMOTE(sampling_strategy=0.5)
under = RandomUnderSampler(sampling_strategy=0.8)
steps = [('o', over), ('u', under)]
pipeline = Pipeline(steps=steps)*# transform the dataset*
X, y = pipeline.fit_resample(X, labels['label'])*# One-hot encoding of labels*
**from** **keras.utils.np_utils** **import** to_categorical
y = to_categorical(y)

从上面 0 和 1 之间的数据分布可以看出,与以前相比,现在的数据看起来相当平衡。

5.3 将数据分为训练集和测试集

既然数据已经平衡,我们就可以将数据分成训练集和测试集了。我将收集 30%的数据集进行测试。

# Split the dataset into train and test sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=43) 

5.4 培训注册护士

在这一部分,我将向您展示如何实现 RNN 深度学习架构的几个变体,3 层 SimpleRNN 和 3 层 LSTM 架构。默认情况下,SimpleRNN 和 LSTM 图层的激活函数都设置为“tanh ”,所以让我们保留其默认设置。我将使用所有 65,125 个唯一单词作为词汇表的大小,将每个输入的最大长度限制为 14 个单词,因为这与 tweet 中的最大单词长度一致,并将嵌入矩阵的输出维度设置为 32。

SimpleRNN

脱落层将用于强制正则化项以控制过度拟合。由于我的数据集被标记为二进制类,我将使用二进制交叉熵作为损失函数。就优化器而言,Adam optimizer 是一个不错的选择,我将准确性作为衡量标准。我将在训练集上运行 10 个时期,其中 70%的训练集将用于训练模型,而剩余的 30%将用于验证。这不能和我们放在一边的测试设备混淆。

*# SimpleRNN*
model = Sequential()
model.add(Embedding(input_dim = vocab_size, output_dim = output_dim, input_length = maxlen, embeddings_constraint=maxnorm(3)))
model.add(SimpleRNN(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(SimpleRNN(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(SimpleRNN(output_dim=output_dim))
model.add(Dense(2,activation='softmax'))

型号汇总如下:

SimpleRNN 模型结果如下— 10 个历元:

LSTM

3 层 LSTM 模型将使用漏失层进行训练。我将在训练集上运行 10 个时期,其中 70%的训练集将用于训练模型,而剩余的 30%将用于验证。这不能和我们放在一边的测试设备混淆。

# LSTM
model.add(Embedding(input_dim = vocab_size, output_dim = output_dim, input_length = maxlen, embeddings_constraint=maxnorm(3)))
model.add(LSTM(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(LSTM(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(LSTM(output_dim=output_dim, kernel_constraint=maxnorm(3)))
model.add(Dense(2,activation='softmax'))

型号汇总如下:

LSTM 模型结果如下— 10 个历元:

第六步:模型评估

现在,让我们绘制模型随时间变化的性能图,并查看它们在 10 个时期的精度和损失。

简单:精度

简单:损失

请注意训练精度,SimpleRNN 模型很快开始过度拟合,并且由于相同的原因,验证精度具有很高的方差。

LSTM:精确度

LSTM:损失

从 LSTM 的精度和损失图来看,模型过度拟合,验证精度不仅方差高,而且由于同样的原因下降很快。

结论

在这个项目中,我试图演示如何建立一个深度学习管道,来预测与 2020 年美国大选相关的推文的情绪。为此,我首先通过 Twitter API 和 Tweepy 包抓取原始推文,创建了自己的数据集。

超过 440,000 条推文通过 Twitter API 传输,并存储在一个 CSV 文件中。在争论和可视化数据之后,传统的聚类算法,在这种情况下是 k-means 聚类,被用来给推文贴上两个不同的标签,代表积极或消极的情绪。也就是说,在用数据训练深度学习模型之前,该问题被转换成监督学习问题。然后数据集被分成训练集和测试集。

随后,训练集分别用于训练 SimpleRNN 和 LSTM 模型,并使用每个时期模型性能的损失和精度曲线进行评估。总的来说,这两个模型都表现出应有的性能,并且根据从精度图中看到的情况,可能会过度拟合数据,因此,我为下一步提出以下建议。

建议:

  • 找到另一种方法或不同的学习算法来标记数据集
  • 尝试亚马逊机械土耳其人或地面真相来标记数据集
  • 尝试不同的 RNN 建筑
  • 对 RNN 架构执行更高级的超参数调整
  • 执行交叉验证
  • 使数据成为多类问题

本项目/教程中练习的技能:

  1. 如何通过 Tweepy 和 Twitter API 高效地从 Twitter 收集数据
  2. 如何有效地处理大型数据集

3.如何构建深度学习架构,编译并适应 Keras

4.如何将基本的自然语言处理概念和技术应用于文本数据

同样,在我的 GitHub 中找到我的带有 Python 代码的 Jupyter 笔记本,在这里,让我们在 LinkedIn 上连接。

享受深度学习:)我很想听到你的反馈和建议,所以请使用鼓掌按钮或在下面的部分评论。

谢谢大家!

在线参考和有用资料:

深度学习-为数据集准备图像

原文:https://towardsdatascience.com/deep-learning-prepare-image-for-dataset-d20d0c4e30de?source=collection_archive---------22-----------------------

获取数据集图像的简单方法

每当我们开始一个机器学习项目时,我们首先需要的是一个数据集。数据集将是您培训模型的支柱。您可以自动或手动构建数据集。在这里,我将分享关于手动过程。

什么是数据集?

数据集是满足您的 ML 项目需求的特定数据的集合。数据的类型取决于你需要训练的人工智能的类型。基本上,你有两个数据集:

  • 训练
  • 测试

分别为 90%和 10%的成分

每当你训练一个定制模型时,重要的是图像。是的,当然图像在深度学习中起着主要作用。你的模型的准确性将基于训练图像。所以,在你训练一个定制模型之前,你需要计划如何获取图像?在这里,我将分享我关于获取数据集图像的简单方法的想法。

从谷歌获取图片

是的,我们可以从谷歌上获取图片。使用 下载所有图片 浏览器扩展我们可以在几分钟内轻松获得图片。你可以在这里查看关于这个扩展的更多细节!各大浏览器都有。遗憾的是,Safari 浏览器不支持该扩展。

一旦你使用这个扩展下载图像,你会看到下载的图像在一个文件夹中,文件名是随机的。我们可以重命名文件或删除。png 文件,使用下面的 Python 脚本。

[## 下载所有图像

将活动选项卡中的所有图像保存为. zip 文件。轻松保存来自 Instagram、谷歌图片等的照片。

chrome.google.com](https://chrome.google.com/webstore/detail/download-all-images/ifipmflagepipjokmbdecpmjbibjnakm)

从下载的图像文件夹中删除 png。

重命名您的图像文件

从视频中获取图像

这里我们有另一种方法来为数据集准备图像。我们可以很容易地从视频文件中提取图像。 Detecto 给出了从视频中获取图像的简单解决方案。更多信息参见 探测器

pip3 install detecto

使用下面的代码,我们可以从视频文件中提取图像。

使用你的一组图像

您可以拍摄将用于训练模型的对象的照片。重要的是要确保你的图像不超过 800x600。这将有助于您的数据集训练更快。

我准备了一个视频,并解释了上述过程。请查看下面的视频博客。

为数据集准备图像的视频博客

结论

作为一名 ML noob,我需要找出为训练模型准备数据集的最佳方法。希望这能有用。我的最终想法是为这个过程创建一个 Python 包。😃

是的,我会想出我的下一篇文章!

原载于www.spritle.com

Keras 深度学习入门

原文:https://towardsdatascience.com/deep-learning-primer-with-keras-3958705882c5?source=collection_archive---------53-----------------------

图片由皮克斯拜的 Gerd Altmann 提供

Keras 是什么?

Keras 是一个深度学习框架,位于 TensorFlow 等后端框架之上。

为什么要用 Keras?

Keras 是优秀的,因为它允许你以很高的速度实验不同的神经网络!它位于 TensorFlow 等其他优秀框架之上,非常适合有经验的数据科学家和新手!它不需要那么多代码就可以启动并运行!

Keras 为您提供了构建所有类型架构的灵活性;这可以是递归神经网络、卷积神经网络、简单神经网络、深度神经网络等。

有什么区别?

你可能会问自己 Keras 和 TensorFlow 之间有什么区别…让我们来澄清一下!Keras 实际上是集成到 TensorFlow 中的。它是 TensorFlow 后端的包装器(从技术上讲,您可以将 Keras 与各种潜在的后端一起使用)。那是什么意思?在 TensorFlow 中,您可以根据需要拨打任何 Keras 电话。您可以享受 TensorFlow 后端,同时利用 Keras 的简单性。

神经网络最适合处理什么问题?

特征抽出

神经网络和传统机器学习的主要区别是什么?特征提取!传统上,无论是谁在操作机器学习模型,都是在执行与特征提取相关的所有任务。神经网络的不同之处在于,它们非常擅长为你执行这一步。

非结构化数据

当涉及到本质上不是表格并且是非结构化格式的数据时;即音频、视频等。;很难执行特征工程。你方便的神经网络将会在这类任务中表现得更好。

当你不需要解释的时候

当涉及到神经网络时,你对你的模型的结果没有太多的可视性。虽然这可能是好的,但取决于神经网络的应用,这也可能是棘手的。如果你能正确地将一幅图像归类为一匹马,那就太好了!你做到了;你其实不需要知道你的神经网络是怎么算出来的;而对于其他问题,这可能是模型价值的一个关键方面。

神经网络是什么样子的?

你最基本的神经网络将由三个主要层组成:

你的输入层,将由你所有的训练数据组成,

您的隐藏层,这是所有参数加权发生的地方,

最后是你的输出层——你的预测将在这里得到体现!

重量调整

当谈到应用于神经网络隐藏层的权重时,有几个主要因素可以帮助我们优化神经网络以获得正确的权重。其中之一是使用激活函数来确定权重。激活函数有助于网络识别数据中复杂的非线性模式。您可能会发现自己在使用 sigmoid、tanh、relu 和 softmax。

把手弄脏!

您需要从 Keras 导入所需的包。Sequential允许你实例化你的模型,&允许你添加每个层,基础,隐藏,&输出。此外,model.add()调用是我们如何将每一层添加到深度学习网络,直到最终输出层。

from keras.models import Sequential
from keras.layers import Dense# instantiate model
model = Sequential()
model.add(Dense(4, input_shape=(2,), activation="relu"))
model.add(Dense(1))
model.summary()

结论

如果你一路走到这里,那么你已经成功地运行了你的第一个神经网络!我希望这个对 Keras 的快速介绍是有益的。如果你想了解更多的其他话题或原则,请告诉我。在那之前,祝数据科学快乐!

用 fastai 构建深度学习项目——从模型训练到部署

原文:https://towardsdatascience.com/deep-learning-projects-with-fastai-from-model-training-to-deployment-2be3135bd757?source=collection_archive---------20-----------------------

用 fastai 开发计算机视觉应用的入门指南

去飞溅

深度学习正在引发许多学科的革命性变化。随着 TensorFlow、PyTorch 和现在的 fastai 等库的出现,领域专家和人工智能爱好者也越来越容易访问它。

以民主化深度学习为使命, fastai 是一家研究机构,致力于帮助每个人,从初级程序员到熟练的深度学习实践者,通过该领域最新研究的最先进模型和技术实现世界级的结果。

目标

这篇博文将带你了解使用 fastai 开发狗分类器的过程。目标是学习如何轻松地开始深度学习模型,并能够使用预先训练的模型,用有限的数据量获得近乎完美的结果。

先决条件

开始的唯一先决条件是你知道如何用 python 编码,并且你熟悉高中数学。

你会学到什么

  1. 导入库并设置笔记本
  2. 使用 Microsoft Azure 收集影像数据
  3. 将下载的数据转换为 DataLoader 对象
  4. 数据扩充
  5. 使用模型训练清理数据
  6. 导出定型模型
  7. 用你的 Jupyter 笔记本构建一个应用程序

导入库并设置笔记本

在我们开始构建我们的模型之前,我们需要从名为 fastbook 的笔记本集合中导入所需的库和实用函数,该集合旨在介绍使用 fastai 和 PyTorch 的深度学习。

让我们安装 fastbook 包来设置笔记本:

!pip install -Uqq fastbook
import fastbook
fastbook.setup_book()

然后,让我们从 fastbook 包和 fastai vision widgets API 导入所有函数和类:

from fastbook import *
from fastai.vision.widgets import *

使用 Microsoft Azure 收集影像数据

对于大多数类型的项目,你可以从各种数据仓库和网站找到在线数据。为了开发一个狗分类器,我们需要有狗的图像,在互联网上有很多狗的图像。

为了下载这些图片,我们将使用微软 Azure 提供的 Bing 图片搜索 API 。因此,在 Microsoft Azure 上注册一个免费帐户,您将获得价值 200 美元的点数。

转到您的门户网站,使用快速入门创建一个新的认知服务资源。启用 Bing 图像搜索 API,然后从左侧面板中的Keys and Endpoint选项将复制到您的资源中。

使用检索到的密钥,将这些密钥设置为环境,如下所示:

key = os.environ.get('AZURE_SEARCH_KEY', '<YOUR_KEY>')

现在,fastbook 附带了几个实用函数,如search_images_bing,它返回与您的搜索查询相对应的 URL。我们可以使用帮助功能了解这些功能:

help(fastbook)

您可以查看本帮助指南中的search_image_bing功能。该函数接受您在上面定义的资源和搜索查询的关键字,我们可以使用attrgot方法访问搜索结果的 URL:

results = search_images_bing(key, 'german shepherd dogs')
images = results.attrgot('content_url')
len(images)

我们有 150 个德国牧羊犬图片的网址:

现在,我们可以使用download_url功能下载这些图像。但是让我们首先定义我们想要的狗的类型。在本教程中,我将和三种类型的狗一起工作,德国牧羊犬、黑狗和拉布拉多。

所以,让我们定义一个狗的类型列表:

dog_types = ['german shepherd', 'black', 'labrador']
path = Path('dogs')

然后你需要定义你的图片下载的路径,以及每一类狗的文件夹的语义名称。

if not path.exists():
    path.mkdir()
    for t in dog_types:
        dest = (path/t)
        print(dest)
        dest.mkdir(exist_ok=True)
        results = search_images_bing(key, '{} dog'.format(t))
        download_images(dest, urls=results.attrgot('content_url'))

这将创建一个“狗”目录,其中进一步包含每种类型的狗图像的 3 个目录。

之后,我们传递了搜索查询(也就是 dog_type)和搜索函数的键,然后是下载函数,从搜索结果中下载所有的 URL 到它们各自的目的地(dest)目录中。

我们可以使用get_image_file功能检查下载到某个路径的图像:

files = get_image_files(path)
files

验证图像

您还可以检查文件中损坏文件/图像的数量:

corrupt = verify_images(files)
corrupt##output: (#0) []

通过将 unlink 方法映射到损坏文件列表,可以删除所有损坏的文件(如果有):

corrupt.map(Path.unlink);

就这样,我们准备了 379 张狗的图片来训练和验证我们的模型。

将下载的数据转换为 DataLoader 对象

现在,我们需要一种机制来为我们的模型提供数据,fastai 有数据加载器的概念,它存储传递给它的多个数据加载器对象,并使它们作为trainingvalidation集合可用。

现在,要将下载的数据转换成 DataLoader 对象,我们必须提供四样东西:

  • 我们正在处理什么样的数据
  • 如何获取项目列表
  • 如何给这些物品贴标签
  • 如何创建验证集

现在,为了创建这些数据加载器对象以及上面提到的信息,fastai 提供了一个称为 数据块 API 的灵活系统。 我们可以使用 API 提供的参数和一系列转换方法来指定数据加载器创建的所有细节:

dogs = DataBlock(
        blocks=(ImageBlock, CategoryBlock),
        get_items=get_image_files,
        splitter=RandomSplitter(valid_pct=0.2, seed=41),
        get_y=parent_label,
        item_tfms=Resize(128)
        )

这里,我们有一堆我们应该理解的论点:

  • —指定特征变量(图像)和目标变量(每个图像的类别)
  • get_items —检索底层项目,在我们的例子中是图像,我们有**get_image_files**函数返回该路径中所有图像的列表。
  • 拆分器 —按照提供的方法拆分数据;我们使用随机分割,为验证集保留 20%的数据,并指定种子在每次运行时得到相同的分割。
  • get_y — 目标变量称为 y;为了创建标签,我们使用了**parent_label**函数,它获取文件所在文件夹的名称作为标签。
  • item_tfms —我们有不同大小的图像,这导致了一个问题,因为我们总是向模型发送一批文件,而不是单个文件;因此,我们需要对这些图像进行预处理,将它们调整到标准大小,然后将它们分组到一个张量中以通过模型。我们在这里使用了**Resize**转换。

现在,我们有了 DataBlock 对象,需要通过提供数据集的路径将它转换为 DataLoader:

dls = dogs.dataloaders(path)

然后,我们可以使用show_batch方法检查 dataloader 对象中的图像:

dls.valid.show_batch()

数据扩充

我们可以向这些图像添加变换,以创建输入图像的随机变化,这样它们看起来不同,但仍然代表相同的事实。

我们可以旋转、扭曲、翻转或改变图像的亮度/对比度来创造这些变化。我们也有一套标准的增强功能封装在aug_transforms函数中,对于大多数计算机视觉数据集来说都非常适用。

我们现在可以将这些变换应用于整批图像,因为所有图像都具有相同的大小(224 像素,图像分类问题的标准),现在使用如下:

##adding item transformationsdogs = dogs.new(
                item_tfms=RandomResizedCrop(224, min_scale=0.5), 
                batch_tfms=aug_transforms(mult=2)
               )
dls = dogs.dataloaders(path)
dls.train.show_batch(max_n=8, nrows=2, unique=True)

模型训练和数据清理

是时候用这些数量有限的图片来训练模型了。fastai 提供了许多可供使用的架构,这使得使用迁移学习变得非常容易。我们可以使用适用于大多数应用程序/数据集的预训练模型来创建卷积神经网络(CNN)模型。

我们将使用 ResNet 架构,它对于许多数据集和问题来说既快速又准确。**resnet18**中的 18 代表神经网络的层数。我们还使用来自数据加载器的验证集传递度量来测量模型预测的质量。我们使用 error_rate 来说明模型做出错误预测的频率:

model = cnn_learner(dls, resnet18, metrics=error_rate)
model.fine_tune(4)

fine_tune方法类似于其他 ML 库中的fit()方法。现在,为了训练模型,我们需要指定我们想要在每个图像上训练模型的次数(时期)。

这里,我们只训练 4 个时期:

我们还可以使用混淆矩阵将预测可视化并与实际标签进行比较:

interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix()

如你所见,我们只有五个不正确的预测。让我们检查一下最大损失,即数据集中损失最大的图像:

interp.plot_top_losses(6, nrows=3)

你可以看到模型混淆了黑色和拉布拉多。因此,我们可以使用 ImageClassifierCleaner 类将这些图像指定到特定的类别中。

将模型传递给班级,它将打开一个带有直观 GUI 的小部件,用于数据清理。我们可以更改训练集和验证集图像的标签,并查看损失最大的图像。

在将每个图像添加到它们各自正确的类后,我们必须使用以下命令将它们移动到正确的目录:

for idx,cat in cleaner.change():
    shutil.move(str(cleaner.fns[idx]), str(path/cat).split('.')[0] +"_fixed.jpg")

导出定型模型

在几轮超参数调整之后,一旦您对您的模型满意了,您就需要保存它,以便我们可以将它部署到服务器上用于生产。

当保存一个模型时,我们拥有对我们有价值的模型架构和训练参数。fastai 提供了用扩展名.pkl将模型保存在 pickle 文件中的export()方法。

model.export()
path = Path()
path.ls(file_exts='.pkl')

然后,我们可以加载模型,并通过向加载的模型传递图像来进行推断:

model_inf = load_learner(path/'export.pkl')

使用这个加载的模型进行推理:

model_inf.predict('dogs/labrador/00000000.jpg')

我们可以从模型数据加载器词汇表中检查标签:

model_inf.dls.vocab

用你的 Jupyter 笔记本构建一个应用程序

下一步是创建一个我们可以与朋友、同事、招聘人员等分享的应用程序。要创建一个应用程序,我们需要添加交互式元素,以便我们可以尝试和测试应用程序的功能,我们需要将它作为一个网页在 web 上提供,包括通过一些框架(如 flask)或简单地使用 Voila 来部署它。

你可以简单地使用 Voila 将这个 Jupyter 笔记本转换成一个独立的应用程序。我在这里没有涉及到它,但是你可以通过我的博客/视频完整地了解它。

[## 使用 Python 和 Voila 构建新冠肺炎分析仪表板

用你的 jupyter 笔记本创建一个具有交互式可视化和灵活性的仪表板。

towardsdatascience.com](/building-covid-19-analysis-dashboard-using-python-and-voila-ee091f65dcbb)

部署

我已经在我的文章中介绍了 ML 模型的部署:

[## 使用 Flask 部署已训练的 ML 模型

端到端 ML 项目教程系列的第 2 部分

towardsdatascience.com](/deploying-a-trained-ml-model-using-flask-541520b3cbe9)

但是如果你想要另一种简单自由的方式来部署你的 Voila 应用程序,你可以使用 Binder 。按照以下步骤在 Binder 上部署应用程序:

  1. 将你的笔记本添加到一个 GitHub 库
  2. 将该回购的 URL 插入活页夹的 URL 字段。
  3. 将文件下拉列表改为选择 URL。
  4. 在“要打开的 URL”字段中,输入/voila/render/<*name>*.ipynb
  5. 单击右下角的剪贴板按钮复制 URL 并粘贴到安全的地方。
  6. 单击启动。

这就对了,你的狗分类器是活的!

如果你喜欢看我执行所有这些步骤,这里有这个博客的视频版本:

数据科学与 Harshit

通过这个渠道,我计划推出几个覆盖整个数据科学领域的系列。以下是你应该订阅频道的原因:

请随时在 TwitterLinkedIn 上与我联系。

深度学习:认识你家的宠物!

原文:https://towardsdatascience.com/deep-learning-recognise-your-home-pets-82a35d524703?source=collection_archive---------46-----------------------

深度学习对象检测

想知道宠物的面部识别是如何工作的吗?手机解锁?我会用一种你们也能认出自己宠物的方式来展示这个项目。

(权利:自己的形象)

检查我的 GitHub 库中的源代码。如果遇到任何问题,请给我发电子邮件。

[## miki998 -概述

在 GitHub 上注册你自己的个人资料,这是托管代码、管理项目和构建软件的最佳地方…

github.com](https://github.com/miki998)

路标

下面是本文的路线图:

1】简介

2】演示和使用的前提条件

3]示例和结果

4】未来的改进

开始了。

1]简介

如果您不熟悉对象检测,请查看我最近写的一篇关于 Yolo 架构的文章,尽管在那里谈到了 yolov4,在这里使用了 yolov3,但主要概念仍然存在。

[## 更快的实时物体检测:Pytorch 中的 YoloV4

我发现我可爱的猫比以前更快了!

medium.com](https://medium.com/analytics-vidhya/faster-real-time-object-detection-yolov4-in-pytorch-6eef8436ba75)

2]演示和使用的先决条件

系统先决条件与我的 Github 库中的相同。所以继续克隆我的库吧。

git clone [https://github.com/miki998/pet_recognition](https://github.com/miki998/pet_recognition)

一旦你完成了下载,你将不得不获得一些额外的文件,不幸的是,由于其大小,我不能上传到 git。你要问我,我会通过谷歌驱动器与你分享链接。

将它们放在下面的文件夹中。/暗/重。仔细检查你是否符合所有要求,(requirements.txt)。好了,你现在可以走了。

标准运行

假设所有的,如果一切都按顺序,你只需要把你想让模型记住/认出的宠物的图像放进去。然后

python3 train.py -<arguments>

当你简单地运行 python3 train.py 时,参数将被解释。

如果你想添加更多的宠物(如猫或狗)让模型识别,那么就分别训练它们,并以递增的方式(也就是说,一个接一个,你可以添加同一宠物的多个图像)

认出一只宠物

python3 recog.py -<arguments>

当你简单地运行 python3 train.py 时,参数将被解释。

Docker 容器运行(首选方法)

这些命令与前面的命令类似,只需在开始之前执行以下操作(使用您应该预先构建的映像启动一个容器,您可以在存储库中的 README.md 中找到相关说明)

docker run -it -p 9999 --ipc=host <docker-image-name>

注意是您在构建映像时给它起的名字。

3]示例和结果

首先,我们支持的两种宠物(猫和狗)的不同训练检测的一批例子

我们有眼睛检测:

(自己的形象)

身体检测:

(自己的形象)

人脸检测:

(自己的形象)

在对 7 种不同的宠物进行识别模型训练(即 lbph 特征创建和存储)后(我们没有测试出识别的极限,请注意,我们在相似的环境中测试了所有宠物),以下是我的首选宠物!

(自己创建的 gif)

4]未来的改进

我们对有限的一组宠物进行了“某种”实时识别(因为我们将它用于家庭宠物的产品上,这显然限制了我们需要识别的宠物的范围),通过一些实时技巧,包括不从视频中捕捉所有时间的图像或降低分辨率或使用功率过大的芯片(我不负责这一部分)。我们仍在尝试改进识别部分,因为在数量上有明显的限制(权重的大小至少与宠物的数量成线性增加),涉及自动人脸标志的其他特征加上大规模微分同胚注册可以帮助标准化人脸,并且找到其他特征也可以有所帮助(即行为,因为我们有身体检测)。在检测部分,可以做大量的事情,例如,用 EfficientDet 和 TensorRT 进行替换,当我们进行第一次人体检测时,通过图像分割进行并行化。

结论

感谢您的阅读,如果您喜欢或发现这篇文章有用,请在 medium 和 GitHub 上关注我的更多项目。

[## 陈宸-中等

阅读媒体上的陈宸作品。数据驱动投资者主网站作家数学和计算机科学理学士…

medium.com](https://medium.com/@michaelchan_2146)

深度学习研究和如何沉浸其中

原文:https://towardsdatascience.com/deep-learning-research-and-how-to-get-immersed-8bab98c20577?source=collection_archive---------36-----------------------

所以你有兴趣了解更多关于深度学习的研究,但你还没有机会在研究实验室工作。也许你刚刚完成了一个在线课程或训练营,或者你只是对这个领域的最新发展感到好奇。你从哪里开始?

如果你不确定你是否想专注于阅读研究论文,保持与新研究保持一致的最简单的方法之一是订阅一份时事通讯或邮件列表来整理内容。一些例子是分析调度(针对数据科学文章——较少关注研究,更多关注应用)或机器学习(关注关于人工智能和机器学习的新闻文章)。

如果你更喜欢视觉学习,你可能会对两分钟论文感兴趣,这是一个 YouTube 频道,它将科学研究浓缩成动画短片,展示他们的核心概念。由于媒体的性质,它通常围绕着一个演示,如果你对新研究的应用更感兴趣,这是完美的。

阅读报纸

用批判的眼光看待论文是很重要的。与对该材料更有经验的人讨论论文的内容,可以帮助你抓住细微差别和重点学习的领域。

此外,不要从表面上看论文讨论的内容,而要考虑论文的结构和背景。

  • 这个领域最大的未解问题是什么?
  • 结果什么时候有用,为什么有用?
  • 研究的限制是什么?
  • 这些见解可以转移到其他领域吗?
  • 为什么有些想法得到了更广泛的传播,而另一些却不了了之?
  • 作者在论文中没有讨论什么?

至少在深度学习领域,有些论文更侧重于理论,有些论文更侧重于实现。就你可能想要如何对待自己的兴趣和工作而言,从实现开始可能更容易,因为这些论文的效果更具体。

不管你以前是否读过论文,回忆一下如何阅读论文的过程可能会有所帮助。从阅读导言开始,而不是摘要。通常,摘要会让你对报纸上的真实内容产生偏见。确保你理解了大背景,以及这篇论文如何适应其领域的更大范围。确定背景的要点,以及研究背后的问题,然后找出方法。

在这一点上,你可能想阅读全文,密切关注方法和结果。弄清楚结论和摘要是如何与你在纸上的想法联系起来的,然后弄清楚其他人对此有什么看法。这最后一步是可选的,因为你手头可能不会立即有文献评论,但知道作者的同行是否支持他们的结果是有帮助的。

策划文件

计算机科学最佳论文奖根据各个领域的顶级会议,收集各个研究领域的年度论文。例如,有些论文获得了 AAAI 大学(人工智能)和 ICML 大学(机器学习)的“杰出论文奖”或“杰出论文奖”。

我们喜爱的论文是一个由计算机科学家和研究爱好者组成的社区,他们为计算机科学的所有学科收集顶级论文。该小组主持以城市为基础的分会会议,并就某些论文发表演讲。

费马的图书馆是寻找注释论文的绝佳资源——有点像来自一个论文阅读俱乐部的异步见解。他们专注于所有科学研究领域的论文,尽管他们也有一个按研究领域分类的过去论文列表(包括计算机科学)。最重要的是,他们有一份时事通讯,每周发送一份新的论文,里面有从简单的解释到 gif 的令人敬畏的评论。

蒸馏是一个关于机器学习研究的视觉解释的在线杂志。该出版物旨在以更加透明和可视化的方式交流研究,在论文中嵌入了交互式小部件、代码片段和动画。

令人敬畏的深度学习论文有点过时(上次更新是在两年前),但它确实列出了 2012 年至 2016 年被引用最多的论文,按学科排序,如卷积神经网络模型、优化技术、对象检测和强化学习。

由 UMass Amherst 教授 Emery Berger 创建的 CS 排名是一个很好的资源,可以查看由出版物和顶级教师排名的研究机构。您可以搜索计算机科学学科,包括人工智能、机器学习、自然语言处理和计算机视觉,以找到每个学科的顶级会议和期刊。

结束语

发表的论文肯定比你能读的要多得多,所以挑战的一部分是确保你读的是你感兴趣的或者可能对你的工作有帮助的论文。如果你已经在某个领域工作了,并且有同事,那就去寻求书面的推荐信。否则,如果有机会参加座谈会和讲座,一定要查看一下发言人名单,他们的见解可能与你的工作一致。

也有可能建立或加入一个读报小组——如果你有一个可以讨论的社区,你总能从报纸中获得更多。

还有什么建议吗?把它们留在下面的评论里吧!

用于研究聚糖介导的宿主-微生物相互作用的深度学习资源

原文:https://towardsdatascience.com/deep-learning-resources-for-studying-glycan-mediated-host-microbe-interactions-ab11b8621f4b?source=collection_archive---------55-----------------------

一个关于糖、细菌和人类健康的故事

莎伦·麦卡琴在 Unsplash 上的照片

生物学家非常熟悉 DNA、RNA 和蛋白质——正如我们所知,这三种生物序列使生命成为可能。不太熟悉的(尽管至少同样重要)是多聚糖或复杂碳水化合物。这些各种糖(或技术上称为单糖)的链可以单独存在,例如构成细菌、真菌以及植物细胞的荚膜,或者修饰各种其他生物分子,如蛋白质、脂质或 RNA。与蛋白质物理连接的特定聚糖序列从根本上改变了蛋白质的性质和功能,微调了稳定性、结构和功能。这导致了令人难以置信的复杂相互作用的混杂,进而产生了我们所知的极其复杂的现象,即生命。它确实非常复杂,因为聚糖拥有数百种单糖,相比之下,蛋白质只有区区 20 个氨基酸,DNA 只有 4 个核苷酸。

此外,聚糖不仅是唯一的非线性生物序列(导致分子具有多个分支),而且是唯一的非模板序列,是通过密切依赖于细胞当前状态的几十种专门酶的相互作用而产生的。所有这些使聚糖成为最多样化的生物序列,也是最动态的序列,能够在没有基因突变的情况下即时调整序列。最重要的是,从炎症到癌症,多聚糖与基本上所有人类疾病都有关联。因此,鉴于这一切,你会认为一个名副其实的研究大军将致力于解开聚糖在生物学各个方面的作用,对吗?结果……不完全是这样。

这是细胞实际上看起来的样子…被聚糖覆盖着。

虽然有一个名为“糖生物学”的研究领域,但与它们的相关性相比,聚糖在生命科学中的突出地位仍然微不足道。尽管深度学习最近彻底改变了对其他复杂生物序列的分析,如蛋白质RNA ,但聚糖迄今仍未被机器学习所捕获。其原因主要在于它们的非线性,这阻止了为线性序列开发的标准自然语言处理工具的应用。然而,我们相信,作为最多样和最复杂的生物聚合物,多聚糖将从最先进的深度学习技术中受益最多,这些技术最终可以促进从序列到功能的映射,并允许对糖生物学采取全面的方法。这就是为什么在我们最近发表在杂志细胞宿主&微生物上的工作中,我们开发了第一个多聚糖的语言模型,我们称之为 SweetTalk。

我们工作的概述。doi:10.1016/j . chom . 2020 . 10 . 004

当然,在此之前,我们必须收集数据。我们收集了尽可能多的聚糖序列,并将所有 19,299 个聚糖序列收集在我们自己的数据库 SugarBase 中。当时,SweetTalk 由一个具有长短期记忆(LSTM)单元的双向递归神经网络(RNN)组成。基本上,我们训练 SweetTalk 通过预测前面给出的糖链中的下一个单糖或键(我们定义为糖链)来学习糖链中的序列依赖性。这为我们提供了一个训练有素的多聚糖语言模型,以及我们可以用于可视化目的的每个乙醇字母的学习表示。为了避免聚糖序列的非线性性质,我们通过从聚糖序列中提取“糖字”来处理序列,聚糖序列是由五个字母组成的集合,为 SweetTalk 提供了学习正确的字母之间的上下文关系的机会。在的论文相关的 预印本中,我们对学习到的聚糖表达进行了大量分析,并开发了聚糖比对算法,但我想在这里重点介绍我们的分类器,所以如果你想了解更多关于聚糖嵌入的信息,请随意阅读论文。

由于我们肠道的整个内层都覆盖着聚糖(粘液中的粘蛋白),每个细胞表面也都覆盖着聚糖(包括肠道细菌),我们推断,我们的微生物组(或病原体)和我们之间的相互作用可能为我们的方法提供了一个有前途的应用领域。这一点尤其重要,因为研究表明,一些细菌模仿我们的聚糖来欺骗我们的免疫系统。因此,我们想看看我们能否预测特定的聚糖是否会被人类免疫系统识别。为此,我们在标记了免疫原性的聚糖的较小数据集上微调了我们预先训练的 SweetTalk 模型,并实现了超过 90%的准确率,优于随机森林等其他机器学习方法。这项分析支持了分子模拟的概念,与人类聚糖相似的细菌聚糖具有较低的免疫原性得分。我们还成功训练了准确率接近 90%的分类器,用于纯粹根据聚糖预测常见细菌大肠杆菌菌株的致病性,这清楚地支持了我们的假设,即聚糖可以提供致病性等特性的信息。重要的是,我们甚至可以识别出似乎最能预测致病性的序列基序,再次强烈地指向聚糖的分子模拟。我们做的另一个有趣的观察是,尽管使用了致病性的二元标签,我们的模型预测了致病性的连续性,反映了致病性对环境条件的依赖性,并支持早期关于这一现象的报道

我们的基准任务&模型 SweetOrigins。doi:10.1016/j . chom . 2020 . 10 . 004

最后,我们解决了与高维数的聚糖序列相比缺乏数据的紧迫问题。虽然我们使用无监督语言模型的迁移学习方案已经改善了模型结果,但我们开始设计一种数据增强方案,以进一步提高以聚糖为中心的机器学习的效率。为此,我们设计了一个多类基准问题,我们称之为 SweetOrigins:预测给定聚糖序列来自哪个分类组。这代表了一系列的困难,从预测四个分类领域中的一个到预测成百上千个物种中的一个。对于我们的数据扩充方法,我们利用了众所周知的用于聚糖序列的模糊符号,括号表示分支。这个明显的缺点允许我们为同一聚糖分子制定不同的括号符号字符串,有效地扩大了我们的序列数量。这使得我们的模型更加健壮,并且确实在我们的基准测试任务中显著提高了性能,对于最困难的任务,绝对精度提高了 6%。

以聚糖为中心的机器学习的数据扩充。doi:10.1016/j . chom . 2020 . 10 . 004

我们预计,我们开发的基准任务可以用于继续改善以聚糖为中心的机器学习,以解决聚糖在其中发挥重要作用的大量潜在应用。类似于以蛋白质为重点的机器学习对蛋白质工程和全新设计蛋白质的设计的影响,我们相信,以聚糖为重点的机器学习可以在不久的将来以类似的效果提升糖工程。

如果你想了解更多,这里有论文相关 预印本的链接。此外,这里有一些易于理解的新闻文章,介绍哈佛大学 Wyss 生物工程研究所和 Branco Weiss Fellowship-Society in Science 项目的工作。当然,这里是 GitHub 上的代码和我们在 SugarBase 上的数据。如果您对以聚糖为中心的机器学习感兴趣,请随时联系我们!

基于三维贝叶斯卷积神经网络的不确定性深度学习分割

原文:https://towardsdatascience.com/deep-learning-segmentation-with-uncertainty-via-3d-bayesian-convolutional-neural-networks-6b1c7277b078?source=collection_archive---------25-----------------------

神经网络如何学习概率分布来量化其预测中的不确定性?

我们的贝叶斯卷积神经网络(BCNN)在材料数据集的不确定性量化方面击败了以前的最先进的结果。请注意,BCNN 不确定性地图捕捉连续性和视觉梯度,而 MCDN 不确定性地图是像素化和不可解释的。

论文:https://arxiv.org/abs/1910.10793】T2

https://github.com/sandialabs/bcnn】代号:

关键要点:

测量不确定性在常规的深度神经网络中是不可能的,但是对于可解释性和有效性是极其重要的

贝叶斯神经网络学习概率分布而不是点估计,允许它们测量不确定性

我们为 3D 分割设计了第一个成功的贝叶斯卷积神经网络(BCNN)架构

我们的 BCNN 在不确定性量化方面击败了当前最先进的神经网络,同时实现了相同或更好的分割精度

我们的学术论文和完整的开源代码实现可在线获得

简介

C 考虑这个场景:某飞机制造公司为商用飞机生产安全关键的发动机零件。由于必须保证发动机零件能够工作,该公司在长达数月的艰苦过程中验证了每一个零件,他们对零件进行 3D CT 扫描,手工注释数亿个体素,并使用注释扫描来分析零件的缺陷。

丹尼尔·埃勒杜特在 Unsplash 上拍摄的照片

这既不省时也不划算,因此该公司雇佣了一个数据科学家团队来设计一个深度神经网络,该网络使用最先进的体积分割技术自动验证零件。神经网络看似成功,但有一天由神经网络验证的零件在使用过程中莫名其妙地出现故障,导致飞机发动机故障,并导致数百人死亡和公司数十亿美元的损失。

那么是哪里出了问题呢?嗯,深度神经网络以做出准确的预测而闻名,但它们最大的弱点之一是缺乏测量预测中不确定性的能力。因此,深度学习系统没有能力区分 100%认证的部分和勉强合格的部分。

人们可能认为 sigmoid 输出的值可用作不确定性的度量,但这不是真的,因为这些值取决于推断样本是否“接近”训练分布。如果根据远离训练分布的样本(即,其中有缺陷的零件)进行推断,则 sigmoid 输出不能用作模型不确定性的代理。

换句话说,当测试集与训练集“相似”时,深度神经网络的性能最佳;换句话说,测试集中可能存在神经网络不确定的示例,因为没有类似的训练示例。但由于没有“我不知道”的输出可用,有缺陷的零件最终可能会被深度学习系统验证并转移到生产中。

图像分割如何在实践中导致不良预测,以及贝叶斯神经网络生成的不确定性图的分析如何有助于决策。

这个例子说明了深度神经网络中不确定性量化的至关重要性,其研究和开发在过去五年中飞速发展。最近的技术铸造神经网络,通常逐点估计,作为概率或贝叶斯模型。用于此目的的两种最常见的神经网络架构是蒙特卡洛漏失网络(MCDNs)和贝叶斯卷积神经网络(BCNNs)。

mcdns 使用漏失层来近似深高斯过程,虽然易于实现,但是它们的统计可靠性已经被称为 question⁹.BCNNs 使用变分推理来学习给定数据集的权重的后验分布,并且更加难以实现,但是给出了大大改善的不确定性结果。

已经假定,用于大问题的贝叶斯神经网络,包括在 3D 图像分割空间中,由于过高的计算成本而不可行。在这里,我们反驳了这种说法,并首次成功实现了用于体积分割中不确定性量化的 3D BCNN,详细说明了它是如何工作的,并解释了开源代码库的一些部分。

特别地,与 MCDNs 相比,这种新颖的神经网络架构提供了改进的不确定性量化,同时实现了相等或更好的分割精度。通过对电池电极和激光焊接金属的 CT 扫描的实验,我们表明由 BCNN 产生的不确定性图捕获连续性和视觉梯度,使它们可解释为分割的置信区间。

BCNN 概况

虽然大多数神经网络学习其权重的逐点估计,但更严格的观点是,这些估计并没有完全包含权重值中固有的不确定性。相反,在 BCNN 中,每个权重都被隐式描述为(多元)概率分布。

典型与贝叶斯神经网络中的权重表示

将神经网络的权重描述为概率分布有几个结果。首先,它使神经网络具有不确定性;每次我们计算向前传递时,我们必须从每个重量分布中取样,以获得可用于推断的点估计。重复应用这种抽样技术,称为蒙特卡罗抽样,将产生不同的预测,然后可以分析不确定性。第二,它改变了反向传播算法,因为我们不能通过采样操作反向传播(它没有梯度)。在后面的部分中,我们将讨论如何使用 Bayes by Backprop 算法来解决这个问题。最后,这使得神经网络更加难以可靠地训练,尤其是在 3D 中,并且容易受到消失/爆炸梯度的影响。我们使用一种称为组规范化的巧妙的规范化技术来解决这个问题,这也将在后面的部分中详细介绍。

贝叶斯学习

我们如何准确地得到权重的分布?嗯,在一个完美的世界里,我们可以用贝叶斯法则精确地计算它们。为此,我们将从权重的先验分布开始;这是我们对体重分布的“初步猜测”。表示为 p(w) ,一般为标准正态分布。然后,我们将使用我们的数据来计算给定数据集的权重的后验分布,表示为 p(w|D) 。这相当于找到一个 w ,它在给定这些权重的情况下最大化数据集的可能性,表示为 p(D|w) ,我们可以通过贝叶斯规则来执行此计算:

然而,由于在神经网络中发现的极端过度参数化,分母中的积分通常是难以处理的。所以,我们需要学习后验分布,而不是精确地计算它。辛顿、范·camp⁵和 Graves⁴之前的工作提出了变分学习(也称为变分推断)作为一种近似后验分布的方法。变分学习通过变分自由能代价函数 F 的最小化,找到分布 p(w|θ) 的参数 θ ,称为变分分布,通常称为期望下界(ELBO)。

变分自由能由 Kullback-Leibler (KL)散度和负对数似然性之和组成,前者衡量先验分布和变分分布之间的距离,后者衡量模型的拟合优度。布伦德尔等人 将变分自由能损失函数解释为满足简单先验(由 KL 项表示)和满足数据集复杂性(由 NLL 项表示)之间的折衷:

我们训练神经网络的时间越长,我们就越接近最小化这个成本函数,我们的变分分布就越接近真实的后验分布。在实践中,KL 项对神经网络的输出具有正则化效果,以训练集中较低的 NLL 项为代价,防止学习的分布过度拟合。

单重变分自由能损失函数下的训练可视化

该损失函数可通过如下缩放小批量 i 的成本来服从小批量优化,本质上在整个数据集上展开 KL 散度损失:

如果在张量流概率中实现贝叶斯神经网络,下面是变分自由能损失的有效 Python 实现(注意,二进制交叉熵只是否定 NLL):

from tensorflow.keras.losses import binary_crossentropydef vfe_loss(model, dataset_size, batch_size, alpha=1):
    """Defines variational free energy loss. 
       Sum of KL divergence and binary cross-entropy."""

    # KL Divergence should be applied once per epoch only.
    kl = sum(model.losses) / (dataset_size / batch_size) def loss(y_true, y_pred):
        bce = binary_crossentropy(y_true, y_pred)
        return alpha * kl + (1\. / alpha) * bce return loss

贝叶斯学习的挑战

变分贝叶斯学习通常被认为在统计上比例如通过丢失 layers⁹.的近似贝叶斯推断更合理然而,这是以一些计算挑战为代价的。

首先,从分布中采样的随机变量没有梯度,因此贝叶斯神经网络似乎与反向传播不兼容。然而,金马等人 ⁶表明,将随机变量重新参数化为确定性变量进行计算是可能的。作为一个例子,假设从具有平均值 μ 和方差 σ 的正态分布中采样一个权重 w 。那么,有效的重新参数化是 w=μ+σϵ ,其中 ϵ 是从标准正态分布采样的辅助噪声变量。现在,代替采样操作,我们有一个仿射组合,它很容易在反向传播中使用。需要更复杂的计算来有效地缩放该计算;详见金玛的论文。这通常被称为局部重新参数化技巧

局部重新参数化技巧的可视化,从

接下来,贝叶斯学习以前被认为在计算上是不可行的,因为如果使用集成方法训练,需要大量的权重更新。为了解决这个问题,Blundell 等人设计了贝叶斯反推算法。先前的工作集中于训练随机隐藏单元,但是权重比隐藏单元容易多两个数量级,并且 Backprop 的 Bayes 是第一个在神经网络中有效训练概率权重的算法。Bayes by Backprop 通过使用反向传播中计算的梯度来“缩放和移动”后验的变化参数,从而以最小的额外计算更新后验。

由于 3D 训练量可能非常大,我们的批处理大小受到可用 GPU 内存量的限制,导致批处理大小太小,无法进行批处理标准化来准确计算批处理统计数据。因此,我们使用一种由吴和何提出的称为组归一化的技术,该技术将通道组归一化,并且显示出具有与批量大小无关的精确性能。观察到适当的标准化是我们模型收敛的关键因素,因为它有助于避免消失/爆炸梯度;通过调整组标准化图层中使用的组数,我们发现当使用 4 个组时,BCNN 收敛最可靠。

群体规范化的可视化,从到这里

最后,与概率权重相关的一个挑战是,小批量中的所有样本通常具有相似的采样权重,这限制了大批量的方差减少效果。上面提到的局部重新参数化 trick⁶的一个副作用是,它通过将全局权重不确定性转化为小批量样本中的独立局部噪声,极大地降低了随机采样权重的方差。同样,Wen 等人提出了 Flipout 估计量,该估计量通过对每个样本伪独立地采样权重,根据经验实现了理想的方差减少。一个重要的区别是,本地重新参数化只对全连接网络有效,而 Flipout 可以有效地用于全连接、卷积和递归网络。

BCNN 建筑

O ur 3D BCNN 架构利用 V-Net⁷和 3D U-Net 中常见的编码器-解码器设置,从图像分割文献中提取,3D u-net 是最初分别用于人类前列腺和青蛙肾脏的 3d 分割的深度神经网络。在这种架构中,网络的编码器部分(左)将输入压缩到潜在空间中,而解码器部分(右)将输入的潜在表示解压缩到分段图中。

我们的 BCNN 建筑示意图,包括体积尺寸样本。尺寸为(深度、高度、宽度、通道)。

BCNN 的编码器部分使用典型的 3D 卷积来最大化原始音量和潜在空间之间的信息传输,但是网络的解码器部分使用 3D 贝叶斯卷积层。这些中的每一个都用标准的正态先验来初始化,并采用前述的翻转估计器来近似正向传递期间的分布。请注意黄色的跳过连接,它有助于整个网络的功能转发。我们的实现利用了包含在张量流概率中的贝叶斯层库⁰,其跟踪表示层的后验分布相对于其先验的 KL 散度的损失,并使得计算变化的自由能损失变得简单。

这个 BCNN 架构的实现可以在https://github . com/Sandia labs/bcnn/blob/master/Bayesian _ vnet . py获得。

训练注意事项

在实践中,唱 BCNN 带来了一些难以有效实现的特性。首先,目前不可能保存组合了 Keras 层和 Bayesian 层的模型的架构和权重。相反,必须只保存权重,然后将它们加载到实例化的架构中。当模型被指定为多 GPU 时,情况会变得更糟,这在处理许多 3D 数据集时实际上是必要的。当多 GPU 模型仅保存为权重时,很难重新加载模型,因为神经网络体系结构期望导入单 GPU 权重。一个巧妙的解决方案是通过提取多 GPU 模型中倒数第二层的权重,将多 GPU 权重重新保存为单 GPU。以下代码提供了一个示例:

from tensorflow.keras.utils import multi_gpu_model# Assumes the BCNN architecture is defined in the model file.
from model import bcnndef load_model(input_shape, weights_path, num_gpus):
    """Loads model from .h5 file. If model is
       saved as multi-gpu, re-saves it as single-gpu.""" # Loads model as multi-gpu, if possible.
    try:
        model = bcnn(input_shape)
        model = multi_gpu_model(model, gpus=num_gpus) # Converts .h5 file to single-gpu.
        model.load_weights(weights_path)
        model = model.layers[-2]
        model.save_weights(weights_path) except ValueError as e:
        pass # Loads single-gpu model.
    model = bcnn(input_shape)
    model.load_weights(weights_path) # Converts to multi-gpu model if applicable.
    if num_gpus > 1:
        model = multi_gpu_model(model, gpus=num_gpus) return model

此外,3D 数据集管理可能会变得非常迅速。许多 CT 和 MRI 扫描的尺寸可以是 1000 x 1000 x 1000 甚至更大,这是不可能一次对所有的进行推断的。相反,需要一种“分块”技术,将大量数据分成重叠的数据块,然后输入 BCNN。然后,在组块上训练神经网络,并预测相同大小的组块,可以通过反转组块过程来重建这些组块,以获得完全推断的完整体积。

分块过程包括以一定的重叠比例(称为“步长”)穿过原始体积的滑动矩形棱柱“窗口”。我们必须小心避免一个接一个的错误,我们还需要保存每个块的坐标,以便在重建过程中使用。该算法的输出是一个巨大的 5D 数数组,它包含数据集中的所有组块。此外,有一个 Keras bug ,每当一个 epoch 中的最后一批不能在所有 GPU 之间划分时,它都会导致错误;避免这个错误需要截断数组的末尾。

这个算法的一个实现在这里的“块”方法中:【https://github.com/sandialabs/bcnn/blob/master/dataset.py

计算 BCNN 预测和不确定性

因为 BCNNs 是不确定的,所以当对一个组块进行多次预测时,人们将获得许多不同的(并且可能非常错误的)预测。为了获得准确的预测以及不确定性图,我们必须对每个块进行多次预测,以获得 sigmoid 值的分布。这被称为蒙特卡罗抽样。这个过程是高度可定制的,但是这里我们将分割表示为所有 sigmoid 值的平均值(对于二进制分割,转换为 0 和 1),不确定性映射表示为第 20 个和第 80 个百分点之间的差。

关键的是,分块重建过程可能导致输出分割体积中的严重伪像。这是因为神经网络没有足够的空间上下文来有效地预测每个块的边缘;相反,我们丢弃了每个块周围的某个百分比(大约 5%),以确保我们只保留合理的预测。

这个算法的一个实现在这里的“预测”方法中:https://github.com/sandialabs/bcnn/blob/master/test.py

验证和结论

BCNN 是体积分割不确定性量化的最新技术;特别是,我们使用锂离子电池石墨电极和激光焊接金属接头的 CT 扫描验证了 BCNN。与先前优越的 MCDN 相比,BCNN 提供了大大改进的不确定性图,同时实现了相等或更好的分割精度。下面是我们论文中的一个样本图像,它突出了 BCNN 不确定性图的连续性和视觉梯度,而 MCDN 生成了一个无法解释的逐点不确定性图。

此外,我们采用了帕夫普 metric⁸,一种最近设计的验证不确定性结果的方法,并发现在编码不确定性和准确性之间的关系时,BCNN 始终并大大优于 MCDN。参见我们在https://arxiv.org/pdf/1910.10793.pdf的论文,深入分析和验证 BCNN 及其相对于 MCDN 的优势,并在https://github.com/sandialabs/bcnn随意使用和分叉开源代码库。虽然我们的新颖贡献是在 3D 空间中,但是我们也为典型的图像分割提供了 2D 实现。

参考

[1]查尔斯·布伦德尔、朱利安·科尔内比斯、科雷·卡武克库奥卢和金奎大·威斯特拉。神经网络中的权重不确定性。2015 年第 32 届机器学习国际会议论文集。【https://arxiv.org/abs/1505.05424

[2]奥兹冈·希切克、艾哈迈德·阿卜杜勒卡迪尔、苏伦·s·连坎普、托马斯·布罗克斯和奥拉夫·龙内贝格。3d u-net:从稀疏注释中学习密集体积分割。2016 年第 19 届国际医学图像计算和计算机辅助介入会议论文集。https://arxiv.org/abs/1606.06650

[3]亚林·加尔和邹斌·格拉马尼。作为贝叶斯近似的辍学:表示深度学习中的模型不确定性。2016 年第 33 届机器学习国际会议论文集。https://arxiv.org/abs/1506.02142

[4]亚历克斯·格雷夫斯。神经网络的实用变分推理。2011 年第 24 届神经信息处理系统进展会议论文集。https://papers . nips . cc/paper/4329-神经网络的实用变分推理

5 杰弗里·e·辛顿和德鲁·范·坎普。通过最小化权重的描述长度来保持神经网络的简单性。《第 16 届学习理论会议论文集》,1993 年。https://www.cs.toronto.edu/~hinton/absps/colt93.html

[6]迪德里克·p·金马、蒂姆·萨利曼斯和马克斯·韦林。变分丢失和局部重新参数化技巧。2015 年第 28 届神经信息处理系统进展会议论文集。https://arxiv.org/abs/1506.02557

[7] Fausto Milletari、Nassir Navab 和 Seyed-Ahmad Ahmadi。V-net:用于体积医学图像分割的全卷积神经网络。2016 年第四届 3D 视觉国际会议论文集。https://arxiv.org/abs/1606.04797

[8]吉什努·穆克霍蒂和亚林·加尔。评估用于语义分割的贝叶斯深度学习方法。arXiv 预印本 1811.12709,2019 年。【https://arxiv.org/abs/1811.12709

[9]伊恩·奥斯本。深度学习中的风险与不确定性:贝叶斯、自助和辍学的危险。《第 29 届神经信息处理系统进展会议论文集:贝叶斯深度学习研讨会》,2016 年。https://pdfs . semantic scholar . org/DDE 4/b95be 20 a 160253 a 6 cc 9 ECD 75492 a 13d 60 c 10 . pdf

[10]达斯汀·特兰、迈克尔·w·杜森伯里、马克·范德维尔克和达尼亚尔·哈夫纳。贝叶斯层:神经网络不确定性的模型。2019.https://arxiv.org/abs/1812.03973

[11]叶明·温、保罗·维科尔、吉米·巴、达斯汀·特雷恩和罗杰·格罗斯 Flipout:小批量的有效伪独立重量扰动。2018 年第六届国际学习表征会议论文集。https://arxiv.org/abs/1803.04386

[12]吴雨欣和明凯·何。群体规范化。2018 年欧洲计算机视觉会议论文集,2018。https://arxiv.org/abs/1803.08494

资金报表

这项工作是在作者在桑迪亚国家实验室实习期间完成的。桑迪亚国家实验室是一个多任务实验室,由霍尼韦尔国际公司的全资子公司桑迪亚国家技术和工程解决方案有限责任公司根据合同 DE-NA0003525 为美国能源部国家核安全局管理和运营。2020 年至 1419 年

深度学习并驾齐驱:Julia v.s. Python

原文:https://towardsdatascience.com/deep-learning-side-by-side-julia-v-s-python-5ac0645587f6?source=collection_archive---------7-----------------------

你能说出哪一种是未来的语言吗?

SuperRGBUnsplash 上拍摄的照片

Julia 可能是 Python 最大的威胁。对于各种应用程序来说,Julia 无疑比 Python 更快,几乎和 C 语言一样快。Julia 还提供了多分派和元编程等特性,这些特性让它比 Python 更有优势。

与此同时,Python 被建立,被广泛使用,并拥有各种经过时间考验的包。切换到朱莉娅的问题是一个很难解决的问题。通常答案是令人沮丧的,“看情况”。

为了帮助展示 Julia 并解决是否使用它的问题,我从两种语言中提取了深度学习代码的样本,并将它们串联起来以便于比较。我将在 CIFAR10 数据集上训练 VGG19 模型。

模型

照片由汤姆·帕克斯Unsplash 上拍摄

深度学习模型可能非常庞大,通常需要大量的工作来定义,尤其是当它们包含像 ResNet [1]这样的专门层时。我们将使用一个中等大小的模型(没有双关的意思),VGG19,来进行比较[2]。

Python 中的 vgg 19

我选择 Keras 作为我们的 Python 实现,因为它的轻量级和灵活的设计与 Julia 具有竞争力。

from keras.models import Sequential
from keras.layers import Dense, Conv2D, MaxPool2D , Flattenvgg19 = Sequential()
vgg19.add(Conv2D(input_shape=(224,224,3),filters=64,kernel_size=(3,3),padding="same", activation="relu"))
vgg19.add(Conv2D(filters=64,kernel_size=(3,3),padding="same", activation="relu"))
vgg19.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
vgg19.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
vgg19.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
vgg19.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
vgg19.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
vgg19.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
vgg19.add(Flatten())model.add(Dense(units=4096,activation="relu"))
vgg19.add(Dense(units=4096,activation="relu"))
vgg19.add(Dense(units=10, activation="softmax"))# Code from [Rohit Thakur](https://github.com/1297rohit) on [GitHub](https://github.com/1297rohit/VGG16-In-Keras)

这里的任务是连接 21 层深度学习机器。Python 很好地处理了这一点。语法简单易懂。虽然.add()函数可能有点难看,但它的作用是显而易见的。此外,代码中很清楚每个模型层做什么。(卷积、合并、扁平化等..)

茱莉亚中的 vgg 19

using Fluxvgg16() = Chain(            
    Conv((3, 3), 3 => 64, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 64 => 64, relu, pad=(1, 1), stride=(1, 1)),
    MaxPool((2,2)),
    Conv((3, 3), 64 => 128, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 128 => 128, relu, pad=(1, 1), stride=(1, 1)),
    MaxPool((2,2)),
    Conv((3, 3), 128 => 256, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 256 => 256, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 256 => 256, relu, pad=(1, 1), stride=(1, 1)),
    MaxPool((2,2)),
    Conv((3, 3), 256 => 512, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 512 => 512, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 512 => 512, relu, pad=(1, 1), stride=(1, 1)),
    MaxPool((2,2)),
    Conv((3, 3), 512 => 512, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 512 => 512, relu, pad=(1, 1), stride=(1, 1)),
    Conv((3, 3), 512 => 512, relu, pad=(1, 1), stride=(1, 1)),
    BatchNorm(512),
    MaxPool((2,2)),
    flatten,
    Dense(512, 4096, relu),
    Dropout(0.5),
    Dense(4096, 4096, relu),
    Dropout(0.5),
    Dense(4096, 10),
    softmax
)# Code from [Flux Model Zoo on Github](https://github.com/FluxML/model-zoo/blob/master/vision/cifar10/cifar10.jl)

讨论

乍看之下,Julia 看起来没有 Python 那么杂乱。导入语句更简洁,代码更容易阅读。和 Python 一样,每一层做什么都很清楚。Chain类型有点不明确,但是很明显它将各层连接在一起。

需要注意的是没有模型类。事实上,Julia 不是面向对象的,所以每一层都是类型而不是类。这一点值得注意,因为它强调了 Julia 模型是非常轻量级的。这些层中的每一层都是独立定义的,然后链接在一起,没有任何类结构来控制它们如何交互。

然而,在训练巨型模型时,避免一点混乱并不重要。Python 的优势在于它对故障排除和解决 bug 有大量的支持。文档非常好,网上有数百个 VGG19 示例。相比之下,Julia 在网上有五个独特的 VGG19 例子(也许)。

数据处理

桑德罗·卡塔琳娜Unsplash 拍摄的照片

对于数据处理,我们将查看通常与 VGG19 相关联的数据集 CIFAR10。

Python 中的数据处理

from keras.datasets import cifar10
from keras.utils import to_categorical(X, Y), (tsX, tsY) = cifar10.load_data() # Use a one-hot-encoding
Y = to_categorical(Y)
tsY = to_categorical(tsY)# Change datatype to float
X = X.astype('float32')
tsX = tsX.astype('float32')

# Scale X and tsX so each entry is between 0 and 1
X = X / 255.0
tsX = tsX / 255.0

为了根据图像数据训练模型,必须将图像转换成正确的格式。只需要几行代码就可以做到这一点。图像和图像标签一起被加载到变量中。为了使分类更容易,标签被转换成一个热点编码格式。这在 Python 中相对简单。

Julia 中的数据处理

using MLDatasets: CIFAR10
using Flux: onehotbatch# Data comes pre-normalized in Julia
trainX, trainY = CIFAR10.traindata(Float64)
testX, testY = CIFAR10.testdata(Float64)# One hot encode labels
trainY = onehotbatch(trainY, 0:9)
testY = onehotbatch(testY, 0:9)

Julia 需要与 Python 相同的图像处理来为训练过程准备图像。这些代码看起来极其相似,而且似乎不支持任何一种语言。

培养

照片由 Zii MillerUnsplash 上拍摄

接下来,我们将查看模型训练循环。

Python 培训

optimizer = SGD(lr=0.001, momentum=0.9)
vgg19.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
history = model.fit(X, Y, epochs=100, batch_size=64, validation_data=(tsX, tsY), verbose=0)

茱莉亚的培训

using Flux: crossentropy, @epochs
using Flux.Data: DataLoadermodel = vgg19()
opt = Momentum(.001, .9)
loss(x, y) = crossentropy(model(x), y)
data = DataLoader(trainX, trainY, batchsize=64)
@epochs 100 Flux.train!(loss, params(model), data, opt)

这里的代码同样冗长,但是不同语言之间的差异显而易见。在 Python 中,model.fit返回包含准确度和损失评估的字典。它也有关键字参数来自动优化过程。朱莉娅更瘦了。训练算法要求用户提供他们自己的损失函数、优化器和包含批量数据的迭代程序以及模型。

Python 实现更加用户友好。培训过程很容易,并产生有用的输出。Julia 对用户的要求更高一些。同时,Julia 更加抽象,允许任何优化器和损失函数。用户可以以任何方式定义损失函数,而无需查阅内置损失函数列表。这种抽象是 Julia 开发人员的典型特征,他们致力于使代码尽可能的抽象和通用。

由于这个原因,Keras 对于实现已知技术和标准模型训练更实用,但使 Flux 更适合于开发新技术。

速度

弗洛里安·斯特丘克在 Unsplash 上拍摄的照片

不幸的是,互联网上没有比较 Flux 和 Keras 的可用基准。有几个资源给了我们一个思路,我们可以使用 TensorFlow 速度作为参考。

一项基准测试发现,在 GPU 和 CPU 上, Flux 几乎不比 TensorFlow 慢。已经证明 Keras 在 GPU 上也比 TensorFlow 稍慢。不幸的是,这并没有给我们一个明确的赢家,但表明两个包的速度是相似的。

上面的 Flux 基准测试是在 Flux 的自动差异软件包进行重大返工之前完成的。新的软件包 Zygote.jl 大大加快了计算速度。在 CPU上的一个更近的通量基准发现改进的通量比 CPU 上的 TensorFlow 更快。这表明 Flux 在 GPU 上也可以更快,但在 CPU 上获胜并不一定意味着在 GPU 上的胜利。同时,这仍然是 Flux 将在 CPU 上击败 Keras 的好证据。

谁赢了?

两种语言在各个领域都表现出色。两者之间的差异很大程度上是口味问题。然而,每种语言都有两个优势。

Python 的边缘

Python 有一个庞大的支持社区,并提供经过时间考验的库。它是可靠和标准的。Python 中的深度学习要普遍得多。使用 Python 进行深度学习的开发者会很好地融入深度学习社区。

朱莉娅的优势

茱莉亚更干净,更抽象。深度学习代码肯定会更快,改进工作正在进行中。朱莉娅有潜力。Python 中的深度学习库要完整得多,没有那么大的发展潜力。Julia 拥有更丰富的基础语言,在未来可能会有许多新的想法和更快的代码。采用 Julia 的开发人员将更接近编程的前沿,但将不得不处理打造自己的道路。

赢家

深度学习很难,需要大量的故障排除。很难达到目前的精确度。正因如此, Python 赢得了这次比较。Julia 中的深度学习没有对深度学习故障排除的强大在线支持。这可能会使编写复杂的深度学习脚本变得非常困难。Julia 对于很多应用都很优秀,但是对于深度学习,我会推荐 Python。

[## Julia 如何利用多重调度击败 Python

亲自看

medium.com](https://medium.com/swlh/how-julia-uses-multiple-dispatch-to-beat-python-8fab888bb4d8) [## 已经会 Python 了怎么学 Julia

跳到好的方面

towardsdatascience.com](/how-to-learn-julia-when-you-already-know-python-641ed02b3fa7)

参考资料:

[1],何,,,,,,,【用于图像识别的深度残差学习,2016 .

[2]卡伦·西蒙扬,安德鲁·齐泽曼,用于大规模图像识别的极深度卷积网络,国际学习表征会议,2015

深度学习:用 TensorFlow 解决问题

原文:https://towardsdatascience.com/deep-learning-solving-problems-with-tensorflow-3722b8eeccb1?source=collection_archive---------11-----------------------

了解如何解决优化问题,并使用 MNIST 数据集训练您的第一个神经网络!

图片来自 Unsplash

介绍

本文的目标是用 TensorFlow 定义和解决实际用例。为此,我们将解决:

  • 最优化问题
  • 线性回归问题,我们将调整回归直线到数据集
  • 并且我们将结束用 MINST 数据集解决深度学习分类项目的“Hello World”。

优化问题

网飞决定在一栋大楼里放置他们的一张著名海报。营销团队已经决定,广告海报的面积必须达到 600 平方米,上下各 2 米,左右各 4 米。

然而,他们没有被告知该建筑的立面尺寸。我们可以发一封电子邮件给业主,问他,但由于我们知道数学,我们可以很容易地解决它。我们怎样才能知道这座建筑物的尺寸?

按作者分列的数字

该建筑的总面积为:

宽度= 4 + x + 4 = x +8

身高= 2 + y + 2 = y +4

面积=宽度 x 高度= (x + 8)*(y + 4)

并且存在约束: x*y = 600

这允许我们写出一个方程系统:

xy = 600 → x = 600/y

S(y)=(600/y+8)(y+4)= 600+8y+4 * 600/y+32 =632+8y+2400/y

在优化问题中,函数(导数)的斜率信息用于计算其最小值。我们必须使一阶导数等于 0,然后检查二阶导数是否为正。所以,在这种情况下:

S '(y)= 8–2400/y

S''(y) = 4800/y

s '(y)= 0→0 = 8–2400/y→8 = 2400/y→y = 2400/8 = 300→y =sqrt(300)= sqrt(100–3)= sqrt(100)-sqrt(3)= 10-sqrt(3)=17.32(我们舍弃负号,因为它没有物理意义)

在 x 中替换:

x =600/10-sqrt(3)= 60/sqrt(3)= 60-sqrt(3)/sqrt(3)-sqrt(3)= 60-sqrt(3)/3 = 20-sqrt(3)=34.64

至于 y = 17.32 -> S''(y) = 0.9238 > 0,我们找到了最小解。

因此,建筑的尺寸为:

宽度:x + 8 = 42.64 米

高度:y + 4 = 21.32 米

你看到衍生品有多有用了吗?我们只是分析性地解决了这个问题。我们已经能够解决它,因为这是一个简单的问题,但有许多问题,它是非常昂贵的计算来解决他们的分析,所以我们使用数值方法。这些方法之一是梯度下降。

如果我们这次用张量流数值解决这个问题,你觉得怎么样?我们走吧!

import numpy as np
import tensorflow as tfx = tf.Variable(initial_value=tf.random_uniform([1], 34, 35),name=’x’)
y = tf.Variable(initial_value=tf.random_uniform([1], 0., 50.), name=’y’)# Loss function
s = tf.add(tf.add(632.0, tf.multiply(8.0, y)), tf.divide(2400.0, y), ‘s’)opt = tf.train.GradientDescentOptimizer(0.05)
train = opt.minimize(s)sess = tf.Session()init = tf.initialize_all_variables()
sess.run(init)old_solution = 0
tolerance = 1e-4
for step in range(500):
 sess.run(train)
 solution = sess.run(y)
 if np.abs(solution — old_solution) < tolerance:
 print(“The solution is y = {}”.format(old_solution))
 break

 old_solution = solution
 if step % 10 == 0:
 print(step, “y = “ + str(old_solution), “s = “ + str(sess.run(s)))

我们已经使用梯度下降算法计算出了 y 。当然,我们现在需要计算 x 代入 x = 600/y

x = 600/old_solution[0]
print(x)

这与我们的结果相符,所以它似乎是有效的!让我们画出结果:

import matplotlib.pyplot as plty = np.linspace(0, 400., 500)
s = 632.0 + 8*y + 2400/y
plt.plot(y, s)

print("The function minimum is in {}".format(np.min(s)))
min_s = np.min(s)
s_min_idx = np.nonzero(s==min_s)
y_min = y[s_min_idx]
print("The y value that reaches the minimum is {}".format(y_min[0]))

让我们看看其他例子

在这种情况下,我们希望找到 y = log2(x)函数的最小值。

x = tf.Variable(15, name='x', dtype=tf.float32)
log_x = tf.log(x)
log_x_squared = tf.square(log_x)optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(log_x_squared)init = tf.initialize_all_variables()def optimize():
  with tf.Session() as session:
    session.run(init)
    print("starting at", "x:", session.run(x), "log(x)^2:", session.run(log_x_squared))
    for step in range(100):  
      session.run(train)
      print("step", step, "x:", session.run(x), "log(x)^2:", session.run(log_x_squared))

optimize()

我们来策划一下吧!

x_values = np.linspace(0,10,100)
fx = np.log(x_values)**2
plt.plot(x_values, fx)print("The function minimum is in {}".format(np.min(fx)))
min_fx = np.min(fx)
fx_min_idx = np.nonzero(fx==min_fx)
x_min_value = x_values[fx_min_idx]
print("The y value that reaches the minimum is {}".format(x_min_value[0]))

让我们解决一个线性回归问题

让我们看看如何将一条直线调整到一个数据集,这个数据集代表了辛普森一家中每个角色的智力,从拉尔夫·威根到弗林克医生。

让我们绘制智力随年龄的分布图,从 0 到 1 归一化,其中玛吉最小,蒙哥马利·伯恩斯最大:

n_observations = 50
_, ax = plt.subplots(1, 1)
xs = np.linspace(0., 1., n_observations)
ys = 100 * np.sin(xs) + np.random.uniform(0., 50., n_observations)
ax.scatter(xs, ys)
plt.draw()

按作者分列的数字

现在,我们需要两个 tf .占位符,一个在回归算法的入口,另一个在出口。占位符是在执行网络之前不需要赋值的变量。

X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

让我们试着优化线性回归的直线。我们需要两个变量,权重(W)和偏差(b)。tf 类型的元素。变量需要初始化,并且其类型在声明后不能更改。我们可以通过“赋值”方法改变它的值。

W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')
Y_pred = tf.add(tf.multiply(X, W), b)

现在让我们把成本函数定义为我们的预测值和真实值之间的差值。

loss = tf.reduce_mean(tf.pow(Y_pred - y, 2))

我们现在定义优化方法,我们将使用梯度下降。基本上,它计算每个权重相对于总误差的变化,并更新每个权重,使得总误差在随后的迭代中减小。学习率表示权重更新的突然程度。

learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)**# Definition of the number of iterations and start the initialization using the GPU**
n_epochs = 1000with tf.Session() as sess:
  with tf.device("/GPU:0"): **# We initialize now all the defined variables**
    sess.run(tf.global_variables_initializer()) **# Start the adjust**
    prev_training_loss = 0.0
    for epoch_i in range(n_epochs):
      for (x, y) in zip(xs, ys):
        sess.run(optimizer, feed_dict={X: x, Y: y}) W_, b_, training_loss = sess.run([W, b, loss], feed_dict={X: xs, Y: ys}) **# We print the losses every 20 epochs**
      if epoch_i % 20 == 0:
        print(training_loss) **# Ending conditions**
      if np.abs(prev_training_loss - training_loss) < 0.000001:
        print(W_, b_)
        break
      prev_training_loss = training_loss **# Plot of the result**
    plt.scatter(xs, ys)
    plt.plot(xs, Y_pred.eval(feed_dict={X: xs}, session=sess))

按作者分列的数字

我们有了!有了这条回归线,我们将能够预测每个辛普森的性格的智力知道年龄。

MNIST 数据集

现在让我们看看如何用逻辑回归对数字图像进行分类。我们将使用深度学习数据集的“Hello world”。

让我们导入相关的库和数据集 MNIST:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

我们通过用一键编码对标签进行编码来加载数据集(它将每个标签转换为长度= N_CLASSES 的向量,除了指示图像所属的类的索引(包含 1)之外,所有的 0 都是 0)。比如我们有 10 个类(数字从 0 到 9),标签属于数字 5:label =[0 0 0 1 0 0 0 0 0]。

mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)print("Train examples: {}".format(mnist.train.num_examples))
print("Test examples: {}".format(mnist.test.num_examples))
print("Validation examples: {}".format(mnist.validation.num_examples))**# Images are stored in a 2D tensor: images_number x image_pixels_vector
# Labels are stored in a 2D tensor: images_number x classes_number (one-hot)**
print("Images Size train: {}".format(mnist.train.images.shape))
print("Images Size train: {}".format(mnist.train.labels.shape))**# To see the range of the images values**
print("Min value: {}".format(np.min(mnist.train.images)))
print("Max value: {}".format(np.max(mnist.train.images)))**# To see some images we will acess a vector of the dataset and resize it to 28x28**
plt.subplot(131)
plt.imshow(np.reshape(mnist.train.images[0, :], (28, 28)), cmap='gray')
plt.subplot(132)
plt.imshow(np.reshape(mnist.train.images[27500, :], (28, 28)), cmap='gray')
plt.subplot(133)
plt.imshow(np.reshape(mnist.train.images[54999, :], (28, 28)), cmap='gray')

我们已经了解了 MNIST 数据集的一些内容。现在,让我们创建我们的回归变量:

首先,我们为输入数据创建占位符。在这种情况下,输入将是一组大小为 768 的向量(我们将一次传递几个图像到我们的回归器,这样,当它计算梯度时,它将在几个图像中扫描,因此估计将比它只使用一个图像更精确)

n_input = 784  **# Number of data features: number of pixels of the image**
n_output = 10  **# Number of classes: from 0 to 9**
net_input = tf.placeholder(tf.float32, [None, n_input])  **# We create the placeholder**

现在让我们定义回归方程:y = W*x + b

W = tf.Variable(tf.zeros([n_input, n_output]))
b = tf.Variable(tf.zeros([n_output]))

由于输出是多类的,我们需要一个函数返回图像属于每个可能类的概率。例如,如果我们放一个 5 的图像,可能的输出是:[0.05 0.05 0.05 0.05 0.55 0.05 0.05 0.05 0.05 0.05]其概率之和是 1,概率最高的类是 5。

我们应用 softmax 函数来归一化输出概率:

net_output = tf.nn.softmax(tf.matmul(net_input, W) + b)

SoftMax 函数

**# We also need a placeholder for the image label, with which we will compare our prediction And finally, we define our loss function: cross entropy**
y_true = tf.placeholder(tf.float32, [None, n_output])**# We check if our prediction matches the label**
cross_entropy = -tf.reduce_sum(y_true * tf.log(net_output))
idx_prediction = tf.argmax(net_output, 1)
idx_label = tf.argmax(y_true, 1)
correct_prediction = tf.equal(idx_prediction, idx_label)**# We define our measure of accuracy as the number of hits in relation to the number of predicted samples**
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))**# We now indicate that we want to minimize our loss function (the cross entropy) by using the gradient descent algorithm and with a rate of learning = 0.01.**
optimizer = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

现在一切都设置好了!让我们执行图表:

from IPython.display import clear_outputwith tf.Session() as sess: sess.run(tf.global_variables_initializer()) **# Let's train the regressor**
  batch_size = 10 
  for sample_i in range(mnist.train.num_examples):
    sample_x, sample_y = mnist.train.next_batch(batch_size)
    sess.run(optimizer, feed_dict={net_input: sample_x, 
                                   y_true: sample_y}) **# Let's check how is performing the regressor**
    if sample_i < 50 or sample_i % 200 == 0:
      val_acc = sess.run(accuracy, feed_dict={net_input: mnist.validation.images, y_true: mnist.validation.labels})
      print("({}/{}) Acc: {}".format(sample_i, mnist.train.num_examples, val_acc))**# Let's show the final accuracy**
  print('Teste accuracy: ', sess.run(accuracy, feed_dict={net_input: mnist.test.images, y_true: mnist.test.labels}))

我们刚刚用 TensorFlow 训练了我们的第一个神经元网络!

想一想我们刚刚做了什么。

我们实现了一个逻辑回归,公式为:y = G(Wx + b),其中 G = softmax(),而不是典型的 G = sigmoid()。

如果你看下图,它定义了感知器(单层神经网络),你可以看到输出=激活 _ 功能(Wx)。你看到了吗?只差偏了!注意输入是 1?所以权重 w0 没有乘以任何东西。没错。权重 w0 是偏差,用这种符号表示只是为了能够将其实现为矩阵乘法。

所以,我们刚刚实现的是一个感知器

  • 批处理大小= 10
  • 1 个纪元
  • 下降梯度作为优化器
  • 和 softmax 作为激活函数。

最后的话

一如既往,我希望你喜欢这篇文章,你已经学会了如何使用 TensorFlow 来解决线性问题,并且你已经成功地训练了你的第一个神经网络!

如果你喜欢这篇帖子,那么你可以看看我在数据科学和机器学习方面的其他帖子

如果你想了解更多关于机器学习和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!

深度学习跳跃

原文:https://towardsdatascience.com/deep-learning-to-jump-e507103ab8d3?source=collection_archive---------50-----------------------

Maxime Bergeron & Ivan Sergienko,Riskfuel

在这篇简短的笔记中,我们描述了一个跳转单元,它可以用来用一个简单的神经网络拟合阶跃函数。我们的动机来自于经常出现不连续性的定量金融问题。

(图片由作者提供)

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

为什么要跳?

不连续函数在金融工具中是常见的。例如,下图显示了典型的五年期固定利率债券的价格,票面利率为半年。我们设定的票面利率高于贴现率,所以债券的价值保持在票面价值 100 美元以上。如果你不熟悉债券定价,这里有一本很好的入门书。

(图片由作者提供)

为了我们的目的,需要注意的重要事情是在每个息票支付日发生的跳跃。这仅仅是因为钱不可能凭空产生。证券所有者的“财富”在息票前后保持不变。因此,我们有:

息票前价值=息票后价值+息票现金。

在行权日,更复杂的路径依赖型金融衍生品的价值也会出现类似的跃升。这里的一个经典例子是百慕大互换期权,这是一种用于管理抵押贷款提前还款风险的流行工具。百慕大式期权可以在价值可能跃升的预定日期行使。

(图片由作者提供)

为了使事情具体化,我们将把注意力集中在学习具有单一向下跳跃的分段常数函数的子问题上。我们生成的训练数据如上图所示。请读者跟随我们在这个 Jupyter 笔记本中的代码。

Sigmoid 函数

那么我们机器如何学习跳跃呢?这里一个自然的方法是使用一个 s 形然而,在我们的问题中,步骤是尖锐的。息票支付日期左边的所有点都严格位于右边的点之上,这导致了真正的不连续。拟合简单的一维神经网络

(图片由作者提供)

包括夹在两个线性层之间的 s 形激活函数需要初始线性层中的无界系数(权重)。数量无限增长对于数值方法来说总是坏消息,但对于神经网络来说情况更糟。事实上,这导致了臭名昭著的爆炸梯度问题,使最佳参数值几乎不可能学习。我们将不得不通过保持大而有限的权重来进行妥协,从而导致输入的一个区域(就在跳跃附近)难以消除显著的误差。

(图片由作者提供)

我们能做得更好吗?

亥维赛函数

为什么不简单地用…一个跳跃来学习一个跳跃呢?用不连续的激活来代替上面一维网络中的 sigmoid 函数是很有诱惑力的。这里最简单的候选函数是 Heaviside 阶跃函数 H(x) ,对于 x < 0 它等于 0 ,否则等于 1 :

(图片由作者提供)

这是一个显而易见的想法,它会立即导致如下图所示的失败:

(图片由作者提供)

为了理解这里的问题,让我们看看数学。我们的小神经网络对应的损失函数是:

这里, yᵢ 是对应于时间 tᵢ的训练数据值,子脚本 w 项是最后一个线性层的权重,子脚本 b 项是来自两个线性层的偏差。敏锐的读者会注意到,在不失一般性的情况下,我们已经将第一个线性层的权重设置为 1 ,剩余的权重和偏差决定了台阶的大小和位置。深度学习所依赖的用于最小化误差函数的梯度下降方法需要使用一阶导数。在这方面,其中一个问题很大:

这里的问题是第二个因素,当 bt 项相互抵消时,这个因素就会爆发。下面的图清楚地说明了这个问题:函数是分段常数!

(图片由作者提供)

虽然实际的最小值是我们期望的,但基于梯度的方法永远达不到它。相反,这一过程陷入了一个小平台。

事实上,这个问题是 sigmoid 函数成为机器学习的主要内容的原因之一。用 sigmoidal 函数代替 Heaviside 函数允许通过梯度下降成功地训练复杂的神经网络,例如多层感知器。

在这一点上,可能会开始觉得我们在兜圈子。s 形函数在拟合急剧跳跃方面用处有限,但它们的引入是为了解决 Heaviside 函数的明显问题。

跳跃单元

下表总结了前面两个部分,并显示了当面临学习锐阶跃函数的任务时,我们对这两个激活函数的喜欢和不喜欢之处:

一个自然的问题是,我们是否可以将这两种功能结合起来,保留我们喜欢的功能,丢弃我们不喜欢的功能。进入跳转单元,如下图所示:

(图片由作者提供)

它由三个线性节点以及平行排列的 sigmoid 和 Heaviside 激活函数组成。为了理解这个单元如何工作,考虑它编码的等式:

为了简化方程,我们省略了 sigmoid 激活之后的线性层中的偏置项,因为它是由 Heaviside 激活之后的线性层的偏置项来解决的。现在让我们看看之前有问题的导数:

由于麻烦的偏差项现在出现在 S(-)H(-)的论证中,其梯度在大多数点不再消失,网络能够学习。请注意,在这个过程的最后,我们还希望 sigmoid 激活后的线性层的重量消失,这样只有 Heaviside 贡献保留下来。

(图片由作者提供)

上面的图显示了我们的跳转单元的 MSE 误差作为它的两个关键参数的函数。我们看到,沿着偏置轴的阶跃之间的平台现在是倾斜的,允许基于梯度的算法学习全局最小值。

最后,我们画出结果函数,瞧!

(图片由作者提供)

结论

总之,我们已经展示了如何结合 sigmoidal 和 Heaviside 激活函数的优点和缺点来产生能够通过梯度下降学习不连续阶跃函数的跳跃单元。

我们鼓励读者在这款 Jupiter 笔记本中亲自尝试一下!

在 MacBook 上使用 GPU 进行深度学习

原文:https://towardsdatascience.com/deep-learning-using-gpu-on-your-macbook-c9becba7c43?source=collection_archive---------2-----------------------

使用 PlaidML 并利用 AMD/Intel GPU 进行深度学习

我有 GPU,我学得很深

作为一名 MacBook Pro 的拥有者,我意识到无法利用其 GPU 进行深度学习的沮丧,考虑到难以置信的质量和纹理,当然还有它的价格。我还记得当我在 MacBook Pro 13 '和 15 '之间选择时,当时我对数据科学一点都不熟悉,我选择 15 '只是因为它有一个独立的 AMD GPU。很快我发现,在机器学习&深度学习方面,额外的一块 GPU 几乎没有带来任何帮助。长期以来,大多数现代机器学习模型只能通过通用 GPU 库 CUDA 来利用 Nvidia GPUs。

然而,现在已经是 2020 年了,今天的事情可能会有点不同: PlaidML 最初是由 Vertex 在 2017 年发布的。AI 旨在带来“面向每个平台的深度学习”。自从 2018 年被英特尔收购以及之后的 0.3.3 版本发布以来,你可以利用你的 AMD 和英特尔 GPU 用 Keras 做并行深度学习工作。自今年 1 月 15 日发布 0.7.0 版本以来, PlaidML 为所有主要目标的 GPU & CPU 提供了完整的条带后端。但首先,我们为什么需要用 GPU 做并行计算?

房屋建筑的例子

让我们以建造一所房子为例:如果你独自一人,比方说建造房子可能需要 400 个小时。然而,如果你雇佣一个额外的建筑工人和你一起建造,只需要 200 个小时,因为你把工作分成了一半。同样,你雇佣的工人越多,你就能越快地把房子建好。有一个众所周知的阿姆达尔定律描述了当我们增加更多的处理器(工作者)时,一个程序可以加速到什么程度。

好吧,那么为什么要用 GPU 呢?GPU,也就是众所周知的图形处理单元,显然一开始就不是为做深度学习而设计的。然而,并行计算的本质似乎与图形处理类似:GPU 的内核虽然较弱,但由于其高度并行的结构和内核数量,对于处理大数据块的算法来说,GPU 的内核比 CPU 更高效(GPU 由数百个计算能力较弱的内核组成,而 CPU 通常由 4 到 32 个更强大的内核组成)。由于图形处理和深度学习的内在本质相似(大多数操作可以同时完成,而不是一个接一个),GPU 成为深度学习和并行计算时自然的首选。

正如我最喜欢的一句来自 Linus Torvalds 的名言所说:

“空谈是廉价的。给我看看代码。”

让我们动手,使用您自己的笔记本电脑,使用您的 GPU 运行一个简单的 CNN 案例!

1.安装和设置 PlaidML 和相关组件

首先,确保你的笔记本电脑有一个工作的 Python3 环境。我建议随时在虚拟环境下运行:

请记住,TensorFlow 下的 Keras 将无法使用 PlaidML。

设置 PlaidML 第 1 部分

首先你会看到一个欢迎页面和一个询问你是否使用实验设备支持的问题。正如它所建议的,使用实验设备会导致性能下降、崩溃和其他问题,您可以键入“n”或什么都不输入,然后返回选择使用默认配置设备。

设置 PlaidML 第 2 部分

现在你得到了一个你可以选择的所有设备的列表。对于我的 Macbook Pro 15' 2018,以下选项为:

  1. 我的 CPU
  2. 我的英特尔 UHD 显卡 630 GPU
  3. 我的 AMD 镭龙 pro 560x GPU

我选择 3 是因为 AMD 是目前最强大的。

设置 PlaidML 第 3 部分

最后,键入“y”或什么都不输入,然后返回保存设置。现在,您已经完全设置好了,并准备好使用您的 GPU 进行深度学习项目。

2.在时尚 mnist 数据集上构建简单 CNN 分类器的教程:

首先,让我们启动一个 Jupyter 笔记本。(不确定为什么使用 Jupyter 笔记本或如何使用?查看我的上一篇文章了解更多详情)。

您需要按照正确的顺序运行这几行代码,以利用 PlaidML 作为 Keras 后端,否则它将默认使用 TensorFlow。

现在我们导入包并下载时尚数据集。

我们将使用 Keras 序列模型构建一个简单的 CNN(卷积神经网络)并编译它。

现在我们拟合模型并测试准确性。

模型结果

我们训练了一个 CNN 模型,仅用了大约 2 分钟就对时尚数据集进行了 91%的分类。你可能认为这并不令人印象深刻,但是看看与我的笔记本电脑的 CPU 的比较:

结论

从上面的比较中我们可以看到,在我的 MacBook Pro 上使用 GPU 比使用 CPU 运行这个简单的 CNN 代码快大约 15 倍。在 PlaidML 的帮助下,用自己的笔记本电脑做深度学习不再是无法忍受的事情。这个项目的完整脚本可以在我的 github 找到。

截止到今天(2020 年 2 月), PlaidML 已经支持 KerasONNXNGraph 。它在 GPU 上运行良好,并且不需要在 Nvidia 硬件上使用 CUDA/cuDNN,同时实现可比的性能。在 PlaidML github 页面上有更多的演示和相关项目。现在你 GPU 可能还不能得到 PlaidML 的完全支持,但是我相信很快 GPU 学习将不再是 Nvidia T21 的特权。

用 PyTorch 深度学习表格数据

原文:https://towardsdatascience.com/deep-learning-using-pytorch-for-tabular-data-c68017d8b480?source=collection_archive---------8-----------------------

来源

这篇文章将通过一个真实的例子为您提供使用 Pytorch 处理表格数据的详细的端到端指南。在本文结束时,您将能够构建您的 Pytorch 模型。

开始前有几件事:

课程:我同时开始了 fast.ai 课程和deep learning . aispecialization(Coursera)。他们给了我关于深度学习的基础知识。伟大的斯坦福 cs231n 也强烈推荐。

看的课程越来越多,非常容易。我认为最重要的是【动手】。写代码!开始一个项目或尝试解决一个难题。

  • 使用 Python 的 set_trace()全面理解每一步。
  • 你可以在这里找到完整的代码

T 何数据

我选择从事 Kaggle 的纽约市出租车费用预测工作,该公司的任务是预测乘客的出租车费用。请注意,这是一个回归问题。你可以在这里找到更多细节和完整数据集

训练数据包含超过 200 万个样本(5.31 GB)。为了最大限度地减少训练时间,我们随机抽取了 100k 个训练样本。

import pandas
import randomfilename = r"C:\Users\User\Desktop\offir\study\computer learning\Kaggle_comp\NYC Taxi\train.csv"n = sum(1 for line in open(filename)) - 1 #number of records in file (excludes header)
s = 100000 #desired sample size
skip = sorted(random.sample(range(1,n+1),n-s)) #the 0-indexed header will not be included in the skip listdf = pandas.read_csv(filename, skiprows=skip)
df.to_csv("temp.csv")

国家政治保卫局。参见 OGPU

我用免费的谷歌实验室写了我的代码。

要使用 GPU:运行时->更改运行时设置->硬件加速器-> GPU。

密码

导入相关库

运行以下命令后,您需要从您的计算机上传 CSV 文件。检查您上传的 CSV 文件是否命名为 sub_train。

也上传测试集

数据预处理

下一步是删除所有小于 0 的票价(它们没有意义)

df_train 现在的长度是 99990。在每个步骤中记录不同数据集的类型和长度非常重要。

堆叠训练集和测试集,使它们经历相同的预处理

目标是预测票价金额。因此,将其从 train_X 数据帧中删除。

而且,我选择了一边训练一边预测价格的 log。解释超出了这篇博客的范围。

特征工程

让我们做一些特征工程。

一个是定义 haverine_distatance 函数,并添加一个 DateTime 列来导出有用的统计信息。你可以在 GitHub 回购 中看到完整的流程。

在这个阶段之后,数据帧看起来像这样:

准备模型

定义分类列和连续列,并且只采用相关的列。

将 cat 类别设为“category”类型,并将其标记为 encoder。

定义分类列的嵌入大小。确定嵌入大小的经验法则是将每列中唯一条目的数量除以 2,但不超过 50。

现在我们来处理连续变量。在规范化它们之前,重要的是在训练集和测试集之间进行划分,以防止数据泄漏。

列车有效分离

在定型集和验证集之间拆分。在这种情况下,验证集占总训练集的 20%。

X_train, X_val, y_train, y_val = train_test_split(X, Y, test_size=0.20, random_state=42,shuffle=**True** )

在这一步之后,重要的是看看不同的形状。

模型

目前,我们的数据存储在熊猫数组中。PyTorch 知道如何与张量合作。以下步骤将把我们的数据转换成正确的类型。跟踪每一步中的数据类型。我添加了当前数据类型的注释。

是时候使用 PyTorch DataLoader 了。我选择的批量是 128,随便玩玩吧。

定义一个表格模型

目标是基于连续列的数量+分类列的数量及其嵌入来定义一个模型。输出将是一个单浮点值,因为它是一个回归任务。

  • ps:每层的丢失概率
  • emb_drop:提供嵌入丢弃
  • emd_szs:元组列表:每个分类变量的大小与一个嵌入大小成对出现
  • 连续变量的数量
  • out_sz:输出大小

为预测设置 y_range(可选),并调用模型。请随意使用输入。

该模型如下所示:

定义一个优化器。我选择了学习率为 1e-2 的亚当。学习是你应该调整的第一个超参数。此外,使用学习率有不同的策略(拟合一个周期、余弦等)。这里我使用一个恒定的学习率。

训练和健身

训练你的模型。试着跟踪和理解每一步。使用 set_trace()命令非常有帮助。评估指标是 RMSE。

将输入传递给 fit 函数。在这种情况下,损失函数是 MSEloss。

绘制列车与验证损失图

完成培训部分

在玩了模型和调整了超参数之后,你就达到了满意的程度。只有这样,你才能进入下一步:在测试集上测试你的模型。

测试集

请记住:您的测试必须经历与训练集相同的过程(我们已经这样做了)。接下来的步骤是“准备”接受评估。

分为分类列和连续列,并使它们成为张量。

做一个预测

好吧,你终于做出了预测!恭喜你。

注意,预测现在是一个张量。如果您想将其更改为熊猫数据框,请完成回购中的步骤。接下来,您可以将其导出为 CSV 文件。

如果你在做 Kaggle 比赛,上传到 Kaggle 看看你的分数。

结论

总之,您了解了如何从头开始为表格数据构建 PyTorch 模型。你必须扔掉全部代码,并努力理解每一行。

如果您有任何问题、意见或担忧,请不要忘记通过 Linkedin 与我联系。

开始工作!

参考文献:

深度学习与机器学习

原文:https://towardsdatascience.com/deep-learning-vs-machine-learning-e0a9cb2f288?source=collection_archive---------9-----------------------

Unsplash 上的 Pietro Jeng 拍摄

这些流行语到底是什么意思?而机器和深度学习的区别是什么?

介绍

近年来,机器学习、深度学习和人工智能已经成为热门词汇,在越来越多公司的营销材料和广告中随处可见。但是什么是机器学习和深度学习,它们之间有什么区别?在本文中,我将尝试回答这些问题,并向您展示一些深度和机器学习应用的案例。

什么是机器学习?

机器学习是计算机科学的一部分,它基于数据,用数学模型来表示现实世界的事件或对象。这些模型是用特殊算法构建的,这些算法调整模型的一般结构,使其适合训练数据。根据所解决问题的类型,我们定义了有监督和无监督的机器学习以及机器学习算法。受监督的机器学习专注于创建模型,这些模型能够将我们手头已经拥有的关于数据的知识转移到新数据,在训练阶段建模(训练)算法看不到这些新数据。我们提供了一种算法,该算法具有特征数据以及该算法应该学会从中推断的相应值(所谓的目标变量)。在无监督的机器学习中,我们只为算法提供特征,允许它自己找出它们的结构和/或依赖性。没有指定明确的目标变量。无监督学习的概念一开始可能很难理解,但是看一看下面四个图表中提供的例子应该会让这个想法变得清晰。

图表 1a

图表 1b

图表 1a 给出了一些数据,这些数据用轴 xy 上的两个特征来描述。图表 1b 显示了相同颜色的数据。我们使用 K-means 聚类算法将这些点分组为 3 个簇,并相应地对它们进行着色。这是一个无监督机器学习算法的例子。算法只给出特征,标签(聚类数)要算出来。

图表 2a

图表 2b

图表 2a 显示了一组不同的标记(并相应地着色)数据。我们先验地知道每个数据点所属的组。我们使用 SVM 算法找到两条直线,这两条直线将向我们展示如何分割数据点以最适合这些组。这种分割并不完美,但这是用直线能做到的最好的了。如果我们想要将一个组分配给一个新的、未标记的数据点,我们只需要检查它在平面上的位置。这是一个由监督的机器学习应用的例子。

机器学习模型的应用

创建标准的机器学习算法是为了处理表格形式的数据。这意味着,为了使用它们,我们需要某种类型的表,其中的行可以被认为是建模对象的实例(例如,贷款),而列是这个特定实例的特征(特性)(例如,贷款的月还款额、借款人的月收入)。表 1。是这类数据的一个很短的例子。当然,这并不意味着纯数据本身必须是表格和结构化的。但如果我们想在一些数据集上应用标准的机器学习算法,我们通常必须首先清理、混合并将其转换为表格。在监督学习中,还有一个包含目标值的特殊列(例如,贷款是否违约的信息)。训练算法通过调整模型的参数来尝试使模型的一般结构适合这些数据,以便得到的模型尽可能准确地描述给定数据和目标变量之间的关系。重要的是,该模型不仅很好地符合给定的训练数据,而且还能够进行概括。一般化意味着我们可以使用该模型来推断训练期间没有使用的实例的目标。泛化是一个有用模型的关键特征。构建一个良好概括的模型不是一件容易的事情,通常需要复杂的验证技术和全面的模型测试。

表 1。表格形式的贷款数据

机器学习算法被用于各种应用中。表二。介绍一些可以应用非深度机器学习算法和模型的业务用例,以及对潜在数据、目标变量和选定的适用算法的简短描述。

表二。机器学习用例的例子

深度学习和深度神经网络

深度学习是机器学习的一部分,其中我们使用一种特定类型的模型,称为深度人工神经网络(ann)。自从它们被引入以来,人工神经网络经历了广泛的进化过程,产生了许多亚型,其中一些非常复杂。但是为了介绍它们,最好解释一下它们的一种基本形式——多层感知器(MLP)。

简而言之,MLP 具有顶点(也称为神经元)和边(由称为权重的数字表示)的图形(网络)形式。神经元按层排列,并且连续层中的神经元相互连接。数据通过网络从输入层流向输出层,在神经元和神经元之间的边缘进行转换。一旦一个数据点通过整个网络,输出层在其神经元中包含预测值。每次有一大块训练数据通过网络时,我们都会将预测值与相应的真实值进行比较,并调整模型的参数(权重)以使预测更好。这是通过一种叫做反向传播的算法实现的。经过一定次数的迭代后,如果模型的结构设计得很好,专门用于处理手头的机器学习问题,并且足够的数据已经多次通过网络,我们就可以获得高精度的模型。在实践中,有大量的转换可以应用于神经元,使人工神经网络非常灵活和强大。然而,人工神经网络的强大是有代价的。通常,模型的结构越复杂,将它训练到高精度所需的数据和时间就越多。

图一。一个 4 层人工神经网络的结构,根据三个简单的特征预测一个新闻应用程序的用户下个月是否会流失。为了清楚起见,仅标记了选定(粗体)边的权重,但是每个边都有自己的权重。数据从输入层流向输出层,通过中间的两个隐藏层。在每条边上,输入值乘以边的权重,所得乘积将到达边结束的节点。然后,在隐藏层的每个节点中,来自边缘的输入信号被求和,然后用某种函数进行变换。然后,这些转换的结果被视为下一层的输入。在输出层,传入的数据再次被汇总和转换,产生两个数字形式的结果——用户在下个月离开应用的概率,以及他们不离开的概率。

在更高级类型的神经网络中,各层具有更复杂的结构。它们不仅由 MLPs 中已知的具有单操作神经元的简单密集层组成,还包括更复杂的多操作层,如卷积层和递归层。卷积层主要用于计算机视觉应用。它们由在图像的像素表示上滑动的小型数字阵列组成。像素值乘以这些数字,然后聚合,产生新的、压缩的图像表示。递归层用于建模有序的序列数据,如时间序列或文本。他们对输入的数据应用复杂的多参数转换,试图找出序列项之间的依赖关系。然而,无论网络的类型和结构如何,总有一些(一个或多个)输入和输出层,以及数据在网络中流动的严格定义的路径和方向。

一般来说,深度神经网络是具有多个层的 ann。下图 1、2 和 3 显示了选定深度人工神经网络的架构。它们都是在谷歌开发和培训的,并向公众开放。他们给出了当今使用的高精度深度人工网络有多复杂的想法。

这些网络规模巨大。例如,图 3 中部分显示的 InceptionResNetV2 有 572 层,总共超过 5500 万个参数!它们都是作为图像分类模型开发的(它们为给定的图像分配一个标签,例如“汽车”),并在 ImageNet 集合的图像上进行训练,该集合包含超过 1400 万个带标签的图像。

图二。NASNetMobile 的结构

图 3。例外结构

图 4。InceptionResNetV2 的一部分(约 25%)的结构

近年来,我们观察到深度学习及其应用的巨大发展。我们的智能手机和应用程序的许多“智能”功能都是这一进步的成果。虽然人工神经网络的想法并不新鲜,但最近的繁荣是一些条件得到满足的结果。首先,我们发现了 GPU 计算的潜力。图形处理单元的架构非常适合并行计算,对高效的深度学习非常有帮助。此外,云计算服务的兴起使得获取高效硬件变得更加容易、更加便宜,并且有可能在更大范围内实现。最后,最新移动设备的计算能力足以应用深度学习模型,从而为 DNN 驱动的功能创造了一个巨大的潜在用户市场。

深度学习模型的应用

深度学习模型通常适用于处理不具有简单行列结构的数据的问题,如图像分类或语言翻译,因为它们擅长处理这些任务处理的非结构化和复杂结构的数据——图像、文本和声音。使用经典的机器学习算法处理这些类型和大小的数据存在问题,并且创建和应用一些深度神经网络来解决这些问题已经在过去几年中在图像识别、语音识别、文本分类和语言翻译领域中引起了巨大的发展。

将深度学习应用于这些问题是可能的,因为 dnn 接受被称为张量的多维数字表作为输入和输出,并可以跟踪它们的元素之间的空间和时间关系。例如,我们可以将图像表示为 3 维张量,其中第一维和第二维表示数字图像的分辨率(图像宽度和高度的大小也分别如此),第三维表示每个像素的 RGB 颜色编码(因此第三维的大小为 3)。这使得我们不仅可以用张量表示图像的所有信息,还可以保持像素之间的空间关系,这在所谓的卷积层的应用中至关重要,在成功的图像分类和识别网络中至关重要。

神经网络在输入和输出结构上的灵活性也有助于其他任务,如语言翻译。当处理文本数据时,我们向深度神经网络输入单词的数字表示,根据它们在文本中的出现进行排序。每个单词由一百或几百个数字的向量表示,通过计算(通常使用不同的神经网络)使得对应于不同单词的向量之间的关系模拟单词本身的关系。这些被称为嵌入的向量语言表示,一旦被训练,就可以在许多架构中被重用,并且是神经网络语言模型的核心构件。

表 3。包含将深度学习模型应用于现实生活问题的示例。正如你所看到的,深度学习算法处理和解决的问题比标准机器学习技术解决的任务复杂得多,如表 1 所示。然而,重要的是要记住,今天机器学习可以帮助企业的许多用例不需要如此复杂的方法,并且可以通过标准模型更有效地(和更高的准确性)解决。表 3。也给出了有多少不同类型的人工神经网络层的想法,以及有多少不同的有用的架构可以用它们来构建。

表 3。深度学习用例示例

深度学习模型的优势

深度神经网络最令人印象深刻的应用之一是生成式对抗网络(GANs)的兴起。它们是由 Ian Goodfellow 在 2014 年引入的,此后他的想法被纳入到许多工具中,有些工具取得了惊人的结果。GANs 负责应用程序的存在,这些应用程序使我们在照片中看起来更老,变换图像,使它们看起来像是梵高画的,甚至为多个乐器乐队协调旋律。在训练 GAN 的过程中,两个神经网络竞争。生成器网络从随机输入生成输出,而鉴别器则试图区分生成的实例和真实的实例。在训练期间,生成器学习如何成功地“愚弄”鉴别器,并最终能够创建看起来好像是真实的输出。

值得注意的是,尽管训练深度神经网络是一项计算量非常大的任务,并且可能需要很长时间,但应用经过训练的网络来完成特定任务并不是必须的,特别是如果它同时应用于一个或几个案例。事实上,今天我们能够在智能手机的移动应用程序中运行强大的深度神经网络。甚至有一些专门设计的网络架构在应用于移动设备时非常高效(例如图 1 所示的 NASNetMobile)。尽管与现有技术的网络相比,它们的尺寸小得多,但它们仍然能够获得高精度的预测性能。

人工神经网络的另一个非常强大的功能是迁移学习,它能够广泛使用深度学习模型。一旦我们有了一个根据某些数据(或者是我们自己创建的,或者是从公共存储库中下载的)训练的模型,我们就可以在它的全部或部分基础上构建一个解决我们特定用例的模型。例如,我们可以使用在巨大的 ImageNet 数据集上训练的预训练 NASNetLarge 模型,该模型为图像分配标签,在其结构顶部进行一些小的修改,用一组新的标记图像进一步训练它,并使用它来标记一些特定类型的对象(例如,基于树叶图像的树的种类)。迁移学习非常有用,因为通常训练一个深度神经网络来执行一些实际有用的任务需要大量的数据和巨大的计算能力。这通常意味着数百万个带标签的数据实例,以及数百个图形处理单元(GPU)运行数周。并不是每个人都能负担得起或获得这样的资产,这使得从头构建一个高精度的定制解决方案非常困难,比如说,图像分类。幸运的是,一些预训练的模型(特别是用于图像分类的网络和用于语言模型的预训练嵌入矩阵)已经开源,并且可以以易于应用的形式免费获得(例如,作为神经网络 API Keras 中的模型实例)。

如何为您的应用选择和构建正确的机器学习模型

当你想应用机器学习来解决一个商业问题时,你不需要马上决定模型的类型。通常有几种方法可以测试。一开始从最复杂的模型开始往往很诱人,但是从简单的开始,并逐渐增加所应用的模型的复杂性是值得的。更简单的模型通常在设置、计算时间和资源方面更便宜。此外,他们的结果是评估更高级方法的一个很好的基准。拥有这样的基准可以帮助数据科学家评估他们开发模型的方向是否正确。一个额外的优势是可以重复使用一些以前建立的模型,并将它们与新的模型合并,创建一个所谓的集合模型。混合不同类型的模型通常会产生比单独的组合模型更高的性能指标。此外,通过迁移学习,检查是否有一些预先训练的模型可以用于和适应您的业务案例。

无论您使用什么模型,都要确保数据得到正确处理。记住“垃圾进,垃圾出”的规则。如果提供给模型的训练数据质量很低,或者没有被正确地标记和清理,则很可能得到的模型也将表现不佳。还要确保模型——不管它有多复杂——在建模阶段得到了广泛的验证,并在最后测试了它是否能很好地推广到看不见的数据。

更实际的是,确保创建的解决方案可以在可用的基础设施上实现。如果你的企业可以收集更多的数据,用于在未来改进你的模型,那么应该准备一个再培训管道,以确保其易于更新。这种流水线甚至可以被设置成以预定义的时间频率自动地重新训练模型。

最后,不要忘记在将模型部署到产品中之后跟踪它的性能和可用性。业务环境是非常动态的,数据中的一些关系可能会随着时间的推移而改变,并且可能会出现新的现象。它们可以改变你的模型的效率,应该被正确对待。此外,还可以发明新的、功能强大的模型。一方面,它们可以使您的解决方案相对薄弱,但另一方面,给你机会进一步改善您的业务和利用最新的技术。

机器和深度学习模型可以帮助您为您的业务和应用程序构建强大的工具,并为您的客户提供卓越的体验。创建这些“智能”功能需要大量的努力,但潜在的好处是值得的。只要确保您和您的数据科学团队尝试合适的模型并遵循良好的实践,您就将走上正轨,为您的业务和应用提供尖端的机器学习解决方案。

来源:

* [## Home - Keras 文档

Keras 是一个高级神经网络 API,用 Python 编写,能够运行在 TensorFlow、CNTK 或…

keras.io](https://keras.io/)

https://en.wikipedia.org/wiki/Unsupervised_learning

https://machinelearningmastery.com/what-is-deep-learning/

https://developer.nvidia.com/deep-learning

https://arxiv.org/abs/1707.07012

http://yifanhu.net/PUB/cf.pdf

https://towards data science . com/detecting-financial-fraud-using-machine-learning-three-way-winning-the war-against-balanced-a03f 8815 CCE 9

https://scikit-learn.org/stable/modules/tree.html

https://aws.amazon.com/deepcomposer/

https://blog . keras . io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras . html

https://keras.io/examples/imdb_bidirectional_lstm/

https://towards data science . com/how-do-self-driving-cars-see-13054 aee 2503

https://towards data science . com/r-CNN-fast-r-CNN-faster-r-CNN-yolo-object-detection-algorithms-36d 53571365 e

https://towards data science . com/building-a-next-word-predictor-in-tensor flow-e 7e 681d 4 f 03 f

https://arxiv.org/pdf/1707.07012.pdf

https://en.wikipedia.org/wiki/Unsupervised_learning

sklearn 软件包—适用于图表 1a、1b、2a、2b

keras 包—用于图像 2、3、4

draw.io —用于图像 1*

深度学习 vs 益智游戏

原文:https://towardsdatascience.com/deep-learning-vs-puzzle-games-e996feb76162?source=collection_archive---------28-----------------------

深度学习是否比古老的强力技术更适合解决流量自由?

我们都经历过。你无聊地玩着手机,有一些时间可以消磨,所以你决定——违背你更好的判断——访问 app store 的游戏部分,看看有什么趋势。你看到一个看起来很有趣的益智应用,但这并不重要,因为你只会玩半个小时,然后删除它并忘记它,对吗?

两个月后,我完成了 2000 多级的免流量,坚持在每一级都获得“完美”评级。这款游戏是自 2012 年发布以来 iOS 和 Android 上最受欢迎的手机游戏之一,它的前提非常简单:在 2D 网格上连接不同颜色的“阀门”,没有两条线相交:

自由流动——你可以从一张截图中很好地理解这个游戏

截图中的关卡看似简单,但确实越来越难。随着关卡的进展,我发现自己想出了一些策略来帮助我更快地解决这些高级关卡(例如,尽可能坚持最外面的未填充边界,避免创建未填充方块的“入口”,等等)。)浏览网络论坛,看到其他玩家都有自己的技术,有些和我的相似,有些不同。这就引出了一个问题——一台计算机,不是通过蛮力,而是通过“经验”,也能学习这些技术吗?

一个人类(你真正的)正在解决一个自由流动的难题

从基础开始:A*

如今的深度学习问题大多归结为决定使用哪种算法。我从搜索开始。即使它本身不是深度学习,它也让我们很好地了解了问题的内在复杂性,并让我们有机会尝试一些更高级的算法可以自己解决的启发式算法。

空间复杂度太大,无法一次解决整个棋盘,所以我从逐颜色递归解决开始(如果给定的路径被“阻塞”,则回溯到上一个颜色)。作为启发,我使用了可靠的曼哈顿距离。我在 4 种尺寸的电路板上测试了我的算法:小型(2x4)、小型(5x5)、中型(8x8)和大型(14x14)。我确保了中型和大型棋盘的颜色比普通棋盘少种,因为这实际上使谜题变得更加困难,对人类和计算机都是如此(更多可能的路径/选项/状态)。

这在小型电路板上运行良好,但需要相当多的时间。因此,我在下一个状态函数中添加了一些规则,希望强化学习算法能够自己找出这些规则:防止颜色相同的非连续相邻方块或空“入口”:

在我用了 7 年的电脑上的结果更令人鼓舞,但仍需要改进:

我很惭愧地说,我可能花了更多的时间在我的 Tkinter 绘图功能上,而不是实际的人工智能

如果你认为你是第一个这样做的人,你可能错了

在进入强化学习之前,我正在进一步优化我的 A*搜索,这时我发现了 Matt Zucker 的这篇优秀博客文章,他已经为 Flow Free 构建了一个 A求解器(很高兴看到我不是唯一一个痴迷于此的人),并且更加仔细地考虑了要从他的 A搜索中删除的州。更重要的是,他发现一个只有 6 条规则的简单 SAT 算法胜过了他非常先进的 A*搜索,并且用 SAT 得到了非常好的求解时间(甚至对于 14x14 的电路板也是亚秒)。

到目前为止,我们似乎都得出了同样令人沮丧的结论:对于这种类型的(非对抗性的、封闭的)益智游戏,简单的暴力技术将胜过基本的人工智能算法。

然而,停留在那里是没有用的。毕竟,启动这一探索的问题仍然存在:作为人类玩家,我们在玩了几个级别后,发现了更有效地击败流自由谜题的特定技术。为什么机器不能学习同样的技术?

线索强化学习

我非常兴奋能在 Flow Free 上尝试 Q-learning,因为这才是“人工智能”中的“我”真正开始发挥作用的地方。A*搜索的工作绝不是浪费时间,因为我们可以用它作为 Q 学习代理的状态-动作空间。我们认为状态空间是棋盘上哪些方格被哪种颜色占据,以及哪条路径(颜色)当前是“活动的”的组合。一个动作就是填充该路径的下一个方块。

学习代理在一开始犯了一些基本错误后,很快学会了如何解决小问题(1.5s 内迭代 100 次)——目前看起来不错。然而,在中型板上,在 10,000 次迭代之后仍然没有骰子,这花费了 10 分钟:

不完全是你听到“人工智能”时想到的

为了改善这一点,我开始摆弄那些帮助不大的标准 Q-learning 参数(学习率α、折现率γ、探索/开采率ε),于是我把注意力转向了奖励函数。除了玩实际的奖励之外,奖励函数本质上还有一个参数可以切换(或者有变得过于规定性的风险,这将违背整个机器学习练习):代理是否会因为解决了一条路径而不是整个谜题而获得奖励。不幸的是,这并没有带来多大的不同。

最后,很明显,该算法在较大的电路板上很难运行,仅仅是因为选项空间太大。与 A*搜索相比,Q-learning 确实在这种情况下有所帮助,因为它做出了更聪明的选择,但是仍然有太多的情况,即使在 10,000 次迭代之后,确切的 Q-learning 代理还没有看到。因此,下一个自然的步骤是:

近似 Q 学习

近似 Q 学习的应用非常吸引人,尤其是在游戏中。这个想法不是让代理在给定的状态下决定最佳行动,而是给它一些直观的特征,它可以在每一步快速计算,与确切的状态(棋盘的配置)无关,并让它决定哪些是最重要的。这可能是像 Pacman 这样的游戏中的游戏规则改变者(例如,根据到最近的小球和最近的幽灵的距离来决定你的下一步行动,而不是针对每个可能的状态的行动),或者当然是自由流动,其中可能的状态的数量对于精确的 Q 学习来说太多了,以至于没有效果。

权衡的结果是,现在由开发人员来选择“正确的”特性。我将列表缩小到我知道在许多情况下很重要的特征(例如,关闭每条路径的剩余曼哈顿总距离),以及一些我怀疑很重要(但没有办法证明)的特征,我会让算法找出这些特征。其中包括:

  • 关闭每条路径的剩余曼哈顿总距离
  • “圈数”
  • “盒子”的数量
  • 箱中阀门的数量
  • 没有阀门的盒子的数量(人们可以从逻辑上证明这种情况永远不会发生——我想看看算法是否能解决这个问题)
  • 一条路径是否“靠墙”(即,一条路径是否能粘住另一条相邻的路径)

不幸的是,有了这些特性,Q-learning agent 甚至不能解决小棋盘,即使在改变 Q-learning 参数之后。然而,看到它的运行是一个有趣的练习。例如,该算法给“没有阀门的盒子”附加了一个很大的负权重,这意味着它能够了解到,有一个没有阀门的盒子会导致谜题无法解决

近似 Q 学习检测更好的游戏策略

也许有了更大的谜题样本,它可以更好地学习实际解决它们,但我很兴奋地看到它实际上选择了什么是重要的。这是人工智能中一个迷人的现象,尤其是在游戏人工智能中非常普遍:即使一个算法不能赢得比赛,它也可以找到帮助人类更好地比赛的技术。

走向监督:卷积神经网络

起初,我对自由流动的监督方法的想法有偏见。首先,它需要一个大样本的解决流量免费游戏,很难在公共互联网上找到。第二,似乎最接近无流匹配的监督方法——神经网络——是一个臭名昭著的黑箱,它将排除练习中最有趣的部分:看到算法学习解决难题的技术。

然而,我在《走向数据科学》杂志上看到了希瓦·维尔马的一篇文章,他在文章中对数独做了一些非常类似的事情:本质上将数独棋盘视为图像,并使用卷积神经网络(CNN)来解决它。作者在数独上取得了很好的结果,这让我重新审视了我最初的保留意见,并尝试了这种无流量的方法。

当然,第一个障碍是获取输入数据;以可解析文本格式解决的自由流谜题比数独谜题更难找到。我一开始发现的最好的方法是查看 Android 应用程序的代码,它有一千多个以文本格式存储的谜题:

CNN 的最初结果令人失望:测试样本中只有 0%的谜题被解决,尽管 CNN 正在学习它应该制作路径,而不仅仅是孤立地填充颜色。

我们需要更多的数据

调整层、时代、内核大小和其他类似的常见问题没有多大帮助。看起来我们又回到了数据科学家最常见的问题上:如果没有足够的数据,世界上最好的算法就什么也不是。我找到的最好的其他数据来源是 www.flowfreesolutions.com,有数以千计的全新谜题的免费解答,但都是图片格式的。

尽管我多次尝试通过各种渠道与他们联系(甚至提供了经济激励),我还是无法让他们给我发送他们解决方案的可解析文本版本。嗯,这不是一篇没有意义的人工智能文章——当一个人拥有现代图像处理时,谁还需要底层的解决方案矩阵?提示一个子项目来构建一个无流解决方案图像处理器:

sci kit-图像 FTW

利用对称性来增加我们可用的数据

这又产生了几千个数据点,但这仍然不多。但我随后意识到,就 CNN 而言,颜色的确切值并不重要,重要的是颜色不同的事实。因此,我们可以改变周围的颜色,仍然有另一个非冗余数据点。即使 5x5 电路板有多达 6 种不同的颜色,这给我们的 CNN 多达 6 种!=要处理的数据点增加了 720 倍(当然,更大的电路板和更多颜色的组合可供选择):

数学家将从群论中认识对称群 S_n

有朋友指出,这其实是游戏 AI 中常用的增加数据点的方法。有了 720 倍的数据点,我们终于取得了一些进展——在我 7 岁的 GPU 上运行 20 个时期的模型,大约 200,000 个数据点,测试数据的准确率为 12%。请注意,我们在这里使用了一个严格的成功标准:即使电路板差了一个单元,我们也认为这是一次失败。

然而,这里的失败比成功有趣得多。在几乎所有的失败中,CNN 正确地解决了大部分问题,足以让人类轻松完成。从这个意义上说,CNN 能够解决文章的原始前提:直观地学习人类的技术:

CNN 的误差分布

结论

  • 简单的方法通常更适合解决基于网格的、非对抗性的益智游戏。事实上,随着方法逐渐变得更先进,性能变得更差。
  • 然而,尽管更先进的 ML 方法不会很快解决这个难题,但它们确实找到了有趣的见解,并帮助人类找到更好的解决方案——卷积神经网络在这方面做得最好。此外,它们的性能比更传统的解决方案更具扩展性。
  • 更好的数据胜过更好的算法。

更进一步:读者和编辑建议

我请一些更有经验的人工智能/人工智能专家(非常感谢马特·祖克优素福·基鲁兹马克·萨鲁菲姆)来评论这篇文章,他们建议尝试以下想法来改进 CNN 算法。这可能是第 2 部分文章的主题,或者您可以在 https://github.com/kgaspard/flow-free-ai上随意尝试一下(以及本文中详述的方法):

  • 改变 CNN 的层数(消融似乎没有帮助)
  • 除了使用对称来增加我们的数据点,还使用旋转/反射
  • 使用 CNN 预测作为强化学习代理的特征

使用 CIFAR-10 进行深度学习

原文:https://towardsdatascience.com/deep-learning-with-cifar-10-image-classification-64ab92110d79?source=collection_archive---------9-----------------------

基于 CNN 的图像分类

神经网络是可编程的模式,有助于解决复杂的问题,并带来最佳的可实现的输出。我们都知道深度学习比机器学习领先一步,它有助于训练神经网络来获得未回答问题的解决方案或改进解决方案!

在本文中,我们将使用 CIFAR-10 数据集实现一个深度学习模型。数据集通常用于深度学习,用于测试图像分类的模型。它有 60,000 幅彩色图像,包括 10 个不同的类别。图像大小为 32×32,数据集包含 50,000 幅训练图像和 10,000 幅测试图像。人们可以在这里找到 CIFAR-10 数据集

导入数据

深度学习模型需要具有高计算能力的机器。一般建议使用类似 Kaggle 或 Google Collaboratory 的在线 GPU。我已经在谷歌合作实验室实施了该项目。对于这个项目,我们将使用 TensorFlow 和 matplotlib 库。由于数据集是全局使用的,因此可以直接从 TensorFlow 库的 keras 模块导入数据集。

import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import cifar10 

数据预处理

任何机器学习、深度学习或数据科学项目的第一步都是对数据进行预处理。我们将定义类的名称,数据集分布在这些类上。大小为 32x32 的彩色图像有 10 种不同的类别。一旦我们设置了类名。我们需要标准化图像,以便我们的模型可以更快地训练。彩色图像的像素范围是 0–255。我们将图像的每个像素除以 255,因此像素范围将在 0-1 之间。实际上,我们将把它除以 255.0,因为它是一个浮点运算。对于该模型,我们将使用卷积神经网络(CNN)。

# setting class names
class_names=[‘airplane’,’automobile’,’bird’,’cat’,’deer’,’dog’,’frog’,’horse’,’ship’,’truck’]x_train=x_train/255.0
x_train.shape
x_test=x_test/255.0
x_test.shape

在 shape 的输出中,我们看到 4 个值,例如(50000,32,32,3)。这 4 个值如下:第一个值,即(50,000/10,000)表示图像的数量。第二个和第三个值显示图像大小,即图像高度和宽度。这里的图像大小为 32x32。第四个值显示“3”,它显示 RGB 格式,因为我们使用的图像是彩色图像。

建立 CNN 模型

CNN 模型分三个阶段工作。在第一阶段,卷积层提取图像/数据的特征。在第二阶段,池层减少了图像的维度,因此小的变化不会对模型产生大的变化。简单地说,它防止过度拟合。在第三阶段,展平层将我们的模型转换为一维,并将其提供给完全连接的致密层。这个密集层然后执行图像预测。一个好的模型有多层卷积层和池层。

CNN 架构(图片由作者提供,灵感来自https://debugger cafe . com/convolutionary-neural-network-architectures-and-variants/

在创建神经网络模型时,一般使用两种 API:顺序 API功能 API顺序 API 允许我们逐层创建模型,并将其添加到顺序类中。顺序 API 的缺点是我们不能用它来创建一个模型,在这个模型中我们想要使用多个输入源并在不同的位置得到输出。为了克服这个缺点,我们使用函数式 API。通过使用功能 API 我们可以创建多个输入和输出模型。但是,在大多数情况下,使用的是顺序 API 。我们将为我们的 CNN 模型使用顺序 API

cifar10_model=tf.keras.models.Sequential()
# First Layer
cifar10_model.add(tf.keras.layers.Conv2D(filters=32,kernel_size=3, padding=”same”, activation=”relu”, input_shape=[32,32,3]))

我们使用卷积神经网络,因此我们将使用卷积层。最常用和我们正在使用的层是 Conv2D。Conv2D 表示卷积发生在 2 轴上。它将卷积扩展到三个层次,红色、绿色和蓝色。另一类卷积层是 Conv1D。Conv1D 一般用于“文本”, Conv2D 一般用于“图像”。我想大多数读者都知道什么是卷积以及如何做,但是这个视频将帮助你清楚卷积在 CNN 是如何工作的。

Conv2D 层的参数

第一个参数是 【滤镜】 。号码。滤波器的值表示 CNN 模型和卷积层将从中学习的滤波器的数量。从每个这样的过滤器,卷积层学习一些关于图像,像色调,边界,形状/特征。参数的值应该是 2 的幂。

第二个参数是“”。内核指的是一个过滤器,它将在图像中移动,并使用点积提取零件的特征。内核大小是指过滤器的尺寸(高 x 宽)。内核大小的值通常是奇数,例如 3,5,7..等等。这里我们使用的内核大小为 3,这意味着过滤器大小为 3 x 3。

下一个参数是“。有两种类型的填充,同样&有效。在有效填充中,图像边界上没有零填充。因此当卷积发生时,会有数据丢失,因为一些特征不能被卷积。在相同的填充中,在图像的所有边界上都填充了一层零,因此没有数据丢失。此外,卷积后图像输出的维数与图像输入的维数相同。上述是这种衬垫命名的原因。因为在初始层中我们不能丢失数据,所以我们使用了相同的填充。

图像和填充(作者提供的图像)

使用深度学习模型的原因是为了解决复杂的功能。为了得到更好的输出,我们需要以过于复杂的方式来拟合模型,因此我们需要使用能够解决模型的非线性复杂性的函数。这是通过使用激活层来完成的。在任何深度学习模型中,最少需要一个具有 激活功能 的层。激活函数的工作是给模型添加非线性。如果我们不添加这一层,模型将是一个简单的线性回归模型,不会达到预期的结果,因为它无法拟合非线性部分。

有 4 个著名的激活功能:

  1. )Sigmoid 函数:取值范围在 0 到 1 之间。该图是一个陡峭的图,所以即使是很小的变化也能带来很大的不同。它主要用于二元分类,因为当值高于或低于 0.5 时可以很容易地进行划分。

Sigmoid 函数的图形(图片由作者提供,创建于https://www . maths isfun . com/data/function-grapher . PHP # functions)

2.)双曲正切函数:是正切双曲函数的缩写。它是 Sigmoid 函数的衍生函数。这些激活函数背后的数学原理超出了本文的范围,所以我不会跳到这里。该值的范围在-1 到 1 之间。

双曲正切函数图(图片由作者提供,创建于https://keisan.casio.com/exec/system/1223039747?lang=en&charset = utf-8&var _ x = TanH % 28x % 29&ketasu = 14

3.)ReLu 函数:是整流线性单元的缩写。是深度学习最著名的激活。这是著名的,因为它更容易计算,因为数学函数比其他激活函数更容易和简单。

ReLu 函数的图形(图片由作者提供,创建于https://www . maths isfun . com/data/function-grapher . PHP # functions)

4.)SoftMax 函数:SoftMax 函数是 Sigmoid 函数的更多阐明形式。它用于多类分类。该函数计算函数中特定类的概率。因此,该函数的输出值范围在 0 到 1 之间。Sigmoid 函数和 SoftMax 函数的主要区别在于,Sigmoid 函数可用于二分类,而 SoftMax 函数也可用于多分类。

汇集层

*#MaxPoolingLayer
cifar10_model.add(tf.keras.layers.MaxPool2D(pool_size=2,strides=2, padding=’valid’))*

池层用于减小图像的大小,同时保留角色中的重要参数。这样有助于减少模型中的计算量。在执行卷积时,卷积层保留了关于特征的确切位置的信息。因此不太重要的特征也被完美地定位。因此,我们会遇到一个问题,即使是像素或特征的微小变化也会导致模型输出的巨大变化。通过最大池化,我们缩小了所有特性的范围,只考虑最重要的特性。因此,上述问题得以解决。池化有两种方式:平均池化或最大池化。通常使用最大池。

平均池(图片由作者提供,灵感来自https://people . mines Paris . PSL . eu/fabien . moutarde/ES _ machine learning/TP _ conv nets/conv net-notebook . html)

在平均池中,取池大小的平均值。在最大池中,取池大小的最大值。这个概念将从上面和下面的图像中被清除。

Max Pooling(图片由作者提供,灵感来自https://people . mines Paris . PSL . eu/fabien . moutarde/ES _ machine learning/TP _ conv nets/conv net-notebook . html)

池大小是指将取其最大值的过滤器的大小。这里的池大小 2 表示将使用 2x2 的池,在该 2x2 池中,平均值/最大值将成为输出。池将穿过图像。它将根据步幅值移动。

步幅意味着泳池的大小能跳多远。如果步幅为 1,2x2 池将从一列逐渐向右移动到另一列。我使用了 stride 2,这意味着池大小将一次移动两列。我前面用来解释最大池化和平均池化的图像的池大小为 2,步幅= 2。

在池中,我们使用填充“有效”,因为我们准备丢失一些信息。因为池的功能是减少图像的空间维度并减少模型中的计算。

最后一层

*# Flattening Layer
cifar10_model.add(tf.keras.layers.Flatten())*

在卷积层和汇集层的堆叠之后添加了展平层。展平层将 3d 图像矢量转换为 1d。因为在前面提到的层的堆叠之后,添加了最终的完全连接的致密层。现在,密集层要求数据以一维方式传递,因此扁平化层是最重要的。

平整层的工作(图片由作者提供)

展平一层后,还有一层致密层。致密层是一个完全连接的层,将先前功能的所有输出提供给所有神经元。密集层具有权重 W、偏差 B 和传递给每个元素的激活。用一种清晰的方式说,它把所有的点连接起来。这一层使用之前提取的所有特征,并完成训练模型的工作。提到的单位显示了模型将要使用的神经元的数量。

*# Droput Layer
cifar10_model.add(Dropout(0.2))
# Adding the first fully connected layer
cifar10_model.add(tf.keras.layers.Dense(units= 128,activation='relu’))*

现在,为了防止过度拟合,增加了一个脱落层。在数据训练期间,一些神经元被随机禁用。传递给神经元的值意味着在一次迭代中想要丢弃的神经元的比例。因此,在训练之后,神经元不会受到其他神经元的权重的很大影响。因此该模型可以更好地推广。

辍学层的工作(图片由作者提供,灵感来自https://people . mines Paris . PSL . eu/fabien . moutarde/ES _ machine learning/TP _ conv nets/conv net-notebook . html

输出层

在输出中,图层根据数据集中的类数量使用单位数量。这里我们用 10,因为有 10 个单位。在输出中,我们使用 SOFTMAX 激活,因为它给出了每个类的概率。

在编制模型时,我们需要考虑损失函数。通常使用两种损失函数,稀疏分类交叉熵(scce)和分类交叉熵(cce)。稀疏分类交叉熵(scce)在类别互斥、类别完全不同时使用。当一个标签或部分可以有多个类别时,使用分类交叉熵。在我们的场景中,类是完全不同的,所以我们使用稀疏分类交叉熵。

我们将使用普遍使用的 Adam 优化器。Adam 是“自适应学习率法”的缩写。这个优化器使用梯度的初始值来适应学习速率。现在使用 Adam 代替 ML 中使用的随机梯度下降,因为它可以在每次迭代后更新权重。

玩了一会儿 epochs 后的最终输出是:

使用这个模型,我能够得到 78%的准确率。因此,在本文中,我们将使用 Google Collaboratory 完成深度学习项目。我们了解卷积神经网络的卷积层和池层中使用的参数。在 CNN 中提取特征后,我们需要一个密集层和一个 dropout 来实现识别图像的这一特征。最后,我们看到了一些损失函数和亚当优化。

您可以在我的 git 资源库中找到完整的代码:https://github.com/aaryaab/CIFAR-10-Image-Classification

*请随时联系我,电话:【https://www.linkedin.com/in/aarya-brahmane-4b6986128/ *

参考资料:你可以在找到并制作一些有趣的图表

图形图像是我在 Power point 上制作的。

快乐深度学习!

和平!!

用容器进行深度学习。第一部分

原文:https://towardsdatascience.com/deep-learning-with-containers-part-1-4779877492a1?source=collection_archive---------15-----------------------

照片由 Antoine Petitteville 在 Unsplash 上拍摄

TL;速度三角形定位法(dead reckoning)

容器是在主机计算环境中独立运行的轻量级软件包。使用集装箱化的环境进行研究是有帮助的,因为它们易于使用,可重复,并保持您的主要系统干净。您可以使用 Docker Compose 轻松设置一个功能完整的多容器应用程序。所有需要的脚本都可以在这里找到。

更新 02/2021: 该系列的第二部分可在这里

为什么是集装箱?

当进行深入研究时,有时很难维持你周围正在发生的事情。大量包含数据的文件,几十个你不用但又不确定能清除它们的库,保存在你主目录中某处的临时文件,应有尽有。虚拟环境有所帮助,但作用不大。您仍然必须管理它们,并且可能会以同样混乱的位置结束,但是环境的数量会成倍增加。在设置我的笔记本电脑以处理深度 NLP 模型时,我想到了创建易于使用且完全一次性的实验环境的方法——容器。它们让我只需一个命令就可以设置带有 Tensorboard 跟踪功能的 Jupyter 笔记本。用另一个命令,我可以把这些都拉下来,而不用担心留在内存或硬盘上的东西。在这篇文章中,我将描述如何在您的系统中设置和部署深度学习的容器,在下一篇文章中,我将展示如何扩展特定任务的基本图像——使用拥抱面部变形器的连体学习。

我使用的堆栈如下:

  • Docker 。创建容器的平台和软件。该领域事实上的标准工具。
  • PyTorch 带 GPU 支持。我选择的框架,简直太棒了。
  • Jupyter 笔记本。支持在浏览器中进行交互式开发的软件。
  • 张量板。实验跟踪的良好起点。从那你可以切换到快板 AI重量&偏差
  • 抱脸。简单地说,你可以得到基于变压器和其他架构的最先进模型的最佳方式。

容器

如果你不熟悉容器的概念,阅读一些介绍性的文章(例如来自 DockerGoogle )并浏览覆盖基础知识的教程会是一个好主意。

我们现在将创建两个容器—一个用于 Jupyter Notebook,另一个用于 Tensorboard。我们从 Tensorboard 容器开始,因为它非常小,容易理解。以下是它的完整版本:

*# Use small image with Python pre-installed.*
**FROM** python:3.8-slim-buster
*# Install tensorboard*
**RUN** pip3 install tensorboard

为了运行和操作 Tensorboard,我们不需要任何东西,除了它的包。您现在可以将这个文件保存为tensorboard.Dockerfile,构建容器(docker build -t dl-tensorboard:latest -f tensorboard.Dockerfile .)并使用命令docker run --rm -it dl-tensorboard:latest /bin/bash交互运行它,命令tensorboard将可供运行。但是它不会自己运行,它需要一个存储实验运行数据的目录。我们将在稍后的服务设置阶段处理它。

下一部分是用 Jupyter 笔记本建立一个图像。这里有相当多的细微差别。首先,我们将与深度学习合作,因此我们的容器中需要一个 GPU 支持。幸运的是,NVIDIA 用他们的容器工具包覆盖了我们。经过几个简单的步骤,您就可以随意使用支持 GPU 的 Docker 容器了。NVIDIA 的另一个非常有用的项目是一组安装了 CUDA 的预建图像。几个版本的 Ubuntu 之前,安装 NVIDIA 驱动程序和 CUDA 是一个巨大的痛苦。现在容易多了,但是有了这些图像,你不需要做任何与 CUDA 设置相关的事情,这很酷。

到写这篇文章的时候,PyTorch 已经支持 CUDA 10.2 版本了,所以我们将使用 NVIDIA base image 搭配 CUDA 10.2。此外,NVIDIA 提供了三种风格的图像— baseruntimedevel。我们的选项是runtime,因为包含了 cuDNN。

下一个有趣的点是,我们将执行我们的映像的多阶段构建。这意味着在构建过程中,我们将有一个封装了所有与设置相关的逻辑的基础映像,以及一个根据手头的任务添加收尾工作的最终映像,例如安装额外的包或复制所需的文件。这个逻辑将允许我们在 Docker 缓存中保存一个基础映像,这样就不需要每次添加新的包时都下载 PyTorch。毫无疑问,我们可以通过在 Dockerfile 中现有的行之后添加新的行,并且不打乱已经添加的行的顺序(因为Docker 缓存的工作方式)来实现相同的目的,而不需要多阶段构建,但是这种方法给出了责任分工,易于操作,并且为我们将在下一篇文章中讨论的更多高级场景奠定了基础。

在我们进入 Jupyter 图像的 docker 文件之前,我想澄清几个问题。首先,由于我们使用 NVIDIA CUDA 映像作为基础,我们将需要安装 Python 和一些必需的工具。第二,由于已知问题,不可能在容器中运行笔记本二进制程序。前一段时间,需要在 docker 文件中设置 Tini,如链接中所述。但是现在 Tini 已经内置到 Docker 中,所以不需要任何额外的设置,只需在运行容器时添加--init标志。稍后我们将看到如何将它合并到 Docker compose 中。

最后,我们可以看看 Jupyter 笔记本图像的实际 docker 文件:

*# NVIDIA CUDA image as a base*
*# We also mark this image as "jupyter-base" so we could use it by name*
**FROM** nvidia/cuda:10.2-runtime AS jupyter-base
**WORKDIR** /
*# Install Python and its tools*
**RUN** apt update && apt install -y --no-install-recommends **\
**    git **\
**    build-essential **\
**    python3-dev **\
**    python3-pip **\
**    python3-setuptools
**RUN** pip3 -q install pip --upgrade
*# Install all basic packages*
**RUN** pip3 install **\
**    *# Jupyter itself*
    jupyter **\
**    *# Numpy and Pandas are required a-priori*
    numpy pandas **\
**    *# PyTorch with CUDA 10.2 support and Torchvision*
    torch torchvision **\
**    *# Upgraded version of Tensorboard with more features*
    tensorboardX

*# Here we use a base image by its name - "jupyter-base"*
**FROM** jupyter-base
*# Install additional packages*
**RUN** pip3 install **\
**    *# Hugging Face Transformers*
    transformers **\
**    *# Progress bar to track experiments*
    barbar

记住之前描述的一切,脚本非常简单——获取 NVIDIA CUDA 映像,安装 Python,安装基本包,使用所有这些作为最终映像的基础,并根据具体问题添加一些额外的包。

服务

创建环境的最后一步是在 Docker Compose 的帮助下,将两个图像组合成完整的多容器应用程序。该工具允许创建一个 YAML 文件,该文件包含构成应用程序的服务的描述。这是一个很好的工具,主要关注单主机部署,这正是我们的用例。撰写本文时 Compose 的一个主要缺点是缺乏 GPU 支持,尽管 Docker 和它的 API 已经实现了这个特性。但是有一个解决方法支持在组合服务中使用 GPU。我已经将集成到最新发布的 Compose 中,并计划维护它,直到 GPU 和其他设备请求得到支持。在这方面,您需要安装 Compose 的这个分支,以便能够运行服务。

让我们看看docker-compose.yml文件:

**version**: "3.8"
**services**:
    **tensorboard**:
        **image**: dl-tensorboard
        **build**:
            **context**: ./
            **dockerfile**: tensorboard.Dockerfile
        **ports**:
            - ${TENSORBOARD_PORT}:${TENSORBOARD_PORT}
        **volumes**:
            - ${ROOT_DIR}:/jupyter
        **command**:
            [
                "tensorboard",
                "--logdir=${TENSORBOARD_DIR}",
                "--port=${TENSORBOARD_PORT}",
                "--bind_all",
            ]

    **jupyter-server**:
        **image**: dl-jupyter
        **init**: **true**
        **build**:
            **context**: ./
            **dockerfile**: jupyter.Dockerfile
        **device_requests**:
            - **capabilities**:
                - "gpu"
        **env_file**: ./.env
        **ports**:
            - ${JUPYTER_PORT}:${JUPYTER_PORT}
        **volumes**:
            - ${ROOT_DIR}:/jupyter
        **command**:
            [
                "jupyter",
                "notebook",
                "--ip=*",
                "--port=${JUPYTER_PORT}",
                "--allow-root",
                "--notebook-dir=${JUPYTER_DIR}",
                '--NotebookApp.token=${JUPYTER_TOKEN}'
            ]

这里有很多东西需要解开。首先,定义了两个服务— tensorboardjupyter-serverimage部分定义了将为服务构建的映像的名称。build部分定义了一个路径,指向将用于构建映像的目录或带有 Dockerfile 的存储库。在ports部分,我们指定主机的哪些端口将暴露给容器。这里事情变得有趣了——我们看到的不是数值,而是环境变量的名称。Docker compose 从一个名为.env的特殊文件中获取这些变量,用户在该文件中列出了在合成过程中必须使用的所有变量。这允许有一个单独的位置来存储不同环境中不同的合成脚本的所有部分。例如,一台机器上用于 Tensorboard 的端口可以被另一台机器占用,这个问题可以通过更改.env文件中TENSORBOARD_PORT变量的值来轻松解决。

对于我们的场景,.env文件如下所示:

ROOT_DIR=/path/to/application/root/directory *# path on the host*
JUPYTER_PORT=42065
JUPYTER_TOKEN=egmd5hashofsomepassword
JUPYTER_DIR=/jupyter/notebooks               *# path in the container*
TENSORBOARD_PORT=45175
TENSORBOARD_DIR=/jupyter/runs                *# path in the container*

ROOT_DIR是一个目录,将存储我们的应用程序所需的所有信息(笔记本、数据、运行历史)。从docker-compose.yml中的volumes部分可以看到,这个目录作为/jupyter安装到两个容器中,这解释了为什么JUPYTER_DIRTENSORBOARD_DIR变量都有这个前缀。文件中的其他变量定义了要公开的端口和用于身份验证的 Jupyter Notebook 的令牌。

服务定义的command部分包含一组参数,这些参数组合成一个命令,将在容器启动时执行。为了解决笔记本二进制文件的上述问题,我们为 Jupyter 服务添加了init: true。我们还使用部分env_file将环境变量从.env文件传递到 Jupyter 笔记本的容器中。这是因为我们将在笔记本中使用这些变量,细节将在下一篇文章中介绍。服务定义的最后但并非最不重要的特性是一个device_requests部分。这正是使 GPU 在容器内部可用的解决方法。没有它,你将无法在多容器应用程序中享受顶级 NVIDIA 卡的强大功能。

最后,我们得到工作目录的如下结构:

├── .env                     *# File with environment variables.*
├── docker-compose.yml       *# Compose file with services.*
├── jupyter.Dockerfile       *# Dockerfile for the Jupyter image.*
├── tensorboard.Dockerfile   *# Dockerfile for the Tensorboard image.*

完成所有设置后,您终于可以在我们的工作目录中运行docker-compose up -d了。在下载了所有基本映像并安装了所有必需的包之后,两个容器都应该启动并运行了。第一次启动需要相当长的时间,但是接下来的会非常快——即使你在最终映像中安装了新的包,所有下载和安装基础包的繁重工作都会被跳过。当你完成工作后,只要运行docker-compose down所有的容器就会消失,让你的系统保持干净,为其他有趣的事情做好准备,比如在 Go 中开发分布式系统或者在 COMSOL 中运行复杂的物理模拟。

结论

在这篇文章中,我们看了一个例子,如何用 Jupyter Notebook、PyTorch 和 Tensorboard 建立一个可用于深度学习研究的容器化环境。在下一篇文章中,我们将深入探讨如何将这种环境用于一个真实的用例——新闻的几个镜头分类的暹罗学习。这篇文章的主要摘录:

  1. 使用多阶段构建,其中基础映像完成一次性的重要工作,最终映像根据您的需求定制环境。你知道,就像微调。
  2. Docker Compose 不支持将 GPU 绑定到容器。但如果你真的想,它会的。

利用 NGC 的 docker 容器进行深度学习——英伟达 GPU 云

原文:https://towardsdatascience.com/deep-learning-with-docker-container-from-ngc-nvidia-gpu-cloud-58d6d302e4b2?source=collection_archive---------15-----------------------

有一个基本的复制粘贴操作指南

docker 容器:)图片来自 pixabay

不再为深度学习环境的安装而烦恼。不再与 Cuda 版本和 GCC 编译器争斗。欢迎来到码头工人时代。你所需要的只是一个带有最新 Cuda 驱动程序的 Unix 系统。你只需要从 NGC 云下载一个 docker,它包含了你需要的环境和所有的 Cuda 代码。

其实写完这个帖子,发现自己用的越来越多了。由于我的主要工作是对医疗(高度安全)数据进行深度学习,所以我大量使用 dockers。当你必须在没有互联网的服务器上工作时(是的,没有 StackOverflow 这很痛苦),docker 就是你的救星:)。您在正常环境中准备您的工作环境,然后您/系统管理员将其迁移到服务器。我现在正在探索的一个有趣的优势是用 git 库、手册等来丰富您的环境。我将在这里更新我发现的方法。

这里我们将使用 Python 3 和 TensorFlow 1.9,但也有带有 Pytorch、Caffe、trained model 等的 dockers。

英伟达云图片来自英伟达云网站

获得自己的 Nvidia Docker

转到https://ngc.nvidia.com/catalog/all。选择“容器”标签,查看所有可用的容器。我选择了 TensorFlow 容器:

Nvidia cloud 上的 TensorFlow 容器

可以直接从云端使用,用:nvcr.io/nvidia/tensorflow: 19.12-tf2-py3一个 TensorFlow2 docker。或者在您创建帐户并登录后下载它。

要下载 TensorFlow2 docker,请使用 pull 命令:

docker pull nvcr.io/nvidia/tensorflow:20.10-tf2-py3

下载 docker 需要一些时间。

启动 docker 容器

列出所有可用的本地 docker 图像

$ sudo docker images

**docker run --rm -it --runtime=nvidia --net=host -v <local dir>:<destination dir> <Image id>**

例如,对于本地码头,使用:

**docker run --rm -it --runtime=nvidia --net=host -v /my_server_dir/:/naomi** 989143febb16

或者使用 Nvidia cloud 的 docker:

docker run --gpus all -it --rm -v local_dir:container_dir nvcr.io/nvidia/tensorflow:19.12-tf2-py3

其中:

  • -it表示以交互方式运行
  • --rm完成后会删除容器
  • -v是挂载目录
  • local_dir是您希望从容器内部访问的来自主机系统的目录或文件(绝对路径)。container_dir是您在容器中时的目标目录。举个例子,

比如下面路径中的local_dir/home/jsmith/data/mnist ,目标目录是:/data/mnist

-v /home/jsmith/data/mnist:/data/mnist

例子取自:https://ngc.nvidia.com/catalog/containers/nvidia:tensorflow

停止码头集装箱

# list running dockers:
$ docker ps# Find the docker container id, then run:docker kill <container id>

附加到正在运行的 docker 容器

当您想在 docker 中从外部运行一个命令时,您可以使用 exec,它允许您告诉正在运行的 docker 运行一个特定的命令。例如,当您失去管理 docker 的命令行窗口时,您可以使用 exec 在 docker 中运行命令行环境。这样,您可以附加到正在运行的 docker 容器。例如,使用下面的命令在 docker 容器中创建一个 shell。

**docker exec -it <container id> /bin/bash**

将包和数据添加到 Docker 容器中

当您在 docker 容器“内部”时,您是在 linux cmd 空间中。比如可以用 pip 安装 python 包,也可以上传数据。这个选项对于在没有互联网的服务器上处理安全数据的人来说非常有用,就像我在医疗行业一样。这样你就可以准备好你需要的一切,然后提交并传输到你的封闭服务器上。

如果你使用 Nvidia docker 容器,它没有 jupyter。您可以通过以下方式安装它:

**pip install jupyter**

在 docker 容器上运行 Jupyter 笔记本

如果你在一个图形用户界面环境中,像 RDP,你可以很容易地运行 jupyter 笔记本,只需做如下。如果您在服务器上只有 cmd,就像在 mobaxterm 中一样,那么就需要更多的步骤,这些步骤是在前面几节中指定的。

用以下命令启动笔记本:

**jupyter notebook --ip 0.0.0.0 --allow-root**

在您的浏览器中,键入: http:// <服务器 ip > :8888/?令牌= <令牌>。在我们的案例中:

[http://100.200.15.20](http://192.168.15.20/):8888/?token=2a0630188ca7bc5b99d2c5b7923e2a2ebe391bc15a4bc3f1

复制 cmd 中给出的令牌。

如果端口 8888 被占用,或者有其他原因需要绑定端口,ise:

**jupyter-notebook --ip 0.0.0.0 --allow-root --port 5080**

然后使用地址:

[http://100.200.15.20](http://192.168.15.20/):**5080**/?token=2a0630188ca7bc5b99d2c5b7923e2a2ebe391bc15a4bc3f1

或者

[http://](http://192.168.15.20/)**0.0.0.0**:**5080**/?token=2a0630188ca7bc5b99d2c5b7923e2a2ebe391bc15a4bc3f1

使用笔记本安装软件包和其他后端人员非常方便。就用!命令行的开头,并在单独的单元格中运行每个命令行。例如:

! pip install keras

要在 docker 映像中保存您的安装,不要忘记提交 docker。

提交码头工人

提交一个 docker,将为您的所有安装创建一个新的 docker。

docker commit <docker container id> <new docker name>:<docker tag>

例如,使用以下命令提交 docker:

docker commit   9571cb71d812 naomi/brats:version2

将创建一个 docker 映像,运行“docker images”时将如下所示:

Docker —基本摘要

一篇没有复制粘贴的文章有什么价值呢:)

**# run
docker run --rm -it --runtime=nvidia --net=host -v <local dir>:<destination dir> <docker Image id>****# list available dockers
docker images****# list running docker
docker ps****# attach to a running docker
docker exec -it <container id> /bin/bash****# run notebook
jupyter notebook --ip 0.0.0.0 --allow-root****# commit a docker
docker commit <docker container id> <new docker name>**

更多关于使用 dockers 和每个标志的含义的解释可以在这里找到:https://ngc.nvidia.com/catalog/containers/nvidia:tensorflow

下面是一些不太常见但却是必需的场景。

从 Mobaxterm 运行 Jupyter 笔记本

这个想法是在 cmd 上运行 jupyter 命令,并在本地机器上打开笔记本。这需要 ssh 隧道,如下所述:

Windows 端首先,生成 ssh 密钥:https://phoenixnap.com/kb/generate-ssh-key-windows-10,这个过程会在你的本地电脑上创建一个文件。

Mobaxterm 端打开隧道菜单来定义你的隧道。

Mobaxterm ssh 隧道

假设你的远程服务器是 52.522.52.522,你的用户名是naomi,你选择了 1200 作为端口(你可以选择任意一个 antaken 号),填写下面,保存。

保存并添加您之前创建的 ssh 密钥,在密钥图标中:

为隧道和 ssh 会话添加 ssh 密钥

窗口端在 Powershell 中以管理员身份运行以下命令

**ssh -NL 1200:localhost:1200 naomi@**52.522.52.522

Mobaxterm side 在 Mobaxterm cmd 窗口中运行以下命令:

jupyter notebook — no-browser — port 1200

将您从输出中获得的地址复制到本地 windows 机器上的 chrome 或类似设备中,您就可以在笔记本中工作了:

[http://127.0.0.1:1200/?token=36401f7dada8b4cb5eb2d15b70ac3e4963633e7dd5b922d1](http://127.0.0.1:1250/?token=36401f7dada8b4cb5eb2d15b70ac3e4963633e7dd5b922d1)

重新连接到正在运行的 Jupyter 笔记本

深度学习训练通常需要很长时间。因此,在大多数情况下,当在远程服务器上工作时,连接被关闭,笔记本的令牌丢失。要查找正在运行的笔记本的令牌,请执行以下操作:

# use -mtime -30 to list only notebooks that started in the last 30 days.find `jupyter --runtime-dir` -mtime -30 | grep nbserver | xargs cat

您将看到如下内容:

...
<body><p>
    This page should redirect you to Jupyter Notebook. If it doesn't,
    <a href="[http://0.0.0.0:8888/tree?token=7caaccce4fb4e670d9053b67c773e93c4a6ceb128fde2f56](http://0.0.0.0:8888/tree?token=7caaccce4fb4e670d9053b67c773e93c4a6ceb128fde2f56)">click here to go to Jupyter</a>.
</p>
...

只需将地址(将 0.0.0.0 更改为您的服务器 IP 或 localhost)复制到您的浏览器,即可重新打开正在运行的笔记本。

用户问题

在 docker 容器中,你是你的王国的国王,你是根用户,我猜这是安装所需要的。即使您没有 root 密码,您编写的文件也会在磁盘上获得 root 所有权。删除您在容器中创建的文件只能通过 root 密码或 docker 来完成。我还没想明白。如有真知灼见,不胜感激。

安装 Docker 引擎

如果您需要安装新的 docker 引擎,请遵循此处的说明。为了方便起见,我将添加推荐方法的简短摘要。

使用存储库安装

对于主机:焦点 Ubuntu 20.04 LTS,版本:20.04。x86_64 / amd64。

# Set up the repository
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common# Add Docker’s official GPG key:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -# set up the **stable** repository
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

安装 Docker 引擎

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

启动 docker 守护进程

sudo dockerd

用 Jax 和 Elegy 进行深度学习

原文:https://towardsdatascience.com/deep-learning-with-jax-and-elegy-c0765e3ec31a?source=collection_archive---------16-----------------------

照片由张秀坤镰刀Unsplash 上拍摄

超越张量流、Pytorch 和 Keras

在这篇文章中,我们将探索如何利用 JaxElegy 来创建深度学习模型。在这个过程中,我们将看到 Jax 如何与 TensorFlow 和 Pytorch 相比较,以及 Elegy 如何与 Keras 相比较。

Jax 是什么?

毫无疑问,TensorFlow (2015)和 Pytorch (2016)在 ML 社区中产生了巨大的影响,他们之间的“军备竞赛”使他们收敛到一组类似的功能(查看 ML 框架 2019 年的状态,可以很好地总结他们的斗争)。Jax (2018)是最新加入的一员,它很好地体现了这种融合。但是 Jax 没有直接成为一个深度学习框架,而是创建了一个超级完美的线性代数库,具有自动微分和 XLA 支持,一些人将其称为类固醇上的 Numpy。

这里有一些让 Jax 变得令人敬畏的东西。

Numpy API

Jax 实现了 Numpy API,并使它成为操作 Jax 数组的主要方式。

这实际上是一件大事,因为 Numpy 是 Python 中数值计算的通用语言,每个数据科学家都已经有了无数小时的 Numpy 经验,而不管其具体的实践领域。这让和 Jax 一起工作变得非常愉快。不仅如此,Jax 的ndarray基类继承了 Numpy 的ndarray类型,这意味着第三方库可以接受这些结构。您甚至可以开始使用 Jax“仅仅”加速您现有的 Numpy 代码,只需很少的改动。

统一的 API

Jax 为 eager 和 JIT 执行提供了一个干净统一的 API。

现在 TensorFlow 和 Pytorch 都有 eager 和 compiled 执行模式,但是,它们都添加了在框架生命周期后期缺失的模式,这留下了伤疤。例如,在 TensorFlow 中,急切模式是以这样一种方式添加的,它与图形模式不是 100%兼容,这导致了糟糕的开发人员体验。在 Pytorch 的案例中,它最初被迫使用不太直观的张量格式(如其 vision API 上的NCWH),只是因为它们在 eager 模式下更具性能,并且出于兼容性原因保留了它们。另一方面,Jax 天生就有这两种模式,并受这两种模式的影响,它主要侧重于使用 eager for debugging 和 JIT 来实际执行繁重的计算,但是您可以在方便的时候混合使用这两种模式。

XLA

Jax 基于下一代 ML 编译器技术。

Jax 专门使用 XLA ,而不是求助于设备相关的 C++和 CUDA 代码的混合。虽然 TensorFlow 是 XLA 存在的原因,但它的使用并没有在其代码库中完全普及,仍然有设备相关的代码。另一方面,Pytorch 有令人沮丧的大量依赖于设备的代码,以至于某些操作只在特定设备上受支持( pytorch/xla 是个东西,但它只关注 TPU 支持)。

特种作战

Jax 带来了一组独特的强大的函数转换。

Jax 有一些新颖的、易于使用的转换,使用户能够执行在其他框架中很难甚至不可能执行的复杂操作。例如,grad使计算 n 阶阶梯度变得极其容易,vmap使用户能够编写每个样本的操作,并自动将它们应用到整个批次,而pmap使用户能够轻松地在器件之间分配计算。你可以在 Jax 的官方文档中找到更多的转换。

兼容性

Jax 是 Pythonic 的。

这曾经是 Pytorch 的发明,但是 Jax 通过将它的架构建立在函数组合和基本 python 类型的基础上,将它带到了另一个层次,也就是说,Jax 可以区分列表、元组和字典等类型!这不仅仅是一个巧妙的技巧,许多基于 Jax 的框架都依赖于这个特性。Jax 还实现了像__array____array_module__这样的协议,最大化了它与 Python 数据科学生态系统的兼容性。

挽歌深度学习

虽然 Jax 从一开始就具备了创建神经网络的所有要素,但它并没有一个用于此目的的成熟框架。然而,在过去的几个月中,出现了一些面向研究的框架,如 FlaxTraxHaiku ,这些库专注于定义一个层接口,同时试图提出策略来执行与 Jax 的功能纯度限制兼容的状态管理。

虽然这些努力是朝着正确方向迈出的一大步,但如果你正在寻找像 Keras 这样更实用的东西,它们会让你感到有点格格不入,因为你会发现自己在编写自己的训练循环、损失函数和指标。

进入挽歌。

什么是挽歌?

Elegy 是一个基于 Jax,受 Keras 和俳句启发的深度学习框架。挽歌有以下目标:

  • 易于使用:Keras 模型 API 超级简单易用,所以 Elegy 移植了它,并试图尽可能地遵循它。Keras 用户在使用 Elegy 时要有宾至如归的感觉。
  • 灵活性:虽然 Keras 很简单,但对于某些用例来说也非常严格,Elegy 使用依赖注入在定义模型、损失和指标时给你最大的灵活性。
  • 简洁:与 Keras 或 Pytorch 相比,Elegy 基于钩子的模块系统使得编写模型代码更加容易(不那么冗长),因为它允许您直接在call (forward)方法中声明子模块、参数和状态。

要查看 Jax 和 Elegy 的运行情况,让我们看一个简单但重要的例子。

研究案例:混合密度网络

我们将为这个 1D 回归问题创建一个模型:

如你所见,这是一个逆问题,这意味着对于 X 中的一些值,在 Y 中有不止一个可能的解。这个问题很有趣,因为开箱即用的分类器不能很好地处理这种类型的数据。如果我们将这些数据进行简单的线性回归,将会产生这个模型:

这显然不是一个好的解决方案,因为它的大多数预测都在数据分布之外。对此建模的一个好方法是使用混合密度网络,这是一种混合模型。我们不会在这里深入讨论这个理论的细节,但是你可以参考混合密度网络的便车指南了解更多信息。

进口

我们将从导入我们将使用的一些库开始,包括 Numpy、Jax 和 Elegy。

定义架构

接下来,我们将定义模型的架构。在《挽歌》中,基本的抽象被称为“T0”,这个命名惯例是从俳句“T23”中借用来的。像 Keras 中的Layer一样,Module必须定义代表网络前向计算的call方法。在call方法中,你可以使用 Jax 函数和其他模块来定义架构,你可以在elegy.nn中找到像LinearConv2D这样的通用模块。

对于我们的混合密度网络,我们将定义一个简单的主干结构(x),然后将其分成多个组件 ( y),其中每个组件将尝试对一部分数据的均值和方差进行建模。从主干我们还将创建一个门控头(probs),它将分配概率权重给由x调节的每个组件。

这段代码中发生了很多事情,您现在不需要理解所有内容,但是请注意以下事项:

  1. 我们正在使用k组件创建一个混合密度网络,其中k是一个超参数。我们将该值设置为5
  2. 我们正在对elegy.nn.Linear进行各种各样的内联调用,事实上,我们甚至在列表理解中直接这样做。相比之下,Keras 或 Pytorch 通常会先在__init__上定义子模块,然后在call / forward中使用它们,从而分割代码。这些内联调用被称为模块挂钩,它们使得读写模型代码更加容易。
  3. 我们使用来自jax.nn 模块的函数,像relusoftmax,这个模块包含了很多对神经网络有用的函数。
  4. 我们使用了来自 Jax 的 Numpy APIstack函数,我们将其作为jnp导入。

如果我们为这个模型生成一个 Keras 风格的摘要(我们将在后面看到如何做),我们将得到下面的描述:

这里我们使用的是64的批量大小。请注意,我们有 2 个输出:

  • 我们称之为y的第一个包含了我们的5分量的均值和方差,这就是为什么它具有形状[64, 5, 2]
  • 第二个我们称之为probs的是我们每个5组件的概率权重,这就是为什么它有形状[64, 5]

创建损失函数

接下来我们将定义我们的损失函数。对于这种问题,如果我们假设每个组件都由正态分布建模,那么损失应该是给定数据的模型的负对数似然性。损耗由以下公式给出:

这里𝜋 k 代表每个成分k的概率权重,我们称之为probs,函数 N (…)代表每个成分的正态分布的概率密度函数,这将由y参数化。我们将通过创建一个从elegy.Loss继承的类来实现这个损失,并使用常规的 Jax 操作来计算这个公式。

在 Keras 中,定义复杂的损失函数和指标是一个公认的痛点,幸好 Elegy 给了我们更多的灵活性,我们实际上可以基于多个输出创建一个单一损失,而无需匹配数量的标签🥳.默认情况下,y_pred只是模型返回的内容,在这种情况下是一个元组,所以我们在第三行将其销毁为yprobs,而y_true只是用户传递的标签,在这种情况下,它只是一个带有 Y 值的数组,所以我们不必做任何事情。

代码或多或少以一对一的方式实现了上面的公式。注意,我们使用jax.scipy.stats.norm.pdf来计算给定模型输出参数的数据的概率,这很酷,因为大多数 Numpy 用户都熟悉 Scipy,可以利用他们对这个库的了解。safe_log只是log的一个简单的自定义函数,数值稳定。

训练模型

Elegy 附带了一个模型接口,它实现了 Keras 上的大多数方法,如fitevaluatepredictsummary等,只做了一些小的改动。这使得挽歌中的训练模型超级容易!Model的构造函数接受一个Module作为它的第一个参数,并且大多数参数被keras.Model.compile接受,我们将使用它来传递我们的MixtureModelMixtureNLL损失的一些实例,加上来自 optax 库的adam优化器。

有了这个模型实例,我们可以使用summary来打印带有我们之前看到的架构描述的表格,它与 Keras 版本略有不同,因为它要求您传递一个样本输入作为其第一个参数,它还接受一个可选的depth参数,该参数允许您控制您希望摘要有多详细。

最后,我们使用fit方法训练模型。虽然在这种情况下,给出的例子在 Keras 中也是有效的,但是 Elegy 的fit方法对输入数据做了轻微的修改。特别是,Elegy 对您使用的数据管道框架保持不可知,因为它只支持ndarrays或包含ndarrays(元组、列表、字典)的结构以及ndarrays的生成器/迭代器或这些结构。你可以通过利用dataset . as _ numpy _ iterator方法或 Pytorch 的DataLoader来避免to_tensor转换,从而轻松使用tf.data

在培训过程中,您将看到通常的 Keras 进度条,显示损失和指标的值😊。总的来说,您会发现,与其他更面向研究的 Jax 库相比,Elegy 中的培训要简单得多,因为它提供了常见损失、指标和 Keras 中可用的大多数回调的实现,这些实现支持创建检查点、提前停止、TensorBoard 等。

查看 Elegy 的文档了解更多信息。

结果

一旦训练完毕,我们就可以通过绘制覆盖在数据上的预测来检查每个组件学习到的分布。

这里黑线是成分的预测平均值,红线代表数据的估计标准偏差。我们将每个分量的图限制在概率高于某个阈值的区域,以了解其沿数据的分布。但是,我们也可以独立地将 X 中每个点的每个分量的概率权重可视化:

正如所料,有一个分量在 X < -0.75 的点(靠近左下方的分量)占优势,另一个分量在 X > 0.75 的点(靠近右上方的分量)占优势。其余的点将其概率分布在不同的成分中,但根据不同点的数据密度略有不同。

代码

如果你想要更详细的代码视图或者自己运行它,你可以在cgarciae/simple-mixture-models 查看。

概述

  • Jax 是一个干净的线性代数库,内置自动微分功能,在 XLA 的基础上实现,吸取了前人的所有经验。
  • Jax 非常 Pythonic 化,它的 Numpy API 非常棒,并且它与数据科学生态系统的其余部分非常兼容。
  • Elegy 为创建深度学习模型提供了类似 Keras 的体验,而且它比 Flax、Trax 和 Haiku 等替代品更容易使用。
  • Elegy 引入了一些机制,使得定义模型代码变得更容易/不那么冗长,并且与 Keras 相比,在损失和度量的定义方面提供了更多的灵活性。

我们希望你喜欢这篇文章。如果你喜欢它请分享它,如果你喜欢挽歌在 Github 上给它一颗星。欢迎反馈。

我要感谢大卫·卡多佐卡洛斯·阿尔瓦雷斯的反馈和支持。

与 Julia 深度学习,Flux.jl story

原文:https://towardsdatascience.com/deep-learning-with-julia-flux-jl-story-7544c99728ca?source=collection_archive---------17-----------------------

步入淡水

照片由富山武广Unsplash 上拍摄

介绍

数据科学领域出现了一个新的挑战者:Julia。它速度快,易于输入,有很好的文档和社区。

但它缺乏例子和教程来学习,所以在这篇文章中,我们将建立一个经典的:MNIST 分类器使用卷积神经网络。

是给谁的?

对于那些对深度学习略知一二,但对尝试一门新语言充满好奇的人来说,我将把重点放在对初学者更友好的风格上。我将尝试解释 Julia 语法与 Python 的不同之处。

我们将使用什么?

Flux.jl .是 Julia 主要的深度学习库之一。你可以在这里查看一些例子,尽管它们对初学者来说有些吓人。

来自 flux 主页的官方 logo:https://fluxml.ai/

我为什么要在乎?

虽然 PyTorch 或 TensorFlow 已经为 Python 的深度学习提供了一个很好的生态系统,但它们大多是用 C++甚至 Cuda 编写的,以获得出色的 GPU 性能。

PyTorch GitHub 页面的语言统计

因此,如果你想写一些自定义代码来做一点试验,这可能会变得相当复杂(尽管在其中编写生产代码可能仍然是一个更好的主意)

来自 TensorFlow GitHub 页面的语言统计

另一方面,朱莉娅从一开始就为你提供了速度。所以如果你想写一些自定义的损失函数,你可以在 Julia 中完成。将它与很少的努力结合起来,放在 GPU 上并清除源代码,即使对初学者来说,你也有相当吸引人的东西。

Flux GitHub 页面的语言统计

包和数据集

导入包非常简单。为了更简单的数据准备,我们将导入通量 (当然)统计MLDatasets

using Flux
using Flux: Data.DataLoader
using Flux: onehotbatch, onecold, crossentropy
using Flux: @epochs
using Statistics
using MLDatasets# Load the data
x_train, y_train = MLDatasets.MNIST.traindata()
x_valid, y_valid = MLDatasets.MNIST.testdata()# Add the channel layer
x_train = Flux.unsqueeze(x_train, 3)
x_valid = Flux.unsqueeze(x_valid, 3)# Encode labels
y_train = onehotbatch(y_train, 0:9)
y_valid = onehotbatch(y_valid, 0:9)# Create the full dataset
train_data = DataLoader(x_train, y_train, batchsize=128)

(亲提示:默认情况下 Julia 会打印该函数的输出。您可以抑制它,但键入“;”结束)

Flux 将期望我们的图像数据按照 WHCN 顺序(宽度,高度,#通道,批量),所以我们必须添加一个通道层。幸运的是,已经有了一个名为unsqueeze的函数。

稍后我们将使用交叉熵损失,因此我们还需要使用onehotbatch对标签进行编码。

模型

我们的模型将有 8 层。其中 4 个将是 Relu 的卷积,然后我们将意味着池化,展平它,最后用 softmax 填充到一个线性层中。

我们可以使用Chain函数将所有东西“链接”在一起

model = Chain(
    # 28x28 => 14x14
    Conv((5, 5), 1=>8, pad=2, stride=2, relu),
    # 14x14 => 7x7
    Conv((3, 3), 8=>16, pad=1, stride=2, relu),
    # 7x7 => 4x4
    Conv((3, 3), 16=>32, pad=1, stride=2, relu),
    # 4x4 => 2x2
    Conv((3, 3), 32=>32, pad=1, stride=2, relu),

    # Average pooling on each width x height feature map
    GlobalMeanPool(),
    flatten,

    Dense(32, 10),
    softmax)

每个卷积层获取一个图像,并从中创建通道层。因此,下一个卷积层将采取一个更小的图像,其中有更多的通道。我们还在第一层应用填充,并在所有层上应用步长 2。

如果你需要复习一下下面的 gif 和这篇文章。对于内核来说,填充基本上使我们的图像更大,而 stride 定义了它需要多大的步长。

Vincent Dumoulin,Francesco vision—深度学习卷积算法指南

然后是平均池层。它从卷积层获取特征图,并从每个通道获取平均值。

由作者提供

但是在我们将数据进一步输入到线性层之前,我们必须去掉称为单线态的 1x1 维度。这就是扁平化层的目的。

如果你想知道每一层的尺寸是如何变化的,我会在文章末尾提供一个 jupyter 笔记本的链接。

现在是我们可以将数据输入模型并获得预测的时候了。它们还没有任何用处,但这是检查我们是否做对了所有事情的好方法。要解码预测,使用onecold函数。

# Getting predictions
ŷ = model(x_train)
# Decoding predictions
ŷ = onecold(ŷ)
println("Prediction of first image: $(ŷ[1])")

损失函数、优化器和指标

现在是时候选择如何更新模型参数以及如何检查其性能了。

accuracy(ŷ, y) = mean(onecold(ŷ) .== onecold(y))
loss(x, y) = Flux.crossentropy(model(x), y)# learning rate
lr = 0.1
opt = Descent(lr)ps = Flux.params(model)

我们有标准的精度度量和通量的交叉熵损失。对于优化器,我们将选择学习率为 0.1 的简单梯度下降。当然还有更好的选择,比如Momentum或者ADAM,但是对于一个简单的向导来说已经足够了。

例如,Flux 的分化库 Zygote 的工作方式与 PyTorch 中使用的有些不同。它本身是值得研究的,但是现在我们只需要知道我们必须从我们的模型中获取参数。

为此,我们简单地调用params函数,将我们的模型作为输入。

培养

现在我们在等待的事情是:训练模型。

number_epochs = 10
@epochs number_epochs Flux.train!(loss, ps, train_data, opt)accuracy(model(x_train), y_train)

就是这样。这就是训练。我们用损失、参数、数据和优化器调用train!函数。我们使用@epochs宏,指定我们希望它执行的次数(默认情况下它只执行一次)

现在来看看朱莉娅的更多方面。

“!”在函数名中,通常意味着函数会产生副作用或者就地执行(如果在 Python 中使用 numpy)

“@”位于宏之前。这是通向所谓元编程的大门。他们改变了函数的代码,所以你可以将它与 Pyton 中的 decorators 进行比较(尽管严格来说它们不是同一个东西)

更深入

现在让我们自己编写训练循环。最好的一点是,如果我们比较执行这两种方法所花的时间,会发现它们实际上是相似的。

从文档中:

Flux.train!函数可以非常方便,特别是对于简单的问题。回调的使用也非常灵活。但是对于一些问题来说,编写自己的定制训练循环要干净得多。

所以,我们就这么做吧。

for batch in train_data

    gradient = Flux.gradient(ps) do
      # Remember that inside the loss() is the model
      # `...` syntax is for unpacking data
      training_loss = loss(batch...)
      return training_loss
    end

    Flux.update!(opt, ps, gradient)
end

我们循环训练数据集(来自数据加载器)。然后,我们使用do关键字将损失计算映射到梯度函数。然后我们用优化器、参数和保存的梯度调用update!,就完成了。

更深

哦,你不喜欢update!功能?没问题。让我们编写自己的循环。

for x in ps
    x .-= lr .* gradient[x] # Update parameters
end

每个符号前的.告诉 Julia 按元素进行操作。

如果你仔细查看 Flux 的源代码,你会发现,仅仅在两个函数中。不相信我?自己看这里这里

这就是朱莉娅最吸引人的地方。它会很快,并且已经为 GPU 做好了准备。厉害!

甚至更深

想要更多吗?让我们创建一些回调。它们本质上是在训练时将被调用的函数。

loss_vector = Vector{Float64}()
callback() = push!(loss_vector, loss(x_train, y_train))Flux.train!(loss, ps, train_data, opt, cb=callback)

你可以把push!当作 numpy 的一个append函数。

现在,我们有了一个列表,列出了每批数据之后的损失(请记住,这是针对更大数据集的大量计算)

包扎

现在你知道如何在朱莉娅使用通量。您甚至知道如何为您的模型编写高效的定制函数。花了多长时间?不多,不是吗?

毫无疑问,Julia 和 Flux 的时代还很早,但是如果你喜欢这种语言和这些包的编写方式,我认为值得尝试一下。

毕竟,如果我们有一些与他人交流的经验,我们都可以用自己喜欢的语言写出更好的代码。

你可以在这里看到一个 jupyter 笔记本,里面有所有的代码。

来和我一起在推特上闲逛吧,感谢你的阅读!

使用 PyTorch 进行深度学习

原文:https://towardsdatascience.com/deep-learning-with-pytorch-a93b09bdae96?source=collection_archive---------24-----------------------

深度强化学习讲解— 04

初学 PyTorch

我们将在本系列的许多文章中使用 PyTorch,所以读者需要确保她/他熟悉它。这篇文章将向读者介绍 PyTorch 的基本特性,它使我们能够使用 Python 语言实现深度学习模型。这篇文章并没有假装是 PyTorch 的完整手册,它只是介绍了 PyTorch 的基本知识,以开始在 PyTorch 中编码神经网络,我们将在整个系列中引入我们需要的新功能。好好享受吧!

本出版物的西班牙语版本

[## 8.PyTorch básico

请访问第 8 页的自由介绍

medium.com](https://medium.com/aprendizaje-por-refuerzo/8-pytorch-básico-a60ce5fc8b74)

深度学习框架

深度学习框架领域的明确领导者现在是谷歌开发的 TensorFlow 和脸书开发的 PyTorch,它们正在从使用量、份额和势头上脱离市场的其余部分。

三年前,第一个版本的 PyTorch 问世,毫无疑问,它正在获得巨大的发展势头。PyTorch 最初由脸书孵化,作为快速实验和原型制作的理想灵活框架,迅速赢得了声誉,在深度学习社区中赢得了成千上万的粉丝。例如,我的研究团队中的博士生更喜欢使用 PyTorch,因为它允许他们编写看起来像本机的 Python 代码,并且仍然可以获得良好框架的所有好处,如自动微分和内置优化。这就是我决定在这个系列中使用 PyTorch 的原因。

虽然 PyTorch 由于脸书(和 AWS)而在市场上获得了动力,但 TensorFlow 仍然在各个方面保持领先,并且是目前行业中使用最多的。你可以阅读这篇简短的文章“ TensorFlow vs PyTorch:战斗仍在继续”来了解关于这两种环境的更多细节。

环境设置

我建议使用 Google 提供的(Colab)来执行本文描述的代码。它基本上由一个 Jupyter 笔记本环境组成,不需要配置,完全在云中运行,允许使用不同的深度学习库,如 PyTorch 和 TensorFlow 。Colab 的一个重要特点是它完全免费提供 GPU(和 TPU)。关于该服务的详细信息可以在常见问题页面上找到。

默认情况下,Colab 笔记本运行在 CPU 上。你可以切换你的笔记本电脑运行与 GPU(或 TPU)。为了访问一个 GPU,您需要选择“运行时”选项卡,然后选择“更改运行时类型”,如下图所示:

当弹出窗口出现时,选择 GPU。确保“硬件加速器”设置为 GPU(默认为 CPU)。然后,确保您已连接到运行时(在菜单功能区中“已连接”旁边有一个绿色复选标记):

现在你可以运行这篇文章中的代码了。我建议将这篇文章的代码复制粘贴到一个 Colab 笔记本上,以便在你阅读这篇文章的同时看到执行过程。准备好了吗?

这篇文章的完整代码可以在 GitHub 上找到,并且可以使用这个链接作为一个 Colab google 笔记本运行。

使用 PyTorch 的手写数字示例

在这篇文章中,我们将编写一个神经网络模型,对在上一篇文章中出现的手写数字进行分类。请记住,我们创建了一个数学模型,给定一幅图像,该模型识别它所代表的数字,返回一个具有 10 个位置的向量,指示 10 个可能数字中每一个的可能性。

来源: torres.ai

为了引导解释,我们将遵循为神经网络编程所要采取的步骤列表:

  1. 导入所需的库
  2. 加载和预处理数据
  3. 定义模型
  4. 定义优化器和损失函数
  5. 训练模型
  6. 评估模型

让我们去吧!

1.导入所需的库

我们总是需要导入 PyTorch 的核心 Python 库torch。对于我们的例子,我们还将导入torchvision包,以及常用的库numpymatplotlib

**import torch 
import torchvision**

为了代码的清晰,我们可以在这里定义一些训练所需的超参数:

 **import numpy as np 
import matplotlib.pyplot as plt EPOCH = 10 
BATCH_SIZE= 64**

2.加载和预处理数据

加载数据

下一步是加载将用于训练我们的神经网络的数据。我们将使用前一篇文章中已经介绍过的 MNIST 数据集,可以从MNIST 数据库页面下载使用torchvision.dataset. PyTorch 数据集是根据请求返回单个数据点的对象。然后,它被传递到处理数据点批处理和并行性的数据加载器。这是我们示例的代码:

**xy_trainPT = torchvision.datasets.MNIST(root='./data', 
             train=True, download=True,transform=
             torchvision.transforms.Compose(
             [torchvision.transforms.ToTensor()]))xy_trainPT_loader = torch.utils.data.DataLoader
                    (xy_trainPT, batch_size=BATCH_SIZE)**

因为数据通常太大,无法一次将数据放入 CPU 或 GPU 内存中,所以将数据分成大小相等的批次。每一批都包括数据样本和目标标签,并且两者都必须是张量(我们将在下面介绍)。BATCH_SIZE参数表示我们将在每次更新模型参数时使用的数据数量。

该数据集包含 60,000 个手工制作的数字图像来训练模型,对于首次进入模式识别技术来说是理想的,无需花费大量时间预处理和格式化数据,这在数据分析中是非常重要和昂贵的步骤,并且在处理图像时具有特殊的复杂性。

我们可以验证前面的代码已经用库matplotlib.pyplot加载了预期的数据:

**fig = plt.figure(figsize=(25, 4)) 
for idx in np.arange(20):
   image, label = xy_trainPT [idx]
   ax = fig.add_subplot(2, 20/2, idx+1, xticks=[], yticks=[])
   ax.imshow(torch.squeeze(image, dim = 0).numpy(), 
             cmap=plt.cm.binary)
   ax.set_title(str(label))**

预处理数据

记得在上一篇文章中,我们解释过,为了便于将数据输入到我们的神经网络中,我们将输入(图像)从二维(2D)转换为一维(1D)的向量。也就是说,28×28 个数字的矩阵可以由 784 个数字(逐行连接)的向量(数组)来表示。

当我们使用这种类型的变换(例如,应用于第一幅图像)将数据摄取到神经网络时,我们将应用这种变换:

**image, _ = xy_trainPT[0] 
print(image.size())
image_flatten = image.view(image.shape[0], -1)
print (image_flatten.size())torch.Size([1, 28, 28]) 
torch.Size([1, 784])**

张量

张量是一个多维数组,是 PyTorch 的基本构造块,相当于 NumPy,它存储一组数字:

**a = torch.randn(2, 3)
print(a)tensor([[ 1.1049, 0.2676, -0.4528],
        [ 0.0105, -0.5095, 0.7777]])**

我们可以知道它的尺寸和大小:

**print(a.size())
print(a.dim())torch.Size([2, 3])
2**

除了维度,张量的特征还在于其元素的类型。为此,我们有一个dtype参数,它故意与同名的标准 NumPy 参数类型相似:

**matrix=torch.zeros([2, 4], dtype=torch.int32)
print(matrix)tensor([[0, 0, 0, 0],
        [0, 0, 0, 0]], dtype=torch.int32) print(matrix.dtype)torch.int32**

Torch 定义了九种类型的 CPU 张量和九种类型的 GPU 张量:

如你所见,GPU 张量有特定的类型。PyTorch 透明支持 CUDA GPUs,这意味着所有操作都有两个版本——CPU 和 GPU——自动选择。这个决定是基于你正在操作的张量的类型做出的。

在 PyTorch 中创建张量有不同的方法:调用所需类型的构造函数,将 NumPy 数组(或 Python 列表)转换为张量或要求 PyTorch 创建具有特定数据的张量。例如,我们可以使用torch.zeros()函数创建一个填充零值的张量:

**b = torch.zeros(2, 3)
print(b)tensor([[0., 0., 0.],
        [0., 0., 0.]]) c = torch.ones(2, 3)
print(c)tensor([[1., 1., 1.],
        [1., 1., 1.]])**

张量的元素可以使用其索引(从 0 开始)来访问:

**c[0,0]=222 
print(c)tensor([[222.,   1.,   1.],         
        [  1.,   1.,   1.]])** 

此外,就像 Python 中常见的数据结构一样,我们可以在“: ”字符的帮助下,在索引中使用范围标记来选择和操作张量的各个部分。索引从 0 开始,我们可以对索引使用负值,其中-1是最后一个元素,依此类推。让我们来看下面的一段代码作为例子:

**x = torch.Tensor([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) 
print (x) tensor([[ 1., 2., 3., 4.],
        [ 5., 6., 7., 8.],
        [ 9., 10., 11., 12.]]) print (“x column 1: “, x[:, 1])
print (“x row 0: “, x[0, :])
print (“x rows 0,1 & cols 1,2: \n”, x[0:2, 1:3])x column 1: tensor([ 2., 6., 10.])
x row 0: tensor([1., 2., 3., 4.])
x rows 0,1 & cols 1,2:
tensor([[2., 3.],
        [6., 7.]])**

PyTorch 张量可以非常有效地转换为 NumPy 矩阵,反之亦然。通过这样做,我们可以利用 Python 生态系统中围绕 NumPy 数组类型发展起来的大量功能。让我们用一个简单的代码来看看它是如何工作的:

**x = np.array([[1,2], [3,4], [5,6]])
print (x) [[1 2]
 [3 4]
 [5 6]]**

这个数组x可以很容易地转换成张量,如下所示:

**y=torch.from_numpy(x)
print(y)tensor([[1, 2],
       [3, 4],
       [5, 6]])**

我们可以看到第二个印记表明它是一个张量。相反,如果我们想把一个张量转换成一个 NumPy 数组,我们可以这样做:

**z = y.numpy()
print (z)[[1\. 2.]
 [3\. 4.]
 [5\. 6.]]**

我们将使用reshape()函数,它返回一个与输入具有相同数据和元素数量的张量,但是具有指定的形状。如果可能,返回的张量将是输入的视图。否则,它将是一个副本(在内存中):

**one_d = torch.arange(0,16)
print (one_d)two_d= one_d.reshape(4,4)
print (two_d)print(two_d.size())tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])tensor([[ 0, 1, 2, 3],
        [ 4, 5, 6, 7],
        [ 8, 9, 10, 11],
        [12, 13, 14, 15]])torch.Size([4, 4])**

3.定义模型

torch.nn包中,您可以找到许多预定义的类,它们提供了编程神经网络所需的基本功能块。要定义上一篇文章中呈现的模型,可以使用该包中的Sequential类来完成:

**modelPT= torch.nn.Sequential(            
         torch.nn.Linear(784,10),
         torch.nn.Sigmoid(), 
         torch.nn.Linear(10,10), 
         torch.nn.LogSoftmax(dim=1) 
         )**

该代码定义了由两个密集层(线性层)组成的神经网络,每个密集层 10 个神经元,一个具有 Sigmoid 激活函数,另一个具有 Softmax 激活函数。随着本系列的推进,我们将引入其他激活函数作为 ReLU,我们将在本系列的下一篇文章中使用。

我想强调的是,前面的代码对前一篇文章中介绍的神经网络进行了一个小的转换:此外,它对最后一层的每个输出应用了对数运算。具体来说, LogSoftmax 函数可视为:

其中 Softmax 按照上一篇中的定义计算。与 Softmax 相比,LogSoftmax 有许多实际和理论上的优势,这些优势促使我们在构建神经网络时使用它,我们将在后面的部分中对此进行讨论。

总之,我们定义的网络可以直观地表示出来,如下图所示:

来源: torres.ai

神经网络的第一层接收 784 个特征的张量,这些特征表示传递给第一层中 10 个神经元中的每一个的像素。一旦这 10 个神经元处理了这些信息,它们中的每一个都将信息传递给下一层的所有神经元,即第一层的所有 10 个神经元都与第二层的所有 10 个神经元相连。

第二层是具有 10 个神经元的 softmax 激活函数的层,这意味着它将返回 10 个概率值的张量,代表 10 个可能的数字。一般来说,分类网络的输出层将具有与类一样多的神经元,除了在二进制分类中,其仅需要一个神经元。让我们记住,我们使用的是 LogSoftmax 层,而不是 Softmax 层,因此返回的每个值将是当前数字的图像属于每个类的概率的对数。

我们可以用这个简单的例子来分析构成神经网络的参数。例如,在第一层中,对于 10 个神经元中的每一个,权重需要 784 个参数,因此需要 10 × 784 个参数来存储 10 个神经元的权重。此外,对应于每个神经元的 10 个偏置需要 10 个附加参数。因此,对于第一层,需要 7850 个参数。

在第二层中,作为 softmax 函数,需要将其所有 10 个神经元与前一层的 10 个神经元连接,因此,权重需要 10 × 10 个参数;除了对应于每个节点的 10 个偏置。这给了我们第二层总共 110 个必需的参数。

总之,对于我们极其简单的神经网络,我们看到需要 7960 个参数,第一层需要 7850 个参数,第二层需要 110 个参数。

通过对所有神经网络模块的基类nn.Module进行子类化,我们可以创建自己的构建块,这些构建块可以堆叠在一起并在以后重用,这是通常所做的。但是考虑到这篇文章的初始性质,我们可以用这种基本的方式来定义我们的神经网络。读者可以查阅官方文件,了解关于这个话题的更多细节。

4.定义优化器和损失函数

正如我们在上一篇文章中所展示的,这些模型是通过迭代求解一个无约束优化问题来训练的。在每次迭代中,随机的一批训练数据被输入到模型中以计算损失函数值。然后,计算损失函数相对于网络权重的梯度(反向传播),并在梯度的负方向上更新权重。这些网络被训练,直到它们收敛到损失函数最小值。

损失函数

PyTorch 中大约有 20 种不同的损失函数,驻留在nn包中,并作为nn.Module子类实现。我们将在本系列中使用的一些常见标准损失函数有:

  • nn.MSELoss:自变量之间的均方误差,是回归问题的标准损失。
  • nn.NLLLoss:它计算“最大似然”标准,一般用于多类分类问题(如我们的 MNIST 例子)。
  • nn.CrossEntropyLoss:计算与nn.NLLLoss相同,但是它期望每个类的原始分数,并在内部应用 LogSoftmax(而 nn。NLLLoss 期望将对数概率作为输入)。

由于我们正在处理一个多类分类问题,我们选择交叉熵作为我们的损失函数。在这个例子中,我们使用负对数似然神经网络。NLLLoss()与 softmax nn 结合使用。LogSoftmax()函数,我们已经介绍过了。正如我们所说的,我们不应用 Softmax 来增加训练过程的数值稳定性,提出了一种替代方法来首先计算 Softmax,它使用指数运算,然后计算交叉熵损失,它使用概率的对数。如果读者对这方面的更多细节感兴趣,我推荐看一看这篇文章

使用 LogSoftmax 定义神经网络的缺点是,每次我们需要从神经网络输出中获取概率时,我们都需要记住应用 Softmax。

一般来说,读者会看到 PyTorch 代码中分配给criterion的损失函数:

**criterion = torch.nn.NLLLoss()**

因此,计算误差的方法如下:

**loss = criterion(logps, labels)**

我们在自变量中指出神经网络的输出和正确的标签。

【计算机】优化程序

请记住,优化器采用模型参数的梯度并更改这些参数,以减少损失值。我们使用 PyTorch 提供的模块torch.optim来优化模型,执行梯度下降,并通过反向传播来更新权重。这个软件包允许我们在几个算法(AdaGrad,RMSProp,Adam 等)中进行选择。)是梯度下降算法的不同变体,梯度下降算法是一种能够找到各种问题的最优解的通用优化算法。此刻,在这个例子中,我们将使用基本的随机梯度下降 (SGD):

**optimizer = torch.optim.SGD(modelPT.parameters(), lr=0.01)**

参数是优化器必须调整的参数和指示这些调整应该如何进行的学习率。请记住,优化器会以正确的方向迭代调整模型的参数(权重和偏差)(在其值上加一个“小”或减一个“小”,其中这个“小”是由学习率定义的),从而减少误差。一般来说,重复该过程,直到误差降到可接受的水平以下。

导数用于计算正确的方向,特别是误差相对于参数的梯度。PyTorch 中的自动签名包正是通过自动微分来自动计算神经网络中的反向传递,从而提供了这种功能。

5.训练模型

一旦我们的模型被定义,学习方法被配置,它就可以被训练了。因此,我们只需定义将迭代所有数据的训练循环,以便优化器迭代地调整权重。让我们用这几行代码来讨论一个训练循环的通用蓝图:

**1: for e in range(EPOCHS):
      running_loss = 0
2:    for images, labels in xy_trainPT_loader:
3:        images = images.view(images.shape[0], -1)
4:        output = modelPT(images)
5:        loss = criterion(output, labels)
6:        loss.backward()
7:        optimizer.step()
8:        optimizer.zero_grad()
          running_loss += loss.item()
      print(“Epoch {} — Training loss: {}”.format(e, 
             running_loss/len(xy_trainPT_loader)))**

第 1 行**:通常,训练循环会反复迭代我们的数据。记住,对一组完整的例子的一次迭代被称为一个时期。EPOCHS变量表示在整个例子集上的迭代次数。

第 2 行:**我们已经介绍过,数据通常太大,无法一次放入 CPU 或 GPU 内存,因此它被分成大小相等的批次。每个批次都包含数据样本和目标标签,两者都必须是张量。

****第 3 行:为了便于将数据输入我们的神经网络,我们必须将输入(图像)从二维(2D)转换为一维(1D)向量。

****第 4 行:我们将每批图像张量传递到模型中,该模型将返回一个对该批图像进行预测的张量,即前向传递。

****第 5 行:得到预测后,我们将它们和它们的实际标签一起传递到交叉熵损失函数(criterion)中,并计算损失。通常,损失函数接受两个参数:网络输出(预测)和期望输出(真实数据,也称为数据样本的标注)。

一些 PyTorch 的损失函数将类标签作为它们的目标(例如 NLLloss ),所以如果我们使用它们(如在我们的例子中),我们不需要像我们在上一篇文章中介绍的那样将目标转换成一个热点向量(为了便于解释)。

****第 6 行:我们使用损失值进行反向传递,以计算损失相对于模型参数的梯度。在loss.backward()调用结束后,我们累积了梯度。

****第 7 行:现在是优化器使用方法step()修改模型参数的时候了,该方法从参数中提取所有梯度并应用它们。

****第 8 行:训练循环的最后一部分,也是最重要的一部分,是我们对参数梯度归零的责任。在我们的网络上调用zero_grad()清除所有优化变量的梯度。

为了检查训练过程是如何发展的,我们在这个训练循环中添加了几行代码。首先,通过将每批迭代的所有损失相加,我们得到整个时期的训练损失:

**running_loss += loss.item()**

第二步,用迭代次数对其求平均,并打印出来:

**print(“Epoch {} — Training loss: {}”.format(e, 
             running_loss/len(xy_trainPT_loader)))**

查看该输出,我们可以看到训练循环如何调整网络的权重,以便在每次迭代中,损失函数产生更小的损失。

**Epoch 0 — Training loss: 2.1822925415882932 
Epoch 1 — Training loss: 1.8671700155048736
Epoch 2 — Training loss: 1.5379922698809902
Epoch 3 — Training loss: 1.287035460029838. . .Epoch 15 — Training loss: 0.5162741374264139
Epoch 16 — Training loss: 0.49991638108547815
Epoch 17 — Training loss: 0.48541215611800453
Epoch 18 — Training loss: 0.4724724407929347
Epoch 19 — Training loss: 0.4608637086554631**

在 PyTorch 中,没有像 Keras 或 Scikit-learn 中的fit()那样的“预制”数据模型调优函数,所以训练循环必须由程序员指定。

6.评估和使用模型

现在,我们已经完成了模型的训练,我们可能想要通过在测试数据集上应用它来测试我们的模型的一般化程度。

在 PyTorch 中,再次要求程序员指定评估循环:

**xy_testPT = torchvision.datasets.MNIST(root='./data', 
            train=False, download=True, 
            transform=torchvision.transforms.
            Compose([torchvision.transforms.ToTensor()]))xy_test_loaderPT = torch.utils.data.DataLoader(xy_testPT)correct_count, all_count = 0, 0
for images,labels in xy_test_loaderPT:
  for i in range(len(labels)):
    img = images[i].view(1, 784)
    logps = modelPT(img)
    ps = torch.exp(logps)
    probab = list(ps.detach().numpy()[0])
    pred_label = probab.index(max(probab))
    true_label = labels.numpy()[i]
    if(true_label == pred_label):
        correct_count += 1
    all_count += 1print("\nAccuracy of the model =", (correct_count/all_count)) Accuracy of the model = 0.8657**

读者可以看到这个循环中的指令与前一个训练循环中的指令相似。但在这种情况下,不是保留损失计算,而是计算准确性,即模型从未见过的数据的命中率。

仅此而已!你已经设计了一个完整的神经网络。恭喜你。

下一篇见

深度强化学习讲解系列

UPC 巴塞罗那理工 巴塞罗那超级计算中心

一个轻松的介绍性系列以一种实用的方式逐渐向读者介绍这项令人兴奋的技术,它是人工智能领域最新突破性进展的真正推动者。

** [## 深度强化学习解释-乔迪托雷斯。人工智能

本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)

关于这个系列

我在五月份开始写这个系列,那是在巴塞罗那的封锁期。老实说,由于封锁,在业余时间写这些帖子帮助了我 #StayAtHome 。感谢您当年阅读这份刊物;它证明了我所做的努力。

免责声明 —这些帖子是在巴塞罗纳被封锁期间写的,目的是分散个人注意力和传播科学知识,以防对某人有所帮助,但不是为了成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。**

React Native 深度学习(仅限 iOS)

原文:https://towardsdatascience.com/deep-learning-with-react-native-ios-only-8089fed59773?source=collection_archive---------19-----------------------

(图片由作者提供)

文章原载于 dev.to

介绍

在本教程中,我将涵盖如何构建移动应用程序和训练深度学习模型的所有步骤,以便您可以通过使用手机的摄像头预测 0 到 9 之间的手写数字。

预测手写数字的应用程序(作者图片)

但是在我们开始构建移动应用之前,我们需要想出一个高层次的策略。让我们回顾一下思考过程:

  • 我们是构建一个纯 React-Native ( RN )还是一个 Expo 应用?
  • 我们想用哪个相机库?
  • 我们需要裁剪图像吗?我们需要使用什么样的库?
  • 我们如何训练一个深度学习模型?
  • 我们如何对照照片使用那个模型?
  • 我们如何显示结果?

注意:本教程需要一些先决条件和对 RN 和 Javascript 的全面理解。如果你是一个绝对的初学者,我建议在继续学习本教程之前,先在 Youtube、Udemy 或 Egghead 上学习一门好的课程。

我们开始吧

我将把这个教程分成三个部分

第一章:创建 RN 应用
第二章:训练深度学习模型
第三章:实现模型,预测并展示结果

第 1 章:创建 RN 应用程序

还记得我们思考过程的第一点是创建一个裸应用还是 Expo 样板应用吗?

经过一些研究,我决定在本地加载训练好的模型。这是最简单的方法,不需要从云服务器获取模型,但是你也可以这样做。

在本教程中,我们将使用[@tensorflow/tfjs-react-native](http://twitter.com/tensorflow/tfjs-react-native)中不幸与 Expo 不兼容的bundleResourceIO

此外,因为我们想使用相机,我们必须使用物理手机,而不是模拟器。为此,你必须有一个苹果开发者帐户来签署你的应用程序,否则你将无法运行该应用程序。

让我们使用以下命令创建应用程序:

$ react-native init MyFirstMLApp

安装过程完成后,请确保您的所有豆荚也已安装!

$ cd MyFirstMLApp
$ npx pod-install

让我们在你的物理 iPhone 上第一次运行这个应用程序。打开 Xcode,找到MyFirstMLApp.xcworkspace并打开。使用 lightning 线缆将 iPhone 连接到 Mac,然后选择您的手机。首次构建和运行应用程序时,请按播放按钮。你应该会在你的 iPhone 上看到欢迎反应屏幕。

🏆牛逼!

让我们为这个应用程序添加一些包:

yarn add [@react](http://twitter.com/react)-native-community/async-storage [@react](http://twitter.com/react)-native-community/cameraroll [@tensorflow/tfjs](http://twitter.com/tensorflow/tfjs) [@tensorflow/tfjs-react-native](http://twitter.com/tensorflow/tfjs-react-native) expo-camera expo-gl expo-gl-cpp expo-image-manipulator react-native-fs react-native-svg react-native-unimodules victory-native

最后,安装导航库。

yarn add react-native-navigation && npx rnn-link

后一个命令会将导航包添加到 iOS 和 Android 中。但是我们还没有完成。

因为我们使用 RN 的裸框架,单模块需要手动安装。

请点击链接,并按照 iOS 部分所述修改Podfile。那次跑步之后

$ npx pod-install

并构建 Xcode 项目,看看是否所有东西都已正确安装。

然后继续将单模块的代码添加到AppDelegate.m中,并再次构建项目。

因为我们想用相机拍照,我们还需要给Info.plist添加几个私钥

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “[http://www.apple.com/DTDs/PropertyList-1.0.dtd](http://www.apple.com/DTDs/PropertyList-1.0.dtd)">
<plist version=”1.0">
  <dict>

    <! — Required for iOS 10 and higher -->
    <key>NSCameraUsageDescription</key>
    <string>We need to use the camera for taking pictures of the digits</string><! — Required for iOS 11 and higher: include this only if you are planning to use the camera roll -->
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>We need to access the photo library to upload the images</string><! — Include for only if you are planning to use the camera roll -->
    <key>NSPhotoLibraryUsageDescription</key>
    <string>We need to access the photo library to upload the images</string><! — Include this only if you are planning to use the microphone for video recording -->
    <key>NSMicrophoneUsageDescription</key>
    <string>We need to access the microphone</string>

    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>

如果 Xcode 构建良好,您可以继续从 Xcode 运行应用程序,或者只使用终端。

如果你决定从现在开始从命令行运行这个应用程序,像我一样,请将— device添加到你的package.json文件的ios脚本中并运行

yarn ios

一旦应用程序在你的 iPhone 上启动,不要惊讶你再也看不到欢迎页面了。那是因为我们用了react-native-navigation。但是你应该看到加载屏幕 MyFirstMLApp

现在是时候创建我们的 2 个屏幕,并将这些屏幕的导航添加到我们的项目中。

请在我们项目的根目录下创建src/screens/CameraViewsrc/screens/EvaluationView目录。

src/screens/CameraView中创建一个index.js文件并添加以下代码:

import React, { useState, useRef, useEffect } from "react";
import {
  SafeAreaView,
  TouchableOpacity,
  View,
  Text,
  StatusBar,
} from "react-native";
import { Navigation } from "react-native-navigation";
import { Camera } from "expo-camera";const MASK_DIMENSION = 100;export const CameraView = (props) => {
  const [hasPermission, setHasPermission] = useState(null);
  const [showShutterButton, setShowShutterButton] = useState(false);
  const cameraRef = useRef();useEffect(() => {
    (async () => {
      const { status } = await Camera.requestPermissionsAsync();
      setHasPermission(status === "granted");
    })();
  }, []);const handlePictureProcessing = async () => {
    goToEvaluationView();
  };const goToEvaluationView = () => {
    Navigation.push(props.componentId, {
      component: {
        name: "evaluationView",
        options: {
          topBar: {
            title: {
              text: "Evaluating ML result",
              color: "white",
            },
            background: {
              color: "#4d089a",
            },
            backButton: {
              color: "white",
              showTitle: false,
            },
          },
        },
        passProps: {},
      },
    });
  };if (hasPermission === null) {
    return <View />;
  }if (hasPermission === false) {
    return <Text> No access to camera </Text>;
  }return (
    <React.Fragment>
      <StatusBar barStyle="light-content" />
      <SafeAreaView style={styles.safeArea}>
        <Camera
          ref={cameraRef}
          type={Camera.Constants.Type.back}
          whiteBalance={Camera.Constants.WhiteBalance.auto}
          onCameraReady={() => setShowShutterButton(true)}>
          <View style={styles.cameraView}>
            <View style={styles.mask} />
            {showShutterButton && (
              <TouchableOpacity
                style={styles.shutterButton}
                onPress={handlePictureProcessing}>
                <Text style={styles.shutterButtonText}>
                  Take a picture
                </Text>
              </TouchableOpacity>
            )}
          </View>
        </Camera>
      </SafeAreaView>
    </React.Fragment>
  );
};const styles = {
  safeArea: {
    backgroundColor: "#4d089a",
  },
  cameraView: {
    height: "100%",
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "transparent",
  },
  mask: {
    height: MASK_DIMENSION,
    width: MASK_DIMENSION,
    borderWidth: 3,
    borderColor: "white",
    borderStyle: "dotted",
    borderRadius: 15,
  },
  shutterButton: {
    position: "absolute",
    bottom: 0,
    width: 150,
    height: 40,
    justifyContent: "center",
    alignItems: "center",
    borderWidth: 1,
    borderColor: "white",
    borderRadius: 15,
    marginBottom: 20,
  },
  shutterButtonText: {
    fontSize: 18,
    color: "white",
  },
};CameraView.options = {
  statusBar: {
    backgroundColor: null,
  },
  topBar: {
    title: {
      text: "Take a picture",
      color: "white",
    },
    background: {
      color: "#4d089a",
    },
  },
  tapBar: {
    background: {
      color: "#4d089a",
    },
  },
};

src/screens/EvaluationView中创建一个index.js文件并添加以下代码:

import React from "react";
import { SafeAreaView, View, Text, StatusBar } from "react-native";export const EvaluationView = (props) => {
  return (
    <React.Fragment>
       <StatusBar barStyle="light-content" />
      <SafeAreaView style={styles.safeArea}>
        <View style={styles.container}>
           <Text style={styles.headerText}>ANALYSIS</Text>
        </View>
      </SafeAreaView>
    </React.Fragment>
  );
};const styles = {
  safeArea: {
    backgroundColor: "#4d089a",
  },
  container: {
    height: "100%",
    alignItems: "center",
    backgroundColor: "white",
  },
  headerText: {
    fontSize: 20,
    fontWeight: "500",
    color: "#4d089a",
    margin: 20,
  },
};

然后用下面的代码覆盖根目录中的index.js文件:

import { Navigation } from "react-native-navigation";
import { CameraView } from "./src/screens/CameraView";
import { EvaluationView } from "./src/screens/EvaluationView";Navigation.registerComponent("cameraView", () => CameraView);
Navigation.registerComponent("evaluationView", () => EvaluationView);Navigation.setDefaultOptions({
  statusBar: {
    style: "light",
    backgroundColor: "#4d089a",
  },
  topBar: {
    title: {
      color: "white",
    },
    background: {
      color: "#4d089a",
    },
    backButton: {
      color: "white",
      showTitle: false,
    },
  },
});Navigation.events().registerAppLaunchedListener(() => {
  Navigation.setRoot({
    root: {
      stack: {
        children: [
          {
            component: {
              name: "cameraView",
            },
          },
        ],
      },
    },
  });
});

最后,您可以删除App.js文件,因为不再需要它了。

重启你的 metro bundler,你应该会看到这个应用程序是这样运行的…

带有工作导航的应用程序的屏幕录制(图片由作者提供)

🏆恭喜恭喜!

您已经创建了基本应用程序,该应用程序还不能拍照,但可以从一个屏幕导航到另一个屏幕。

第二章:训练深度学习模型

最初,我使用的是这个来自 Kaggle 的预训练模型,但是让这个应用程序工作起来的努力是巨大的。

我不得不创建了一个 AWS EC2 深度学习 AMI(Amazon Linux 2)30.1 版本实例并使用 SSH 访问,因为我的 Macbook 不支持 CUDA。(训练模型需要 GPU 支持)
然后我必须从 Kaggle 复制Jupyter笔记本,运行笔记本在 AWS 实例上训练模型(它运行了 3 个小时)并将模型移回我的项目。
此外,我不得不安装 OpenGL 来修改图像,并编写了一个非常复杂的脚本来将 base64 字符串整形为张量,以匹配模型[1, 28, 28, 1]的预期输入。

模型开始在 AWS 上训练(图片由作者提供)

所有这些让我重新思考如何写这篇教程。毕竟,本教程应该是为那些只想玩机器学习模型而没有事先学习 PythonJupyterTensorflowKeras 的人准备的。此外,教程的长度将是现在的 5 倍。

注:如果你想学习如何使用tensor flow&Keras我用 deeplizard 找到了一个很好的关于深度学习的 Youtube 频道,内容非常丰富,也很符合我们在本教程中想要做的事情。
还有,Udemy
上的这门课也不错,可惜不是免费的。*😕*****

反正为了这个教程,我决定用 谷歌的可教机器 来训练图像。

这个想法是用我们刚刚建立的应用程序拍摄 28 x 28 像素的图像,将图像上传到可教机器,并将训练好的模型下载回我们的项目。

以防你问我为什么用 28 x 28 像素的图片?这是我首先使用的模型的原始输入大小。所以我坚持了下来。

这也意味着我们必须裁剪并保存拍摄的图像到相机库中。为了做到这一点,我们需要稍微修改一下我们的代码。

请在CameraView文件夹中创建一个helper.js文件,并粘贴以下代码:

**import { Dimensions } from "react-native";
import * as ImageManipulator from "expo-image-manipulator";
import CameraRoll from "[@react](http://twitter.com/react)-native-community/cameraroll";const { height: DEVICE_HEIGHT, width: DEVICE_WIDTH } = Dimensions.get("window");// got the dimension from the trained data of the *Teachable Machine*; pixel resolution conversion (8x)
export const BITMAP_DIMENSION = 224;export const cropPicture = async (imageData, maskDimension) => {
  try {
    const { uri, width, height } = imageData;
    const cropWidth = maskDimension * (width / DEVICE_WIDTH);
    const cropHeight = maskDimension * (height / DEVICE_HEIGHT);
    const actions = [
      {
        crop: {
          originX: width / 2 - cropWidth / 2,
          originY: height / 2 - cropHeight / 2,
          width: cropWidth,
          height: cropHeight,
        },
      },
      {
        resize: {
          width: BITMAP_DIMENSION,
          height: BITMAP_DIMENSION,
        },
      },
    ];
    const saveOptions = {
      compress: 1,
      format: ImageManipulator.SaveFormat.JPEG,
      base64: false,
    };
    return await ImageManipulator.manipulateAsync(uri, actions, saveOptions);
  } catch (error) {
    console.log("Could not crop & resize photo", error);
  }
};export const saveToCameraRoll = async (uri) => {
  try {
    return await CameraRoll.save(uri, "photo");
  } catch (error) {
    console.log("Could not save the image", error);
  }
};**

src/screens/CameraView/index.js中添加导入该文件

**import { cropPicture, saveToCameraRoll } from ‘./helpers’;**

添加takePicture功能,并修改handlePictureProcessing功能

**const handlePictureProcessing = async () => {
  const imageData = await takePicture();
  const croppedData = await cropPicture(imageData, MASK_DIMENSION);
  await saveToCameraRoll(croppedData.uri);
  // we don't want to go to the evaluation view now
  //goToEvaluationView();
};const takePicture = async () => {
  const options = {
    quality: 0.1,
    fixOrientation: true,
  };
  try {
    return await cameraRef.current.takePictureAsync(options);
  } catch (error) {
    console.log("Could not take photo", error);
  }
};**

如你所见,我们注释掉了行//goToEvaluationView();,这样我们就不会转到另一个屏幕。这意味着您可以连续拍摄任意多张照片。现在,所有照片都将保存在您的照片库中。

我们的下一个任务是在一张纸上写出尽可能多的 0 到 9 之间的数字变化。我们使用的数字、颜色和笔的形状越多,预测就越准确。

我很懒,最后每个数字大概有 10 个变化,但是对于一些数字,比如 4 和 8,预测有点偏差。

书写数字形状的变化(图片由作者提供)

所以由你决定让可教机器训练多少个数字。

当你完成拍摄图像后,把它们全部空投回你的 Mac,从那里把它们上传到 可教机器 并开始训练它们。

训练好的模型截图(图片由作者提供)

完成后,你可以用你的应用程序拍摄更多的照片并上传,以测试训练好的模型。

如果你对结果满意,点击Export Model->-Tensorflow.js ->-Download->-Download my model,会下载一个 ZIP 文件。

下载模型 poup(图片由作者提供)

解压 zip 文件,在src目录(src/model)下创建一个model文件夹,并将model.jsonweights.bin复制到该文件夹中。

我们还需要告诉 metro 处理新的文件格式:*.bin。所以请这样修改metro.config.js:

**const { getDefaultConfig } = require("metro-config");module.exports = (async () => {
  const {
    resolver: { assetExts },
  } = await getDefaultConfig();
  return {
    transformer: {
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: false,
        },
      }),
    },
    resolver: {
      assetExts: [...assetExts, "bin"],
    },
  };
})();**

太好了!现在我们的模型已经在项目中了,让我们开始使用模型来预测数字。

第三章:实现模型,预测并展示结果

首先,我们不想再保存照片到我们的照片库中。(除非你愿意)。

于是注释掉了那行//await saveToCameraRoll(croppedData.uri);
我们还需要裁剪图像的base64 string,最后,我们想通过props将那个base64 string传递给EvaluationView

让我们像这样再次修改我们的 CameraView src/screens/CameraView/index.js文件:

**const handlePictureProcessing = async () => {
  const imageData = await takePicture();
  const croppedData = await cropPicture(imageData, MASK_DIMENSION);
  // await saveToCameraRoll(croppedData.uri);
  goToEvaluationView(croppedData);
};const goToEvaluationView = (croppedData) => {
  Navigation.push(props.componentId, {
    component: {
      name: "evaluationView",
      options: {
        topBar: {
          title: {
            text: "Evaluating ML result",
            color: "white",
          },
          background: {
            color: "#4d089a",
          },
          backButton: {
            color: "white",
            showTitle: false,
          },
        },
      },
      passProps: {
        base64: croppedData.base64 || null,
      },
    },
  });
};**

🏆太棒了!

让我们在EvaluationView中显示图像。从react-native导入图像并将图像组件添加到View容器中

**<View style={styles.container}>
  <Text style={styles.headerText}>ANALYSIS</Text>
  <Image
    style={styles.imageContainer}
    source={{ uri: `data:image/gif;base64,${props.base64}` }}
    resizeMethod="scale"
  />
</View>;**

并在headerText样式下添加imageContainer的样式。

**imageContainer: {
 height: 300,
 width: 300,
},**

最后一步是转到src/screens/CameraView/helpers.js文件,将saveOptions更改为base64: true

🏆瞧!

你应该在分析文本下方的EvaluationView中看到拍摄的图像。**

现在我们要显示预测结果。我们需要将胜利图表和一些react-native包一起添加到EvaluationView

**import React from "react";
import {
  Dimensions,
  ActivityIndicator,
  SafeAreaView,
  View,
  Image,
  Text,
  StatusBar,
} from "react-native";
import {
  VictoryChart,
  VictoryAxis,
  VictoryBar,
  VictoryTheme,
} from "victory-native";const { width: DEVICE_WIDTH } = Dimensions.get("window");**

为了获得设备的【the VictoryChart 需要的),我们使用了Dimensions库。

然后添加胜利图容器。因为我们只想在得到预测结果后显示图表,所以我们添加了一个基于graphData.长度的条件

由于我们还没有工作模型,我们必须添加一些假的图表数据来查看图表的水平条

**import React from "react";
import {
  Dimensions,
  ActivityIndicator,
  SafeAreaView,
  View,
  Image,
  Text,
  StatusBar,
} from "react-native";
import {
  VictoryChart,
  VictoryAxis,
  VictoryBar,
  VictoryTheme,
} from "victory-native";const { width: DEVICE_WIDTH } = Dimensions.get("window");export const EvaluationView = (props) => {
  const graphData = [
    { number: 0, prediction: 0.04 },
    { number: 1, prediction: 0.02 },
    { number: 2, prediction: 0.02 },
    { number: 3, prediction: 0.1 },
    { number: 4, prediction: 0.85 },
    { number: 5, prediction: 0.04 },
    { number: 6, prediction: 0.2 },
    { number: 7, prediction: 0.12 },
    { number: 8, prediction: 0.0 },
    { number: 9, prediction: 0.0 },
  ];return (
    <React.Fragment>
      <StatusBar barStyle="light-content" />
      <SafeAreaView style={styles.safeArea}>
        <View style={styles.container}>
          <Text style={styles.headerText}>ANALYSIS</Text>
          <Image
            style={styles.imageContainer}
            source={{ 
              uri: `data:image/gif;base64,${props.base64}` 
            }}
            resizeMethod="scale"/>
          <View style={styles.resultContainer}>
            {graphData.length ? (
              <VictoryChart
                width={DEVICE_WIDTH - 20}
                padding={{ 
                  top: 30, bottom: 70, left: 50, right: 30 
                }}
                theme={VictoryTheme.material}>
                <VictoryAxis
                  tickValues={[1, 2, 3, 4, 5, 6, 7, 8, 9]}
                  tickFormat={[1, 2, 3, 4, 5, 6, 7, 8, 9]}/>
                 <VictoryAxis 
                   dependentAxis 
                   tickFormat={(tick) => tick} />
                <VictoryBar
                  style={{ data: { fill: "#c43a31" } }}
                  barRatio={0.8}
                  alignment="start"
                  data={graphData}
                  x="number"
                  y="prediction"/>
              </VictoryChart>
            ) : (
              <ActivityIndicator size="large" color="#4d089a" />
            )}
          </View>
        </View>
      </SafeAreaView>
    </React.Fragment>
  );
};**

你应该有一个这样的屏幕:

聊天显示虚假数据(图片由作者提供)

🏆你是冠军!

我们正在慢慢进入教程的最后一部分,在这里我们将加载模型,并将拍摄的照片与模型进行比较。

请在src目录下创建一个util.js并粘贴以下代码。

**/* eslint-disable no-bitwise */
/*
Copyright (c) 2011, Daniel Guerrero
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL DANIEL GUERRERO BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *//**
 * Uses the new array typed in javascript to binary base64 encode/decode
 * at the moment just decodes a binary base64 encoded
 * into either an ArrayBuffer (decodeArrayBuffer)
 * or into an Uint8Array (decode)
 *
 * References:
 * [https://developer.mozilla.org/en/JavaScript_typed_arrays/ArrayBuffer](https://developer.mozilla.org/en/JavaScript_typed_arrays/ArrayBuffer)
 * [https://developer.mozilla.org/en/JavaScript_typed_arrays/Uint8Array](https://developer.mozilla.org/en/JavaScript_typed_arrays/Uint8Array)
 */export const Base64Binary = {
  _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",/* will return a  Uint8Array type */
  decodeArrayBuffer: function (input) {
    var bytes = (input.length / 4) * 3;
    var ab = new ArrayBuffer(bytes);
    this.decode(input, ab);return ab;
  },removePaddingChars: function (input) {
    var lkey = this._keyStr.indexOf(input.charAt(input.length - 1));
    if (lkey === 64) {
      return input.substring(0, input.length - 1);
    }
    return input;
  },decode: function (input, arrayBuffer) {
    //get last chars to see if are valid
    input = this.removePaddingChars(input);
    input = this.removePaddingChars(input);var bytes = parseInt((input.length / 4) * 3, 10);var uarray;
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    var j = 0;if (arrayBuffer) {
      uarray = new Uint8Array(arrayBuffer);
    } else {
      uarray = new Uint8Array(bytes);
    }input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");for (i = 0; i < bytes; i += 3) {
      //get the 3 octects in 4 ascii chars
      enc1 = this._keyStr.indexOf(input.charAt(j++));
      enc2 = this._keyStr.indexOf(input.charAt(j++));
      enc3 = this._keyStr.indexOf(input.charAt(j++));
      enc4 = this._keyStr.indexOf(input.charAt(j++));chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;uarray[i] = chr1;
      if (enc3 !== 64) {
        uarray[i + 1] = chr2;
      }
      if (enc4 !== 64) {
        uarray[i + 2] = chr3;
      }
    }return uarray;
  },
};**

出于对开发者的尊重请不要删除版权免责声明😃**

现在创建另一个helpers.js文件,但这次是在EvaluationView目录src/screens/EvaluationView/helpers.js中,并复制这段代码

**import * as tf from "[@tensorflow/tfjs](http://twitter.com/tensorflow/tfjs)";
import "[@tensorflow/tfjs-react-native](http://twitter.com/tensorflow/tfjs-react-native)";
import { bundleResourceIO, decodeJpeg } from "[@tensorflow/tfjs-react-native](http://twitter.com/tensorflow/tfjs-react-native)";
import { Base64Binary } from "../../util";
import { BITMAP_DIMENSION } from "../CameraView/helpers";const modelJson = require("../../model/model.json");
const modelWeights = require("../../model/weights.bin");// 0: channel from JPEG-encoded image
// 1: gray scale
// 3: RGB image
const TENSORFLOW_CHANNEL = 3;export const getModel = async () => {
  try {
    // wait until tensorflow is ready
    await tf.ready();
    // load the trained model
    return await tf.loadLayersModel(bundleResourceIO(modelJson, modelWeights));
  } catch (error) {
    console.log("Could not load model", error);
  }
};export const convertBase64ToTensor = async (props) => {
  try {
    const uIntArray = Base64Binary.decode(props.base64);
    // decode a JPEG-encoded image to a 3D Tensor of dtype
    const decodedImage = decodeJpeg(uIntArray, 3);
    // reshape Tensor into a 4D array
    return decodedImage.reshape([
      1,
      BITMAP_DIMENSION,
      BITMAP_DIMENSION,
      TENSORFLOW_CHANNEL,
    ]);
  } catch (error) {
    console.log("Could not convert base64 string to tesor", error);
  }
};export const startPrediction = async (model, tensor) => {
  try {
    // predict against the model
    const output = await model.predict(tensor);
    // return typed array
    return output.dataSync();
  } catch (error) {
    console.log("Error predicting from tesor image", error);
  }
};export const populateData = (typedArray) => {
  const predictions = Array.from(typedArray);
  return predictions.map((item, index) => {
    return {
      number: index,
      prediction: item,
    };
  });
};**

这些是我们加载模型、将 base64 字符串转换为张量、预测数字和填充胜利图表数据的函数。

最后但同样重要的是,我们在src/screens/EvaluationView/index.jsuseEffect()钩子中调用这些函数。

这是该视图的完整代码:

**import React, { useState, useEffect } from "react";
import {
  Dimensions,
  ActivityIndicator,
  SafeAreaView,
  View,
  Image,
  Text,
  StatusBar,
} from "react-native";
import {
  VictoryChart,
  VictoryAxis,
  VictoryBar,
  VictoryTheme,
} from "victory-native";
import {
  getModel,
  convertBase64ToTensor,
  startPrediction,
  populateData,
} from "./helpers";const { width: DEVICE_WIDTH } = Dimensions.get("window");export const EvaluationView = (props) => {
  const [graphData, setGraphData] = useState([]);useEffect(() => {
    const predictDigits = async () => {
      const model = await getModel();
      const tensor = await convertBase64ToTensor(props);
      const typedArray = await startPrediction(model, tensor);
      setGraphData(populateData(typedArray));
    };
    predictDigits();
  }, [props]);return (
    <React.Fragment>
      <StatusBar barStyle="light-content" />
      <SafeAreaView style={styles.safeArea}>
        <View style={styles.container}>
          <Text style={styles.headerText}>ANALYSIS</Text>
          <Image
            style={styles.imageContainer}
            source={{ uri: `data:image/gif;base64,${props.base64}` }}
            resizeMethod="scale"
          />
          <View style={styles.resultContainer}>
            {graphData.length ? (
              <VictoryChart
                width={DEVICE_WIDTH - 20}
                padding={{ top: 30, bottom: 70, left: 50, right: 30 }}
                theme={VictoryTheme.material}
              >
                <VictoryAxis
                  tickValues={[1, 2, 3, 4, 5, 6, 7, 8, 9]}
                  tickFormat={[1, 2, 3, 4, 5, 6, 7, 8, 9]}
                />
                 <VictoryAxis dependentAxis tickFormat={(tick) => tick} />
                <VictoryBar
                  style={{ data: { fill: "#c43a31" } }}
                  barRatio={0.8}
                  alignment="start"
                  data={graphData}
                  x="number"
                  y="prediction"
                />
              </VictoryChart>
            ) : (
              <ActivityIndicator size="large" color="#4d089a" />
            )}
          </View>
        </View>
      </SafeAreaView>
    </React.Fragment>
  );
};const styles = {
  safeArea: {
    backgroundColor: "#4d089a",
  },
  container: {
    height: "100%",
    alignItems: "center",
    backgroundColor: "white",
  },
  headerText: {
    fontSize: 20,
    fontWeight: "500",
    color: "#4d089a",
    margin: 20,
  },
  imageContainer: {
    height: 300,
    width: 300,
  },
  resultContainer: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
};**

正如我之前提到的,模型会像你训练的模型一样好。

在现实世界中,数据工程师会使用数万种不同的手写数字来训练模型。然后将使用另一个集合来调整模型,并使用一个全新的集合来检查模型性能。

在我结束本教程之前,顺便提一下;如果你是一个经验丰富的 React 原生开发者,你现在应该已经意识到,通过一些手动导入,特别是*react-native-unimodules**expo-camera*和权限设置,这个项目也可以在 Android 上开箱即用。🤓**

我希望你已经学到了一些新东西。

如果我可以做一些不同的事情,或者如果你喜欢这个教程,请留下评论。毕竟我们都是来学习的,对吧?👨🏼‍🎓

10 分钟用深度 Java 库中的 Spark 进行深度学习

原文:https://towardsdatascience.com/deep-learning-with-spark-in-deep-java-library-in-10-minutes-923a73704094?source=collection_archive---------37-----------------------

介绍

Apache Spark 是一种广泛用于数据处理的技术,被机器学习用户大量使用。Spark 可用于产品分类、需求预测和个性化推荐。虽然 Spark 支持多种编程语言,但首选的 Spark SDK 是为 Scala 实现的,大多数深度学习框架都没有很好的支持。大多数机器学习框架喜欢 Python 及其 SDK,给 Spark 开发人员留下了次优选择:将他们的代码移植到 Python 或实现定制的 Scala 包装器。这些选项会影响开发人员的速度,并通过脆弱的代码威胁生产环境。

在这篇博客中,我们展示了用户如何使用 Deep Java 库 (DJL)直接从 Scala 执行深度学习工作负载。DJL 是一个框架无关的库,开发它是为了在用 Java 开发的 Spark jobs 中直接提供深度学习。在下面的教程中,我们将使用 MXNet 完成一个图像分类场景,尽管 PyTorch 和 TensorFlow 也受支持。完整代码见 DJL 星火图像分类示例

示例:使用 DJL 和火花进行图像分类

在本教程中,我们使用 resnet50 ,一个预先训练好的模型来运行推理。对于本教程,我们将使用一个具有三个工作节点的集群进行分类。工作流程如下图所示:

具有 3 个工作节点的 Spark 上的示例图像分类工作流

我们的示例将在流程中创建几个执行者,并为他们每个人分配任务。每个执行器包含一个或多个在不同线程中执行任务的核心。这为每个工作节点提供了平衡的大数据处理工作负载。

第一步。创建 Spark 项目

我们使用流行的开源工具 sbt 在 Scala 中构建这个 Spark 项目。您可以在这里找到更多关于如何开始使用 sbt 的资源。我们使用以下代码块在 sbt 中定义我们的项目:

name := "sparkExample"version := "0.1"scalaVersion := "2.11.12"
scalacOptions += "-target:jvm-1.8"resolvers += Resolver.mavenLocallibraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0"libraryDependencies += "ai.djl" % "api" % "0.5.0"
libraryDependencies += "ai.djl" % "repository" % "0.5.0"
// Using MXNet Engine
libraryDependencies += "ai.djl.mxnet" % "mxnet-model-zoo" % "0.5.0"
libraryDependencies += "ai.djl.mxnet" % "mxnet-native-auto" % "1.6.0"

本教程使用 MXNet 作为其底层引擎。切换到另一个框架很简单,如下例所示:

// Using PyTorch Engine
libraryDependencies += "ai.djl.pytorch" % "pytorch-model-zoo" % "0.5.0"
libraryDependencies += "ai.djl.pytorch" % "pytorch-native-auto" % "1.5.0"

步骤 2:配置 Spark

在本教程中,我们在本地机器上运行这个例子。Spark 应用程序将使用以下配置:

// Spark configuration
val conf = new SparkConf()
  .setAppName("Simple Image Classification")
  .setMaster("local[*]")
  .setExecutorEnv("MXNET_ENGINE_TYPE", "NaiveEngine")
val sc = new SparkContext(conf)

MXNet 中的多线程推理需要NaiveEngine参数。如果使用 PyTorch 或 TensorFlow,可以删除以下行:

.setExecutorEnv("MXNET_ENGINE_TYPE", "NaiveEngine")

步骤 3:识别输入数据

在本教程中,输入数据表示为包含要分类的图像的文件夹。Spark 将加载这些二进制文件,并将它们划分到不同的分区。每个分区由一个执行器执行。以下语句将把文件夹中的所有图像均匀地分布在每个分区上。

val partitions = sc.binaryFiles("images/*")

步骤 4:定义 Spark 工作

接下来,我们使用上一步中创建的分区为这个作业创建执行图。在 Spark 中,每个执行器以多线程的方式执行任务。因此,在执行推理之前,我们需要将每个模型加载到执行器中。我们使用以下代码进行设置:

// Start assign work for each worker node
val result = partitions.mapPartitions( partition => {
   // before classification
    val criteria = Criteria.builder
        .optApplication(Application.CV.IMAGE_CLASSIFICATION)
        .setTypes(classOf[BufferedImage], classOf[Classifications])
        .optFilter("dataset", "imagenet")
        .optFilter("layers", "50")
        .optProgress(new ProgressBar)
        .build
   val model = ModelZoo.loadModel(criteria)
    val predictor = model.newPredictor()
   // classification
   partition.map(streamData => {
        val img = ImageIO.read(streamData._2.open())
        predictor.predict(img).toString
    })
})

需要为每个分区指定模型动物园的标准,以定位相应的模型并创建预测器。在分类过程中,我们从 RDD 加载图像,并为它们创建推论。

这个模型用 ImageNet 数据集训练,存储在 DJL 模型动物园。

步骤 5:定义输出位置

在我们完成映射过程之后,主节点将收集、聚合结果并将其保存在文件系统中。

result.collect().foreach(*print*)
result.saveAsTextFile("output")

运行这段代码会产生前面列出的输出类。输出文件将保存到不同分区的output文件夹中。本教程完整代码请见 Scala 示例

控制台的预期输出:

[
    class: "n02085936 Maltese dog, Maltese terrier, Maltese", probability: 0.81445
    class: "n02096437 Dandie Dinmont, Dandie Dinmont terrier", probability: 0.08678
    class: "n02098286 West Highland white terrier", probability: 0.03561
    class: "n02113624 toy poodle", probability: 0.01261
    class: "n02113712 miniature poodle", probability: 0.01200
][
    class: "n02123045 tabby, tabby cat", probability: 0.52391
    class: "n02123394 Persian cat", probability: 0.24143
    class: "n02123159 tiger cat", probability: 0.05892
    class: "n02124075 Egyptian cat", probability: 0.04563
    class: "n03942813 ping-pong ball", probability: 0.01164
][
    class: "n03770679 minivan", probability: 0.95839
    class: "n02814533 beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon", probability: 0.01674
    class: "n03769881 minibus", probability: 0.00610
    class: "n03594945 jeep, landrover", probability: 0.00448
    class: "n03977966 police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria", probability: 0.00278
]

在您的生产系统中

在这种方法中,我们使用 RDD 来执行我们的图像作业,用于演示目的。随着数据帧使用和节省高速缓存的趋势,生产用户应该考虑为这些图像创建一个模式,并以数据帧格式存储它们。从 Spark 3.0 开始,Spark 提供了一个二进制文件阅读器选项,使得图像转换为数据帧更加方便。

个案研究

亚马逊零售系统(ARS)使用 DJL 通过 Spark 路由的大量数据流进行了数百万次预测。这些预测使用成千上万的客户属性来确定客户在多个类别中采取行动的倾向,然后向客户呈现相关的广告和横幅。

ARS 使用数十万个特征,拥有数亿个客户——超过十万亿个数据点。他们需要一个能够有效扩展的解决方案。为了解决这个关键问题,他们最初为自己的工作创建了一个 Scala 包装器,但是这个包装器有内存问题,执行起来很慢。在采用 DJL 之后,他们的解决方案与 Spark 完美配合,总的推理时间从几天降到了几个小时。

敬请关注我们的下一篇博文,我们将深入探讨并介绍更多 ARS 面临的挑战,以及他们如何通过与 DJL 建立管道来解决这个问题。

了解更多关于 DJL 的信息

完成本教程后,你可能想知道 DJL 是什么。深度 Java 库(DJL)是一个开源库,用于在 Java 中构建和部署深度学习。该项目于 2019 年 12 月推出,由亚马逊各地的工程团队使用。这一努力受到了其他 DL 框架的启发,但是是从底层开始开发的,以更好地适应 Java 开发实践。DJL 是框架不可知的,支持 Apache MXNet、PyTorch、TensorFlow 2.x(实验)和 fastText(实验)。

要了解更多,请查看我们的网站Github 资源库Slack channel。

使用尖峰网络的深度学习:优化能耗

原文:https://towardsdatascience.com/deep-learning-with-spiking-networks-optimising-energy-consumption-50588b4435fd?source=collection_archive---------28-----------------------

神经形态硬件提供了通过尖峰进行通信的超低功耗神经网络,有点像真正的神经元。但是我们如何训练他们呢?

神经形态芯片的特写。照片 Ole Richter/aiCTX AG

在如今被称为“神经网络”(在深度学习的意义上)和大脑中的神经元网络之间有几个重要的区别。一个特别明显的例子是,人工网络具有模拟激活——人工神经元的输出是一个连续的数字。相反,生物神经元通过称为动作电位或尖峰的离散、全有或全无的电事件进行交流。当然,我们也可以模拟和使用尖峰网络(SNNs)。

你可能想训练一个尖峰神经网络有两个原因:也许,你正试图理解大脑计算或学习的某些方面;或者,您可能希望使用脉冲网络来执行机器学习任务,就像您使用卷积网络(CNN)等“常规”神经网络一样。

你为什么要做这种事?如何训练一个尖峰网络肯定不如深度学习中使用的反向传播和梯度下降的过程那样为人所知。尖峰网络不会优于 CNN,并且训练和模拟会困难得多。然而,人们有兴趣这样做。这是因为与传统计算机相比,脉冲网络可以在极低功耗的神经形态硬件上运行。这是因为神经形态芯片是专门为低功率推理而构建的,并在其电路中复制一个尖峰神经元的动态,而不是在计算机上模拟它。其次,尖峰网络以基于事件的方式进行计算,这使得它们成为处理基于事件的数据的理想工具,例如动态视觉传感器的输出。

DVS 录音示例。图像由记录了位置和时间的事件(类似于尖峰)组成。没有帧率。当场景中没有变化时,就没有事件(因此背景大部分是不可见的)。(自己的工作)

神经形态工程是一个不断发展的领域,开发有用的脉冲网络模型是一个相应的有趣的挑战。可以使用“替代梯度”技巧通过梯度下降来训练脉冲网络,避免信号离散性的问题,但这仍然复杂而缓慢[1,4]。当我们对生物合理性不感兴趣,也对时间相关方面不太感兴趣时,事实证明训练传统(模拟)CNN 更容易,然后在尖峰网络上使用相同的权重[2]。你可以想象,如果放电频率足够高,在给定的时间间隔内接收到的棘波数量可以很好地近似一个连续的数字:CNN 中相应神经元的激活值。这就是计算神经科学家所说的速率编码

优化能源消耗的费率代码

我们试图以稍微聪明一点的方式使用这种蛮力方法。如我所说,在速率编码中,每个神经元都试图用特定的尖峰频率来代表激活。这个频率应该和激活成正比,但是应该有多大呢?1.42 这个数字应该用每秒多少个尖峰来表示?有两种风险:

  • 如果尖峰信号的数量太低,我们最终会离散化激活,我们将无法安全地分辨出,比如说,1.42 和 1.35,因为它们都由相同数量的尖峰信号表示。
  • 如果尖峰信号太多,我们将会消耗更多的能量。当网络静默时,神经形态硬件几乎不使用任何功率,但每当每个下游神经元接收到一个尖峰信号时,都会消耗能量。这些突触操作的数量与神经形态芯片的有效功耗成正比。顺便说一句,大脑也面临类似的限制。

我们介绍了两种对策,帮助我们在这两个问题之间找到正确的平衡。我们的方法类似于[5]中为 TrueNorth 神经形态系统开发的方法。

量化感知训练

首先,虽然训练是在常规的模拟 CNN 上进行的,但我们希望我们的网络至少能够意识到它的激活将在某个点上被转移到一个脉冲 convnet 上,信号将被强制离散化。为此,我们在每个 ReLU 层将所有 CNN 激活向下舍入到下一个整数值。这是为了保护我们免受上面列出的两个问题中的第一个。训练过程将考虑离散化误差。

正如一些读者已经猜到的,这导致梯度几乎在所有地方都变为零,对反向传播造成灾难性的后果。但不要担心:我们总是可以用一个替代(即假)梯度来装备我们的“量化”ReLU (QReLU),这忽略了离散化。换句话说,我们在向前传递时进行向下舍入,但在向后传递时不进行向下舍入。

QReLU 响应函数。(自己的工作)

如果您想知道如何欺骗 PyTorch 将手动选择的渐变替换为实际渐变,那么使用自定义的 backward()定义 PyTorch 函数非常简单:

# Defining a PyTorch function with a custom backward()
class _Quantize(torch.autograd.Function):
    @staticmethod
    # ctx is a "context object" that we don't need
    def forward(ctx, input):
        # round down
        return input.floor()

    @staticmethod
    def backward(ctx, grad_output):
        # don't do anything (identity function)
        return grad_output.clone()

训练期间的量化并不是一个新的想法,实际上也越来越受欢迎,但在一个相当不同的背景下。当我们想为激活、网络参数或两者使用低精度数据类型(通常是 int8,而不是 PyTorch 中的标准,即 float32)来节省内存时,这很有用。PyTorch 最近引入了这个特性

最小化突触操作的数量

我们在做机器学习,我们想最小化一些东西,我们该怎么做?当然是加在损失上。

即使在训练期间,我们也可以估计 SNN 中将要发生的突触操作的数量,这是在它完全变成 SNN 之前。我们通过观察我们的量化激活来估计尖峰的数量,并将每个神经元的尖峰率乘以该神经元的“扇出”——将接收其尖峰的神经元数量。我们为这个量设定一个目标(我称之为“SynOps”),并给损失加上一个二次惩罚。

有了这两个工具,即“SynOp loss”和量化感知训练,我们可以训练更好的脉冲卷积神经网络来解决类似 CNN 的计算机视觉任务。值得重复的是,我们离大脑中的尖峰网络学习的目标还很远。但这不是我们的目标(我希望现在已经很清楚了)。

测试

我们在两个物体识别任务上测试了我们的 snn。一个是常见的 CIFAR10,另一个是 MNIST-DVS ,这是一组用动态视觉传感器(基于事件的相机)记录的移动 MNIST 手指的短视频。

来自 MNIST-DVS 数据集的样本,显示数字 2。(自己的工作)

我们在适当的尖峰网络模拟上测试结果,并在测试集上测量概要(记住,它与网络的能量消耗成比例)和分类准确度。

MNIST-DVS 的调查结果。(来源:[3])

在 MNIST-DVS 数据集上,与上下缩放权重(或输入)以减少活动的基线方法相比,我们获得了明显更好的能量准确性平衡。例如,用我们的方法训练的特别好的网络具有比基线稍低的准确度(从 96.3%到 95.0%),几乎低一个数量级的天气计数。在 CIFAR10 上,我们实现了非常高的 SNN 精度,但功耗却低得多。

文献学

[1] E. Neftci,H. Mostafa 和 F. Zenke,脉冲神经网络中的代理梯度学习:将基于梯度的优化的力量引入脉冲神经网络 (2019),IEEE 信号处理杂志 36,6。

[2] B. Rueckauer 等连续值深度网络向高效事件驱动网络的转换用于图像分类, (2017)神经科学前沿。

[3] M. Sorbaro,Q. Liu,M. Bortone 和 S. Sheik,优化用于神经形态应用的脉冲神经网络的能量消耗 (2019),arXiv 预印本。

[4] Shrestha,S. B .,& Orchard,G. (2018 年)。杀戮者:钉层错误重新分配时间。在神经信息处理系统的进展(第 1412-1421 页)。

[5]埃塞、S. K .、梅罗拉、P. A .、阿瑟、J. V .、卡西迪、阿普斯瓦米、r .、安德烈奥普洛斯、a .、… &巴奇、D. R. (2016)。用于快速、节能神经形态计算的卷积网络。2016.ArXiv 上的预印本。

更多信息

请阅读(并引用)我们在 arXiv 上提供的预印本。这项工作已经作为原始研究文章提交给神经科学前沿专题。

复制我们的作品

GitLab 上有一个公共知识库供那些想要复制这项工作的人使用。您还需要下载(免费提供的)数据集。这在自述文件中有解释,但是如果您需要帮助,请联系我们。

使用 TensorFlow 进行深度学习

原文:https://towardsdatascience.com/deep-learning-with-tensorflow-5d3a7a8c55cd?source=collection_archive---------65-----------------------

深度学习

深度学习是机器学习的子集,机器学习是人工智能的子集。人工智能是一种使机器能够模仿人类行为的技术。深度学习是一种机器学习,受人脑结构的启发。这种结构被称为人工神经网络。

深度学习 vs 机器学习

机器学习使用算法来解析数据,从数据中学习,并根据所学内容做出决策。深度学习将算法结构化为多层,以创建一个“人工神经网络”,它可以自己学习并做出智能决策。虽然两者都属于人工智能的大范畴,但深度学习是最像人类的人工智能的动力。

什么是神经网络?

神经网络是人脑的简化。它是由神经元层构成的。这些神经元是网络的核心处理单元。一个神经网络由三种类型的层组成:输入层、输出层和隐藏层。首先,我们有接收输入的输入层和预测最终输出的输出层。在中间,我们有隐藏层,它执行我们的网络所需的大部分计算。此外,值得一提的是,神经网络被设计用来识别数据中的模式。

问题

让我们尝试解决上一篇帖子的问题—https://towards data science . com/big-data-analyses-with-machine-learning-and-py spark-135119 ef6b 31。在这个特殊的案例中,我们需要在一个金融机构中进行多种统计计算。一个例子是根据独立变量的数量来确定客户是否有存款。这次我们将尝试使用 TensorFlow 来训练模型。

数据预处理

数据预处理是机器学习中至关重要的一步,对模型的准确性至关重要。这种技术允许我们将原始数据转换成干净可用的数据集。使用这一步,我们将通过重新缩放、标准化、二进制化等使数据更有意义。我们正在使用的数据集是经过预处理的(关于这一点的更多信息,请参见上一篇文章https://towardsdatascience . com/data-preprocessing-for-machine-learning-in-python-2d 465 f 83 f 18 c)。

在这种情况下,我们应该对数据集做的唯一事情就是将它分成训练集、验证集和测试集。

  • 训练数据集:用于拟合模型的数据样本。
  • 验证数据集:数据样本,用于在调整模型超参数时,对训练数据集上的模型拟合提供无偏评估。
  • 测试数据集:用于提供最终模型在训练数据集上的无偏评估的数据样本。

此外,我们将把数据保存在。npz 文件格式。NPZ 是 numpy 开发的一种文件格式,使用 gzip 压缩提供数组数据的存储。

张量流

深度学习的主要软件工具是 TensorFlow。它是一个开源的人工智能库,使用数据流图来建立模型。张量流主要用于:分类、感知、理解、发现、预测、创造。TensorFlow 的五个主要用例是:

  • 语音/声音识别
  • 基于文本的应用
  • 图像识别
  • 时间序列
  • 视频检波

导入库

我们需要导入将要使用的库。在我们的例子中,我们需要:

  • Numpy—Python 编程语言的库,增加了对大型多维数组和矩阵的支持,以及对这些数组进行操作的大量高级数学函数
  • TensorFlow —一个免费的开源软件库,用于数据流和跨一系列任务的差异化编程。

加载数据

首先,我们需要从之前保存的文件中加载数据。这可以通过使用 numpy 的 load 方法来完成。

定义模型

我们需要定义输出大小—在我们的例子中,我们期望两个输出(1 —是和 0 —否),所以大小将是 2。

接下来,我们需要定义隐藏层的大小。隐藏层的大小应介于输入层和输出层的大小之间。在这种情况下,隐藏层大小将为 30。

唯一剩下的事情就是定义模型。本例中的模型是使用 keras 定义的。顺序模型是层的线性堆叠。当我们定义模型时,我们需要为隐藏层和输出层选择激活函数。

激活功能

激活函数是神经网络的组成部分之一。如果我们有一个没有激活函数的神经网络,每个神经元将只使用权重和偏差对输入执行线性变换。这样定义的话,神经网络的功能将会减弱,它将无法从数据中学习复杂的模式。因此,激活函数用于将非线性变换添加到输入中。在下图中,我们可以看到可以使用的常用激活功能。

在这种情况下,我们对隐藏层使用 ReLU(校正线性单位),对输出层使用 Softmax。

  • ReLU 是神经网络中最常用的激活函数,尤其是在 CNN 中。如果您不确定在您的网络中使用什么激活功能,ReLU 通常是一个不错的首选。
  • Softmax 是指数型的,会扩大差异—将一个结果推至接近 1,而将另一个结果推至接近 0。它将分数即逻辑转换成概率。

编译模型

在这一步中,我们将为培训配置模型。Compile 定义了损失函数、优化器和指标。我们需要一个编译好的模型来训练(因为训练使用了损失函数和优化器)。

  • 优化器:优化算法或策略负责减少损失,并尽可能提供最准确的结果。在这个例子中,我们使用了一种叫做 Adam 的优化算法。 Adam 是一种优化算法,可用于替代经典的随机梯度下降过程,根据训练数据迭代更新网络权重。
  • Loss :这是一种评估特定算法对给定数据建模程度的方法。如果预测与实际结果相差太多,损失函数就会产生一个非常大的数字。分类交叉熵和稀疏分类交叉熵具有相同的损失函数,唯一的区别是,当输入是一次热编码时,我们使用分类交叉熵,当输入是整数时,我们使用稀疏分类交叉熵。
  • 指标:指标是用来判断模型性能的函数。

拟合模型

当我们拟合模型时,我们实际上是在为固定数量的历元(数据集上的迭代)训练模型。我们需要定义批量大小、最大时期和提前停止。

  • 批量 —一次正反向通过的训练样本数。
  • 最大时期 —训练模型的时期数。一个历元是对所提供的整个 x 和 y 数据的迭代。
  • 提前停止 —当监控的数量停止提高时,停止训练。耐心是一个数字,它定义了产生无改善的监控量的时期数,在此之后训练将停止。

结果

在下图中,我们可以看到训练的结果。如果我们将准确性(86%)与之前博客帖子中的准确性(82%)进行比较,我们可以看到,在这种情况下,它更大。

评估模型

返回测试模式下模型的损耗值和度量值。在这个函数中,输入数据将是我们的测试集。该函数将返回标量测试损失(如果模型只有一个输出,没有指标)或标量列表(如果模型有多个输出和/或指标)。

结论

这就是深度学习的基本思想。有许多类型的深度学习、不同种类的神经网络、各种架构和训练算法。神经网络背后的想法已经存在了很长时间,但今天它有了很大的进展。深度学习的未来特别光明!未来深度学习的可能性是无限的,从无人驾驶汽车到探索宇宙的机器人。

如果你对这个话题感兴趣,请随时联系我。

领英简介:【https://www.linkedin.com/in/ceftimoska/

博客原文可从以下链接获得:【https://interworks.com.mk/deep-learning-with-tensorflow/

另外,你可以在下面的链接中找到另一篇类似的博文:https://interworks.com.mk/focusareas/data-management/

基于 FastAI 的不平衡表格数据加权交叉熵损失深度学习

原文:https://towardsdatascience.com/deep-learning-with-weighted-cross-entropy-loss-on-imbalanced-tabular-data-using-fastai-fe1c009e184c?source=collection_archive---------12-----------------------

轻松构建深度学习模型同时避免陷阱的指南

照片由 Unsplash 上的 Aditya Das 拍摄

FastAI 是一个非常方便和强大的机器学习库,将深度学习(DL)带给大众。我写这篇文章的动机是为了解决与训练二进制分类任务的模型相关的一些问题。我的目标是向您介绍使用 FastAI 为一个 表格不平衡 数据集构建一个简单有效的 DL 模型所需的步骤,同时避免我曾经犯过的错误。本文中的讨论是根据下面列出的部分组织的。

  1. 资料组
  2. 示例代码
  3. 代码分解
  4. FastAI 与 PySpark ML & Scikit-Learn 的比较
  5. 结论

1.资料组

数据集来自 ad 转换的上下文,其中 二进制 目标变量 1 和 0 对应转换成功和失败。这个专有数据集(不,我没有权利)有一些特别有趣的属性,因为它的维度、类别不平衡以及特征和目标变量之间相当弱的关系。

首先,数据的维度:这个表格数据集包含相当大量的记录和 分类特征 ,它们具有非常高的

:在 FastAI 中,分类特征使用 嵌入 来表示,这样可以提高高基数特征的分类性能。

二、二进制 类标签 高度不平衡由于成功的广告转换比较少见。在本文中,我们通过算法级方法(加权交叉熵损失函数)来适应这种约束,而不是数据级方法(重采样)。**

三、 关系特征目标变量 之间的 是相当弱的 。例如,在显著的模型调整后,逻辑回归模型的 ROC 曲线下的验证面积为 0.74。**

数据集属性摘要

  • 维度:17 个特征,1 个目标变量,3738937 行
  • 二元目标类
  • 阶层失衡比例为 1:87
  • 6 个数字特征
  • 8 个分类特征
  • 分类要素的组合基数为 44,000

2.示例代码

这段代码是在 Google Cloud — AI 平台 上的 Jupyter Lab 笔记本上运行的,规格如下。

  • 4 个 N1 标准 vCPUs,15 GB 内存
  • 1 个英伟达特斯拉 P4 GPU
  • 环境:PyTorch 1.4
  • 操作系统:Debian 9

模型培训管道将在下一节中解释,如下所示。

用于表格数据二进制分类的 FastAI 流水线

3.代码分解

导入包

通过命令终端安装fastaifastbook。有关设置的更多详细信息,请查看此链接

**conda install -c fastai -c pytorch fastai
git clone https://github.com/fastai/fastbook.git
pip install -Uqq fastbook**

将 FastAI 库和熊猫导入笔记本。

**import pandas as pd 
from fastai.tabular.all import ***

按要素类型加载数据和分组列名

由于隐私原因,列名必须匿名。

**df = pd.read_csv('data/training.csv')# Categorical Features
CAT_NAMES = ['col_1', 'col_2', 'col_3', 'col_4', 
             'col_5', 'col_6', 'col_7', 'col_8'] # Continuous Features
CONT_NAMES = ['col_9', 'col_10', 'col_11', 
              'col_12', 'col_13', 'col_14'] # Target Variable
TARGET = 'target'**

强制转换目标变量数据类型

将二进制目标变量的数据类型改为类别

**df[TARGET] = df[TARGET].astype('category')**

陷阱#1 :如果目标变量数据类型保留为数值,FastAI/PyTorch 会将其视为数值,并产生运行时错误。**

实例化数据加载器

接下来,列出数据预处理程序、训练/验证集拆分并创建表格数据加载器。

**# Data Processors
procs = [Categorify, FillMissing, Normalize] # Training/Validation Dataset 80:20 Split 
splits = RandomSplitter(valid_pct=0.2)(range_of(df)) dls = TabularDataLoaders.from_df(df,                                         
                                 y_names=TARGET,                                  
                                 cat_names=CAT_NAMES,                                 
                                 cont_names=CONT_NAMES,                                 
                                 procs=procs,                                 
                                 splits=splits)**

使用dls.xs查看转换后的训练数据。

构造损失函数权重

类别不平衡被用于创建交叉熵损失函数的权重,从而确保多数类别被相应地向下加权。此处使用的砝码公式与 scikit-learnPySPark ML 中的公式相同。

**class_count_df = df.groupby(TARGET).count() 
n_0, n_1 = class_count_df.iloc[0, 0], class_count_df.iloc[1, 0] 
w_0 = (n_0 + n_1) / (2.0 * n_0)
w_1 = (n_0 + n_1) / (2.0 * n_1) 
class_weights=torch.FloatTensor([w_0, w_1]).cuda()**

陷阱#2 : 确保将类权重转换为浮点张量,并通过.cuda()启用 cuda 操作。否则,你会得到一个类型的错误。**

**TypeError: cannot assign 'list' object to buffer 'weight' (torch Tensor or None required)**

实例化 ROC 指标下的区域

**roc_auc = RocAucBinary()**

陷阱#3 :对于二进制类标签,使用RocAucBinary()而不是RocAuc(),以避免值错误。**

**ValueError: y should be a 1d array, got an array of shape (2000, 2) instead.**

实例化损失函数

**loss_func = CrossEntropyLossFlat(weight=class_weights)**

陷阱#5: 使用 FastAI 交叉熵损失函数,与torch.nn.CrossEntropyLoss()的 PyTorch 等价函数相反,以避免错误。此处列出了 FastAI 损失函数。使用 PyTorch 交叉熵损失给了我以下运行时错误。

**RuntimeError: Expected object of scalar type Long but got scalar type Char for argument #2 'target' in call to _thnn_nll_loss_forward**

实例化学习者

使用 FastAI 中的tabular_learner轻松实例化一个架构。

**learn = tabular_learner(dls, 
                        layers=[500, 250],    
                        loss_func=loss_func, 
                        metrics=roc_auc)**

仔细检查learn是否使用了正确的损失函数:

**learn.loss_func 
Out [1]: FlattenedLoss of CrossEntropyLoss()**

模型训练和验证分数

在所需的历元数上训练模型。

**learn.fit_one_cycle(3)**

训练和验证集的性能度量和损失函数值如下所示。

ROC 曲线下面积在短短 3 个时期内达到 0.75!

太好了!通过最小的调整,FastAI 模型比使用 PySpark 和 Scikit-Learn 精心构建的模型性能更好。

4.FastAI 与 PySpark ML & Scikit-Learn 逻辑回归模型的比较

在这一节中,我们比较了这三个 ML 库的模型性能和计算时间。

****注:虽然神经网络在没有大量超参数调整的情况下表现良好,但 PySpark ML 和 Scikit-Learn 则不然。因此,我添加了这些时间,因为它们与训练下降模型相关。

模型训练时间

  1. FastAI — 6 分钟
  2. PySpark ML — 0.7 秒+ 38 分钟用于超参数调整
  3. Scikit-Learn — 36 秒+ 8 分钟用于超参数调整(基于数据的子样本)

ROC 曲线下面积

  1. FastAI — 0.75
  2. PySpark ML — 0.74
  3. Scikit-Learn — 0.73

更多详情,请查看我的 Github 回购

5.结论

在本文中,我们看到了 FastAI 在快速构建 DL 模型方面的强大功能。在使用 FastAI 之前,我会推迟使用神经网络,直到我已经尝试了逻辑回归、随机森林等等。因为神经网络难以调整且计算昂贵。然而,随着通过谷歌人工智能平台笔记本和分层 FastAI 方法对 GPU 的可访问性增加,现在它肯定会是我在大型复杂数据集上进行分类任务时首先使用的工具之一。

深度学习的数学

原文:https://towardsdatascience.com/deep-learnings-mathematics-f52b3c4d2576?source=collection_archive---------8-----------------------

罗马法师在 Unsplash 上拍摄的照片

探索深度学习成功背后的数学和方程式

深度学习是基于人工神经网络的机器学习科学的一个分支。它有几个衍生物,如多层感知器-MLP,卷积神经网络-CNN-和递归神经网络-RNN-可应用于许多领域,包括计算机视觉,自然语言处理,机器翻译…

深度学习的兴起有三个主要原因:

  • 本能特征工程:虽然大多数机器学习算法需要人类的专业知识来进行特征工程和提取,但深度学习会自动处理变量及其权重的选择
  • 巨大的数据集:持续不断的数据收集产生了大型数据库,这使得更深层次的神经网络成为可能
  • 硬件发展:用于图形处理单元的新 GPU 允许更快的代数计算,这是 DL 的核心基础

在这篇博客中,我们将主要关注多层感知器-MLP-我们将详细介绍深度学习成功背后的数学背景,并探索用于提高其性能的优化算法。

摘要如下:

  1. 定义
  2. 学习算法
  3. 参数初始化
  4. 正向-反向传播
  5. 激活功能
  6. 最优化算法

注意:因为 Medium 不支持 LaTeX,所以数学表达式是作为图像插入的。因此,为了更好的阅读体验,我建议你关闭黑暗模式。

1-定义

神经元

它是一组连接实体的数学运算

让我们考虑这样一个问题,我们根据房子的大小来估计房子的价格,它可以被图解如下:

一般来说,神经网络更好地被称为 MLP,意为“多层感知器”,是一种直接形式的神经网络,被组织成若干层,其中信息仅从输入层流向输出层。

每一层都由一定数量的神经元组成,我们区分:

-输入层

-隐藏层

-输出层

下图表示一个神经网络,其输入端有 5 个神经元,第一个隐藏层有 3 个,第二个隐藏层有 3 个,输出端有 2 个。

隐含层中的一些变量可以根据输入特征来解释:在房屋定价的情况下,在假设第一个隐含层的第一个神经元更关注变量x1etx2的情况下,可以解释为例如房屋的家庭规模的量化。

作为监督任务的 DL

在大多数 DL 问题中,我们倾向于使用一组变量 X 来预测输出 y,在这种情况下,我们假设对于数据库的每一行 X_i 我们都有相应的预测 y_i ,因此有标记的数据。

应用:房地产、语音识别、图像分类……

使用的数据可以是:

  • 结构化:明确定义了特性的数据库
  • 非结构化:音频、图像、文本……

通用逼近定理

现实生活中的深度学习是给定函数 f 的近似。由于以下定理,这种近似是可能的和精确的:

(*)在有限维中,如果一个集合是闭且有界的,则称它是紧的。更多详情,请访问此链接
这种算法的主要优点是深度学习允许解决任何可以用数学表达的问题

数据预处理

一般来说,在任何机器学习项目中,我们将数据分为 3 组:

-训练集:用于训练算法和构造批次

- Dev set :用于微调算法,评估偏差和方差

-测试集:用于概括最终算法的误差/精度

下表根据数据集 m 的大小总结了三个数据集的重新划分:

标准的深度学习算法需要一个大的数据集,其中样本数量大约为行。现在数据已经准备好了,我们将在下一节看到训练算法。通常,在分割数据之前,我们还会对输入进行归一化处理,这一步将在本文后面详细介绍。

2.学习算法

神经网络中的学习是计算与整个网络中各种回归相关的参数权重的步骤。换句话说,我们的目标是从输入开始,找到给出真实值的最佳预测/近似的最佳参数。
为此,我们定义了一个目标函数,称为loss function,记为J,它量化了整个训练集的实际值和预测值之间的距离。我们通过以下两个主要步骤来最小化 J:

**- Forward Propagation**:我们通过网络完整地或成批地传播数据,并且我们计算该批上的损失函数,该损失函数只不过是在不同行的预测输出处提交的误差的总和。

**- Backpropagation**:包括计算关于不同参数的成本函数的梯度,然后应用下降算法来更新它们。

我们多次重复同样的过程,称为epoch number。定义架构后,学习算法编写如下:

(∫)成本函数 L 计算单个点上实际值和预测值之间的距离。

3.参数初始化

定义神经网络结构后的第一步是参数初始化。这相当于将初始噪声注入模型的权重。

  • 零初始化:我们可以考虑用 0 来初始化参数,即:W=0,b=0

使用正向传播方程,我们注意到所有隐藏单元将是对称的,这不利于学习阶段。

  • 随机初始化:这是一种常用的替代方法,包括在参数中注入随机噪声。如果噪声太大,一些激活函数可能会饱和,这可能会影响梯度的计算。

两种最著名的初始化方法是:

  • Xavier的:它包括用从服从正态分布的中心变量中随机抽样的值填充参数;

  • Glorot的:相同的方法有不同的方差:

4.正向和反向传播

在深入研究深度学习背后的代数之前,我们将首先设置注释,该注释将用于解释正向和反向传播的方程。

神经网络的表示法

神经网络是一系列的regressions后跟一个activation function。它们都定义了我们所说的正向传播。并且是每层的学习参数。反向传播也是一系列从输出到输入的代数运算。

正向传播

  • 通过网络代数

让我们考虑具有如下L layers的神经网络:

通过训练集的代数

让我们考虑通过神经网络预测单行数据帧的输出。

当处理一个 m 行的数据集时,对每一行分别重复这些操作是非常昂贵的。
我们在每一层都有[ ]:

参数 b_i 使用广播通过列重复自身。下图对此进行了总结:

反向传播

反向传播是学习的第二步,它包括将预测(正向)阶段犯下的错误注入网络,并更新其参数以在下一次迭代中表现更好。
因此,函数 J 的优化,通常通过下降法。

计算图形

大多数下降方法需要计算表示为∇ J ( θ )的损失函数的梯度。

在神经网络中,使用将函数 J 分解成几个中间变量的计算图进行运算。

我们来考虑下面这个函数: f ( xyz)=(x+y)。 z

我们使用两个通道进行计算:

  • 正向传播:计算从输入到输出的 f 的值:f(2,5,4)=-12
  • 反向传播:递归应用链规则计算从输出到输入的梯度:

导数可以在下面的计算图中恢复:

方程式

数学上,我们计算成本函数 J ,w.r.t 架构参数 Wb 的梯度。

其中(⋆)是逐元素乘法。
我们递归地将这些等式应用于 i = LL1,…,1

梯度检查

当执行反向传播时,增加了额外的检查以确保代数计算是正确的。

算法:

它应该接近 ϵ 的值,当量值比 ϵ.高一千时,怀疑有错误

我们可以在下面的方框中总结前向和后向传播:

参数与超参数

-参数,表示为 θ ,是我们通过迭代学习的元素,我们对其应用反向传播和更新: Wb.

-超参数是我们在算法中定义的所有其他变量,可以调整以改进神经网络:

  • 学习率 α
  • 迭代次数
  • 激活功能的选择
  • 层数 L
  • 每层中的单元数量

5.激活功能

激活函数是一种选择在神经网络中传播的数据的传递函数。潜在的解释是,只有当网络中的神经元被充分激发时,才允许它传播学习数据(如果它处于学习阶段)。

以下是最常见的函数列表:

备注:如果激活函数都是线性的,那么神经网络就相当于一个简单的线性回归

6.最优化算法

风险

让我们考虑一个用 f 表示的神经网络。优化的真正目标被定义为所有语料库的预期损失:

其中 X 是来自一个连续的可观测空间的一个元素,对应于一个目标 Yp ( XY )是观测到该对的边际概率( XY )。

经验风险

由于我们不能拥有所有的语料库,因此我们忽略了分布,我们将风险的估计限制在能很好地代表整个语料库的某个数据集上,并考虑所有情况都是等概率的。
在这种情况下:我们将 m 设为代表性语料库的大小,我们得到:∫=∑和 p ( XY )=1/m。因此,我们迭代优化损失函数,定义如下:

另外我们可以断言:

存在许多技术和算法,主要基于梯度下降来执行优化。在下面的章节中,我们将介绍最著名的几个。值得注意的是,这些算法可能会陷入局部极小值,没有什么能保证达到全局最优。

标准化输入

在优化损失函数之前,我们需要对输入进行归一化,以加快学习速度。在这种情况下, J ( θ )变得更紧密和更对称,这有助于梯度下降更快地找到最小值,从而减少迭代次数。
标准数据是常用的方法,包括减去变量的平均值并除以它们的标准差。考虑到这一点,下图说明了对右侧标准数据等高线上的输入进行归一化的效果:

假设 X 是我们数据库中的一个变量,我们设置:

梯度下降

通常,我们倾向于构造一个convexdifferentiable函数 J ,其中任何局部极小值都是全局极小值。从数学上讲,寻找凸函数的全局最小值等价于求解方程∇ J ( θ )=0,我们把它的解记为 θ ⋆。
大多数使用的算法是这样的:

小批量梯度下降

这项技术包括将训练集分成几批:

小批量的选择:

  • 少量行 2000 行
  • 典型大小:2 的幂,有利于记忆
  • 小批量应该适合 CPU/GPU 内存

备注:在批处理中只有一条数据线的情况下,该算法称为随机梯度下降

动量梯度下降

包括动量概念的梯度下降的变体,算法如下:

( αβ )为超参数。
由于 是在小批量上计算的,因此产生的梯度∇ J 噪声很大,动量中包含的指数加权平均值可以更好地估计导数。

RMSprop

均方根 prop 非常类似于带动量的梯度下降,唯一的区别是它包括二阶动量而不是一阶动量,加上参数更新的微小变化:

( αβ )是超参数,而 ϵ 确保数值稳定性(≈108)

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

Adam 是一种自适应学习率优化算法,专门用于训练深度神经网络。Adam 可以看作是 RMSprop 和带动量的梯度下降的组合。
它使用平方梯度将学习率设置为 RMSprop,并通过使用梯度的移动平均值而不是梯度本身来利用动量,因为梯度随动量下降。
主要思想是通过加速向正确方向下降来避免优化过程中的振荡。
Adam 优化器的算法如下:

学习率衰减

学习率衰减的主要目的是随着时间/迭代缓慢降低学习率。它在这样一个事实中找到了合理性,即我们在学习开始时可以迈出大步,但当接近全局最小值时,我们会放慢速度,从而降低学习速度。
学习率存在许多衰减规律,下面是一些最常见的:

正规化

方差/偏差

训练神经网络时,它可能会遇到以下问题:

  • 偏高:或者欠拟合,网络在数据中找不到路径,这种情况下 J_train 非常高与 J_dev 相同。从数学上讲,进行交叉验证时;在所有考虑的褶皱上, J 的平均值较高。
  • 高方差或过拟合,模型完全符合训练数据,但无法对未见过的数据进行概括,在这种情况下, J_train 非常低,而 J_dev 相对较高。从数学上讲,进行交叉验证时;在所有考虑的褶皱上 J 的方差很高。

让我们考虑一下飞镖游戏,击中红色目标是最好的情况。拥有低偏差(第一行)意味着平均而言我们接近目标。在低方差的情况下,击中全部集中在目标周围(击中分布的方差低)。当方差较高时,在低偏差的假设下,命中分散开,但仍在红色圆圈周围。
反之亦然,我们可以用低/高方差来定义高偏差。

从数学上讲,设 f 为真回归函数:y =f(x)+ϵ其中: ϵ~N(0,σ )
我们用 MSE 拟合一个假设h(x)=wx+b并认为 x_0 是一个新的数据点,【t

通过使用 AIC 标准或交叉验证,必须在方差和偏差之间找到一个平衡点,以找到模型的最佳复杂性。
以下是解决偏差/差异问题的简单方案:

L1 — L2 正规化

正则化是一种防止过度拟合的优化技术。
它包括在目标函数中添加一项,以最小化如下:

λ 是正则化的超参数。

反向传播和正则化
反向传播期间参数的更新取决于梯度∇ J ,其中增加了新的正则化项。在 L2 正规化,它变成如下:

考虑到 λ > > 1,最小化成本函数导致参数的弱值,因为项(λ/2m)θ∨)简化了网络并使其更加一致,因此较少暴露于过拟合。

退学正规化

粗略地说,主要思想是采样一个均匀的随机变量,for each layer for each node,并且有 p 的机会保留该节点,并且有 1p的机会移除该节点,这减小了网络。辍学的主要直觉是基于这样的想法,网络不应该依赖于一个特定的特征,而是应该分散权重!
从数学上讲,当 dropout 关闭时,考虑到第I层的第j节点,我们有以下等式:

当 dropout 打开时,方程式如下:

提前停止

该技术非常简单,包括当 J_trainJ_dev 开始分离时,停止该区域周围的迭代:

梯度问题

梯度的计算有两个主要问题:梯度消失和梯度爆炸。
为了说明这两种情况,让我们考虑一个神经网络,其中所有激活函数 ψ [ i ]都是线性的,并且:

我们注意到,1,5^((T7)将作为深度 l 的函数按指数规律爆炸。如果我们使用 0.5 而不是 1.5,那么 0,5^(l-1(T7)也将按指数规律消失。
渐变也会出现同样的问题。

结论

作为一名数据科学家,了解神经网络背景下的数学转变非常重要。这允许更好的理解和更快的调试。

不要犹豫,检查我以前的文章处理:

机器学习快乐!

参考

原载于 2020 年 1 月 31 日https://www.ismailmebsout.com

深度学习的快速进步让我们感到不知所措

原文:https://towardsdatascience.com/deep-learnings-rapid-progress-leads-us-to-feel-overwhelmed-1cbe3dabdce5?source=collection_archive---------66-----------------------

我们不应该急于快速学习任何东西。

照片由 Iwona Castiello d'AntonioUnsplash 上拍摄

深度学习正达到其最佳进展年份。它也成为了最近一年任何利益相关者的流行语。因此,有很多资源存在,比如课程、论文、社区等等。

令人惊讶的是,大多数资源都是免费提供的,并且在互联网上公开。因此,深度学习对世界各地的社区都是可用的,不管他们的背景是什么,他们代表哪里。

由于这些因素使深度学习这次如此出名,一些影响将影响到我们。其中之一就是影响我们的心理健康。面对如此庞大的资源,我们变得不知所措。

感到不知所措是一种因为某些因素而变得沮丧的感觉。如果我们不认真对待它,它会让我们失去做很多事情的动力。

2018 年图灵奖获得者之一、著名深度学习研究者 Yoshua Bengio 最近在博客上发表了一篇文章,内容是重新思考机器学习领域的出版物会是什么样子。它类似于一个叫做慢科学的宣言。我已经引用过了,说的是这样的,

我们确实需要时间思考。我们确实需要时间来消化。我们确实需要时间来误解对方,尤其是在促进人文科学和自然科学之间的对话时。我们不能不断地告诉你我们的科学意味着什么;对什么有好处;因为我们还不知道。科学需要时间。

——当我们思考时,请忍耐。

根据上面的引用,它表明,作为一名科学家,我们应该放慢自己的速度来完成事情。他真正想要的是这个领域应该有更多的对话。因此,它可能会产生突破,也可能是新的灵感。

这个概念本身不仅仅是为了科学家,也是为了我们,作为一个学习者,让我们放慢脚步,从这个领域获得更多。

现在,让我问你这些问题,

  • 你现在对海量的深度学习资源有什么感觉?
  • 你最近看了多少新的深度学习研究论文?
  • 关于深度学习,你已经了解了哪些东西?

很可能你会回答你学到了很多,而且在学习深度学习的时候你也觉得还好。你确定吗?也许你会回答是或不是。但是如果你已经打开了这么多的资源,却不觉得你从中学到了任何东西,你应该休息一下。

我们可能想学那么多东西,想成就很多事情,但是不要急于求成。我们必须让自己慢下来,否则我们会变得没有动力。

避免不知所措的小贴士

现在的问题是,我们如何在不被淹没的情况下学习深度学习?

以下是我关于如何在不被淹没的情况下学习的建议。

找到你的学习方式

人们可以学到所有的东西。但是要学习它,可能你会用一种不同的学习方式。学习方式有很多种。他们是,

  • 视觉型学习者
    这种类型的学习者通过使用任何图形或可视化来理解事物。这种类型的例子是那些喜欢用思维导图做笔记的人。
  • 听觉型学习者 这种类型通过听课和讨论来理解概念进行学习。
  • 读写学习者
    这种类型基本上是通过看书和记笔记来学习。
  • 动觉型学习者 这种类型基本是边做边学。例如,通过对某些神经网络执行代码来了解神经网络如何工作。

那么,根据这些类型,哪一种适合你呢?不一定非要选一个。你可以把这些结合起来,使你的学习更有效。我属于动觉型和阅读型学习者,因为我更喜欢从阅读书籍中学习,然后付诸实践。

你了解你自己。所以,你要选择适合自己的。

只坚持一门课程,直到它结束

在你知道你的学习方式后,下一步是决定使用哪种资源。学习深度学习的资源有很多,比如斯坦福大学、麻省理工学院、Deep Mind 等等。你可以使用任何一种,但是你必须遵守一条规则,

使用。一个。资源。只有!

每门课程都有自己的独特之处,但大多数情况下,它给你的是相同的概念。因此,你应该坚持下去,你必须学习,直到你完成课程。

如果你觉得你不理解这门课程,你可以搜索其他资源作为你的额外参考,不要把它作为你的主要资源。只需将第一个用于您的主要资源。

花 1-2 天时间学习或做其他事情

学习有时候会让你觉得无聊。为了确保你总是有动力,你应该做一些对你来说重要的事情或者你喜欢的事情。或者可能你是一个公司的雇员,所以你不能选择什么时候学习新的东西。

克里斯汀·休姆在 Unsplash 上拍摄的照片

可以应用 OpenAI 的学习日来解决这个。学习日是学习你不擅长的新事物的日子。比如你是一个数据分析师,你对强化学习很感兴趣。因此,你可以分配一整天来学习。大概你可以安排在工作日或者周末。

这样做,你就不会感到无聊,你还可以增加另一个领域的技能。

最终想法

公开可用的资源使任何人都可以进行深度学习。但是大量的信息让我们不知所措。因此,你应该学得慢一点,只专注于一种资源。通过这样做,你会变得不那么不知所措,它会让你保持动力,直到你完成任务。

参考

[1] Bengio Y. 是时候重新思考机器学习中的发布过程了 (2020)。
【2】teach . com .学习风格
【3】《慢科学宣言》
【4】open ai。学习日 (2019)。

感谢您阅读我的文章,您也可以在下面查看我以前的文章:

[## 数据科学和竞争性编程

他们在解决问题,但方法不同。

towardsdatascience.com](/data-science-and-competitive-programming-2887300207c0) [## Python 中的客户细分

基于 K-均值聚类算法的图像分割。

towardsdatascience.com](/customer-segmentation-in-python-9c15acf6f945) [## R 中 ARIMA 模型的时间序列预测

从勘探到预测 1970 年至 2015 年的二氧化碳排放数据。

towardsdatascience.com](/time-series-forecasting-with-arima-model-in-r-77f4e2ae7abb)

基于深度学习和 LSTM 的恶意软件分类

原文:https://towardsdatascience.com/deep-lstm-based-malware-analysis-6b36ac247f34?source=collection_archive---------29-----------------------

使用 Windows Exe API 调用进行恶意软件分析的基于深度学习的顺序模型

恶意软件开发在架构和功能方面呈现出多样性。恶意软件能力的这一进步构成了严重的威胁,并为恶意软件检测开辟了新的研究领域。这项研究的重点是变形恶意软件,它是恶意软件家族中最高级的成员。使用传统的基于签名的方法的反病毒应用程序很难检测变形恶意软件,这使得很难相应地对这种类型的恶意软件进行分类。最近关于恶意软件检测和分类的研究文献讨论了与恶意软件行为相关的这个问题。

引用作品
如果你觉得这个实现有用,请引用它:

@article{10.7717/peerj-cs.285,
title = {Deep learning based Sequential model for malware analysis using Windows exe API Calls},
author = {Catak, Ferhat Ozgur and Yazı, Ahmet Faruk and Elezaj, Ogerta and Ahmed, Javed},
year = 2020,
month = jul,
keywords = {Malware analysis, Sequential models, Network security, Long-short-term memory, Malware dataset},
volume = 6,
pages = {e285},
journal = {PeerJ Computer Science},
issn = {2376-5992},
url = {https://doi.org/10.7717/peerj-cs.285},
doi = {10.7717/peerj-cs.285}
}

你可以从我的我的 GitHub 库访问数据集。

介绍

恶意软件,通常被称为恶意软件,是任何故意设计来破坏计算机系统和危害用户安全的软件。如果某个应用程序或代码暗中违背计算机用户的利益并执行恶意活动,则该应用程序或代码被视为恶意软件。恶意软件针对各种平台,如服务器、个人电脑、手机和相机,以获得未经授权的访问,窃取个人数据,并破坏系统的正常功能。

处理恶意软件保护问题的一种方法是通过识别恶意软件并评估其行为。通常,这个问题是通过分析恶意软件行为来解决的。该领域紧密遵循恶意软件家族的模型,该模型也反映了恶意行为的模式。很少有研究证明了根据恶意软件家族进行分类的方法。

任何软件对操作系统 API 的调用都显示了这个程序的总体方向。该程序是否是恶意软件可以通过深入检查这些操作来了解。如果是恶意软件,那么它的恶意软件家族是什么。恶意软件制造的操作系统 API 调用是一种数据属性,并且这些 API 调用生成的顺序对于检测恶意软件家族也是至关重要的。执行特定的 API 调用是代表一种行为的特定顺序。深度学习方法之一 LSTM(长短期记忆)通常用于处理这种时序数据。

系统结构

这项研究有两个主要目标:首先,我们创建了一个相关的数据集,然后,使用这个数据集,我们进行了一项比较研究,使用各种机器学习来根据恶意软件的类型自动检测和分类。

数据集创建

这项工作最重要的贡献之一是新的 Windows PE 恶意软件 API 序列数据集,其中包含恶意软件分析信息。在这个数据集中有 7107 个来自不同类别的恶意软件。如上所述,Cuckoo 沙箱应用程序用于获取恶意软件的 Windows API 调用序列,而 VirusTotal 服务用于检测恶意软件的类别。

下图说明了用于收集数据并使用 LSTM 算法对数据进行分类的系统架构。

我们的系统包括三个主要部分,数据收集,数据预处理和分析,以及数据分类。

创建数据集时遵循了以下步骤。

Cuckoo 沙盒应用程序安装在运行 Ubuntu Linux 发行版的计算机上。分析机器作为虚拟服务器运行,以运行和分析恶意软件。此服务器上安装了 Windows 操作系统。

让我们编码吧

我们导入常用的标准库来构建一个 LSTM 模型来检测恶意软件。

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from keras.preprocessing.text import Tokenizer
from keras.layers import LSTM, Dense, Dropout, Embedding
from keras.preprocessing import sequence
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import SpatialDropout1D
from mlxtend.plotting import plot_confusion_matrix

在这项工作中,我们将使用标准的恶意软件数据集来显示结果。您可以从 My GitHub Repository 访问数据集。我们需要合并调用和标签数据集。

malware_calls_df = pd.read_csv("calls.zip", compression="zip",
                               sep="\t", names=["API_Calls"])

malware_labels_df = pd.read_csv("types.zip", compression="zip",
                                sep="\t", names=["API_Labels"])

malware_calls_df["API_Labels"] = malware_labels_df.API_Labels
malware_calls_df["API_Calls"] = malware_calls_df.API_Calls.apply(lambda x: " ".join(x.split(",")))

malware_calls_df["API_Labels"] = malware_calls_df.API_Labels.apply(lambda x: 1 if x == "Virus" else 0)

让我们分析一下阶级分布

sns.countplot(malware_calls_df.API_Labels)
plt.xlabel('Labels')
plt.title('Class distribution')
plt.savefig("class_distribution.png")
plt.show()

现在我们可以创建我们的序列矩阵。为了构建 LSTM 模型,您需要创建一个基于符号化的序列矩阵作为输入数据集

max_words = 800
max_len = 100

X = malware_calls_df.API_Calls
Y = malware_calls_df.API_Labels.astype('category').cat.codes

tok = Tokenizer(num_words=max_words)
tok.fit_on_texts(X)
print('Found %s unique tokens.' % len(tok.word_index))
X = tok.texts_to_sequences(X.values)
X = sequence.pad_sequences(X, maxlen=max_len)
print('Shape of data tensor:', X.shape)

X_train, X_test, Y_train, Y_test = train_test_split(X, Y,
                                                    test_size=0.15)

le = LabelEncoder()
Y_train_enc = le.fit_transform(Y_train)
Y_train_enc = np_utils.to_categorical(Y_train_enc)

Y_test_enc = le.transform(Y_test)
Y_test_enc = np_utils.to_categorical(Y_test_enc)Found 278 unique tokens.
Shape of data tensor: (7107, 100)

作为练习,这里给出了基于 LSTM 的分类模型:

def malware_model(act_func="softsign"):
    model = Sequential()
    model.add(Embedding(max_words, 300, input_length=max_len))
    model.add(SpatialDropout1D(0.1))
    model.add(LSTM(32, dropout=0.1, recurrent_dropout=0.1,
                   return_sequences=True, activation=act_func))
    model.add(LSTM(32, dropout=0.1, activation=act_func, return_sequences=True))
    model.add(LSTM(32, dropout=0.1, activation=act_func))
    model.add(Dense(128, activation=act_func))
    model.add(Dropout(0.1))
    model.add(Dense(256, activation=act_func))
    model.add(Dropout(0.1))
    model.add(Dense(128, activation=act_func))
    model.add(Dropout(0.1))
    model.add(Dense(1, name='out_layer', activation="linear"))
    return model

下一步是训练模型。我训练并保存了我的模型。由于数据集的原因,训练阶段需要花费大量时间。为了减少执行时间,您可以从 GitHub 存储库中加载我以前训练过的模型。

model = malware_model()
print(model.summary())
model.compile(loss='mse', optimizer="rmsprop",
              metrics=['accuracy'])

filepath = "lstm-malware-model.hdf5"
model.load_weights(filepath)

history = model.fit(X_train, Y_train, batch_size=1000, epochs=10,
                    validation_data=(X_test, Y_test), verbose=1)Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, 100, 300)          240000    
_________________________________________________________________
spatial_dropout1d (SpatialDr (None, 100, 300)          0         
_________________________________________________________________
lstm (LSTM)                  (None, 100, 32)           42624     
_________________________________________________________________
lstm_1 (LSTM)                (None, 100, 32)           8320      
_________________________________________________________________
lstm_2 (LSTM)                (None, 32)                8320      
_________________________________________________________________
dense (Dense)                (None, 128)               4224      
_________________________________________________________________
dropout (Dropout)            (None, 128)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               33024     
_________________________________________________________________
dropout_1 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 128)               32896     
_________________________________________________________________
dropout_2 (Dropout)          (None, 128)               0         
_________________________________________________________________
out_layer (Dense)            (None, 1)                 129       
=================================================================
Total params: 369,537
Trainable params: 369,537
Non-trainable params: 0
_________________________________________________________________
None
Epoch 1/10
7/7 [==============================] - 22s 3s/step - loss: 0.0486 - accuracy: 0.9487 - val_loss: 0.0311 - val_accuracy: 0.9672
Epoch 2/10
7/7 [==============================] - 21s 3s/step - loss: 0.0378 - accuracy: 0.9591 - val_loss: 0.0302 - val_accuracy: 0.9672
Epoch 3/10
7/7 [==============================] - 21s 3s/step - loss: 0.0364 - accuracy: 0.9604 - val_loss: 0.0362 - val_accuracy: 0.9625
Epoch 4/10
7/7 [==============================] - 20s 3s/step - loss: 0.0378 - accuracy: 0.9593 - val_loss: 0.0328 - val_accuracy: 0.9616
Epoch 5/10
7/7 [==============================] - 22s 3s/step - loss: 0.0365 - accuracy: 0.9609 - val_loss: 0.0351 - val_accuracy: 0.9606
Epoch 6/10
7/7 [==============================] - 21s 3s/step - loss: 0.0369 - accuracy: 0.9601 - val_loss: 0.0369 - val_accuracy: 0.9606
Epoch 7/10
7/7 [==============================] - 22s 3s/step - loss: 0.0371 - accuracy: 0.9594 - val_loss: 0.0395 - val_accuracy: 0.9625
Epoch 8/10
7/7 [==============================] - 22s 3s/step - loss: 0.0378 - accuracy: 0.9601 - val_loss: 0.0365 - val_accuracy: 0.9588
Epoch 9/10
7/7 [==============================] - 22s 3s/step - loss: 0.0358 - accuracy: 0.9618 - val_loss: 0.0440 - val_accuracy: 0.9456
Epoch 10/10
7/7 [==============================] - 21s 3s/step - loss: 0.0373 - accuracy: 0.9589 - val_loss: 0.0354 - val_accuracy: 0.9644

模型评估

现在,我们已经完成了 LSTM 模型的培训阶段。我们可以使用混淆矩阵来评估模型的分类性能。根据混淆矩阵,该模型的分类性能相当好。

y_test_pred = model.predict_classes(X_test)
cm = confusion_matrix(Y_test, y_test_pred)

plot_confusion_matrix(conf_mat=cm,
                      show_absolute=True,
                      show_normed=True,
                      colorbar=True)
plt.savefig("confusion_matrix.png")
plt.show()

让我们继续我们模型的训练历史。

plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.grid()
plt.savefig("accuracy.png")
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.grid()
plt.savefig("loss.png")
plt.show()

结论

这项研究的目的是使用我以前的恶意软件数据集创建一个基于 LSTM 的恶意软件检测模型。虽然我们的数据集包含属于一些分布不平衡的恶意软件家族的实例,但我们已经表明这个问题不会影响分类性能。

深度清醒梦

原文:https://towardsdatascience.com/deep-lucid-dreaming-94fecd3cd46d?source=collection_archive---------38-----------------------

人工艺术合成——连同朱利安·厄本

对于迷幻艺术的爱好者来说,深度梦境的技术无疑是迷人的。当应用于图像时,它给人一种 Instagram 滤镜目前正在参加 Woodstock 的印象。从一开始,这种方法就产生了大量令人惊叹的艺术作品。虽然对一些人来说这可能已经是一顶旧帽子,但考虑到无害输入的无限可能性,我们还远远没有达到这个桶的底部。

嗯,从技术上讲,它们可能不是无穷无尽的。以在 ImageNet 数据集上训练的图像分类体系结构为例,可用于做梦的内容由 1000 个对象类组成,尽管如此,这仍然令人印象深刻。原则上,对于所有这些类别,特征可以在做梦过程中出现,这些特征反映了网络已经了解到的关于这些物体的内部表征。并非所有这些对人类都有意义,但我们都见过用这种方法生成的令人毛骨悚然的逼真的眼睛和狗脸。作为一个深度梦想实践者,你可以选择在哪一层应用梯度提升进化来最大化激活。通常,在早期图层中,你会看到边缘和基本形状等低级特征。越深入,会产生更多高级功能和可识别的对象。

不幸的是,除了选择层之外,使用这种方法,我们无法控制网络将在输入中识别和放大什么。然而,如果我们移动到最后一层,我们实际上可以精确地指定我们希望看到的内容,在最后一层,激活直接对应于对象类,我们可以选择我们希望最大化的对象类。如果你愿意,这种方法是一种艺术的对抗性攻击。

在本帖中,我们将利用这个想法,使用预先训练好的 VGG-19 架构来更深入地探索一些 ImageNet 类。为了促进单类做梦,我们使用一些输入图像执行通过整个网络的完全正向传递。然后,输出是包含对应于每个类别的概率的向量。为了只挑选和优化一个或几个类,我们生成一个目标向量,其中我们希望看到的标签为 1,否则为零。如果你想变得更有趣,你也可以使用不同的权重来混合类,与其他对象相比,更强调某些对象。所有 ImageNet 类的完整列表可以在这里找到。使用目标向量,我们可以根据网络输出的标准交叉熵计算损失,并对输入执行梯度下降步骤。我们只需要小心这里的标志,因为做梦通常是用坡度上升完成的。

举个明确的例子,假设我们想让 VGG-19 梦到鸵鸟(对应的类标签是 9):

criterion **=** torch**.**nn**.**BCEWithLogitsLoss()
label = 9 
output = model(input_image) target = torch.zeros(output.size())               
target[0, label] = 100           
loss = -criterion(output, target)

注意,对于目标类,我们使用 100 而不是 1。这放大了梯度,我们发现它比调整学习率给出更好的结果。在反向传递之后,我们简单地将输入图像中每个像素的梯度加到它自身上。冲洗,重复,我们得到了一些真正迷人而具体的梦!让我们来看看一些最有趣的结果。我们在所有示例中使用的输入是下图,它取自这里:

在这篇文章的封面图片中,我们使用卷心菜类生成了一个梦。让网络梦见鸵鸟,就像上面的例子一样,会导致这样的结果:

即使在修正了我们自己的确认偏差后,我们仍然相信他们可以很容易地从他们的头和脖子的形状被认出来。由于鸟类似乎工作得很好,我们也尝试了鹈鹕类:

其他有趣课程的例子有扁虫、交通灯和睡袋:

过去观察到深度做梦很难控制,这可能阻止了一些艺术家对媒体合成领域产生更大的兴趣。正如我们在这篇文章中所看到的,对生成的结构进行一些控制当然是可能的,并会产生令人着迷的结果。因此,我们恰当地将这种努力命名为“深度清醒梦”。此外,从更技术性的角度来看,这种对抗性攻击也揭示了网络的内部表现。这允许我们直接调查它是否已经学习了关于相应类的不相关或错误的特征,这可能是数据集的产物。

我们很兴奋地看到这种艺术和科学的宏伟融合将在未来带来什么奇迹,并祝愿我们的深度梦想家们旅途愉快。

使用深度度量学习来学习区分

原文:https://towardsdatascience.com/deep-metric-learning-76fa0a5a415f?source=collection_archive---------11-----------------------

最近,计算机视觉算法为使用卷积神经网络(CNN)开发非常高效的视觉搜索工作流做出了巨大贡献。由于近来数据量已经增加,对象识别模型能够识别对象并按比例概括图像特征。然而,在一个具有挑战性的分类设置中,类别的数量是巨大的,有几个约束需要解决,以设计有效的视觉搜索工作流。

  • 对象类别数量的增加也增加了 CNN 倒数第二层的权重数量。这使得很难在设备上部署它们,因为它们最终也会增加型号的大小
  • 当每类只有个图像时,很难实现更好的收敛,从而很难在各种光照差异、对象比例、背景、遮挡等情况下实现良好的性能。
  • 在工程空间中,通常需要设计适应产品生态系统的视觉搜索工作流,该产品生态系统包含不稳定的产品,或者根据季节趋势或地理位置而变化。这种情况使得以循环(特定时间间隔后的训练)或在线(实时数据训练)的方式训练/微调模型变得棘手。

深度度量学习

图 1 给定椅子和桌子的两幅图像,度量学习的思想是使用适当的距离度量来量化图像的相似性。当我们的目标是区分对象而不是识别它们时,这在很大程度上提高了模型的可扩展性,因为我们不再依赖于给定图像所属的类别。

为了缓解这些问题,深度学习和度量学习共同形成了深度度量学习(DML)的概念,也称为距离度量学习。它提出训练基于 CNN 的非线性特征提取模块(或编码器),该模块将语义相似的提取的图像特征嵌入(也称为嵌入)到附近的位置,同时使用适当的距离度量(例如欧几里德或余弦距离)将不相似的图像特征推开。与判别分类算法(如 K-最近邻、支持向量机和朴素贝叶斯)一起,我们可以使用提取的图像特征执行对象识别任务,而不受类别数量的限制。注意,这种经过训练的 CNN 模块的辨别能力描述了具有紧凑的类内变化和可分离的类间差异的特征。这些特征也足够一般化,甚至可以用来区分新的看不见的类。在下一节中,我们将使用基于的训练范例来形式化训练和评估用于 DML 的 CNN 的过程。

形式主义

图 2 是使用 CNN 提取的示例图像 xᵢ和特征嵌入向量 f(xᵢ。

设 X = {(xᵢ,yᵢ)} I∈【1,2,… n】为 n 幅图像的数据集,其中(xᵢ,yᵢ)建议 iᵗʰ图像及其对应的类别标签。数据集中存在的类的总数为 c,即 yᵢ ∈ [1,2,… C]。让我们考虑 f(xᵢ)一个特征向量(或者一个嵌入)对应一个图像 xᵢ ∈ Rᴰ,其中 f: Rᴰ→Rᵈ是一个参数为θ的可微深度网络。这里, Dd 分别指原始图像尺寸和特征尺寸。形式上,我们将两个图像特征之间的欧几里德距离定义为 Dᵢⱼ = ||f(xᵢ) — f(xⱼ)||,这是分别对应于图像 xᵢ和 xⱼ的深层特征 f(xᵢ)和 f(xⱼ)之间的距离。注意,尽管我们在这里关注欧几里德距离,但是在文献中有几个其他度量经常用于优化嵌入空间。我们将在以后的文章中讨论这个问题。

图三。相对相似性约束 : R = {(xᵢ、xⱼ、xₖ): xᵢ比 xₖ}.更像 xⱼdᵢⱼdᵢₖ+α>0 量化了一对锚正图像和锚负图像之间的相似性。三重损失、N 对损失、提升结构、代理 NCA 损失是使用相对相似性约束的一些损失函数。绝对相似性约束 : S = {(xᵢ,xⱼ) : xᵢ和 xⱼ相似},D = {(xᵢ,xₖ) : xᵢ和 xₖ不相似}。Dᵢⱼ和 Dᵢₖ量化了分别共享相似和不相似类别标签的一对正图像和一对负图像的相似性和不相似性的度量。对比丢失和排序列表丢失使用该约束来学习距离度量。

为了学习距离度量函数 f ,大多数 DML 算法使用相对相似性或绝对相似性约束,使用如图 2 和图 3 所示的一对或三对碱基方法。图像的三元组可以定义为(f(xᵢ)、f(xⱼ)、f(xₖ),其中 f(xᵢ)、f(xⱼ)和 f(xₖ)分别对应于主播 xᵢ、正面 xⱼ和负面图像 x⃈的特征向量。xᵢ和 xⱼ有着相似的阶级标签,而 xₖ有着不同于锚和正面形象的阶级标签。一对图像特征对应一个图像 pair(xᵢ,xⱼ),定义为(f(xᵢ),f(xⱼ)).如果两幅图像共享相似的标签,则称为正对,否则称为负对。
训练端到端 DML 模型的整个过程可以总结为如图 4 所示。最初,为了得到聚类不均匀性的概念,对一批图像进行采样。每批包含对象类 P,每个类有 Q 个图像。我们使用下面讨论的取样策略,用这个批次形成一个或多个小批次。这些小批量用于计算损失并通过反向传播进行训练。让我们总结一下使用 DML 损失函数训练深度学习模型的训练过程。稍后,我们将讨论这个框架的几个重要的训练组件,采样和损失函数。

图 4。DML 的培训程序

培训程序

1.批量抽样:批量 B,类别数 P,每个类别的图像数 q。输入:嵌入函数 f(即预先训练的 CNN 的 Imagenet 数据集)、学习速率 B、批量 B 和图像类别数量 P、一批中的图像总数 B = PQ
3。特征提取:给定参数状态θₜ,使用 CNN 前馈所有批次图像,获得图像嵌入 f( xᵢ )。
4。抽样:从批量中进行小批量计算。根据批次的大小,可以形成对应于步骤 1 中采样的图像的一个或多个小批次的特征向量。
5。损失计算和训练:对于每个小批量计算梯度和反向传播,以更新从θₜ到θₜ₊₁.的参数状态

度量学习损失函数

当我们使用卷积神经网络来识别目标时,Softmax 交叉熵(CE)损失函数是最常见的选择。然而,当插入这个损失函数来学习 DML 模型时,有一些必须考虑的事项。

  • Softmax 交叉熵(CE)损失被视为 max 算子的软版本。如果使用恒定缩放因子 s、来缩放,则 Logit 向量或类别概率不会影响给定图像的类别分配。结果,分离良好的特征拥有更大的量级,并且它促进了类的可分离性。总之,如下图所示,它使特征分布呈“放射状”,并且使用鉴别特征学习算法(例如 KNN 分类器)对特征进行分类,关键是要有一个不仅可分离而且可鉴别的嵌入空间。度量学习损失函数被设计成学习有区别的特征空间。

图 5 从为给定数据集训练的 CNN 的倒数第二层提取的特征模式,并投影到 2D 特征空间。左图:使用 Softmax 损失的 2D 特征分布。右图:使用 DML 损失函数的区别特征分布。

  • CE loss 不直接利用小批量图像中样本的结构关系,因为每个图像(随机选择)单独负责计算损失数。通过引入解决图像之间语义差异的惩罚,具有区分一对或三组图像的训练范例有效地检查了图像之间的关系。

认识到这些方面,研究团体已经提出了各种损失函数来使用 DML 学习区分特征空间。提升结构损失函数就是其中之一。

* [## 利用损失函数深入挖掘度量学习

关于度量学习损失函数的介绍性注释。

towardsdatascience.com](/metric-learning-loss-functions-5b67b3da99a5)

提升结构损失充分利用了小批量,改进了小批量随机梯度下降训练。一方面,三重损失或对比损失分别使用三重或一对图像来计算损失项,提升结构损失提出通过提升小批量(O(m))中可用的所有图像对来采用成对距离度量(O(m))。此外,与仅关于锚图像定义负样本的三重损失或对比损失相反,提升结构损失训练给定对、锚和正中的图像,以从小批量图像中找到它们的负样本。关于 DML 中使用的损失函数的更多信息,请参考上面的博文。提升结构损失的公式如下。

这里, (i,j) 表示对应于共享相似标签图像(xᵢ,xⱼ)的正图像对。Dᵢⱼ是一对图像之间的距离。Dᵢₖ和 Dⱼₗ是迷你批次中从锚和正面到其余负面图像的距离。α是指距离余量。 PN 分别是小批量可用的所有正负线对。

抽样

诚然,直接作用于特征对之间的距离直观地引导我们向学习图像的有意义嵌入的目标前进。因此,标准交叉熵损失主要被 DML 社区忽略了。
在 DML 训练机制中,我们分别使用一对或三对图像来使用绝对或相对相似性,在将图像馈送到 CNN 时,有意义地对图像批次进行采样是必要的。对于数据集,其中用于前馈图像的小批量比数据集中的类的总数大得多,随机馈送图像将保证大多数图像样本在小批量中将具有具有相似类标签的其他图像。但是,当我们考虑具有大量图像类的数据集时,例如,斯坦福在线产品数据集,其中图像类的数量接近 22000,随机采样的小批量图像不一定包含共享相似标签的图像对。在这种情况下,尽管每个批次都遇到了类间变化(因为存在具有不同类标签的图像),但是它未能解决类内变化(因为没有必要具有两个具有相似类标签的图像),最终未能实现更好的收敛。

图六。负类挖掘抽样

虽然使用 DML 的训练需要对图像对或三元组进行采样,但是这种采样分别粗略地增加了 O(m)或 O(m)数量级的数据集大小。此外,如果图像对或图像对是随机采样的,随着训练的进行,大多数图像对或图像对以较小的方式起作用,因为不是所有的图像都违反了余量α(例如,在三个一组丢失的情况下)。很难计算有意义的损失,这不可避免地导致收敛缓慢。
为了克服这些问题,有各种各样的采样策略,我们可以用来更快更好地收敛训练参数。

硬负数据挖掘策略在基于距离的度量学习算法中很常见。它包括计算硬的负面或正面特征实例,以形成给定锚例的正面或负面对。然而,当给定的批处理中涉及大量的类时,这个过程在计算上是具有挑战性的。在这样的场景中,可以方便地执行负的“挖掘,而不是负的“实例挖掘。遵循下面的过程来为基于对的损失函数执行负“类”挖掘。

  1. 为了具有给定参数状态θₜ的嵌入空间的有意义的表示,对包含几百个类(即上述训练过程中的 p)的大批量图像进行采样。对于每个基于对的损失函数,对于给定批次中的每个给定类别,必须有至少两个示例图像。例如,在斯坦福在线产品数据集的情况下,必须随机采样至少 2 个图像(Q=2)。
  2. 对于给定 CNN 的给定参数状态θₜ,提取步骤 1 中采样的每个图像的特征向量。使用这些图像特征获得类别表示向量或类别代理(平均嵌入向量)。
  3. 对于从步骤 1 中采样的 P 个类别中随机选择的每个类别,我们对最近的类别进行采样,并对相应的图像重新排序,如上图 5 所示。这一步骤也可以使用基于边缘的类选择来执行,如果只有一个具有距离边缘的类被选择作为给定锚类的最近类。
  4. 根据计算能力,我们可以形成一个或多个小批量的特征向量,如图 5 所示,以计算损失和梯度。

评估和推理

图 DML 的推理过程。图像被馈送到网络以从瓶颈层获得特征向量。因为它们是用 DML 损失函数训练的,所以它们将创建区别特征嵌入空间,如图中 2D 所示。

与传统的对象识别模型(其中图像被馈送以生成对象类别概率)相反,DML 图像被馈送以提取图像特征。评估这些图像特征的聚类质量和检索性能。F1 和归一化互信息(NMI)分数是标准的评估度量,我们用来估计聚类质量度量。对于检索,k 处的召回率是我们在处理 DML 训练时使用的基准评估度量。为了本文的完整性,我们在这里总结了这些评估指标。

  • 在 K 回忆:对于每个查询图像(来自测试数据集),我们使用来自相同测试集的适当距离度量(欧几里德或余弦)检索 K 个最近邻。如果在检索到的 K 个最近邻居中存在来自相同类别的图像,则查询图像得到分数 1。K 值召回表示测试数据集中所有法师的召回次数。
  • F1 : F1 度量值定义为在 K 处测量的精度和召回率的调和平均值,即 F1 = 2PR/(P+R)。
  • 归一化互信息 ( NMI ):对于一组输入聚类赋值ω和地面真实聚类ℂ,NMI 得分是互信息与聚类平均熵和标签熵的比值。即 NMI = I(ω;ℂ)/2(h(ω)+h(ℂ)).这里,ω={ω₁,ω₂ … ωₙ},这是聚类的输入集,ℂ = {c₁,c₂,… cₙ}是基础真值类。具有聚类分配 i 的示例被给定为ωᵢ,而具有基础真实类标签 j 的示例被定义为 cᵢ.
  • K 处的准确性:这个度量标准服务于我们的目标,即以无监督的方式使用这个训练过的模型作为对象识别模型。对于图像,使用适当的度量获得 K 个最近邻。查询图像被分配给在 K 个最近邻居中出现次数最多的类别。K 处的准确度对测试数据集中的每个查询图像的准确度进行平均。

结论

我们描述了一种深度度量学习范式来解决对象识别问题。这种模型训练提供了如下几个优点。

  • 它们不会增加模型的大小,因为我们总是可以使用相同的维度嵌入层来训练模型。
  • 由于我们正在学习区分和不识别物体,我们可以利用这样一个范例,该范例可以使用各种采样策略以每类更少的图像来执行训练,并且甚至可以推断对不可见的类的识别。
  • 循环在线的方式对一组较新的产品类别进行微调将会传播渐变。

这些属性使我们能够为给定的产品生态系统设计灵活且可扩展的可视化搜索工作流。此外,我们还描述了采样对于使用 DML 损失函数训练 CNN 的重要性。请跟进 这篇 文章的附加损耗功能。随着近来这一领域的发展,我们也可以有效地练习一些其他的训练程序来达到同样的目的。我们将在以后的文章中讨论其中的一些。*

参考

  1. 王,x,华,y,柯迪洛夫,e,胡,g,卡尼尔,r .,&罗伯逊,N. M. (2019)。深度度量学习的排序列表丢失。在IEEE 计算机视觉和模式识别会议论文集(第 5207–5216 页)中。
  2. movshowitz-Attias,y .,Toshev,a .,Leung,T. K .,Ioffe,s .,& Singh,S. (2017)。没有大惊小怪的距离度量学习使用代理。IEEE 计算机视觉国际会议论文集(第 360–368 页)。
  3. Ranjan,r .,Castillo,C. D .,& Chellappa,R. (2017 年)。用于鉴别性人脸验证的 L2 约束软最大损失。 arXiv 预印本 arXiv:1703.09507
  4. 2017 年 10 月,王,项,程,陈建杰,尤妮尔。人脸验证的 L2 超球面嵌入。第 25 届 ACM 多媒体国际会议论文集(第 1041–1049 页)。
  5. Wu c . y .,Manmatha,r .,Smola,A. J .,& Krahenbuhl,P. (2017 年)。深度嵌入学习中的采样问题。在IEEE 计算机视觉国际会议论文集(第 2840-2848 页)。
  6. 温,张,李,张,乔,(2016 年 10 月)。一种用于深度人脸识别的鉴别特征学习方法。在欧洲计算机视觉会议(第 499–515 页)。斯普林格,查姆。
  7. 刘,张,罗,邱,王,唐,(2016)。Deepfashion:通过丰富的注释支持强大的服装识别和检索。在IEEE 计算机视觉和模式识别会议论文集(第 1096-1104 页)。
  8. Oh Song,h .,Xiang,y .,Jegelka,s .,& Savarese,S. (2016 年)。基于提升结构特征嵌入的深度度量学习。在IEEE 计算机视觉和模式识别会议论文集(第 4004–4012 页)。
  9. Sohn,K. (2016 年)。具有多类 n 对损失目标的改进深度度量学习。在神经信息处理系统的进展(第 1857-1865 页)。
  10. Schroff,d . Kalenichenko 和 j . Phil bin(2015 年)。Facenet:人脸识别和聚类的统一嵌入。IEEE 计算机视觉和模式识别会议论文集(第 815–823 页)。**
  11. Bellet,a .,Habrard,a .,和 Sebban,M. (2013 年)。特征向量和结构化数据的度量学习综述。 arXiv:1306.6709
  12. 哈德塞尔,r .,乔普拉,s .,&勒村,Y. (2006 年 6 月)。通过学习不变映射进行降维。在 2006 年 IEEE 计算机学会计算机视觉和模式识别会议(CVPR’06)(第 2 卷,第 1735-1742 页)。IEEE。芝加哥

具有 Scikit-learn 的深度神经多层感知器(MLP)

原文:https://towardsdatascience.com/deep-neural-multilayer-perceptron-mlp-with-scikit-learn-2698e77155e?source=collection_archive---------3-----------------------

MLP 是一种人工神经网络。最简单的 MLP 至少由三层节点组成:输入层、隐藏层和输出层。

Robina Weermeijer 在 Unsplash 上的照片

在深度学习的世界里,TensorFlow、Keras、微软认知工具包(CNTK)、PyTorch 都很受欢迎。我们大多数人可能没有意识到,非常流行的机器学习库 Scikit-learn 也能够进行基本的深度学习建模。在这篇文章中,我将讨论 Scikit-learn 中深度学习建模的可行性和局限性。此外,我将通过两个例子讨论实际实现。

sci kit-learn 中多层感知器(MLP)的显著点

  • 输出层没有激活功能。
  • 对于回归场景,平方误差是损失函数,交叉熵是分类的损失函数
  • 它可以处理单个以及多个目标值回归。
  • 与其他流行的软件包不同,像 Keras Scikit 中 MLP 的实现不支持 GPU。
  • 我们不能像不同的激活函数、权重初始化器等一样微调参数。对于每一层。

回归示例

步骤 1:Scikit-Learn 包中,MLPRegressor 在 neural_network 模块中实现。我们将导入其他模块,如“train_test_split”来将数据集拆分为训练集和训练集以测试模型,“fetch_california_housing”来获取数据,以及“StandardScaler”来缩放数据,因为不同的特征(独立变量)具有较宽的值域范围。缩放用于训练模型的数据是非常重要的。

您可以在文章功能缩放-不同 Scikit 的效果-了解缩放器:深入探讨中了解更多关于不同缩放器的信息

"""Import the required modules"""**from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import r2_score
import pandas as pd**

步骤 2: 我们将把数据集分成训练数据集和测试数据集。我们保留了 20%的数据集用于检查训练模型的准确性。独立的训练和测试数据集被进一步缩放,以确保输入数据是标准的正态分布,以零为中心,并且具有相同数量级的方差。

**cal_housing = fetch_california_housing()
X = pd.DataFrame(cal_housing.data,columns=cal_housing.feature_names)
y = cal_housing.target****X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=1, test_size=0.2)**

第三步:我们就像上面的回归例子一样缩放数据,原因相同。

**sc_X = StandardScaler()
X_trainscaled=sc_X.fit_transform(X_train)
X_testscaled=sc_X.transform(X_test)**

步骤 4: 在下面的代码中,建模了三个隐藏层,每层有 64 个神经元。考虑到输入和输出层,我们在模型中共有 5 层。如果没有提到任何优化器,那么“Adam”就是默认的优化器,它可以管理非常大的数据集。

**reg = MLPRegressor(hidden_layer_sizes=(64,64,64),activation="relu" ,random_state=1, max_iter=2000).fit(X_trainscaled, y_train)**

除了“RELU”激活之外,MLPRegressor 还支持“sigmoid”和“双曲线 tan”功能。

步骤 5:在下面的代码中,训练好的模型用于预测保留的测试数据集的目标值,该模型以前没有见过。

**y_pred=reg.predict(X_testscaled)
print("The Score with ", (r2_score(y_pred, y_test))**

分类举例

我们已经看到了一个回归的例子。接下来,我们将看一个分类示例。在 Scikit-learn 中,“MLPClassifier”可用于多层感知器(MLP)分类场景。

像往常一样,首先我们将导入我们将在示例中使用的模块。我们将使用 Iris 数据库和 MLPClassifierfrom 作为分类示例。

**from sklearn.datasets import load_iris
from sklearn.neural_network import MLPClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScaler
import pandas as pd
from sklearn.metrics import plot_confusion_matrix
import matplotlib.pyplot as plt**

步骤 2: 在单独的数据帧“X”和“y”中,存储独立和从属特征的值。

**iris_data = load_iris()
X = pd.DataFrame(iris_data.data, columns=iris_data.feature_names)
y = iris_data.target**

步骤 3: 类似于上面的回归示例,我们将把数据集分成训练数据集和测试数据集。我们保留了 20%的数据集用于检查训练模型的准确性。独立的训练和测试数据集被进一步缩放,以确保输入数据是标准的正态分布,以零为中心,并且具有相同数量级的方差。

**X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=1, test_size=0.2)
sc_X = StandardScaler()
X_trainscaled=sc_X.fit_transform(X_train)
X_testscaled=sc_X.transform(X_test)**

步骤 4: 在下面的代码中,我们建立了四个隐藏层,每个层中有不同的神经元。考虑到输入和输出层,我们在模型中共有 6 层。如果没有提到任何优化器,那么“Adam”就是默认的优化器。

**clf = MLPClassifier(hidden_layer_sizes=(256,128,64,32),activation="relu",random_state=1).fit(X_trainscaled, y_train)
y_pred=clf.predict(X_testscaled)
print(clf.score(X_testscaled, y_test))**

分类器对测试数据显示出相当高的分数。重要的是要了解分类模型出错的领域,以充分了解模型的准确性。

你可以在“准确性可视化:监督机器学习分类算法”中了解更多关于我们应该使用混淆矩阵来判断分类模型准确性的原因。

第五步:我们将绘制一个混淆矩阵来理解模型造成的错误分类。

**fig=plot_confusion_matrix(clf, X_testscaled, y_test,display_labels=["Setosa","Versicolor","Virginica"])
fig.figure_.suptitle("Confusion Matrix for Iris Dataset")
plt.show()**

似乎只有一种“云芝”被模型错误地识别为“海滨锦鸡儿”。

结论:我们可以在 Scikit-learn 中做简单的深度学习回归和分类模型。在我看来,它不适合任何现实生活中的大规模建模,因为没有 GPU 的支持,调整参数的选项也非常有限。

你可以在文章深度学习中的准确性可视化中了解更多关于深度学习可视化技术的信息

对于开始机器学习之旅的人来说,你可以从文章中的《为匆忙中的人学习机器》开始。

深度神经网络语言识别

原文:https://towardsdatascience.com/deep-neural-network-language-identification-ae1c158f6a7d?source=collection_archive---------9-----------------------

使用 DNN 和字符 n 元语法对一段文本的语言进行分类(使用 Python 代码)

来源: flaticon

语言识别可以是自然语言处理(NLP)问题中的重要步骤。它包括试图预测一段文本的自然语言。在采取其他行动(即翻译/情感分析)之前,了解文本的语言是很重要的。例如,如果你去谷歌翻译,你输入的框显示‘检测语言’。这是因为谷歌首先试图识别你的句子的语言,然后才能翻译。

来源:作者

有几种不同的语言识别方法,在本文中,我们将详细探讨其中一种。即使用神经网络和字符 n-grams 作为特征。最后,我们证明了这种方法可以达到 98%以上的准确率。一路上,我们将讨论关键的代码片段,你可以在 GitHub 上找到完整的项目。首先,我们将讨论用于训练神经网络的数据集。

资料组

数据集由 Tatoeba 提供。完整的数据集由 328 种独特语言的 6872356 个句子组成。为了简化我们的问题,我们将考虑:

  • 6 种拉丁语言:英语、德语、西班牙语、法语、葡萄牙语和意大利语。
  • 长度在 20 到 200 个字符之间的句子。

我们可以在表 1 中看到每种语言的一个句子的例子。我们的目标是使用提供的文本创建一个可以预测目标变量的模型。

表 1:每种语言的文本片段示例

我们加载数据集,并在下面的代码中做一些初始处理。我们首先过滤数据集,以获得所需长度和语言的句子。我们从每种语言中随机选择 50,000 个句子,这样我们总共有 300,000 行。这些句子然后被分成训练集(70%)、验证集(20%)和测试集(10%)。

特征工程

在拟合模型之前,我们必须将数据集转换为神经网络能够理解的形式。换句话说,我们需要从我们的句子列表中提取特征来创建特征矩阵。我们使用由 n 个连续字符组成的字符 n 元语法来实现这一点。这是一个类似于单词袋模型的方法,除了我们使用字符而不是单词。

对于我们的语言识别问题,我们将使用字符三元组/三元模型(即 3 个连续字符的集合)。在图 2 中,我们看到了一个如何使用三元模型向量化句子的例子。首先,我们从句子中得到所有的三元模型。为了减少特征空间,我们取这些三元模型的子集。我们使用这个子集对句子进行矢量化。第一个句子的向量是[2,0,1,0,0],因为三元组“is_”在句子中出现了两次,“his”出现了一次。

图 1:使用三元模型向量化句子的例子

创建三元模型特征矩阵的过程是相似的,但是有点复杂。在下一节中,我们将深入研究用于创建矩阵的代码。在此之前,有必要对我们如何创建特征矩阵有一个总体的了解。采取的步骤是:

  1. 使用训练集,我们从每种语言中选择 200 个最常见的三元模型
  2. 从这些三元模型中创建一个独特的三元模型列表。这两种语言有一些共同的三元模型,所以我们最终得到了 663 个独特的三元模型
  3. 通过计算每个三元模型在每个句子中出现的次数,创建一个特征矩阵

我们可以在表 2 中看到这样一个特征矩阵的例子。最上面一行给出了 663 个三元模型中的每一个。然后每一个编号的行给出我们数据集中的一个句子。矩阵中的数字给出了三元模型在句子中出现的次数。例如,“j'a”在第二句中出现一次。

表 2:训练特征矩阵

创建特征

在本节中,我们将查看用于创建表 2 中的训练特征矩阵和验证/测试特征矩阵的代码。我们大量使用 SciKit Learn 提供的计数矢量器包。这个包允许我们基于一些词汇列表(即单词/字符列表)对文本进行矢量化。在我们的例子中,词汇表是一组 663 个三元模型。

首先,我们必须创建这个词汇表。我们首先从每种语言中获取 200 个最常见的三元模型。这是使用下面代码中的 get_trigrams 函数完成的。这个函数获取一个句子列表,并从这些句子中返回 200 个最常见的三元模型列表。

在下面的代码中,我们遍历了 6 种语言中的每一种。对于每种语言,我们从训练集中获得相关的句子。然后,我们使用 get_trigrams 函数获得 200 个最常见的三元模型,并将它们添加到一个集合中。最后,由于这些语言共享一些共同的三元模型,我们有一组 663 个独特的三元模型。我们用这些来创建一个词汇表。

然后,CountVectorisor 包使用词汇表对我们训练集中的每个句子进行矢量化。结果就是我们之前看到的表 2 中的特征矩阵。

在我们可以训练我们的模型之前,最后一步是缩放我们的特征矩阵。这将有助于我们的神经网络收敛到最佳的参数权重。在下面的代码中,我们使用最小-最大缩放来缩放训练矩阵。

我们还需要获得验证和测试数据集的特征矩阵。在下面的代码中,我们像处理训练集一样对这两个集进行矢量化和缩放。值得注意的是,我们使用了词汇表以及从训练集中获得的最小值/最大值。这是为了避免任何数据泄漏。

探索三元模型

我们现在有了一种形式的数据集,可以用来训练我们的神经网络。在我们这样做之前,探索数据集并对这些特征在预测语言方面的表现建立一点直觉会很有用。图 2 给出了每种语言与其他语言共有的三元模型的数量。例如,英语和德语有 55 个最常见的三元组是相同的。

有了 127,我们看到西班牙语和葡萄牙语有最多的三元组。这是有道理的,因为在所有的语言中,这两种语言在词汇上是最相似的。这意味着,使用这些特征,我们的模型可能会发现很难区分西班牙语和葡萄牙语,反之亦然。类似地,葡萄牙语和德语有最少的三元组,我们可以期望我们的模型在区分这些语言方面更好。

图 2:三元模型特征相似性图

系统模型化

我们使用 keras 软件包来训练我们的 DNN。模型的输出层中使用了 softmax 激活函数。这意味着我们必须将我们的目标变量列表转换成一个一次性编码列表。这是使用下面的编码功能完成的。这个函数接受一个目标变量列表,并返回一个独热编码向量列表。例如,[eng,por,por,fra,…]将变成[[0,1,0,0,0,0],[0,0,0,0,1,0],[0,0,0,0,1,0],…]。

在选择最终的模型结构之前,我做了一些超参数调整。我改变了隐藏层中的节点数、历元数和批量大小。在验证集上实现最高准确度的超参数组合被选择用于最终模型。

最终模型有 3 个隐藏层,分别有 500、500 和 250 个节点。输出层有 6 个节点,每种语言一个。隐藏层都有 ReLU 激活函数,并且如前所述,输出层有 softmax 激活函数。我们使用 4 个时期和 100 的批量大小来训练这个模型。使用我们的训练集和独热编码的目标变量列表,我们在下面的代码中训练这个 DDN。最终,我们达到了 99.70%的训练准确率。

模型评估

在模型训练过程中,模型可能会偏向训练集和验证集。因此,最好在未知的测试集上确定模型的准确性。在测试集上的最终准确率为 98.26%。这低于 99.70%的训练准确度,表明出现了对训练集的一些过度拟合。

通过查看图 3 中的混淆矩阵,我们可以更好地了解该模型在每种语言中的表现。红色对角线给出了每种语言的正确预测数。非对角线上的数字给出了一种语言被错误地预测为另一种语言的次数。例如,德语被错误地预测为英语 10 次。我们看到,该模型最常混淆葡萄牙语和西班牙语(124 次),或者西班牙语和葡萄牙语(61 次)。这是我们在探索我们的特征时所看到的。

图 3:混乱热图

下面给出了用于创建这个混淆矩阵的代码。首先,我们使用上面训练的模型对测试集进行预测。使用这些预测的语言和实际的语言,我们创建了一个混淆矩阵,并使用 seaborn 热图将其可视化。

最终 98.26%的测试准确率还有提升空间。在特征选择方面,我们保持简单,只为每种语言选择了 200 个最常见的三元模型。一种更复杂的方法可以帮助我们区分更相似的语言。例如,我们可以选择在西班牙语中常见但在葡萄牙语中不常见的三元模型,反之亦然。我们也可以尝试不同的模型。希望这是你语言识别实验的一个好的起点。

图像来源

所有图片都是我自己的或从www.flaticon.com获得的。在后者的情况下,我拥有他们的高级计划中定义的“完全许可”。

参考

[1] A. Simões、J.J .阿尔梅达和 S.D .拜尔斯,语言识别:一种神经网络方法。(2014)https://www . research gate . net/publication/290102620 _ Language _ identificati on _ A _ neural _ network _ approach

[2] G.R. Botha 和 E. Barnard,影响基于文本的语言识别准确性的因素(2012)https://www . science direct . com/science/article/ABS/pii/s 0885230812000058

有序逻辑回归的深层表示

原文:https://towardsdatascience.com/deep-ordinal-logistic-regression-1afd0645e591?source=collection_archive---------19-----------------------

用 TensorFlow 2 预测秩次

介绍

如果目标变量是数字排序的,则可以使用排序算法。该模型将捕捉相邻类之间的共享变化。该模型也可用于半监督分类,其中代理目标被分配为比实际目标低的等级。

最简单的排名模型是回归模型。回归模型的输出将被舍入到最接近的整数,并且这些值也在目标的最大值和最小值之间被剪裁。多类模型线性模型是另一种选择,但应该注意的是,每个类都是单独处理的,而不是按等级排序的方式。XGBoost 还有一个排名实现。我还没有尝试过,但它在 Expedia Kaggle 比赛中取得了成功。有序逻辑回归,或比例优势模型,是逻辑回归模型的扩展,可用于有序目标变量。它最初是由彼得·麦卡勒在 20 世纪 80 年代创作的。在这篇文章中,我们将在 TensorFlow 中设计并实现一个深度有序逻辑回归模型。代码的链接发布在 TensorFlow 公式部分。

数学直觉

比例优势模型,或有序逻辑回归,旨在预测有序目标变量。目标 y 和输入 X 之间的关系是线性的。线性核的输出被定义为 y*。

一组阈值将把线性核的输出分成 K 个排序等级。该模型将具有 K-1 个阈值,其中 K 是 y 的最大等级。注意,在该模型中,每个等级的类共享参数 w 和 b。

最后一个等级 K 是总括类,它捕获最后一个类以及没有被其他阈值分开的数据点。

阈值被约束为单调递增且大于或等于零,如等式(3)所示。使用单调递增的阈值确保了数据点被分配给一个且仅一个等级类别。

下图说明了线性核和分级阈值之间的关系。注意,阈值是线性核的子空间。

数据点到分级阈值的线性核的距离将被映射到数据点“属于”分级类别的概率。到分级阈值的距离是通过从 K-1 个阈值中的每一个减去线性核的输出来创建的。然后,sigmoid 函数将该输出映射到分级目标变量的累积分布函数,如等式(4)所示。

因为对阈值参数的单调增加的约束,j 处的累积概率将总是大于 j-1。数据点属于分级类别 j 的概率被定义为 j 和 j-1 处的累积分布函数之间的差。

边缘情况,即秩 0 和秩 K,由 P(y <0) and 1-P(y < K-1), respectively. Notice that the relative probability of a data point belonging to rank 0 increases as the predicted output decreases or becomes negative. This is due to the monotonic constraint on the thresholds. The probability of a data point belonging to class K, or above, is simply one minus the maximum probability in the cumulative distribution function, in this case the CDF probability at ranked class K-1.

Optimization

The ranked class probability distribution defined above, can be optimized with a 交叉熵损失函数定义,如等式(6)所示。

输出 y 是一个热编码矩阵,用于指示观察值属于哪个类。因为 y 是离散概率分布,所以等式(6)中所示的交叉熵损失函数可用于最大化估计参数的似然性。

我们可以检查对数概率的导数,并在损失函数中看到相邻阈值参数之间的关系。等式(7)和(8)显示了有用导数公式。

方程(9)和(10)中示出了在分级等级 j 处对数概率函数的导数。注意,如果一项不包括等级为 j 的θ,则它的导数在等式(6)中为零。

上述导数的简化形式如等式(12)所示。我删除了显示将(10)转换为(12)的步骤的等式(11),因为它太长了:)

导数显示了 j 和 j-1 处的不同累积概率与 j 和 j-1 处的累积概率比之间的有趣关系。如果 j 处的概率为零,梯度将是不确定的。如果 j 和 j-1 的概率太接近,梯度也会消失。此外,梯度有可能将符号换成负阈值。

张量流公式

在 TensorFlow 中,有各种方法来制定有序逻辑回归。主要问题将是定义阈值,以便梯度与上一节中定义的梯度一致。示例笔记本可以在这里找到。

该模型的线性部分由输入数据和权重之间的点积定义。线性核的输出具有 shape (Nx1),其中 N 是数据点的数量。我决定使用一个线性激活的密集层作为有序层的输入。您可能需要在序数层中添加一个非负偏差来处理潜在的负值。

一个潜在的变量,欧米加,被创建来构建阈值参数。潜在变量被初始化为等间距单调递增序列。最后排序的类别 K 的阈值被丢弃,并且 CDF 概率从先前排序的类别 K-1 中推断。阈值参数θ将具有形状(1x(K-1))。等级为 0 的第一阈值将被静态地定义为恒定的零值。

最初,我试图用潜在变量平方的累积和来创建阈值参数。然而,模型似乎没有收敛。我认为这是梯度如何传播回阈值的问题。以下是它不起作用的一些可能原因:1)累积和的导数对所有等级≤j 的类传播相同的梯度。换句话说,它没有考虑 j 和 j-1 个阈值参数之间的关系 2)对于平方潜在变量,梯度可能在 0 附近不稳定,即,如果潜在变量在优化期间改变符号。

为了解决这个问题,我首先创建了 K-1 个阈值,然后取 j 和 j-1 个潜在变量之间的差,即累积函数的逆运算。这导致 K-2 个阈值参数。然而,差值仍然可能是负的,所以我添加了一个 ReLU 层来确保差值是正的。常数+1,用于确保梯度始终被定义,即大于零。最后,我将阈值连接在等级为 0 的类上,它被静态地定义为零。

CDF 是通过从阈值中减去线性核,然后应用 sigmoid 函数来创建的。然后,可以通过应用等式(6)将 CDF 转换成 PDF。最后,可以使用稀疏分类交叉熵损失来优化模型。

估价

从这个中收集了三个有序数据集,即波士顿住房、股票和运动学数据集。根据平均交叉验证 MAE、精确度和推土机距离 (EMD)对模型进行评估。EMD 捕捉预测 CDF 和目标 CDF 之间的相似性。

选择分层的 5 重交叉验证策略来评估这两个模型的性能。我发现多个交叉验证结果之间存在一些差异。为了限制这种可变性,我运行了 3 次交叉验证策略,并保存了每个 k 倍验证集的预测值和实际值。

目标是评估和比较有序模型和回归模型的结果。为了简单起见,将使用相同数量的隐藏单元,即 32 个隐藏单元,和相同的优化策略来训练回归模型。回归模型的损失函数有两种选择,即平均绝对误差(MAE)和均方误差(MSE)。我决定使用 MAE,因为它似乎比 MSE 更适合排名。

由于序数模型使用稀疏分类交叉熵损失,我认为这是一个好主意,分层的 k 倍对排名类变量。两个模型都采用了提前停车。

结果

下表显示了两个模型在每个数据集上的指标。出乎意料的是,对于所有三个数据集,序数模型产生的交叉验证 MAE 都比回归模型好。顺序模型在准确性和推土机的距离度量方面也表现得更好。

序数模型和回归模型在波士顿住房数据集上具有相似的性能。在运动学数据集上,序数模型比回归模型有最大的改进。

下图显示了回归(右)和有序(左)模型的预测输出与实际分布的分布。这些图显示了 1)波士顿住房数据集 2)股票数据集 3)和运动学数据集。

下图显示了每个 k 倍模型中阈值参数的变化。有趣的是,阈值的变化似乎与回归模型的改进成反比。

结论

在 TensorFlow 2.0 中设计并实现了有序逻辑回归模型的一个潜在实现。该设计使用了经典的比例优势定义和自定义阈值参数化。通过检查和分析阈值参数的梯度来构造阈值参数化。序数模型模型在平均交叉验证 MAE、准确性和 EMD 指标上与 MAE 回归模型产生了竞争结果。

资源

深度 Q 网(DQN)-I

原文:https://towardsdatascience.com/deep-q-network-dqn-i-bce08bdf2af?source=collection_archive---------6-----------------------

深度强化学习讲解— 15

开放式健身乒乓球和包装纸

之前的帖子中,我们已经展示了在一个小表格中表示动作值的解决方法。我们将这个表称为 Q 表。在 " 深度强化学习解释 " 系列的下三篇文章中,我们将向读者介绍使用神经网络来扩展我们可以通过强化学习解决的问题规模的想法,展示了深度 Q 网络(DQN),,它将最佳动作值函数表示为神经网络,而不是表格。在本帖中,我们将对 DQN 做一个概述,并介绍 Pong 的 OpenAI 健身房框架。在接下来的两篇文章中,我们将介绍该算法及其实现。

本出版物的西班牙语版本

[## 9.基于价值的营销:深度 Q 网络

请访问第 9 页的自由介绍

medium.com](https://medium.com/aprendizaje-por-refuerzo/9-métodos-value-based-deep-q-network-b52b5c3da0ba)

雅达利 2600 游戏

我们在之前的文章中提到的 Q-learning 方法通过遍历完整的状态集解决了这个问题。然而,我们常常意识到我们有太多的状态要跟踪。一个例子是 Atari 游戏,它可以有大量不同的屏幕,在这种情况下,问题不能用 Q 表来解决。

雅达利 2600 游戏机在 20 世纪 80 年代非常受欢迎,许多街机风格的游戏都可以为它提供。以今天的游戏标准来看,Atari 游戏机已经过时了,但它的游戏对计算机来说仍然具有挑战性,并且是 RL 研究中非常受欢迎的基准(使用模拟器)

雅达利 2600(来源:维基百科)

2015 年,DeepMind 利用所谓的深度 Q 网络(DQN) 或深度 Q 学习算法,学会了比人类更好地玩许多雅达利视频游戏。介绍它的研究论文,应用于 49 个不同的游戏,发表在 Nature(通过深度强化学习的人类水平控制,doi:10.1038/nature14236,Mnih,和其他)和可以在这里找到

Atari 2600 游戏环境可以通过 OpenAI 健身房框架中的街机学习环境进行重现。该框架有每个游戏的多个版本,但为了本文的目的,将使用 Pong-v0 环境。

我们将研究这个算法,因为它真的允许我们学习在本系列的未来帖子中非常有用的提示和技巧。DeepMind 的《自然》论文包含了一个表格,其中列出了用于在所有 49 款用于评估的雅达利游戏上训练其模型的超参数的所有细节。然而,我们在这里的目标要小得多:我们只想解决乒乓游戏。

正如我们在以前的一些帖子中所做的那样,这篇帖子中的代码受到了 Maxim Lapan 的代码的启发,他写了一本关于这个主题的优秀的实用书籍

这篇文章的全部代码可以在 GitHub 上找到,而可以通过这个链接作为一个 Colab google 笔记本运行。

从计算需求的角度来看,我们之前的 FrozenLake 或 CartPole 示例并不苛刻,因为观测值很小。然而,从现在来看,事实并非如此。这篇文章中分享的代码版本在 2 小时内收敛到 19.0 的平均分数(使用 NVIDIA K80)。所以在训练循环的执行过程中不要紧张。;-)

恶臭

Pong 是一款以乒乓球为主题的街机电子游戏,以简单的二维图形为特色,由 Atari 制造,最初于 1972 年发布。在乒乓球比赛中,如果球从另一名球员身边经过,一名球员得分。当其中一名玩家达到 21 分时,一集结束。在 OpenAI Gym 框架版 Pong 中,右边显示代理人,左边显示敌人:

在乒乓球运动中,两个拍子来回移动球。分数由屏幕顶部的数字记录。(来源: torres.ai )

在 Pong 环境中,代理(玩家)可以采取三种动作:保持静止、垂直向上平移和垂直向下平移。然而,如果我们使用方法action_space.n ,我们可以认识到环境有 6 个动作:

import gym
import gym.spacesDEFAULT_ENV_NAME = “PongNoFrameskip-v4”
test_env = gym.make(DEFAULT_ENV_NAME)print(test_env.action_space.n)**6**

尽管 OpenAI Gym Pong 环境有六个动作:

print(test_env.unwrapped.get_action_meanings())**[‘NOOP’, ‘FIRE’, ‘RIGHT’, ‘LEFT’, ‘RIGHTFIRE’, ‘LEFTFIRE’]**

六个中的三个是多余的(FIRE 等于 NOOP,LEFT 等于 LEFTFIRE,RIGHT 等于 RIGHTFIRE)。

DQN 概述

在这种新方法的代理的核心,我们发现了一个深度神经网络,而不是我们在以前的帖子中看到的 Q 表。应该注意的是,代理仅被给予原始像素数据,即人类玩家将在屏幕上看到的数据,而不能访问底层的游戏状态、球的位置、球拍等。

作为强化信号,它反馈每个时间步的游戏分数变化。一开始,当神经网络用随机值初始化时,它真的很糟糕,但随着时间的推移,它开始将游戏中的情况和序列与适当的动作关联起来,并学会实际玩好游戏(毫无疑问,读者将能够用本系列中将要展示的代码来验证)。

输入空间

Atari 游戏以 210 X60 像素的分辨率显示,每个像素有 128 种可能的颜色:

print(test_env.observation_space.shape)**(210, 160, 3)**

从技术上讲,这仍然是一个离散的状态空间,但处理起来非常大,我们可以优化它。为了降低这种复杂性,需要执行一些最小的处理:将帧转换为灰度,并将它们缩小到 84 乘 84 像素的正方形块。现在让我们仔细想想,如果有了这个固定的图像,我们是否可以决定游戏的动态。观察中肯定有歧义,对吗?例如,我们无法知道球的前进方向)。这显然违反了马尔科夫属性

解决方案是维护过去的几个观察值,并将它们作为一种状态使用。在 Atari 游戏的情况下,论文的作者建议将 4 个后续帧堆叠在一起,并使用它们作为每个状态的观察值。由于这个原因,预处理将四个帧堆叠在一起,导致最终的状态空间大小为 84×84×4:

输入状态空间转换(来源: torres.ai

输出

与迄今为止我们提出的一次仅产生一个 Q 值的传统强化学习设置不同,深度 Q 网络被设计成在单次正向传递中为环境中可用的每个可能动作产生 Q 值:

(来源: torres.ai )

这种通过网络一次计算所有 Q 值的方法避免了必须为每个动作单独运行网络,并且有助于显著提高速度。现在,我们可以简单地使用这个向量,通过选择具有最大值的向量来采取行动。

神经网络体系结构

最初的 DQN 代理商在所有 49 款游戏中使用了相同的神经网络架构,将 84x84x4 的图像作为输入。

屏幕图像首先由三个卷积层处理。这允许系统利用空间关系,并且可以划分空间规则空间。此外,由于四个帧被堆叠并作为输入提供,这些卷积层也提取这些帧的一些时间属性。使用 PyTorch,我们可以将模型的卷积部分编码为:

nn.Conv2d(input_shape, 32, kernel_size=8, stride=4),
        nn.ReLU(),
        nn.Conv2d(32, 64, kernel_size=4, stride=2),
        nn.ReLU(),
        nn.Conv2d(64, 64, kernel_size=3, stride=1),
        nn.ReLU()

其中input_shape是环境的observation_space.shape

卷积层之后是一个具有 ReLU 激活的全连接隐藏层和一个产生动作值向量的全连接线性输出层:

nn.Linear(conv_out_size, 512),
         nn.ReLU(),
         nn.Linear(512, n_actions)

其中conv_out_size是由给定形状的输入产生的卷积层输出中的值的数量。此值需要传递给第一个完全连接的图层构造器,并且可以进行硬编码,因为它是输入形状的函数(对于 84x84 输入,卷积图层的输出将为 3136)。然而,为了编码一个可以接受不同输入形状的通用模型(用于所有游戏),我们将使用一个简单的函数,_get_conv_out,该函数接受输入形状并将卷积层应用于这种形状的伪张量:

def get_conv_out(self, shape):
         o = self.conv(torch.zeros(1, *shape))
         return int(np.prod(o.size()))conv_out_size = get_conv_out(input_shape)

另一个要解决的问题是需要将卷积输出馈送到完全连接的层。但是 PyTorch 没有一个“更平坦”的图层,我们需要将一批 3D 张量重新整形为一批 1D 向量。在我们的代码中,我们建议在forward()函数中解决这个问题,在这里我们可以使用张量的view()函数将我们的一批 3D 张量重新整形为一批 1D 向量。

view()函数用与输入相同的数据和元素数“整形”一个张量,但具有指定的形状。这个函数有趣的地方在于,让一个单独的维度成为一个-1,在这种情况下,它是从剩余的维度和输入中的元素数量中推断出来的(该方法将执行数学运算以填充该维度)。例如,如果我们有一个形状张量(2,3,4,6),它是 144 个元素的 4D 张量,我们可以使用view(2,72)将其重塑为 2 行 72 列的 2D 张量。通过view(2,-1),due [144/ (346) = 2]可以得到相同的结果。

在我们的代码中,实际上,张量在第一维度中有一个批量大小,我们展平了一个 4D 张量(第一维度是批量大小,第二维度是颜色通道,这是我们后续帧的堆栈;第三和第四是形象维度。)从卷积部分到 2D 张量,作为我们的全连接层的输入,以获得每批输入的 Q 值。

我们刚刚描述的 DQN 类的完整代码写在下面:

import torch
import torch.nn as nn
import numpy as npclass DQN(nn.Module):
    def __init__(self, input_shape, n_actions):
        super(DQN, self).__init__()self.conv = nn.Sequential(
        nn.Conv2d(input_shape[0], 32, kernel_size=8, stride=4),
        nn.ReLU(),
        nn.Conv2d(32, 64, kernel_size=4, stride=2),
        nn.ReLU(),
        nn.Conv2d(64, 64, kernel_size=3, stride=1),
        nn.ReLU()
    )conv_out_size = self._get_conv_out(input_shape)self.fc = nn.Sequential(
         nn.Linear(conv_out_size, 512),
         nn.ReLU(),
         nn.Linear(512, n_actions)
    )def _get_conv_out(self, shape):
         o = self.conv(torch.zeros(1, *shape))
         return int(np.prod(o.size()))def forward(self, x):
         conv_out = self.conv(x).view(x.size()[0], -1)
         return self.fc(conv_out)

我们可以使用print功能查看网络架构概要:

DQN(
  (conv): Sequential(
    (0): Conv2d(4, 32, kernel_size=(8, 8), stride=(4, 4))
    (1): ReLU()
    (2): Conv2d(32, 64, kernel_size=(4, 4), stride=(2, 2))
    (3): ReLU()
    (4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1))
    (5): ReLU()
  )
  (fc): Sequential(
    (0): Linear(in_features=3136, out_features=512, bias=True)
    (1): ReLU()
    (2): Linear(in_features=512, out_features=6, bias=True)
  )
)

开放式健身房包装纸

DeepMind 的论文中,为了提高方法的速度和收敛性,将几种转换(如已经介绍的将帧转换为灰度,并将它们缩小到 84 乘 84 像素的正方形块)应用于 Atari 平台交互。在我们使用 OpenAI Gym simulator 的例子中,转换是作为 OpenAI Gym 包装器实现的。

完整的列表相当长,在不同的源代码中有相同包装器的几种实现。我使用的是基于 OpenAI 基线库Lapan 的书的版本。让我们来介绍它们中每一个的代码。

例如,一些游戏如 Pong 需要用户按下 FIRE 按钮来开始游戏。以下代码对应于包装器FireResetEnv,该包装器在要求游戏启动的环境中按下 FIRE 按钮:

class FireResetEnv(gym.Wrapper):
   def __init__(self, env=None):
       super(FireResetEnv, self).__init__(env)
       assert env.unwrapped.get_action_meanings()[1] == ‘FIRE’
       assert len(env.unwrapped.get_action_meanings()) >= 3def step(self, action):
       return self.env.step(action)def reset(self):
       self.env.reset()
       obs, _, done, _ = self.env.step(1)
       if done:
          self.env.reset()
       obs, _, done, _ = self.env.step(2)
       if done:
          self.env.reset()
       return obs

除了按下 FIRE 之外,这个包装器还检查一些游戏中出现的几个角落情况。

我们需要的下一个包装器是MaxAndSkipEnv,它为 Pong 编写了几个重要的转换:

class MaxAndSkipEnv(gym.Wrapper):
    def __init__(self, env=None, skip=4):
        super(MaxAndSkipEnv, self).__init__(env)
        self._obs_buffer = collections.deque(maxlen=2)
        self._skip = skipdef step(self, action):
        total_reward = 0.0
        done = None
        for _ in range(self._skip):
           obs, reward, done, info = self.env.step(action)
           self._obs_buffer.append(obs)
           total_reward += reward
           if done:
               break
        max_frame = np.max(np.stack(self._obs_buffer), axis=0)
        return max_frame, total_reward, done, infodef reset(self):
       self._obs_buffer.clear()
       obs = self.env.reset()
       self._obs_buffer.append(obs)
       return obs

一方面,它允许我们通过将 max 应用到 N 个观察值(默认为 4 个)并将其作为该步骤的一个观察值返回,从而显著加快训练速度。这是因为在中间帧上,所选择的动作被简单地重复,并且我们可以每 N 步做出一个动作决定,因为用神经网络处理每一帧是一个相当费力的操作,但是后续帧之间的差异通常很小。

另一方面,它取最后两帧中每个像素的最大值,并将其用作观察值。一些 Atari 游戏有闪烁效果(当游戏在偶数和奇数帧上绘制屏幕的不同部分时,Atari 2600 开发者增加游戏精灵复杂性的正常做法),这是由于平台的限制。对于人眼来说,这种快速变化是不可见的,但它们会混淆神经网络。

请记住,我们已经提到过,在将帧馈送到神经网络之前,每一帧都使用色度灰度转换从 210x160(三色帧(RGB 颜色通道))缩小到单色 84 x84 图像。不同的方法是可能的。其中之一是裁剪图像的不相关部分,然后按比例缩小,如下面的代码所示:

class ProcessFrame84(gym.ObservationWrapper):
     def __init__(self, env=None):
         super(ProcessFrame84, self).__init__(env)
         self.observation_space = gym.spaces.Box(low=0, high=255, 
                               shape=(84, 84, 1), dtype=np.uint8)def observation(self, obs):
         return ProcessFrame84.process(obs)@staticmethod
     def process(frame)
         if frame.size == 210 * 160 * 3:
             img = np.reshape(frame, [210, 160,  3])
                                     .astype(np.float32)
         elif frame.size == 250 * 160 * 3:
             img = np.reshape(frame, [250, 160, 3])              
                                     .astype(np.float32)
         else:
             assert False, “Unknown resolution.”       
             img = img[:, :, 0] * 0.299 + img[:, :, 1] * 0.587 + 
                                          img[:, :, 2] * 0.114
             resized_screen = cv2.resize(img, (84, 110),            
                              interpolation=cv2.INTER_AREA)
             x_t = resized_screen[18:102, :]
             x_t = np.reshape(x_t, [84, 84, 1])
             return x_t.astype(np.uint8)

正如我们已经讨论过的在一个游戏帧中缺乏游戏动态的快速解决方案,类BufferWrapper将几个(通常是四个)后续帧堆叠在一起:

class BufferWrapper(gym.ObservationWrapper):
    def __init__(self, env, n_steps, dtype=np.float32):
        super(BufferWrapper, self).__init__(env)
        self.dtype = dtype
        old_space = env.observation_space
        self.observation_space =
                 gym.spaces.Box(old_space.low.repeat(n_steps, 
                 axis=0),old_space.high.repeat(n_steps, axis=0),     
                 dtype=dtype)
    def reset(self):
        self.buffer = np.zeros_like(self.observation_space.low,
        dtype=self.dtype)
        return self.observation(self.env.reset())def observation(self, observation):
        self.buffer[:-1] = self.buffer[1:]
        self.buffer[-1] = observation
        return self.buffer

张量的输入形状有一个颜色通道作为最后一个维度,但 PyTorch 的卷积层假设颜色通道是第一维。这个简单的包装器将观察的形状从 HWC(高度、宽度、通道)改变为 PyTorch 要求的 CHW(通道、高度、宽度)格式:

class ImageToPyTorch(gym.ObservationWrapper):
    def __init__(self, env):
        super(ImageToPyTorch, self).__init__(env)
        old_shape = self.observation_space.shape
        self.observation_space = gym.spaces.Box(low=0.0, high=1.0,            
                                shape=(old_shape[-1], 
                                old_shape[0], old_shape[1]),
                                dtype=np.float32)def observation(self, observation):
      return np.moveaxis(observation, 2, 0)

从模拟器获得的屏幕被编码为具有从 0 到 255 的值的字节张量,这不是神经网络的最佳表示。因此,我们需要将图像转换成浮点数,并将值重新调整到范围[0.0…1.0]。这是由ScaledFloatFrame包装器完成的:

class ScaledFloatFrame(gym.ObservationWrapper):
     def observation(self, obs):
         return np.array(obs).astype(np.float32) / 255.0

最后,下面这个简单的函数make_env将会很有帮助,它根据名字创建了一个环境,并对它应用了所有需要的包装器:

def make_env(env_name):
    env = gym.make(env_name)
    env = MaxAndSkipEnv(env)
    env = FireResetEnv(env)
    env = ProcessFrame84(env)
    env = ImageToPyTorch(env) 
    env = BufferWrapper(env, 4)
    return ScaledFloatFrame(env)

下一步是什么?

这是致力于深度 Q 网(DQN)的三篇帖子中的第一篇,在这三篇帖子中,我们提供了 DQN 的概况以及对 Pong 的 OpenAI 健身房框架的介绍。在接下来的两篇帖子(帖 16帖 17 )中,我们将展示该算法及其实现,其中我们将涵盖 dqn 提高其训练稳定性和收敛性的几个技巧。

深度强化学习讲解系列

UPC 巴塞罗那理工 巴塞罗那超级计算中心

一个轻松的介绍性系列以一种实用的方式逐渐向读者介绍这项令人兴奋的技术,它是人工智能领域最新突破性进展的真正推动者。

[## 深度强化学习解释-乔迪托雷斯。人工智能

本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)

关于这个系列

我在五月份开始写这个系列,那是在巴塞罗那的封锁期。老实说,由于封锁,在业余时间写这些帖子帮助了我 #StayAtHome 。感谢您当年阅读这份刊物;它证明了我所做的努力。

免责声明 —这些帖子是在巴塞罗纳封锁期间写的,作为个人消遣和传播科学知识,以防它可能对某人有所帮助,但不是为了成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。

深度 Q-网络(DQN)-II

原文:https://towardsdatascience.com/deep-q-network-dqn-ii-b6bf911b6b2c?source=collection_archive---------1-----------------------

深度强化学习讲解— 16

体验重放和目标网络

这是【深度 Q 网】(DQN)、深度强化学习讲解系列中的**的第二篇帖子,其中我们将分析当我们将深度学习应用于强化学习时出现的一些挑战。我们还将详细介绍使用在上一篇文章中介绍的 DQN 网络解决 OpenAI Gym Pong 游戏的代码。

本出版物的西班牙语版本

** [## 9.基于价值的营销:深度 Q 网络

请访问第 9 页的自由介绍

medium.com](https://medium.com/aprendizaje-por-refuerzo/9-métodos-value-based-deep-q-network-b52b5c3da0ba)

深度强化学习的挑战

不幸的是,当使用神经网络来表示动作值时,强化学习更加不稳定,尽管应用了上一节介绍的包装器。训练这样的网络需要大量的数据,但即使这样,也不能保证收敛到最优值函数。事实上,由于动作和状态之间的高度相关性,存在网络权重可能振荡或发散的情况。

为了解决这个问题,本节我们将介绍深度 Q 网络使用的两种技术:

  • 体验回放
  • 目标网络

研究人员还发现了更多的技巧和窍门来使 DQN 训练更加稳定和有效,我们将在本系列的后续文章中介绍其中的精华。

体验回放

我们试图用神经网络来逼近一个复杂的非线性函数 Q(s,a)。要做到这一点,我们必须使用贝尔曼方程计算目标,然后考虑我们手头有一个监督学习问题。然而,SGD 优化的一个基本要求是训练数据是独立和同分布的,并且当代理与环境交互时,经验元组的序列可以是高度相关的。以连续顺序从这些经验元组中的每一个学习的朴素 Q 学习算法冒着被这种相关性的影响所左右的风险。

我们可以使用我们过去的经验和样本训练数据的大缓冲区,而不是使用我们的最新经验,来防止行动值发生灾难性的波动或偏离。这个技术叫做重放缓冲或者经验缓冲。重放缓冲器包含经验元组的集合( SARS’)。当我们与环境交互时,元组被逐渐添加到缓冲区中。最简单的实现是一个固定大小的缓冲区,将新数据添加到缓冲区的末尾,以便将最老的体验推出。

为了学习,从重放缓冲器中采样一小批元组的行为被称为体验重放。除了打破有害的相关性,经验回放允许我们多次从单个元组中学习更多,回忆罕见的事件,并在总体上更好地利用我们的经验。

总之,经验重放背后的基本思想是存储过去的经验,然后使用这些经验的随机子集来更新 Q 网络,而不是仅使用单个最近的经验。为了存储代理的经验,我们在 Python 的内置集合库中使用了一个名为deque的数据结构。它基本上是一个列表,你可以设置一个最大大小,这样,如果你试图添加到列表中,它已经满了,它会删除列表中的第一个项目,并在列表的末尾添加新的项目。体验本身就是【观察、动作、奖励、完成标志、下一个状态】的元组,保持从环境中获得的跃迁。

Experience = collections.namedtuple(‘Experience’, 
           field_names=[‘state’, ‘action’, ‘reward’, 
           ‘done’, ‘new_state’])class ExperienceReplay:
  def __init__(self, capacity):
      self.buffer = collections.deque(maxlen=capacity) def __len__(self):
      return len(self.buffer) def append(self, experience):
      self.buffer.append(experience)

  def sample(self, batch_size):
      indices = np.random.choice(len(self.buffer), batch_size,
                replace=False)
      states, actions, rewards, dones, next_states = 
             zip([self.buffer[idx] for idx in indices])
      return np.array(states), np.array(actions),         
             np.array(rewards,dtype=np.float32), 
             np.array(dones, dtype=np.uint8),    
             np.array(next_states)

每当代理在环境中执行一个步骤时,它就将转换推入缓冲区,只保留固定数量的步骤(在我们的例子中,10k 个转换)。对于训练,我们从重放缓冲区中随机抽取一批转换,这允许我们打破环境中后续步骤之间的相关性。

大多数体验重放缓冲区代码非常简单:它基本上利用了deque库的功能。在sample()方法中,我们创建一个随机索引列表,然后将采样条目重新打包到 NumPy 数组中,以便更方便地计算损失。

目标网络

记住在 Q-Learning 中,我们 用猜测 更新猜测,这可能会导致有害的相关性。贝尔曼方程通过 Q(s’,a’)为我们提供了 Q(s,a)的值。然而,状态 s 和 s’之间只有一步之遥。这使得它们非常相似,神经网络很难区分它们。

当我们执行神经网络参数的更新以使 Q(s,a)更接近期望的结果时,我们可以间接改变 Q(s ',a ')和附近其他状态产生的值。这会使我们的训练非常不稳定。

为了使训练更加稳定,有一个技巧,称为目标网络,通过它我们保留了一份我们神经网络的副本,并将其用于贝尔曼方程中的 Q(s ',a ')值。

也就是说,被称为目标网络的第二 Q 网络的预测 Q 值被用于反向传播并训练主 Q 网络。需要强调的是,目标网络的参数不是训练出来的,而是周期性地与主 Q 网络的参数同步。想法是使用目标网络的 Q 值来训练主 Q 网络将提高训练的稳定性。

稍后,当我们呈现训练循环的代码时,我们将更详细地输入如何对这个目标网络的初始化和使用进行编码。

深度 Q 学习算法

深度 Q 学习算法中有两个主要的交错阶段。一个是我们通过执行动作对环境进行采样,并将观察到的经验元组存储在重放存储器中。另一个是我们从这个内存中随机选择小批元组,然后使用梯度下降(SGD)更新步骤从那批元组中学习

这两个阶段并不直接相互依赖,我们可以执行多个采样步骤,然后是一个学习步骤,甚至是不同随机批次的多个学习步骤。在实践中,您无法立即运行学习步骤。你需要等到你在 D 中有足够的经验元组。

算法的其余部分被设计成支持这些步骤。我们可以用这个基本 DQN 算法的伪代码来总结前面的解释,它将指导我们实现该算法:

一开始,我们需要创建主网络和目标网络,并初始化一个空的重放存储器 D 。请注意,内存是有限的,因此我们可能希望使用类似循环队列的东西来保留 d 最近的经验元组。我们还需要初始化代理,它是与环境交互的主要组件之一。

请注意,我们不会在每集之后清除记忆,这使我们能够回忆和建立跨集的经验批次。

编码训练循环

超参数和执行时间

在进入代码之前,请注意 DeepMind 的自然论文包含一个表格,其中列出了用于在所有 49 款用于评估的 Atari 游戏上训练其模型的超参数的所有细节。DeepMind 为所有游戏保留了相同的参数,但为每个游戏训练了单独的模型。该团队的目的是表明该方法足够健壮,可以使用一个单一的模型架构和超参数来解决许多具有不同复杂性、动作空间、奖励结构和其他细节的游戏。

然而,我们在这篇文章中的目标只是解决 Pong 游戏,与 Atari 测试集中的其他游戏相比,这是一个非常简单和直接的游戏,所以本文中的超参数不是最适合像这篇文章这样的说教性文章。出于这个原因,我们决定为 Pong 环境使用更个性化的参数值,根据 colab 分配给我们的执行的 GPU 类型(最多几个小时),Pong 环境在合理的墙时间内收敛到平均分数 19.0。记住,我们可以通过命令!nvidia-smi知道分配给我们的运行时环境的 GPU 的类型。

让我们开始更详细地介绍代码。这篇文章的全部代码可以在 GitHub 上找到(而可以使用这个链接作为 Colab google 笔记本运行)。我们跳过了包的导入细节,这很简单,我们集中在超参数的解释上:

DEFAULT_ENV_NAME = “PongNoFrameskip-v4” 
MEAN_REWARD_BOUND = 19.0 gamma = 0.99                    or
batch_size = 32                 
replay_size = 10000             
learning_rate = 1e-4            
sync_target_frames = 1000        
replay_start_size = 10000 eps_start=1.0
eps_decay=.999985
eps_min=0.02

这些DEFAULT_ENV_NAME确定了训练的环境,MEAN_REWARD_BOUND确定了停止训练的奖励界限。当我们的代理人在过去的 100 场比赛中平均赢得 19 场比赛(共 21 场)时,我们将认为这场比赛已经收敛。其余参数表示:

  • gamma是贴现因子
  • batch_size,迷你批次大小
  • learning_rate是学习率
  • replay_size重放缓冲区大小(存储在重放存储器中的最大体验次数)
  • sync_target_frames表示我们将模型重量从主 DQN 网络同步到目标 DQN 网络的频率(同步之间间隔多少帧)
  • replay_start_size开始训练前添加到重放缓冲区的帧数(体验数)。

最后,与ε衰变时间表相关的超参数与之前的相同:

eps_start=1.0
eps_decay=.999985
eps_min=0.02

代理人

我们需要的一个主要组件是代理,它与环境交互,并将交互的结果保存到体验回放缓冲区中。我们将要设计的代理类已经将与环境交互的结果直接保存到体验重放缓冲区 中,执行前面伪代码部分中指示的样本阶段的这三个步骤:

首先,在代理的初始化期间,我们需要存储对环境和经验重放缓冲区 D 的引用,该缓冲区在创建代理的对象时被指示为参数exp_buffer:

class Agent: 
    def __init__(self, env, exp_buffer):
        self.env = env
        self.exp_buffer = exp_buffer
        self._reset()def _reset(self):
        self.state = env.reset()
        self.total_reward = 0.0

为了在环境中执行代理的步骤并将其结果存储在体验回放内存中,我们建议使用以下代码:

def play_step(self, net, epsilon=0.0, device=”cpu”): done_reward = None if np.random.random() < epsilon:
       action = env.action_space.sample()
    else:
       state_a = np.array([self.state], copy=False)
       state_v = torch.tensor(state_a).to(device)
       q_vals_v = net(state_v)
       _, act_v = torch.max(q_vals_v, dim=1)
       action = int(act_v.item())

方法play_step使用 ϵ-greedy(Q) 策略在每个时间步选择动作。换句话说,根据概率epsilon(作为参数传递),我们采取随机行动;否则,我们使用过去的模型来获得所有可能动作的 Q 值,并选择最佳的。

在获得action之后,该方法执行环境中的步骤以获得下一个观察值:next_staterewardis_done:

 new_state, reward, is_done, _ = self.env.step(action)
    self.total_reward += reward

最后,该方法将观察结果存储在体验重放缓冲器中,然后处理剧集结束的情况:

 exp = Experience(self.state,action,reward,is_done,new_state)
    self.exp_buffer.append(exp)
    self.state = new_state
    if is_done:
       done_reward = self.total_reward
       self._reset()
    return done_reward

该函数的结果是如果我们已经到达这一步的最后一集的总累积奖励,或者是 None 如果不是

主循环

在初始化部分,我们创建了应用了所有必需的包装器的环境,我们将要训练的主 DQN 神经网络,以及具有相同架构的目标网络。我们还创建所需大小的体验重放缓冲区,并将其传递给代理。在训练循环之前,我们要做的最后一件事是创建一个优化器、一个完整剧集奖励的缓冲区、一个帧计数器和一个变量来跟踪达到的最佳平均奖励(因为每次平均奖励超过记录时,我们都会将模型保存在一个文件中):

env = make_env(DEFAULT_ENV_NAME)
net = DQN(env.observation_space.shape,
          env.action_space.n).to(device)
target_net = DQN(env.observation_space.shape,
          env.action_space.n).to(device)buffer = ExperienceReplay(replay_size)
agent = Agent(env, buffer)epsilon = eps_startoptimizer = optim.Adam(net.parameters(), lr=learning_rate)
total_rewards = []
frame_idx = 0best_mean_reward = None

在训练循环的开始,我们计算完成的迭代次数,并更新 epsilon,就像我们在之前的文章中介绍的那样。接下来,代理在环境中执行单个步骤(使用当前神经网络和 epsilon 的值作为参数)。请记住,只有当这一步是本集的最后一步时,该函数才会返回 non-None 结果。在这种情况下,我们在控制台中报告进度(播放的剧集数、最近 100 集的平均奖励以及 epsilon 的当前值):

while True:
  frame_idx += 1
  epsilon = max(epsilon*eps_decay, eps_min)
  reward = agent.play_step(net, epsilon, device=device) if reward is not None:
     total_rewards.append(reward)
     mean_reward = np.mean(total_rewards[-100:])
     print(“%d: %d games, mean reward %.3f, (epsilon %.2f)” % 
          (frame_idx, len(total_rewards), mean_reward, epsilon))

之后,每次我们对过去 100 集的平均奖励达到最大值时,我们都会在控制台中报告这一情况,并将当前的模型参数保存在一个文件中。同样,如果这意味着奖励超过了指定的MEAN_REWARD_BOUND(在我们的例子中是 19.0),那么我们就停止训练。第三个 if 帮助我们确保我们的经验重放缓冲区对于训练来说足够大:

if best_mean_reward is None or 
        best_mean_reward < mean_reward:
             torch.save(net.state_dict(), 
                       DEFAULT_ENV_NAME + “-best.dat”)
             best_mean_reward = mean_reward
             if best_mean_reward is not None:
             print(“Best mean reward updated %.3f” % 
                  (best_mean_reward))if mean_reward > MEAN_REWARD_BOUND:
             print(“Solved in %d frames!” % frame_idx)
             breakif len(buffer) < replay_start_size:
             continue

学习阶段

现在,我们将开始描述主循环中的代码部分,它指的是网络学习的阶段(前面伪代码的一部分):

我们为实现这一部分而编写的完整代码如下:

batch = buffer.sample(batch_size) 
states, actions, rewards, dones, next_states = batchstates_v = torch.tensor(states).to(device)
next_states_v = torch.tensor(next_states).to(device)
actions_v = torch.tensor(actions).to(device)
rewards_v = torch.tensor(rewards).to(device)
done_mask = torch.ByteTensor(dones).to(device)state_action_values = net(states_v).gather(1, 
                          actions_v.unsqueeze(-1)).squeeze(-1)
next_state_values = target_net(next_states_v).max(1)[0]
next_state_values[done_mask] = 0.0
next_state_values = next_state_values.detach()expected_state_action_values=next_state_values * gamma + rewards_vloss_t = nn.MSELoss()(state_action_values, 
                     expected_state_action_values)optimizer.zero_grad()
loss_t.backward()
optimizer.step()if frame_idx % sync_target_frames == 0:
   target_net.load_state_dict(net.state_dict())

我们将对其进行剖析,以便于描述,因为它可能是最难理解的部分。

要做的第一件事是从重放存储器中随机抽取少量事务:

batch = buffer.sample(batch_size) 
states, actions, rewards, dones, next_states = batch

接下来,代码用 PyTorch 张量中的批量数据包装各个 NumPy 数组,并将它们复制到 GPU(我们假设在参数中指定了 CUDA 设备):

states_v = torch.tensor(states).to(device)
next_states_v = torch.tensor(next_states).to(device)
actions_v = torch.tensor(actions).to(device)
rewards_v = torch.tensor(rewards).to(device)
done_mask = torch.ByteTensor(dones).to(device)

这个代码的灵感来自于马克西姆·拉潘的代码。它以一种形式编写,通过向量运算处理(并行)所有批量样本,最大限度地利用 GPU 的能力。但是一步一步解释,就能明白,没有问题。

然后,我们将观察结果传递给第一个模型,并使用gather()张量运算提取所采取行动的特定 Q 值。这个函数调用的第一个参数是一个维度索引,我们希望对其执行聚集。在这种情况下,它等于 1,因为它对应于操作维度:

state_action_values = net(states_v).gather(1, 
                          actions_v.unsqueeze(-1)).squeeze(-1)

第二个参数是要选择的元素的索引张量。这里解释代码有点复杂。我们试试吧!。 Maxim Lapan 建议使用功能unsqueeze()squeeze()。因为索引应该具有与我们正在处理的数据相同的维数(在我们的例子中是 2D ),所以它对action_v(也就是 1D)应用一个unsqueeze(),来计算聚集函数的索引参数。最后,为了删除我们创建的额外维度,我们将使用squeeze()函数。让我们在一个简单的示例案例中,用一批四个条目和四个动作来说明一个聚集做了什么:

请注意,应用于张量的 gather()的结果是一个可微分的运算,它将保持关于最终损失值的所有梯度。

既然我们已经计算了重放缓冲区中每个转换的状态-动作值,我们还需要计算重放缓冲区中每个转换的目标“y”。这两个向量都是我们将在损失函数中使用的向量。为此,请记住我们必须使用目标网络。

在下面的代码中,我们将目标网络应用于我们的下一个状态观察,并沿着相同的动作维度 1 计算最大 Q 值:

next_state_values = target_net(next_states_v).max(1)[0]

函数max()返回最大值和这些值的索引(因此它计算 max 和 argmax)。因为在这种情况下,我们只对值感兴趣,所以我们取结果的第一个条目。

请记住,如果批次中的过渡是从剧集的最后一步开始的,那么我们的动作值没有下一个状态的折扣奖励,因为没有下一个状态可以收集奖励:

next_state_values[done_mask] = 0.0

虽然我们不能深入细节,但重要的是要强调目标神经网络对下一个状态值的计算不应该影响梯度。为了实现这一点,我们使用 PyTorch 张量的detach()函数,该函数在不连接到父操作的情况下复制它,以防止梯度流入目标网络的图形:

next_state_values = next_state_values.detach()

现在,我们可以计算目标向量(“y”)的贝尔曼近似值,这是重放缓冲区中每个转换的预期状态-动作值的向量:

expected_state_action_values=next_state_values * gamma + rewards_v

我们拥有计算均方误差损失所需的所有信息:

loss_t = nn.MSELoss()(state_action_values, 
                     expected_state_action_values)

训练循环的下一部分使用 SGD 算法通过最小化损失来更新主神经网络:

optimizer.zero_grad()
loss_t.backward()
optimizer.step()

最后,代码的最后一行每隔sync_target_frames将参数从我们的主 DQN 网络同步到目标 DQN 网络:

if frame_idx % sync_target_frames == 0:
   target_net.load_state_dict(net.state_dict())

至此,主循环的代码!

下一步是什么?

这是三篇专门介绍深度 Q 网络(DQN)基础知识的文章中的第二篇,在这三篇文章中,我们详细介绍了该算法。在下一篇文章中,我们将讨论该算法的性能,并展示我们如何使用它。**

深度强化学习讲解系列

UPC 巴塞罗那理工 巴塞罗那超级计算中心

一个轻松的介绍性系列以一种实用的方式逐渐向读者介绍这项令人兴奋的技术,它是人工智能领域最新突破性进展的真正推动者。

** [## 深度强化学习解释-乔迪托雷斯。人工智能

本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)

关于这个系列

我在五月份开始写这个系列,那是在巴塞罗那的封锁期。老实说,由于封锁,在业余时间写这些帖子帮助了我#呆在家里 。感谢您当年阅读这份刊物;它证明了我所做的努力。

免责声明 —这些帖子是在巴塞罗纳封锁期间写的,作为个人消遣和传播科学知识,以防它可能对某人有所帮助,但不是为了成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。**

深度 Q-网络(DQN)-三

原文:https://towardsdatascience.com/deep-q-network-dqn-iii-c5a83b0338d2?source=collection_archive---------30-----------------------

深度强化学习讲解— 17

DQN 的性能和用途

这是第三篇专门讨论【深度 Q 网】(DQN)、深度强化学习讲解系列中的**的帖子,其中我们展示了如何使用 TensorBoard 来获得模型性能的图形化视图。我们还提供了一种方法来查看我们训练有素的代理如何能够玩乒乓。

本出版物的西班牙语版本

** [## 9.基于价值的营销:深度 Q 网络

请访问第 9 页的自由介绍

medium.com](https://medium.com/aprendizaje-por-refuerzo/9-métodos-value-based-deep-q-network-b52b5c3da0ba)

这篇文章的全部代码可以在 GitHub 上找到(而可以使用这个链接作为 Colab google 笔记本运行)。

运行训练循环

当我们运行本例中的笔记本时,我们在控制台中获得以下输出:

. . .

由于训练过程中的随机性,您的实际动态将与此处显示的不同。

但是,尽管信息丰富,却很难从一百万行中得出结论。读者应该记得,在之前的帖子 5 ( PyTorch 使用 tensor board)中,我们介绍了工具tensor board,该工具有助于跟踪不同参数的进度,并且可以为找到超参数的值提供出色的支持。

我们在这里不再重复解释应该插入什么代码,但是读者可以在 GitHub 中找到这个例子的详细代码,它为 DQN 获得了一个在交互 TensorFlow 窗口中绘制的轨迹,如下所示:

例如,使用此代码,我们可以获得跟踪以监控 epsilon、奖励和平均奖励的行为:

有了这个工具,我邀请用户找到更好的超参数。

使用模型

最后,在 GitHub 中,读者可以找到允许我们看到我们训练有素的代理如何玩 Pong 的代码:

我们已经准备了代码,生成一个游戏的一集视频。视频存储在文件夹video中。

代码几乎是代理类的方法play_step()的精确拷贝,没有ε-贪婪动作选择。我们只是将我们的观察传递给代理,并选择具有最大值的动作。这里唯一的新东西是环境中的render()方法,这是 Gym 中显示当前观察的标准方式。

代码中的主循环,将动作传递给环境,统计总奖励,当剧集结束时停止循环。在这一集之后,它会显示总奖励和代理执行该动作的次数。

因为它需要有一个图形用户界面(GUI ),并且我们是在 colab 环境中执行我们的代码,而不是在我们的个人计算机中,所以我们需要运行一组命令(从这个链接中获得)。

摘要

这是专门介绍深度 Q 网络(DQN)基础知识的三篇文章中的第三篇,在这三篇文章中,我们介绍了如何使用 TensorBoard 来帮助我们进行参数调整。我们还展示了如何可视化我们的代理的行为。

下期**

深度强化学习讲解系列

UPC 巴塞罗那理工 巴塞罗那超级计算中心

一个轻松的介绍性系列逐渐并以实用的方法向读者介绍这一令人兴奋的技术,这是人工智能领域最新突破性进展的真正推动者。

**** [## 深度强化学习解释-乔迪托雷斯。人工智能

本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)

关于这个系列

我是在五月份开始写这个系列的,那是在巴塞罗纳的封锁期。老实说,由于封锁,在业余时间写这些帖子帮助了我 #StayAtHome 。感谢您当年阅读这份刊物;这证明了我所做的努力。

免责声明 —这些帖子是在巴塞罗纳封锁期间写的,目的是分散个人注意力和传播科学知识,以防对某人有所帮助,但无意成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。****

深度强化学习和超参数调整

原文:https://towardsdatascience.com/deep-reinforcement-learning-and-hyperparameter-tuning-df9bf48e4bd2?source=collection_archive---------14-----------------------

用雷的曲子优化你的模型

深度强化学习最困难和最耗时的部分之一是超参数的优化。这些值(如折扣系数[latex]\gamma[/latex]或学习率)会对代理的性能产生重大影响。

代理需要接受培训,以了解超参数如何影响绩效——没有先验的方法来知道给定参数的更高或更低的值是否会提高总报酬。除了跟踪实验、数据和与训练模型相关的一切之外,这转化为多次昂贵的训练运行以获得好的代理。

Ray 提供了一种使用 Tune library 处理所有这些的方法,它可以自动处理您的各种模型,保存数据,调整您的超参数,并总结结果以便快速轻松地参考。

TL;速度三角形定位法(dead reckoning)

我们通过一个简单的例子来说明如何使用 Tune 的网格搜索特性来优化我们的超参数。

安装 Tune

Tune 是 Ray 项目的一部分,但是需要单独安装,所以如果您还没有安装它,您需要运行下面的命令来让 Tune 工作。

pip install ray[tune]

从这里,我们可以导入我们的包来训练我们的模型。

import ray
from ray import tune

调整您的第一个模型

从基础开始,让我们用 Tune 训练一个 agent 来解决CartPole-v0。Tune 需要一些具有不同设置和标准的字典来训练。它必须具有的两个参数是configstop

config字典将为调优提供它需要运行的环境,以及您可能想要指定的任何特定于环境的配置。这也是你的大部分超参数将要驻留的地方,但是我们一会儿会讲到。

stop字典告诉 Tune 什么时候结束训练或者什么时候完全停止训练。它可以根据奖励标准、经过的时间、完成的步数等进行定制。当我第一次开始使用 Tune 时,我忽略了设置任何停止标准,最终让算法训练了几个小时才意识到这一点。所以,你可以不用这个来运行它,但是如果你不小心的话,你可能会得到一个不错的 AWS 账单!

尝试使用以下代码在CartPole-v0上运行 PPO 算法 10,000 个时间步长。

ray.init(ignore_reinit_error=True)
config = {
    'env': 'CartPole-v0'
}
stop = {
    'timesteps_total': 10000
}
results = tune.run(
    'PPO', # Specify the algorithm to train
    config=config,
    stop=stop
)

通过这些设置,您应该可以看到您的工作人员、内存以及logdir状态的打印输出,所有数据都存储在这里以供以后分析。

控制台将在每次迭代中打印这些值,除非tune.run()中的verbose参数被设置为 0(无声)。

当训练完成时,你会得到一个输出,显示状态已经终止,经过的时间,以及过去 100 集的平均奖励和其他数据。

使用网格搜索调整超参数

当我们利用它来调整我们的超参数时,Tune 的力量就真正发挥出来了。为此,我们将求助于grid_search函数,它允许用户为要测试的模型指定一组超参数。

为此,我们只需要在tune.grid_search()函数中包装一个值列表,并将其放入我们的配置字典中。让我们回到上面的CartPole例子。我们可能想看看学习速度是否有什么不同,双头网络是否有什么好处。我们可以使用grid_search()来实现这些的不同组合,如下所示:

config = {
    "env": 'CartPole-v0',
    "num_workers": 2,
    "vf_share_layers": tune.grid_search([True, False]),
    "lr": tune.grid_search([1e-4, 1e-5, 1e-6]),
    }
results = tune.run(
    'PPO', 
    stop={
        'timesteps_total': 100000
    },
    config=config)

现在我们看到一个展开的状态打印输出,其中包含我们想要运行的各种试验:

当 Ray 启动其中的每一个时,它将显示我们想要探索的超参数的组合,以及每个超参数的回报、迭代和运行时间。当它完成时,我们应该看到每个的状态为终止,以表明它正常工作(否则它将读取错误)。

分析调节结果

我们的tune.run()函数的输出是一个被我们标记为resultsanalysis对象。我们可以利用这一点来进一步了解我们实验的细节。可以通过results.dataframe()访问相关数据,这将返回一个 Pandas 数据帧,其中包含平均奖励、迭代次数、KL 散度、配置设置等等。数据框还包含保存您的实验的特定目录(logdir),因此您可以了解您的特定运行的详细信息。

如果您查看logdir目录,您会发现许多包含您的训练运行中保存的数据的文件。出于我们的目的,主文件将是progress.csv——它包含来自每个迭代的训练数据,允许您深入细节。

例如,如果我们想要查看不同设置的训练和损耗曲线,我们可以循环遍历数据框中的logdir列,加载每个progress.csv文件并绘制结果。

# Plot training results
import matplotlib.pyplot as plt
import pandas as pdcolors = plt.rcParams['axes.prop_cycle'].by_key()['color']
df = results.dataframe()# Get column for total loss, policy loss, and value loss
tl_col = [i for i, j in enumerate(df.columns)
          if 'total_loss' in j][0]
pl_col = [i for i, j in enumerate(df.columns)
          if 'policy_loss' in j][0]
vl_col = [i for i, j in enumerate(df.columns)
          if 'vf_loss' in j][0]
labels = []
fig, ax = plt.subplots(2, 2, figsize=(15, 15), sharex=True)
for i, path in df['logdir'].iteritems():
    data = pd.read_csv(path + '/progress.csv')
    # Get labels for legend
    lr = data['experiment_tag'][0].split('=')[1].split(',')[0]
    layers = data['experiment_tag'][0].split('=')[-1]
    labels.append('LR={}; Shared Layers={}'.format(lr, layers))

    ax[0, 0].plot(data['timesteps_total'], 
            data['episode_reward_mean'], c=colors[i],
            label=labels[-1])

    ax[0, 1].plot(data['timesteps_total'], 
           data.iloc[:, tl_col], c=colors[i],
           label=labels[-1])

    ax[1, 0].plot(data['timesteps_total'], 
               data.iloc[:, pl_col], c=colors[i],
               label=labels[-1])

    ax[1, 1].plot(data['timesteps_total'], 
               data.iloc[:, vl_col], c=colors[i],
               label=labels[-1])ax[0, 0].set_ylabel('Mean Rewards')
ax[0, 0].set_title('Training Rewards by Time Step')
ax[0, 0].legend(labels=labels, loc='upper center',
        ncol=3, bbox_to_anchor=[0.75, 1.2]) ax[0, 1].set_title('Total Loss by Time Step')
ax[0, 1].set_ylabel('Total Loss')
ax[0, 1].set_xlabel('Training Episodes')ax[1, 0].set_title('Policy Loss by Time Step')
ax[1, 0].set_ylabel('Policy Loss')
ax[1, 0].set_xlabel('Time Step')ax[1, 1].set_title('Value Loss by Time Step')
ax[1, 1].set_ylabel('Value Loss')
ax[1, 1].set_xlabel('Time Step')plt.show()

超越网格搜索

Tune 中提供了更多的调优选项。如果你想看看你能调整什么,看看你的特定算法的文档。此外,Tune 支持不同的超参数优化方法。网格搜索可能会很慢,所以只需改变几个选项,就可以使用贝叶斯优化、HyperOpt 等。最后,Tune 使得基于人口的培训 (PBT)变得容易,允许多个代理跨不同的机器伸缩。所有这些都将在以后的帖子中介绍!

用于自动股票交易的深度强化学习

原文:https://towardsdatascience.com/deep-reinforcement-learning-for-automated-stock-trading-f1dad0126a02?source=collection_archive---------0-----------------------

使用强化学习通过 Python 和 OpenAI Gym 交易多只股票|在 ICAIF 2020 上展示

图像由 克里斯

来自《走向数据科学》编辑的注释: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

这篇博客基于我们的论文: 自动化股票交易的深度强化学习:一个集合策略 ,发表于ICAIF 2020:ACM 金融 AI 国际会议。

我们的代码可以在 Github 上找到。

[## 主 AI4Finance 的 FinRL-Trading/old _ repo _ ensemble _ strategy-Foundation/FinRL-Trading

该库提供 ICAIF 2020 论文的代码。该集合策略在 Jupiter 笔记本中重新实施,网址为…

github.com](https://github.com/AI4Finance-Foundation/FinRL-Trading/tree/master/old_repo_ensemble_strategy)

使用 FinRL 的集成策略:

[## FinRL/FinRL _ Ensemble _ stock trading _ ICAIF _ 2020 . ipynb at master ai4 finance-Foundation/FinRL

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/AI4Finance-Foundation/FinRL/blob/master/examples/FinRL_Ensemble_StockTrading_ICAIF_2020.ipynb)

我们的论文刊登在 SSRN。

[## 自动股票交易的深度强化学习:一种集成策略

撰写日期:2020 年 9 月 11 日股票交易策略在投资中起着至关重要的作用。然而,它是…

papers.ssrn.com](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3690996)

如果要引用我们的论文,参考格式如下:

杨红阳,,钟山和安瓦尔·瓦利德。2020.自动股票交易的深度强化学习:一个集成策略。ICAIF '20: ACM 金融人工智能国际会议,2020 年 10 月 15-16 日,纽约曼哈顿。美国纽约州纽约市 ACM。

一个最新的 DRL 自动交易库- FinRL 可以在这里找到:

[## GitHub-ai4 finance-Foundation/FinRL:自动化交易的深度强化学习框架…

新闻:我们计划分享我们的纸上交易和现场交易的代码。请积极与我们分享您的兴趣…

github.com](https://github.com/AI4Finance-Foundation/FinRL)

量化金融 FinRL:单只股票交易教程

量化金融 FinRL:多只股票交易教程

量化金融 FinRL:投资组合配置教程

ElegantRL 支持最先进的 DRL 算法,并在 Jupyter 笔记本中提供用户友好的教程。核心代码<1000 行,使用 PyTorch,OpenAI Gym,和 NumPy。

[## ElegantRL:一个轻量级且稳定的深度强化学习库

一天掌握深度强化学习。

towardsdatascience.com](/elegantrl-a-lightweight-and-stable-deep-reinforcement-learning-library-95cef5f3460b)

概观

人们很难高估股票交易策略在投资中的重要作用。

盈利的自动股票交易策略对投资公司和对冲基金至关重要。它适用于优化资本配置和最大化投资绩效,如预期回报。回报最大化可以基于对潜在回报和风险的估计。然而,在一个复杂多变的股票市场中设计一个有利可图的策略是具有挑战性的。

每个玩家都想要一个获胜的策略。不用说,在如此复杂和动态的股票市场中,一个有利可图的策略是不容易设计的。

然而,我们将揭示一种深度强化学习方案,通过最大化投资回报来自动学习股票交易策略。

图片由 素妍 上的 Unsplash

我们的解决方案:集成深度强化学习交易策略
该策略包括三种基于行动者-批评家的算法:近似政策优化(PPO)、优势行动者-批评家(A2C)和深度确定性政策梯度(DDPG)。
它结合了三种算法的最佳特性,从而稳健地适应不同的市场条件。

使用夏普比率评估具有不同强化学习算法的交易代理的性能,并与道琼斯工业平均指数和传统的最小方差投资组合分配策略进行比较。

AI4Finance-Foundation 版权所有

第一部分。为什么要用深度强化学习(DRL)来炒股?

现有的作品并不令人满意。深度强化学习方法有许多优点。

1.1 DRL 与现代投资组合理论(MPT)

  1. MPT 在样本外数据表现不佳。
  2. MPT 对异常值非常敏感。
  3. MPT仅基于股票收益计算,如果我们要考虑其他相关因素,例如一些技术指标如移动平均线收敛发散(MACD)相对强弱指数(RSI) ,MPT 可能无法将这些信息很好地结合在一起。

1.2 DRL 和监督机器学习预测模型

  1. DRL 不需要大的带标签的训练数据集。这是一个显著的优势,因为如今数据量呈指数级增长,标记大型数据集变得非常耗时耗力。
  2. DRL 使用奖励函数来优化未来的奖励,与预测未来结果概率的 ML 回归/分类模型形成对比。

1.3 利用 DRL 进行股票交易的理由

  1. 股票交易的目标是在规避风险的同时最大化收益。DRL 通过最大化一段时间内未来行动的预期总回报来解决这个优化问题。
  2. 股票交易是一个连续的过程测试新的想法,从市场获得反馈,并试图随着时间的推移优化交易策略。我们可以将股票交易过程建模为马尔可夫决策过程,这是强化学习的基础。

1.4 深度强化学习的优势

  1. 深度强化学习算法可以在很多挑战性游戏中胜过人类玩家。例如,2016 年 3 月, DeepMind 的 AlphaGo 程序,一种深度强化学习算法,在围棋比赛中击败了世界冠军 Lee Sedol。
  2. 回报最大化为交易目标:通过将回报函数定义为投资组合价值的变化,深度强化学习随着时间的推移使投资组合价值最大化。
  3. 股票市场提供顺序反馈DRL 可以在训练过程中依次提高模型性能。
  4. 探索-开发技术平衡尝试不同的新事物和利用已发现的东西。这与其他学习算法不同。此外,不需要技术人员提供训练样本或标记样本。此外,在探索过程中,智能体被鼓励去探索未知的人类专家。
  5. 经验回放:能够克服相关样本问题,因为从一批连续样本中学习可能会经历很大的差异,因此效率很低。体验重放通过从预先保存的重放存储器中随机采样小批量的过渡,有效地解决了这个问题。
  6. 多维数据:通过使用连续的动作空间,DRL 可以处理多维数据。
  7. 计算能力 : Q-learning 是一种非常重要的 RL 算法,然而,它无法处理大空间。DRL 作为一种高效的函数逼近器,被神经网络赋予了强大的处理超大状态空间和动作空间的能力。

图像由 凯文 上的 Unsplash

第二部分:什么是强化学习?什么是深度强化学习?利用强化学习进行股票交易的相关著作有哪些?

2.1 概念

强化学习是机器学习技术的三种方法之一,它通过从环境中顺序接收状态和奖励,并采取行动以达到更好的奖励,来训练智能体与环境进行交互。

深度强化学习用神经网络逼近 Q 值。使用神经网络作为函数逼近器将允许强化学习应用于大量数据。

贝尔曼方程是设计强化学习算法的指导原则。

马尔可夫决策过程(MDP) 用于环境建模。

2.2 相关作品

深度强化学习在金融市场中的最新应用考虑离散或连续的状态和行动空间,并采用以下学习方法之一:仅批评方法、仅行动者方法或行动者-批评方法。

1。仅批评者方法:仅批评者学习方法是最常见的,它使用 Q 学习、深度 Q 学习(DQN)及其改进来解决离散动作空间问题,并在单个股票或资产上训练代理。唯批评方法的思想是使用一个 Q 值函数来学习最优行动选择策略,该策略在给定当前状态的情况下最大化预期未来回报。 DQN 不是计算状态-动作值表,而是最小化目标 Q 值之间的均方误差,并使用神经网络来执行函数逼近。唯批评方法的主要限制是,它只适用于离散和有限的状态和行为空间,这对于大量股票投资组合是不实际的,因为价格当然是连续的。

  • Q-learning: 是一种基于值的强化学习算法,用于使用 Q 函数寻找最佳行动选择策略。
  • DQN: 在深度 Q 学习中,我们使用神经网络来逼近 Q 值函数。状态作为输入给出,允许动作的 Q 值是预测的输出。

2。只有行动者的方法:这里的思想是代理直接学习最优策略本身。神经网络学习策略,而不是让神经网络学习 Q 值。策略是一种概率分布,本质上是一种针对给定状态的策略,即采取允许的行动的可能性。只有演员的方法可以处理连续的动作空间环境。

  • 策略梯度:旨在通过直接学习最优策略本身,使期望总报酬最大化。

3。行动者-批评家方法:行动者-批评家方法最近被应用于金融领域。想法是同时更新代表政策的演员网络和代表价值函数的评论家网络。批评家估计价值函数,而行动者用政策梯度更新批评家引导的政策概率分布。随着时间的推移,演员学会了采取更好的行动,而评论家也更善于评估这些行动。演员-评论家方法已经被证明能够学习和适应大型和复杂的环境,并被用于玩流行的视频游戏,如 Doom。因此,行动者-批评家方法非常适合大规模股票投资组合的交易。

  • A2C: A2C 是典型的演员-评论家算法。A2C 使用相同代理的副本并行工作,用不同的数据样本更新梯度。每个代理独立工作,与同一个环境交互。
  • PPO: PPO 的引入是为了控制政策梯度更新,保证新政策不会与之前的政策相差太大。
  • DDPG: DDPG 结合了 Q 学习和政策梯度的框架,使用神经网络作为函数逼近器。

第三部分:如何使用 DRL 交易股票?

图像由 马库斯 上的 Unsplash

3.1 数据

我们跟踪并选择道琼斯 30 股票(2016/01/01) 并使用从 01/01/2009 到 05/08/2020 的历史日数据来训练代理人并测试其表现。数据集从通过 沃顿研究数据服务(WRDS) 访问的 Compustat 数据库下载。

整个数据集在下图中被分割。2009 年 1 月 1 日至 2014 年 12 月 31 日的数据用于培训,2015 年 10 月 1 日至 2015 年 12 月 31 日的数据用于验证和参数调整。最后,我们在从 2016 年 1 月 1 日到 2020 年 5 月 8 日的交易数据上测试我们的代理的性能。为了更好地利用交易数据,我们在交易阶段继续培训我们的代理,因为这将帮助代理更好地适应市场动态。

AI4Finance-Foundation 版权所有

3.2 股票交易的 MDP 模型:

𝒔 = [𝒑,𝒉,𝑏]:]一个向量,包括股票价格𝒑 ∈ R+^D,股票份额𝒉 ∈ Z+^D,以及余额 R+,其中表示股票数量,Z+表示非负整数。

动作𝒂:𝐷股票的动作向量。每只股票的允许操作包括出售、购买或持有,分别导致𝒉股票的减少、增加和不变。

奖励𝑟(𝑠,𝑎,𝑠′):the 直接奖励在𝑠州采取行动的𝑎到达新的州𝑠′.

政策𝜋(𝑠):)𝑠州的交易策略,这是𝑠.州行动的概率分布

Q 值 𝑄𝜋 (𝑠,𝑎):)在政策𝜋之后,在𝑠采取行动𝑎的预期回报。

我们的股票交易过程的状态转换如下图所示。在每个状态下,对投资组合中的股票𝑑 (𝑑 = 1,…,𝐷)采取三种可能的行动之一。

  • 卖出𝒌[𝑑]∈【1,𝒉[𝑑】]股票的结果是𝒉𝒕+1[𝑑]=𝒉𝒕[𝑑]—𝒌[𝑑],where𝒌[𝑑]∈z+and𝑑=1,…,𝐷.
  • 控股,𝒉𝒕+1[𝑑]=𝒉𝒕[𝑑].
  • 购买𝒌[𝑑股票的结果是𝒉𝒕+1[𝑑] = 𝒉𝒕 [𝑑] + 𝒌[𝑑].

如图 2 所示,在𝑡时间采取行动,并且在𝑡+1 更新股票价格,因此,投资组合价值可以分别从“投资组合价值 0”变为“投资组合价值 1”、“投资组合价值 2”或“投资组合价值 3”。请注意,投资组合的价值是𝒑𝑻 𝒉 + 𝑏.

AI4Finance-Foundation 版权所有

3.3 约束:

  • 市场流动性:订单能够以收盘价快速执行。我们假设股票市场不会受到我们的强化交易代理的影响。
  • 非负余额:允许的动作不应该导致负余额。
  • 交易成本:每笔交易都会产生交易成本。交易费用有很多种,如交易费、执行费和证交会费。不同的券商佣金不同。尽管费用有这些变化,我们假设我们的交易成本是每笔交易价值的 1/1000(买入或卖出)。
  • 市场崩盘风险规避:有可能导致股市崩盘的突发事件,如战争、股市泡沫破裂、主权债务违约、金融危机等。为了在像 2008 年全球金融危机这样的最坏情况下控制风险,我们采用金融 动荡指数 来衡量极端的资产价格变动。

3.4 回报最大化作为交易目标

我们将我们的回报函数定义为当𝑎在状态𝑠采取行动并到达新的状态𝑠 + 1 时,投资组合价值的变化

目标是设计一个在动态环境中最大化投资组合价值𝑟(𝑠𝑡,𝑎𝑡,𝑠𝑡+1 变化的交易策略,我们采用深度强化学习方法来解决这个问题。

图片由萨克Unsplash 上拍摄

3.5 多只股票的环境:

状态空间:我们用一个 181 维向量(30 只股票 6 + 1)组成的七部分信息来表示多只股票交易环境的状态空间*

  1. 余额:当前时间步账户中剩余的可用金额
  2. 价格:每只股票当前调整后的收盘价。
  3. 股份:每只股票拥有的股份。
  4. MACD :使用收盘价计算移动平均趋同背离(MACD)。
  5. RSI :相对强弱指数(RSI)是用收盘价计算出来的。
  6. CCI :商品通道指数(CCI)是用最高价、最低价和收盘价计算出来的。
  7. ADX :使用最高价、最低价和收盘价计算平均方向指数(ADX)。

动作空间:

  1. 对于单只股票,动作空间定义为 {-k,…,-1,0,1,…,k} ,其中 k 和-k 表示我们可以买卖的股票数量, k ≤h_maxh_max 是一个预定义的参数,设置为每次买入动作的最大股票数量。
  2. 对于多只股票,因此整个行动空间的大小是 (2k+1)^30 )。
  3. 然后,动作空间被归一化为 [-1,1] ,因为 RL 算法 A2C 和 PPO 直接在高斯分布上定义策略,该高斯分布需要被归一化和对称。
**class StockEnvTrain**(gym.Env):**“””A stock trading environment for OpenAI gym”””
** metadata = {‘render.modes’: [‘human’]}def __init__(self, df, day = 0):
 self.day = day
 self.df = df # Action Space
 # action_space normalization and shape is STOCK_DIM
 **self.action_space = spaces.Box(low = -1, high = 1,shape = (STOCK_DIM,))** 
 # State Space
 # Shape = 181: [Current Balance]+[prices 1–30]+[owned shares 1–30] 
 # +[macd 1–30]+ [rsi 1–30] + [cci 1–30] + [adx 1–30]
 **self.observation_space = spaces.Box(low=0, high=np.inf, shape = (181,))** # load data from a pandas dataframe
 self.data = self.df.loc[self.day,:]
 self.terminal = False # initalize state
 **self.state = [INITIAL_ACCOUNT_BALANCE] + \
 self.data.adjcp.values.tolist() + \
 [0]*STOCK_DIM + \
 self.data.macd.values.tolist() + \
 self.data.rsi.values.tolist() + \
 self.data.cci.values.tolist() + \
 self.data.adx.values.tolist()** # initialize reward
 self.reward = 0
 self.cost = 0 # memorize all the total balance change
 self.asset_memory = [INITIAL_ACCOUNT_BALANCE]
 self.rewards_memory = []
 self.trades = 0
 #self.reset()
 self._seed()

3.6 基于深度强化学习的交易代理

A2C

AI4Finance-Foundation 版权所有

A2C 是一个典型的演员-评论家算法,我们将其作为集成方法中的一个组件。A2C 出台梯度更新完善政策。A2C 利用一个优势函数来减少政策梯度的方差。评论家网络不是仅估计价值函数,而是估计优势函数。因此,对一个行动的评价不仅要看这个行动有多好,还要考虑它还能好到什么程度。从而降低了策略网络的高方差,使模型更加健壮。

A2C 使用同一代理的个副本并行工作,用不同的数据样本更新梯度。每个代理独立工作,与同一个环境交互。在所有并行代理完成计算它们的梯度后,A2C 使用协调器将所有代理的平均梯度传递给全局网络。以便全球网络可以更新演员和评论家网络。全球网络的存在增加了培训数据的多样性。同步梯度更新更具成本效益,速度更快,在批量较大时效果更好。A2C 是股票交易的好榜样,因为它稳定。

DDPG

AI4Finance-Foundation 版权所有

DDPG 是一种基于演员-评论家的算法,我们将其作为整体策略的一部分,以最大化投资回报。DDPG 结合了 Q 学习和策略梯度 t 的框架,并使用神经网络作为函数逼近器。与通过 Q 值表间接学习并遭受维数灾难问题的 DQN 相反,DDPG 通过政策梯度直接从观察中学习。建议确定性地将状态映射到动作,以更好地适应连续动作空间环境。

PPO

我们探索并使用多酚氧化酶作为系综方法的一个组成部分。引入 PPO 是为了控制策略梯度更新,并确保新策略不会与旧策略相差太大。PPO 试图通过在目标函数中引入限幅项来简化信任区域策略优化(TRPO) 的目标。

PPO 的目标函数取限幅和正常目标的最小值。PPO 不鼓励超出限定区间的大的政策变动。因此,PPO 通过在每个训练步骤限制策略更新来提高策略网络训练的稳定性。我们选择 PPO 进行股票交易,因为它稳定、快速,并且更容易实现和调整。

集成策略

我们的目的是创建一个高度稳健的交易策略。所以我们使用一种集合方法根据夏普比率PPOA2CDDPG 中自动选择表现最好的代理进行交易。总体过程描述如下:

步骤一。我们利用𝑛t32】个月的成长窗口来同时再培训我们的三名代理。在本文中,我们每隔三个月对我们的三名代理进行再培训。

步骤二。我们通过使用 3 个月验证滚动窗口来验证所有三个代理,然后进行培训以挑选具有最高夏普比率的最佳代理。在我们的验证阶段,我们还通过使用湍流指数来调整风险厌恶。

第三步。验证后,我们只使用夏普比率最高的最佳模型来预测和交易下一季度。

**from** stable_baselines **import** SAC
**from** stable_baselines **import** PPO2
**from** stable_baselines **import** A2C
**from** stable_baselines **import** DDPG
**from** stable_baselines **import** TD3
**from** stable_baselines.ddpg.policies **import** DDPGPolicy
**from** stable_baselines.common.policies **import** MlpPolicy
**from** stable_baselines.common.vec_env **import** DummyVecEnv**def** **train_A2C**(env_train, model_name, timesteps=10000):
 **“””A2C model”””** start = time.time()
 model = A2C(‘MlpPolicy’, env_train, verbose=0)
 model.learn(total_timesteps=timesteps)
 end = time.time() model.save(f”{config.TRAINED_MODEL_DIR}/{model_name}”)
 print(‘Training time (A2C): ‘, (end-start)/60,’ minutes’)
 return model**def** **train_DDPG**(env_train, model_name, timesteps=10000):
 **“””DDPG model”””** start = time.time()
 model = DDPG(‘MlpPolicy’, env_train)
 model.learn(total_timesteps=timesteps)
 end = time.time() model.save(f”{config.TRAINED_MODEL_DIR}/{model_name}”)
 print(‘Training time (DDPG): ‘, (end-start)/60,’ minutes’)
 return model**def** **train_PPO**(env_train, model_name, timesteps=50000):
 **“””PPO model”””** start = time.time()
 model = PPO2(‘MlpPolicy’, env_train)
 model.learn(total_timesteps=timesteps)
 end = time.time() model.save(f”{config.TRAINED_MODEL_DIR}/{model_name}”)
 print(‘Training time (PPO): ‘, (end-start)/60,’ minutes’)
 return model**def** **DRL_prediction**(model, test_data, test_env, test_obs):
 **“””make a prediction”””** start = time.time()
 **for** i in range(len(test_data.index.unique())):
   action, _states = model.predict(test_obs)
   test_obs, rewards, dones, info = test_env.step(action)
   # env_test.render()
 end = time.time()

3.7 绩效评估

我们使用 Quantopian 的投资组合进行回溯测试。这些图表看起来非常好,并且只需要一行代码就可以实现。你只需要把一切都转换成日收益。

**import** pyfolio**with** **pyfolio**.plotting.plotting_context(font_scale=1.1):
 pyfolio.create_full_tear_sheet(**returns** = **ensemble_strat**,
 **benchmark_rets**=**dow_strat**, set_context=False)

AI4Finance-Foundation 版权所有

AI4Finance-Foundation 版权所有

AI4Finance-Foundation 版权所有

参考文献:

A2C :
沃洛季米尔·姆尼、adrià·巴迪亚、迈赫迪·米尔扎、亚历克斯·格雷夫斯、蒂莫西·利利克拉普、蒂姆·哈利、大卫·西尔弗和科雷·卡武克库奥卢。2016.深度强化学习的异步方法。第 33 届机器学习国际会议(02 2016)。https://arxiv.org/abs/1602.01783

DDPG :
蒂莫西·莉莉卡普、乔纳森·亨特、亚历山大·普里策尔、尼古拉斯·赫斯、汤姆·埃雷兹、尤瓦尔·塔萨、大卫·西尔弗和金奎大·威斯特拉。2015.深度强化学习的连续控制。2016 年国际学习代表大会(ICLR)(2015 年 9 月)。https://arxiv.org/abs/1509.02971

约翰·舒尔曼、谢尔盖·莱文、菲利普·莫里茨、迈克尔·乔丹和彼得·阿贝耳。2015.信任区域策略优化。在第 31 届机器学习国际会议上。https://arxiv.org/abs/1502.05477

约翰·舒尔曼、菲利普·沃尔斯基、普拉富拉·德里瓦尔、亚历克·拉德福德和奥列格·克里莫夫。2017.近似策略优化算法。arXiv:1707.06347(2017 年 07 月)。https://arxiv.org/abs/1707.06347

如何通过深度强化学习改善您的供应链

原文:https://towardsdatascience.com/deep-reinforcement-learning-for-supply-chain-optimization-3e4d99ad4b58?source=collection_archive---------13-----------------------

利用雷和 DFO 优化多级供应链

是什么让亚马逊在网上零售的竞争中脱颖而出?他们的供应链。事实上,这一直是他们的主要竞争对手之一沃尔玛的最大优势之一。

供应链是高度复杂的系统,由全球数百家甚至数千家制造商和物流承运商组成,他们整合资源,创造出我们每天使用和消费的产品。要跟踪所有的投入到一个单一的、简单的产品将是惊人的。然而,纵向一体化公司内部的供应链组织的任务是管理从原材料到制造、仓储和向客户分销的投入。在这方面做得最好的公司减少了过量储存造成的浪费,减少了不必要的运输成本,减少了将产品和材料运送到系统后期的时间。优化这些系统是像苹果和 Saudi Aramco 这样不同的企业的关键组成部分。

照片由 Shawn AngUnsplash 上拍摄

已经投入了大量的时间和精力来构建有效的供应链优化模型,但是由于它们的规模和复杂性,它们可能难以构建和管理。随着机器学习的进步,特别是强化学习,我们可以训练一个机器学习模型来为我们做出这些决定,在许多情况下,比传统方法做得更好!

TL;速度三角形定位法(dead reckoning)

我们使用射线[or-gym](https://arxiv.org/abs/2008.06319)来训练深度强化学习模型,以优化多级库存管理模型,并使用鲍威尔的方法根据无导数优化模型对其进行基准测试

多级供应链

在我们的例子中,我们将使用一个有提前期的多级供应链模型。这意味着我们需要为供应链的不同阶段做出决策,我们在不同层面做出的每个决策都会影响下游的决策。在我们的案例中,我们有从原材料生产商到客户的几个阶段。过程中的每个阶段都有不同的提前期,即一个阶段的输出到达并成为链中下一个阶段的输入所需的时间。这可能是 5 天,10 天,无论如何。这些交付周期变得越长,您就需要越早预测客户订单和需求,以确保您不会缺货或失去销售!

多级供应链示意图(图片由作者提供,来自 Hubbs 等人

使用 OR-Gym 进行库存管理

OR-Gym 库有几个多级供应链模型可以用来模拟这种结构。为此,我们将使用InvManagement-v1环境,它具有如上所示的结构,但是如果您没有足够的库存来满足客户需求,就会导致销售损失。

如果您还没有,请继续安装该软件包:

pip install or-gym

安装完成后,我们可以使用以下工具设置我们的环境:

env = or_gym.make('InvManagement-v1')

默认情况下,这是一个四级供应链。这些行动决定了在每个时间步从上面的层级订购多少材料。订单数量受限于供应商的能力及其当前库存。因此,如果你从一个供应商那里订购 150 个部件,而该供应商的发货能力是 100 个部件,而你手头只有 90 个部件,那么你只能收到 90 个部件。

每个层级都有自己的成本结构、定价和交付周期。最后一个梯队(在这种情况下是阶段 3)提供原材料,我们在这个阶段没有任何库存限制,假设矿山、油井、森林或任何生产原材料的东西足够大,这不是我们需要关心的限制。

Invmanagement-v 1 环境的默认参数值。

与所有的or-gym环境一样,如果这些设置不适合您,只需将一个环境配置字典传递给make函数来相应地定制您的供应链(这里给出了一个例子)。

和雷一起训练

为了训练你的环境,我们将利用射线库来加速我们的训练,所以继续导入你的包。

import or_gym
from or_gym.utils import create_env
import ray
from ray.rllib import agents
from ray import tune

首先,我们需要一个简单的注册函数来确保 Ray 知道我们想要运行的环境。我们可以用下面显示的register_env函数注册它。

def register_env(env_name, env_config={}):
    env = create_env(env_name)
    tune.register_env(env_name, 
        lambda env_name: env(env_name,
            env_config=env_config))

从这里,我们可以设置我们的 RL 配置和训练模型所需的一切。

# Environment and RL Configuration Settings
env_name = 'InvManagement-v1'
env_config = {} # Change environment parameters here
rl_config = dict(
    env=env_name,
    num_workers=2,
    env_config=env_config,
    model=dict(
        vf_share_layers=False,
        fcnet_activation='elu',
        fcnet_hiddens=[256, 256]
    ),
    lr=1e-5
)# Register environment
register_env(env_name, env_config)

rl_config字典中,您可以设置所有相关的超参数,或者将您的系统设置为在 GPU 上运行。这里,我们将使用 2 个工作线程进行并行化,并训练一个具有 ELU 激活功能的双层网络。此外,如果您打算使用[tune](https://www.datahubbs.com/hyperparameter-tuning-with-tune/) 进行超参数调优,那么您可以使用tune.gridsearch()之类的工具来系统地更新学习率、改变网络或任何您喜欢的东西。

一旦你满意了,就去选择你的算法并开始训练吧!下面,我只使用 PPO 算法,因为我发现它在大多数环境下训练得很好。

# Initialize Ray and Build Agent
ray.init(ignore_reinit_error=True)
agent = agents.ppo.PPOTrainer(env=env_name,
    config=rl_config)results = []
for i in range(500):
    res = agent.train()
    results.append(res)
    if (i+1) % 5 == 0:
        print('\rIter: {}\tReward: {:.2f}'.format(
                i+1, res['episode_reward_mean']), end='')
ray.shutdown()

上面的代码将初始化ray,然后根据您之前指定的配置构建代理。如果你对此感到满意,那么让它运行一段时间,看看效果如何!

在这种环境下需要注意的一点是:如果学习率太高,政策函数将开始发散,损失将变得巨大。此时,您将得到一个错误,通常来自 Ray 的默认预处理器,状态显示奇怪的值,因为网络给出的动作都是nan。这很容易通过降低学习速度并再次尝试来解决。

让我们来看看表演。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec# Unpack values from each iteration
rewards = np.hstack([i['hist_stats']['episode_reward'] 
    for i in results])
pol_loss = [
    i['info']['learner']['default_policy']['policy_loss'] 
    for i in results]
vf_loss = [
    i['info']['learner']['default_policy']['vf_loss'] 
    for i in results]p = 100
mean_rewards = np.array([np.mean(rewards[i-p:i+1]) 
                if i >= p else np.mean(rewards[:i+1]) 
                for i, _ in enumerate(rewards)])
std_rewards = np.array([np.std(rewards[i-p:i+1])
               if i >= p else np.std(rewards[:i+1])
               for i, _ in enumerate(rewards)])fig = plt.figure(constrained_layout=True, figsize=(20, 10))
gs = fig.add_gridspec(2, 4)
ax0 = fig.add_subplot(gs[:, :-2])
ax0.fill_between(np.arange(len(mean_rewards)), 
                 mean_rewards - std_rewards, 
                 mean_rewards + std_rewards, 
                 label='Standard Deviation', alpha=0.3)
ax0.plot(mean_rewards, label='Mean Rewards')
ax0.set_ylabel('Rewards')
ax0.set_xlabel('Episode')
ax0.set_title('Training Rewards')
ax0.legend()ax1 = fig.add_subplot(gs[0, 2:])
ax1.plot(pol_loss)
ax1.set_ylabel('Loss')
ax1.set_xlabel('Iteration')
ax1.set_title('Policy Loss')ax2 = fig.add_subplot(gs[1, 2:])
ax2.plot(vf_loss)
ax2.set_ylabel('Loss')
ax2.set_xlabel('Iteration')
ax2.set_title('Value Function Loss')plt.show()

图片作者。

看起来我们的代理学会了一个体面的政策!

这些经典运筹学问题的深度强化学习的困难之一是缺乏最优性保证。换句话说,我们可以看看上面的训练曲线,看到它正在学习越来越好的政策——它似乎正在向一个政策靠拢——但我们不知道这个政策有多好。我们能做得更好吗?我们应该在超参数调优上投入更多的时间(和金钱)吗?要回答这个问题,我们需要转向一些不同的方法,并开发一个基准。

无导数优化

测试 RL 模型的一个好方法是使用无导数优化 (DFO)。像 RL 一样,DFO 将系统视为一个黑盒模型,提供输入并获得一些反馈,作为回报,在寻求最优值时再次尝试。

与 RL 不同,DFO 没有国家的概念。这意味着我们将试图找到一个固定的再订购政策,使库存达到一定水平,以平衡持有成本和销售利润。例如,如果阶段 0 的策略是重新订购多达 10 个小部件,而目前我们有 4 个小部件,则策略声明我们将重新订购 6 个。在 RL 的情况下,它将考虑当前的管道和我们提供给状态的所有其他信息。因此 RL 更具适应性,并且应该优于直接的 DFO 实现。如果没有,那么我们知道我们需要重新开始。

虽然这听起来可能过于简单,但这种固定的再订购策略在工业应用中并不罕见,部分原因是真实的供应链由比我们在这里建模更多的变量和相关决策组成。因此,一个固定的政策是易处理的,供应链专业人员可以很容易地处理。

实施 DFO

对于 DFO,有很多不同的算法和求解器。出于我们的目的,我们将利用 Scipy 的optimize库来实现 Powell 的方法。我们不会在这里进入细节,但这是一种快速找到函数最小值的方法,并可用于离散优化-就像我们在这里。

from scipy.optimize import minimize

因为我们将使用固定的再订购策略,所以我们需要一个快速的功能来将库存水平转化为要评估的行动。

def base_stock_policy(policy, env):
    '''
    Implements a re-order up-to policy. This means that for
    each node in the network, if the inventory at that node 
    falls below the level denoted by the policy, we will 
    re-order inventory to bring it to the policy level.

    For example, policy at a node is 10, current inventory
    is 5: the action is to order 5 units.
    '''
    assert len(policy) == len(env.init_inv), (
        'Policy should match number of nodes in network' + 
        '({}, {}).'.format(
            len(policy), len(env.init_inv)))

    # Get echelon inventory levels
    if env.period == 0:
        inv_ech = np.cumsum(env.I[env.period] +
            env.T[env.period])
    else:
        inv_ech = np.cumsum(env.I[env.period] +
            env.T[env.period] - env.B[env.period-1, :-1])

    # Get unconstrained actions
    unc_actions = policy - inv_ech
    unc_actions = np.where(unc_actions>0, unc_actions, 0)

    # Ensure that actions can be fulfilled by checking 
    # constraints
    inv_const = np.hstack([env.I[env.period, 1:], np.Inf])
    actions = np.minimum(env.c,
                np.minimum(unc_actions, inv_const))
    return actions

base_stock_policy函数获取我们提供的策略级别,并如上所述计算该级别和库存之间的差异。需要注意的一点是,当我们计算库存水平时,我们也包括所有在运输途中的库存(在env.T中给出)。例如,如果阶段 0 的当前现有库存为 100,并且阶段 0 和阶段 1 之间有 5 天的提前期,那么我们也会考虑过去 5 天的所有订单。因此,如果阶段 0 每天订购 10 件,那么该层级的库存将为 150 件。这使得策略级别大于容量变得有意义,因为我们不仅要查看我们今天仓库中的库存,还要查看所有正在运输的物品。

我们的 DFO 方法需要进行函数评估调用,以查看所选变量的执行情况。在我们的例子中,我们有一个要评估的环境,所以我们需要一个函数来运行我们环境中的一集并返回适当的结果。

def dfo_func(policy, env, *args):
    '''
    Runs an episode based on current base-stock model 
    settings. This allows us to use our environment for the 
    DFO optimizer.
    '''
    env.reset() # Ensure env is fresh
    rewards = []
    done = False
    while not done:
        action = base_stock_policy(policy, env)
        state, reward, done, _ = env.step(action)
        rewards.append(reward)
        if done:
            break

    rewards = np.array(rewards)
    prob = env.demand_dist.pmf(env.D, **env.dist_param)

    # Return negative of expected profit
    return -1 / env.num_periods * np.sum(prob * rewards)

我们不是返回奖励的总和,而是返回对奖励的负面期望。消极的原因是我们使用的 Scipy 函数寻求最小化,而我们的环境是为了最大化回报而设计的,所以我们反转这个函数以确保一切都指向正确的方向。我们通过乘以基于分布的需求概率来计算预期回报。我们可以获取更多样本来估计分布,并以这种方式计算我们的期望(对于许多现实世界的应用来说,这是必需的),但在这里,我们可以访问真实的分布,因此我们可以使用它来减少我们的计算负担。

最后,我们准备优化。

下面这个函数会根据你的配置设置搭建一个环境,拿我们的dfo_func来评估,应用鲍威尔的方法来解决问题。它将返回我们的策略,并确保我们的答案只包含正整数(例如,我们不能订购半个部件或负数部件)。

def optimize_inventory_policy(env_name, fun,
    init_policy=None, env_config={}, method='Powell'):

    env = or_gym.make(env_name, env_config=env_config)

    if init_policy is None:
        init_policy = np.ones(env.num_stages-1)

    # Optimize policy
    out = minimize(fun=fun, x0=init_policy, args=env, 
        method=method)
    policy = out.x.copy()

    # Policy must be positive integer
    policy = np.round(np.maximum(policy, 0), 0).astype(int)

    return policy, out

现在是时候把它们放在一起了。

policy, out = optimize_inventory_policy('InvManagement-v1',
    dfo_func)
print("Re-order levels: {}".format(policy))
print("DFO Info:\n{}".format(out))Re-order levels: [540 216  81]
DFO Info:
   direc: array([[  0\.        ,   0\.        ,   1\.        ],
       [  0\.        ,   1\.        ,   0\.        ],
       [206.39353826,  81.74560612,  28.78995703]])
     fun: -0.9450780368543933
 message: 'Optimization terminated successfully.'
    nfev: 212
     nit: 5
  status: 0
 success: True
       x: array([539.7995151 , 216.38046861,  80.66902905])

我们的 DFO 模型发现了一个固定库存策略,第 0 阶段的再订购水平为 540,第 1 阶段为 216,第 2 阶段为 81。它只用了 212 次功能评估就做到了这一点,即它模拟了 212 集来寻找最佳值。

我们可以运行该策略,然后将其输入到我们的环境中,比如说 1000 次,以生成一些统计数据,并将其与我们的 RL 解决方案进行比较。

env = or_gym.make(env_name, env_config=env_config)
eps = 1000
rewards = []
for i in range(eps):
    env.reset()
    reward = 0
    while True:
        action = base_stock_policy(policy, eenv)
        s, r, done, _ = env.step(action)
        reward += r
        if done:
            rewards.append(reward)
            break

比较性能

在我们开始报酬比较之前,请注意这些并不是完美的,1:1 的比较。如前所述,DFO 为我们提供了一个固定的策略,而 RL 提供了一个更加灵活、动态的策略,可以根据状态信息进行更改。我们的 DFO 方法也提供了一些需求概率方面的信息来计算期望,RL 必须从额外的抽样中进行推断。因此,虽然 RL 从近 65k 的剧集中学习,而 DFO 只需要进行 212 次函数调用,但他们并不完全可比。考虑到枚举每一个有意义的固定政策一次将需要大约 2 亿集,那么 RL 看起来并不那么低效。

那么,这些是如何叠加的呢?

图片作者。

从上面我们可以看到,RL 确实比我们的 DFO 策略平均高出 11%(460 比 414)。RL 模型在大约 15k 集后超过了 DFO 策略,并在此后稳步改进。然而,RL 政策有一些更高的差异,其中有一些可怕的插曲。总的来说,我们确实从 RL 方法中得到了更好的结果。

在这种情况下,这两种方法都很难实现,计算量也不大。我忘记将我的rl_config设置改为在我的 GPU 上运行,在我的笔记本电脑上训练仍然只需要大约 25 分钟,而 DFO 模型需要大约 2 秒钟。更复杂的模型可能在这两种情况下都不那么友好。

另一点需要注意的是,这两种方法对初始条件都非常敏感,而且都不能保证在每种情况下都能找到最优策略。如果你有一个想应用 RL 的问题,也许可以先使用一个简单的 DFO 解算器,尝试一些初始条件来了解问题,然后旋转完整的 RL 模型。你会发现 DFO 政策足以完成你的任务。

希望这很好地概述了如何使用这些方法和or-gym库。如果您有任何反馈或问题,请留下!

轻松实现视频游戏的深度强化学习

原文:https://towardsdatascience.com/deep-reinforcement-learning-for-video-games-made-easy-6f7d06b75a65?source=collection_archive---------35-----------------------

深度 Q 网络已经彻底改变了深度强化学习领域,但是简单实验的技术先决条件直到现在还禁止新人进入…

使用 DQN 代理的雅达利乒乓

在本帖中,我们将调查如何使用谷歌强化学习库多巴胺为雅达利 2600 游戏训练一个深度 Q 网络(DQN)代理 (Mnih 等人,2015)。虽然有许多 RL 函数库,但这个函数库是根据的四个基本特性特别设计的:

  • 简单的实验
  • 柔性开发
  • 紧凑可靠
  • 可再生的

我们相信这些原则使得多巴胺成为当今最好的学习环境之一。此外,我们甚至让这个库在 Windows 上工作,我们认为这是一个了不起的成就!

在我看来,在强化学习中,任何受过训练的 RL 代理的可视化都是绝对必要的!因此,我们将(当然)在最后为我们自己的训练有素的代理人包括这一点!

我们将检查所有需要的代码片段(与其他库相比是最少的),但是你也可以在下面的 Github repo 中找到所有需要的脚本。

1.强化学习和深度 Q 学习简介

深度强化学习的一般前提是

“从高维度的感官输入中获得环境的有效表示,并使用这些来将过去的经验推广到新的情况。”

  • Mnih 等人(2015 年)

如前所述,我们将由 Deepmind 实现 DQN 模型,它只使用原始像素和游戏分数作为输入。使用类似于图像分类的卷积神经网络来处理原始像素。主要区别在于目标函数,对于 DQN 代理来说,它被称为最优行动值函数

其中 rₜ 是在时间 tγ 折现的最大奖励总和,使用行为策略 π = P(as) 为每个观察-动作对获得。

深度 Q-Learning 的细节相对较多,如的经验重演和的迭代更新规则。因此,我们建议读者参考原始论文,以便更好地了解数学细节。

与当时(2015 年)之前的方法相比,DQN 的一个关键优势是能够使用相同的超参数集仅像素值和游戏分数作为输入,超越 Atari 2600 游戏的现有方法,这显然是一个巨大的成就。

2.装置

这篇文章不包括安装 Tensorflow 的说明,但我们想强调的是,你可以同时使用CPU 和 GPU 版本

然而,假设您使用的是Python 3.7.x,这些是您需要安装的库(它们都可以通过pip安装):

tensorflow-gpu=1.15   (or tensorflow==1.15  for CPU version)
cmake
dopamine-rl
atari-py
matplotlib
pygame
seaborn
pandas

3.训练我们的特工

深度强化学习的超参数调整需要大量的计算资源,因此被认为超出了本指南的范围。幸运的是,多巴胺的作者已经提供了 Bellemare 等人(2017)使用的具体超参数,可以在下面的文件中找到。我们使用这个“配置文件”的内容作为一个字符串,我们使用 gin 配置框架解析它。它包含所有相关的训练、环境和所需的超参数,这意味着我们只需要更新我们想要运行的游戏(尽管超参数可能不会对所有游戏都同样有效)。

我们从导入所需的库开始

import os
import gin.tf
from dopamine.discrete_domains import run_experiment

接下来,我们定义根路径来保存我们的实验

DQN_PATH **=** '/tmp/path/to/save/experiments/dqn'

然后,我们定义想要运行的游戏(在本例中,我们运行游戏“Pong”),

GAME **=** 'Pong'

最后,我们定义 DQN 配置字符串:

dqn_config **=** """
# Hyperparameters used for reporting DQN results in Bellemare et al. (2017).
import dopamine.discrete_domains.atari_lib
import dopamine.discrete_domains.run_experiment
import dopamine.agents.dqn.dqn_agent
import dopamine.replay_memory.circular_replay_buffer
import gin.tf.external_configurables

DQNAgent.gamma = 0.99
DQNAgent.update_horizon = 1
DQNAgent.min_replay_history = 50000  # agent steps
DQNAgent.update_period = 4
DQNAgent.target_update_period = 10000  # agent steps
DQNAgent.epsilon_train = 0.01
DQNAgent.epsilon_eval = 0.001
DQNAgent.epsilon_decay_period = 1000000  # agent steps
DQNAgent.tf_device = '/gpu:0'  # use '/cpu:*' for non-GPU version
DQNAgent.optimizer = @tf.train.RMSPropOptimizer()

tf.train.RMSPropOptimizer.learning_rate = 0.00025
tf.train.RMSPropOptimizer.decay = 0.95
tf.train.RMSPropOptimizer.momentum = 0.0
tf.train.RMSPropOptimizer.epsilon = 0.00001
tf.train.RMSPropOptimizer.centered = True

atari_lib.create_atari_environment.game_name = "{}"
# Deterministic ALE version used in the DQN Nature paper (Mnih et al., 2015).
atari_lib.create_atari_environment.sticky_actions = False
create_agent.agent_name = 'dqn'
Runner.num_iterations = 200 # 200
Runner.training_steps = 250000 #   250000  # agent steps
Runner.evaluation_steps = 125000 # 125000  # agent steps
Runner.max_steps_per_episode = 27000 # 27000  # agent steps

AtariPreprocessing.terminal_on_life_loss = True

WrappedReplayBuffer.replay_capacity = 1000000
WrappedReplayBuffer.batch_size = 32
""".format(GAME)

基本上就是这样了!

现在,我们只需编写训练代理的最终代码,

运行上面的(需要很长时间!),你应该看到 DQN 模型粉碎乒乓游戏!

4.想象我们的特工

我们在 GTX 1070 GPU 上运行了大约 22 小时的实验。

我们包含了优化结果的可视化和 Pong 代理的【live】性能。我们将此分为两段:

a)培训结果

导航到 tensorboard logs 文件夹,该文件夹可以在您之前定义的DQN_PATH中找到,然后运行以下命令:

tensorboard --logdir .

这应该会给你一个类似这样的视觉效果

您可以看到,运行 12 次后,性能才逐渐提高。

b)现场演示

现在是有趣的部分!

我们将使用位于多巴胺库的utils文件夹中的example_vis_lib脚本。因此,我们运行实时演示的脚本如下所示:

运行上面的代码,您应该看到脚本开始为 1000 步生成图像,然后将图像保存到 video.mp4 文件中。

这是我们模型的 gif 图:

雅达利突破使用 DQN 代理培训 22 小时

很明显,经纪人并不完美,也确实输了不少比赛。尽管如此,它做了一个相对不错的工作!

如果我们多训练几天(或者使用更大的 GPU),我们可能会得到一个接近完美的代理。

5.结论

就这样吧!

这基本上就是我们实际上需要多么少的代码来实现一个最先进的 DQN 模型来运行 Atari 2600 游戏并进行现场演示!

随意试验明显更好的彩虹模型 ( Hessel et al .,2018 ),这是也包括在多巴胺库,以及其他非雅达利的游戏!

作为最终演示,我们提供了一个小的 gif 图片,展示了一名代理人使用彩虹模型接受了为期两天的雅达利突破培训:

雅达利突破与彩虹模型训练了两天

你可以看到彩虹模型表现得非常好!

如果你喜欢这篇文章,请不要犹豫留下你的任何意见或建议!

6.参考

[1]林隆基,用神经网络进行机器人的强化学习(1993),CS-93-103 号。

[2] M. Hessel 等,Rainbow:结合深度强化学习的改进(2018),第三十二届 AAAI 人工智能会议。

[3] P. S. Castro,S. Moitra,C. Gelada,S. Kumar,M. G. Bellemare,多巴胺:深度强化学习的研究框架 (2018),arXiv 预印本 arXiv:1812.06110。

[4] V. Mnih 等人,(2015),通过深度强化学习实现人类水平的控制,Nature 518.7540(529–533)。

原载于 2020 年 7 月 22 日https://holmdk . github . io

生产中的深度强化学习

原文:https://towardsdatascience.com/deep-reinforcement-learning-in-production-7e1e63471e2?source=collection_archive---------28-----------------------

Zynga 使用强化学习来个性化用户体验

弗兰基·查马基在 Unsplash 上拍摄的照片

由来自 Zynga ML 工程团队的迈赫迪·本·阿耶德帕特里克·哈利娜

系列介绍

设计用户体验是一门困难的艺术。与其他应用程序相比,视频游戏为设计师提供了一个巨大的工作空间。在 Zynga,我们一直在想创新的方法来最大化用户在玩游戏时的体验。

在这个多部分的系列中,Zynga 的 ML 工程团队将讨论如何在制作中使用深度强化学习(RL)来个性化 Zynga 游戏的许多方面。深度强化学习的使用已被证明在增加关键指标方面是成功的,如用户保留率和用户参与度。这些文章是我们在 2019 年多伦多机器学习峰会和 2020 年 Spark 峰会上的演讲的延伸。

2019 年多伦多机器学习峰会

在第一篇文章中,我们将:

  • 介绍深度强化学习
  • 解释为什么它是驱动个性化系统的良好候选
  • 对其在 Zynga 的使用做一个高层次的概述

本系列的其余部分将涵盖以下内容:

关于 Zynga

Zynga 是全球领先的手机游戏开发商之一。它的投资组合有一些世界上最受欢迎的手机游戏,如与朋友的话,帝国和谜题,香椿爆炸,CSR2,扑克,等等。Zynga 的使命是通过游戏将世界各地的人们联系起来。

个性化用户体验的需求

为广泛的用户构建成功的应用程序是具有挑战性的。日常挑战应该有多难?应该推荐什么游戏模式?每个用户都是不同的,这使得很难构建一个适合每个人需求的应用程序。这种差异可能是由于玩家的人口统计,位置,甚至他们的游戏风格。因此,构建个性化的用户体验有可能提高用户参与度和忠诚度。

虽然在用户会话期间有许多旋钮和杠杆可以控制,但个性化可以归结为一个共同的模式:给定用户的状态,选择一个动作以最大化长期回报。

这些是 Zynga 个性化问题中典型的状态、行为和奖励的例子:

  • State :用户的背景,由一组特征组成,例如,他们玩游戏多长时间了,他们在什么级别,在过去几个级别的表现历史,等等。
  • 动作:应用程序被控制的方面。可能是下一关的难度,发送消息的时间,推荐的游戏模式等等。
  • 奖励:这是我们希望个性化改进的关键绩效指标(KPI)。对于 Zynga 来说,其中一些指标是参与度指标,如玩家玩的关卡数量和会话长度。

分段个性化

Zynga 在使用个性化来增强游戏体验方面有着悠久的历史。一种已经被成功使用的简单方法是基于规则的优化。这种方法根据玩家的属性将玩家分成不同的部分(或组),并为每个部分提供定制体验。

细分对于广泛的群体很有效,但是对于细粒度的个性化就不那么有效了。该过程也是非常手动的,并且需要人在回路中进行任何调整。这导致了一些问题:

  1. 将用户群细分需要人类的直觉和反复试验。
  2. 需要进行 A/B 测试,以发现应该将哪种经验分配给每个细分市场,从而提升 KPI。
  3. 规则中可以使用的属性数量是有限的(一个人只能制定这么多规则)。这将细分限制为非常粗粒度的个性化。
  4. 随着应用程序功能的变化和受众变得更加成熟,微调的细分策略会变得陈旧,这就需要不断的手动调整和维护。

深度加固解决方案

近年来深度学习的兴起及其与强化学习的结合为个性化提供了新的解决方案。

深度学习是一种机器学习,利用人工神经网络来学习数据中的复杂关系。给定一大组数据和预期输出,训练神经网络来学习将输入数据转换为预期输出的模式。

除了使用激活函数之外,这些网络的分层架构允许这些模型学习数据中较低和较高层次的概念,这是使用经典机器学习模型所不可能的。

近年来,深度学习经历了大量的突破,导致了图像和语音识别以及深度强化学习等领域的大量成功。

安娜斯塔西娅·杜尔吉尔在 Unsplash 上的照片

另一方面,强化学习是一种经典的机器学习技术。它专注于训练代理人做出一系列决策,使长期总回报最大化。长期方面是关键;代理不会选择短期优化的操作。代理人可能会在短期内遭受损失,以便在稍后的时间点获得更大的收益。

强化学习代理在一个循环中与环境交互,并通过试错进行学习。在每个周期,它:

  1. 从环境(例如,用户上下文)接收观察
  2. 根据观察结果选择行动
  3. 接收对所选行动的反馈,作为奖励和新的观察

图片来自 Pixabayuleem odhitPexelscottonbro

深度强化学习是两种技术的结合。使用深度神经网络作为函数逼近允许代理解决使用经典强化学习不可能解决的问题。它允许代理:

  • 使用大的状态空间来表示环境的观察值
  • 改进未来奖励近似值
  • 使用隐藏层学习和概括复杂的问题
  • 适当地处理新的观察,即使他们以前没有经历过

使用深度强化学习训练的代理不仅可以学习解决复杂问题的最佳策略,还可以适应环境的变化。

结论

深度学习和深度强化学习释放了解决以前不可能解决的问题的力量,例如复杂环境中的规划和高维空间中的学习模式。在 Zynga,我们相信深度强化学习的使用将继续使我们能够为每个用户个性化我们的游戏,无论他们的技能水平、位置或人口统计。

下一步是什么?

在接下来的文章中,我们将与您分享有关深度强化学习代理的不同用例的更多信息,以便个性化我们的用户体验。我们还将提供对我们的机器学习基础设施和深度强化学习框架的见解,我们建立并开源了名为 rl-bakery 的框架。最后,我们将分享在此过程中遇到的一些主要挑战和学到的东西。

敬请期待!

Zynga 生产中的深度强化学习

原文:https://towardsdatascience.com/deep-reinforcement-learning-in-production-at-zynga-334cd285c550?source=collection_archive---------55-----------------------

活动讲座

帕特里克·哈琳娜和迈赫迪·本·阿耶德| TMLS2019

https://torontomachinelearning.com/

深度强化学习已经在新闻中看到了很多突破,从像围棋、雅达利和 Dota 这样的游戏到自动驾驶汽车,但在生产中将其应用于数百万人带来了很多挑战。

强化学习的承诺是自动化的用户体验优化。作为世界上最大的移动视频游戏公司之一,Zynga 需要自动化,以便为我们 7000 万月活跃用户提供个性化的游戏体验。

本次演讲讨论了 RL 如何解决许多业务问题,在生产中使用 RL 的挑战,以及 Zynga 的 ML 工程团队如何通过我们的个性化管道克服这些挑战。

Zynga 生产中的深度强化学习

生产中的深度强化学习第 2 部分:个性化用户通知

原文:https://towardsdatascience.com/deep-reinforcement-learning-in-production-part-2-personalizing-user-notifications-812a68ce2355?source=collection_archive---------24-----------------------

Zynga ML 工程团队的迈赫迪·本·阿耶德(T1)和 T2·帕特里克·哈琳娜(T3)。

这个系列讨论了 Zynga 如何在产品中使用深度强化学习来个性化我们游戏中的用户体验。它基于我们在 Spark 峰会多伦多 ML 峰会上的陈述。

在这篇文章中,我们将讨论如何使用 RL 来个性化通知,并提高 Words with Friends Instant 的点击率。它作为一个例子来说明构建 RL 应用程序需要什么,以及为什么 RL 如此强大。

亚历克·鲍德温欣喜若狂地收到了来自 Words With Friends 的个性化推送通知(由 Zynga 公司提供)

我们使用强化学习的旅程始于 2018 年。我们知道它在理论上符合个性化的需求,但我们需要测试它在现实世界中是否可行。在本文中,我们将讨论一个 Zynga 应用程序来说明 RL 如何对个性化产生真正的影响。为了保护商业秘密,一些细节被模糊处理。剧透警告:RL 特工成功了!从那以后,我们继续为深度 RL 应用开发开源库, RL Bakery ,并推出了其他几个生产应用。

推送通知计时

大多数移动应用程序每天都向他们的用户群发送消息。例如,Zynga 的热门文字游戏 Words With Friends 会发送消息提醒用户,他们的朋友正在等待搬家。决定何时发送该信息是一个挑战。我们有全球用户群,每个人都有自己的时间表。发送通知的时间是敬业度的关键驱动因素。

  • 如果在合适的时间发送通知,用户可能会回来参与游戏。
  • 如果通知是在一个糟糕的时间发送的,用户可能会忽略它,不再回到游戏中来。你甚至会错过你的妈妈正等着你采取下一步行动!

与朋友的对话 2(由 Zynga 公司提供)

以前的方法

在我们开始之前,游戏已经实现了一个基于工作段的解决方案。玩家群根据用户所在的国家分为 3 个时区。每个用户在他们所在时区的晚上都会收到一条消息,因为那是最受欢迎的游戏时间。这种方法作为快速的第一次尝试效果很好,但是他们准备对其进行优化。

我们如何为全球用户选择最佳的通知时间?(由凯尔·格伦Unsplash 上拍摄)

你能想到这个解决方案有什么缺点吗?

首先是粗略的时区近似值。当然,世界上不止有三个时区。不仅如此,像美国和加拿大这样的国家有多个时区,很难将玩家的国家映射到一个特定的时区。我们甚至可能没有与所有用户相关联的正确国家。

除了数据问题之外,缺乏个性化是基于细分的个性化方案的常见问题。即使我们确定了某人的时区,每个人都有自己的时间表。如果是周一,在凌晨 3 点给某人发信息可能会更好,因为那是他们夜班的“午休时间”。细分策略没有使用足够的玩家背景来执行细粒度的用户体验个性化。

这种方法的前提有一个更关键的问题,说明了为什么 RL 对于个性化如此强大。最终,我们的目标是提高用户参与度。如果我们有一个完美的模型告诉我们这个用户将在晚上 7 点玩,那么在那个时间发送消息有意义吗?他们已经开始参与游戏了!我们应该试着在一小时前发送消息吗?12 小时前?如果我们连续三次尝试在晚上 7 点给用户发消息,而他们没有回应,我们是否应该尝试不同的时间?这就是 RL 的用武之地。它回答了这个问题:我对这个用户采取什么行动来增加参与度。

强化学习设置

回顾我们系列的第 1 部分,我们将个性化问题公式化为为给定状态选择一个动作,以最大化长期回报。对于通知定时问题,我们使用以下状态、动作和奖励:

  • 状态:用户与之前推送通知的历史交互。时间窗口被限定为 14 天,并且数据点被结构化为时间序列。
  • 操作:发送下一个通知的时间。所以有 24 个动作可用。
  • 奖励:当用户与推送通知交互时,提供一个积极的奖励。否则不提供奖励。

我们建立了一个机器学习管道,为所有符合推送通知条件的玩家收集、训练和执行批量推荐。

(关于基础设施的更多细节将在本系列的第 3 部分中分享。)

强化学习培训设置

构建强化学习应用实际上意味着什么?本质上,我们是在训练一个代理来选择动作。有很多训练智能体的深度学习算法:DQN、PPO、TD3、SAC 等。每个月都有新的算法(有新的 3 个字母缩写)发表在 ML 论文上。

我们的专业不是研究和实现这些算法。我们使用了来自开源 TF-Agents 库的现成实现。我们选择使用 DQN 算法进行概念验证。这是一种更简单的算法,但它实际上被用于 AlphaGo 项目,以击败世界上最好的围棋选手。

选择 RL 算法后,我们选择了一组超参数。其中许多都涉及任何深度学习算法核心的深度学习模型。您需要选择最能代表您的功能和策略(代理的决策逻辑)的网络架构。)您还需要选择深度学习超参数,如学习率、优化算法(如 ADAM、SGD)等。

还有一些 RL 特定参数。对 DQN 来说,探索是以一种ε贪婪机制进行的。这意味着在概率为ε的情况下,会选择一个随机行动。其余时间,将使用具有最佳预测奖励的动作。通常以较高的ε开始,以鼓励探索,然后随着时间的推移降低ε,因为代理专注于成功的策略。

使用 RL 选择超参数值很困难。与监督学习不同,您不能简单地提供一组静态的标记数据,并确定哪些超参数会产生最佳结果。RL 只从环境的反馈中学习。从一个时间步长到未来时间的复杂交互无法从静态数据集中捕捉到。然而,在这种情况下,我们有一个现有的策略(简单的分割方法,将世界分成 3 个时区。)我们通过训练代理模仿现有方法来测试不同的超参数。我们将在本系列的第 4 部分对此进行更详细的讨论。

强化学习训练循环

每天,我们都会运行一个批处理培训工作流来更新我们的代理,并生成发送下一个推送通知的时间。该工作流收集以下培训数据:

  • 两天前用户的状态
  • 2 天前的操作(发送通知的时间)
  • 用户的下一个状态(1 天前)
  • 1 天前的用户参与度值(奖励)

对每个用户来说,这被组合成一个轨迹

(状态、动作、下一状态、奖励)

这组轨迹用于更新现有的 RL 代理。更新意味着在 Tensorflow 上运行深度学习工作流:代表智能体的神经网络的值被更新,以更好地反映状态、行动和长期奖励之间的关系。

RL 代理的一个好处是,他们暗中跟踪“长期回报”。请注意,我们只告诉代理第二天的即时奖励。我们不需要等一个星期再告诉 it 关于 7 天保留期的信息。RL 算法基于即时奖励和下一个状态,建立它们自己的长期奖励的内部估计。

这是一个离线、批量 RL 问题的例子。它是离线的,因为我们从离线数据(而不是与环境的即时交互)中训练代理。)之所以是批量,是因为我们在批量输入数据。这种设置不同于论文和研究中讨论的大多数 RL 问题。在大多数学术问题中,代理人在模拟环境中接受在线训练,并立即做出反应。然而,离线问题在现实世界中更为典型,因为奖励往往从行动发生时就开始延迟。

结果

经过几天的数据收集和训练,代理将点击率提高了 10%左右(相对而言)。这第一次成功展示了使用一个相当简单的解决方案强化学习的力量。它通过算法测试不同的策略,以个性化每个用户的价值,并学习如何优化关键指标,如长期保留和参与。

代理能够回答这个问题:我应该在什么时候给每个用户发消息,以便提高参与度。它不知疲倦地工作,探索新的策略,寻找新的模式。如果游戏或用户模式改变,它也能适应。在这种情况下,强化学习框架为我们提供了一种通过最小的调整和无手动过程来优化关键指标的方法。这使得它成为个性化应用程序的完美方法。

这第一次的成功让我们将这个解决方案部署到 Friends Instant 的所有玩家群中。它现在每天为几百万玩家投入生产。

下一步是什么

培训 RL 代理并将其部署到生产环境中会带来一些挑战。它需要设置定制的机器学习基础设施,能够在需要时维护和提供建议。本系列的下一篇文章将讨论这些挑战。

使用 Python 进行深度强化学习|第 2 部分|使用深度 Q 网络创建和训练 RL 代理(DQN)

原文:https://towardsdatascience.com/deep-reinforcement-learning-with-python-part-2-creating-training-the-rl-agent-using-deep-q-d8216e59cf31?source=collection_archive---------6-----------------------

第一部分 我们一行一行的讲解了游戏环境的制作。在这一部分,我们将学习如何创建和训练深度 Q 网络(DQN ),并使代理能够使用它,以便成为我们游戏中的专家。

[## 使用 Python 进行深度强化学习|第 1 部分|创建环境

设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。

towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d)

在这一部分,我们将讨论:

1-为什么是深 Q 网(DQN)?

2-什么是 DQN?

3-DQN 是如何工作的?

4-解释我们的 DQN 建筑。

5-解释代理类。

6-培训代理。

有人可能会问“你为什么不用 Q-Learning 而不用 DQN?”这个问题的答案取决于许多因素,例如:

环境有多复杂?

在我们的例子中,我们可以用两种方式回答这个问题:

  • 如果我们希望 RL 代理的输入与人类的输入一样接近,我们将选择输入作为字段的数组表示。

RL 代理所看到的与人类玩家所看到的

在这种情况下,当我们使用 Q-Learning 时,环境会很复杂,而且由于 Q-Table 非常大,所以不可能存储它。为了证明这一点,考虑以下计算:

输入数组的状态数= (数组中每一项可以取的不同值的个数)^(宽度*高度)

输入数组可以具有的状态数= 4 ^ 10 * 20

= 4 ^ 200 = 2.58225e120

Q-表格大小 =动作空间大小*输入数组可以具有的状态数

Q-表格尺寸= 5 * 2.58225 e120 = 1.291125 e121

要存储这个数量的数组(每项 8 位),我们需要 9.39417077e109 太字节。

这就是为什么我们简单地使用 DQN 而不是 Q-Learning。

  • 另一方面,如果你想使用 Q-Learning,使用另一种输入会更有效。例如,您可以使用球员和球洞的 X 坐标、球员的宽度和球洞的宽度。这种方式的输入比使用数组表示简单得多。

什么是 DQN?

它只是一个普通的神经网络,唯一的区别是它的输入是环境的状态,它的输出是为了最大化当前步骤的回报而执行的最佳动作。

我们通过使用经验重放和重放记忆来做到这一点,这些概念将在下一节解释。

深度 Q 网(DQN)如何运作?

要完全理解 DQN 是如何工作的,你需要知道一些与 DQN 相关的概念:

1-体验回放和回放记忆:

类似于人类通过使用他们以前经验的记忆来学习的方式,dqn 也使用这种技术。

经验回放:代理执行每一步后收集的一些数据,这个经验回放包含【当前状态,当前动作,步骤回报,下一个状态】。

重放存储器:是一堆n经验重放,重放存储器主要用于通过获得重放的随机样本来训练 DQN,并使用这些重放作为 DQN 的输入。

为什么使用随机重放样本而不是顺序重放?

  • 当使用顺序重放时,DQN 倾向于过度拟合而不是一般化。

使用重放记忆的一个关键原因是打破连续样本之间的相关性。

2-模型和目标模型:

为了获得一致的结果,我们将训练两个模型,第一个模型【模型】将在代理做出每一步后拟合,另一方面,第二个模型【目标 _ 模型】每 n 步加载【模型】的权重(n = UPDATE_TARGET_EVERY)。

我们这样做是因为从一开始,一切都是随机的,从“模型”的初始权重到代理执行的动作。这种随机性使得模型更难执行好的动作,但是当我们有另一个模型每 n 步使用第一个模型获得的知识时,我们就有了某种程度的一致性。

在我们解释了一些关键概念知道我们可以总结学习的过程后,我将使用来自这篇精彩博客的 DeepLizard 的话:

解释我们的 DQN 建筑:

对于我们的 DQN,尝试了许多架构,其中许多都不工作,但最终有一个架构被证明工作良好。

失败的尝试次数:

  • 最初的失败之一是具有两个输出层的架构,第一个输出层负责预测最佳移动(向左、向右或不移动),而另一个输出层负责预测最佳宽度改变动作(增加宽度、减小宽度、不改变宽度)。
  • 另一个失败包括太深的网络,除了他们缓慢的训练过程,他们的表现太差。

寻找更好的架构:

在一些失败之后,进行了网格搜索,以找到能够胜过玩游戏的人的架构,下表显示了一些网格搜索的结果:

注意:下面的表格是为了最后显示最佳结果而排列的。

从第一次网格搜索的结果,我们可以清楚地看到,复杂和深度网络未能学会如何玩游戏,另一方面,最简单的网络工作得最好。

使用第一次网格搜索的结果,执行了另一次网格搜索,得到了一些好的结果:

从这个结果我们可以看出, 最好的只有并不能提高模型的性能,另一方面,同时使用 ECC(ε条件约束)和 EF(ε波动)可以提高模型的性能。

我们将在另一篇博客中讨论 ECC 和 EF。

其他一些网格搜索结果:

  • 测试 【仅最佳】:

  • 测试更简单的网络:

在所有这些网格搜索之后,我们最终决定使用一种架构,其中一个卷积层有 32 个滤波器,批量大小为 128,两个密集(全连接)层各有 32 个节点,我们将同时使用 ECC 和 EF。

网络摘要:

*Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 20, 10, 1)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 18, 8, 32)         320       
_________________________________________________________________
dropout_1 (Dropout)          (None, 18, 8, 32)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 4608)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 32)                147488    
_________________________________________________________________
dense_2 (Dense)              (None, 32)                1056      
_________________________________________________________________
output (Dense)               (None, 5)                 165       
=================================================================
Total params: 149,029
Trainable params: 149,029
Non-trainable params: 0
_________________________________________________________________*
  • 输入层:输入形状与代表游戏场地的数组形状相同 (20 乘 10)。
  • 卷积层:一个 Conv2D 层,有 32 个滤波器,大小为 22*
  • 辍学率为 20%
  • 展平:将 2D 卷积层的输出转换成 1D 数组。
  • 密集(全连接)层:两个密集层各有 32 个节点。
  • 输出层:输出层包含 5 个输出节点,每个节点代表一个动作【无动作,左移,右移,减宽,增宽】**

讲解代理*类:*

代理类是一个包含所有与代理相关的东西的类,比如 DQN、训练函数、重放记忆和其他东西,下面是这个类的逐行解释。

模型创建:

这两个函数用于创建给定两个列表的模型:

  • conv 列表:该列表的每一项定义了卷积层的滤波器数量。
  • 密集列表:该列表的每一项定义了密集层的节点数。

培训代理:

为了保持跟踪最佳模型并保存它以在训练后使用,使用以下函数:

接下来是一些常量:

接下来是将被训练的架构:

将使用前面的三种架构执行网格搜索,网格搜索的结果存储在数据帧中。

查看我的 Github 代码库:

* [## ModMaamari/强化-学习-使用-python

使用 Python 的强化学习。通过以下方式为 ModMaamari/强化-学习-使用-python 开发做出贡献…

github.com](https://github.com/ModMaamari/reinforcement-learning-using-python)*

概括地说,我们讨论了:

  • 选择 DQN 而不是 Q-Learning 的原因。
  • DQNs,简单解释一下。
  • dqn 是如何工作的?
  • 我们使用了什么架构,为什么?
  • 代理 类,解释代码。
  • 训练模型和网格搜索最佳模型的过程。

在下一部分,我们将:

  • 使用 Tensorboard 分析训练结果。
  • 尝试最好的模式。

资源:

本系列的其他部分:

* [## Python 强化学习|第 1 部分|创建环境

设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。

towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d) [## 使用 Python 进行深度强化学习|第 3 部分|使用 Tensorboard 分析训练好的模型

在前面的部分中:

towardsdatascience.com](/deep-reinforcement-learning-with-python-part-3-using-tensorboard-to-analyse-trained-models-606c214c14c7)

您可以关注我:

您可能还喜欢:

使用 Python 进行深度强化学习|第 3 部分|使用 Tensorboard 分析训练好的模型

原文:https://towardsdatascience.com/deep-reinforcement-learning-with-python-part-3-using-tensorboard-to-analyse-trained-models-606c214c14c7?source=collection_archive---------30-----------------------

在前面的部分中:

[## Python 强化学习|第 1 部分|创建环境

设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。

towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d)

  • 第二部分讨论了训练 DQN 的过程,解释了 DQNs 并给出了选择 DQN 而不是 Q-Learning 的理由。

[## 使用 Python 的深度强化学习|第 2 部分|使用深度 Q 创建和训练 RL 代理…

在第一部分,我们经历了制作游戏环境,并逐行解释。在这一部分,我们是…

towardsdatascience.com](/deep-reinforcement-learning-with-python-part-2-creating-training-the-rl-agent-using-deep-q-d8216e59cf31)

在这一部分中:

我们将:

  • 使用 Tensorboard 可视化训练好的模型。
  • 解释加载和尝试已训练模型的方式。
  • 用最好的模型,让它玩游戏。

使用张量板:

1-使用修改的 Tensorboard 使 Tensorboard 在一个日志文件中记录来自训练过程中所有情节的数据,而不是每次我们拟合模型时都制作新的日志文件。

下一个代码modified tensor board来自 sentdex 的这个博客,我只是稍微修改了一下,让它可以在 TensorFlow2.0 上运行:

2-在代理类的 init 中定义修改后的 tensorboard 的对象:

路径名称 用于定义保存日志文件的完整路径。

3-拟合模型时,将修改后的张量板作为回调传递:

4-每集开始时:

5-要更新日志,请使用下一行:

可视化日志:

在“logs”文件夹所在的目录下打开终端,并运行:

tensorboard --logdir="logs/"

将出现一个浏览器窗口:

你可以自己尝试其他选项。

通过使用这些可视化,我们可以看到记录的变量之间的关系,例如 epsilonmax_reward。

加载和使用训练模型:

代理人玩游戏的一些镜头:

资源:

本系列的其他部分:

[## Python 强化学习|第 1 部分|创建环境

设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。

towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d) [## 使用 Python 的深度强化学习|第 2 部分|使用深度 Q 创建和训练 RL 代理…

在第一部分,我们经历了制作游戏环境,并逐行解释。在这一部分,我们是…

towardsdatascience.com](/deep-reinforcement-learning-with-python-part-2-creating-training-the-rl-agent-using-deep-q-d8216e59cf31)

您可以关注我:

您可能还喜欢:

深度 RL 案例研究:自动化工程

原文:https://towardsdatascience.com/deep-rl-case-study-automating-engineering-96779921d108?source=collection_archive---------36-----------------------

人工智能和计算机系统能接管工程的其他领域吗?

在不同的工程领域中,参数调整是一个常数。计算机科学家调整他们模型的值,电气工程师改变他们晶体管的宽度,化学工程师检查他们过程的效率。这些不同角色的不变方面:人类在高维、非凸优化问题上是不可靠的。在所有这些情况下,我们的大脑就是优化功能——设计工程师还可以使用哪些优化器,为什么要使用?最近发现的这些工程角色之间的差异:只有计算问题被结构化和规范化到足以让学习戏剧性地改变它们。

自动参数调整— AutoML:

AutoML,即自动机器学习,正在流行起来。当我在脸书的时候,我正在测试 PyTorch 的预发布版本,Berkeley 的同事刚刚发布了他们自己的开源包 Tune (for Ray)

[## 使用射线调谐的尖端超参数调谐

介绍 Ray Tune,这是最先进的超参数调节库,可供研究人员和开发人员在任何…

medium.com](https://medium.com/riselab/cutting-edge-hyperparameter-tuning-with-ray-tune-be6c0447afdf)

AutoML 是做什么的?简而言之,它…

  1. 加载设计变量和目标的向量
  2. 将模型拟合到目标函数,
  3. 返回当前数据集中的最佳参数

现在,我们可以了解这意味着什么。

设计变量和设置

每个设计问题都有一组要优化的变量,变量的数量决定了要使用的优化器的类型。由于难以限制优化器可访问的变量,自动化设计的采用受到限制。工程师运用多层次的知识来理解系统是如何工作的。他们利用这些知识来调整许多方面,并汇聚成一个解决方案——通常在不受约束的环境中工作。现代机器学习在结构化问题中工作得非常好,所以在实际问题中启用 AutoML 的很大一部分是有效的数据科学。设计师必须将系统最重要的方面提取到变量的子集里(有人知道主成分分析吗?)被标准化并准备好供计算机拟合和迭代。

这些原则只有在工具设置好之后才能应用,也就是说,学习算法可以直接改变感兴趣的变量并运行新的模拟。自动化设计的影响力取决于它改变和测试新参数的能力。工具的障碍是这些问题的解决方案变得非常小众的原因— 需要对参数优化和设计工具有博士水平的理解才能在硬件中部署它们

为目标建模

贝叶斯优化是 AutoML 优化器中使用最频繁的工具(可以使用任何非梯度依赖优化器:备选包括 遗传算法 交叉熵方法 )。

贝叶斯优化循环(算法)中迭代高斯过程(模型)的拟合。黑点代表数据,这显示了 2 到 4 个数据点。目标函数通过测量拟合表面,并预测状态空间剩余部分的平均值和方差。绿色(激活功能)用于选择下一组参数,参见下面的优化选择部分。(来源— 将人类从循环中解放出来……)

目标的模型就是所捕获的正在设计的系统的行为。这是至关重要的一步,它使计算机成为一种更加结构化的选择形式。计算机可以用平滑高斯过程、深度神经网络或概率分布的组合来模拟复杂的非线性函数。

这些不同的模型选项在表达性、可解释性和样本效率之间进行权衡。高斯过程(最终是非参数高斯分布)是一个很好的选择,因为它们在样本效率方面占优势,同时带有可解释的不确定性概念。

最佳选择

这是计算机比人类获益最多的地方。

人类擅长将一种设计与另一种设计进行比较(也许是不可思议的强烈直觉),但我们缺乏任何真正的能力来提出给定数据集的最佳或接近最佳的下一组参数。使用结构化学习模型为算法提供了一种明确的方式来决定下一个参数集。

在贝叶斯优化中,传递下一组参数的工具被称为采集函数。获取功能是另一个可供人类选择的设计选项。其他方法(CMA、CEM 等)可以将他们的预测建模为样本分布,取这种分布的平均值就是当前的最优估计。采集函数的不同选择在参数探索、模型开发和先验知识之间进行平衡。关键是优化器消除了困扰人类调优 的选择歧义。

* [## 将人带出循环:贝叶斯优化综述

编辑描述

dash.harvard.edu](https://dash.harvard.edu/handle/1/27769882)

如果你正在为你的项目寻找一个 AutoML 工具——看看这个来自弗赖堡的研究小组。*

我们认为优化一组参数——人类在 中调十几个变量 还是人类选择几个 算法棋子 哪个更好?让我们看看在研究中选择适合当前特定设计问题的优化器和模型的可能性。

来源——我的大阪之旅。

自动化设计的前沿

我概述了去年给我留下深刻印象的自动化工程的两个最近的例子。(我正试图从这些研究中获得灵感,在我自己的研究中优化机器人设计,这有望导致这篇博文的第二个版本。)

电路设计

Kourosh Hakhamaneshi 等人。al 将进化算法(优化选择)和深度神经网络鉴别器(目标函数模型)应用于高维电路设计问题(设计空间)。

电路设计涉及许多方面,但在高层次上,设计一个片上系统的一个组件归结为四个步骤:1)改变原理图(使用的组件,例如晶体管、电阻),2) 模拟原理图,直到它是准确的,3) 布局原理图,以便它可以在电路代工厂(TSMC,英特尔)创建,4) 模拟电路布局。最耗时的环节是最后一步,模拟可能需要几天时间。原理图-模拟-布局-模拟是一个非常宽的循环,其中简单的迭代不会产生任何功能性结果。

(来源— BAIR 在 BagNet 上的博客文章)

如果一种算法不能减少模拟(和验证)电路如何制造所需的时间,那么它知道在哪里放置带电阻的晶体管只是难题的一小部分。有一个核心技术方面使本文能够实现功能性结果(过去其他项目失败的地方):使用深度学习鉴别器来判断哪些新设计应该在布局后仿真中进行评估

电路设计的复杂性是作者以这种方式设置问题的原因。他们需要使用进化算法,因为它可以快速地提出更多的样本,并获得关于参数是否应该工作的初始指示(给定历史人口数据),然后鉴别器充当过滤器,以大幅减少计算负担。

这种方法的主要优势是 它能够在模拟电路设计 的各种约束条件下工作。这篇论文的作者代表了离线优化和电路设计领域的知识高峰——在专门问题上实现新颖优化所需的罕见组合,因此希望 BagNet 取得成功。

* [## 模拟电路设计的样本高效进化算法

在这篇文章中,我们分享了一些关于深度学习在模拟 IC 设计中的应用的最新成果…

bair.berkeley.edu](https://bair.berkeley.edu/blog/2019/09/26/circuits/)

机器人设计

这里托马斯·廖等人。al 将贝叶斯优化(优化选择)和高斯过程(目标函数模型)应用于微机电系统优化(设计空间)。

在任何硬件设计问题中,设计的评估通常会因几周的制造时间而延迟。这在微机电系统(MEMs)中尤其如此,其中有两个阶段用于延迟和变化:掩模组装(工具设置)和纳米制造(实际构造)。该方法通过启用参数空间的并行搜索来增加设计优化的吞吐量。本文使用贝叶斯优化循环的升级版本。

(来源—MEMs 论文中的形态学学习)

伟大的洞察力是用一个新的获取函数修改贝叶斯优化,该函数返回一组参数向量以在下一次评估中尝试。然后,该模型可以立即适应所有这些试验,并提出另一批试验。这就是所谓的分层过程约束批量贝叶斯优化(HPC-BBO) 。该模型可以拟合来自问题的任何数据,因此并行评估是挂钟时间的实质性改进(使用新的采集功能可能会稍微降低采样效率)。

实现这一点的两个关键技术细节是 1) 用模型想象真实过程的回报(标准贝叶斯优化需要在获得另一个样本之前评估真实系统上的参数),首先在批量贝叶斯优化中提出,以及 2) 关于第二个约束的批量建议参数的上下文优化——需要设计与特定控制器一起工作,这成为一个联合学习问题。

这种学习协议强调了 AutoML 在结构问题上的工作能力,这些问题过去是专门留给人类设计师的。结构和并行化使其在实际硬件中循环时非常高效。

[## 微机器人形态学和控制器的高效数据学习

机器人设计通常是一个缓慢而困难的过程,需要反复构建和测试原型,并且…

arxiv.org](https://arxiv.org/abs/1905.01334)

来自我实验室的真实(外部)和想象的微型机器人。(来源相关学术 论文来自我的小组)*

这种方法在很多方面都站不住脚——设计变量太多,无法访问特定机构使用的专有设计工具之外的数据,缺乏老一辈工程师的教育。也就是说,一些年轻的专家在他们的领域所付出的努力会产生巨大的回报。

深度 RL 案例研究:基于模型的规划

原文:https://towardsdatascience.com/deep-rl-case-study-model-based-planning-1d85822b0c0d?source=collection_archive---------22-----------------------

模型学习为强化学习领域提供了结构和可解释性。

什么是基于模型的强化学习,什么是对其未来的乐观,DeepMind 在最近的一篇论文中说它的代理可以通过“做梦”从零开始学习计划是什么意思。基于模型的学习可能是样本最优的——如果我们能够恰当地捕捉环境的动态,那么代理可以精确地计划来完成我们想要的任何任务(其中无模型学习专注于单个任务)。DeepMind 最近的 MuZero 算法向世界表明,由于其规划能力,MBRL 将继续存在。

快速历史拍摄

许多决策算法一直使用环境模型来解决问题。一些经典的例子包括搜索方法,如 A-Star 或树搜索。这些计划顺序动作的方法的问题是它们缺乏在连续环境中的能力。当您试图创建一个包含无限个候选动作的动作选择树时,会发生什么?这个缩放问题是深度强化学习中基于模型的规划试图通过将动作选择转换为易处理的优化问题来覆盖的众多问题之一——给我们一个动作而不是一个样本空间。

基于模型的强化学习回顾

MBRL 的方块图。来源,我在 IROS 2019 的演讲。

基于模型的强化学习(MBRL)遵循代理在其环境中行动的方法,学习所述环境的模型,然后利用该模型来行动。它通常以参数化的动态模型为特征,通知某种控制器。该回路在图中用 Clank 表示。在 MBRL,通常控制问题在它本身和动态模型的学习之间缺少一个链接,这引入了一些最优性的损失。本文将关注如何使用某种动力学模型来计划一系列的动作。我首先回顾了一些过去的方法,并借鉴了 DeepMind 最近的工作,该工作正在准备使用基于模型的规划来解决 RL 中令人兴奋的前沿问题。

我年轻的非专业摄影还在继续。降落在哥斯达黎加的坦博尔。

使用概率动力学模型的少量试验中的深度强化学习

MBRL 和规划一直在大幅上升,特别是自从蔡氏等人在 2018 年神经信息处理会议上的一篇同事论文:“使用概率动力学模型的少数试验中的深度强化学习(spot light paper ~ 4%的被接受论文)。艾尔。它描述了如何将动力学模型塑造成一个有用的控制器,这是 MBRL 第一次因为渐近最优(与软 actor-critic 和其他无模型算法相比)和样本效率更高而受到关注。

PETS 中使用的三个模块是深度动力学模型、轨迹传播器(不是真正的规划器)和基于采样的控制(来源)。

何时信任您的模型:基于模型的策略优化

另一篇直接导致 DeepMind 最近工作的论文(我认为是 MBRL 领域相当有开创性的)是 Janner 等人的论文“何时信任你的模型:基于模型的策略优化”,该论文对 MBRL 的早期工作进行了两项根本性的改变:1)他们成功地表明基于模型的算法可以使用标准的上下文策略(当状态传入时返回动作的网络)作为控制器,2) MBRL 可以使用动态模型的离线模拟来改进控制策略的当前迭代。

这种算法的工作原理是创建一个动态模型,然后在模拟中对动态模型运行非常短的软 actor-critic 部署,这在很少的环境交互中生成可靠的策略,创造了基于模型的策略优化(MBPO)。

在模型上进行模拟时,对未来的不确定性估计迅速增加(来源)。

从头开始学习基于模型的规划

Pascanu、李和 DeepMind 团队的这篇较老的论文“从零开始学习基于模型的规划”试图解决这样的批评:“虽然模型可以用来评估一个计划,但它并没有规定如何构建一个计划。”以经典的 DeepMind 方式——他们改进并整合了最近研究的许多方面到一个令人印象深刻的系统中。他们正在接受 MBRL 挑战,并为动力学模型的离线模拟创造了术语“想象力”(非常类似于两年后问世的 MBPO)。这种情况下的关键区别是,在这种新的基于想象的计划方法(IBP)中,他们还学习何时想象,并以巧妙的方式使用真实和模拟体验中的上下文。

IBP 的想象框架。

类似于 MBPO,这项最新的工作使用情境化的策略进行控制。扩展在于,IBP 不是仅仅使用过去的状态来决定下一步行动,而是有自己的方法来生成上下文。作者使用长短期记忆(LSTM)模块从最近的模拟和真实经历中学习上下文,这提高了控制任务的性能。本文评估了向前一步、向前 n 步和全树探索的性能。全树探索允许管理者通过不同深度的不同动作来探索想象,通过最大计算成本来限制探索的深度和广度。 MBPO 在这个设置上做了改进,在想象时使用了一种无模型算法的状态,以获得令人印象深刻的性能。

学习基于树的规划允许对不同深度和宽度的真实世界和想象的行动进行评估,以及估计的回报(来源)。

作者提出,这种想象框架也可以很好地进行概括。我认为这与元学习有关,在这种情况下,管理者——处理何时行动与何时计划——可以处理任务抽象,并学习学习不同的任务(在现实和模拟中)。经理目前是一个离散的行动,奖励很少,所以学习起来一定很难——他们目前在这里使用强化算法。

这篇论文是 DeepMind 刚刚发布的一些工作的前身,他们将规划集成到他们的巨型机器学习系统中,以解决具有巨大行动空间和高天花板的游戏。

高潮:穆泽罗

Schrittwieser 等人的模型“通过计划掌握雅达利、围棋、国际象棋和日本象棋。al 是基于模型的 RL 的一个重要时刻。显示 MBRL 可以直接从像素(建立模型的常见斗争点)解决雅达利游戏作为一种新的艺术状态,将进一步推动 MBRL 在顶级强化学习会议中的指数级上升(几年前不到 1%,很快达到 RL 论文的 10%左右)。

用一个已学过的模型来计划、表演和训练。a)动态模型返回一个估计的奖励和状态,它可以被转换成一个未来值,B) MuZero 根据上下文策略(类似于之前)在每个时间步使用蒙特卡罗树搜索进行操作,C) MuZero 通过验证来自重放缓冲器的轨迹并通过在真实轨迹的每一步将它们想象成一个模拟的未来来训练(来源)。

MuZero 算法将来自 MBRL 的许多块构建到一个系统中,该系统显示了无模型算法的有效性。算法需要从像素而不是物理状态观察中运行的项目,因此 MBRL 需要聪明的编码来使它们最佳地执行。主要区别包括:

  1. 动态模型不是试图从真实的隐藏状态中计划行动和奖励,而是对一种内部状态进行编码,这种状态没有真实环境的语义表示。这允许反向传播直接最大化期望的度量,而对问题的形状具有较少的约束。
  2. 从这个隐藏的内部状态计算策略和值函数,类似于来自 AlphaZero 的联合策略和值函数(它们最近的无模型 RL 成功)。
  3. 与 AlphaZero 的蒙特卡罗树搜索(MCTS)不同的是,在推出潜在行动时,他们可以使用学习到的模型来引导或想象,即未来价值估计,这变成了一种基于模型的基本规划。

这个规划函数提高了学习算法的样本效率,因为提前规划可以达到赢得一场比赛的稀疏回报。最终,这是为什么规划有助于更快地学习的一个潜在原因——它让算法从它当前的行动中寻找回报,而不是依赖随机探索(这在 MBRL 也有帮助和贡献)。

(这篇文章中没有提到的对 MBRL 的一个限制是基于模型的 RL 的墙时间效率很差——运行一个运行中的半猎豹的模拟可能需要一周时间。我希望在未来从事这项工作——基本上所有的动力学模型训练和想象步骤都会导致算法比无模型的算法运行得慢得多。一些算法,如 MBPO,甚至有奇怪的事件顺序(在每个实时步骤进行想象),这使得它无法在真实的机器人上运行。

更多?订阅我关于机器人、人工智能和社会的时事通讯!

** [## 自动化大众化

一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…

robotic.substack.com](https://robotic.substack.com/)**

深度堆叠网络(DSN)

原文:https://towardsdatascience.com/deep-stacking-network-dsn-f98dcf4a3631?source=collection_archive---------47-----------------------

神经网络已经存在了一段时间,但是提供诸如特征提取等功能的能力使得它们的使用更加可行

深度堆叠网络(DSN)是一种深度架构,旨在支持大型 CPU 集群,并受益于深度神经网络的深度学习能力。深度堆叠网络架构最初是由邓梨和董宇在 2011 年提出的,通常被称为深凸网络(DCN),以强调用于学习网络的算法的深度。

深度网络模型已被证明是一种有前途的范式,它为高性能机器学习提供复杂数据,其中多个集中在神经网络上。近年来,为了使用非神经网络方法构建不同的深度架构,已经进行了更多的实验。深度堆叠网络(DSN)模型使用简单易学的模块来创建复杂的并行参数训练网络。

DSN 架构的核心理论是堆叠原理,正如最初建议的那样,首先组装基本的功能模块或分类器,然后相互堆叠,以便学习复杂的功能或分类器。

基于 SVM 的深度堆叠网络(SVM-DSN)

基于 SVM 的深度堆叠网络(SVM-DSN)使用 DSN 架构来组织用于深度学习的线性 SVM 分类器。从全局的角度来看,SVM-DSN(基于 SVM 的深层堆叠网络)可以从局部的角度,将数据表示作为深层网络逐层提取,但是是并行的。SVM 堆栈可以收敛到其理想解,并获得支持向量,与神经网络相比,这可能导致抗饱和和理解方面的令人着迷的改进。

由于其特性,SVM 和 DSN 之间的训练并行化只能达到基础水平——训练数据的定向特征和 SVM 可以为从训练数据中学习块提供支持向量。传统的 D-SNA 只能达到块级别,但是基于向量的 SVM 可以用于块学习。

SVM-DSN 模型具有一些有益的特征,例如整体和空间优化以及并行化。

自动编码器

自动编码器是一种人工神经网络,旨在无人值守的情况下学习有效的数据编码。深度学习当然不是什么新鲜事,但由于它能够对神经网络进行深度分层并加速其执行,近年来经历了爆发式增长。深度学习结构依赖于更多的数据,网络越深,基于样本数据进行训练并基于其成功进行奖励的受监控学习算法的数量就越多。

自动编码器堆叠是一种训练深度网络的方法,深度网络由多个层组成,并使用贪婪方法进行训练。深度堆叠网络使用采取多层感知器的简化形式的基本模块的堆叠。

有几种方法可以学习堆栈中的自动编码器,例如使用多个编码器。堆叠式自动编码器结构已经在深度神经网络的模型中使用了许多年,例如在深度学习的神经网络中。

虽然构建这些类型的深层架构可能很复杂,但它们可以很快上手。Tensorflow 中从头构建的深度堆栈自动编码器模型。在批处理架构中,每个编码层都有自己的层,它应该是一个完整的自动编码器,并且这些层都是堆叠的。由自动编码器生成的函数可以被馈送到网络的其他层,例如代码和数据层。

DSN 的优势

神经网络已经存在了一段时间,但提供特征提取等功能的能力使其使用更加可行。GPU 能够从深度学习中受益,因为它可以更容易地训练和运行原始处理器效率不高的深度网络。这一优势使得 SVM 和 DSN 能够避免深度神经网络中的神经元饱和问题,从而提高性能。

引用来源

用于图像分类的深度迁移学习

原文:https://towardsdatascience.com/deep-transfer-learning-for-image-classification-f3c7e0ec1a14?source=collection_archive---------3-----------------------

从数据导入到精度评估的分步指南

以下教程介绍了如何为图像分类建立先进的深度学习模型。该方法基于机器学习框架“Tensorflow”和“Keras”,并包括复制本教程中的结果所需的所有代码(不幸的是,在中型文章中包含代码块时的语法看起来不太好,但它应该是可读的)。

建立模型的先决条件是访问标记数据,作为一个例子,我使用了各种交通标志的图像(可以在这里下载)。因此,该模型的任务是预测它看到的是哪种交通标志。为了使示例更真实,我将数据量减少到每个类最多 200 张图像(因为在机器学习的实际应用中,数据量通常是有限的)。

这些图片当然只是作为一个例子,让你开始。只要遵循与当前设置相同的文件夹结构,就可以很容易地用您自己的图像替换它们,如下所述。

用您自己的数据替换图像:

将您的图像放在主文件夹“data/”下的子文件夹中,将图像类别的名称作为子文件夹名称,如下所示的示例文件夹结构。首先,您需要将图像分成训练、验证和测试数据。“training_data”文件夹中的图像是用于训练模型的实际图像,而“validation_data”文件夹中的图像用于优化训练和模型超参数。然后,测试数据被用作最终评估,在一组完全独立的图像上评估模型的准确性。

包含数据集的文件夹结构示例:

培训数据:

  • 数据/列车/类别 1:类别 1 中的标志图像
  • 数据/列车/类别 2:来自类别 2 的标志图像
  • …………………………………..

验证数据:

  • data/val/category_1:来自类别 1 的标志图像
  • data/val/category_2:第 2 类标志的图像
  • …………………………………..

测试数据:

  • 数据/试验/类别 1:类别 1 中的标志图像
  • 数据/测试/类别 2:类别 2 中的标志图像
  • …………………………………..

在“训练”、“验证”和“测试”之间分割图像的一种方式是,例如,使用 80%的图像来训练模型,并且分别对 10%的图像进行验证/测试。关于分离“训练”、“验证”和“测试”数据的重要性的简要介绍,你也可以阅读这里的

定义和运行模型所需的库和包:

这些是一些有用的 python 库/包,它们使我们的生活变得更加容易,因为我们不必从头开始编写所有的代码和功能。如果没有这些库/包,构建深度学习模型实际上将是一项非常艰巨的任务!

**import** **numpy** **as** **np**
**import** **os**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**

**from** **numpy.random** **import** seed
seed(1337)
**from** **tensorflow** **import** set_random_seed
set_random_seed(42)

**from** **tensorflow.python.keras.applications** **import** vgg16
**from** **tensorflow.python.keras.applications.vgg16** **import** preprocess_input
**from** **tensorflow.python.keras.preprocessing.image** **import** ImageDataGenerator, load_img
**from** **tensorflow.python.keras.callbacks** **import** ModelCheckpoint
**from** **tensorflow.python.keras** **import** layers, models, Model, optimizers

**from** **sklearn.metrics** **import** classification_report, confusion_matrix, accuracy_score
**from** **plot_conf_matr** **import** plot_confusion_matrix

定义训练/测试数据和不同的类别:

在这里,我们定义了 train/val/test 图像的位置以及我们想要分类的所有不同类别的名称。然后,我们绘制训练集中每个类别的图像数量。

train_data_dir = "data/train"
val_data_dir = "data/val"
test_data_dir = "data/test"category_names = sorted(os.listdir('data/train'))
nb_categories = len(category_names)
img_pr_cat = []**for** category **in** category_names:
    folder = 'data/train' + '/' + category
    img_pr_cat.append(len(os.listdir(folder)))sns.barplot(y=category_names, x=img_pr_cat).set_title("Number of training images per category:")

每节课的训练图像数量概述

让我们也从各种标志类别中绘制一些示例图像,以直观显示典型的图像质量:

**for** subdir, dirs, files **in** os.walk('data/train'):
    **for** file **in** files:
        img_file = subdir + '/' + file
        image = load_img(img_file)
        plt.figure()
        plt.title(subdir)
        plt.imshow(image)
        **break**

一些示例图像

正如你从上面的例子中看到的,分辨率和质量都不是很好。然而,在机器学习的实际应用中,图像质量和数据量往往非常有限。因此,与使用成千上万的“完美的”高质量图像相比,限制为每类最多 200 个训练图像的低质量图像代表了更真实的例子。

迁移学习:

现阶段不需要了解各种类型的深度学习模型的所有细节,但是可以在这里找到一些常用的建模方式的总结,供感兴趣的人参考。

在本教程中,我们使用预训练的深度学习模型(VGG16)作为我们图像分类器模型的基础,然后根据我们自己的数据重新训练该模型,即迁移学习

img_height, img_width = 224,224
conv_base = vgg16.VGG16(weights='imagenet', include_top=**False**, pooling='max', input_shape = (img_width, img_height, 3))

您可能会注意到上面的参数“pooling= 'max '”。原因是,我们不是将 VGG16 模型的卷积基础连接到最终输出层之前的几个完全连接的层(这是在原始 VGG16 模型中完成的),而是使用最大池输出(也可以使用“平均池”,因为这取决于哪种方法效果最好的用例)。这种方法是使用完全连接的图层从要素地图过渡到模型输出预测的替代方法。根据我的经验,这种方法通常非常有效,并且使模型不容易过度拟合,正如这篇论文中所描述的:

传统的卷积神经网络在网络的较低层执行卷积。对于分类,最后一个卷积层的特征图被矢量化,并馈入完全连接的层,随后是 softmax 逻辑回归层。这种结构将卷积结构与传统的神经网络分类器联系起来。它将卷积层视为特征提取器,生成的特征以传统方式进行分类。

然而,完全连接的层容易过度拟合,从而阻碍了整个网络的泛化能力。在本文中,我们提出了另一种称为全局平均池的策略来取代 CNN 中传统的全连接层。我们没有在特征地图上添加完全连接的层,而是取每个特征地图的平均值,并将结果向量直接输入 softmax 层。与完全连接的图层相比,全局平均池的一个优势是,它通过加强要素地图和类别之间的对应关系,更适合卷积结构。因此,特征图可以很容易地解释为类别置信度图。另一个优点是在全局平均池中没有要优化的参数,因此在这一层避免了过拟合。此外,全局平均池汇总了空间信息,因此对输入的空间平移更具鲁棒性。我们可以把全局平均池看作一个结构正则化器,它明确地强制特征图成为概念(类别)的置信度图。

加载了预训练的 VGG16 模型后,我们还可以选择在下面的代码块中冻结模型的“更深的层”,只在我们自己的数据上重新训练最后几层。这是一种常见的迁移学习策略,当可用于训练的数据量有限时,这通常是一种很好的方法。

迁移学习

这个选项目前在代码中被注释掉了(使用#符号),因此我们正在重新训练模型的所有层。训练的层数代表了一个你可以自己试验的参数。可训练层数如何影响模型性能?

*#for layer in conv_base.layers[:-13]:*
*#    layer.trainable = False*

作为检查,我们还可以打印模型所有层的列表,以及它们是否可训练(对/错)

**for** layer **in** conv_base.layers:
    print(layer, layer.trainable)

使用 VGG16 模型作为基础,我们现在在上面构建最终的分类层来预测我们定义的类。然后,我们打印模型摘要,列出模型的参数数量。如果你决定“冻结”一些层,你会注意到下面的“可训练参数”的数量将会减少。

model = models.Sequential()
model.add(conv_base)
model.add(layers.Dense(nb_categories, activation='softmax'))
model.summary()

正如您所看到的,模型最后一层的输出形状对应于类的数量,在我们的例子中是 10。

用于读取和处理图像的发生器:

然后,我们需要定义一些函数,从我们的文件夹中读取图像,并将它们提供给图像分类器模型。作为其中的一部分,我们还添加了一些基本的图像预处理,其中输入图像被缩放为具有范围[0,1]内的像素值(在原始图像中为 0–255)。

*#Number of images to load at each iteration*
batch_size = 32*# only rescaling*
train_datagen =  ImageDataGenerator(
    rescale=1./255
)
test_datagen =  ImageDataGenerator(
    rescale=1./255
)*# these are generators for train/test data that will read pictures #found in the defined subfolders of 'data/'*print('Total number of images for "training":')
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size, 
class_mode = "categorical")print('Total number of images for "validation":')
val_generator = test_datagen.flow_from_directory(
val_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = "categorical",
shuffle=**False**)print('Total number of images for "testing":')
test_generator = test_datagen.flow_from_directory(
test_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = "categorical",
shuffle=**False**)

运行上述代码块的输出

定义模型参数并开始训练:

这里,我们定义一些控制模型训练过程的参数。重要的参数是例如训练率、多少个时期来训练模型以及使用哪个优化器。你不需要理解所有这些术语来跟随教程,但是感兴趣的人可以在这里快速阅读。

我们还定义了一个检查点参数,在训练期间,我们在每个时期之后跟踪验证的准确性。利用这一点,我们总是保留在训练过程中表现最好的模型的副本。

learning_rate = 5e-5
epochs = 10checkpoint = ModelCheckpoint("sign_classifier.h5", monitor = 'val_acc', verbose=1, save_best_only=**True**, save_weights_only=**False**, mode='auto', period=1)
model.compile(loss="categorical_crossentropy", optimizer=optimizers.Adam(lr=learning_rate, clipnorm = 1.), metrics = ['acc'])

我们现在准备好开始根据我们自己的数据训练模型,对于每个“时期”,我们打印训练和验证损失和准确性。在训练数据上测量的模型精度由“acc”给出,在验证集中的图像上的精度由“val_acc”给出。这是最重要的量,因为它告诉我们模型在训练过程中尚未看到的图像上有多精确。

理想情况下,“val_acc”应该随着我们不断训练模型而针对每个时期增加,并且当我们的模型不能从我们的训练数据中学习到任何更有用的信息时,最终达到稳定的值。

history = model.fit_generator(train_generator, 
                              epochs=epochs, 
                              shuffle=**True**, 
                              validation_data=val_generator,
                              callbacks=[checkpoint]
                              )

培训期间的输出

从上面显示的输出中,我们可以看到,在训练过程中,损耗减少了,而精度增加了。每次验证精度达到新的最大值时,都会保存检查点文件(输出:“将模型保存到 sign_classifier.h5”。训练完成后,我们加载在训练期间具有最佳验证准确性的检查点文件:

model = models.load_model("sign_classifier.h5")

评估模型准确性:

我们首先将模型精度的变化和训练过程中的损失可视化,因为这为我们提供了重要的信息来评估我们可以做些什么来提高精度。想要更好地了解这个话题,你也可以看看这个视频:

绘制和保存学习曲线的代码:

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']epochs = range(1,len(acc)+1)plt.figure()
plt.plot(epochs, acc, 'b', label = 'Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
*plt.savefig('Accuracy.jpg')*plt.figure()
plt.plot(epochs, loss, 'b', label = 'Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
*plt.savefig('Loss.jpg')*

从左图开始,显示了训练/验证准确性:蓝线表示在训练图像上测量的模型准确性,我们看到这很快达到几乎为 1 的值(这表示对 100%的训练图像进行了正确分类)。然而,验证准确性是在验证集上测量的准确性,这是我们真正关心的准确性。在这种情况下,准确率稳定在 97–98%左右,这意味着我们成功地将验证集中的几乎所有图像分类到正确的类别。

为了了解不同类别的准确性,我们可以计算并绘制“混淆矩阵”。这代表了评估模型准确性的说明性方式,因为它比较了测试集中所有图像的“真实”与“预测”类别。注意:如果重新运行代码时没有得到完全相同的数字,也不用担心!在模型初始化等方面存在一些固有的随机性。这使得结果有时略有不同。

(计算和绘制混淆矩阵的代码包含在图的下方)

Y_pred = model.predict_generator(test_generator)
y_pred = np.argmax(Y_pred, axis=1)

cm = confusion_matrix(test_generator.classes, y_pred)
plot_confusion_matrix(cm, classes = category_names, title='Confusion Matrix', normalize=**False**, figname = 'Confusion_matrix_concrete.jpg')

是脚本“plot_conf.py”中的代码,其中包含绘制混淆矩阵的函数“plot _ conf _ matrix”。

import numpy as np
import matplotlib.pyplot as pltdef plot_confusion_matrix(cm, classes, figname,
 normalize=False,
 title=’Confusion matrix’,
 cmap=plt.cm.Blues):
 “””
 This function prints and plots the confusion matrix.
 Normalization can be applied by setting `normalize=True`.
 “””
 import numpy as np
 import matplotlib.pyplot as plt
 import itertools
 if normalize:
 cm = cm.astype(‘float’) / cm.sum(axis=1)[:, np.newaxis]
 print(“Normalized confusion matrix”)
 else:
 print(‘Confusion matrix, without normalization’)plt.figure(figsize=(8,8))
 plt.imshow(cm, interpolation=’nearest’, cmap=cmap)
 plt.title(title)
 #plt.colorbar()
 tick_marks = np.arange(len(classes))
 plt.xticks(tick_marks, classes, rotation=90)
 plt.yticks(tick_marks, classes)fmt = ‘.2f’ if normalize else ‘d’
 thresh = cm.max() / 2.
 for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
 plt.text(j, i, format(cm[i, j], fmt),
 horizontalalignment=”center”,
 color=”white” if cm[i, j] > thresh else “black”)plt.ylabel(‘True label’)
 plt.xlabel(‘Predicted label’)
 plt.tight_layout()
 plt.savefig(figname)

从上面的混淆矩阵中可以看出,模型错误分类的主要类别是“交叉点”,在其中的 10 幅图像中,它将该类别与“产量”类别相混淆。作为最后的度量,我们还可以计算在测试集上评估的总准确性

accuracy = accuracy_score(test_generator.classes, y_pred)
print("Accuracy in test set: **%0.1f%%** " % (accuracy * 100))

这给出了 98%的输出精度,这还不错!但是,我们能做得更好吗?我们的数据量有限,那么使用图像增强来改善它怎么样?

图像增强模型:

在我们的例子中,该模型已经表现得非常好,准确率为 97–98%。然而,当处理有限数量的训练数据时,一种策略是“图像增强”。也就是说,我们收集了现有图像的副本,但是做了一些小的修改。这些变化可以是变换,例如轻微旋转、缩放、水平翻转图像、++。此处还介绍了图像增强的更多示例。

在下文中,我们定义了与之前相同的模型,但是这里我们也将图像增强作为一种人工增加训练数据量的方式。

使用与之前相同的卷积基础和模型结构,编写代码来构建新模型:

conv_base = vgg16.VGG16(weights='imagenet', include_top=**False**, pooling='max', input_shape = (img_width, img_height, 3))

*#for layer in conv_base.layers[:-13]:*
*#    layer.trainable = False*model = models.Sequential()
model.add(conv_base)
model.add(layers.Dense(nb_categories, activation='softmax'))

增强功能:

我们代码中唯一需要更改的是下面显示的训练数据生成器的定义。我们可以在这里添加一些数据增加策略,例如[-10,10]度范围内的随机旋转,范围±10%内的随机缩放和宽度/高度移动,以及范围±10%内的亮度变化。

作为增强图像的示例,我们可以将它们保存到指定的文件夹“augm_images ”,如下面的功能“train_generator”中所定义的。此选项目前已被注释掉(以避免保存数千幅图像),但如果您想要可视化您合并的增强,您可以更改此选项。这通常是一个好主意,只是为了确保增强的图像对于您正在处理的用例仍然有意义。

train_datagen = ImageDataGenerator(
        rescale=1./255,
        rotation_range=10,
        zoom_range=0.1,
        width_shift_range=0.1,
        height_shift_range=0.1,
        horizontal_flip=**False**,
        brightness_range = (0.9,1.1),
        fill_mode='nearest'
        )

*# this is a generator that will read pictures found in*
*# subfolers of 'data/train', and indefinitely generate*
*# batches of augmented image data*

train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size, 
*#save_to_dir='augm_images',* 
save_prefix='aug', 
save_format='jpg',
class_mode = "categorical")

使用扩充数据训练新模型

我们现在准备使用额外的增强数据来训练相同的模型,这应该有望提高模型的准确性。

learning_rate = 5e-5
epochs = 20
checkpoint = ModelCheckpoint("sign_classifier_augm.h5", monitor='val_acc', verbose=1, save_best_only=**True**, save_weights_only=**False**, mode='auto', period=1)
model.compile(loss="categorical_crossentropy", optimizer=optimizers.Adam(lr=learning_rate, clipnorm=1.), metrics = ['acc'])history = model.fit_generator(train_generator, 
                              epochs=epochs, 
                              shuffle=**True**, 
                              validation_data=test_generator,
                              callbacks=[checkpoint]
                              )

训练完成后,我们再次加载在训练期间具有最佳验证准确性的检查点文件:

model = models.load_model("sign_classifier_augm.h5")

绘制学习曲线:

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1,len(acc)+1)

plt.figure()
plt.plot(epochs, acc, 'b', label = 'Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
*#plt.savefig('Accuracy_Augmented.jpg')*

plt.figure()
plt.plot(epochs, loss, 'b', label = 'Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
*#plt.savefig('Loss_Augmented.jpg')*

计算并绘制混淆矩阵:

Y_pred = model.predict_generator(test_generator)
y_pred = np.argmax(Y_pred, axis=1)

cm_aug = confusion_matrix(test_generator.classes, y_pred)
plot_confusion_matrix(cm_aug, classes = category_names, title='Confusion Matrix', normalize=**False**, figname = 'Confusion_matrix_Augm.jpg')

计算在测试集上评估的最终准确度:

accuracy = accuracy_score(test_generator.classes, y_pred)
print("Accuracy in test set: **%0.1f%%** " % (accuracy * 100))

这给出了 99.3%的输出,与我们没有增强图像的初始模型相比,这是一个改进!

模型精度的评估:

从上述模型准确性的结果可以看出,数据扩充确实提高了我们模型的准确性。在当前示例中,我们获得了大约 99%的最终准确度。此外,通过检查上面的混淆矩阵,我们可以检查模型错误地分类了哪些标志类别。在这里,我们注意到,在少数情况下,该模型仍然将“交叉点”错误分类为“产量”,但明显优于没有图像增强的模型。

注意:如果重新运行代码时没有得到完全相同的数字,也不用担心!在模型初始化等方面存在一些固有的随机性。这可能会使结果有时略有不同。

从测试集中绘制一些图像,并将模型预测与实际情况进行比较:

作为模型准确性的最终可视化,我们可以绘制测试图像的子集以及相应的模型预测。

为“test_subset”定义一个文件夹,其中包含了测试集中的 50 幅图像:

test_subset_data_dir = "data/test_subset"

test_subset_generator = test_datagen.flow_from_directory(
test_subset_data_dir,
batch_size = batch_size,
target_size = (img_height, img_width),
class_mode = "categorical",
shuffle=**False**)

对该文件夹中包含的图像进行预测,并将图像与预测的和实际的类一起可视化。你同意这些分类吗?

Y_pred = model.predict_generator(test_subset_generator)
y_pred = np.argmax(Y_pred, axis=1)

img_nr = 0
**for** subdir, dirs, files **in** os.walk('data/test_subset'):
    **for** file **in** files:
        img_file = subdir + '/' + file
        image = load_img(img_file,target_size=(img_height,img_width))
        pred_emotion = category_names[y_pred[img_nr]]
        real_emotion = category_names[test_subset_generator.classes[img_nr]]
        plt.figure()
        plt.title('Predicted: ' + pred_emotion + '**\n**' + 'Actual:      ' + real_emotion)
        plt.imshow(image)
        img_nr = img_nr +1

分类模型的输出示例

总结:

如果您设法使用包含的数据集浏览了整个教程,您有望对深度学习和图像识别如何用于解决交通标志分类的现实问题有所了解。祝你好运,用其他图片进一步探索这个模型,这些图片可以来自你的公司,也可以来自 kaggle 等资源,或者只是谷歌图片搜索!

如果你想要更多关于这个图像分类教程(以及一般的机器学习)的详细信息,我还会在下面的研讨会演示中介绍这些材料:“从炒作到现实世界的应用”。(教程演练大约开始。视频开始 35 分钟)。

祝你好运!

你觉得这篇文章有趣吗?如果是这样的话,你可能也会喜欢我的其他一些关于人工智能、机器学习、物理等主题的文章。,你可以在下面的链接和我的中型作者简介中找到:【https://medium.com/@vflovik】

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

[## 通过我的推荐链接加入 Medium—Vegard flo vik

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

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

更多来自 Vegard Flovik 媒体:

  1. 蒙特卡洛方法简介
  2. 从物理学到数据科学的转变
  3. 什么是图论,为什么要关心?
  4. 如何(不)使用机器学习进行时间序列预测:续集
  5. 建造一个能读懂你思想的人工智能
  6. 人工智能和大数据隐藏的风险
  7. 如何使用机器学习进行异常检测和状态监控
  8. 如何(不)使用机器学习进行时间序列预测:避免陷阱
  9. 如何利用机器学习进行生产优化:利用数据提高绩效
  10. 你是怎么把物理教给 AI 系统的?
  11. 我们能使用纳米级磁铁建立人工大脑网络吗?
  12. 供应链管理中的人工智能:利用数据推动运营绩效

深层变分推理

原文:https://towardsdatascience.com/deep-variational-inference-2a7e43244723?source=collection_archive---------26-----------------------

用 DL 体系结构研究变分推理

深度变异推理——伽玛分布

作者:纳坦·卡茨

贝叶斯推理

在机器学习(ML)的世界里,贝叶斯推理经常被当作是没有人愿意采纳的奇特的谜一样的大叔。一方面,贝叶斯推理提供了大量来自数学、统计学和物理学的理论科学工具。此外,它承载着令人印象深刻的科学突破的历史遗产。另一方面,正如几乎每个数据科学家都会说的那样:它在实践中几乎从未奏效。

这篇文章由两部分组成:

1.变分推理的产生概述(六)

2.描述我尝试使用 DL 技术解决一个 VI 问题。

贝叶斯问题

贝叶斯问题可以描述如下:我们有观测数据 X

其中数据可以表示数字、类别或任何其他可以想象的数据类型。我们假设该数据是使用潜在变量 Z. 生成的,我们手头有四种分布:

1.P( Z )潜在变量的先验分布

2.P( X | Z )可能性—此函数的分布类型由数据决定,(例如:如果我们有整数,我们可能会想到泊松,如果我们有正数,我们可能会使用伽马分布)。

3.P( X ) —观测数据的分布。

4.P( Z | X )后验分布——给定值 X 时,具有值 Z 的概率

这些分布通过贝叶斯公式结合在一起:

因此,贝叶斯问题是关于寻找后验分布和 Z 的值。障碍在于,在现实生活的模型中,P(X)很难处理。

直到 1999 年,解决贝叶斯问题的工作方式是利用抽样。诸如 Metropolis Hastings 或 Gibbs 之类的算法被成功地用于在广泛的科学领域中求解后验函数。尽管它们工作得很好,但存在两个重大问题:

高方差

缓慢收敛

1999 年迈克尔·乔丹发表了一篇论文《变分图形模型导论》(这一年更著名的 MJ 退出了,这提出了宇宙是否受“MJ 守恒定律”支配的问题)

在这篇论文中,他描述了贝叶斯问题的解析解。在这个解决方案的核心中,他建议,我们可以通过设置 q 的家族函数引入潜在变量 Z. 的分布函数 q ,而不是通过采样来追踪后验函数,我们可以使用这个 q 来逼近后验函数。对于这个解,他使用了欧拉-拉格朗日方程,这是变分法中的一个基本方程,它带来了的概念:变分推理(VI)

什么是变分推理?

在本节中,我们将详细描述 VI。回想一下,我们的目标是使用函数 q 来逼近后验函数 P( Z | X ),该函数是 Z 的分布。乔丹建议的衡量标准是 KL 散度(https://project Euclid . org/download/pdf _ 1/Euclid . aoms/1177729694

这种解析解的思想减少了高方差和缓慢收敛的障碍。另一方面,由于我们设置了一系列函数,我们引入了一些偏差。以下公式说明了所提供的解决方案:

LHS 不依赖于 Z ,因此可以将其视为常数。最小化 KL 散度相当于最大化第二项:“证据下界”(ELBO)

作为具有预定义形状的函数, q 具有由λ表示的常数。

我们可以将 VI 视为一个 ELBO 最大化问题:

物理!

Jordan 使用这个解决方案的动机来自于 Helmholtz 和 Boltzmann 在热力学方面的工作。ELBO 函数非常类似于亥姆霍兹自由能,其中第一项是能量,第二项是熵。Jordan 使用伊辛模型的平均场定理(MFT ),假设磁自旋不相关,这简化了处理 q 的方式。伊辛问题有一个指数解(玻尔兹曼分布),这成为了 q 形状的普遍选择

VI —示例

我现在将提供一个例子来说明如何制定一个 VI 问题。我们将假设我们有一个高斯似然的实数数据。潜变量 Z,因此是一对

利用平均场定理, q 可以写成乘积

我们在哪里

详细的配方可以在这里找到

https://towards data science . com/variation-inference-in-Bayesian-multivarious-Gaussian-mixture-model-41 c8 cc 4d 82d 7

可以看出,这样的公式需要对每个模型进行大量的分析计算。当我们讨论 BBVI 时,我们将在下面的一个部分中讨论这一点。

2002 年,Blei 发表了他的“潜在的狄利克雷分配”,在那里他使用 VI 进行主题抽取,VI 得到了很大的提升

有几种工具可用于 VI,如 Edward、Stan、PyMC3 和 Pyro

利用 VI 进行分布尾部的推断

我必须处理的问题是识别观察数据的尾部。数据本身是一组概率值,因此我们假设可能性具有贝塔分布。在讨论建模步骤之前,我先举一个尾部典型问题的例子。

让我们假设我们有一个预测疾病的模型,准确率为 99%。我们可以假设 0.1%的人口患病。每天有 10 万人接受测试。990 个健康的人会听到自己有病。这个错误代价很高,因为他们要做医疗程序。出现这种问题主要是因为模型通常被训练成在对称假设下优化准确性。如果我们依赖我们的模型,阈值的微小变化可能会造成巨大的损失。因此,我们需要尽可能准确地理解 1%的尾部。

VI 作为一种分析解决方案,似乎是实现这一目的的一个有趣的工具。令人惊讶的是,我发现 DL 的世界并没有大量拥抱 VI,这确实鼓励我走这条路。

变分推理的深度学习

在这一部分,我将描述我使用 DL 解决 VI 问题的尝试。回想一下,我们的数据的可能性有一个贝塔分布。这个分布有一个非常困难的先验。因此,我们把γ作为先验,因为它在正实线上有支持。在 VI 术语中,γ是先验分布和 q 分布。因此,我们训练 Gamma 对 Z进行采样,Z 本身就是β的{α,β}对。

混合密度网络-MDN

要考虑的第一个框架是 MDN(混合密度网络)。毕晓普(http://publications.aston.ac.uk/id/eprint/373/)提出的这类网络旨在学习给定分布的参数。我们修改损失:而不是使用可能性,我们使用 ELBO。

在所有图中,红色代表我们基于 VI 的样本,蓝色是由随机引擎创建的合成样本。

以下是我们 MDN 试验的典型结果:

基于 VI 的样品相对接近合成样品。然而,它肯定是可以改进的。此外,虽然在内部和左侧(从我的角度来看,这是感兴趣的尾巴)非常相似,但在上部尾巴,我们遭受巨大的差异。

我们希望尝试其他工具。

强化学习——演员评论家

变分推理经常被解释为强化学习问题(http://www 0 . cs . UCL . AC . uk/staff/d . silver/web/Publications _ files/viral . pdf)。我们认为 q 函数为策略函数, Z 为选项,报酬为 ELBO。当我们使用 RL 工具解决此类问题时,我们必须注意到需要进行两项修改:

我们没有插曲——我们有 IID 样本

选项不是离散的,而是伽玛分布的

为了解决第一个子句,我们必须修改 Q 学习更新公式:

因为没有真正的插曲,所以必须去掉第二项,因为它表示未来的预期回报。

关于第二个子句,我们必须训练一个 Gamma 形式的策略函数(这里有一个很好的动机http://proceedings.mlr.press/v70/chou17a/chou17a.pdf

为了训练一个策略函数,我们将使用 actor-critic with experience replayhttps://towards data science . com/understanding-actor-critic-methods-931 b 97 b 6 df 3 f并添加我们的修改。

这些是我们得到的图表:

对于小正值,结果在区间[0,1-a]内相当好。我们完全没有建立上尾翼的模型。

黑盒变分推理

虚拟仪器的出现为研究后验分布提供了新的方向。然而,它对期望值进行了大量的分析计算(参见 Gaussian dist 的例子)。以上)。有一个明确的目标,就是找到一个更通用的方案,减少分析量,更好地处理大量数据。下面的幻灯片是 Blei 对这种需求的描述:

提供的解决方案使用了随机优化。Robbins 和 Monro 提出的一类算法(一种随机近似方法,1951 年)

罗宾斯-门罗算法

罗宾斯门罗算法旨在解决一个根问题:设 F 为函数,α为常数。我们假设方程存在唯一的解:

我们希望找到它。

假设 F 不可观测,但是存在随机变量 T,使得

Robbins 和 Monro 已经表明,对于某些规则,以下算法收敛于 L:

这个序列叫做罗宾斯门罗序列。

返回 BBVI

在 2013 年https://arxiv.org/pdf/1401.0118.pdf的一篇论文中,Blei 建议通过使用 Robbins-Monro 序列对 VI 进行两步改进。这种算法被称为“黑盒变分推理”(BBVI)。第一步如下所示:

主要思想是构建一个针对 ELBO 梯度的蒙特卡罗估计器,并使用 Robbins Monro 序列,如后面部分所述。这种算法(和许多其他蒙特卡罗算法一样)存在高方差。Blei 提出了两种方法来减少这种差异:

在这篇论文中,Blei 使用 Rao Blackwell 通过使用条件分布的 Rao Blackwell 性质来创建每个常数的估计量。

现在绘图

我使用的 BBVI 没有方差减少技术

我们可以看到,与 AC 相比,我们减少了尾部问题,但仍然存在这个问题。在最后一个图中,我们没有尾部问题,但是近似性变弱了

成绩汇总

我们看到,将深度学习工具用于 VI 取得了部分成功。我们在区间内进行了相当好的逼近,但无法逼近上尾部。此外,在所有的框架中,我都遭受了一定程度的不稳定。

有几个看似合理的原因:

DL-问题

建筑不够复杂

更多时代

γ-β问题

传统上,DL 问题是在高斯或均匀等常见分布上研究的。这些分布没有依赖于偏度和峰度的参数。这在 Gamma 中不是这样,在 Gamma 中,由引擎训练的参数完全确定偏斜度和峰度。这可能需要不同的技术

我们用 ELBO 作为损失函数。该函数强烈依赖于先前的形状。伽玛并不是贝塔的真正先验。这可能意味着需要修改损失

Beta 有紧凑的支持。事实上,我们只在尾部附近有问题(分布的一个“奇点”),这可能会带来障碍。这个“奇点”问题有待研究

我们可以总结说,这些实验已经表明 VI 可以使用 DL 机制来解决。然而,这需要进一步的工作。尽管如此,我们还是为这位神秘的叔叔澄清了一些事情。

这里有一个模仿我的试验的 torch 代码(抱歉,真实的代码已经用于我做的一些商业工作)

https://github.com/natank1/DL-_VI

致谢

我要感谢 Uri Itai 在工作之前和期间进行的富有成效的讨论以及他的全面审查,感谢 Shlomo Kashani 和 Yuval Shachaf 提出的想法和意见,感谢 Leonard Newnham 澄清强化学习领域的问题

参考文献

http://www.jmlr.org/papers/volume3/blei03a/blei03a.pdf

https://people . eecs . Berkeley . edu/~ Jordan/papers/variable-intro . pdf

https://towards data science . com/a-hitch illers-guide-to-mixture-density-networks-76b 435826 CCA

https://publications . Aston . AC . uk/id/eprint/373/1/NCRG _ 94 _ 004 . pdf

https://www . ri . CMU . edu/WP-content/uploads/2017/06/thesis-Chou . pdf

http://www.michaeltsmith.org.uk/#

https://github.com/trevorcampbell/ubvi/tree/master/examples

https://arxiv.org/pdf/1811.01132.pdf

http://proceedings.mlr.press/v70/chou17a/chou17a.pdf

https://towards data science . com/understanding-actor-critic-methods-931 b 97 b 6 df 3 f

https://www . freecodecamp . org/news/an-intro-to-advantage-actor-critic-methods-let-play-sonic-the-hedgehog-86d 6240171d/

http://incompleteideas.net/book/the-book-2nd.html

https://arxiv.org/pdf/1401.0118.pdf

https://towards data science . com/variation-inference-in-Bayesian-multivarious-Gaussian-mixture-model-41 c8 cc 4d 82d 7

https://project Euclid . org/download/pdf _ 1/Euclid . aoms/1177729586

http://edwardlib.org/tutorials/klqp

https://mc-stan.org/users/interfaces/

https://github.com/stan-dev/pystan/tree/develop/pystan

https://docs.pymc.io/notebooks/getting_started.html

https://project Euclid . org/download/pdf _ 1/Euclid . aoms/1177729694

https://www . cs . Princeton . edu/courses/archive/fall 11/cos 597 c/lessons/variation-inference-I . pdf

http://publications.aston.ac.uk/id/eprint/373/

https://www . researchgate . net/profile/Thomas _ Leitner/publication/14066429/figure/fig 1/AS:349553518759937 @ 1460351461646/The-gamma-distribution-described-by-different-shape-parameters-01-to-13-15-17 . png

深度行走:被忽视的 NLP 和图数据结构的私生子

原文:https://towardsdatascience.com/deep-walk-the-overlooked-lovechild-of-nlp-and-graph-data-structures-657793831800?source=collection_archive---------31-----------------------

随机漫步和 Word2Vec 优于矩阵分解,产生了惊人的强大的节点嵌入

信用:Pixabay

该理论

近年来,自然语言处理(NLP)经历了创新的复兴;似乎每年都有一些新的算法超越了它的前辈。例如,开创性的论文“注意是你所需要的”真正震撼了 NLP 雪花玻璃球,使以前的艺术级神经网络架构,如 LSTM,相形见绌。然而,您可能会惊讶地听到,随着神经网络的应用,图形数据结构刚刚达到学术兴趣的顶峰。

图形很棘手;它们可以被表示为(邻接)矩阵,但是它们也可以被表示为它们自己独特的数据结构,其中每个节点引用同一图中可变数量的其他节点。这种可变性是图表如此迷人的真正原因——它们不完全是表格数据,很容易用矩阵表示,但也不完全是非结构化的。事实上,有些人可能会认为图像比图表更具结构性。图像的内容可能变化很大,但是给定指定的尺寸,每个像素都有相同数量的相邻像素(邻居)。相反,图节点的邻居数量是可变的。尽管有其微妙的本质,图表在社会中随处可见;社交网络、电网和供应链只是图形多功能性的几个明显例子。

人们对一些问题进行了大量思考,比如“如何最好地搜索一个图——先搜索深度还是广度?”但是越来越多的人对寻找节点间的相似性(或相异性)感兴趣。这可以用于人道主义目标(例如,根据以前的病毒爆发位置及其结构,确定潜在的病毒爆发高风险城市)或简单的商业目标(例如,向应用程序用户推荐朋友和/或产品)。)

考虑推荐系统——不是所有的用户都喜欢相同数量的产品,也不是所有的产品都被相同数量的用户喜欢;它几乎要求图形数据结构。然而……使用矩阵和分解技术(比如 SVD)来呈现推荐是非常普遍的。

为了学习节点嵌入,必须以某种方式对图结构进行采样。一种简单(但令人惊讶的有效)的方法是通过随机漫步,这非常简单:从任何给定的节点开始,识别所有邻居,随机选择一个……然后漫步。冲洗并重复,直到你走了足够多的(这需要一些判断并引入一些偏差。)在推荐系统的上下文中,我们的图是 二分图——意味着有两类节点(产品和用户。)这样,给定的随机游走将从一个类的实例跳到另一个类的实例。例如:

*John -> Titanic -> Allie -> Pearl Harbor -> Adam -> The Pianist* 

对图形进行采样有点像在迷宫中漫步;您从一个起点随机行走(在完成行走之前可能会多次返回到起点),并重复这个过程几次。当你完成每一步的时候,你会对迷宫 看起来像 有一个相当不错的想法。然而,在它们目前的形式下,这些随机漫步不能直观地使用。别担心——NLP 来帮忙了!

Google 在 2013 年提出的算法 Word2Vec,可以通过滑动窗口方案来学习单词的相似度。一次看到 x 个单词(在窗口中),一个目标单词和(通常)5 个来自直接周围上下文的上下文单词(duh。)一个神经网络简单地学习回答问题,“是目标词*****(在当前窗口中)的一个上下文词吗?”所以像“狗”这样的词可能有频繁出现的上下文词,如“散步”和“宠物”同样,“猫”这个词可能有半相似的上下文词(也许不包括散步——我不知道谁会带着猫散步。我们能够通过任何两个单词共享(或不共享)相同上下文的频率来量化它们之间的相似性。并且这些上下文在嵌入中被捕获(当被目标词“激活”时,完全训练的神经元的神经网络层。)嵌入的观察数值可以通过距离度量(例如余弦相似度)与其他数值进行比较,以确定与单词的相似程度。***

所以我们知道两件事:(A)我们的随机行走产生了语言样本,以及(B) Word2Vec 可以学习给定语言的单词嵌入(或者在我们的例子中,节点嵌入)。这就是深度行走算法的全部内容。

如果您对白皮书感兴趣,请不要再看了!

应用程序

在一家著名的技术公司工作时,我带领一个数据科学实习生团队开发了一个产品,可以将求职者与招聘海报相匹配。竞争对手让求职者充斥着招聘海报,反之亦然。目标不是高质量的比赛,而是注意力超载。如果你找不到工作候选人,说明你不够努力。我的主管想要一款可以帮助求职者和求职者找到对方的产品——不是通过匹配职位,而是通过匹配技能。我拿到的教科书案例是:

X-Corp(一个隐藏身份和利益的假名)例行公事地需要 C++专家;他们上传“软件工程师”的招聘信息,但似乎无法及时找到合格的候选人。 你能做什么?

我思考了这个问题,意识到工作描述和简历没有被充分地分析技能。仅仅一个职位头衔就足以引发 Glassdoor 上的匹配,的确如此。我们需要了解技能对技能、工作对工作以及(最重要的)技能对工作之间的关系。成功学习这些关系的意义是非常有益的。

*由于保密协议状态,我不能提供实际的数据,也不能提供用于解决这个问题的具体架构。然而,我将使用公开可用的数据通过一个综合问题来说明这些概念。劳工统计局维护着一个名为 ONET ( 的数据集,我相信这是职业网络的简称。这个资源由统计学家、经济学家和劳动研究人员维护。一些数据集可以在网上免费获得。感兴趣的是技术技能数据集

技术技能数据预览

我们只对第二列和第三列感兴趣,即职称(title)和技能职称(Example。)这些数据形成了一个二分图,其中给定的工作与多种技能有关系,给定的技能与给定的工作有多种关系。通过一点数据预处理,我们可以从推荐系统中借用一页(尽管我将证明这不如深度行走方法有效。)我们简单地为每个技能-工作关联创建一个“一次性”编码,在工作-技能矩阵中,如果工作需要某项技能,则用 1 表示(如果不需要,则用 0 表示)。与推荐系统没有任何不同!

为了简洁起见,我将把存储库链接留在这里

Pandas 有一些很酷的内置函数,允许我们相对轻松地将上述格式的数据转换成一种热编码。(但是请注意矩阵是多么稀疏!)

数据清理

现在,我们有几个矩阵分解的选项。就个人而言,我更喜欢使用 PyTorch 的基于梯度的方法,使用均方误差成本函数。然而,奇异值分解也在推荐系统中广泛使用。代码细节已在回购中详细说明!

我们可以通过“抽查”节点嵌入来定性地评估我们的性能。我写的一个简单的函数找到正确类别的节点,(工作或技能),给定余弦相似性最小阈值和最大计数阈值。有些结果是直观的,比如数据库管理员,也许还有生物统计学家。然而,像供应链经理和技术作家这样的角色会提出这样一个问题——“一切都是随意相似的吗?“并且有证据支持这个结论,直觉匹配和非直觉匹配都落在余弦相似度范围内(0.8- > 0.9)。也许有意义的比赛只是一个机会的问题?

矩阵分解方法

类别设置为无

注意,在第二个截图中,我将类别设置为 none。这将检索技能和工作;但是,在给定阈值的情况下,我们没有捕获任何作业。事实上,Adobe Systems Illustrator 是 C++第二常见的节点;它比 Python“更相似”,比软件开发人员更相似(如上面的“仅工作匹配”中所示。)

我们可以评估节点嵌入结果的一个有趣的方法是查看它们的二维分布。我们可以通过主成分分析将维数从 10 减少到 2,这保留了模型中的大部分方差,在 2D 表示中捕获。PCA 是一个棘手的概念,我们今天不会在这个理论上绕太远。现在,让我们只检查结果!

矩阵分解 PCA 图

然而,在这种表示中,你看不出职业是用红色编码的,而技能是用蓝色编码的。实际上,所有节点都映射到相同的接近 0 的 x 轴值,而所有有意义的变化都发生在 y 轴上。有一些例外,但这些只是少数的技能。那么…哪里出了问题?

嗯,我们有几个重要的限制要讨论。第一,有近 9000 个技术技能,只有(差不多)1000 个工作岗位。此外,有些工作比其他工作需要更多的技能。因此,与职务对应的给定基准表行的总和可能是相对较高的数字,如 100(意味着该职务拥有 100 项技能)或相对较低的数字,如 10。这里起作用的潜在变量是节点连通性、介数和/或中心性。一些节点与技能有很好的联系,这些技能可能与其他工作有很好的联系,也可能没有。此外,由于工作与技能之间的不平衡,这种一键矩阵非常稀疏。矩阵因式分解需要将一个矩阵分解成两个,当两个矩阵相乘时,返回原矩阵。正如你所看到的,0 的存在远远超过了 1 的影响。

换句话说,就都不具备的技能而言,工作是相似的!当矩阵稀疏性是一个问题时,这种直觉可以应用于推荐系统。**

您可能已经注意到,使用一次性编码矩阵可能不是最理想的。你是对的!我们可以从 NLP 中采用各种编码策略来增强我们的结果…然而,这将不可避免地引入用户偏见。例如,伪 TF-IDF 设计可能会考虑某项技能在所有作业中出现的总次数以及单个作业的总技能数。 Microsoft Excel 在这个数据集中极为常见;应该和 C++这种相对不常见的技能一样有影响力吧?问得好!

(对于那些好奇的人,我还使用 SVD 来分解一个热编码矩阵。这是主成分分析图。)

奇异值分解主成分图

我们可能会花费数周时间来尝试对最佳设计进行特征设计(不管分解技术如何),但此时,让我们后退一步,考虑一种更直观、图形友好的方法。进入——深走。

如前所述,我们需要通过随机游走的图形采样来收集语言的“语料库”。让我们从技能 Python 来考察一个随机游走。

从 Python 开始的随机漫步

请注意,职业统计员出现了 3 次,作为技能、 SAS JMP数据描述数据表之间的中间跳转。随机漫步发现了什么?这些技能有些孤立,没有很好的联系,工作关联也很少。这正是扰乱矩阵分解方法的原因。然而,随机漫步雄辩地抓住了这些技能的中心性(或缺乏中心性)。注意,这个随机漫步是使用 NetworkX 执行的,NetworkX 是一个非常棒的基于 python 的图形/网络建模包。

现在,我们将简单地使用 Gensim 实现,而不是从头开始实现 Word2Vec。为了保持矩阵分解结果的一致性/可比性,我们还将学习 10 个潜在特征。无论是哪种情况,这都是一个你需要关注的超参数——它有效地控制了过度拟合(这在推荐系统和节点嵌入的上下文中是一个棘手的话题)。)

让我们看看 Deep Walk 的表现。请注意,技能和工作都被检索到,这说明它们被映射到相似的空间,但并不是任意地彼此相似——节点相似性差异是有意义的!

为了进一步说明生成的节点嵌入的质量,让我们检查另一个 PCA 图。(还是那句话,职业和红色,技能是蓝色。)

深度行走 PCA 图

****哇!这不仅是美丽的,它显示了我们应该想从我们的嵌入这么多的东西。(A)嵌入分布在更大的空间上。(B)存在主要是“技能”的不同分类区域和主要是“职业”的区域(C)然而,这些区域有适度的重叠,描绘了高度相互关联的节点(无论是技能还是职业。这种方法表现如此之好的一个原因是随机漫步本身。技能可能比职业多,但整个“语料库”采用了 job -> skill -> job -> skill... 的形式,这意味着稀疏的影响将以一种巧妙的方式得到缓解!

最后,我们开始的源问题——我们如何更快地找到 C++程序员?天真的直觉会告诉我们,软件开发人员是现任的 C++专家。然而,我们可以看到物理学家和机器人工程师更接近 C++。我们无法确定为什么会这样,但我们可以提出一些叙述。C++是一种低级语言。web 开发人员越来越多地使用框架,这样他们就不需要不断地重复发明轮子。期望一个 web 开发人员成为安全专家、网络专家、图形渲染专家、数据库专家等等,以及 web 应用程序可能需要的所有元素是不现实的。然而,物理学家可能非常需要知道从同一实验室的工程师设计的传感器中收集数据,一种低级语言将帮助他们最大限度地利用分配给他们的计算资源。

TL/DR —推荐系统广泛使用矩阵分解。当存在最小的阶级不平衡时(无论是用户对产品,工作对技能,等等),这是非常有用的。)像 TF-IDF 这样的编码技巧可以(理论上)增强一键编码产生的结果。然而,稀疏性会极大地限制矩阵分解的有效性。图形友好的方法是推荐系统、信息检索等等的未来!我鼓励您尝试链接存储库中的代码,并将这些技术应用到您自己选择的新颖应用程序中。

如果你认为我的内容没问题,请订阅!😃

DeepAnT——时间序列的无监督异常检测

原文:https://towardsdatascience.com/deepant-unsupervised-anomaly-detection-for-time-series-97c5308546ea?source=collection_archive---------24-----------------------

只有当你有大海捞针的方法时,才能观察到图案的美!

丹尼尔·塔夫乔德在 Unsplash 上的照片

什么是异常现象,我为什么要担心?

“一个异常值”或“异常值”是样本空间中那些异常的数据点,或超出趋势。现在,问题是,“你如何定义异常或异常的东西?”
答:数学上,不在相同趋势中的数据点与其邻域中的数据点相同。

作为业务伙伴或技术专家,在日常工作中从大量数据中发现异常模式。在这里,我们将讨论一种能够以接近实时的格式检测数据中所有(几乎)异常的方法。

在本文中,我们将尝试学习如何从数据中检测异常而无需事先训练模型,因为你无法根据数据训练模型,而我们对此一无所知!
这就是无监督学习的想法出现的地方。
选择时间序列数据的原因是,它们是最常见的真实世界数据之一,我们作为数据科学家进行分析。

来到模型——“DeepAnT”是一个无监督的基于时间的异常检测模型,它由卷积神经网络层组成。在检测时间序列数据中的各种异常时,它确实工作得很好。但这可能需要注意检测噪声,这可以通过调整超参数来处理,如内核大小、回看时间序列窗口大小、隐藏层中的单元等等。

代码和数据的链接在这里的 Github 链接中提供—

[## bmonikraj/medium-ds-unsupervised-异常检测-deepant-lstmae

使用 DeepAnT 和 LSTM 自动编码器数据描述的无监督异常检测的基于深度学习的技术…

github.com](https://github.com/bmonikraj/medium-ds-unsupervised-anomaly-detection-deepant-lstmae)

数据中的特征数= 27(包括'时间戳'特征)
数据特征类型=数值

现在我们知道了数据,让我们进入代码库,解决我们遇到的问题。
问题描述:-我们有大约 80 年的加拿大气候数据(数据频率=每天),我们想从气候数据中识别异常。

import numpy as np
import pandas as pd
import torch
from sklearn.preprocessing import MinMaxScaler
import time
import datetime
import matplotlib.pyplot as plt
import seaborn as sns
import os

data_file = ""
MODEL_SELECTED = "deepant" *# Possible Values ['deepant', 'lstmae']*
LOOKBACK_SIZE = 10
for dirname, _, filenames **in** os.walk('/kaggle/input'):
    for filename **in** filenames:
        data_file = os.path.join(dirname, filename)

模块被导入,文件被加载到 Kaggle 内核的环境中。

def read_modulate_data(data_file):
    *"""*
 *Data ingestion : Function to read and formulate the data*
 *"""*
    data = pd.read_csv(data_file)
    data.fillna(data.mean(), inplace=True)
    df = data.copy()
    data.set_index("LOCAL_DATE", inplace=True)
    data.index = pd.to_datetime(data.index)
    return data, df

在上面的代码片段中,我们从文件中读取数据,该文件存在于环境中。
读取后,我们将索引数据转换为时间戳
将时间戳作为数据索引的主要动机是,如果需要,通过数据帧图和重采样进行更好的分析。

def data_pre_processing(df):
    *"""*
 *Data pre-processing : Function to create data for Model*
 *"""*
    try:
        scaled_data = MinMaxScaler(feature_range = (0, 1))
        data_scaled_ = scaled_data.fit_transform(df)
        df.loc[:,:] = data_scaled_
        _data_ = df.to_numpy(copy=True)
        X = np.zeros(shape=(df.shape[0]-LOOKBACK_SIZE,LOOKBACK_SIZE,df.shape[1]))
        Y = np.zeros(shape=(df.shape[0]-LOOKBACK_SIZE,df.shape[1]))
        timesteps = []
        for i **in** range(LOOKBACK_SIZE-1, df.shape[0]-1):
            timesteps.append(df.index[i])
            Y[i-LOOKBACK_SIZE+1] = _data_[i+1]
            for j **in** range(i-LOOKBACK_SIZE+1, i+1):
                X[i-LOOKBACK_SIZE+1][LOOKBACK_SIZE-1-i+j] = _data_[j]
        return X,Y,timesteps
    except **Exception** as e:
        print("Error while performing data pre-processing : **{0}**".format(e))
        return None, None, None

在这里,我们在[0,1]的范围内对数据进行标准化,然后通过将“时间步长”作为一个维度纳入图片来修改数据集。
想法是将维度数据集从[Batch Size, Features]转换到[Batch Size, Lookback Size, Features]

class **DeepAnT**(torch.nn.Module):
    *"""*
 *Model : Class for DeepAnT model*
 *"""*
    def __init__(self, LOOKBACK_SIZE, DIMENSION):
        super(DeepAnT, self).__init__()
        self.conv1d_1_layer = torch.nn.Conv1d(in_channels=LOOKBACK_SIZE, out_channels=16, kernel_size=3)
        self.relu_1_layer = torch.nn.ReLU()
        self.maxpooling_1_layer = torch.nn.MaxPool1d(kernel_size=2)
        self.conv1d_2_layer = torch.nn.Conv1d(in_channels=16, out_channels=16, kernel_size=3)
        self.relu_2_layer = torch.nn.ReLU()
        self.maxpooling_2_layer = torch.nn.MaxPool1d(kernel_size=2)
        self.flatten_layer = torch.nn.Flatten()
        self.dense_1_layer = torch.nn.Linear(80, 40)
        self.relu_3_layer = torch.nn.ReLU()
        self.dropout_layer = torch.nn.Dropout(p=0.25)
        self.dense_2_layer = torch.nn.Linear(40, DIMENSION)

    def forward(self, x):
        x = self.conv1d_1_layer(x)
        x = self.relu_1_layer(x)
        x = self.maxpooling_1_layer(x)
        x = self.conv1d_2_layer(x)
        x = self.relu_2_layer(x)
        x = self.maxpooling_2_layer(x)
        x = self.flatten_layer(x)
        x = self.dense_1_layer(x)
        x = self.relu_3_layer(x)
        x = self.dropout_layer(x)
        return self.dense_2_layer(x)

我们正在创建模型 DeepAnT 架构(关于论文的更多信息可以在 IEEE 的链接— 研究论文中找到)。
它包含两层卷积层,在确定数据时间模式中的异常时非常有效。
可以根据数据进一步调整内核大小和过滤器数量,以实现更好的性能。

让我们来看看模型架构,以便更好地直观理解—

由 Mohsin Munir、Shoaib Ahmed Siddhiqui、Andreas Dengel 和 Sheraz Ahmed 撰写的 IEEE 论文中的 DeepAnT 模型架构

def make_train_step(model, loss_fn, optimizer):
    *"""*
 *Computation : Function to make batch size data iterator*
 *"""*
    def train_step(x, y):
        model.train()
        yhat = model(x)
        loss = loss_fn(y, yhat)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()
        return loss.item()
    return train_step

功能make_train_step是创建迭代器,它可以向计算模型提供小批量的数据。

MSE 损失函数传递给 make_train_step 函数,Adam 优化器用于多个历元后的损失函数优化和收敛。

def compute(X,Y):
    *"""*
 *Computation : Find Anomaly using model based computation* 
 *"""*
    if str(MODEL_SELECTED) == "deepant":
        model = DeepAnT(10,26)
        criterion = torch.nn.MSELoss(reduction='mean')
        optimizer = torch.optim.Adam(list(model.parameters()), lr=1e-5)
        train_data = torch.utils.data.TensorDataset(torch.tensor(X.astype(np.float32)), torch.tensor(Y.astype(np.float32)))
        train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=32, shuffle=False)
        train_step = make_train_step(model, criterion, optimizer)
        for epoch **in** range(30):
            loss_sum = 0.0
            ctr = 0
            for x_batch, y_batch **in** train_loader:
                loss_train = train_step(x_batch, y_batch)
                loss_sum += loss_train
                ctr += 1
            print("Training Loss: **{0}** - Epoch: **{1}**".format(float(loss_sum/ctr), epoch+1))
        hypothesis = model(torch.tensor(X.astype(np.float32))).detach().numpy()
        loss = np.linalg.norm(hypothesis - Y, axis=1)
        return loss.reshape(len(loss),1)
    else:
        print("Selection of Model is not in the set")
        return None

最后一步是通过数据运行模型(批量)。我们使用 MSE 损失函数和 Adam 优化器,并在 30 个时期内运行。
此后,我们生成假设并计算损失,即数据集中给定的各个时间戳的异常置信度得分。

形象化

异常置信度得分的频率分布|作者图片

异常可信度分数与时间戳(freq="daily") |作者图片

看上面的两个图,我们可以得出结论,异常置信度得分大于 1.2 的时间戳是那些可以被视为潜在异常的时间戳,并且可以通过分析采取进一步的行动:)

  • DeepAnT 是一种适用于基于时间序列的异常检测的体系结构模型。
  • 用于类似问题的其他架构有:LSTM 自动编码器、具有时间信息的 kNN 聚类。
  • 时间序列数据,在需要实时分析的情况下,应该考虑数据流。

对于想直接在 Kaggle 内核上运行的:)

[## 无监督时间序列异常检测

使用 Kaggle 笔记本探索和运行机器学习代码|使用加拿大 80 年的气候数据

www.kaggle.com](https://www.kaggle.com/bmonikraj/unsupervised-timeseries-anomaly-detection/notebook)

如有任何疑问,请通过bmonikraj@gmail.com联系我本人

deep chem——在生命科学和化学信息学中使用 ML 和 DL 的框架

原文:https://towardsdatascience.com/deepchem-a-framework-for-using-ml-and-dl-for-life-science-and-chemoinformatics-92cddd56a037?source=collection_archive---------28-----------------------

使 ML 和 DL 在药物发现、材料科学、量子化学和生物学中的使用民主化。

图片来源: Pixabay

将机器学习和深度学习应用于药物发现、基因组学、显微观察和量子化学可以产生根本性的影响,并有可能显著加快医学研究和疫苗开发的进程,这是任何像 Covid19 这样的疫情所必需的。

在我们开始之前,这篇文章是一篇非常高水平的文章,专门针对对药物发现感兴趣的数据科学家和 ML 研究人员,尤其是在像 Covid19 这样的现有疫情时期。

DeepChem 是一个开源框架,内部使用 TensorFlow,该框架专门用于简化各种生命科学应用的深度学习模型的创建。

在本教程中,我们将了解如何设置 DeepChem,以及如何将 DeepChem 用于:

1.训练一个可以预测分子毒性的模型

2.训练预测分子溶解度的模型

3.使用智能字符串查询分子结构。

设置 DeepChem

虽然,在多个来源中,我看到用户表达了他们对在 Windows、Linux 和 Mac 环境中设置 DeepChem 的关注,但是我发现使用 pip 安装程序很容易做到这一点。

DeepChem 开发团队非常活跃,他们确实提供每日构建,所以我希望每个人都能看看他们的 pypi 页面:https://pypi.org/project/deepchem/#history并安装一个合适的版本,以防最新版本有任何问题。一个简单的 pip 安装 deepchem 将会安装最新的版本。

接下来,除了 DeepChem,您还需要安装 TensorFlow。我已经使用 pip install tensorflow 和开源化学信息学软件包 RDkit 安装了最新版本的 TensorFlow。对于 RDkit 和在 Windows 中安装,我没有找到任何可靠的 pip 安装程序,所以使用 conda 安装程序从https://anaconda.org/rdkit/rdkit安装它:conda install-c RDkit RDkit

一旦这三个模块安装完毕,我们就可以开始实验了。

预测分子的毒性

分子毒性可以被定义为一种物质对任何有机体表现出的副作用的总和。计算方法实际上可以利用分子的化学和结构特性来确定给定化合物的毒性,并利用分子描述符(Dong 等人, 2015 )和指纹(薛和 Bajorath,【2000】)来确定分子特征,可以有效地提取任何给定分子固有的化学和结构信息,用于基于预测的方法。

为了预测毒性,我们将使用 MoleculeNet 的 Tox21 毒性数据集,并使用 DeepChem 加载所需的数据集。

import numpy as np
import deepchem as dc
tox21_tasks, tox21_datasets, transformers = dc.molnet.load_tox21()

在此之后,我们将看到所有的毒性类,只是打印到 21_tasks

['NR-AR',
 'NR-AR-LBD',
 'NR-AhR',
 'NR-Aromatase',
 'NR-ER',
 'NR-ER-LBD',
 'NR-PPAR-gamma',
 'SR-ARE',
 'SR-ATAD5',
 'SR-HSE',
 'SR-MMP',
 'SR-p53']

我们可以通过以下方式将整个数据集分为训练、测试和验证数据集:

train_dataset, valid_dataset, test_dataset = tox21_datasets

如果我们检查数据集的分布,我们会发现数据集是不平衡的,因此我们需要平衡数据集,因为通常我们会尝试解决多类分类问题。因此,如果数据集不平衡,多数类会给分类器增加偏差,这会扭曲结果。因此,默认使用的 transformer 对象是一个平衡转换器。

print(transformers)
[<deepchem.trans.transformers.BalancingTransformer at 0x26b5642dc88>]

现在,对于培训部分:

model = dc.models.MultitaskClassifier(n_tasks=12, n_features=1024, layer_sizes=[1000])
model.fit(train_dataset, nb_epoch=10)
metric = dc.metrics.Metric(dc.metrics.roc_auc_score, np.mean)
train_scores = model.evaluate(train_dataset, [metric], transformers)
test_scores = model.evaluate(test_dataset, [metric], transformers)

现在,DeepChem 的子模块包含各种 dc.models 不同的生命科学专用模型。

最后我们看到,最终的 AUC-ROC 分数是:

{'training mean-roc_auc_score': 0.9556297601807405}
{'testing mean-roc_auc_score': 0.7802496964641786}

这向我们表明,在模型中存在一些过度拟合,因为与训练集相比,测试数据集度量得分要少得多。但是,尽管如此,现在我们确实有了一个可以预测分子毒性的模型!

预测分子的溶解度

溶解度是一种度量,它显示了分子在水中溶解的难易程度。对于任何药物发现,检查化合物的溶解度是非常重要的,因为药物应该溶解到患者的血流中,以达到所需的治疗效果。通常,药物化学家花费大量时间来修饰分子以增加溶解性。在本节中,我们将使用 DeepChem 来预测分子的溶解度。

我们将使用 MoleculeNet 的 delaney 数据集来预测分子溶解度,该数据集也可在 DeepChem 中获得。

# load the featurized data 
tasks, datasets, transformers = dc.molnet.load_delaney(featurizer='GraphConv')# Split into traintest-validation dataset
train_dataset, valid_dataset, test_dataset = datasets# Fit the model
model = dc.models.GraphConvModel(n_tasks=1, mode='regression', dropout=0.2)
model.fit(train_dataset, nb_epoch=100)# Use r2 score as model evaluation metric
metric = dc.metrics.Metric(dc.metrics.pearson_r2_score)
print(model.evaluate(train_dataset, [metric], transformers))
print(model.evaluate(test_dataset, [metric], transformers))

甚至在第一遍中,我们从模型评估结果中看到一些过度拟合。

{'training pearson_r2_score': 0.9203419837932797}
{'testing pearson_r2_score': 0.7529095508565846}

让我们看看如何预测一组新分子的溶解度:

smiles = ['COC(C)(C)CCCC(C)CC=CC(C)=CC(=O)OC(C)C',
'CCOC(=O)CC',
'CSc1nc(NC(C)C)nc(NC(C)C)n1',
'CC(C#C)N(C)C(=O)Nc1ccc(Cl)cc1',
'Cc1cc2ccccc2cc1C']

接下来,我们需要从它们的 SMILES 格式来描述这些新的分子

from rdkit import Chem
mols = [Chem.MolFromSmiles(s) for s in smiles]
featurizer = dc.feat.ConvMolFeaturizer()
x = featurizer.featurize(mols)predicted_solubility = model.predict_on_batch(x)
predicted_solubility

因此,我们可以看到预测的溶解度值:

array([[-0.45654652],
       [ 1.5316172 ],
       [ 0.19090167],
       [ 0.44833142],
       [-0.32875094]], dtype=float32)

我们很容易看到 DeepChem 如何使上述两个用例变得非常容易,这可能需要一个人类化学家花很多时间来解决这些问题!

对于最后一部分,我们将看到一些可视化和查询技术作为 RDkit 的一部分,这是任何人在处理这种用例时都非常需要的。

智能字符串来查询分子结构

SMARTS 是前面描述的 SMILES 语言的扩展,可用于创建查询。

# To gain a visual understanding of compounds in our dataset, let's draw them using rdkit. We define a couple of helper functions to get startedimport tempfile
from rdkit import Chem
from rdkit.Chem import Draw
from itertools import islice
from IPython.display import Image, displaydef display_images(filenames):
    """Helper to pretty-print images."""
    for file in filenames:
          display(Image(file))def mols_to_pngs(mols, basename="test"):
    """Helper to write RDKit mols to png files."""
    filenames = []
    for i, mol in enumerate(mols):
        filename = "%s%d.png" % (basename, i)
        Draw.MolToFile(mol, filename)
        filenames.append(filename)
    return filenames

现在,让我们来看一个微笑的样本,并想象它的分子结构。

from rdkit import Chem
from rdkit.Chem.Draw import MolsToGridImage
smiles_list = ["CCCCC","CCOCC","CCNCC","CCSCC"]
mol_list = [Chem.MolFromSmiles(x) for x in smiles_list]
display_images(mols_to_pngs(mol_list))

这就是视觉结构是如何从微笑字符串形成的。

现在,假设我们想要查询具有三个相邻碳的微笑字符串。

query = Chem.MolFromSmarts("CCC")
match_list = [mol.GetSubstructMatch(query) for mol in
mol_list]
MolsToGridImage(mols=mol_list, molsPerRow=4,
highlightAtomLists=match_list)

我们看到,突出显示的部分,代表有三个相邻碳的化合物。

同样,让我们看看一些通配符查询和其他子结构查询选项。

query = Chem.MolFromSmarts("C*C")
match_list = [mol.GetSubstructMatch(query) for mol in
mol_list]
MolsToGridImage(mols=mol_list, molsPerRow=4,
highlightAtomLists=match_list)

query = Chem.MolFromSmarts("C[C,N,O]C")
match_list = [mol.GetSubstructMatch(query) for mol in
mol_list]
MolsToGridImage(mols=mol_list, molsPerRow=4,
highlightAtomLists=match_list)

因此,我们可以看到,选择性子查询也可以很容易地处理。

因此,这就把我们带到了本文的结尾。我知道这篇文章水平很高,专门针对对药物发现感兴趣的数据科学家和 ML 研究人员,尤其是在 Covid19 等现有疫情的时代。希望我能帮上忙!如果你在生物信息学或化学信息学方面有很强的背景,并希望进入数据科学领域,请通过这里提到的**中的任何选项联系我。继续关注:https://medium.com/@adib0073和我的网站:https://www.aditya-bhattacharya.net/了解更多

DeepDow —深度学习的投资组合优化

原文:https://towardsdatascience.com/deepdow-portfolio-optimization-with-deep-learning-a3ffdf36eb00?source=collection_archive---------19-----------------------

DeepDow 是一个 Python 包,专注于在单次正向传递中执行资产分配的神经网络。

单前锋传球?

投资组合优化传统上是一个两步程序:

  1. 建立对证券未来表现的信念
  2. 根据这些信念寻找最优投资组合

两步程序的一个臭名昭著的例子(受 Markowitz 启发)是

  1. 预期收益估计 μ 和协方差矩阵σ
  2. 求解凸优化问题

通常,这两个步骤是完全分开的,因为它们需要不同的方法和不同的软件。

deepdow绝对抛弃这种范式。它力求将上述两个步骤合二为一。基本思想是构建端到端的深度网络,输入最原始的特征(回报、交易量……)并输出资产配置。这种方法有多种好处:

  • 超参数可以变成可训练的重量(即第二阶段的𝛾)
  • 利用深度学习提取有用的特征进行分配,不需要技术指标
  • 单一损失函数

核心理念

金融时间序列可以被视为一个三维张量,具有以下维度

  • 时间
  • 资产
  • 指示器/通道

举一个具体的例子,我们可以研究多个纳斯达克股票(资产维度)的每日(时间维度)开盘价回报、收盘价回报和交易量(渠道维度)。形象地说,人们可以想象

通过固定一个时间步长(代表现在),我们可以将张量分成 3 个不相交的子张量

首先, x 代表所有关于过去和现在的知识。第二个张量 g 代表包含在不久的将来的信息,我们不能用它来做投资决策。最后, y 是市场的未来演变。现在可以沿着时间维度移动,并在每个时间步长应用相同的分解。这种生成数据集的方法称为滚动窗口。

现在我们关注一种特殊类型的神经网络,它输入 x 并返回所有资产的单个权重分配 w ,使得它们的总和为 1。换句话说,根据我们过去的知识, x 我们构建了一个投资组合, w 我们立即买入并持有一段时间。设 F 是带有参数𝜃的神经网络,下图代表高级预测管道。

难题的最后一块是损失函数的定义。在最一般的术语中,每样本损失 L 是输入 wy 并输出实数的任何函数。然而,在大多数情况下,我们首先计算投资组合在时间范围内每个时间步的回报率 r ,然后应用一些汇总函数 S 如均值、标准差等。

网络层

好吧,但是我们如何构建这样的网络呢?不是硬编码一个单一的架构deepdow实现强大的构建块(层),用户可以自己组装。两个最重要的图层组是

变形层

目标是从输入中提取特征。

  • RNN
  • 1D 卷积
  • 时间扭曲

分配层

给定输入张量,它们输出有效的资产分配。

  • 可微凸优化(cvxpylayers)即 Markowitz
  • Softmax(稀疏和约束变量也是)
  • 基于聚类的分配器

一般的模式是创建一个由多个转换层组成的管道,最后是一个分配层。注意,几乎任何实值超参数都可以变成一个可学习的参数,甚至可以被某个子网络预测。

想了解更多?

如果这篇文章引起了你的兴趣,请随时查看下面的链接。

我将非常乐意回答任何问题。此外,建设性的批评或帮助发展是非常受欢迎的。

Deepfake 检测超级难!!!

原文:https://towardsdatascience.com/deepfake-detection-is-super-hard-38f98241ee49?source=collection_archive---------28-----------------------

脸书 Deepfake 检测挑战赛回顾与分析。

照片由 stock.adobe.com 斯塔夫罗斯授权

人工智能(AI)和云计算技术的最新进展导致了音频、视频和图像处理技术的快速发展。这种合成媒体内容通常被称为“deep fakes【1】”基于人工智能的工具可以以越来越可信的方式操纵媒体,例如通过复制一个公众人物的声音或将一个人的脸叠加在另一个人的身体上。

这本书现已在亚马逊上架——https://www . Amazon . com/deep fakes-aka-Synthetic-Media-Humanity-ebook/DP/b0b 846 ycnj/

立法、政策、媒体素养和技术必须协同工作,为恶意使用 deepfakes 提供有效的补救措施。

用于减轻 deepfakes 影响的技术对策分为三类:媒体认证、媒体出处和 deepfake 检测。

媒体身份验证包括通过使用水印、媒体验证标记、签名和监管链记录来帮助证明整个媒体生命周期的完整性的解决方案。身份验证是防止对可信媒体进行欺骗性操作的最有效方法,因为它可以在整个内容生命周期中验证和跟踪完整性,或者在分发端点进行验证。

媒体出处包括提供关于媒体来源的信息的解决方案,或者在媒体本身中,或者作为媒体的元数据。反向媒体搜索也可以是一个有效的出处工具,一个特定媒体过去出现过的网站列表可以用来证明媒体的来源。出处和认证一起,可以提供重要的取证工具来帮助揭穿 deepfakes。

Deepfake 检测包括利用多模式检测技术来确定目标媒体是否被操纵或合成生成的解决方案。现有的检测技术可以大致分为手动和算法方法。手工技术包括人类媒体法医从业者,通常配备有软件工具。算法检测使用基于人工智能的算法来识别被操纵的媒体。

由于大多数 deepfakes 都是通过对抗性训练(GANs)创建的,因此 creator 算法规避基于人工智能的检测方法的能力将随着它们被引入新的检测系统而提高。如果创建者可以使用它,任何检测器都将有很短的保质期。

业内有一个广泛的共识,即 deepfake 检测可能在短期内解决问题,但从长远来看,实际的解决方案将是认证和出处技术,以及媒体素养。

我将在以后的文章中更详细地讨论技术对策。]

脸书 Deepfake 检测挑战赛(DFDC)结果

最好的模型在真实世界的数据上有 65%的准确率。这些结果增加了 deepfake 检测的难度,并强调了人工智能模型在减轻合成媒体威胁方面的局限性。

2019 年 9 月,脸书与微软、AWS、Partnership on AI 合作,在 Kaggle 宣布了 Deepfake 检测挑战赛( DFDC ),邀请研究人员开发 deepfake 检测算法。为了提供数据来训练潜在的算法,脸书雇佣了 3500 名演员来录制数千个视频,然后使用各种 deepfake cheapfake 创作技术对这些视频进行处理。总共向研究人员发布了 100,000 个原始和被操纵内容的视频剪辑,作为建立 deepfake 检测器算法的训练集。值得注意的是,这个数据集包括了比以前的训练数据集更多样化和包容性的演员。

挑战赛的提交于 3 月 31 日截止,脸书于 6 月 12 日宣布了比赛的结果。

超过 2000 名参与者提交了 35,000+个检测算法。性能最好的模型使用了谷歌的 EfficientNet 算法,这是一种高性能和可扩展的卷积神经网络 (CNN)。

脸书在这里发表了一篇详细介绍这场竞争的论文

在 DFDC 的训练数据上,获胜团队的准确率达到了 82.56%。虽然这看起来很高,但同样的算法在不可预见的真实世界 deepfakes 中获得了 65.18%的精度* 。

DFDC 结果数据的主要观察结果:

  1. 约 65%的精度意味着系统识别为阳性(deepfakes)的 deepfakes 中有 35%是假阳性(不是 deepfakes)。被算法归类为 deepfakes 的 1/3 的 deepfakes 不是 deepfakes。
  2. 在 65%精度的算法中,召回率(或算法识别为真阳性的 deepfakes 的数量与数据集中实际 deepfakes 的数量相比的度量)约为 50%(请参见下面的精度召回率图表)。也就是说,该算法在 50%的情况下将真实视频识别为 deepfake(假阳性)。一半的时间算法不能识别一个深假。
  3. ROC(受试者操作特征)上的 AUC(曲线下面积)是~0.7,ROC 是真阳性率(TPR)和假阳性率(FPR)的图。获胜的算法并没有表现得特别好,相比之下,一个简单的模型,如扔硬币算法,可以实现 0.5[2]的 AUC。

DFDC 的结果增加了检测 deepfake 的难度。除了媒体识读措施之外,最有希望的技术对策仍然是认证和出处技术。

关于 AI 的伙伴关系(PAI)建议

PAI 在 2019 年末创建了 AI 和媒体完整性指导委员会,作为合作伙伴的正式机构,开发和建议加强错误/虚假信息解决方案的项目,包括检测操纵和合成内容。DFDC 是人工智能和媒体诚信指导委员会的第一个项目。他们发表了一份关于 DFDC 的重要经验的报告。

关于 Deepfake 检测的主要建议:

  1. 单靠检测无法解决信息完整性挑战。
  2. 检测应该结合真实世界例子和线索才有意义。
  3. 检测能力必须以易于理解的界面扩展到记者、事实审查员和民间社会团体。
  4. Deepfake 检测解决方案的开发面临着开源数据集和模型与阻止对手使用这些资源来改进 deep fake 之间的权衡。
  5. 在这个问题领域,我们需要一个有意义的多利益攸关方协作方法。

该报告是了解 deepfake 检测挑战和有效对策建议的重要资源。

DFDC 结果的技术分析

一些技术术语的词汇表和机器学习度量的快速指南。

真阳性(TP) : Deepfakes 被检测为 Deepfakes

真阴性(TN) :非 Deepfakes 检测为非 deepfakes。

假阳性(FP) :非 Deepfakes 检测为 deepfakes。

假阴性(FN) : Deepfakes 被检测为非 Deepfakes。

准确率:定义为找到的所有准确数据(TP+TN)与所有数据(TP+FP+TN+FN)的比值。对于 DFDC 上下文,由于类偏斜,不使用精度,而是使用加权精度。

DFDC 的精确测量:由于深度假检测(分类真阳性)比真阴性(非深度假阳性)更关键,并且由于类别偏斜,真实世界中假与真视频的不平衡,假阳性数字(非深度假阳性)将为任何模型提供高精确度。脸书创建了一个加权精度指标来衡量算法的有效性。将权重添加到假阳性以使假阳性标准化,从而使检测模型具有实际效用。

:也称为特异性,由算法分类出的所有阳性 deepfakes (TP)中的真阳性 deep fakes(TP)计算得出,包括假阳性,(TP+FP)。

精度= TP / (TP + FP)

由于 DFDC 模型的精度是 65%,这意味着系统识别为阳性的 deepfakes(deep fakes)中有 35%不是 deep fakes。这些算法有 35%的时候将非 deepfakes 错误分类为 deepfakes,这是非常高的。

****回忆:也称为模型的敏感度,计算为真阳性(deepfakes)与数据集中所有真 deepfakes 的比值(TP + FN)。

召回= TP / (TP + FN)

根据下面 0.65 精度的图表,召回率约为 50%,这意味着最好的模型将真实视频归类为 deepfake 的概率为 50%。

****F1 得分:理想情况下,我们想要一个没有误报(精度= 1)和漏报(召回= 1)的算法。因此,算法的性能通常由 F1 分数来衡量,F1 分数是精确度和召回率的调和平均值。根据域,您可以调整可接受的误报和漏报的阈值。像在晚期疾病分类场景中,假阴性可能具有可怕的后果,因此更高的召回(低假阴性)是期望的。对于垃圾邮件分类器,误报(错过重要邮件)可能是不可接受的,但误报(收到垃圾邮件)是可以的,因此他们可以同意较低的召回率但较高的精确度。

F1 得分= 2 (精度召回)/(精度+召回)

对于 DFDC 算法来说,F1 值(0.65 的精度和 0.5 的召回率)是 0.56,在我看来,这对于 DFDC 算法来说不是一个好的性能指标。该算法在假阳性和假阴性上都是错误的。

受试者操作者特征(ROC) 曲线:是真阳性率和假阳性率的曲线。曲线下面积(AUC)是算法性能的良好指示。我突出显示了 AUC。

精确召回曲线https://arxiv.org/abs/2006.07397

**ROC (TPR FPR 曲线)【https://arxiv.org/abs/2006.07397 **

喜欢吗? 随便给我买本书

参考文献:

【1】https://www . vice . com/en _ us/article/bjye 8a/Reddit-fake-porn-app-daisy-Ridley

【2】https://people.inf.elte.hu/kiss/11dwhdm/roc.pdf

Deepfake 通过使用生成式对抗网络(GANs)来绕过面部识别

原文:https://towardsdatascience.com/deepfake-to-bypass-facial-recognition-by-using-generative-adversarial-networks-gans-37a8194a87b1?source=collection_archive---------25-----------------------

随着面部识别软件越来越多地用于解锁智能手机和电脑,仅举几个用例,Deepfakes 将使实现真正的面部识别成为可能。随着我们达到一个更高的水平,科技正在迅速进步,在这个水平上,很难区分欺骗和朋友。

Deepfake 使用深度学习 AI 将视频中一个人的面部和声音替换为他们自己的面部、声音或两者的组合。人工智能(AI)的进步是近年来人机交互领域最令人兴奋的发展之一,但还有很长的路要走。

目前有许多涉及虚假语言技巧的欺诈案例,例如试图说服公司的一名员工将钱转到一个欺诈账户[1]。欺诈者使用被称为生成式对抗网络(GANs)的分析技术,为此转向 Deepfake,创造了一种无法区分真实事物和 Deepfakes 的方法。这使得保证收费变得相当困难,因为无法区分合法和假冒[8]。

生成对抗网络(GANs) [2]是一种较新的分析技术,另一方面,它可以以虚假图像和视频的形式产生假阳性和假阴性。这种现象的一个更近的表现是 Deepfake,这是一种人工智能驱动的技术,可以产生极其逼真的文本、图像或视频,人类很难将其与赝品区分开来。

幸运的是,Deepfakes 背后的技术也是可以检测欺诈的技术[3]。随着计算能力的增长和算法变得更快,深度假货正在成为远程客户识别的越来越大的威胁。目前,由虚假视频驱动的技术还不足以推翻现有的生物识别技术。然而,已经有一些高调的尝试访问账户,并覆盖使用假视频的生物特征数据和身份验证解决方案[7]。

通过结合使用人工智能和生物面部识别,公司可以验证用户,而不必通过驾照或护照等身份证明来验证他们的实际存在。Deepfakes 的使用可以绕过这些生物特征和身份证明,获取个人数据[4]。

生物面部识别技术的使用被监管机构视为在入职过程中验证个人数字身份的一种手段。然而,这不足以防范在线身份识别,尤其是随着深度伪造技术的兴起[7]。

Deepfake 技术已被用于实施在线欺诈,并利用它来影响公众舆论和让政治官员难堪。这种技术对那些通过远程生物特征认证带来新客户的组织构成了明显的威胁。

客户 KYC onboarding 播放器嵌入了一种生命识别形式,作为身份验证流程的一部分。活体检查试图确认其身份的人是否是活的主体,而不是复制品或仿制品。结合了活性检测以减少欺骗尝试的成功机会。

一款名为 Zao 的应用程序使用人工智能将电影或电视剪辑中人物的脸替换为你上传到该应用程序的任何人的照片。使用 Zao 的面部交换技术可以绕过面部识别系统。用它来破解安全系统不是一件容易的事。在用户发现该应用背后有“中国开发者”,尽管有可疑的小字,人们开始猜测中国人出于邪恶的目的从手机上偷拍人脸和照片。幸运的是,事实证明这些面孔实际上在亚马逊位于美国本土的数据中心的服务器上,并在 48 小时内被删除了,但恐慌是巨大的[6]。

这项技术近年来取得了巨大的进步,有人担心它可能被用来创建妥协的照片和视频认证,以绕过语音和面部识别协议。

RemoteVerify 是一个身份验证解决方案,结合了 NorthRow 最流行的两项技术:活体检测和生物认证。在一个例子中,生物认证的成功关键在于识别“活动性”,生物认证试图确定你是坐在电脑前还是拿着智能手机并允许你创建和访问银行账户的真人。

活体检测有可能防止骗子在试图绕过验证协议时使用机器人、视频、照片和伪造的文档。相比之下,美国政府欧盟(EU) 已经提倡使用经过认证的活体检测方法,这些方法反过来又被绑定到一个被称为 ISO 30107 的全球生物特征标准上。

引用来源

Deepfakes 危害和威胁建模

原文:https://towardsdatascience.com/deepfakes-harms-and-threat-modeling-c09cbe0b7883?source=collection_archive---------25-----------------------

Jr Korpa 在 Unsplash 上拍摄的照片

Deepfakes 使得人们有可能在未经同意的情况下制造媒体——交换面孔、对口型和木偶——并给心理安全、政治稳定和商业中断带来威胁。

这本书现在可以在亚马逊上买到——https://www . Amazon . com/deep fakes-aka-Synthetic-Media-Humanity-ebook/DP/b0b 846 ycnj/

与任何新的创新技术一样,它可以被用作改善人民生活的工具,也可以被邪恶的行为者用来通过将其武器化来造成伤害。Deepfakes 也不例外。deepfakes 的武器化会对经济和国家安全产生巨大影响,会对个人和民主造成伤害。Deepfakes 将进一步侵蚀已经下降的对媒体的信任。

在政策和立法真空中,Deepfakes 变得越来越容易制造,甚至更容易传播。

在过去两年中,利用人工智能模型创建的合成数据的潜在恶意使用已经开始引起技术专家、公民社会和立法者的警惕。这项技术现在已经发展到有可能被武器化,对个人、社会、机构和民主造成破坏和伤害。Deepfakes 可以促成事实相对论,让威权领导人得以茁壮成长。还可以帮助公众人物将自己的不道德行为隐藏在 deepfakes 和假新闻的面纱下,称自己的实际危害行为为虚假,这也被称为骗子的红利[ 1 ]。

对个人的威胁

恶意使用 deepfake 的第一个案例出现在色情行业,对个人(主要是女性)造成情感、名誉和某些情况下的暴力。根据深度追踪,现在的强度为。ai,关于 Deepfake[ 2 ]的报道,96%的 deepfakes 都是色情视频,仅色情网站就有超过 1.35 亿的浏览量。

Deepfake 色情专门针对女性。

2018 年 4 月,驻孟买的记者 Rana Ayyub 在写了一篇关于印度执政党 BJP 的批评文章后,面临了一场 deepfake 攻击将她的脸叠加在一个色情视频上,然后被 doxed,视频在社交媒体上传播。骚扰和羞辱使 Ayyub 因心悸被送往医院,并导致她退出网络生活。

2017 年,有人使用 deepfakes 制作了一段和其他名人的色情视频。诺埃尔·马丁(Noelle Martin)是澳大利亚珀斯的一名法学毕业生,她发现有人拍摄了她的社交媒体照片,并将其 PS 成裸照,以制作深度假视频。最近,基丝汀·贝尔开展了一项公共活动,讨论并提高对深度假冒色情及其对个人造成的伤害的认识。

色情假货可以威胁,恐吓,并对个人造成心理伤害。Deepfake 色情将女性降低为性对象,折磨她们,造成情绪困扰,名誉伤害,虐待,在某些情况下,还会造成经济损失等物质伤害和失业等附带后果。

Deepfake 可以描述一个人沉溺于反社会行为,说一些他们从未做过的卑鄙的事情。这些假货会严重影响他们的声誉。它会破坏他们现在和未来的生活,包括但不限于职业生涯、职业市场、政治、人际关系和爱情。即使受害者可以通过不在场证明或其他方式揭穿谎言,这种修复可能为时已晚,无法补救最初的伤害。

在许多情况下,消除对他们的声誉、代理和材料的间接损害是具有挑战性的。随着社交媒体的传播能力和人类对八卦和谎言的天生渴望,丑闻式的造假传播得更快,而不是反驳和纠正。大多数人都没有批判地审视谬误的欲望。

对基于人工智能的合成媒体 deepfakes 缺乏认识,导致印度村民认为 WhatsApp 上儿童绑架的虚假信息是准确的,虚假的图像和视频导致了几起暴民私刑和杀戮案件。

恶意行为者可以利用不知情的个人,使用音频和视频 deepfakes 骗取经济利益。Deepfake 可以用来勒索。虚假媒体,视频和音频,可以用来榨取金钱,机密信息,或从个人身上索取好处。

在娱乐和艺术领域,我们已经看到了一些 deepfakes 的例子,当一个演员在完成电影之前去世时,工作室已经使用 deepfakes 来完成电影。死者可能获利是一个复杂的法律问题,可能会在死后损害名誉。

语音技术已经发展到这样一个水平,只需几句话,人工智能就可以对任何人产生令人印象深刻的准确模仿,即使是在发出他们很可能从未说过的单词或短语时。对于画外音艺术家,合成语音可以用来增加或扩展艺术家的角色。如果 deepfake 内容是在未经艺人同意的情况下创作的,将会影响他们的业务,限制他们的代理。这也可能对他们的生计产生影响。

对社会的威胁

假货会造成短期和长期的社会危害。基于人工智能的合成媒体可能会加速对媒体已经下降的信任。这种侵蚀会助长事实相对主义的文化,磨损民间社会日益紧张的结构。数字平台已经取代了传统的新闻把关人。信息传播的民主化性质和社交媒体渠道的财务激励使对社会机构的不信任永久化。如果虚假在平台上流行并被进一步分享,它就是有利可图的。加上不信任,现有的偏见和政治分歧可以帮助创造回音室和过滤泡沫,在社会中制造不和谐。

深度造假有助于改变民主话语。由 deepfake 提供的关于机构、政策和公共领导人的虚假信息可以被用来歪曲信息和操纵信仰。Deepfakes 将使公共和私人机构面临挑战,以抵御声誉攻击并揭穿错误信息和虚假信息。

适时的深度造假会对人身财产和生命造成重大伤害,并可能引发社会动荡。

反堕胎组织 CMP(医学进步中心)发布了一系列经过大量编辑的视频,声称计划生育协会的代表非法出售胎儿组织牟利,生殖健康非营利组织对此予以强烈否认。此后的多次调查都没有发现计划生育有任何不当行为,而 CMP 的创始人和另一名成员面临的法律后果

Deepfake 可以用来传播速度和规模的恶意虚假信息,以侵蚀对机构的信任。

2016 年总统大选前发布了一个虚假的故事,指控克林顿和她的竞选主席约翰·波德斯塔(John Podesta)在一家名为彗星乒乓球(Comet Ping Pong)的餐厅经营一个虐待儿童的团伙。随着这个故事的传播,乒乓彗星收到了来自该理论信徒的数百次威胁。华盛顿警方逮捕了一名北卡罗来纳州男子,据称他带着一支半自动步枪走进彗星披萨店“自我调查”这一理论,将枪对准一名员工,并至少开了一枪。虽然《假新闻》没有使用 deepfakes,但是一个真实的视频《假新闻》可能会导致可怕的结果。

Deepfakes 可以通过使用虚假视频和音频来传播关于某个社区的虚假信息,从而加剧社会分裂。南亚、缅甸和印度都有一些反对穆斯林的例子。

Deepfake 可能成为恶意民族国家破坏公共安全和制造不确定性和混乱的强大工具。2018 年初,一个关于弹道导弹来袭的假警报被发送给夏威夷居民和游客。这是一个人为的错误,误解了一个测试指令,导致发送了一个实时警报,引起了全州的恐慌和混乱。一个流氓演员用一枚弹道导弹击中美国一个州的深度假警报发出同样的现场警报,会使这个国家走上报复的道路,破坏公共安全和外交。

对民主的威胁

2018 年,加蓬人民怀疑他们的总统阿里·邦戈病重或已经死亡。为了揭穿这一猜测,政府宣布邦戈曾中风,但健康状况良好。政府很快发布了邦戈向加蓬人民发表新年致辞的视频。一周内,军方发动了一场不成功的政变,称该视频为 deepfake。事实上,这个视频从未被证实是伪造的,但是它会改变加蓬政府的进程。deepfakes 的想法足以加速已经岌岌可危的局面的瓦解。

政治候选人的深度造假可以破坏政治候选人的形象和声誉,还可能改变选举的进程。

在投票前几天,一个精心制作的政治领袖候选人散布种族歧视言论或从事不道德行为的假新闻会破坏他们的竞选。即使在有效揭穿人工智能生成的合成媒体虚假信息之后,竞选活动和候选人甚至可能没有时间从这一事件中恢复过来。美国 2016 年总统选举和 2017 年法国选举中出现了国家支持的虚假信息运动。高质量的 deepfake 可以注入引人注目的虚假信息,从而给投票过程和选举结果蒙上非法的阴影。

在许多国家,殖民时代的法律将同性活动视为犯罪。在社会保守的马来西亚,它们仍然被用于政治目的。2019 年,一段关于两名男子性丨爱丨视丨频的视频在 WhatsApp 上疯传,其中一人酷似经济事务部长阿兹明·阿里。视频中的另一名男子供认不讳,并声称该视频是在未经同意的情况下创作的。他随后因鸡奸指控被捕。阿里和包括马来西亚总理在内的其他人辩称,该视频纯属捏造。数字法医专家尚未断定该视频的真实性。这可能会毁了阿里的政治生涯。

一个比利时政党制作了一个美国总统的假视频,视频中特朗普呼吁比利时退出巴黎气候协定。发布该视频的佛兰德社会党(Flemish Socialist Party sp.a)声称,deepfake 旨在引起人们对气候变化的关注,因为该视频最终呼吁签署一份投资可再生能源、电动汽车和公共交通的请愿书。

在政治上,夸大事实,过度表现政策立场,为反对者提供替代事实是可以接受的策略。使用假货和合成媒体可能会对投票结果产生深远的影响。Deepfake 可以对选民和候选人产生影响。Deepfakes 还可能被用于错误归因、对候选人撒谎、错误地放大他们的贡献或对候选人造成名誉伤害。

说谎者红利是指一则真实的媒体报道或令人不快的真相可能会被领导者斥之为深度假消息或假新闻。

对企业的威胁

一项研究估计,由于虚假信息,企业每年损失大约 780 亿美元。其中包括 90 亿美元用于修复名誉损失,以及另外 170 亿美元因金融虚假信息造成的损失。

Deepfakes 被用来冒充商业领袖和高管的身份,以方便欺诈。2019 年 3 月,一家英国能源公司的首席执行官通过电话要求他的老板,即该公司德国母公司的首席执行官,向匈牙利供应商汇款 243,000 美元。英国首席执行官照办了。据能源公司的保险公司 Euler Hermes Group S.A .称,他们后来才意识到,基于人工智能的软件被用于模仿德国首席执行官的声音。

据赛门铁克称,三家公司被盗数百万美元,它们成为 deepfake 音频攻击的受害者。在每次攻击中,人工智能生成的合成声音会给高级财务官打电话,请求紧急转账。deepfakes 模型是根据 CEO 的公开演讲训练出来的。2020 年 2 月,一名宾夕法尼亚州的律师被他儿子的假声音愚弄了,声称他需要 9000 美元的保释金。

在一起不太复杂的诈骗案中,以色列诈骗犯在 Skype 视频通话中冒充法国外交部长,从一名商人那里窃取了约 900 万美元。冒名顶替者伪装成部长和办公厅主任,并重新创建了一个虚假的办公室环境来进行视频通话。如果他们用了 deepfakes,就不需要办公室和伪装了。Deepfakes 还可以在社交工程中用来欺骗员工以获取商业秘密。

Deepfakes 可能会带来独特的劳动和就业风险。员工越来越依赖秘密的视频和音频记录来支持他们对骚扰或虐待的指控。根据当地的规定,这些录音通常可以作为最可靠的证据,尽管许多雇主禁止在工作场所录音。一个从事不当行为的商业领袖的深度伪装可以被用来证实骚扰指控或支持集体诉讼。补救这些努力造成的声誉损害可能需要投入大量的时间和资源。

2017 年 8 月,一场使用星巴克字体和标志的逼真图形的虚假社交媒体活动在 twitter 上流行,标签为“ borderfreecoffee ”。这个骗局是为了散布虚假信息,说星巴克在所谓的梦想家日期间向无证移民提供免费饮料。同样,在 2019 年 8 月,一则关于连锁餐厅橄榄花园(Olive Garden)正在帮助资助川普总统竞选连任的谣言是以标签“抵制橄榄花园”开始的。两起案件都给橄榄园和星巴克造成了一时的名誉伤害。Deepfakes 将使影响成倍恶化。

一些恶作剧网站,如 Channel23News 允许用户创建自己看起来真实的假新闻文章,并直接发布到社交媒体上,降低了宣传者的进入成本,甚至使小企业也面临这样的危险。还有许多关于其他品牌的虚假故事,比如可口可乐因“明确的寄生虫”召回 Dasani 瓶装水,Xbox 游戏机杀死一名青少年,好事多结束会员计划。企业必须为这种潜在的额外法律和商业风险做好准备。

Deepfakes 可用于市场操纵。

在他们的报告中,来自 Wilmerhale 的 Ferraro、Chipman 和 Preston 确定了虚假信息和 deepfake 的法律和商业风险,并广泛关注了对公司的损害。他们特别指出,企业不仅会损失被骗资金的价值、声誉和商誉,还会受到股东的诉讼、监管机构的调查,并失去获得更多资本的机会。

摩根大通发表了一份关于使用基于帖子的交易算法的市场参与者的报告,头条新闻特别容易受到虚假信息操纵。有几个利用协同假情报活动的泵送和倾倒方案的例子。一个由虚假视频和音频支持的虚假故事很容易在短期内操纵市场。如果 deepfake 显示最近推出的自动驾驶汽车自发着火,或者首席执行官对某个种族群体发表贬低性评论,或者以明确的非自愿行为描绘一位商业领袖,消费者信心将会直线下降。这些威胁的危险性会对一家公司的估值产生破坏性的影响。

关于谁拥有你的声音,法律上的共识是有限的。美国许多州保护姓名和肖像,只有少数几个州保护声音。大多数州只为活着的人保护这些权利。美国只有少数几个州对可能性进行死后保护。还有讽刺和戏仿作品中合理使用的权利以及公众人物的定义和第一修正案权利的其他问题。音频 deepfakes 将冲击录音行业。

结论

与任何新技术一样,邪恶的行为者将利用这种创新,并利用它为自己谋利。未经同意的假货会对心理安全、政治稳定和商业破坏造成威胁。今天,deepfakes 主要用于色情行业,对个人(主要是女性)造成情感、名誉和某些情况下的暴力。除了 deepfake 色情,我们还没有看到任何相应的 deepfake 事件。专家指出,他们对 deepfakes 的主要担忧是,当一个不受欢迎的真相被斥为 deepfake 或假新闻时,骗子会从中获利。我坚信,从长远来看,deepfakes 对企业构成了重大威胁。

喜欢? 随便给我买本书

参考

[1]https://www.daniellecitron.com/ted-talk/

https://sensity.ai/mapping-the-deepfake-landscape/

[3]https://www . king greisen . com/blog/common-evidential-trial-issues-in-employment-law-cases-from-get-the-meto-evidence-in-keeping-the-collateral-source-evidence-out/

[4]https://www . wilmer hale . com/en/insights/client-alerts/2020 03 12-identifying-the-legal-and-business-risk-of-dis-information-and-deep fakes-what-every-business-need-to-know

DeepMind 刚刚发布了用于神经网络和强化学习的 Haiku 和 RLax

原文:https://towardsdatascience.com/deepmind-just-released-haiku-and-rlax-for-neural-networks-and-reinforcement-learning-a6468f9352cc?source=collection_archive---------18-----------------------

图片由 Gerd AltmannPixabay 拍摄

利用最新的 JAX 图书馆来促进你的人工智能项目

人工智能(AI)研究每天都在发展,其工具也是如此——尖端人工智能公司 DeepMind 刚刚发布了两个基于 JAX 的神经网络(NN)和强化学习(RL)库,分别是俳句RLax 、。由于两者都是开源的,我们可以利用这些最新的库来进行我们自己的人工智能工作。

JAX 是什么?

JAX 由谷歌于 2018 年发布,是一款开源工具,通过转化 Python 和 NumPy 程序生成高性能加速器代码。在幕后, JAX 高度集成了亲笔签名,可以有效区分原生 Python 和 NumPy 函数, XLA ,是一个线性代数编译器,可以优化 TensorFlow 模型。

因此, JAX 通过提供学习模型优化的集成系统,为高性能机器学习研究而构建。它在人工智能研究人员中越来越受欢迎。然而,这并不是最容易处理的事情,这可能导致 DeepMind 开发了俳句RLax

什么是俳句和 RLax?

俳句是为 JAX 准备的简单 NN 库,这个库是由十四行诗的一些作者开发的——为张量流准备的神经网络库。这个库通过提供面向对象的编程模型,允许人工智能研究人员完全访问 JAX 的纯函数转换。通过提供两个核心工具— hk.Modulehk.transform,Haiku 被设计用来管理 NN 模型参数和其他模型状态。

RLax 是为 JAX 设计的简单 RL 库。这个库没有为 RL 提供完整的算法,而是为实现特定的数学运算以构建全功能的 RL 代理提供了有用的构建块。RL 中的代理是学习与嵌入式环境交互的学习系统。通常,智能体与环境的交互有一些离散的步骤,包括智能体的动作,被称为观察的环境更新状态,以及被称为奖励的可量化反馈信号。RLax 专门用于改进代理如何更好地与环境交互,从而使 RL 更加有效。

为什么是他们?

由于这两个库都是开源的,开发人员可能会考虑在自己的项目中使用它们。当然,在生产项目中使用它们可能还为时过早,但是有两个主要因素可以证明我们应该开始试验它们。

  • 整体质量高。这两个库都由 DeepMind 支持,并且已经在合理的规模上进行了测试。例如,俳句的作者也在开发 Sonnet,一个著名的tensor flowNN 库。
  • 用户友好。两个库都执行一组定义良好的易用操作。对于俳句来说,它的 API 和抽象非常接近于十四行诗,使得过渡到俳句变得不那么痛苦。如果您不熟悉 Sonnet,您仍然可以相对快速地学会使用它,因为它提供了面向对象的编程模型。

结论

这两个库都将通过在 JAX 保护伞下提供一个伟大的集成工具来促进 NN 和 ML 模型的开发。如果你喜欢尝试新事物,我肯定会推荐你考虑使用这些库,至少可能是为了实验的目的。

有用的链接

GitHub JAX

GitHub 俳句

GitHub RLax

DeepMind 不断涌现,发布了 Acme 和 Reverb RL 库

原文:https://towardsdatascience.com/deepmind-surges-on-releasing-acme-and-reverb-rl-libraries-10545996cd05?source=collection_archive---------76-----------------------

Alphabet 子公司继续为机器学习研究社区提供有用的软件库。

Unsplash 上由 Franck V. 拍摄的照片

要旨

Deepmind 现在完全是 Alphabeta 的子公司,是一家专注于人工智能的创新软件公司。你可能因为他们在训练 AlphaGoAlphaGoZero 中的成就而知道他们。AlphaGoZero 强化学习代理从零开始学习,直到成为围棋世界冠军

尽管取得了这样或那样的巨大成功,但由于缺乏可重复性,该公司的学术成就一直面临挫折。独立复制学术作品的能力是验证和进一步合作的生命线。因此,提供服务至关重要,尤其是在一个计算资源丰富的人和其他人之间的差距越来越大的世界里。

DeepMind 明白。

近年来,他们已经进入了一个凹槽,不断地发布模块化软件库来帮助其他研究人员。这些库有多种用途,包括:

  • 再现性
  • 简单
  • 模块性
  • 并行化
  • 效率

随着他们的 Acme 和 Reverb 库的发布,这一趋势继续发展。事实上,该库的作者在他们的网站上明确提出了 Acme 的高层次目标:

1。使我们的方法和结果具有可重复性——这将有助于澄清是什么使 RL 问题变得困难或容易,这是很少显而易见的。
2。为了简化我们(以及整个社区)设计新算法的方式——我们希望下一个 RL 代理对每个人来说都更容易编写!
3。提高 RL 代理的可读性——当从一篇论文过渡到代码时,不应该有隐藏的惊喜。

DeepMind 极致作者

好吧,但是怎么做?

他们实现这些目标的方法之一是通过适当的抽象层次。强化学习的领域就像一个洋葱,就其层次而言,它的使用效果最好。从表面上看,你有一个从数据中学习的代理。剥开数据部分,你会看到这个数据要么是一个存储的数据集,要么是一个活生生的体验序列。剥开代理,您会看到它计划并采取行动,从它的环境中产生一个有度量的响应。你可以再次剥离更多,深入研究政策,经验,重放等。下图很好地展示了这一点。

分层显示的强化学习问题[ 来源

Acme 实现其目标的另一种方式是通过一种可扩展的数据存储机制,实现为配套的混响库。为此,考虑代理的典型经验重放缓冲。这个缓冲区有多大?通常,它是在至少几万到几十万个经验元组的数量级上,这是针对每个代理的。当处理一个涉及数千到数百万代理的模拟时,你会得到…很多。

通过解耦数据生产者(代理)和数据消费者(学习者)的概念,一个有效的数据存储机制可以独立地位于两者之间。这正是混响的作用。作为一个公司支持的库,它有超过 70%的 C++代码和一个整洁的 python 界面,我真的很兴奋能够深入其中。

一名 R2D2 RL 代理人正在玩街机游戏 Breakout [ 来源

结论

通过不断发布类似这样的精彩开源库,DeepMind 有助于降低准入门槛,并为 ML 和 AI 研究创造公平的竞争环境。将此与低成本云计算解决方案相结合,任何人都可以直接加入进来!提交你用这些库做的任何酷项目。我迫不及待想见到他们。

跳进来

【极致】Github 资源库
【极致】白皮书
【极致】Google Colab 示例
【混响】Github 资源库
【混响】Google Colab 示例

保持最新状态

在学术界和工业界,事情发展得很快!用一般的 LifeWithData 博客和 ML UTD 时事通讯让自己保持最新状态。

如果你不是时事通讯的粉丝,但仍想参与其中,可以考虑将 lifewithdata.org/blog 的和 lifewithdata.org/tag/ml-utd 的添加到 Feedly 聚合设置中。

原载于 2020 年 6 月 1 日 https://lifewithdata.org*。***

DeepMind:大规模 RL 的存在证明

原文:https://towardsdatascience.com/deepmind-the-existence-proof-for-rl-at-scale-8707791d9762?source=collection_archive---------58-----------------------

大脑是普遍智能的存在证据——谷歌的 DeepMind 是我们在复制它方面取得进展的证据。

DeepMind 与 AlphaGo、AlphaZero 等的强化学习成功案例。正在为部署大规模人工智能项目的下一代科技公司铺平道路。理论上,DeepMind 远不是一个盈利的实体(尽管他们确实给了谷歌一个优势),但他们正在向世界展示如何使用人工智能,更令人印象深刻的是在特定任务中对过时的人类使用增强学习。既然它已经存在,它将被用来完成有利可图的任务。

DeepMind 是做什么的?

DeepMind 想解决智能。近年来,他们将世界上最优秀的机器学习研究人员与最优秀的计算机科学家融合在一起,创造出在游戏中击败人类的计算机。确切地说,是他们尝试过的任何游戏AlphaZero 在无人参与的情况下自行解决了无数游戏。DeepMind 瞄准了一个系统,并给了计算机掌握它的工具。在高层次上,这是一个美丽的暗示:计算机在没有人类输入的情况下可以做的事情每天都在扩展。

作为一名研究人员,我对前来参与前沿机器学习研究的科技巨头又爱又恨。DeepMind 在强化学习领域更有意图、更有影响力。人们应该模仿他们的方法。

美丽的岩石。来源,作者。

等等,什么是存在证明?

E 存在意味着有 一条通往某物的路径。人脑的存在意味着进化的确产生了一般的智力,但这并不意味着它从目前的生物体或计算机中再次进化而来。存在证明通常比人们想要的要弱得多。

数学中的存在证明也很棘手。一个经典的例子是哥德尔的不完全性定理:他证明了数学中每一个公理的形式系统都能够展示所有的真理。工程师的外卖:每个系统都有限制(没有免费的午餐)。

也就是说,我对人工智能的看法要积极得多:

大脑是人工智能存在的证据,就像鸟类是飞行的证据一样。

解决一般智力问题可能来自我们无法预测的事件(研究突破),所以给它一个时间表是不值得的。除了希望 AGI(人工智能)被缺乏挑战动机的人发现之外,我正在寻找其他事情去做。

[## 深度学习不是解开奇点的钥匙

深度学习改变了人工智能领域,但它不会给我们人工通用…

towardsdatascience.com](/deep-learning-is-not-the-key-to-unlocking-the-singularity-913f960ac345)

伯克利的钟楼。来源,作者。

RL 按比例

强化学习 (RL)最近在主流媒体上得到大量炒作。这是一个试图设计能够像人类婴儿一样学习完成任何任务的智能体的研究领域。在规模上,在技术上,意味着在一个项目上融合许多工程师来创造一些有价值的东西(通常是应用程序或算法)。研究人员研究强化学习,DeepMind 是第一个让他们在重要的事情上合作的公司(嗯,公开地说——另一家公司可能已经做了这件事,但没有告诉我们)。重要的是在人类时代最具历史意义的游戏中摧毁人类。

大规模研发是将研究中的创新应用到现有的问题中,以这种方式使人类做的工作变得无用。

在接下来的几年里,我认为人工智能的进步会在哪些领域引起轰动?

1 我未来的公司将从可穿戴设备和杂货账单中记录健康数据,并能够告诉某人如何饮食以 a)减肥,b)保持头脑清醒,或 c)保持肠道健康。

Batch RL 将使许多创业公司拥有的数据更具影响力。目前,这项研究受到数据不规则性和控制策略训练的不稳定性的限制,但只要再给它几年时间。

[## 批量强化学习

sascha Lange Thomas Gabel Martin ried miller 适应、学习和优化系列丛书的一部分(ALO,卷…

link.springer.com](https://link.springer.com/chapter/10.1007/978-3-642-27645-3_2)

2 体现智能:将机器学习创新从新闻传播到户外。赋予机器学习一个身体有时被称为体现智能。我们已经看到昂贵的机器人如何解决一些令人印象深刻的有用任务。下一步是让廉价的机器人完成更简单的任务——我认为我们正处于自动化指数的底部。在这个领域有很多地方可以成立一家公司。幸运的是,在这里做研究,我将继续前进,继续学习。

[## 通过教机器人学习来推进人工智能

脸书人工智能正在进行机器人学习方面的研究项目,这将导致人工智能能够更有效地学习和…

ai.facebook.com](https://ai.facebook.com/blog/advancing-ai-by-teaching-robots-to-learn/)

3 我的公司将提供一个平台,制药公司可以在这个平台上交叉引用他们的药物机制,并通过成为药物数据的中心枢纽,有可能省去设计阶段。数据并不意味着知识,但它可以超级有用。

我以前写过一个关于这个的场景——如果一家公司得到了一个精确的人体模拟器,我们就可以为药物研发和许多其他产品进行强化学习。这将产生超乎想象的影响和收益。

[## 生物医药奇点

一场基于机器学习的革命能否在人工全科医疗之前改变生物医学和治疗学

towardsdatascience.com](/the-bio-medicine-singularity-a9615708a925)

我接下来要写的将揭开炒作的面纱。 ai 全球创业公司——你可以在这里得到提示:

[## 解说:大部分‘AI’公司都不是 AI 公司。以下是辨别的方法

人工智能(AI)公司利用深度或机器学习,而不仅仅是基础数据分析。

fortune.com](https://fortune.com/2018/07/03/ai-artificial-intelligence-deep-machine-learning-data/)

像这样?请在https://robotic.substack.com/订阅我关于机器人、自动化和人工智能的直接通讯。

[## 自动化大众化

一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…

robotic.substack.com](https://robotic.substack.com/)

Deepnote 将成为 Jupyter 黑仔

原文:https://towardsdatascience.com/deepnote-sets-course-to-become-the-jupyter-killer-d0cb6e3ca011?source=collection_archive---------5-----------------------

DeepNote 笔记本体验预览(来源)

DeepNote,一个位于旧金山的小型团队,想要在你的数据科学工作流程中取代 Jupyter。我想他们可能会这么做。

如果你像我一样是一名数据科学家,你可能会花更多时间在工程任务上,而不是实际研究上。安装库、管理数据库、跟踪你的实验、调试代码、耗尽内存……你明白了。

【关于】 页面 深注

Jupyter 笔记本非常适合数据科学原型开发。在一个单一的环境中,人们可以无缝地执行探索性分析,可视化数据,并建立 ML 模型原型。

也就是说,不久前,大多数数据科学家认为 Spyder IDE 是万能的。即使是最伟大的工具最终也会寿终正寝,不管是因为缺乏适应性、缺乏持续的支持,还是其他什么原因。

尽管 Jupyter 笔记本在数据科学社区广受欢迎,但许多人也指出了一些重要的弱点。新工具以更好或更快的方式解决现有工具中的弱点的能力通常使它们能够被现状工具集所采用。让我们来看看 DeepNote 提供的一些激动人心的竞争优势。

实时协作

谷歌的在线协作工具套件(文档、表格、幻灯片等)占据了微软 Office 的巨大市场份额,却没有增加多少功能。他们是怎么做到的?让世界踏上通往他们家门口的道路的主要区别在于实时协作。

通过在谷歌套件中与同事实时协作,你不再需要同步开发,也不再需要为融合差异而烦恼。此外,您总是知道您的合作者目前在哪里工作,这使得分工更加容易。

DeepNote 带来了开箱即用的功能,在共享计算环境中实现无缝协作。事实上,这确实会带来名称空间变化的问题。然而,我认为这是一个比共享 Jupyter 笔记本更好的问题,因为要获得给定的状态,必须重新运行这些笔记本。

在此查看实时 DeepNote 协作的运行

此外,DeepNote 为每个协作者提供了不同的权限级别:查看、执行、编辑、管理和所有者。这允许对这些笔记本电脑的操作进行大量控制。

首先,想象一个师生场景。在线课程的教师可以在虚拟教室中浏览共享的笔记本。教师拥有管理员/所有者权限,而教室的其余部分仅包含查看权限。

作为另一个例子,考虑一个上级评估一个团队成员的工作。团队成员使用所有者权限来完全控制笔记本。上级使用编辑权限提供内联反馈,但不能执行任何单元格。通过只对团队成员保留执行权限,上级不能更改(读取:污染)团队成员的名称空间。

变量浏览器

Spyder IDEs 中我在 Jupyter 笔记本中真正错过的一个方面(至少,没有扩展/小部件)是易于访问的名称空间浏览器。当然,有who / whos魔法命令。然而,这些并不能真正与 Spyder 的产品相提并论。

我们再一次用 DeepNote 填补了空白!

DeepNote 笔记本为你的变量提供了漂亮的摘要(来源)

除了坚固的变量浏览器,没有漂亮的熊猫DataFrame显示器,任何有自尊的笔记本环境都是不完整的。

是的,DeepNote 笔记本也有漂亮的熊猫DataFrame显示屏(来源)

DeepNote 附着在云硬件上

我肯定你听说过经验法则(实际上,更多的是抱怨),大约 80%的数据科学是除了数学和统计之外的一切。在云计算环境中,这一比例变得更像 90/10,额外损失了 10%的时间来为您的笔记本电脑提供合适的计算能力。

轻松查看和选择笔记本电脑运行的硬件( source )

DeepNote 了解您的困难,并提供对基于云的硬件的无缝访问,以满足您的所有需求。所谓无缝,我的意思是你在笔记本界面上设置一切!哦,顺便说一下,他们不会关闭你的内核,除非它实际上是空闲的。

Python 包管理

Python 有一个很棒的包管理系统。DeepNote 意识到了这一点,并坚持使用其工作目录中的一个requirements.txt文件。即使这样,仍然很容易忘记预先安装一些依赖项。当这种情况发生时,直到我们尝试导入并失败时,我们才意识到遗漏!

为此,DeepNote 的笔记本会主动监控您的包导入,通知您声明的需求中缺少的依赖项。此外,如果需求文件还不存在,它会对该文件进行最好的猜测。剧透警告:猜测通常是正确的。

DeepNote 包管理器建议安装一个缺少的依赖项(

DeepNote 集成了…很多

创建新项目的示例(来源

最后,DeepNote 提供了几乎所有你期望使用的集成。为了保持笔记本的有序,您可以选择不同的源代码控制库连接。这可以在笔记本创建过程中使用,也可以用于写回更新。

除了源代码控制,DeepNote 笔记本还允许连接到云计算数据存储,如 S3、GCS 和公共数据库引擎。

正式连接到各种云基础设施(来源)

暂时就这样了

虽然 DeepNote 还没有达到真正消灭 Jupyter 的境界,但这个轨迹肯定是存在的。我渴望看到他们如何继续!然而,不要只相信我的话。像我一样,报名参加他们的早期接入项目。他们在一周内做出了回应,从那以后我们就一直在漫不经心地讨论改进!不要只是抱怨现状,成为改善现状的一份子。

保持最新状态

学术界和工业界的事情发生得非常快!通过一般的 LifeWithData 博客、ML UTD 简讯和 Twitter feed 让自己保持最新状态。

如果你不是收件箱时事通讯的粉丝,但仍然想参与其中,可以考虑将这个 URL 添加到聚合设置中。

原载于 2020 年 2 月 23 日 https://lifewithdata.org

DeepPavlov:自然语言处理的“Keras”回答 COVID 问题

原文:https://towardsdatascience.com/deeppavlov-keras-for-natural-language-processing-answers-covid-questions-9da6199c5489?source=collection_archive---------55-----------------------

使用 Azure 机器学习和 DeepPavlov 库在 COVID 论文数据集上训练开放域问答模型。

奥比·奥尼耶德在 Unsplash 上拍摄的照片

在与图像相关的深度学习领域,Keras 库发挥了重要作用,从根本上简化了迁移学习或使用预训练模型等任务。如果您切换到 NLP 领域,执行相对复杂的任务,如问题回答或意图分类,您将需要让几个模型一起工作。在这篇文章中,我描述了使 NLP 民主化的 DeepPavlov 库,以及如何使用它和 Azure ML 在 COVID 数据集上训练问答网络。

本帖是AI April倡议的一部分,四月的每一天我的同事都会在这里发布与 AI、机器学习和微软相关的新原创文章。看看 日历 找到其他已经发表的有趣的文章,并在这个月内继续查看那个页面。

在过去的几年里,我们见证了许多与自然语言处理相关的任务取得了重大进展,这主要归功于 transformer 模型BERT 架构。一般来说,BERT 可以有效地用于许多任务,包括文本分类,命名实体提取,预测上下文中的屏蔽词,甚至问答。

从头开始训练 BERT 模型是非常资源密集型的,大多数应用程序依赖于预先训练的模型,使用它们进行特征提取,或者进行一些温和的微调。因此,我们需要解决的原始语言处理任务可以分解为更简单步骤的管道,BERT 特征提取是其中之一,其他是标记化,将 TF-IDF 排名应用于一组文档,或者只是简单的分类。

这个流水线可以看作是由一些神经网络代表的一组处理步骤。以文本分类为例,我们将有提取特征的 BERT 预处理器步骤,然后是分类步骤。这一系列步骤可以组成一个神经架构,并在我们的文本数据集上进行端到端的训练。

DeepPavlov

DeepPavlov 图书馆来了。它主要为你做这些事情:

  • 允许您通过编写一个配置,将文本处理管道描述为一系列步骤。
  • 提供了许多预定义的步骤,包括预训练的模型,如 BERT 预处理器
  • 提供了许多预定义的配置,您可以使用它们来解决常见的任务
  • 从 Python SDK 或命令行界面执行管道训练和推理

这个库实际上做的远不止这些,它让你能够在 REST API 模式下运行它,或者作为微软机器人框架的 chatbot 后端。然而,我们将关注使 DeepPavlov 对自然语言处理有用的核心功能,就像 Keras 对图像一样。

您可以通过在https://demo . DeepPavlov . ai上玩一个交互式 web 演示来轻松探索 DeepPavlov 的功能。

用 DeepPavlov 进行 BERT 分类

再次考虑使用 BERT 嵌入的文本分类问题。 DeepPavlov 包含一些预定义的配置文件,例如,看看 Twitter 情感分类。在此配置中,chainer部分描述了管道,包括以下步骤:

  • simple_vocab用于将预期输出(y),即一个类名,转换成数字 id ( y_ids)
  • transformers_bert_preprocessor取输入文本x,产生一组伯特网络期望的数据
  • transformers_bert_embedder实际上为输入文本生成 BERT 嵌入
  • one_hottery_ids编码成分类器最后一层所需的一位热码
  • keras_classification_model是分类模型,是定义了参数的多层 CNN
  • proba2labels最终层将网络的输出转换成相应的标签

Config 还定义了dataset_reader来描述输入数据的格式和路径,以及train部分中的训练参数,以及其他一些不太重要的东西。

一旦我们定义了配置,我们就可以从命令行训练它,如下所示:

python -m deeppavlov install sentiment_twitter_bert_emb.json
python -m deeppavlov download sentiment_twitter_bert_emb.json 
python -m deeppavlov train sentiment_twitter_bert_emb.json

install命令安装执行该过程所需的所有库(如 Keras、transformers 等)。),第二行download是所有预训练的模型,最后一行执行训练。

一旦模型经过训练,我们就可以从命令行与它进行交互:

python -m deeppavlov interact sentiment_twitter_bert_emb.json

我们也可以使用任何 Python 代码中的模型:

model **=** build_model(configs**.**classifiers**.**sentiment_twitter_bert_emb) result **=** model(["This is input tweet that I want to analyze"])

开放领域问答

可以使用 BERT 执行的最有趣的任务之一叫做 开放领域问答 ,简称 ODQA。我们希望能够给计算机一堆文本来阅读,并期望它对一般问题给出具体的答案。开放领域问答的问题指的是我们不是指一个文档,而是指一个非常广阔的知识领域。

ODQA 通常分两个阶段工作:

  • 首先,我们试图为查询找到最匹配的文档,执行信息检索的任务。
  • 然后,我们通过网络处理该文档,以从该文档中产生特定答案(机器理解)。

开放领域问答架构,来自 DeepPavlov 博客

在这篇博文中已经很好地描述了使用 DeepPavlov 进行 ODQA 的过程,然而,他们在第二阶段使用的是 R-NET,而不是 BERT。在本帖中,我们将把 ODQA 与 BERT 一起应用于新冠肺炎开放研究数据集,该数据集包含超过 52,000 篇关于新冠肺炎的学术文章。

使用 Azure ML 获取训练数据

为了训练,我将使用 Azure 机器学习,特别是笔记本。将数据放入 AzureML 的最简单方法是创建一个数据集。在语义学者页面可以看到所有可用的数据。我们将使用非商业子集,位于这里

为了定义数据集,我将使用 Azure ML Portal ,并从 web 文件创建数据集,选择文件作为数据集类型。我唯一需要做的就是提供网址。

要访问数据集,我需要一台笔记本计算机。因为 ODQA 任务相当密集,而且需要大量内存,所以我会用 112Gb 或 RAM 的 NC12 虚拟机创建一个大计算。这里描述了创建计算机和笔记本的过程

要从我的笔记本中访问数据集,我需要以下代码:

from azureml.core import Workspace, Dataset
workspace **=** Workspace**.**from_config()
dataset **=** Dataset**.**get_by_name(workspace, name**=**'COVID-NC')

数据集包含一个压缩的.tar.gz文件。为了解压缩它,我将数据集挂载为一个目录,并执行 UNIX 命令:

mnt_ctx **=** dataset**.**mount('data')
mnt_ctx**.**start() 
!tar **-**xvzf **./**data**/**noncomm_use_subset**.**tar**.**gz 
mnt_ctx**.**stop()

所有文本以.json文件的形式包含在noncomm_use_subset目录中,在abstractbody_text字段中包含摘要和完整的纸质文本。为了将文本提取到单独的文本文件中,我将编写简短的 Python 代码:

from os.path import basename**def** **get_text**(s):     
    **return** ' '**.**join([x['text'] **for** x **in** s]) os**.**makedirs('text',exist_ok**=**True) 
**for** fn **in** glob**.**glob('noncomm_use_subset/pdf_json/*'):
     **with** open(fn) **as** f:
         x **=** json**.**load(f)
     nfn **=** os**.**path**.**join('text',basename(fn)**.**replace('.json','.txt'))       
     **with** open(nfn,'w') **as** f:         
         f**.**write(get_text(x['abstract']))         
         f**.**write(get_text(x['body_text']))

现在我们将有一个名为text的目录,所有的论文都以文本的形式存在。我们可以去掉原来的目录:

!rm **-**fr noncomm_use_subset

设置 ODQA 模型

首先,让我们在 DeepPavlov 中建立原始的预训练 ODQA 模型。我们可以使用名为en_odqa_infer_wiki的现有配置:

import sys 
!{sys**.**executable} **-**m pip **--**quiet install deeppavlov 
!{sys**.**executable} **-**m deeppavlov install en_odqa_infer_wiki 
!{sys**.**executable} **-**m deeppavlov download en_odqa_infer_wiki

这将需要相当长的时间来下载,你将有时间意识到你是多么幸运地使用云资源,而不是你自己的电脑。下载云到云要快得多!

要从 Python 代码中使用这个模型,我们只需要从 config 构建模型,并将其应用到文本:

from deeppavlov import configs 
from deeppavlov.core.commands.infer import build_model 
odqa **=** build_model(configs**.**odqa**.**en_odqa_infer_wiki) 
answers **=** odqa([ "Where did guinea pigs originate?",                   		 
                 "When did the Lynmouth floods happen?" ])

我们将得到的答案是:

['Andes of South America', '1804']

如果我们试图问网络一些关于冠状病毒的问题,下面是我们将得到的答案:

  • 什么是冠状病毒?— 一种特定病毒的毒株
  • 什么是新冠肺炎?— 在屋顶或教堂塔楼上筑巢
  • 新冠肺炎起源于哪里?— 阿帕特北部海岸
  • 上一次疫情是什么时候?— 1968 年

远非完美!这些答案来自旧的维基百科文本,该模型已被训练过。现在我们需要根据我们自己的数据重新训练文档提取器。

训练模型

用你自己的数据训练 ranker 的过程在 DeepPavlov 博客中有描述。因为 ODQA 模型使用en_ranker_tfidf_wiki作为排序器,我们可以单独加载它的配置,并替换用于训练的data_path

from deeppavlov.core.common.file import read_json 
model_config **=** read_json(configs**.**doc_retrieval**.**en_ranker_tfidf_wiki) 
model_config["dataset_reader"]["data_path"] **=** 
			os**.**path**.**join(os**.**getcwd(),"text") 
model_config["dataset_reader"]["dataset_format"] **=** "txt" model_config["train"]["batch_size"] **=** 1000

我们还减小了批量大小,否则训练过程将无法适应内存。再次意识到我们手头可能没有 112 Gb RAM 的物理机器。

现在让我们训练模型,看看它的表现如何:

doc_retrieval **=** train_model(model_config) doc_retrieval(['hydroxychloroquine'])

这将为我们提供与指定关键字相关的文件名列表。

现在让我们实例化实际的 ODQA 模型,看看它是如何执行的:

*# Download all the SQuAD models* squad **=** build_model(configs**.**squad**.**multi_squad_noans_infer,
					download **=** True) 
*# Do not download the ODQA models, we've just trained it* odqa **=** build_model(configs**.**odqa**.**en_odqa_infer_wiki, 
					download **=** False)
odqa(["what is coronavirus?","is hydroxychloroquine suitable?"])

我们将得到的答案是:

['an imperfect gold standard for identifying King County influenza admissions',  'viral hepatitis']

还是不太好…

使用 BERT 回答问题

DeepPavlov 有两个预先训练好的问答模型,在斯坦福问答数据集 (SQuAD): R-NET 和 BERT 上训练。在前面的例子中,使用了 R-NET。我们现在将它切换到 BERT。squad_bert_infer config 是使用 BERT Q & A 推论的良好起点:

!{sys**.**executable} **-**m deeppavlov install squad_bert_infer 
bsquad **=** build_model(configs**.**squad**.**squad_bert_infer, 
						download **=** True)

如果你看 ODQA 配置,以下部分负责问答:

{    
   "class_name": "logit_ranker",    
   "squad_model": {
       "config_path": ".../multi_squad_noans_infer.json" },
   "in": ["chunks","questions"],
   "out": ["best_answer","best_answer_score"]
}

为了改变整个 ODQA 模型中的问答引擎,我们需要替换 config:

odqa_config **=** read_json(configs**.**odqa**.**en_odqa_infer_wiki)
odqa_config['chainer']['pipe'][**-**1]['squad_model']['config_path'] **=**                      
			'{CONFIGS_PATH}/squad/squad_bert_infer.json'

现在,我们以与之前相同的方式构建和使用模型:

odqa **=** build_model(odqa_config, download **=** False) 
odqa(["what is coronavirus?",       
      "is hydroxychloroquine suitable?",
      "which drugs should be used?"])

以下是我们从最终模型中获得的一些问题和答案:

  • 什么是冠状病毒?— 呼吸道感染
  • 羟氯喹合适吗?— 耐受性良好
  • 应该使用哪些药物?— 抗生素、乳果糖、益生菌
  • 潜伏期是多少?—3–5 天
  • 患者在潜伏期有传染性吗?— 中东呼吸综合征不会传染
  • 如何污染病毒?— 基于辅助细胞的拯救系统细胞
  • 什么是冠状病毒类型?— 包膜单链 RNA 病毒
  • 什么是 covid 症状?— 失眠、食欲不振、疲劳和注意力不集中
  • 什么是生殖数?— 5.2
  • 杀伤力如何?— 10%
  • 新冠肺炎起源于哪里?— 葡萄膜黑色素细胞
  • 抗生素疗法有效吗?— 不太有效
  • 什么是有效的药物?— M2、神经氨酸酶、聚合酶、附着和信号转导抑制剂
  • 对抗 covid 什么有效?— 神经氨酸酶抑制剂
  • covid 和 sars 相似吗?— 所有冠状病毒的功能和结构基因都有非常相似的组织
  • covid 类似于什么?— 血栓形成

结论

这篇文章的主要目的是演示如何使用 Azure 机器学习和 DeepPavlov NLP 库来做一些很酷的事情。我没有动力在 COVID 数据集中做出一些意想不到的发现——ODQA 方法可能不是最好的方法。然而,DeepPavlov 可以以类似的方式用于在该数据集上执行其他任务,例如,实体提取可以用于将论文聚类到主题组中,或者基于实体对它们进行索引。我绝对鼓励读者去看看 Kaggle 上的 COVID 挑战赛,看看你是否能提出可以使用 DeepPavlov 和 Azure 机器学习实现的原创想法。

Azure ML 基础设施和 DeepPavlov 库帮助我在几个小时内完成了我描述的实验。以这个例子为起点,你可以取得好得多的结果。如果有,请与社区分享!数据科学可以做很多奇妙的事情,但当许多人开始一起研究一个问题时,就更是如此了!

https://soshnikov.com】原载于 2020 年 4 月 29 日

DeepStyle(第 1 部分):使用最先进的深度学习生成现实的高级时尚服装和风格

原文:https://towardsdatascience.com/deepstyle-f8557ab9e7b?source=collection_archive---------20-----------------------

提供github 代码!点击此处进入第二部分。

模特走秀(来源)

这是我在 2019 年春天在我的家乡大学 香港科技大学 为计算机视觉深度学习课程做的一个项目。那时候,我正在慢慢了解时尚和风格的世界:如何穿得更好,跟上现代潮流。我开始观看高级时尚奢侈品牌的时装秀,甚至街上随便一个人都知道。迪奥、古驰、路易威登、香奈儿、爱马仕、乔治·阿玛尼、卡地亚、博柏利等等。随着我看得越来越多,我开始逐渐融入时尚界。当我需要为我的计算机视觉课程想出一个最终项目主题的时候,我想,为什么不创建一个深度学习系统,它将能够生成好看且有创意的高级时装?想象一下会很有趣,对吗?

所以我和我的队友创造了深度风格

什么是 DeepStyle?

简而言之, DeepStyle 就是具有生成高级时尚服装单品能力的定制深度学习框架。它可以作为时装设计师的灵感,也可以预测时装业的下一个流行项目。DeepStyle 吸收流行时尚图片,并创造新的产品,作为有效预测未来趋势的一种方式。

我们的研究包括两个部分:建立高级奢侈品时尚数据库,并使用人工智能生成类似的时尚物品。第一部分,我们需要一个可靠的来源,在那里我们可以收集所有来自 t 台的高级奢华时尚图片。但除此之外,我们还希望有一个模型,可以识别服装裁剪出图像的其余部分,因为最终,如果我们在后台生成假的模型和观众,那会很奇怪😂。在我们将图像裁剪为仅包含服装本身之后,我们可以将图像输入到另一个模型中,该模型将能够从头开始生成新的服装。裁剪图像对于尽可能去除噪声至关重要。

框架

在简要分析了我们试图构建的东西之后,这里有一个粗略的框架。

深度风格框架

DeepStyle 的第一部分包含 更快的 R-CNN 这是一个实时对象检测模型,已经证明使用其 区域提议网络 可以达到最先进的准确性。你可以在这里阅读官方文件了解更多细节。我们将用香港中文大学发布的 深度时尚数据库 来训练我们更快的 R-CNN。

深度时尚数据库的快速介绍:这是迄今为止最大的时尚数据集,由大约 80 万张不同的时尚图片组成,这些图片具有不同的背景、角度、光线条件等。这个数据集由四个用于不同目的的基准组成,我们在项目中使用的是 类别和属性预测基准 。该基准具有 289,222 幅服装图像,每幅图像都由包围盒坐标和相应的服装类别标注。

deep fashion 数据库来源的类别和属性预测基准

在对 DeepFashion 数据库训练更快的 R-CNN 后,该网络将能够预测服装在哪里,给定任何测试图像。这就是 Pinterest 数据库 出现的地方。我们可以建立一个刮刀,从 Pinterest 上刮下几个大型奢侈品牌的高级时装秀,并将其用作我们更快的 R-CNN 的测试图像。我们之所以选择 Pinterest,是因为 Pinterest 提供了大量干净、高质量的图片,而且也很容易刮。

经过推理,Pinterest 图像的边界框将被预测,图像的其余部分可以被裁剪掉,因为我们只需要特定的项目。然后,我们最终将它传递给我们的时尚 GAN ,它将使用 DCGAN 或深度卷积生成对抗网络来实现。另一个的快速教程:一个生成式对抗网络基本上包含两个主要组件:生成器和鉴别器。生成器努力创建看起来真实的图像,而鉴别器试图区分真实图像和虚假图像。在训练过程中,随着时间的推移,发生器在生成真实图像方面变得更好,而鉴别器在辨别真假方面变得更好。当鉴别者不再能判断出发生器产生的图像是真是假时,就达到了最终的平衡。

最终结果是由 DCGAN 产生的一组图像。希望它们看起来很时尚!

履行

步骤 1 安装 Detectron 和 DeepFashion 数据集

为了实现更快的 R-CNN,我们将使用由脸书 AI 提供的 Detectron 库。Detectron 库包含用于实现最先进的对象检测算法的代码,如更快的 R-CNN、Mask R-CNN、Retina-Net 等。可以通过以下步骤安装官方库:

根据您的 CUDA 版本安装 Caffe2

  1. 对于支持 CUDA 9 和 CuDNN 7 的 Caffe2:
conda install pytorch-nightly -c pytorch

2.对于支持 CUDA 8 和 CuDNN 7 的 Caffe2:

conda install pytorch-nightly cuda80 -c pytorch

安装了 Caffe2 之后,现在继续安装 COCO API。

# COCOAPI=/path/to/clone/cocoapi
git clone https://github.com/cocodataset/cocoapi.git $COCOAPI
cd $COCOAPI/PythonAPI
# Install into global site-packages
make install
# Alternatively, if you do not have permissions or prefer
# not to install the COCO API into global site-packages
python setup.py install --user

现在,你可以下载官方回购并安装 Detectron。

git clone [https://github.com/facebookresearch/Detectron.git](https://github.com/facebookresearch/Detectron.git)

您可以通过以下方式安装 Python 依赖项:

cd Detectron
pip install -r requirements.txt

通过以下方式设置 Python 模块:

make

您可以通过以下方式验证 Detectron 是否已成功安装:

python detectron/tests/test_spatial_narrow_as_op.py

更多安装细节,可以参考这里

注:脸书 AI 最近发布了Detectron 2,是 Detectron 的更新版本。我在做这个项目的时候用过 Detectron,如果你愿意,你可以看看 Detectron 2。

接下来,我们要下载 DeepFashion 数据集。你可以从他们的主页阅读更多关于数据集的细节。你可以从谷歌硬盘上下载数据集。我们想要的是类别和属性预测基准,可以从这里下载。

步骤 2 将 DeepFashion 数据集转换为 COCO 格式

为了使用 Detectron 的自定义数据集训练模型,我们必须首先将数据集转换成 COCO 格式。COCO 是一个大规模的对象检测、分割和字幕数据集,也是对象检测数据集的标准格式。我们可以使用以下代码将 DeepFashion 数据集转换为 COCO 格式:

COCO 基本上将数据集的轮廓保存在一个.json文件中,该文件包括关于对象检测数据集的基本信息。最值得注意的是coco_dict['images']coco_dict['annotations'],它们分别给出了图像及其相应注释的信息。

DeepFashion 数据库到 COCO 输出

在 DeepFashion 上训练更快的 R-CNN 模型

在成功地将数据集转换成 COCO 格式后,我们终于可以训练我们更快的 R-CNN 模型了!在此之前,我们需要首先选择我们想要使用的更快的 R-CNN 的具体变体。有大量端到端更快的 R-CNN 变体供我们选择:

支持更快的 R-CNN 型号(来源)

当时,我训练了三种不同的变体:R-50-FPN_1x,R-101-FPN_1x,X-101–32x8d-FPN _ 1x。然而,为了简单说明的目的,我将只告诉你如何训练 R-50-FPN,因为步骤是相同的。你可以通过访问这里获得 Detectron 支持的型号列表。

在我们决定使用更快的 R-CNN R-50-FPN_1x 后,我们可以前往configs/12_2017_baselines/查看提供的现有模型配置。我们可以找到我们想要的——它被命名为[e2e_faster_rcnn_R-50-FPN_1x.yaml](https://github.com/facebookresearch/Detectron/blob/master/configs/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_1x.yaml)。在那里你可以看到并根据我们的意愿修改模型和训练配置。

最重要的是将训练和测试数据集改为我们的 DeepFashion 数据集,它已经是 COCO 格式了。我们还可以将规划求解参数更改为我们想要的参数。我的看起来像这样:

在我们选择完模型及其配置后,现在我们终于可以开始训练这个模型了!根据您拥有的 GPU 数量,您可以通过执行以下命令开始培训:

  1. 单 GPU 训练
python tools/train_net.py \
    --cfg configs/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_1x.yaml \
    OUTPUT_DIR [path/to/output/]

2.多 GPU 支持

python tools/train_net.py \
    --multi-gpu-testing \
    --cfg configs/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_1x.yaml \
    OUTPUT_DIR [path/to/output/]

运行上面的任何一个命令后,指定为--cfg的模型将开始训练。包括模型参数、验证集检测等的输出。会保存在/tmp/detectron-output下。更多训练细节,可以参考这里

第四步建立高级时装的 Pinterest 数据库

示例图像(左侧源中间源右侧源)

注意:由于版权问题,上面的图片实际上不是 Pinterest 数据库中的项目,而只是作为项目一般外观的参考。

在我们测试我们更快的 R-CNN 定位服装商品的能力之前,我们首先需要有我们自己的测试数据库。我们可以建立一个刮刀,从 Pinterest 上刮下时装秀的图片。当时,我们搜索了 2017 年,2018 年和 2019 年的秋冬时装秀。我们搜集的品牌包括:博柏利、香奈儿、克洛伊、迪奥、纪梵希、古驰、爱马仕、Jimmy Choo、路易威登、迈克高仕、普拉达、范思哲、圣罗兰。我们最终收集了分散在所有这些品牌中的总共 10,095 张时尚图片。

尽管我很想给出 Pinterest 的 scraper 代码,我已经没有代码了:()。因为我不再能够访问我们当时在这个项目中使用的虚拟机。然而,使用 BeautifulSoup 可以很容易地构建这个刮刀,因为 Pinterest 图片都是静态的,而不是使用 Javascript 动态生成的。

恭喜你走了这么远!下一步是在 Pinterest 数据库上运行我们速度更快的 R-CNN。在那之后,我们可以开始构建一个 DCGAN,它将能够获取服装图像,并生成与它们相似的好东西。因为这篇文章已经很长了,我们将把它留到第 2 部分。

要继续,请点击此处查看第 2 部分:

[## 时尚的甘(下)

第 2 部分继续:构建 DCGAN 以生成逼真的服装

towardsdatascience.com](/deepstyle-part-2-4ca2ae822ba0)

时尚的甘(下)

原文:https://towardsdatascience.com/deepstyle-part-2-4ca2ae822ba0?source=collection_archive---------26-----------------------

构建 DCGAN 以生成逼真的高级时尚服装

如果您还没有阅读第 1 部分,请先阅读它,因为本文假设您已经阅读了第 1 部分。

[## DeepStyle:使用最先进的深度学习生成现实的高级时装服装和…

提供论文和 Github 代码

towardsdatascience.com](/deepstyle-f8557ab9e7b)

现在假设您已经阅读了第 1 部分,让我们继续。

在 Pinterest 数据库和 Crop 上运行更快的 R-CNN

在收集了 Pinterest 数据库之后,现在我们可以使用我们之前训练的更快的 R-CNN 对这些图像进行推理。但在我们这样做之前,我们需要首先添加功能,我们将裁剪检测到的对象并保存结果图像,因为该功能不是开箱即用的。你可以去这个项目的 github repo 下载vis.py来完成。然后,导航到detectron/utils,用下载的版本替换现有的vis.py。新的vis.py与已经提供的相同,但有一个主要的不同——裁剪检测到的对象并将其保存在一个目录中。

添加的代码预测检测到的对象的类别,如果类别是“Full ”,即全身衣服,那么它将裁剪图像并将其保存在指定的目录中。我们只保存全身服装,因为我们希望能够生成全身服装,而不仅仅是简单的衬衫或裙子。

经过微小的修改后,我们就可以在 Pinterest 数据集上运行我们的模型了!我们可以在之前通过以下方式训练的更快的 R-CNN 上运行推理:

python tools/infer.py \
   --im [path/to/image.jpg] \
   --rpn-pkl [path/to/rpn/model.pkl] \
   --rpn-cfg configs/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_1x.yaml \
   --output-dir [path/to/output/dir]

[path/to/image.jpg]是我们存储 Pinterest 图像的目录,--rpn-pkl是我们之前保存模型.pkl文件的地方,--rpn-cfg是我们存储配置文件的地方,最后,--output-dir是我们想要保存预测的地方。然而,这个--output-dir并不重要,因为它将包含带有预测的未剪裁图像。我们要寻找的是我们在vis.py中指定的目录,因为那是保存裁剪图像的地方。

包围盒预测(左源中间源右源)

在对模型进行推断之后,我们应该得到以服装为中心的裁剪图像,并且模型以及背景大部分被移除。即使仍然有一些噪音,我们已经足够好了。

将裁剪后的图像传递给时尚 GAN ( 来源)

第 6 步将预测和图像传递给 DCGAN 进行生成

DCGAN 架构(来源)

现在我们终于有了高质量的服装图像,我们可以开始构建 DCGAN 模型了!

注意:代码基于 Pytorch 的官方 DCGAN 教程,您可以从这里的 访问 。代码就不解释太详细了,更详细的解释可以参考教程。

我们开始吧。首先,我们必须导入所有必需的库:

接下来,我们设置稍后需要的所有变量:

设置完变量后,我们现在创建数据集和数据加载器,稍后我们将把它们输入到模型中。我们调整图像的大小,将它们居中裁剪到所需的图像大小,并使它们正常化。我们的图像尺寸设置为 64,因为较小的尺寸通常更一致。

我们还绘制了一些训练图像来可视化:

样本训练图像

之后,我们定义了生成器上的权重初始化和待构建的鉴别器:

我们制造发电机:

发电机架构

还有鉴别器!

鉴别器架构

然后我们定义培训流程。我们使用 BCELoss 函数,因为鉴别器的工作是识别图像是真是假。我们为生成器和鉴别器设置了 Adam 优化器。然后,我们逐批更新两个网络:

这将开始培训过程。输出是:

培训产出

培训过程需要一段时间。训练后,我们可以绘制训练期间的发生器和鉴频器损耗:

生成器和鉴别器训练损失与迭代

完成所有这些工作后,这是最后一步——将图像保存到本地硬盘:

结果

最后,伙计们,在所有这些工作之后!我们将看到生成的结果:

DCGAN 生成的图像!

现在,我们可以并排绘制并比较数据集的真实图像和生成的图像。

真实服装和生成的服装的并排比较

不错吧?假图像与真实图像相差不远。事实上,有些在我眼里看起来相当时尚😁。

就是这样,伙计们!希望你们都喜欢我的文章,并希望再次见到你。同样,本文中显示的全部代码以及我写的论文可以在我的 github repo 中获得!如果你喜欢我的内容,请在 Medium 上关注我,我会定期发布关于深度学习的话题!

参考

[## Facebook 研究/检测

Detectron 已被弃用。请参阅 detectron2,这是 PyTorch 中 detectron 的全新重写版本。侦探是脸书·艾…

github.com](https://github.com/facebookresearch/Detectron) [## 更快的 R-CNN:用区域提议网络实现实时目标检测

最先进的目标检测网络依靠区域提议算法来假设目标位置…

arxiv.org](https://arxiv.org/abs/1506.01497) [## 深度时尚数据库

我们贡献了 DeepFashion 数据库,一个大规模的服装数据库,它有几个吸引人的特性:首先…

mmlab.ie.cuhk.edu.hk](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html) [## COCO -上下文中的常见对象

编辑描述

cocodataset.org](https://cocodataset.org/#home) [## 深度卷积生成对抗网络的无监督表示学习

近年来,卷积网络的监督学习(CNN)在计算机视觉领域得到了广泛应用…

arxiv.org](https://arxiv.org/abs/1511.06434) [## DCGAN 教程- PyTorch 教程 1.5.1 文档

本教程将通过一个例子对 DCGANs 进行介绍。我们将训练一个生成性的对抗网络…

pytorch.org](https://pytorch.org/tutorials/beginner/dcgan_faces_tutorial.html)

DeepWalk:它的行为和如何实现它

原文:https://towardsdatascience.com/deepwalk-its-behavior-and-how-to-implement-it-b5aac0290a15?source=collection_archive---------18-----------------------

照片由法比奥·布拉克特Unsplash 上拍摄

使用 Python、Networkx 和 Gensim 快速分析和评估图网络关系的备忘单

图形数据结构表示复杂交互的能力带来了新的方法来分析和分类由它们的共同交互定义的实体。虽然这些分析在发现社区内的不同结构方面是强大的,但是它们缺乏对图形的各个方面进行编码以输入到传统的机器学习算法中的能力。随着 DeepWalk 的提出,[1]图中的相互作用可以被简单的神经网络捕获并编码到可由上述 ML 算法使用的嵌入中。然而,虽然有文章简单介绍了 DeepWalk 算法,但我能找到的很少文章提供了代码并讨论了这些系统的实现细节。细节包括模型参数化、部署考虑和处理不可见数据。

在这篇短文中,我将提供对图网络、Word2Vec / Skip-Gram 和 DeepWalk 过程的高级概述。为了帮助解决这个问题,我将给出一个多类分类的例子来演示这个算法。之后,我将考虑不同的参数配置,并展示它们对算法性能的影响。最后,我将概述在系统中部署和处理不可见数据的一些注意事项。

图形网络

图是有效地表示生态系统中两个或多个对象之间的交互的数据结构。该结构由两个对象定义,一个节点顶点定义系统内的实体。在本文中,我将使用一个电子商务网站上的购物网络示例,图中的节点是正在销售的产品。

作者图片

图的另一个方面是连接它们的东西:一条,它定义了连接两个节点的交互。一条边可以是有向的,显示出一种 to-from 关系——想象一个人 A 给人 b 发了一封电子邮件。一条边也可以有一个定义他们交互的权重。在我们的例子中,我们可以定义一个边缘权重,代表在我们的电子商务网站上购买了两种产品的消费者的比例。

深度行走算法:

DeepWalk 是一种图形神经网络【1】—一种直接在目标图形结构上操作的神经网络。它使用随机路径遍历技术来洞察网络中的局部结构。它通过利用这些随机路径作为序列来做到这一点,然后使用这些序列来训练 Skip-Gram 语言模型。为了简单起见,本文中我们将使用 Gensim 包 Word2Vec 来训练我们的 Skip-Gram 模型。

Word2Vec

DeepWalk 算法的这个简单实现非常依赖于 Word2Vec 语言模型[2]。由谷歌在 2013 年推出的 Word2Vec 允许将单词嵌入到 n 维空间中,相似的单词彼此靠近。这意味着经常一起使用/在类似情况下使用的单词将具有较小的余弦距离。

单词嵌入行为的三维示例,作者的图片

Word2Vec 通过使用 Skip-Gram 算法将目标单词与其上下文进行比较来实现这一点。在高层次上,Skip-Gram 使用滑动窗口技术进行操作——在给定中间目标单词的情况下,它试图预测周围的单词。对于我们试图将图中的相似节点编码为在 n 维空间中彼此靠近的用例,这意味着我们有效地试图猜测我们网络中目标节点周围的邻居

一个来自 S. Doshi [3]的 Skip-Gram 示例,修改了取自原作者的图像[2]

深度行走

DeepWalk 通过图使用随机路径来揭示网络中的潜在模式,然后这些模式被神经网络学习和编码,以产生我们的最终嵌入。这些随机路径以极其简单的方式生成:从目标根开始,随机选择那个节点的一个邻居,并将其添加到路径中,接下来,随机选择那个节点的一个邻居,并继续遍历,直到已经走了期望的步数。以电子商务为例,这种对网络路径的重复采样产生了一个产品 id 列表。然后,这些 ID 被视为句子中的标记,使用 Word2Vec 模型从这些 ID 中学习状态空间。更简洁地说,DeepWalk 过程遵循以下步骤:

DeepWalk 过程分几个步骤进行:

  1. 对于每个节点,从该节点开始执行 N 个“随机步骤”
  2. 将每次遍历视为一系列节点 id 字符串
  3. 给定这些序列的列表,使用 Skip-Gram 算法对这些字符串序列训练一个 word2vec 模型

作者图片

这在代码中看起来像什么?

我们从核心的 networkx 数据结构开始,它定义了一系列产品,这些产品由它们的 ID 给出。两个产品之间的顶点是在电子商务生态系统中共同购买的产品。首先,我们要定义一个函数 get_random_walk (Graph,Node_Id):

# Instantiate a undirected Networkx graph
G = **nx.Graph**()
G.**add_edges_from**(list_of_product_copurchase_edges)**def get_random_walk**(graph:nx.Graph, node:int, n_steps:int = 4)->List[str]:
   """ Given a graph and a node, 
       return a random walk starting from the node 
   """ local_path = [str(node),]
   target_node = node **for** _ **in** **range**(n_steps):
      neighbors = **list**(**nx.all_neighbors**(graph, target_node))
      target_node = **random.choice**(neighbors)
      **local_path.append**(**str**(target_node)) **return** local_pathwalk_paths = []**for** node **in** **G.nodes**():
   **for** _ **in** **range**(10):
      walk_paths.**append**(**get_random_walk**(G, node))

walk_paths[0]
***>>>*** *[‘10001’, ‘10205’, ‘11845’, ‘10205’, ‘10059’]*

这些随机漫步提供给我们的是一系列字符串,它们充当从起始节点开始的路径——沿着列表从一个节点随机漫步到下一个节点。我们接下来要做的是将这个字符串列表视为一个句子,然后利用这些字符串序列来训练一个 Word2Vec 模型

# Instantiate word2vec model
embedder = **Word2Vec**(
   window=4, sg=1, hs=0, negative=10, alpha=0.03, min_alpha=0.0001,    
   seed=42
)# Build Vocabulary
**embedder.build_vocab**(walk_paths, progress_per=2)# Train
**embedder.train**(
   walk_paths, total_examples=embedder.corpus_count, epochs=20, 
   report_delay=1
)

调谐和参数

现在我们已经有了 DeepWalk 的基本结构,在 Word2Vec 模型的一般模型参数的之外,还有许多方面是可参数化的。这些可能包括:

  1. 为 W2V 训练数据执行的随机行走的次数
  2. 从节点开始的每次行走的深度

我将利用一个样本数据集上的通用分类方法来展示这些参数如何影响模型的性能。在上面描述的图表中——利用一系列产品,用一个图表定义共同购买的产品——我们试图将产品分类到它们各自的 10 个类别。

作者图片

上面显示了在我们的 Word2Vec 模型的节点向量上训练的分类器的分类性能(精确度),在 y 轴上使用增加的随机行走次数,在 x 轴上使用增加的随机行走深度。我们看到的是,准确性随着两个参数的增加而增加,但随着两个参数的增加,回报率逐渐降低。需要注意的一点是,随着行走次数的增加,训练时间线性增加,所以训练时间会随着行走次数的增加而激增。例如,左上角的训练时间只相差 15 秒,而右下角的训练时间则相差一个多小时。

部署系统:

热启动再培训

既然我们知道了它的行为方式,我们如何让它变得实用呢?在大多数图形系统中,核心问题是更新和维护系统,而不必立刻重新训练整个模型。幸运的是,由于 DeepWalks 与 NLP 的关系,我们可以依赖类似的更新过程。使用 gensim 时,更新算法更加简单,其流程如下:

  1. 将目标节点添加到图中
  2. 从该节点执行随机行走
  3. 使用这些序列来更新 Word2Vec 模型
# Add new nodes to graph from their edges with current nodes
**G.add_edges_from**([new_edges])# From a list of the new nodes' product_ids (unknown_nodes) get rw's
sequences = [**get_random_walks**(G, node) **for** node **in** unknown_nodes]**model.build_vocab**(new_nodes, update=True)
**model.train**(sequences,total_examples=model.corpus_count, epochs=model.epochs)

不需要再培训

或者,有一种更简单的方法来处理系统中的新节点。您可以利用模型的已知嵌入来推断未知节点的嵌入。遵循与前面的实现类似的模式:

  1. 将目标节点添加到图中
  2. 从该节点执行随机行走
  3. 聚集来自随机行走的嵌入,然后使用该聚集来代替未知节点嵌入
# Add new nodes to the graph from their edges with current nodes
**G.add_edges_from**([new_edges])sequences = [**get_random_walk**(G, node) **for** node **in** unknown_nodes]**for** walk **in** sequences:
   nodes_in_corpus = [
        node **for** node **in** walk **if** node **in** word2vec
   ]
   node_embedding = [ # here we take the average of known embeddings
        **np.mean**(embedder[nodes_in_corpus])
   ]

这里,我们的嵌入是从未知节点开始的随机行走中已知节点的平均值。这种方法的好处是它的速度,我们不需要重新训练任何东西,并且正在执行几个对 Gensim 中类似字典的数据结构的 O ( 1 )调用。缺点是它的不精确性,在没有重新训练模型的情况下,新节点和它的邻居之间的交互是近似的,并且只和你的聚合函数一样好。要更深入地了解这些方法,您可以查阅讨论此类聚合功效的论文,如 TF-IDF 平均等。[4]

在过去的 10 分钟里,我们走过了[哈。】DeepWalk 的核心组件,如何实现,以及在自己的工作中实现的一些考虑。对于图网络的评估,有许多可能性可以考虑,鉴于其简单性和可伸缩性,DeepWalk 当然应该在其他可用的算法中加以考虑。下面你可以找到一些上面概述的算法的参考,以及一些关于单词嵌入的进一步阅读。

来源:

[1] Perozzi 等人。深度行走:在线学习社交表征https://arxiv.org/pdf/1403.6652.pdf

[2]米科洛夫等人。向量空间中单词表示的有效估计https://arxiv.org/pdf/1301.3781.pdf

[3] S .多希。 Skip-Gram: NLP 上下文单词预测算法:https://towardsdatascience . com/Skip-Gram-NLP-context-words-prediction-algorithm-5 bbf 34 f 84 e0c?gi = 8 ff 2 eada 829

[4] Levy 等人。利用从单词嵌入中吸取的经验教训改进分布相似性【https://www.aclweb.org/anthology/Q15-1016/T22

捍卫数据科学大师

原文:https://towardsdatascience.com/defending-the-data-science-masters-e2013a9e029b?source=collection_archive---------49-----------------------

支持数据科学研究生学位的考虑

简介

(本文中的任何陈述均为本人所作,不代表任何其他实体、个人或组织)

尽管数据科学可以被定义为一个领域,但它是一个不断发展的领域。凭借其独特的计算机科学、统计学、科学探索、可视化以及在一系列跨领域领域的巨大增长潜力,美国的大学和学院开设数据科学课程应该不足为奇。但是数据科学硕士课程包括什么呢?值得有人在这个项目上花两年时间吗?我刚刚在 GWU 大学获得理学硕士学位,我可以提供我的经验,我认为它最终会如何发展,以及我在申请这样一个项目时所做的主要考虑,以及为什么有人应该考虑这样一个项目,而不是编码训练营或 MOOCs 自学和其他非学位导向的学习。

图片由 Couleur 通过 Pixabay 拍摄

我为什么这么做

首先,当我试图进入数据科学领域时,我开始关注数据科学项目。尽管我已经在从事数据科学的入门级工作,但我知道我还有很多东西要学(并且我不确定我会学到在我当时的角色中有效工作所需的一切)。但更重要的是,我没有看起来像数据科学家或任何其他组织的学术背景。但我一直在学习 Python,并投身于这个领域,我知道我需要强化训练。那么如何获得呢?对我来说,MOOCs 是不够的,因为我觉得我需要一个显示能力的高级学位。但是发现一个程序比我想象的要难。

许多程序似乎是由校园内其他系提供的课程组合而成,而不仅仅是统计和计算机科学系。有时他们需要商业课程,更接近于数据分析 MBA,但被更名为数据科学。通常,这些项目不会包括明确的深度学习、分布式计算、高级技术或研究方法类型的课程。这是一个问题,对我来说,内容似乎非常肤浅。对我来说,唯一可以确认的方法就是与程序对话。

四处打听

当我与这些数据科学硕士项目交流时,我对几个领域感兴趣,这些领域可以归纳为以下几个问题:

1)可获得何种经济资助(包括助教奖学金):

这个项目将会是你的首选。由于这是一个硕士项目,你可能已经有学生债务,你想确保你的钱花得值。让财务变得有意义可能不是你知道的事情,直到你得到一个报价和财务包。

2)学生是全日制还是非全日制?

如果学生是兼职或全职,你知道你有多少支持工作和参与该计划。绝大多数好处不会在课堂上出现,当你进入就业市场时,你将需要专业经验,最好是真实世界的数据集,而不仅仅是 MNIST 数据集。

3)核心教师(兼职教师等)的任期状况如何?)?

如果教职员工是兼职教授,或者终身职位不能反映他们的教学质量。然而,你可以从这个答案中推断出两件事。教员研究的重点(主要是终身职位)还是申请(主要是兼职)?教员是主要的区别,他们的行业经验将为你提供比课堂材料更多的信息。

4)学生成果(如果他们不能清晰表达,这是一个巨大的危险信号):

为什么一个项目最终可能不会给你提供一份工作?如果这个项目太新,不能告诉你,或者对讨论这些结果不感兴趣(这就是为什么一个电话会有所不同),那就回答了你所有的问题。

5)覆盖哪种材料?有没有更广阔的视野/教学原则?

坦率地说,其他问题都无关紧要。课程包括哪些内容?他们能和你分享教学大纲吗?他们教图书馆还是教概念?有深度学习课吗?他们是否深入到作为所有机器学习基础的线性代数、统计学和微积分中?有什么样的重点课程内容,如何教授?他们是否有针对高级 NLP、时间序列分析、贝叶斯方法、分布式或高性能计算的特定课程,或者任何其他重要的深入研究的主题领域,这些领域是基础的,但不是头条新闻?他们是打算教那些能让你在职业生涯中适应的技能,还是基于表面?在这里,课程的进步是一件好事,但是忽视高级课程所涵盖的内容是一个重大错误。

6)存在什么样的校园组织来支撑?

类似于教职员工的终身职位,这个问题更多的是关于项目的支持和文化。这个项目位于什么部门?什么样的专用资源可用于该计划?有职业顾问吗?一般来说,这些问题的答案会告诉你,这是一个他们打算发展和投资的项目(为你的学位增加价值),还是一个在大肆宣传期间快速获得财务收益的项目。

即使有这些问题,当你第一次看它的时候,还是有一些危险信号需要注意。

红旗

1)21 世纪最性感的工作!学习构建未来的人工智能!他们在哪里提到过这些短语吗?这个项目对与他们学校无关的权威有吸引力吗?问问你自己为什么他们会这样做,他们对他们的教员、学校或项目没有信心吗?他们说 AI 吗?说真的,如果他们一直说 AI,那就有问题了。如果他们参考的是这些项目,而不是数据科学的应用,该计划可能不会给你带来很好的结果,或者提供超出你自己能力范围的教育。这是我个人最讨厌的,也让我对说话人的知识产生了怀疑。

2)学生成绩有限,课程设置古怪

他们分享结果吗?你对你所听到的满意吗?他们列出的课程是否有意义,听起来是否会填补你的空白?请记住,你将填补你技能组合中的空白,并在你的所有技能中获得认证。

3)缺乏清晰度

他们似乎不愿意深入回答问题吗?学校想要吸引新的学生,尤其是研究生项目。问问自己为什么他们不把问题告诉你,一直把你发给新人回答问题。他们把你和现在的学生联系起来了吗?当我决定我选择的硕士项目时,我已经和项目管理员、项目主管、一名教师、一名学生和另一名教师谈过了。这些人中的每一个人都把我和下一个人联系起来,并对我的后续行动保持开放,而且会及时把我要求的信息发给我。一些和我交谈过的程序一直把我指向他们的网站,而没有把我发送给另一个人,这让我很担心。

4)非常新的程序

让我们面对现实吧,数据科学是新定义的,高等教育很难适应一切。一个学术项目在最初的 2-3 个阶段会有很大的变化。你想加入那些实验小组吗?我可能是一个相对规避风险的人,但你的里程可能会有所不同。

5)商业项目(我不喜欢,但你的里程数可能会有所不同)

我不愿参与商学院的课程。数据分析有用,但不是数据科学。如果在数据可视化和通信上没有强调机器学习,它就不是一个数据科学项目。这是商业分析。这不是一个问题,除非你想做数据科学的发展需求,而不是通信方面。

那么,为什么我最终加入了这个项目呢?从根本上说,我选择的程序对上述所有问题提供了满意的答案,危险信号是有限的。

注意事项:

硕士不应该是你进入这个领域的第一步,但如果你的目标是改变职业,它应该是你考虑的主要一步。最终,像硕士学位这样的学术证书会有持久的影响力,而 MOOC 或编码训练营可能不会对你的职业生涯有持久的影响力。尽管专业经验比课堂更有价值,但它会让你获得一个可以毫无疑问地向前传递的证书,并且会勾选相关领域的高级学位(以及博士学位的时间和资金限制相对较低)。

硕士不应该是你进入这个领域的第一步,但如果你的目标是改变职业,它应该是你考虑的主要一步。最终,像硕士学位这样的学术证书会有持久的影响力,而 MOOC 或编码训练营可能不会对你的职业生涯有持久的影响力。尽管专业经验比课堂更有价值,但它会让你获得一个可以毫无疑问地向前传递的证书,并且会勾选相关领域的高级学位(以及博士学位的时间和资金限制相对较低)。

防御性查询编写

原文:https://towardsdatascience.com/defensive-query-writing-1fa07674899b?source=collection_archive---------82-----------------------

照片来自 Pexels

数据工程

使用防御性编码原则编写 SQL 查询

源自防御性编程,防御性查询编写是一种尝试确保查询运行不会失败的实践。就像在应用程序开发中一样,尽量避免愚蠢的错误,控制不可预见的情况。有时,您需要决定是希望查询失败,还是希望查询即使有一些不正确的数据也能运行。我将分享几个简单的例子,在这些例子中,我们可以在编写查询时使用这些实践。

检查数据库对象是否存在

以创建和删除数据库对象为例。不要使用CREATE TABLE xyz,使用CREATE TABLE IF NOT EXISTS xyz (id int)或者如果你想重新创建丢失所有数据的表,你可以运行DROP TABLE IF EXISTS xyz,然后运行CREATE TABLE IF NOT EXISTS xyz (id int)

同样的实践可以用于创建和删除数据库、视图、索引、触发器、过程、函数等等。我开始意识到,在大多数情况下,使用这个是有帮助的。

使用数据库和列别名

防止自己出现不明确的列错误。参见下面的例子,列city可能同时出现在TABLE_1TABLE_2中。你如何期望数据库知道你希望它选择哪个字段?

通常,为数据库对象创建别名,然后使用别名而不是完整名称来访问这些数据库对象及其子对象是一个非常好的做法。显然,为了高效地完成这项工作,您需要遵循 SQL 样式表。我在这里写了更多关于它的内容—

[## 如何避免编写草率的 SQL

让您的 SQL 代码更易读、更容易理解

towardsdatascience.com](/how-to-avoid-writing-sloppy-sql-43647a160025)

使用极限,偏移

不,我不是在说使用LIMIT来限制最终查询中的记录数量。相反,我说的是这样的查询。

返回列的子查询中的LIMIT子句很重要,因为如果子查询返回多行,即对于TABLE_1中的每条记录,如果TABLE_2中有多条记录,它可以防止查询失败。这是编写更好的查询的一个非常有用的技巧。

使用LIMIT有一个警告。如果你不确定数据的质量或者你对数据库不够了解,使用LIMIT经常会给你错误的答案。在某些情况下,您更希望作业失败时抛出错误,而不是查询返回不正确的结果集。

使用存储过程和预准备语句

信不信由你,SQL 注入仍然非常流行。近年来,许多受欢迎的公司发现自己受到了黑客攻击 SQL 注入的摆布。有非常具体的方法来防止您的应用程序受到这种攻击。关于这个话题最有资源的网站是 OWASP。

[## SQL 注入

SQL 注入攻击包括通过从客户端到客户端的输入数据插入或“注入”SQL 查询

owasp.org](https://owasp.org/www-community/attacks/SQL_Injection)

防止这些攻击背后的想法是通过使用准备好的语句或使用存储过程来安全地参数化您的查询。即使这些解决方案也要求在运行查询之前进行严格的验证检查——使用特殊字符、转义字符等等。

小心使用触发器

我有触发器的问题。我曾经试图在生产数据库触发的触发器上构建一个轻量级的数据转换管道。我在想什么,对吧?它是轻量级的,它本来可以工作更长时间,但由于应用程序中的一些 bug(很可能是关于事务边界的),它没有得到解决。即使那没有成功,我仍然真的非常喜欢触发器,但它们确实会带来自己的痛苦。

必须格外小心,确保触发器不是相互依赖的,并且在数据库应用程序中不可能有循环触发器。

执行前模拟 DML 语句

总是试图将您的生产查询模拟成SELECT语句,即使您正在尝试DELETEUPDATE。这样做会给你一个公平的想法,当你DELETEUPDATE时,你实际上要做什么。这些年来,我发现这个方法真的很有用。这无疑增加了另一个耗费时间的步骤,但我认为这比额外的成本有好处。

除了嘲讽之外,您还必须在您的开发/测试环境中运行相同的DELETEUPDATE语句,这样您就可以在生产中做任何激烈的事情之前签署它们。

这些是我的一些建议。我发现这些在处理数据系统时非常有用。类似地,我在这里也谈到了许多提高数据库查询性能的好的、简单的 SQL 技巧

[## SQL 查询的简单修复

查询任何传统关系数据库的经验法则

towardsdatascience.com](/easy-fixes-for-sql-queries-ff9d8867a617)

快乐阅读!

定义数据科学、机器学习和人工智能

原文:https://towardsdatascience.com/defining-data-science-machine-learning-and-artificial-intelligence-95f42a60b57c?source=collection_archive---------44-----------------------

有可能区分它们吗?

随着可用数据的数量、种类和速度不断增加,科学学科为我们提供了先进的数学工具、过程和算法,使我们能够以有意义的方式使用这些数据。数据科学(DS)、机器学习(ML)和人工智能(AI)就是三个这样的学科。在许多与数据相关的讨论中经常出现的一个问题是,DS、ML 和 AI 之间的区别是什么?它们能被比较吗?根据你和谁交谈,他们有多少年的经验,以及他们做过什么项目,你可能会得到上述问题的非常不同的答案。在这篇博客中,我将尝试根据我的研究、学术和行业经验来回答这个问题;并促成了许多关于这一主题的对话。然而,这仍然是一个人的意见,应该被视为如此。我还将提到,这篇文章旨在提供这三个领域之间的概念差异;因此,一般情况下,肯定会有边缘情况。

如果你把 DS、ML 或 AI 看作是一套工具和技术,要恰当地区分它们几乎是不可能的。它们重叠;然而,它们是 而不是彼此的适当子集 。例如,如果有人使用“聚类”算法,他们可能正在进行 DS、ML 或 AI 工作,甚至可能是 ML+DS、DS+AI、ML+AI 或三者的组合!我希望您考虑一种定义这些领域的替代方法,将它们与工具和技术分开,并将其与最终目标联系起来。尽管它们可能使用重叠的技能、工具和技术,但是 DS、ML 和 AI 可以通过它们对实现不同最终目标的关注来区分。

以下是概括的重点领域:

数据科学是关于使用数据提供价值(金钱、增长、声誉等)。)到一个组织。

机器学习是关于使用数据进行优化的推理和预测。

人工智能是利用数据将类似人类的决策传递给机器。

有了这些定义,很容易看出这些字段非常有趣地重叠在一起。例如,能够做出类似人类的决定可能包括让更好 推论等等。向一个组织提供价值可能涉及创造具有类人决策的数字代理。类似地,在创建学习模型以使更好地预测时,人们可能希望致力于将为组织提供最大价值的指标。你可以想象,这三个学科之间的界限变得混乱,我们经常用一个为另一个服务。真正的“为什么”是你正在做的,你正在用数据做什么,这可以帮助确定你当前的工作是否应该归入数据科学、机器学习或人工智能。需要记住的另一点是,在数据科学中几乎总是有一个人类代理人参与其中。你可能会听到“这台计算机正在运行机器学习算法”或“这个数字代理正在展示人工智能”,但你不会听到“这台机器正在做数据科学。”数据科学几乎总是由人类来完成。

下面我们考虑一个简化的例子来把这些概念结合起来。

考虑一个正在研究为老年患者制造辅助机器人的医疗机构。机器人的任务是在没有人护理的情况下帮助老年病人行走。机器人需要知道这个人什么时候起床,这样它才能开始行动。这种确定可以通过观察手和腿的运动来进行。医疗保健机构将这个项目外包给另一家公司,要求他们设计一种算法(模型),可以对一个人的站立意图进行准确预测。这可以通过对图像和视频进行训练来完成,以预测哪些手和腿的运动可能表明这个人正在起床。这是一个 机器学习 项目。

一旦人起来了,机器人的任务就是帮助他们行走。最好的帮助方式是什么?那么,在这种情况下,一个训练有素的人类护理人员会怎么做呢?他们可能会走近病人,根据病人走路需要多少帮助,提供一只或两只手臂或手来依靠。此外,护理人员可以温和地抓握虚弱的人,并且更牢固地抓握,将脚牢牢地放在地上以支撑肥胖的人。让机器人模仿训练有素的人类护理员的行为是人工智能的领域。

现在考虑医疗保健机构想要决定是否继续投资这个项目。这种确定可以通过从各种来源收集数据来进行,例如老年人跌倒造成的伤害率、人类护理人员的工作时间和工资、通过使用新机器人减少的跌倒率、训练机器人的成本、技术采用率、由于减少伤害而节省的医疗费用等。一旦对数据进行了整合、建模和分析,就可以向医疗保健机构提出几项建议,例如,辅助机器人导致 80%(虚构数字)的较少跌倒,并且该机构可以在 5 年内收回其投资(虚构数字)。这个以数据开始,以对决策者有价值的见解结束的过程就是 数据科学

我希望下一次你看到这些术语时,你会比它们所使用的工具和技术看得更深。工具和技术随着时间而发展;意图依然存在。

【www.freepik.com】由故事创造的载体——

在 Python 中定义函数

原文:https://towardsdatascience.com/defining-functions-in-python-d0affe657e1d?source=collection_archive---------56-----------------------

定义 Python 函数

来源

在计算机科学中,函数提供了执行特定任务的一组指令。函数是软件程序的重要组成部分,因为它们是我们今天使用的大多数应用程序的核心。在这篇文章中,我们将讨论如何在 python 中定义不同类型的函数。

我们开始吧!

定义一个简单函数

首先,让我们定义一个简单的函数。我们使用“def”关键字来定义 python 中的函数。让我们定义一个函数来打印引用自托马斯·品钦的万有引力的彩虹:

def print_quote():
    print("If they can get you asking the wrong questions, they don't have to worry about the answers.")

现在,如果我们调用我们的函数,它应该显示我们的报价:

print_quote()

如果我们愿意,我们可以让函数使用 return 关键字返回字符串:

def print_quote():
    return "If they can get you asking the wrong questions, they don't have to worry about the answers."

然后,我们可以将函数返回值存储在一个变量中,并打印存储的值:

quote = print_quote()
print(quote)

编写函数的一种更简洁的方式是将字符串存储在函数范围内的一个变量中,然后返回该变量:

def print_quote():
    quote =  "If they can get you asking the wrong questions, they don't have to worry about the answers."
    return quote

让我们将函数返回值存储在一个变量中,并打印存储的值:

my_quote = print_quote()
print(my_quote)

用输入定义函数

现在,让我们讨论如何用输入定义函数。让我们定义一个函数,它接受一个字符串作为输入,并返回该字符串的长度。

def quote_length(input_quote):
    return len(input_quote)

我们可以定义一些变量来存储不同长度的报价。让我们引用威廉·加迪斯的中的几句话:

quote_one = "The most difficult challenge to the ideal is its transformation into reality, and few ideals survive."quote_two = "We've had the goddamn Age of Faith, we've had the goddamn Age of Reason. This is the Age of Publicity."quote_three = "Reading Proust isn't just reading a book, it's an experience and you can't reject an experience."

让我们用这些引用来调用我们的函数:

quote_length(quote_one)
quote_length(quote_two)
quote_length(quote_three)

我们还可以对输入字符串执行各种操作。让我们定义一个函数,将我们的引号组合成一个字符串。我们可以使用“join()”方法将一系列字符串组合成一个字符串:

quote_list = [quote_one, quote_two, quote_three]def combine_quote(string_list):
    return ''.join(string_list)

如果我们用“quote_list”作为输入来打印函数,我们会得到以下结果:

print(combine_quote(quote_list))

我们的函数中也可以有多个输入值。让我们的函数接受一个指定作者姓名的输入字符串。在函数的范围内,让我们打印作者的名字:

def combine_quote(string_list, author_name):
   print("Author: ", author_name)
   return ''.join(string_list)

现在,让我们调用我们的函数并打印它的返回值:

print(combine_quote(quote_list, 'William Gaddis'))

返回多个值

在一个函数中返回多个值也非常简单。让我们定义一个函数,它接受一段引文、书名、作者姓名和书中的页数。在我们的函数中,我们将创建一个数据框,其中包含报价、书名、作者和页数等列。该函数将返回数据帧及其长度。

首先,让我们定义一个引用、对应作者、书名和页数的列表:

quote_list = ["If they can get you asking the wrong questions, they don't have to worry about the answers.", "The most difficult challenge to the ideal is its transformation into reality, and few ideals survive.", "The truth will set you free. But not until it is finished with you."]book_list = ['Gravity's Rainbow', 'The Recognitions', 'Infinite Jest'] author_list = ["Thomas Pynchon", "William Gaddis", "David Foster Wallace"]number_of_pages = [776, 976, 1088]

接下来,让我们用适当的键将每个列表存储在字典中:

df = {'quote_list':quote_list, 'book_list':book_list, 'author_list':author_list, 'number_of_pages':number_of_pages}

现在,让我们将字典从 Pandas 库中传递到数据框构造函数中:

import pandas as pd 
df = pd.DataFrame({'quote_list':quote_list, 'book_list':book_list, 'author_list':author_list, 'number_of_pages':number_of_pages})

让我们放松对使用 Pandas 的显示列数量的限制,并打印结果:

pd.set_option('display.max_columns', None)
print(df)

现在让我们将这段代码包装在一个函数中。让我们将我们的函数命名为“get_dataframe”。我们的函数将返回数据帧及其长度:

def get_dataframe(quote, book, author, pages):
    df = pd.DataFrame({'quotes':quote,   'books':book, 'authors':author, 'pages':pages})
    return df, len(df)

现在让我们用列表调用函数,并将返回值存储在两个独立的变量中:

df, length = get_dataframe(quote_list, book_list, author_list, number_of_pages)
print(df)
print("Data Frame Length: ", length)

我们可以自由选择在函数中返回哪些值和多少个值。让我们也返回对应于“报价”和“书籍”列的熊猫系列:

def get_dataframe(quote, book, author, pages):
    df = pd.DataFrame({'quotes':quote,   'books':book, 'authors':author, 'pages':pages})
    return df, len(df), df['books'], df['quotes']

现在,让我们再次调用我们的函数:

df, length, books, quotes = get_dataframe(quote_list, book_list, author_list, number_of_pages) 

我们可以印刷书籍:

print(books)

和报价:

print(quotes)

我就讲到这里,但是您可以自己随意摆弄代码。

结论

总之,在这篇文章中,我们讨论了如何在 python 中定义函数。首先,我们展示了如何定义一个打印字符串的简单函数。对应一本书的引用。接下来,我们讨论了如何定义一个接受输入值、操作输入并返回值的函数。最后,我们展示了如何定义一个返回多个值的函数。我希望你觉得这篇文章有用/有趣。这篇文章中的代码可以在 GitHub 上找到。感谢您的阅读!

P 值到底是什么?

原文:https://towardsdatascience.com/defining-the-p-value-for-everyone-9103130f4fc2?source=collection_archive---------35-----------------------

数据科学概念

解释 P 值

彼得·德·格兰迪在 Unsplash 上拍摄的照片

O 作为一名数据科学家,你必须学会的第一件事是 P 值。如果你没有统计学背景,并且希望进入数据科学领域,你会遇到 P 值的概念。你最终还会发现的另一件事是,在你可能进行的任何技术面试中,你都必须解释 P 值。p 值的重要性永远不会被低估,因为它经常被用于大多数(如果不是全部)数据科学项目。

这里我们将解释 P 值的概念以及如何解释它的值。即使您没有统计学和数学背景,在本文结束时,您也应该能够理解 P 值的概念和目的。

P 值是多少?

斯文·米克在 Unsplash 上拍摄的照片

让我们从解释 P 值到底是多少开始。P 值中的“P”表示概率。它所指的值是从 0 到 1 的数值。到目前为止,这是 P 值的最基本情况。

数值的计算是由一个叫做 的东西决定的 z 值 。而 z-score 是从另一个计算 标准差 的公式推导出来的。这些都一起工作,以检索 P 值。

在这里注册一个中级会员,可以无限制地访问和支持像我这样的内容!在你的支持下,我赚了一小部分会费。谢谢!

P 值有什么用?

照片由艾丽卡·李Unsplash 上拍摄

进行统计或假设检验时,p 值用于确定结果是否具有统计显著性。这是什么意思?换句话说,这个结果是由于其他一些因素和而不是随机的。这个因素可能就是您第一次开始测试时所寻找的因素。

P 值中的数字

照片由米卡·鲍梅斯特Unsplash 上拍摄

当我们进行这些统计假设检验时,我们通常会寻找一个小于我们期望阈值的 P 值。该阈值通常小于 0.05%或 5%。为什么会有这些数字?因为这些数字在统计学上已经足够低了,而且通常是大多数统计学家设定他们统计显著性水平的地方。

该数字表示由于随机性或偶然性而获得结果的可能性。如果这个值小于 0.05,那么我们可以有把握地说,这个结果不是随机的。仅凭这一点可能还不足以得出结论,但这是一个开始。

P 值的简单示例

让我们通过提供一个示例,用更多的上下文来解释 P 值:

照片由 Rai VidanesUnsplash 上拍摄

假设你是一个面包师,刚进了一批生蜂蜜。但问题是,你以前从未吃过或听说过蜂蜜。人们告诉你,它会让你的饼干变甜,就像糖一样,但你不相信他们,你会自己尝试。所以你开始用蜂蜜做你自己的实验或测试。

首先,你把两种不同的饼干食谱放在一边。一杯加蜂蜜,一杯不加蜂蜜。然后,你混合并烘烤它们。在烤箱中烘烤后,你把它们拿出来品尝每一个,看看甜度是否有差异。你可以比没有蜂蜜的饼干更能尝到蜂蜜饼干里的甜味。然而,因为你是一个固执而传统的面包师,从不远离糖,你认为这个测试可能是侥幸的。所以你做了另一个测试,但是用了更多的饼干。

Erol Ahmed 在 Unsplash 上拍摄的照片

在接下来的测试中,你要烘烤 200 块饼干:100 块有蜂蜜,100 块没有蜂蜜。这些是很多饼干,但你要确保蜂蜜实际上是一种甜味剂。所以你在测试开始时简单陈述一下你的总体信念,统计学家称之为零假设:

“蜂蜜不会让这些饼干变得更甜”

因此,另一种替代说法,也就是统计学家所说的替代假说:

“蜂蜜会让这些饼干更甜吗”

混合、烘焙,最后品尝并给每块饼干一个甜度分数后,你开始计算 P 值:

  1. 你找到了饼干甜度分数的标准偏差。
  2. 你找到了 Z 值。
  3. 你通过知道 Z 值来找到 P 值。

在这一切之后,你得出一个 P 值,像 0.001 这样小得可笑的值。由于 p 值远低于 0.05 的统计显著性阈值,您别无选择,只能拒绝您在开始时声明的一般陈述或无效假设。你已经得出结论,根据统计概率,蜂蜜确实使你的饼干更甜。

从现在开始,你可以考虑时不时地在你的食谱中加入蜂蜜。

结论

以上是一个简单的例子,说明了人们可能如何进行假设检验,以及他们可能如何解释实验结束时的 P 值。通过使用从面包师测试结束时得出的 P 值,他们能够以足够的统计概率确定饼干中有蜂蜜会更甜。

希望你对 P 值以及如何解读 P 值有更清晰的理解。理解它们的重要性很重要,因为它们在数据科学中无处不在,最终会在面试中出现。如果你愿意,用这篇文章来准备和理解。希望你喜欢学习数学和统计学!

在 Twitter 上关注我:@Marco_Santos

人工智能产品战略的 7 个要素

原文:https://towardsdatascience.com/defining-your-ai-product-strategy-7-areas-of-focus-2cf112c82c07?source=collection_archive---------25-----------------------

构建 ML 驱动的产品、团队和业务的剧本

资料来源:Anne Nygå rd,Unsplash

构建和销售机器学习(ML)产品很难。底层技术不断发展,要求组织时刻保持警觉……而关于成功和盈利产品的规则手册仍在编写中,导致不确定的结果。

我们在 Semantics3 与机器学习产品合作了 5 年多,不得不应对许多源于行业不景气的挑战。在这篇文章中,我从这些经历中提炼出一组考虑因素,用于主动预测和处理这些突发事件。仔细考虑这些因素有助于我们调整产品以取得长期成功。

以下观点涵盖了总体趋势;当然,规范总会有例外。

#1 —人工智能/人工智能在您的产品中扮演什么角色?

象限 A(左上):以 ML 模型为核心的独立黑盒产品

你销售的是一个黑盒 ML 模型,在这个模型中,客户决定如何最好地利用所提供的智能(例如,像 Amazon Transcribe 或 Google Speech-To-Text 这样的转录服务)。

如果你的产品属于这一类,仔细想想顾客可能会给你的所有输入的怪癖。您的模型可能已经在特定的上下文中进行了训练,在您的训练数据集中有所表示,您需要防止客户测试边缘情况、接收到较差的输出并得出您的服务没有达到标准的结论。

在 Semantics3,当我们发布我们的电子商务分类 API 时,我们遇到了这一挑战…同时我们的系统被训练为接收产品名称(“苹果 iPhone X — 64GB 黑色”),客户发送的不兼容的通用输入(“iPhone”,“手机”)。

有三种方法可以防止这种情况。

  1. 确保您的产品被正确使用,要么通过定义输入的自由度(强制使用某种格式的输入),要么通过教育客户(通过文档、培训材料和直接沟通渠道)。
  2. 通过构建检测图层来拒绝不符合标准的输入(通过与训练数据进行比较来检测异常值的非监督方法效果很好)。
  3. 构建一个处理所有边缘情况的产品。这是困难的,并且可能在超过一个阈值后收益递减。但是,如果你的客户对所有人都有很强的亲和力——欢迎谷歌搜索框用户体验,它可能会带你度过难关。

象限 B(右上):以 ML 模型为核心的端到端解决方案

机器学习是你的产品的核心,没有它你的产品就无法运行,但你已经将它打包成一个更广泛的解决方案,旨在解决特定的需求(例如无人驾驶汽车)。

使用这样的产品,您可以控制自由度,从而避免黑盒方法的陷阱。您还可以获得更多的价值,并有可能扩大您的市场,为不太精明的客户提供服务。

但另一方面,自由度的减少意味着理解客户需求和设计所需体验的责任落在了你身上。您的开发团队的需求也可能更加多样化——您可能需要投资构建支持硬件、软件和数据层以及可定制的组件。我的经验是,这些挑战比前一组更容易应付。

象限 C(右下角):采用 ML 技术的端到端解决方案

机器学习实现了你产品的一个关键特性,但是即使没有任何机器学习的参与,你的产品也有显著的效用(例如网飞推荐)。

从数据科学家的角度来看,这些产品为部署 ML 模型提供了最有利的环境。由于机器学习的附加值是递增的,即使没有这一功能,客户也能获得效用,因此逐步推广和迭代是可能的。最棒的是,该产品本身通常会生成构建模型所需的训练数据集。

在这些生态系统中,机器学习有可能增加产品的价值,并建立更强的防御能力……但产品基本面需要由数据科学领域以外的举措来驱动。

象限 D(左下角):具有 ML 供电功能的独立黑盒产品

如果你的产品落入这个桶里,你就看错文章了!

#2 —您的产品如何影响客户的工作流程?

a]该产品是否通过取代相关人员来实现手动流程的自动化?

完全取代人类是一件非常困难的事情。人类有能力处理边缘情况和细微差别,这种方式对编程到模型中是一种挑战。您的模型将总是根据这个基准来衡量,并且很可能在经验上(如果不是统计上)达不到要求。

此外,减少人力成本节约的角度没有你想象的那么吸引人。客户不会主动裁员来实现节约,除非他们真的被迫这样做,并且确信你的解决方案是一个时代的解决方案,因为这种激烈的措施很难收回。即使你越过了这个障碍,你所能控制的收入上限也将永远是以节省的成本而不是交付的价值来衡量的。

如果允许预算有限的组织大规模执行原本只能在子集上完成的任务,这种策略通常效果最佳。

该产品是否能让参与手工流程的人更快地完成任务?

支持人类活动通常是更好的策略。使用这种方法,您可以利用帕累托原则并调整您的模型来处理最常见的决策类型。有了正确的产品工作流程,您可以进行设置,以便在遇到边缘情况时,人在回路中可以介入并覆盖。同样,缺点是你的附加值将会以节约成本为框架,而你的产品将会以人力来衡量。

c】该产品是否解决了以前没有类似手动替代方案的问题?

这包括以下产品:

  • 解决人类根本无法解决的问题(例如人工智能药物发现)
  • 在需要的地方释放人力(例如自动驾驶汽车)
  • 以比人快得多的速度执行决策,从而实现迄今为止无法实现的新用例(例如实时 HS 代码估计)

这些问题更像是绿地,因此争议更少,更有利于价值捕捉。

#3 —你的独特辩护销售主张(USP)是什么?

有很多原因可以让顾客发现你的产品的价值,其中一些比另一些更有说服力。

一个获得数据科学的人才

向技术采用缓慢的老行业销售可以帮助获得早期回报,但这种策略不能提供强大的防御能力。如果合同规模变得太大,产品开始变得对客户的需求太重要,或者市场上出现了新的竞争对手,那么你的立足点将开始变得薄弱。这也不是快速增长的咒语,所以不要被早期采用所迷惑。

b]唯一数据集

如果你可以访问独特的数据集,你训练的模型可能比你的竞争对手带来的更有效。但是,您应该认识到数据集的独特性:

  • 最强有力的保护形式是从一个独特的来源长期合法地保证你的访问。
  • 如果建立训练数据集的成本是阻止竞争对手的原因,那么你可以肯定,如果市场有利可图,你的蓝海不会长期没有鲨鱼。
  • 如果这种独特性源于你的先发优势或你最初客户群的规模,那么请再想一想——已经有很多关于数据网络效应 是否会形成强大的护城河的文章。

c】创新的模型架构

有时,你的数据科学团队可能非常有能力,在一个普遍可用的数据集上获得比其他任何人都好得多的结果。然而,这几乎从来不是长期防御的来源。由于该行业的开源基因,新的创新迅速扩散。更重要的是,由于创新的速度,看似开创性的技术很快就会被新的浪潮完全淹没。

通常,这三个选项中没有一个足以确保增长和防御。从长远来看,造成差异的是你如何将它们结合在一起,来制作你的过程和产品。流程是指如何将模型和数据集与人在回路中、分类法、试探法和分析法编织在一起,以解决手头的问题。产品是指如何以满足客户需求的方式使这些过程对客户可用。

#4 —人类在你的循环中扮演什么角色?

“每当你有歧义和错误时,你需要考虑如何将人置于循环中,并升级到人来做出选择。对我来说,这是人工智能产品的艺术形式。如果你有歧义和错误率,你必须能够处理异常。但首先你必须检测出异常,幸运的是,在人工智能中,你有信心、概率和分布,所以你必须利用所有这些让人类参与进来。”——塞特亚·纳德拉

具有讽刺意味的是,人工智能需要人类才能使其可用,无论是处理边缘案件,建立训练数据集,生成启发式或量化样本准确性。在这些人类活动中,有些活动比其他活动影响力更大,成本更低。你如何将人的角色设计到你的产品工作流程中,将决定你的成本和你的用户体验。一些需要思考的观点:

  • 你有没有在你的产品中建立反馈环,让你的用户间接地“训练”你的模型?还是所有识别和提供反馈的成本都由您的后端注释团队承担?
  • 您的注释团队是否处理单个数据点,或者您是否有一种机制让他们交流他们在数据中看到的更广泛的模式?
  • 你会像一个庞然大物一样解决潜在的问题吗?还是使用智能采样技术和主动学习模型将人的注意力集中在可以提供最高 RoI 的地方?

#5 —您的客户如何衡量您产品的质量?

在学术界,ML 系统的质量是通过对 ImageNet 等标准化数据集进行基准测试来衡量的,精确度越高,模型越好。

然而在工业界,这些标准化的基准并不存在。您训练的数据集是自定义的,可能不代表手头的问题-事实上,最大的挑战通常是建立一个准确模拟问题的数据集。此外,没有两个客户从同一个角度看待问题,因此单一精度/召回基准的想法是象征性的,最多可能是指示性的。加上像数据漂移和概念漂移这样的现象,你会发现自己漂浮在海上,没有锚。

你面临的挑战是不仅要找到一种方法来衡量每个客户的质量,还要找到一种方法来将这个数字传达给客户,以管理他或她对你产品的看法。我们使用 5 个步骤来处理这个问题:

a】统计教育

让你的客户了解统计思维和经验思维的区别。无论你采取什么样的措施,边缘案例和断层线总是存在的。虽然从统计数据来看,完美几乎从来不是一个要求,但问题是人类倾向于凭经验思考。客户对个别例子的负面反应并不少见(导致数据科学家发泄他们的统计愤怒)。

然而,统计教育说起来容易做起来难,即使你与客户有直接的沟通渠道。我倾向于从与客户的第一次营销互动开始,并确保这种想法渗透到您的销售组织的推销中。顾客通常会接受合理的论点,即使竞争对手向他们许下种种承诺。根据你的业务性质,以及你与客户的接触程度,你可能需要找到创新的方法来做到这一点。

b】确定代表性数据集

寻找或建立一个数据源,定量地获取客户使用产品的方式。通常,这包括跟踪和记录客户行为,无论是输入到您的模型中,还是基于反应的反馈循环。该数据集代表了客户的问题空间。

c】抽样方法

如果代表性数据集的大小太大而无法进行分析或标注,则决定一种采样方法来放大到更小的子集。

d】评估方法

确定最能抓住客户优先事项的指标。如果要对数据集进行注释,就要包含一组简单且一致的规则来定义如何进行注释。此外,决定执行这些评估的频率。

e】设定目标和补救措施

确定每个指标的最小阈值,以及如果没有达到这些阈值将采取的补救措施。

f】获得客户认可并定期报告

这是关键部分——尽你所能,让客户了解你选择采用的方法,并且最好将他们的反馈反馈反馈到流程中。然后,定期严格地主动向客户提供这些指标,以消除任何不满。

如果您从事销售企业合同的业务,并且每个客户的毛利润很高,请将这些指标用作合同中保证的 SLA。虽然这给你的团队带来了更多的挑战,但它确保了任何关于质量的讨论都是通过一个共同的统计透镜来简化的。

讨论了所有这些之后,统计教育说起来容易做起来难。由于各种各样的原因,观察者偏差很难克服。我们遇到过很多这样的情况,我们产品的日常用户对我们的方法很满意,但是当一个高级主管(和产品的零星用户)遇到一个边缘情况并敲响了所有的警钟时,他们就变得手忙脚乱了。要处理这种情况,请考虑内置覆盖机制来根据症状处理问题。你的数据科学团队中的清教徒可能会不高兴,但这是一个你可能想要做出的权衡,以确保对你的产品功效的感知不会被变幻莫测的机会所左右。

此外,客户特定的调整和测量并不便宜。您必须考虑质量和成本之间的权衡,并配置您的定价模型,以将这些“支持”成本转嫁给客户。

# 6——你是否接受了过多的挑战?

ML 产品团队在两种项目上花费了大量的时间,这两种项目损害了用户体验并增加了运营成本。

解决不属于产品核心价值主张核心的“模糊”问题

可以用机器学习解决的问题范围很广。然而,这并不意味着你遇到的所有问题都应该用机器学习来解决。在构建您的产品时,您可能会遇到许多挑战,数据科学团队对此的第一反应是使用 ML。在这样的时刻,有必要问一下,是否有不那么优雅、效率可能更低、但更简单的解决方案可供选择。

机器学习通常被视为必须尽可能撒在任何地方的魔法灰尘,即使是那些理解它的人也是如此。训练第一组模型来解决一个新问题,甚至交付有希望的结果,可能是非常容易和令人兴奋的。但是如上所述,部署到生产环境需要的不仅仅是一个有好结果的模型。因此,在实践中,尽可能少用魔法,求助于不那么令人兴奋但肯定有效的替代方法,比如启发式……或者尽可能完全放弃产品功能,这可能不是一个坏主意。

b】内部构建工具以弥补开源或云生态系统中的空白

Tensorflow 和 PyTorch 是两个领先的深度学习框架,还不到 5 岁。像 Sagemaker 和 Kubeflow 这样的基础设施工具还不到 2 岁。开源工具的生态系统才刚刚兴起,每隔几个月就会有新的改变游戏规则的库出现。

当您开始使用这些工具时,您经常会发现您的特定开发工作流或产品特性所必需的某些组件不见了。对于一个有进取心的工程师团队来说,这可能是一个建立新工具来填补空白的号召。在 Semantics3,这些年来我们已经这样做了很多次。我们已经建立了一个并行处理暨缓存层,用于处理需要大量预处理的训练数据集…最近,我们使用脸书的 FAISS 库创建了我们自己的网络数据库。

不过,这种暴跌应该仔细考虑,并通过构建 vs 购买 vs 等待演算。如果你发现开源或云生态系统中有一个巨大的需求需要满足,很可能你不是唯一的一个,其他人也在做这件事——询问周围的人以获得早期访问是值得的。如果你没有其他选择或者发现你的需求很紧急,记住这些工具需要定期维护,尤其是当它们被放在你的书架上的时候。

#7 —您的数据科学团队是否具备完成手头任务的合适 DNA?

一旦你理解了你的产品是什么,你就可以反过来确定你需要组建什么样的团队:

  • 你正在解决绿色领域的问题吗?这些问题要求你在这一领域的工作中聘请最前沿的博士。
  • 您的增值是否来自调整模型架构—您是否需要一群数据科学家整天训练模型和优化超参数?
  • 钉住边缘案例对你的用户体验至关重要吗——你是否需要有黑客心态的测试人员来放弃注释思想、启发式框架和其他合适的工具?
  • 在这里,对领域的深刻理解是必不可少的吗——你需要对你的问题领域有多年经验的人吗?
  • 您的销售和售后流程的结构化程度如何?您是否需要通才数据科学家与整个组织的员工合作,以确保流程正确?
  • 优化运营执行的云成本是否是获得合理毛利润的瓶颈——您是否需要同时拥有基础架构头衔的数据科学家?
  • 如果 ML 模型只是一个更大整体的一个组成部分,那么在预算有限的情况下,你需要在产品经理和前端工程师身上投资多少

我见过一些产品是由大批 ML 工程师在发布前制造的,还有一些是由游击队员组成的迷你披萨团队制造的。一个和另一个是不一样的,每个群体对挑战的反应都不一样。拥有正确的 DNA 会带来巨大的不同。

总之,企业主对价值主张、防御能力和成本的计划越多,增长的可预测性就越大。产品经理对他们的方法考虑得越周到,ML 模型、环中人和客户工作流之间的和谐就越大。数据科学经理对工具选择和团队构成越慎重,代码和愿景之间的协同作用就越大。客户负责人在衡量质量和管理认知方面越系统,你的流失率就越低。

“人工智能行业”不是一个整体——有许多方法来构建机器学习支持的产品。虽然现在还为时尚早,这方面的剧本还在继续编写,但如果你正着手在这个领域开发一款产品,那么系统地考虑可能影响你成功的各种决策会有所帮助。

绝对不要点击这个点击诱饵

原文:https://towardsdatascience.com/definitely-dont-click-on-this-click-bait-20d3289a7691?source=collection_archive---------27-----------------------

Unsplash 上的 Mael BALLAND 拍摄的照片

社交媒体的政治

互联网政策假新闻技术算法伤害社会

W 社交媒体出现之前的世界是什么样的?在六度、Friendster、LinkedIn、MySpace、Twitter、Snapchat、Reddit、Instagram 和脸书出现之前,社会是什么样子的?

2004 年,MySpace 成为首个月活跃用户达到 100 万的社交媒体网站。如今,脸书拥有超过 1.62 亿 日活跃用户。虽然 Instagram、WhatsApp 和 Messenger 等公司帮助这一数字增长,但不可否认的是,社交媒体已经深深嵌入社会。

快速的技术变革不是没有代价的。用户慢慢发展社交媒体平台,以适应他们的 UX 需求,但人们往往忘记了社交媒体如何同样影响社会。

“技术不仅是人类活动的辅助工具,也是重塑人类活动及其意义的强大力量。”—兰登·温纳

听过煮青蛙的古老寓言吗?

要煮一只活青蛙,把它放在一锅沸水里是行不通的——它会直接从锅里跳出来。相反,必须将它放入一壶室温的水中,随着时间的推移慢慢加热。青蛙不会意识到它舒适的炉顶热水浴缸已经成为一个坟墓,直到为时已晚。

社交媒体就像一口烧开的锅

每个社交媒体平台都有被黑客操纵的风险。算法多年来一直受到攻击。每天有超过 10 亿的活跃用户,这些算法有能力引导社会走向更好或更坏。一些平台比其他平台面临更大的攻击风险。

1.Twitter 趋势

Twitter 最脆弱的算法是允许标签、事件和短语免费到达数百万观众的算法。虽然 Twitter 趋势最初是为了显示用户周围的实际上是趋势信息而创建的,但它已经成为参与度操纵的一个大目标。

对于黑客来说,Twitter 的趋势比简单的 #throwbackthursday 要强大得多。数百万的观众很容易就足以左右选举,传播假新闻,隐藏重要的真相。

2011 年,垃圾邮件即服务市场攻击 Twitter 趋势,审查关于俄罗斯议会选举结果的公众意见。2012 年,墨西哥竞选总统的政客雇佣了成千上万的墨西哥公民通过推特操纵趋势来影响公众舆论。2015 年,趋势算法被用于试图让公众脱离伊朗核谈判,也被用于推动委内瑞拉公众的政治观点

黑客们发现了如何人为夸大虚假趋势和人为缩小真实趋势来操纵公众知识和参与度。甚至还存在秘密市场和团体,它们可以被雇佣来以低廉的价格人为地创造一种 Twitter 趋势。

换句话说,黑客、垃圾邮件制造者和政客已经找到了非常有效的方法来控制哪些内容会出现在 Twitter 的首页。尽管 Twitter 在打击其平台上的虚假趋势和机器人方面做得很好,但决定什么时候成为趋势的算法仍然是专有的。这意味着用户没有办法知道 Twitter 趋势是真是假。*

2.剑桥分析和脸书公司

2015 年至 2018 年间的扎克伯格迷因和大数据流行语让许多数字公民感到害怕、有趣和严重困惑。脸书和剑桥分析公司之间到底发生了什么,出了这么大的问题?

这是几年前开始的。剑桥分析公司最初并没有违反任何法律。脸书也没有。剑桥分析公司只是一家战略传播公司。他们利用潜在选民的数据来战略性地与他们交流选举细节(并希望说服他们投票给他们的客户)。然而,他们做了一些错误的决定。

2013 年,剑桥分析公司开始通过完全合法的手段收集脸书用户的数据。他们最初收集的每个用户的账户都是经过同意的。这不成问题。

当分析公司开始滥用这种同意时,问题就出现了。对于每一个同意的用户,他们也可以从他们账户上的所有朋友那里获得所有的个人资料信息,而不需要征得同意。

他们开始收集数据;大量的数据。

数据变成了力量。他们对人们了解得越多,就越能影响他们。

“今天在美国,我们在每个人身上有近四五千个数据点……所以我们对美国大约 2.3 亿成年人的个性进行建模。”——剑桥分析公司首席执行官亚历山大·尼克斯,2016 年 10 月。

2015 年,特德·克鲁兹竞选团队聘请剑桥分析公司帮助他影响目标潜在选民。2016 年,川普竞选团队做了同样的事情。2018 年,一名举报者将这一政治活动公之于众。

剑桥分析公司违法了吗?关于这个还有争论。

剑桥分析公司的行为不道德吗?这就更清楚一点了。简而言之:

  1. 该公司从没有明确表示同意的不知情的社交媒体用户那里收集数据。这些用户也没有被告知他们的数据是在事后收集的。
  2. 这些数据是打着【学术目的】的幌子收集的,而它却被用于完全不同的用途。

说到研究,大多数伦理问题都不是法律问题。

在第二次世界大战期间对人进行了不人道的科学实验后,机构审查委员会(IRB)成立,为科学家提供伦理指导。

在大学,IRB 委员会管理研究伦理。社交媒体数据挖掘很难监管,因为很难知道什么被认为是“公开可用的数据”。例如,收集和分析公开的 Twitter 帖子进行研究通常不需要征得同意。但是,下载一个脸书朋友的私人帖子需要得到同意。

如果剑桥分析公司要求 IRB 批准他们的活动,他们会被拒绝。未经同意,他们不可能收集任何“朋友”的个人资料。他们也不可能将人类数据用于与其最初意图不同的目的。

一些人仍在争论剑桥分析公司是否真的对美国选举进程产生了那么大的影响。截至目前,还没有办法衡量其影响。

然而,不可否认的是,剑桥分析公司收集的数据是危险的和强大的。**

我们是青蛙

拍摄的照片

社交媒体公司可能是公开交易的,但它们是私有的。用户可以免费玩游戏,那么这些大型科技巨头是如何赚钱的呢?

如果你不是顾客,你就是产品。

UX 设计最初并不是为了让用户满意而创造的。它是为用户保留期创建的。社交媒体用户不用钱支付,他们用数据支付。用户就是产品。真正的客户是那些想要数据、想要喜欢和想要参与的人。

对于剑桥分析公司来说,参与就是投票率。对脸书来说,互动吸引了广告商。对于 Twitter 趋势来说,参与影响了从选举到公共审查的一切。

社会还能怎样被社交媒体无声地伤害?

每天都有数十亿人使用社交平台。数以万亿计的文字被发布、点赞、分享、发推特,并传播给大众。算法操纵只是众多危险之一。最近的研究强调了社交媒体上出现的一些有趣现象:

  1. 过滤气泡和回音室:社交媒体用户经常上网,让自己置身于类似的社区中,有效地将自己置于一个重申其信仰/观点的内容“气泡”中。当推荐与兴趣相匹配时,过滤泡沫就会加剧,思想的多样性就会消失。当用户被推入极端分子的回音室时,这变得更加危险。
  2. 反馈回路:

clickbait 的示例。这些能激起你的兴趣吗?

从心理学上来说,人类更容易传播吸引两样东西的信息:情感和信任。情感是由点击诱饵和极端主义引发的。某样东西看起来越令人兴奋,就越能引发我们的注意。社交媒体上的信任以喜欢和分享的形式出现。又名:人们信任那些被分享和喜欢的帖子。

具有讽刺意味的是,假新闻引发争议。争议滋生情绪。情绪引发更多的喜欢和分享。喜欢和分享创造信任。直接导致人们信任误传

总之,社交媒体上的内容总是主观的,而且经常是假的。但是用户没有办法衡量它的主观性或有效性。

青蛙正在享受温水。

如何走出沸腾的锅

照片由拉德·格林Unsplash 上拍摄

第一步:背书

大约一年前,我把手机换成了西班牙语,为去南美旅行做准备。虽然切换语言让我对优秀的 UX 设计有了新的欣赏,但它也让我在一天早上滚动 LinkedIn feed 时获得了有趣的见解。

在英语中,当我想对 LinkedIn 上某人的帖子做出反应时,我会点击“ like ”按钮。然而,在我的西班牙语手机上,我注意到“喜欢”按钮在西班牙语中没有被动词“ gustar ”(喜欢)取代。取而代之的是“建议者”。

这种区别非常重要。

**在社交媒体上喜欢某件事并不一定等同于同意某件事。如果我喜欢一条推文或一个帖子,我很容易讨厌那个帖子。我可以对一个帖子有各种各样的情绪,但仍然喜欢它。我可能会喜欢一篇让我感到非常愤怒的虚假政治新闻文章。我会喜欢一个点击诱饵,因为它有一个有趣的标题。

在西班牙语中,recomendar 的意思是推荐建议,或者建议

如果我看到一篇假新闻文章,我会推荐别人看吗?我会建议我的朋友受它的影响吗?我会建议向公众传播吗?大概不会。

这让我想知道,如果“喜欢”按钮变成了“认可”按钮,社交媒体会发生怎样的变化。当参与等同于认可时,用户传播的错误信息就少了,假新闻也不再像以前那样有那么大的影响力。

第二步:脸书的内部评级法

《剑桥分析》并不是脸书第一次被置于公众监督之下。2016 年,一个 A/B 测试出错的案例凸显了一个怪异的未来。脸书的研究人员发表了一篇关于脸书情绪传染能力的论文。

这篇文章强调了一些可怕的事实,其中之一是脸书时间线的内容严重影响了用户的离线情绪。研究人员通过随机选择一组脸书用户作为更多负面时间线内容的实验对象,而另一组则被给予更多正面时间线内容,从而发现了这一点。不足为奇的是,结果证明了脸书供稿中内容的情感确实与消费该内容的用户的情感相关。又名:负面的社交媒体信息会产生负面的人,反之亦然。

这项研究发表后,公众强烈反对。脸书用户对该公司在未经他们同意的情况下将他们的在线生活用作实验室感到愤怒。讽刺的是,这些研究一直都在发生。私企每天都在用户身上做 A/B 测试,没有问过他们。这是用户在签署社交媒体最畅销的条款和条件文档时同意的许多事情之一。

不管怎样,公众对脸书在他们身上做实验感到愤怒。幸运的是,脸书像大学一样,创建了自己的内部 IRB 委员会。脸书的 IRB 由五名员工组成,他们审查提交的研究来决定它们是否符合伦理。

虽然脸书的内部评级法还有很大的改进空间,但这是朝着非常好的方向迈出的一步。

目前,在不道德行为成为法律问题之前,私有公司不会被追究责任。当涉及到社交媒体时,这个概念可能会非常危险,原因有两个:(1)对于数据隐私,大多数道德问题都不是法律问题。(2)在操纵参与度的情况下,当技术丑闻成为法律问题时,伤害通常已经造成了。

针对私营科技公司的内部评级法可以消除这些担忧。如果政策不支持技术伦理,那么公共关系可以为合规提供动力。对于社交媒体公司来说,如果 IRB 意味着增加用户保留率,那么道德就是性感的。

第三步:正念

多年来,特朗普一直在发动一场反对媒体的战争。这是一个危险的游戏。如果新闻机构失去了全体民众的信任,还有可能区分现实和诱饵吗?

即使是现在,当你登录你的脸书、Twitter、LinkedIn 或者你喜欢的社交媒体时,是什么让你相信你所看到的是真实的呢?你真的确定你上周分享的文章不是假的吗?你的 feed 里那些推荐的文章呢,你能相信那些吗?Twitter 上的这种趋势是由人还是由机器人发起的呢?

在一个充满误传的世界里,真理的源泉在哪里?有吗?

我不认为特朗普应该与媒体机构开战。当所有的新闻都被看做假新闻,社会就不知道该相信谁了。

然而,怀疑并不一定是一件坏事。

许多主观的真理拼凑在一起,可以描绘出一幅类似客观的画面。

这就是为什么做一个负责任的数字公民是如此重要,尤其是在社交媒体网站上。假新闻没有。私营科技公司没有内部评级法。剩下的只有直觉和信任。

以下是我的主观建议:

如果你的新闻订阅中出现了一篇有争议的文章,在点击分享按钮之前做一些研究。不要相信 clickbait,除非你知道它会把你带到哪里。在网上要小心。为信息丰富的互联网做出贡献,而不是有害的互联网。

不要做开水锅里的青蛙。

不要相信你看到的一切。

不要相信你所相信的一切。

脚注:

召集所有编码员!!如果你有兴趣成为一个更用心的数字公民,请随意查看我制作的这个教程。在这个回购中,您将获得尝试逆向设计 Twitter 趋势算法所需的所有资源,以更好地了解是什么推动了我们的在线参与。*

* [## jesmith 14/Twitter 趋势

欢迎光临!在您开始之前,我建议您阅读这项研究的报告。在本存储库/教程中…

github.com](https://github.com/jesmith14/TwitterTrends)*

可变形卷积及其在视频学习中的应用

原文:https://towardsdatascience.com/deformable-convolution-and-its-applications-in-video-learning-e21005cab58e?source=collection_archive---------42-----------------------

实践教程

利用带有稀疏标记数据的视频帧

(来源

卷积层是卷积神经网络的基本层。虽然它广泛应用于计算机视觉和深度学习,但它有几个缺点。例如,对于特定的输入特征图,核权重是固定的,并且不能适应局部特征变化,因此我们需要更多的核来建模特征图的复杂上下文,这是多余的并且效率不高。此外,由于输出像素的感受野总是矩形,作为分层卷积的累积效应,感受野变得更大,其中将包含一些与输出像素无关的上下文背景。不相关的背景会给输出像素的训练带来噪声。

想象一下,为了克服上述问题,你想对传统的卷积层做一个小小的改变:核可以适应局部特征变化,感受野可以收敛到与输出像素对应的语义背景。幸运的是,它已经实现了,细化卷积层的名称叫做可变形卷积层。

在本帖中,我将介绍这些话题:

  1. 可变形卷积
  2. 利用可变形卷积提高关键点估计的性能
  3. 使用可变形卷积增强实例分割的性能

可变形卷积

(可变形卷积)

可变形卷积是卷积层加偏移学习。如上所示,对于卷积核的每个足迹,学习 2D 偏移,以便将足迹引导到对训练最优化的位置。偏移学习部分也是卷积层,其输出通道的数量是输入通道数量的两倍,因为每个像素有两个偏移坐标。基于该方法,核可以适应局部特征变化,有利于语义特征学习。

(覆盖区偏移示例)

这是偏移学习的一个例子。a 是传统的卷积,其中内核足迹完全不移动。b、c 和 d 表示足迹的移动。

(可变形卷积的感受野细化)

结果,在可变形卷积中,深像素的感受野集中于相应的物体。如上图,在 a 中,深蓝色像素(上图)属于大羊。然而,它的矩形感受野(底部)包含左下方的小绵羊,这可能会为实例分割等任务带来模糊性。b 中感受野变形,集中在大羊上,其中避免了歧义。

理解可变形卷积中的偏移

如上所述,偏移有助于局部特征的核心适应和感受野的集中。顾名思义,offset 用于使内核足迹局部变形,从而使感受野整体变形。

现在棘手的部分来了:既然可以学习偏移来适应当前图片中的对象,我们是否可以通过提供偏移来使当前图片中的对象适应另一张图片中的对象?

让我们把它具体化。假设我们有一个视频,其中每一帧都与其相邻帧相似。然后,我们稀疏地选择一些帧,并在像素级对它们进行标记,如语义分割或关键点等。既然这几类像素级的标签都很贵,那我们能不能用无标签的相邻帧来提高概化的精度呢?具体来说,用一种方法将未标记帧的特征图变形到其相邻的标记帧,以补偿标记帧中缺失的信息?

从稀疏标记视频中学习时间姿态估计

(特征地图扭曲模型)

这项研究很好地解决了上面讨论的问题。由于标记是昂贵的,所以在视频中只有少量的帧被标记。然而,标记帧图像中的固有问题,如遮挡、模糊等。阻碍模型训练的准确性和效率。为了解决这个问题,作者使用可变形卷积将未标记帧的特征映射变形为它们相邻的标记帧的特征映射,以补偿上面讨论的固有问题。偏移量就是已标记帧与其未标记相邻帧之间的优化特征差异。可变形部分由多分辨率特征金字塔构成,其中使用了不同的膨胀。这种方法的优点是,我们可以利用相邻的未标记帧来增强标记帧的特征学习,因此我们不需要标记视频的每一帧,因为相邻的帧是相似的。这种变形方法,也被作者称为“扭曲”方法,比其他一些视频学习方法,如光流或 3D 卷积等,更便宜,更有效。

(扭曲模型的训练和推断)

如上所示,在训练期间,未标记帧 B 的特征图被扭曲到其相邻的标记帧 A 的特征图。在推断期间,帧 A 的基本事实可以使用训练的扭曲模型来传播,以获得帧 B 的关键点估计。此外,可以扭曲更多的相邻帧,聚集它们的特征图,以提高关键点估计的准确性。

具有掩模传播的视频中的实例分割

(基于掩码 RCNN 的掩码传播)

作者还通过在现有的 Mask-RCNN 模型中添加掩模传播头,提出了用于实例分割的掩模传播,其中在时间 t 的预测实例分割可以传播到其相邻的帧 t + δ。

(掩模传播的网络结构)

网络结构类似于上面讨论的姿态估计网络,但有点复杂。它有三个部分:1)帧 t 的实例分割预测;2)帧 t 和 t + δ之间的偏移优化和分割变形;3)用于帧 t + δ处实例分割的最终预测的特征图聚集。在这里,作者还使用乘法层来过滤噪声,只关注对象实例存在的特征。利用来自相邻帧的特征集合,可以减轻遮挡、模糊的问题。

结论

可变形卷积可以被引入到具有给定偏移的视频学习任务中,其中标签传播和特征聚集被实现以提高模型性能。与传统的一帧一标签学习方式相比,作者提出了多帧一标签学习方式,利用相邻帧的特征图来增强表征学习。因此,模型可以被训练来从相邻帧中看到被其他眼睛遮挡或模糊的内容。

参考

可变形卷积网络,2017
从稀疏标记的视频中学习时间姿态估计,2019
利用掩模传播对视频中的对象实例进行分类、分割和跟踪,2020

[## 加入我的介绍链接-陈数杜媒体

阅读陈数·杜(以及媒体上成千上万的其他作家)的每一个故事。您的会员费直接支持…

dushuchen.medium.com](https://dushuchen.medium.com/membership)

去神秘化的可变形卷积

原文:https://towardsdatascience.com/deformable-convolutions-demystified-2a77498699e8?source=collection_archive---------5-----------------------

可变形卷积越来越受欢迎,并被应用于复杂的计算机视觉任务,如物体检测。在这篇文章中,我将尝试详细解释它们,并阐明它们在未来计算机视觉应用中的重要性。

(来源)

先决条件:

帖子的读者必须对卷积神经网络有一个基本的了解。如果你不熟悉这个话题,你可以参考这个链接 如果你想了解更多关于卷积运算的知识,它实际上是从基本的图像处理中派生出来的,你也可以阅读这个 博客

介绍

简而言之,卷积神经网络或 CNN 是人工智能研究在一个非常艾龙的冬天之后复兴的主要原因之一。基于它们的应用首次展示了人工智能或深度学习的力量,并恢复了该领域的信心。在马文·明斯基指出感知器只能处理线性可分数据,而不能处理最简单的非线性函数(如 XOR)后,这种信心已经丧失。
卷积神经网络在计算机视觉领域非常流行,几乎所有最新的应用程序,如谷歌图像、无人驾驶汽车等,都基于它。在非常高的水平上,它们是一种神经网络,其关注局部空间信息,并使用权重共享以分层方式提取特征,这些特征最终以某种特定于任务的方式聚集,以给出特定于任务的输出。

虽然 CNN 在视觉识别任务方面表现出色,但在对物体比例、姿态、视点和部分变形的几何变化或几何变换建模时却非常有限。
几何变换是将图像的位置和方向变换为另一个位置和方向的基本变换。
一些基本的几何变换包括缩放、旋转、平移等。
卷积神经网络缺乏模拟几何变化的内部机制,只能使用固定且受用户知识限制的数据扩充来模拟几何变化,因此 CNN 无法学习用户未知的几何变换。
为了克服这个问题并增加 CNN 的能力,微软亚洲研究院推出了。在他们的工作中,他们引入了一种简单的高效的端到端的机制,使得 CNN 能够根据给定的数据学习各种几何变换。

为什么卷积神经网络无法模拟几何变换?

图一。简单卷积运算 ( 来源 )

图二。2x2 矩形内核的最大池操作(来源)

CNN 对模型几何变换的限制源于用于从特征图采样的核的固定结构。CNN 内核使用固定的矩形窗口(图 1 )在固定位置从输入特征地图中进行采样,汇集层使用相同的矩形内核(图 2 )以固定比率降低空间分辨率。这引入了各种问题,例如给定 CNN 层中的所有激活单元具有相同的感受野,即使在不同的空间位置可能存在不同尺度的对象。对于需要精细定位的视觉识别任务,例如物体检测、分割等,需要适应物体的比例并对不同的物体具有不同的感受野大小。

可变形卷积

高级解释:

在可变形卷积中,为了将不同对象的尺度考虑在内并根据对象的尺度具有不同的感受野,在标准卷积运算中,将 2D 偏移添加到规则网格采样位置,从而使前面激活单元的恒定感受野变形。使用额外的卷积层,添加的偏移可以从前面的特征图中获知。因此,所应用的变形以局部、密集和自适应的方式取决于输入特征。添加的可变形卷积层向现有模型添加了非常小的参数和计算,并且可以使用正常的反向传播进行端到端训练。

图 3。正常卷积运算(a)与可变形卷积运算(b,c,d)的采样位置。

详解:

为了详细解释可变形卷积,我将首先讨论正常的卷积运算,然后解释将它们转换为可变形卷积的简单思想。

正常的卷积运算包括两个基本步骤:

  1. 使用矩形核对输入图像或特征图的小区域进行采样。
  2. 将采样值乘以矩形核的权重,然后在整个核上对它们求和,以给出单个标量值。

我会用方程式和视觉的形式来解释以上两个概念。
让我们先试着用数学方程式来理解。

设 R 是一个 3×3 的核,用于对输入特征图的一个小区域进行采样。

方程式 1。采样内核

那么正常的二维卷积运算的等式将如下图所示,其中 w 是核的权重, x 是输入特征图, y 是卷积运算的输出, p₀ 是每个核的起始位置, pₙ 是 r 中所有位置的枚举

方程式 2。普通卷积运算

该等式表示卷积运算,其中采样网格上的每个位置首先乘以权重矩阵的相应值,然后求和以给出标量输出,并且在整个图像上重复相同的运算给出了新的特征图。

下面直观地描述了上面解释的操作,其中绿色内核滑过由蓝色矩阵描述的图像,并且相应的权重值与来自图像的采样值相乘,然后求和以给出输出特征图中给定位置的最终输出。

图 4 。卷积运算的直观演示

可变形卷积不是使用简单的固定采样网格,而是将 2D 偏移引入到上述正常卷积运算中。

如果 R 是正常网格,则可变形卷积运算将学习到的偏移增加到网格,从而使网格的采样位置变形。

可变形卷积运算由下面的等式描述,其中δpₙ表示添加到正常卷积运算的偏移。

方程式 3 。变形卷积运算

现在,由于采样是在不规则和偏移位置上进行的,并且δpₙ通常是分数,我们使用双线性插值来实现上述等式。
使用双线性插值是因为当我们向现有采样位置添加偏移时,我们获得的分数点不是网格上定义的位置,为了估计它们的像素值,我们使用双线性插值,使用相邻像素值的 2x2 网格来估计新变形位置的像素值。

下面给出了用于执行双线性插值和估计分数位置处的像素值的等式,其中 p(**p₀+pₙ+δpₙ)**是变形位置, q 列举了输入特征图上的所有有效位置,而 G(..)是双线性插值核。****

方程式 4。双线性插值运算

注: G(..)是二维的,并且可以根据轴分解成两个一维内核,如下所示。

方程式 5。轴向双线性插值内核

从视觉上看,可变形卷积的实现如下图所示。

图五。可变形卷积运算的可视化表示

如图图 5 所示,通过在输入特征地图上应用卷积层获得偏移。所使用的卷积核具有与当前卷积层相同的空间分辨率和膨胀。输出偏移字段的分辨率与输入要素地图的分辨率相同,具有 2N 个通道,其中 2N 对应于 N 个 2d 偏移。

网络修改详细信息

可变形卷积层主要应用于卷积网络的最后几层,因为与提取更多基本特征如形状、边缘等的早期层相比,它们更可能包含对象级语义信息。实验结果表明,将可变形卷积应用于最后 3 个卷积层在诸如对象检测、分割等任务中提供了最佳性能。

图 6。标准卷积中固定感受野和变形卷积运算中自适应感受野的图示。

使用可变形卷积的优点

图 7。描绘每个对象的适应性感受野的三联图像。

使用可变形卷积运算的优势在图 7 中有清晰的描述。如您所见,有 4 个图像三元组,其中特定三元组中的每个图像描绘了关于特定对象的感受野。如果这是一个正常的卷积运算,那么给定图像中所有物体的感受野应该是相同的。但是正如你所注意到的,在可变形卷积的情况下,感受野根据物体的大小是自适应的。与大尺寸物体相比,小尺寸物体(例如第一组中的汽车)具有较小的感受野。你可以注意到,背景物体的感受野是最大的,与前景物体相比,需要大的感受野来检测背景物体。

结论:

在这篇文章中,我试图解释可变形卷积,这种卷积在当前新颖的对象检测和分割模型中很容易应用。它们获得动力的主要原因是它们提供了内部机制,使卷积神经网络能够模拟各种空间变换。它们提供了自适应感受野的优势,该感受野从数据中学习并根据对象的规模而变化。

希望你喜欢这篇文章,如果你有任何疑问或建议,请使用 TwitterLinkedIn 联系我。

参考文献:

  1. 可变形卷积网络。戴,齐,熊,李,张,胡,魏

通过 NLP & R 提供即时商业价值

原文:https://towardsdatascience.com/delivering-immediate-business-value-with-nlp-r-c51020d72ce4?source=collection_archive---------44-----------------------

让我们面对现实吧——我们不能整天坐在那里训练神经网络

照片: 弗洛伦西亚 Viadana ,Unsplash

作为数据科学家,我们的工作是为企业提供切实的底线结果。虽然我喜欢整天训练神经网络,但关键是我们要与业务部门建立稳固的关系,并找到交付易于理解和量化的价值的方法。

除非你在一家大型科技公司工作,否则你的团队很可能有大量的分析用例。在这个简短的教程中,我将为您提供代码,并概述如何利用基本的自然语言处理(NLP)来交付真实、可沟通、有价值的分析。

关于从互联网上收集必要的文本数据的教程(和一些警告),请查看我关于 web 爬行的文章:

完全初学者的第 1 部分可以在这里找到和第 2 部分,在那里我们采取了一种更加面向对象和可重用的方法,可以在这里找到

TL;博士-给我密码

数据集可以在这里找到(代码中也有链接)。********

让我们来分解一下:语料库

语料库是我们将用于 NLP 的核心数据结构。因为我们将一个字符向量传递给 Corpus()函数,所以我们需要指定源是一个向量源。使用 inspect()方法将允许您查看新创建的语料库。

在语料库创建之后,我们使用一些常用的方法清理文本数据。我们的 cleaner()函数做了一些基本的操作,比如删除数字,但是它也删除了所有的停用词,这些词本身没有什么意义。流行的停用词是“the”和“a”

请注意,删除停用字词时可能会丢失一些信息。这就是分析变得更像艺术而不是科学的地方。你可以选择只删除基本术语,也可以决定删除特定行业术语,等等。

产品的原始评论(图片由作者提供)

去掉了停用词。请注意,“它没有”不再出现在句子中(图片由作者提供)

TDM 和词云

当我们创建语料库时,R 基本上将每篇评论编码为一个单独的文本文档。术语文档矩阵(TDM)采用语料库,并对每个单词制作一个的矢量化频率表。下面是一个 TDM 中包含 3 个虚拟评论的示例:****

TDM 是如何制作的示例(图片由作者提供)

从这个 TDM 中,我们可以创建一个矩阵,按行和(词频)排序,然后使用词云可视化结果。这是我们分析的第一部分。

药品评论的文字云(图片由作者提供)

单词相关性

云这个词是一个很好的开始,但却是一个很基础的起点。我们可以通过评估单词之间的相关性来增强我们的分析。单词相关性利用 R 的 base cor()函数使用的相同方法,Pearson 相关性是默认的。这是皮尔逊相关公式:

皮尔逊相关系数(r)公式,

因为我们的 TDM 是矢量化的,所以 R 可以有效地执行这些比较。在我们的主代码中,我们需要输入一个感兴趣的项和一个相关下限。如果你看到大多数单词的相关度都在 15%以下,不要惊讶。事实上,由于我们数据集的庞大规模,15%可能是一个显著的相关性。即使我们的数据集很小(按 ML 标准),我们的 TDM 也非常大(2300 万个元素——3107 条评论 x 750 个单词)。

让我们看一下单词“Pain”和我们的 TDM 的其余部分之间的相关图,施加 18%的相关下限:

TDM 和“疼痛”之间的关联图,18%关联下限(图片由作者提供)

这张图表立刻向我们展示了一些见解。例如,我们看到“神经”与疼痛有很高的相关性,相关性为 22%。这可以产生直接、即时的业务影响;我们有效地总结了 3000 多篇评论,并找出了一个常见的问题。

情感分析

虽然有许多复杂的方法来执行情感分析,但在本文中,我们将重点关注合理执行的开箱即用的方法。对于情感分析的详细概述,请查看这个维基百科页面。对于快速启动,我们基本上利用了微软情感词典中大量预先标记的消极/积极词汇。我们用我们的单词列表加入词典,然后只计算正面和负面单词的比率。

来自我们合并列表的片段(图片由作者提供)

N-Grams

但是等等,还有呢!虽然我们可以更仔细地观察单个词频,但这表面上是我们在词云中可视化的条形图/表格形式。单个单词也有信息缺失的问题。类似于我们在讨论停用词时看到的,我们可能会用这种方法丢失句子中的重要修饰语。例如,我们可以将“粉丝”作为我们的首选词之一,但可能有一半的句子也包括“我不是一个…

作者图片

我们可以用 N-gram 分析来应对这种信息丢失。一个 N-gram 基本上是在我们的数据集中同现的“N”个单词。在这个代码模板中,我们需要做的就是将方法中的“n”改为我们想要的大小。以下是运行二元和三元模型分析并清理数据集后的结果。

几乎是瞬间,我们对热门话题有了一个很好的了解(图片由作者提供)

太好了,我怎么卖?

这个代码模板有几个很大的技术和非技术优势:

  1. 战斗偏见&显著性:采用程序化方法的最重要优势之一是消除了人为因素。对于公司来说,让一个关键人员审查报告的药物副作用、内部调查等是很常见的。这是一个问题。人都是有偏见的,不管自己知不知道。潜意识偏见会导致一种类型的评论保持突出或直接影响结果的交付。像这样的程序可以很容易地扩展和大规模共享(见#4),消除了孤立的偏见/突出的影响。
  2. 谁不喜欢字云?由此产生的视觉效果易于理解,看起来很漂亮,是建立业务方对您的分析的信心的好方法。
  3. 速度:当然,不是完全优化,但是这个代码是。从开始到结束,这个程序在我的电脑上运行 6.25 秒。诚然,我的电脑比大多数工作机器快一点,但也没快多少。一个人仔细梳理这 3100 条评论可能需要几天时间。**

脚本计时(图片由作者提供)

4.没有分析基础设施?没问题!该模板可以回收用于任何文本分析,几乎不需要用户交互。基础设施有所帮助,但并不是真正必要的。如果我们想对此类代码进行“软部署”:

  • 添加您想要查看的任何导出条件(图表、n-gram 等。)
  • 创建引用此脚本的. bat 文件
  • 安排一个 windows 进程在数据更新时每“X”天运行一次可执行文件,或者只需单击。蝙蝠

戴尔 EMC 和 Comet 宣布机器学习平台合作

原文:https://towardsdatascience.com/dell-emc-and-comet-release-kubernetes-reference-architecture-1706c1575530?source=collection_archive---------65-----------------------

为数据科学团队提供全栈解决方案的领先提供商戴尔 EMC 和行业领先的元机器学习实验平台 Comet 发布了一个参考体系结构,供希望利用戴尔 EMC 基础架构与 Comet 元机器学习平台的强大功能的数据科学团队使用。阅读由 Comet 和戴尔共同撰写的白皮书,了解 Comet 与戴尔 EMC 人工智能基础架构的配合使用。

借助 Dell EMC PowerEdge 参考体系结构,组织可以部署人工智能工作负载优化的机架系统,比设计正确的配置和部署解决方案大约快 6 到 12 个月。组织现在可以依赖由我们的戴尔工程师测试和验证的体系结构,并且知道服务可以在您需要的时间和地点提供。

Comet 联合创始人/首席执行官 Gideon Mendels 表示:“对于我们的许多客户来说,协调和管理企业数据科学团队的堆栈是一个巨大的难题。“戴尔 EMC 的 Kubeflow 和 Kubernetes 解决方案是同类最佳的解决方案,是任何希望构建强大且可扩展的 ML 平台的数据科学团队的绝佳选择。”

Comet 是一个元机器学习实验平台,允许用户自动跟踪他们的指标、超参数、依赖性、GPU 利用率、数据集、模型、调试样本等。通过利用 Comet,数据科学团队产生了更快的研究周期,以及更加透明和协作的数据科学。Comet 还提供了内置的超参数优化服务、交互式混淆矩阵、完整的代码跟踪和可再现性特性。Comet 本地安装可以支持任何规模的团队,从单台机器到分布式微服务。

“这是一种让你质疑没有它你如何运作的产品。“Comet 为数据科学团队提供了他们需要的所有自动化和生产力功能,但他们从来没有时间开发自己,”戴尔 EMC 高级首席工程师兼杰出技术人员菲尔·胡梅尔说。

参考体系结构利用戴尔 EMC 支持人工智能的 Kubernetes 解决方案,由 Canonical 的charged Kubernetes和 Kubeflow 提供支持,符合人工智能工作负载的所有要求。该解决方案包括 100%上游 Kubernetes 的最新代码,这些代码被打包成易于使用的包,并由 Canonical 提供支持。

戴尔 EMC 和 Comet 的参考体系结构和数据科学团队用户案例说明了我们的联合解决方案如何为团队提供管理其机器学习工作流(数据存储、实验和模型构建以及部署)所需的工具和基础架构,同时随着团队的扩展提供灵活而强大的部署选项。要了解有关戴尔 EMC 支持人工智能的 Kubernetes 集群选项的更多信息,请阅读更多信息此处或直接联系戴尔 EMC安排电话。要了解更多关于 Comet 的元机器学习平台的信息,请阅读更多关于 Comet 的信息这里或者联系 Comet 的客户解决方案团队以获取更多信息或安排演示。

点击此处阅读完整白皮书,该白皮书涵盖(a)将 Comet 与戴尔 EMC 人工智能基础架构结合使用,以及(b)技术安装说明。

三角洲湖在行动:Upsert &时间旅行

原文:https://towardsdatascience.com/delta-lake-in-action-upsert-time-travel-3bad4d50725f?source=collection_archive---------11-----------------------

在 Apache spark 中使用 Delta lake 的初学者指南

卢卡斯·布拉塞克Unsplash 上拍摄的照片

这是我介绍 Delta Lake with Apache Spark 文章的后续文章,请继续阅读,了解如何使用 Delta Lake with Apache Spark 来执行操作,如更新现有数据、检查以前版本的数据、将数据转换为 Delta 表等。

在深入研究代码之前,让我们试着理解什么时候将 Delta Lake 与 Spark 一起使用,因为这并不像我某天醒来就将 Delta Lake 包含在架构中:P

可使用三角洲湖泊:

  • 当处理同一个数据集的【覆盖】时,这是我处理过的最头疼的问题,Delta Lake 在这种情况下真的很有帮助。
  • 当处理有更新的数据时,Delta Lake 的“merge”功能有助于处理数据中的更新(再见,混乱的连接/过滤操作!!)

当然,有许多使用 Delta Lake 的用例,但这是两个场景,它们真正帮助了我。

说够了,让我们深入代码!

如何用 Apache Spark 运行 Delta Lake

首先,要开始使用 Delta Lake,需要将其添加为 Spark 应用程序的一个依赖项,可以这样做:

  • 对于pyspark外壳
pyspark --packages io.delta:delta-core_2.11:0.6.1 --conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" --conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog"
  • 作为 maven 的依赖项,delta lake 可以包含在pom.xml中,如下所示
<dependency>
  <groupId>io.delta</groupId>
  <artifactId>delta-core_2.11</artifactId>
  <version>0.6.1</version>
</dependency>

注意事项:

  • 在这里,2.11scala版本,如果使用 scala 2.12相应地修改版本。
  • 0.6.1是 Delta Lake 版本,是支持Spark 2.4.4的版本。
  • 截止到20200905,delta lake 的最新版本是0.7.0,支持Spark 3.0
  • AWS EMR 特定:不要将 delta lake 与EMR 5.29.0一起使用,它有已知问题。建议升级或降级 EMR 版本,以便与 Delta Lake 配合使用。

如何将数据写成 Delta 表?

Delta lake 使用存储为 Delta 表的数据,因此数据需要以 Delta 表的形式写入。

  • 要将现有数据转换为增量表,需要一次完成。
df = spark.read.parquet("path/of/some/data") # Read existing datadf.coalesce(5).write.format("delta").save("path/of/some/deltaTable")
  • 将新数据写入增量表
df.coalesce(5).write.format("delta").save("path/of/some/deltaTable")

注意事项:

  • 当数据保存为增量表时,该路径包含跟踪增量表元数据的_delta_log目录。
  • 编写使用某些列进行分区的 DeltaTable,如下所示:
df.coalesce(5).write.partitionBy("country").format("delta").save("path/of/some/deltaTable")

如何读取增量表?

  • 作为火花数据帧:
df = spark.read.format("delta").load("path/of/some/deltaTable")As DeltaTable:

将 DeltaTable 作为 Spark 数据帧读取允许对 DeltaTable 进行所有数据帧操作。

  • 作为增量表:
deltaTable = DeltaTable.*forPath*("path/of/some/deltaTable")

将数据读取为 DeltaTable 仅支持 DeltaTable 特定函数。此外,DeltaTable 可以转换为 DataFrame,如下所示:

df = deltaTable.toDF

阿帕奇斯帕克的三角洲湖

DeltaTable 上的 UPSERT 操作允许数据更新,这意味着如果 DeltaTable 可以与一些新的数据集合并,并且在一些join key的基础上,可以在 delta 表中插入修改后的数据。这是在 DeltaTable 上进行向上插入的方法:

val todayData = # new data that needs to be written to deltaTableval deltaTable = DeltaTable.*forPath*("path/of/some/deltaTable")deltaTable.alias("oldData")
  .merge(
    todayData.alias("newData"),
    "oldData.city_id = newData.city_id")
  .whenMatched()
  .updateAll()
  .whenNotMatched()
  .insertAll()
  .execute()

似乎很简单,对吗?就是这样!所以接下来会发生的是,如果城市已经存在于deltaTable中,那么todayData中带有城市更新信息的行将在deltaTable中被修改,如果城市不存在,那么行将被插入到deltaTable中,这是我们的基本更新!

注意事项:

  • 可以使用分区来修改 Upsert 操作,例如,如果需要合并特定的分区,可以指定它来优化合并操作,如:
deltaTable.alias("oldData")
  .merge(
    todayData.alias("newData"),
    "(country = 'India') AND oldData.city_id = newData.city_id")
  .whenMatched()
  .updateAll()
  .whenNotMatched()
  .insertAll()
  .execute()
  • deltaTable中的行与连接键匹配或不匹配时,要执行的操作是可配置的,详情请参考文档。
  • 默认情况下,合并操作会写很多小文件,为了控制小文件的数量,相应地设置下面的spark conf属性,详细信息请参考文档。
spark.delta.merge.repartitionBeforeWrite true
spark.sql.shuffle.partitions 10
  • 在成功的合并操作之后,将在_delta_log目录中创建一个日志提交,浏览其内容以了解 Delta Lake 的工作方式可能会很有趣。
  • 合并只支持一对一的映射,即只有一行应该尝试更新DeltaTable中的一行,如果多行尝试更新DeltaTable中的同一行,则合并操作失败。预处理数据来解决这个问题。

阿帕奇星火中的三角洲湖时光旅行

Delta Lake 支持返回到先前数据版本的功能,同样可以通过指定要读取的数据版本来实现:

df= spark.read.format("delta").option("versionAsOf", 0).load("path/of/some/deltaTable")

版本化从0开始,在delta_log 目录中有多少日志提交,就会有多少数据版本。

似乎,简单吧?

供参考:

[## 欢迎来到三角洲湖文档

学习如何使用三角洲湖。

文档增量 io](https://docs.delta.io/latest/index.html)

下次见,
Ciao。

有火花的三角洲湖:什么和为什么?

原文:https://towardsdatascience.com/delta-lake-with-spark-what-and-why-6d08bef7b963?source=collection_archive---------6-----------------------

了解支持 ACID 和 Spark 更新的存储层

弗兰基·查马基在 Unsplash 上拍摄的照片

让我首先介绍两个问题,这是我在使用 Apache Spark 的过程中反复遇到的问题:

  1. 同一路径上的数据“覆盖”会在作业失败时导致数据丢失。
  2. 数据的更新。

有时我通过设计变更解决上述问题,有时通过引入另一个层,如 Aerospike,或者有时通过维护历史增量数据。

维护历史数据通常是一个直接的解决方案,但是我不太喜欢处理的历史增量数据,如果不是真的需要的话,因为(至少对我来说)它会在失败的情况下引入回填的痛苦,虽然失败可能不太可能,但是不可避免。

以上两个问题都是“问题”,因为 Apache Spark 并不真正支持 ACID。我知道 Spark 从来没有处理事务的用例(你好,你不可能拥有一切),但有时,可能会有这样的场景(就像我上面的两个问题),ACID 合规性会派上用场。

当我读到德尔塔湖和它的耐酸性时,我认为它是我的两个问题的可能解决方案之一。请继续阅读,了解这两个问题如何与酸性合规失败相关联,以及三角洲湖如何被视为救世主?

三角洲湖是什么?

三角洲湖文档将三角洲湖介绍为:

Delta Lake开源存储层,为数据湖带来可靠性。Delta Lake 提供了 ACID 事务、可扩展的元数据处理,并统一了流式和批量数据处理。Delta Lake 运行在您现有的数据湖之上,并且与 Apache Spark APIs 完全兼容。

三角洲湖关键点:

  • 支持酸
  • 实现时间旅行
  • 启用 UPSERT

火花如何失败酸?

考虑下面这段从数据集中删除重复项的代码:

# Read from HDFS
df = spark.read.parquet("/path/on/hdfs") # Line 1
# Remove duplicates
df = df.distinct() # Line 2
# Overwrite the data
df.cache() # Line 3
df.write.parquet("/path/on/hdfs", mode="overwrite") # Line 4

对于运行在这段代码上的 spark 应用程序,考虑一个场景,它在第 4 行失败,也就是在写入数据时失败。这可能会也可能不会导致数据丢失。【问题#1:如上所述】。您可以通过创建测试数据集来复制该场景,并在作业处于阶段时终止作业。

让我们试着用上面的场景来理解 spark 中的酸失效。

酸中的 a 代表原子数,

  • 什么是原子性:要么所有的变化都发生,要么都不发生,系统永远不会处于中途状态。
  • 【spark 如何失败:在写入数据时,(上面第 4 行),如果在旧数据被删除而新数据尚未写入的阶段发生失败,则发生数据丢失。我们丢失了旧数据,并且由于作业失败、原子性失败,我们无法写入新数据。[它可以根据使用的文件输出提交器而变化,请务必阅读文件输出提交器,以了解数据写入是如何发生的,我解释的场景是针对 v2 的]

酸中的 c 代表一致性,

  • 什么是一致性:数据在系统中必须始终保持一致和有效。
  • 【Spark 如何失败:如上所述,在失败和数据丢失的情况下,我们在系统中留下无效数据,一致性失败。

酸中的 I 代表隔离,

  • 什么是隔离:多个事务隔离发生
  • spark 如何失败:考虑并行运行的两个作业,一个如上所述,另一个也使用相同的数据集,如果一个作业覆盖数据集,而另一个仍在使用它,可能会发生失败,隔离失败。

酸中的 d 代表耐久性,

  • 什么是持久性:更改一旦做出就永远不会丢失,即使在系统出现故障的情况下。
  • Spark 可能如何失败: Spark 确实不影响耐用性,它主要由存储层管理,但由于我们在作业失败的情况下会丢失数据,在我看来,这是一个耐用性故障。

三角洲湖如何支持酸?

Delta lake 在写入数据的路径中维护一个 Delta 日志。增量日志维护如下详细信息:

  • 类似于
    的元数据-写入操作中添加的路径。
    -写入操作中移除的路径。
    -数据大小
    -数据的变化
  • 数据模式
  • 提交信息,如
    -输出行数
    -输出字节数
    -时间戳

在某些操作后创建的 delta_log directory 中的示例日志文件:

成功执行后,会在 delta_log 目录中创建一个日志文件。重要的是要注意,当你保存你的数据作为增量,没有文件一旦写入被删除。这个概念类似于版本控制。

通过在 delta_log 中跟踪删除、添加的路径和其他元数据信息,Delta lake 是 ACID 兼容的。

版本控制启用了 Delta Lake 的时间旅行属性,也就是说,我可以回到任何数据状态,因为所有这些信息都保存在 delta_log 中。

三角洲湖如何解决我上面提到的两个问题?

  • 有了对 ACID 的支持,如果我的作业在“覆盖”操作期间失败,数据不会丢失,因为更改不会提交到 delta_log directory 的日志文件。此外,由于 Delta Lake 不会在“覆盖操作”中删除旧文件,因此我的数据会保持旧状态,不会有数据丢失。(是的,我测试过)
  • Delta lake 支持上面提到的更新操作,因此它使得处理数据更新更加容易。

下次见,
再见。

posted @ 2024-10-15 13:44  绝不原创的飞龙  阅读(360)  评论(0)    收藏  举报