TowardsDataScience-博客中文翻译-2016-2018-十二-

龙哥盟 / 2024-10-13 / 原文

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

用 ISOMAP 分解非线性

原文:https://towardsdatascience.com/decomposing-non-linearity-with-isomap-32cf1e95a483?source=collection_archive---------10-----------------------

数据科学的许多应用包括处理像图像这样的高维数据。面对如此大量的多元数据,一个潜在的问题就是如何将它们可视化。为此,我们通常将数据投影到更低的维度。传统的降维技术,如 PCA、LDA 等,由于大多是线性方法,不能给出正确的结果,不能解释数据的非线性结构。

nonlinear data after applying PCA.

线性方法基于欧几里德距离来降低维度,而 ISOMAP(等距映射)在多元数据点中使用测地线距离方法。

Isomap 按照以下步骤工作:

  1. 它根据流形距离确定相邻点,并连接固定半径内的点。
  2. 它计算在上述步骤中确定的点之间的测地线距离。
  3. 最后,在距离图上应用多维缩放,并且保持几何形状,然后优化点的位置。

让我们举一个简单的例子来理解这一点。我们将在 sklearn 生成的非线性数据集上测试这些算法。

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.ticker import NullFormatter
from sklearn.manifold import Isomapfrom sklearn import datasetsn_points = 1000# S datasetX, color = datasets.samples_generator.make_s_curve(n_points, random_state=0)
n_neighbors = 10
n_components = 2X, color = datasets.samples_generator.make_s_curve(n_points, random_state=0)
n_neighbors = 10
n_components = 2

可视化我们生成的数据集。

%matplotlib inline
fig = plt.figure(figsize=(15, 8))plt.suptitle("S shape dataset"
             % (1000, n_neighbors), fontsize=14)
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
ax.view_init(4, -72)

S shaped dataset

现在我们在上面的数据集上应用 PCA。

Y = PCA(n_components).fit_transform(X)ax = fig.add_subplot(111)
plt.scatter(Y[:, 0], Y[:, 1], c=color, cmap=plt.cm.Spectral)
plt.title("PCA on S curve")
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
plt.axis('tight')
plt.show()

在上面的图中,PCA 在二维上分解 3d 图的维度,但是在这样做的时候丢失了很多信息。

让我们检查流形上的 Isomap 的结果

Y = Isomap(n_neighbors, n_components).fit_transform(X)ax = fig.add_subplot(111)
plt.scatter(Y[:, 0], Y[:, 1], c=color, cmap=plt.cm.Spectral)
plt.title("Isomap on S curve")
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
plt.axis('tight')
plt.show()

这里,非线性数据被适当地投影在 2d 图上。Isomap 根据点之间的测地线距离分解数据。

解构 BERT:从 1 亿个参数中提取 6 种模式

原文:https://towardsdatascience.com/deconstructing-bert-distilling-6-patterns-from-100-million-parameters-b49113672f77?source=collection_archive---------4-----------------------

从伯特混乱的注意力网络中,一些直观的模式浮现出来

2018 年标志着自然语言处理领域的一个转折点,一系列深度学习模型在从问题回答到情感分类的 NLP 任务中取得了最先进的成果。最近,谷歌的 BERT 算法已经成为一种“统治所有人的一种模式”,这是基于它在各种各样的任务上的卓越性能。

试玩一个 互动演示 伯特维兹

BERT 建立在两个关键的理念之上,这两个理念是 NLP 最近许多进步的原因:(1)转换器架构和(2)无监督的预训练。变形金刚是一个序列模型,它放弃了 RNN 的循环结构,采用了一种完全基于注意力的方法,正如即时经典中所描述的那样。伯特也是经过预先训练的;它的权重是通过两个无监督的任务提前学习的:掩蔽语言建模(在给定左右上下文的情况下预测一个缺失的单词)和下一句预测(预测一句话是否跟随另一句话)。因此,伯特不需要为每个新任务从头开始训练;相反,它的权重是微调过的。关于伯特的更多细节,请查看插图伯特。

伯特是一头(多头)野兽

伯特不像传统的注意力模型,在 RNN 的隐藏状态上使用扁平的注意力结构。相反,BERT 使用了多层注意力(12 层或 24 层,取决于模型),并且还在每层(12 层或 16 层)中加入了多个注意力“头”。由于模型权重不在层之间共享,单个 BERT 模型实际上具有多达 24×16 = 384 种不同的注意机制。

可视化伯特

由于 BERT 的复杂性,很难直观地理解其学习到的权重的含义。深度学习模型通常是出了名的不透明,各种可视化 工具已经被开发出来帮助理解它们。然而,我还没有找到一个可以解释伯特正在学习的注意力模式的方法。幸运的是, Tensor2Tenso r 有一个很好的工具来可视化编码器-解码器变压器模型中的注意力,所以我修改了它来与 BERT 的架构一起工作,使用了 BERT 的 PyTorch 实现。适配后的界面如下图,可以使用 Github 上的笔记本自己运行。

该工具将注意力可视化为连接被更新的位置(左)和被关注的位置(右)的线。颜色标识相应的注意力头部,而线条粗细反映注意力得分。在工具的顶部,用户可以选择模型层,以及一个或多个注意力头(通过单击顶部的色标,代表 12 个头)。

伯特到底学到了什么?

我使用该工具探索了预训练 BERT 模型(基于 BERT 的无案例版本)各层/头部的注意力模式。我试验了不同的输入值,但出于演示目的,我只使用以下输入:

句子 A: 我去了商店。

在商店,我买了新鲜的草莓。

BERT 使用词块标记化,插入特殊量词(【CLS】)和分隔符(【SEP】)标记,所以实际输入顺序是:**【CLS】我去商店。在商店,我买了新鲜的草莓。****

我发现了一些相当独特和令人惊讶的直觉注意力模式。下面我确定了六个关键模式,对于每一个模式,我都展示了展示该模式的特定层/头的可视化。

模式 1:注意下一个单词

在这种模式中,特定位置的大部分注意力都集中在序列中的下一个标记上。下面我们看到一个第 2 层,头 0 的例子。(所选的头部由顶部颜色栏中高亮显示的正方形表示。)左边的图显示了对所有标记的关注,而右边的图显示了对一个选定标记(“I”)的关注。在这个例子中,几乎所有的注意力都集中在序列中的下一个标记“got”上。

Pattern 1: Attention to next word. Left: attention weights for all tokens. Right: attention weights for selected token (“i”)

在左边,我们可以看到【SEP】记号扰乱了下一个记号的注意力模式,因为来自【SEP】的大部分注意力被导向【CLS】而不是下一个记号。因此,这种模式似乎主要在每个句子中起作用。

这种模式与向后 RNN 相关,在向后中,状态更新是从右到左顺序进行的。模式 1 出现在模型的多个层上,在某种意义上模拟了 RNN 的周期性更新。

模式二:注意前一个单词

在这种模式中,大部分注意力都集中在句子中前面的标记上。例如,在下图中,“去了”的大部分注意力都指向了前面的单词“我”。图案不像上一个那样清晰;一些注意力也被分散到其他令牌上,尤其是*【SEP】令牌。与模式 1 一样,这与顺序 RNN 有着松散的联系,在本例中是前向 RNN。*

Pattern 2: Attention to previous word. Left: attention weights for all tokens. Right: attention weights for selected token (“went”)

模式 3:注意相同/相关的单词

在这种模式中,注意相同或相关的单词,包括源单词本身。在下面的例子中,第一次出现的“store”的大部分注意力都集中在它本身和第二次出现的“store”上。这种模式不像其他一些模式那样明显,注意力分散在许多不同的单词上。

Pattern 3: Attention to identical/related tokens. Left: attention weights for all tokens. Right: attention weights for selected token (“store”)

模式 4:注意其他句子中的相同/相关单词

在这个模式中,注意另一个句子中相同或相关的单词例如,第二句中“商店”的大部分注意力都指向第一句中的“商店”。人们可以想象这对于下一个句子预测任务(BERT 预训练的一部分)特别有帮助,因为它有助于识别句子之间的关系。**

Pattern 4: Attention to identical/related words in other sentence. Left: attention weights for all tokens. Right: attention weights for selected token (“store”)

模式 5:注意单词的其他预测词

在这种模式中,注意力似乎被引向预测源单词的其他单词,而不包括源单词本身。在下面的例子中,来自“吸管”的大部分注意力被导向“#浆果”,来自“#浆果”的大部分注意力集中在“吸管”上。

Pattern 5: Attention to other words predictive of word. Left: attention weights for all tokens. Right: attention weights for selected token (“##berries”)

这种模式不像其他一些模式那样独特。例如,大部分注意力都集中在定界符标记上(【CLS】),这是接下来讨论的模式 6 的定义特征。

模式 6:注意分隔符标记

在这个模式中,大部分注意力都集中在定界符标记上,要么是【CLS】标记,要么是【SEP】标记。在下面的例子中,大部分注意力都集中在两个【SEP】标记上。正如本文中所讨论的,这种模式充当一种“无操作”:当注意力头在输入句子中找不到任何有意义的东西来关注时,它会关注*【SEP】*标记。

Pattern 6: Attention to delimiter tokens. Left: attention weights for all tokens. Right: attention weights for selected token (“store”)

笔记

有人说数据可视化有点像罗夏测验:我们的解释可能被我们自己的信念和期望所影响。虽然上面的一些模式非常独特,但其他模式有些主观,因此这些解释只能作为初步观察。

此外,上述 6 种模式描述了 BERT 的粗略注意结构,并不试图描述注意可能捕获的语言模式。例如,有许多不同类型的“关联性”可以在模式 3 和模式 4 中表现出来,例如同义词、共指等。看看不同的注意力是否专注于不同类型的语义和句法关系会很有趣。

试试吧!

可以在 Github 上查看可视化工具。请玩玩它,分享你的发现!

为了进一步阅读

第二部分 中,我扩展了可视化工具来展示伯特是如何形成其独特的注意力模式的。在我最近的文章 中,我探索了 OpenAI 的新文本生成器,GPT-2。**

在这里 了解更多我的可视化与可解释性工作 。你可以在 Twitter 上找到我@Jesse _ vig

大感谢Llion Jones独创 Tensor2Tensor 可视化工具

解构介质上的度量

原文:https://towardsdatascience.com/deconstructing-metrics-on-medium-bf5b4863bf96?source=collection_archive---------9-----------------------

利用数据科学设计更好的媒体统计体验

入门指南

如果你以前曾经在 Medium 上发表过一个故事,那么你很有可能熟悉 Medium Stats 和它的产品。Medium Stats 是一个工具,您可以在其中查看您在平台上发布的帖子的流量和访客统计数据。这也是一个严重缺乏的工具。

该功能让我们可以访问他们发布的每个故事的视图、阅读、阅读率和粉丝等指标。它还提供了过去 30 天内某些指标的累计总数。

A look into Medium Stats

页面的设计一直备受争议,但事实是,除了视觉上的改进,还有更多工作要做。Medium 跟踪大量在页面的有限功能中不可用的信息。此外,所做的存在的任何功能都是以虚荣心为中心,难以传达全貌。

该项目

我们可能无法访问收集到的过多的指标,但是我们确实有中等的统计数据。也许真的有一些有意义的见解埋藏在那里的某个地方。也许,只是也许…

有没有什么方法可以利用这些数据获得比目前提供给我们的更有用的信息?

带着这个问题,我继续从我自己的媒体统计页面收集数据,然后对我之前 30 多个故事中任何值得注意的关系和趋势进行一些探索性数据分析。

如果你有兴趣对自己的媒体数据进行类似的分析,请查看下面链接的回购协议。你会发现我的个人数据集可以开始使用,还有几个笔记本应该会有用。

自从我开始在数据中挖掘,我开始思考很多关于指标和它们在媒体上的意义。

在这篇文章中,我将深入研究 Medium Stats 提供的每个指标,并探索可能的替代方案。我还将引用探索性数据分析对我以前的故事提出的见解和问题。

[## conordewey 3/Medium-Stats-分析

Medium-Stats-Analysis -探索数据并分析特定于用户的 Medium Stats 的指标

github.com](https://github.com/conordewey3/Medium-Stats-Analysis)

关于度量的几点注记

创建或选择新的度量标准当然不是一件容易的事情。出于这个原因,我们经常用一些更容易理解的简化问题来代替最初的问题。有很多有用的启发式方法,但是当考虑度量标准时,我经常会将事情分解为以下几点:

1。在这种背景下,成功是什么样的?

2。怎么才能量化呢?

由于任务的主观性质,分析是什么使得某个指标''好''或''坏''往往更加困难。也就是说,有几个属性值得一提,它们通常与有效的指标相关联。下面是来自计划兄弟的一个简短列表:

比较的

一个好的衡量标准必须能够与时间、其他同等群体和竞争对手相比较。

明白

创建易于理解的指标。如果人们不能记住细节或讨论它们,这意味着度量标准令人困惑。

基于比率

每个指标都应该基于一个明确的比率。想想开车吧。行驶距离是信息性的,但不是可操作的。另一方面,每小时的距离是你可以行动的。

行为改变

一个好的指标可以产生数据,为必要的调整提供信息,并推动行动。根据这些信息,我会做哪些不同的事情?

记住这些属性,让我们开始一些分析。关于度量的更多信息,我强烈推荐查看 Julie Zhuo 和她关于设置度量的各种帖子。我们开始吧!

指标#1:视图

对于基于网络的内容来说,浏览量是一个主要因素。它们非常容易解释,而且非常有效地让我们自我感觉良好。就我个人而言,以下是我的五个点击率最高的帖子:

你可能会注意到,最上面的两个故事明显比其他的突出。经过进一步分析,我发现我一生中超过 70%的观点来自我在 Medium 上的 30 多个故事中的 2 个。这些帖子通过在 Python 中实现机器学习和数据操作和中的概念来重点讲解它们。我想这是作家之间的一个共同主题——不是每篇文章都会是全垒打。

这进一步说明了观点并不能说明全部。如果有的话,他们正在衡量一个职位的范围。它影响了多少人。某个故事吸引眼球的数量非常具有误导性,并且经常鼓励点击诱饵标题和充满流行词汇的描述。

替代度量:Shares

有人可能会说观点可以被完全抛弃。这种衡量标准往往弊大于利,导致作者更多地关注吸引注意力,而不是创作有见地的作品。

如果你需要一个计数指标来衡量作品的范围,我建议用股份来代替。我认为这是一个进步的原因有几个:

  1. 分享仍然衡量帖子的范围,但也考虑内容,因为读者不会分享他们不喜欢的帖子。
  2. 股票惩罚肤浅的、点击诱饵的投资者,而不是奖励他们。

使用分享的一个可能的不利之处是,一个知名影响者的转发会被赋予与关注者较少的人相同的权重。

这是好是坏有待讨论。在量化范围的背景下,份额最初不足,将取决于发生的连锁效应。例如,当一个拥有 100,000 名粉丝的人在 Twitter 上转发你的文章时,它最初被记录为+1 份额。特定的有影响力的分享的额外权重必须以暴露给更多读者的形式出现,这些读者也将有机会分享帖子,等等。

即使考虑到这一点,我仍然认为在提供有意义的反馈方面,分享是一种进步。即使这并不能取代那些始终如一的观点,因为作家们无疑仍然对有多少人看过他们的故事感兴趣。

在评估一个帖子的真实范围和传播力时,应该提供分享和观点。

指标#2:读取

Reads 在剔除肤浅的文章方面做得更好,因为读者可能会点击它们,但一旦他们意识到自己没有从中获得任何价值,他们可能就不会读完了。

您可能还记得,通常应该避免计算指标。向朋友提起它们或者用它们来增强我们的自尊心可能会很有趣,但当涉及到驾驶行动时,它们就不够了。

正如人们所料,阅读量和浏览量之间存在明显的相关性,这使得我们无法从这个指标中获得任何洞察力。请注意,为了更好地了解下面的关系,我已经删除了异常值:

阅读和观点有一点不同。虽然 Views 希望衡量范围,但 Reads 关注的是参与度。人们对材料的实际参与程度如何?这很难用计数度量来回答。

为了真实地捕捉一个帖子有多吸引人,我们需要使用更多基于比率的东西。幸运的是,Medium 已经有了这个问题的答案。

替代度量:读取比率

我现在不会深入讨论读取率,因为我们稍后会更深入地讨论它,但是让我们来看看一些显著的改进:

  1. 读取率根据视图数量进行调整,消除了之前影响读取的偏差。
  2. 阅读率在大多数类型的帖子中不相上下,无论是内容还是受欢迎程度。

阅读率被证明是评估我的文章可读性的一个非常有用的指标。归根结底,如果你不能让读者参与进来,你就无法向他们传递价值。

指标#3:读取率

终于有了一个关于中等统计的可行指标!正如我们刚才提到的,读取率是对传统读取计数的更有意义的改变。此外,它仍然可以很容易地理解为逗留和阅读帖子的观众的百分比。让我们通过阅读率来看看我在媒体上的热门帖子:

这对我来说非常有趣。看起来我的第一篇媒体文章拥有最高的阅读率。当我回去回顾上面的热门故事时,我注意到了一个主题。几乎所有的都有点短;阅读时间不到 6 分钟。他们也有大量的图片和标题,使读者很容易浏览。

这看起来很直观,但是让我们通过评估帖子的阅读率和它们各自的阅读时间来进一步观察这种直觉。

正如人们所料,有人通读帖子的可能性很大程度上取决于文章的长度。这绝对阻碍了我们对 Read Ratio 的解读。所以让我们解决它。

替代度量:调整后的读取比率

我们需要设计一种方法来告诉用户,相对于阅读时间相同的其他帖子,什么是好的,什么是坏的。为了做到这一点,我们可以标准化每个读取时间组内的读取比率,并报告 0 和 1 之间的新分数。

这个指标可以更准确地评估一个职位的参与度,但它带来了可解释性的问题。在选择度量标准时经常会有取舍;我们想回答手头的问题,但我们需要一些容易理解的东西。

让我们找到一个折中的办法。注意,我在这里要作弊一点。这不一定是它自己的独立指标,而是一个微妙的信息设计调整。通过将相对性能添加到已经可以解释的读取率中,用户可以从中推断出更多信息。

这并不惊天动地,但这个小小的变化却让世界变得不同。让我们回想一下强指标的四个特征:可比较、可理解、基于比率和行为改变。

最初,读比率是很好理解的,并且是基于比率的。然而,由于对阅读时间的偏见,它缺乏可比性和实质性的行为改变能力。

有了这个新的设计,所有的四个底座都被覆盖了,作家可以很容易地解释他们的作品相对于它的长度有多吸引人。

衡量标准 4:粉丝

在 Read Ratio 取得短暂成功后,我们又回到了虚荣指标上。注意 Fans 并没有告诉我们拍手的数量,只是简单的将每个拍手的用户注册为粉丝。不用说,这里可能有更多的内容。

对于粉丝,我们希望评估一些完全不同于我们之前的观点(范围)或阅读(参与度)。我们尤其希望量化影响。帖子的影响有多大?人们有多喜欢它?

为了改进这一指标,让我们保持简单,并采用基于比率的替代方法。对于每一个阅读这篇文章的人来说,有多少人受到了足够的影响而至少鼓掌一次?答案是粉丝比。

替代指标:调整后的风扇比率

一些中型用户已经谈到手工计算这一指标,所以我有点惊讶它没有被纳入中型统计产品。

通过使用 Fan Ratio 而不是 Fans,我们得到了使用 Ratio 而不是 count 的明显好处。最值得注意的是,它为我们提供了一个可比较的指标,并包含可操作的信息。以下是我关于粉丝比例的热门帖子:

我在这里注意到的第一件事是,我关于自我提升的帖子比我的技术类帖子获得了明显更高的粉丝比率。

某些类型的故事比其他类型的故事有更好的粉丝比率吗?

幸运的是,我把所有的帖子都提交给了基于该主题的出版物。关于自我提升主题的帖子去了 The Ascent 和 The Startup ,而更多的技术帖子去了forward Data Science、 freeCodeCamp 和 Hackernoon 。最后,任何与设计相关的帖子通常都会提交给 UX 星球。

虽然基于 30 个故事的小样本,但这似乎证实了我们的猜测,即一些类型比其他类型表现得更好。然后,通过介绍出版物,可能只是一些出版物比其他出版物有更多的参与用户。在没有更多数据的情况下,很难明确回答这个问题,但是我的直觉告诉我选择第一个选项:流派。

这在我看来很有道理。尤其是涉及到自我提升岗位的表现。从长远来看,他们似乎是媒体中最受欢迎的,经常吸引大量的粉丝。他们中的许多人可以在任何情况下针对任何人,因此更有可能对某人产生积极影响,并创造一个粉丝。

Medium 甚至可以更进一步,使用其他基于内容的功能将相似的帖子聚集在一起,从而创建一个分析系统。

与其将一个帖子的粉丝比率与其类别中的其他帖子进行比较,不如将它与该类别中的其他帖子进行比较,以更准确地反映其真实的相对优势。

更好的 KPI

经过大量的思考和分析,我发现一篇成功的媒体文章通常具有以下特征:

  1. 它吸引读者,让他们有足够的兴趣读完。
  2. 它积极地影响读者,提供一些价值或享受。

在这篇文章中,我们已经触及了许多不同的指标和见解,但是真的就这么简单。你把读者带进来,给他们提供价值。

正如我们前面提到的,我们可以用调整后的读取比率来衡量参与度,用调整后的风扇比率来衡量影响。幸运的是,这两个因素似乎与这个特定样本上的 0.54 相关性有很强的相关性。

很高兴在这里看到某种程度上的线性关系,这意味着强势帖子通常在阅读率和粉丝率方面都表现良好。考虑到这一点,我考虑了归一化和加权平均值最终成为一个包罗万象的指标的几种可能性,但出于可解释性的考虑,我选择了不这样做。

“当人类的判断和大数据相交时,会发生一些有趣的事情。”——内特·西尔弗

如果我有自己的方式,当你把鼠标放在一个特定的帖子上时,我会提供类似下面的可视化效果。正如我们前面所探讨的,这提供了一个给定职位有效性的更好的表示,同时保持了可解释性和可比较性。参与和影响。

最后的话

恭喜你坚持了这么久!我从来没有预料到这个项目会从一个简短的探索性数据分析转变为一个 2600 字的度量标准的深度挖掘。然而,我还有最后一点要说。

我们知道数据的力量有多大。我们知道它对几乎任何环境都是有用的——是的,包括写作。据推测,公司每天都变得越来越受数据驱动。

那么,这场运动是什么时候冲击 Medium 的作家平台的呢?

这种类型的分析应该适用于所有的作者,而不仅仅是数据科学爱好者和从业者。我们需要让内容创作者的数据分析民主化。从 one Medium Stats 页面中抽取 30 篇文章的样本,这些见解就成为可能。想象一下我们拥有更多数据和信息的可能性。

通过授权作家分析他们的内容并了解读者如何看待它,他们创作出更有影响力的更好的作品。

这不是一个小任务,但我相信这是可以做到的。你的移动,媒介。

感谢阅读!如果你想检查我的分析或者用你自己的媒体数据执行一个类似的项目,请访问我在 Github 上的回购:媒体统计分析。

如果你对未来的更多帖子感兴趣,请确保关注我并订阅下面的我的简讯以接收任何新内容。想了解更多关于我和我在做什么,请查看我的网站。

解密生成式人工智能和 GANs

原文:https://towardsdatascience.com/decrypt-generative-artificial-intelligence-and-gans-16646dbb4426?source=collection_archive---------9-----------------------

大家好,

今天的话题是 AI 的一个非常令人兴奋的方面,叫做生成式人工智能。简言之,生成式人工智能指的是一种算法,它使机器能够使用文本、音频文件和图像等东西来创建/生成内容。在之前的帖子中,我谈到了变化的自动编码器以及它们如何用来生成新图像。我提到过它们是一个更大的模型集的一部分,称为生成模型,我将在下一篇文章中更多地讨论它们。所以我们在这里。

正如我在那篇文章中简要解释的,有两种模式。判别性和生成性。第一类是最常见的模型,如卷积或递归神经网络,用于区分/辨别数据中的模式,以便将它们归类。图像识别、皮肤癌诊断、以太坊预测等应用都属于判别模式的范畴。

后者能够在数据中生成新模式。因此,他们可以产生新的图像,新的文本,新的音乐。以严格的数学形式来说,判别模型试图估计后验概率 p(y|x),这是给定输入样本(手写数字的图像)的输出样本(例如手写数字)的概率。另一方面,生成模型估计联合概率 p(x,y),这是输入样本和样本输出同时为真的概率。实际上,它试图计算一组类的分布,而不是它们之间的边界。

你能想象可能性吗?嗯,你可以通过查看该领域的当前进展和一些现有的应用来了解它们。迄今为止,生成模型已经被用于从图像中产生文本,开发肿瘤学分子,发现新药,将梵高等艺术家的风格转化为新的图像。我敢肯定你听说过 Deepfakes,他们把名人的脸放在任何类型的视频上。如果你认为你能分辨真假,那就别想了。你不能。

如果你点击了上面的一些链接,你可能会注意到一些更有趣的东西。由于一种叫做 GANs 的东西,所有的应用都成为可能。GANs 或生成性对抗网络是大多数生成性应用背后的基础架构。当然,还有许多其他很酷的模型,如变分自动编码器、深度玻尔兹曼机器、马尔可夫链,但 GANs 是过去三年围绕生成式人工智能有如此多宣传的原因。

什么是生成性对抗网络?

2016 年,伊恩·古德菲勒(Ian Goodfellow)在过去十年最有前途的人工智能论文中引入了生成性对抗网络。它们是一种无监督的学习技术,基于一个简单的前提:

你想生成新的数据。你是做什么的?你建造两个模型**。你训练第一个产生假数据,第二个辨别真假。你让他们互相竞争**。

嘣!这就是了。我希望事情就这么简单。它不是。但这是 GANs 背后的主要原则。

好的,让我们进入一些细节。第一个模型是神经网络,称为生成器。生成器的工作是产生虚假数据,输入时只有噪音。第二个模型,鉴别器,接收真实图像和伪造图像(由生成器产生)作为输入,并学习识别图像是否是伪造的。当你让他们互相竞争并同时训练他们时,奇迹就开始了:

生成器在图像生成方面变得越来越好,因为它的最终目标是欺骗鉴别器。鉴别器变得越来越擅长区分真假图像,因为它的目标是不被愚弄。结果是我们现在有了来自鉴别器的难以置信的真实的假数据。

上图是一个很好的类比,描述了 GAN 之间的功能。生成者可以被视为制造欺诈性文件的伪造者,而鉴别者可以被视为试图检测这些文件的侦探。他们参与了一场零和游戏,随着时间的推移,他们都变得越来越好。

到目前为止一切顺利。我们有模型,现在我们必须训练它们。这就是问题开始出现的地方,因为它不是我们用梯度下降和损失函数训练神经网络的标准方法。这里我们有两个相互竞争的模型。那么,我们该怎么办?

我们不确定。GAN 的优化是目前最活跃的研究领域之一,不断有新的论文出现。我将尝试解释这里的基础,我需要一些数学和一些博弈论。!!)来做到这一点。请不要离开。和我在一起,最后,一切都会变得有意义。

如何训练他们?

我们可以认为这里有一个极小极大博弈。引用维基百科的话:“一个玩家的马希民值是在不知道其他玩家的行动的情况下,该玩家能够确定得到的最高值;等价地,这是当其他玩家知道该玩家的动作时,他们可以强迫该玩家接受的最低值”

换句话说,第一个玩家试图最大化他的奖励,同时最小化他的对手奖励。第二个玩家试图完成完全相同的目标。

在我们的例子中,鉴别器试图最大化分配正确标签给真实数据和生成样本的概率。而生成器试图最小化鉴别器正确答案的概率

我们将损失表示为一个极大极小函数:

这是什么?

鉴别器试图使函数最大化;因此,我们可以对目标函数执行梯度上升。生成器试图最小化函数;因此,我们可以对函数进行梯度下降。通过在梯度上升和下降之间交替,可以训练模型。

当鉴别器不能最大化函数,生成器不能最小化函数时,训练停止。用博弈论的术语来说,他们达到纳什均衡。

我希望你还在。这是主要的想法,被称为对抗性训练。当然,有几个经常出现的陷阱,例如:

  • 模型参数振荡并且从不收敛,
  • 鉴别器太成功了,以至于发生器梯度消失
  • 它对超参数高度敏感
  • 生成器产生有限种类的样本

在过去的几年里,科学家们为解决这些问题做出了巨大的贡献,我们可以说已经取得了很大的进展。只要在 arxiv-sanity 上快速搜索一下。不过,现在还早。记住。甘的存在不到三年。

我将用一些关键事实来结束我的发言。如果你跳过整篇文章,没关系。但是不要忽略这些:

  • 生成式人工智能用于从真实数据中生成新数据
  • GAI 最突出的模式是生成性对抗网络。
  • 甘的是两个神经网络参与了一个游戏。第一个试图制造新的虚假数据,第二个试图将它们与真实数据区分开来。随着训练的进行,他们都越来越擅长自己的工作。
  • 甘的训练还有很多工作要做
  • GAN 的实时应用是……(我该如何用一个词来形容呢?嗯嗯……)huuuuge。

菲尼托…

如果您有任何想法、评论、问题或者您只想了解我的最新内容,请随时在LinkedinTwitterinsta gramGithub或在我的

原载于 2018 年 9 月 13 日sergioskar . github . io

用石灰解密你的机器学习模型

原文:https://towardsdatascience.com/decrypting-your-machine-learning-model-using-lime-5adc035109b5?source=collection_archive---------1-----------------------

你为什么要相信你的模型?

最近,人们开始重新关注模型的可解释性。ML 专家能够理解模型可解释性在随后的业务适应中的重要性。模型可解释性的问题在于,很难以人类可以理解的方式定义模型的决策边界。LIME 是一个 python 库,它试图通过产生局部忠实的解释来解决模型的可解释性。下面是一个解释文本分类问题的例子。

Example of an explanation by LIME for a binary classification model(atheism/Christian). The words (features) highlighted in blue support atheism.

本帖将涵盖以下主题:

  1. 信任你的模型的重要性
  2. 什么是石灰?
  3. 什么使 LIME 成为一个好的模型解释者?
  4. 【LIME 如何实现模型可解释性?
  5. 在分类问题上使用石灰的实例

信任你的模型的重要性

为了在模型中建立信任,我们运行多个交叉验证并执行拒绝集验证。这些模拟给出了未知数据上模型性能的汇总视图。这无助于理解为什么我们的一些预测是正确的,而另一些是错误的,我们也无法追踪我们的模型的决策路径。换句话说,我们无法理解它的学习或找出它的虚假结论。但是,如果我告诉你,有一种工具可以用人类可以理解的方式解释你的模型的决策边界,那会怎么样呢?这个魔法图书馆的名字叫莱姆。

什么是石灰?

LIME(局部可解释模型不可知解释)是一种新颖的解释技术,它通过学习预测周围的局部可解释模型,以可解释和忠实的方式解释任何分类器的预测。

LIME 在模型可解释性方面提供了什么? 1。一致的模型不可知论解释者[ LIME ]。
2。一种选择具有解释[ SP-LIME ]的代表性集合的方法,以确保模型在复制人类逻辑时行为一致。这个代表性的集合将提供对模型的直观的全局理解。

LIME 解释了一个预测,因此即使是非专家也可以通过特征工程对一个不可信的模型进行比较和改进。一个理想的模型解释器应该包含以下理想的特性:

  1. 可解释的
    它应该提供输入变量和响应之间的定性理解。应该很好理解。
  2. 一个解释不可能完全忠实,除非它是模型本身的完整描述。已经说过,它应该至少是局部忠实的,即它必须在被预测的实例附近复制模型的行为。
  3. 模型不可知论者 解释者应该能够解释任何模型,在提供解释的同时不应该对模型做任何假设。
  4. 全局视角
    解释者应向用户解释一个代表性集合,以便用户对模型有一个全局直觉。

什么使莱姆成为一个好的模型解释者?

让我们看看石灰是如何衡量这些特征的:

1。可解释的数据表示法 使用人类理解的表示法,而不管模型使用的实际特征。这被称为可解释的表现。一个可解释的表示会随着我们正在处理的数据类型而变化,例如:
1。对于文本:它表示有/没有单词。
2。对于图像:它表示超像素(相似像素的连续块)的存在/不存在。
3。对于表格数据:它是列的加权组合。

简而言之,LIME 的解释者即使是非专家也能理解。

2。保真度-可解释性权衡

我们想要一个忠实的(本地复制我们模型的行为)和可解释的(第一点)解释器。为了达到这一时间,最大限度地减少以下内容:

Explanation model equation

方程变量 f :原始预测值
x :原始特征
g :解释模型,可以是线性模型、决策树、 或者下降规则列出了 Pi*:z 的一个实例到 x 之间的邻近性度量,以定义 x 周围的局部性,它根据它们到 x 的距离来加权 z’(扰动的实例)* 第一项*:g 在 Pi 定义的局部性中逼近 f 的不忠实性的度量。 这在原始论文* 中被称为 位置感知损失 最后一项 :解释模型复杂度 g 的度量。例如,如果你的解释模型是决策树,它可以是树的深度,或者在线性解释模型的情况下,它可以是非零权重的数量

速记以备将来参考
1。x’(可解释表示)
:这个二进制向量是原始模型使用的实际特征的人类可理解版本。
2。z’(扰动样本):x’的非零元素的分数。
3。 f(z) :等级标签
4。 g(z') :这是 LIME 学习的模型(解释模型)。

为了确保可解释性和局部保真度 最小化位置感知损失 ,同时保持第二项足够低以便人类能够解释。这将被引用为***ω(g)***用于后文 的其余部分,同时优化位置感知损失时间以实现局部保真度。

3。用于局部探测的采样 只是重申 g 是要学习的模型,z’是训练数据的一个实例, f (z) 是 y。为了创建完整的训练集,我们从x’执行随机均匀采样。换句话说,我们从一行 x 中创建多个z’(原始训练示例)。
然后这些由 Pi(x) 加权,以更加关注更接近 x 的z’
给定该数据集和标签,等式 1 被优化以学习解释模型。总而言之,LIME 提供的解释不依赖于原始模型的类型(模型不可知)。

The black-box model’s complex decision function f (unknown to LIME) is represented by the blue/pink background, which cannot be approximated well by a linear model. The bold red cross is the instance being explained. LIME samples instances get predictions using f and weigh them by the proximity to the instance being explained (represented here by size). The dashed line is the learned explanation that is locally (but not globally) faithful.

**4。稀疏线性解释
我们假设
1。 g(z') = w . z' (使解释模型线性)2 。局部感知损耗 =平方损耗
3。 Pi(z) 😗* exp(-D(x,z)(2)/sigma(2))(样本的近似加权)
4。 D(x,z) :距离函数

Locally-aware square loss

了解石灰算法

K 是解释时要考虑的变量数量的限制。例如,对于文本,K 是要考虑的字数,对于图像,是超像素的数量,对于表格数据,是列的数量。为了实现这一点,我们使 Omega 趋向于无穷大,如果 size(w) > K. 总而言之,使用线性解释器来近似原始模型的决策边界。

第 2 部分:解释模型的子模型选择(SP-LIME)

LIME 旨在将模型的预测归因于人类可以理解的特征。为了做到这一点,我们需要在一组不同但有代表性的实例上运行解释模型,以返回一个非冗余的解释集,它是模型的全局表示。在介绍算法之前,让我们先了解一下先决条件:
1。 B (预算):用户愿意检查的说明数量
2。挑选步骤:从所有实例中挑选 B 实例的任务
3 . W (解释矩阵): n (样本数)
d’(人类可理解的特征)矩阵
4 . I(j): 解释空间中分量 j 的全局重要性
5。 V :说明
6 所考虑的特征。
【V,W,I】***:计算在集合 V 中的至少一个实例中出现的特征的总重要性。3)

Nonredundant coverage intuition

Maximizing the weighted coverage function

算法 2 步骤 1。对所有实例(所有 x)运行解释模型
2。计算单个组件的全局重要性
3。通过迭代地添加具有最高最大覆盖增益的实例来最大化覆盖函数。
4。Return V(代表性非冗余解释集)

由此,我们可以看到 LIME 拥有理想模型解释器的所有 4 个理想属性。

在一个分类问题上使用石灰的实际例子

下面是运行泰坦尼克号经典分类案例的模型解释的代码。我用 LightGBM 来训练模型(点击了解 LightGBM 库,这里了解其优化)。

这是对训练数据中第 1 行的解释

orange colored features support class 1 and blue colored features support class 0

使用不同的数据实例运行最后两行,以获得不同的特征图。

这个解释有三个部分:

  1. 最左边部分显示预测概率
  2. 中间部分返回 5 个最重要的特性。对于二进制分类任务,它将是橙色/蓝色两种颜色。橙色的属性支持类别 1,蓝色的属性支持类别 0。Sex_le ≤0 支持 1 类。水平条上的浮点数代表这些特性的相对重要性。
  3. 各部分的颜色编码是一致的。它包含前 5 个变量的实际值。

使用下面的代码运行 SP-LIME

Results of running SP-LIME

为了在我们的模型中建立信任,我们不仅需要向 ML 专家解释模型,还需要向领域专家解释,这需要人类可以理解的解释。这是通过创建一个模型不可知的本地忠实解释集来实现的,它甚至可以帮助非专家理解原始模型是如何做出决策的。通过创建代表性样本集,LIME 为用户提供了模型决策边界的全局视图。这个模型的可解释性对于人类与 ML 系统的有效交互是至关重要的。解释个人预测在评估信任度时很重要,称赞也支持模型选择中的集合验证。

参考文献

  1. *原文链接:【https://arxiv.org/abs/1602.04938 *
  2. Github 链接:https://github.com/marcotcr/lime
  3. 博客作者:论文作者:https://homes.cs.washington.edu/~marcotcr/blog/lime/

请在下面分享您的想法、反馈或建议。

用于协同过滤的深度自动编码器

原文:https://towardsdatascience.com/deep-autoencoders-for-collaborative-filtering-6cf8d25bbf1d?source=collection_archive---------0-----------------------

预测用户对电影的评价——实用教程

协同过滤是推荐系统使用的一种方法,通过从许多其他用户收集品味或偏好信息来预测特定用户的兴趣。协同过滤技术具有潜在的假设,即如果用户 A 与人 B 在一个问题上具有相同的品味或观点,则 A 更有可能在不同的问题上具有 B 的观点。

在这篇文章中,你将学习如何根据一个用户的喜好以及观看并评价了同一部电影和其他电影的其他用户的喜好来预测这个用户对这部电影的评价。

如果你喜欢这篇文章,想分享你的想法,问问题或保持联系,请随时通过 LinkedIn 与我联系。

目录:

  • 介绍
  • 深度自动编码器
  • 模型实现

1。简介

自动编码器是一种深度学习神经网络架构,在协作过滤领域实现了最先进的性能。在文章的第一部分,我会给你一个简单自动编码器及其扩展深度自动编码器背后的理论概述和基础数学。在第二部分中,我们将深入实践,我将一步一步向你展示如何在 TensorFlow 中实现这一技术。在本文中,我将只包括和评论模型中最重要的部分。整个模型、输入管道和预处理可以在相应的 GitHub 库中查看。

2.深度自动编码器

自动编码器

在我们关注深度自动编码器之前,我们应该讨论它的简单版本。自动编码器是一种人工神经网络,用于学习一组输入数据的表示(编码),通常是为了实现降维。

在架构上,自动编码器的形式是一个前馈神经网络,具有一个输入层、一个隐藏层和一个输出层(图 1)。输出层具有与输入层相同数量的神经元,用于重建其自身的输入。这使得自动编码器成为一种无监督学习的形式,这意味着不需要标记数据,只需要一组输入数据,而不是输入输出对。

Fig. 1. Typical AutoEncoder architecture.

自动编码器的隐藏层比输入层小是很有用的。这种效果迫使模型通过学习数据中的相关性来创建隐藏层中数据的压缩表示。

从输入层到隐藏层的过渡被称为编码步骤,从隐藏层到输出层的过渡被称为解码步骤。我们也可以用数学方法将这些转换定义为映射:

通过将输入数据向量 x 乘以权重矩阵,添加偏置项,并对所得向量应用非线性运算 σ ,例如 sigmoid、tanh 或整流线性单元,来实现映射。

即将推出: 面向软件开发人员、数据分析师、学者和业内人士的高级深度学习教育

更多详情请看:www.deeplearning-academy.com

www.deeplearning-academy.com

自动编码器的训练

在训练时间期间,编码器获取输入数据样本 x 并将其映射到所谓的隐藏或潜在表示 z. ,然后解码器将 z 映射到输出矢量x’,该矢量(在最佳情况下)是输入数据 x 的精确表示。请注意,通常不可能精确重建输入 x

具有输出x’训练包括应用随机梯度下降以最小化预定义损失,例如均方误差:

深度自动编码器

简单自动编码器的扩展是深度自动编码器(图 2)。从图 2 中可以看出,它的简单配对部分的唯一区别是隐藏层的数量。

Fig. 2. Deep Autoencoder architecture.

附加的隐藏层使自动编码器能够从数学上学习数据中更复杂的潜在模式。深度自动编码器的第一层可以学习原始输入中的一阶特征(例如图像中的边缘)。第二层可以学习与一阶特征的外观中的模式相对应的二阶特征(例如,在什么边缘倾向于一起出现方面——例如,形成轮廓或角检测器)。深度自动编码器的更深层倾向于学习甚至更高阶的特征。

总而言之:我们需要额外的层来处理更复杂的数据——比如我们在协同过滤中使用的数据。

3.履行

如前所述,你将学会预测用户对电影的评价。为此,我们将使用著名的电影镜头数据集。 MovieLens 是一个基于网络的推荐系统和在线社区,为用户推荐电影观看。

更具体地说,我们将使用 ml-1m.zip 数据集,该数据集包含 6,040 MovieLens 用户制作的约 3,900 部电影的 1,000,209 个匿名评级。我们需要的导入文件是 ratings.dat. 这个文件包含 1,000,209 行,都具有以下格式:user _ idmovie _ idrating:time _ stamp。

例如 ratings.dat 中的第一行:

1::595::5::978824268 

意味着用户号。1 给电影编号。595 a 五星评级。时间戳可以忽略,因为它不会被使用。

我们实现的深度学习模型需要特定的数据结构来进行训练和测试。这个数据结构是一个 U x M 矩阵,其中 U 是用户数量,而 M 是电影数量。每行 iU 是唯一的用户 id,每列 jM 是唯一的电影 id。这种矩阵的可视化可以在图 3 中看到

这个矩阵中的每个条目都是用户对一部特定电影的评价。条目 0 表示用户没有给这部电影任何评价。例如,用户 1 给电影 3 的评级是 4 星,而电影 1 根本没有评级。

由于本教程的重点是深度学习模型的实现,所以这里不介绍从 ratings.dat 文件中制作用户电影矩阵的步骤。关于这个主题的更多问题,我想把你重定向到我的 GitHub 库,在那里你可以检查相应的 python 脚本。

训练和测试数据集

在模型可以被实现和训练之前,数据的另一个再处理步骤是必要的——将数据分成训练和测试数据集。这一步非常简单。到目前为止,我们有一个用户-电影矩阵,其中每一行都是评级列表。为了从该列表中获得训练集和测试集,我们必须从每一行中取出评级的子集,并且仅将它们用于训练,而将剩余的子集仅用于测试。

作为所述过程的一个例子,让我们考虑仅由 15 部电影组成的小得多的数据集。特定用户可能给了这些电影以下评级:

Movie Nr. : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15Rating:     5 0 2 4 0 0 2 1 5  1  0  4  5  1  3

请记住,0 表示电影未分级。现在,我们将由前 10 部电影组成的子集作为训练集,并假设其余的电影尚未分级:

Movie Nr. : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15Rating:     5 0 2 4 0 0 2 1 5  0  0  0  0  0  0

因此,原始数据的最后 5 个电影分级被用作测试数据,而电影 1-10 被屏蔽为未分级:

Movie Nr. : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15Rating:     0 0 0 0 0 0 0 0 0  1  0  4  5  1  3

这只是一个简单的演示如何获得不同的集合。在最初的 MovieLens 数据集中,我对每个用户只使用了 10 个电影评级进行测试,而其余的(绝大多数)用于模型的训练。

TensorFlow 实现

模型架构

深度自动编码器被实现为一个类,具有所有必要的操作,如推理、优化、丢失、准确性等。在课堂上。

在构造函数中,为权重和偏差设置了内核初始化器。在下一步中,网络中的所有权重和偏差都被初始化。权重呈正态分布,平均值为 0.0,方差为 0.02,而偏差在开始时都设置为 0.0。

在这个特定的例子中,网络有三个隐藏层,每个包含 128 个神经元。输入层(和输出层)的大小对应于数据集中所有当前电影的数量。

培养

给定输入数据样本 x (用户电影矩阵的一行),进行计算网络输出的正向传递。隐藏层使用 sigmoid 作为激活函数。请注意,最后一层既没有非线性也没有偏置项。

有了网络预测,我们可以计算这些预测和相应标签之间的损失(网络输入 x )。为了计算损失的平均值,我们还需要知道非零标签的数量,换句话说,就是用户在训练集中的总评分数。

网络的优化/训练步骤可能会显得有点棘手,让我们一步一步来讨论。给定一个输入 x 计算相应的输出。正如您可能已经注意到的,输入 x 中的大多数值都是零值,因为用户几乎肯定没有观看数据集中的所有 5953 部电影并对其进行评级。因此,建议不要直接使用网络的原始预测。相反,我们必须识别数据输入 x 中零值的索引,并将对应于这些索引的预测向量中的值也设置为零。这种对预测的操纵极大地减少了网络的训练时间,使网络有机会将其训练努力仅集中在用户实际做出的评级上。

在这个步骤之后,可以计算损失以及正则化损失(可选)。AdamOptimizer 将损失函数降至最低。请注意,该方法返回的是均方根误差(RMSE ),而不是均方误差(MSE ),测量精度更高。

测试

在训练阶段的一些时期之后,神经网络已经多次看到每个用户的训练数据集中的所有评级。此时,模型应该已经学习了数据中的潜在隐藏模式以及用户的相应协作电影品味。给定用户评级训练样本 x ,模型预测输出x’。该向量由输入 x 的重建组成(如预期的那样),但现在也包含输入 x 中先前零额定值的值。这意味着该模型对尚未分级的电影进行了分级。这种评级对应于用户的喜好——模型从数据中识别和学习到的喜好。

为了测量模型的准确性,需要训练和测试数据集。基于训练集进行预测。类似于训练阶段,我们仅考虑与测试集中非零值的索引相对应的输出值。

现在,我们可以计算预测和实际评级之间的均方根误差损失(RMSE)。RMSE 表示预测值和观察值之间差异的样本标准差。例如,0.5 的 RMSE 意味着平均而言,预测评级偏离实际评级 0.5 颗星。

培训结果

最后一步是执行培训过程并检查模型的性能。在这一点上,我不会进入构建数据输入管道、图形、会话等的细节。因为这些步骤是众所周知的。对这个话题感兴趣的读者可以在我的 GitHub 资源库中查看这些步骤。

在这里,您可以观察前 50 个时期的训练和测试性能。在 50 个时期之后,我们在测试集上得到预测和实际评级之间的 0.929 星偏差。

epoch_nr: 0,  train_loss: 1.169, test_loss: 1.020
epoch_nr: 10, train_loss: 0.936, test_loss: 0.959
epoch_nr: 20, train_loss: 0.889, test_loss: 0.931
epoch_nr: 30, train_loss: 0.873, test_loss: 0.923
epoch_nr: 40, train_loss: 0.859, test_loss: 0.925
epoch_nr: 50, train_loss: 0.844, test_loss: 0.929

如果你喜欢这篇文章,想分享你的想法,问问题或保持联系,请随时通过 LinkedIn 与我联系。

参考

** [## artem-opper Mann/Deep-auto encoders-For-Collaborative-Filtering

深度自动编码器-用于协同过滤-使用深度自动编码器预测电影分级。

github.com](https://github.com/artem-oppermann/Deep-Autoencoders-For-Collaborative-Filtering)

http://proceedings.mlr.press/v27/baldi12a/baldi12a.pdf

http://deeplearning.net/tutorial/SdA.html**

使用 Tensorflow 的深度自动编码器

原文:https://towardsdatascience.com/deep-autoencoders-using-tensorflow-c68f075fd1a3?source=collection_archive---------3-----------------------

在本教程中,我们将探索一种称为自动编码器的无监督学习神经网络。

因此,自动编码器是用于在输出层再现输入的深度神经网络,即输出层中神经元的数量与输入层中神经元的数量完全相同。考虑下图

此图显示了典型深度自动编码器的结构。自动编码器架构的目标是在输出层创建输入的表示,使得两者尽可能接近(相似)。但是,自动编码器的实际用途是确定输入数据的压缩版本,同时具有最低的数据丢失量。我这么说的意思是:你在开发机器学习项目的时候一定听说过一个术语,叫做主成分分析。PCA 的概念是在数据集具有大量参数的情况下,为模型的训练找到最佳和相关的参数。

自动编码器以类似的方式工作。该架构的编码器部分将输入数据分解为压缩版本,确保重要数据不会丢失,但数据的总体大小会显著减小。这个概念叫做降维。

这个概念的缺点是,压缩数据是一个黑盒,也就是说,我们不能确定数据在压缩版本中的结构。请记住,假设我们有一个包含 5 个参数的数据集,我们在这个数据上训练一个自动编码器。为了更好地表示,编码器没有省略一些参数,而是将参数融合在一起以创建具有更少参数的压缩版本(将参数数量从 5 个减少到 3 个)。

因此,自动编码器有两部分,即编码器和解码器。

编码器压缩输入数据,解码器反过来产生数据的未压缩版本,以尽可能精确地重建输入。

我们将使用 Tensorflow 创建一个自动编码器神经网络,并在 mnist 数据集上测试它。那么,让我们开始吧!!

首先,我们导入相关的库并读入 mnist 数据集。如果数据集存在于您的本地机器上,那很好,否则它将通过运行以下命令自动下载

接下来,为了方便起见,我们创建了一些常数,并预先声明了我们的激活函数。mnist 数据集中的图像大小为 28x28 像素,即 784 像素,我们将把它压缩为 196 像素。你可以一直深入下去,进一步减小像素尺寸。但是,过度压缩可能会导致自动编码器丢失信息。

现在,我们为每一层的权重和偏差创建变量。然后,我们也使用之前声明的激活函数来创建层

通常不使用tf.variance_scaling_initializer()。但是,我们在这里使用它是因为我们要处理不断变化的输入大小。因此,占位符张量形状(占位符用于输入批次)会根据输入大小的形状进行自我调整,从而防止我们陷入任何维度错误。隐藏层是通过简单地将前一个隐藏层作为具有相关权重和偏差的输入馈送到激活函数(ReLu)中来创建的。

我们将为这个神经网络使用 MSE 损失函数,并将其通过 Adam 优化器。你可以随时玩这些有趣的结果。

现在,我们定义时期数和批量大小,并运行进程。我们使用来自 mnist 的效用函数来获得每个新批次:mnist.train.next_batch()。此外,我们将在每个时期后输出训练损失,以监控其训练。

最后,我们将编写一个小的绘图函数来绘制原始图像和重建图像,看看我们的模型效果如何。

Final output

在这里,我们可以看到重建并不完美,但非常接近原始图像。请注意,2 的重建看起来像 3,这是由于压缩时的信息丢失。

我们可以通过超参数调整以及在 GPU 加速器上训练来改进自动编码器模型。

好了,这是一个在 Tensorflow 上从头开始构建的深度(或堆叠)自动编码器模型。完整的代码点击下面的横幅。

下次见!!

深度卷积神经网络

原文:https://towardsdatascience.com/deep-convolutional-neural-networks-ccf96f830178?source=collection_archive---------14-----------------------

这篇文章的目的是在深入阅读描述深层架构的原始出版物之前,作为对深层架构的一个很好的介绍。

我觉得研究界缺乏帮助。一个研究人员花一点点时间制作漂亮的可视化效果、仪表盘、演示甚至视频,可以节省所有跟在他/她后面的研究人员的时间,创新会发展得更快。

我的贡献是通过直觉理解如此使用的深度卷积神经网络作为计算机视觉问题的默认选项的演变。

DenseNet — Example of how networks will be demystified

指数

0.1: 卷积运算

0.2: 1x1 卷积

(1): LeNet — LeCun 1998 — 论文 …………(TBI)

(2)Alex net—krijevsky 2012—论文

(3):Google net/Inception—Szegedy 2014—Paper……(TBI)

(4): VGG —西蒙扬/齐塞曼 2014 — 论文 …………(TBI)

(5)ResNets for ImageNet—何 2015 — 论文

  • *** 为 CIFAR10 保留**

(6)dense nets for ImageNet

  • dense nets for cifar 10—黄 2016 — 论文****

(7):fractal nets—Larsson—2016—论文 …………..(TBI)

(8):—胡— 2018 — 论文

(9): MobileNets — Howard — 2016 — 论文 ………………。(TBI)

深入研究监督学习

原文:https://towardsdatascience.com/deep-dive-into-supervised-learning-e7952c0692e9?source=collection_archive---------11-----------------------

当你在学校的时候,你被要求练习很多加减法题。最初,你必须检查你得出的答案是对还是错,但过了一段时间,你对自己的答案变得有信心,认为它是正确的。这基本上就是监督学习

在监督学习中,算法由示例输入和期望输出提供。算法的工作是建立输入和输出之间的映射。在足够数量的输入之后,该算法能够以一定的精度预测输出。

下面是展示 Alvin 的视频,它是人工智能系统通过观察人的驾驶来学习。正如我所说,第一步是训练一个网络/算法来驾驶。在训练人类驾驶员时,转向角度被提供给 Alvin。阿尔文的工作是学习“如何驾驶”。

在上面的视频中,有一个图像如下所示。它表示实时算法的输入和输出。

让我们从监督学习开始,但在此之前,您应该熟悉一些符号:

  • m:训练实例的数量
  • x:输入变量/特征
  • y:输出变量/目标变量
  • (x,y):训练示例
  • n:输入变量或特征的数量
  • θ:参数或权重。算法的工作是选择合适的权重

总之,我们提供学习算法的训练样本。它为我们提供了一个假设(h)。假设在提供一些输入时会给我们预期的输出。假设由下式给出

当我们想要训练“m”个样本时,上述等式可以表示为:

现在,θ表示为假设预测值的平方和减去“m”个训练样本的实际值。

为了最小化 J(θ),我们使用了被称为梯度下降的算法。它可以解释如下:想象你站在一个山顶上,你想向最陡的下坡方向迈出一小步,这可以让你尽快下山。梯度下降也是如此。你从一个点开始应用梯度下降,在一个新的点结束,重复同样的动作,直到你到达最小点。

假设只有一个训练样本,我们将进行梯度下降的推导

现在θ由下式给出

注:上式中的α是学习率。这就像下山时你想走多大的步。如果你步子迈得太小,下山会花很长时间。如果你的步长太大,你可能会超过局部最小值。如果有“m”个训练样本,则广义方程由下式给出

我会给你一个图像,让你看到梯度下降是行动。

上述梯度下降也被称为批量梯度下降。这意味着每次该算法将针对所有训练示例运行。梯度下降还有一种变化,称为随机梯度下降递增下降。如下所示:

随机梯度下降法的优点是根据误差相对于单个训练样本的梯度来更新参数。已经观察到,对于大数据集,随机梯度下降更快。

如果你发现我的帖子有不一致的地方,欢迎在评论中指出。感谢阅读。

深入研究支持向量机

原文:https://towardsdatascience.com/deep-dive-into-support-vector-machine-654c8d517103?source=collection_archive---------16-----------------------

支持向量机是机器学习领域中最流行的监督分类器之一。让我们了解一下支持向量机(SVM)背后的直觉。请注意,在接下来的所有章节中,支持向量机将被称为 SVM。

让我们建立直觉

Figure 1: Improper Classifiers

考虑上面的分类器。有两类:

  • ' +1 ':暗数据点。
  • ' -1 ':轻数据点。

那么,以上的量词有什么问题呢???如果我们仔细查看图 1 中的分类器,我们无法确定这两个类的正确区域。超平面(超平面是将两个类分类的平面。这里,分类器 A 中的虚线)看起来非常接近于类“ -1 ”。分类器 B 中的超平面看起来更接近于类“ +1 ”。分类器 C 中的超平面看起来更接近于类“ -1 ”。看起来,如果超平面更接近一个阶级,那么它更偏爱那个特定的阶级而不是另一个阶级。如果是这样的话,那么分类器出错的机会将会更大,如图 2 所示。

Figure 2: The red coloured data point is mistakenly classified by the classifier

可以观察到,最好的分类器应该是超平面与两个类的距离相等的分类器(没有偏好)。如果班级和超平面之间的距离最大,那就更好了。这就是 SVM 的情况,如图 3 所示。注:偏爱的概念只是为了理解直觉。没有这样的想法被用来制定 SVM。

Figure 3: The red coloured dashed line is the optimal hyper plane. The green coloured dashed lines define the boundary for each class. And the data points with green coloured thick outline that are on the boundary of the class are called support vectors. Hence, the name Support Vector Machine

图 3 的标题很好地描述了该图。关于 SVM 有趣的事情是,只有支持向量被认为是确定最佳超平面。我们将很快证明这一说法。

问题 1:如果数据点不能像图 3 中那样被一个直的超平面分隔开会怎样???

Figure 4

如果我们考虑图 4,在二维空间中不存在可以对图中所示的数据点进行分类的超平面。但是,SVM 有一个解决方案,这就是为什么 SVM 很有趣。在这种情况下,给定的空间被转换到更高维度的空间,使得数据点在新的空间中是可分离的。因此,数据点被分类到更高维度的空间中,并被映射回原始空间。这个概念似乎有些棘手。因此,仔细查看下面显示的观想。

Figure 5: Visualisation of transformation from given space to higher dimensional, classify data points in the new space and then map everything back to the original space. Source: https://www.youtube.com/watch?v=3liCbRZPrZA

图 5 中的可视化给出了从给定空间到更高维度空间的转换的清晰概念。在上面的可视化中,粉红色的超平面可以很容易地对高维空间中的数据点进行线性分类。因此,图 4 中的数据点可以如图 6 所示进行分类。

Figure 6

核函数的作用和问题 2

SVM 的另一个问题是,转换到更高维度空间,然后确定新空间中的最优超平面,然后转换回原始空间的过程非常复杂,并且开销很高。例如,如果在 100 维空间中有 1000 个特征,并且如果 100 维空间被转换成 1000 维空间,那么每个特征向量将具有 1000 个分量和 1000 * 1000 次计算**(如此多的计算是因为超平面被描述为 W.X + b = 0,其中 X 是特征向量)**将被要求确定最佳超平面,并且超平面将再次被映射回原始空间。而且这整个过程开销很大。

解决上述问题的方法是 k ernel 函数。关于核函数有趣的事实是,核函数做了上面的映射,而实际上没有去更高维的空间。换句话说,核函数进行上述映射,而不实际执行高维空间中的所有上述计算。

使用如图 7 所示的多项式核函数ϕ((a,b)=(a,b,a + b)来完成图 5 所示的可视化中的变换。

Figure 7: Training example of SVM with kernel given by ϕ((a, b)) = (a, b, a² + b²). Source: https://en.wikipedia.org/wiki/Support_vector_machine

请注意,只有当问题包含点积或内积时,核函数才适用。幸运的是,SVM 的公式依赖于点积(将在接下来的章节中被证明)。

数学建模

让我们来破解支持向量机背后的数学。给定,训练集{(Xᵢ,Yᵢ)其中 i=1,2,3,…,n},Xᵢ ∈ ℜᵐ,Yᵢ ∈ {+1,-1}。这里,Xᵢ是 iᵗʰ数据点的特征向量,Yᵢ是 iᵗʰ数据点的标签。标签可以是正类的“+1”或负类的“-1”。取值“1”是为了数学上的方便。

设 Wᵢ是垂直于决策边界(最佳超平面)的向量,Xᵢ是未知向量。那么 Xᵢ向量在 Wᵢ单位向量上的投影将确定该未知点属于正类还是负类,如图 8 所示。

Figure 8

注:在接下来的章节中,Wᵗ或 w 上升到 t 表示 w 转置。并且两个向量 w 和 x 之间的点积与 Wᵗ和 x 之间的矩阵乘法相同。

基本上,对于具有由 WᵗXᵢ + b = 0 给出的判定边界的分类器,可以说:

Figure 9

Figure 10

现在,如果我们取所有'+1 '模式的最小值,那么它将是某个常数ϵ,如果我们取所有'-1 '模式的最大值,那么它将是某个常数-ϵ.这里,ϵ和-ϵ代表支持向量。在图 10 中,具有粗边界的数据点是支持向量。所以,它可以写成:

Figure 11

现在,如果我们用 1/{ϵ} 缩放上述不等式,那么最优超平面将保持不变。所以,我们用相同的符号来表示缩放后的向量。所以,它可以写成:

Figure 12

可以观察到,如果上述不等式乘以相应的 Yᵢ,则上述断言可以由单个表达式描述:

Figure 13

在图 12 的 1ˢᵗ方程中, Yᵢ=1 并且当 1 乘以 RHS 时,我们得到 1。而在 2ⁿᵈ方程 Yᵢ=-1 中,当 -1 乘以 RHS (-1) 则得到 1 。因为,负数被相乘,所以符号改变。

设, X⁺ 为正类下的支持向量, X⁻ 为负类下的支持向量。然后,wx⁺+b = 1wx⁺= 1-b。同理,wx⁻+b =-1wx⁻=-1-b。然后,向量 (X⁺ — X⁻)W 向量的单位向量上的投影给出了两个类的支持向量之间的分离间隙的宽度或余量。边距的宽度由下式给出:

Figure 14: Width of the separation gap

SVM 的目的是最大化分离间隙的宽度。这意味着最大化 2/||W||与最小化||W||相同,与最小化||W||相同,与最小化(1/2)||W||相同,同样的东西可以写成(1/2)WᵗW. ),这样做是为了数学上的方便。此外,这样做将问题转化为二次优化问题,二次优化问题没有局部最大值。除此之外,二次优化问题的原始和对偶总是相同的。SVM 的基本问题可以简单地写成:

Figure 15: The problem for a hard SVM

在真实场景中,数据不是严格线性可分的。因此,通过引入松弛变量**‘ξ’和惩罚项‘C’对问题进行了修正。这里,‘C’是一种正则化参数。实际上,如果‘C’的值很大,这意味着它不会忽略任何错误,而是会惩罚几乎每个错误,在这种情况下,它可能无法找到最佳的 Wb 。反之,如果‘C’的值非常小,则意味着它忽略了几乎所有的错误,然后 Wb 将获得任意随机值。因此,我们必须使用交叉验证来选择合适的值‘C’,它必须在很小和很大之间。因为每个错误并不都一样糟糕,所以它使用松弛变量‘ξ’**,这是数据点和另一边的类的边距之间的距离,如图 16 所示。如果一个数据点的 ξᵢ 越少,那么错误就越少,并且 C*ξᵢ 也会越少。所以,对错误的惩罚会少一些。如果一个数据点的 ξᵢ 高,则错误更严重,相应地 C*ξᵢ 也会更多。因此,对这一错误的惩罚将会很高。

Figure 16: SVM with optimal hyper plane and slack variables

因此,图 15 中的问题可以改写为:

Figure 17: Problem for Soft SVM

硬 SVM 试图严格分类的数据点,但在现实中,这是不可能的。因此,很少考虑错误,软 SVM 开始发挥作用。

在继续之前,请考虑以下几点:

  1. 理解等高线图对于理解拉格朗日的概念是非常重要的。如果您不熟悉等值线图,请仔细浏览此链接中的视频:https://www . khanacademy . org/math/multivariable-calculus/multivariable-derivatives/gradient-and-direction-derivatives/v/gradient-and-contour-maps
  2. 如果您不熟悉拉格朗日法,强烈建议您浏览给定链接中的每个视频,以便更好地理解:https://www . khanacademy . org/math/multivariable-calculus/applications-of-multivariable-derivatives/la grange-multipliers-and-constrained-optimization/v/constrained-optimization-introduction
  3. 如果你想跳过第 2 点中提到的视频,那么只需记住以下几点:(I)如果问题是找到极值(最大值或最小值),那么使用拉格朗日。(ii)拉格朗日将约束优化问题转化为无约束优化问题。
  4. 约束优化问题的拉格朗日函数由主问题以及所有约束和拉格朗日乘子组成。对于每个约束,使用拉格朗日乘数。
  5. 对偶:根据对偶,每个优化问题都有另一个与之相关的问题,因此可以从前者派生出来。原问题被称为**‘原始’,衍生问题被称为‘对偶’**。在二次优化问题中,原始问题和对偶问题的解是相同的。

希望你已经考虑了上述几点。因此,图 17 中的等式是最主要的问题。但是,我们实际上对对偶问题感兴趣。因为由特征向量和核函数之间的点积组成的对偶问题可以用于非线性扩展(换句话说,对于不可线性分离的数据点的非线性扩展)。

这里,拉格朗日乘数用于二元化。拉格朗日乘子的总数等于原问题中约束的总数。由于图 17 中的等式有两个约束,拉格朗日函数中将使用两个拉格朗日乘数。拉格朗日函数如下所示:

Figure 18: The Lagrangian

图 18 中的等式(L)是拉格朗日乘数,μ,λ是拉格朗日乘数,μ,λ ≥ 0。拉格朗日方程的最小值是通过对变量取偏导数并使它们等于零(根据卡鲁什-库恩-塔克(KKT)条件)得到的。给定问题的 KKT 条件如下:

Figure 19: The KKT conditions

注:这里, 1/Yᵢ 始终等于 Yᵢ 。因为,对于 yᵢ= 11/yᵢ= 1/1 = 1 =yᵢ对于 yᵢ=-11/yᵢ= 1/(-1)=-1 =yᵢ。因此,在接下来的章节中, 1/Yᵢ 总是被写成 Yᵢ

根据图 19 中的 1ˢᵗ方程,它可以写成:

W=∑ᵢⁿ μᵢYᵢXᵢ对于 i = 1,2,…,n————>(a)

现在,根据图 19 中的 3ʳᵈ方程,可以写成 C = μᵢ+λᵢ 。因此,对于μᵢc,λᵢ = 0 ,因此ξᵢ = 0 。因此,图 19 中的 6ᵗʰ方程: μᵢ⋅[Yᵢ(WᵗXᵢ+b) -1 + ξᵢ] = 0 可以改写为:

yᵢ(wᵗxᵢ+b)= 1—————>(b)

等式 (B) 描述了支持向量。对于yᵢ= 1 wᵗxᵢ+b = 1,即位于类**'+1’边界上的点。对于yᵢ=-1 wᵗxᵢ+b =-1**,即位于类 '-1' 边界上的点。因此,最佳超平面取决于支持向量。现在,等式 (B) 可以重写为:

b = Yᵢ-WᵗXᵢ使得 0<μᵢ<c————>(c)

因此,方程 (A) 和方程 (C) 给出了最优的 W 和最优的 C ,从而得到最优的超平面( WᵗXᵢ + b = 0 )。此外,在等式 (A) 中可以观察到 W 可以完全描述为训练模式 Xᵢ 的线性组合。现在,将最优值 Wb 放入拉格朗日方程,对偶优化问题为:

Figure 20: Dual optimisation problem

注意,根据图 20 中的等式,完整的算法可以用数据点之间的点积来描述( XᵢᵗXⱼ )。因此,核技巧可用于非线性扩展,即任何核函数可用于在更高维度空间中寻找点积,如xᵢᵗxⱼ=k(ϕ(xᵢ),ϕ(xⱼ)】。一些流行的内核函数有:

Kernel Functions

谢谢,这就是 SVM。希望这篇文章是有用的。

参考

[1] **P. H .温斯顿,学习:支持向量机。**网址:https://OCW . MIT . edu/courses/electrical-engineering-and computer-science/6-034 人工智能-2010 年秋季/讲座-视频/讲座-16-学习-支持-向量-机器/

【2】**p . p . Sastry,支持向量机——导论,获得最优超平面。**网址http://nptel.ac.in/courses/117108048/32

[3] M. Awad,R. Khanna,高效的学习机器,APress,2015,Ch。3,4,第 39-80 页。

深入探讨基于电子邮件网络的推荐

原文:https://towardsdatascience.com/deep-dive-on-e-mail-network-based-recommendations-6666c46a8f4f?source=collection_archive---------19-----------------------

source: unsplash.com

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

遵循第 1 部分:我们综合了各种措施,以建议的形式向员工推断进一步的见解,告诉他们如何改善沟通,以及向谁寻求建议和支持。此外,通过这些建议,员工能够接触到影响者和顾问,从而对组织产生影响。

这些建议是模块化的,由于其 API 服务实现,可以集成到任何系统中。在本文中,我们只关注两个例子:

1.为了增加你对公司的影响,请联系

2.改善与的沟通和协作。

假设已经同意被推荐。

以下是这些建议的样子:

source: own

1。增加你对组织的影响

每个人都想在他们的组织中有更大的影响力,但有时很难知道怎么做。在一个大型复杂的组织中很难驾驭,甚至很难知道下一步该做什么来增加自己的影响力,也很难让别人听到你的声音。出于各种原因,员工需要被赋予能力、联系、支持和培训。我们专注于社交方面和沟通流程优化。

我们的影响力推荐器是如何工作的?

想象一下这样一种情况:员工 Maria 负责、透明、守时,并让她的经理 Laura 随时了解情况。Maria 始终如一,并在与其他相关同事的沟通中应用相同的原则。像 Maria 这样的员工是影响组织的第一要素。想象一下,Maria 与组织中合适的人的联系仍然不够紧密。下一步是确认 Maria 的人脉还不够广(否则推荐就没什么意义了,她认识合适的人)。一旦我们筛选出关键影响者,并且我们知道 Maria 不在其中,我们将继续找出 Maria 是否已经与公司中的任何高层影响者有联系——Maria 应该与至少几个影响者有松散的联系。

下一步,我们要确保这些影响者(潜在的直线经理)不在 Maria 的实际近距离沟通范围内(如果在内,可能是她的直线经理或特定的组织沟通环境已经使她能够接触到)。我们确定了影响者的交流群,Maria 与这些影响者有合理的交流,但交流不多。从这些聚类中,我们识别出属于同一聚类的其他员工 John 和 Rita(不是识别出的影响者),并且具有与实际影响者的高边介数中心性(这意味着影响者与 John 和 Rita 有良好的沟通,因此可以提供关于 Maria 的支持的参考)。

一旦我们确定了约翰和丽塔,我们继续向玛丽亚推荐他们——通常,我们推荐三个人。现在,由 Maria 和 John 或 Rita 进行交流并安排他们的合作。下面,您将看到该用例的简单图表形式:

source: own

2。改善您与同事的协作

对于依赖沟通的员工来说,能够有效地进行沟通是非常重要的。这对大多数办公室职员来说是真实的,而对蓝领工人、外勤人员等来说就不那么真实了。我们将沟通作为一种工具,用于识别需要改进沟通和协作的对手。

我们的协作推荐器是如何工作的?

想象一下,迈克尔是一名高度参与的员工,沟通是他的主要工具之一。我们关注电子邮件,但这也可以是任何有来源和目的地的书面交流,无论是即时聊天、评论还是反馈。随着迈克尔交流或交换电子邮件,将会出现交流模式、衰减和高峰——这取决于工作如何发展、关系如何变化以及公司结构如何改变整体交流。我们分析了迈克尔的交际群(他经常与之交流的人),同时也包括时间方面。我们得出的结论是,迈克尔的沟通率相对较高,这意味着他是很多话题的关键联系人。

接下来,在我们确定了与迈克尔关系密切的人之后,我们应用时间序列分析来理解交流模式是如何演变的。我们专注于容易衰退的交流模式——无论出于什么原因。一旦我们确定了几个与 Michael 沟通最多的员工,我们就应用边缘中间性来了解它是如何随时间变化的。我们终于找到了汤姆和杰森,迈克尔与他们的交流发生了变化。这种沟通的变化可能是由于任何人的角色、位置或组织的变化,然而这些都没有改变——然而,沟通模式确实发生了变化。

最后,通过我们的推荐器实现,我们建议 Michael 与 Tom 和 Jason 会面,讨论可能的改进选项。很明显,还有其他原因超出了我们的概念范围,但这需要由上述员工来判断情况并根据建议采取行动。这个概念的主要价值是我们的推荐者引入的机会,以改善员工之间重要的缺乏沟通。

下图以简化的形式展示了这一概念:

source: own

产品定义的概念超出了本文的范围。作为一个提示,产品经理会将这些产品定义为用户友好且在隐私范围内。虽然一些措施已经到位,但我们不会透露用于确定推荐同事的影响者的姓名。此外,我们假设被推荐的员工或教练已经同意被推荐,并愿意支持其他员工。

我们的推荐人可以作为开始谈话和改善合作的“借口”。通常情况下,员工只有在没有其他选择的情况下才能交流和合作,这往往只是由于历史、背景,甚至可能是由于个人的不兼容。我们的推荐者支持组织打破僵局,将人们聚集在一起,最终提高沟通效率和生产力。

我们结合和加权各种算法,类似于集成方法。我们使用的一些度量标准是中枢、特征向量中心性、卢万模块性、边缘中间性中心性。我们还利用位置和角色等上下文数据。在未来,我们计划添加业务逻辑和贡献或已经与直线经理达成一致的目标。

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


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

自我学习人工智能代理 III:深度(双)Q 学习

原文:https://towardsdatascience.com/deep-double-q-learning-7fca410b193a?source=collection_archive---------2-----------------------

让深度 Q 学习再次变得伟大。关于自学习人工智能代理的系列文章的第三部分。

自学习人工智能代理系列—目录

  • 第一部分:马尔可夫决策过程
  • 第二部分:深度 Q 学习
  • 第三部分:深(双)问学习(本文)
  • 第四部分:持续行动空间的政策梯度
  • 第五部分:决斗网络
  • 第六部分:异步演员-评论家代理

如果你喜欢这篇文章,想分享你的想法,问问题或保持联系,请随时通过 LinkedIn 与我联系。

0.介绍

在“自我学习 AI-Agents”系列的第二篇文章中,我向您介绍了作为一种算法的深度 Q-Learning,它可以用来教会 AI 在离散动作空间中的行为和解决任务。然而,这种方法并不是没有缺点,有可能导致人工智能代理的性能降低。

在下文中,我将介绍一个常见的问题深度 Q-Learning ,并向您展示如何将普通实现扩展到我们所说的双重深度 Q-Learning ,这通常会提高 AI 代理的性能。

怎么才能练成深度双 Q 学习?

OpenAI 的体操横竿问题的这个例子是用这里介绍的双 Q 学习算法解决的——以及上一篇文章中的一些技术。文档齐全的源代码可以在我的 GitHub 库中找到。我选择了 CartPole 作为一个例子,因为这个问题的训练时间非常短,你可以很快地自己重现它。克隆存储库并执行 run_training.py 来启动算法。

1.动作值函数

在本系列的前两部分中,我介绍了动作值函数 Q(s,a) 作为期望回报G _ tAI 代理将通过从状态 s 开始,采取动作 a ,然后遵循某个策略 π 来获得。

Eq. 1 Action value function Q(s,a).

等式的右边部分也被称为时间差目标(TD-目标)。TD-Target 是代理人在状态中为动作 a 获得的即时奖励与贴现值**Q(s ')****a '之和,贴现值是代理人将在下一个状态 s' 中采取的动作。

Q(s,a) 告诉代理一个可能动作的值(或质量)s。给定一个状态 s ,动作值函数计算该状态下每个可能动作 a_i 的质量/值作为标量值。更高的质量意味着对于给定的目标更好的行动。对于一个人工智能代理,一个可能的目标是学习如何走路或如何与人类棋手下棋。

**遵循贪婪策略 w.r.t Q(s,a) ,意味着采取导致 **Q(s,a’)的最高值的动作导致贝尔曼最优性方程,给出了 Q(s,a) ( 参见第一篇贝尔曼方程也可用于递归计算任何给定动作或状态的所有值***【Q(s,a)】***。

Eq.2 Bellmann Optimality Equation.

在系列文章的第二篇文章中,介绍了时间差异学习作为估计值 Q(s,a) 的更好方法。时间差异学习的目标是最小化 TD 目标和***【s,a】***之间的距离,这表明 Q(s,a) 向其在给定环境中的真实值收敛。这被称为 Q-Learning

2.深度 Q-网络

我们已经看到,神经网络方法被证明是估计 Q(s,a) 的更好方法。主要目标保持不变。它是 Q(s,a) 与 TD-Target 的距离(或 Q(s,a) 的时态距离)的最小化。这个目标可以表示为误差损失函数的最小化:

Eq. 3 Squared error loss function.

深度 Q 学习TD-Targety _ IQ(s,a) 分别由两个不同的神经网络估计,这两个网络通常称为 Target-和 Q-网络(图 4)。参数 θ(i-1) (权重、偏差)属于目标网络,而 θ(i) 属于 Q 网络。

根据行为策略 (a|s)选择 AI 代理的动作。 另一边,贪婪目标策略 π(a|s) 只选择动作*【a’即最大化【Q(s)*,即用于计算 TD-Target。

Fig. 1 Target,- and Q-Network. s being the current and s’ the next state.

误差损失函数的最小化可以通过深度学习中使用的常用梯度下降算法来实现。

**即将推出 😗* 面向软件开发人员、数据分析师、学者和行业专家的高级深度学习教育,旨在加快向人工智能职业的过渡。

更多详情请看:www.deeplearning-academy.com

www.deeplearning-academy.com

3.深度 Q 学习的问题

深度 Q 学习已知有时会学习不切实际的高行动值,因为它包括对估计行动值的最大化步骤,这往往倾向于高估而不是低估的值,这可以在 TD-Targety _ I的计算中看到。**

在实践中,高估是否会对人工智能代理的性能产生负面影响,这仍然是一个或多或少有待解决的问题。过于乐观的价值估计本身并不一定是一个问题。如果所有的值都一致地更高,那么相对的动作偏好被保留,并且我们不期望得到的策略会更差。

然而,如果高估并不一致,也没有集中在我们希望了解更多的州,那么它们可能会对最终政策的质量产生负面影响。

4.双重深度 Q 学习

****双 Q 学习的思路是通过将目标中的 max 运算分解为动作选择动作评估来减少高估。

在普通实现中,动作选择和动作评估是耦合的。我们使用目标网络来选择行动,同时评估行动的质量。这意味着什么?

目标网络为状态 s 中的每个可能动作 a_i 计算 Q(s,a_i) 。贪婪策略决定选择最高值 Q(s,a_i) 哪个动作 a_i 。这意味着目标网络选择动作 a_i ,同时通过计算 Q(s,a_i)来评估其质量。双 Q 学习试图将这两个过程相互分离。****

双 Q 学习中,TD 目标看起来如下:

正如您所看到的,目标中的最大运算消失了。虽然具有参数 θ(i-1) 的目标网络评估动作的质量,但是动作本身由具有参数 θ(i)的 Q 网络确定。 该过程与深度 Q 学习的普通实现形成对比,在深度 Q 学习中,目标网络负责动作选择和评估。

新 TD-Targety _ I的计算可以总结为以下步骤:

  • Q-网络使用下一个状态*【s’来计算质量Q(s’,a)*** 对于每个可能的动作 a 处于状态***【s’*****
  • argmax 操作应用于Q(s’,a)** 选择属于最高质量的动作****动作选择*****
  • 选择属于动作【a*】*【a 】(由目标网络确定)的质量 (由 Q 网络确定)用于目标的计算。(动作评价)

Fig 2. Path of the agent through different states.

双 Q 学习的过程可以再一次以图形的形式可视化,以便进一步理解(图 2)。一个 AI 智能体开始时处于状态 s 。基于一些先前的计算,他知道在该状态下可能的两个动作的品质 Q(s,a_1)Q(s,a_2) 。他决定采取行动 a_1 并结束于状态s’**。****

*Q-网络计算质量Q(s’,a _ 1’)***和 **Q(s,a _ 2’)用于这个新状态中可能的动作。动作a _ 1’被挑选,因为根据 Q 网络,它产生最高质量。

状态中动作 a_1 的新动作值 Q(s,a1) 现在可以用图 2 中的等式来计算,其中Q(s’,a _ 1’)是由目标网络确定的a _ 1’的评估。**

4.实证结果

在[1] 中,David Silver 等人在几款 Atari 2600 游戏上测试了深度 Q 网络(DQNs)和深度双 Q 网络(Double DQNs)。在图 3 中示出了由这两种方法的 AI 代理实现的标准化分数以及可比较的人类表现。该图还包含双 DQN 的调谐版本,其中执行了一些超参数优化。然而,这个版本的 DQN 将不在这里讨论。

可以清楚地注意到,这两个不同版本的双 dqn 在这方面比它的普通实现获得了更好的性能。

Fig. 3 Performances on Atari 2600 games.

深度生成模型

原文:https://towardsdatascience.com/deep-generative-models-25ab2821afd3?source=collection_archive---------2-----------------------

生成模型是一种使用无监督学习来学习任何类型的数据分布的强大方法,并且在短短几年内取得了巨大的成功。所有类型的生成模型都旨在学习训练集的真实数据分布,以便生成具有一些变化的新数据点。但是,无论是隐式还是显式地了解我们数据的准确分布并不总是可能的,因此我们试图建立一个尽可能与真实数据分布相似的分布模型。为此,我们可以利用神经网络的能力来学习一个函数,该函数可以将模型分布近似为真实分布。

两种最常用和最有效的方法是变分自动编码器(VAE)和生成对抗网络(GAN)。VAE 旨在最大化数据对数似然的下限,而甘旨在实现生成器和鉴别器之间的平衡。在这篇博文中,我将解释 VAE 和甘斯的工作以及他们背后的直觉。

变型自动编码器

我假设读者已经熟悉了普通自动编码器的工作原理。我们知道,我们可以使用自动编码器将输入图像编码为更小的维度表示,这可以存储关于输入数据分布的潜在信息。但是在普通的自动编码器中,编码向量只能通过解码器映射到相应的输入。它当然不能用于生成具有一些可变性的相似图像。

为了实现这一点,模型需要学习训练数据的概率分布。VAE 是以无监督方式使用神经网络来学习复杂数据分布(例如图像)的最流行的方法之一。它是一种基于贝叶斯推理的概率图形模型,即,该模型旨在学习训练数据的潜在概率分布,以便它可以容易地从学习到的分布中采样新数据。想法是学习训练数据的低维潜在表示,称为潜在变量(不是直接观察到的变量,而是通过数学模型推断的变量),我们假设这些变量已经生成了我们的实际训练数据。这些潜在变量可以存储关于模型需要生成的输出类型的有用信息。潜在变量 z 的概率分布用 P(z)表示。选择高斯分布作为先验来学习分布 P(z ),以便在推断时间期间容易地采样新的数据点。

现在,主要目标是用一些参数对数据建模,这些参数使训练数据 X 的可能性最大化。简而言之,我们假设一个低维潜在向量已经生成了我们的数据 x (x ∈ X ),并且我们可以使用确定性函数 f(z;θ)由我们需要评估的θ参数化(见图 1[1])。在这种生成过程下,我们的目标是最大化 X 中每个数据的概率,

Pө(X) = ∫Pө(X,z)dz = ∫Pө(X|z)Pө(z)dz (1)

这里,f(z;θ)已被分布 Pө(X|z).取代

Fig. 1. Latent vector mapped to data distribution using parameter ө [1]

这种最大似然估计背后的直觉是,如果模型可以从这些潜在变量中生成训练样本,那么它也可以生成具有一些变化的类似样本。换句话说,如果我们从 P(z)中抽取大量潜在变量,并从这些变量中生成 x,那么生成的 x 应该与数据分布 Pdata(x)相匹配。现在我们有两个问题需要回答。如何捕捉潜变量的分布,如何在 z 的所有维度上积分方程 1?

显然,手动指定我们想要在潜在向量中编码以生成输出图像的相关信息是一项繁琐的任务。相反,我们依靠神经网络来计算 z,只是假设这个潜在向量可以很好地近似为正态分布,以便在推断时容易采样。如果我们在 n 维空间中有一个 z 的正态分布,那么使用一个足够复杂的函数来生成任何类型的分布总是可能的,并且这个函数的逆函数可以用来学习潜在变量本身。

在等式 1 中,积分在 z 的所有维度上进行,因此很难处理。然而,它可以使用蒙特卡罗积分方法来计算,这是不容易实现的。因此,我们遵循另一种方法来近似最大化等式 1 中的 Pө(X。VAE 的想法是用我们不知道的 P(z|X)来推断 P(z)。我们使用一种称为变分推断的方法来推断 P(z|X ),这基本上是贝叶斯统计中的一个优化问题。我们首先使用容易找到的更简单的分布 Q(z|X)对 P(z|X)建模,并且我们尝试使用 KL-散度度量方法最小化 P(z|X)和 Q(z|X)之间的差异,以便我们的假设接近真实分布。接下来是很多数学方程,我不会在这里解释,但你可以在原始论文中找到。但是我必须说,一旦你有了 VAE 背后的直觉,这些方程并不难理解。

VAE 的最终目标函数是:-

上面的等式有一个非常好的解释。Q(z|X)项基本上是我们的编码器网络,z 是数据 x(x ∈ X)的编码表示,P(X|z)是我们的解码器网络。所以在上面的等式中,我们的目标是在 D_KL[Q(z|X) || P(z|X)]给定的误差下最大化我们的数据分布的对数似然。很容易看出,VAE 试图最小化 log(P(X))的下限,因为 P(z|X)不容易处理,但是 KL 散度项> =0。这与最大化 E[logP(X|z)]和最小化 D_KL[Q(z|X) || P(z|X)]相同。我们知道,最大化 E[logP(X|z)]是最大似然估计,并使用解码器网络建模。正如我前面说过的,我们希望我们的潜在表示接近高斯,因此我们假设 P(z)为 N(0,1)。按照这个假设,Q(z|X)也应该接近这个分布。如果我们假设它是具有参数μ(X)和ʃ(x 的高斯分布,则由 KL-divergence 给出的这两个分布(即 P(z)和 Q(z|X ))之间的差异引起的误差导致下面给出的封闭形式的解。

考虑到我们正在优化较低的变分界限,我们的优化函数是:

log(P(X | z))—D _ KL[Q(z | X)‖P(z)],其中第二个的解如上图所示。

因此,我们的损失函数将包含两项。第一个是输入到输出的重建损失,第二个损失是 KL-散度项。现在我们可以使用反向传播算法来训练网络。但是有一个问题,那就是第一项不仅仅依赖于 P 的参数,也依赖于 Q 的参数,但是这种依赖性没有出现在上面的等式中。因此,如何通过我们从分布 Q(z|X)或 N[μ(X),ʃ(x]随机采样 z 的层反向传播,以便 p 可以解码。渐变不能流过随机节点。我们使用重新参数化技巧(见图 1)使网络可区分。我们从 N(μ(X),σ(X))开始采样,首先采样ε∾N(0,I),然后计算 z =μ(X)+σ1/2(X)∑ε。

这已经非常漂亮地显示在图 2[1]中了?。应当注意,前馈步骤对于这两个网络(左和右)是相同的,但是梯度只能通过右网络反向传播。

Fig.2. Reparameterization trick used to backpropagate through random nodes [1]

在推理时,我们可以简单地从 N(0,1)中采样 z,并将其馈送到解码器网络以生成新的数据点。因为我们正在优化较低的变分界限,所以与像生成对抗网络这样的最新技术相比,生成的图像的质量有些差。

VAE 最好的一点是,它学习生成模型和推理模型。虽然 VAE 和甘斯都是使用无监督学习来学习底层数据分布的非常令人兴奋的方法,但是甘斯比 VAE 产生更好的结果。在中,我们优化了变分下限,而在 GAN 中,没有这样的假设。事实上,GANs 不处理任何显式的概率密度估计。VAE 在生成清晰图像方面的失败意味着该模型不能学习真实的后验分布。和甘的主要区别在于训练的方式。现在让我们深入到生成性对抗网络。

生成性对抗网络

Yann LeCun 说对抗训练是自切片面包以来最酷的事情。看到生成性敌对网络的流行及其产生的结果的质量,我想我们大多数人都会同意他的观点。对抗性训练完全改变了我们教神经网络完成特定任务的方式。生成敌对网络不像变分自动编码器那样与任何显式密度估计一起工作。相反,它是基于博弈论的方法,目标是找到两个网络之间的纳什均衡,发电机和鉴别器。其思想是从高斯这样的简单分布中采样,然后学习使用通用函数逼近器(如神经网络)将这种噪声转换为数据分布。

这是通过这两个网络的对抗训练来实现的。生成器模型 G 学习捕获数据分布,鉴别器模型 D 估计样本来自数据分布而不是模型分布的概率。基本上,生成器的任务是生成看起来自然的图像,而鉴别器的任务是判断图像是假的还是真的。这可以被认为是一个迷你-最大双人游戏,其中两个网络的性能都随着时间的推移而提高。在这个游戏中,生成器通过尽可能生成真实图像来欺骗鉴别器,而鉴别器通过提高其鉴别能力来试图不被生成器欺骗。下图显示了 GAN 的基本架构。

Fig.3. Building block of Generative Adversarial Network

我们定义输入噪声变量 P(z)的先验,然后发生器使用参数为өg.的复可微函数将其映射到数据分布。除此之外,我们还有另一个称为鉴别器的网络,它接收输入 x,并使用另一个参数为өd 的可微函数输出单个标量值,表示 x 来自真实数据分布 Pdata(x)的概率。GAN 的目标函数定义为

在上述等式中,如果鉴别器的输入来自真实数据分布,则 D(x)应输出 1 以最大化上述目标函数 w . r . t . D,而如果图像是从生成器生成的,则 D(G(z))应输出 1 以最小化目标函数 w . r . t . G。后者基本上意味着 G 应生成可以欺骗 D 的这种真实图像。但是在优化发电机目标方面存在一个问题。在游戏开始时,当生成器没有学习到任何东西时,梯度通常很小,当它做得很好时,梯度很高(见图 4)。但是我们想要相反的行为。因此,我们最大化 E[log(D(G(z))]而不是最小化 E[log(1-D(G(z))]

Fig.4. Cost for the Generator as a function of Discriminator response on the generated image

训练过程包括在鉴别器和发生器上同时应用随机梯度下降。训练时,我们在小批量优化 D 的 k 个步骤和优化 G 的一个步骤之间交替。当鉴别器不能区分ρg 和ρ数据即D(x,өd) =或ρg =ρ数据时,训练过程停止。

采用卷积神经网络的 GAN 的最早模型之一是代表深度卷积生成对抗网络的 DCGAN 。该网络将从均匀分布中抽取的 100 个随机数作为输入,并输出所需形状的图像。网络由许多卷积层、反卷积层和全连接层组成。该网络使用许多反卷积层将输入噪声映射到所需的输出图像。批量归一化用于稳定网络的训练。ReLU 激活用于发生器中除输出层之外的所有层,输出层使用 tanh 层,泄漏 ReLU 用于鉴别器中的所有层。使用小批量随机梯度下降来训练该网络,并且使用 Adam 优化器来通过调整的超参数来加速训练。论文的结果相当有趣。作者表明,生成器具有有趣的矢量算术属性,利用这些属性,我们可以按我们想要的方式操纵图像。

Fig.5. Generator of DCGAN

Fig.6. Discriminator of DCGAN

最广泛使用的 GAN 变体之一是条件 GAN,它是通过简单地将条件向量与噪声向量相加而构建的(见图 7)。在 cGAN 之前,我们从噪声 z 的随机样本中随机生成图像。如果我们想要生成具有一些所需特征的图像,该怎么办?有什么方法可以向模型提供额外的信息,告诉我们想要生成什么类型的图像?答案是肯定的,有条件的 GAN 是实现这一目标的方法。通过根据提供给生成器和鉴别器的附加信息来调节模型,可以指导数据生成过程。条件甘用于各种任务,例如文本到图像生成、图像到图像翻译、自动图像标记等。下图显示了两个网络的统一结构。

Fig. 7. A basic example of cGAN with y as the conditioning vector

GANs 的一个很酷的地方是,即使只有很少的训练数据,它们也可以被训练。实际上,GANs 的结果是有希望的,但是训练过程并不简单,尤其是建立网络的超参数。此外,gan 难以优化,因为它们不容易收敛。当然,这里有一些破解 GANs 的技巧和窍门,但它们可能并不总是有用。你可以在这里找到一些建议。此外,除了检查生成的图像在感知上是否真实之外,我们没有任何对结果进行定量评估的标准。

结论

深度学习模型在监督学习中确实达到了人类水平的性能,但在无监督学习中却并非如此。尽管如此,深度学习科学家正在努力提高无监督模型的性能。在这篇博文中,我们看到了两个最著名的生成模型的无监督学习框架实际上是如何工作的。我们知道了可变自动编码器中的问题,以及为什么敌对网络更擅长产生真实的图像。但是 GANs 也有一些问题,比如稳定他们的训练,这仍然是一个活跃的研究领域。然而,GANs 非常强大,目前它们正被用于各种任务,如高质量图像(参见此 视频 )和视频生成、文本到图像的翻译、图像增强、从图像重建物体的 3D 模型、音乐生成、癌症药物发现等。除此之外,许多深度学习研究人员也在努力统一这两种模型,并获得这两种模型的最佳效果。看到深度学习的推进速度越来越快,相信 GANs 会打开半监督学习、强化学习等人工智能的很多紧闭的大门。在接下来的几年里,生成模型将会对图形设计、有吸引力的用户界面设计等非常有帮助。使用生成对抗网络来生成自然语言文本也是可能的。

参考文献:-

【1】。https://arxiv.org/pdf/1606.05908.pdf

[2].https://arxiv.org/pdf/1406.2661.pdf

[3].https://wise odd . github . io/tech blog/2016/12/10/variation-auto encoder/

使用 3D 卷积神经网络的深部灰质(DGM)分割:在 QSM 的应用(第二部分)

原文:https://towardsdatascience.com/deep-gray-matter-dgm-segmentation-using-3d-convolutional-neural-network-application-to-qsm-part-83c247416389?source=collection_archive---------16-----------------------

背景信息和以前的结果可在第 1 部分中找到:

代码(更新)

可在 Github 获得:【https://github.com/zl376/segDGM_CNN

描述

该记录包括对先前用于 QSM 图像上的深灰质(DGM)分割的 3D 卷积神经网络模型(基线模型)的以下更新:

Example cases where proposed and manual segmentation are performed

网络体系结构

Flowchart for Baseline (left) and Proposed (right) model

  • 内核大小:从(3,3,3)变为(7,7,3),以说明各向异性的图像分辨率
  • 每层后批量归一化以提高收敛性
  • 空间坐标输入作为辅助特征

训练参数

执行 10 重交叉验证,其中 18 个案例用于训练,2 个用于测试。最大纪元是 60 年。学习率最初设置为 0.001,每 20 个时期减少 10 倍。

改进的结果

Comparison of Baseline, proposed and manual segmentation for Caudate Nucleus.

较大的卷积核有助于完全捕捉 DGM 结构,如上例所示,其中基线模型中使用的较小核不必要地关注尾状核边界的对比度。

Precision and Dice score for Baseline and proposed model

在精确度和骰子得分度量中也观察到了改进,尤其是对于红核,其横截面形状类似于其他结构,例如静脉或出血。辅助输入中的空间信息有助于区分红核和那些结构。

后续步骤

  • 数据扩充:缩放和旋转训练数据集,以处理临床应用中 DGM 大小和方向的变化。
  • 合并其他模态如 R2*图像或 T1w 图像。

使用 3D 卷积神经网络的深部灰质(DGM)分割:在 QSM 的应用(第一部分)

原文:https://towardsdatascience.com/deep-gray-matter-dgm-segmentation-using-neural-network-application-to-qsm-a0183cb3e3ae?source=collection_archive---------4-----------------------

【更新 2018–02–04】:新的结果可以在 Part 2 找到。

密码

可在 Github 获得:【https://github.com/zl376/segDGM_CNN

动机

在 MRI 分析中,计算机化的自动分割是期望的,并且实际上被广泛研究。具体而言,对于 QSM(定量磁化率绘图),一种量化和描绘受试者中铁/钙分布的 MRI 技术,深灰质(DGM)的感兴趣区域(ROI)测量是不同重建算法之间一致性的公认度量。DGM 铁矿资源丰富,是 QSM 的一个亮点,因此通常选择该地区作为研究目标。

Deep Gray Matter includes: Basal ganglia (Globus pallidus, Putamen and Caudate nucleus), subthalamic nucleus and substantia nigra.

通常,DGM ROI 的绘制是由经验丰富的放射科医生手动完成的,这需要花费大量的时间,并且固有地限制了分析的样本量(<20 subjects). Therefore, I try to train a neural network to segment the DGM based on QSM, for ROI measurement analysis at a potentially large scale (e.g. ~500 subjects).

Method

Convolutional Neural Network is chosen as the framework for segmentation. The model used in this work is based on:

  • 用于 MRI 皮质下分割的 3D 全卷积网络:一项大规模研究
  • 使用三维完全卷积神经网络和伪标记进行六个月婴儿脑组织分割

当前的 CNN 是通过以下平台/包实现的:

  • 张量流
  • Python 3.5
  • Keras 2.0.2

数据预处理

这项工作收集并命名了来自 20 个受试者的 QSM。由有经验的专家在每个病例上绘制不同深灰质(DGM)的 ROI,并将其作为参考分割。

Example for QSM (left) and ROI (right) for DGM

QSM 重建的原始结果跨越一系列矩阵大小、分辨率和覆盖范围(视野),因此数据在输入网络之前需要归一化。

数据标准化

所有 20 个三维图像被重新调整到相同的体素尺寸(1 毫米、1 毫米、3 毫米)并被裁剪成矩阵尺寸(160、220、48)。这提供了(16 厘米,22 厘米,14.4 厘米)的体积覆盖,对于普通人的大脑来说足够大。QSM 的磁化率值被裁剪为-0.2ppm 至 0.2ppm,并重新调整为 0~255。从人工分割中提取 11 个类别:1 个类别用于背景,2 个类别(左/右)用于 5 个 DGM 中的每一个。处理后的图像保存为 Nifti 文件,并提供给以下 CNN。

15 个案例表示为训练集,5 个用于测试。

训练 CNN

Overview of the 3D CNN, as proposed by Dolz et al. Neuroimage 2017.

如在用于 iSeg2017 的解决方案中所建议的,输入 3D 体积(QSM 和类别标签)被分割成对应于输出片尺寸(9,9,9)的更小的片(27,27,27),并且仅具有背景标签的那些被从训练中丢弃。这个技巧极大地减少了数据的大小,从而减少了用于训练的内存。对于这项工作,这里的切片厚度(3 毫米)比他们的(1 毫米)大 3 倍,因此输入面片大小选择为 (27,27,21) ,对应于输出大小(9,9,3)。

选择 1/4 的输入数据进行验证。选择交叉熵作为损失函数。

针对误报的微调

由于一些补丁在训练前就被丢弃了,这些区域的信息还没有被 CNN 利用。在训练 CNN 之后,如果这些小块通过网络并与参考标签比较(验证),观察到背景类可能被错误分类为 DGM,这被表征为假阳性。

那些假阳性被 CNN 的第二轮微调处理:那些具有假阳性的小块被包括在输入集合中;然后,基于先前获得的“最优”权重,使用扩充的输入数据来重新训练网络。

参数选择

学习率被指定为 0.0001,然后减少到 0.00001。最大历元数为 40,当验证损失停止下降时,触发提前停止。

后处理

正如在大型研究论文中注意到的,分割可能由一些孤立的小“岛”组成,而不是目标 DGM 构造。这是为了在每个 DGM ROI 的分割中保持最大的连通分量。

结果和评估

计算每个 DGM 的精度(真阳性对所有阳性预测)和骰子点数,如下所示。

一个很好的例子:

一个不太好的例子:

在结果中观察到对特定 DGM(尤其是黑质和尾状核)的低估。对于这两个 DGM,这也在表中表示为低骰子分数。

讨论

样本量

在这项工作中,样本量有点小(15 个训练+ 5 个测试),但已经给出了一些有希望的结果,如上所示。保存所有 3D 碎片所需的昂贵的 3D 卷积和存储器是使用大样本量的主要障碍。在目前的训练平台上(酷睿 i3,16GB RAM,11GB 内存的 GTX 1080Ti),微调阶段占用了大约 50%的 GPU 内存。潜在地,样本大小可以加倍(到~40)并且可以使用交叉验证来进一步评估 CNN 的性能。

损失函数

在当前的训练中,分类交叉熵被用作损失函数。虽然 Dice 分数等其他指标被广泛用于量化 ROI 协议,但有趣的是,看看用 Dice 分数代替交叉熵是否会提高 CNN。

分割不足

当应用于 5 个测试病例时,CNN 有时不能描绘某些 DGM 区域的整个结构,尤其是尾状核。这可能与卷积层中使用的内核大小有关。

这就引出了另一个有趣的问题:欠分割真的是 ROI 分析的一个问题吗,尤其是在比较不同的 QSM 重建算法时?

多类 vs .二进制?

考虑到 DGM 在解剖和功能上是相互联系的,至少对于基底神经节而言是如此,在基底神经节中,苍白球、壳核和尾状核之间的界面难以确定,因此多类分割可能不是这一特定任务的最佳框架。同时,整个任务可能被分成更小的子任务,其中我们使用二元分类器来分割每个 ROI:例如,在分割左侧苍白球时,目标结构中的体素被标记为类 1,而其他所有的被表示为类 0。训练速度可以受益于这种任务划分,因为对于每个子任务(ROI ),涉及的补丁数量比原始多类任务中的小得多。当所有子任务同时执行时,训练过程以 ROI 数量的因子加速。

多模态输入

在iseg 2017的解决方案中,T1 和 T2 加权图像均用作每个受试者的输入。T1 和 T2 加权图像显示的不同对比度可能有助于区分不同的结构。而在 QSM 的研究中,T1/T2 图像通常是稀少的,或者如果有的话,也是未注册的,因为它们是在不同的时段获得的。然而,其他图像模态,如幅度(单回波)或 R2*图(演示信号在多个回波中衰减的速度)很容易与每个 QSM 图一起使用,并可以并入当前的 CNN。它对多通道输入数据的性能将是一个有趣的研究课题。

Tensorflow 中的“深度”独立分量分析[TF 中的手动背道具]

原文:https://towardsdatascience.com/deep-independent-component-analysis-in-tensorflow-manual-back-prop-in-tf-94602a08b13f?source=collection_archive---------8-----------------------

Photo by Bernard Hermant on Unsplash

我们可以使用独立分量分析来捕捉局部变化,然而,我们在现实生活中遇到的图像数据生活在非常高维的空间中。我想看看我们是否可以结合深度学习来执行 ICA。

请注意,这篇文章只是为了娱乐和自学。

人脸数据或 MRI 数据上的 ICA

Image from this website

如上所述,当我们在人脸图像或脑部 MRI 上执行 ICA 时,我们可以注意到我们能够(清楚地)捕捉到局部变化。然而,这能在现实生活中的图像上工作吗?我的意思是,我们是否能够从包含许多差异的一组图像中捕捉到一个物体的大致结构。

Image from this website

如上所述,对于给定对象,图像看起来会有很多不同。(带刻度或方差)。但是如果我们仔细想想,面部图像和大脑核磁共振成像一样,已经是居中的,不包含太多的变化。STL 数据集中的鸟类图像子集怎么样?

如上所述,所有的图片都包含了鸟的图像,但是有些在飞,有些在坐。有不同的规模以及旋转,角度等。

PCA、KPCA 和 ICA 的直接方法

让我们使用高级 API 方法对 STL 数据集中的 500 幅鸟类图像执行一些降维技术。(我准备用 Sklearn。)还有,我只会得到前 40 个主分量以及独立分量。

Left the whole data set \ Right split the data set in to 4 components

我们可以看到,在我们的第一张主图像中,我们的图像中心有一个白色斑点。(那看起来确实像一只鸟)。在轴上移动,我们可以观察到很少的主成分像鸟一样的图形。然而,在第三行之后,不清楚图像中到底有什么。

Left the whole data set \ Right split the data set in to 4 components

同样,让我们使用高级 api 方法来执行 KPCA,类似于 PCA 的结果。同样,前几个主要图像确实像一个鸟一样的数字。

Left the whole data set \ Right split the data set in to 4 components

最后,高级 ICA 方法。我们可以看到,总的来说,它捕捉到了图像中的局部变化。如果我看得足够近,我真的可以在图像中看到一些鸟一样的人物。

“深度”学习方法

黄框 →卷积层
蓝框 →主成分分析层
红框 →独立成分分析层

现在,从上面的图中,我们已经知道我想要尝试什么,只需用几个卷积层从图像中提取更高层次的特征,然后执行 PCA 以降低维度,并使用 ICA 以统计方式使这些主成分相互独立。

我之所以在 ICA 之前使用 PCA,是因为从我过去的实验来看,使用 ICA 作为降维手段并没有很好地收敛。另外请注意,我们可以选择多种独立分量分析方法,例如梯度上升法。我正要用 FastICA。

在继续之前,让我们首先实现 PCA 层,如上所述,这里还要注意的另一件事是,我将使用 Adam 来优化快速 ICA 的权重,而不是直接分配。

最后,我不想在 ICA 上进行优化,而是想分成四个不同的流。

可用于快速 ICA 的函数形状

Image from this website

我不会进入细节,但对于快速 ICA 有几个激活功能(不是正确的名称,但我会这样称呼它。),我们可以选择使用。我想把它们形象化。

ICA 作为损失函数

左上 →原图像
右上 →第一层后图像
左下 →第二层后图像
右下 →第三层后图像

因此,随着图像在层中向上移动,图像中的一些部分变暗,而其他部分变得更白。现在让我们看看 40 张组合的原则图片。

一些黑色的数字看起来像鸟,但不是那么脆,当我们看到 40 个独立的组件。

我们可以看到,一些部分看起来更像鸟,但没有那么脆,我想还有很长的路要走。收敛过程如下图所示。

本岗位代码

对于谷歌 Colab,你需要一个谷歌帐户来查看代码,而且你不能在谷歌 Colab 中运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要访问 sklearn High 级别的代码,请单击此处。
点击此处获取 Tensorflow 的代码。

最后的话

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。

同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。我还实现了广残网,请点击这里查看博文 t。

参考

  1. PIL?,H. (2018)。如何保存 PIL 的图像?。堆栈溢出。检索于 2018 年 9 月 15 日,来自https://stack overflow . com/questions/14452824/how-can-I-save-a-image-with-pil
  2. 南 PIL(2018 年)。用 PIL 拯救形象。堆栈溢出。检索于 2018 年 9 月 15 日,来自https://stack overflow . com/questions/1965 10 55/saving-image-with-pil
  3. 慢,S. (2018)。使用 Matplotlib 保存图形非常慢。树莓 Pi 栈交换。检索于 2018 年 9 月 16 日,来自https://raspberrypi . stack exchange . com/questions/72542/saving-graphs-using-matplotlib-is-very-slow
  4. 用于视觉识别的 CS231n 卷积神经网络。(2018).cs 231n . github . io . 2018 年 9 月 16 日检索,来自http://cs231n.github.io/classification/

内心深处:自动编码器

原文:https://towardsdatascience.com/deep-inside-autoencoders-7e41f319999f?source=collection_archive---------0-----------------------

自动编码器(AE)是神经网络,旨在将它们的输入复制到它们的输出。他们通过将输入压缩到一个潜在空间 表示中,然后从这个表示中重建输出。这种网络由两部分组成:

  1. 编码器:这是网络的一部分,它将输入压缩成潜在空间表示。可以用编码函数 h=f(x) 来表示。
  2. **解码器:**该部分旨在从潜在空间表示中重建输入。可以用解码函数 r=g(h) 来表示。

Architecture of an Autoencoder

因此,自动编码器作为一个整体可以由函数 g(f(x)) = r 来描述,其中您希望***【r***与原始输入 x 一样接近。

为什么要将输入复制到输出?

如果自动编码器的唯一目的是将输入复制到输出,那么它们将毫无用处。事实上,我们希望通过训练自动编码器将输入复制到输出,潜在表示将呈现有用的属性。

这可以通过对复制任务创建约束来实现。从自动编码器获得有用特征的一种方式是约束使其尺寸小于 x ,在这种情况下,自动编码器被称为欠完成。通过训练欠完整表示,我们迫使自动编码器学习训练数据的最显著特征。如果给自动编码器太多的容量,它可以学习执行复制任务,而不提取任何关于数据分布的有用信息。如果潜在表示的尺寸与输入相同,以及在过完全的情况下,潜在表示的尺寸大于输入,也会发生这种情况。在这些情况下,即使线性编码器和线性解码器也可以学习将输入复制到输出,而无需学习任何关于数据分布的有用信息。理想情况下,可以成功地训练自动编码器的任何体系结构,根据要建模的分布的复杂性选择编码维数以及编码器和解码器的容量。**

自动编码器的用途是什么?

今天数据去噪和用于数据可视化的降维被认为是自动编码器的两个主要有趣的实际应用。通过适当的维度和稀疏性约束,自动编码器可以学习比 PCA 或其他基本技术更有趣的数据投影。

自动编码器是从数据示例中自动学习的。这意味着很容易训练将在特定类型的输入上表现良好的算法的专门实例,并且它不需要任何新的工程,只需要适当的训练数据。

然而,自动编码器在图像压缩方面表现不佳。当自动编码器在给定的数据集上被训练时,它将在与所使用的训练集相似的数据上实现合理的压缩结果,但是将是较差的通用图像压缩器。像 JPEG 这样的压缩技术会好得多。

自动编码器被训练为当输入通过编码器然后通过解码器时尽可能多地保留信息,但是也被训练为使新的表示具有各种良好的属性。不同种类的自动编码器旨在实现不同种类的属性。我们将重点讨论四种类型的自动编码器。

自动编码器的类型:

在本文中,将描述以下四种类型的自动编码器:

  1. 标准自动编码器
  2. 多层自动编码器
  3. 卷积自动编码器
  4. 正则化自动编码器

为了说明不同类型的自动编码器,我们使用 Keras 框架和 MNIST 数据集创建了一个示例。每种自动编码器的代码都可以在我的 GitHub 上找到。

标准自动编码器

在其最简单的形式中,自动编码器是三层网络,即具有一个隐藏层的神经网络。输入和输出是相同的,我们学习如何重建输入,例如使用 adam 优化器均方误差损失函数**。**

这里,我们看到我们有一个欠完成自动编码器,因为隐藏层尺寸(64)小于输入(784)。这种约束将迫使我们的神经网络学习数据的压缩表示。

多层自动编码器

如果一个隐藏层不够,我们显然可以将自动编码器扩展到更多的隐藏层。

现在我们的实现使用 3 个隐藏层,而不是只有一个。可以选择任何隐藏图层作为要素制图表达,但我们将使网络对称,并使用最中间的图层。

卷积自动编码器

我们也可以问自己:自动编码器可以用于卷积而不是全连接层吗?

答案是肯定的,原理是相同的,但是使用图像(3D 矢量)而不是扁平的 1D 矢量。对输入图像进行下采样,以给出较小尺寸的潜在表示,并迫使自动编码器学习图像的压缩版本。

正则化自动编码器

除了施加比输入维度更小的隐藏层之外,还有其他方法可以约束自动编码器的重构。正则化的自动编码器不是通过保持编码器和解码器浅和代码大小小来限制模型容量,而是使用损失函数来鼓励模型具有除了将其输入复制到其输出的能力之外的其他属性。在实践中,我们通常会发现两种类型的正则化自动编码器:稀疏的 T2 自动编码器和去噪的 T4 自动编码器。

****稀疏自动编码器:稀疏自动编码器通常用于学习另一个任务的特征,例如分类。已经被正则化为稀疏的自动编码器必须响应它已经被训练的数据集的独特统计特征,而不是简单地充当身份函数。通过这种方式,以稀疏性为代价执行复制任务的训练可以产生一个附带学到有用特征的模型。

我们可以约束自动编码器的重构的另一种方式是对其损耗施加约束。例如,我们可以在损失函数中加入一个正则项。这样做将使我们的自动编码器学习数据的稀疏表示。

请注意,在我们的隐藏层中,我们添加了一个 l1 活动正则化器,它将在优化阶段对损失函数应用惩罚。因此,与普通的自动编码器相比,这种表示更加稀疏。

****去噪自动编码器:通过改变损失函数的重建误差项,我们可以获得一个自动编码器,它可以学习一些有用的东西,而不是向损失函数添加惩罚。这可以通过在输入图像中添加一些噪声,并让自动编码器学习去除噪声来实现。通过这种方式,编码器将提取最重要的特征,并学习数据的鲁棒表示。

摘要

在本文中,我们介绍了自动编码器的基本架构。我们还研究了许多不同类型的自动编码器:普通的、多层的、卷积的和正则化的。每一种都有不同的属性,这取决于所施加的约束:要么是隐藏层的维度减少,要么是另一种惩罚。

我希望这篇文章对新的深度学习实践者来说是清晰和有用的,并且它让你对什么是自动编码器有了很好的了解!如果有不清楚的地方,请随时给我反馈或问我问题。

** [## nathan hubens/自动编码器

在 GitHub 上创建一个帐户,为 Autoencoders 的开发做出贡献。

github.com](https://github.com/nathanhubens/Autoencoders)**

隐藏在深度学习下的深层问题:

原文:https://towardsdatascience.com/deep-issues-lurking-within-deep-learning-f923a96564c7?source=collection_archive---------5-----------------------

对吴恩达深度学习 Coursera 专业化的思考

TL;DR——我强烈推荐这个 MOOC 专业。但是,要注意!这不仅仅是另一张证书。更深层次的问题潜伏在表面之下,促使您更深入地思考使用这项新技术的责任。

读者注意(2018–06–07):文章分为两部分。第一部分描述了面向数字图书馆潜在学生的 MOOC 课程。第二部分探讨了“那又怎样?”含义,尤其是 DL 实践者的责任。

我最近完成了 Coursera 深度学习(DL)专业化课程,包括 5 门课程、14 个课程周、180 个视频、29 个实验室和 5 次“英雄”访谈。[01]

我的动机是学习一项新技能,我做到了。然而,我也带走了许多问题和顾虑,以及一系列需要调查的项目。如果你致力于这一专业,你将获得更多的-另一个证书!以下是我对这一经历及其在更大背景下的意义的思考。

我的经历

DeepLearning.ai 的吴恩达和斯坦福以一种人性化的风格教授这门课程,在适当的时候逐步揭示细节。他有理解学生在努力学习这门复杂学科时的想法的天赋。他的任务是培训数百万专业人员使用人工智能工具,“这样他们就可以去发明没有大公司能做的事情。”[02]

我在 2013 年上过 Ng 的机器学习课程,用的是 Octave,很兴奋能用 Python 更深入。2017 年 9 月,我开始了五门课程中的第一门。我立刻注意到,Coursera 在这四年里对他们的 MOOC 基础设施进行了许多学习改进。以下是我学习经历中难忘的元素。

了解你的数学!

像第一个课程一样,主题流从基础数学开始,并使用逻辑回归的经典例子将其转化为工作代码。然而,我注意到对符号(尤其是奇怪的上标)的更多强调,就像我们在构建更复杂的东西一样。我是正确的!我很快了解到 NumPy 是你的朋友,它支持向量化重构代码。*回见。嗯,不完全是。*我最终了解到,矢量化是为深度神经网络粉碎张量的核心,为实际应用提供了必要的计算能力。

复古粉笔对话

视频很短,平均 7 分钟。Ng 以复古的粉笔演讲风格进行了演讲——从一张白纸开始,用几乎无法辨认的脚本详细地写下一切*。*我很快适应了他的风格,在每个片段结束时捕捉最终屏幕,粘贴到 PowerPoint 中,并添加更多评论。还提供了 MP3 视频和粗略的 TXT 翻译。

只是-足够的测验

每周,讲座都以一个简短的多项选择题测验结束。起初,这些小测验很烦人,但事实证明它们击中了关键点,足以确保我关注视频。

英雄访谈

令人高兴的是“英雄”访谈,Ng 将采访 DL 研究人员关于深度学习的历史和里程碑。后面课程的英雄视频我都错过了!Ng 是不是英雄用完了?

填空实验室

最好的部分是实验室,由特定结构内的填空组成。这也是使用 Jupyter 笔记本进行教学的一个很好的例子,清晰详细的说明激励学生进行编码并获得即时反馈。因此,学生被激励去学习良好的实践,小心翼翼地插入调试语句和仔细地关注单元测试。

与实验室的薄弱环节是自动评分程序,这是草率的,有时很奇怪。*DL 的巨大应用前景!*这个小故障迫使学生花费额外的时间来理解算法中的数学到代码的转换和数据流。凭借极大的耐心、论坛评论和 StackOverflow,我能够找到解决方案,通常是预计时间的两倍。

软性截止日期

我偶尔会面临提交实验的最后期限,这增加了完成实验的戏剧性和满足感。这些截止日期是“软”的,只是将课程完成时间推迟到下一个月周期(不损失之前的工作)。我发现截止日期对我来说是有益的,就像任何忙碌的专业人士一样。

付钱还是不付钱

你可以作为一名审计员免费参加整个专业化认证!我是这样开始的,直到第一次测验。审核员不会对他们的测验或实验评分。你可以做实验,但是你不会收到自动评分系统的反馈。在我的专业阶段,我不需要另一个证书。但是,我需要反馈!而且,这个反馈确实提高了我的学习质量。

最佳实践

在第一次基础课程后,我期待着与性感的 CNN 和 RNN 模特一起处理图像和自然语言的令人兴奋的事情。令我失望的是,Ng 将接下来的两门课程重点放在了神经网络调优的实践方面(测试/开发、正则化、偏差/方差、小批量、超参数调优)和结构化开发项目(评估指标、人的水平性能、错误分析)。真扫兴!

事后看来,这两门课程是整个专业中更有洞察力的。Ng 在深度学习的艺术方面指导我们,强调不断发展的最佳实践及其实验性质。结合“英雄”访谈,Ng 向我介绍了 DL 专业人士社区。手感不错!

全栈

最后,这种专业化让我掌握了在 Python、NumPy、TensorFlow 和 Keras 的全套工具上设计和实现深度神经网络的技能,以及熟悉基于云的编程环境,如 Jupyter 笔记本。我经常将实验室笔记本文件(和其他相关文件)复制到我的本地 Anaconda3 环境中,并且不加修改地执行。为了增加计算能力,我安装了一个 GTX1060 卡。令我惊讶的是,无论是本地还是基于云的 DL 技术变得如此方便和平易近人。

那又怎样?

完成 DL 专业后,我感到宽慰的是我的时间被释放了,而悲伤的是安德鲁的粉笔演讲结束了。我花了很多时间学习这个复杂的学科。然而,我学到了什么持久的意义?这只是区分狗和猫的可爱方法吗?把梵高的风格应用到朋友的照片上?深度学习有实用价值和社会救赎的潜力吗?

经过这么多努力,那又怎样?

意义的问题一直在我脑海中翻腾。所以,我回到第一堂课,整理了一份完整的专业化大纲(十页纸!).是的,有很多材料。但是,我突然意识到,我的“哦,我的上帝”时刻到了!

DL 的意义在于揭示关于思考和学习的基本原理,而不是通过模仿人脑(它只是肤浅地模仿)。相反,DL 使人类能够在几个具有挑战性的智力任务中创造出超过“人类水平的性能”的算法。换句话说,…

我们人类已经创造了足够聪明的工具来超越我们自己!

这不是通常的超级智能机器人因为我们的自卑而决定消灭人类的科幻故事。真正的问题是在大型系统中嵌入 DL 应用程序的意想不到的后果,如脸书、亚马逊、谷歌和其他影响许多人生活的公司。此外,这些数字图书馆的应用将在未来几年大幅增加!

我的见解

下面是我从上面得出的一些见解?

以数据开始和结束

一张简单而深刻的 Ng 幻灯片的标题是“规模推动 DL 进步”,如下图所示。

From Coursera Course “Neural Networks & Deep Learning” by Andrew Ng

对于任何预测算法,预测的性能(或准确性)都受到数据量的严重影响。数据必须是有质量标签的数据,其中观察正确地反映了现实,并标有“良好”指标。蹩脚或贴错标签的数据不算!

这里有几点需要注意…

  • 更多的数据总是胜过更少的数据!控制最多数据的公司最终会战胜所有其他公司!
  • 在低数据量的情况下,任何预测算法都和其他算法一样好。所以 DL 没有优势;因此,使用传统的机器学习算法(如随机森林),因为它们更容易,更快,并提供更好的可解释性。
  • 在高数据量的情况下,深度神经网络可以显著提高性能。
  • 绩效往往是不明确的。测试数据的预测准确性(正确预测/总预测)经常被使用,但是这对于许多用例可能是误导的。在这里深入挖掘!

洞察力是…一切都依赖于数据,这是 DL 的“阿喀琉斯之踵”。将数据视为有价值的资产。

数据不仅仅是数字

在实验室中,我对数据的想法发生了微妙的转变。作为商业智能的背景,我一直认为数据是一个大数字表中的行(实例)和列(特征)。处理图像和音乐会动摇这种心态。

我清楚地记得 Ng 的 Octave 实验室处理一位数的图像(来自 MNIST)。每个像素的灰度值被放入一个长的线性阵列(特征),使像素的 x-y 位置的任何指示无效。我认为这种做法不会产生任何有用的结果。*这怎么可能?*然而这个简单的一层神经网络达到了 82%的准确率。惊喜!

在最新的 Ng 的 CNN 课程中,我们学习了如何应用卷积变换,它确实保留了位置信息。预测精度提高到 90%以上,超过了人类的水平。太神奇了!

重点是,DL 要求同时从两个角度查看数据:

  1. 以矩阵形式构造的数字,可在 GPU 上进行高效计算。在这里,形状(维度大小的向量)对于矩阵计算是至关重要的,更重要的是,保持矩阵的意义。每次我弄乱形状的顺序,都是因为我忘记了矩阵的意义,尤其是它与数学的对应关系。
  2. 现实的碎片,每一个都有其独特的品质。自然抗拒被数字化,无论是作为图像、声音、振动等等。对我来说,这在 RNN 的课程中很明显,处理音乐中的序列模式。通常,我不得不提醒自己,这些数字实际上是一个爵士钢琴家打出的旋律,数字化成 MIDI 编码。现在,我可以正确地处理观点 1。

这种观点认为,数据具有数字和现实的双重性格,两者的完全共存对任何人来说都是难以维持的。

近乎炼金术

DL 是一门正在努力寻找其理论的原始科学。*想想 17 世纪的化学。*因为 DL 缺乏坚实的理论,研究人员正在尝试模型结构、成本函数、数据转换等疯狂的想法。而且,这些疯狂的想法已经产生了惊人的效果!这太令人兴奋了!

但是,这也让 DL 的新生感到困惑。所以,当一个学生问,“为什么要使用盗梦网络”,答案通常是“因为它能产生更高的测试准确度”。真实的回答应该是“因为我们不确定要做什么,所以我们正在尝试一切可能的方法”。

正如在 Geoffrey Hinton 的“英雄”采访中所讨论的,原始科学的斗争在随机梯度下降(SGD)与反向传播的结合中最为明显。这是可行的,但是如何在一个非平凡的网络中理解和优化它的过程呢?辛顿表示,他对 SGD“深表怀疑”,也许应该“扔掉它,重新开始”。相反,他强调对无监督学习的研究,这可能意味着“摆脱反向传播”。[03]

其观点是,DL 是一门实验性的原始科学,缺乏坚实的理论指导。拥抱它!适当地促进其成熟。同时,认识到一个人有很大的责任去坚定地基于好的数据不断地测试算法性能的准确性。

想象一下出现在法庭上解释为什么你控制自动驾驶汽车的 DL 算法导致了一起死亡事故。因此,要对你的模型的有效性着迷甚至偏执![04]

元学习是新的秘方

在我看来,DL 正在迅速超越 SGD,进入一些人称为“元学习”的模糊领域——意识到并控制学习(模型训练)过程。[05]

作为元学习的一瞥,我特别着迷于 ng 的讲座和实验室:

  • 人脸识别,重新使用预先训练好的模型将其权重“转移”到新的应用程序中。
  • 神经风格转移,戏弄成本函数以平衡内容与风格激活。
  • 爵士乐独奏,欺骗一个预先训练好的模型,生成一个可能的输入数据序列。
  • 去除词向量的偏见,用类比来检测和纠正性别偏见。
  • 语言翻译,通过管理注意力放置节点来增强。

我的兴趣促使我学习各种元学习方法,例如:

  • AlphaGo Zero 证明了问题域(如围棋)的良好模拟可以替代生成标记数据,使用生成式对抗网络(GAN)。
  • 由 Hinton 引入的胶囊网络 (CapsNet),用于纠正图像分类器中的缺陷。
  • 通过遗传进化算法优化 DNN 类型、组件和超参数。

这个观点是,人们应该急切地探索 DL 的新秘方——元学习。

智能可扩展学习的潜力

对我来说,从这些 DL 课程中可以明显看出,MOOC 基础设施在最近几年已经成熟。当我观看视频、参加测验和在实验室工作时,我生成了大量的点击数据,这些数据可以用测验分数和实验室完成情况来标记。鉴于论坛上的活动,我是数百名(也许数千名)其他学生中的一员。随着课程设置的持续循环,这种点击数据的积累将对指导学习过程非常有用。[06]

我们能设计和训练一个 DNN 模型来指导为新生定制的有效学习吗?把这个学习过程想象成一个旅行到目的地的冒险游戏。一路上有许多难题有待解决。并且,许多路径都是可能的。到达目的地,你就获得了认证。

不仅仅是深度学习的主题,这种方法也适用于成千上万的其他主题。此外,如果可以为一名学生提供定制学习,那么这种定制学习可以扩展到数千名新学生,最终成熟为全球学习服务。

问题是……我们现在有技术为全世界提供智能的可扩展学习资源吗?维基百科的‘教学’?涡轮增压的卡恩学院?

我的新超能力

最后,我的思绪回到了 DL 的社会和伦理含义上。在他的最后一个视频中,吴恩达祝贺他的学生完成了这个专业,并敦促他们进一步发展自己的职业生涯,追求自己的梦想。

From Coursera Course “Sequence Models” by Andrew Ng

ng 进一步将深度学习的学习比作一个人获得了使计算机能够看到、合成艺术和音乐、翻译语言和诊断放射图像的超能力。他接着敦促道:

做你认为对人类最好的工作。
当今世界面临诸多挑战。但是借助深度学习的力量,我认为我们可以把它变成一个更好的地方。
现在你有了这种超能力,我希望你能利用它走出去
,让自己和他人的生活变得更好。[07]

他的观点是…

伟大的能力意味着伟大的责任。

深度学习赋予我们巨大的力量,也赋予我们巨大的责任去明智地使用它,造福人类。

作为促进这种责任的一个积极的实质性例子,Francois Chollet 最近提出,深度学习工具不应该被用来操纵人。相反,深度学习应该让人们能够控制这些工具,以追求自己的目标和激情。[08]

一些专家将深度学习比作人类的其他重大发明,如核能。如果这种比较是正确的,那么它是一个非常发人深省的想法。

参考

[01] Coursera,《深度学习专业化》。链接所有五个球场现在都是每月循环一次。关于其内容的概述,请参见泰丝·费兰德斯 2018 年 3 月 8 日撰写的精彩的 28 页幻灯片笔记。另外,Ryan Shrott 的关于“11 个经验教训”的文章是这些课程中教授的概念的一个很好的例子。

[02] Knight,“吴恩达的下一招:培养一百万人工智能专家”,《麻省理工科技评论》,8 月 8 日。2017.链接采访聚焦 ng 的在线课程和他培养新人工智能专家的目标。《麻省理工科技评论》29:18 吴恩达谈论人工智能状态的精彩视频。链接一条评论称“Ng 是煤矿里最完美的金丝雀。只要他不抓狂,我们应该相对安全。”

[03]莱文,《人工智能先驱说我们需要重新开始》,Axios,2017 年 9 月 15 日。链接

[04] Moore,“关于深度学习的深层误解”,走向数据科学,2018 年 1 月 26 日。链接开发 DL 应用的最佳实践。我是偏执狂!我的模特是故意骗我的!它是来抓我的!

[05]元学习的定义是从这个维基百科条目中提炼出来的。
关于 DL 元学习的不太密集的文章正在出现,比如:

  • Perez,《深度元学习的方法分类学》,直觉机器,2017 年 3 月 5 日。链接
  • Rodriguez,《深度学习研究的新进展:理解元学习》,走向数据科学,2018 年 3 月 15 日。链接
  • Miikkulainen 等,《进化中的深度神经网络》,arXiv,2017 年 3 月 1 日。 link CoDeepNEAT 通过遗传进化算法优化 DNN 类型、组件和超参数。

[06]在上面的注释#02 中,吴恩达评论道,Coursera 已经检查了 MOOC 交互数据,以实现“教育本身的自动化”。

[07] Ng,“结论和感谢”视频,Coursera 课程“序列模型”,第 3 周。

[08] Chollet,《AI 让我担心什么》,2018 年 3 月 28 日。链接

如果您从这篇文章中受益,请支持 my Patreon 创建并指导小型经理同行小组,以探索由深度学习实现的分析系统的关键管理问题。如果同事对该计划感兴趣,请分享链接或推文。谢谢,理查德

深层潜在因素模型与反投影变分推理

原文:https://towardsdatascience.com/deep-latent-factor-models-and-variational-inference-with-backprop-89d4aae0fe34?source=collection_archive---------3-----------------------

Multivariate normally distributed factors generate the image together with complex f(.) function. (Just an illustration of a process)

我们周围的材料,我们正在目睹的过程和场合,我们拥有的数据集都是我们的观察结果,自然界中有生成模型,我们无法观察但可以生成这些观察结果。潜在因素模型从概率上描述了我们对观察结果生成过程的信念。今天的主题是深度潜在因素模型,这是一种试图用低维(希望是可解释的)因素解释高维复杂数据的统计模型。在深层潜在因素模型中,我们假设有一个复杂的函数,它接受很少的潜在因素作为输入,并生成我们观察到的复杂输出。

人们可能有各种动机去使用潜在因素模型。可解释性显然是其中之一。想象一下,我们找到了产生面部图像的可解释因素。我们有决定头发形状的因素,决定眼睛颜色的因素,以及决定性别的因素。如果我们有这些因素,我们将能够通过指定它们的一些属性来生成全新的面孔。你可能会说 GANs 也会产生新的看不见的面孔。但是记住 GANs 是从估计的概率分布中抽取样本,完全随机,GANs 中没有属性规范(至少据我所知是这样的。有大量的 GAN 模型,很难跟上人工智能的最新发展。打破维度的诅咒是另一个动机。如果数据的维数很大,并且我们想要训练分类模型,则需要学习的参数数量也很高,并且对于一个良好概括的模型来说需要大量数据。通过降低维度,我们还减少了参数的数量,因此学习所需的数据更少。降维对于可视化也很有用,尤其是当维度可以降到 2 或 3 的时候。这些只是使用潜在因素模型的少数动机。

快速提示:了解一些期望值最大化算法的知识是理解本文其余部分的先决条件。在毕晓普的《模式识别与机器学习》一书中可以找到见解清晰、数学优雅的精彩章节。

A general graphical representation of latent factor models. z represents latent variable vector. x is observation vector and there are N observations.

开始时,我们假设有模型参数θ,我们希望应用最大似然参数估计,即设置参数以使似然分布达到最大值。如果我们知道每个数据的 z 值,估计参数就相当容易了(更多信息,请看看我在 GLM 的文章)。记住,我们的任务之一是估计将 z 值映射到 x 值的参数。如果我们不知道 z 值,那怎么可能呢?EM 算法为我们提供了一种通过迭代应用期望和最大化步骤来实现它的方法。让我们通过定义目标来钻研数学

Maximum likelihood objective function where X and Z represent all the observations and latent variables respectively. Theta is model parameter(s).

不幸的是,由于需要求和的元素呈指数增长,上述目标包含难以处理的求和操作。为了克服这个问题,我们引入了一个 q(Z)项,并利用詹森不等式找到对数似然的一个下界。

Lower bound to log-likelihood which is a function of q and theta

寻找对数似然性下限背后的动机是,虽然我们不能直接评估对数似然性,但我们可以评估下限,以便我们可以获得关于对数似然性的信息。为此,我们重新排列了下界项,并把它写成对数似然项和一个附加散度项之和。

loglikelihood can be written as summation of Lower bound and reverse-KL divergence terms

KL 散度是一种非对称度量,度量两个概率分布之间的散度,当两个分布相同时,取 0 的值为最小值。正如你所看到的,当 KL 散度取最小值时,对数似然变得等于下限。因此,我们需要使 q(Z)等于 Z p(Z|X)的后部,以使 KL 散度为 0。让我们用 p(Z|X)代替 q(Z)重写 lower bound。

Changing the q(Z) terms with the posterior of Z which is calculated for the old theta parameters

现在,我们可以评估旧θ参数的对数似然值,它基本上等于旧θ的下限值。但是下限值可以通过优化θ值来增加。下限的第二项仅包括旧的θ参数,对于该部分没有任何作用。但是可以进一步优化第一部分,并且可以增加下界的值。这也意味着对数似然性可以通过估计新的θ值来进一步增加。当你仔细观察第一部分时,你会发现它是一个期望项,对这个期望项求值就形成了 EM 算法的 E 部分。E 步包含了 Z 的后验的推断,所以我们可以用推断步来重命名 E 步。通过估计新的模型参数来最大化下界,这叫 M 步,但我觉得叫学习步没有错。考虑到文章接下来的部分,我倾向于重命名 E 和 M 步骤。

E and M steps

寻找潜在因素的后验并不总是容易的,尤其是当我们处理复杂的模型时。这一次,我们不是精确地计算后验概率,而是用一个具有可变参数φ的建议分布 q(z)来逼近它。在这种情况下,我们假设没有模型参数。

We assume there are no model parameters theta, and we approximate to p(Z|X) by tuning variational parameters phi.

在这种情况下,对数似然是常数,不随 q 和 phi 的选择而变化,但我们不能直接评估它。我们需要做的是巧妙地选择一个变分分布 q(我们试图选择一个与 z 的后验分布尽可能相似的分布族)并优化它的参数φ,以便减小原始后验分布和建议分布之间的 KL 散度。换句话说,我们通过调整输入 q 和 phi 来逼近具有下限的对数似然。寻找函数 q 是变分法的主题,但是对于完全分解的 q(平均场近似),q 的形式是已知的(更多信息请看 Bishop 的书)。这个过程被称为变分贝叶斯。

在下一部分,我们将深入到深层潜在因素模型的变分推理的细节,我将介绍著名的变分自动编码器。在这之前,我们将重新安排一下下限方程。

Rearranging lower bound equation

如果模型也有参数呢?然后下界变成 q,theta,和 phi 的函数。

Lower bound is the function of q, theta, phi

为了使问题更简单,我们可以通过考虑共轭性来仔细设计模型,并使用全分解的 q 函数来不优化关于 q 的目标函数。因此,下界需要关于模型参数θ和变分参数φ进行优化。模型参数的估计就是 e M 算法的 M 步。另一方面,变分参数估计与寻找潜在变量的后验有关,因此它是一个推理步骤,构成了 EM 算法的 E 步骤。我们称这个全过程为变分 EM。

现在考虑一个具有高斯似然的复杂模型,其中均值和协方差是接受潜在因子 z 作为输入的神经网络。我们还将潜在因素的先验分布定义如下。

A complex generative model

用经典的变分推理方法很难对如此复杂的模型做出有效的推理。变分推理的最新进展使我们能够在这些复杂的模型中进行推理。在上面的模型中,我们想要估计的模型参数(θ)只不过是神经网络的权重。

对于推理,我们将高斯分布指定为变分分布族,但这次我们定义了神经网络结构,该结构将观察值映射到变分分布的均值和协方差(我们可能不喜欢使用观察和推理网络,但在可能的情况下使用它们是明智的)。所以变分 EM 部分的目标变成了

Lower bound for stochastic training

Inference network

有趣的是,观察到每个潜在特征(z_i)都有它自己的变分参数(均值和协方差矩阵),但是这些参数是由作为推理网络权重的观测值(x_i)和全局变分参数(phi)产生的。

深度学习社会更喜欢使用损失函数作为目标,因此我们可以最小化它的负值,而不是最大化下界。

Loss function

损失函数定义了一个自动编码器,因为它的第一项试图重建涉及解码器的观测值,而第二项通过试图使观测值尽可能接近先验值来将观测值编码成潜在表示。

KL divergence between two multivariate Gaussians

损失函数的第二项是两个多元高斯函数之间的 KL 散度,我们知道它的形式。该表达式取决于变分参数φ,并且该项将随着随机梯度下降而相对于φ进行优化。

Monte Carlo integration to estimate expectation

第一项是一个期望值,我们可以用蒙特卡罗积分来估计它,而不是用解析方法计算(我们不能)。这里的问题是,在从 q(z|x)采样 z 之后,我们失去了与变分参数的所有联系,并且不能优化 w.r.t .变分参数项,尽管该项依赖于它们。重新参数化技巧是克服这个问题的好方法。

Reparametrization trick

在重新参数化技巧中,我们将样本 z 写成具有参数μ和适马的确定性函数的输出,输入ε是来自零均值单位方差正态分布的样本。现在我们可以用链式法则(dE/dz * dz/dphi)优化 w.r.t .变分参数项。

在这篇文章中,我试图从众所周知的 EM 算法开始解释变分自动编码器的基本思想。有趣的是,通过在目标函数中引入具有小更新的推理网络,我们得到了一种特殊类型的正则化自动编码器,这使得我们能够运行具有反向传播算法的变分 EM 的 E 和 M 步骤。

参考

金玛、迪德里克·p 和马克斯·韦林。“自动编码变分贝叶斯” arXiv 预印本 arXiv:1312.6114 (2013)。

毕晓普的模式识别和机器学习书

EM 和变分推理

深度学习#1:设置 AWS 和图像识别

原文:https://towardsdatascience.com/deep-learning-1-1a7e7d9e3c07?source=collection_archive---------0-----------------------

这篇文章是深度学习系列文章的一部分。检出部分 2 此处 和部分 3 此处

This week: classifying images of cats and dogs

欢迎来到这个实用深度学习系列的第一篇文章。在这个条目中,我将设置 Amazon Web Services (AWS)实例,并使用一个预先训练好的模型对猫和狗的图像进行分类。

在这个完整的系列中,我将在博客中记录我在快速人工智能深度学习课程的第一部分中的过程。这门课程最初是在旧金山大学的数据学院开设的,现在作为 MOOC 开放。最近作者给出了课程的第二部分,将在几个月后在网上提供。学习这门课程的主要原因是我对深度学习的极大兴趣。我发现了许多关于机器学习的在线资源,但关于深度学习的实用课程似乎很少。深度学习似乎是一个排他性的群体,只是更难进入而已。开始深度学习首先需要的是一个 GPU。在本课程中,我们使用 AWS 中的 p2 实例。让我们开始吧。

这门课的第一周主要是设置。让你的深度学习设置正确可能需要一段时间,重要的是让一切正常工作。这包括设置 AWS、创建和配置 GPU 实例、设置 ssh-ing 到服务器的过程以及管理您的目录。

我在实习笔记本电脑上遇到了一些权限问题。让我给你一个建议,可以节省很多时间来绕过它:在尝试这样做之前,确保你在你的笔记本电脑上有完全的管理员权限。一些可爱的工程师提出为我设置 GPU 实例,但他们没有时间很快完成。所以我决定亲自动手。

设置 AWS 实例的脚本是用 bash 编写的。如果你在一台 Windows 机器上工作,你将需要一个能处理这个的程序。我用的是 Cygwin。我想分享一些我在安装过程中遇到的问题(及其解决方案)。如果你没有跟随快速人工智能课程,只是跟着阅读,你可以跳过这一步。我在安装过程中遇到的一些问题是:

  • bash 脚本抛出一个错误

我读过一些对此可能的解释,但没有一个明确的解决方案对我有效。Github 上的课程设置脚本现在分为两个脚本:setup_p2.sh 和 setup_instance.sh。如果您无法使用这两个脚本,您可以使用这个脚本来设置您的 p2 实例。如果脚本不运行,请确保也尝试原始版本。

我在 aws-alias.sh 脚本中遇到了类似的问题。在第 7 行末尾添加一个'修复了这个问题。下面是第 7 行的前后一段:

alias aws-state='aws ec2 describe-instances --instance-ids $instanceId --query "Reservations[0].Instances[0].State.Name"

alias aws-state='aws ec2 describe-instances --instance-ids $instanceId --query "Reservations[0].Instances[0].State.Name"'

这里是给不熟悉 Bash 的大家看的 Bash 小抄。我强烈推荐这样做,因为您将需要 Bash 来与您的实例进行交互。

  • 巨蟒装置。视频中提到要先安装 Anaconda 再安装 Cygwin。这可能有点令人困惑,因为您需要使用“Cygwin python”在那里运行 pip 命令,而不是本地 Anaconda 发行版。

此外,这个存储库有一个很好的让实例运行的分步指南。

深度学习入门

经过一些问题,我让我的 GPU 实例运行。是时候开始深度学习了!一个简短的声明:在这些博客中,我不会重复课堂笔记中列出的内容,没有必要。我将强调一些我发现非常有趣的事情,以及我在课程中遇到的问题和想法。

让我们从你可能想到的第一个问题开始:什么是深度学习,为什么它现在会受到如此大肆宣传?

深度学习只是一个具有多个隐藏层的人工神经网络,这使它们变得“深”。一般的神经网络只有一个,也许两个隐藏层。深度神经网络有更多的隐藏层。与普通神经网络中的“简单”层相比,它们还具有不同类型的层。

(Shallow) Neural Network

目前,深度学习在众所周知的数据集上一直表现出色。因此,深度学习已经经历了很多炒作。深度学习的流行有三个原因:

  • 无限灵活的功能
  • 通用参数拟合
  • 快速且可扩展

神经网络是模仿人脑的。根据通用逼近定理,它理论上可以求解任何函数。通过反向传播来训练神经网络,这允许我们将模型的参数拟合到所有这些不同的函数。最后一个原因是最近在深度学习方面取得成就的主要原因。由于游戏行业的进步和强大 GPU 的发展,现在有可能以快速和可扩展的方式训练深度神经网络。

在第一课中,我们的目标是使用一个预先训练好的模型,即 Vgg16 来对猫和狗的图像进行分类。Vgg16 是 2014 年赢得 Imagenet 挑战赛的车型的轻量版。这是一年一度的挑战,也可能是计算机视觉领域最大的挑战。我们可以将这个预先训练好的模型应用到我们的猫和狗图像数据集上。我们的数据集已经由本课程的作者编辑过,以确保其格式适合我们的模型。原始数据集可以在 Kaggle 上找到。当这项比赛最初在 2013 年举办时,最先进的技术是 80%的准确性。我们的简单模型已经达到了 97%的准确率。令人震惊吧。这是一些图片及其预测标签的外观:

Predicted labels for dogs and cats

目标标签是使用一种称为“一键编码”的过程设置的,这种过程通常用于分类变量。[1.0.]指一只猫和[0。1.]指的是狗。我们创建了一个包含两个值的数组,而不是一个名为“target”的变量包含两个级别 0 和 1。你可以把这些变量看成‘猫’和‘狗’。如果变量为真,则标记为 1,否则标记为 0。在多分类问题中,这可能意味着您的输出向量如下所示:[0 0 0 0 0 0 0 0 1 0 0 0]。在这种情况下,Vgg16 模型输出图像属于类别“猫”的概率和图像属于类别“狗”的概率。下一个挑战是调整这个模型,以便我们可以将它应用到另一个数据集。

狗和猫的对决

本质上,这是与前一个相同的数据集,但是课程作者没有对其进行预处理。Kaggle 命令行界面(CLI)提供了一种快速下载数据集的方法。它可以通过 pip 安装。美元符号通常用于表示命令正在终端中运行。

$ pip install kaggle-cli

训练集包含 25000 张狗和猫的标记图像,而测试集包含 12500 张未标记图像。为了微调参数,我们还通过选取训练集的一小部分来创建验证集。建立完整数据集的“样本”也很有用,您可以使用它来快速检查您的模型在构建过程中是否正常工作。

为了运行我们的模型,我们使用 Keras 库。这个库位于流行的深度学习库 Theano 和 TensorFlow 之上。Keras 基本上使你的网络编码更加直观。这意味着您可以更多地关注网络的结构,更少地担心 TensorFlow API。为了知道哪张图片属于哪个类,Keras 查看它存储的目录。因此,确保将图像移动到正确的目录是很重要的。完成这项工作所需的 bash 命令可以直接从 Jupyter 笔记本上运行,我们在那里编写所有代码。此链接包含这些命令的附加信息。

在我的 Amazon p2 实例上,一个 epoch(完整遍历数据集)需要 10 分钟。在这种情况下,该数据集是由 23.000 幅图像组成的训练集。其他 2000 幅图像在验证集中。我决定在这里使用 3 个纪元。验证集的准确率在 98%左右。训练完模型后,我们可以看看一些正确分类的图像。在这种情况下,我们使用图像是一只猫的概率。1.0 表示图像是猫的完全置信度,0.0 表示图像是狗的完全置信度。

Correctly classified images

现在让我们来看看一些被错误分类的图片。正如我们所看到的,大部分都是从很远的地方拍摄的,以多种动物为特色。最初的 Vgg 模型用于图像,其中目标类的一个东西在图片中清晰可见。只有我一个人觉得第四张图有点恐怖吗?

Incorrectly classified images

最后,这些是模型最不确定的图像。这意味着概率最接近 0.5(其中 1 是猫,0 是狗)。第四张照片是一只猫,只有脸是可见的。第一个和第三个图片是矩形的,而不是像原始模型被训练的图片那样是方形的。

Images where the model is most uncertain

这就是这周的内容。就我个人而言,我迫不及待地想开始学习第 2 课,了解更多关于模型的内部知识。希望我们也能从零开始用 Keras 建立一个模型!

另外,感谢所有更新 Github 脚本的人。帮了大忙!再次感谢 Fast AI 论坛上的所有人,你们太棒了。

如果你喜欢这篇文章,一定要推荐给别人看。你也可以按照这个简介来跟上我在快速人工智能课程中的进程。那里见!

我目前是一名微型公司的数据科学家。我们正在努力寻找数据工程师和软件工程师。我们也在为自己和我们的合作伙伴招募数据科学家,这些合作伙伴包括荷兰、以色列的一些最大的组织和一些大型全球公司!

通过 LinkedIn 联系我,加入我们在阿姆斯特丹或特拉维夫的团队,或者让我帮助您加入我们遍布全球的合作伙伴组织!

深度学习#2:卷积神经网络

原文:https://towardsdatascience.com/deep-learning-2-f81ebe632d5c?source=collection_archive---------0-----------------------

CNN 怎么学,学什么?

这篇文章是深度学习系列文章的一部分。检出部分 1 此处 和部分 3 此处

本周我们将探索卷积神经网络(CNN)的内部工作原理。你可能想知道这些网络内部发生了什么?他们是如何学习的?

我所学课程背后的教学理念是基于自上而下的方法。基本上,我们马上就可以玩完整的模型,随着我们的进行,我们对它的内部运作了解得越来越多。因此,这些博客文章将逐渐深入神经网络的内部工作。这只是第 2 周,所以我们开始朝着这个目标前进。

上周,我在猫和狗的图像数据集上训练了 Vgg16 模型。我想首先说明为什么使用预先训练的模型是一个好方法。为了做到这一点,思考这些模型正在学习什么是很重要的。实质上,CNN 正在学习过滤器,并将它们应用于图像。这些滤镜与你应用于 Instagram 自拍的滤镜不同,但概念并没有太大的不同。CNN 拿起一个小方块,开始在图像上应用,这个方块通常被称为“窗口”。然后,网络寻找该过滤器匹配图像内容的图像部分。在第一层,网络可能会学习一些简单的东西,比如对角线。在每一层中,网络能够结合这些发现,并不断学习更复杂的概念。这听起来仍然很模糊,所以让我们看一些例子。泽勒和弗格斯(2013) 在视觉化 CNN 所学方面做得很好。这是他们在论文中使用的 CNN。赢得 Imagenet 竞赛的 Vgg16 型号就是基于这种型号。

CNN by Zeiler & Fergus (2013)

这张图片现在可能看起来很混乱,不要惊慌!先说一些我们都能从这张图中看到的东西。首先,输入图像是 224x224 像素的正方形。我之前说的滤镜是 7x7 像素。该模型有一个输入层、7 个隐藏层和一个输出层。输出层中的 c 是指模型将预测的类的数量。现在让我们来看看最有趣的东西:模型在不同的层中学到了什么!

Layer 2 of the CNN. The left image represents what the CNN has learned and the right image has parts of actual images.

在 CNN 的第二层,这个模型已经获得了比对角线更有趣的形状。在第六个方块(水平计数)中,您可以看到模型正在拾取圆形。还有,最后一个方块在看角落。

Layer 3 of the CNN

在第 3 层中,我们可以看到模型开始学习更具体的东西。第一个方块显示模型现在能够识别地理模式。第六个方块是识别汽车轮胎。而第十一个方块是认人。

Layers 4 and 5 of the CNN

最后,第 4 层和第 5 层延续了这一趋势。第五层是挑选对我们的猫狗问题非常有用的东西。它还识别独轮车和鸟类/爬行动物的眼睛。请注意,这些图像只显示了每一层所学知识的很小一部分。

希望这能告诉你为什么使用预先训练的模型是有用的。如果你想了解这个研究领域的更多信息,你可以查阅“迁移学习”。Vgg16 模型已经知道很多关于识别狗和猫的知识了。针对猫狗问题的训练集只有 25000 张图片。新模型可能无法从这些图像中学习所有这些特征。通过一个称为微调的过程,我们可以改变 Vgg16 模型的最后一层,这样它就不会输出 1000 个类别的概率,而只输出 2 个类别(猫和狗)的概率。

如果你有兴趣阅读更多关于深度学习背后的数学知识,斯坦福的 CNN 网页提供了一个很好的资源。他们还称浅层神经网络为“数学上的可爱”,这是第一次。

微调和线性层

我上周用来分类猫和狗的预先训练好的 Vgg16 模型并不自然地输出这两个类别。它实际上产生了 1000 个类。此外,该模型甚至不输出“猫和狗”类,但它输出特定品种的猫和狗。那么,我们如何有效地改变这个模型,只将图像分类为猫或狗呢?

一种选择是手动将这些品种映射到猫和狗,并计算概率。但是,这种方法忽略了一些关键信息。例如,如果图片中有一根骨头,则该图像可能是一只狗。但是如果我们只看每个品种的概率,这些信息就会丢失。在那里,我们替换了模型末端的线性(密集)层,并用一个只输出 2 个类的层来替换它。Vgg16 模型实际上在末端有 3 个线性层。我们可以微调所有这些层,并通过反向传播来训练它们。反向传播通常被视为某种抽象的魔法,但它只是使用链式法则计算梯度。你永远不必担心数学的细节。TensorFlow、Theano 和其他深度学习库会帮你做到这一点。

如果你正在浏览快速人工智能课程第二课的笔记本,请注意内存问题。我建议您首先仅使用示例图像运行笔记本。如果您使用的是 p2 实例,如果您一直保存和加载 numpy 数组,您可能会耗尽内存。

激活功能

我们刚刚讨论了网络末端的线性层。然而,神经网络中的所有层都不是线性的。在计算了神经网络中每个神经元的值之后,我们将这些值通过一个激活函数。人工神经网络基本上由矩阵乘法组成。如果我们只使用线性计算,我们可以把它们堆叠起来。这不会是一个非常深的网络…因此,我们经常在网络的每一层使用非线性激活函数。通过将线性和非线性函数层层叠加,理论上我们可以模拟任何东西。这是三种最流行的非线性激活函数:

  • Sigmoid (解析一个介于 0 和 1 之间的值)
  • TanH (解析一个介于-1 和 1 之间的值)
  • ReLu (如果值为负,则变为 0,否则保持不变)

Three most used activation functions: Sigmoid, Tanh & Rectified Linear Unit (ReLu)

目前,ReLu 是最常用的非线性激活函数。这样做的主要原因是它减少了消失梯度和稀疏性的可能性。我们将在后面更详细地讨论这些原因。模型的最后一层一般使用不同的激活函数,因为我们希望这一层有一定的输出。softmax 函数在做分类的时候很受欢迎。

在微调 Vgg16 模型中的最后层之后,该模型具有 138.357.544 个参数。谢天谢地,我们没有手动计算所有的梯度:)。下周我将深入 CNN 的工作,我们将讨论适配不足和适配过度。

如果你喜欢这篇文章,一定要推荐给别人看。你也可以按照这个简介来跟上我在快速人工智能课程中的进程。那里见!

我目前是一名微型公司的数据科学家。我们正在努力寻找数据工程师和软件工程师。我们也在为自己和我们的合作伙伴招募数据科学家,这些合作伙伴包括荷兰、以色列的一些最大的组织和一些大型全球公司!

请通过 LinkedIn联系我,加入我们在阿姆斯特丹或特拉维夫的团队,或者让我帮助您加入我们遍布全球的合作伙伴组织!

深度学习#3:更多关于 CNNs &处理过度拟合

原文:https://towardsdatascience.com/deep-learning-3-more-on-cnns-handling-overfitting-2bd5d99abe5d?source=collection_archive---------0-----------------------

什么是卷积,最大池和辍学?

这篇文章是深度学习系列文章的一部分。退房 第一部分 第二部分

Data augmentation is one of the techniques for reducing overfitting

欢迎来到深度学习系列的第三篇文章!本周我将探索卷积神经网络(CNN)的更多部分,还将讨论如何处理欠拟合和过拟合。

卷积

那么卷积到底是什么呢?你可能记得我以前的博客文章,我们基本上采取了一个小过滤器,并在整个图像上滑动这个过滤器。接下来,图像的像素值与过滤器中的像素值相乘。使用深度学习的好处在于,我们不必考虑这些过滤器应该是什么样子。通过随机梯度下降(SGD ),网络能够学习最优滤波器。过滤器是随机初始化的,并且是位置不变的。这意味着他们可以在图像的任何地方找到一些东西。同时,模型也知道它在图像中的什么地方找到了这个东西。

应用此过滤器时,零填充是一个有用的工具。所有这些都是在图像周围零像素的额外边界上完成的。这使得我们在图像上滑动滤镜时也可以捕捉图像的边缘。你可能想知道过滤器应该有多大。研究表明,较小的过滤器通常表现更好。在这种情况下,我们使用大小为 3x3 的过滤器。

当我们将这些滤镜滑过我们的图像时,我们基本上创建了另一个图像。因此,如果我们的原始图像是 30×30,则具有 12 个滤波器的卷积层的输出将是 30×30×12。现在我们有一个张量,它基本上是一个二维矩阵。现在你也知道 TensorFlow 这个名字的由来了。

在每个卷积层(或多层)之后,我们通常有一个最大池层。这一层只是减少了图像中的像素数量。例如,我们可以取一个正方形的图像,并用正方形上的最高值来替换它。

Max Pooling

由于 Max Poling,我们的过滤器可以探索图像的更大部分。此外,由于像素的损失,我们通常会在使用最大池后增加过滤器的数量。

从理论上讲,每个模型架构都是可行的,应该能够为您的问题提供一个好的解决方案。然而,有些架构比其他架构做得快得多。一个非常糟糕的架构可能需要比你剩余的年数更长的训练…因此,考虑你的模型的架构以及为什么我们使用像 max pooling 这样的东西并改变所使用的过滤器的数量是有用的。为了结束 CNN 的这一部分,这个页面提供了一个很棒的视频,它可视化了 CNN 内部发生的事情。

欠拟合与过拟合

你如何知道你的模型是否不合适?如果验证集的准确性高于训练集的准确性,则您的模型不符合要求。此外,如果整个模型表现不佳,这也称为欠拟合。例如,使用线性模型进行图像识别通常会导致模型欠拟合。或者,当你的深层神经网络出现不适应时,这可能是由辍学引起的。在训练过程中,Dropout 随机将激活设置为零,以避免过度拟合。在对验证/测试集进行预测的过程中,这不会发生。如果是这种情况,您可以删除辍学。如果模型现在过度拟合,你可以开始增加小块的辍学。

一般规则是:从过度拟合模型开始,然后采取措施防止过度拟合。

当您的模型太适合训练集时,就会发生过度拟合。然后,模型就很难归纳出不在训练集中的新示例。例如,您的模型识别训练集中的特定图像,而不是一般模式。您的训练准确度将高于验证/测试集的准确度。那么我们能做些什么来减少过度拟合呢?

减少过拟合的步骤:

  1. 添加更多数据
  2. 使用数据扩充
  3. 使用通用的架构
  4. 添加正规化(主要是辍学,L1/L2 正规化也是可能的)
  5. 降低架构复杂性。

第一步当然是收集更多的数据。但是,在大多数情况下,您将无法。让我们假设你已经收集了所有的数据。下一步是数据扩充:总是推荐使用的东西。

数据扩充包括像随机旋转图像、放大、添加滤色器等。数据扩充只发生在训练集,而不发生在验证/测试集。检查您是否使用了过多的数据扩充会很有用。例如,如果你放大得太多以至于猫的特征不再可见,那么模型不会因为这些图像的训练而变得更好。让我们探索一些数据增强!

对于 Fast AI 课程的追随者:请注意,笔记本使用“width_zoom_range”作为数据增强参数之一。但是,该选项在 Keras 中不再可用。

Original image

现在让我们看看执行数据增强后的图像。所有的“猫”对我来说仍然清晰可辨。

Augmented cats

第三步是使用一个通用的架构。然而,更重要的是第四步:添加正则化。三个最受欢迎的选项是:辍学,L1 正则化和 L2 正则化。在深度学习中,你通常会看到辍学,这是我之前讨论过的。Dropout 删除训练中激活的随机样本(使其为零)。在 Vgg 模型中,这仅适用于模型末端完全连接的层。然而,它也可以应用于卷积层。请注意,辍学会导致信息丢失。如果你在第一层丢失了一些东西,那么整个网络都会丢失。因此,好的做法是从第一层的低压差开始,然后逐渐增加。第五个也是最后一个选择是降低网络复杂性。实际上,在大多数情况下,各种形式的正则化应该足以处理过度拟合。

Visualization of dropout

批量正常化

最后,我们来讨论一下批量规范化。这是你应该经常做的事情!批处理规范化是一个相对较新的概念,因此还没有在 Vgg 模型中实现。

如果你对机器学习感兴趣,标准化你的模型的输入是你一定听说过的事情。批处理规范化更进了一步。批量标准化在每个卷积层后添加一个“标准化层”。这允许模型在训练中收敛得更快,因此也允许您使用更高的学习速率。

简单地标准化每个激活层中的权重是行不通的。随机梯度下降非常顽固。如果想使其中一个权重很高,它会在下一次简单地这样做。通过批量标准化,模型了解到它可以调整所有权重,而不是每次只调整一个。

MNIST 数字识别

MNIST 手写数字数据集是机器学习中最著名的数据集之一。该数据集也是一个很好的方式来实验我们现在所知道的关于 CNN 的一切。Kaggle 也托管 MNIST 数据集。我快速编写的这段代码是在这个数据集上获得 96.8%准确率所必需的。

import pandas as pd
from sklearn.ensemble import RandomForestClassifiertrain = pd.read_csv('train_digits.csv')
test = pd.read_csv('test_digits.csv')X = train.drop('label', axis=1)
y = train['label']rfc = RandomForestClassifier(n_estimators=300)
pred = rfc.fit(X, y).predict(test)

深度学习#4:为什么你需要开始使用嵌入层

原文:https://towardsdatascience.com/deep-learning-4-embedding-layers-f9a02d55ac12?source=collection_archive---------0-----------------------

以及它不仅仅是单词嵌入。

这篇文章是深度学习系列文章的一部分。在这里检查其他部分:

  1. 设置 AWS &图像识别
  2. 卷积神经网络
  3. 更多关于 CNN&处理过度拟合的信息

欢迎来到深度学习系列的第 4 部分。你可能已经注意到,前三篇文章和这篇文章之间有一点延迟。这个系列最初的目标是与深度学习的 fast.ai 课程一起写作。然而,后面讲座的概念经常重叠,所以我决定先完成课程。通过这种方式,我可以更详细地概述这些主题。在这篇博客中,我想介绍一个概念,它跨越了课程(4-6)的多个讲座,并且在实践中证明对我非常有用:嵌入层。

在介绍时,嵌入层的概念可能是非常陌生的。例如,Keras 文档除了“将正整数(索引)转化为固定大小的密集向量”之外,没有提供任何解释。快速的谷歌搜索可能也不会让你走得更远,因为这些类型的文档是首先弹出的东西。然而,在某种意义上,Keras 的文档描述了所有发生的事情。那么,为什么要使用嵌入层呢?这里有两个主要原因:

  1. 独热编码矢量是高维稀疏的。假设我们在做自然语言处理(NLP),有一个 2000 字的字典。这意味着,当使用一键编码时,每个单词将由一个包含 2000 个整数的向量来表示。并且这些整数中的 1999 个是零。在大型数据集中,这种方法计算效率不高。
  2. 每次嵌入的向量在训练神经网络时得到更新。如果你看过这篇文章顶部的图片,你就会明白如何在多维空间中找到单词之间的相似之处。这使我们可以可视化单词之间的关系,也可以通过嵌入层将一切转化为矢量。

这个概念可能还是有点模糊。让我们用一个单词的例子来看看嵌入层是做什么的。然而,嵌入的起源来自于词的嵌入。有兴趣了解更多可以查一下 word2vec 。让我们以这句话为例(不要当真):

“深度学习很深”

使用嵌入层的第一步是通过索引对这个句子进行编码。在这种情况下,我们为每个唯一的单词分配一个索引。句子看起来是这样的:

1 2 3 4 1

接下来创建嵌入矩阵。我们决定给每个指数分配多少“潜在因素”。基本上这意味着我们希望向量有多长。一般的用例是 32 和 50 这样的长度。让我们在这篇文章中为每个指数分配 6 个潜在因素,以保持可读性。嵌入矩阵看起来像这样:

Embedding Matrix

因此,我们可以使用嵌入矩阵来保持每个向量的大小更小,而不是以巨大的独热编码向量结束。简而言之,所有发生的事情就是单词“deep”由一个向量[.32、. 02、. 48、. 21、. 56、. 15]表示。然而,并不是每个单词都被向量所取代。相反,它被用于在嵌入矩阵中查找向量的索引所取代。同样,当使用非常大的数据集时,这在计算上是高效的。因为嵌入的向量也在深度神经网络的训练过程中得到更新,所以我们可以在多维空间中探索哪些单词是彼此相似的。通过使用像 t-SNE 这样的降维技术,这些相似性可以被可视化。

t-SNE visualization of word embeddings

不仅仅是单词嵌入

这些前面的例子表明,单词嵌入在自然语言处理领域非常重要。它们让我们能够捕捉语言中的关系,否则很难捕捉。然而,嵌入层可以用来嵌入更多的东西,而不仅仅是文字。在我目前的研究项目中,我使用嵌入层来嵌入在线用户行为。在这种情况下,我为用户行为分配指数,如“门户 Y 上页面类型 X 的页面视图”或“滚动 X 像素”。这些指数然后被用于构建用户行为序列。

在“传统”机器学习模型(SVM、随机森林、梯度增强树)与深度学习模型(深度神经网络、递归神经网络)的比较中,我发现这种嵌入方法对深度神经网络非常有效。

“传统的”机器学习模型依赖于特征工程的表格输入。这意味着,作为研究人员,我们决定什么会变成一个特征。在这些情况下,特征可以是:访问的主页数量,完成的搜索数量,滚动的像素总量。然而,在进行特征工程时,很难捕捉空间(时间)维度。通过使用深度学习和嵌入层,我们可以通过提供一系列用户行为(作为索引)作为模型的输入来有效地捕捉这个空间维度。

在我的研究中,具有门控循环单元/长短期记忆的循环神经网络表现最好。结果非常接近。从“传统”特征工程模型来看,梯度增强树表现最好。以后我会写一篇关于这项研究的更详细的博文。我想我的下一篇博文将更详细地探索递归神经网络。

其他研究探索了使用嵌入层来编码 MOOCs 中的学生行为(皮赫等人,2016 年)和用户通过在线时装商店的路径(塔姆哈尼等人,2017 年)。

推荐系统

嵌入层甚至可以用来处理推荐系统中的稀疏矩阵问题。由于深度学习课程(fast.ai)使用推荐系统来引入嵌入层,所以我也想在这里探索它们。

推荐系统到处都在使用,你可能每天都受到它们的影响。最常见的例子是亚马逊的产品推荐和网飞的节目推荐系统。实际上,网飞举办了一场 100 万美元的挑战赛,为他们的推荐系统寻找最佳的协同过滤算法。你可以在这里看到这些模型中的一个。

有两种主要类型的推荐系统,区分这两种是很重要的。

  1. 基于内容的过滤。这种类型的过滤基于关于项目/产品的数据。例如,我们让用户填写一份关于他们喜欢什么电影的调查。如果他们说他们喜欢科幻电影,我们会向他们推荐科幻电影。在这种情况下,所有项目都必须有大量的元信息。
  2. 协同过滤:让我们找到和你一样的人,看看他们喜欢什么,然后假设你也喜欢同样的东西。像你这样的人=对你看过的电影评价相似的人。在大型数据集中,这已被证明比元数据方法好得多。从本质上讲,询问人们的行为不如观察他们的实际行为好。进一步讨论这个问题是我们当中的心理学家的事情。

为了解决这个问题,我们可以创建一个所有用户对所有电影的评级的巨大矩阵。然而,在许多情况下,这将创建一个极其稀疏的矩阵。想想你在网飞的账户。你看过的连续剧和电影占他们总供应量的百分比是多少?这可能是一个很小的百分比。然后,通过梯度下降,我们可以训练一个神经网络来预测每个用户对每部电影的评价有多高。如果你想知道更多关于深度学习在推荐系统中的使用,请告诉我,我们可以一起进一步探索。总之,嵌入层是惊人的,不应该被忽视。

如果你喜欢这篇文章,一定要推荐给别人看。你也可以按照这个简介来跟上我在快速人工智能课程中的进程。那里见!

参考

c .、Bassen、j .、Huang、j .、Ganguli、s .、Sahami、m .、Guibas、L. J .、& Sohl-Dickstein,J. (2015 年)。深度知识溯源。神经信息处理系统进展(第 505-513 页)。

塔哈内,a .,阿罗拉,s .,&瓦里耶,D. (2017 年 5 月)。对时尚电子商务中用户行为的情境变化进行建模。亚太知识发现和数据挖掘会议(第 539-550 页)。斯普林格,查姆。

深度学习是 Monty Hall 策略(或者,用 PyTorch 温和地介绍 Deep-Q 学习和 OpenAI 健身房)

原文:https://towardsdatascience.com/deep-learning-a-monty-hall-strategy-or-a-gentle-introduction-to-deep-q-learning-and-openai-gym-d66918ac5b26?source=collection_archive---------4-----------------------

你永远不知道一系列事件会如何影响你。

对我来说,暴饮暴食布鲁克林 99 旧集,结合 Tensorflow 最近宣布他们已经正式纳入爱德华概率编程库,让我在一段时间内第一次思考贝叶斯概率。

在这一集里,霍尔特上尉和他的丈夫在争论蒙蒂·霍尔的问题。

One of TV’s best characters, Captain Holt in Fox’s (now NBC’s!) Brooklyn 99. A rare show of emotion for AI here.

我不熟悉旧游戏,但问题的表述是这样的:

有三扇门,一扇门后是一辆汽车,另外两扇门后是山羊。选一个。一旦你选择了,gameshow 主持人 Monty 将会打开你没有选择的两扇门中的一扇门——一扇绝对没有汽车在后面的门。你应该坚持你最初的猜测,还是换到两扇门中的另一扇门?

This article assumes you want to win the car, not the Greatest Of All Time

很明显,每扇门都有 1/3 的胜算,这一点在蒙蒂打开一扇门后并没有改变。贝叶斯先验为【1/3,1/3,1/3】。然而,一旦失败的大门被打开,就会有新的信息出现,概率应该被重新检查。事实上,汽车在未选择的门后面的概率现在“集中”到 2/3,吸收了蒙蒂打开的哑门的概率。即后验为【1/3,0,2/3】。因此,你不太可能总是赢,但是通过切换到你最初没有选择的未打开的门,你的机会增加了一倍。

这是这个博弈的优势策略。

如果你想直接跳到本文附带的相对简单的 Jupyter 笔记本,这里是。

我过去与人工智能有关的大部分工作都是回归一点生成性的东西,我已经远离了标题制作技术:人工智能自学玩末日游戏人工智能现在比人类更擅长围棋,人工智能自动驾驶汽车自组织成汽车人和霸天虎等等。因为这个,我也没有机会玩开 AI 健身房。事实证明,两者都很容易使用,我认为它们应该在每个人的深度学习工具箱中占有一席之地。

像往常一样,我会省去大部分的数学。深度 Q 学习涉及到一些内容,尽管这并不复杂,但我可以从我的论文工作中告诉你,随机的实际实现是第一位的,数学是一个很好的事后完整性证明,使你能够写一篇严肃的论文。直觉很重要。

在这篇文章中,我实际上并不打算讨论可训练分布和 Tensorflow 的 Edward,而是展示如何构建一个简单的、可扩展的代理来解决一个博弈论类型的问题,该问题可以与当今前沿的人工智能环境进行交互。

开放 AI 健身房

让我们先解决这个问题。健身房没有任何魔力,只是一套良好的标准化环境,在其中测试自主 AI 代理,模拟他们的行为对环境的影响。只需通过pip install gym安装,在 Jupyter 笔记本内部就能轻松使用。

健身房附带的一个非常简单的环境叫做 CartPole,它看起来像这样:

杆子通过枢轴连接到轨道上的手推车上,手推车的目标是保持杆子直立——想象一下试图在手掌上平衡一支笔。

环境模拟力和重力,环境的动作空间是推车可以被向左或向右推(轨道是无摩擦的,所以任何推动都会增加推车的速度,然后它会继续以那个速度前进)。当杆子越过一个无法返回的角度时,游戏结束。

动作空间定义了人工智能(我假设它是一个神经网络)输出的维度;每个时刻都有两种可能的行动。因此,您可能有一个输出神经元,其中输出> 0 被解释为向右推,而≤ 0 被解释为向左推。更有可能的是,你可能有两个神经元对应左右,取其中的 argmax

相反,环境的观察空间形成了对人工智能的输入。任何试图求解 CartPole 的人工智能都有四个输入:代表速度和角度的浮点数。

通常当你听到 Open AI Gym 被提及时,人们会谈论 Atari 游戏:动作空间将是游戏手柄上的按钮,观察空间将是小行星游戏中屏幕上的像素。在这里,我正在解决一个简单的博弈论问题,但以一种与健身房兼容(即子类化)的标准化方式。

在典型的 PyTorch 训练循环中使用健身房看起来像这样:

import gym
env = gym.make("CartPole-v0")
model = MyAI()
optimizer = torch.optim.Adam(model.parameters())
env.reset()for frame in range(0, 6000): # frames of the game to play out
  action = model.act(state, epsilon)
  next_state, reward, done, _ = env.step(action)
  replay_buffer.append(state, action, reward, next_state, done)
  state = next_state
  env.render()
  if done:
    env.reset()
  if len(replay_buffer) > batch_size: # won or died
    loss = calc_loss_over_episode(replay_buffer)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

在进入深度 Q 学习之前,这里有几件事情要解开:

  • MyAI 是一个神经网络模型的占位符,按照下面的标准 PyTorch 方式构建,但是增加了一个 act 方法。
  • 可以预见,重置健身房环境会将其设置回初始状态。
  • ε是一个随时间衰减的数,就像模拟退火一样(更多内容见下文)。
  • 环境中的每一步都返回一个新的状态、一个奖励(在赢得游戏之前可能是零)、一个表示我们是否完成的标志(赢了还是输了,在这种情况下重置环境),以及一些可选的调试信息。
  • env.render() 只做图形。Gym 提供了一些有用的图形原语,如果你想自己制作的话。
  • 损失是一集或一批的平均值,其中可能包含一个或多个完整的游戏。在这段时间内发生的所有动作都存储在重播缓冲区中,使其能够在一集结束时回放,这样我们就可以在我们希望更接近目标时计算损失。
  • calc_loss_over_episode 会在下面的深 Q 位覆盖!

环境

为开放人工智能创建一个健身房很容易。你只需要子类化 gym 并实现一些方法。这里有一个模板:

from gym import spaces
from gym.envs.classic_control import rendering
out = 3
in = 3class MyEnv(gym.Env):
  def __init__(self):
    self.action_space = spaces.Discrete(out)
    self.observation_space = spaces.Discrete(in)
    self.initial_state = whatever_you_like
    self.state = self.initial_state
    self.viewer = rendering.Viewer(640, 480) def step(self, action):
    # do something to calculate next state, reward, and done
    return self.state, reward, self.done, {} def reset(self):
    self.state = initial_state
    self.done = False
    return self.state def render(self, mode='human'):
    # This gets you a window and primitives e.g.
    # cart = rendering.FilledPolygon([(l,b), (l,t), (r,t), (r,b)])
    return self.viewer.render()

行动空间需要离散,因为每个行动将是 0 或 1(采取,不采取)。观察空间可能会更大。这取决于你如何表述这个问题,我是这样表述蒙蒂·霍尔的:

信不信由你,用一种适合人工智能的方式来阐述这个问题是这篇文章中最困难的部分。

首先,有一个隐藏状态,在游戏重置时初始化(每两次移动后)。隐藏状态只是说车在哪个门后面;另外两扇门关着山羊。对 AI 可见的观察状态从[0,0,0]开始。接下来,人工智能选择一扇门,这个动作会得到 0.3 的持续奖励。(这个数字是我随意选的;奖励可以是任何正数或负数,AI 的任务是最大化它)。

当蒙蒂打开一扇门时,状态发生了变化;这通过观察到的状态的变化指示给 AI,用 2 标记新打开的(和包含山羊的)门。接下来,人工智能采取第二个行动:它可以选择打开的门(失败!),坚持它原来的猜测,或者扭曲。游戏结束,如果人工智能最终选择了正确的门,它将得到+1 奖励。如果没有,它得到 0 奖励。正如我们所知,大多数情况下,扭转会更好:将原来的猜测改为另一扇未打开的门。

所以,人工智能看到的是:3 扇门(输入),每扇门都有一些值。人工智能在每一步可以采取的行动:打开三扇门中的一扇门。

也许,有更简洁的方法来构建这个问题,但我选择的方法似乎很简单,直观地映射到实际的游戏中——这是一个简单的问题,我后来发现用少量的神经元训练真的很快,所以,那就行了,猪

在许多强化学习演示中,观察空间是一个 2D 盒子,代表雅达利游戏的电视输出。

模型

这里需要的是 PyTorch 神经网络模型,它将环境的当前状态(来自观察空间)作为输入,并预测来自动作空间的动作作为输出。这只是通过网络向前传递,但是!存在局部最小值的可能性。我在 Q-learning 空间读到了一个很好的解释,代理人/网络可能第一次服用海洛因,并一遍又一遍地重复奖励,但最终永远无法解决这个游戏。

Like the crew of Red Dwarf never escaping the Despair Squid

所以,你不希望人工智能学习或收敛得太快。不是每次都预测它的最佳行动,最大化它的回报(这是比较科学术语中的贪婪算法),而是希望人工智能最初探索行动空间。因此,随着某种概率ε的降低,AI 将从动作空间中选择一个随机动作,而不是它的最佳预测。

这就是 act 方法所做的一切,这就是 epsilon greedy 学习。其余时间,它只需通过调用 forward (即通过网络运行当前状态来预测最佳的下一个动作)来挑选网络的最佳预测动作。

下面是做这项工作的简单 PyTorch 网络:

# env is the AI gym defined and instantiated aboveclass DQN(nn.Module):
  def __init__(self):
    super(DQN, self).__init__()
    self.layers = nn.Sequential(
      nn.Linear(env.observation_space.n, 20),
      nn.ReLU(),
      nn.Linear(20, 20),
      nn.ReLU(),
      nn.Linear(20, env.action_space.n)
    )

    def forward(self, x):
        return self.layers(x)

    def act(self, state, epsilon):
      if random.random() > epsilon:
        state = Variable(torch.FloatTensor(state).unsqueeze(0)) 
        q_value = self.forward(state)
        action  = q_value.max(1)[1]
      else:
        action = random.randrange(env.action_space.n)
      return action

如您所见,它有 3 个输入(每个输入可以是 0、1 或 2,代表当前状态),扇出 20 个具有 ReLU 非线性的神经元的输入层,20 个也具有 ReLU 的神经元的隐藏层,减少到 3 个神经元的输出层,我们将取其最大值来预测下一个动作。

20 的隐藏大小是任意的。有一些简单的样板文件:

  • 我们的状态只是一个像[0,1,2]这样的向量。PyTorch 需要一个张量Nxnum _ features,其中 N 是批量大小。实际上,Unsqueeze 将[0,1,2]转换为[[0,1,2]],也就是说,批量大小为 1;给定当前状态,一次预测一个动作。概念上很简单,但可能是你想为生产优化的东西,否则 GPU 的能力被浪费了。
  • q_value 是网络前向传递的输出,它给出了给定状态下我们可以采取的三种行动中的每一种行动的预期回报。我们沿着神经元的轴(不是 0,批处理轴)找到最大值,max()函数给出一个元组,其中[0]是值,[1]是索引。因此,如果向前传递收益 Y=[-1.34,0.62,0.32] — Y.max(1)将是[0.62,1],Y.max(1)[1]意味着净建议我们采取行动 1。Y.max(1)[0]表明,如果我们采取这一行动,Q 值将是 0.62。

q 学习

这就是问题的核心。Q-Learning 实际上只是问了一个问题,“如何在给定的时间步计算损失?”从游戏结束时的奖励往回看,看看我们在每一步的行动是如何促成最终奖励的。

如果你回想几年前谷歌花了很多钱收购 DeepMind 的时候,头条新闻表明这是因为 DeepMind 有一些解决 Atari 游戏的革命性方法,这导致了 AlphaGo 和最近的电话呼叫 Duplex。就我现在所知,我不认为那是原因。或许,他们有一个像样的基础设施,通过它他们可以将老式算法应用到一个奇特的问题领域,但更重要的是,他们有一个大 G 想要挖走的伟大团队。

我以前在我的文章中强调过这一点,但人工智能真的只是通过人们尝试东西来进步,不一定是大公司,只是有人拿着 GTX 1080 问为什么总是通过 X 来完成,而 Y 在实践中更好。

于是我们来到了上面神秘提到的函数 calc_loss_over_episode() 。代码看起来就像这样:

# gamma is a learning-rate hyperparameter, try 0.9def calc_loss_over_episode(batch_size):
  state, action, reward, next_state, done = replay_buffer.sample(batch_size) state = Variable(torch.FloatTensor(state))
  next_state = Variable(torch.FloatTensor(next_state))
  action = Variable(torch.LongTensor(action))
  reward = Variable(torch.FloatTensor(reward))
  done = Variable(torch.FloatTensor(done)) q_values = model(state)
  next_q_values = model(next_state) q_value = q_values.gather(1, action.unsqueeze(1)).squeeze(1)
  next_q_value     = next_q_values.max(1)[0] if done:
    expected_q_value = reward
  else:
    expected_q_value = reward + gamma * next_q_value loss = (q_value - Variable(expected_q_value)).pow(2).mean()

  optimizer.zero_grad()
  loss.backward()
  optimizer.step()
  return loss

这个的高层次是:

  • 在批次的随机样本中的每个时间步长(通过不总是以相同的顺序移动批次来改进训练)。
  • 在给定的当前状态下预测 Q 值(如果网络在给定的当前状态下采取了 3 个可用的 Monty Hall 行动中的每一个,则预期的回报)。理解这一点的关键是,网络的估计 Q 值将开始完全随机,但最终开始收敛到真实的答案。
  • 在我们采取了上一步预测的行动后,预测实际下一个状态的 Q 值(同样,它们完全是随机开始的)。
  • 在将 Q 值添加到预期奖励之前,对其进行一点折扣(乘以 gamma)。这是因为在随机环境中,我们无法对一个行动的结果有 100%的把握;因此,gamma 对未来的奖励比眼前的奖励打了一点折扣。
  • 找出均方误差(从实际中减去理想/预期回报,对差值求平方并取平均值),然后反推并优化网络参数以最小化损失(使用 SGD、Adam 等)。

对于 Monty Hall 问题,假设一批按顺序处理。 *Q(状态,动作)*产生我们下一个建议的动作。这是一个由输出神经元激活组成的向量。 Q(【所有门都关闭】,2) 是在所有输入都为 0 的网络中单次正向传递后输出神经元 2 的激活。它从未经训练的神经网络的随机垃圾开始。

网络为这一步获得健身房环境 0.3 奖励,蒙蒂打开一扇门。神经网络又迈出了一步。 *Q([AI 选择了门 2 & Monty 打开了门 1】,动作)*由另一个通过具有输入[0,2,1]的网络的向前传递来计算(根据我上面的图)。我们的网还是垃圾;假设这次输出神经元的 argmax 为 1(“开门#1”),值为 0.64。愚蠢的网络试图打开蒙蒂已经打开的门!

健身房环境现在返回奖励 0,并发出游戏已经终止的信号(称之为时间 T)。我们的损失函数现在表示“我的预期 Q 值是 0.64[嗯,它是一个向量,所以其他两个动作也包括在内],我得到的回报是 0。我们可以反推该损失,这将帮助我们更好地猜测时间 T-1 时的 Q 值(给定一个状态)。这将有助于更好地猜测 Q 值和在时间 T-2 要采取的行动。(除了在学习步骤中,时间向前流动,因此在步骤 T-2 计算损失将预测 T-1 和时间 T 的行动/状态/回报)。

一次学习迭代只跨越两个时间段,这是我们从一个批次中随机抽取的。在某个时候,我们将对一个终端案例(时间 T)进行采样,这将使我们更好地了解网络在前一步(T-1)的行为是如何对最终奖励做出贡献的。然后在某个时候,我们将对倒数第二步(T-1)的移动进行采样,我们现在对它如何影响最终回报有了更好的了解,我们可以用它来更好地了解在那之前(T-2)的移动,以此类推,倒回到开始。

如果这对你来说看起来像是欺骗,只是一点点,那么我同意:这只是利用大数据来弥补理解和直觉的完全缺乏。然而,它确实让你得到了一个趋向于零的漂亮图形,这是机器学习研究人员的未声明的目标:

(L) Loss per batch, (R) Mean loss per frame (many batches)

对于每一批(在上面的图表中,我使用了 32 个)移动(可能包括 16 个已完成的游戏),你可以看到损失趋向于零,但没有达到零——因为 Monty Hall 参与者仍有至少 1/3 的机会会输。有时候人工智能有一轮非常不幸的比赛。

与此同时,回到现实世界,在蒙蒂打开一扇门后,人工智能确实学会了改变它的猜测:

After the middle door is opened, with an initial guess of the first door, the AI’s next action is to open the 3rd door. Separately, after the 3rd door is opened and the AI’s initial guess was the first door, it switches to the middle door. 0.00001 is a small value for epsilon, meaning “make your best guess, not a random one”

我完整的 Jupyter 笔记本就是这里的。

后续步骤

正如人工智能中的许多东西一样,Deep-Q 学习已经有些过时了,但如果你能稍微落后于潮流,这是一个很好的强化学习材料的仓库。

只是不要忘记,所有这一切都是因为我们有在数千场比赛中训练我们的人工智能的自由;这个网络只用 20 个神经元就“解决”了蒙蒂·霍尔,这比完全无脑的蛔虫少了一个数量级。

这不是人类大脑的工作方式,所以即使是一个坚定的贝叶斯应该原谅队长霍尔特没有“解决”蒙蒂的游戏。当训练样本非常少时,人工智能应该如何学习;它应该如何对第一次遇到的问题进行元推理,就像蒙蒂霍尔游戏的第一次参赛者会做的那样?(除了 gameshow 的参赛者似乎通常没有多余的 20 个神经元这一事实)。

没有人知道这些问题的答案——让我们继续努力,找出答案!

深度学习和机器学习

原文:https://towardsdatascience.com/deep-learning-and-machine-learning-c1101debe0c?source=collection_archive---------3-----------------------

2015 年 7 月 14 日

这篇博客文章是关于我目前正在从事的一项正式工作的非正式讨论——我的博士背景文献综述。因此,它的链接非常丰富——我在这里记录的旅程本质上是由其他人的工作组成的。这篇文章也可能被解释为试图说服我的上司 奥马尔·拉纳教授 罗南·雷利教授 我实际上是在做事情,而不是阅读论文和调试torch 7/Theano代码。但事实并非如此:)

机器学习-背景

机器学习领域目前非常活跃。一周接一周,一个月接一个月,以前的记录在翻滚然后又翻滚(尽管规则在一路上被打破)。库使用 Nvidia 的 CUDA 实现针对 GPU 硬件优化的算法,研究人员可以从 Nvidia 购买硬件,或者在云中租赁机器,每次一小时。家庭/小公司的程序员现在可以在非常大的数据集上训练非常大的模型,这在 3-4 年前只有大得多的公司才能考虑做。

为什么这很重要?嗯,机器学习最简单的定义是软件,当针对特定任务进行测量时,它会随着时间的推移提高自己的性能。这句话描述了一种与我们目前所习惯的软件非常不同的软件——操作系统、浏览器和大多数应用程序不会根据“经验”有意义地修改它们的行为——它们一次又一次地重复做完全相同的事情。拥有可训练的——可以学习的——软件是一种非常有价值的能力,我们将在后面看到。

在我看来,机器学习代表了我们这个时代的重大挑战之一,与理解现实的结构或什么是生命本身不相上下。

机器学习!=深度学习(只不过现在有点)

机器学习不是深度学习(它是深度学习的超集),但最近(尤其是在主流媒体上),这两个术语已经成为同义词。深度学习是机器学习的一个分支,它源于人工神经网络——在我看来是所有人工智能分支中最有趣的,因为它具有生物合理性(映射到人类大脑中类似的功能或特征)以及它为研究人员提供的路线图/思想宝库。自 20 世纪 60 年代以来,人工神经网络一直非常受欢迎,也非常不受欢迎,因为第一次炒作超过了现实,然后从业者又赶上了(明斯基和帕普特在 1969 年的书感知器中对人工神经网络的贬低至今仍在该领域回响,尽管它遭到了反驳)。

在这里引用明斯基是恰当的——直到最近谈论在 Prolog 和 Lisp 中实现的符号逻辑和神经网络一样可以接受(甚至更可以接受)。但是像神经网络一样,Prolog 和 LISP 已经过时了。然而,从软件工程的角度来看,它们是诱人的。例如,Prolog 处理如下易于理解的事实和规则:

likes(joe, fish).
likes(joe, mary).
likes(mary, book).
likes(john, book).

当我们带着问题“咨询”系统时,Prolog 使用归结反驳来回答,于是我们得到:

?- likes(mary,fish).
no
*"no" means nothing matches the question, no does not mean false.*

但是 Prolog 很慢,规则/事实数据库变得难以管理。Prolog / Lisp 在日本遭遇了自己的人工智能冬天,因为非专业硬件超过了优雅的专用硬件(它们的表现基本上符合摩尔定律)。最近,谷歌的研究人员建立了深度学习系统,专注于相同的领域,显示出有希望的结果,但它们的内部工作方式不像(尽管简单)Prolog 等效程序那样明显/清晰。这既不是一件好事也不是一件坏事——简而言之,这是对古老的象征主义与联结主义辩论的重述。在实践中,硬结果很重要,现在神经网络正在赢得这场辩论..

下面的示意图显示了人工智能的同心分组/子集,以提供深度学习和机器学习之间关系的更真实的画面。

图一。描述人工智能中不同子领域之间关系的示意图,来自本吉奥的书。

神经网络有它们的问题——其中之一是不透明的问题。虽然可视化工具存在,但大部分神经网络看起来像,而且确实是,浮点数的大格子。不经意的观察者从它们那里得到的信息不会比通过观察人类大脑更有意义,当试图将神经网络集成到工作软件系统中时,这不是很好。

那么什么是神经网络呢?

Haykin 的规范文本将神经网络定义如下:

“由简单处理单元组成的大规模并行分布式处理器,具有存储经验知识并使其可供使用的自然倾向”。

这些简单的处理单元就是神经元。神经元的标准模型是由麦卡洛克和皮茨在 1943 年提出的,从那以后就没怎么改变过。神经元接受输入 X 的向量,这些输入被加权,并且可选的偏置 b(图中未示出)基于应用于权重的某个函数(根据期望的特性使用许多不同的函数)生成输出或激活。下图描绘了这种风格化的神经元。

图二。单个神经元的标准(麦卡洛克-皮茨)模型。

现实世界的神经网络有成千上万个这样的神经元,它们一起提供了经验知识的存储,最有用的是,在先前已经看到的数据的背景下理解新的、看不见的数据的能力。GPU 非常适合训练神经网络,因为它们也是大规模并行的,如下图所示。

图 3。Nvidia 的 Titan X GPU,拥有 3,072 个 CUDA 内核。

神经网络的个人历史

我第一次遇到神经网络是在 1997 年——我最后一年的项目结合了SNNS(torch 7/the ano 的祖先)和西姆德雷拉创造了一个“通过观察学习”的 6 自由度机械臂。我们教网络嵌套杯子——就像一个孩子会做的那样。事实上,随着网络的训练,它显示了嵌套策略的复杂性进展(线性- >预堆叠),正如皮亚杰为真实儿童记录的。这个项目也旨在成为进一步工作的垫脚石,该工作受到人类大脑中布罗卡区发展的启发,如果我们预先训练或调节简单任务的神经网络,它在学习更复杂的任务时会更成功。预训练/调节是训练深网时要考虑的一个重要启发(见下文)。事后看来,我怀疑我为了我的项目结束演示过度训练了这个网络,以确保在我使用的简单的 20x20 视网膜上找到杯子的准确性!在 1997 年(从主观上来说),从计算机科学的角度来看,神经网络被认为是优雅的,但可疑地接近心理学和软件工程,可以从诸如基于案例的推理、推理、决策树等技术中获得更好的(和可理解的)结果。

2003 年,我的理学硕士再次关注神经网络,但几乎是作为主要活动(分布式计算)的副业。这项工作的主要目的是展示一个异构计算节点集群如何有效地复制一个非常著名的基准测试,该基准测试使用钱和 Sejnowski,1998 的神经网络模型预测球状蛋白质的二级结构,使用基于的 Linda 和 David Gelernter 的基于元组的架构进行近似线性加速。此外,这项工作只使用了前馈神经网络——递归网络,当然 LSTM 会产生更好的结果,因为它们能够保留氨基酸输入序列的信息。

2003 年,关于投资银行使用神经网络来预测股票市场和监控投资组合风险的流言四起。如果这是真的,那么我向读者提出,2008 年的事件表明,这些神经网络可能已经找到了一系列不幸的局部极小值..

2006 年,世界变了。 Geoffrey Hinton 、 Yoshua Bengio 和 Yann LeCun 开始将神经网络分层堆叠——每一层都从其输入中提取重要/相关的特征,并将这些特征传递给其上一层。此外,焦点从简单的分类器转移到了生成模型——实际上,网络的主要任务变成了在不断增加的抽象级别(通过堆栈)上生成输入数据,以便提取有用的特征。这些都是重大突破,时机也很偶然——在硬件方面,Nvidia(和 AMD,但 OpenCL 对深度学习来说几乎是死的)正在让 GPU 卡成为通过 CUDA 访问的计算资源。即使在今天,我们仍然处于一个黄金时代,因为这三位一体的融合:

  1. 带有训练算法的核心思想(神经网络)反向传播:Rumelhart,Hinton,Williams 本质上服从并行化。
  2. 内在并行硬件(GPU)来训练这些神经网络。
  3. 越来越大的数据集(标记的和未标记的)作为输入提供给神经网络。

2013 年 3 月,辛顿加入谷歌,2013 年 12 月,乐存加入脸书。这两家公司、百度以及更多公司都在深度学习方面投入巨资,以自动分类、理解和翻译网络上的丰富内容——文本、图像、视频、语音..你为什么会这么做是显而易见的——社交平台变得更加相关,手机变得更加强大和有用,广告变得更有针对性,电子商务网站提供更好的搜索结果,推荐是真正有用的——可能性是无限的。仅仅是让谷歌和脸书在这一领域开展工作,就要为当前许多(准确和不准确的)主流媒体对人工智能的报道负责。

这让我们很好地了解了神经网络的典型用途。

实际应用

简而言之,神经网络从它们接受训练的数据中提取特征和模式——通常是人类看不到的特征和模式。然后,一个经过训练的神经网络可以得到新的、看不见的数据,并做出预测。这个一般化步骤非常有用,特别是对于递归神经网络,其可以随时间吸收数据*,即编码时间信息或序列。神经网络变得非常擅长:*

  • 图像解析(边缘检测、对象检测和分类)
  • 场景理解
  • 语音识别
  • 自然语言处理
  • 语言翻译
  • 玩简单的电子游戏
  • 多标签系统的分类和聚类
  • 时间序列预测。

对于特定的用例,人工神经网络有时能够并且将会表现更好,通常是通过更简单/更老的技术。构建一个允许使用多种 ML 技术的问题总是明智的,这样可以进行对等比较。然而,特别是在计算机视觉和序列翻译领域,深度学习方法主导了各种排行榜。

更一般地,如果神经网络 N 可以在系统 S 和从时间步长 0 到当前时间步长 t 在该系统中发生的事件 E 上被训练,例如 E = {e0,..然后可以对 e(t+1),e(t+2)等中将要发生的事情提供合理到良好的预测。,那么这就有广泛的适用性——在电子商务、个性化医疗、库存管理中——只要是你能想到的,都需要这种预测。这是神经网络的基本吸引力(与理解图像及其元素相比,这一点经常被忽视/低估)。

神经网络的弱点

毫无疑问,神经网络是令人沮丧的工作。神经网络是:

  1. 难以培训(时间过长,最终表现平平)。
  2. 对输入的呈现方式非常敏感,因此可以提取正确的特征(ICLR 是一个致力于表征学习的会议)——本吉奥、库维尔和文森特对这些复杂性进行了很好的综述。
  3. 权重的初始状态会对最终绩效产生巨大的(正面和负面)影响。
  4. 服从“经验法则”,这些法则散布在文献中,被发现/重新发现/重新发明:例如,课程学习,颠倒输入顺序,调整学习速度。无论如何,这不是一个完整的列表..

尽管如此,各种形式的神经网络已经在许多不同的领域展示了一流的成果。这就是它们有趣的原因,也是我认为研究人员和公司坚持使用它们的原因。它们复杂、深奥的本质远远超过了它们产生的结果。

深度学习的“国家状况”——2015 年 ICLR

看看某个研究领域最近的会议上提出的主题,了解该领域当前的“国家状况”是有益的。机器学习也不例外,我参加的最后一次会议是几周前在加州圣地亚哥举行的 ICLR 2015 。正如在对 ICLR 的其他评论中已经提到的,所有提交的论文都可以在 Arxiv 上获得,这太棒了。很高兴看到这些论文的作者展示他们的作品,或者在海报会议上直接谈论他们。还有很多其他优秀的会议——NIPS、 KDD 、IJCAI——我选择 ICLR,因为它在我心目中是最新鲜的!

首先,至今使用的数据集开始挣扎。

第二,研究人员正在寻找共同的参考点,以此来对正在开发的最新系统进行评级。玩具任务是一个很好的例子,它与课程学习有着清晰的渊源。ICLR 2015 的一篇论文正在接受审查,但我猜没有被接受的是递归神经网络正则化。关于这篇论文,我最喜欢的是 Github 上的代码——一种将论文中的数据与可再现的输出相匹配的好方法。

带 fbfft 的快速卷积网络:一个 GPU 性能评估演示了在训练深度网络时如何更努力地驱动 GPU,并且已经有了该库的另一个版本(提示:使用 16 位浮点而不是 32 位!)不难想象,如果确定了进一步的不同优化,Nvidia 将在未来为深度学习社区生产专用硬件..

最后,从直觉的角度来看,我个人最喜欢的是记忆网络。它具有较低的生物学似然性(或者当然该论文中没有探讨这方面),但是具有较高的实际应用性。我们可以很容易地想象出这种架构的变体,例如,它学会了访问 SQL / NoSQL 数据库中保存的业务事实,或者访问类似 Prolog 的事实和规则。

机器学习的商品化

机器学习已经渡过了某种难关,现在被视为商业应用的必备工具。语音和计算机视觉的传统应用将继续,但 ML 也将在 POBAs(普通的旧商业应用)中变得无处不在。ML 的商品化已经开始了:

  1. 微软(今年)
  2. 谷歌(2011 年,很少被采用)
  3. 亚马逊(今年)

还存在许多较小的服务,随着时间的推移,随着赢家的出现,我们可以期待看到整合。对于那些希望在本地使用 ML 的工程师,我们提供以下服务:

ML 从业者的祸根是超参数选择(也称为上帝参数——使你美丽的神经网络出色工作或比随机猜测好不了多少的配置标志)。事实上, Bergstra 和 Bengio 证明了随机猜测超参数通常是一种“足够好”的策略,因为算法通常只对一两个超参数敏感。最近,Snoek 等人应用贝叶斯先验和高斯过程来进一步完善这种方法(我猜我会称之为智能随机性加学习)。Spearmint——构建的实现已经被剥离成一个具有漂亮的 API 的启动。考虑到一些深度网络需要大约两周的时间来训练,任何更快的到达最优超参数的路径都是有利的。

该领域的未来方向

很明显,与理论相比,围绕机器学习的软件工具相当不成熟。研究人员撰写并发表论文,而不是生产强度代码。因此,将机器学习与计算机科学的其他分支(操作系统、网络、数据存储、搜索)进行比较表明,在这一领域需要做很多工作。

冒着过度对冲的风险,下一个突破要么来自现有的方法(见 2014 / 2015 年,施密德胡伯和霍克雷特的《长短期记忆》又名 LSTM 变得多么受欢迎),经过 15 年的探索之后),要么来自新的思维,可能是受生物构造的启发。Geoffrey Hinton 目前关于胶囊/流形学习的工作就是一个很好的例子。对于研究人员来说,看到文献中存在哪些由于计算困难而被放弃的想法/技术,现在可能更容易处理,这肯定是有希望的!

有可能我们所要做的就是将网络堆叠得更高(900+层深?)根据 Srivastava、Greff 和 Schmidhuber 的高速公路网论文继续前进,但我的感觉是“深度”方法只剩下这么多距离了。无论如何,有趣的是,目前六层似乎是最佳的(但是谷歌网使用 22 或 27 层,这取决于你如何计算它们)。

有点奇怪的是,反向传播结合随机梯度下降(SGD)仍然是使用的最好/规范的学习算法。自 1986 年以来,它确实经受住了时间的考验,并且非常适合 GPU。目前的研究似乎集中在网络架构上,但学习算法的复兴似乎也将不可避免。

大多数神经网络都是由老师训练的——对于好的输出,我们奖励网络低误差,对于差的输出,我们惩罚它。这种方法工作得很好,但是需要很好标记的数据,这通常是一种奢侈或者根本不可能实现的。谷歌 Deepmind 正在倡导强化学习,将其作为开发能够很好地跨问题转移的系统的一种方式(在他们迄今为止的开创性论文中,一个单一的神经网络已经学习/泛化到足以玩所有的雅达利游戏)。

最后,有理由期待神经网络复杂性的降低,如果不是理论上的,那么肯定是实践和使用上的。使用最小描述长度或VAP Nik–Chervonenkis 维度作为度量,我们感兴趣的是构建最简单、最紧凑的神经网络(具体来说,使用最少的参数)来解决给定的问题或任务。更简单的网络也会训练得更快——这在实践中是一个非常好的好处。

回顾/总结

这篇博文比我预想的要长!一部分是历史之旅,一部分是对机器学习的概述,带有明显的深度学习倾向,这是一篇比我目前正在为我的博士论文撰写的文章更非正式的文献综述。

这一领域的创新步伐很快——每年有四五个大型会议,每个会议都会带来新的公告和突破。目前,软件工程、快速、可扩展的硬件和良好的理论真正融合在一起。

深度学习/神经网络可能不是将所有人工智能结合在一起的单一统一理论(有太多的未知和以前的失败),但我怀疑它将对人工智能的发展产生深远的影响,至少在未来十年内。

进一步阅读

如果你仍然对机器学习感兴趣(你为什么会不感兴趣?!)我认为公平地说,在这个领域,你只是不能做足够的阅读——基础已经建立,但前沿每天都在被推进和挑战。这篇博文包含了许多有趣的链接,除此之外,如果你想了解更多,我强烈推荐这个领域的主要思想领袖/实践者的 Reddit ML AMAs。它们是(没有优先顺序——它们都有助于优秀的、有洞察力的阅读):

  1. 吴恩达和亚当·科茨(2015 年 4 月 15 日)
  2. 于尔根·施密德于贝尔(2015 年 3 月 4 日)
  3. 杰弗里·辛顿(2014 年 11 月 10 日)
  4. 迈克尔·乔丹(2014 年 9 月 10 日)
  5. 扬·勒村(2014 年 5 月 15 日)
  6. 约舒阿·本吉奥(2014 年 2 月 27 日)

深度学习和毒蘑菇

原文:https://towardsdatascience.com/deep-learning-and-poisonous-mushrooms-4377ea4c9b80?source=collection_archive---------2-----------------------

在对蘑菇或机器学习知之甚少的情况下,使用深度学习网络解决一个常见问题。

简介

机器学习是一个如此迷人的话题,它允许机器学习如何完成历史上需要人类完成的任务。虽然几年前机器学习还需要最强大的超级计算机,但云计算、更便宜的 CPU 和更好的算法的出现让机器学习变得更广泛。今天,高中生可以在普通家用计算机上使用机器学习,其能力可以提供比人类更好的图像分类结果。但首先,这就是为什么我对机器学习,特别是深度学习感到兴奋。

鉴于最近媒体报道了人工智能的进步,特别是深度学习网络的进步,我决定了解一些核心概念,这些概念允许机器在危险中击败人类,围棋,扑克或自动驾驶汽车以及其他许多通常需要人脑的应用。我认为深度学习网络是极其庞大和复杂的分层试错系统,当给定大型数据集和大量计算资源时,它们可以自我学习。

研究深度学习网络

我转向谷歌搜索,以确定 AlphaGo 的技术,这是一种击败世界上最好的围棋选手的人工智能。谷歌使用了一个名为 DeepMind 的深度学习网络系统。在战胜最优秀的人类选手后不久,DeepMind 转而使用开源的深度学习库 TensorFlow。由于对 TensorFlow 了解不多,我继续寻找一个易于管理的切入点,不需要博士学位,以了解 TensorFlow 的基础知识和一些我可以在家里的笔记本电脑上复制的示例。我发现了一个包含 YouTube 视频、GitHub 项目、博客帖子和类似内容的大型资料库。

我发现这两个资源对了解 TensorFlow 最有帮助:

Siraj Raval 的 YouTube 视频,他希望在人工智能方面启发和教育开发人员,这样他们就可以使用 Youtube 视频和 Udacity 开发游戏、音乐、聊天机器人、创造艺术和许多其他很酷的东西。我在 YouTube 上看过他的视频,据说是教你*“在 5 分钟内建立一个 TensorFlow 图像分类器”*。https://youtu.be/QfNvhPx5Px8。

该视频是实践性的,节奏很快,很难跟上,但在看了几遍后,我确信我可以效仿这个例子,并受到启发,创建了我自己的图像分类器,它不是基于达斯·维德和熊猫。

谷歌开发者 Codelabs 正在提供一个名为*“诗人的 tensor flow”*的图像分类示例,它允许你识别给定花的属。这个例子使用了几种,像雏菊、向日葵、蒲公英、郁金香和玫瑰。它提供了一个详细的步骤列表,只要一切按计划进行,就很容易遵循。https://code labs . developers . Google . com/code labs/tensor flow-for-poets/# 0

您可以查看完整说明的链接。

蘑菇是如何发挥作用的

对于图像分类器来说,有什么比将图像与达斯·维德进行匹配更好的用例,可以基于可用的图像库来实现?我转向蘑菇。每当我们在森林里徒步旅行时看到蘑菇,我通常不知道斑点蘑菇是否可以食用。几年前,我和我的合作伙伴认为开发一个可以判断主题是否适合消费的移动应用程序会很棒。只要把你的相机对准蘑菇,应用程序就会告诉你它是否可以食用。需要说明的是,我没有计划构建这样一个应用程序所需的 web 服务,但基于 TensorFlow 的图像分类能够提供当今解决方案中最复杂的部分,人们可以相对容易地构建由深度学习网络支持的蘑菇标识符应用程序。

项目及成果

我是这样做的:

我用谷歌图片搜索下载了 600 张食用蘑菇和同样数量的有毒蘑菇的图片,并将其输入到我基于 TensorFlow 的深度学习网络中。经过大约 30 分钟的训练,精确度和损失函数值都指向正确的方向,所以我知道这个网络能够提供结果。

准确度和损耗的张量图

这个图表显示了深度学习网络的准确性水平。x 轴上的训练步数和 y 轴上的精确度。达到~97%是相当可观的。

在这种情况下,y 轴上的交叉熵用作损失函数。它基本上显示了网络学习的效率。数字越小越好。x 轴上的训练步数。

例:飞木耳

不可食用!毒药(得分= 0.99746)可食用(得分= 0.00230)

例子:鸡油菌

我会吃这些。可食用(得分= 0.96285)毒药(得分= 0.03706)

这是两个最令人印象深刻的结果。还有其他不太确定的结果,我相信这些结果是基于有点不科学的研究图像库,因为网络的准确性相当高。清理图像数据库并使用更大的食用和有毒蘑菇数据集将是一个有趣的项目。

结论

让我惊讶的是,建立并运行一个有效的深度学习网络所需的简单性和低技术知识门槛。这项突破性的技术现在对全世界的开发者和爱好者开放,使用它不需要计算机科学学位。我们正在见证一个重要的转变,强大的机器学习技术正在从少数科学家的实验室转移到成千上万的开发人员手中,他们将提供成千上万的人工智能应用,对我们的生活产生难以想象的影响。TensorFlow 等工具包将使这一切成为可能。

深度学习和土壤科学—第 1 部分

原文:https://towardsdatascience.com/deep-learning-and-soil-science-part-1-8c0669b18097?source=collection_archive---------3-----------------------

预测土壤性质的土壤光谱学

这是我致力于深度学习在土壤科学中的应用的系列文章的第一篇。我的动机是为了表明深度学习对其他事情有用,而不是对猫和狗的照片或情感进行分类。并不是说猫和狗有什么不好,但是已经有数百万个这样的例子了…

这是一个正在进行的系列,到目前为止还包括:

[## 深度学习和土壤科学—第二部分

使用上下文空间信息的数字土壤制图。从点信息生成土壤图的多任务 CNN。

towardsdatascience.com](/deep-learning-and-soil-science-part-2-129e0cb4be94) [## 深度学习和土壤科学—第 3 部分

土壤光谱学与迁移学习。将大陆土壤光谱模式“本地化”到国家范围。

towardsdatascience.com](/deep-learning-and-soil-science-part-3-c793407e4997)

其他与地球科学相关的文章:

[## 用 SHAP 解释 CNN 生成的土壤地图

使用 SHAP 来证实数字土壤制图 CNN 捕捉到了合理的关系。

towardsdatascience.com](/explaining-a-cnn-generated-soil-map-with-shap-f1ec08a041eb) [## GeoVec:用于地球科学的单词嵌入

词语嵌入的类比、分类、关联和空间插值。

towardsdatascience.com](/geovec-word-embeddings-for-geosciences-ac1e1e854e19)

一点背景知识

土壤科学是一个相对广泛的学科,所以我将尝试给出一些关于我们所做的事情和我们通常处理的数据类型的背景。

现场和实验室的土壤

土壤是一个复合体,可以用多种方式描述,这取决于你是否对它的物理、化学和/或生物特性感兴趣,它在景观中的位置,它与生物圈其他部分的相互作用,等等。

通常,描述从土壤剖面开始。我们挖了一个坑,我们能够看到类似下图的东西。

Soil profile (Spodosol) in Denmark.

图片中你首先注意到的是不同的颜色和不同层次的垂直结构。每一层都有不同的特征,作为土壤科学家,我们有兴趣尽可能全面地描述它们。

典型的描述通常包括现场可观察到的属性(坐标、层厚、颜色等。)和我们在实验室处理样品后获得的信息(pH 值、颗粒大小、营养成分等。).

可以想象,数据采集的现场和实验室部分非常昂贵,因此我们花费大量时间来优化采样设计,预测我们在某个位置会发现什么,并根据更容易、更快或更便宜的测量方法来预测土壤属性。

土壤光谱学

土壤光谱学是一种允许在野外或实验室快速获取土壤信息的技术。简单地说,我们用一束光照射土壤样本,然后测量反射回来的东西。根据样品的成分,反射回仪器(光谱仪)的能量因样品而异,从而获得样品的光谱特征。

Spectral signature of a soil sample.

表示该数据的另一种方式是通过生成频谱图。你可能见过它们被用于音频分析。你可以在这里找到更多关于他们的信息。频谱图的 2D 结构使其成为被卷积神经网络摄取的完美候选。

Spectrum (bottom) and its corresponding spectrogram (top).

卷积神经网络模型

设计卷积神经网络(CNN)是一个高度迭代的过程。有时候感觉更像一门艺术,而不是一门精确的科学。然而,阅读别人的作品并从中获得灵感总是好的。我不会解释它们是如何工作的,但在这里你可以找到一个很好的描述 MNIST 数据集的图像分类的例子。

在设计本研究中使用的 CNN 时,一系列因素引导或限制了这一过程:

  • **输入数据的 2D 结构:**声谱图是一个矩阵(1 波段图像),使用 2D-CNN 处理可能更好。
  • 数据集规模相对较小:切记数据是从现场样本中获取的,这一点很重要。这意味着去实地,挖一个洞,在实地或在将样本送到实验室后扫描样本。这个过程既费时又费钱。我们在本例中使用的数据集包含来自全欧洲的大约 20,000 个样本。这不是你能找到的最小的数据集,但与用于训练 AlexNet 的数据集(超过 1500 万张图像)相比,还是很小的。很容易过度适应一个小数据集,所以我用了一个小网络
  • **多种输出:**我们可以使用光谱预测许多土壤特性。在这项具体研究中,我们有兴趣预测:a)有机碳含量(OC),b)阳离子交换容量(CEC),c)粘土颗粒尺寸部分,d)砂颗粒尺寸部分,e)水中测得的 pH 值,以及 f)总氮含量(N)。我们可以为他们每个人训练不同的模型,但我对 多任务学习 产生某种协同效应的潜力感兴趣。

最终的网络结构如下所示:

Multi-task network architecture

网络的头部(“公共层”)是图像分类中常见的一系列卷积层和最大池层。网络的这一部分由所有目标土壤属性共享,并且应该能够了解谱图是如何构造的。在“公共层”提取由谱图表示的数据的一般表示之后,信息被导向 6 个不同的分支,每个分支对应一个目标土壤特性。每个分支由一个卷积层(BN)组成,在产生输出之前,卷积层被展平(到 1D)。这些分支应该能够学习光谱图中的信号,这些信号是针对每种土壤特性的。****

结果

与其他传统方法的比较

使用光谱数据预测土壤特性的两种常用模型是立体回归树模型(Quinlan 等人,1992 年)和偏最小二乘回归(PLSMartens 和 Naes,1989 年)。我们使用这些模型作为基线来评估 CNN 的性能。使用光谱(不是光谱图)训练模型,这些光谱是使用文献中常用的一系列方法预处理的:

  1. 将反射率转换为表观吸光度(a = log10(r))。
  2. Savitzky-Golay 平滑(Savitzky 和 Golay,1964),使用 11 的窗口大小和二阶多项式。
  3. 边缘修整(< 500 nm and > 2450 纳米)以去除伪影。
  4. 每十次测量取样一次。
  5. 应用标准正态变量变换(Barnes 等人,1989)。

下图比较了所有模型(PLS,Cubist,CNN)的预测误差。我们还包括了 CNN 预测单个属性的误差作为参考。

Comparison between PLS, Cubist and CNN for each target property.

CNN 的表现优于 PLS 和 Cubist 模型,多任务 CNN 的表现通常优于单预测 CNN。

多任务学习的协同效应

我认为最有趣的结果是通过使用多任务网络观察到的协同效应。在下图中,您可以看到随着我们增加同时预测的属性数量(我们修改了每种情况下的网络架构,获得了范围[1,6]内的分支数量),预测误差如何减少(pH 除外)。与单独预测 OC 相比,同时预测我们的 6 个属性将 OC 的预测误差降低了近 50%。

Percentage change in error when more properties are predicted simultaneously. X-axes correspond to number of extra variables used, starting from zero. Value next to first point corresponds to the RMSE when only the target property is used. Error bars correspond to the 90% confidence interval.

当网络预测一个属性时,它使用其余的预测属性作为约束预测的“提示”。一个简单的例子是粘土和砂含量的情况。在最普遍的情况下,土壤矿物颗粒被分成 3 组逐渐增大的颗粒:粘土、淤泥和沙子。这三组的比例相加应为 1 (100%)。如果模型预测粘土含量非常高,这是一个暗示,表明砂含量应该很低。显然,6 个属性之间的相互作用更加复杂,但是网络正在捕捉这种效应。因此,我们观察到预测误差的减少。

最后的话

在我的研究小组中,我们通常使用机器学习技术,如随机森林、回归树等。这是我第一次尝试使用卷积神经网络来做一些不同于分类图像的事情。

我特别喜欢这项工作的是多任务学习的协同效应。在我们的头脑中,我们产生了指导我们做决定的规则,CNN 能做类似的事情真是太棒了。

结果很有希望,自从我开始研究这个,我一直在尝试用 CNN 做任何事情!

在接下来的文章中,我将探索一点迁移学习,以及在土壤制图中的一些应用,敬请关注!

引用

关于这项工作的更多细节可以在相应的论文中找到。

Padarian,j .,Minasny,b .和 McBratney,A.B .,2018。使用深度学习从区域光谱数据预测土壤特性。地域晶洞。https://doi.org/10.1016/j.geodrs.2018.e00198

参考

  • 巴恩斯,r .,达诺亚,硕士和李斯特,S. J. (1989)。近红外漫反射光谱的标准正态变量变换和去趋势。应用光谱学 43 (5),772–777。
  • 马滕斯,h .和奈斯,T. (1989 年)。多元校准。约翰·威利父子公司。
  • 昆兰,J. R. (1992)。连续上课学习。第五届澳大利亚人工智能联合会议。第 92 卷。新加坡,第 343-348 页。
  • 萨维茨基和戈雷(1964 年)。用简化的最小二乘法对数据进行平滑和微分。分析化学 36 (8),1627–1639。

深度学习和土壤科学—第二部分

原文:https://towardsdatascience.com/deep-learning-and-soil-science-part-2-129e0cb4be94?source=collection_archive---------10-----------------------

利用上下文空间信息的数字土壤制图

这是我致力于深度学习在土壤科学中的应用的系列文章的第二篇。这是一个正在进行的系列,到目前为止还包括:

[## 深度学习和土壤科学—第 1 部分

预测土壤性质的土壤光谱学。根据光谱图预测多种土壤特性的多任务卷积神经网络。

towardsdatascience.com](/deep-learning-and-soil-science-part-1-8c0669b18097) [## 深度学习和土壤科学—第 3 部分

土壤光谱学与迁移学习。将大陆土壤光谱模式“本地化”到国家范围。

towardsdatascience.com](/deep-learning-and-soil-science-part-3-c793407e4997)

其他与地球科学相关的文章:

[## GeoVec:用于地球科学的单词嵌入

词语嵌入的类比、分类、关联和空间插值。

towardsdatascience.com](/geovec-word-embeddings-for-geosciences-ac1e1e854e19)

在本系列的第一部分,我给出了土壤科学家如何收集信息的一些背景,这通常涉及一些实地工作和实验室分析。这是一个昂贵而耗时的过程,这也是我们试图建立模型来预测土壤特性的原因之一。

在本文中,我将重点放在生成地图的空间模型上。首先,我给出了一些关于传统的和“机器学习”方法制作土壤图的背景。然后,我深入探讨了为什么上下文信息很重要,以及我们如何使用卷积神经网络(CNN)来利用这些信息。

语境

土壤理论史

19 世纪晚期,负责绘制俄罗斯帝国土壤图的地质学家和地理学家 v·v·道库恰耶夫提出了土壤形成(以及变化)取决于多种因素的观点,包括其母质、气候、地形、植被和时间。这个一般概念是现代土壤学(土壤研究)的基础。

传统土壤制图

人类绘制土壤地图已经有很长时间了。为了税收等目的,决定在哪里种什么。要了解土壤和自然界,观察是整个过程的关键部分。在野外,挖好坑后,我们描述土壤剖面和它的地层,试图了解它的历史。但这只是故事的一部分。由于这个坑被淹没在景观中,土壤学家在得出任何结论(或绘制地图)之前都要观察周围环境。

描述观察完了,就该画图了!你将所有点(坑)放在一张白纸上,并根据以下两个因素在它们周围画多边形:1)它们的相似性(不相似性)和 2)关于形成因素的信息。过了一段时间(在本例中可能是很多年),您会得到如下结果:

Humus content in Russian soils. Dokuchaev (1883).

数字土壤制图

自从道库恰耶夫的工作以来,情况发生了变化。理论上不多,但我们如何观察自然,如何处理数据。现在,技术出现在大部分过程中,从 GPS 获得坑的准确位置,到描述土壤形成因素的卫星图像。

在传统的土壤制图中,通过观察形成因素之间的相互作用得出的结论是在土壤科学家的头脑中得出的。在数字土壤制图(DSM)中,整个过程现在由建模和机器学习来辅助。土壤学家可以了解到山谷中的土壤不同于山坡上的土壤。我们当然可以训练一个模型做同样的事情,对吗?

DSM 是土壤科学的一个动态子领域,所以很难概括社区正在做的一切。我们使用从线性回归到随机森林的模型。我们有许多来源来获得预测因子(形成因素),包括卫星图像和衍生产品。要获得更多关于 DSM 的信息,我建议你参考 McBratney 等人 (2003)。

卷积神经网络和 DSM

正如我在前面提到的,需求侧管理的理论背景是基于土壤属性和土壤形成因素之间的关系。在实践中,单个土壤观测值通常被描述为坐标为(x,y)的点p,相应的土壤形成因子由同一位置的多个协变量栅格(a1,a2,…,an)的像素值的向量表示,其中n是协变量栅格的总数。

这种点表示无疑是有用的,但它相当于土壤科学家只查看土壤剖面,而不考虑周围的景观。为了完成这幅图,我们可以将模型暴露在每次观察的空间环境中…相当于走出土坑,四处张望。

在 CNN 的帮助下,我们可以扩展传统的 DSM 方法,包括关于(x,y)附近的信息,并充分利用土壤观测的空间背景。我们可以用形状为(w,h,n)的 3D 数组替换协变量向量,其中wh是以点p为中心的窗口的宽度和高度,以像素为单位。

Representation of the vicinity around a soil observation p, for n number of covariate rasters. w and h are the width and height in pixels, respectively. Each raster A is a proxy for a forming factor.

因为我是多任务学习的爱好者,所以我们使用具有 3D 阵列的 CNN 作为输入,并基于数字高程模型、坡度、地形湿度指数、长期年平均温度和年总降雨量,生成了 5 个深度范围的土壤属性(土壤有机碳)预测。网络看起来像这样:

Multi-task network architecture

网络负责人(“共享层”)提取数据的通用表示,然后将该数据导向 5 个不同的分支,每个分支对应一个目标深度。分支应该能够学习特定于每个深度的信号。****

结果

数据扩充

数据扩充是机器学习中常见的预处理。当我们谈论地图时,我们通常有兴趣点的俯视图,因此增加数据的最简单方法是旋转。这里我们将图像旋转了 90 度、180 度和 270 度。这样做有两个好处:

  • 最明显的优势是,我们有效地将观察次数增加了四倍。
  • 第二个优点是,我们通过引入旋转不变性来帮助模型进行更鲁棒的概括。

Effect of using data augmentation as a pre-treatment.

正如预期的那样,数据扩充在减少模型误差和可变性方面是有效的(图 4)。我们观察到平均误差在 0-5、5-15、15-30、30-60 和 60-100 厘米深度范围内分别降低了 10.56、10.56、11.25、14.51 和 24.77%。

邻域大小

Effect of vicinity size on prediction error (RMSE, y-axis), by depth range. Ref_1x1 corresponds to a fully connected neural network without any surrounding pixels. Ref_Cubist corresponds to the Cubist models used in a previous study (Padarian et al., 2017).

邻域窗口(邻域)的大小对预测误差有显著影响(图 5)。大于 9 像素的尺寸显示误差增加。在本例中,对于 100 米网格大小的国家级 SOC 制图,150 至 450 米半径的信息是有用的。该范围类似于 Paterson 等人在一篇综述中报告的耕地的空间相关性范围。(2018),其中,基于 41 个变异函数,作者估计平均空间相关范围约为 400 m。由于我们使用了相对粗糙的像素分辨率(100m),因此很难判断提高 SOC 预测所需的最小上下文量。我们相信使用更高的分辨率(<10 米)可以产生更多关于这个问题的见解。

将 CNN 的结果与更传统的方法(Cubist)进行比较,对于 0-5、5-15、15-30、30-60 和 60-100 厘米的深度范围,CNN 分别显著降低了 23.0、23.8、26.9、35.8 和 39.8%的误差。

多层土壤预测

在 DSM 中,有两种主要方法来处理土壤性质的垂直变化。您可以逐层进行预测(深度是隐式的),或者在模型中包含深度(深度是显式的)。这两种方法都表明,随着预测深度的增加,模型解释的方差会减小。这是意料之中的,因为用作协变量的信息通常代表地表条件。

在这项研究中,我们可以再次看到使用多任务 CNN 的协同效应(我在第一篇文章中谈到过)。如下图所示,在这种情况下,模型解释的差异实际上随着深度而增加。不应该在模型和数据集之间比较 R 的绝对值,但是绝对有可能比较趋势。

Percentage change in model R² in function of depth.

我想这是我喜欢多任务 CNN 的主要原因。但是请注意,它并不总是有效的…在以后的帖子中,我会给你看一些例子。

地图呢?

如果你已经到了这一步,你绝对值得拥有一张地图!毕竟,这就是介绍的内容,对吗?这项研究是利用智利的土壤信息进行的。在下图中,你可以看到一个小测试区域的预测示例(最终我会分享一个完整地图的链接)。

Detailed view of (left panel) map generated by a Cubist model (Padarian et al., 2017) and (right panel) model generated by the multi-task CNN.

视觉上,与传统模型(立体派)相比,CNN 生成的地图显示出一些差异。使用 Cubist 模型生成的地图显示了与地形相关的更多细节,但由于树规则生成的明显限制,也会出现一些假象,并且可能会出现协变量栅格的一些假象。另一方面,使用 CNN 生成的地图显示了平滑效果,这是使用相邻像素的预期行为结果。

很难从视觉上评价一幅地图,因为我们不可避免地基于审美来判断它。现实有多平滑或尖锐?这是我所在领域正在进行的讨论。传统的土壤多边形并不是描述土壤的最佳方式,因为土壤是一个连续体,但我们不难发现两种土壤之间存在明显变化的情况,因此非常平滑的栅格可能是错误的…最有可能的解决方案是介于两者之间。

(编辑)解释模型

在不同的场景中测试了这种方法之后,很明显,我们需要一种方法来解释 CNN 模型,至少证实它们捕捉到了 SOC 和预测者之间的合理关系。在下面链接的文章中,你可以读到我是如何利用 SHAP 价值观做到这一点的。

[## 用 SHAP 解释 CNN 生成的土壤地图

使用 SHAP 来证实数字土壤制图 CNN 捕捉到了合理的关系。

towardsdatascience.com](/explaining-a-cnn-generated-soil-map-with-shap-f1ec08a041eb)

最后的话

数字土壤制图是一个非常有趣和动态的学科,很高兴看到像卷积神经网络这样的方法在这里适用。直观地说,一种能够利用背景空间信息的方法完全符合土壤科学的理论框架。

此外,我们再次看到了多任务网络的协同效应,通过在更深的层中调整预测。如果模型已经做出了预测顶层的努力,那么它肯定应该使用它来指导更深层的预测!这正是土壤科学家在描述剖面图时所做的事情!

我已经承诺了一个关于迁移学习的帖子,希望这将是下一个帖子。我有一个半生不熟的草稿,但是我的博士学位让我很忙…所以请耐心点!

引用

关于这项工作的更多细节可以在相应的论文中找到。

帕达里安,j .,米纳斯尼,b .,和麦克布拉特尼,A. B .,2019。使用深度学习进行数字土壤制图,土壤,5,79–89,https://doi.org/10.5194/soil-5-79-2019。

注 04/09/2018: 该文件尚未被接受,并在 2018 年 10 月 15 日之前接受公众审查和讨论。欢迎您参与这一过程。

注 27/02/2019: 论文已被接受并发表。

参考

道库恰耶夫,弗吉尼亚州,1883 年。黑钙土带土壤上层腐殖质含量示意图:对“俄罗斯黑钙土”一书的补充。

2003 年获学士学位的麦克布拉特尼、获硕士学位的桑托斯和获学士学位的米纳斯尼。论数字土壤制图。《地球学报》,第 117 卷第 1-2 期,第 3-52 页。

Padarian,b . minas ny 和 and McBratney:智利和智利土壤网格:对 GlobalSoilMap 的贡献,Geoderma Regional,9,17–28,2017。

Paterson,s .、McBratney,A. B .、Minasny,b .和 Pringle,M. J .:农业和环境应用的土壤特性变异图,载于:土壤计量学,第 623-667 页,Springer,2018 年。

承认

我要感谢我的编辑 Clara da Costa-Reidel 的更正。有一个有科学背景的人来校对你的作品真是太好了!

深度学习和视觉问答

原文:https://towardsdatascience.com/deep-learning-and-visual-question-answering-c8c8093941bc?source=collection_archive---------1-----------------------

视觉问答是关于建立一个计算机系统来回答用图像和自然语言表达的问题的研究领域。首先,我们来考察一下视觉问答中的三个数据集。

VQA 数据集

Figure 1. VQA Dataset from www.visualqa.org

在来自 www.visualqa.org 的VQA 数据集中,计算机系统需要解决问题,例如,二进制分类问题(伞是不是颠倒的?),一个计数问题(床上有几个孩子?),或者一个开放式的问题(谁戴着眼镜?孩子设定在哪里?)

CLEVR 数据集

Figure 2. CLEVR Dataset from Stanford

在斯坦福 的 CLEVR 数据集里,计算机系统需要回答关于物体的形状/颜色/大小/材料,以及其空间/逻辑关系的问题。

图 QA 数据集

Figure 3. FigureQA from Maluuba

在来自 Maluuba 的 图 QA 数据集中,计算机系统需要回答以条形图、饼状图或线图呈现的问题。

视觉问答和深度学习

因为视觉问答需要涉及图像识别和自然语言处理的技术,所以研究的一个主要方向是在深度学习上:使用卷积神经网络(CNN) 进行图像识别,使用递归神经网络(RNN) 进行自然语言处理,然后将结果组合起来给出最终答案,如图图 4 所示。

Figure 4. Combining CNN/RNN for VQA

Keras给出了视觉问答的通用模型,如图图 5** 所示。**

Figure 5. VQA/CNN/RNN Model from keras.io

  • 第 1–4 行:导入 Keras
  • 第 6–21 行:实现 CNN 进行图像识别
  • 第 23–26 行:实现自然语言处理的 RNN
  • 综合 CNN 和 RNN 的结果,给出最终答案

视觉问答与关系网络

视觉问答领域,一个有趣且重要的想法是由deep mind[12]提出的关系网络**。关系网的主要目的是探索图像和问题中呈现的对象之间的空间关系或逻辑关系,如***“…与图 6 问题中的*** 大小相同,以及***“…在图 7 问题中的*** 的左侧。**

Figure 6. non-relational questions and relational questions in CLEVR Dataset

Figure 7. the model of relation network

图 7 示出了视觉问答系统内部的关系网络的架构。注意,关系网络可能在基于对象到对象的或基于特征到特征的中探索关系。图 8 显示了 Keras/Theano 中特征提取关系提取的简单实现。

Figure 8. a simple implementaion of feature extraction and relation extraction in Keras/Theano

结论

****视觉问答是一项有趣的挑战,结合了不同的学科,包括计算机视觉、自然语言理解和深度学习。希望我们能在 Medium 下看到更多这方面的文章。

参考

[1] VQA 数据集

[2] CLEVR 数据集

[3] 图 QA 数据集

[4] 科拉斯 VQA 模型

[5] 来自 DeepMind 的关系网

[6] 视觉问答的人工智能进度测量

理解人类推理的深度学习方法

原文:https://towardsdatascience.com/deep-learning-approaches-to-understand-human-reasoning-46f1805d454d?source=collection_archive---------8-----------------------

对于一个正在使用深度学习来发现患者是否患有多发性硬化症的医生来说,从模型中获得是或否的答案一点也不好。对于自动驾驶汽车这样的安全关键应用,预测碰撞是不够的。迫切需要让机器学习模型对其断言进行推理,并向人类表达出来。由 Devi Parikh、Druv Batra【17】所做的视觉问题回答工作以及由费-李非团队所做的关于理解视觉关系的工作【16】是实现这一点的少数线索。但是在学习推理结构方面还有很长的路要走。所以在这篇博客中,我们将讨论,如何将推理整合到 CNN 和知识图中。

长期以来,推理被理解为一堆演绎和归纳。抽象符号逻辑的研究使得这些概念规范化,正如约翰·维恩在 1881 年所描述的。就像我们做的那些智商测试。A 暗示 B,B 暗示 C,所以 A 暗示 C,等等。把它想象成一堆逻辑方程。

但后来,这种固定的归纳/演绎推理的思想在 1975 年被扎德【2】所拆解,他在那里描述了近似推理的概念。它还引入了与数字变量(年龄=21、15、19、57、42、72)相对的术语,称为语言变量(年龄=年轻、非常年轻、非常年轻、非常年轻、年老、非常年老、非常年老),这形成了通过单词【3】建立模糊逻辑的基础。这是一种标准化,考虑到推理中的模糊性或歧义性。

例如,在我们的日常语言中,我们不会说“我在和一个身高 173 cm 的 21 岁男性说话,我会说“我在和一个高个子年轻小伙子说话。因此,模糊逻辑在构建推理模型时考虑到了论证的模糊性。

尽管包含了模糊性,但它不能抓住人类推理的本质。其中一个解释可能是,除了像“ A 不是 B,B 是 C,意味着 A 不是 C ”这样的简单推理之外,在人类理性的情况下,还有一个压倒性的隐含推理元素。在一瞬间,人类可以推断出事情,而不需要经过一系列的步骤。有时候这也是本能。如果你有一只宠物狗,那么你知道当你从它嘴里抢走玩具时它会做什么。

随着时间的推移,人类表现出抽象和改进推理的显式形式(一次性的、可区分的记忆)的非凡能力。这意味着它不是以纯粹的统计形式炮制出来的。基于统计学习【4】的语言模型是内隐学习的一个例子,在这里我们不使用任何规则、命题、模糊逻辑。相反,我们允许时间模型学习长程相关性【5】【6】。你可以把它想象成手机的自动完成功能。

您可以训练推理结构来预测最符合逻辑的短语,或者让统计方法来预测概率上合适的完成短语。

这些类型的模型不能用于单词或图像的罕见出现,因为它们由于罕见而忘记了这些信息。它也不能概括一个概念。例如,如果我们看到一种类型的奶牛,我们能够将我们的学习推广到所有其他类型的奶牛。如果我们听过一次话语,我们就能识别出它在不同口音、方言和韵律中的变体。

一次性学习【7】为学习一个罕见的事件铺平了道路,这是基于我们利用过去知识的能力,不管它多么不相关。如果一个人从出生起就只见过正方形和三角形,就像臭名昭著的猫实验【8】),然后第一次接触到一只鹿,一个人就不会仅仅把它记为一个图像,还会下意识地存储其相似度 w.r.t 正方形和三角形。对于一次性学习,记忆库变得必不可少。内存必须与核心模型交互,以使它更有效地学习和更快地推理。****

One Shot Learning

我知道你可能会纠结于这个学期。这里有一个简单的例子,我们用 Imagenet 进行一次性学习。现在把 1000 类图像网络想象成一场真人秀的评委,比如猴子、人类、汽车等等。每个人都根据是猴子还是人类的可能性来打分。

让我们假设有一个第 1001 个类的模型没有被训练。如果我从这堂课上拿两个项目,那么它们都不会给出一个有把握的分数,但是如果我们看看这两个项目的 1000 向量分数,它们可能有相似性。例如加拉帕戈斯蜥蜴,可能比任何其他类别的法官得到更多鳄鱼和蜥蜴的投票。评委们肯定会给加拉帕戈斯蜥蜴的图像打相似的分数,尽管它不在类别列表中,而且在训练数据中甚至没有一张图像。这种基于特征相似性的聚类是一次性学习的最简单形式。

桑托罗【9】最近关于记忆增强神经网络的工作考虑通过可微分的记忆操作来自动化与记忆的交互,这是受神经图灵机【10】的启发。

因此,网络学习决定它认为有用的特征向量,与它从未见过的类一起存储在可区分的存储块中。这种表现形式一直在演变。它赋予了神经网络学习“如何快速学习”的能力,这就是为什么他们称之为元学习。所以它开始表现得更像人类。我们把过去和现在联系起来的能力是惊人的。例如“如果我没有见过这种奇怪的外星生物,我仍然可以说它看起来更像狒狒或长着牛角的大猩猩。

从这次讨论中得到的关键信息是

1.基于模糊逻辑的纯显式推理未能抓住人类推理的本质。

2.像传统的一次性学习这样的隐式模型本身无法从罕见事件中归纳或学习。它需要增加记忆。

这种增强记忆的结构可以是由 cho,sutskever【5】【6】提出的 LSTM 的形式,或者它可以是像 santoro 最近的工作那样的动态查找表。【9】。这种动态查找可以基于本吉奥实验室的 Sungjin 提出的外部知识图【11】进一步丰富。这就是所谓的神经知识语言模型。

假设你想学习如何完成一个不完整的句子。现在,我可以通过简单的序列到序列模型来实现这一点。但是这样不好,因为命名实体很少出现。它以前很少听到“Crazymuse”。但是,如果我们学会从知识图中获取命名实体,通过识别主题或关系,并识别是从 LSTM 还是从知识图中获取,那么我们就可以用甚至很少的命名实体来完成句子。这是一种将丰富的知识图和神经网络结合起来的非常棒的方式。感谢 Reddit ML 组和“你在读什么”主题,我读了一组精选的论文。

现在,我们刚刚学到的知识打开了推理和推断的可能性,因为知识表示(主语、谓语、宾语)允许我们执行更复杂的推理任务,类似于显式模糊逻辑和隐式统计学习。

这种从知识图中学习检索的能力连同注意力机制【13】可以导向可解释的模型。

诸如 SQUAD【14】【15】之类的问答数据集的可用性有助于在可推断语言模型方面取得重大进展。近期作品在视觉问答【16】【17】【18】使用视觉基因组【19】、CLEVR【20】和 VRD【21】等数据集以

Evolution of Architectures to learn Reasoning

但是,尽管基于场景理解的背景问答有所进步,但还是有一些限制

1.将 LSTMs 用于基于记忆的模型并学习视觉关系方面的注意力转移【16】无疑提高了对上下文的理解和概括能力。但是在学习和提高推理的标准形式方面还有很多工作要做。

2.使用卷积神经网络的结构化流水线的窒息使得该模型对于人类解释是不透明的。它可能适用于基本分类和领域特定的生成任务,但不是为推理而设计的。相反,如果我们能够像 Tom Mitchell在“永不停止的学习”中提出的那样,直接学习知识图和本体中更丰富的多模态实体表示就好了。然后,我们可以学习跨领域的推理结构,并迫使模型更好地阐明其对实体关系的理解。

我梦想有一天,机器将学会推理。有一天,我们可以问机器,为什么你认为这个人有多发性硬化症。然后,它可以找到词语来阐明它的推理。我知道纳夫塔利在信息瓶颈原理方面的工作,以及林可唯的【24】在永无止境的学习方面的工作。但是缺少的是主动学习模糊逻辑提供的基本推理结构的抽象。你可以通过奖励来学习最优策略,或者基于一次性学习原则的某种验证,或者一些基于半监督图的方法来驱动它。但是不管驱动因素是什么,模型都需要学习提高推理能力。模型需要学习将这个推理引擎与来自声音或图像的丰富特征表示关联起来,这甚至可能催化“改进表示、改进推理、改进表示、改进推理”的循环,就像策略迭代一样。最重要的是,模型应该能够清晰地向人类表达抽象概念,并说,“嘿,人类,我认为猫很可爱,因为它们的眼睛像婴儿的眼睛,充满活力,不像你单调的日常生活”

在那之前,让我们继续训练模型,继续梦想模型建立并运行的那一天。因为梦想变成现实的速度超乎你的想象!

关于我

Jaley 是 youtuber 和创作者在Edyoda(www . Edyoda . com)。他过去是哈曼公司的高级数据科学家,对人类推理的结构非常好奇。****

独立研究刊物 鼓掌表示支持。

我的微课相关知识图

课程链接: 知识图谱与深度学习

参考

约翰·维恩[1]。符号逻辑。1881.

【洛杉矶】扎德。语言变量的概念及其在近似推理中的应用——信息科学,8(3):199–249,1975。

洛特菲·扎德。模糊逻辑=用文字计算。IEEE 模糊系统汇刊,4(2):103–111,1996。

[4] 尤金·查尔尼亚克。统计语言学习。麻省理工学院出版社,1996 年。

[5] 赵京贤、巴特·范·梅林波尔、卡格拉尔·古尔切雷、迪米特里·巴丹瑙、费特希·布加雷斯、奥尔赫·施文克和约舒阿·本吉奥。使用 rnn 编码器-解码器学习用于统计机器翻译的短语表示。arXiv 预印本 arXiv:1406.1078,2014。

伊利亚·苏茨基弗、奥里奥尔·维尼亚尔斯和阔克·V·勒。用神经网络进行序列间学习。《神经信息处理系统进展》,第 3104–3112 页,2014 年。

李菲菲、罗布·弗格斯和皮埃特罗·佩罗娜。对象类别的一次性学习。IEEE 模式分析和机器智能汇刊,28(4):594–611,2006。

大卫·罗斯和科林·布莱克莫尔。猫视觉皮层的方位选择性分析。实验性大脑研究,20(1):1–17,1974。

[9]亚当·桑托罗、谢尔盖·巴图诺夫、马修·伯特温尼克、金奎大·威斯特拉和蒂莫西·莉莉卡普。记忆增强神经网络的元学习。在机器学习国际会议上,第 1842-1850 页,2016 年。

亚历克斯·格雷夫斯、格雷格·韦恩和伊沃·达尼埃尔卡。神经图灵机。arXiv 预印本 arXiv:1410.5401,2014。

[11] Sungjin Ahn、Heeyoul Choi、Tanel Pä rnamaa 和 Yoshua Bengio。一种神经知识语言模型。arXiv 预印本 arXiv:1608.00318,2016。【12】凯文·徐、吉米·巴、瑞安·基罗斯、赵京贤、亚伦·库维尔、鲁斯兰·萨拉库迪诺夫、里奇·泽梅尔、约舒阿·本吉奥。展示、参与和讲述:具有视觉注意力的神经图像字幕生成。在机器学习国际会议上,第 2048–2057 页,2015 年。

[13] 罗伯特·戴西蒙和约翰·邓肯。选择性视觉注意的神经机制。神经科学年度评论,18(1):193–222,1995。

[14] 普拉纳夫·拉杰普尔卡、、康斯坦丁·洛皮列夫和珀西·梁。小队:机器理解文本的 10 万+题。arXiv 预印本 arXiv:1606.05250,2016。

[15] Pranav Rajpurkar,Robin Jia 和 Percy Liang。知道你不知道的:无法回答的问题。arXiv 预印本 arXiv:1806.03822,2018。

兰杰·克里希纳、伊内斯·横山雅美、迈克尔·伯恩斯坦和李菲菲。推荐关系。IEEE 计算机视觉和模式识别会议论文集,第 6867-6876 页,2018 年。

[17]斯坦尼斯劳·安托尔、艾西瓦娅·阿格拉瓦尔、贾森·卢、、德鲁夫·巴特拉、C·劳伦斯·兹尼克和德维·帕里克。Vqa:视觉问答。IEEE 计算机视觉国际会议论文集,第 2425–2433 页,2015 年。

[18] 吴起、王鹏、沈春华、安东尼·迪克和安东·范·登·亨格尔。Askme anything:基于外部资源知识的自由形式的可视化问题回答。IEEE 计算机视觉和模式识别会议论文集,第 4622–4630 页,2016 年。

[19] Ranjay Krishna,Zhu,Oliver Groth,,Kenji Hata,Joshua Kravitz,,Yannis Kalantidis,Li-李嘉,David A,等.视觉基因组:使用众包密集图像注释连接语言和视觉.国际计算机视觉杂志,123(1):32–73,2017。

[20]贾斯廷·约翰逊、巴拉思·哈里哈兰、劳伦斯·范德马腾、李菲菲、劳伦斯·兹尼克和罗斯·吉希克。Clevr:组合语言和初级视觉推理的诊断数据集。计算机视觉与模式识别(CVPR),2017 年 IEEE 会议,第 1988–1997 页。IEEE,2017。

[21] 吴策·卢、兰杰·克里希纳、迈克尔·伯恩斯坦和李菲菲。基于语言先验的视觉关系检测。在 2016 年欧洲计算机视觉会议上

【22】纪、、何、徐、、。基于动态映射矩阵的知识图嵌入。《计算语言学协会第 53 届年会暨第 7 届自然语言处理国际联合会议论文集》(第 1 卷:长论文),第 1 卷,第 687–696 页,2015 年。

[23] 安托万·博德斯、尼古拉斯·乌苏尼尔、阿尔韦托·加西亚·杜兰、杰森·韦斯顿和奥克萨纳·亚赫年科。翻译用于多关系数据建模的嵌入。《神经信息处理系统进展》,第 2787-2795 页,2013 年。

[24] 汤姆·米切尔,威廉·科恩,埃斯特瓦姆·赫鲁什卡,帕萨·塔鲁克达尔,杨博,贾斯汀·贝特里奇,安德鲁·卡尔森,B·达尔维,马特·加德纳,布莱恩·基西尔,等.永无止境的学习.ACM 通讯,61(5):103–115,2018。

大规模深度学习:-精确、大型迷你批量 SGD:

原文:https://towardsdatascience.com/deep-learning-at-scale-accurate-large-mini-batch-sgd-8207d54bfe02?source=collection_archive---------4-----------------------

使用分布式计算(😄大数据)有一段时间,我想知道深度学习算法如何扩展到多个节点。脸书人工智能研究中心(FAIR)最近发表了一篇论文,介绍了他们如何在 ImageNet 数据集上成功运行 resnet-50 层模型,使用 256 个 GPU 在一小时内小批量处理 8192 张图像。我相信本文中介绍的许多信息适用于试图在多 GPU 设置上快速构建模型的每个人。在这篇文章中,我总结了论文中的关键观点,当你试图扩展深度学习实现时,这些观点将是有用的。

关键见解:

  1. 分布式同步 SGD 提供了一种解决方案,可以将 SGD 小批量划分到一堆节点上,这些节点可以是多个 GPU。
  2. 大的小批量导致优化困难,并且有解决它的技术。
  3. 使用线性比例规则来调整学习率,学习率是小批量和预热方案的函数。

为什么规模很重要?

最近的事实证明,当提供大量数据时,深度学习算法工作得更好。随着更多的数据,它显示了计算机视觉,自然语言处理和语音领域的巨大进步。但是,在 256 个节点的规模上运行像 Resnet -50 这样的架构也有其自身的挑战。

什么是分布式同步 SGD?

下面是 SGD 公式。

其中 X 是总数据集,X 是来自数据集的样本,l(x,w)是针对标签的每个样本计算的损失(交叉熵损失)。

但在实践中,我们使用迷你批量 SGD,计算每批的损耗和梯度,并相应地修改权重。如下所述。

其中β代表最小批量,它是 X 的子集。

在分布式同步 SGD 的情况下,每个 GPU 在小批量数据的子集上运行相同的图形,一旦 GPU 完成处理,权重被传输到参数服务器,参数服务器聚集来自多个 GPU 的所有梯度并发送回它们。

需要应用一些技巧,如线性缩放、预热策略,以使模型达到与在单个 GPU 上以较小批量训练的模型相当的结果。

Source : Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour

为什么技巧很重要?

使用 1000 数量级的大批量的一个主要挑战是,当以正常学习速率训练时,梯度倾向于振荡。因此,实验表明,当批量增加时,很难进行训练。

提出了三种重要的解决方案来缓解上述问题。

  1. 线性标度法则
  2. 热身策略
  3. 大型迷你批次的批次标准化

什么是线性比例法则?

使用大批量的能力对于跨多个工作节点并行处理图像是非常有用的。所有的线性比例规则说的是将学习率提高“k”倍。其中“k”是批量增加的次数。虽然这个规则很简单,但它却是一个强有力的规则。

Source : Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour

带有(a)的图像显示了仅应用线性比例规则时模型的表现。查看结果,很明显,批量大小为 8k 的模型表现得几乎与用正常批量训练的模型一样好。预热策略有助于模型表现得与用较小批量训练的模型一样好。

什么是热身策略?

讨论了两种标记策略。一种是持续预热和逐渐预热。

**恒定预热:**在恒定预热中,你用很小的学习率对模型进行几个时期(文中 5 个时期)的训练,然后将学习率提高到“k 倍学习率”。然而,当学习速率改变时,这种方法导致训练误差的尖峰。在上面的(b)图中可以看到观察结果。与简单的线性标度规则相比,模型的训练误差也更高。

**渐进热身:**顾名思义,你从一个小的学习速率开始,然后在每个历元以一个常数逐渐增加,直到达到“k 倍学习速率”。这种方法有助于模型在大批量(本例中为 8k)时表现更好,这与用较小批量训练的模型的训练误差相当。

使用大批量时,批量规范化有什么特殊之处?

批次归一化计算小批次中样本的统计数据。当我们计算跨多个节点的样本损失时,一个样本的损失独立于另一个样本是很重要的。但是,当您使用批量标准化时,一个样本的损失函数不再独立于其他损失函数。计算的小批量统计数据是损失的关键组成部分。如果每个工人的小批量样本大小发生变化,它会影响正在优化的基本损失函数。

因此,建议在所有工人节点上保持最小批量大小相同,在本文中,每个工人有 32 个样本,工人数量为 256。应该在节点(大小为 32)级别而不是批处理级别(大小为 8k)计算批处理规范化。

分布式 SGD 的微妙之处和缺陷:

  1. 缩放交叉熵损失不等同于缩放学习率。
  2. 有两种应用动量的流行方法,一种是在使用学习率之前计算(eq 9),另一种是使用学习率(eq 10)。

Source : Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour

Source : Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour

观察到在改变学习率之后应用动量校正提供了更多的训练稳定性。

3.执行梯度聚合时,通过 kn 而不是 n 来归一化每个工作节点中的梯度。“n”表示每个工作节点处理的样本数,“k”表示工作节点的总数。

本文还描述了用于网络通信的算法、使用的软件、使用的硬件以及使用各种超参数进行的实验。如果你打算尽快扩大规模,这是一本必读的书。

很快会看到另一篇文章😃

深度学习笔记,第三章(第一部分):概率导论

原文:https://towardsdatascience.com/deep-learning-book-notes-chapter-3-part-1-introduction-to-probability-49d13c997f2a?source=collection_archive---------8-----------------------

这些是我对深度学习这本书第三章的笔记的第一部分。它们也可以作为概率的快速入门。这些笔记涵盖了这一章的大约一半(介绍性概率的部分),后续的文章将涵盖其余部分(一些更高级的概率和信息理论)。

我在第二章的笔记可以在这里找到:

[## 深度学习笔记,第 2 章:用于深度学习的线性代数

这些是我对深度学习书第二章的笔记。它们也可以作为线性代数的快速介绍…

becominghuman.ai](https://becominghuman.ai/deep-learning-book-notes-chapter-2-linear-algebra-for-deep-learning-af776cf52506)

像往常一样,这篇文章基于一个 Jupyter 笔记本,可以在这里找到。

书籍推荐

可能性

出自本书:

  • 概率论:科学的逻辑 杰恩斯著。
    我的评论: (还)没看。然而,如果你是概率新手,我不建议你这么做。引用这本书的序言: “下面的材料是写给已经熟悉应用数学的读者的,在大学本科或更高的水平。”你可能不知道高等本科或更高层次的应用数学,如果你知道,你可能已经知道足够的概率,这可能不是你目前的主要优先事项。也就是说,这绝对是一本关于概率的经典研究生教材,值得放在你的数学书籍清单上阅读。请注意,它没有太多的练习,而且它所做的练习更多的是关于完成书中的证明,而不是练习(我猜这与它是一本研究生书是一致的)。

本人推荐:

  • 概率导论布利茨坦和黄。
    我的评论: 不错,引人入胜的书,很好地覆盖了概率最重要的方面。使用故事、代码和许多练习,其中一些有在线解决方案。 100%推荐,如果你已经不太懂概率的话肯定适合。请注意,你需要了解一些微积分来阅读它,因为概率经常涉及积分和导数。
    我唯一的批评:有解决方案的练习太少,练习的交错应该更精细(即应该在每一节的结尾有练习,而不是在每一章的结尾),如果代码是 Python 而不是 R 就好了;).
    这本书也是基于哈佛大学的统计数据 110,你可以在这里观看:

  • 贝特塞卡斯和齐茨克里斯的概率 导论。
    我的评论: 没看过,但显然挺有说服力的。应该与上面的另一本《概率导论》相当相似,事实上,几乎可以说这本书是“麻省理工版本”,而前一本是“哈佛版本”。这个还附带了开放式课程视频:

  • 海明的概率艺术 。我的评论:我没有读过这本书,但我确实买了它,因为我在研究为这篇文章推荐的书籍,因为它看起来很有竞争力。引用其中一篇评论:
    “海明对概率的贡献就像费曼在他的讲座中对物理学的贡献一样。” 这本书似乎也呈现了一些信息论,这是我们目前深度学习书章节的另一个话题!

  • *数学和尚 概率初级读本
    **我的评论:*这是一个 Khanacademy 风格的 youtube 播放列表。我把它包括在内,因为这可能是学习一些应用于概率的测度理论的最简单的方法,因为我相信除了杰恩斯以外,上面没有任何一本书提到测度理论。深度学习需要了解什么测度理论吗?几乎肯定不会,但人们可能会参考它(例如,深度学习的书会参考),对它有一些模糊的概念会很有用。

信息论

出自本书:

  • 信息论的要素 由盖和托马斯。
    我的评论: 没看过。坦白地说,我从来没有读过任何一本专门关于信息论的书。然而,这基本上被认为是信息论上的经典。坦白地说,对于深度学习,你可能不需要非常深入地了解信息论,但如果你确实想学习它,阅读这本书似乎是一个不错的方法。
  • 信息理论、推理和学习算法 麦凯著。
    我的评论: 我也没看过。然而,我推荐它多于,原因如下:
    -它在亚马逊上的评论比封面&托马斯好。
    -它明确涵盖了机器学习背景下的信息论。
    -是免费的!!!!!!!!!

我的推荐:

(目前)没有。

可能性

什么?

也许描述概率的一种方式类似于逻辑,但是当不确定性出现时。

例如,逻辑可以接受“如果某物会飞,那么它是一只鸟”和“如果某物是一只鸟,那么它是美味的”这样的陈述,并允许我们推断出“如果某物会飞,那么它是美味的”,但是在并非所有会飞的都是鸟或者并非所有是鸟的都是美味的情况下,它对我们没有帮助。概率可以:有了概率,我们就可以知道“如果一个东西会飞,那么有 90%的可能是一只鸟”和“如果是一只鸟,有 80%的可能是美味的,否则肯定不好吃”。由此我们可以推断,有 72%的可能性会飞的东西是美味的,这是我们用逻辑无法做到的。

“频繁主义者”和“贝叶斯”对概率的解释是有区别的……我不会对此做过多解释。坦率地说,大多数人通常在不同的情况下使用这两种方法,这本质上可以归结为,他们接受我们在日常生活中用概率语言谈论的几乎所有事情确实是概率。

这里有一个关于这个话题的有趣视频:

为什么?

那么深度学习为什么需要概率呢?根据这本书,有两个原因:

  • 概率推理在这个世界上是必要的,因为很少有事情是确定的,所以我们的人工智能系统应该使用概率规则进行推理。
    举一个具体的深度学习例子,就拿下面的 MNIST 形象来说。是奇怪的 4 还是奇怪的 9?结果是 4,你可能会认为这是最合理的答案,但我相信你不会肯定地说,这就是为什么你的深度学习算法似乎也不必肯定地给出答案。

  • 我们经常需要对深度学习算法进行概率分析。
    举个简单的例子,当我们评估一个分类模型时,我们经常使用它的
    准确度*,这毕竟是模型在给定一个例子的情况下输出正确答案的概率。更复杂的是,我们可以问这样的问题,比如“如果我给它 N 个例子来训练,我的算法将具有精度 X 的概率是多少”,就像在 PAC learning 中一样,等等。*

在我看来,有一个关键的原因被忽略了,那就是逻辑是离散的而概率是连续的*。就拿这张图来说吧,是狗还是猫?*

我想我们都同意这里不涉及概率。这绝对是一只 100%的猫,所以上面的“很少事情是确定的”论点不应该适用。

事实上,我认为它没有,但对我们的模型来说,返回某样东西是猫而不是确定性的概率仍然很重要,因为概率是连续的而确定性不是:如果我们的算法输出确定性,并认为上面的图片是一只狗,那就真的很难知道如何改变它的参数,以便它输出正确的答案,而不会破坏它在例子上的表现。相比之下,对于概率,有一个简单的方法来增加图片是一只猫的概率,我们在第四章会看到。

不确定性来源

这本书给出了 3 个(或者可以说是 4 个)不确定性的来源。我认为有可能将它们合二为一:

  • “真正的”随机性(“随机性”只是“随机性”的一个花哨说法):有时候这个世界真的在抛硬币,你必须处理好这个问题。一个深度学习的例子是语言建模,其中深度学习模型需要在给定一系列先前单词的情况下预测下一个单词。如果我给你一个句子“法国是一个……”,你能预测下一个单词是什么吗?不,因为它实际上可以是任何数量的东西:就在法国的维基百科页面上,这些词后面是“国家”、“统一”、“发达”、“创始”、“成员”和“永久”。这本书区分了“固有的随机性”和“不完全的可观察性”。在我看来,这通常不是一个有用的区别:如果有人抛硬币,答案是随机的,因为有实际的量子过程决定它最终在哪一边,还是看起来是随机的,因为我们没有硬币旋转速度、空气分子密度等信息。?答案几乎总是:没关系。
  • 建模不完整:有时候你就是不能对所有事情建模,或者不想建模。
    再次以语言建模为例,事实是尽管最近取得了真正的进步,但计算机仍然无法像人类一样理解语言,这有时意味着人类可以 100%的概率预测句子中的下一个单词,而机器还不能。这意味着我们的算法需要依赖输出概率,因为它们还不够好。类似地,你可能会认为,对确定某件事所涉及的所有复杂性进行建模太高了,你有时犯错误也没关系。书中的例子很好地说明了这一点:记住“大多数鸟都会飞”比记住“除了生病、受伤或非常年幼的鸟,以及几维鸟、鸵鸟、鸸鹋等,所有的鸟都会飞”要便宜得多。

随机变量

随机变量是其值随机变化的“变量”。

从代码的角度来看,这没有任何意义,所以你可以把随机变量想象成一个不带参数的函数,返回一个随机值。这是一个随机变量 X 的例子,它是随机的 1 或 2。

所以当我谈论随机变量 X 时,你可能会问,我是在谈论用def X(): ...定义的函数,还是在谈论通过调用X()得到的返回值?

答案是:看情况。事实是,数学符号是如此草率,但在实践中,它通常会直截了当地指出人们是在谈论def X(): ...还是X()

最后要注意的是,如果随机变量在数学表达式中作为一个数字使用,它通常不会每次都重新计算,所以例如:X < 1.5 and X > 0.5 意味着:

不是

随机变量可以是连续离散*。难道而不是读连续和离散随机变量的定义,是因为它是错误的,而且我不是指“有点简化”中的“错误”,而是更多的“错误”是指“如此简化,以至于人们会错误地认为某些 r.v.s 实际上是连续的却是离散的,这完全错过了为什么一开始就有区别的要点”。*

以下是我认为保持准确性的两者的简化定义:

  • 离散随机变量是一种随机变量,它只能返回(也称为“接受”)“断开的”值。换句话说,在它能返回的任意两个数之间,还有其他数(实际上是无穷多个)是它不能返回的。
    例如,我们上面的变量 X 是离散的,因为它只能返回 1 或 2,而不能返回 1.5、1.25、1.58928921 或 1 和 2 之间的任何其他数字。同样,即使一个变量可以取下列任何一个数字:0.5,1,1.5,2,2.5…等等,它也是离散的,尽管它有无限的可能性。
  • 一个连续的随机变量可以取一个(或几个)区间上的任何值。
    例如,下面的变量 Y 可以取 0 到 1 之间的任何数字。它能达到 0.03920 吗?是的。0.23?是的。等等。

这种区别很重要,原因有二:

  • 离散的随机变量可以用正规的算术来处理。连续随机变量需要微积分。
  • 一个离散随机变量可以取的所有值都有大于 0 的概率。一个连续的随机变量可以取的所有值有一个概率…等于 0!
    想想下面的变量 Y:0 到 1 之间的每一个数被 Y 返回的概率都是一样的……但是 0 到 1 之间有多少个数呢?无限!所以不可能每个数字的概率都大于 0,因为否则总的概率将等于无穷大。

分发、PMF 和 pdf

分布是描述随机变量不同可能输出的概率的一种方式。分布可以告诉我们一个随机变量输出一个给定值或一个给定区间值的概率是多少。

在 Python 中,scipy.stats模块支持许多发行版。我们将在这里解释一下如何探索这个模块。

离散分布有一个概率质量函数(PMF)。它接受一个值并输出一个概率,例如,如果 P 是上面变量 X 的 PMF,则 P(1) = 0.5。有时我们写 P(X = 1),这样我们就确定它是 X 的 PMF

如果你画出这个函数,x 轴将显示它可以取的不同值,而 y 轴将显示该值的概率。当然,所有 y 值之和必须等于 1,因为随机变量的概率之和必须为 1。

scipy 支持的离散分布可以在这里找到。这允许我们使用已知的分布创建随机变量,这比编写自己的函数更方便。需要注意的一点是,为了从一个 r.v .中采样,我们现在需要调用 distribution 对象上的rvs()函数。例如,让我们从“二项式”分布中取样:

因为离散 r.v .的值是不连续的,所以 PMF 看起来像这样“尖尖的”:

对于多个变量可以有一个 PMF,在这种情况下我们称之为“联合 PMF”。所以 PMF P(X = x,Y = y)给出了 X 等于 X,Y 等于 Y 的概率,通常这与 X 等于 x 乘以 Y 等于 Y 的概率相同,但并不总是如此(见下文)。

这是一个联合 PMF 的样子:

另一方面,连续随机变量具有概率密度函数。它也是 r.v .可以取的值的函数,但是它不而不是返回给定值的概率:正如我们已经说过的,对于每个可能的值,概率都是 0。

然而,我们可能想要表达这样的概念,例如,接近 0 的值应该比接近* 2 的值更有可能,即使 0 和 2 的概率都是 0。这就是概率密度函数的用武之地:在 x ( p(x) )的 PDF p 的值与得到一个在区间*内非常接近 x 的数的概率成比例。**

具体来说,它是这样定义的,即值落在一个区间内的概率是该区间内 PDF 曲线下的面积。换句话说,要获得某个区间内的值的概率,你需要对该区间内的 PDF 进行积分,就像如果你想对一个离散的 r.v .做同样的事情,你需要对该区间内的 PMF 值求和:积分基本上是求和的连续等价物。

遗憾的是,与求和不同,手工积分相当困难。幸运的是,借助现代软件,有两种方法可以轻松获得积分:

  • 使用 Wolfram Alpha ,你通常可以获得积分的精确解析解:例如,只需写下“integrate 2x+1 from 0.1 to 0.8”,Wolfram Alpha 就会告诉你确切的答案,即 1.33。
  • 在 python 中使用 scipy:可以使用scipy.integrate.quad。它返回的第一个值是积分,第二个值可以忽略(这是对答案中可能存在的误差的估计,因为数值积分是一个近似过程)。

scipy 中的连续分布可以在这里找到。让我们重新定义上面的 r.v. Y,你会记得它是从 0 到 1 均匀分布的:

正如我们所记得的,Y 是一个连续的随机变量,从 0 到 1 的所有值被选中的概率相等,而 0 以外的所有值被选中的概率为 0。让我们展示一下它的 PDF 格式:

我们预计 Y 返回一个介于 0.3 和 0.4 之间的数字的概率是 0.1,因为该区间覆盖了允许范围的 10%。同样,很明显,值落在 0 和 1 之间的概率一定是 1,并且它落在-1 和 2 之间的概率也一定是 1。

让我们通过整合来检查:

就像 PMF 一样,一个 PDF 可以关联到两个不同的随机变量。我们称之为“联合 PDF”。下面是一个例子:

排斥

如果给你一个联合 PMF,想知道单个变量对应的 PMF 或者 PDF 怎么办?换句话说,你知道 P(X=x,Y=y),想知道的只是 P(X=x)。

从逻辑上看,X = x 忽略 Y 的概率应该是 X=x Y=0(或者 Y 的第一个可能值)的概率加上 X=x Y=1 的概率,等等。换句话说,我们对所有可能的 Y 取 P(X=x,Y=y)的。在数学上:

这个过程确实是正确的,叫做边缘化。X 的最终分布称为边际分布。让我们看看 PMF 是什么样子,提醒一下,我们在join_probabilities变量中有一组联合概率:

**

在这种情况下,我们恢复了 X 的原始 PMF,因为joint_probabilities包含了独立变量的概率。情况不一定总是如此。

边缘化也适用于 pdf,同样,唯一的区别是我们需要在所有可能的 y 上使用积分,而不是 sum,即:

让我们看看当我们在之前的连续连接 PDF 中边缘化 X 时会是什么样子:

**

也许一种看待边缘化的方式是一种“挤压”的形式:想象沿着 y 轴压缩你在上面看到的 3D 图片,将概率质量推到它自己的顶部,直到 3D 图形完全变平,只留下原始的 x 轴。

当然,因为你可以有两个以上变量的联合分布,这个可视化只能到此为止,但是记住我们上次的引用:

要处理一个 14 维的空间,想象一个 3 维的空间,大声对自己说“14”。每个人都这样做。

杰弗里·辛顿

条件概率

边缘化可以让我们从 X 和 Y 的联合分布中得到忽略变量 Y 的变量 X 的分布,但是如果给定 Y 的一个特定值,我们想知道 X 的分布呢?

给定 Y,这个概率称为 X 的条件概率,表示如下:

在这种情况下,竖线通常读作“given”。

举个具体的例子,假设你想知道某人是否来自德国,你知道他说一口流利的德语。以下是显示世界上说德语且居住在德国的人口比例的联合 PMF:

**

怎么知道说德语的人是德国人的概率?看起来你需要知道世界上有多少人说德语,以及德国总共有多少人。事实上,在这两种情况下,你都不需要实际的人口数量,世界人口的比例就足够了。换句话说:

我们得到分母的方法当然是使用如上所述的边缘化*,即把生活在德国的每个人的语言相加。*

我们得到:

84.2%的几率,这当然不足为奇,因为德国是一个讲德语的大国。

正如您可能猜到的,一般规则如下:

将这个规则应用于 X 的所有可能值,我们得到一个新的分布,称为给定 y 的 X 的条件分布。

类似于我们所说的边缘化可以被认为是“挤压”联合分布的图形,采用条件分布类似于切割图形,然后重整图形,使得最终分布仍然总计为 1。让我们沿着 Y = 1.0 对之前的 3D 关节 PDF 进行“切片”:

**

重要的是不要将条件概率与实际可行的东西混淆。在我们德国的例子中,很明显,教某人德语并不会使他们更有可能来自德国,但是这个陷阱通常并不那么明显。

条件概率链规则

我们现在知道如何从联合分布到边际分布,从联合边际分布到条件分布。现在,让我们完成从边际和条件分布到联合分布的循环。

这个过程非常简单。假设你知道一个人说德语是德国人的概率,也知道世界上任何地方的人说德语的概率,你想知道一个人既是德国人又会说德语的概率。看起来你需要简单地将条件概率和边际概率相乘:

事实上,这直接来自上面条件概率的定义。

总的来说:

贝叶斯法则

最后假设你不想知道你的朋友是德国人的概率,而不是他会说德语,而是想知道某人会说德语的概率,因为他们来自德国。

当然,我们可以使用以前的完整联合 PMF 表来完成,但不幸的是,我们并不总是能够访问这些表。假设我们从上面知道了概率(说德语的人来自德国),以及世界上任何地方的人是德国人的概率和世界上有人说德语的概率。我们能搞清楚吗?

当然,我们只需要恢复联合概率,我们在上面做过,然后除以德国人的比例。

一般来说,我们有:

(来自条件概率的定义)

所以:

(来自条件概率的链式法则)。

这最后一个等式以贝叶斯法则而闻名。它在许多情况下都非常有用,尽管你可以看到,尽管它的名字很花哨,但它只是我们定义的一个简单应用。

最后的话

以上仅涵盖了第三章的大约一半。这比我预期的要花更长的时间来写,我认为我们已经在材料中取得了很好的自然突破(剩下的更多的是各种有趣的技术的大杂烩),所以我将在随后的帖子中完成第三章的笔记。回头见!

深度学习第十章:序列建模:递归和递归网络

原文:https://towardsdatascience.com/deep-learning-chapter-10-sequence-modeling-recurrent-and-recursive-nets-68aee18c5eae?source=collection_archive---------5-----------------------

我们有幸请到了作者 Ian Goodfellow 介绍《第 10 章序列建模:深度学习的递归和递归网络》一书。

以下是他在演讲中提到的论文列表:

用于递归神经网络序列预测的预定采样
教授强制:用于训练递归网络的新算法
用于训练非常深的前馈网络的随机行走初始化
层归一化
多预测深度玻尔兹曼机器

我希望你喜欢伊恩的演讲!

我们刚刚完成了该书的第二部分,并将从 8 月 28 日开始复习第三部分:深度学习研究。即将举行的活动时间表:

08/28 13 线性因子模型
09/05 14 自动编码器
09/11 15 表征学习
09/18 16 用于深度学习的结构化概率模型
09/25 17 蒙特卡罗方法
10/02 18 面对配分函数【T33

我希望你能加入我们!

书:

深度学习书籍是唯一一个教授深度学习核心原则的有组织的出版物。这本书可以在网上免费获得:http://www.deeplearningbook.org/

俱乐部:

深度学习读书会 是留出一段时间来复习书中的资料,一起解决问题。每周,我们行业专家都会介绍一个章节。我们每周一下午 6:30-8:30 在旧金山霍华德街 101 号的 USF 数据研究所会面。

对未来事件的 RSVP:

**过往事件录音在此有:https://www.youtube.com/c/AlenaKruchkova

我现在挖的东西:

  1. fast.ai 的雷切尔·托马斯(Rachel Thomas)开设了令人惊叹的计算线性代数课程*。这是一门“完全以实际应用为中心”的课程,使用了“前沿算法和工具”。
    https://github . com/fastai/numerical-linear-algebra/blob/master/readme . MD***
  2. 奥莱利人工智能大会在旧金山举行,拥有一个令人印象深刻的发言人名单:
    https://conferences . oreilly . com/artificial-intelligence/AI-ca
    如果你在那里见到我,打个招呼!

深度学习第三章:概率与信息论

原文:https://towardsdatascience.com/deep-learning-chapter-3-probability-and-information-theory-36c64d7f376c?source=collection_archive---------6-----------------------

在 5 月 15 日的第三次会议上,我们复习了第三章:概率和信息理论。(这本书可以在网上免费获得:【http://www.deeplearningbook.org/】T2

我们有一个由 Pierre Dueck 所做的可爱的报告,它引起了很多讨论!你可以在这里观看:

完全披露:我们没有谈到信息论。我们希望尽快解决这个问题,见下文。

我们还与特邀嘉宾亚历山大·托舍夫进行了问答。亚历克斯是谷歌大脑的研究工程师,专门研究计算机视觉,你可以在这里查看他的出版物:https://research.google.com/pubs/AlexanderToshev.html

我们的下一次会议是在 5 月 22 日星期一。我们将讨论第 4 章:数值计算。这是我们深入研究 ML 和 DL 之前的最后一章。

雅罗斯拉夫·布拉托夫将回来做报告,由于第四章很短,我们可以进一步回顾线性代数和概率/信息理论。

所以进来准备好测试他所有这些科目!

在接下来的 12 周里,我们每周一都会见面。有关未来的活动,请查看我们的 meetup 页面。我们将通过这个链接获得现场直播:https://youtu.be/-l1JGI-cCvY

深度学习第四章:数值计算

原文:https://towardsdatascience.com/deep-learning-chapter-4-numerical-computation-14de09526931?source=collection_archive---------4-----------------------

第四章:数值计算由雅罗斯拉夫·布拉托夫提出。

在我们讨论第 3 章的时候,我们没有机会复习这一章的信息论部分,所以在我们进入第 4 章之前,我们请雅罗斯拉夫给我们一个快速的概述。

然后我们继续讨论数值计算。雅罗斯拉夫用他自己的幻灯片(请见下面附的幻灯片)向我们概述了这一章,然后在演示结束时浏览了 Ian Goodfellow 的幻灯片。

[## presentation.pdf

雅罗斯拉夫·布拉托夫的数字计算幻灯片

drive.google.com](https://drive.google.com/open?id=0B653sCwrWAVNclZZRU5fdkRkakU)

这是我们深入 ML 和 DL(也称为有趣的东西)之前的最后一章:),所以请继续关注不久的将来的更多帖子。

我们每周一都会在 USF 数据研究所见面。对于未来的活动,请查看我们的 meetup 页面。下一次会议在 2017 年 6 月 12 日星期一下午 6:30-8:30 我们将讨论第 5 章:机器学习基础。我们将有一个现场直播的链接:https://youtu.be/-l1JGI-cCvY

深度学习第六章:深度前馈网络

原文:https://towardsdatascience.com/deep-learning-chapter-6-deep-feedforward-networks-d0e40758b555?source=collection_archive---------4-----------------------

上周我们讨论了深度学习一书的第六章(这本书可以在网上免费获得:http://www.deeplearningbook.org/)。

讨论由蒂莫西·库尔主持。Timo 拥有宾州大学计算机视觉博士学位,曾在谷歌地图担任 ML 工程师。目前,他是 Lighthouse AI 的高级机器学习工程师,他们正在为你的家建造眼睛。仅供参考,他们正在招聘;)

Andrej Karpathy (OpenAI 研究科学家,cs231 stanford 计算机视觉课程讲师)的一篇文章,讲述了理解前馈网络的重要性:https://medium . com/@ kar pathy/yes-you-should-understand-back prop-e 2f 06 eab 496 bBTW cs 231n 是对深度学习的惊人介绍,当然还有我们最喜欢的书。

我希望你喜欢蒂莫西关于前馈网络的介绍!

我对即将到来的事情感到非常兴奋!

第七章正规化将由雅罗斯拉夫布拉托夫呈现!他很兴奋!我引用他的话:“我想展示优化,但我记得我也很喜欢正则化。”:)这一章有点长,但比其他一些章节组织得更好,所以我想我们会很开心。RSVP 这里:https://www . meetup . com/Deep-Learning-Book-Club/events/240769087/

第 8 章优化讨论将由 Vazgen Hakobjanyan 主持。瓦兹根是耶里万研究实验室的董事会成员。这些家伙真的很棒!看看这篇最近的论文https://arxiv.org/abs...
他们的数字图书馆指南被谷歌排名第一,因为它太棒了——你应该使用它!【http://yerevann.com/a...】T21 回复此处:https://www . meetup . com/Deep-Learning-Book-Club/events/240769100/

第九章 CNN 将由路易·莫尼耶主持。我无法告诉你,让他来主持这场讨论,我有多兴奋!他是一位行业资深人士,如果你不知道他的许多成就,你应该谷歌一下他:)目前他是 Airbnb 人工智能实验室的负责人。但最重要的是,他是一位出色的教育家,对揭开艾的神秘面纱充满热情!RSVP 这里:https://www . meetup . com/Deep-Learning-Book-Club/events/240769114/

然后我们有杰瑞米·霍华德回来了!严重昏厥

如果你想在我们未来的会议中主持讨论,请联系我!

我就知道这些了,周一见!

我们将于周一下午 6:30-8:30 在霍华德街 101 号会面

链接到 meetup 页面:https://www.meetup.com/Deep-Learning-Book-Club/

链接到 YouTube 频道,上面有之前会议的记录(随意忽略带有紫色大脑缩略图的视频——这些是直播视频,一旦完成,我会用编辑过的版本替换它们)https://www.youtube.com/c/AlenaKruchkova

深度学习概念—第 1 部分

原文:https://towardsdatascience.com/deep-learning-concepts-part-1-ea0b14b234c8?source=collection_archive---------4-----------------------

激活功能

Sigmoid 函数:

乙状结肠的导数:

之前,我们一直使用 sigmoid 函数作为隐藏单元的激活函数,在分类的情况下,作为输出单元的激活函数。然而,这不是你能使用的唯一的激活功能,实际上有一些缺点。

如反向传播材料中所述,s 形的导数在 0.25 处达到最大值(见上文)。这意味着,当您使用 sigmoid 单元执行反向传播时,返回网络的误差将在每一层至少缩小 75%。对于接近输入图层的图层,如果您有很多图层,权重更新将会很小,并且这些权重将需要很长时间来训练。由于这个原因,sigmoids 已经不再受欢迎的激活隐藏单位。

输入校正的线性单位

最近的深度学习网络使用整流线性单元 (ReLUs)代替 sigmoids 用于隐藏层。如果输入小于 0,整流线性单元具有输出 0,否则具有原始输出。也就是说,如果输入大于 0,则输出等于输入。数学上,这看起来像

f(x)= max(x,0)。

函数的输出或者是输入, x ,或者是 0,以较大者为准。所以如果x= 1,那么 f ( x )=0,如果 x =0.5,那么 f ( x )=0.5。从图形上看,它看起来像:

ReLU 激活是您可以使用的最简单的非线性激活功能。当输入为正时,导数为 1,因此不会出现 sigmoids 反向传播误差的消失效应。研究表明,ReLUs 可以大大加快大型网络的训练速度。像 TensorFlow 和 TFLearn 这样的大多数框架使得在隐藏层上使用 ReLUs 变得很简单,所以你不需要自己实现它们。

缺点

有可能一个大的梯度可以设置权重使得一个 ReLU 单位总是 0。这些“死的”单元将总是 0,并且大量的计算将被浪费在训练中。

摘自安德烈·卡帕西的 CS231n 课程:

不幸的是,ReLU 部队在训练中很脆弱,可能会“死亡”。例如,流过 ReLU 神经元的大梯度可能导致权重更新,使得神经元再也不会在任何数据点上激活。如果发生这种情况,那么从该点开始,流经该单元的梯度将永远为零。也就是说,ReLU 单元在训练期间可能会不可逆地死亡,因为它们可能会从数据流形上脱落。例如,如果学习率设置得太高,您可能会发现多达 40%的网络可能是“死的”(即,在整个训练数据集内从未激活的神经元)。有了正确的学习率设置,这个问题就不那么常见了。

Softmax

之前我们已经看到神经网络用于回归(自行车骑手)和二元分类(研究生入学)。通常,您会发现想要预测某个输入是否属于多个类中的一个。这是一个分类问题,但乙状结肠不再是最佳选择。相反,我们使用 softmax 功能。softmax 函数将每个单元的输出压缩到 0 和 1 之间,就像一个 sigmoid。它还对每个输出进行分频,使输出的总和等于 1。softmax 函数的输出相当于分类概率分布,它告诉您任何类为真的概率。

这与正常的 sigmoid 之间唯一的真正区别是 softmax 将输出归一化,使它们的总和为 1。在这两种情况下,您都可以放入一个向量,并得到一个向量,其中输出是一个大小相同的向量,但所有值都压缩在 0 和 1 之间。对于二进制分类,您可以使用带有一个输出单元的 sigmoid。但是,如果您正在进行多项式分类,您可能希望使用多个输出单元(每个类一个)并在输出上激活 softmax。

例如,如果一个 softmax 函数有三个输入,比如一个网络有三个输出单元,它看起来像:

数学上,softmax 函数如下所示,其中 z 是输出层的输入向量(如果有 10 个输出单元,则 z 中有 10 个元素)。再次, j 索引输出单元。

不可否认,这看起来很难理解,但实际上很简单,如果你不懂数学也没关系。请记住,输出被压缩,它们的总和为 1。

为了更好地理解这一点,考虑训练一个网络来从图像中识别和分类手写数字。该网络有十个输出单元,每个单元对应一个数字 0 到 9。然后,如果你给它输入一个数字 4 的图像(见下文),对应于数字 4 的输出单元就会被激活。

图片来自 MNIST 数据集

建立这样的网络需要 10 个输出单元,每个单元对应一个数字。每个训练图像都标有真实数字,网络的目标是预测正确的标签。因此,如果输入是数字 4 的图像,则对应于 4 的输出单元将被激活,并且对于其余单元以此类推。

对于上面的示例图像,softmax 函数的输出可能如下所示:

预测上述数字的网络的 softmax 输出示例

这个图像看起来最像数字 4,所以你有很大的可能性。然而,这个数字在没有完成循环的情况下看起来有点像 7,又有点像 9。所以,你最有可能得到 4,但也有可能得到 7 或 9。

softmax 可用于任意数量的课程。接下来你会看到,它将被用来预测两类情绪,积极的或消极的。它也用于成百上千的类,例如在对象识别问题中,有成百上千个不同的可能对象。

Softmax 函数与 Sigmoid 函数:

Sigmoid 函数的性质

  • sigmoid 函数返回实值输出。
  • sigmoid 函数的一阶导数将是非负或非正的。
  • **非负:**如果一个数大于等于零。
  • **非正数:**如果一个数小于或等于零。

Sigmoid 函数用法

  • 逻辑回归模型中用于二元分类的 Sigmoid 函数。
  • 在创建人工神经元时,sigmoid 函数用作激活函数
  • 在统计学中, sigmoid 函数图通常作为累积分布函数。

Softmax 函数的性质

下面是 softmax 函数的几个属性。

  • 计算出的概率将在 0 到 1 的范围内。
  • 所有概率之和等于 1。

Softmax 函数用法

  • 用于多分类逻辑回归模型。
  • 在构建神经网络时,softmax 函数用于不同的层级别。

Sigmoid 函数和 Softmax 函数的区别

范畴交叉熵

之前,我们一直使用误差平方和作为网络的成本函数,但在这些情况下,我们只有单一(标量)输出值。

然而,当你使用 softmax 时,你的输出是一个向量。一个向量是来自输出单元的概率值。你也可以使用所谓的一键编码将你的数据标签表示为一个向量。

这仅仅意味着您有一个长度为类的数量的向量,并且 label 元素被标记为 1,而其他标签被设置为 0。在对之前的数字进行分类的情况下,数字 4 的图像的标签向量将是:

y =[0,0,0,0,1,0,0,0,0,0]

我们的输出预测向量可以是这样的

^ =[0.047,0.048,0.061,0.07,0.330,0.062,0.001,0.213,0.013,0.150]。

我们希望误差与这些向量的距离成正比。为了计算这个距离,我们将使用交叉熵。然后,我们在训练网络时的目标是通过最小化交叉熵来使我们的预测向量尽可能接近标签向量。交叉熵计算如下所示:

交叉熵计算

如上所述,交叉熵是标签元素的总和乘以预测概率的自然对数。注意,这个公式是不对称的!翻转向量是个坏主意,因为标签向量有很多零,取零的对数会导致错误。

对标签向量使用独热编码的酷之处在于除了一个 true 类之外,yj都是 0。然后,除了其中 y j =1 之外,该和中的所有项都是零,并且对于真实标签,交叉熵简单地是d*= lny^。例如,如果您的输入图像是数字 4,并且它被标记为 4,那么只有对应于 4 的单元的输出在交叉熵成本中起作用。*

关于这个的好博客:https://ljvmiranda 921 . github . io/notebook/2017/08/13/soft max-and-the-negative-log-likelihood/

KL 散度:

https://www . countbayesie . com/blog/2017/5/9/kull back-lei bler-divergence-explained

学分:来自课堂讲稿:https://classroom.udacity.com/nanodegrees/nd101/syllabus

深度学习概念—第 2 部分

原文:https://towardsdatascience.com/deep-learning-concepts-part-2-9aed45e5e7ed?source=collection_archive---------4-----------------------

part 1:https://medium . com/forward-data-science/deep-learning-concepts-part-1-ea 0 b 14b 234 c 8

损失函数选择:MSE 与交叉熵;

交叉熵是各种模型(如分类、分割、生成模型等)的首选损失函数。这里我们解释行为的差异:

假设您只有三个训练数据项。您的神经网络对输出神经元使用 softmax 激活,因此有三个可以解释为概率的输出值。例如,假设神经网络的计算输出和目标值(也称为期望值)如下:

computed       | targets              | correct?
-----------------------------------------------
0.3  0.3  0.4  | 0  0  1 (democrat)   | yes
0.3  0.4  0.3  | 0  1  0 (republican) | yes
0.1  0.2  0.7  | 1  0  0 (other)      | no

该神经网络具有 1/3 = 0.33 的分类误差,或者等效地,2/3 = 0.67 的分类精度。请注意,神经网络只是勉强得到前两个正确的训练项目,在第三个训练项目上差得很远。但是现在考虑下面的神经网络:

computed       | targets              | correct?
-----------------------------------------------
0.1  0.2  0.7  | 0  0  1 (democrat)   | yes
0.1  0.7  0.2  | 0  1  0 (republican) | yes
0.3  0.4  0.3  | 1  0  0 (other)      | no

这个 NN 也有 1/3 = 0.33 的分类误差。但是第二个神经网络比第一个好,因为它固定了前两个训练项目,并且几乎没有错过第三个训练项目。总而言之,分类误差是一种非常粗略的误差度量。

现在考虑交叉熵误差。上述第一个神经网络中第一个训练项目的交叉熵误差为:

-( (ln(0.3)*0) + (ln(0.3)*0) + (ln(0.4)*1) ) = -ln(0.4)

请注意,在神经网络分类的情况下,计算有点奇怪,因为除了一项之外,所有项都将消失。(关于如何计算交叉熵,网上有几个很好的解释。)因此,第一个神经网络的平均交叉熵误差(ACE)计算如下:

-(ln(0.4) + ln(0.4) + ln(0.1)) / 3 = 1.38

第二个神经网络的平均交叉熵误差为:

-(ln(0.7) + ln(0.7) + ln(0.3)) / 3 = 0.64

请注意,第二个高级神经网络的平均交叉熵误差小于第一个神经网络的 ACE 误差。交叉熵中的 ln()函数考虑了预测的接近程度,是一种更细粒度的计算误差的方法。

交叉熵误差优于均方误差。简而言之,在反向传播训练期间,您希望根据目标值将输出节点值驱动到 1.0 或 0.0。如果使用 MSE,权重调整因子(渐变)包含(输出)(1-输出)项。随着计算的输出越来越接近 0.0 或 1.0,(输出) (1 —输出)的值变得越来越小。例如,如果输出= 0.6,则(输出)* (1 —输出)= 0.24,但如果输出为 0.95,则(输出)* (1 —输出)= 0.0475。随着调整因子变得越来越小,权重的变化也变得越来越小,可以说训练会停止。

但是如果你使用交叉熵误差,那么(输出)* (1 —输出)项就消失了(数学很酷)。所以,体重的变化不会越来越小,所以训练不太可能停止。请注意,此参数假设您正在使用 softmax 输出节点激活进行神经网络分类。

调试深度学习模型:

查看验证集中每类标签的前几个错误预测(损失最大的预测)总是一个好主意。它通常能让你对你的模型的行为以及你的标签数据有多好或多干净有很好的了解。

伪标签:

http://deep learning . net/WP-content/uploads/2013/03/pseudo _ label _ final . pdf

[## keras 中一个简单的伪标签实现

(此贴与 fast.ai 第七课 jupyter 笔记本高度相关在此)我目前正在参加…

shaoanlu.wordpress.com](https://shaoanlu.wordpress.com/2017/04/10/a-simple-pseudo-labeling-function-implementation-in-keras/)

**基本思路:**思路是用标注数据训练一个模型。使用该模型来预测未标记数据的标签,然后包括伪标记数据作为数据的一部分,以在假设伪标签是真实标签的情况下与标记数据一起训练该模型。

**来自上面的博客:**一种有效的伪标记方法是,如 2015 年全国数据科学碗获奖者在这里提到的,以 67:33 的比例混合原始数据和伪标记数据。fast.ai 的课视频里也提到了这一点。

fast.ai 一课伪标注的另一个实现可以在第七课笔记本这里找到。

preds = model.predict([conv_test_feat, test_sizes], 
                      batch_size=batch_size*2)
gen = image.ImageDataGenerator()
test_batches = gen.flow(conv_test_feat, preds, batch_size=16)
val_batches = gen.flow(conv_val_feat, val_labels, batch_size=4)
batches = gen.flow(conv_feat, trn_labels, batch_size=44)
mi = MixIterator([batches, test_batches, val_batches)bn_model.fit_generator(mi, mi.N, nb_epoch=8, 
                       validation_data=(conv_val_feat, val_labels))

在上面的代码中,fast.ai 课程的讲师杰瑞米·霍华德写了一个自定义迭代器,用于混合训练数据和伪标签数据。

原木损失

衡量分类模型的性能,其中预测输入是介于 0 和 1 之间的概率值。机器学习模型的目标是最小化这个值。完美的模型的对数损失为 0。随着预测概率偏离实际标签,测井曲线损失增加。

测井损失与准确性

  • 准确性是预测值等于实际值的预测数。准确性并不总是一个好的指标,因为它具有是或否的性质。
  • 测井损失根据实际标签的变化程度,考虑您预测的不确定性。这让我们对模型的性能有了更细致的了解。

下图显示了给定真实观测值(isDog = 1)的可能测井损失值的范围。随着预测概率接近 1,测井曲线损失缓慢下降。然而,随着预测概率的降低,测井曲线损失迅速增加。日志丢失惩罚了这两种类型的错误,尤其是那些有把握的和错误的预测!

**def** logloss(true_label, predicted, eps=1e-15):
  p = np.clip(predicted, eps, 1 - eps)
  **if** true_label == 1:
    **return** -log(p)
  **else**:
    **return** -log(1 - p)

在二进制分类中(M=2),公式等于:

多类分类

在多类分类(M>2)中,我们取观测值中每个类预测的测井损失值的总和。

跨类的所有日志损失值的总和

为什么是负号?

Log Loss 使用负 Log 来提供一个简单的比较指标。之所以采取这种方法,是因为数字的正对数< 1 returns negative values, which is confusing to work with when comparing the performance of two models.

Log Loss vs Cross-Entropy

Log loss and cross-entropy are slightly different depending on the context, but in machine learning when calculating error rates between 0 and 1 they resolve to the same thing. As a demonstration, where p and q are the sets p∈{y, 1−y} and q∈{ŷ, 1−ŷ} we can rewrite cross-entropy as:

  • p = set of true labels
  • q = set of prediction
  • y = true label
  • ŷ = predicted prob

Which is exactly the same as log loss!

Data leakage:

Here are good blog posts explaining this and apply to general machine learning/data mining:

https://medium . com/machine-intelligence-report/new-to-machine-learning-avoid-this-three-errors-73258 b 3848 a 4

深度学习滴滴:破解验证码

原文:https://towardsdatascience.com/deep-learning-drops-breaking-captcha-20c8fc96e6a3?source=collection_archive---------4-----------------------

在浏览了一些网站后,我发现了这样一个验证码:

作为一个人工智能爱好者,我总是想到计算机模仿人类。所以一些自然的问题出现在我的脑海里:“这似乎是一个容易破解的验证码。为什么他们在这个网站使用它?”“我能用我所知道的机器学习破解这个验证码吗?”,“这要花多长时间?”。

一周后,我在 Tensorflow 中创建了一个模型,可以以 96%的准确率解决这种验证码。我只用了一台普通的电脑就做到了,成本很低。我写这篇文章的动机并不是声称简单的验证码是可以解决的(这并不奇怪),而是我想强调一下现在做这个是多么容易。

仔细看看

这种验证码的低效始于它缺乏方差。这是另一个例子:

我们总是有一个 6 个字母并排的灰度图像,背景中有一些随机噪声。模式是如此固定,以至于我们可以很容易地将图像分解成 6 个不同的较小图像序列:

每个图像显示一个字符。但是等一下,字符识别是我们在深度学习中学到的最基础的东西!如果我们将这些小图片中的每一个都视为与来自 MNIST 数据集的图片相似的图片,我们就将验证码问题转化为模式识别问题。作为输入,我们有一个 50x28 的图像,作为输出,我们有像“A”、“g”、“5”等标签。

现在的问题是如何建立数据集。在过去,我必须花一些时间来标记一堆图像,以产生一个合理大小的数据集,或者在最好的情况下,我可以召集一个朋友任务组来帮助我。但每个人都有更重要的事情要做(我也是)。所以我决定稍微作弊一下。我使用了一些承诺低价破解验证码的付费网站。花了一些钱后,我得到了大约 6 万个验证码。

剩下的就是机器学习程序了。我将数据分为训练、验证和测试,并训练了一个卷积神经网络。我写了一个超参数调整的脚本,并让它在一个周末在一台计算机上运行(仅 CPU)。

其中一个结果是,我并不需要我认为的那么多数据:

当我使用一组 50k 验证码时,获得了最好的结果,但是如果,例如,我们将其与 5k 图像的样本进行比较,改进并不巨大。

就是这样。验证码解决了。如果我想,我可以破解那个网站 96.68%的验证码。

最后

当然,我不会透露这些验证码来自哪个网站。但是你不需要走很远就能碰到类似的情况。互联网上有很多例子:

不用说,像这样的验证码是完全没有效率的。这样做既不需要强大的计算机能力,也不需要惊人的黑客技能。在只有 3k 个例子的数据集上,我得到了非常好的结果,为了得到这么多的验证码,我只需要花 3 美元!

现在有了机器学习工具,破解这样的验证码只需要 3 美元和一台普通电脑。网站创建者认为机器人能做的和机器人真正能做的似乎不匹配。

因此,如果这里有一个教训是,如果你担心你的网站上的机器人,你不应该使用这种验证码。谷歌的 reCAPTCHA 是一个更好的选择。

看到这些结果,我认为任何关于创建新验证码的讨论都应该从卷积神经网络的能力和局限性开始*。*

初学者的深度学习

原文:https://towardsdatascience.com/deep-learning-for-beginners-practical-guide-with-python-and-keras-d295bfca4487?source=collection_archive---------2-----------------------

Python 和 Keras 实用指南

这篇文章将展示如何使用 Keras 对数字识别的示例进行编码,以向读者提供使用这个 Python 库进行深度学习的第一次实际接触,该示例在之前的文章(我强烈建议之前阅读它)中给出。

环境设置

为什么是 Keras?

Keras 是推荐给初学者的库,因为与其他库相比,它的学习曲线非常平滑,目前它是实现神经网络的流行中间件之一。Keras 是一个 Python 库,它以一种简单的方式,使用 TensorFlow、Theano 或 CNTK 等其他库作为后端,提供了广泛的深度学习模型的创建。它由来自谷歌的工程师弗朗索瓦·乔莱开发和维护,他的代码已经在麻省理工学院的许可下发布。还有一点很重要,Keras 作为 API 包含在 TensorFlow 中。虽然 Keras 目前包含在 Tensorflow 包中,但是也可以作为 Python 库使用。首先,我认为第二个选择是最合适的。

这篇文章中的代码可以在 GitHub 中以 Jupyter 笔记本的形式获得(https://GitHub . com/JordiTorresBCN/DEEP-LEARNING-practical-introduction-with-Keras),尽管如果读者愿意,这可以作为 Python 中的正常程序运行。

合作环境

在本帖中,我们将使用 Google 提供的 合作实验室

这是谷歌的一个研究项目,旨在帮助传播机器学习教育和研究。这是一个 Jupyter 笔记本环境,不需要任何配置,完全在云中运行,允许使用 Keras、TensorFlow 和 PyTorch。Colab 区别于其他免费云服务的最重要的特点是;Colab 提供 GPU,完全免费。关于该服务的详细信息可以在常见问题页面上找到。

笔记本存储在 Google Drive 中,可以像使用 Google Docs 一样共享。这个环境是免费使用的,只需要一个谷歌账户。此外,该环境允许免费使用 NVIDIA K80 GPU。

第一次进入时,您会看到如下所示的窗口。在此窗口中,您应该选择 GITHUB 选项卡,并在 URL 字段中填写“JordiTorresBCN”,在存储库字段中填写“JordiTorresBCN/DEEP-LEARNING-practical-introduction-with-Keras”。

要加载笔记本,请单击出现在他们右侧的按钮(在新选项卡中打开笔记本):

默认情况下,Colab 笔记本运行在 CPU 上。你可以切换你的笔记本运行 GPU。为了访问一个 GPU,我们需要选择选项卡 Runtime ,然后选择“Change runtime type ”,如下图所示:

当弹出窗口出现时,选择 GPU。确保“硬件加速器”设置为 GPU(默认为 CPU)。

可能会出现一条警告,指出该代码不是由 Google 创建的。我希望您相信我的代码,并运行它!;-)

然后,确保您已连接到运行时(在菜单功能区中“已连接”旁边有一个绿色复选标记):

现在你可以在 Google Colab 中运行 GitHub repo 了。尽情享受吧!

输入神经网络的数据

用于培训、验证和测试的数据集

在展示前一个例子的 Keras 实现之前,让我们回顾一下我们应该如何分配可用的数据,以便正确地配置和评估模型。

对于机器学习中模型的配置和评估,因此深度学习,可用数据通常分为三组:训练数据、验证数据和测试数据。训练数据是那些用于学习算法的数据,以通过我们已经提到的迭代方法获得模型的参数。

如果模型不完全适应输入数据(例如,如果它出现过度拟合),在这种情况下,我们将修改某些超参数的值,并在使用训练数据再次训练它之后,我们将使用验证数据再次评估它。我们可以在验证数据的指导下对超参数进行这些调整,直到获得我们认为正确的验证结果。如果我们遵循了这个过程,我们必须意识到,事实上,验证数据已经影响了模型,所以它也符合验证数据。由于这个原因,我们总是保留一组测试数据用于模型的最终评估,这些数据只会在整个过程结束时使用,此时我们认为模型已经过微调,我们将不再修改它的任何超参数。

考虑到这篇文章的介绍性质,我们不会深入到超参数调优的细节,在示例中,我们将忽略验证数据,只使用训练和测试数据。

Keras 中预加载的数据

在 Keras 中,MNIST 数据集以四个 Numpy 数组的形式预加载,可通过以下代码获得:

import kerasfrom keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_trainy_train 包含训练集,而 x_testy_test 包含测试数据。图像被编码为 Numpy 数组,它们对应的标签从 0 到 9。按照 post 的策略,逐步引入主题的概念,正如我们已经指出的,我们还不会看到如何分离一部分训练数据来使用它们作为验证数据。我们将只考虑训练和测试数据。

如果我们想检查我们加载了哪些值,我们可以选择 MNIST 集的任何图像,例如图像 8,并使用以下 Python 代码:

import matplotlib.pyplot as plt
plt.imshow(x_train[8], cmap=plt.cm.binary)

我们得到了下面的图像:

如果我们想看到它对应的标签,我们可以通过:

print(y_train[8])1

正如我们所看到的,它返回的值为“1 ”,这是意料之中的。

Keras 中的数据表示

正如我们所见,Keras 使用 Numpy 的多维数组作为基本数据结构,称这种数据结构为张量。简而言之,我们可以说张量有三个主要属性:

  • 轴数 ( ):一个包含单个数的张量将被称为标量(或 0 维张量,或张量 0D)。我们称之为矢量或张量 1D 的一组数字。一组向量将是一个矩阵,或 2D 张量。如果我们把这个矩阵打包成一个新的数组,我们就得到一个 3D 张量,我们可以形象地把它解释为一个数字的立方体。通过将 3D 张力器打包成阵列,我们可以创建 4D 张力器,等等。在 Python Numpy 库中,这被称为张量的 ndim
  • 形状:它是一个整数元组,描述张量沿每个轴有多少维。在 Numpy 库中,这个属性被称为形状
  • D 数据类型 : 该属性表示包含张量的数据类型,例如可以是 uint8float32float64 等。在 Numpy 库中,这个属性被称为 dtype

我建议我们从前面的例子中获得张量 train_images 的轴数和维数:

print(x_train.ndim)3print(x_train.shape)(60000, 28, 28)

如果我们想知道它包含什么类型的数据:

print(x_train.dtype)uint8

Keras 中的数据规范化

这些 28×28 像素的 MNIST 图像表示为一个数值数组,其值的范围为 uint8 类型的[0,255]。但是通常将神经网络的输入值调整到一定的范围。在这篇文章的例子中,输入值应该在区间[0,1]内换算成 float32 类型的值。我们可以通过下面几行代码实现这种转换:

x_train = x_train.astype(‘float32’)
x_test = x_test.astype(‘float32’)x_train /= 255
x_test /= 255

另一方面,为了便于将数据输入到我们的神经网络中(我们将看到在卷积中这是不必要的),我们必须将张量(图像)从二维(2D)转换为一维(1D)的向量。也就是说,28×28 个数字的矩阵可以由 784 个数字(逐行连接)的向量(数组)表示,这种格式接受密集连接的神经网络作为输入,就像我们将在本文中看到的那样。在 Python 中,将 MNIST 数据集的每幅影像转换为包含 784 个分量的矢量可通过以下方式完成:

x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)

在执行这些 Python 指令后,我们可以验证 x_train.shape 采用(60000,784)的形式,而 x_test.shape 采用(10000,784)的形式,其中第一维索引图像,第二维索引每个图像中的像素(现在像素的亮度是 0 到 1 之间的值):

print(x_train.shape)(60000, 784)print(x_test.shape)(10000, 784)

除此之外,我们还有每个输入数据的标签(记住,在我们的例子中,它们是 0 到 9 之间的数字,表示哪个数字代表图像,也就是与哪个类相关联)。在这个例子中,正如我们已经提到的,我们将用 10 个位置的向量来表示这个标签,其中对应于表示图像的数字的位置包含 1,向量的剩余位置包含值 0。

在这个例子中,我们将使用所谓的一键编码,我们已经提到过,它包括将标签转换成与不同标签的数量一样多的零向量,并在对应于标签值的索引中包含值 1。Keras 提供了许多支持函数,包括to _ categorial来精确地执行这种转换,我们可以从 keras.utils 导入这些函数:

from keras.utils import to_categorical

为了查看转换的效果,我们可以看到将应用到 _ categorial之前和之后的值:

print(y_test[0])7print(y_train[0])5print(y_train.shape)(60000,)print(x_test.shape)(10000, 784)y_train = to_categorical(y_train, num_classes=10)
y_test = to_categorical(y_test, num_classes=10)print(y_test[0])[0\. 0\. 0\. 0\. 0\. 0\. 0\. 1\. 0\. 0.]print(y_train[0])[0\. 0\. 0\. 0\. 0\. 1\. 0\. 0\. 0\. 0.]print(y_train.shape)(60000, 10)print(y_test.shape)(10000, 10)

现在,我们已经准备好了用于简单模型示例的数据,我们将在下一节中用 Keras 对其进行编程。

喀拉斯的密集连接网络

在本节中,我们将介绍如何在 Keras 中指定我们在前面几节中定义的模型。

Keras 中的顺序类

Keras 中的主要数据结构是顺序类,它允许创建一个基本的神经网络。Keras 还提供了一个 API ,允许以图形的形式实现更复杂的模型,可以有多个输入、多个输出,以及它们之间的任意连接,但这超出了本文的范围。

Keras 库的 序列类是 Keras 提供的序列神经网络模型的包装器,可以通过以下方式创建:

from keras.models import Sequential
model = Sequential()

在这种情况下,Keras 中的模型被视为一系列层,每一层都逐渐“提取”输入数据以获得所需的输出。在 Keras 中,我们可以找到所有需要的层类型,通过 add() 方法可以很容易地添加到模型中。

定义模型

我们识别数字图像的模型在 Keras 中的结构如下:

from keras.models import Sequential
from keras.layers.core import Dense, Activationmodel = Sequential()
model.add(Dense(10, activation=’sigmoid’, input_shape=(784,)))
model.add(Dense(10, activation=’softmax’))

在这里,神经网络已经被定义为密集连接(或完全连接)的两层序列,意味着每层中的所有神经元都连接到下一层中的所有神经元。视觉上,我们可以用以下方式表示它:

在前面的代码中,我们在第一层的 input_shape 参数中明确表达了输入数据是什么样的:一个张量,表明我们有模型的 784 个特征(事实上,被定义的张量是 (None,784,),我们将在前面看到更多)。

Keras 库的一个非常有趣的特点是,它会在第一个张量之后自动推导出层间张量的形状。这意味着程序员只需要为其中的第一个建立这些信息。此外,对于每一层,我们指出它所具有的节点数量以及我们将在其中应用的激活函数(在本例中, sigmoid )。

本例中的第二层是由 10 个神经元组成的 softmax 层,这意味着它将返回代表 10 个可能数字的 10 个概率值的矩阵(通常,分类网络的输出层将具有与类一样多的神经元,除了在二元分类中,只需要一个神经元)。每个值将是当前数字的图像属于它们中的每一个的概率。

Keras 提供的一个非常有用的检查模型架构的方法是 summary() :

model.summary()_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 10) 7850
_________________________________________________________________
dense_2 (Dense) (None, 10) 110
=================================================================
Total params: 7,960
Trainable params: 7,960
Non-trainable params: 0

稍后,我们将更详细地介绍返回 summary() 方法的信息,因为当我们开始构建非常大的网络模型时,神经网络所拥有的参数和数据大小的计算是非常有价值的。对于我们的简单示例,我们看到它指示需要 7960 个参数(列 Param # ),这对应于第一层的 7850 个参数和第二层的 110 个参数。

在第一层中,对于每个神经元 i (在 0 和 9 之间),我们需要 784 个参数用于权重 wij ,因此需要 10×784 个参数来存储 10 个神经元的权重。此外还有 10 个附加参数,用于 10 个 bj 偏置,与它们中的每一个相对应。在第二层中,作为 softmax 函数,需要将所有 10 个神经元与前一层的 10 个神经元连接。因此,需要 10 个 x10 wi 参数,另外还需要 10 个 bj 偏置,对应于每个节点。

我们可以为 密集层指出的参数细节可以在 Keras 手册中找到。在我们的例子中,最相关的出现了。第一个参数表示层中神经元的数量;下面是我们将在其中使用的激活函数。在下一篇文章中(很快:-),我们将更详细地讨论除了这里介绍的两个激活函数之外的其他可能的激活函数:sigmoid 和 softmax。

权重的初始化也经常被表示为密集层的自变量。初始值必须足以使优化问题尽可能快地收敛。各种初始化选项也可以在 Keras 手册中找到。

在 Keras 中实现神经网络的基本步骤

接下来,我们将简要描述实现一个基本神经网络所必须执行的步骤,在接下来的文章中(很快),我们将逐步介绍每个步骤的更多细节。

学习过程的配置

顺序模型中,我们可以用 add() 方法以一种简单的方式定义这些层,正如我们在上一节中提到的。一旦我们定义了我们的模型,我们就可以用 compile() 方法配置它的学习过程,用它我们可以通过方法参数指定一些属性。

第一个参数是损失函数,我们将使用它来评估训练数据的计算输出和期望输出之间的误差程度。另一方面,我们指定了一个优化器,正如我们将看到的,这是我们指定优化算法的方式,允许神经网络根据输入数据和定义的损失函数计算参数的权重。损失函数和优化器的确切目的的更多细节将在下一篇文章(不久)中呈现。

最后,我们必须指出我们将用来监控我们的神经网络的学习过程(和测试)的度量。在第一个例子中,我们将只考虑准确度(被正确分类的图像的比例)。例如,在我们的例子中我们可以在 compile() 方法中指定以下参数来在我们的计算机上测试它:

model.compile(loss=”categorical_crossentropy”,
              optimizer=”sgd”,
              metrics = [‘accuracy’])

在这个例子中,我们指定损失函数是分类 _ 交叉熵,使用的优化器是随机梯度下降(sgd) ,度量是准确度,我们将使用它来评估正确猜测的百分比。

模特培训

一旦我们的模型被定义,学习方法被配置,它就可以被训练了。为此,我们可以通过调用模型的 fit() 方法,将模型训练或“调整”为可用的训练数据:

model.fit(x_train, y_train, batch_size=100, epochs=5)

在前两个参数中,我们已经以 Numpy 数组的形式指出了用于训练模型的数据。 batch_size 参数表示我们将在每次更新模型参数时使用的数据数量,而时期则表示我们将在学习过程中使用所有数据的次数。这最后两个论点将会在下一篇文章中详细解释。

这种方法通过我们提到的迭代训练算法找到网络参数的值,我们将在下一篇文章(很快)中更详细地介绍。大致来说,在该算法的每次迭代中,该算法从 x_train 中获取训练数据,将它们通过神经网络(带有它们的参数在该时刻的值),将获得的结果与期望的结果(在 y_train 中表示)进行比较,并计算损失来指导模型参数的调整过程。 其直观地包括应用上面在 compile() 方法中指定的优化器来计算每次迭代中每个模型参数(权重和偏差)的新值,从而减少损失。

正如我们将看到的,这种方法可能需要更长的时间,Keras 允许我们使用冗长的参数(默认情况下等于 1)来查看其进度,此外还指示每个时期花费的估计时间:

Epoch 1/5
60000/60000 [========] — 1s 15us/step — loss: 2.1822 — acc: 0.2916
Epoch 2/5
60000/60000 [========] — 1s 12us/step — loss: 1.9180 — acc: 0.5283
Epoch 3/5
60000/60000 [========] — 1s 13us/step — loss: 1.6978 — acc: 0.5937
Epoch 4/5
60000/60000 [========] — 1s 14us/step — loss: 1.5102 — acc: 0.6537
Epoch 5/5
60000/60000 [========] — 1s 13us/step — loss: 1.3526 — acc: 0.7034
10000/10000 [========] — 0s 22us/step

这是一个简单的例子,因此读者在文章结束时已经能够编写他们的第一个神经网络,但是,正如我们将看到的, fit() 方法允许更多的参数,这些参数对学习结果有非常重要的影响。此外,这个方法返回一个历史对象,我们在这个例子中忽略了它。其 History.history 属性是连续时期中训练数据和其他度量的损失值的记录,以及验证数据的其他度量(如果它们已经被指定的话)。

模型评估

此时,神经网络已经训练完毕,现在可以使用 evaluation() 方法评估其在新测试数据下的行为。此方法返回两个值:

test_loss, test_acc = model.evaluate(x_test, y_test)

这些值表明我们的模型在处理从未见过的新数据时表现得如何。当我们执行 mnist.load_data() 时,这些数据已经存储在 x_testy_test 中,并将它们作为参数传递给方法。在本帖的范围内,我们将只关注其中之一,准确性:

print(‘Test accuracy:’, test_acc)Test accuracy: 0.9018

准确性告诉我们,我们在这篇文章中创建的模型,应用于该模型从未见过的数据,正确分类了 90%。

读者应该注意到,在本例中,为了评估模型,我们只关注其准确性,即模型做出的正确预测与总预测之间的比率,而不管它是什么类别。然而,虽然在这种情况下这就足够了,但有时有必要再深入一点,并考虑模型在其每个类别中做出的正确和不正确预测的类型。

在机器学习中,评估模型的一个非常有用的工具是混淆矩阵,这是一个包含行和列的表格,用于将预测值与实际值进行比较。我们使用这个表来更好地理解模型的行为,当一个类与另一个类混淆时,明确地显示出来是非常有用的。类似于上一篇文章中解释的二元分类器的混淆矩阵具有这样的结构:

真阳性(TP)、真阴性(TN)、假阳性(FP)和假阴性(FN),是对具有类“1”(“正”)和“0”(“负”)的两类情况的单个预测的四种不同的可能结果。

假阳性是指结果被错误地归类为阳性,而实际上却是阴性。假阴性是指当结果实际上是阳性时却被错误地归类为阴性。真阳性和真阴性显然是正确的分类。

利用这个混淆矩阵,可以通过将对角线的值相加并除以总和来计算精度:

精度 = (TP + TN) / (TP + FP + FN + TN)

尽管如此,就模型的质量而言,准确性可能是误导性的,因为当对具体模型进行测量时,我们不区分假阳性和假阴性类型的错误,好像两者具有相同的重要性。例如,想象一个预测蘑菇是否有毒的模型。在这种情况下,假阴性(即食用毒蘑菇)的代价可能是巨大的。相反,假阳性的代价非常不同。

出于这个原因,我们有另一个称为敏感度(或回忆)的指标,它告诉我们该模型如何避免假阴性:

灵敏度 = TP / (TP + FN)

换句话说,从正面观察(毒蘑菇)的总数中,模型检测到多少。

从混淆矩阵中,可以获得几个指标来关注其他案例,如此链接所示,但更详细地讨论这个主题超出了本文的范围。使用一种度量或另一种度量的便利性将取决于每个特定情况,特别是与模型的每个分类错误相关的“成本”。

但是读者会想知道这个混淆矩阵在我们的分类器中是怎么回事,这里有 10 个类而不是 2 个。在这种情况下,我建议使用 Scikit-learn 包通过计算混淆矩阵来评估模型的质量,如下图所示:

在这种情况下,对角线的元素表示模型预测的标签与标签的实际值相符的点数,而其他值则表示模型分类不正确的情况。因此,对角线的值越高,预测就越好。在本例中,如果读者计算对角线值除以矩阵总值的和,他或她将看到它与 evaluate() 方法返回的精度相匹配。

在帖子的 GitHub 中,读者可以找到用来计算这个混淆矩阵的代码。

生成预测

最后,读者需要知道我们如何使用上一节中训练的模型进行预测。在我们的例子中,它包括预测哪个数字代表一幅图像。为了做到这一点,Keras 提供了 predict() 方法。

为了测试这种方法,我们可以选择任何元素。为了方便起见,让我们从测试数据集 x_test 中选取一个。例如,让我们选择这个数据集的元素 11x _ test

在看到预测之前,让我们看看图像,以便能够检查我们自己模型是否做出了正确的预测(在进行之前的整形之前):

plt.imshow(x_test[11], cmap=plt.cm.binary)

我想读者会同意,在这种情况下,它对应于数字 6。

现在让我们看看模型的 predict() 方法,执行下面的代码,正确地预测了我们刚刚估计它应该预测的值。

predictions = model.predict(x_test)

predict()方法返回一个向量,其中包含对整个数据集元素的预测。通过 Numpy 的 argmax 函数,我们可以知道哪个类给出的归属概率最大,该函数返回包含向量最高值的位置的索引。具体而言,对于项目 11:

np.argmax(predictions[11])6

我们可以通过打印方法返回的向量来检查它:

print(predictions[11])[0.06 0.01 0.17 0.01 0.05 0.04 0.54 0\. 0.11 0.02]

我们看到向量中的最高值在位置 6。我们还可以验证预测的结果是一个向量,它的所有分量之和等于 1,正如所预期的那样。为此,我们可以使用:

np.sum(predictions[11])1.0

到目前为止,读者已经能够在 Keras 中创建他们的第一个模型,该模型在 90%的情况下正确地对 MNIST 数字进行分类。在下一篇文章中(很快),我们将介绍学习过程是如何工作的,以及我们可以在神经网络中使用的几个超参数来改善这些结果。

在以后的文章中,我们将会看到如何使用卷积神经网络来改进这些分类结果。

下期贴子见(更新):

[## 深度神经网络的学习过程

人工神经网络是如何学习的?[更新版本]

towardsdatascience.com](/learning-process-of-a-deep-neural-network-5a9768d7a651)

日本古典文学的深度学习

原文:https://towardsdatascience.com/deep-learning-for-classical-japanese-literature-48ae04c17dfd?source=collection_archive---------11-----------------------

论文摘要

Fig 1. Toons Discussing about converting Kuzushiji-Kanji to Modern Kanji

这是一篇论文的论文摘要: 对日本古典文学的深度学习 塔林·克兰瓦特、 米克尔·波贝尔-伊里扎尔、浅野武·北本、亚历克斯·兰姆、山本和树、大卫·哈。
论文:

概观

本文介绍了 3 个新的机器学习基准数据集,即:
-Kuzushiji-MNIST-
替代 MNIST 数据集(28x 28)-
-Kuzushiji-49-
一个更大但不平衡的数据集,包含 48 个平假名字符和 1 个平假名迭代标记(28x 28)-
-Kuzushiji-Kanji-(64x64)

Fig 2. An example of a Kuzushiji script

由于在这个时代日本语言的现代化,Kuzushiji 文字不再在正常的学校课程中教授。尽管日本人已经使用了 1000 多年,但今天大多数日本人都不会读或写 150 多年前写的书!

Fig 3. Difference between text printed in 1772 and 1900

在国家图书总目录中有超过 170 万册注册图书,超过 300 万册未注册图书和超过 100 万份 1B 历史文献,除了其中一些被数字化外,只有了解《藏书世纪》的人才能阅读这些文献。

本文介绍了一个专门为 ML 研究建立的数据集,并向日本文学界介绍了 ML 社区。

该论文使用最近的模型发布了 Kuzushiji-MNIST 和 Kuzushiji-日本汉字数据集的基准。库祖什基-MNIST 可用作正常 MNIST 数据集的替代品。

本文还将生成模型应用于未知汉字到现代汉字的领域转换任务。

Fig 4. Domain Transfer Experiment between Kuzushiji Kanji and Modern Kanji

数据集

Kuzushiji 数据集由NIJL 国立日本文学研究所创建,由人文科学开放数据中心(CODH)* 管理。
Kuzushiji 全数据集于 2016 年 11 月发布,现在数据集包含 3999 个字符类型,403242 个字符。*

本文作者对从 18 世纪印刷的 35 本古典书籍中扫描的字符进行预处理,并将它们分成 3 个数据集:
-Kuzushiji-MNIST-
MNIST 数据集(28x 28)*
-Kuzushiji-49-一个更大但不平衡的数据集,包含 48 个平假名字符和 1 个平假名迭代标记(28x 28)
-Kuzushiji-Kanji(64x64)*

Fig 5. 10 Classes of Kuzushiji-MNIST

One characteristic of Classical Japanese which is very different from Modern Japanese is Hentaigana(変体仮名).

汉字是一种平假名字符,它有一种以上的书写形式,因为它们来自不同的汉字。

因此,Kuzushiji-MNIST 和 Kuzushiji-49 的一个平假名类可能映射了许多字符(如上图所示)。这使得 Kuzushiji 数据集比 MNIST 数据集更具挑战性。

Fig 6. Few examples from Kuzushiji-Kanji

Kuzushiji-49 和 Kuzushiji-Kanji 中的高类别不平衡是由于真实教科书中的出现频率,并且保持这种方式以表示真实的数据分布。

  • Kuzushiji-49 —有 49 个类别,共有 266,407 张图像 (28x28)
  • kuzushiji-Kanji-有 3832 个类,总共有 140,426 个图像,从 1,766 个示例到每个类只有一个示例。 (64x64)

Kuzushiji-MNIST 是平衡的。Kuzushiji-Kanji 是为更多的实验任务而创建的,而不仅仅是分类和识别基准。

Fig 7. Kuzushiji-49 Classes

实验

库祖什基-MNIST 和库祖什基-49 的分类基线

Fig 8. Classification baselines for Kuzushiji-MNIST and Kuzushiji-49

从日本汉字到现代汉字的域名转移

Kuzushiji-Kanji 数据集用于从像素图像到矢量图像的域转移(与以前的此类方法相反,以前的方法侧重于从像素图像到像素图像的域转移)

所提出的模型旨在以基于像素和笔画的格式生成给定汉字输入的现代汉字版本。

Fig 9. Kuzushiji Kanji to Modern Kanji

下图展示了整体方法。

Fig 10. Kuzushiji-Kanji to Modern Kanji Approach

他们训练两个独立的卷积变分自动编码器,一个在 Kuzushiji-Kanji 数据集上,另一个在 KanjiVG 数据集的像素版本上,渲染为 64x64 像素以保持一致性。VAE 的建筑与【3】相同。* 并且两个数据集都被压缩到各自的 64 维潜空间中, z_oldz_new 。KL 损失项在低于某个阈值时没有被优化。*

然后,训练具有 2 个隐藏层的混合密度网络(MDN)来模拟近似为混合高斯分布的密度函数 P(z_new | z_old)

然后,给定从 Kuzushiji-Kanji 编码的潜在向量 z_old,我们可以采样潜在向量 z_new

该论文称,与端到端地训练单个模型相比,在每个数据集上训练两个独立的 VAE 模型要高效得多,并且取得了更好的结果。

在最后一步中,草图-RNN 解码器模型被训练以基于 z_new 生成现代汉字。

Fig 11. The algorithm for domain transfer from Kuzushiji-Kanji to KanjiVG

两个数据集之间有 3600 个重叠字符。
-对于不在重叠空间中的那些,我们从编码在 KanjiVG 数据上的 z_new 调节 sktech-RNN 模型,以同样从 KanjiVG 生成笔画数据[ 参见图 10
中的(1).-对于存在于重叠数据集中的那些,我们使用从以 z_old 为条件的 MDN 采样的 z_new,以同样从 KanjiVG 生成笔画数据[ 参见图 10 中的(2)

这有助于 sketch-RNN 微调 VAE 潜在空间的各个方面,当只在像素上训练时,这些方面可能无法很好地捕捉现代汉字的数据分布。

参考

****【1】**y . le Cun。MNIST 手写数字数据库,1998 年。http://yann.lecun.com/exdb/mnist/
**c .对于人文学科的开放数据。Kuzushiji 数据集,2016。
http://codh.rois.ac.jp/char-shape/
***【3】*d .哈和 j .施密德胡伯。循环世界模型促进政策演变. arXiv 预印本 arXiv:1809.01999,2018。https://worldmodels.github.io/

所以,简而言之,这就是论文的全部内容! 如果我发现一些有趣的见解需要补充,会更新这个故事! 一定要走纸!

感谢阅读!

图像识别的深度学习:为什么它具有挑战性,我们已经走过的路,以及下一步

原文:https://towardsdatascience.com/deep-learning-for-image-classification-why-its-challenging-where-we-ve-been-and-what-s-next-93b56948fcef?source=collection_archive---------1-----------------------

想获得灵感?快来加入我的 超级行情快讯 。😎

在过去几年里,深度学习绝对统治了计算机视觉,在许多任务及其相关竞赛中取得了最高分。这些计算机视觉竞赛中最受欢迎和最知名的是 ImageNet 。ImageNet 竞赛要求研究人员创建一个模型,最准确地对数据集中的给定图像进行分类。

在过去的几年里,深度学习技术使这项比赛取得了快速进展,甚至超过了人类的表现。今天,我们将回顾这一进展,以深入了解这些进步是如何伴随深度学习而来的,我们可以从中学习到什么,以及我们可以从这里走向何方。

ImageNet 的挑战

那么 ImageNet 挑战赛有什么难的呢?让我们先看一下数据。ImageNet 分类任务的数据是从 Flickr 和其他搜索引擎收集的,由人工标记,每张图像属于 1000 个对象类别中的一个。下表显示了数据集的分布情况。

ImageNet Dataset

到 2012 年,ImageNet 拥有近130 万张训练图片。如此大规模的图像分类任务的主要挑战是图像的多样性。这里我们可以看几个例子。

看看下面的图片。在左边,我们看到一些来自另一个图像分类挑战的示例图像: PASCAL 。在帕斯卡挑战中,只有大约 20,000 幅训练图像和 20 个对象类别。这个挑战有非常通用的类别,如“鸟”、“狗”和“猫”,如下所示。转移到 ImageNet 挑战,这是一个全新的游戏。ImageNet 没有一个包含所有种类狗的名为“dog”的通用类,而是为每种狗都提供了类。事实上,不同于帕斯卡的“狗”类别,ImageNet 有 120 个不同品种的狗的类别!因此,我们用于这项任务的任何模型/算法必须能够处理这些非常细粒度的特定的 ,即使它们看起来非常相似并且难以区分。

用更专业的术语来说,我们希望最大化**类间可变性。**这意味着我们希望两张包含不同种类鸟类的图像在我们的模型中看起来非常不同,因为尽管它们都是鸟类,但在我们的数据集中它们属于不同的类别。看看下面的插图。

Inter-class Variability

ImageNet 的另一个具有挑战性的特性是:同一类的对象看起来会有很大的不同。让我们看看下面的图片。左边的两个都来自“橘子”班,右边的两个都来自“台球桌”班。然而,每一对图像看起来非常不同!作为人类,我们可以看到一个橙子被切开,而另一个没有;我们还可以看到,台球桌的一张照片被放大了,另一张没有。这叫做类内变异性。我们希望最小化这种可变性,因为我们希望同一类的两幅图像看起来非常类似于我们的深度学习模型,也就是说,在数量上。

Intra-class Variability

知道了这些图像分类挑战,让我们回顾一下深度学习是如何在这项任务上取得巨大进展的。

图像分类深度学习的快速进展

自 2012 年以来,几乎每年都让我们在为图像分类任务开发深度学习模型方面取得重大突破。由于其大规模和具有挑战性的数据,ImageNet 挑战已成为衡量进展的主要基准。在这里,我们将看看深度学习在这项任务上的进展,以及使这一进展成为可能的一些主要架构。

开始这一切的人:AlexNet

AlexNet Architecture

**早在 2012 年,多伦多大学的一篇论文发表在 NIPS 上,这真是令人震惊。那篇论文是 ImageNet 用深度卷积网络分类 它在 ImageNet 挑战赛中实现了近 50%的错误率降低,这在当时是前所未有的进步,随后成为该领域最具影响力的 论文之一。论文中 AlexNet 的神经网络架构如上所示。

本文提出使用深度卷积神经网络(CNN)来完成图像分类的任务。与现在使用的相比,它相对简单。这篇论文的主要贡献是:

  • 第一个成功地使用 deep 进行大规模图像分类。这之所以成为可能,是因为来自 ImageNet 的标记为 大量 数据,以及使用两个 GPU 上的并行计算来训练模型。****
  • 他们将 ReLU 用于 - 线性 激活 功能,发现它们相对于 tanh 功能表现更好,并减少了训练时间。ReLU 非线性现在倾向于成为深度网络的默认激活功能。
  • 他们使用数据 增强技术,包括图像平移、水平反射和均值减法。如今,这些技术被广泛用于许多计算机视觉任务。
  • 为了解决超过 - 拟合训练数据的问题,他们使用了剔除层。
  • 他们提出的风格是让连续 卷积汇集 ,然后是完全 - 连接最后的层,这仍然是今天许多先进网络的基础。

基本上,AlexNet 设置了标杆,提供了使用 CNN 完成计算机视觉任务的基线和默认技术!

让我们更深入:VGGNet

VGGNet Architecture

VGGNet 论文“用于大规模图像识别的极深度卷积神经网络”于 2014 年问世,进一步扩展了使用具有许多卷积和 ReLUs 的深度网络的思想。论文中 VGGNet 的神经网络架构如上所示。他们的主要想法是,你真的不需要任何花哨的技巧来获得高精度。只要一个有很多 3×3 小卷积和非线性的深度网络就可以了!上图中相同大小的重复块的堆叠是使用 3x3s 堆叠的直接结果!VGGNets 的主要贡献是:

  • 仅使用3x 3 大小的过滤器,而不是 AlextNet 中使用的 11x11。他们表明,两个连续的 3×3 卷积具有等同于单个 5×5 卷积的接收** 或“视野”(即它看到的像素);同样,三个连续的 3×3 卷积相当于一个 7×7 卷积。这样做的好处是,它模拟了一个更大的滤波器,同时保留了较小滤波器的优点。较小滤波器的第一个好处是减少了参数数量。第二个是能够在每个卷积之间使用 ReLU 函数,这将更多的 - 线性引入网络,这使得决策 函数更具辨别能力。**
  • 随着每一层的输入体积的空间大小减小(作为汇集层的结果),体积的深度增加。这背后的想法是,随着空间信息的减少(从通过最大池的向下采样),它应该被编码为更具区分度的 特征,以用于精确和高区分度的分类。因此,特征图的数量随着深度而增加,以便能够捕捉这些特征用于分类。
  • 它引入了一种新的数据扩充方式:标度抖动。
  • 用 Caffe 工具箱建立模型。在这一点上,深度学习库变得越来越受欢迎。

更深入:GoogLeNet 和 Inception 模块

Inception Module from GoogLeNet

GoogLeNet 架构是第一个真正解决计算 资源以及 - 规模 处理的问题的,在论文“用卷积走得更深”。随着我们不断地让我们的分类网络越来越深,我们到达了一个耗尽大量内存的点。此外,过去已经提出了不同的计算滤波器大小:从 1x1 到 11x11 你如何决定哪一个?inception 模块和 GoogLeNet 通过以下贡献解决了所有这些问题:

  • 通过在每个 3x3 和 5x5 之前使用 1x1 卷积,初始模块减少了通过每层的特征 映射的数量,从而减少了计算和内存消耗!
  • 初始模块有 1x1、3x3 和 5x5 个卷积,都在并行中。这背后的想法是让网络通过训练来决定学习和使用什么信息。它还允许 - 尺度 处理:该模型既可以通过较小的卷积恢复局部 特征,也可以通过较大的卷积恢复 抽象 特征。厉害!
  • GoogLeNet 是第一个引入 CNN 层不必总是按顺序堆叠的想法的模型之一。这篇论文的作者表明,你还可以增加网络宽度以获得更好的性能,而不仅仅是深度。

使用快捷方式跳过:ResNet

Residual block from ResNet

自从 2015 年首次发表论文“图像识别的深度剩余学习”以来,ResNets 已经在许多计算机视觉任务的准确性方面取得了重大进步。ResNet 架构是第一个在 ImageNet 上通过人类水平性能的架构,他们对残差 学习的主要贡献通常默认用于当今许多最先进的网络:

  • 显示出一个幼稚的 层层叠加让网络变得很深并不总是有帮助,实际上还会让事情变得更糟。
  • 为了解决上述问题,他们引入了跳过连接的剩余学习。其思想是通过使用附加的跳过 连接作为快捷方式,深层具有从先前层直接访问 特征。允许功能信息更容易地通过网络传播。这也有助于训练,因为梯度也可以更有效地反向传播。
  • 第一个“ ”网络,通常使用超过 100-200 层。

走极端的捷径:DenseNet

DenseNet visualization

随着论文“密集连接的卷积网络”中 DenseNets 的引入,快捷连接被发挥到了极致。DenseNets 扩展了快捷连接的概念,但具有比 ResNet 更密集的连接:

  • DenseNets 以前馈方式将每一层与每一层连接起来。这允许每个层使用在 之前的所有 的所有特征图作为输入,并且它自己的特征图被用作所有后续层的输入。
  • 这是通过连接完成的,而不是在 ResNets 中使用的加法,这样原始特征直接通过层。
  • 显示出执行 比 ResNets更好。DenseNets 有助于缓解消失梯度问题,加强特征传播,鼓励特征重用,并大大减少参数的数量。

这些是在过去几年中形成图像分类进展的主干的主要体系结构。已经取得了很大的进展,这是令人兴奋的,因为它允许使用这种新技术来解决许多现实世界的问题。只剩下一个问题…..

我们将何去何从

正如我们刚刚回顾的,针对图像分类的深度学习研究一直在蓬勃发展!我们已经在改进这项任务的方法上迈出了巨大的步伐,甚至超越了人类水平的表现。深度神经网络现在广泛用于许多企业对图像进行分类,甚至是许多新启动技术的基础。

很高兴看到所有这些进步,但我们必须一直努力改进。深度学习模型在图像分类方面仍然存在许多挑战。如果我们想要前进,这些挑战是必须解决的。在这里,我将回顾其中一些我认为重要的、研究人员正在积极尝试解决的问题:

从监督学习到非监督学习

An example of Supervised vs Unsupervised learning

目前,大多数应用于计算机视觉任务的深度学习方法都是由监督的。这意味着我们需要大量的标记的训练数据。获取这些数据既繁琐又昂贵。想想看:ImageNet 挑战赛有130 万个训练样本,而这仅仅是针对 1000 个不同的类别!一个人需要得到所有的数据,浏览每一幅图像,并给它贴上标签;好多手动工作!

大多数情况下,当企业想要为自己的特定应用应用图像分类网络时,他们必须使用迁移学习来微调预先训练的 ImageNet 网络。为了进行这种微调,他们仍然需要收集大量自己的数据并对其进行标记;繁琐昂贵退一步说。

研究人员正在积极努力解决这个问题并取得进展。像快速有效 转移 学习****半 - 监督 学习一次 - 射击 学习这样的事情越来越多。我们可能不会直接跳到无监督学习,但这些方法的研究是朝着正确方向迈出的有力一步

抵御我们的敌人

Adversarial images can cause major problems

使用生成 对抗 网络 (GANs)的日益流行,揭示了图像分类的新挑战:对抗 图像。简而言之,敌对图像的类别对人类来说显而易见,但在深层网络中会导致大量 故障。看看上面的图片。仅仅有一点点扭曲(看起来),一个深层网络的图像分类就从熊猫变成了长臂猿!

对我们人类来说,很明显这个图像仍然是一只熊猫,但出于某种原因,它导致深层网络无法完成任务。这在真实 - 世界 应用中可能是非常危险的:如果你的自动驾驶汽车没有认出一个行人,而是从他们身上碾过去怎么办?部分问题可能源于这样一种想法,即我们并不完全了解我们的网络内部发生了什么。无论如何,研究人员正在积极研究这个具有挑战性的问题。

加快进程

MobileNets benchmarking

深度学习的许多进展都是由硬件的改进推动的,特别是 GPU。GPU 允许高速处理可以并行完成的计算。由于矩阵运算运算,深度网络需要大量的乘加运算;GPU 擅长执行这些操作。这是一个了不起的进步,但是我们并不是到处都有 GPU!

许多最先进的网络,包括上面讨论过的网络,只能在高端 GPU 上以合理的速度运行。移动 设备是一个巨大的市场,采取措施为该市场服务非常重要。此外,随着网络越来越深,它们往往需要更多的内存,从而限制更多的设备运行网络!

这一领域的研究最近实际上有了很大进展。 MobileNets 是一个体系结构家族,已经流行于直接在移动设备上运行深度网络。他们使用不同风格的卷积来减少内存消耗和推理时间。

把一切都包起来

这是一个总结!我们看到了对图像进行分类有多么困难,并回顾了使用深度学习在该领域取得的惊人进展。我们也看到了未来的一些挑战。但是用新的科学和工程来应对这些挑战是技术令人兴奋的地方。

喜欢学习?

在推特上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上与我联系!

机器共情的深度学习:机器人和人类的互动——第一部分

原文:https://towardsdatascience.com/deep-learning-for-machine-empathy-robots-and-humans-interaction-part-i-8142fccd6050?source=collection_archive---------10-----------------------

当我们思考下一次数字革命迫在眉睫的发展时,人类将面临前所未有的自动化浪潮。越来越多的智能和互联设备将与我们共存。这场革命已经在发生,从手机到自动驾驶汽车,甚至我们的冰箱。有一点是肯定的,机器人已经出现了,而且会一直存在下去。

问题不是我们是否同意,而是我们将如何与这些新租户互动。除了传统的设计原则,如实用性和风格,一个新的标准将获得相关性:机器同理心。随着越来越多的公司认识到人机交互(HMI)是安全技术采用的关键,这种趋势将变得更加强烈。

但是,我们能做些什么来改善人机交互呢?我们能至少软化我们的共存吗?

融入社会的关键是掌握理解他人感受和想法的能力,并做出相应的反应。直到现在,这种能力只保留给(一些)人类。这种被称为同理心的美德促进了社会化,而人类天生善于交际。

因此,答案可能是让机器有能力理解我们的感受、我们的需求和我们的目标。这样他们就能做出相应的反应,最大限度地提高我们的舒适度。这也包括给他们正确的形式。这种新一代机器人会是类人机器人吗?温和的自动机像无害的 Roomba ?或者可能是可怕的黑镜的金属头机器人“狗”和他们现实生活中来自波士顿动力的远亲。这是讨论 HMI 时整体的一部分。

许多研究人员已经在这个领域开展工作,特别是麻省理工学院的人形机器人小组。他们开发了社交机器人 Kismet。Kismet 对观众表现出的情绪做出友好的反应,让人们参与自然而富有表现力的面对面互动。初步结果显示,人类与这些机器之间的互动有了很大的改善。

Kismet, MIT’s social robot.

很明显,这一新的自动化浪潮的成功将在很大程度上取决于机器人的同情心和个性。想象一下,一辆汽车检测到你感到悲伤,并自动播放你喜欢的歌曲让你感觉更好,或者一个机器人医疗助理识别你的需求并做出反应,给你最大限度的关注和安慰。通过添加强大的自动语音识别和自然语言处理(由亚马逊 Alexa 和其他公司广泛开发),可能性是无限的。

这样一个系统可以从外部信息源获取信息,并根据经验不断发展。您的设备将不断向您学习。这种超个性化将产生一个直接的结果:独特性。独特性是依恋、的燃料,而依恋在本质上是人类的。

Real Steel robot Atom (2011)

在科幻电影《铁钢》(2011)中,拳击手机器人 Atom 在战斗中多次遭受严重损伤。突然,情绪开始出现,作为一个明显的标志,我们不想失去原子;它是独一无二的。我们知道是什么让 Atom 与其他机器人相比如此特别,它表现出感情;很有同情心。

不过不用担心,那时候云存储和电信技术会那么发达,你的机器人失去个性的可能性很小。

尚不清楚这将如何改变科技行业并影响消费者习惯。你会像以前一样频繁地换车吗?您会觉得您的设备独一无二吗?你能和它建立联系吗?

现实是,我们仍然没有这些问题的答案。这场革命正在开始,其潜在后果尚未被完全理解。那么这个话题将成为未来几年公开讨论的一部分。

深度学习和情感识别

情感识别是拥有真正的“移情”机器之旅的第一步。这种系统已经使用深度学习架构,特别是卷积神经网络(CNN)成功构建。

这一成功背后的秘密是 CNN 能够自动学习识别输入图像的相关低级和高级特征。该网络生成越来越明确的图像表示,学习将低级和高级特征结合起来,最终关心实际内容,而不是单个像素信息。这个最终的表示用于将情绪分类成几个类别,例如,悲伤、快乐、愤怒、恐惧、惊讶和中立。关于这一点的非常详细的解释可以在臭名昭著的论文'A Neural Algorithm to Transfer Style'中找到。

以下视频是一周沉浸在使用深度卷积神经网络的实时情感识别中的结果。为了测试这个解决方案,我们选择了著名的《悲伤的本·阿弗莱克》采访。初步结果如下所示(更多改进即将推出):

Sad Affleck inteview meets AI

在下一篇文章中,我们将直接讨论基于深度学习的机器人基本(和功能)移情模块的实现。我们将深入研究计算机视觉技术,从经典的快速人脸检测算法到用于情感识别和迁移学习的深度神经网络。

问题

我希望你和我一样喜欢这篇文章。我很乐意阅读你对这个话题的看法。不要犹豫留下你的评论,掌声也欢迎。请关注我,让您了解本文的下一部分。如果你想了解更多关于 Axionable、项目和职业的信息,请访问我们的网站并在 Twitter 上关注我们。

参考书目

Breazeal,C. (2000),“社交机器:人类和机器人之间的表达性社会交换”。麻省理工学院电子工程和计算机科学系博士论文。

洛杉矶 Gatys 公司、埃克公司和 m . Beth ge 公司(2015 年)。艺术风格的神经算法。 CoRR,abs/1508.06576

命名实体识别的深度学习#2:为 CoNLL 2003 实现最先进的双向 LSTM + CNN 模型

原文:https://towardsdatascience.com/deep-learning-for-named-entity-recognition-2-implementing-the-state-of-the-art-bidirectional-lstm-4603491087f1?source=collection_archive---------6-----------------------

基于 Chiu 和 Nichols (2016),该实现在 2003 年 CoNLL 新闻数据上取得了 90%以上的 F1 分数。

CoNLL 2003 是对 NER 有用的许多公开可用的数据集之一。在这篇文章中,我们将使用 Keras 和 Tensorflow 在 Python 中实现 Chiu 和 Nichols (2016) ( 此处)的当前 SOTA 算法。该实现的核心是双向 LSTM (BLSTM ),同时还使用卷积神经网络(CNN)来识别字符级模式。

假设读者熟悉 CNN(如果不熟悉,请阅读 Denny Britz 的摘要这里,但不太熟悉 BLSTMs,让我们快速描述一下为什么 BLSTMs 特别适合 NER。

双向 LSTMs

长短期记忆(LSTM)细胞是递归神经网络(RNNs)的构建模块。虽然前馈神经网络中的普通 LSTM 细胞像人类一样处理文本(从左到右),但 BLSTMs 也考虑相反的方向。随着输入信息量的增加,这使得模型能够发现更多的模式。换句话说,该模型不仅考虑感兴趣的记号之后的记号序列,还考虑感兴趣的记号之前的*。*

下图更正式地表达了这一观点。请注意, x 代表输入序列, h 代表向前或向后运行的输出序列(分别由指向右边或左边的箭头定义), y 代表串接的输出序列,其中串接向前和向后输出元素。

Unfolded BLSTM architecture with 3 consecutive steps. From Cui et al. (2017) (here).

维基百科的文章(此处)包含了更多的细节,包括到舒斯特和帕利瓦尔(1997)的原始论文的链接(此处)。

Keras 实施

我使用 Keras 和 Tensorflow 后端。这通常是最有效的设置,尤其是在 GPU 上运行时。

[## MX hofer/命名实体识别双向 TM-CNN-CoNLL

命名实体识别双向 TM-CNN-CoNLL - Keras 实现 Chiu 和 Nichols (2016)

github.com](https://github.com/mxhofer/Named-Entity-Recognition-BidirectionalLSTM-CNN-CoNLL)

以下是主要步骤。

嵌入

加载训练、开发和测试数据文件后, embed 函数创建单词和字符级嵌入。这意味着单词和字符被映射到神经网络可以处理的实数。更具体地说,标签(例如 B-ORG、I-ORG、B-LOC 等。)、记号大小写(例如,小写、大写或数字记号)和字符使用字典数据结构被映射到实数。此外,所有唯一的单词被映射到手套嵌入向量。

模型架构

BLSTM 层构成网络的核心,具有以下三个输入:

  1. 字符级模式由卷积神经网络识别
  2. 来自手套嵌入的单词级输入
  3. 大小写输入(无论单词是小写、大写等。)

下图显示了所有层的模型架构。一个 softmax 激活层生成最终输出。

Model architecture, Chiu and Nichols (2016).

因素

推荐参数与论文略有不同。这可能是因为我们不知道 Chiu 和 Nichols (2016)在不使用额外的基于规则的方法的情况下会取得什么样的 F1 分数。仅考虑他们的机器学习模型组件,这些参数达到 90%+的 F1 分数:

  • 80 个时代
  • 0.68 辍学
  • 200 个 LSTM 州大小
  • 3 卷积宽度
  • 那达慕乐观主义者

在您的本地机器上运行代码时,您只需 30 个历元和大约 1 个小时的训练,就可以获得大约 86%的 F1 分数,其中包括上述的下降、LSTM 状态大小、卷积宽度和优化器参数(见下图)。

Learning curve with 30 epochs.

总之,双向 LSTMs 是用于命名实体识别的非常强大和灵活的神经网络类型。提示:尝试在 CoNLL 格式的不同数据上重用模型。表现如何?

我希望这为 CoNLL 2003 数据的当前 SOTA 模型提供了一个有用的概述和实现。让我知道你用不同的参数和其他调整得到的结果!👋

命名实体识别的深度学习#3:在临床文本数据上重用双向 LSTM + CNN

原文:https://towardsdatascience.com/deep-learning-for-named-entity-recognition-3-reusing-a-bidirectional-lstm-cnn-on-clinical-text-e84bd28052df?source=collection_archive---------10-----------------------

这篇文章描述了 BLSTM + CNN 网络如何在 i2b2 临床文本中重复使用,以提取药物名称、剂量、频率和处方原因等。重用该模型可使 F1 得分达到 85.65%,与 i2b2 2009 挑战赛的获胜团队不相上下。

在本系列的 post #2 中,我们在 CoNLL 2003 新闻数据上验证了最先进的模型,一个 BLSTM + CNN 模型,实现了 90%+的 F1 分数。下面是使用 Python 和 Keras 实现的这个网络:

[## MX hofer/命名实体识别双向 TM-CNN-CoNLL

命名实体识别双向 TM-CNN-CoNLL - Keras 实现 Chiu 和 Nichols (2016)

github.com](https://github.com/mxhofer/Named-Entity-Recognition-BidirectionalLSTM-CNN-CoNLL)

该模型在我的 arxiv 论文“【https://arxiv.org/abs/1811.05468】”[]中用于医学文本中命名实体识别的少镜头学习。

i2b2 2009 临床文本数据

i2b2 基金会在 2009 年 NLP 挑战赛后发布了文本数据(由参赛团队标注)。总共有 261 份出院小结注明了药物名称(m)、剂量(do)、给药方式(mo)、给药频率(f)、持续时间(du)和给药原因(r)。以下是训练集、验证集和测试集中每个类别的计数:

Medication annotations:  9318
Dosage annotations:  4666
Mode annotations:  3513
Frequency annotations:  4229
Duration annotations:  571
Reason annotations:  1694

下载和预处理

你可以在这里下载数据(签订数据使用协议是必需的 ) 。一旦您获得访问权限并下载了所有文件,请打开文件夹“annotations_ground_truth”和“training.ground.truth ”,打开并阅读一些注释和相应的文本文件。让自己熟悉注释模式。例如,在“annotations_ground_truth”文件夹中,一个名为“1234.m”的假设注释文件可能是:

m = " Caltrate plus d " 5:1 5:3 | | do = " one " 5:4 5:4

…表示名为“caltrate plus d”的药物包含在名为“1234”(无文件扩展名)的文本文件中,第 5 行,偏移量 1 至 3(含)。类似地,剂量“一”直接跟随在第 5 行偏移 4 处的药物之后。

您必须对文件名进行一些预处理,去掉文件名中任何不必要的文本。我发现最简单的方法是创建一个名为“数据”的文件夹,其中包含两个子文件夹“注释”和“条目”。将相应的文件添加到子文件夹中。目标是从注释到文本条目有一个 1:1 的映射,这些条目可以连接起来创建完整的数据集。对于 id 为“1234”的出院小结,注释和条目均应命名为“1234”。i2b2 2009 数据中的文件以文档 id 开始,因此这个代码片段可以帮助您去掉剩余的文本:

将 i2b2 解析为 CoNLL 格式

注释和条目文件名匹配后,我们现在可以将数据从 i2b2 解析为 CoNLL 格式。这涉及到几行代码,下面简要介绍一下。这是 iPython 笔记本:

[## mxhofer/i2b2_2009-to-CoNLL

在 GitHub 上创建一个帐户,为 i2b2_2009-to-CoNLL 开发做出贡献。

github.com](https://github.com/mxhofer/i2b2_2009-to-CoNLL)

首先,解析器为注释和条目建立语料库。注释语料库用于建立注释数据框,包含文档 id、NER 标签(使用 BIO 方案)、注释的行和偏移。条目语料库用于建立条目数据框架,包含文档 id、行、偏移量和相应的单词。它还包含空行关键字(-EMPTYLINE)和新文档的开始关键字(-DOCSTART)。

其次,注释和条目数据框在文档 id、行和偏移列上连接。然后用来自 nltk.pos_tag 函数的 POS 标签对结果数据帧进行标记。

最后,在将数据集分成大约 70%的训练数据、15%的验证数据和 15%的测试数据之前,添加名词和动词短语的组块标签。该脚本的输出是一组。txt 文件,即 train.txt、valid.txt 和 test.txt。

请注意解析器的这些限制:

  • 不考虑跨换行符的注释(总共 23,991 个注释中丢失了大约 71 个)。
  • Chunk tagger 只标记名词短语(NP)和动词短语(VP)。
  • 生物注释方案通过在 XXX 类型的每个序列的开始处的标签“B-XXX”来实现(而不仅仅是为了区分 XXX 类型的连续标签)。

重复使用模型的性能— F1 为 85.65%

如果我们的神经网络模型在新数据上表现不好,那么所有的解析又有什么价值呢?这就是机器学习的魅力所在。尽管针对路透社的新闻数据进行了优化,但该模型仍与 i2b2 2009 挑战赛的最佳提交数据持平,F1 得分为 85.65%。这是一个了不起的结果!

在我的实验中,这些参数运行良好:

  • 50 个时代
  • 0.5%辍学
  • 200 个 LSTM 州大小
  • 3 卷积宽度
  • 那达慕乐观主义者

调整这些参数,看看你能否打破 2009 年的最先进的分数。

结论

最后,我们从下载 i2b2 2009 数据集开始,继续将 i2b2 数据解析为 CoNLL 格式,以便重用 BLSTM + CNN 模型。在这个过程中,我们了解到神经网络(在某种程度上)不知道底层数据来自哪个领域。虽然 i2b2 2009 挑战赛中的大多数系统都使用了由临床医生硬编码的手工制作的功能和规则,但没有临床知识(像我一样)但有一些机器学习知识的人可以构建一个强大的命名实体识别工具。

您想将此模型用于哪些文本数据?

奖金-计算每个注释类别的 F1 分数

如果您想深入了解,请计算每个注释类别的 F1 分数。您应该会发现,该模型在提取药物名称(m)方面表现良好,但在管理原因(r)方面表现不佳。这是有道理的:实施治疗的原因比药物名称要模糊得多。此外,可用于培训的药物名称数量超过 5 倍。

希望代码对您来说很好。如果没有,请在下面的评论中留言,我很乐意帮忙。👋

命名实体识别的深度学习#1:公共数据集和标注方法

原文:https://towardsdatascience.com/deep-learning-for-ner-1-public-datasets-and-annotation-methods-8b1ad5e98caf?source=collection_archive---------1-----------------------

欢迎来到我的“命名实体识别的深度学习”系列的第一篇文章——让我们从访问高质量数据集开始!🚀

Need for data: Deep Learning for NER requires thousands of training points to achieve reasonable accuracy.

在撰写关于使用深度学习进行命名实体识别(NER)的硕士论文时,我将在一系列帖子中分享我的学习成果。主题包括如何以及在哪里找到有用的数据集(本帖!),最先进的实现以及今年晚些时候一系列深度学习模型的利弊。

公共数据集

与任何深度学习模型一样,你需要大量数据。高质量的数据集是任何深度学习项目的基础。幸运的是,有几个带注释的、公开的、大部分免费的数据集。

CoNLL 2003

这个数据集包括 1393 篇英语和 909 篇德语新闻文章。英语语料库是免费的,但不幸的是,德语语料库要 75 美元。这是本帖中唯一有价值的语料库。为了建立英语语料库,你需要 RCV1 路透社语料库。您将在提交组织和个人协议几天后免费获得访问权限。

实体标注有 LOC (位置) ORG (组织) PER (人员)和 MISC (其他)。这是一个例句,每行由[单词][词性标签][组块标签] [NER 标签]组成:

联合国 NNP I-NP I-ORG
官方 NN I-NP O
埃克乌斯 NNP I-NP I-PER
首脑 VBZ I-VP O
为 I-PP O
巴格达 NNP I-NP I-LOC
。哦哦

这里有一个POS 标签代表什么的综合列表。这是官方的 2003 年 CoNLL 介绍文件和 GitHub wiki 的 SOTA 排名。

onto notes 5.0/2012 年

OntoNotes 版由 1,745,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,0000 个阿拉伯文本数据组成,这些数据来自一系列来源:电话交谈,新闻专线,广播新闻,广播,广播,广播对话和网络博客。实体标注有组织地点等类别(此处 18 个类别的完整列表,第 21 页)。通过你的大学/系获得访问权是最容易的——当你在这里注册时检查。

i2b2 挑战

整合生物学和床边信息学(i2b2)中心发布了大量 NER 的临床数据集。特别是 2009 年(提取药物),2012 年(提取问题,治疗等。)和 2014 年(提取疾病、危险因素、用药等。)挑战是非常相关的,包括记录良好的最先进的实施。获得访问权是免费的——它需要签署一份协议,声明你基本上是以体谅的态度对待数据的。i2b2 回复很快!

更多数据

我没有详细查看其他数据集,但它们可能对您的应用程序仍然有用: NLPBA 2004 标记有蛋白质/DNA/RNA/细胞系/细胞类型(2,404 MEDLINE 摘要)和 Enron 电子邮件标记有姓名/日期/时间(大约 500 K 条消息)。

注释方法

了解不同的注释模式需要一些时间。有许多框架,从标记方法(类似 HTML)到键值对。

标记(例如 OntoNotes 5.0)

这种注释方法使用带有尖括号的标记标签来定义命名实体,例如组织:

迪士尼是一个全球品牌。

IOB(如 CoNLL 2003)

IOB(或 BIO)代表 B 内, I 内, O 外。用 O 标记的单词在命名实体之外,而 I-XXX 标记用于类型为 XXX 的命名实体内的单词。每当两个类型为 XXX 的实体彼此紧邻时,第二个实体的第一个单词将被标记为 B-XXX 以突出显示它开始另一个实体。下面是一个例句,每行由[单词][词性标签] [NER 标签]组成:

我们PRP B-NP
看见了 VBD O
那个 DT B-NP
黄 JJ I-NP
狗 NN I-NP

北京生物工程学院

一种更复杂的注释方法区分命名实体和单个实体的结尾。这种方法被称为内侧、**B、**n、 **O、**n、 **E、**d、 **S、**S。上述数据集都没有使用现成的 BIOES,但它显示出比 BIO 有相当大的性能改进(例如 Chiu 和 Nichols,2016 )。

更多方法和细节

这里有一篇很棒的博文关于进一步的注释方法及其复杂性。

第一篇帖子到此结束。理解可用的数据以及如何对其进行注释,为您以后构建可靠的统计模型提供了良好的基础。让我知道你是否找到了其他有用的数据来源!👋

用于物体检测的深度学习:综述

原文:https://towardsdatascience.com/deep-learning-for-object-detection-a-comprehensive-review-73930816d8d9?source=collection_archive---------0-----------------------

随着自动驾驶汽车、智能视频监控、面部检测和各种人数统计应用的兴起,对快速准确的物体检测系统的需求不断增加。这些系统不仅包括识别和分类图像中的每个对象,还包括通过在每个对象周围绘制适当的边界框来定位每个对象。这使得物体检测比其传统的计算机视觉前身图像分类困难得多。

然而,幸运的是,目前最成功的对象检测方法是图像分类模型的扩展。几个月前,谷歌为 Tensorflow 发布了一个新的对象检测 API 。随着这一版本的发布,为少数特定型号提供了预构建的架构和重量:

  • 带 MobileNets 的单次多箱探测器 (SSD)
  • 带盗梦空间 V2 的固态硬盘
  • 基于区域的全卷积网络 (R-FCN)带 Resnet 101
  • 使用 Resnet 101 实现更快的 RCNN
  • 更快的 RCNN 与 Inception Resnet v2

在我的上一篇博文中,我介绍了上面列出的三种基础网络架构背后的直觉:MobileNets、Inception 和 ResNet。这一次,我想对 Tensorflow 的对象检测模型做同样的事情:更快的 R-CNN、R-FCN 和 SSD。到这篇文章结束时,我们将有望了解深度学习如何应用于对象检测,以及这些对象检测模型如何相互启发和分歧。

更快的 R-CNN

更快的 R-CNN 现在是基于深度学习的对象检测的规范模型。它帮助启发了许多后来的检测和分割模型,包括我们今天要研究的另外两个模型。不幸的是,如果不了解它的前身 R-CNN 和 Fast R-CNN,我们就无法真正开始了解更快的 R-CNN,所以让我们快速了解一下它的祖先。

R-CNN

有线电视新闻网是更快的有线电视新闻网的始祖。换句话说,R-CNN 真的开球了。

R-CNN,或称 R 基于地区的Con 可选 N eural N 网络,由 3 个简单的步骤组成:

  1. 使用一种称为选择性搜索的算法扫描输入图像中的可能对象,生成大约 2000 个区域提议
  2. 在这些区域建议的基础上运行卷积神经网络( CNN )
  3. 获取每个 CNN 的输出,并将其输入 a)SVM 以对区域进行分类,以及 b)线性回归以收紧对象的边界框,如果这样的对象存在的话。

这三个步骤如下图所示:

换句话说,我们首先提出区域,然后提取特征,然后根据特征对这些区域进行分类。本质上,我们已经将目标检测转化为图像分类问题。R-CNN 非常直观,但是非常慢。

快速 R-CNN

R-CNN 的直系后裔是 Fast-R-CNN。快速 R-CNN 在许多方面与原来的相似,但通过两个主要增强功能提高了检测速度:

  1. 在提出区域之前,对图像执行特征提取,从而在整个图像上仅运行一个 CNN,而不是 2000 个 CNN 的 2000 多个重叠区域
  2. 用 softmax 图层替换 SVM,从而扩展用于预测的神经网络,而不是创建新模型

新模型看起来像这样:

正如我们从图像中看到的,我们现在基于网络的最后一个特征图而不是原始图像本身来生成区域建议。因此,我们可以为整个图像只训练一个 CNN。

此外,有一个 softmax 图层直接输出分类概率,而不是训练许多不同的 SVM 来对每个对象类进行分类。现在,我们只有一个神经网络来训练,而不是一个神经网络和许多 SVM 氏症。

快速 R-CNN 在速度方面表现得好得多。只剩下一个大瓶颈:生成区域提议的选择性搜索算法。

更快的 R-CNN

在这一点上,我们回到了我们最初的目标:更快的 R-CNN。快速 R-CNN 的主要观点是用快速神经网络取代缓慢的选择性搜索算法。具体来说,它介绍了区域提案网络 (RPN)。

RPN 是这样工作的:

  • 在初始 CNN 的最后一层,3×3 的滑动窗口在特征图上移动,并将其映射到更低的维度(例如 256-d)
  • 对于每个滑动窗口位置,它基于 k 固定比率锚框(默认边界框)生成多个可能区域
  • 每个区域提议包括 a)该区域的“客观性”分数,以及 b)表示该区域的边界框的 4 个坐标

换句话说,我们查看上一个特征地图中的每个位置,并考虑以它为中心的不同盒子:高盒子、宽盒子、大盒子等等。对于这些盒子中的每一个,我们输出我们是否认为它包含一个对象,以及这个盒子的坐标是什么。这是在一个滑动窗口位置的外观:

2 个 k 个分数表示每个 k 个边界框位于“对象”上的最大软概率请注意,尽管 RPN 输出边界框坐标,但它并不试图对任何潜在的对象进行分类:它唯一的工作仍然是提出对象区域。如果锚定框的“客观性”分数高于某个阈值,则该框的坐标将作为区域建议向前传递。

一旦我们有了地区提案,我们就把它们直接输入到一个快速的 R-CNN 中。我们添加一个池层,一些完全连接的层,最后是一个 softmax 分类层和边界框回归。从某种意义上来说,快 R-CNN = RPN +快 R-CNN。

总之,更快的 R-CNN 实现了更好的速度和最先进的准确性。值得注意的是,虽然未来的模型做了很多工作来提高检测速度,但很少有模型能够远远超过更快的 R-CNN。换句话说,更快的 R-CNN 可能不是最简单或最快的对象检测方法,但它仍然是性能最好的方法之一。举个例子,Tensorflow 更快的 R-CNN 和 Inception ResNet 是他们最慢但最精确的模型。

说到底,更快的 R-CNN 可能看起来很复杂,但它的核心设计与最初的 R-CNN 是一样的:假设对象区域,然后对它们进行分类。这是现在许多物体检测模型的主要管道,包括我们的下一个。

R-FCN

还记得 R-CNN 通过在所有区域提案中共享一个 CNN 计算来提高原始的检测速度有多快吗?这种想法也是 R-FCN 背后的动机:通过最大化共享计算来提高速度。

R-FCN,或者说基于区域的 RFfullyCon 可选的 N et,在每一个输出上共享 100%的计算。由于是完全卷积的,它在模型设计中遇到了一个独特的问题。

一方面,在对一个物体进行分类时,我们要学习一个模型中的位置不变性:不管猫出现在图像的什么地方,我们都要把它归类为猫。另一方面,当执行对象的检测时,我们想要学习位置方差:如果猫在左上角,我们想要在左上角画一个方框。因此,如果我们试图在 100%的网络上共享卷积计算,我们如何在位置不变性和位置方差之间折衷?

R-FCN 的解决方案:位置敏感得分图

每个位置敏感得分图代表一个对象类的一个相对位置。例如,一个分数图可能会在检测到右上角时激活。当看到汽车左下方的时,另一个得分图可能会激活。你明白了。本质上,这些分数图是卷积特征图,已经被训练来识别每个对象的某些部分

现在,R-FCN 的工作方式如下:

  1. 对输入图像运行 CNN(在本例中是 ResNet)
  2. 添加一个完全卷积层,以生成前述“位置敏感得分图”的得分库应该有 k (C+1)个分数图,其中 k 表示划分对象的相对位置的数量(例如,3×3 网格为 3),C+1 表示类别加上背景的数量。
  3. 运行完全卷积区域建议网络(RPN)以生成感兴趣区域(RoI)
  4. 对于每个 RoI,将其划分为与分数图相同的 k 个“箱”或子区域
  5. 对于每个媒体夹,检查乐谱库以查看该媒体夹是否与某个对象的相应位置相匹配。例如,如果我在“左上角”框上,我将抓取对应于对象“左上角”的得分图,并对 RoI 区域中的这些值进行平均。这一过程对每个班级都重复进行。
  6. 一旦 k 个箱中的每一个都具有每个类的“对象匹配”值,则对箱进行平均以获得每个类的单个分数。
  7. 在剩余的 C+1 维向量上用 softmax 对 RoI 进行分类

总的来说,R-FCN 看起来像这样,一个 RPN 生成 RoI:

即使有了解释和图像,您可能仍然会对这个模型的工作原理感到有点困惑。老实说,当你能想象它在做什么时,R-FCN 就更容易理解了。这是一个 R-FCN 在实践中检测婴儿的例子:

简单地说,R-FCN 考虑每个区域提议,将其划分为子区域,并在子区域上迭代,询问:“这看起来像婴儿的左上方吗?”,“这看起来像婴儿的顶部中心吗?”“这看起来像婴儿的右上方吗?”等。它对所有可能的类重复这一过程。如果足够多的子区域说“是的,我与婴儿的那部分匹配!”,RoI 在所有类的 softmax 之后被分类为婴儿。

通过这种设置,R-FCN 能够通过建议不同的对象区域来同时解决位置变化,并且通过使每个区域建议引用回相同的分数地图库来解决位置不变性。这些评分图要学会把一只猫归为一只猫,不管这只猫出现在哪里。最重要的是,它是完全卷积的,这意味着所有的计算在整个网络中共享。

因此,R-FCN 比更快的 R-CNN 快几倍,并达到相当的准确性。

(同 solid-statedisk)固态(磁)盘

我们最后的型号是 SSD,代表Ssingle-ShotDetector。像 R-FCN 一样,它提供了比更快的 R-CNN 更大的速度增益,但是以一种明显不同的方式。

我们的前两个模型在两个独立的步骤中执行区域提议和区域分类。首先,他们使用区域提议网络来生成感兴趣的区域;接下来,他们使用全连接层或位置敏感卷积层对这些区域进行分类。SSD 在“单次拍摄”中完成这两项工作,在处理图像时同时预测边界框和类。

具体来说,给定一个输入图像和一组基本事实标签,SSD 执行以下操作:

  1. 将图像通过一系列卷积层,产生几组不同比例的特征图(例如 10x10、6x6、3x3 等。)
  2. 对于这些特征图的每个中的每个位置,使用 3×3 卷积过滤器来评估一小组默认边界框。这些默认的边界框本质上相当于更快的 R-CNN 的锚框。
  3. 对于每个框,同时预测 a)边界框偏移和 b)类别概率
  4. 在训练期间,根据 IoU 将地面实况框与这些预测框匹配。最佳预测框将被标记为“正”,以及所有其他具有真值为 0.5 的 IoU 的框。

SSD 听起来很简单,但是培训它有一个独特的挑战。使用前面的两个模型,区域建议网络确保我们试图分类的所有东西都有成为“对象”的最小概率。然而,对于 SSD,我们跳过了过滤步骤。我们从图像的每一个位置开始分类并绘制边界框,使用多个不同的形状*,在几个不同的比例。结果,我们生成了比其他模型多得多的包围盒,而且几乎所有的包围盒都是反例。*

为了修复这种不平衡,SSD 做了两件事。首先,它使用非最大抑制将高度重叠的框组合成一个框。换句话说,如果四个形状、大小等相似的盒子。包含同一只狗,NMS 会保留最有信心的一只,丢弃其余的。其次,该模型使用了一种叫做硬负挖掘的技术来平衡训练期间的类。在硬负挖掘中,在每次迭代训练时,仅使用具有最高训练损失(即,假阳性)的负样本的子集。固态硬盘保持 3:1 的正负比例。

它的架构是这样的:

正如我上面提到的,在最后有“额外的特征层”,尺寸缩小。这些不同尺寸的特征地图有助于捕捉不同尺寸的物体。例如,下面是固态硬盘的应用:

在较小的特征地图(例如 4x4)中,每个单元覆盖图像的较大区域,使它们能够检测较大的对象。区域提议和分类是同时执行的:给定 p 个对象类别,每个边界框与一个(4+ p )维向量相关联,该向量输出 4 个框偏移坐标和 p 个类别概率。在最后一步中,再次使用 softmax 对对象进行分类。

最终,SSD 与前两种型号没有太大区别。它简单地跳过了“区域提议”步骤,而是在分类的同时考虑图像的每个位置中的每个单个边界框。因为 SSD 一次搞定一切,所以是三款中最快的,表现还是相当不俗的。

结论

更快的 R-CNN、R-FCN 和 SSD 是目前最好和最广泛使用的三种对象检测模型。其他流行的模式往往与这三个相当相似,都依赖于深度 CNN 的(阅读:ResNet,Inception 等。)来完成最初的繁重工作,并在很大程度上遵循相同的提议/分类流程。

此时,将这些模型投入使用只需要了解 Tensorflow 的 API。Tensorflow 有一个使用这些模型的入门教程在这里。试试吧,祝你黑客生涯愉快!

用于从非结构化文本中抽取特定信息的深度学习

原文:https://towardsdatascience.com/deep-learning-for-specific-information-extraction-from-unstructured-texts-12c5b9dceada?source=collection_archive---------1-----------------------

这是与我们的 iki 项目工作相关的系列技术帖子的第一篇,涵盖了机器学习和深度学习技术用于解决各种自然语言处理和理解问题的一些应用案例。

在这篇文章中,我们将解决从非结构化文本中提取某些特定信息的问题。我们需要从用户的简历中提取他们的技能,即使他们是以任意的方式写的,比如“在生产服务器上部署量化交易算法”。

本帖有一个 演示页面 ,在你的简历上查看我们模特的表现。

语言模型

现代语言模型( ULMfit , ELMo )使用无监督学习技术,例如在大型文本语料库上创建 RNNs 嵌入,以在更具体的监督训练步骤之前获得语言结构的一些原始“知识”。相反,在某些情况下,你需要一个在非常具体的小数据集上训练的模型。这些模型对一般的语言结构几乎一无所知,并且只能处理特殊的文本特征。一个经典的例子是用于电影评论或新闻数据集的幼稚情感分析工具——最简单的工作模型只能在“好”或“坏”形容词同义词和一些强调词存在的情况下运行。在我们的研究中,我们利用了两种方法的优点。

一般来说,当分析某个文本语料库时,我们会查看每个文本的全部词汇。文本矢量化的流行方法,例如 tfidf、 word2vec GloVe模型使用整个文档的词汇来创建其向量,除了停用词(例如冠词、代词和在这种统计平均过程中带来很少语义意义的其他相当通用的语言元素)。如果有一个更具体的任务,你有一些关于文本语料库的额外信息,你可能会说一些信息比另一些更有价值。例如,要对烹饪食谱语料库进行分析,从文本中提取配料或菜名类别是很重要的。另一个例子是从简历的语料库中提取专业技能。例如,如果我们可以通过将简历与提取的技能向量相关联来对每份简历进行矢量化,这将让我们更成功地进行行业职位聚类。

示例:

简历: 数据科学家,在机器学习、大数据、开发、统计和分析方面有动手能力。我的数据科学家团队实施了 Python 机器学习模型集成、堆叠和特征工程,展示了预测分析的高准确率。使用 Doc2Vec 单词嵌入和神经网络创建了一个推荐系统。

提取专业技能: 机器学习、大数据、开发、统计、分析、Python 机器学习模型集成、堆栈、特征工程、预测分析、Doc2Vec、单词嵌入、神经网络。

步骤 1:词性标注

实体抽取的任务是文本挖掘类问题的一部分——从非结构化的文本中抽取一些结构化的信息。让我们仔细看看建议的实体提取方法。至于主要存在于所谓的名词短语中的技能,我们提取过程的第一步将是由 NLTK 库内置方法执行的实体识别(从文本中提取信息的检验, NLTK book,part 7 )。词性标注方法提取名词短语,并建立代表名词短语和句子其他部分之间关系的树。NLTK 库有许多工具可以执行这样的短语分解。

NLTK book, chapter 7, pic 2.2: An example of a simple regular expression based NP Chunker.

我们可以将模型定义为给出句子分解的正则表达式(例如,我们可以将一个短语定义为多个形容词加一个名词),或者我们可以在 NLTK 中带有提取的名词短语示例的标记数量的文本上教授模型。这一步导致接收许多实体,其中一些是目标技能,一些不是——除了技能 CV 可以包含一些其他实体,如地点、人员、对象、组织等等。

步骤 2:用于候选分类的深度学习架构

下一步是实体分类。这里的目标很简单——区分技能和“非技能”。用于训练的特征集是根据候选短语的结构和上下文构成的。显然,为了训练一个模型,我们必须创建一个带标签的训练集,我们手动为 1500 个提取的实体做了这件事,这些实体中有技能和“非技能”。

我们从来没有试图让我们的模型适合一些有限的硬编码技能,该模型背后的核心思想是学习英语简历中技能的语义,并使用该模型提取看不见的技能。

每个单词的向量由二进制特征组成,如数字或其他特殊字符的出现(技能通常包含数字和符号:C#、Python3)、首字母大写或整个单词大写(SQL)。我们还检查一个单词是否出现在英语词汇和一些主题列表中,如名称、地名等。使用所列特征的最终模型在实体测试集上显示了 74.4%的正确结果。使用另一个二元特征来描述候选中流行的英语前缀和后缀的存在,将模型的性能提高到测试集上 77.3%的正确结果。在模型的特征集中加入编码词性的独热向量后,我们的结果提高到了 84.6%。

可靠的语义单词嵌入模型不能在 CV 数据集上训练,它太小并且太窄,为了减轻这个问题,你应该使用在其他一些非常大的数据集上训练的单词嵌入。我们使用 50 维的手套模型向量,在测试集上将我们的模型性能提高到 89.1%的正确结果。您可以通过上传您简历中的文本,在我们的 演示 中玩最终模型。

流行的词性标注者( NLTK POS tagger , Stanford POS tagger )经常在简历的短语标注任务中出错。原因是,为了突出经验并赋予其一定的结构(人们以谓语而不是主语开始句子,有时短语缺少适当的语法结构),简历文本经常忽略语法,许多单词是特定的术语或名称。我们必须编写自己的 postager 来解决上述问题。

分类是用 Keras 神经网络执行的,该网络具有三个输入层,每个输入层被设计成接受特殊类别的数据。第一输入层采用由候选短语的上述特征组成的可变长度向量,该候选短语可以具有任意数量的单词。这个特征向量用 LSTM 层处理。

第二个可变长度向量带来上下文结构信息。对于给定的窗口大小 n,我们取候选短语右侧的 n 个相邻单词和左侧的 n 个单词,这些单词的矢量表示被连接成可变长度矢量并被传递到 LSTM 层。我们发现最优的 n=3。

第三输入层具有固定的长度,并利用关于候选短语及其上下文的一般信息来处理向量——短语及其上下文中的单词向量的坐标最大值和最小值,这些信息以及其他信息表示整个短语中许多二元特征的存在或不存在。

我们称这个建筑技能为“拖拉机”,这就是。

Skills Extractor network architecture

它的 Keras 实现如下所示:

在学习率降低到 0.0001 的情况下,用 Adam 优化器实现了模型训练的最佳结果。我们选择 binary_crossentropy 作为损失函数,因为该模型被设计成分类成两类。

为了方便使用,我们加入拟合方法,利用交叉验证和预测函数进行神经网络的训练和自动停止,形成候选短语特征向量的预测。

pad_sequences 函数将特征序列列表转换为一个 2d 数组,其宽度等于列表中最长的序列。这是为了将进入 LSTM 层的可变长度数据转换成模型训练所需的格式。

onehot_transformfunction 将目标值 0 和 1 转换为 one-hot 向量[1,0]和[0,1]

只要实体及其上下文中的字数是任意的,使用稀疏固定长度向量看起来就不合理。因此,处理任意长度向量的递归神经网络在这里成为一种方便且非常自然的解决方案。我们的测试证明,使用密集层来处理固定长度向量,使用 LSTM 层来处理可变长度向量的架构是最佳的。

已经用密集层与 LSTM 层的不同组合测试了几种架构。最终的架构配置(层的大小和数量)显示了交叉验证测试的最佳结果,这对应于训练数据的最佳使用。可以通过增加训练数据集的大小以及适当地缩放层的大小和数量来执行进一步的模型调整,使用相同的数据集进行后期调整会导致模型过度拟合。

结果

Examples of extracted skills

所有用于模型训练的简历都来自 IT 行业。我们很高兴地看到,我们的模型在属于其他行业(如设计和金融)的简历数据集上也显示出相当合理的性能。显然,处理结构和风格完全不同的 cv 会导致模型性能降低。我们还想提一下,我们对“技能”概念的理解可能与其他人不同。对于我们的模型来说,一个困难的情况是分辨新公司名称中的技能,因为技能通常等同于软件框架,有时你无法分辨这是提到的初创公司名称,还是新的 JS 框架或 Python 库。然而,在大多数情况下,我们的模型可以成为自动 CV 分析的有用工具,并且与一些统计方法一起可以解决任意 CV 语料库上的广泛的数据科学任务。

面向大众的深度学习(…和语义层)

原文:https://towardsdatascience.com/deep-learning-for-the-masses-and-the-semantic-layer-f1db5e3ab94b?source=collection_archive---------7-----------------------

深度学习现在无处不在,在你的手表里,在你的电视机里,在你的手机里,在某种程度上,在你阅读这篇文章的平台上。在这里我将谈论如何以一种非常简单的方式开始使用深度学习来改变你的业务。但是首先,你需要了解语义层。

深度学习简介

本文的范围不是介绍深度学习,我已经在其他文章中介绍过了,您可以在这里找到:

[## 深度学习的“怪异”介绍

有关于深度学习的惊人介绍、课程和博文。但这是一种不同的介绍…

towardsdatascience.com](/a-weird-introduction-to-deep-learning-7828803693b0) [## 我的深度学习之旅

在这篇文章中,我将分享我如何研究深度学习并使用它来解决数据科学问题。这是一个…

towardsdatascience.com](/my-journey-into-deep-learning-c66e6ef2a317) [## 关于深度学习的对话

有人无意中听到两个人谈论深度学习,让我知道每一个小细节。其中一个完全…

towardsdatascience.com](/a-conversation-about-deep-learning-9a915983107)

但是如果你想从这里体验一下,我可以告诉你:

…深度学习是使用不同种类的神经网络(深度神经网络)和优化网络的超参数来获得(学习)我们数据的最佳表示的表示学习。

如果你想知道这是从哪里来的,请阅读上面的文章。

深度学习没那么难

This is harder

目前,组织的深度学习并不难。我并不是说深度学习整体上很容易,该领域的研究需要大量的数学、微积分、统计学、机器学习、计算等知识。你可以从我不久前创建的时间线中看到深度学习的来源:

从那里我可以说反向传播的思想,网络参数的更好初始化,更好的激活函数,辍学的概念,以及一些类型的网络,如卷积神经网络,残差网络,区域基 CNN,递归神经网络和生成对抗网络,是我们在深度学习领域取得的最重要的进展之一。

但是你现在如何使用深度学习呢?

hehe

数据第一

Oh, you’d want to be them. Right?. Or maybe not, IDK.

你想知道秘密吗?大型科技公司使用的秘方?不仅仅是深度学习(可能根本不是深度学习)

这里不做完整的演讲,一切从数据说起。正如您可以想象的那样,数据现在是公司的重要资产(可能是最重要的资产)。所以在你可以应用机器学习或深度学习之前,你需要拥有它,知道你拥有什么,理解它,治理它,清理它,分析它,标准化它(也许更多),然后你才能想到使用它。

摘自 Brian Godsey 的惊艳文章:

无论哪种形式,数据现在无处不在,而不仅仅是分析师用来得出结论的工具,它已经成为自己的目的。公司现在似乎将收集数据作为一种目的,而不是一种手段,尽管他们中的许多人声称计划在未来使用这些数据。独立于信息时代的其他定义特征,数据获得了自己的角色、自己的组织和自己的价值。

因此,您可以看到,它不仅将最新的算法应用于您的数据,还能够以良好的格式保存数据,理解数据,然后使用数据。

语义层

These layers mean something. Ok but this is not the semantic layer. Keep reading.

从我这里听到这种事情很不寻常,但是我已经做了很多调查,并且与几家公司合作,他们似乎都有同样的问题。他们的数据。

数据可用性、数据质量、数据接收、数据集成等是常见问题,不仅会影响数据科学实践,还会影响整个组织。

有多种方法可以清理您的数据并为机器学习做准备,并且有很好的工具和方法,您可以在这里阅读更多信息:

[## 宣布 Optimus v2 —简化敏捷数据科学工作流程

作为一名数据科学家,您是否正在寻找一个库来提升您的工作效率?看看这个。

towardsdatascience.com](/announcing-optimus-v2-agile-data-science-workflows-made-easy-c127a12d9e13)

但这意味着你有一个吸收和整合数据的过程。现在有很多很好的工具可以用于 AutoML,我之前已经谈到过:

[## Auto-Keras,或者说如何用 4 行代码创建深度学习模型

自动化机器学习是这个城市的新生事物,它会一直存在下去。它帮助我们创造越来越好的产品…

www.kdnuggets.com](https://www.kdnuggets.com/2018/08/auto-keras-create-deep-learning-model-4-lines-code.html)

以及其他商业工具,如 DataRobot:

[## 用于预测建模的自动机器学习| DataRobot

DataRobot 的自动化机器学习平台使构建和部署准确的预测模型变得快速而简单…

www.datarobot.com](https://www.datarobot.com/)

但是自动摄取和集成呢?

这是语义层令人惊奇的好处之一。但是语义层到底是什么呢?

语义这个词本身就意味着意义或理解。因此,语义层与数据有关,涉及数据的含义而不是数据的结构。

理解这是一个非常重要的过程,我之前已经讲过了:

[## 用数据科学创造智能

在这篇文章中,我将展示数据科学如何让我们通过人工智能创造智能。

towardsdatascience.com](/creating-intelligence-with-data-science-2fb9f697fc79)

这里我提到(来自 Lex Fridman )的是:

理解是将 复杂的 信息转化为 简单的 ,有用的 信息的能力。

当我们理解时,我们正在解码组成这个复杂事物的各个部分,并把我们一开始得到的原始数据转化成有用的、简单易懂的东西。我们通过建模来做到这一点。你可以想象我们需要这样的模型来理解数据的意义。

关联数据和知识图

我们需要做的第一件事是链接数据。链接数据的目标是以一种易于使用和与其他链接数据组合的方式发布结构化数据。

链接数据是 Web 上数据发布和互操作性的新的事实上的标准,并且也正在进入企业。像谷歌、脸书、亚马逊和微软这样的大公司已经采纳了它背后的一些原则。

链接数据的过程是知识图的开始。知识图是一种高级的方法,可以映射某个特定主题的所有知识,填补数据之间的空白,或者数据库内部的虫洞。

知识图由数据和信息的集成集合组成,其中还包含不同数据之间的大量链接。

这里的关键是,在这个新模型下,我们不是在寻找可能的答案,而是在寻找答案。我们想要事实——这些事实从何而来并不重要。

这里的数据可以代表概念、物体、事物、人,实际上是你脑海中的任何东西。图表填充了概念之间的关系和联系。

以下是谷歌 6 年前(是的,6 年前)对知识图谱的精彩介绍:

知识图谱对你和你的公司意味着什么?

按照传统的方式,数据仓库中的数据模型虽然是一项了不起的成就,但却无法吸收向我们袭来的海量数据。创建关系数据模型的过程就是跟不上。此外,用于支持数据发现的数据提取量也太小。

因此,基于 Hadoop 或云存储的数据湖已经激增为数据沼泽,而没有所需的管理和治理能力。

https://timoelliott.com/blog/2014/12/from-data-lakes-to-data-swamps.html

您是否问过您的数据工程师和科学家,他们是否了解您组织拥有的所有数据?动手吧。

分析你所有的数据也非常困难。并了解其背后的关系。

因为是图,知识图更直观。人们不会用表格来思考,但他们会立刻理解图表。当你在白板上画出一个知识图表的结构时,它对大多数人的意义是显而易见的。

知识图表还允许您为图表中的关系创建结构。你可以讲一个图,父母有孩子,父母可以是孩子,孩子可以是兄弟姐妹,这些都是人。提供这样的描述性信息允许从图中推断出新的信息,例如如果两个人有相同的父母,他们一定是兄弟姐妹。

为您的组织扩展语义层

当我在寻找可以帮助我和你实现端到端平台以在企业级交付真正的语义层时,我发现了一个很棒的平台:由一家名为Cambridge Semantics的公司创建的 Anzo。

I’m going to edit this. Keep reading!!

你可以用 Anzo 建立一个叫做“企业知识图”的东西。

图中的节点和边灵活地捕捉了每个数据源的高分辨率孪生数据—结构化的或非结构化的。该图表可以帮助用户快速、交互式地回答任何问题,允许用户与数据进行对话以揭示见解。

除了使每天的大数据分析问题变得简单之外,graph 还开启了 graph 特别适合的新的可能性。基于开放标准的图表是一个持续改进的平台。在图表中,使用业务规则、文本分析甚至机器学习(这将很快变得重要)来快速链接和协调来源。

我也喜欢数据结构的想法。然后我意识到其他人也在用同样的概念。这让我想起了时空结构。我继续定义了数据结构(不知道作者是什么意思,也没有阅读其他定义)。

物理学中时空结构的概念是为了解释空间和时间的连续性而创建的,它由四个维度(或者 11 个或者 26 个,取决于你的理论)组成。在这个结构中,重力是扭曲时空结构的一种表现。

From Ethan Siegel: You can talk about space as a fabric, but if you do, be aware that what you’re doing is implicitly reducing your perspective down to a two-dimensional analogy. Space in our Universe is three dimensional, and when you combine it with time, you get a four dimensional quantity.

那么什么是数据结构呢?如果我们想到物理学中的定义,我们可以说对于一个组织来说:

数据结构是支持公司所有数据的平台。它是如何被管理、描述、组合和普遍访问的。该平台由企业知识图构成,以创建统一的数据环境。

有了 Anzo,这是可能的。这就是使用 Anzo 的数据结构的样子(看起来有点像时空结构,太棒了!):

数据结构之上的是数据层。这些数据层可以添加数据清理、转换、链接和访问控制等内容,以迭代的方式动态增强内存中的图形。

这种堆叠方式的数据层非常灵活,这意味着您可以轻松地打开或关闭层,并根据需要移除、复制和创建层。

有了 Anzo,你可以自动生成查询(是的,这是一个东西),并使用它们来处理复杂的图形,使提取特征变得容易,并最终完全自动化!

通过 Anzo 的几个组件,用户可以真正地与他们的数据进行对话——快速而轻松地根据问题的答案以新的方向进行分析,而无需专业的查询知识,他们甚至可以遍历最复杂的多维数据,以构建探索性的图表、过滤器、表格甚至网络视图。

通过 Spark、Featuretools 和 Optimus 等开源技术的连接,您可以充分准备您的数据,并最终为机器和深度学习做好准备。

我将在未来写更多关于这方面的内容,但现在,让我们认为我们已经有了我们的数据结构和一切,我们想做机器和深度学习。

适合你的深度学习

好的,深度学习。你想用它。它的主要应用是什么?

在这里你可以看到其中的一些:

https://www.slideshare.net/NVIDIA/deep-learning-workflows-training-and-inference

在深度学习成为人工智能世界之王的几年里,它取得了巨大的成就,Franç ois Chollet 列出了深度学习的以下突破:

  • 接近人类水平的图像分类。
  • 接近人类水平的语音识别。
  • 接近人类水平的手写转录。
  • 改进的机器翻译。
  • 改进的文本到语音转换。
  • Google Now 或亚马逊 Alexa 等数字助手。
  • 接近人类水平的自动驾驶。
  • 谷歌、百度和必应使用的改进的广告定位。
  • 改进的网络搜索结果。
  • 回答自然语言问题。

所以你可以用它做很多事情。现在,你怎么做呢?

可悲的是,人工智能专业知识(严重)短缺,这给准备采用人工智能的组织造成了重大障碍。通常我们做深度学习编程,学习新的 API,有些比其他的更难,有些真的很容易,比如 Keras。

现在,你可以使用一种更具表现力的方式来创建深度学习模型。那就是利用深度认知。我以前讲过:

[## 深度认知让深度学习变得简单

在过去的一个月里,我有幸见到了 DeepCognition.ai 的创始人

becominghuman.ai](https://becominghuman.ai/deep-learning-made-easy-with-deep-cognition-403fbe445351)

他们的平台 Deep Learning Studio 有云解决方案、桌面解决方案(【http://deepcognition.ai/desktop/】)可供选择,软件将在您的机器或企业解决方案(私有云或内部解决方案)上运行。

您可以使用预先训练的模型以及内置的辅助功能来简化和加速模型开发过程。您还可以导入模型代码,并使用可视化界面编辑模型。

当您迭代和调整超参数以提高性能时,平台会自动保存每个模型版本。您可以比较不同版本的性能,以找到您的最佳设计。

这个系统建立的前提是让人工智能对每个人来说都很容易,当创建这个复杂的模型时,你不必成为专家,但我的建议是,你对自己正在做的事情有一个想法,阅读一些 TensorFlow 或 Keras 文档,观看一些视频并获得信息是很好的。如果你是这方面的专家,那太好了!这将使你的生活更容易,你仍然可以在构建模型时应用你的专业知识。

你实际上可以下载产生预测的代码,正如你将看到的,它是用 Keras 编写的。然后,您可以上传代码,并使用系统提供的笔记本进行测试,或者在您的笔记本电脑或其他平台上使用它。

语义层和深度学习

因此,通过语义层与 Anzo 等平台和 Deep Learning Studio 等深度学习系统的连接,您可以加速数据和人工智能在您公司的使用。我认为这是一条几乎适用于所有组织的道路:

I went ahead and modified the original picture. I think this is with a touch of Python, Spark and stuff like that can be the future of data science and data technologies.

我认为这与敏捷商业科学问题框架(ABSPF)这样的方法一起,从端到端的角度来看,确实可以为组织带来价值。有关 ABSPF 的更多信息:

[## 创建 ROI 驱动的数据科学实践的敏捷框架

数据科学是一个令人惊叹的研究领域,学术界和工业界都在积极发展…

www .商业科学. io](https://www.business-science.io/business/2018/08/21/agile-business-science-problem-framework.html)

我认为我们可以让世界变得更好,改善我们的生活,改善我们工作、思考和解决问题的方式,如果我们现在就调动我们所有的资源,让这些知识领域为更大的利益而共同努力,我们就可以对世界和我们的生活产生巨大的积极影响。

这是我想和你开始的一个更长对话的开始。我希望它能帮助你在这个神奇的领域开始,或者只是发现一些新的东西。

如果这篇文章对你有帮助,请分享给你的朋友!

如果您有任何问题,请在 Twitter 上关注我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

和 LinkedIn:

[## favio vázquez——science ia y Datos | LinkedIn 创始人

查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 16 个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/faviovazquez/)

那里见:)

深度学习框架 Power Scores 2018

原文:https://towardsdatascience.com/deep-learning-framework-power-scores-2018-23607ddf297a?source=collection_archive---------2-----------------------

谁在使用、兴趣和受欢迎程度上领先?

深度学习仍然是数据科学中最热门的事情。深度学习框架正在快速变化。就在五年前,除了首席执行官之外,其他领导人都不在。

我想找到哪些框架值得关注的证据,所以我开发了这个权力排名。我使用了 7 个不同类别的 11 个数据源来衡量框架的使用、兴趣和受欢迎程度。然后我对这个 Kaggle 内核中的数据进行加权合并。

2018 年 9 月 20 日更新:由于普遍的需求,我扩展了评估的框架,包括 Caffe,Deeplearning4J,Caffe2 和 Chainer。现在所有在 KDNuggets 使用调查中报告使用率超过 1%的深度学习框架都包括在内。

2018 年 9 月 21 日更新:我在几个指标上做了一些方法上的改进。

事不宜迟,下面是深度学习框架的能力得分:

虽然 TensorFlow 是明显的赢家,但也有一些令人惊讶的发现。让我们开始吧!

竞争者

所有这些框架都是开源的。除了一个人之外,其他人都可以使用 Python,还有一些可以使用 R 或其他语言。

TensorFlow 是无可争议的重量级冠军。它拥有最多的 GitHub 活动,谷歌搜索,中型文章,亚马逊上的书籍和 ArXiv 文章。它还拥有大多数开发人员使用它,并被列在大多数在线职位描述中。TensorFlow 由谷歌提供支持。

Keras 有一个“为人类设计的 API,而不是为机器设计的”这是几乎所有评估领域中第二受欢迎的框架。 Keras 位于 TensorFlow、Theano 或 CNTK 之上。如果你是深度学习的新手,可以从 Keras 开始。

PyTorch 是第三大流行的整体框架,也是第二大流行的独立框架。它比 TensorFlow 年轻,受欢迎程度增长迅速。它允许 TensorFlow 不允许的定制。它得到了脸书的支持。

Caffe 是第四大流行的框架。已经有将近五年了。雇主对它的需求相对较大,学术文章中也经常提到,但最近很少报道它的使用。

Theano 于 2007 年在蒙特利尔大学开发,是最古老的重要 Python 深度学习框架。它已经失去了很多人气,它的领导者声明主要版本已经不在路线图上了。但是,更新仍在继续。Theano 仍然是得分第五高的框架。

MXNET 由 Apache 孵化,亚马逊使用。它是第六大最受欢迎的深度学习库。

CNTK 是微软的认知工具包。它让我想起了微软的许多其他产品,因为它试图与谷歌和脸书的产品竞争,但并没有赢得广泛的采用。

Deeplearning4J ,也叫 DL4J,配合 Java 语言使用。这是 Python 中唯一不可用的半流行框架。但是,您可以将使用 Keras 编写的模型导入 DL4J。这是唯一一个两个不同的搜索词偶尔会有不同结果的框架。我对每个指标都使用了较高的数字。由于该框架得分很低,这并没有造成实质性的差异。

Caffe2 是另一个脸书开源产品。它构建于 Caffe 之上,现在存放在 PyTorch GitHub 库中。因为它不再有自己的存储库,所以我使用了旧存储库中的 GitHub 数据。

Chainer 是由日本公司 Preferred Networks 开发的一个框架。它有一小群追随者。

FastAI 建立在 PyTorch 上。它的 API 受 Keras 的启发,只需要更少的代码就能得到很好的结果。截至 2018 年 9 月中旬,FastAI 处于领先地位。它正在为定于 2018 年 10 月发布的 1.0 版本进行重写。杰瑞米·霍华德,FastAI 背后的力量一直是一个顶级卡格勒和卡格勒的总裁。他在这里讨论了为什么 FastAI 从 Keras 转到制作他们自己的框架。

FastAI 还没有被职业需求,也没有被广泛使用。然而,它通过广受欢迎的免费在线课程拥有庞大的用户渠道。它功能强大且易于使用。它的采用可能会显著增加。

标准

我选择了以下类别,以提供对深度学习框架的流行度和兴趣的全面看法。

评估类别包括:

  • 在线工作列表
  • KDnuggets 使用调查
  • 谷歌搜索量
  • 中等物品
  • 亚马逊图书
  • ArXiv 文章
  • GitHub 活动

搜索于 2018 年 9 月 16 日至 9 月 21 日进行。源数据在这张谷歌表中。

我使用了 plotly 数据可视化库和 Python 的 pandas 库来探索流行性。对于交互式 plotly 图表,请参见我的 Kaggle 内核这里。

在线工作列表

如今的就业市场需要哪些深度学习库?我在 LinkedIn 上搜索了工作列表,事实上,简单雇佣,怪物和天使列表。

当谈到工作列表中提到的框架时,TensorFlow 显然是赢家。如果你想找一份做深度学习的工作,就去学吧。

我使用术语机器学习后跟库名进行搜索。于是用机器学习 TensorFlow 对 TensorFlow 进行了评测。我测试了几种搜索方法,这一种给出了最相关的结果。

需要一个额外的关键字来区分框架和不相关的术语,因为 Caffe 可能有多种含义。

使用

流行的数据科学网站 KDnuggets 对世界各地的数据科学家进行了调查,询问他们使用的软件。他们问:

在过去 12 个月中,您在实际项目中使用了哪些分析、大数据、数据科学、机器学习软件?

以下是这一类别框架的结果。

Keras 显示了惊人的使用量——几乎与 TensorFlow 一样多。有趣的是,美国雇主压倒性地寻求张量流技能,而 Keras 至少在国际上几乎同样频繁地被使用。

这一类别是唯一包含国际数据的类别,因为包含其他类别的国际数据会很麻烦。

KDnuggets 报告了几年的数据。虽然我在这次分析中只使用了 2018 年的数据,但我应该注意到,Caffe,Theano,MXNET 和 CNTK 的使用量自 2017 年以来有所下降。

谷歌搜索活动

在最大的搜索引擎上进行网络搜索是衡量受欢迎程度的一个很好的标准。我查看了过去一年谷歌趋势的搜索历史。谷歌不提供绝对搜索数字,但提供相对数字。

我在 2018 年 9 月 21 日更新了这篇文章,因此这些分数将包括截至 2018 年 9 月 15 日的一周内在机器学习和人工智能类别中的全球搜索。感谢 Franç ois Chollet 提出改进这一搜索指标的建议。

Keras 离 TensorFlow 不远。PyTorch 排名第三,其他框架的相对搜索量得分在 4 分或以下。这些分数用于功效分数计算。

让我们简单看看搜索量是如何随着时间的推移而变化的,以提供更多的历史背景。谷歌下面的图表显示了过去两年的搜索量。

TensorFlow = red, Keras = yellow, PyTorch = blue, Caffe = green

对张量流的搜索在过去的一年里并没有增长,但是 Keras 和 PyTorch 看到了增长。Google Trends 只允许同时比较五个术语,所以其他图书馆是在单独的图表上进行比较的。除了对 TensorFlow 的搜索兴趣很小之外,其他任何库都没有显示任何其他内容。

出版物

我在 power score 中包括了几种出版物类型。先看中等文章。

中等物品

Medium 是流行数据科学文章和指南的地方。而你现在在这里**——**太棒了!

终于有了新的赢家。在媒体文章提及方面,Keras 在 TensorFlow 之前破了带子。FastAI 的表现优于其通常的表现。

我假设这些结果可能已经发生,因为 Keras 和 FastAI 是初学者友好的。他们对新的深度学习从业者有相当多的兴趣,Medium 通常是教程的论坛。

在过去的 12 个月里,我用谷歌网站搜索了 Medium.com,搜索的关键词是框架名和“学习”。这种方法对于防止“咖啡”一词的错误结果是必要的。在几个搜索选项中,它的文章减少幅度最小。

现在让我们看看哪些框架在亚马逊上有关于它们的书籍。

亚马逊图书

我在书籍 - > 计算机&技术下搜索了 Amazon.com 上的各个深度学习框架。

张量流再次获胜。MXNET 的书比预期的多,而 Theano 的书比预期的少。PyTorch 的书相对较少,但这可能是因为这个框架还很年轻。由于出版一本书需要时间,这种方法偏向于老图书馆。

ArXiv 文章

ArXiv 是大多数学术机器学习文章发表的在线仓库。在过去的 12 个月里,我使用 Google 站点搜索结果在 arXiv 上搜索了每个框架。

更多相同的学术文章来自 TensorFlow。注意 Keras 在 Medium 和 Amazon 上比在学术文章上更受欢迎。Pytorch 在这一类别中排名第二,显示了它在实现新想法方面的灵活性。Caffe 的表现也相对不错。

GitHub 活动

GitHub 上的活动是框架受欢迎程度的另一个指标。我在下面的图表中列出了星星、叉子、观察者和贡献者,因为它们分开比组合起来更有意义。

TensorFlow 显然是 GitHub 上最受欢迎的框架,拥有大量的用户。考虑到 FastAI 还不到一岁,它已经有了相当多的追随者。有趣的是,所有框架的贡献者级别都比其他三个指标更接近。

收集和分析数据后,是时候将其整合到一个指标中了。

动力评分程序

以下是我如何创建能力分数的:

  1. 在 0 和 1 之间缩放所有特征。
  2. 聚合的工作搜索列表和 GitHub 活动子类别。
  3. 根据下面的权重对类别进行加权。

如上图所示,在线工作列表和 KDnuggets 使用情况调查占总得分的一半,而网络搜索、出版物和 GitHub 关注占另一半。这种划分似乎是各种类别之间最恰当的平衡。

4.可理解性的加权分数乘以 100。

5.将每个框架的类别得分相加,得到一个单项得分。

数据如下:

这是加权和汇总子类别后的分数。

这张漂亮的图表再次显示了最终的能力得分。

100 分是可能的最高分,表示每个类别的第一名。TensorFlow 几乎获得了 100 分,这并不奇怪,因为它在每个类别中都名列前茅。Keras 显然是第二名。

要互动地玩图表或分叉 Jupyter 笔记本,请前往这个 Kaggle 内核。

将来的

目前,TensorFlow 稳稳占据榜首。在短期内,它似乎有可能继续占据主导地位。然而,鉴于深度学习世界的发展速度,这种情况可能会改变。

时间会证明 PyTorch 是否超过 TensorFlow,因为 React 超过 Angular。这些框架可能是类似的。PyTorch 和 React 都是脸书支持的灵活框架,通常被认为比谷歌支持的竞争对手更容易使用。

FastAI 会在课程之外获得用户吗?它有大量的学生,是一个比 Keras 更容易上手的 API。

你认为未来会怎样?

2019 年 4 月 1 日更新:未来在这里!至少有一部分。😄我用这篇文章发表后的六个月的增长分数评估了领先的框架。点击此处查看新文章:

[## 哪个深度学习框架发展最快?

TensorFlow 与 PyTorch

towardsdatascience.com](/which-deep-learning-framework-is-growing-fastest-3f77f14aa318)

给学习者的建议

如果你正在考虑学习这些框架中的一个,并且拥有 Python、numpy、pandas、sklearn 和 matplotlib 技能,我建议你从 Keras 开始。它拥有庞大的用户群,雇主对它有需求,在媒体上有很多文章,并且有一个易于使用的 API。

如果你已经知道了 Keras ,决定下一个要学习的框架可能会很棘手。我建议你选 TensorFlow 或者 PyTorch,好好学学,这样就能做出很棒的深度学习模型。

如果你想掌握什么是需求,TensorFlow 显然是学习的框架。但是 PyTorch 的易用性和灵活性使其受到研究人员的欢迎。下面是 Quora 对这两个框架的讨论。

一旦你掌握了这些框架,我建议你继续关注 FastAI。如果你想学习基础和高级深度学习技能,请查看其免费在线课程。FastAI 1.0 承诺让你轻松实现最新的深度学习策略,快速迭代。

无论你选择哪种框架,我希望你现在对哪种深度学习框架需求最大、使用最多、写得最多有了更好的了解。

如果你觉得这很有趣或有帮助,请通过分享和鼓掌来帮助其他人找到它。

快乐深度学习!

从名字-LSTM 递归神经网络深度学习性别

原文:https://towardsdatascience.com/deep-learning-gender-from-name-lstm-recurrent-neural-networks-448d64553044?source=collection_archive---------2-----------------------

[## prdeepakbabu/Python

Python - All *。py 脚本

github.com](https://github.com/prdeepakbabu/Python/tree/master/Deep%20learning%20gender)

深度学习神经网络已经在与视觉、语音和文本相关的问题上显示出有希望的结果,并取得了不同程度的成功。我在这里试着看一个文本问题,我们试着从人名中预测性别。rnn 非常适合这种情况,因为它涉及到从序列(在这种情况下是字符序列)中学习。由于梯度消失,传统的 rnn 存在学习问题。最近的进展表明,RNN 的两种变体可以帮助解决这个问题

(i) LSTM 或长短期记忆-使用记忆/遗忘门来保留或传递顺序学习的模式,用于预测目标变量。我们将在我们的模型中使用它。(推荐 colah 的博客以深入了解 LSTM 背后的理论)

㈡GRU 或门控循环单元

为了正式陈述这个问题,我们感兴趣的是预测给定的名字是男是女。在过去,已经有尝试基于在 NLTK 中看到的关于姓名的简单规则来预测性别,例如,依赖于姓名中的最后一个字符来分类性别,这由于高度概括而遭受低准确性。

我们将使用组成名字的字符序列作为 X 变量,Y 变量作为 m/f 来表示性别。我们使用一个堆叠的 LSTM 模型和一个带有 softmax 激活的最终密集层(多对一设置)。分类交叉熵损失与 adam 优化器一起使用。添加 20%的丢弃层用于正则化,以避免过拟合。示意图显示了模型设置。

LSTM RNN Architecture.

关于数据集

我们使用在 mbejda github 账户中可用的印度名字数据集,该账户具有从公共记录中收集的男性和女性印度名字数据库的集合。基本的预处理是删除重复的特殊字符。男/女班的最终分配比例为 55%:45%。值得注意的是,我们在这里使用全名。一些名字有两个以上的单词,这取决于姓氏、家族名字等。

使用 keras 实施

完整的数据集、代码和 python 笔记本可在我的 github repo 中获得。完整的实现是使用 keras 和 tensorflow 后端完成的。输入表示&参数在下面突出显示

(i) 词汇:我们有一组 39 个字符,包括 a-z、0-9、空格、点号和一个特殊的结束标记。
(二)最大序列长度:选择为 30 ie。超过 30 个字符的字符将被截断。如果名称少于 30 个字符,则填充“END”标记。
(iii) one hot encoding :对每个字符进行 one-hot 编码,表示为[1 X 39]维数组。
(iv) 批量:一批 1000 个样本
(v) 时期 : 50 个时期或 50 次我们迭代整个数据集(见一次)
(vi) Y 标签:表示为[1 X 2]的数组,第一列表示男性,第二列表示女性。例:[1 0]代表男性。

Loss & Accuracy charts as a function of epochs. As seen from loss charts, after 40 epochs the validation loss saturates while training loss keep reducing indicating over-fitting problems.

这个模型在我的中等高端笔记本电脑(基于 CPU)上运行了大约 2 个小时。在验证数据集上,最终的分类准确率为 86% 。更多关于精确度、召回率和混淆矩阵的统计数据如下所示。

模型显示识别男性(88%)比识别女性(84%)的精确度更高。在总共 3,028 个验证样本中,411 个样本被错误地预测,导致 86.43%的准确度和 13.5%的误差

解读模型(模型学到了什么?)

查看在验证集上做出的预测,模型似乎已经在序列中学习了以下模式。例如,出现的“先生”暗示可能是男性名字,而出现的“smt”和“mrs”则表示女性名字。深度学习的魅力在于端到端的学习能力,而不需要传统学习中所需的显式特征工程步骤。此外,女性的名字往往以元音 a,I,o 结尾,这似乎是模特们选择的。有更复杂的模式被模型拾取,不容易通过检查看到。

下一步

提高模型精度的一些想法是

(I)使用预先训练的字符嵌入,而不是一键编码(像这个)。记住这句话同样适用于角色

从一个人交的朋友,你就可以知道这个人说的话

(二)更好的抽样
a .限于名和姓。
b .按 1:1 的比例对男性班级和女性班级进行子抽样。从词汇表中删除所有非字符。
(三)超参数整定
a .序列的最大长度
b .堆叠层数。LSTM·盖茨

我很乐意听到你对这篇文章的评论/问题/建议,如果你觉得有趣,请分享。

深度学习 II L9:生成模型

原文:https://towardsdatascience.com/deep-learning-ii-l9-generative-models-dcd599ad6e0b?source=collection_archive---------4-----------------------

fast.ai 的深度学习课程中的第九课继续从制作艺术的角度深入到生成对抗网络(GANs)中。这主要涉及(截至编写时)课程库中的神经风格和神经-sr Jupyter 笔记本。:这篇帖子比较长。从简单开始,不断深入。

在第 8 课中,我们学习了获取一幅图像,将它放入由风格损失和内容损失组成的损失函数中,输出损失和梯度,并使用这些梯度来更新图像并在下一次迭代中减少损失——冲洗并重复。像这样:

copyright: my notebook …

根据杰瑞米·霍华德在讲座中的说法,这是对许多不同的风格和图像进行风格转换的最好方法,比如在 web 应用程序中。然而,如果你想应用一个单一的风格到任何图像:这是我们可以改变事情做得更好的地方。原因是你不需要做上面的优化循环来产生一些东西。相反,你可以只训练 CNN 来学习如何以特定的风格输出图像(并且通过 CNN 向前传递是非常快的——权衡是 CNN 被训练成特定的风格)。

这一次我们开始像以前一样将多个图像输入到同一个损失函数中(样式+内容)。在这个例子中,对于风格损失,我们使用梵高的虹膜,对于内容损失,我们使用当前输入到函数中的图像。这里最大的不同是,我们将在输入图像和损失函数之间放置一个 CNN。CNN 将学习输出一个图像,这样当它进入损失函数时,它将输出一个小的损失值。在英语中,这意味着 CNN 已经学会制作内容与原始输入图像相似、风格与所选风格相似的图像。

这里有一些注释。有了 CNN,你可以选择任何你喜欢的损失函数(你的里程可能会有所不同)。深度学习 I & II 到目前为止已经使用了相当简单的,比如 MSE 和交叉熵。不过,这里我们将使用样式+内容损失,就像上面的第一个例子一样。注意:因为样式+内容损失函数是由神经网络生成的:它是可微的;并且可以优化任何可微的损失函数。

现在,如果我们采用相对于 CNN 权重的输出梯度,我们可以使用它们来更新这些权重,这样 CNN 就可以更好地将图像转变为与风格相匹配的图像。

something like this

这一点的强大之处在于,没有优化步骤来减缓推理——或者模型的“预测”操作。通过 CNN 的单次向前传递几乎是瞬时的。

你还能做更多。

the future is here. ENHANCE.

事实证明,深度学习神经网络可以用来放大图像和推断细节。

we have the technology

我们从在传说和雇佣图像之间放一个 CNN 开始。CNN 将 LoRes 图像作为输入,并将其输出发送到仅计算内容损失的损失函数中。内容损失是通过将其从 CNN 的输入与从 HiRes 图像的激活进行比较来计算的。换句话说,损失函数是检查 CNN 是否从原始知识中创建了一个更大的图像,该图像与雇佣图像具有相同的激活。

这场讨论引发了我在课堂上听到的最好的问题之一:

我们能不能在任何两个事物之间放一个 CNN,它就能知道它们之间的关系?

杰瑞米·霍华德:

是的,绝对的。

这就涉及到了我们与 CNN 之前不同的做法。一篇 2016 论文详细介绍了 CNN 使用不同的损失函数来做超分辨率。在此之前, MSE 通常用于升级网络像素输出和 HiRes 图像之间。问题是:模糊图像在 MSE 下仍然表现良好,但这对于图像任务来说有点不可接受。另一方面:

…如果你拿下 VGG 的第二或第三个 conv 街区,那么它需要知道这是一个眼球,否则它不会好看。

教训:使用内容损失而不是像素损失。(题外话:从在像素上使用MSE到内容丢失,显然花了 1 年时间。回顾过去,发现直观事物所花费的时间是很有趣的。)

论文列出了这种方法的一些有用应用——将它们框定为图像变换任务:

  • 图像处理:去噪、超分辨率、彩色化
  • 计算机视觉:语义分割,深度估计

(这里的另一个题外话是,使用生成模型,你可以通过添加噪声或使彩色图像灰度化等方式产生尽可能多的标签数据。)

high-level view of Content (Perceptual) Loss for Super Resolution or Style Transfer

2。现在进入代码。如果您想继续学习,请参见 neural-style.ipynb (注意:课程的未来更新可能会完全更改代码或笔记本)。

the final network — “The Upsampling Network”

上面的代码首先接收一批低分辨率图像,作为一个维度为arr_lr.shape[1:](这里是:(72, 72, 3))的张量。在笔记本中,arr_lrarr_hr是 NumPy 数组。

inp = Input(arr_lr.shape[1:])

该输入然后被放入具有 64 个大小为 9 的滤波器和单位步幅(即输入大小没有变化)。

x = conv_block(inp, 64, 9, (1,1))

这是一个大的过滤器尺寸,因为我们想要一个大的初始感受野。显然,拥有 64 个滤波器可以确保没有信息丢失(来自 3 个颜色通道),但我不知道输入滤波器与滤波器的信息丢失曲线是什么样的。但显然这也变得越来越普遍。

接下来是大部分计算将要完成的地方。这是 GAN 必须弄清楚的部分,例如,那个黑点是眼球,然后一个更高分辨率的眼球看起来会是什么样子

for i in range(4): x = res_block(x) # res_block()是在别处定义的 ResNet 块。

在创成式模型中,我们希望以低分辨率完成这个主要的计算步骤。低分辨率意味着工作量更少,因此计算速度更快,但最重要的是:我们将有一个更大的感受域。为什么这很重要?你可以很容易地想象出一张放大版的某人脸部照片是什么样子,因为你知道脸是什么样子的。你知道那个黑色的东西是一只眼睛,而那个黑色的区域是它们下颚投下的阴影。你一开始就知道这些,因为你能一眼看到整张照片,并认出它是一张脸,而不是餐盘或抽象艺术作品。GAN 必须做同样的事情。

决定感受域的有几个因素:卷积层深度、滤波器大小和下采样(非单位步长、最大池等)。

hopefully this makes some amount of sense

回到代码。ResNet 块是这样定义的:

ip: input; nf: num. filters

这个块接受一个输入,用它来构建两个卷积块(通过 Keras 的函数式 API ),然后将这些 Conv 块的结果添加回原始输入:return merge([x, ip], mode='sum')最后的 Conv 块没有激活(act=False),因为最近的一篇论文(不确定是哪一篇)发现没有 ResNet 块通常会执行得更好。

1st conv_block has ReLU activation; 2nd block no activ. ip is input. merge using sum operation.

从我目前对深度残差网络的理解来看,ResNet 的优势在于它给了网络的每一层一些关于原始输入的上下文。在讲座中,杰瑞米·霍华德说,一堆 ResNet 块可以磨练他们需要做什么来完成一项任务(这里:放大图像)。

y = f(x) + x;f(x) = y — x;其中y — x = the residual

那么,如果函数是输出 y 和输入 x 之差,即残差,这就给出了一些关于如何最小化损失函数的上下文信息?我将不得不及时了解更多关于那件事。

conv_block相当标准:

a convolution, then batch-normalization, and optionally an activation

在这一点上,我们实际上需要改变图像的尺寸。最初的讲座使用了反卷积模块,执行反卷积/转置/分数阶卷积来重建图像的外观,如果它的当前版本(输入)是卷积的结果。简而言之:它是对(零)填充输入的卷积。如果你想深入了解,这是讲座中提到的链接。在课程的 github 存储库中,课程笔记本的当前版本、 neural-style.ipynb 以及 neural-sr.ipynb 都使用一个定义为:

如果我理解正确的话,这是课程代码的一点逻辑发展。转置/分形步长/去卷积的一个问题是棋盘:根据步长,卷积滤波器重叠的地方会出现棋盘图案的假象。谷歌大脑和蒙特利尔大学的一些研究人员写了一篇关于这个问题的很棒的论文。

Figure from Odena, et al., “Deconvolution and Checkerboard Artifacts”, Distill, 2016. http://doi.org/10.23915/distill.00003

简而言之:步长为 2 — stride=(2,2) —意味着过滤器在扫描输入时以 2 个像素或单元为步长移动,size=3意味着过滤器是一个3x3正方形。看一下上图,问题就很明显了。纠正这个问题的一个方法是确保你的过滤器大小是你步幅的倍数。另一种方法是根本不使用去卷积。

相反,该论文建议首先进行上采样,这本质上与最大池操作相反:例如,每个像素都成为同一像素的2x2网格。在常规卷积之后进行上采样不会产生棋盘效应。这看起来就像杰瑞米·霍华德在新版代码中所做的一样。酷毙了。

让我们再深入一点:原始代码使用了两个去卷积模块来放大低分辨率图像,从72x72144x144288x288。较新的代码通过两个上采样模块来实现这一点,每个模块执行一个Upsampling2D()操作,然后进行卷积和批量归一化。UpSampling2D()的 Keras 文档显示:

keras.layers.convolutional.UpSampling2D(size=(2,2), data_format=None)

对我们来说重要的是size参数:

size : int,或者 2 个整数的元组。行和列的上采样因子。

所以默认的行为是将图像的大小增加一倍,这就是为什么对UpSampling2D()的两次空调用实现了预期的效果。

Just a reminder for what’s going on: the super-resolution network we’re building. inp is the original LoRes input tensor. outp is the HiRes output tensor. The Upsampling Network.

在放大之后,我们有一个最终的9x9卷积层,以便回到 3 个颜色通道。讲座中的解释是,在图像输出从 64 个过滤器或通道减少到 3 个时,我们希望大量的上下文(因此是9x9)能够做到这一点。因此,将前面的(288, 288, 64)张量通过最后的卷积层输出一个(288, 288, 3)张量:一个图像。最后一条outp = Lambda(lambda x: (x+1) * 127.5)(x)线需要将每个像素从之前的 tanh 激活中恢复到正确的0,255颜色强度等级。Tanh 在范围0±1我觉得,所以→ ([-1:+1] + 1) * 127.5 = [0:255]Lambda(..)是一个 Keras 包装器,它将内部的所有东西都视为自定义层。注意:感知损失论文的作者之一在 reddit 上提到,他们在没有 tanh 激活和没有最终 Lambda 处理层的情况下运行网络,并获得了同样好或更好的结果(无链接)。

现在可以训练网络,但是我们仍然需要定义我们的损失函数。Ie:网络自我评估的标准是什么?我们首先将我们的上采样网络连接到 VGG。VGG 将仅被用作内容损失的损失函数。在将上采样网络的输出张量输入 VGG 之前,需要对其进行预处理(VGG 模型中使用的归一化)。我们通过定义一个定制的 Keras 预处理层,并定义一个新的输出张量outp_λ作为预处理层运行outp的结果,来实现这一点:

vgg_λ = Lambda(preproc)
outp_λ = vgg_λ(outp)
# I just discovered code blocks in Medium :D (```)

接下来,我们创建一个 VGG16 网络,并将其所有层设置为不可训练。这…有点重要。因为这个网络我们的损失函数——我们的测量棒——它必须是静态的。想象一下如果千克或米改变了。如果你想看现场混乱,只要看看外汇市场。

shp = arr_hr.shape[1:]vgg_inp = Input(shp)
vgg     = VGG16(include_top=False, input_tensor=vgg_λ(vgg_inp))
for λ in vgg.layers: λ.trainable=False

VGG 网络的输入张量形状shp是 HiRes 图像维度。于是:shp = arr_hr.shape[1:]vgg_inp = Input(shp)arr_hr是从磁盘上的 bcolz 压缩数组创建的 NumPy 数组,其维数(形状)为:(num-elements,dim1,dim2,dim3,…)。在我们的例子中是:(图像数量,高度,宽度,颜色通道)。所以取arr_hr.shape[1:]会返回一个形状张量:(288, 288 , 3)VGG16(..)include_top=False将省略网络末端的全连接分类块。这是 VGG16 w/ Average-Pooling &批处理规范化的 fast.ai 实现,位于: vgg16_avg.py (如果课程目录结构发生变化,链接可能会断开)。

为了获得我们想要的 VGG 网络的部分内容损失,有几个实现。最初的课堂讲授通过选择提取特征的单个块(特别是块 2 中的 conv 第 2 层)来创建单个模型。在课程存储库中,这已经发展成为从多个块中检索特征的功能。

讲座的实施:

vgg_content = Model(vgg_inp, vgg.get_layer('block2_conv2').output)
vgg1 = vgg_content(vgg_inp)
vgg2 = vgg_content(outp_λ)

更新的课程 repo 在 neural-sr.ipynb 中的实现:

note how similar the 1 & l look. Wait, in this font which is an I and which is an l? → Making my case for the λ. =) vgg_content here is a Multi-Output model (covered in Deep Learning I)

在这两种情况下,我们都使用模型中相对较早的激活。在 L8 中,我们发现我们完全可以使用早期层激活来重建图像。然后我们使用 Keras 的功能 API 创建 VGG 输出的两个版本。这个 Keras API 的一个伟大之处在于,任何层(模型被视为层)都可以被视为一个函数。然后,我们可以将任何我们喜欢的张量传递到这个“函数”中,Keras 将创建一个新的模型,将这两个部分连接在一起。因此vgg2outp,底部是上采样网络,顶部是vgg_content,VGG16 中我们希望用作损失函数的部分。

旁白:你可能会有点困惑。我不应该说outp_λ而不是outp吗?在讲座的代码中,它是outp_λ:这是经过预处理λ层后的输出张量。然而,在更新的课程代码中,该步骤包含在 VGG16 模型的初始化调用中。新的号召是:

vgg = VGG16(include_top=False, input_tensor=Lambda(preproc)(vgg_inp))

因此,现在我们有两个版本的 VGG 图层输出。vgg1基于雇佣输入,而vgg2基于升级网络的输出(接受了知识输入)。我们将比较招聘目标图像和招聘汇总结果,因此两个张量都具有高分辨率形状(288,288,3)。需要明确的是:vgg1是雇佣内容/感知激活,vgg2是知识增采样内容/感知激活。

注意:对于损失函数和最终模型的定义,原始讲座和更新的存储库代码之间存在显著差异。我将先浏览一下讲座版本,然后浏览一下新内容。

接下来我们计算它们之间的均方误差。在 Keras 中,任何时候你想把某个东西放到一个网络中,你都需要把它变成一个层,而这是通过把它扔进一个Lambda(..)来完成的:

loss = Lambda(lambda x: K.sqrt(K.mean((x[0]-x[1])**2, (1,2))))([vgg1, vgg2])

最终模型将采用 LoRes 输入和 HiRes 输入作为其两个输入,并返回刚刚定义为其输出的损失函数:

m_final = Model([inp, vgg_inp], loss)

此外,当您试图在 Keras 中适应事物时,它会假设您试图获取一些输出并使其接近目标。这里的损失是我们想要的实际损失函数;没有目标,我们只是希望它越小越好。由于我们的损失函数使用的是 MSE ,我们可以说我们的目标是零。然而,Keras 中的目标是标签,所以每行(每个输入)都必须有一个标签,所以我们需要一个零数组:

targ = np.zeros((arr_hr.shape[0], 128))

为什么每个图像有 128 个零?讲座回答:Lambda 层,loss,对应目标数组有 128 个滤镜。128,因为该层包含了vgg1vgg2,两者都有 64 个过滤器。

接下来,我们使用 Adam 优化器和 MSE 损失编译模型,并对其进行拟合:

m_final.compile('adam', 'mse')
m_final.fit([arr_lr, arr_hr], targ, 8, 2, **pars)

注意: pars包含一对这样定义的参数变量:pars = {'verbose': 0, 'callbacks': [TQDMNotebookCallback(leave_inner=True)]} —这关闭了冗长性,并使用 TQDM 进行状态报告。

在第一轮训练后,学习率有所降低(称为“学习率退火”):

K.set_value(m_final.optimizer.lr, 1e-4)
m_final.fit([arr_lr, arr_hr], targ, 16, 2, **pars)

训练之后,我们对模型中的上行采样网络感兴趣。一旦我们完成训练&试图最小化损失函数,我们不再关心损失:我们关心的是来自上采样网络的输出图像。所以现在我们定义了一个模型,它接受知识输入inp并返回雇佣输出outp:

top_model = Model(inp, outp)

当我第一次为它做任务时,这让我有点困惑:outp在我们上面的训练步骤中已经被训练过了。事实上,如果你记得:inpoutp只是我们的上采样网络的输入层和输出激活。我们基本上建立了一台机器来对图像进行上采样,使用现有的模块(VGG16)来训练这台机器,方法是将它放在上面,然后在完成后断开该模块,现在我们有了一台经过训练的机器来对图像进行上采样。

现在,我做这件事的方式与课程库中的方式有些不同。定义vgg1vgg2后,训练前的部分如下:

def mean_sqr_b(diff):
    dims = list(range(1, K.ndim(diff)))
    return K.expand_dims(K.sqrt(K.mean(diff**2, dims)), 0)w = [0.1, 0.8, 0.1]def content_fn(x):
    res = 0; n=len(w)
    for i in range(n): res += mean_sqr_b(x[i]-x[i+n]) * w[i]
    return resm_sr = Model([inp, vgg_inp], Lambda(content_fn)(vgg1+vgg2)
m_sr.compile('adam', 'mae')

还记得在 VGG16 中,新代码是如何使用多输出模型在不同的块上进行激活的吗?我们将对每个块对损失函数的相对影响进行加权:w = [0.1, 0.8, 0.1]表示block1_conv2的权重为 10%,block_2_conv2的权重为 80%,&等等。

我们的损失函数本身就是函数中的函数。content_fn(x)取张量x,输出标量损失值res。对于w中的每个权重,content_fn(.)根据x的第 I 个元素和x的第 I+n 个元素之差调用mean_sqr_b(.)(其中 n =在w中权重的数量),将结果乘以w中的第 I 个权重,并将该值加到res

如果你认为进入content_fn(.)x是我们的雇佣张量和我们的 LoRes 上采样张量的连接,如果这两个张量都是多输出模型(3 个不同的 conv 块激活)的结果,那么content_fn(.)所做的只是两个张量的相应加权块激活的 MSE 。

如果这仍然有点难以理解,试试这个:

yes I see it too.

我要在这里暂停一会儿,希望我没有让它变得更糟。

Terek

没错。这就是损失函数。

最终的模型,这次称为m_sr的超分辨率模型,将一组张量作为输入:LoRes 和 HiRes originals,并输出应用于vgg1 + vgg2的损失函数content_fn的结果。

m_sr = Model([inp, vgg_inp], Lambda(content_fn)(vgg1+vgg2)

想象这是一个温和的噩梦:想象多重计算图形的不同之处仅在于它们将 VGG 的哪个块作为输出,它们的输出是如何被编织到损失函数中的;这还没有考虑每个上采样网络内部发生了什么,或者反向传播实际上是如何更新网络的。这可以被抽象成几行代码,这很酷。我想过画一个巨大的图表…过了某个点,它是光明会遇到矩阵,你在比赛找出情节。

尽管使用了平均绝对误差而不是 MSE : m_sr.compile('adam', 'mae'),但编译还是很简单的。另一个区别是训练。加载大约 40k 的图像刚好刚好适合我工作站的内存,有时。如果你想要更多呢?这就是 bcolz 库的用武之地。你把数据保存在磁盘上,然后分批加载。代码是这样的:

see: bcolz_array_iterator.py

bs是批量大小。它必须是压缩时定义的 bcolz carray 的块长度的倍数。bcolz 数组有一个问题,它的块长度是 64,而我的工作站只能处理 6 的批量大小;8 如果行星排成一行。我通过创建新数组并显式设置参数chunklen解决了这个问题。这可能是或可能不是犹太人。

neural_sr_attempt3.ipynb

niter是迭代次数。targ和之前一样是目标向量,但是这次是一个 0 的数组,一个 0 代表批处理中的一个元素。bc是一个迭代器,它在每次调用next(bc)时返回下一批arr_hrarr_lr。我真的很喜欢这个,因为我在一个深度学习任务中遇到了系统内存限制的问题,我拼凑了一堆类似的函数来批量从磁盘中提取数据,并正确处理最后的剩余部分。代码更先进一些,把它拆开看看它是如何工作的会很有趣。它使用了线程和with语句,这些我还没有用过。

对于niter迭代,train(..)加载下一批雇佣和知识图像,然后调用m_sr.train_on_batch([lr[:bs], hr[:bs]], targ)。为什么当lr是长度bs时,确切地说是lr[:bs]而不仅仅是lr呢,反正我不确定——也许不是?在最后一批中,我遇到了输入和目标数组长度不匹配的问题。如果您有 16,007 个图像,批处理大小为 8,那么您的目标数组大小被设置为批处理大小→您会得到一个减一的错误。我通过将目标指定为targ[:len(hr)]来解决这个问题,这样最终的输入和目标数组长度相同。至于niter,我将其设置为:niter = len(arr_hr)//6 + 1以说明余数,尽管回想起来,只有在余数存在时才添加1会更好。

毕竟,结束是容易的。训练几个纪元,降低学习速度,然后再训练几个纪元。然后获得您训练有素的工作模型:

top_model = Model(inp, outp)

并开始向上采样。我得到了这个(:这里的数据一次全部加载到内存中,模型通过model.fit(..)进行训练):

it enhanced the mashed potatoes

虽然正如课程笔记本暗示的那样,这种良好的表现可能部分是由于过度拟合。以下是木星照片的结果:

LoRes — SuperRes — HiRes

LoRes — SuperRes — HiRes (used batch-loading method)

这并不奇怪。首先,我肯定忘记了至少一个实现中的学习率退火部分——我更感兴趣的是让它工作起来:大量的资源耗尽错误和 bcolz 迭代器的故障排除——而我正在处理的数据集只有 19,439 幅图像。也许这已经足够了,但是如果In: len(arr_hr)//16; Out: 62277有任何线索的话,课程中的模型至少训练了 996,432 张图像,尽管那可能是在讲座被录制之后。不管是哪种情况,你都应该在 ImageNet 上进行训练,而不是一个小的子集,如果你有发言权的话。理想情况下,你也应该正确地进行训练。顺便说一下,我的两次成功尝试总共花费了大约 12 个小时的计算时间。所以 20k 就可以了。

关于木星和过度拟合的一个注意事项:在所有图片中,似乎确实存在对比度增加和褪色的问题,但据我所知,ImageNet 中也没有行星类别。所以那里可能发生了什么。

3。快速风格转移。我们可以使用来自超分辨率的相同基本思想,利用感知(内容)损失进行快速风格转换。这次我们拍摄一张照片,通过 CNN,然后通过一个损失函数对一张固定风格的图片进行风格和内容损失。关于这个话题有一篇论文和补充材料。

论文在输入上使用反射填充而不是零填充——也就是说:反射边界周围的图像而不是只有黑色像素。杰瑞米·霍华德用一个定制层实现了这个,在 Keras 中这个定制层是作为一个 Python 类来实现的。

neural-style.ipnb

第一部分是构造函数。此后,在定义自定义 Keras 层时需要做两件事:您需要定义get_output_shape_for(self, input),它接受输入张量的形状,并返回输出张量的形状——在这种情况下,它与s ( s[0])具有相同的批处理大小,相同的通道数(s[3]),以及两倍的行和列填充量(s[1] + 2 * self.padding[0], s[2] + 2 * self.padding[1],)。当你把东西放在一起时,Keras“神奇地”知道中间层的输入/输出有多大,因为每一层都包含这种信息。第二个要定义的是call(self, x, mask=None)call(..)获取你的层数据x,并返回你的层所做的一切。 Keras 的文件规定:

这是层的逻辑所在。

我们希望这一层添加反射填充。TensorFlow 有一个名为tf.pad(..)的内置函数。

该图层现在可用于网络定义:

inp = Input((288, 288, 3))
ref_model = Model(inp, ReflectionPadding2D((40, 2))(inp)
ref_model.compile('adam', 'mse')p = ref_model.predict(arr_hr[10:11]) # run model on 10th img

neural-style.ipynb

论文作者使用40x40像素对图像进行反射填充。因为它们在它们的 ResNet 块中使用“有效”卷积,所以图像通过层被逐渐裁剪,所以反射填充的存在是为了保留图像。

From: Perceptual Loss Supplementary Material

其实作者的架构和我们的很像。一般模式是:通过卷积对输入进行下采样,并增加通道和感受野的数量,从而创建更复杂的数据表示(第 3-5 行),对这些表示进行计算(剩余层),然后对其进行上采样(最后 3 行)。1/2 步是去卷积:它与分数步卷积相同。

没有进入太多的细节,实现这一点(主要遵循更新的课程笔记本)我采取了这种风格的形象:

artist: Alena Aenami

并把它应用到这幅 Waynakh 中世纪塔的图片上:

image: Ahmed Osmiev

两幅图像都被调整到500x500。回头看看代码,我看到了一些愚蠢的错误:样式图像被裁剪为288x288以适应样式张量…因此丢弃了 33%的样式图像。在将塔的内容图片调整到333x333 …那不适合,所以我只是裁剪它以适合输入张量。尽管如此,在用学习速率退火(2p @ default→2p @ 0.0001)在 4 个时期中训练快速风格转移模型大约 6 小时之后,该模型在大约 1 秒或更短时间内完成了其风格转移,并产生了以下结果:

resized in Apple Pages to (kind of) match original proportions

有点像角色扮演游戏的卡片。闹鬼的城堡什么的。显然,如果我使用原始内容和风格图像的全分辨率会好得多,但我还没有研究它。由于这种模型首先进行训练,而不是像以前的风格转移模型那样在运行时进行训练……感觉要让它在计算资源有限的情况下处理大型图像会很困难。你可以尝试简单的极端情况,重新压缩 bcolz 数组,使其块长度为 1,这样你就可以使用批量大小为 1 的数组,以低得多的学习速率开始,只需接受更长的训练时间,然后就可以了……但是这种解决方案感觉简单了。在给定固定资源的情况下,应该有一种方法可以缩放到任何图像大小,并且只在计算时间上付出代价。嗯..

你可以试着把图像分成一个网格马赛克,在每一块上运行,然后把它们拼接起来。但现在你要付出一个定性的代价:如果这是一张雇佣照片,那么有一些重要信息你的社交网络不会知道,因为它实际上会被放大到只见树木不见森林。

等等,有没有一种方法可以使用288x288x3张量作为视野,并扫描更大的图像,将视野中的内容加载到内存中,并将其余内容保存在磁盘上,也许可以使用 bcolz?嗯..

4。 设计:深度视觉语义嵌入模型。第九课的最后一部分,也是这篇博文的开始。Andrea Frome 在一篇论文中描述了这一点。),DeVISE 试图通过用单词嵌入取代一键编码来更接近我们在图像识别方面所做的事情。

作为一个(非常)粗略的概述:在你传统的一键编码模型中,鲨鱼和鱼之间几乎没有相似之处,或者“鲨鱼”的概念是所有类型鲨鱼的超集。当然,这不是我们在现实生活中感知事物的方式。在一个不同的领域,自然语言处理,有一种方法可以捕捉到类别之间的相互关系,叫做单词嵌入。它基本上是一个矩阵,每行(每列??)由映射一个单词与所有其他单词的相关性的向量组成。我们在深度学习 I 中使用它来创建一种类似尼采的机器人,也用于电影推荐(嵌入可以将电影映射到类别,而不仅仅是单词到单词)。

因此,对于图像,pug 的向量不是 1000 个元素,pug 类别的索引是 1,其他地方都是 0,而是用 pug 的密集单词向量来替换它(向量长度取决于我们使用的嵌入)。我们将使用一个 Softmax 层来进行一键编码(答案是1其他都是0),但是现在我们将使用线性层。

棘手的是要通过 ImageNet。150 万张左右的图片已经很多了。这就是 bcolz 和数组迭代器(在前面使用过)的用武之地。

这里有一个来自杰瑞米·霍华德的提示:他定义了两条数据路径——一条用于高速固态硬盘/非易失性存储器上的数据,另一条用于大型硬盘。他使用 RAID 1 SSD 来快速访问调整大小的图像和功能阵列,以及用于批量数据的 HDD 路径。好主意。

使用的单词嵌入是 word2vec。

讲座中提到的另一个有趣的事情是 Python 的 single-star (zip-star?)语法。如果您有一个将单词映射到向量的数据结构,并且想要获得单词列表和向量列表,如果您能够以迭代器的形式获得该数据结构,那么:

words, vectors = zip(*wordvec_iterator)

将所有的单词放入words,所有对应的向量放入vectors

所以在这个讲座的例子中,如果wordvec_iterator包含"fox:", array01, "wolf", array02, ...,那么当你压缩wordvec_iterator时,这与把这些内容放入zip(.)是一样的,就像这样:

zip("fox", array01, "wolf", array02)

那么测试一下这个:

>>> words = ["fox:","wolf:"]; vecs = [[1,2,3],[4,5,6]]; 
>>> zipped = zip(words, vecs)
>>> list(zipped)Out: [('fox:', [1,2,3]), ('wolf', [4,5,6])]>>> w, v = zip(*zip(words, vecs)) # or: zip(*zipped) ## for fresh `zipped`
>>> words == list(w) and vecs == list(v)Out: True>>> w, vOut: (('fox:', 'wolf:'), ([1,2,3], [4,5,6]))

或者说得迂腐一点:

>>> word, vecsOut: (['fox:', 'wolf:'], [[1, 2, 3], [4, 5, 6]])>>> list(w), list(v)Out: (['fox:', 'wolf:'], [[1, 2, 3], [4, 5, 6]])

所以我今天学到了一些新东西。基本经验:如果你想把一个元组列表转换成一个列表元组,使用 zip-star (Python)。

杰瑞米·霍华德做了更多设置笔记本的工作,将文字嵌入应用到 ImageNet 图片。我不会在这里详述,因为这篇文章遭受了它自己的任务爬行形式——而且我还没有为一个完全解压缩的 ImageNet 腾出 TB 左右的自由空间。Howard 对单词列表做了一些处理,对它们进行了重新排序,这样更常见的单词就会排在前面——并且还将所有单词都变成了小写,因为大写在这里并不重要。他通过使用np.corrcoef(..)来查看他的名字的大写和小写版本与他的名字和不相关的对象之间的相关系数,从而进行了几次健全性检查。

然后,他创建了两个单词向量映射(Python 字典),分别映射到 1,000 个 Imagenet 类别和 WordNet 中的 82,000 个名词——目标是创建一个可以超越 ImageNet 的 1,000 个类别的系统。

最后,他创建了一个在 WordNet 中找不到的 ImageNet 类别列表,并将这些图像文件夹移出目录。

另一个有用的提示:Howard 保存所有花费大量时间的输出。获取一百万张图像的文件名需要一段时间,尤其是当它们在旋转的磁盘上时。

他还利用了我在计算/数值线性代数课上看到的三种技术:内存局部性、SIMD/向量化和并行处理。【讲座环节】。我觉得关于 SIMD 的那段很有趣。

到目前为止,对我来说,这是这门课最长的一课。有很多事情要做,但我喜欢从大规模架构的角度来看代码的想法。在黑暗的森林中很容易迷路,并且忘记你的模型的一部分来自哪里。人们也很容易害怕做出任何改变,因为害怕再也无法完全理解。但是如果你有一个连续的主题“我通过 CNN 输入图像,CNN 的输出通过一个损失函数与我想要它产生的相比较”,记住你实际上在做什么就变得容易多了。这就差不多结束了!

关于符号的几个注意事项:我将经常大写某些术语,如卷积或生成等。我发现,在阅读新的技术主题时,将一些关键术语强调得恰到好处,就像路径标记一样,会有所帮助,可以避免只是通读像散文这样的文本墙而迷失方向。

此外,每当代码中有一个单独的l时,我会用λ替换它。除了λ漂亮之外,在许多字体中1 I l看起来完全相同或者非常接近,足以让人迷惑;所以它有一个额外的用途——保持理智。

金融领域的深度学习

原文:https://towardsdatascience.com/deep-learning-in-finance-9e088cb17c03?source=collection_archive---------0-----------------------

我写这篇文章是为了跟进新加坡再工作深度学习峰会上的同名讲座。在演讲中,我试图详细说明金融模型失败的原因,以及深度学习如何弥合这一差距。接下来,我继续介绍了金融领域深度学习的三个用例,以及这些模型优越性的证据。

虽然金融是计算最密集的领域,但金融中广泛使用的模型——监督和非监督模型、基于状态的模型、计量经济学模型甚至随机模型——都存在过度拟合、启发式和样本外结果差的问题。这是因为,金融领域非常复杂,并且是非线性的,有太多的因素相互影响。

为了解决这个问题,如果我们看看在图像识别、语音识别或情感分析等成熟领域的深度学习中所做的研究,我们会发现这些模型能够从大规模未标记数据中学习,形成非线性关系,形成递归结构,并且可以轻松调整以避免过度拟合。

如果这些模型能在金融领域得到应用,那么它们的应用将会非常广泛。这些模型可用于定价、投资组合构建、风险管理甚至高频交易等领域。因此,让我们来解决其中的一些问题。

回报预测

以预测每日黄金价格的样本问题为例,我们首先来看看传统的方法。

ARIMA

使用自回归综合移动平均模型,试图预测一个平稳的时间序列,保持季节性因素不变,我们得到一个结果

VAR

如果我们将相关的预测变量添加到我们的自回归模型,并转移到向量自回归模型,我们会得到以下结果—

深度回归

使用相同的输入,如果我对数据拟合一个简单的深度回归模型,我会得到好得多的结果,

卷积神经网络

修改我的架构以使用卷积神经网络来解决相同的问题,我的结果是

这些结果要好得多。但是接下来是最好的结果。

【长短期记忆(LSTM)

这就对了。使用这些变化的递归神经网络,我的结果是:

所以总的来说,均方差的趋势是一个启示!

投资组合构建

我们将尝试使用深度学习解决的第二个金融问题是投资组合的构建。深度学习在这个问题上的应用有一个漂亮的结构。我的研究受到了 T4 一篇名为《深度投资组合》的论文的启发。

这篇论文的作者试图做的是构建自动编码器来将一个时间序列映射到它自身。使用这些自动编码器的预测误差成为股票 beta(与市场的相关性)的代理,自动编码器是市场的模型!

基于上述自动编码器误差选择不同的股票集合,我们可以使用另一个深度神经网络来构建深度指数,并且结果相当好。

这里的深度神经网络已经成为一种使用股票复制指数的指数构建方法。

但这只是开始!如果我们应用智能指数,我从指数中删除极端下降的时期,并在智能指数上训练我的指数映射深度神经网络,我就能够以激烈的方式超越指数!

这项技术在投资组合构建领域有着巨大的潜力!

结论

金融行业的当前趋势正在引领更复杂、更合理的模型进入市场。对于所有银行来说,技术是一个巨大的压力领域,有大量数据科学家进入该领域。像 RelTec 和 Worldquant 这样的对冲基金已经在交易中使用这种技术。这些复杂的模型在其他领域表现出了卓越的结果,而金融建模领域存在巨大的差距,这就产生了一系列引人注目的创新!

更好地解决我们在金融和贸易领域的关键问题将提高效率,增加透明度,加强风险管理和创新。

PS:以上所有分析使用的代码可以在我的 github repo 上找到

我正在计划我的下一篇关于投资组合管理的文章,请继续关注!

欢迎任何好的建议。

请访问我的网站http://www . Wright research . in/了解更多我管理的投资策略!

[## 返工

RE*WORK 活动将企业家精神、技术和科学结合起来,利用……

videos.re-work.co](http://videos.re-work.co/videos/410-how-machine-learning-is-transforming-finance)

实践中的深度学习

原文:https://towardsdatascience.com/deep-learning-in-practice-8836be560dc1?source=collection_archive---------18-----------------------

当你的结果看起来太好或太差时该怎么办

从业者知道深度学习方法非常强大和灵活,但在真实世界的数据集上“在野外”应用它们,与在 CIFAR-10/100 或 ImageNet 等知名数据集上重新运行最新的 SOTA(最先进的)模型是非常不同的。数据缺失、数值错误、打字错误、标签错误等。,使事情变得更加复杂,因此有时我们不确定是否可以相信我们的结果。让我们来看看一些实用的技巧,当你得到的结果看起来*“好得不像真的”“坏得没用”*时,该检查些什么。

好得令人难以置信的结果

结果会“好得难以置信”吗?例如,你可能正在使用迁移学习:你没有时间从头开始构建和训练一个复杂的架构,所以你得到一个预训练的模型(比方说,在 ImageNet 上训练的 ResNet101)并将其输入你的数据集。您希望在不花费长时间学习的情况下获得良好的准确性,但是您并不期望获得优异的结果,除非您的数据集与最初训练模型的数据集极其相似。

或者,在训练一个复杂且耗时的架构之前,您可能想先尝试一个简单的模型。更简单的神经网络将作为基线,以测量使用 bigger/badder 模型获得的优势。你不会期望一个简单的模型得到 SOTA 结果。

最后,您可能正在处理一个简单的模型,因为它的用例(例如,一个移动应用程序,或一个内部部署的应用程序)阻止您走得太远,尤其是如果您计划执行在线培训的话。

那么,如果你第一次测试就获得了 99.3%的准确率,你会怎么想?你不应该马上断定这个问题很简单,你不需要一个很深的关系网来解决它。相反,这里有一些实用的提示,可以帮助你评估你是否幸运,问题是否简单,或者你犯了一些明显的错误。其中一些技巧只对分类器有意义,而另一些则可以应用于各种深度学习模型。

在下文中,我们将假设您已经遵循了最佳实践以避免过度拟合,即,您使用了 k 折叠交叉验证(CV)或训练/验证/测试集分割来估计您的模型的泛化误差,并且您发现了一个可疑的低值。

检查数据泄漏

首先,检查所有数据转换(或估计量,在 Tensorflow 行话中)是否适合训练集,并应用于测试集, k 的每个折叠的*——折叠 CV。例如,如果放弃“无用”的特征是你的模型的一部分,你不能在完整的训练集中选择“有用”的特征,然后每次折叠都使用相同的特征。相反,您必须为每个折叠重复特征选择操作,这意味着在每个折叠中您可能使用不同的特征来进行预测。如果使用训练/验证/测试集分割而不是kfold CV,等效的方法是仅使用验证集来选择有用的特征,而不需要查看测试集。
如果您使用 Python 编码,确保对每个折叠重复相同的精确操作的一个简单方法是使用“Pipeline”类(在“scikit-learn”中)或“Estimator”类(在 Tensorflow 中),并确保对数据的所有操作都在 pipeline/estimator 内部执行。*

您使用的度量标准正确吗?

如果构建分类器,请验证您使用了正确的分类度量。例如,如果群体中的各种类别达到合理的平衡,准确性作为分类度量只有才有意义。但是在一个医学数据集上,人群中疾病的发病率是 0.1%,你可以在一个代表性的数据集上获得 99.9%的准确性,只需将每个点分类到多数类。在这种情况下,99.9%的准确性没有什么好惊讶的,因为准确性不是这里使用的正确度量。

问题真的简单吗?

同样,在分类的情况下,检查问题是否过于简单。例如,您可以拥有完全可分离的数据。换句话说,在输入空间中存在一个流形(或多个流形的交集),它完美地分离了各种类别(无噪声)。在两类线性可分问题的情况下,输入空间中有一个超平面完美地将两类分开。这很容易诊断,因为超平面的所有低维投影都是超平面。因此,例如在所有特征对的 2D 散点图中,两个类别可以由一条线完美地分开:

当然,由于深度学习经常应用于具有数千或数万数量级的 K (特征的数量)(例如,图像像素)的问题,因此甚至可能无法可视化所有 (K+1)K/2 散点图的一小部分。这不是一个问题,因为线性可分数据将被更简单的机器学习工具完美地(或接近完美地)分类,例如线性判别分析、线性支持向量机(SVM)或正则化逻辑回归(非正则化逻辑回归拟合 MLE 对于线性可分问题是不稳定的)。因此,如果可视化是不可能的,拟合这些模型将给出相同的信息,尽管以一种不太直接的方式。

非线性完全可分离的数据在没有可视化的情况下更难检测:

然而,机器学习工具,如内核支持向量机(或更好的,无标签 VAE),或先进的可视化方法,如 t-SNE,可能有助于识别这种情况。
绘制决策区域,例如使用“scikit-learn”的“mlxtend”助手包中的“plot_decision_regions”函数,是快速识别非线性完全可分数据的另一种方法。然而,在你有大量特征的深度学习问题中,这样的可视化可能是不可能或不切实际的。

在这两种情况下(线性和非线性可分离数据),关键是类之间有一个“硬”分离边界(即没有噪声),因此有可能获得完美的分类。可以说,很少有现实世界的问题属于这些类别:在大多数情况下,对于从群体中提取的所有训练集,没有一个“硬”边界可以完美地将这两个类别分开。尽管如此,做这个检查还是值得的。

在随机标签上训练

一个经常具有启发性的测试是在混洗(置换)标签上重新安装 DNN。在这种情况下,特征和类别标签之间没有关系,因此神经网络只有一种方法来获得良好的训练集误差:记住整个训练集。这通常会表现在更长的训练时间。此外,它没有办法获得良好的测试集误差。如果您在测试集上仍然获得了出色的性能,那么要么是您的代码有严重的问题(考虑增加您的单元测试的覆盖率,以找到问题所在),要么是您使用的框架有问题。在后一种情况下,您应该考虑在此时打开一个 GitHub 问题。

在小数据集上训练

走向极端的反面:在单个(或非常少的)数据点上训练。在这种情况下,你应该很快在训练集上获得 100%的准确率(极短的训练时间),当然在测试集上获得极低的准确率。同样,如果您不这样做,这表明您的代码或您正在使用的框架中存在一些严重的问题。

上次检查:获取新数据

最后,您可以尝试获得一些新的测试点,代表 DNN 的真实用例,这是您之前从未见过的(更不用说在培训中使用了)。如果你仍然得到优秀的准确性,那么恭喜你,你的模型太棒了!

Source

“坏得没用”的结果

“人们担心计算机会变得太聪明并接管世界,但真正的问题是它们太笨了,它们已经接管了世界。”
佩德罗·多明戈斯

我们已经看到了当我们在第一次尝试中获得优秀的结果时应该做什么,特别是如何验证我们没有被愚蠢的错误愚弄,例如将测试集泄露给训练集。在这一部分中,我们将看到如何处理神经网络预测不够准确这一更常见的问题。注意:已经有很多次的经验表明,足够深度的神经网络可以记住巨大数据集上的随机标签(例如参见理解深度学习需要重新思考泛化)。因此,原则上,有了足够大的 NN,我们应该总是能够将训练误差减少到极小的值,也就是说,减少过度适应训练集,不管学习任务是多么的无意义。对于泛化错误,情况完全不同。一般来说,不能保证对于每个学习问题,都存在一个可学习的神经网络模型,它可以产生尽可能低的泛化误差。然而,有一些技巧可以帮助你设定现实的目标,并最大化你达到目标的机会。

1.确认你的目标是现实的

在一个问题(数据集+学习任务)上找到一个能达到我们需要的精确度的有信誉的参考,这个问题与我们正在研究的问题足够相似,这将是非常好的。这并不总是可能的,但是保持各种任务的最新技术状态,例如物体检测或命名实体识别,有助于正确设置我们的期望。主题专业知识也可以指导我们选择现实的精度目标。

2.确保你的训练程序中没有错误

当然,如果我们的神经网络训练不正确,我们就不能指望它能很好地推广新数据。以下检查有助于我们验证培训流程:

  • 编写**单元测试,**可能使用 Chase Robert 的机器学习库进行单元测试
  • 数据集检查:查看训练集和测试集的一些随机输入/标签样本,并检查标签是否正确;检查输入图像的宽度和大小;打乱训练/测试集中的样本,看看它是否会影响结果;等等。
  • 过度拟合测试 : 1)将训练集减少到几个样本(两到三个)。训练误差现在应该很快达到 0(NN 立即过拟合如此小的训练集),但是测试集应该增长很多(数据如此之少,NN 不能概括)。2)关闭所有正则化,验证 NN 能够过拟合全部训练集。这并不总是可能的,因为一些架构本质上是不稳定的,如果没有某种形式的调整,训练是不可能的。然而,当测试工作时,它表明 NN 相对于我们的训练集具有过剩的能力,因此,给定适当的正则化,它应该获得低测试误差,只要训练集是测试集的代表,并且特征足以预测标签(如果标签是随机的,再多的训练也不会使 NN 学习:参见下一个要点)。
  • 随机化测试:随机洗牌训练标签。现在,训练误差应该减少(尽管慢得多),但是测试集误差不应该低于随机分类误差(即,如果我们将每个类别分配给多数类,则所犯的误差等于 1-f_m ,其中 f_m 是多数类的频率)。
  • 标准化您的预处理和包版本。使用 Docker 容器来构建您的模型是确保您的模型无论在哪里部署都以相同的方式运行的最佳方式,而不必担心库安装、环境配置、破坏旧功能的库更新等等。
  • 保存详细的数值实验日志

3.尽可能以超收敛为目标

在某些情况下,大学习率与 Leslie N. Smith 的循环学习率方法的结合起到了正则化的作用,使收敛速度加快了一个数量级,并减少了大量正则化的需要。参见超收敛:使用大学习率快速训练神经网络。

4.针对你的问题使用正确的规范化形式

正则化倾向于增加训练时间和训练误差,但同时倾向于减少测试误差。然而,过于一般化实际上会增加这两种错误(欠拟合)。出于这个原因,如果您成功地在没有正则化(过度拟合测试)的情况下使训练集过度拟合,那么一次引入一种正则化技术通常会更好。原因是正则化本身并不一定意味着你的泛化误差会变小:模型必须有足够大的容量来实现良好的泛化特性。一个深度足以过拟合训练集的神经网络,在没有正则化的情况下,一旦正则化开始起作用,应该能够实现低测试误差。

最著名的调整方法是早期停止和体重下降。其他常用工具有:

  • 小批量培训:较小的批量通常与较小的概括误差相关,所以这是一种尝试。然而,请注意,一些研究人员对迷你电池的有效性提出了质疑。迷你批处理与批处理规范化不兼容(见下文),所以在使用这两种方法时要格外小心。
  • 尝试使用 SGD 来代替 Adam 等自适应优化器:论文通过从 Adam 切换到 SGD 来提高泛化性能表明,对于某些任务,SGD 优化器虽然速度较慢,但能够找到对应于较低测试集误差的最小值。
  • 使用下降:如果使用 LSTMs,只对 LSTM 层的输入和输出单元使用标准下降。对于循环单元(门),使用循环辍学,这是 Yarin Gal 在他的博士论文中首次提出的。如果您使用 CNN,当应用于具有更多单元的层(即全连接层)时,dropout 会更有效,除非您使用的是 FCN(全卷积网络),它没有全连接层。然而,对于 CNN 辍学生来说,最近已经失宠了。
  • 批量标准化:最新的 CNN 架构避免了丢弃,支持批量标准化。这可能是由于明显的丢失和批量正常化不能很好地配合(通过方差转移理解丢失和批量正常化之间的不协调)。因为当你有大量数据集时,批处理规范比丢弃更有效,这可能是丢弃不再受 CNN 架构青睐的原因。如果使用批量归一化,请验证各图层的权重和偏差分布看起来近似标准正态。对于 RNNs 来说,实现批处理规范是复杂的:权重归一化(一种简单的重新参数化,以加速深度神经网络的训练)是一种可行的替代方案。

5.超参数/架构搜索

如果上述步骤没有足够减少测试误差,您将不得不测试多个不同的超参数设置(贝叶斯优化在这里可能有所帮助)或多个不同的架构变化(例如使用高效神经架构搜索)。确保在有序的日志中记录这些漫长而复杂的实验结果。

6.魔术袋

最后,AWS 最近的一篇论文包含了一个有用的提高测试准确性的技巧包。这篇论文只限于一个任务(图像分类)和一个架构(CNN),尽管它是目前该任务的最佳架构。总之,这篇论文很有趣,充满了有用的见解。

7.摘要

即使最近在深度学习方面取得了所有的进展,建立和训练一个泛化能力很好的神经网络模型仍然是一门艺术,也是一门科学。然而,应用这篇文章中描述的技巧,重用成功的架构并进行仔细的数值实验,将允许您提高模型的泛化能力。

结论

我们描述了一些关于如何验证深度学习模型结果的可靠性的有用提示,以及当它们不令人满意时如何改进它们。如果你知道其他的建议,欢迎在评论中提出来!

浏览器中的深度学习:简明指南

原文:https://towardsdatascience.com/deep-learning-in-your-browser-a-brisk-guide-ca06c2198846?source=collection_archive---------3-----------------------

使用网络摄像头和 Tensorflow.js 实时检测物体。

Original Image

Tensorflow.js 是一个新的深度学习库,可以在你的浏览器中运行。作为一名机器学习和 Javascript 爱好者,我在 Tensorflow.js 发布后立即开始使用它进行对象检测库的工作。

在这里,我将走过我是如何开始的,并分解 tfjs-yolo-tiny 的不同点。你可以点击这里查看现场演示。

我们将涉及提取原始的微型 YOLO 暗网模型,将其转换为 Keras,将其转换为 Tensorflow.js,进行一些预测,在 Tensorflow.js 中编写时捕获数据,以及轻松使用网络摄像头/图像进行预测。

更好、更快、更强

是的那是认真的原论文题目。我们将使用微型 YOLO ,一种可以以 200 FPS 运行的快速对象检测模型。我们将使用小 YOLO 而不是完整的 YOLOv2。为什么?首先,YOLOv2 在一个强大的桌面上“只能”以 40 fps 的速度运行,大多数用户都无法访问。该模型文件也比微型 YOLO 大 5 倍左右,从网上下载要花很长时间。最后,YOLOv2 有一个 reorg 层,它还不支持作为原生 Tensorflow.js 层。我们将在下一步中获取微小 YOLO 的网络配置(神经网络结构)和权重(幻数)。

YAD2K:又一个 Darknet 2 Keras(转换器)

你可能已经注意到 YOLO 是用暗网写的,暗网听起来不像张量流。所以我们的第一站是将我们的 YOLO 模型转换成更张量流的东西,在我们的例子中,就是 Keras !Keras 是一个更高级的深度学习框架。这是将您的权重转换为 Tensorflow.js 格式的推荐格式。

我们将使用 YAD2K 将暗网模型转换为 Keras。继续按照这里的说明安装 YAD2K,我等着。

好吧,你也可以假装是你做的,并使用我已经发布的最终重量文件,但这不会那么有趣!

现在,我们必须修复 YAD2K 中的一个错误,以正确加载微小的 YOLO。

在您最喜欢的文本编辑器中打开 yad2k.py ,在第 83 行,将buffer=weights_file.read(16)改为buffer=weights_file.read(20)。为什么?不知道。

现在在您的终端中运行以下命令。它将下载微小的 YOLO 重量和配置,以及输出转换后的模型文件到model_data/yolov2-tiny.h5

wget [https://pjreddie.com/media/files/yolov2-tiny.weights](https://pjreddie.com/media/files/yolov2-tiny.weights)
wget [https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov2-tiny.cfg](https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov2-tiny.cfg)./yad2k.py yolov2-tiny.cfg yolov2-tiny.weights model_data/yolov2-tiny.h5

接下来,我们要确保我们的新模型实际可行!有趣的事实:我忘记这样做了,我花了一整天的时间想知道 Tensorflow.js 为什么是 b0rk。

./test_yolo.py model_data/yolov2-tiny.h5

该模型应该输出一些预测。如果没有,欢迎在下面评论我!

Tensorflow.js 转换器:我们最后的重量转换

这一步更简单,我保证!看官方指南这里。同样,如果这看起来太多了,我已经完成了所有困难的工作,所以你可以直接跳过:)

我们需要安装官方的转换工具。在你的终端中运行pip install tensorflowjs来安装转换器。

现在再次使用终端来转换我们的模型!

tensorflowjs_converter --input_format keras \
    model_data/yolov2-tiny.h5 \
    tfjs_model_data

现在我们终于在tfjs_model_data有了我们所有的模型文件!注意,该文件夹包含一个model.json以及一堆其他碎片文件。model.json告诉 Tensorflow.js 神经网络的结构是什么,哪些碎片文件对应什么权重。碎片文件包含模型的权重。确保碎片文件位于model.json的同一个目录中,否则您的模型将无法正确加载。

Tensorflow.js 时间

现在,有趣的部分。(每一部分都是好玩的部分。)ML 和 JS 代码同时!

我们将从导入一些 Tensorflow 并加载模型开始。

import * as tf from ‘@tensorflow/tfjs’;const model = await tf.loadModel(url);

等等,什么是“网址”?您可以在这里使用托管模型文件或者提供您转换的文件的路径。在这里了解更多!

太棒了,现在我们可以做一些真正的深度学习:

function yolo (input) {
   return model.predict(input);
}

哼。这似乎很平常。哦等等。我们忘记了将输出转换成边界框、类标签和概率!

The numbers Mason, what do they mean?? Original Image

把数字变成盒子和数字

我不打算深入探讨这个问题,因为 YOLO 的后期处理可以是他们自己的几篇博文。相反,我将强调我在将 Python 版本转换为 Javascript 时所面临的挑战。

某些张量运算不可用

Tensorflow.js 还很年轻,因此有些东西还不可用,如布尔遮罩或 NMS 。您也可能遇到这个问题,但幸运的是,您可以通过使用

const expected_shape = tensor.shape;
const data = await tensor.data(); // Async transfer from GPU to CPU
// Note: data is a flattened TypedArray of the original tensor
//... data manipulation in JS on CPU
tf.tensor1d(data).reshape(expected_shape); // Shape it back into where we were before

注意:这样做可能会成为应用程序的瓶颈,但是有时候这是不可避免的。

不能像 Python 一样使用-1 索引

在 python 中,你可以使用-1 作为“最后一个元素”。不幸的是,在 Tensorflow.js 中,如果你在tf.slice上尝试这样做,它会无声地失败。相反,你必须明确地指定尺寸。

不能用 5d 张量

当心 Tensorflow.js 的 WebGL 后端不支持 5d 张量。如果我连 5 维都想象不出来,为什么还要用它们?在 YOLO,我们将产出重塑为[batch_size, xy, wh, box_confidence, box_class_pred]。这明明是 5d。幸运的是,为了避免这样的痛苦和折磨,我简单地删除了 batch_size 维度。一种替代方法是不整形为 5d 张量。需要警惕的事情。

除此之外,我的经历是流动的。我只需要在 CPU(传统 JS)中重新实现 Tensorflow 通常开箱即用的两个 算法。

NPM 装置

让我们把我们的深度学习放到一个应用程序中吧!

幸运的是,一个可怜的家伙已经写好了代码,所以只需在你的终端上运行一个 NPM 安装程序:

npm i tfjs-yolo-tiny

现在我们将挥舞一下我们的 Javascript 魔杖

import yolo, { downloadModel } from ‘tfjs-yolo-tiny’;const model = await downloadModel();
const inputImage = webcam.capture();const boxes = await yolo(inputImage, model);

哇哇,你说的这个webcam.capture()是什么?

Original Traffic Image: https://pxhere.com/en/photo/423261

也许比 NPM 装置多一点…

你可能已经注意到,我们还没有触及我们的 YOLO 到底在喂什么。而这是 Tensorflow.js 最酷的部分之一。

我们可以从文档(DOM)中取出一个视频或图像,并将其转换为张量!

我们可以用 JavaScript 写这样的东西:

/* Pretend we had the following element in index.html. Always use alt tags for accessibility!
<img id=”image” src=”/test_input.jpg” alt=”YOLO Model Test Image”>
*/const image = document.getElementById(‘image’);
const input = tf.fromPixels(image);

嘭!输入现在有图像作为张量!要从图像切换到网络摄像头,你只需将它指向正确的元素。这对我来说是相当✨的魔法。

在这之后,我们必须做一些预处理。在这种情况下,将其裁剪为正方形,大小调整为 416x416,然后除以 255 以获得范围从 0 到 1 的像素值。为什么?因为老板是这么说的(我们就是这样训练 YOLO 的)。

最后的想法

我们已经演练了如何将模型转换为 Tensorflow.js 格式。我们可以加载一个模型并用它来预测。然后我们探索了在 Tensorflow.js 中编写后处理代码的一些痛点,但是我们占了上风。我们现在还知道如何通过静态图像或网络摄像头获取数据。现在我们可以将大多数 ML 模型从 Python 转换为 Tensorflow.js,并在您的浏览器中运行它们。

想看看所有的行动吗?查看现场演示。想在您的应用程序中轻松使用它吗?检查一下 NPM 包。查看 Github repo 的演示来看看所有这些代码的运行以及如何使用 NPM 包。

欢迎加入 ModelDepot 的讨论,或者在 Gitter Chat 上找到我们!或者甚至为您的项目浏览下一个机器学习模型!

特别感谢 HS、KZ、VP 和 JS 润色我的字母汤

深度学习魔法:小企业类型

原文:https://towardsdatascience.com/deep-learning-magic-small-business-type-8ac484d8c3bf?source=collection_archive---------4-----------------------

企业情报很难,NAICS 代码很糟糕。一些公司按行业购买公司列表,以保持他们的潜在客户数据库最新(例如 D+B )。购买清单的主要问题是它们马上就过时了,而且它们不能很好地捕捉小公司的数据。我们如何使用机器学习来猜测一个小企业仅根据他们的企业名称做什么?

大企业通常在公司简介上标注得很好。我们可以从免费来源或商业级 API 获得这些,如彭博和路透社。甚至的小型公司也有现成的数据。但是小企业没有被很好的记录。更糟糕的是,大多数企业都是小企业。让我们把注意力集中在小企业上,看看我们如何从它们的名字中猜出它们是做什么的。

作为一个人,你自动完成这项任务。你看到一家企业的名称“渥太华街角超市”,并根据你的经验得出结论,这是一家便利店。如何从公司名称转换成公司标签?我们认为一个很好的方法是在 Google Places API 中读取 类型。事实证明,这是一个很好的数据源,但还不够好。对于谷歌没有标签的 80%+的小企业,我们能做什么?

我们决定发布一个深度学习的 keras 模型来解决这个问题。DNN 模型在超过 500,000 个公司名称及其相关类别上进行了训练。您想要分类的公司名称被编码到一个 word2vec (gensim)单词嵌入模型中,该模型对大约 250 万个公司名称进行了训练。以下是我们训练模型识别的所有 127 个类别的列表:

我们做了大量的设计空间探索研究,以找出在我们的神经网络模型中使用的正确的层数和每层神经元数。

Trying various model hyperparameters in a shallow search yielded a 1024-neuron wide, 3-layer deep (input, hidden, output) DNN. The model we picked corresponds to the top pink line.

The model scored 60% on test data it never saw before. That’s pretty good for a 127 class classification problem.

原来宽浅才是这个模式要走的路。以下是一个示例数据集的结果:

以下是你如何得到这款机型的方法( GitHub link ):

git clone [https://github.com/dcshapiro/smallCompanyType.git](https://github.com/dcshapiro/smallCompanyType.git)
cd smallCompanyType/
pip3 install h5py
pip3 install keras --upgrade
pip3 install tensorflow --upgrade
python3 setup.py install

以下是您使用它的方法:

cd test
python3 test_text.py
python3 test_pandas.py

有趣的是,这里有一个视频展示了在 DigitalOcean 机器学习 droplet 上的成功安装。就是我之前贴的几篇文章里提到的一键安装镜像。

The smallCompanyType package installs cleanly in a new VM. It depends on the latest sklearn, h5py, keras, numpy, and tensorflow. The tests use glob, pandas, and some more fun stuff.

你能把这个模型用于商业目的吗?是的。没有性能保证,但请继续。尝试一下,让我知道你的想法。

试用拍手工具。轻点那个。关注我们的媒体。分享这篇文章的链接,或者 GitHub repo 的链接。去吧。

编码快乐!

-丹尼尔
丹尼尔@lemay.ai ←打个招呼。
LEMAY . AI
1(855)LEMAY-AI

您可能喜欢的其他文章:

  • 人工智能和不良数据
  • 人工智能:超参数
  • 人工智能:让你的用户给你的数据贴上标签

深度学习和医疗诊断

原文:https://towardsdatascience.com/deep-learning-medical-diagnosis-c04d35fc2830?source=collection_archive---------5-----------------------

越来越多的领域正在将机器学习应用于基于医学成像的诊断。

在过去的几个月里,已经有许多研究发现宣布,声称深度学习已经被应用于某个特定的诊断领域,并且经常是立即胜过医生。

我最初开始写这篇博文是为了跟踪他们——我打算以草稿的形式发表这篇博文,并希望定期更新。

医学影像诊断中的深度学习试图做什么?

在深入研究具体结果之前,我想强调一下,下面的方法(到目前为止)具有相同的共同模式。我试着用下面一句话来概括:

通过机器学习的诊断在病症可以被简化为对**生理数据的* 分类任务 时起作用,在这些领域中,我们当前依赖于临床医生能够视觉上 识别指示病症的存在或类型的模式*

把它分解成细节:

  • 分类。结果是医学诊断的领域,可以简化为一个分类问题:给定一些数据,诊断可以简化为将该数据映射到 N 个不同结果之一的问题。在某些情况下,N = 2:任务仅仅是识别数据(例如,x 射线)是否显示条件。请注意,还有其他问题(如图像分割)可以用深度学习来解决,但我还没有看到它们被单独使用用于诊断(而不是,比如说,仅用于分析)。**
  • 生理数据。下面的结果倾向于使用医学成像数据或来自其他类型传感器的数据。这些领域结果的激增在很大程度上归因于数据集的创建(例如这些数据集),这些数据集远远大于以前可用的数据集。注释数据集(例如,标记 x 射线是否包含肿瘤)的一种常见方法是让一组临床医生给出他们的意见并核对响应。
  • 我们依靠视觉识别模式。自动诊断系统的替代方案是让专业临床医生查看您的数据(也许与一些同行专家讨论一下)来确定结果。这一点抓住了为什么深度学习应该在这一领域取得成功:深度学习自动化了在这种“非结构化”数据中提取模式和学习关系的整个过程。还有很多深度学习的非医疗应用(如人脸识别)也有类似的需求;正因为如此,技术已经相当成熟。事实上,甚至训练有素的医学图像模型现在也被开源。

对于该领域的优秀评论,请查看我在本文底部的参考资料部分添加的评论论文和博客文章。

这种方法而不是应该在哪里起作用?

**上面的模式让我们对这种方法目前不适用的领域有了一些了解。就像这篇文章提到的一样,深度学习并没有告诉我们应该如何治疗患者,或者在治疗时他们会有多好。然而,与上述各点特别相关的是,有些领域:

  • ****不是分类问题。如果我们对疾病不够了解,我们就无法创建数据来训练任何算法。例如,有些情况没有很好理解的进展,可以列举成一组阶段。在这些情况下,建立一个可靠的模型来告诉我们患者处于哪个进展阶段将是非常具有挑战性的——因为我们不知道应该是哪个阶段。
  • ****缺乏(或有主观)数据。如果很少或没有数据,我们就无法训练模型。诚然,这种情况正在开始改变——有深度学习实验证明从极小的数据集中学习。如果有数据,但其中的数据和/或模式是主观的(例如,痛苦或压力的瞬间体验),那么我认为下面的方法需要重新设想。
  • 不依赖医疗器械。类似地,无法通过将患者连接到某种机器并收集单个数据“样本”来得出诊断的领域(例如,需要长期跟踪或通过排除进行诊断)。这可能是因为(a)我们还没有开发出一种检测疾病的方法——因此,如上所述,需要更多的基础研究,或者(b)我们还没有开发出可行的产品来进行长期、非侵入性的监测,以收集支持机器学习的数据。

医疗条件列表

我添加到这个列表的标准是:(a)一个数据集已经发布,(b)研究已经发表,(c)一个公司或研究小组已经写了关于进展中的工作,或者(d)有描述解决问题的博客文章。我已经按字母顺序把条件分类了。

我错过了什么吗?你可以在推特上 @我,我来加。

痴呆症

…”是一种慢性神经退行性疾病,通常开始缓慢,并随着时间的推移而恶化伦敦的研究人员发表了一篇论文,报告使用来自ADNI的数据来训练一个具有单一卷积层的三层神经网络,该网络可以预测核磁共振扫描是否是一个健康的大脑,一个有轻度认知障碍的大脑和一个有老年痴呆症的大脑。

心律不齐

…”是一组心跳不规则的情况斯坦福大学的研究人员发表了一篇论文,报告称他们开发的 34 层卷积神经网络“在从单导联可穿戴监护仪记录的心电图中检测各种心律失常方面,超过了委员会认证的心脏病专家的性能”(项目页面,博客文章)。

孤独症

“是一种以社交互动受损为特征的神经发育障碍”一组研究人员发表了一篇论文,报告称“一种主要使用来自 6 个月和 12 个月大的大脑 MRI 的表面积信息的深度学习算法预测了自闭症高家族风险儿童的 24 个月自闭症诊断”(通过 @datarequena 在推特上)。

乳腺癌

…“是一种从乳腺组织发展而来的癌症。DeepMind Health 发布了一篇博客帖子 t,其中他们宣布他们已经与英国癌症研究所合作,对来自 7500 名女性的匿名乳房 x 光片进行分析并应用机器学习。

牙洞

…”是由于细菌产生的酸而导致的牙齿损坏 ParallelDots 的研究人员已经发表了一篇论文报道了一个 100+层的卷积网络对牙齿 x 光片进行像素级的二进制分类(有龋/无龋)。

糖尿病视网膜病

…”是一种因糖尿病导致视网膜受损的医学状况。两年多前,有一场 kaggle 竞赛,试图将眼睛的图像分为 5 类(从无糖尿病视网膜病变,到轻度中度重度,以及增生性)。获胜的解决方案使用了稀疏卷积网络和随机森林的组合,从一对图像(左眼和右眼)对结果进行预测。

革兰氏染色

…是否有一种染色的方法用于区分和分类细菌种类为两大类这是一种实验室技术,在怀疑感染时对体液(如血液)进行检测。研究人员发表了一篇论文(本文引用)描述了使用卷积神经网络将显微镜图像分类为革兰氏阳性、革兰氏阴性和背景(无细胞)。在论文中,他们描述他们没有从零开始培养一个 CNN 他们为这个任务微调了 Inception v3 。

肺癌

…”是一种以肺组织中不受控制的细胞生长为特征的恶性肿瘤这个 2017 kaggle 竞赛包括一组 CT 扫描的数据,目标是预测肺癌的可能性。这里有一些有趣的挑战,包括数据是三维的——获奖解决方案的文章描述了一些有趣的解决方法。这篇博客文章从临床的角度概述了这个竞赛的一些局限性。另外,Enlitic 似乎也在研究一种肺癌筛查解决方案。

甲真菌病

…”是指甲的真菌感染。正如这条推文所指出的,韩国的研究人员发表了一篇论文,报告称使用 CNN(VGG-19,ResNet-152)创建了一个训练数据集(例如,从临床照片中提取手和脚的图像)并将指甲分为六类(如下所示:(甲癣、指甲营养不良、甲松脱、黑甲、正常和其他),以实现“使用深度学习对甲癣的诊断准确性,优于大多数皮肤病的诊断准确性

肺炎

“是肺部的一种炎症状态,主要影响称为肺泡的小气囊。”斯坦福大学的研究人员发表了一篇论文,报告称他们开发的 121 层卷积神经网络“可以在超过执业放射科医生的水平上从胸部 x 光片中检测肺炎”(项目页面)。

皮肤癌

…“是由于有能力侵入或扩散到身体其他部位的异常细胞的发展。”斯坦福大学的研究人员发表了一篇论文,报道了使用“皮肤科医生标记的 129,450 张临床图像的数据集,包括 3,374 张皮肤镜图像”,对 Inception v3 进行微调,以分类 757 种疾病类别通过不同的预测任务检查结果,准确率似乎与临床医生的分数相当。

…我相信这个名单会越来越长。

参考资料和资源

**[## [1702.05747]医学图像分析中的深度学习调查

摘要:深度学习算法,特别是卷积网络,已经迅速成为一种选择方法…

arxiv.org](https://arxiv.org/abs/1702.05747)** ** [## 加速医学成像领域的深度学习

当前方法的概述,可公开获得的数据集,领域的方向,和机会…

medium.com](https://medium.com/the-mission/up-to-speed-on-deep-learning-in-medical-imaging-7ff1e91f6d71) [## 医学成像中的深度学习:概述

机器学习(ML)被定义为一组自动检测数据中模式的方法,然后利用这些模式进行学习

www.ncbi.nlm.nih.gov](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5447633/) [## 医学图像分析中的深度学习——science direct 综述

深度学习算法,特别是卷积网络,已经迅速成为一种方法学的选择…

www.sciencedirect.com](http://www.sciencedirect.com/science/article/pii/S1361841517301135) [## albarquni/医学应用深度学习

面向医学应用的深度学习-医学图像分析的深度学习论文

github.com](https://github.com/albarqouni/Deep-Learning-for-Medical-Applications)**

深度学习遇上物理学:受限玻尔兹曼机器第一部分

原文:https://towardsdatascience.com/deep-learning-meets-physics-restricted-boltzmann-machines-part-i-6df5c4918c15?source=collection_archive---------2-----------------------

受限玻尔兹曼机背后的理论——重组系统的有力工具

本教程是关于受限玻尔兹曼机器的两部分系列的第一部分,这是一种用于协作过滤的强大深度学习架构。在这一部分,我将介绍受限玻尔兹曼机背后的理论。第二部分由一个模型的实际实现的逐步指导组成,该模型可以预测用户是否喜欢一部电影。

实用的部分现在可以在这里得到。

目录:

  • 0。简介
  • 1。受限玻尔兹曼机器
  • 1.1 架构
  • 1.2 基于能量的模型
  • 1.3 概率模型
  • 2。使用受限玻尔兹曼机器的协同过滤
  • 2.1 识别数据中的潜在因素
  • 2.2 利用潜在因素进行预测
  • 3。培训
  • 3.1 吉布斯采样
  • 3.2 对比差异

如果你喜欢这篇文章,想分享你的想法,问问题或保持联系,请随时通过 LinkedIn 与我联系。

0.介绍

受限玻尔兹曼机器(RBM)是属于所谓的基于能量的模型的神经网络。这种类型的神经网络可能不像前馈或卷积神经网络那样为本文的读者所熟悉。然而,这种神经网络近年来在 Netflix 奖的背景下大受欢迎,RBM 在协同过滤方面取得了最先进的表现,并击败了大多数竞争对手。

1.受限玻尔兹曼机器

1.1 架构

在我看来,RBM 是所有神经网络中最简单的架构之一。如图 1 所示,RBM 由一个输入/可见层(v1,…,v6)、一个隐藏层(h1,h2)和相应的偏置向量 Bias a 和 Bias b 组成。输出层的缺失是明显的。但是正如后面可以看到的,输出层是不需要的,因为预测的方式与常规前馈神经网络不同。

1.2 基于能源的模型

能量是一个可能一开始就不会与深度学习联系在一起的术语。相反,能量是物理学的一个定量属性。重力能量描述了一个有质量的物体由于重力而相对于另一个大质量物体的势能。然而,一些深度学习架构使用能量的概念作为衡量模型质量的指标。

Fig. 2. Gravitational energy of two body masses.

深度学习模型的一个目的是编码变量之间的依赖关系。通过将标量能量与变量的每个配置相关联来捕获依赖性,这用作兼容性的度量。高能量意味着差的兼容性。基于能量的模型总是试图最小化预定义的能量函数。RBMs 的能量函数定义为:

Eq. 1. Energy function of a Restricted Boltzmann Machine

可以注意到,能量函数的值取决于可见/输入状态、隐藏状态、权重和偏差的配置。RBM 的训练在于寻找给定输入值的参数,使得能量达到最小。

1.3 一个概率模型

受限玻尔兹曼机器是概率性的。与分配离散值相反,该模型分配概率。在每个时间点,RBM 都处于特定的状态。状态是指可见层和隐藏层的神经元的值 vh 。可以观察到 vh 的某一状态的概率由以下联合分布给出:

Eq. 2. Joint Distribution for v and h.

这里 Z 被称为“配分函数”,它是所有可能的可见和隐藏向量对的总和。

这是受限玻尔兹曼机器第二次与物理学相遇的地方。这种联合分布在物理学中被称为玻尔兹曼分布,它给出了在能量为 E 的状态下可以观察到粒子的概率。正如在物理学中我们分配一个概率来观察一个状态 v 和 **h,**这取决于模型的总能量。不幸的是,由于配分函数 Zvh 的大量可能组合,计算联合概率非常困难。给定状态 v 时状态 h 的条件概率以及给定状态 h 时状态 v 的条件概率的计算要容易得多:

Eq. 3. Conditional probabilities for h and v.

应该事先注意到(在实际例子上证明这个事实之前)RBM 中的每个神经元只能以 0 或 1 的二进制状态存在。最有趣的因素是隐藏或可见层神经元处于状态 1 的概率——因此被激活。给定输入向量 v ,单个隐藏神经元 j 被激活的概率为:

Eq. 4. Conditional probability for one hidden neuron, given v.

这是 Sigmoid 函数。这个等式是通过将贝叶斯规则应用于等式 3 并进行大量扩展而得到的,这里不做介绍。

类似地,可见神经元 i 的二进制状态被设置为 1 的概率为:

Eq. 5. Conditional probability for one visible neuron, given h.

2。使用受限玻尔兹曼机器的协同过滤

2。1 识别数据中的潜在因素

让我们假设一些人被要求对一组电影进行 1-5 颗星的评分。在经典因素分析中,每部电影都可以用一组潜在因素来解释。例如,像《哈利·波特》、《速度与激情》这样的电影可能与奇幻动作的潜在因素有很强的关联。另一方面,喜欢玩具总动员瓦力的用户可能会对潜在的皮克斯因素产生强烈的联想。成果管理制被用来分析和找出这些潜在的因素。在训练阶段的一些时期之后,神经网络已经多次看到每个用户的训练数据集中的所有评级。此时,该模型应该已经基于用户偏好和所有用户的相应协作电影品味学习了潜在的隐藏因素。

隐藏因素的分析以二进制方式进行。用户不是给模型用户连续的评级(例如 1-5 颗星),而是简单地告诉他们是否喜欢(评级 1)特定的电影(评级 0)。二进制等级值表示输入/可见图层的输入。给定输入,人民币然后试图发现数据中的潜在因素,可以解释电影的选择。每个隐藏的神经元代表一个潜在的因素。给定一个由成千上万部电影组成的大数据集,很确定用户只观看和评价了其中的一小部分。有必要给尚未分级的电影也赋予一个值,例如-1.0,以便网络可以在训练时间期间识别未分级的电影,并忽略与它们相关联的权重。

让我们考虑下面的例子,其中用户喜欢指环王哈利波特,但是不喜欢黑客帝国搏击俱乐部泰坦尼克号。《霍比特人》还没有被看过,所以它的评级是-1。给定这些输入,玻尔兹曼机器可以识别对应于电影类型的三个隐藏因素戏剧幻想科幻

Fig. 3. Identification of latent factors.

给定电影,人民币分配一个概率 p(h|v) (等式。4) 为每个隐藏神经元。神经元的最终二进制值是通过使用概率 p 从伯努利分布中采样获得的。

在这个例子中,只有代表流派幻想的隐藏神经元被激活。给定电影分级,受限玻尔兹曼机器正确地识别出用户最喜欢幻想。

2.2 利用潜在因素进行预测

在训练阶段之后,目标是预测尚未看过的电影的二进制评级。给定特定用户的训练数据,网络能够基于该用户的偏好识别潜在因素。由于潜在因素由隐藏的神经元表示,我们可以使用 p(v|h) (等式。5)并从伯努利分布中取样以找出哪些可见神经元现在变得活跃。

Fig. 4. Using hidden neurons for the inference.

图 4 示出了在使用隐藏神经元值进行推断之后的新评级。电视网的确将《T32》奇幻片《T33》确定为首选电影类型,并将《霍比特人》评为用户喜欢的电影。

总之,从训练到预测阶段的过程如下:

  1. 根据所有用户的数据训练网络
  2. 在推理期间,获取特定用户的训练数据
  3. 使用这些数据来获得隐藏神经元的激活
  4. 使用隐藏神经元值获得输入神经元的激活
  5. 输入神经元的新值显示了用户对尚未看过的电影的评价

3.培养

受限玻尔兹曼机器的训练不同于通过随机梯度下降的常规神经网络的训练。RBM 训练程序的偏差不在这里讨论。相反,我将给出两个主要训练步骤的简要概述,并建议本文的读者查阅关于受限玻尔兹曼机器的原始论文。

3.1 吉布斯采样

训练的第一部分叫做吉布斯采样。给定输入向量 v ,我们使用 p(h|v) (等式 4)来预测隐藏值 h. 已知隐藏值,我们使用 p(v|h) (等式 5)来预测新的输入值 v 。这个过程重复 k 次。在 k 次迭代之后,我们获得了另一个输入向量 v_k ,它是从原始输入值 v_0 重新创建的。

3.2 对比分歧

权重矩阵的更新发生在对比发散步骤期间。向量 v_0v_k 用于计算隐藏值 h_0h_k 的激活概率(等式 4)。这些概率的外积与输入向量 v_0v_k 之间的差导致更新矩阵:

Eq. 6. Update matrix.

使用更新矩阵,可以用梯度**上升、**计算新的权重,由下式给出:

Eq. 7. Update rule for the weights.

参考

  1. https://www.cs.toronto.edu/~rsalakhu/papers/rbmcf.pdf
  2. 【https://www.cs.toronto.edu/~hinton/absps/guideTR.pdf

深度学习遇上物理学:受限玻尔兹曼机器第二部分

原文:https://towardsdatascience.com/deep-learning-meets-physics-restricted-boltzmann-machines-part-ii-4b159dce1ffb?source=collection_archive---------5-----------------------

建造你自己的受限玻尔兹曼机器

本文是**的续篇,第一部分 在这里我介绍了受限玻尔兹曼机背后的理论。该第二部分包括通过受限玻尔兹曼机器的实际实现的逐步指导,该受限玻尔兹曼机器用作推荐系统,并且可以基于用户的喜好来预测用户是否喜欢电影。**

(1)在本文中,我不会涉及我所做的步骤背后的理论,我将只解释实际的部分。请务必通过复习本系列第一部分来更新您的理论知识。

(2)我在本文中展示的代码来自我在 GitHub 上的项目资源库。因为我只关注模型的实现,所以我跳过了一些预处理步骤,比如将数据分成训练/测试集以及构建输入管道。可以在存储库中检查这些步骤。

先决条件

  • Python 3.6
  • 张量流 1.5 或更高
  • 1.11 或更高版本

资料组

我们使用的是 MovieLens 1M 数据集。该集合包含由大约 6000 个用户制作的大约 4000 部电影的 100 万个评级。该模型将在这个数据集上进行训练,并将学习预测用户是否喜欢随机电影。数据集需要一些重新处理步骤。因为通常的受限玻尔兹曼机器只接受二进制值,所以有必要给等级 1-2 一个 0 值——因此用户不喜欢这部电影。相应地,等级 3-5 的值为 1。尚未分级的电影的值为-1。

在下一步中,转换后的原始数据被分成两个独立的训练和测试数据集。这是必要的两个完全相同的用户在两个数据集,但不同的电影评级。图 1 示出了将原始数据集划分成训练和测试数据的简单示例。在此示例中,前 5 个评级被放入训练集,而其余的用-1 屏蔽,表示尚未评级。相应地,测试集接收剩余的 5 个等级。

在训练时间期间,受限的 Boltzmann 机器学习每个用户的前 5 部电影评级,而在推断时间期间,该模型试图预测后 5 部电影的评级。然后,将这些预测的评级与放入测试集的实际评级进行比较。

两个数据集都以二进制 TFRecords 格式保存,这使得数据输入管道非常高效。

Fig. 1. Partitioning of the data into training and test datasets.

模型架构

该模型以面向对象的方式实现。受限玻尔兹曼机器是一个具有所有必要操作的类,如训练、丢失、精确、推理等。在里面。一些助手功能被外包到一个单独的脚本中。

构造函数为权重和偏差设置内核初始化器。在下一步中,网络中的所有权重和偏差都被初始化。权重呈正态分布,平均值为 0.0,方差为 0.02,而偏差在开始时都设置为 0.0。可以注意到,网络仅由一个隐藏层组成。结果,只需要一个权重矩阵。

****采样隐藏的状态

Eq. 1. Probability that a hidden neuron is activated.

给定二进制输入 v ,下面的函数_sample_h(self) 获得隐藏神经元被激活的概率(等式 1)。这是通过将输入 v 乘以权重矩阵、添加偏置并应用 s 形激活来实现的。获得的概率用于从伯努利分布中采样。采样值 1.0 或 0.0 是隐藏神经元的状态。

可视状态的采样

Eq. 2. Probability that a visible neuron is activated.

给定隐藏状态 h ,我们可以使用这些来获得可见神经元活动的概率(等式 2)以及相应的状态值。这是在_sample_v(self)中实现的。

吉布斯采样

Fig.2. Gibbs Sampling.

训练的第一部分是一个叫做吉布斯采样的操作。简而言之,我们取一个输入向量 v_0 并用它来预测隐藏状态 h_0 的值。另一方面,隐藏状态用于预测新的输入状态 v 。这个过程重复 k 次。这个过程如图 2 所示。

**吉布斯采样在下面截取的代码中实现。迭代发生在 while 循环体中。体内重要的一步是Vk=tf.where(tf.less(V,0),V,Vk)。该操作确保在每次迭代中,对于每个 v_k ,为-1 的 v 中的评级(意味着还没有看过的电影)保持为-1。在 k 迭代之后,我们得到 v_k 和相应的概率 **p(h_k|v_k)。连同 v_0h_0 这些值可用于在下一个训练步骤中计算梯度矩阵。

计算梯度

在前一步骤中获得的值可以用于计算梯度矩阵和梯度向量。根据等式计算梯度。3 是直截了当的。请注意,这个等式中的符号 ab 分别代表隐藏的可见偏差,与我在代码中使用的不同符号形成对比。

唯一棘手的是 TensorFlow 1.5 不支持外积。但是这个问题可以通过临时整形和应用通常的点乘来解决。

Eq. 3. Computation of gradients for the weights and biases.

注意,梯度的计算发生在 while 循环中。这仅仅是因为培训是小批量进行的。这意味着循环为小批量中的每个数据样本计算梯度,并将它们添加到先前定义的梯度占位符中。最后,梯度的总和除以小批量的大小。

更新步骤

在计算梯度之后,所有的权重和偏差可以根据等式通过梯度上升来更新。4.对于这个过程,我们必须在_update_parameter(self).中创建一个赋值操作

Eq. 4. Update step of the parameters through gradient ascent.

**整个训练操作在名称范围“操作”下用optimize(self)方法计算。在此之下,执行更复杂的训练精度操作。基本上,该操作从吉布斯采样 **期间获得的 v_k 中减去原始输入值 v_0减法只发生在 v_0 ≥ 0 时。在此之后,相减之和除以所有等级数≥ 0。准确度给出了训练期间正确预测的二进制电影分级的比率。

推理

在推理时间期间,方法inference(self)接收输入 v. 该输入是特定用户的一个训练样本,用于激活隐藏的神经元(用户电影品味的潜在特征)。隐藏的神经元再次用于预测新的输入 v 。在最好的情况下,这种新的输入包括对已经存在的评级以及尚未评级的电影的评级的重新创建。

TensorFlow 会话之外,将做出的预测与相应的测试数据进行比较,以进行验证。

网络图

为了概述前面的步骤,这里是主网络图的定义和执行训练和推理步骤的会话的开始。

模型的性能

在训练过程中,我们可以在训练集和测试集上检查准确性的进展。准确度给出了正确预测的二进制电影分级的比率。可以看出,在 6 个时期之后,如果用户喜欢或不喜欢随机电影,该模型正确预测的时间为 78%。

epoch_nr: 0, batch: 50/188, acc_train: 0.721, acc_test: 0.709
epoch_nr: 1, batch: 50/188, acc_train: 0.767, acc_test: 0.764
epoch_nr: 2, batch: 50/188, acc_train: 0.772, acc_test: 0.773
epoch_nr: 3, batch: 50/188, acc_train: 0.767, acc_test: 0.725
epoch_nr: 4, batch: 50/188, acc_train: 0.768, acc_test: 0.717
epoch_nr: 5, batch: 50/188, acc_train: 0.772, acc_test: 0.769
epoch_nr: 6, batch: 50/188, acc_train: 0.774, acc_test: 0.771
epoch_nr: 7, batch: 50/188, acc_train: 0.779, acc_test: 0.780

参考

https://github . com/artem-opper Mann/Restricted-Boltzmann-Machine/blob/master/readme . MD

深度学习模型训练循环

原文:https://towardsdatascience.com/deep-learning-model-training-loop-e41055a24b73?source=collection_archive---------8-----------------------

用 Python、PyTorch 和 TorchVision 实现一个简单的神经网络训练循环。

几个月前,我开始探索 py torch——一个奇妙且易于使用的深度学习框架。在的上一篇文章中,我描述了如何使用 MovieLens 数据集实现一个简单的推荐系统。这一次,我想把重点放在对任何机器学习管道都至关重要的主题上——训练循环。

PyTorch 框架为您提供了构建机器学习模型的所有基本工具。它给你 CUDA 驱动的张量计算,优化器,神经网络层,等等。然而,要训练一个模型,你需要把所有这些东西组装成一个数据处理管道。

最近开发人员发布了 PyTorch 的 1.0 版本,已经有很多很棒的解决方案帮助你训练模型,而不需要钻研张量和层的基本操作。(在下一节中简要讨论)。然而,我相信每隔一段时间,大多数软件工程师都有一种“从零开始”实现东西的强烈愿望,以更好地理解底层过程,并获得不依赖于特定实现或高级库的技能。

在接下来的部分中,我将展示如何使用torchtorchvision Python 包实现一个简单但有用的训练循环。

TL;DR: 请跟随这个链接直接进入资源库,在那里你可以找到这篇文章中讨论的源代码。此外,这里有一个到笔记本的链接,它包含了所有的实现,以及帖子中没有包含的其他信息,以使其简洁。

现成的解决方案

正如前面提到的,有一些构建在框架之上的高级包装器,它们极大地简化了模型训练过程。按照复杂性增加的顺序,从最简单到非常复杂:

  1. Ignite—py torch 的官方高级接口
  2. torch sample——一个类似 Keras 的包装器,带有回调、增强和方便的实用程序
  3. Skorch —一个 scikit-learn 兼容的神经网络库
  4. fastai —一个强大的端到端解决方案,以高精度和计算速度训练各种复杂性的深度学习模型

高级库的主要好处是,不用编写定制的实用程序和包装程序来读取和准备数据,人们可以专注于数据探索过程本身——不需要在代码中寻找错误,辛勤工作的维护人员可以改进库,并在您有问题时随时提供帮助。不需要实现定制的数据扩充工具或训练参数调度,一切都已经在这里。

如果您正在开发生产就绪的代码,或者参加数据科学竞赛并需要搜索最佳模型,而不是坐在调试器前试图找出这个内存错误的来源,那么使用维护良好的库无疑是一个选择。如果您正在学习新的主题,并且希望更快地获得一些工作解决方案,而不是花费许多天(或几周)来编写 ResNets 层和编写 SGD 优化器,情况也是如此。

然而,如果你像我一样,那么有一天你会想测试你的知识,用更少的抽象层来构建一些东西。如果是这样,让我们进入下一部分,开始重新发明轮子!

核心实现

训练循环的最基本实现并不困难。 pytorch 包已经包含了允许实例化数据集访问器和迭代器的便利类。所以本质上,我们需要做一些如下面代码片段所示的事情。

我们可以停止对这一部分的讨论,节省一些时间。然而,通常我们需要的不仅仅是简单的损失计算和更新模型权重。首先,我们希望使用各种性能指标来跟踪进展。第二,初始设置的优化器参数应该在训练过程中被调整以改善收敛性。

一种简单的方法是修改循环代码,使其包含所有这些附加特性。唯一的问题是,随着时间的推移,我们可能会因为添加越来越多的技巧而失去实现的清晰性,引入回归错误,并最终得到杂乱无章的代码。我们如何在代码的简单性和可维护性以及训练过程的效率之间找到一个折衷?

附加物

答案是使用软件设计模式。观察者是面向对象语言中众所周知的设计模式。它允许将一个复杂的系统分解成更容易维护的片段。我们不试图将所有可能的特性封装到一个类或函数中,而是将调用委托给从属模块。每个模块负责对收到的通知做出适当的反应。如果消息是发给其他人的,它也可以忽略通知。

该模式有不同的名称,反映了实现的各种特性:观察器、事件/信号调度器、回调。在我们的例子中,我们使用回调,这种方法在 Keras 和(特别是) fastai 库中有所体现。 ignite 包的作者采用的解决方案有点不同,但本质上,它归结为相同的想法。看看下面这张图。它显示了我们改进的训练循环的图解组织。

每个彩色部分是委托给回调组的一系列方法调用。每个回调都有类似epoch_startedbatch_started等方法,通常只实现其中的几个。例如,考虑损失度量计算回调。它不关心向后传播之前运行的方法,但是一旦收到batch_ended通知,它就会计算一个批处理丢失。

下一个片段展示了这个想法的 Python 实现。

仅此而已,并不比原始版本复杂多少,对吗?它仍然干净简洁,但功能更多。现在训练算法的复杂度完全由委托调用决定。

回调示例

我们可以实现许多有用的回调(参见 keras.io 和 docs.fast.ai 获取灵感)。为了保持文章的简洁,我们将只描述其中的几个,并将其余的几个移到 Jupyter 笔记本中。

失败

当谈论机器学习模型训练时,首先想到的是损失函数。我们用它来指导优化过程,并希望看到它在培训过程中如何变化。因此,让我们实现一个回调来跟踪这个指标。

在每一批结束时,我们计算一个运行损失。计算可能看起来有点复杂,但主要目的是平滑损失曲线,否则会很颠簸。公式a*x + (1 — a)*y 是新旧值之间的一个线性插值。

Geometric interpretation of linear interpolation between vectors A and B

分母有助于我们计算开始时的偏差。查看这篇文章详细描述了平滑损失计算公式。

准确(性)

accuracy指标可能是机器学习中最著名的指标之一。虽然在很多情况下它不能给你一个好的模型质量评估,但是它非常直观,易于理解和实现。

请注意,回调在每批结束时以及训练时期结束时接收通知。它迭代地计算精度度量,因为否则,我们将需要在整个训练时期将输出和目标保存在存储器中。

由于我们计算的这种迭代性质,我们需要批量计算大量样本。我们使用该值在该时期结束时调整我们的计算。实际上,我们正在使用下图所示的公式。

其中 b(i) 是迭代 i 时的批量大小,a(i) — 根据批量 b(i)N 计算的准确度—样本总数。如最后一个公式所示,我们的代码计算出一个精确度的样本均值。查看这些有用的参考资料,了解有关迭代指标计算的更多信息:

  1. 指标作为来自 fastai 的回调
  2. 准确度度量来自点火

参数调度程序

现在最有趣的事情来了。现代神经网络训练算法不使用固定的学习速率。最近的论文(一篇、两篇和三篇)显示了一种调整深度学习模型训练参数的受过教育的方法。其思想是使用循环调度器,在单个或几个训练时期调整模型的优化器参数幅度。此外,这些调度程序不仅会随着处理批次数量的增加而降低学习率,还会在一定数量的步骤内或周期性地增加学习率。

例如,考虑以下函数,它是经过缩放和移位的余弦函数:

Half-period of shifted and scaled cosine function

如果我们重复这个函数几次,使其周期加倍,我们将得到一个余弦退火调度程序,如下图所示。

Cosine annealing with restarts scheduler

将优化器的学习率乘以这个函数值,我们有效地获得了一个随机梯度,它允许我们从局部极小值中逃脱。下面的片段显示了如何实现余弦退火学习率。

还有一个更令人兴奋的调度器,叫做单周期策略。该时间表的想法是在整个训练过程中使用单周期的学习率递增-递减*,如下图所示。*

One-cycle policy scheduler

在训练过程的最开始,模型权重不是最优的,因此我们可以允许自己使用更大的更新步长(即,更高的学习率),而没有错过最优值的风险。经过几个训练时期后,权重变得越来越好,越来越适合我们的数据集,所以我们放慢了学习速度,更仔细地探索学习表面。

如果我们使用前面显示的类,单周期策略有一个非常简单的实现。我们只需要在余弦衰减之前添加一个线性段,如线27-30所示。

最后一步是用回调接口包装调度程序。为了使这篇文章简洁易读,这里没有给出实现的例子。然而,你可以在前面提到的Jupyter 笔记本中找到完整的功能代码。

流记录器

我们想添加的最后一件事是一些日志记录,以查看我们的模型在训练过程中的表现如何。最简单的方法是将统计数据打印到标准输出流中。然而,你可以把它保存成 CSV 文件,甚至把它作为通知发送到你的手机。

好了,最后,我们准备开始使用我们的训练循环!

你最喜欢的数据集

现在,当试听准备就绪,是时候展示我们的训练循环是如何工作的了。为此,让我们选择无处不在的 MNIST 数据集。你甚至可以在几分钟内在 CPU 上轻松训练它。

数据集对于现代深度学习架构和算法来说非常简单。因此,我们可以使用相对较浅的架构,有几个卷积和线性层。

我们这里不使用迁移学习,但是你在日常工作中绝对应该使用。与从头开始的训练相比,它使你的网络收敛得更快。

接下来,我们使用torchvision包来简化数据集加载和迭代。此外,我们还应用了一些增强方法来提高模型的质量。然后,我们建立了一个回调组,它向我们的基本训练循环添加了一些特性。最后,我们做了一些小的准备工作,并调用训练函数来优化模型。

您应该会得到类似如下所示的输出。

Epoch:    1 | train_loss=0.8907, train_accuracy=0.6387, valid_loss=0.1027, valid_accuracy=0.9695Epoch:    2 | train_loss=0.4990, train_accuracy=0.8822, valid_loss=0.0828, valid_accuracy=0.9794Epoch:    3 | train_loss=0.3639, train_accuracy=0.9086, valid_loss=0.0723, valid_accuracy=0.9823

注意,上面显示的代码包括这里没有显示的make_phases() 功能。请参考笔记本查看其实现。本质上,它用瘦结构包装数据加载器,有助于在模型训练期间跟踪性能指标。

结论

深度学习工程师的最终目标是为特定的数据集和任务建立一个健壮而准确的解决方案。实现这一目标的最佳方式是使用世界各地的用户在许多用例中测试过的经过验证的工具和维护良好的框架和库。

然而,如果你想精通数据科学并最终构建你的定制解决方案,你可能“应该了解 backprop ”。充分了解您的工具使您能够根据您的特定需求定制它们,添加新功能并更快地学习新工具。

我相信,在使用经过验证的 API 和理解“低级”细节之间保持平衡,可以让你成为一名更好的工程师,可以轻松地将获得的知识转移到新的平台、语言和接口上。

对 Python 语言感兴趣?离不开机器学习?看过网上的其他东西吗?

那么你可能会对我的博客 感兴趣,我的博客 在这里我谈论了各种编程话题,并提供了我感兴趣的教科书和指南的链接。

基于深度学习的自动驾驶车辆和高级驾驶员辅助系统的对象分类模型

原文:https://towardsdatascience.com/deep-learning-object-classification-models-for-autonomous-vehicles-and-advanced-driver-assist-e4355802e684?source=collection_archive---------11-----------------------

基于 Python 的对象分类模型,使用 tensorflow 在自制数据集上进行训练,并部署在嵌入式计算平台上,用于向驾驶员实时传输数据

Figures: Artistic rendition of an autonomous vehicle’s object detection system versus our algorithm working in real-time

专用对象检测系统需要快速、准确,并且专用于对少数但相关数量的对象进行分类。我们的目标是集成一个系统,该系统利用 Inception 庞大的启发式映射图像预测树,以及一个实时系统,该系统足够精确和健壮,能够在各种处理能力下工作,并给用户足够的信心用单个帧识别和检测对象。由于这种特性可以在大量依赖实时检测的地方使用,它可能不仅限于驾驶辅助或自动驾驶系统,而是超出了本项目的范围。

为了提出一种新颖的数据集,该数据集将具有具有足够权重和多样性的图像树,以便以高准确度和精确度预测被识别的对象,该数据集被用来建立 softmax 层的初始状态,该初始状态先前被现有的 ImageNet 数据集加权。结果是令人信服的识别准确性和预测的信心与实时测试帧的视频。随着自动驾驶汽车的出现,人们也越来越担心行人的安全。这也已经使用实时单帧行人识别器以令人满意的准确度解决了。通过我们的算法,我们打算在这一领域做出重大贡献,因为我们提出了一种集成了物体检测和安全的驾驶员辅助系统,这有助于提高道路安全,并有助于满足车辆中自动和智能驾驶员辅助系统领域不断增长的需求。

Figure : How a basic deep neural network performs weight distribution and classification of images

Figure: Inception v3 architechture that is utilized here for training classifier

在我们的工作中,我们提出了一个算法,可用于创建一个智能驾驶辅助系统。该算法分两个阶段实现,以下部分将描述该算法每个阶段的实现。该项目还延伸到一个描述自主安全和监控系统的子部分,该系统包括一个用于识别车辆类型的车辆分类器,以及一个用于捕获和存储车辆注册号码的车牌识别系统。它还有一个部分专门描述我们的实时对象检测系统,该系统用于识别每个视频帧中常见的路上对象。

之前的相关工作

Figure : Accuracy performance of various object classification models

当前关于实时对象检测和跟踪的工作涉及使用传统的特征提取算法,如 SURF 和背景减法,以便识别运动对象。但是我们的算法使用了一个更有效的物体检测系统,名为 YOLO,它比 SURF 有明显的优势。SURF 是一种可变形零件模型(DPM ),因为它采用滑动窗口来执行对象检测。DPM 使用不相交的管道来提取特征、对区域进行分类以及预测高分区域的边界框等。使用 YOLO,这些不同的部分被执行特征提取、边界框预测等任务的单个卷积神经网络代替。,并发。这导致更快和更准确的对象检测系统。车辆检测和识别是一个重要的,但具有挑战性的任务,因为车辆图像是扭曲的,并受到多种因素的影响。几种车辆检测算法主要将任何车辆分类为汽车或其他。他们还采用传统的分类算法,如 SVM,并使用滑动窗口技术进行特征提取。一些研究人员还研究了使用正面车辆图像的车辆标志检测和识别,以获取将揭示车辆制造商的信息。但是这并不总是提供足够的功能来满足用户的需求。

Figure : New dataset of cars created in order to tune the max pooling layer weights of Inception v3 model

另一方面,我们的系统能够将任何车辆分为三类,即 SUV、轿车和小型车。这是通过创建印度道路上 750 幅车辆图像的数据集来实现的,这使得将该系统集成到现有车辆中变得更加简单。此外,我们的系统采用 CNN 进行分类,这使得它成为一个更快和更有效的系统。一些系统还采用雷达来执行目标检测。

然而,雷达也有自己的缺点。当大型车辆过于靠近雷达系统时,雷达接收器可能会饱和。此外,与计算机视觉算法相比,雷达系统速度较慢,因为它们最多需要 2 秒钟才能锁定。因此,我们的系统采用计算机视觉来检测和跟踪车辆。驾驶辅助系统在过去几年中获得了巨大的欢迎,这主要是由于谷歌和特斯拉等公司所做的出色工作。这些公司是电子自动驾驶汽车领域的主要贡献者,这些汽车采用计算机视觉技术进行物体检测、识别和跟踪,并采用激光雷达技术在低能见度条件下工作。

通过我们的算法,我们打算在这个新的和创新的研究领域做出重大贡献。我们的驾驶员辅助系统集成了用于自动驾驶功能的物体检测和用于改善道路安全的安全性。

Figure : Cross-entropy and weights output graphs versus epochs for the trained model

我们即将推出另一个部分,用一个集成了物体探测器的自动车牌识别系统来扩展这个项目。正如我们在一些交通事故数据中研究的那样,这在紧急情况下可能是至关重要的。

Figure : Number plate text recognition capabilities integrated with the program

如需了解更多信息,请随时前往关于自动驾驶汽车的链接和更多有趣的项目以及同一项目的github 回购。

此外,训练目标识别模型并将其转移到 Raspberry-pi 模块,以利用远程目标检测。虽然 R-pi 响应不是实时的(大约 71 秒检测一帧中的对象),但它可以通过更好的板载计算能力来提高。

Figure : YOLO v3 object detection system trained and deployed on a Raspberry-pi embedded module

该项目的另一个版本计划使用 NVIDIA Jetson tx2 嵌入式 GPU,以便在没有远程高级驾驶辅助系统所需的连接性的情况下具有边缘功能。

Getting to play with this cool thing for the upcoming projects on autonomous driving based on intelligent cameras and object detection !

此外,这是我的 youtube 教程视频,用于安装和启动带有外围设备和摄像头模块的 Nvidia Jetson tx2 套件:

希望你们喜欢并评论,你们的反馈很有价值!

汽车模拟器上的深度学习

原文:https://towardsdatascience.com/deep-learning-on-car-simulator-ff5d105744aa?source=collection_archive---------6-----------------------

这个项目的代码可以在: Github 上找到。
这篇文章也可以在我的网站这里找到。

在 udacity 自动驾驶汽车工程师课程的第三个项目中,我使用了课程组织者提供的汽车模拟器来收集预期驾驶行为的数据,然后使用这些数据来训练深度学习 CNN 模型( NVIDIA 卷积神经网络架构)在模拟环境中驾驶汽车。

该项目包括以下几个阶段:

  1. 通过在模拟器周围驾驶汽车来收集训练数据。
  2. 实现 NVIDIA 神经网络。
  3. 训练和测试模型性能。

收集培训数据

模拟器可以在两种模式下运行:训练模式和自主模式。

在训练模式中,用户使用转向角、油门和刹车来控制汽车的移动。你可以用键盘或鼠标控制汽车。在训练模式下,你可以点击记录键,模拟器将开始保存驾驶数据到一个特定的位置。行驶数据包括来自汽车左、右和前摄像机(160x320x3 尺寸)的每幅图像,以及相应的转向、油门和刹车测量值。

Figure 1. Left: center lane driving on simulator. Right: record mode in simulator.

为了收集训练数据,汽车在训练模式下使用中心车道驾驶行为绕赛道行驶两圈。然后,通过在弯道周围的选择性驾驶行为进一步加强数据,以解决转向过度和转向不足的问题,这使得模型能够学习在这些弯道周围行驶所需的更大转向角度。

从训练运行中总共收集了 7,098 个数据点。通过水平翻转图像并找到转向角的附加倒数来执行进一步的增强。扩充后,数据点的总数增加了一倍,达到 14,196 点。

Figure 2. Left: view from right side camera. Right: flipped image.

实施 NVIDIA 神经网络

对于这个项目,使用了 Keras 深度学习库。

作为初始模型,我实现了一个只有一个卷积层和一个密集连接层的神经网络。转向角是作为模型输出的唯一测量值;油门和制动测量的增加增加了驾驶行为的噪音。这种基本模型能够在赛道的直道段保持汽车在道路上行驶,但无法在弯道处正确驾驶汽车。

为了改进我的解决方案,我决定使用他们的开发者博客上描述的 NVIDIA 神经网络架构。引自他们的文章:

在一项新的汽车应用中,我们使用卷积神经网络(CNN)将来自前置摄像头的原始像素映射到自动驾驶汽车的转向命令。这种强大的端到端方法意味着,通过最少的人类训练数据,系统可以在当地道路和高速公路上学习驾驶,无论有没有车道标志。

以下是取自他们博客的 NVIDIA 神经网络架构图:

Figure 3. NVIDIA’s CNN Architecture (source: link)

上面的 NVIDIA 神经网络由 9 层组成:1 个归一化层,5 个卷积层,3 个全连接层。

我对 CNN 的实现略有不同,我总共有 12 层:1 个裁剪层,1 个归一化层,4 个卷积层,3 个分离层,3 个全连接层。

裁剪图层被用来移除场景(树、水等)..)从输入数据中提取,以便模型可以关注道路特征。输入图像从顶部裁剪 70 像素,从底部裁剪 25 像素。此外,根据多伦多大学研究员 Nitish Srivastava 题为 dropout:一种防止神经网络过度拟合的简单方法的论文的建议,添加了 Dropout 层以减少过度拟合。

下面是每一层的详细描述:

Figure 4. Description of layers used in neural network.

而下面是以上各层在 Keras 中的代码实现:

培训和测试性能

训练数据被拆分,80%的数据用于训练,20%的数据用于验证。数据在分割前被打乱。所用的性能指标是均方误差损失,目的是尽可能将其最小化。

经过实验,我发现训练模型的理想时期数是 5 个时期,大于 10 个时期会过度拟合模型。

使用 adam 优化器对模型进行拟合,因此不必手动调整学习速率。

下图显示了每个历元的训练集和验证集的均方误差损失:

Figure 5. model mean squared error loss for deep learning model.

正如预期的那样,训练集和验证集的均方误差损失随着模型被训练的次数(时期)而降低。

在训练过程结束时,该模型能够在不离开道路的情况下,在赛道上自主驾驶车辆。以下是模型运行的视频:

数字海洋堆栈上的深度学习?还没有

原文:https://towardsdatascience.com/deep-learning-on-the-digitalocean-stack-not-quite-yet-5c408e7d1a41?source=collection_archive---------3-----------------------

所以你想要一个更便宜的解决方案来运行你的深度学习代码。AWS 每月给你大约 1K 的账单,但你的业务逻辑真的需要深度学习的魔力。更糟糕的是,你不能仅仅调用一个 API 就让它消失。不,不。你处理的数据太多了。但是你喜欢云。你想待在云中。让我们一起踏上尝试新事物的旅程。

Docker 是一种虚拟化(特别是容器化)技术。docker 上有很多很棒的程序可以运行。非常棒,但是记住 DigitalOcean 仍然没有 GPU 支持,所以在这些容器中的机器学习将会非常慢。

也许如果我们在一个高 CPU 水滴上运行我们的深度学习代码,性能会足够好,价格会更低?我记得看过一篇文章,说 DigitalOcean CPU 实例在一些工作负载上可以在成本和性能上打败 AWS。也许是 word 嵌入模型工作得很好。我记不清了,也找不到文章了…那我们去了解一下吧!科学!

首先让我们看看成本。今天(2017 年 8 月 10 日)AWS 上的一个 p2.xlarge 费用为 0.900 美元/小时。它拥有惊人的 K80 GPU。DigitalOcean 中的 32 CPU“高 CPU”水滴费用为 0.952 美元/小时。这台机器有 48 GB 内存,适合我们想要的任何单词嵌入模型。系统也有 SSD。事实上,数字海洋只是固态硬盘。我喜欢它。让我们在两个平台上运行诗人的 TensorFlow,看看我们在执行时间方面的表现如何。

DigitalOcean droplet 是从 Docker 的一次点击安装开始的。这加速了张量流设置。当它旋转起来的时候,跑上去就很有趣,感觉所有这些 CPU 的原始力量就像某种自大狂巫师一样。好的。回去工作。TensorFlow 安装在 Docker 上又快又好。“你好,世界!”验证脚本有效。

在指令中,我们跳过了“我赶时间”这一部分,因为我们真的想处理一些数字。瓶颈文件的创建速度比在 p2 实例上慢一些。我可以告诉你,我过去经常这么做。结果将是不可思议的。让我们通过运行来量化:

time python retrain.py  \   
--bottleneck_dir=bottlenecks   \ 
--how_many_training_steps=500    \
--model_dir=inception    \
--summaries_dir=training_summaries/basic  \  
--output_graph=retrained_graph.pb    \
--output_labels=retrained_labels.txt    \
--image_dir=flower_photos

高 CPU DigitalOcean 虚拟机上的结果是:

2017-08-11 00:01:07.773065: Step 480: Train accuracy = 92.0%
2017-08-11 00:01:07.773155: Step 480: Cross entropy = 0.345928
2017-08-11 00:01:07.825522: Step 480: Validation accuracy = 88.0% (N=100)
2017-08-11 00:01:08.424932: Step 490: Train accuracy = 91.0%
2017-08-11 00:01:08.425017: Step 490: Cross entropy = 0.354291
2017-08-11 00:01:08.477905: Step 490: Validation accuracy = 90.0% (N=100)
2017-08-11 00:01:09.032948: Step 499: Train accuracy = 94.0%
2017-08-11 00:01:09.033039: Step 499: Cross entropy = 0.262198
2017-08-11 00:01:09.084237: Step 499: Validation accuracy = 90.0% (N=100)
Final test accuracy = 89.8% (N=353)
Converted 2 variables to const ops.**real    6m42.118s**
user    86m49.452s
sys     30m17.000s

因此,在不到 7 分钟的时间内(6*60+42 = 360+42 = 402 秒),我们生成了重新训练 CNN 最后一层的瓶颈文件,以获得大约 90%的分类准确率。

让我们在 AWS 上运行同样的测试。在 AWS 上用 p2 在 Docker 之外运行要快得多。对于相同的命令和相同的数据集,我得到了以下时间:

2017-08-11 00:02:32.848994: Step 480: Train accuracy = 94.0%
2017-08-11 00:02:32.849077: Step 480: Cross entropy = 0.273793
2017-08-11 00:02:32.907405: Step 480: Validation accuracy = 85.0% (N=100)
2017-08-11 00:02:34.094489: Step 490: Train accuracy = 87.0%
2017-08-11 00:02:34.094567: Step 490: Cross entropy = 0.433323
2017-08-11 00:02:34.153172: Step 490: Validation accuracy = 88.0% (N=100)
2017-08-11 00:02:34.694696: Step 499: Train accuracy = 90.0%
2017-08-11 00:02:34.694771: Step 499: Cross entropy = 0.370968
2017-08-11 00:02:34.753167: Step 499: Validation accuracy = 94.0% (N=100)
Final test accuracy = 89.8% (N=353)
Converted 2 variables to const ops.**real    4m10.831s**
user    3m27.290s
sys     0m29.820s

相同的结果,但只是超过 4 分钟,而不是不到 7 分钟(4*60+11 = 240+11 = 251)。考虑到 DigitalOcean droplet 每小时比 AWS 实例贵一点,我认为这里有一个明显的赢家。AWS 的加速比是的 1.6 倍(402/251),而的成本减少了 5.7%(0.952 比 0.900)。坚持用 AWS 做你的 CNN 工作,把数字海洋水滴留给非 GPU /更小的东西。

坚持住!我找到文章了!

[## 云 CPU 上的 TensorFlow 基准测试:比云 GPU 更便宜的深度学习

我一直在与 Keras 和 TensorFlow 合作几个个人深度学习项目。然而,培训模式的深度…

minimaxir.com](http://minimaxir.com/2017/07/cpu-or-gpu/)

那为什么他们说牛逼我说扯淡?让我们开始吧!

  1. 本文作者 Max Woolf 从源代码中编译了 tensorflow,以利用 AVX 和 SSE 指令。懒惰的我,我没有那样做。接得好。
  2. 他的工作量是 MLP 的 MNIST 分类,然后是 CNN,还有其他东西,而我的工作量是《盗梦空间 v3》的 CNN。
  3. 总的来说,他有点同意我的结果,CPU 在运行时间方面与 GPU 不匹配。他运行的每一个 CPU 测试都比 GPU 慢。
  4. 对于成本比较,我们不同意。他使用了谷歌的超级 CPU 怪兽,定价为 0.509 美元/小时,GPU 定价为 0.745 美元/小时。这远远低于 DigitalOcean 的高 CPU 0.952 美元/小时和 AWS 的 p2 实例 0.900 美元/小时。平心而论,我们可以将我们的 p2 降级为 g 2.2x 大,并从那里继续下滑,而不是尖叫着跑到数字海洋。是的,给谷歌云平台一个旋转。关于 GCP 的单位工作成本,马克斯说得很有道理。

所以,最后我们都是对的。你可以在 CPU 上做 ML,但是要确保它确实能为你省钱,因为它肯定不会为你节省任何时间。

希望这对于正在考虑更便宜的机器学习选项的解决方案架构师来说是一个很好的比较。如果你喜欢这篇文章,那么请推荐它,分享它,或者给它一些爱(❤).

编码快乐!

-丹尼尔
丹尼尔@lemay.ai ←打个招呼。
LEMAY . AI
1(855)LEMAY-AI

您可能喜欢的其他文章:

  • 人工智能和不良数据
  • 人工智能:超参数
  • 人工智能:让你的用户给你的数据贴上标签

边缘的深度学习

原文:https://towardsdatascience.com/deep-learning-on-the-edge-9181693f466c?source=collection_archive---------5-----------------------

在移动和边缘设备上执行深度学习的概述。

Photo by Alexandre Debiève on Unsplash

可扩展的深度学习服务取决于几个约束。根据您的目标应用,您可能需要低延迟、增强的安全性或长期成本效益。在这种情况下,将深度学习模型托管在云上可能不是最佳解决方案。

Computing on the Edge (Source)

边缘深度学习缓解了上述问题,并提供了其他好处。这里的 Edge 指的是在消费者的产品上本地执行的计算。这篇博客探讨了使用边缘计算进行深度学习的好处,以及与之相关的问题

为什么是 edge?为什么不用云呢?

有太多令人信服的理由支持边缘计算而不是云计算。

1.带宽和延迟

毫无疑问,对远程服务器的 API 调用有一个有形的往返时间(RTT)。要求近乎即时推断的应用程序无法在这种延迟下正常运行。

Latency and Power consumption stats for Object Detection (DET), Tracking (TRA) and Localization (LOC) on four different edge devices (Source)

自动驾驶汽车为例。足够大的潜伏期会显著增加事故的风险。此外,意外事件,如动物穿越或 jay walking 可能发生在短短几帧。在这些情况下,响应时间极其重要。这就是为什么 Nvidia 让他们定制的板载计算设备在边缘执行推理。

此外,当大量设备连接到同一个网络时,有效带宽会减少。这是因为使用通信信道的固有竞争。如果在边缘上进行计算,这可以显著减少。

Bandwidth requirement for various applications. (Source)

以在多台设备上处理 4K 高清视频为例。在本地处理它们将大大节省带宽的使用。这是因为我们不需要将数据上传到云中进行推断。因此,我们可以相对容易地扩展这个网络。

2.安全和权力下放

商业服务器容易受到攻击和黑客攻击。当然,如果您使用可信的供应商,风险可以忽略不计。但是,为了您收集的数据和您的知识产权(IP)的安全,您需要信任第三方。边缘设备让你对你的 IP 拥有绝对的控制权。

Centralized vs Decentralized vs Distributed. (Source)

如果你听说过区块链,你可能对分权或分配很熟悉。尽管如此,在边缘拥有几个设备可以获得去中心化的所有好处。使用单一 DDoS 攻击来摧毁整个隐藏设备网络比中央服务器更难。这对于使用无人机进行边境巡逻等应用尤其有用。

3.特定于工作的用途(定制)

想象一下,你有一个生产玩具的工厂。它有几百个工作站。每个工作站都需要图像分类服务。问题是,每个工作站都有一组不同的对象,训练单个分类器可能是无效的。此外,在上托管多分类器将会昂贵

成本有效的解决方案是训练针对云上每个部分的分类器,并将训练的模型运送到边缘设备。现在,这些设备是为他们的工作站定制的。它们将比在所有工作站上预测的分类器具有更好的性能。

4.群体智能

继续上面提到的想法,边缘设备也可以帮助训练机器学习模型。这对于强化学习特别有用,你可以在并行中模拟大量的“情节”。

Multiple agents trying to grasp objects. (Source)

此外,边缘设备可用于收集数据,用于在线学习(或继续学习)。例如,我们可以使用多架无人机来勘测一个区域进行分类。使用诸如异步 SGD 之类的优化技术,可以在所有边缘设备中并行训练单个模型。它也可以仅仅用于聚集和处理来自各种来源的数据。

5.裁员

冗余对于强健的内存和网络架构极其重要。网络中一个节点的故障会对其他节点产生严重影响。在我们的例子中,边缘设备可以提供很好的冗余度。如果我们的一个边缘设备(这里是一个节点)发生故障,它的邻居可以暂时接管。这极大地确保了可靠性,并大大减少了停机时间。

6.从长远来看,成本效益高

从长远来看,云服务将比拥有一套专用的推理设备更加昂贵。如果您的设备具有较大的占空比(也就是说,它们大部分时间都在工作),这一点尤其正确。此外,如果批量生产,边缘设备会便宜得多,从而显著降低成本。

边缘深度学习的限制

深度学习模型以计算昂贵而闻名。将这些模型安装到通常具有节省内存的边缘设备中是一个挑战。有许多方法可以解决这些问题。

1.参数有效的神经网络

神经网络的一个显著特征是其庞大的规模。边缘设备通常不能处理大型神经网络。这促使研究人员在保持准确性的同时,最小化神经网络的规模。两种流行的参数高效神经网络是 MobileNet 和 SqueezeNet 。

SqueezeNet 采用了许多策略,如后期下采样和滤波器数量减少,以在低参数数量下获得高性能。他们引入了具有“挤压”和“扩展”层的“点火模块”,优化了网络的参数效率。

Fire module in the SqueezeNet. (Source)

MobileNet 将普通卷积分解为深度方向卷积和 1x1 卷积的组合。这种安排大大减少了所涉及的参数数量。

Top 1 accuracy in the ImageNet dataset with respect to number of Multiply-Accumulates (MACs). (Source)

2.修剪和截断

经过训练的网络中的大量神经元是良性的,对最终的准确性没有贡献。在这种情况下,我们可以修剪这样的神经元来节省一些空间。谷歌的 Learn2Compress 发现,我们可以通过因子 2 获得大小 缩减,同时保留 97%的准确率。

而且,大多数神经网络参数都是 32 位浮点值。另一方面,边缘设备可以被设计为在 8 位值或更少的值上工作。降低精度可以显著减小模型大小。例如,将 32 位型号减少到 8 位型号理想情况下会将型号大小减少到的 4 倍

3.蒸馏

蒸馏是使用更大的“教师”网络来教授更小的网络的过程。谷歌的 Learn2Compress 在他们的尺寸缩减过程中融入了这一点。结合迁移学习,这成为一种在不损失太多准确性的情况下减少模型大小的强大方法。

Joint training and distillation approach to learn compact student models. (Source)

4.优化的微处理器设计

到目前为止,我们已经讨论了缩小神经网络以适应我们的边缘设备的方法。一种替代(或补充)方法是提升微处理器的性能。

最简单的解决方案是在微处理器上安装 GPU,比如广受欢迎的 Nvidia Jetson T1。然而,当大规模部署时,这些设备可能不具有成本效益。

Nvidia Jetson (Source)

一个更有趣的解决方案是使用视觉处理单元(vpu)。英特尔声称他们的 Movidius VPUs 具有“超低功耗的高速性能”。谷歌的 AIY 套件和英特尔的神经计算棒内部使用这种 VPU。

Google AIY’s Vision Bonnet using a Movidius VPU. (Source)

或者,我们可以使用 FPGAs。它们比 GPU 具有更低功耗,且可以适应更低位(< 32 位)的架构。然而,由于其较低的 FLOPs 等级,与 GPU 相比,性能可能会略有下降。

对于大规模部署,定制 ASICs 将是最佳解决方案。制造类似 Nvidia V100 的微架构来加速矩阵乘法可以大大提高性能。

Pascal vs Volta architecture; Nvidia. (Source)

深度学习性能备忘单

原文:https://towardsdatascience.com/deep-learning-performance-cheat-sheet-21374b9c4f45?source=collection_archive---------5-----------------------

简单和复杂的技巧可以帮助您提高深度学习模型的准确性

我从新的和有经验的机器学习工程师那里得到最多的问题是“我如何才能获得更高的准确性?”

很有意义,因为机器学习对商业最有价值的部分通常是它的预测能力。提高预测的准确性是从现有系统中获取更多价值的简单方法。

该指南将分为四个不同的部分,每个部分都有一些策略。

  • 数据优化
  • 算法调整
  • 超参数优化
  • 全体,全体,全体

并不是所有的这些想法都会提高性能,你将会看到你对同样的问题应用的越多,回报就越有限。试了几个之后还是卡住了?这表明你应该重新思考你的业务问题的核心解决方案。这篇文章只是一个备忘单,所以我将在每一节中为您链接更详细的信息来源。

数据优化

平衡您的数据集

对于表现不佳的深度学习模型,提高性能的最简单方法之一是平衡数据集,如果你的问题是分类。现实世界的数据集往往是倾斜的,如果你想要最好的准确性,你就希望你的深度学习系统学习如何根据特征在两个类别之间进行选择,而不是通过复制其分布

常见的方法包括:

  • **二次抽样多数类:**您可以通过二次抽样多数类来平衡类分布。
  • **过采样少数民族:**替换采样可以用来增加你的少数民族比例。

这里有一篇很好的文章,更详细地介绍了这个问题

更多数据

我们很多人都熟悉这个图表。它显示了深度学习和经典机器学习方法的数据量和性能之间的关系。如果你不熟悉这个图表,那么这个教训是清楚而直接的。如果您希望模型具有更好的性能,则需要更多的数据。根据您的预算,您可能会选择创建更多的标记数据或收集更多的未标记数据,并更多地训练您的特征提取子模型。

开源贴标软件

  • 图片
  • 音频
  • 视频

生成更多数据

或者假装,直到你成功。一个经常被忽视的提高准确性的方法是从你已经有的数据中创建新的数据。以照片为例;工程师通常会通过旋转和随机移动现有图像来创建更多图像。这种变换还增加了训练集的减少的过拟合。

为图像问题创建更多数据的优秀资源

算法调整

复制研究人员

你正在解决一个背后有大量研究的问题吗?你很幸运,因为 100 个工程师可能已经对如何获得这个问题的最佳精度进行了大量思考。

阅读一些关于这个主题的研究论文,记下他们用来获得结果的不同方法!他们甚至可能有一个代码的 git-hub 供您使用。

谷歌学术是开始搜索的绝佳地点。他们还提供许多工具来帮助你找到相关的研究。

对于研究论文的存储和组织,我使用门德利

接收每周人工智能研究论文,资源和趋势。免费订阅 AI 书生

算法抽查

不要让你的自负战胜你。不可能知道哪种机器学习算法最适合你的问题。每当我着手解决一个新问题时,在没有太多研究的情况下,我会寻找一些可用的方法,并尝试所有的方法。深度学习(CNN 的,RNN 的等等。)和经典的机器学习方法(随机森林、梯度推进等)。)

对你所有实验的结果进行排序,对表现最好的算法加倍下注。

看看选择机器学习算法的数据驱动方法

超参数优化

学习率

亚当优化算法是可靠的。经常在所有深度学习问题上给出惊人的结果。即使它有极好的性能,它仍然会使你陷入问题的局部最小值。一个更好的算法是带热重启的随机梯度下降,它具有 Adam 的优点,有助于消除陷入局部最小值的机会。

这里有关于学习率的精彩报道

批次大小和时期数

一个标准的程序是对现代深度学习实现使用具有大量时期的大批量大小,但是共同的策略产生共同的结果。试验你的批次的大小和训练时期的数量。

提前停止

这是减少你的深度学习系统的泛化错误的一个极好的方法。持续训练可能会提高数据集的准确性,但在某个点上,它会开始降低模型对模型尚未看到的数据的准确性。要提高实际性能,请尝试提前停止。

提前停车的例子

网络体系结构

如果你想尝试一些更有趣的东西,你可以试试高效神经架构搜索(ENAS) 。该算法将创建一个定制的网络设计,最大限度地提高数据集的准确性,并且比 cloud ML 使用的标准神经架构搜索更有效。

正规化

停止过度拟合的一个健壮方法是使用正则化。

有几种不同的方法来使用正则化,你可以在你的深度学习项目中进行训练。如果你还没有尝试过这些方法,我会开始把它们包含在你做的每个项目中。

  • 辍学 : 他们在训练过程中随机关闭一定比例的神经元。辍学有助于防止神经元群体过度适应自己。
  • 重量惩罚 L1 和 L2: 重量爆炸式增长可能是深度学习中的一个真正问题,并降低准确性。解决这个问题的一个方法是给所有的权重增加衰减。这些方法试图使网络中的所有权重尽可能小,除非有大的梯度来抵消它。除了经常提高性能之外,它还有使模型更容易解释的好处。

全体,全体,全体

在选择最佳型号时遇到困难?通常,您可以组合不同模型的输出,从而获得更高的准确性。每种算法都有两个步骤。

  • 在原始数据的子集上产生简单 ML 模型的分布
  • 将分布组合成一个“聚合”模型

组合模型/视图(Bagging)

在这种方法中,您对相同的数据训练几个不同的模型,这些模型在某些方面是不同的,然后对输出进行平均以创建最终输出。

装袋具有减少模型中方差的效果。你可以直观地把它想成是让不同背景的多个人思考同一个问题,但出发点不同。就像在团队中一样,这可能是获得正确答案的有力工具。

堆叠

这类似于装袋,不同的是,你没有一个综合产量的经验公式。您创建了一个元级学习器,它基于输入数据选择如何权衡来自不同模型的答案,以产生最终输出。

还是有问题吗?

重构你的问题

停下来看看你的屏幕,喝杯咖啡。这个解决方案就是从头开始重新思考你的问题。我发现坐下来集思广益,找出解决问题的不同方法会有所帮助。也许从问自己一些简单的问题开始:

  • 我的分类问题会变成回归问题还是反过来?
  • 你能把你的问题分解得更小吗?
  • 您收集的数据中是否有任何可能改变问题范围的观察结果?
  • 你的二进制输出能变成 softmax 输出吗,反之亦然?
  • 你是用最有效的方式来看待这个问题的吗?

反思你的问题可能是提高绩效的最难的方法,但它通常是产生最佳结果的方法。与在深度学习方面有经验的人聊天会有所帮助,可以让你对你的问题有新的看法。

如果你想找人聊天, 我将在下个月抽出时间与你就你的项目进行 30 分钟的交谈。我对这 30 分钟的通话收取 5 美元,以此作为屏障,阻止那些不认真的人浪费我们的时间。

报名一个时间段

感谢阅读:)如果你喜欢它,尽可能多的点击下面的按钮!这对我意义重大,鼓励我写更多这样的故事

咱们也连线上 推特 或者LinkedIn

深度学习;个人笔记第 1 部分第 2 课,学习率,数据扩充,退火,测试时间扩充

原文:https://towardsdatascience.com/deep-learning-personal-notes-part-1-lesson-2-8946fe970b95?source=collection_archive---------15-----------------------

这个博客系列将会更新,因为我有第二次采取快速人工智能的教训。这些是我的个人笔记,我努力把事情理解清楚并解释好。没什么新意,只活出了这个 博客

第一课复习

我们使用了三行代码来构建图像分类器:

PATH 下的数据组织包括一个 train文件夹和一个valid文件夹。每个文件夹下都有分类标签,即catsdogs,其中有相应的图像。

训练输出:*epoch number* *training loss**validation loss**accuracy*****

***0      0.157528   0.228553   0.927593***

选择一个好的学习率

学习速度决定了我们对解决方案的关注速度。这涉及到寻找一个可能有许多参数的函数的最小值。

我们从一个随机的点开始,然后找到梯度来决定哪条路是向上或向下的。我们到达最小值的距离与梯度成正比;如果更陡,我们就离得更远。我们在一个点选择一个梯度,然后乘以一个数。(学习率/步)。

如果学习率太小,就需要非常长的时间才能触底。如果学习率太大,它可能会远离底部振荡。如果训练一个神经网络,你发现损失或准确性正加速到无穷大,学习率太高。

我们使用学习率查找器(learn.lr_find)来查找合适的学习率。每次小批量(即我们有效利用 GPU 的并行处理能力时,每次查看多少张图像,通常一次查看64128张图像)。我们逐渐成倍地增加学习率,最终学习率会太大,损失会开始变得更严重。

我们绘制学习率与损失的关系图来确定最低点。然后,我们回溯一个数量级,并选择该数量级作为我们的学习率,因为这是损失减少的地方0.01

python 中的数学符号

学习率是要设置的关键数字。快速人工智能为您挑选其余的超级参数。为了获得稍微好一点的结果,我们还可以做更多的调整。

这种学习率查找技术是基于 Adam optimiser 之上的。动量和 Adam 是改进梯度下降的其他方法。

要让模型变得更好,你能做的最重要的事情就是给它更多的数据。由于这些模型有数百万个参数,如果你训练它们一段时间,它们就开始“过度拟合”。

过度拟合—模型开始看到训练集中图像的特定细节,而不是学习可以转移到验证集的一般信息。

我们可以收集更多的数据或者使用数据扩充**。**

数据扩充

这指的是以不影响图像解读的方式随机改变图像。例如水平翻转、缩放和旋转。

我们可以通过将aug_tfms ( 增强变换)传递给tfms_from_model来做到这一点,其中带有一个函数列表,以便按照我们希望的方式将随机变化应用于图像。对于大部分从侧面拍摄的照片(例如,大多数狗和猫的照片,而不是从上到下拍摄的照片,如卫星图像),我们可以使用预定义的功能列表,如transforms_side_on。我们还可以通过添加max_zoom参数来指定图像的随机缩放比例。

你构建一个数据类 6 次,每次你画的都是同一只猫。我们来看一些数据增强的猫图。

场景:

您希望对不同类型的图像使用不同类型的数据增强(水平翻转、垂直翻转、放大、缩小、改变对比度和亮度等等)。例如,您想要识别不想水平翻转的字母和数字,因为它们有不同的含义。你不希望猫和狗垂直翻转,因为图像大多是垂直的。对于卫星图像中的冰山,你可能想把它们翻转过来,因为拍摄图像时卫星是哪一边并不重要。

transfrom side_on —用于从侧面拍摄的图像,轻微改变照片缩放比例,轻微旋转照片,并改变对比度和亮度。

它并不完全是在创建新数据,而是允许卷积神经网络学习如何从不同角度识别猫或狗。

tsf —包含数据扩充。

data对象包括增强。最初,增强并不做任何事情,因为precompute=True

在上面的图片中,每个不同的层都有这样的激活,寻找任何像花的中间或鸟的眼球(用红色圈出)等。这个卷积神经网络的后面几层具有激活(数字),例如在上面的图片中指定了鸟的眼球的位置和置信度(概率)。

我们有预先训练的网络,已经学会识别特征(某些类型的东西,如梯度,边缘圆等)。我们采用倒数第二层,这一层包含了识别这些特定事物的所有必要信息,例如“眼珠子”、“毛绒绒的认真程度”等。我们为每个图像保存激活,称之为预先计算的激活。然后,我们可以创建一个新的分类器,利用这个预先计算的激活。我们可以基于预先计算的激活快速训练简单的线性模型。这就是precompute=True的意思。

这就是为什么当您第一次训练您的模型时,它需要更长的时间-它是预先计算这些激活。

尽管我们每次都尝试展示不同版本的猫,但我们已经预先计算了特定版本猫的激活量,也就是说,我们不会用修改后的版本重新计算激活量。当precompute=True数据增强不起作用时。我们必须将它设置为learn.precompute=False,数据扩充才能工作。

**坏消息是accuracy没有改善,好消息是训练损失(trn_loss),一种衡量该模型误差是否变好的方法,正在减少。验证误差(val_loss)没有减少,但是我们没有过度拟合。过度拟合意味着训练损失远低于验证损失。换句话说,当你的模型在训练集上比在验证集上表现得更好时,这意味着你的模型没有泛化。

循环长度参数。这是什么?

cycle_len=1这使 S 能够以重启(SGDR) 的方式快速梯度下降。基本的想法是,当你越来越接近损失最小的点时,你可能想要开始降低学习速率(采取较小的步骤)以便精确地到达正确的点。在训练时降低学习率的想法被称为学习率退火。这很有帮助,因为随着我们越来越接近最佳重量,我们希望迈出更小的步伐。

逐步退火——你用一定的学习率训练一个模型一段时间,当它停止提高时,手动下拉学习率。选择另一个学习率,手动重复这个过程。

余弦退火——这是一种更好的方法,只需选择某种函数形式——事实证明,真正好的函数形式是余弦曲线的一半,它在开始时以很高的学习速率开始,然后当你更接近时迅速下降。

在训练期间,梯度下降有可能卡在局部最小值而不是全局最小值。

在局部最小值处,损失更严重,并且对于稍微不同的数据集,它不会一般化。在全局最小值时,模型将更好地概括。

请注意,退火不一定与重启相同

我们不是每次都从零开始,但我们会“跳跃”一点,以确保我们处于最佳状态。

然而,我们可能会发现自己处于一个弹性不大的重量空间,即重量的小变化可能会导致损失的大变化。我们希望鼓励我们的模型找到既准确又稳定的权重空间部分。因此,我们不时地增加学习速率(这是“SGDR”中的“重启”),如果当前区域是“尖峰”,这将迫使模型跳到权重空间的不同部分。这是一张图片,展示了如果我们将学习率重置 3 次(在这篇文章中,他们称之为“循环 LR 时间表”):

通过突然增加学习速率,梯度下降可以跳出局部极小值并找到通向全局极小值的路。这样做被称为带重启的随机梯度下降(SGDR),这个想法在这篇论文中被证明是非常有效的。

重置学习率之间的周期数由cycle_len设置,这种情况发生的次数称为周期数,实际上是我们作为第二个参数传递给fit()的。这是我们实际学习率的样子:

The learning rate is restored to its original value after each epoch.

学习率在每个时段开始时被重置为您作为参数输入的原始值,然后在该时段内再次降低,如上文余弦退火中所述。

每次学习率下降到它的最低点(上图中每 100 次迭代),我们称之为一个周期**。**

使用随机起点可以得到同样的效果吗?在 SGDR 诞生之前,人们习惯于创造“群体”,他们会重新学习一个全新的模型十次,希望其中一个会变得更好。在 SGDR,一旦我们足够接近最佳和稳定的区域,重置实际上不会“重置”,但权重会变得更好。所以 SGDR 会给你更好的结果,而不仅仅是随机尝试几个不同的起点。

我们选择最高的学习速率1e-2 (0.01)供 SGD 使用。我们改变每一个小批量的学习率。我们重置它的次数由cycle_len=1参数定义。1意思是每隔一个纪元就重置一次。

我们的主要目标是一般化,而不是在狭窄的最优中结束。在这种方法中,我们是否跟踪最小值,对它们进行平均和组合?我们目前没有这样做,但如果你想让它更好地概括,你可以在重置前保存权重并取平均值。但是现在,我们只选择最后一个。(在 1000 次迭代时)

您可以添加一个名为cycle_save_name的参数以及cycle_len,它将在每个学习率周期结束时保存一组权重,然后您可以集成它们。

我们的确认损失没有多大改善。因此,可能没有必要单独进一步训练最后一层。

保存并加载模型

不时保存你的权重调用learn.save并传递文件名224_lastlayer

预计算的激活和调整大小的图像保存在 tmp 文件的数据文件夹中。删除 tmp 文件夹相当于打开和关闭

调用learn.save时,模型保存在模型文件夹中

**如果您想从头开始重新培训一名模特,该怎么办?通常没有理由删除预先计算的激活,因为预先计算的激活没有任何训练。

微调和差分学习率退火

到目前为止,我们所做的一切都没有改变预先训练的过滤器。我们使用了一个预先训练好的模型,它知道如何找到边缘和渐变(第 1 层)、拐角和曲线(第 2 层),然后是重复的伙伴、文本(第 3 层),最后是眼球(第 4 层和第 5 层)。我们没有在卷积核中重新训练任何更具体的激活权重。我们所做的只是在顶部添加了一些新层,并学习了如何混合和匹配预先训练的功能。

与 ImageNet 图像相比,卫星图像、CT 扫描等图像具有完全不同的特征。所以你需要重新训练很多层。对于狗和猫,图像与模型预先训练的图像相似,但我们仍然会发现稍微调整一些后面的层是有帮助的。

既然我们已经训练了一个好的最终层,我们可以尝试微调其他层。要告诉学习者我们想要解冻剩余的层,只需调用unfreeze()。这告诉学习者我们想要开始改变卷积滤波器。

**learn.unfreeze()**

冻结层是指未被训练的层,即未被更新的层。

unfreeze() 解冻所有层。

检测边缘和梯度的第一层和检测曲线和拐角的第二层不需要太多的学习,它们不需要太多的改变。而更后面的层需要改变。当训练其他图像识别时,这是普遍适用的。

我们所做的是创建一个学习率数组。

**lr=np.array([1e-4,1e-3,1e-2])**

早期的层(如我们所见)有更多的通用特性。因此,我们预计他们对新数据集的微调需求会减少。出于这个原因,我们将对不同的层使用不同的学习速率:最初的几层将在1e-4用于基本几何特征和最接近像素的层,中间层在1e-3用于中间复杂的卷积层,而1e-2如前所述用于我们添加在顶部的层(完全连接的层)。我们称之为 差异学习率,尽管据我们所知,在文献中没有这种技术的标准名称。

为什么是 3?实际上它们是 3 个 ResNet 块,但是现在,把它想象成一组层。

**差分学习率与 网格搜索 有何不同?与网格搜索没有相似之处。网格搜索是您试图找到最佳超参数的地方。对于不同的学习率,它尝试了许多学习率,试图找到最好的学习率。对于整个训练,它对每一层使用不同的学习率。

如果我的图像比模型训练的大怎么办?有了这个图书馆和我们正在使用的现代建筑,我们可以使用任何我们喜欢的大小。

**我们可以只解冻特定的层吗?我们还没有这样做,但是如果你愿意,你可以做learn.unfreeze_to(n)来解冻从层n开始的层。它几乎从来没有帮助,因为使用不同的学习率,优化器可以学习它所需要的。如果你使用一个非常大的内存密集型模型,如果你用完了 GPU,解冻的层数越少,占用的内存和时间就越少。

注意;您不能解冻一个特定的层。

前面我们说3是历元数,但实际上是个周期**。在这种情况下,学习是做1纪元的3周期。(cycle_len=1)**

如果cycle_len=2,它将做 3 个循环,其中每个循环是 2 个时期(即 6 个时期)。

**那它为什么做了 7 个纪元?这是因为cycle_mult使得每个周期的长度加倍。(1 个历元+ 2 个历元+ 4 个历元= 7 个历元)。

使用差分学习率,我们有一个 99.05%准确的模型。

如果循环长度太短,它开始向下寻找一个好点,然后弹出,再向下寻找一个好点,然后弹出,如此循环,这样它就永远找不到一个好点。早些时候,你希望它这样做,因为它试图找到一个更光滑的地方,但后来,你希望它做更多的探索。这就是为什么cycle_mult=2似乎是一个好方法。

我们正在引入越来越多的超参数,已经告诉过你们并不多。你可以选择一个好的学习速度,但是增加这些额外的调整可以帮助你不费吹灰之力就达到额外的水平。一般来说,好的起点是:

  • n_cycle=3, cycle_len=1, cycle_mult=2
  • n_cycle=3, cycle_len=2(无cycle_mult)

为什么更平滑的表面与更一般化的网络相关联?

x 轴显示了当你改变这个特定的参数时,识别狗和猫的能力有多强。一般化意味着当我们给它一个稍微不同的数据集时,我们希望它能够工作。稍有不同的数据集在该参数和它有多像猫和多像狗之间可能具有稍有不同的关系。相反,它可能看起来像红线。换句话说,如果我们在X or Z结束,那么它不会在这个稍微不同的数据集上做得很好。否则,如果我们在Y,结束,它仍然会在红色数据集上做得很好。

让我们来看看我们预测错误的图片

当我们做验证集时,我们对模型的所有输入必须是正方形的。如果不同的图像有不同的尺寸,GPU 不会运行得很快。它需要保持一致,以便 GPU 的每个部分都可以做相同的事情。

为了使它成为正方形,我们只需挑出中间的正方形,正如您在下面看到的,可以理解为什么这张图片被错误地分类。

The dogs head was not identified

我们将使用测试时间增强(TTA)** 或推理时间测试时间它不仅对您的验证集中的图像进行预测,还对它们的许多随机增强版本进行预测(默认情况下,它使用原始图像以及 4 个随机增强版本,假设它们四处移动)。然后,它从这些图像中提取平均预测,并将其用作我们的最终预测。要在验证集上使用 TTA,我们可以使用学习者的TTA()方法。**

准确率提高到 99.25%。神经网络得到同一张图片的多个参数,使准确率上升。

;TTA 用于验证/测试设置。训练时,我们不做 TTA。**

**为什么不加边框或者填充,让它变成方形?对神经网络没有太大帮助,因为猫的形象没有变化。变焦可以工作。反射填充通过在外部添加边框来反射图像,使图像变大,适用于卫星图像。一般来说,使用 TTA 加数据增强,最好的办法是尽量使用大图像。如果你裁剪,你会失去例如狗的脸。

非图像数据集的数据扩充?似乎没有人知道。这似乎会有所帮助,但很少有例子。例如,在自然语言处理中,人们试图替换同义词,但总的来说,这个领域还没有得到充分的研究和开发。

我们可以使用滑动窗口生成其他图像吗?例如,从一张狗的图片生成 3 个图像部分?对于训练来说,这不会更好,因为我们不会得到更好的变化,因为你有三种标准的方法来查看数据。你想给它尽可能多的方法来查看数据。固定的作物位置加上随机的对比度、亮度、旋转变化可能对 TTA 更好。

分析结果

混淆矩阵

评估分类算法的快速方法是使用混淆矩阵。它有助于确定你对哪一组分类有困难。

**preds = np.argmax(probs, axis=1)
probs = probs[:,1]**from** **sklearn.metrics** **import** confusion_matrix
cm = confusion_matrix(y, preds)plot_confusion_matrix(cm, data.classes)**

我们有 987 只预测正确的猫和 13 只预测错误的猫。993 只狗我们预测对了,7 只我们预测错了。

训练世界级图像分类器的步骤

  1. 启用数据增强(side_ontop_down取决于您在做什么),以及precompute=True
  2. 使用lr_find()找到损失仍在明显改善的最高学习率。
  3. 从预计算的激活中训练最后一层,持续 1-2 个时期。
  4. 关闭预计算(precompute=False),这允许我们使用cycle_len=1对 2-3 个时期进行数据扩充
  5. 解冻所有层。
  6. 将前几层的学习速率设置为下一层的 3-10 倍。经验法则:对于预先训练的 ImageNet 类图像为 10 倍,对于卫星或医学成像为 3 倍。
  7. 再次使用lr_find()(注意:如果你调用lr_find已经设置了不同的学习率,它会打印出最后一层的学习率。)
  8. cycle_mult=2训练全网,直到过拟合。

让我们再做一次

这个挑战是确定图像中狗的品种。

使用 kaggle CLI 下载数据。是一个非官方的 kaggle 命令行工具。在使用云虚拟机实例(如 AWS 或 paperspace)下载数据时非常有用。在使用 CLI 之前,请先单击下载按钮,确保您接受竞赛规则。如果您的帐户与另一个帐户连接登录,您必须忘记您的密码,并选择第三个选项来设置新密码和链接您的两个帐户。

**$ kg download -u <username> -p <password> -c dog-breed-identification -f <name of file>**

其中dog-breed-identification是比赛名称,你可以在比赛 URL 的末尾 /c/ 部分[https://www.kaggle.com/c/dog-breed-identification](https://www.kaggle.com/c/dog-breed-identification) 后找到比赛名称。

下面是实际的命令;

**$ kg download -u gerald -p mypassword -c dog-breed-identification**

文件下载完成后,我们可以使用以下命令提取文件。

**#To extract .7z files
7z x -so <file_name>.7z | tar xf -#To extract.zip files
unzip <file_name>.zip**

dogbreeds 文件夹的结构

这与我们之前的数据集不同。不同于train文件夹,每种狗都有一个单独的文件夹,它有一个带有正确标签的 CSV 文件。

进口货

**from fastai.imports import *
from fastai.torch_imports import *
from fastai.transforms import *
from fastai.conv_learner import *
from fastai.model import *
from fastai.dataset import *
from fastai.sgdr import *
from fastai.plots import *PATH = "data/dogbreeds/"
sz = 224
arch = resnext101_64
bs = 58**

我们将阅读熊猫的 CSV 文件。用于进行结构化数据分析。

**label_csv = f'{PATH}labels.csv'
n = len(list(open(label_csv))) - 1 # header is not counted (-1)
val_idxs = get_cv_idxs(n) # random 20% data for validation setn 
10222val_idxs
array([2882, 4514, 7717, ..., 8922, 6774,   37])len(val_idxs) #20% of 10222
2044**

n = len(list(open(label_csv)))-1:打开 CSV 文件,创建一个行列表,然后取长度。-1因为第一行是表头。因此n是我们拥有的图像/行数。

val_idxs = **get_cv_idxs**(n):“获取交叉验证索引”——默认情况下,这将返回随机 20%的行(索引)作为验证集。您也可以发送val_pct来获得特定的百分比,例如val_idxs = get_cv_idxs(n, val_pct=1.0)获得 100%,但默认为 20%。

这包括图像名称或 id 和标签。

下面是一个熊猫的框架来分组不同品种的狗的数量。

有 120 排代表 120 个品种。

经历这些步骤;

**tfms = tfms_from_model(arch, sz, aug_tfms=transforms_side_on, max_zoom=1.1)
data = ImageClassifierData.from_csv(PATH, 'train', f'{PATH}labels.csv', test_name='test', # we need to specify where the test set is if you want to submit to Kaggle competitions
                                   val_idxs=val_idxs, suffix='.jpg', tfms=tfms, bs=bs)**

支持数据扩充;

**tfms = tfms_from_model(arch, sz, aug_tfms=transforms_side_on, max_zoom=1.1)**

调用tfms_from_model并通过aug_tfms=transforms_side_on大概有一面在拍照。

max_zoom —我们将以 1.1 倍放大图像

**data = ImageClassifierData.from_csv(PATH, 'train', f'{PATH}labels.csv', test_name='test', val_idxs=val_idxs, suffix='.jpg', tfms=tfms, bs=bs)**

ImageClassifierData.from_csv —上一次,我们使用了from_paths(它表示文件夹的名称是标签的名称),但是由于标签在 CSV 文件中,我们将改为调用from_csv并调用包含标签的f’{PATH}labels.csv csv 文件。PATH是包含所有数据的文件夹,train是包含训练数据的文件夹。test_name指定测试集在哪里,如果你稍后提交给 Kaggle 的话。

val_idx —没有validation文件夹,但我们仍想跟踪我们在本地的表现有多好。分离出图像并将其放入验证集中。

suffix=’.jpg’ —文件名末尾有.jpg,但 CSV 文件没有。因此,我们将设置suffix,让它知道完整的文件名。

使用包含文件名的trn_ds获取数据对象中的训练数据集。下面是一个文件名(fnames)的例子。

**img = PIL.Image.open(fn); img**

我们需要检查图像的大小。然后我们需要知道如何根据它们是太大还是太小来处理它们。大多数 ImageNet 模型都是通过224224299图像对299进行训练的。

创建字典理解;

**size_d = {k: PIL.Image.open(PATH + k).size for k in data.trn_ds.fnames}**

浏览所有文件并创建一个字典,将文件名映射到文件的大小。

**row_sz, col_sz = list(zip(*size_d.values()))**

获取字典并将其转换为行和列。然后将它们转换成 numpy 数组,如下所示:

**row_sz = np.array(row_sz); col_sz = np.array(col_sz)**

以下是前五种行大小:

**row_sz[:5]
array([500, 500, 500, 500, 500])**

用 matplotlib 绘图。图像和像素数量:

从直方图来看,大多数图像都在500 像素左右。

在图上绘制那些小于 1000 像素的像素以放大:

4599图像位于451 pixels.

**验证集中应该有多少幅图像?验证集的大小取决于数据集的大小。不应该总是 20%。如果多次训练同一个模型,并且得到非常不同的验证集结果,那么您的验证集太小了。

狗的形象似乎在中心,占据了画面的最大部分。因此,我们不需要裁剪,这对于医学成像来说是不同的,因为有时肿瘤可能在帧的一侧,因此需要缩放。

初始模型

下面是常规的两行代码。当我们开始处理新数据集时,我们希望一切都超快。所以我们可以指定大小,从运行速度快的 64 开始。稍后,我们将使用更大的图像和更大的架构,在这一点上,你可能会耗尽 GPU 内存。如果您看到 CUDA 内存不足错误,您需要做的第一件事是重启内核,然后减小批处理大小。

预计算

我们将使用预先计算的分类器。

对于 120 个类别,我们获得了 91%的准确率。没有数据增加或解冻。

让我们关闭预计算,再来几个纪元。

准确率提高到 92%。

一个epoch是一次通过数据,一个cycle是你说的一个周期中有多少个历元。这是学习率从你要求的下降到零。在这种情况下,从cycle_len=1开始,时期和周期是相同的。

让我们节约

**learn.save(‘224_pre’)
learn.load(‘224_pre’)**

增加图像尺寸

如果您在较小尺寸的图像上训练了模型,那么您可以调用learn.set_data并传入较大尺寸的数据集。这将采取你的模型,但是它已经训练到目前为止,它将让你继续在更大的图像上训练。

**learn.set_data(get_data(299, bs))
learn.freeze()**

开始在小图像上训练几个时期,然后切换到更大的图像,继续训练是避免过度拟合的惊人有效的方法。

set_data完全不改变模式。它只是给了它新的数据来训练。

验证损失(0.239)远低于培训损失(0.297)。这是 欠拟合 的标志。Cycle_len=1可能太短了。学习率在有机会放大之前就被重置了。

再加上cycle_mult=2(即第一周期为 1 个历元,第二周期为 2 个历元,第三周期为 4 个历元= 7 个历元)

验证损失和训练损失越来越接近,越来越小,几乎相同。暗示我们在正确的轨道上。

测试时间增加(TTA)

要尝试的其他事情:

  • 运行两个时期的另一个循环
  • 解冻;在这种情况下,训练卷积层没有丝毫帮助,因为图像实际上来自 ImageNet。
  • 删除验证集,重新运行相同的步骤,然后提交。这让我们可以使用 100%的数据。

**我们如何处理不平衡的数据集?这个数据集并不是完全平衡的,每个类别(即品种)有 60 到 100 张图片,但还没有不平衡到让你三思的地步。最近的一篇论文称,处理非常不平衡的数据集的最好方法是复制罕见的案例。

*precompute=True**unfreeze*的区别?**

我们从一个预先训练好的网络开始,这个网络通过丰富的功能来发现激活。我们在它的末端添加了几层,开始是随机的。随着一切冻结和precompute=True,我们正在学习的是我们已经添加的层。使用precompute=True,我们实际上预先计算了图像看起来有多像激活,因此数据增强没有做任何事情,因为我们每次都显示完全相同的激活。

然后我们设置precompute=False,这意味着我们仍然只训练我们添加的最后一层,因为它是冻结的,但数据增强现在正在工作,因为它实际上正在从头开始经历和重新计算所有的激活。最后,我们解除冻结,这意味着“好了,现在您可以开始更改所有这些早期的卷积滤波器”。

为什么不一开始就设定precompute=False?拥有precompute=True的唯一原因是它快了 10 倍甚至更多。如果您正在处理一个相当大的数据集,它可以节省相当多的时间。使用precompute=True没有任何准确性理由

能给你带来好结果的最低版本;

  1. 使用lr_find()找到损失仍在明显改善的最高学习率。
  2. 使用cycle_len=1对最后一层进行 2-3 个时期的数据扩充(即 precompute=False)训练(默认情况下,一切从一开始就被冻结)
  3. 解冻所有层。
  4. 将前几层的学习速率设置为下一层的 3-10 倍。(使用不同的学习率)
  5. cycle_mult=2训练全网,直到过拟合。

**减少批量只影响训练速度吗?是的,如果你每次显示的图像越少,那么它计算梯度的图像就越少,因此也就越不准确。换句话说,知道朝哪个方向走以及朝那个方向走多远就不那么准确了。所以当你把批量变小的时候,你会让它变得更加不稳定。它会影响您需要使用的最佳学习速率,但在实践中,将批量大小除以 2 比 4 似乎不会改变太多。如果批量大小发生了很大变化,您可以重新运行学习率查找器来检查它是否发生了变化。

如果狗跑到角落或者很小,你会怎么做?这将在第 2 部分中讨论,但是有一种技术可以让你大致判断出图像的哪些部分最有可能包含有趣的东西。然后你可以把那部分剪掉。

进一步的改进

  1. 假设您正在使用的图像的大小小于您得到的图像的平均大小,您可以增加图像的大小。正如我们之前看到的,你可以在训练中增加它。
  2. 使用更好的架构。有不同的方法来组合卷积滤波器的尺寸以及它们之间的连接方式。不同的架构具有不同的层数、内核大小、过滤器数量等。

我们使用 ResNet34,它没有太多的参数,适合小数据集。与 ResNet34 相比,ResNext50 需要两倍的时间和 2-4 倍的内存。

我遇到了RuntimeError: cuda runtime error (2) : out of memory.尝试重启你的内核,使用较小的批量,我用了10

使用 ResNext50 达到了 99.65%的准确率。

感谢阅读!跟随@ itsmuriuki

回归学习!

深度学习;个人笔记 Part 1 第三课:CNN 理论;卷积过滤器,最大池,激活,softmax,sigmoid &提交结果给 Kaggle。

原文:https://towardsdatascience.com/deep-learning-personal-notes-part-1-lesson-3-cnn-theory-convolutional-filters-max-pooling-dbe68114848e?source=collection_archive---------17-----------------------

随着我对快速人工智能课程的第二次尝试,这个博客系列将会更新。以上是我的个人笔记;a 努力把事情理解清楚,解释好。没什么新意,只活出了这个 博客

快狗 Vs 猫

这里是一个端到端的过程,以获得狗与猫的最先进的结果:

PATH = "data/dogscats/"

我们假设您的数据在data文件夹中。但是你可能想把它们放在别的地方。在这种情况下,你可以使用符号链接或简称符号链接。

注意:我们没有设置pre_compue=True。这是一种快捷方式,可以缓存一些中间步骤,不必每次都重新计算,也可以省去。当pre_compute=True时,数据增强不起作用。

learn.unfreeze() 
learn.**bn_freeze**(**True**) 
%time learn.fit([1e-5, 1e-4,1e-2], 1, cycle_len=1)

bn_freeze —如果您正在使用更大更深的模型,如 ResNet50 或 ResNext101,即在与 ImageNet 非常相似的数据集上编号大于 34 的任何东西,即尺寸在 200-500 像素之间与 ImageNet 相似的标准对象的侧面照片,您应该添加此行。它导致批量标准化移动平均值不被更新。

使用其他库— Keras

就像 fast ai 坐在 pytorch 上面,keras 坐在 TensorFlow,MXNet,CNTK 等上面。

您需要安装 Keras 或 tensorflow 作为后端:

pip install tensorflow-gpu keras

进口:

import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing import image
from keras.layers import Dropout, Flatten, Dense
from keras.applications import ResNet50
from keras.models import Model, Sequential
from keras.layers import Dense, GlobalAveragePooling2D
from keras import backend as K
from keras.applications.resnet50 import preprocess_input

数据路径:

PATH = "data/dogscats/"
sz=224
batch_size=64train_data_dir = f'{PATH}train'
validation_data_dir = f'{PATH}valid'

Keras 使用 train 文件夹和 validation 文件夹的概念,子文件夹带有标签名称。

Keras 需要更多的代码和设置更多的参数。

train_datagen = ImageDataGenerator(preprocessing_function=preprocess_input,
    shear_range=0.2, zoom_range=0.2, horizontal_flip=True)test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)train_generator = train_datagen.flow_from_directory(train_data_dir,
    target_size=(sz, sz),
    batch_size=batch_size, class_mode='binary')validation_generator = test_datagen.flow_from_directory(validation_data_dir,
    shuffle=False,
    target_size=(sz, sz),
    batch_size=batch_size, class_mode='binary')

不是创建一个单一的数据对象,而是在 Keras 中定义DataGenerator,它指定如何生成数据,还指定我们希望它做什么样的数据扩充(shear_range=0.2, zoom_range=0.2, horizontal_flip=True)以及做什么样的规范化(preprocessing_function=preprocess_input))。换句话说,在 Fast.ai 中,我们可以只说“无论 ResNet50 需要什么,请为我这样做”,但在 Keras 中,您需要知道期望什么。没有标准的扩充集。

train_generator —通过从目录中查找、设置图像的大小以及小批量和小类的大小来生成图像。当训练时,你随机地重新排序图像,显示它们以不同的顺序显示,通过混洗使它们随机。

class_mode= ‘binary’——如果你有两个可能的输出,就用二进制,如果是倍数,就用‘categorical’

train_generator —通过从目录中查找、设置图像大小和小批量的大小来生成图像。

然后创建一个验证数据生成器validation_generator,这个生成器没有数据扩充。还要告诉它不要为了验证而打乱数据集,因为否则你无法跟踪你做得有多好。

创建模型

base_model = ResNet50(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(1, activation='sigmoid')(x)

我们使用 ResNet50,因为 keras 没有 ResNet34。对于 keras,您不能告诉它创建一个适合特定数据集的模型。你必须用手来做。

首先创建一个base_model,然后构建你想要添加的层,即x,在这种情况下,我们添加 3 层。

冻结图层并编译模型

model = Model(inputs=base_model.input, outputs=predictions)for layer in base_model.layers: layer.trainable = Falsemodel.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

layer.trainable=False —循环浏览各层,并使用.trainable = False冻结

通过传递您想要使用的optimizer、要查找的loss和要使用的metric来编译模型。

适合的

%%time
model.fit_generator(train_generator, train_generator.n // batch_size, epochs=3, workers=4,
        validation_data=validation_generator, validation_steps=validation_generator.n // batch_size)

调用 fit_generator 并传递train_generatorvalidation _generator

因为 keras 希望您告诉它每个时期有多少批,所以 bathes 的数量=大小是生成器除以批大小,告诉它有多少个时期,以及有多少个工人,即处理器。

微调

解冻一些层,编译,然后再次适合。

没有层组或差异学习率或部分取消冻结的概念,你必须打印出所有的层,并决定有多少你想要微调。我们从140 开始微调。

split_at = 140**for** layer **in** model.layers[:split_at]: layer.trainable = **False**
**for** layer **in** model.layers[split_at:]: layer.trainable = **True**model.compile(optimizer='rmsprop', loss='binary_crossentropy',
    metrics=['accuracy'])%%time
model.fit_generator(train_generator, train_generator.n // batch_size, epochs=1, workers=3,
        validation_data=validation_generator, validation_steps=validation_generator.n // batch_size)

微调后,你必须重新编译模型,然后拟合。

向 Kaggle 提交结果

在 kaggle 竞赛中,有一个称为评估的部分描述了如何对竞赛进行评估:

对于标签位于不同文件夹的数据集,使用ImageClassifierData.from_paths。如果您有带标签的 aCSV 文件,您可以使用ImageClassifierData.from_csv

要创建提交,您需要使用:

data.classes:包含所有不同的类

data.test_ds.fnames:包含测试文件名

使用测试时间增加(TTA)是一个好主意。通过使用is_test=True,它将给出测试集的预测,而不是验证集的预测。

log_preds, y = learn.TTA(is_test=True) 
probs = np.exp(log_preds)

大多数 PyTorch 模型会给你返回预测的日志,所以你需要做np.exp(log_preds)来得到概率。

probs.shape #(n_images, n_classes(breeds))
(10357, 120)

将矩阵转换成 kaggle 格式,我们使用熊猫数据帧:

df = pd.DataFrame(probs)
df.columns = data.classes

创建一个熊猫数据框架并传递矩阵(probs)。将列名设置为data.classes

df.insert(0, 'id', [o[5:-4] for o in data.test_ds.fnames])

在零位置插入一个名为id的包含文件名的新列。这是文件名的样子。test/ab2520c527e61f197be228208af48191.jpg’。删除前 5 个和最后 4 个字母以获得 id。

查看数据帧:

SUBM = f'{PATH}/subm/'
os.makedirs(SUBM, exist_ok=True)
df.to_csv(f'{SUBM}subm.gz', compression='gzip', index=False)

调用df.to_csv创建一个 CSV 文件,并使用compression=’gzip’对其进行压缩。这将文件保存到服务器。您可以使用 kaggle CLI 通过使用此命令$ kg submissions进行提交,或者使用FileLink(f’{SUBM}subm.gz’)将其下载到您的计算机并上传到 kaggle。这将为您提供一个链接,将文件从服务器下载到您的计算机上。

个体预测

通过模型运行单个图像以获得预测。

打开验证集中的第一个文件:

fn = data.val_ds.fnames[0]
fn
'train/000bec180eb18c7604dcecc8fe0dba07.jpg'
Image.open(PATH + fn).resize((150, 150))

运行预测:

trn_tfms, val_tfms = tfms_from_model(arch, sz)
im = val_tfms(open_image(PATH + fn)) # open_image() returns numpy.ndarray
preds = learn.predict_array(im[None])
np.argmax(preds)

这个形象必须改变。tfms_from_model返回定型转换和验证转换。在这种情况下,我们将使用验证转换。

传递给模型或从模型返回的所有东西通常都被认为是小批量的。这里我们只有一个图像,但是我们必须把它变成一个小批量的单个图像。换句话说,我们需要创建一个不只是[rows, columns, channels]而是[number of images, rows, columns, channels]的张量。通过使用im[None]索引到一个数组,在开始处添加一个额外的单位轴,从而将其从一个图像转换为一个小批量的图像。

卷积神经网络理论

这是一个卷积神经网络可视化视频,由 Word Lens 的优秀创作者奥塔维奥制作。

如果你输入一幅图像,计算机会把它们识别为数字(像素)。

输入层

7 号图像数据来自 MNIST 数据库,我们假设您使用预训练模型进行分类。

隐藏层 1

隐藏图层是对输入进行转换,以便从输出图层的数据中识别更复杂的要素,从而做出更好的评估。

我们应用一个过滤器/内核来检测大部分 3×3 的水平边缘。注意,内核A顶部的1’s和中间的0’s以及底部的-1’s:

 1,   1,   1
 0,   0,   0
-1,  -1,  -1

如果滤波器与输入相乘,我们将为高数值分配高数值,因为它们与 1 相乘,而对低数值几乎不分配任何数值,因为它们与 0 或-1 相乘。因此,我们得到了称为 激活 的第一卷积的输出,它基本上是一个通过从输入中取出某个数字,然后应用某种线性运算(即卷积核)来计算输出(激活)的数字。

Conv1 显示了对输入的 3x3 部分进行处理并乘以卷积内核后两者的激活情况。

我们假设网络经过训练,在训练结束时,它创建了一个卷积滤波器,其中有 9 个数字。

卷积在深度学习中,我们几乎总是有一个 3×3 的小矩阵,并将该矩阵的每个元素乘以图像的 3×3 部分的每个元素,然后将它们加在一起,以在一个点上获得卷积的结果。

让我们应用第二个卷积滤波器B,它也有 9 个数。滤镜B找到垂直边缘,作为隐藏层输出。

1,   0,  -1
1,   0,  -1
1,   0,  -1

Pytorch 不会将它们存储为两个独立的 9 位数组,而是将其存储为张量。这是多维数组。额外的轴允许我们将额外的过滤器堆叠在一起。滤镜和内核意思相同它指的是 3x3 矩阵。

How convolution work: Activation -3 equals the sum of matrix product of the kernel and input

隐藏层(conv1)的大小为 2,因为它有 2 个过滤器/内核。

接下来,我们将应用另一个过滤器,即隐藏层 2 中的过滤器C,它是两个 2x3x3 内核,然后应用校正线性单元(ReLu) 来消除负像。从而创建第二隐藏层 conv2。

整流线性单元(ReLU)-是一种非线性,即扔掉底片。

建筑

架构意味着第一层的内核有多大,第一层的内核中有多少滤波器,第一层有一个 3x3,第二层有一个 3x3,这种架构从两个 3x3 卷积内核开始。第二层有两个 2x3x3 内核。

最大统筹

convolved feature vs pooled feature

这意味着用最大值替换输出矩阵中的最大值。例如最大 2x2 池。注意:它是不重叠的,因此会降低分辨率。

下面是最大池层:

最大池的结果得到适合密集权重一个完全连接的层。

全连接层挑选每一个最大汇集激活,给它们一个权重,并挑选最大汇集激活和 3 维张量的 2 级权重的和积。向外放一个密集激活

这与卷积不同,在卷积中,我们使用 3×3 内核一次激活几次。但是在完全连接的层中,我们创建了一个相当于整个输入的大权重矩阵。

大量使用全连接层的架构可能会有很多权重,因此可能会有过度拟合和速度慢的问题。例如,VGG 有多达 19 层,包含一个完全连接的层,4096 个权重连接到 4096 个隐藏层激活,因此(4096 x 4096 x 内核数),这几乎是 3 亿个权重。

*如果我们有 3 个输入通道,滤波器会是什么形状?*如果我们有 3 个输入通道,它看起来就像 conv1,它有 2 个通道,因此有 2 个滤波器,因此每个通道有 2 个滤波器。

当我们从零开始训练时,我们不是从精心训练的过滤器开始,而是从随机数开始,并使用随机梯度下降来改善这些数字,使它们不那么随机。

实际上,我们必须为十位数计算不止一个数。我们会有十次密集激活。

Softmax

预测图像是猫、狗、飞机、鱼还是建筑物。

在全连接层之外,我们将有 5 个数字。请注意,在最后一层没有 Relu,所以我们可以有底片。你想把 5 个数字转换成从 0 到 1 的概率,如果是猫、狗、飞机、鱼或建筑物,就匹配它。这 5 个类别的概率应该在 0 和 1 之间,并且它们的总和应该为 1。为此,我们使用一个 激活函数 这是一个应用于激活的函数。它接受一个数字,吐出另一个数字。

我们需要把线性和非线性函数叠加在一起做深度学习。我们在每个隐藏层之后使用的非线性是一个 ReLu。激活函数是非线性函数。

Softmax 激活发生在最后一层。softmax 吐出介于 *0* *1* 之间的数字,这些数字加起来就是 *1*

为了让 softmax 发挥作用,我们需要消除所有负面因素。我们将使用对数和指数。他们出现了很多机器和深度学习。

我们做e^-0.36得到exp,然后把它们加起来得到51.31。为了得到softmax,我们除以51.31,得到0.01。softmax 的总和应该等于1.

exp的一个特点是,如果一个数字(output)比另一个稍大,它会使exp变得更大。softmax 倾向于选择一个强有力的东西,也就是说,它将一个高概率分配给一个类。

如果要把图片归类为猫和狗,我们用什么样的激活函数?Softmax 不喜欢预测多个事物。它想挑一样东西。我们可能想要这样做的一个原因是进行多标签分类。

星球竞赛:从太空了解亚马逊

对于猫和狗比赛的单标签分类,图像要么是猫,要么是狗,不是两者都是。对于卫星竞赛来说,图像按照天气(阴霾和晴朗)、农业、原始雨林和水(河流)进行分类。在这种情况下,我们需要预测多种情况,softmax 不会很好,因为它想选择一种情况。

拟人化你的激活功能(赋予个性) softmax 倾向于挑选一个特定的东西。

如果有多个标签,Fast.ai 库将自动切换到多标签模式。所以你什么都不用做。但这是幕后发生的事情:

**from** **planet** **import** f2 metrics=[f2] 
f_model = resnet34label_csv = f'**{PATH}**train_v2.csv'
n = len(list(open(label_csv)))-1
val_idxs = get_cv_idxs(n)**def** get_data(sz):
    tfms = tfms_from_model(f_model, sz,aug_tfms=transforms_top_down,
max_zoom=1.05)
    **return** ImageClassifierData.from_csv(PATH, 'train-jpg',label_csv, tfms=tfms,suffix='.jpg', val_idxs=val_idxs, test_name='test-jpg')data = get_data(256) #gets images of 256x256

我们使用from_csv,因为多标签分类不能使用 Keras 风格的方法,其中子文件夹是标签的名称。

transform_top_down:它不仅仅是一个垂直翻转。正方形有八种可能的对称。它可以旋转 0 度、90 度、180 度和 270 度,并且可以翻转( 二面角 八组 )

x,y = next(iter(data.val_dl))

使用ds(数据集)我们可以得到一个单独的图像*。*

dl是一个数据加载器,它会给你一个小批量,特别是转换的小批量。使用数据加载器,您不能请求特定的小批量,您只能取回next小批量。在 Python 中,它被称为“生成器”或“迭代器”。

PyTorch 真正利用了现代 Python 方法。如果你很了解 python,PyTorch 来的很自然。如果你不太了解 python,PyTorch 是学好 python 的一个很好的理由。

x是小批量的图像,y是小批量的标签。打印 y:

默认情况下,批大小为 64,可能的类为 17。

让我们看看0的图片标签:

list(zip(data.classes, y[0]))

*[('agriculture', 1.0),
 ('artisinal_mine', 0.0),
 ('bare_ground', 0.0),
 ('blooming', 0.0),
 ('blow_down', 0.0),
 ('clear', 1.0),
 ('cloudy', 0.0),
 ('conventional_mine', 0.0),
 ('cultivation', 0.0),
 ('habitation', 0.0),
 ('haze', 0.0),
 ('partly_cloudy', 0.0),
 ('primary', 1.0),
 ('road', 0.0),
 ('selective_logging', 0.0),
 ('slash_burn', 1.0),
 ('water', 1.0)]*

这是农业,清晰,主要刀耕火种和水。

PyTorch 和 fast.ai 是把标签变成one-hot-encoded标签。如果实际标签是 dog,它看起来会像这样:

我们采用softmax并与actuals进行比较来实际预测。actualssoftmax之差加在一起给出了误差,即损失函数。

One-hot-encoding 对于排序来说效率非常低,所以我们将存储一个index值(单个整数),而不是目标值的 0 和 1(y)。如果您查看狗品种竞赛的y值,您实际上不会看到一个由 1 和 0 组成的大列表,但是您会看到一个单一的整数。

PyTorch 在内部将索引转换为 one-hot-encoded vector(尽管您实际上永远看不到它)。PyTorch 对于热编码的和非热编码的有不同的损失函数——但是这些细节被 fast.ai 库隐藏了,所以你不必担心。但要意识到的一件很酷的事情是,我们正在为单标签分类和多标签分类做完全相同的事情。

*为 softmax 更改 log 的基数有意义吗?*不,改变基底只是神经网络可以轻松学习的线性缩放:

注意:图像只是数字的矩阵。图像被洗掉了,所以为了让它更明显(“亮一点”)我们乘以*1.4

像这样试验图像是很好的,因为这些图像一点也不像 ImageNet。你所做的绝大多数涉及卷积神经网络的事情实际上不会像 ImageNet 一样,它们将是医学成像,对不同种类的钢管、卫星图像等进行分类

sz=64data = get_data(sz)data = data.resize(int(sz*1.3), 'tmp')

我们不会用sz=64来进行猫和狗的比赛,因为我们是从预先训练的 ImageNet 网络开始的,它开始时近乎完美。如果我们用 64 乘 64 的图像重新训练整个集合,我们会破坏已经非常好的权重。请记住,大多数 ImageNet 模型都是用 224×224 或 299×299 的图像训练的。

image net 中没有与上面的卫星图像相似的图像。imageNet 唯一有用的部分是发现边缘和渐变的第一层,发现纹理和重复图案的第二层。

当使用卫星图像时,首先用小图像进行训练效果很好。

learn = ConvLearner.pretrained(f_model, data, metrics=metrics)lrf=learn.lr_find()
learn.sched.plot()

适合的

使用[lr/9, lr/3, lr]是因为图像不同于 ImageNet 图像,并且早期的图层可能没有接近它们需要的样子。

绘制损失图:

让我们先将图像尺寸翻倍至 128,然后调整,再翻倍至 256,这样可以达到 93.5%的准确率:

测试时间增加使我们达到 93.6%;

data = data.resize(int(sz*1.3), 'tmp')

这是做什么的?

当我们指定要应用什么转换时,我们传递一个大小:

tfms = tfms_from_model(f_model, sz,
        aug_tfms=transforms_top_down, max_zoom=1.05)

数据加载器做的一件事是按需调整图像的大小。这与data.resize无关。如果初始输入图像是 1000 乘 1000,读取 JPEG 并将其调整为 64 乘 64 比训练卷积网络花费更多的时间。

data.resize告诉它我们不会使用比sz*1.3更大的图像,所以遍历一次并创建这个大小的新 JPEG,它是矩形的,所以最小边的新 JPEG 的大小是sz*1.3中心裁剪的。这类似于循环调整图像大小的批处理脚本。这会节省你很多时间。data.resize是加速便利功能。

metrics=[f2]

我们没有使用accuacy,而是使用了 F-beta ,这是一种衡量假阴性和假阳性的方法。我们使用它的原因是因为这个特别的 Kaggle 比赛想要使用它。查看 planet.py,了解如何使用 Skitlearn 创建自己的度量函数。这是最后打印出来的。在每个时期之后[ 0\. 0.08932 0.08218 **0.9324** ]

多标签分类的激活函数

Fast.ai 检查标签以查看一个图像是否有多个标签,并自动选择激活功能。

多标签分类的激活函数称为 sigmoid。

为了找到乙状结肠,选择exp除以1+exp,即:

0.01/1+0.01 = 0.01
0.08/1+0.08 = 0.07 

这使得可以一次预测多种情况。如果某个值小于 0,则其 sigmoid 小于 0.5,如果大于 0,则其大于 0.5。

与其单独训练最后几层,不如从差别学习率开始训练?你可以跳过最后一层的训练,直接学习不同的学习率,但你可能不想这样做。卷积层都包含预先训练好的权重,所以不是随机的——对于接近 ImageNet 的东西,真的很好;对于不接近 ImageNet 的东西,有总比没有好。然而,我们所有完全连接的层都是完全随机的。因此,您总是希望通过先对它们进行一点训练,使完全连接的权重优于随机权重。否则,如果你直接去解冻,那么你实际上是在摆弄那些早期的层权重,而后面的层权重仍然是随机的——这可能不是你想要的。

解冻时,你想改变什么?内核(过滤器)和权重。训练的意思是设置过滤器和密集权重。密集权重用于完全连接的层,过滤器/内核权重用于卷积。另一方面,激活是根据权重和先前层激活或输入计算的。

如何获得 64 乘 64 的图像尺寸?这取决于变换。默认情况下,我们的变换采用最小的边缘,将其缩小,并为其拍摄中心裁剪,但当使用数据增强时,它会随机选择。

准确性不是模型试图优化的。它优化了损失函数,例如交叉熵,这个指标是打印出来的,让我们可以看到发生了什么。

当您使用差异学习率时,这三个学习率是否在各层之间均匀分布? fast.ai 库有一个“图层组”的概念。在类似 ResNet50 的东西中,有数百个层,您可能不希望编写数百个学习率,因此库为您决定如何拆分它们,最后一个总是指的是我们随机初始化并添加的完全连接的层,其余的学习率在层之间拆分。

可视化图层

learn.summary()*[('Conv2d-1',
  OrderedDict([('input_shape', [-1, 3, 64, 64]),
               ('output_shape', [-1, 64, 32, 32]),
               ('trainable', False),
               ('nb_params', 9408)])),
 ('BatchNorm2d-2',
  OrderedDict([('input_shape', [-1, 64, 32, 32]),
               ('output_shape', [-1, 64, 32, 32]),
               ('trainable', False),
               ('nb_params', 128)])),
 ('ReLU-3',
  OrderedDict([('input_shape', [-1, 64, 32, 32]),
               ('output_shape', [-1, 64, 32, 32]),
               ('nb_params', 0)])),
 ('MaxPool2d-4',
  OrderedDict([('input_shape', [-1, 64, 32, 32]),
               ('output_shape', [-1, 64, 16, 16]),
               ('nb_params', 0)])),
 ('Conv2d-5',
  OrderedDict([('input_shape', [-1, 64, 16, 16]),
               ('output_shape', [-1, 64, 16, 16]),
               ('trainable', False),
               ('nb_params', 36864)]))*
 ...

conv2d-1是层的名称。

‘input_shape’, [-1, **3, 64, 64**] — PyTorch 在图像尺寸64, 64前列出频道3。按照这个顺序,一些 GPU 计算会运行得更快。这是一个 4 维的小批量。

-1是指无论批量有多大,都可以改变。Keras 使用None

‘output_shape’ , [-1, **64**, **32, 32**] 64 是内核数,32 乘 32 是**步距。**像 maxpooling 一样改变大小。

一个非常小的数据集的学习率查找器返回奇怪的数字,图为空。学习率查找器将一次完成一个小批量。如果你有一个很小的数据集,就没有足够的小批量。所以诀窍是让你的批量非常小。

结构化和时间序列数据

有两种类型的数据集。

非结构化 —音频、图像、自然语言文本,其中一个对象内部的所有东西都是同一种东西——像素、波形幅度或单词。

结构化 —损益表,关于脸书用户的信息,其中每一列在结构上不同。“结构化”指的是列数据,您可能会在数据库或电子表格中找到,其中不同的列代表不同种类的事物,每行代表一个观察值。

结构化数据在学术界经常被忽视,因为如果你有一个更好的物流模型,它很难在花哨的会议记录中发表。但它让世界运转,让每个人都赚钱,提高效率。我们不会忽视它,因为我们正在进行实用的深度学习,Kaggle 也不会,因为人们把奖金放在 Kaggle 上,以解决现实世界的问题。

探索这种架构背后的动机是它与现实世界应用的相关性。工业中用于日常决策的大多数数据是结构化或时间序列数据。我们将通过实际的结构化数据问题来探索使用神经网络的端到端过程。

示例:

预测大型杂货连锁店的销售额。此处

使用商店、促销和竞争对手数据预测销售。此处

罗斯曼商店销售

进口:

**from** **fastai.structured** **import** *
**from** **fastai.column_data** **import** *
np.set_printoptions(threshold=50, edgeitems=20)

PATH='data/rossmann/'

structured —不特定于 PyTorch,也用于机器学习课程中,在完全没有 PyTorch 的情况下进行随机森林。它可以在没有 Fast.ai 库的任何其他部分的情况下单独使用。

fastai.column_data —允许我们用柱状结构化数据做 Fast.ai 和 PyTorch 之类的东西。

对于结构化数据,我们需要大量使用熊猫。不熟悉熊猫,这里的(用于数据分析的 Python)是熊猫作者写的一本好书。

创建数据集

除了提供的数据,我们还将使用 Kaggle 竞赛参与者收集的外部数据集,例如 google trends 和 weather。你可以在这里下载所有的。

有大量的数据预处理,这个笔记本包含了第三名获胜者的整个管道(分类变量的实体嵌入)。本课程不涉及数据处理,但机器学习课程会详细介绍,因为特征工程非常重要。

查看 CSV 文件:

StoreType —你经常会得到一些列包含“代码”的数据集。代码是什么意思并不重要。远离了解太多,先看看数据怎么说。然后稍后查看经常随数据一起提供的数据字典。

连接表格

这是一个关系数据集,您已经将相当多的表连接在一起——这对于使用merge的 Pandas 来说很容易做到:

fast.ai 还提供以下功能:

add_datepart(train, "Date", drop=False)

获取一个日期,提取一系列列,如“星期几”、“季度初”、“一年中的月份”等,并将它们全部添加到数据集中。

持续时间部分将计算距离下一个假期还有多长时间,距离上一个假期还有多长时间,等等。

保存包含数据的整个结构化文件:

joined.to_feather(f'{PATH}joined')

to_feather:将一个熊猫的数据帧保存为“羽毛”格式,这种格式将它保存在 RAM 中,并将其转储到磁盘中。所以它真的真的很快。厄瓜多尔杂货比赛有 3.5 亿条记录,所以你会关心用羽毛节省多长时间,它需要 6 秒。

该数据包含特定日期商店中特定商品的销售数量。我们的目标是预测在未来的某一天,在某个特定的商店里会卖出多少这样的商品。

下一课

我们将列分为两种类型:分类的和连续的。

分类变量:是store_id 1 和store_id 2 在数值上没有关系。它们是类别。一周中的每一天;周一(第 0 天)和周二(第 1 天)的电子贸易条件分类数据将被热编码,并且

**连续变量:**像到最近的竞争对手的公里距离这样的东西是我们用数字处理的数字。连续数据将按原样馈入全连接层。

步骤:

  1. 创建验证集。
  2. ColumnarModelData.from_data_frame是我们加载列数据的方式。基本的 API 概念与图像识别相同。
  3. .get_learner
  4. 找出我们的最佳学习率并画出来。
  5. .fit带着一个metric
  6. .fit 同一个cycle_len

感谢阅读!跟随@ itsmuriuki

回归学习!

深度学习;个人笔记第 1 部分第 4 课:结构化学习,自然语言处理,协同过滤。辍学,嵌入,通过时间支持。

原文:https://towardsdatascience.com/deep-learning-personal-notes-part-1-lesson-4-structured-learning-natural-language-processing-26188d744ece?source=collection_archive---------12-----------------------

随着我对快速人工智能课程的第二次尝试,这个博客系列将会更新。以上是我的个人笔记;a 努力把事情理解清楚,解释好。没什么新意,只活出了这个 博客

Fast.ai 采取的方法是“这里是如何使用软件做一些事情,然后通过查看细节来查看幕后。”

拒绝传统社会的人

learn = ConvLearner.pretrained(arch, data, ps=0.5, precompute=True)

预计算来自最后一个卷积层的激活。激活是基于一些权重计算的数字,这些权重也被称为构成应用于先前层激活的核心或过滤器的参数,否则这些权重可能是其他计算的输入或结果。

通过键入学员对象的名称,您可以实际看到其中的层:

learn*Sequential(
  (0): BatchNorm1d(1024, eps=1e-05, momentum=0.1, affine=True)
  (1): Dropout(p=0.5)
  (2): Linear(in_features=1024, out_features=512)
  (3): ReLU()
  (4): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True)
  (5): Dropout(p=0.5)
  (6): Linear(in_features=512, out_features=120)
  (7): LogSoftmax()
)*

*Linear(in_features=1024, out_features=512)* 一个线性层意味着一个矩阵乘数。在这种情况下,我们有一个 1024 行 512 列的矩阵。它接收 1024 个激活,并发出 512 个激活。

ReLu。用零代替负数。

*Linear(in_features=512, out_features=120)* 第二线性层获取第一线性层激活 512 个激活,并将它们通过新矩阵乘以 120 并输出 120 个激活。

*Softmax* —一个激活函数,返回加起来为 1 的数字,每个数字都在 0 和 1 之间。由于较小的数值精度原因,直接取 softmax 的对数比 softmax 更好。这就是为什么当我们从模型中获得预测时,我们必须做np.exp(log_preds)

*Dropout(p=0.5)* 是做什么的?

应用 dropout 意味着在层中选择激活并删除它们。p是删除一个激活的概率。输出激活变化不大。

随机丢弃一个层中的一半激活有一个有趣的效果,它迫使它不要过度拟合。如果一个特定的激活已经学习了确切的狗或猫,它迫使模型找到一个没有随机一半激活的表示。

如果你已经完成了所有的数据扩充,或者为模型提供了足够的数据,那么你能做的事情就很少了,但在很大程度上,你会陷入困境。Geofrey Hinton 等人提出了辍学,这完全是受大脑工作方式的启发。

你放弃了 1%的激活,这根本不会改变什么,因此它不会防止过度拟合,也就是说,不会一般化。

p=0.99 你会丢掉 99%的激活。它也不会过度拟合,因此对概括来说很好,但会杀死你的准确性。

*p* 值可以很好地概括,但会降低您的训练精度,低 *p* 值将不能很好地概括,但会提高您的精度。

在训练的早期,为什么验证损失比训练损失好,因为它没有看到数据集,你不希望损失好得多?这是因为当我们查看验证集时,我们关闭了辍学。当进行推理时,即预测时,我们希望尽可能使用最好的模型。训练中会出现辍学现象。

你需要做些什么来适应你丢弃激活的事实吗?我们不(fast.ai)当我们说p=0.5在幕后 pytorch 扔掉一半的激活,并使激活加倍,因此平均激活没有变化。

在 Fast.ai 中,您可以传入ps,这是所有添加层的p值。它不会改变预训练网络中的辍学,因为它应该已经以某种适当的辍学水平被训练:

learn = ConvLearner.pretrained(arch, data, **ps=0.5**, precompute=True)

我们可以通过设置ps=0来去除掉音。但是过了几个时代后,我们开始过度适应。训练损失小于验证损失。With ps=0 dropout 根本没有添加到模型中。

你可能已经注意到了,它已经增加了两个Linear层。我们不必这样做。您可以设置xtra_fc(额外全连接层)参数。你可以传递一个列表,告诉它你希望每个额外的全连接层有多大。您确实需要至少一个将卷积层的输出(本例中为 1096)转换为 120 个狗品种的类数,即由您的问题定义的类数:

如果xtra_fc是空的,这意味着不要添加任何额外的线性层,只是我们必须有一个,从而给我们一个最小的模型。

默认情况下,我们是否应该使用特定的 p 值?对于第一层,我们有p=0.25,对于第二层,我们有p=0.5,这似乎适用于大多数情况。如果你发现它过量,继续增加,比如 0.2。如果不合适,减少它。

ResNet34 的参数较少,因此不会过度拟合,但对于像 ResNet50 这样的大型架构,通常需要增加压差。

有没有一种特别的方法可以确定它是否过度装配?是的,您可以看到培训损失远低于验证损失。你看不出是不是太过过度。零过拟合通常不是最佳的。您唯一要做的事情是降低验证损失,所以您需要尝试一些东西,看看是什么使验证损失降低。

*为什么平均激活很重要?*如果我们删除一半的激活,那么下一个将它们作为输入的激活也将减半,以及之后的所有激活。比如蓬松耳朵激活大于 0.6 就蓬松,现在大于 0.3 才蓬松,就是改了意思。这里的目标是在不改变含义的情况下删除激活。

*我们可以逐层设置不同的退学等级吗?*是的,这就是它被称为ps的原因,我们可以传递一个数组:ps =[0.1,0.2]

还没有经验法则来确定何时前一层或后一层应该具有不同的漏失量。如果有疑问,对每个完全连接的层使用相同的压差。人们通常只在最后一个线性图层上放置 dropout。

*为什么显示器损耗而不是准确度?*对于验证集和训练集来说,损失是我们唯一可以看到的,我们能够对它们进行比较。我们将在后面了解到,损失是我们实际上正在优化的东西,因此更容易监控和理解这意味着什么。

通过添加辍学,我们似乎添加了一些随机噪声,这意味着我们没有做太多的学习,我们需要调整学习率吗?它对学习速度的影响似乎不足以引起注意。理论上,它可能会影响我们,但还不足以影响我们。

结构化和时间序列数据

数据中有两种类型的列:

分类—它有多个“级别”,例如StoreTypeAssortment

连续——它有一个数,该数的差或比有某种意义。例如CompetitionDistance

我们不会涵盖数据清理和功能工程,我们将假设已经完成。我们需要转换成与神经网络兼容的输入。

这包括将分类变量转换成连续的整数或一键编码,将连续特征标准化为标准常态,等等…

yearmonthday这样的数字虽然我们可以把它们看作是连续的,但我们不必这样。当我们决定将一些事情分类时,我们是在告诉神经网络不同地对待每一个层次。但是,当说它是连续的时,我们是在告诉它用一个光滑的函数来拟合它们。

很多时候,事物实际上是连续的,但没有很多不同的层次(例如YearDayOfWeek),把它们看作是分类的会更好。因为每一天都可能表现出不同的性质。

我们要说哪些变量是分类的,哪些是连续的,这是你必须做出的建模决定。

如果在你的数据中某个东西被编码为“a,b,c ”,你必须称它为分类的,如果它开始是连续的,你必须选择是分类的还是连续的。

注意,连续变量是实际的浮点数。浮点数有许多级别,即它有很高的基数,例如DayOfWeek的基数是 7。

*你曾经 bin 过连续变量吗?*目前没有,但我们可以做的一件事,比如说Max_Temperature,是分组为 0-10,10-20,20-30,称之为分类。一组研究人员发现,有时宁滨是有帮助的。

*如果你是用年份作为一个范畴,当一个模型遇到一个它从未见过的年份会发生什么?*将被视为未知类别。熊猫有一个特殊的类别叫做未知,如果它看到一个以前没有见过的类别,它会被视为未知。

*如果我们的训练数据集没有类别,但我们的测试不知道模型会做什么,它会预测吗?*它将是未知类别的一部分,它仍将预测它将处理 seen 后面的值 0,如果训练集中有未知,它将学会预测它们,如果没有,它将有一个随机向量。

n = len(joined); n
844338

我们有 844338 行,这是每个商店的日期。

通过cat_vars循环,将适用的数据框列转换为分类列。

循环遍历contin_vars并将它们设置为float32 (32 位浮点),因为这是 PyTorch 所期望的。例如PromoSchoolHoliday

从样本开始

我们倾向于从数据集的小样本开始。对于图像,这意味着将图像大小调整为 64 x 64 或 128 x 128。但是对于结构化数据,我们从随机的行样本开始。

因此给我们150000行数据作为开始。

查看数据:

即使我们将一些列设置为“类别”,例如内部保存的‘StoreType’‘Year’.,熊猫在笔记本中仍然显示为字符串。

proc_df(处理数据帧)是一个快速人工智能功能,它:

取一个数据框,告诉它你的因变量是什么,把它放入一个单独的变量,并从原始数据框中删除它。换句话说,df没有Sales列,而y包含了Sales列。

do_scale神经网络确实希望输入数据都在零附近,标准偏差在 1 左右。为了做到这一点,我们取数据,减去平均值,然后除以标准差。它返回一个特殊的对象mapper,该对象跟踪它用于标准化的平均值和标准偏差,因此您可以在以后对测试集做同样的事情。

nas它还处理缺失值,对于分类变量,它变成 ID: 0,其他类别变成 1、2、3 等等。对于连续变量,它用中值替换缺失值,并创建一个新的布尔值列,表明它是否缺失。

Before preprocessing

After preprocessing

例如,2014 年变为 2,因为分类变量已被从零开始的连续整数替换。原因是,我们稍后会将它们放入一个矩阵中,我们不希望矩阵有 2014 行长,因为它可能只有两行。

我们现在有一个不包含因变量的数据框架,其中所有内容都是一个数字。这就是我们需要进行深度学习的地方。

在这种情况下,我们需要预测接下来两周的销售额,因此我们应该创建一个验证集,它是我们训练集的最后两周。

在时间序列数据中,交叉验证不是随机的。相反,我们的维持数据通常是最新的数据,就像在实际应用中一样。这个问题在这里详细讨论。一种方法是将最后 25%的行(按日期排序)作为我们的验证集。

组装我们的模型

重要的是,你要对自己的衡量标准有一个很好的理解,即别人会如何评价你。在这场比赛中,我们将接受均方根百分比误差(RMSPE)的评判。

这意味着我们将实际销售额减去单个预测的预测值,求出其百分比,然后求出平均值。

当你取数据的对数时,得到均方根误差实际上会得到均方根百分比误差:

我们可以直接从外部数据框创建模型数据对象:

md = **ColumnarModelData.from_data_frame**(PATH, val_idx, df, 
         yl.astype(np.float32), cat_flds=cat_vars, bs=128, 
         test_df=df_test)

我们将从创建模型数据对象md开始,它内置了验证集、训练集和可选测试集。从那里,我们将得到一个学习者,然后我们可以选择调用lr_find,然后调用learn.fit,以此类推。

这里的不同之处在于,我们没有使用ImageClassifierData.from_csvfrom_paths,我们需要一种不同的模型数据,称为ColumnarModelData,我们称之为from_data_frame

Path指定存储模型文件的位置

val_idx我们将放入验证集中的行的索引列表。

df 数据框是自变量。

yl因变量,是proc_dfyl = np.log(y)返回的y的日志

cat_flds指定您希望被视为分类的事物。一切都变成了数字,除非我们指定,它会把它们都视为连续的。通过名单cat_vars

bs批量大小

现在我们有了一个包含train_dlval_dltrain_dsval_ds等的标准模型数据对象。

创建适合我们模型数据的学习者:

m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars),
                   0.04, 1, [1000,500], [0.001,0.01], 
                   y_range=y_range)
  • 0.04:一开始要用多少退学者
  • [1000,500]:每层有多少激活
  • [0.001,0.01]:在后面的层使用多少个漏失
  • emb_szs 嵌入

嵌入

让我们暂时撇开分类变量,看看连续变量:

你永远不要把 ReLU 放在最后一层,因为 softmax 需要负数来创造低概率。

完全连接层的简单视图:

以秩 1 张量的形式接收输入,将其通过线性层(矩阵乘积),通过激活(ReLu),再次通过线性层,然后是 softmax,最后是输出。我们可以添加更多的线性层或辍学。

对于回归问题,跳过 softmax。

分类变量

例如,我们创建一个 7 行和 4 列的新矩阵,并用浮点数填充它。为了将“Sunday”添加到我们的具有连续变量的秩 1 张量中,我们查找这个矩阵,它将返回 4 个浮点数,我们将它们用作“Sunday”。

最初,这些数字是随机的。但是我们可以把它们放入神经网络,用梯度下降法更新它们,以减少损失。这个矩阵只是我们的神经网络中的另一组权重,称为嵌入矩阵

嵌入矩阵是指我们从零到该类别最大层数之间的整数开始。我们对矩阵进行索引以找到一个特定的行,并将它附加到我们所有的连续变量上,之后的一切都和之前一样(线性→ ReLU →线性等)。

那 4 个数字代表什么?它们只是我们正在学习的参数,碰巧最终会给我们带来好的损失。我们稍后会发现,这些特定的参数通常是人类可以解释的,而且非常有趣,但这是一个副作用。它们是我们正在学习的一组 4 个随机数。

你对嵌入矩阵的维数有好的启发吗?我们使用每个变量的基数(即其唯一值的数量)来决定其嵌入的大小

上面是每个分类变量及其基数的列表。

我们一周有 7 天,但是看起来基数是 8,额外的基数是为了防止在测试集中有一个未知数,除以 2,因此有 4 个随机数。即使原始数据中没有缺失值,也应该留出一个值以备不时之需。年份也是 3,但我们为未知的 e.t.c .加 1

确定嵌入大小的经验法则是基数大小除以 2,但不大于 50。

查看存储,我们将有1116个存储用于查找,返回长度为50的秩 1 张量。我们必须为每个分类变量建立一个嵌入矩阵。

然后,我们将嵌入大小emb_szs传递给get_learner,这告诉学习者对于每个分类变量,该变量使用哪种嵌入。

m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars),
 0.04, 1, [1000,500], [0.001,0.01], y_range=y_range)
m.summary()

*除了 random 还有初始化嵌入矩阵的方法吗?*基本想法是,如果 Rossmann 的其他人已经训练了一个神经网络来预测奶酪销售,你也可以从他们嵌入的商店矩阵开始预测酒类销售。举例来说,Pinterest 和 Instacart 就是如此。Instacart 使用这种技术为他们的购物者选择路线,Pinterest 使用这种技术决定在网页上显示什么。他们有产品/商店的嵌入矩阵,在组织中共享,因此人们不必培训新的产品/商店。

*使用嵌入矩阵比一次热编码有什么优势?*对于上面的星期几示例,我们可以轻松地传递 7 个数字,而不是 4 个数字,例如[0,1,0,0,0,0,0],表示星期天。这也是一个浮动列表,将完全工作,这就是如何,一般来说,分类变量已被用于统计多年所谓的“虚拟变量”。问题是,星期天的概念只能与一个浮点数相关联。所以它得到了这种线性的行为,它说星期天或多或少是一件单一的事情。有了嵌入,星期天就是一个四维空间的概念。所发生的是这些嵌入向量倾向于得到这些丰富的语义概念。例如,如果发现周末有不同的行为,您会看到周六和周日会有一些特定的数字较高,或者例如一周中的某些天往往与较高的销售额相关联,例如在周五购买酒。

通过拥有更高维度的向量而不仅仅是单个数字,它给了深度学习网络学习这些丰富表示的机会。

嵌入的想法就是所谓的“分布式表示”——神经网络最基本的概念。这是一种想法,即神经网络中的概念具有难以解释的高维表示。这个向量中的这些数字不一定只有一个意义。如果这个是低的,那个是高的,这可能意味着一件事,如果那个是高的,那个是低的,这可能意味着另一件事,因为它经历了这个丰富的非线性函数。正是这种丰富的表征让它能够学习到如此有趣的关系。

*嵌入适合某些类型的变量吗?*嵌入适用于任何范畴变量。唯一不能很好工作的是基数太高的东西。如果你有 600,000 行,一个变量有 600,000 个级别,那就不是一个有用的分类变量。但总的来说,这场比赛的第三个获胜者真的决定了所有不太高的基数,他们把它们都定为绝对的。好的经验法则是,如果你能制造一个分类变量,你也可以,因为这样它就能学习丰富的分布式表示;如果你让它保持连续,它最多能做的就是尝试找到一个适合它的单一函数形式。

矩阵代数如何在幕后工作:

进行查找等同于在独热编码向量和嵌入矩阵之间进行矩阵乘积。

相乘后,你只剩下一个向量。现代的库实现这一点的方式是取一个整数并在数组中查找。

你能谈谈使用日期和时间作为分类,以及这如何影响季节性吗?以下代码从一个完整的日期时间中提取特定的日期字段,用于构造类别。在处理日期-时间时,您应该始终考虑这个特征提取步骤。如果不将您的日期-时间扩展到这些额外的字段中,您就无法在任何这些粒度上捕捉任何趋势/周期行为作为时间的函数。我们将为每个表添加一个日期字段。

add_datepart函数接受一个数据框和一个列名。它可选地从数据框中移除该列,并用表示关于该日期的所有有用信息的许多列来替换它,例如星期几、月几、月几、是四分之一开始还是四分之一结束等等。我们最后列出了我们的功能:

例如,DayOfWeek现在变成了 8 行乘 4 列的嵌入矩阵。从概念上讲,这允许我们的模型创建一些有趣的时间序列模型。如果有一个七天周期的东西,在周一上升,在周三下降,但只在柏林,它完全可以做到这一点,它有它需要的所有信息。

这是一个处理时间序列的绝妙方法。*您只需确保您的时间序列中的周期指标以列的形式存在。*如果没有一个名为星期几的列,神经网络将很难学会进行除法 mod 并在嵌入矩阵中查找。这不是不可能,但真的很难。

例如,如果您预测三藩市的饮料销售,您可能想要美国电话电报公司公园的球赛何时开始的列表,因为这将影响到索玛有多少人在喝啤酒。所以你需要确保基本指标或周期性在你的数据中,只要它们在,神经网络就要学会使用它们。

学习者

m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars),
                   0.04, 1, [1000,500], [0.001,0.01], y_range=y_range)
m.summary()

emb_szs嵌入尺寸

len(df.columns)-len(cat_vars)数据帧中连续变量的数量。

0.04嵌入矩阵有自己的漏失,这就是漏失率。

1我们想要创造多少产出,即销售这一最后线性层的产出。

[1000, 500]第一线性层和第二线性层的激活次数。

[0.001,0.01]第一线性层和第二线性层的脱落。

我们有一个 leaner,让我们找出学习率(lr = 1e-3):

合适的

从样本数据开始:

metrics这是一个自定义指标,它指定了一个函数exp_rmspe,该函数在每个时期结束时被调用并打印出结果。

拟合所有数据:

m.fit(lr, 1, metrics=[exp_rmspe], cycle_len=1)*[ 0\.       0.00676  0.01041  0.09711]*

通过使用所有的训练数据,我们得到 0.09711 的 RMSPE。这会让我们在排行榜上名列前茅。

所以这是一种处理时间序列和结构化数据的技术。有趣的是,与使用这种技术的小组分类变量的实体嵌入相比,第二名获胜者做了更多的特征工程。这场比赛的获胜者实际上是物流销售预测方面的专家,所以他们有自己的代码来创建大量的功能。

Pinterest 的人们建立了一个非常相似的推荐模型,他们也说*当他们从梯度推进机器转向深度学习时,他们做了更少的特征工程,这是一个更简单的模型,需要更少的维护。*所以这是使用这种方法进行深度学习的一大好处,你可以获得最先进的结果,但工作量要少得多。

*我们是否使用了任何时间序列?*间接的,是的。正如我们刚刚看到的,我们的列中有一个DayOfWeekMonthOfYear等,它们中的大多数被视为类别,因此我们正在构建一月、星期日等的分布式表示。我们没有使用任何经典的时间序列技术,我们所做的只是神经网络中两个完全连接的层。与任何标准的时间序列技术相比,嵌入矩阵能够以更丰富的方式处理诸如星期几的周期性之类的事情。

图像模型和这个模型有什么区别?我们称呼get_learner的方式有所不同。在成像中,我们只是做了Learner.trained并传递数据:

learn = ConvLearner.pretrained(arch, data, ps=0., precompute=True)

对于这些类型的模型,事实上对于很多模型,我们建立的模型依赖于数据。在这种情况下,我们需要知道我们有什么嵌入矩阵。所以在这种情况下,数据对象创建了学习者:

m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars), 0.04, 1,
                   [1000,500], [0.001,0.01], y_range=y_range)

步伐

第一步。列出分类变量名称,列出连续变量名称,并将它们放入 Pandas 数据帧中:

cat_vars = ['Store', 'DayOfWeek', 'Year', 'Month', 'Day', 'StateHoliday', 'CompetitionMonthsOpen',
    'Promo2Weeks', 'StoreType', 'Assortment', 'PromoInterval', 'CompetitionOpenSinceYear', 'Promo2SinceYear',
    'State', 'Week', 'Events', 'Promo_fw', 'Promo_bw', 'StateHoliday_fw', 'StateHoliday_bw',
    'SchoolHoliday_fw', 'SchoolHoliday_bw']contin_vars = ['CompetitionDistance', 'Max_TemperatureC', 'Mean_TemperatureC', 'Min_TemperatureC',
   'Max_Humidity', 'Mean_Humidity', 'Min_Humidity', 'Max_Wind_SpeedKm_h', 
   'Mean_Wind_SpeedKm_h', 'CloudCover', 'trend', 'trend_DE',
   'AfterStateHoliday', 'BeforeStateHoliday', 'Promo', 'SchoolHoliday']

第二步。创建您希望在验证集中包含哪些行索引的列表:

val_idx = np.flatnonzero(
    (df.index<=datetime.datetime(2014,9,17)) & (df.index>=datetime.datetime(2014,8,1)))

第三步。调用这一行代码:

md = ColumnarModelData.from_data_frame(PATH, val_idx, df, 
         yl.astype(np.float32), cat_flds=cat_vars, bs=128, 
         test_df=df_test)

第四步。创建一个列表,列出您希望每个嵌入矩阵有多大:

emb_szs = [(c, min(50, (c+1)//2)) for _,c in cat_sz]
emb_szs
[(1116, 50),
 (8, 4),
 (4, 2),
 (13, 7),
 (32, 16),
 (3, 2),
 (26, 13),
 (27, 14),
 (5, 3),
 (4, 2),
 (4, 2),
 (24, 12),
 (9, 5),
 (13, 7),
 (53, 27),
 (22, 11),
 (7, 4),
 (7, 4),
 (4, 2), ...

第五步。打电话给get_learner——你可以用这些精确的参数开始,如果它不合适,你可以摆弄它们。

m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars), 0.04, 1,
                   [1000,500], [0.001,0.01], y_range=y_range)

第六步。呼叫m.fit

m.fit(lr, 3, metrics=[exp_rmspe])

如何对这种类型的数据使用数据扩充,以及 dropout 是如何工作的?不知道。可能它必须是特定领域的,但他(杰里米)从未见过任何论文或行业中的任何人使用结构化数据和深度学习进行数据增强。他认为这是可以做到的,但还没有看到它的实现。dropout 实际上是抛出了一阶张量的一半激活。这也适用于嵌入矩阵。

有什么坏处?几乎没有人在用这个。为什么不呢?基本上答案是,学术界没有人在研究这个,因为这不是人们发表的东西。因此,还没有真正伟大的例子,人们可以看着并说“哦,这里有一种技术工作得很好,让我们的公司实现它吧”。但也许同样重要的是,直到现在有了这个 Fast.ai 库,还没有任何方法可以方便地做到这一点。如果您想要实现这些模型中的一个,您必须自己编写所有的定制代码。现在是 6 步流程。有很多巨大的商业和科学机会来利用这一点,解决以前没有很好解决的问题。

自然语言处理

这是深度学习最有前途的领域,比计算机视觉落后两三年。软件的状态和一些概念远没有计算机视觉成熟。

你在 NLP 中发现的一件事是你可以解决特定的问题,它们有特定的名字。在自然语言处理中有一种特殊的问题叫做**“语言建模”——**这意味着给定一个句子中的几个单词,建立一个模型来预测下一个单词会是什么。

例如,当你输入时,按下空格键,下一个单词是一个语言模型。

为了这个练习,我们从 arXiv.org 下载了 18 个月的论文

数据:

<cat> —纸张的类别。CSNI 是计算机科学和网络。

<summ> —论文摘要。

让我们看看一个经过训练的语言模型的输出,我们传递了类别,在这种情况下是 csni(计算机科学和网络)和一些启动文本:

该模型通过阅读 arXiv 论文了解到,某个写计算机网络的人会这样说话。记住,一开始根本不懂英语。它从随机的每个英语单词的嵌入矩阵开始。通过阅读大量的 arXiv 论文,它学会了跟随他人的是什么样的单词。

该模型不仅学会了如何很好地书写英语,而且在你说出类似“卷积神经网络”的东西后,它会使用括号来指定一个缩写词“(CNN)”。

我们将尝试创建一个预训练模型,用于执行其他一些任务。例如,给定 IMDB 电影评论,我们将计算出它们是正面的还是负面的。这是一个分类问题。

我们想使用一个预先训练的网络,至少知道如何阅读英语。因此,我们将训练一个预测句子下一个单词的模型,即语言模型,就像在计算机视觉中一样,在末尾添加一些新层,并要求它预测某事是积极的还是消极的。

基本上,创建一个语言模型,并使其成为分类模型的预训练模型。

*为什么直接做自己想做的事不会更好?*事实证明,它的表现并不理想。有几个原因。首先,我们知道微调一个预先训练好的网络是非常强大的。因此,如果我们能让它先学习一些相关的任务,那么我们就可以利用所有的信息来帮助它完成第二项任务。另一个原因是 IMDB 电影评论长达 1000 字。因此,在阅读了 1000 个单词(整数)后,你对英语的结构或单词或标点符号的概念一无所知,你得到的只是 1 或 0(肯定或否定)。试图学习英语的整个结构,然后用一个数字来表达积极和消极的情绪,这实在是太难了。通过建立语言模型,我们首先建立了一个理解电影评论英语的神经网络,然后我们希望它学习的东西将有助于决定评论是积极还是消极。

*这与卡帕西的夏尔-RNN 相似吗?*这有点类似于夏尔-RNN,它在给定多个前一个字母的情况下预测下一个字母。语言模型通常在单词级工作,但它们不是必须,我们将集中在单词级建模上。

这些生成的单词和句子在多大程度上是它在训练数据集中找到的内容的实际副本?这些单词肯定是它以前见过的单词,因为它不在字符级别,所以它只能给我们它以前见过的单词。句子,有几种严格的方法,但最简单的方法是看上面的例子,它创建了两个类别,看着它们,它创建了相似的概念。

最重要的是,当我们训练语言模型时,我们将有一个验证集,以便我们试图预测从未见过的东西的下一个单词。

文本分类示例:

  1. 对冲基金,可能会在文章或 Twitter 中找出过去导致市场大幅下跌的原因。
  2. 识别客户服务查询,这些查询往往与下个月取消订阅的人有关。
  3. 将 if 文档分类为它们是否属于法律查询的一部分。

IMDB

进口

PyTorch 的 NLP 图书馆。

数据

大型电影观看数据集包含来自 IMDB 的 50,000 条评论。数据集包含偶数个正面和负面评论。作者只考虑了高度两极分化的评论。负面评价得分≤ 4 分(满分 10 分),正面评价得分≥ 7 分(满分 10 分)。中立评论不包括在数据集中。数据集分为训练集和测试集。训练集是同样的 25,000 个带标签的评论。

情感分类任务包括预测给定文本的极性(积极或消极)。

然而,在我们尝试对情感进行分类之前,我们将简单地尝试创建一个语言模型;也就是可以预测句子下一个单词的模型。为什么?因为我们的模型首先需要理解英语的结构,然后我们才能期望它识别积极情绪和消极情绪。

因此,我们的攻击计划与我们用于狗对猫的计划相同:预训练一个模型来做一件事(预测下一个单词),并微调它来做其他事情(对情绪进行分类)。

不幸的是,没有好的预训练语言模型可供下载,所以我们需要创建自己的模型。

在这种情况下,我们没有单独的测试和验证。培训目录中有许多代表电影评论的文件:

看一个电影评论的例子:

让我们分别检查训练数据集和测试数据集中有多少个单词:

在我们分析文本之前,我们必须先对它进行 标记化 。这指的是将一个句子拆分成一个单词数组,或者更一般地说,拆分成一个记号数组的过程。

一个好的标记器会很好的识别你句子中的片段。每个分隔的标点符号都将被分隔,多部分单词的每个部分也将被适当分隔。下面是标记化的一个示例:

我们使用 Pytorch 的 torchtext 库来预处理我们的数据,告诉它使用 spacy 库来处理标记化。

创建一个字段

首先,我们创建一个 torchtext 字段,它描述了如何预处理一段文本——在本例中,我们告诉 torchtext 将所有内容都变成小写,并用 spacy 对其进行标记。

TEXT = data.Field(lower=True, tokenize="spacy")

lower=True —小写文本

tokenize=spacy_tok —用spacy_tok来标记

我们利用LanguageModelData为语言建模创建一个 ModelData 对象,向它传递我们的 torchtext 字段对象,以及我们的训练、测试和验证集的路径。在这种情况下,我们没有单独的测试集,所以我们也将使用VAL_PATH

bs=64; bptt=70FILES = dict(train=TRN_PATH, validation=VAL_PATH, test=VAL_PATH)
md = LanguageModelData.from_text_files(PATH, TEXT, **FILES, bs=bs, bptt=bptt, min_freq=10)

PATH数据在哪里,模型就保存在哪里

TEXT torchtext 关于如何预处理文本的字段定义。

我们拥有的所有文件的列表:培训、验证和测试

bs批量大小

bptt 背道具穿越时间。意思是我们一次在 GPU 上贴多长的句子

min_freq=10:一会儿,我们将把单词替换成整数,即每个单词都有一个唯一的索引。如果有什么单词出现次数少于 10 次,就叫不认识。

在构建了我们的ModelData对象之后,它会自动为TEXT对象填充一个非常重要的属性:TEXT.vocab。这是一个词汇表,它存储了文本中出现过的单词(或记号),以及每个单词将如何映射到一个唯一的整数 id。我们以后还需要使用这些信息,所以我们保存了这些信息。

(技术说明:python 的标准 *Pickle* 库无法正确处理这个,所以在这个笔记本的顶部我们用了 *dill* 库代替,导入为 *pickle* )

这是从整数 id 到唯一令牌的映射的开始:

vocab让我们将一个单词与一个整数匹配,一个整数与一个单词匹配。我们将使用整数。

做词干分析或词干分析很常见吗?不完全是,不。一般来说,标记化是我们想要的。为了尽可能地概括,我们想知道接下来会发生什么,所以不管它是将来时还是过去式,是复数还是单数,我们都不知道哪些事情会变得有趣,哪些事情不会,所以似乎最好是尽可能不去管它。

在处理自然语言的时候,语境不重要吗?为什么我们要标记和查看单个单词?不,我们不是在看单个单词,它们仍然是有序的。只是因为我们用数字 12 代替了 I,它们还是那个顺序。

有一种不同的处理自然语言的方式叫做“单词袋”,他们确实抛弃了顺序和上下文。在机器学习课程中,我们将学习如何使用单词包表示法,但它们不再有用或即将变得不再有用。我们开始学习如何使用深度学习来恰当地使用上下文。

批量大小和回柱通过时间( BPTT)

在语言模型中发生的事情是,即使我们有许多电影评论,它们都被连接在一起成为一大块文本。因此,我们预测这个巨大的东西的下一个词是所有的 IMDB 电影评论串联在一起。

我们从一大块文本开始,例如 6400 万字。我们将串联的评论分成批次。在这种情况下,我们将把它分成 64 个部分。然后,我们将每个部分移动到前一部分的下方,并对其进行移调。我们最终得到一个 100 万乘 64 的矩阵。然后,我们在时间上抓取一个小块,这些块的长度大约等于 BPTT(这随着每个时期而变化)。我们抓取一个 70 长的小片段,这是我们第一次放入 GPU,也就是批处理。

我们的LanguageModelData对象将创建具有 64 列的批处理(这是我们的批处理大小),以及大约 80 个令牌的不同序列长度(这是我们的bptt参数- 通过时间反向传播)。

每个批次还包含与标签完全相同的数据,但在文本中晚了一个单词,因为我们总是试图预测下一个单词。标签被展平成一维数组。

我们通过用iter包装数据加载器(md.trn_dl)然后调用next来获取第一批训练数据

我们得到一个 77 乘 64 的张量,大约有 70 行,但不完全是。

Torchtext 每次都会随机改变bptt的数字,因此每个时期它都会获得稍微不同的文本比特——类似于计算机视觉中的混洗图像。我们不能随机打乱单词的顺序,因为它们需要有正确的顺序,所以相反,我们随机地移动它们的断点一点点。

77 代表第一篇影评的前 77 个字。

为什么不按句子拆分?不尽然。记住,我们使用的是列。所以我们的每一列都有大约一百万的长度,虽然这些列并不总是以句号结尾,但是它们太长了,我们并不在乎。每列包含多个句子。

创建模型

现在,我们有了一个模型数据对象,它可以为我们提供批处理,我们可以创建一个模型。首先,我们要创建一个嵌入矩阵。

4602批次数量

34945vocab中唯一令牌的数量(唯一字必须至少出现 10 次min_freq=10,否则它们将被替换为Unk)

1数据集的长度,即整个语料库

20621966语料库中的字数。

34945 用于创建嵌入矩阵:

每个单词都有一个嵌入向量。这是一个分类变量,它是一个基数很高的分类变量。这是 34945 分类变量,这就是为什么我们为它创建一个嵌入矩阵。

我们需要设置许多参数:

em_sz = 200  *# size of each embedding vector*
nh = 500     *# number of hidden activations per layer*
nl = 3       *# number of layers*

嵌入大小为 200,比我们之前的嵌入向量大得多。这并不奇怪,因为一个词比星期天的概念有更多的细微差别。

一般来说,一个单词的嵌入大小在 50 到 600 之间。

研究人员发现,大量的动量不能很好地与这些类型的 *RNN(递归神经网络)*模型一起工作,因此我们创建了一个版本的 Adam 优化器,其动量小于默认的0.9

opt_fn = partial(optim.Adam, betas=(0.7, 0.99))

Fastai 使用了由 Stephen Merity 开发的最新的 AWD·LSTM 语言模型的变体。该模型的一个关键特征是,它通过退出提供了出色的正则化。没有已知的简单方法(还没有!)要找到以下辍学参数的最佳值,您只需进行实验…

然而,其他参数(alphabetaclip)通常不需要调整

如果你试图建立一个 NLP 模型,并且你是欠拟合的,那么减少所有这些漏失,如果是过拟合的,那么大约以这个比例增加所有这些漏失。

还有其他方法可以避免过度拟合。目前,learner.reg_fn = partial(seq2seq_reg, alpha=2, beta=1)工作可靠,所以所有的 NLP 模型可能都需要这条特别的线。

learner.clip=0.3当你查看你的梯度,将它们乘以学习率,决定你的权重更新多少,这不会让它们超过 0.3。防止我们迈出太大的步伐(高学习率)。

有一些单词嵌入其中,例如 Word2vec 或 GloVe。它们和这个有什么不同?为什么不一开始就用这些来初始化权重呢?人们在做各种其他任务之前已经预先训练了这些嵌入矩阵。它们不被称为预训练模型;它们只是一个预先训练好的嵌入矩阵,你可以下载。我们没有理由不下载它们。以这种方式建立一个完整的预训练模型似乎不会从使用预训练的单词向量中受益太多;在其他地方,使用整个预先训练的语言模型会产生更大的差异。也许我们可以把两者结合起来,使它们更好一点。

*模型的架构是什么?*它是一个 递归神经网络 使用一种叫做 **LSTM (长短期记忆)**的东西。

拟合模型

learner.fit(3e-3, 4, wds=1e-6, cycle_len=1, cycle_mult=2)
learner.save_encoder('adam1_enc')
learner.load_encoder('adam1_enc')learner.fit(3e-3, 1, wds=1e-6, cycle_len=10) 

在情感分析部分,我们只需要语言模型的一半——编码器 ,所以我们保存这部分:

learner.save_encoder('adam3_10_enc')
learner.load_encoder('adam3_10_enc')

语言建模精度一般用度量 困惑 来衡量,简单来说就是我们使用的损失函数的exp()

math.exp(4.165)*64.3926824434624*pickle.dump(TEXT, open(f'**{PATH}**models/TEXT.pkl','wb'))

测试

我们可以对我们的语言模型进行一些试验,以检查它是否工作正常。首先,让我们创建一小段文本来“启动”一组预测。我们将使用 torchtext 字段对其进行数值化,这样我们就可以将其输入到我们的语言模型中。

我们还没有添加方法来简化语言模型的测试,所以我们需要手动完成以下步骤:

让我们看看短文后的下一个单词的十大预测是什么:

让我们看看我们的模型是否可以自己生成更多的文本:

情感分析

我们有一个预训练的语言模型,现在我们想对它进行微调,以进行情感分类。我们需要从语言模型中保存 vocab,因为我们需要确保相同的单词映射到相同的 id。

TEXT = pickle.load(open(f'{PATH}models/TEXT.pkl','rb'))

sequential=False告诉 torchtext 应该对文本字段进行标记化(在这种情况下,我们只想存储‘正’或‘负’单个标签)。

我们不需要把整件事当作一大段文字,但每篇评论都是独立的,因为每篇评论都有不同的情感。

splits是一个创建训练集、测试集和验证集的 torchtext 方法。IMDB 数据集内置于 torchtext 中,因此我们可以利用这一点。看一看lang_model-arxiv.ipynb,了解如何定义自己的 fastai/torchtext 数据集。

Splits 允许我们查看单个标签t.label和一些文本t.text

fastai 可以直接从 torchtext 分割中创建一个 ModelData 对象,我们可以在md2上训练它:

get_model获取我们的学习者,然后我们可以将预先训练好的语言模型m3.load_encoder(f’adam3_10_enc’)加载到其中。

因为我们正在微调一个预训练的模型,我们将使用不同的学习率,并增加剪辑的最大梯度,以使 SGDR 更好地工作。

我们要确保除了最后一层之外的都被冻结了。然后我们训练一下,解冻它,训练一下。好的一面是,一旦你有了一个预先训练好的语言模型,它实际上训练得非常快。

Bradbury 等人最近的一篇论文,在翻译中学习:语境化的词向量,对解决 IMDB 情感分析问题的最新学术研究进行了方便的总结。这里展示的许多最新算法都是针对这个特定问题进行调整的。

正如你所看到的,我们刚刚在情感分析中获得了一个新的最先进的结果,将误差从 5.9%降低到了 5.5%!使用相同的基本步骤,您应该能够在其他 NLP 分类问题上获得类似的世界级结果。

有很多机会可以进一步改善这一点:

例如,我们可以开始训练查看大量医学期刊的语言模型,然后制作一个可下载的医学语言模型,然后任何人都可以使用它来微调医学文献的前列腺癌子集。

我们也可以将这与预先训练的单词向量相结合。

我们可以预先训练维基百科语料库语言模型,然后将其微调为 IMDB 语言模型,然后将其微调为 IMDB 情感分析模型,我们会得到比这更好的结果。

协同过滤

数据:

电影镜头数据

http://files . group lens . org/datasets/movie lens/ml-latest-small . zip

path='data/ml-latest-small/'

它包含了userId电影movieId ratingtimestamp

我们的目标将是一些我们以前没有见过的用户-电影组合,我们必须预测他们是否会喜欢它。这就是推荐引擎的构建方式。

让我们也来读一下电影名:

我们将(在下一课中)创建一种电影用户交叉标签:

感谢阅读!跟随@ itsmuriuki

回归学习!

深度学习项目创意

原文:https://towardsdatascience.com/deep-learning-project-ideas-1444c0e56cfa?source=collection_archive---------6-----------------------

Building Brains in Python

有许多很棒的教程可以帮助你开始深度学习生涯。然而,你会从尝试自己建造东西中学到最多。以下是一些常见的网络架构,以及它们如何应用于不同的项目:

深度前馈模式:

这是经典神经网络架构的最新版本。将输入通过一系列层传递到一个或多个输出节点。该模型非常适合处理 csv 数据集,如流行的 Pima-Indians 糖尿病数据集、iris flower 数据集等。这些模型基于两个基本的统计模型,即回归和分类器。在这些模型中,我们试图预测数字或分类输出。数字输出/回归映射到实数输出,如“82.4”,而分类输出/分类映射到包含在一组值中的离散数字输出,如“red”。如果你正在寻找更多数据集的灵感,请查看 kaggle 。

**卷积神经网络模型:**计算机视觉的尖端架构,有无数种方法可以应用这个模型。我建议从 MNIST 或 CIFAR-10 教程开始,然后进入二进制分类模型,因为它们更容易理解。你可以在 Jupyter 笔记本上即插即用这个代码并启动你的第一个二进制图像识别模型。这个例子很好,因为它向您展示了如何导入您自己的自定义数据集,这是从教程转移到您自己的项目时最大的挑战之一。

如果您没有立即获得想要的结果,请尝试增加历元的数量,改变您提供给模型的图像大小,添加更多的层,并且如果必要的话,(这将比其他任何事情都更好地提高性能),添加更多的数据!

如果你是一个更中级的水平,你应该看看物体检测算法,如 YOLO,SSD,甚至 R-CNN/快速 R-CNN/更快的 R-CNN。物体检测应用相当普遍,举个随机的例子:检测星球大战电影中的光剑,或者更常见的,网络摄像头中的人脸。

你也可以将这些模型用于自动驾驶应用。无论您是在与遥控汽车、麻省理工学院深度驾驶挑战赛还是马里奥赛车游戏交互,您都可能会应用卷积网络来应用图像反馈,然后将其传递给一系列输出决策,如左转/右转等。然而,一旦你越过了图像处理部分,它就变成了一个更高级的问题,因为你需要使用强化学习算法来处理自动驾驶需要做出的决定。

**递归神经网络模型:**序列模型有许多应用,例如聊天机器人、价格预测、文本挖掘、视频处理等等。我推荐从一个 char 级 RNN 开始,因为它将为理解 LSTM 之门提供一个良好的基础。加载股票价格数据集也是很好的练习。一旦你使用了文本挖掘 rnn,将这些概念扩展到聊天机器人就不会太难了。对于初学者来说,使用 RNNs 的视频分类算法有点困难,因为它需要首先将图像通过卷积层,然后将这种架构与 LSTM 门相结合。

**GANs/自动编码器:**GANs 的许多应用非常华丽和令人兴奋,但是,我建议最初使用它们来增加图像识别数据集的数据。GANs 应该能够在您的数据集中生成更多图像,您可以查看这些图像是否提高了分类器性能并发布您的结果。GANs 和自动编码器通常是更高级的主题,不幸的是超出了本文的范围。如果你真的想从 GANs 和深度学习的潜力中获得灵感,请查看神经风格转移项目:

[## 神经艺术风格转移:综述

大一的春季学期,我参加了斯坦福大学关于卷积神经网络的 CS 231n 课程。我的最终项目…

medium.com](https://medium.com/artists-and-machine-intelligence/neural-artistic-style-transfer-a-comprehensive-look-f54d8649c199)

杂念

我建议简单地从 Tensorflow 开始,这样你对后端过程有一个粗略的了解。当运行在高级 API 上的模型抛出错误时,这非常有用。之后,我更喜欢 TFLearn 或 Keras APIs,两者都不错。我认为 Python 是深度学习的最佳语言,尽管 R 由于其简单的语法和类似的笔记本风格也有一些吸引力。然而,如果您计划将结果导出到 Web 应用程序或 Raspberry Pi 控制器中,Python 更适合构建 API。

这里是文章中提到的应用程序的完整列表:

{聊天机器人,图像分类器,对象检测,自动驾驶,文本情感分析,语音情感分析,语音合成,价格预测,聊天机器人,视频分类器,动作识别}

感谢阅读,请留下掌声!

CShorten

Connor Shorten 是佛罗里达大西洋大学计算机科学专业的学生。对数据科学、深度学习和软件工程感兴趣。主要用 Python,JavaScript,C++编码。请关注更多关于这些主题的文章。

深度学习问题—带演示的答案模型

原文:https://towardsdatascience.com/deep-learning-question-answer-model-with-demo-e21e43f60dd5?source=collection_archive---------4-----------------------

用数据做很酷的事情!

question-answer gif

如果一个模型可以通过从段落中提取最相关的单词来回答任何段落中的问题,那该有多神奇。深度学习让这一切成为可能!

下面看一个演示这样的问答超级模型。在这个演示中,你可以在任何语境中输入多达 300 个单词,并从中提出任何类型的问题。模型托管在 AWS 上,从那里返回结果。我很抱歉演示有点慢,因为我还没有机会优化这个模型的部署。

试玩链接:【http://www.deeplearninganalytics.org/demos

这个模型非常通用,可以有很多实际应用。例如,作为一个机器人,它可以链接到任何网页,所以用户可以问问题,它可以在页面上搜索答案。另一个我个人认为非常有用的想法是链接到大多数人不看就点击我同意的合同条款。如果用户可以问一些重要的问题,而不需要阅读一大堆法律术语,那会怎么样?请看下面的一个小例子:

背景:转换条款经常出现在军火合同中。该功能允许您在指定时间将 ARM 转换为固定利率抵押贷款。条款和条件因贷款人而异。不过,一般来说,你必须在转换前提前 30 天通知你的贷款人。你还必须支付一笔费用,通常是 250 到 500 美元。一些贷款人指定何时可以进行转换,而其他人则允许在贷款的前三至五年内的任何时间进行转换。

问:转换条款的相关费用是多少?

模型的答案:250 到 500 美元

看看这个模型是如何将最后一句关于费用的话与转换条款联系起来的,尽管确切的术语“转换条款”在开头只提到过一次。它可以进行共指解析,这意味着它可以将像它/他们这样的代词正确地关联到实体。

这个模型有几个惊人之处:

  • 它已经接受了维基百科数据的训练,在它能理解的文本类型方面非常灵活。我已经尝试了各种各样的主题,从新闻,体育,合同条款,财产数据,它真的工作
  • 研究不同类型的问题——谁、何时、做什么、如何等等
  • 它返回的答案来自段落,因为它被编码为在段落中找到最相关的单词子集

但它并不完美。主要缺点是:

  • 目前,即使问了一个完全随机的问题,它也会返回一个答案。一种可能的增强是训练它在与答案相关联的置信度低时不返回答案
  • 模型准确性虽然相当好,但并不完美,随着深度学习研究产生最稳健的方法,模型将随着时间的推移而改进

你可以在我的 Github 上找到模型的代码。

如果你对这种模式的运作方式感到好奇,我已经在我的博客这里分享了它的细节。

一个简短的总结是:

资料组

这个模型建立在StanfordQuestionAnsweringDataset(SQuAD1.1)数据集上,该数据集由一组维基百科文章上的众包工作者提出的问题组成,其中每个问题的答案都是相应阅读文章中的一段文字,或 span 。SQuAD 拥有 500+篇文章上的 100,000+问答对,比以前的阅读理解数据集大得多。

小队的主要特征:

I)它是一个封闭的数据集,意味着问题的答案总是上下文的一部分,也是上下文的连续跨度

ii)因此找到答案的问题可以简化为找到对应于答案的上下文的开始索引和结束索引

  1. 75%的答案长度小于等于 4 个单词

模型

这个模型的实现使用了 BiDAF 注意模块,并做了一些改进。模型中的主要层是:

  1. 输入上下文和问题被预处理,转换成原始单词,并且这些单词使用预先训练的手套模型被转换成单词嵌入
  2. 双向 LSTM 层对上下文和问题分别进行编码,创建隐藏的表示,查看给定单词前后的单词,以创建对文本的理解
  3. 现在我们有了上下文和问题的表示,我们需要一起看它们来找到答案。这是通过注意力来完成的。该模型使用 BiDAF 注意力,允许注意力从上下文到问题和从问题到上下文的双向流动。并且这两个注意被连接以创建最终向量。见下面截图

BiDAF attention

4.我们还从 BiDAF 借鉴了建模层的思想,使用双向 LSTM 来学习来自关注层的查询感知
上下文单词表示之间的交互

5.模型的最后一层是 softmax 输出层,帮助我们决定答案范围的开始和结束索引。我们结合上下文隐藏状态和来自前一层的注意力向量来创建混合代表。这些混合代表成为全连接层的输入,该全连接层使用 softmax 来预测开始和结束索引的概率

如果你喜欢这个帖子,请给我一个掌声:)希望你自己拉代码试试。另外,请试玩一下演示,并分享您的任何反馈。

我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请前往 http://deeplearninganalytics.org/的[酒店查看我们的酒店。](http://deeplearninganalytics.org/)

你也可以在https://medium.com/@priya.dwivedi看到我的其他作品

如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我

参考文献:

  • 小队数据集
  • BiDAF 型号

吴恩达深度学习专业化— 21 个经验教训

原文:https://towardsdatascience.com/deep-learning-specialization-by-andrew-ng-21-lessons-learned-15ffaaef627c?source=collection_archive---------1-----------------------

Photo by Charles Deluvio on Unsplash

我最近完成了吴恩达在 Coursera 上的新深度学习课程的所有可用材料(截至 2017 年 10 月 25 日)。该专业目前有 3 门课程可供选择:

  1. 神经网络和深度学习
  2. 改进深度神经网络:超参数调整、正则化和优化
  3. 构建机器学习项目

我发现这 3 门课都非常有用,并从吴恩达老师那里学到了大量的实用知识。Ng 出色地过滤了流行词汇,并以清晰简洁的方式解释了概念。例如,Ng 明确表示,受监督的深度学习只不过是一个多维曲线拟合过程,任何其他代表性的理解,如对人类生物神经系统的共同参考,充其量是松散的。

专门化只需要基本的线性代数知识和 Python 中的基本编程知识。然而,在我看来,你也应该了解向量微积分,以理解最优化过程的内部工作原理。如果你不关心内部工作,只关心获得高水平的理解,你可以跳过微积分视频。

第一课:为什么深度学习正在兴起?

90%的数据是在过去 2 年中收集的。深度神经网络(DNN 的)能够利用大量的数据。因此,DNN 氏症可以主宰较小的网络和传统的学习算法。

Shows how scale drives performance in DNN’s

此外,有许多算法上的创新使得 DNN 的训练速度大大提高。例如,从 sigmoid 激活函数切换到 RELU 激活函数对诸如梯度下降的优化过程具有巨大的影响。这些算法上的改进让研究人员可以更快地迭代整个想法->实验->代码周期,从而带来更多的创新。

Deep Learning Development Cycle

第 2 课:深度学习中的矢量化

在学习本课程之前,我并不知道可以在没有任何显式 for 循环的情况下实现神经网络(除了在层上)。Ng 在传达 Python 中矢量化代码设计的重要性方面做得非常好。家庭作业为你提供了一个样板矢量化代码设计,你可以很容易地将它转移到你自己的应用程序中。

第三课:深刻理解 DNN 的

第一个课程实际上让您从头开始实现 numpy 中的向前和向后传播步骤。通过这样做,我对 TensorFlow 和 Keras 等更高级框架的内部工作有了更深入的理解。Ng 解释了计算图背后的想法,这使我能够理解 TensorFlow 似乎如何执行“神奇的优化”。

第四课:为什么是深层表现?

Ng 对 DNN 作品的层次感有着直观的理解。例如,在面部检测中,他解释说早期的层用于将面部的边缘组合在一起,然后后期的层使用这些边缘来形成面部的部分(例如,鼻子、眼睛、嘴等)。)然后使用进一步的层将各部分放在一起并识别人。他还解释了电路理论的思想,电路理论基本上认为,存在需要指数数量的隐藏单元来适应浅层网络中的数据的函数。指数问题可以简单地通过增加有限数量的附加层来缓解。

第 5 课:解决偏差和差异的工具

Ng 解释了研究人员识别和解决偏差和方差问题的步骤。他描绘的画面给出了解决这些问题的系统方法。

Cookbook for addressing bias and variance problems

他还提出了普遍引用的偏差和方差之间的“权衡”。他解释说,在现代深度学习时代,我们有工具来分别解决每个问题,因此权衡不再存在。

第六课:正规化的直觉

为什么在成本函数中加入惩罚项会减少方差效应?在参加这个课程之前,我的直觉是,它迫使权重矩阵更接近于零,从而产生一个更“线性”的函数。Ng 给出了涉及 tanh 激活功能的另一种解释。其思想是较小的权重矩阵产生较小的输出,这将输出集中在双曲正切函数的线性部分周围。

tanh activation function

他还对辍学给出了一个有趣的直观解释。在参加这个课程之前,我认为辍学基本上是在每次迭代中杀死随机的神经元,所以这就好像我们在用一个更小的网络工作,这是更线性的。他的直觉是从单个神经元的角度看待生命。

Perspective from a single neuron

由于辍学是随机杀死连接,神经元被激励在它的父母之间更均匀地分配它的重量。通过展开权重,它往往具有缩小权重的平方范数的效果。他还解释说,辍学只不过是 L2 正则化的一种适应性形式,两种方法具有相似的效果。

第 7 课:为什么规范化有效?

Ng 演示了为什么归一化往往通过绘制等值线图来提高优化过程的速度。他明确地给出了一个在标准化和非标准化等高线图上迭代梯度下降的例子。

第 8 课:初始化的重要性

Ng 表明,参数的不良初始化会导致渐变消失或爆炸。他演示了几种解决这些问题的方法。基本思想是确保每层的权重矩阵的方差约为 1。他还讨论了 Xavier 初始化 tanh 激活函数。

第 9 课:为什么使用小批量梯度下降?

利用等高线图,ng 解释了小批量和大批量之间的权衡。基本的想法是,较大的规模会使每次迭代变得缓慢,而较小的规模允许您更快地取得进展,但是不能保证收敛。最好的方法是在两者之间做一些事情,这样可以比一次处理整个数据集的速度更快,同时还可以利用矢量化技术。

第十课:对高级优化技术的直观理解

Ng 解释了 momentum 和 RMSprop 等技术如何允许梯度下降来抑制其向最小值的路径。他还用一个球滚下山坡的过程给出了一个极好的物理解释。他将这些方法联系在一起,解释了著名的亚当优化过程。

第 11 课:基本的后端张量流理解

Ng 解释了如何使用 TensorFlow 实现神经网络,还解释了优化过程中使用的一些后端过程。其中一个家庭作业练习鼓励你使用张量流实现辍学和 L2 正则化。这进一步加强了我对后端流程的理解。

第 12 课:正交化

Ng 讨论了正交化在机器学习策略中的重要性。基本思想是,您希望实现一次只影响算法性能的单个组件的控件。例如,要解决偏差问题,您可以使用更大的网络或更强大的优化技术。您希望这些控件只影响偏差,而不影响其他问题,如泛化能力差。缺乏正交化的控制的一个例子是提前停止优化过程(提前停止)。这是因为它同时影响模型的偏差和方差。

第 13 课:单一数字评估指标的重要性

Ng 强调了选择一个单一数字评估指标来评估您的算法的重要性。如果您的目标发生了变化,那么您应该只在稍后的模型开发过程中更改评估指标。Ng 举了一个在猫分类应用中识别色情照片的例子!

第 14 课:测试/开发发行版

始终确保开发和测试集具有相同的分布。这确保了您的团队在迭代过程中瞄准了正确的目标。这也意味着,如果您决定纠正测试集中的标签错误的数据,那么您也必须纠正开发集中的标签错误的数据。

第 15 课:处理不同的培训和测试/开发发行版

Ng 给出了为什么一个团队对训练集和测试/开发集没有相同的分布感兴趣的原因。这个想法是,您希望评估度量是基于您真正关心的例子来计算的。例如,您可能希望使用与您的问题不相关的示例进行训练,但是您不希望根据这些示例来评估您的算法。这使得你的算法可以用更多的数据来训练。经验表明,这种方法在许多情况下会给你带来更好的性能。缺点是您的培训和测试/开发集有不同的发行版。解决方案是省去一小部分训练集,只确定训练集的泛化能力。然后,您可以将这个错误率与实际的开发错误进行比较,并计算一个“数据不匹配”度量。然后,Ng 解释了解决这种数据不匹配问题的方法,如人工数据合成。

第 16 课:培训/开发/测试规模

在深度学习时代,设置训练/开发/测试分离的指导方针发生了巨大的变化。在参加课程之前,我知道通常的 60/20/20 比例。Ng 强调,对于非常大的数据集,应该使用大约 98/1/1 甚至 99/0.5/0.5 的分割。这是因为开发和测试集只需要足够大,以确保团队提供的置信区间。如果您正在处理 10,000,000 个训练样本,那么 100,000 个样本(或 1%的数据)就足以保证您的开发和/或测试集有一定的置信度。

第 17 课:近似贝叶斯最优误差

Ng 解释了在某些应用中,如何将人的水平表现作为贝叶斯误差的代理。例如,对于视觉和音频识别等任务,人类水平的误差将非常接近贝叶斯误差。这允许你的团队量化你的模型中可避免的偏差的数量。如果没有贝叶斯误差这样的基准,就很难理解网络中的方差和可避免的偏差问题。

第十八课:错误分析

Ng 展示了一种显而易见的技术,通过使用误差分析来显著提高算法性能的有效性。基本思想是手动标记你的错误分类的例子,并把你的努力集中在对你的错误分类数据贡献最大的错误上。

Cat Recognition App Error Analysis

例如,在 cat 识别中,Ng 确定模糊图像是导致错误的最主要原因。这种敏感性分析可以让你看到在减少总误差上你的努力值多少钱。可能的情况是,修复模糊的图像是一项非常艰巨的任务,而其他错误是显而易见的,很容易修复。敏感性和近似工作量都将被纳入决策过程。

第 19 课:何时使用迁移学习?

转移学习允许您将知识从一个模型转移到另一个模型。例如,您可以将图像识别知识从猫识别应用程序转移到放射诊断。实施迁移学习包括用更多的数据重新训练用于类似应用领域的网络的最后几层。这个想法是,网络中早期的隐藏单元有更广泛的应用,它通常不特定于你使用网络的确切任务。总的来说,当两个任务有相同的输入特征,并且你试图学习的任务比你试图训练的任务有更多的数据时,迁移学习就起作用了。

第二十课:何时使用多任务学习?

多任务学习迫使单个神经网络同时学习多个任务(而不是每个任务都有一个单独的神经网络)。Ng 解释说,当一组任务可以从共享低级功能中受益,并且每个任务的数据量在数量上相似时,这种方法很有效。

第 21 课:何时使用端到端深度学习?

端到端深度学习需要多个阶段的处理,并将它们合并到单个神经网络中。这允许数据自己说话,而没有在优化过程中人工工程步骤中显示的偏差。相反,这种方法需要更多的数据,可能会排除潜在的手工设计的组件。

结论

Ng 的深度学习课程让我对深度学习模型开发流程有了一个基础的直观认识。我上面解释的课程仅仅代表了本课程中材料的一个子集。完成课程后,你不会成为深度学习的专家。我对这门课唯一的不满是家庭作业太简单了。我写这篇文章没有得到 deeplearning.ai 的背书。

这就是所有人——如果你已经做到了这一步,请在下面评论并在 LinkedIn 上加我。

我的 Github 是这里的。

对具有实体嵌入的结构化数据使用深度学习

原文:https://towardsdatascience.com/deep-learning-structured-data-8d6a278f3088?source=collection_archive---------0-----------------------

说明深度学习可以处理结构化数据,以及如何处理。

The idea of embeddings comes from learning them on words in NLP (word2vec), image taken from Aylien

在这篇博客中,我们将触及机器学习中两个反复出现的问题:第一个问题围绕着深度学习如何在图像和文本上表现良好,但我们如何在我们的表格数据上使用它?其次,在建立机器学习模型时,你必须经常问自己一个问题:我如何处理这个数据集中的分类变量?令人惊讶的是,我们可以用同一个答案来回答这两个问题:实体嵌入。

最近,深度学习在许多方面都超过了其他机器学习方法:图像识别、音频分类和自然语言处理只是许多例子中的一部分。这些研究领域都使用所谓的“非结构化数据”,即没有预定义结构的数据。一般来说,这些数据也可以被组织成一个序列(像素、用户行为、文本)。深度学习已经成为处理非结构化数据的标准。最近出现了深度学习是否也能在结构化数据上表现最好的问题。结构化数据是以表格格式组织的数据,其中列代表不同的要素,行代表不同的数据样本。这类似于数据在 Excel 表中的表示方式。目前,结构化数据集的黄金标准是梯度增强树模型(Chen & Guestrin,2016)。他们总是在 Kaggle 竞赛中表现最佳,在学术文献中也是如此。最近,深度学习已经表明,它可以在结构化数据上匹配这些增强的树模型的性能。实体嵌入在其中扮演着重要的角色。

Structured vs. unstructured data

实体嵌入

当在结构化数据上拟合神经网络时,实体嵌入已经被证明是成功的。例如,Kaggle 竞赛中预测出租车乘坐距离的获胜解决方案使用实体嵌入来处理每次乘坐的分类元数据(de Brébisson 等人,2015 年)。类似地,预测 Rossmann 药店销售额任务的第三名解决方案使用了比第一名和第二名解决方案简单得多的方法。该团队能够通过使用简单的前馈神经网络实现这一成功,该网络具有分类变量的实体嵌入。这包括超过 1000 个类别的变量,如商店 id (Guo & Berkahn,2016)。

如果这是你第一次阅读关于嵌入的文章,我建议你先阅读这篇文章。简而言之,嵌入指的是用向量来表示类别。让我们在一个短句上展示一下这是如何工作的:

深度学习是深刻的

我们可以用一个向量来表示每个单词,所以“deep”这个词就变成了类似于[0.20,0.82,0.45,0.67]的东西。在实践中,人们可以用 1 2 3 1 这样的整数来代替单词,并使用查找表来找到与每个整数相关联的向量。这种做法在自然语言处理中非常常见,也用于由行为序列组成的数据,如在线用户的旅程。实体嵌入指的是在分类变量上使用这个原则,其中分类变量的每个类别都由一个向量表示。让我们快速回顾一下机器学习中处理分类变量的两种常用方法。

  • 一键编码:创建二进制子特征,如 word_deep、word_learning、word_is。属于该数据点的类别为 1,其他类别为 0。因此,对于单词“deep ”,特征单词 _deep 将是 1,单词 _learning,单词 _is 等。将为 0。
  • 标签编码:像我们在前面的例子中那样分配整数,所以深度变成 1,学习变成 2,等等。这种方法适用于基于树的方法,但不适用于线性模型,因为它暗示了赋值的顺序。

实体嵌入基本上将标签编码方法提升到了一个新的层次,不仅仅是将一个整数分配给一个类别,而是分配给整个向量。这个向量可以是任何大小,并且必须由研究者指定。您可能想知道这些实体嵌入的优点是什么。

  1. 实体嵌入解决了一次性编码的缺点。用许多类别对变量进行一次性编码会导致非常稀疏的向量,这在计算上是低效的,并且使得更难达到优化。标签编码也解决了这个问题,但是只能被基于树的模型使用。
  2. 嵌入提供了关于不同类别之间距离的信息。使用嵌入的好处在于,分配给每个类别的向量也在神经网络的训练过程中得到训练。因此,在训练过程的最后,我们得到一个代表每个类别的向量。然后,这些经过训练的嵌入可以被可视化,以提供对每个类别的洞察。在 Rossmann 销售预测任务中,德国各州的可视化嵌入显示了与各州地理位置相似的聚类。即使这些地理信息对模型都不可用。
  3. 经过训练的嵌入可以被保存并在非深度学习模型中使用。例如,可以每个月训练分类特征的嵌入,并保存嵌入。然后,通过加载分类特征的学习嵌入,这些嵌入可用于训练随机森林或梯度增强树模型。

选择嵌入大小

嵌入大小指的是表示每个类别的向量的长度,并且可以为每个分类特征设置。类似于神经网络中超参数的调整过程,没有选择嵌入大小的硬性规则。在出租车距离预测任务中,研究人员对每个特征使用了 10 的嵌入大小。这些特性具有非常不同的维度,从 7(星期几)到 57106(客户端 id)不等。为每个类别选择相同的嵌入大小是一种简单且透明的方法,但可能不是最佳方法。

对于 Rossmann 商店销售预测任务,研究人员选择了一个介于 1 和 M(类别数量)-1 之间的值,最大嵌入大小为 10。例如,星期几(7 个值)的嵌入大小为 6,而商店 id (1115 个值)的嵌入大小为 10。然而,作者没有在 1 和 M-1 之间选择大小的明确规则。

杰瑞米·霍华德重建了罗斯曼竞赛的解决方案,并提出了以下选择嵌入尺寸的解决方案:

# c is the amount of categories per featureembedding_size = (c+1) // 2if embedding_size > 50: 
    embedding_size = 50

可视化嵌入

嵌入的一个优点是,所学习的嵌入可以被可视化以显示哪些类别彼此相似。最流行的方法是 t-SNE,这是一种降维技术,特别适用于可视化高维数据集。让我们用两个可视化嵌入的快速例子来结束这篇文章。以下是家得宝产品的可视化嵌入及其所属的类别。类似的产品如烤箱、冰箱和微波炉彼此非常接近。充电器、电池和电钻等产品也是如此。

Learned embeddings of home depot products.

另一个例子是本文前面提到的 Rossmann 销售预测任务中德国各州的学习状态嵌入。嵌入中各州之间的接近程度类似于它们的地理位置。

Example of the learned state embeddings for Germany

我希望我能够让你对嵌入和深度学习感兴趣。如果你喜欢这篇文章,一定要推荐给别人看。你也可以关注这个简介,跟上我在深度学习方面的进程。那里见!

我目前是一名微型公司的数据科学家。我们正在努力寻找数据工程师和软件工程师。我们也在为自己和我们的合作伙伴招募数据科学家,这些合作伙伴包括荷兰、以色列的一些最大的组织和一些大型全球公司!

通过 LinkedIn 联系我,加入我们在阿姆斯特丹或特拉维夫的团队,或者让我帮助您加入我们遍布全球的合作伙伴组织!

一定要看看我深度学习系列的其余部分:

  1. 设置 AWS &图像识别
  2. 卷积神经网络
  3. 更多关于 CNN&处理过度拟合
  4. 为什么你需要开始使用嵌入层

参考

陈,t .,& Guestrin,C. (2016 年 8 月)。Xgboost:一个可扩展的树提升系统。第 22 届 acm sigkdd 知识发现和数据挖掘国际会议论文集*(第 785–794 页)。ACM。*

德布雷比松,西蒙,埃。a .奥沃拉特、p .文森特和 y .本吉奥(2015 年)。人工神经网络在出租车终点预测中的应用。 arXiv 预印本 arXiv:1508.00021

郭,c .,,伯克哈恩,F. (2016)。分类变量的实体嵌入。 arXiv 预印本 arXiv:1604.06737

深度学习技巧和诀窍

原文:https://towardsdatascience.com/deep-learning-tips-and-tricks-1ef708ec5f53?source=collection_archive---------3-----------------------

以下是我与同龄人和学生就如何优化深度模型进行的对话、信息和辩论的精华集合。如果你有有效的方法,请分享出来!!

首先,为什么要调整模型?

像卷积神经网络(CNN)这样的深度学习模型有大量的参数;我们实际上可以称之为超参数,因为它们在模型中没有被优化。你可以搜索这些超参数的最佳值,但是你需要大量的硬件和时间。那么,一个真正的数据科学家会满足于猜测这些基本参数吗?

改进您的模型的最好方法之一是建立在对您的领域进行了深入研究的专家的设计和架构之上,这些专家通常拥有强大的硬件。优雅地,他们经常开源最终的建模架构和基本原理。

深度学习技术

这里有一些方法可以帮助你通过预先训练的模型来提高你的健身时间和准确性:

  1. 研究理想的预训架构: 了解迁移学习的好处,或者浏览一些强大的 CNN 架构。考虑那些看起来不明显的领域,但是共享潜在的潜在特征。
  2. 使用较小的学习率: 由于预训练的权重通常比随机初始化的权重好,所以修改要更细腻!你在这里的选择取决于学习环境和预训练的进展情况,但是检查跨时代的错误,以了解你离收敛有多近。
  3. 使用退出: 与回归模型的脊和套索正则化一样,所有模型都没有优化的 alpha退出。这是一个超参数,取决于您的具体问题,必须进行测试。从更大的变化开始——像np.logspace()可以提供的数量级的更宽的网格搜索跨度——然后像上面的学习率一样下降。
  4. 限制权重大小: 我们可以限制某些层的权重的最大范数(绝对值),以便推广我们的模型
  5. 不要碰第一层: 神经网络的第一个隐藏层往往会捕捉通用的和可解释的特征,如形状、曲线或跨领域的相互作用。我们应该经常不去管这些,而把重点放在优化更远的元潜在水平上。这可能意味着添加隐藏层,这样我们就不会匆忙的过程!
  6. 修改输出层: 用一个新的激活函数和适合你的域的输出大小替换模型默认值。但是,不要把自己局限在最明显的解决方案上。虽然 MNIST 可能看起来想要 10 个输出类,但一些数字有常见的变化,允许 12-16 个类可以更好地解决这些变化并提高模型性能!正如上面的提示一样,随着我们接近输出,深度学习模型应该越来越多地修改和定制。

喀拉斯的技术

以下是如何在 MNIST 的 Keras 中修改辍学和限制体重的方法:

# dropout in input and hidden layers
# weight constraint imposed on hidden layers
# ensures the max norm of the weights does not exceed 5model = Sequential()model.add(Dropout(0.2, input_shape=(784,))) # dropout on the inputs
# this helps mimic noise or missing datamodel.add(Dense(128, input_dim=784, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(5)))model.add(Dropout(0.5))model.add(Dense(128, kernel_initializer='normal', activation='tanh', kernel_constraint=maxnorm(5)))model.add(Dropout(0.5))model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))

辍学最佳实践:

  • 使用 20–50%的小压降,建议输入为 20%。太低,你的影响可以忽略不计;太高,你吃不饱。
  • 在输入图层和隐藏图层上使用 dropout。这已经被证明可以提高深度学习的性能。
  • 使用具有衰减和大动量的大学习率。
  • 约束你的体重!大的学习率会导致爆炸梯度。对网络权重施加约束条件(例如大小为 5 的最大范数正则化)已被证明可以改善结果。
  • 使用更大的网络。当在更大的网络上使用 dropout 时,您可能会获得更好的性能,从而为模型提供更多学习独立表示的机会。

以下是一个在 Keras 中对 MNIST 的 14 个类进行最终图层修改的示例:

**from** keras.layers.core **import** Activation, Densemodel**.**layers**.**pop() # defaults to last
model**.**outputs **=** [model**.**layers[**-**1]**.**output]
model**.**layers[**-**1]**.**outbound_nodes **=** []
model**.**add(Dense(14, activation**=**'softmax')) 

以及如何在前五层冻结权重的示例:

**for** layer **in** model**.**layers[:5]:
    layer**.**trainable **=** False

或者,我们可以将该层的学习速率设置为零,或者使用每个参数的自适应学习算法,如 Adadelta 或 Adam 。这有点复杂,最好在其他平台上实现,比如 Caffe。

预训练网络的图库:

Keras

  • 卡格尔列表
  • Keras 应用
  • OpenCV 示例

张量流

  • VGG16
  • 盗梦空间 V3
  • ResNet

火炬

  • LoadCaffe

咖啡馆

  • 模型动物园

在 Jupyter 中查看你的张量图

获得模型外观的视觉概念通常是很重要的。如果你在 Keras 中工作,抽象是很好的,但是不允许你深入模型的各个部分进行更深入的分析。幸运的是,下面的代码让我们可以直接用 Python 可视化我们的模型:

# From: [http://nbviewer.jupyter.org/github/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb](http://nbviewer.jupyter.org/github/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/deepdream/deepdream.ipynb)
# Helper functions for TF Graph visualization
from IPython.display import clear_output, Image, display, HTML
def 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 = bytes("<stripped %d bytes>"%size, 'utf-8')
    return strip_def

def rename_nodes(graph_def, rename_func):
    res_def = tf.GraphDef()
    for n0 in graph_def.node:
        n = res_def.node.add() 
        n.MergeFrom(n0)
        n.name = rename_func(n.name)
        for i, s in enumerate(n.input):
            n.input[i] = rename_func(s) if s[0]!='^' else '^'+rename_func(s[1:])
    return res_def

def 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" 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:800px;height:620px;border:0" srcdoc="{}"></iframe>
    """.format(code.replace('"', '&quot;'))
    display(HTML(iframe))# Visualizing the network graph. Be sure expand the "mixed" nodes to see their 
# internal structure. We are going to visualize "Conv2D" nodes.
graph_def = tf.get_default_graph().as_graph_def()
tmp_def = rename_nodes(graph_def, lambda s:"/".join(s.split('_',1)))
show_graph(tmp_def)

用 Keras 可视化你的模型

这将绘制出模型的图形,并将其保存为 png 文件:

**from** keras.utils **import** plot_model
plot_model(model, to_file='model.png')

plot采用两个可选参数:

  • show_shapes(默认为假)控制是否在图形中显示输出形状。
  • show_layer_names(默认为真)控制图层名称是否显示在图形中。

您也可以直接获得pydot.Graph对象并自己渲染它,例如在 ipython 笔记本中显示它:

**from** IPython.display **import** SVG
**from** keras.utils.visualize_util **import** model_to_dotSVG(model_to_dot(model).create(prog='dot', format='svg'))

希望这个合集对你的机器学习项目有所帮助!请在下面的评论中告诉我你是如何优化你的深度学习模型的,并在 Twitter 和 LinkedIn 上与我联系!

深度学习不平衡训练数据?这样解决。

原文:https://towardsdatascience.com/deep-learning-unbalanced-training-data-solve-it-like-this-6c528e9efea6?source=collection_archive---------0-----------------------

当我们处理任何机器学习问题时,我们面临的最大问题之一是不平衡的训练数据问题。不平衡数据的问题是这样的,学术界对其定义、含义和可能的解决方案存在分歧。我们将在这里尝试使用图像分类问题来揭开训练数据中不平衡类的秘密。

阶层不平衡的问题是什么?

在分类问题中,当在您想要预测的所有类别中,如果一个或多个类别的样本数量极低,您可能会面临数据中类别不平衡的问题。

例句

  1. 欺诈预测(欺诈数量将远低于真实交易)
  2. 自然灾害预测(坏事件会比好事件低很多)
  3. 在图像分类中识别恶性肿瘤(在训练样本中具有肿瘤的图像将比没有肿瘤的图像少得多)

为什么这是个问题?

由于两个主要原因,不平衡的类产生了一个问题:

  1. 对于实时不平衡的类,我们得不到优化的结果,因为模型/算法从未充分观察到底层的类
  2. 这就产生了一个制作验证或测试样本的问题,因为在少数类别的观察数量非常少的情况下,很难获得跨类别的表示

有哪些不同的方法可以解决这个问题?

提出了三种主要方法,各有利弊:

  1. 欠采样 -随机删除具有足够观察值的类别,以便两个类别的比较比率在我们的数据中是显著的。虽然这种方法非常简单,但是我们删除的数据很有可能包含关于预测类的重要信息。
  2. 过采样- 对于不平衡类,随机增加现有样本副本的观察值数量。理想情况下,这为我们提供了足够数量的样本。过采样可能导致过拟合训练数据
  3. **综合采样(SMOTE)——**该技术要求综合制造不平衡类的观测值,这类似于使用最近邻分类的现有观测值。问题是当的观测数是一个极其稀少的类时该怎么办。例如,我们可能只有一张稀有物种的图片,我们想使用图像分类算法对其进行识别

尽管每种方法都有自己的优点,但是对于何时使用哪种技术并没有特别的启发。我们现在将使用一个深度学习特定图像分类问题来详细研究这个问题。

图像分类中的不平衡类

在这一节中,我们将提出一个图像分类的问题,它有一个不平衡的分类问题,然后我们将使用一个简单有效的技术来解决它。

问题-我们在 kaggle 上发现了**“座头鲸识别挑战”**,我们预计这将是一个解决不平衡类别的挑战(因为理想情况下,分类的鲸鱼数量将少于未分类的鲸鱼数量,也将有一些稀有的鲸鱼物种,我们将有更少的图像数量)

来自 kaggle: “在这场比赛中,你面临的挑战是构建一个算法来识别图像中的鲸鱼种类。您将分析 Happy Whale 的超过 25,000 张图片的数据库,这些图片是从研究机构和公共贡献者那里收集的。通过做出贡献,你将有助于打开对全球海洋哺乳动物种群动态的丰富理解领域。”

让我们开始看数据

由于这是一个多标签图像分类问题,我首先想检查数据是如何跨类分布的。

上图表明,在 4251 幅训练图像中,超过 2000 幅的每类只有一幅图像。也有包含大约 2–5 个图像的类。现在,这是一个严重的阶级不平衡问题。我们不能期望 DL 模型只使用每类一个图像来训练(虽然有算法可以做到这一点,例如一个镜头分类,但我们现在忽略了这一点)。这也产生了如何在训练样本和验证样本之间创建分割的问题。理想情况下,您会希望每个类都在训练和验证样本中出现。

我们现在应该做什么?

我们特别考虑了两个选项:

选项 1-对训练样本进行严格的数据扩充(我们可以做到这一点,但由于我们只需要特定类别的数据扩充,这可能无法完全解决我们的目的)。因此我选择了选项 2,它看起来很简单,值得一试。

选项 2- 类似于我上面提到的过采样选项。我只是使用不同的图像增强技术将不平衡类的图像复制回训练数据中 15 次。这是受杰瑞米·霍华德的启发,我猜他在 part-1 fast.ai 课程 的一个深度学习讲座中提到过。

在我们开始选项-2 之前,让我们先来看看训练样本中的一些图像。

这些图像是鲸鱼的福禄克所特有的。因此,识别可能会非常具体的方式,图像将被定向。

我还注意到数据中有许多图像是 B&W 特有的或者只是 R/B/G 频道的。

基于这些观察,我决定编写以下代码,对来自训练样本中不平衡类的图像进行小的更改,然后保存它们:

import os
from PIL import Imagefrom PIL import ImageFilterfilelist = train['Image'].loc[(train['cnt_freq']<10)].tolist()for count in range(0,2):

  for imagefile in filelist:
    os.chdir('/home/paperspace/fastai/courses/dl1/data/humpback/train')
    im=Image.open(imagefile)
    im=im.convert("RGB")
    r,g,b=im.split()
    r=r.convert("RGB")
    g=g.convert("RGB")
    b=b.convert("RGB")
    im_blur=im.filter(ImageFilter.GaussianBlur)
    im_unsharp=im.filter(ImageFilter.UnsharpMask)

    os.chdir('/home/paperspace/fastai/courses/dl1/data/humpback/copy')
    r.save(str(count)+'r_'+imagefile)
    g.save(str(count)+'g_'+imagefile)
    b.save(str(count)+'b_'+imagefile)
    im_blur.save(str(count)+'bl_'+imagefile)
    im_unsharp.save(str(count)+'un_'+imagefile)

上述代码块对不平衡类(频率小于 10)中的每个图像执行以下操作:

  1. 将每个图像的增强副本保存为 R/B& G
  2. 保存每个模糊图像的增强副本
  3. 保存每个图像的放大副本

我们在这个练习中严格使用 pillow(一个 python 图像库),如上面的代码所示

现在我们有了所有不平衡类的至少 10 个样本。我们继续训练。

图像增强- 我们保持简单。我们只是想确保我们的模型能够获得鲸爪的详细视图。为此,我们将变焦纳入图像放大。

学习率查找器- 我们决定学习率为 0.01,标识为 lr find。

我们使用 Resnet50(首先冻结和解冻)进行了几次迭代。事实证明,冷冻模型也非常适合这个问题陈述,因为 imagenet 中有鲸豚的图像。

epoch      trn_loss   val_loss   accuracy                     
    0      1.827677   0.492113   0.895976  
    1      0.93804    0.188566   0.964128                      
    2      0.844708   0.175866   0.967555                      
    3      0.571255   0.126632   0.977614                      
    4      0.458565   0.116253   0.979991                      
    5      0.410907   0.113607   0.980544                      
    6      0.42319    0.109893   0.981097

这在测试数据上看起来如何?

终于到了卡格尔排行榜的关键时刻了。提出的解决方案在本次竞赛中排名第 34 位,平均精度为 0.41928:)

结论

有时,最符合逻辑的简单方法(如果没有更多数据,只需稍微修改一下现有数据,假装大部分课堂观察在模型的同一行上)是最有效的方法,可以更容易、更直观地完成工作。

使用设计思维的深度学习

原文:https://towardsdatascience.com/deep-learning-using-design-thinking-f0d20c8f0994?source=collection_archive---------7-----------------------

太多人认为人工智能是我们今天面临的许多问题的商业解决方案。

对于足够大的数据集,可能有一个神经网络可以帮助我们对问题做出决定,并影响用户。但是,为了有效地利用这些数据来创造产品,我们需要了解问题是否真的存在。我们需要理解人们,因为归根结底,消费产品驱动的公司会解决人们面临的问题。

首先,我们需要问自己,这个问题是一个真正的问题,还是只是创造性地应用人工智能的一个理由。在更广泛的范围内,我们需要问一问,将以人为中心的方法应用于数据科学是否是解决人工智能问题的一种方式。

许多行业领袖正成为这一想法的坚定支持者,

“我担心对人工智能的热情会阻止我们考虑它对社会的潜在影响,”李在文章中说。尽管它的名字,这项技术没有任何“人工”的成分——它是由人类制造的,旨在表现得像人类一样,并影响人类。因此,如果我们希望它在未来的世界中发挥积极作用,它必须以人类的关切为指导。”斯坦福大学的费·李非说

“一场人工智能革命正在进行中,但我认为它需要一场设计革命来补充,”德勤咨询 LLP 公司首席数据科学家 Jim Guszcza 说。

在感同身受和进行用户研究后,我们可以知道一个问题是否足够可行,可以使用人工智能来解决。在理解问题并研究其用例后,我们需要提出进一步的问题,以了解与常规预测算法相比,深度学习算法是否是一种方法。了解这一点的一些方法有:

  • 如果这是一个神经网络超越传统算法的问题
  • 如果很明显有足够的数据来训练。
  • 如果问题足够复杂。
  • 如果你有合适的神经网络来解决这个问题。

一旦我们确定人工智能是一个可行的解决方案,那么创建神经网络管道的步骤是:

  • 找出并定义最适合所需问题的神经网络架构
  • 将数据分成批次
  • 使用图像处理对数据进行预处理
  • 扩充数据以增加大小
  • 将批次输入神经网络进行训练
  • 测试您的模型,并保存它以供将来使用

可以认为这个管道使用了大卫·m·凯利提出的非常创新的 5 步设计思维方法。设计思维的过程,一种提供基于解决方案的方法来解决问题的设计方法。这些是使用设计思维进行深度学习可以遵循的步骤。

利用设计思维的深度学习

Source: https://infocus.dellemc.com/william_schmarzo/design-thinking-future-proof-yourself-from-ai/

第一步:同情和分析

设计思维过程的第一步是获得对你试图解决的问题和你的用户的移情理解。

设计思维:通过与人/用户交谈,咨询相关专家,或者深入问题以更好地理解问题,从而更好地理解你希望解决的问题。

深度学习:理解现实世界的消费者问题,其中神经网络的应用将对问题产生重大影响。神经网络并不能解决所有问题。我们需要从用户那里了解现实世界的问题,以便利用人工智能创造一些有意义的东西。我们可以从理解用户的关键决策开始,并捕捉能够更好地预测这些决策的变量和指标。

步骤 2:定义和综合

定义将移情步骤中获得的所有信息整合在一起,并分析数据以创建有意义的挑战陈述的方法。

设计思维:以人为中心,将问题定义为问题陈述。

深度学习:

  1. 根据正在解决的问题查找或综合数据集。
  2. 将数据加载到合适的位置。
  3. 准备数据—随机化、可视化以查看不平衡或关系、预处理、分割和扩充要发送用于训练的数据。
  4. 将数据分为训练、评估和测试。

第三步:构思

构思阶段是你设计过程中的一个阶段,在这个阶段你的目标是产生激进的设计方案。针对上一步中想到的问题,想出尽可能多的解决方案。

**设计思维:**利用前几个阶段的信息产生想法,集思广益,找出尽可能多的潜在解决方案。

**深度学习:**这一步为你的具体问题选择一个模型。已经为图像、诸如文本或音乐的序列、数字数据或基于文本的数据创建了许多模型。如果没有,您甚至可以通过一次添加一层来定义您自己的模型架构,直到您对您的网络满意为止。

步骤 4:原型和调整

原型制作生产出许多廉价的、按比例缩小的产品版本或产品中的特定功能。该团队将致力于创造一些具有特定功能的廉价产品。这允许设计思考者调查在设计思考过程的早期阶段识别的问题的可能解决方案。

**设计思维:**设计模型是基于前一阶段产生的所有想法而创建的。这些是实现构思概念的低保真度或高保真度线框。

深度学习:在这一步,我们使用训练数据来训练模型,然后我们开始操纵数据,并根据训练的结果来调整超参数。

步骤 5:测试和验证

测试是获得对你的解决方案的反馈,改进解决方案使之更好,并继续迭代概念的机会。

**设计思维:**我们使用用户测试技术测试我们的原型,看看它们在多大程度上解决了我们在前面阶段最初分析的问题。

**深度学习:**我们使用测试数据集测试模型,该数据集提供了用于评估模型的黄金标准。基于测试和验证的结果,我们迭代超参数调整的过程,以提高模型的准确性。

这可以总结为 3 个主要步骤:

  1. 研究和原型制作
  2. 为实际终端用户生产模型
  3. 现实世界中系统的改进

使用深度学习的设计思维为一些事情提供了一个框架和一个过程,否则会有许多步骤,并且是一个具有许多阶段的复杂过程。设计思维观有助于整合人工智能中以人为中心的解决问题的方式,并强调建立神经网络的迭代方式,就像设计师如何创造设计一样。

深度学习 vs 经典机器学习

原文:https://towardsdatascience.com/deep-learning-vs-classical-machine-learning-9a42c6d48aa?source=collection_archive---------0-----------------------

想获得灵感?快来加入我的 超级行情快讯 。😎

在过去的几年里,深度学习已经成为大多数人工智能类型问题的首选技术,使经典机器学习黯然失色。原因很明显,深度学习已经在包括语音、自然语言、视觉和玩游戏在内的各种任务上反复展示了其优越的性能。然而,尽管深度学习具有如此高的性能,但使用经典机器学习仍然有一些优势,而且在许多特定情况下,使用线性回归或决策树比使用大型深度网络更好。

在这篇文章中,我们将比较和对比深度学习和经典机器学习技术。在此过程中,我们将确定这两种技术的优缺点,以及它们的最佳使用位置和方式。

深度学习>经典机器学习

  • **同类最佳性能:**深度网络已经在包括语音、自然语言、视觉和玩游戏在内的许多领域实现了远超经典 ML 方法的准确性。在很多任务中,经典 ML 甚至无法抗衡。例如,下图显示了 ImageNet 数据集上不同方法的影像分类精度;蓝色表示经典的 ML 方法,红色表示深度卷积神经网络(CNN)方法。深度学习在这里把经典 ML 打得落花流水。

  • **有效地利用数据扩展:**深度网络在利用更多数据时比经典的 ML 算法扩展得更好。下图简单而有效地说明了这一点。通常,提高深度网络准确性的最佳建议就是使用更多的数据!对于经典的最大似然算法,这种快速而简单的修复甚至不能很好地工作,并且通常需要更复杂的方法来提高精度。

  • **不需要特征工程:**经典的 ML 算法往往需要复杂的特征工程。通常,首先对数据集进行深入的探索性数据分析。为了更容易处理,可以进行维数缩减。最后,必须仔细选择最佳特征以传递给 ML 算法。当使用深层网络时,没有必要这样做,因为人们可以直接将数据传递到网络,通常可以立即获得良好的性能。这完全消除了整个过程中庞大且具有挑战性的特征工程阶段。
  • **适应性和可移植性:**深度学习技术可以适应不同的领域和应用,远比经典的 ML 算法更容易。首先,迁移学习使得将预先训练的深度网络用于同一领域内的不同应用变得有效。例如,在计算机视觉中,预训练的图像分类网络经常被用作对象检测和分割网络的特征提取前端。使用这些预训练的网络作为前端简化了整个模型的训练,并且通常有助于在更短的时间内实现更高的性能。此外,不同领域中使用的深度学习的相同基本思想和技术通常是非常可移植的。例如,一旦理解了语音识别领域的底层深度学习理论,那么学习如何将深度网络应用于自然语言处理就不会太具挑战性,因为基线知识非常相似。对于经典的 ML,情况完全不同,因为构建高性能的 ML 模型需要特定领域和特定应用的 ML 技术和特征工程。不同领域和应用的经典 ML 的知识库是非常不同的,并且通常需要在每个单独的领域内进行广泛的专门研究。

经典机器学习>深度学习

  • **更适用于小数据:**为了实现高性能,深度网络需要非常大的数据集。前面提到的预训练网络是在120 万张图像上训练的。对于许多应用程序来说,这样的大型数据集并不容易获得,而且获取起来既昂贵又耗时。对于较小的数据集,经典的 ML 算法通常优于深度网络。
  • **财务和计算成本低廉:**深度网络需要高端 GPU 在合理的时间内用大数据进行训练。这些 GPU 非常昂贵,但没有它们,将深度网络训练到高性能实际上是不可行的。为了有效地使用这样的高端 GPU,还需要快速的 CPU、SSD 存储以及快速和大容量的 RAM。经典的最大似然算法只需要一个像样的 CPU 就可以很好地训练,不需要最好的硬件。因为它们在计算上不那么昂贵,所以人们也可以更快地迭代,并在更短的时间内尝试许多不同的技术。
  • **更容易解释:**由于经典 ML 中直接涉及的特征工程,这些算法相当容易解释和理解。此外,调整超参数和改变模型设计更加简单,因为我们对数据和底层算法有了更透彻的理解。另一方面,深层网络是非常“黑箱”的,因为即使现在研究人员也没有完全理解深层网络的“内部”。由于缺乏理论基础,超参数和网络设计也是一个相当大的挑战。

喜欢学习?

在推特上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

深度学习周刊:测试自动驾驶(虚拟)

原文:https://towardsdatascience.com/deep-learning-weekly-piece-testing-autonomous-driving-virtually-4839a8e68890?source=collection_archive---------10-----------------------

本周我将重点讨论深度学习如何用于自动驾驶汽车。在这个领域有很多机器学习应用,但我将聚焦于一项非常酷的技术:虚拟测试。

让我切入正题:下面是我的全自动驾驶汽车在虚拟测试环境中行驶的视频。诚然,虽然它看起来像一个 20 世纪 90 年代的复古(相当无聊)驾驶游戏,但这辆车是由深度卷积神经网络(CNN)控制的,该网络基于由 Nvidia 制作的深度学习算法的修改。

让我们深入了解一下这里发生了什么。我知道有些读者比其他人更熟悉自动驾驶技术的某些部分,所以我把它分成几个部分,这样你就可以跳到你感兴趣的部分。

自动驾驶汽车是如何工作的?

当我们开车时,我们会处理和解释周围成千上万的事情,因此自动驾驶汽车(SDC)软件也必须这样做。为了训练该软件,SDC 必须在路上行驶数千小时和数百万英里,以积累足够的信息来学习如何处理通常的道路情况,以及不寻常的情况(例如当一名坐在电动轮椅上的妇女在道路中间用扫帚追赶一只鸭子)。

为了节省令人难以置信的昂贵培训(这需要数千小时的安全驾驶员加上在公共道路上拥有训练车辆的安全风险),SDC 的开发者转向虚拟环境来训练他们的汽车。

SDC 通过车上的传感器(如摄像头、激光雷达、雷达、超声波、GPS 等)有效地“观察”其环境。)并将其转换为发送到汽车执行器的指令。最重要的命令是:

  1. 加速(油门 ) /减速(刹车)
  2. 向左/向右转动 X 度(转向)

虽然这种“转换”软件的细节和方法对于每个 SDC 开发者来说都是不同的,但它通常由一些本地化 ( 车在哪里?)、方位 ( 汽车面向哪个方向?),检测 ( 车周围有什么?)感知 ( 检测到的东西是交通信号还是行人或者其他车辆?)、 预测 ( 被检测到的东西接下来会做什么?)、 运动规划 *(汽车下一步应该移动到哪里?)、*和车辆命令 ( *向汽车的发动机、制动和转向发送信号)。*这些大多以机器和深度学习为核心。

在电子游戏中训练自动驾驶汽车

为真实道路驾驶进行上述转换的相同软件也可以用于虚拟测试环境。为了训练深度学习算法,我将驾驶一辆装有传感器的汽车在模拟器中的赛道上行驶几次(想象一下:任何赛车视频游戏),并记录传感器(在这种情况下,是摄像头)在模拟器中“看到”的图像。

例如,如果这是我在玩赛车游戏时看到的:

然后,我的虚拟汽车左、前、右的摄像头看到这个:

然后,我的代码会将这些图像转换成驾驶命令,这些命令会反馈到汽车的控制装置中(在模拟器中)。简而言之:

  • 虚拟传感器在视频游戏中“看到”他们周围的虚拟世界。
  • 在训练期间(当我驾驶汽车在赛道上行驶 ): 算法被教导将它看到的图像与我手动(即非自主)驾驶汽车在赛道上行驶的方式(油门和速度)相关联。这是标记的训练数据,它教授深度学习算法。
  • 例如,代码被教导将上述三个图像与“将方向盘转到 0.22 度,并将速度设置为 8.99 英里/小时”相关联。
  • 在推理过程中(当汽车在没有我控制的情况下自动驾驶 ): 代码看到它的环境- >将其输入训练好的算法- >算法输出速度和油门- >汽车更新它的速度和油门- >重复。

有很多模拟器可以用于这个训练(我用的是 Udacity 的开源模拟器)。

请注意,如果你玩的是侠盗猎车手,你的 Playstation/Xbox 会将你手持设备上的控制器转换成游戏中的信号。所以不难想象,它也可以像上面算法的“输出”一样,被不同的控制器控制。

Screenshot of Grand Theft Auto V.

那么算法是如何工作的呢?

这是基于一个深度卷积神经网络(CNN:见另一篇每周文章这里)的,它接收模拟器中摄像头捕捉的图像,并返回转向角度(我暂时将油门控制放在一边)。

我使用的神经网络架构类似于英伟达开创性的“自动驾驶汽车的端到端深度学习”神经网络,在这里和在这个架构中描述:

我的代码是使用 Tensorflow(与 Keras)和工作方式:

  • 裁剪图像,只关注前方的道路(而不是天空)
  • 标准化图像
  • 应用四个卷积层
  • 应用四个完全连接的层
  • 在我手动驾驶汽车在赛道上行驶四圈时收集的大约 40,000 张图像上进行训练
  • 应用随机优化(Adam 优化器)来减少转向角的均方误差。

它非常高效——它使用 GPU 支持(一个 g2.2xlarge AWS 实例),仅用两次迭代(称为纪元 ) 10 秒就训练了网络。对于那些感兴趣的人,这里是我的代码。

深度学习周刊:人工智能、人工智能和人工智能之间的差异

原文:https://towardsdatascience.com/deep-learning-weekly-piece-the-differences-between-ai-ml-and-dl-b6a203b70698?source=collection_archive---------2-----------------------

我想后退一步,把一些我们经常听到的术语放在上下文中,即“人工智能”(AI)、“机器学习”(ML)和“深度学习”(DL)。他们之间有什么区别?

免责声明:为了保持这个非常高的水平和简短,我不打算对每一个给出全面的解释。重点是对每一个以及它们之间的差异进行温和的介绍。

Source: Nvidia

1 .艾伦·图灵- >人工智能(AI)

艾伦·图灵(Alan Turing)是一名数学家、密码学家,他在二战中破译了英格玛机,他还是逻辑学家、哲学家、剑桥院士(22 岁)和超长距离赛跑运动员。他还为现代计算机和人工智能奠定了基础。

Alan Turing, photo taken before WW2. Source: turing.org.uk

他的作品在 20 世纪 50 年代渗透到了更广泛的公众知识中。这就产生了“通用人工智能”的概念:计算机能拥有和人类一样的智能特征吗,包括推理、互动和思考?答案是响亮的“不”(至少还没有)。

因此,我们不得不专注于“窄人工智能”——能够完成特定任务的技术,比如下棋、推荐你的下一个网飞电视节目,以及识别垃圾邮件。所有这些都展示了人类智慧的部分。但是它们是如何工作的呢?那是机器学习。

2 .人工智能- >机器学习(ML)

在高层次上,ML 通常意味着

  1. *数据:*获取大量(清理过的)数据,带有人为定义的特征(如“年龄”、“身高”、“FICO 评分”、“这是垃圾邮件吗?”等等。)
  2. 训练:利用数据“调优”各特征的相对重要性
  3. *推断:*根据新数据预测某事

这方面的一个例子是预测垃圾邮件:谷歌邮箱收集了大量关于什么是垃圾邮件和什么不是垃圾邮件的数据(这被称为“标记数据”)。然后,该算法识别垃圾邮件与非垃圾邮件的共同特征。然后,该算法对未标记数据(即新邮件)运行,以预测它们是否是垃圾邮件。

When you select spam messages, you are training Gmail’s ML algorithms to better predict future spam messages

ML 需要大量的人工干预,例如手动告诉垃圾邮件过滤器在垃圾邮件与非垃圾邮件中要查找什么(例如,查找“Western Union”/查找指向可疑网站的链接等)。).在图像上也不太准确。

3 .机器学习- >深度学习

DL 是 ML 的子集。它基于神经网络,这是一种自 20 世纪 50 年代以来就存在的大脑概念模型,但直到最近才被广泛忽视。这是因为它们的计算成本非常高,而且只是在最近,1)通过 GPU 和 FPGAs,处理变得足够便宜和强大,2)有足够的数据来感受 DL 算法。

DL 是以前帖子的重点,所以我不会重复太多细节,除了在高层次上,“深度”一词来自于 DL 算法是在深度神经网络上训练/运行的。这些只是(通常)有三层或更多“隐藏”层的神经网络。例如,每一层可以起到识别奥迪 A7 图片的不同特征的作用。

Abstraction of a DL algorithm (hence trained/run on a deep neural network) to recognize an image of an Audi A7. Source: ACM 2011, Lee et. al

深度学习周刊:什么是神经网络?

原文:https://towardsdatascience.com/deep-learning-weekly-piece-whats-a-neural-network-aa0df888d8a2?source=collection_archive---------3-----------------------

对于本周的文章,我想通过我收集的一个简单的例子来阐明什么是神经网络。我还对它进行了编码,因为我想向大家展示代码输出的各个部分——这是理解神经网络功能的重要部分。

例子:一个困惑的投资者的问题

假设你是一名风险投资家,想知道你应该投资哪些初创企业。你看了数百家初创企业,对每一家都写下:

  1. 他们已经筹集了多少钱
  2. 他们的员工中有百分之多少是工程师
  3. 他们最终是否成功,从 1(最成功)到 4(整个集群)

然后,您决定将这些信息放在一个图表中,在 x 轴上绘制(1)金钱,在 y 轴上绘制(2) %工程师。每个标记的颜色代表他们有多成功。你会发现:

x-axis = money raised (as a percentile of all companies you’ve seen), and y-axis = % of start up that are engineers, also normalized. DISCLAIMER: THIS IS ENTIRELY MADE UP DATA FOR ILLUSTRATIVE PURPOSES.

好吧…😕但是你从中学到了什么呢?不多。数据显示成功的初创企业总是筹集到更多的资金吗?不,不总是…成功的初创企业有更多的工程师吗?不,不总是…

因此,接下来你可以试着画线来区分成功创业和不成功创业的“区域”。你试着去做,但结果发现*真的很难。*这是你徒劳的尝试之一:

虽然你的数据显示,一般来说,拥有最多资金和工程师的公司更成功,但你应该把界限划在哪里?线下面有一堆绿色/蓝色的点,所以很明显这不是一条非常准确的线。

所以你有点卡住了…

“进来”神经网络

(请原谅投资者的双关语……)

上述问题被称为*分类:*给定一家初创公司的数据,你如何系统地对其成功进行分类。

神经网络只是模型,它接受关于“事物”的各种属性,然后对“事物”进行分类。例如,“事物”可以是一个初创企业(属性是筹集的资金和%的工程师),并对其成功程度进行分类。或者“东西”可以是美国选民(属性是她居住的城市和家庭收入),分类是她将投票给民主党还是共和党。

我不会深入讨论它们如何工作的血淋淋的细节,因为我想把重点放在这里的结果上,但是在一个高层次上,这就是你的启动分类示例的神经网络的样子:

The investor’s neural network, to predict the start ups’ success from 1 (very successful) to 4 (a total cluster). Only the first 6 rows are shown, but you’ll generally have thousands of rows / start ups.

这是一个全连接神经网络的例子,因为每个输入都连接到每个输出。输入中的每一行(即启动)都有两个值:筹集的资金和工程师百分比。输出是模型对创业成功的预测**。**

你可以在你的原始图表上想象这个神经网络,来显示你成功的“区域”:

Here we’ve centered both axes on zero, to compare to average.

这当然比你第一次尝试画的直线要好。但还是不太好,因为红色区域有一堆黄色点,蓝色区域有一堆绿色点,等等。

这就是“T2”隐藏层“T3”概念的由来。这意味着在输入和输出层之间附加一层节点(数学函数)。这些改进了模型,也允许非线性,这意味着这些区域不一定会被直线分割。下面是你的神经网络和一个单独的隐藏层的样子:

Your neural network with one hidden layer. The output is the model’s prediction about the start ups’ success level

同样,你可以在你的原始图表上看到这一点:

这是方式更好!你看到隐藏层是如何添加一些非线性的了吗?这个模型现在是一个更好的初创企业分类器。但是…它仍然不是完美的,因为一些蓝色的点延伸到绿色区域(在右边),一些红色的点进入橙色区域。因此,你可以通过在你的神经网络中添加第二个隐藏层来进一步改进这个,这意味着它看起来会像:

Your neural network with two hidden layers. Please don’t make me draw any more lines…

同样,我们可以在图表上直观地看到这一点,看看我们的模型对数据的分类有多好:

如你所见,这几乎是对你的初创企业的完美分类!一旦你验证并测试了这个模型(见下面的警告),你就可以使用这个神经网络来预测一家初创公司是否会成功,只需测量他们已经筹集了多少资金,以及初创公司的下属中有多少是工程师。

(如果你感兴趣,这里的是我上面的代码。)

重要警告

这篇文章的目的是向你展示神经网络是如何创建和工作的。我故意没有深入两个非常重要的概念:培训和验证。如果你想确保你的神经网络不是只对你给它的数据进行操作,这些是绝对重要的。

换句话说,你的神经网络只在你已经见过的初创企业中训练过。只有在你验证了它之后,你才能相信它在新公司(你还没见过的)上的结果。

*如果你对神经网络的工作方式感兴趣,这里有一个很棒的概述

深度学习:应该使用哪些损失和激活函数?

原文:https://towardsdatascience.com/deep-learning-which-loss-and-activation-functions-should-i-use-ac02f1c56aa8?source=collection_archive---------1-----------------------

这篇文章的目的是根据商业目标,为神经网络中最终层激活函数和损失函数的组合提供指导。

这篇文章假设读者了解激活函数。关于这些的概述可以在之前的帖子中看到:深度学习:神经元和激活功能概述

你想解决什么?

像所有机器学习问题一样,业务目标决定了你应该如何评估它的成功。

你是想预测一个数值吗?

例子:预测产品的合适价格,或者预测每天的销售数量

如果是这样,参见回归:预测数值一节

你想预测一个明确的结果吗?

例子:预测图像中看到的物体,或者预测对话的主题

如果是这样,接下来您需要考虑有多少个类以及您希望找到多少个标签。

如果您的数据是二进制的,它是或不是一个类(例如,欺诈、诊断、可能购买),请参见分类:预测二进制结果一节

如果你有多个类别(例如图像中的对象、电子邮件中的主题、适合做广告的产品)并且它们是排他性的——每个项目只有一个标签——参见分类:从多个类别中预测单个标签。如果您的数据中有多个标签,那么您应该查看章节分类:从多个类中预测多个标签

回归:预测数值

例如,预测产品价格

神经网络的最后一层将有一个神经元,它返回的值是一个连续的数值。

为了了解预测的准确性,将其与真实值进行比较,真实值也是一个连续的数字。

最终激活函数

线性 —这产生了我们需要的数值

或者

ReLU —这导致一个大于 0 的数值

损失函数

均方误差(MSE) —这是预测值和真实值之间的均方差

分类:预测二元结果

例如,预测交易是否属于欺诈

神经网络的最后一层将有一个神经元,并将返回一个介于 0 和 1 之间的值,可以推断为一个大概值。

为了了解预测的准确性,将其与真实值进行比较。如果数据是该类,则真值为 1,否则为 0。

最终激活函数

Sigmoid —这导致一个介于 0 和 1 之间的值,我们可以推断该模型对该类中的示例有多确信

损失函数

二元交叉熵 —交叉熵量化两个概率分布之间的差异。我们的模型预测{p,1-p}的模型分布,因为我们有一个二元分布。我们使用二进制交叉熵将其与真实分布{y,1-y}进行比较

分类:从多个类别中预测单个标签

例如预测文档的主题

神经网络的最后一层将为每个类别提供一个神经元,它们将返回一个介于 0 和 1 之间的值,可以推断为一个可能值。输出结果是一个概率分布,其总和为 1。

为了了解预测的准确性,将每个输出与其对应的真实值进行比较。真值已经过一次热编码,意味着 1 出现在对应于正确类别的列中,否则出现 0

最终激活函数

Softmax —这导致每个输出的值在 0 和 1 之间,总和为 1。因此,这可以推断为一个概率分布

损失函数

交叉熵 —交叉熵量化两个概率分布之间的差异。我们的模型预测了{p1,p2,p3}的模型分布(其中 p1+p2+p3 = 1)。我们使用交叉熵将其与真实分布{y1,y2,y3}进行比较

分类:从多个类别预测多个标签

例如,预测图像中动物的存在

神经网络的最后一层将为每个类别提供一个神经元,它们将返回一个介于 0 和 1 之间的值,可以推断为一个可能值。

为了了解预测的准确性,将每个输出与其对应的真实值进行比较。如果“真值”列中出现 1,则它对应的类别存在于数据中,否则出现 0。

最终激活函数

Sigmoid —这导致一个介于 0 和 1 之间的值,我们可以推断出它在该类中的置信度

损失函数

二元交叉熵 —交叉熵量化两个概率分布之间的差异。我们的模型预测每个类别的{p,1-p}(二元分布)的模型分布。我们使用二进制交叉熵将它们与每个类别的真实分布{y,1-y}进行比较,并总结它们的结果

一览表

下表总结了上述信息,以便您快速找到适合您的使用案例的最终层激活函数和损失函数

我希望这篇文章是有价值的!关于神经网络和最终激活函数的更多信息,请参见之前的帖子:

深度学习:神经元和激活功能概述

在朋友的帮助下进行深度学习

原文:https://towardsdatascience.com/deep-learning-with-a-little-help-from-my-friends-596ee10fd934?source=collection_archive---------7-----------------------

当你开始一个新的领域时,最好是从能回答你问题的好公司、朋友或好社区开始。深度认知的社区是一个学习和谈论深度学习的好地方,在这里我就和大家说说。

如果你在这里,很可能你正在开始学习深度学习或相关领域,或者你只是好奇。他们两个都很好。好了,我们的主题是在社区中学习,特别是深度学习。

深度学习是一个令人惊叹的领域,几乎渗透到我们周围的一切。谷歌正在使用它,脸书正在使用它,如果你使用智能手机、Instagram 或 Snapchat,你就是这个伟大领域的用户之一。

学习深度学习

现在学习一些东西可能是令人生畏的;这就是为什么我们相信我们的学校系统或大学系统能够帮助我们应对这一挑战。但是,如果你想学一些普通教室里没有的东西,会发生什么呢?

如果你停留在“常规”的学习方式中,那就没那么容易了。从这篇文章中你将学到的最重要的事情之一是,这是可能的,如果你遵循我将要告诉你的,它可能会更有趣或更容易。

深度学习是使用不同种类的神经网络和优化网络的超参数的表示学习,以获得(学习)我们数据的最佳表示。如果你觉得这听起来很奇怪,请阅读这些介绍:

[## 我的深度学习之旅

在这篇文章中,我将分享我如何研究深度学习并使用它来解决数据科学问题。这是一个…

towardsdatascience.com](/my-journey-into-deep-learning-c66e6ef2a317) [## 深度学习的“怪异”介绍

有关于深度学习的惊人介绍、课程和博文。但这是一种不同的介绍。

towardsdatascience.com](/a-weird-introduction-to-deep-learning-7828803693b0)

在朋友的帮助下学习

互联网给了我们与世界各地的人们一起学习的工具。我们有像 StackOverflow 、 Quora 、 LinkedIn 等许多很棒的平台,让我们可以和其他人见面、交谈、提问、获得答案,以及获得对几乎任何主题的观点。

我们也有 MOOCs,在那里我们可以与成千上万的人一起注册不同的课程,分享我们的学习经验和问题。

而学习深度学习的社区呢?

嗯,这就是 Deep Cognition 的人不久前创建的东西:一个结合了 StackOverflow、Quora 等最佳技术的平台,但其中的一切都是针对机器和深度学习的。

你现在要做的第一件事就是去那里注册:

[## 深度认知社区

一个活跃的社区,共同努力通过人工智能推动增长和创新。

community.deepcognition.ai](https://community.deepcognition.ai/)

好的,如果你现在在那里,你会在一个论坛中看到不同的主题。这些是像你我这样的人问的问题,整个社区都在努力帮助你。

深度认知社区

在社区内,你会发现不同的类别,在那里你可以看到关于计算机视觉、自然语言处理、数据准备,甚至如何在深度学习或机器学习中做 xy 的线程。

这是一个非常酷的地方来分享你的想法,并找到那些让你夜不能寐的问题的答案。

您还可以找到针对深度学习工作室(DLS)用户的几个不同主题的讨论。如果你不知道 DLS 是什么,看看我不久前制作的视频:

[## 深度认知的视频漫游

大家好!在本文中,我将与您分享几个视频,带您浏览深度认知的平台…

towardsdatascience.com](/a-video-walkthrough-of-deep-cognition-fd0ca59d2f76)

它基本上是一个 web IDE,在这里您可以使用非常棒的工具来创建深度学习模型、读取数据、调整参数以及部署模型。你也有深度学习笔记本,里面安装了所有的东西,所以你可以很快开始工作。

你还可以找到关于该公司正在创造的过去和新挑战的帖子,如令人敬畏的汽水瓶识别挑战。你可以在这里看到这条线索:

[## 汽水瓶识别挑战

这个挑战的目标是识别图像中出现的是哪一个汽水瓶。我们为您提供预先标记的…

community.deepcognition.ai](https://community.deepcognition.ai/t/soda-bottle-identification-challenge/267)

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

如果你没有时间在一个简单的帖子中阅读 100 个答案,有一个快速的方法来完成它。在社区中,他们有一个很酷的功能,叫做“总结这个话题”。

点击该按钮后,您将只能看到社区评为最有趣的帖子。你还想要什么?

所以不要再浪费时间了,去那里吧,开始和你的新朋友一起学习,玩得开心点:)。

感谢你阅读这篇文章。希望你在这里发现了一些有趣的东西:)

如果您有任何问题,请在 twitter 上添加我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/FavioVaz)

和 LinkedIn:

[## Favio Vázquez —首席数据科学家— OXXO | LinkedIn

查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 15 个工作职位列在…

linkedin.com](http://linkedin.com/in/faviovazquez/)

那里见:)

使用 Apache Spark 进行深度学习—第 1 部分

原文:https://towardsdatascience.com/deep-learning-with-apache-spark-part-1-6d397c16abd?source=collection_archive---------0-----------------------

第一部分全面讨论了如何使用 Apache Spark 进行分布式深度学习。这部分:什么是 Spark,关于 Spark+DL 的基础知识以及更多。你可以在这里阅读第二部分:用 Apache Spark 进行深度学习——第二部分。

第二部分可以在这里找到:用 Apache Spark 进行深度学习——第二部分。

Apache Spark 入门

如果您在数据领域工作,您很可能知道 Apache Spark 是什么。如果你没有,那也没关系!我来告诉你是什么。

Apache Spark TM.

Spark,被它的创造者定义为一个用于大规模数据处理的快速通用引擎。

快速部分意味着它比以前处理大数据的方法(如经典的 MapReduce)更快。更快的秘密是 Spark 在内存(RAM)上运行,这使得处理速度比在磁盘上快得多。

通用部分意味着它可以用于多种用途,比如运行分布式 SQL、创建数据管道、将数据接收到数据库中、运行机器学习算法、处理图形、数据流等等。

RDD

From PySpark-Pictures by Jeffrey Thompson.

Apache Spark 的主要抽象和开端是弹性分布式数据集(RDD)。

RDD 是可以并行操作的容错元素集合。您可以在驱动程序中并行化现有集合,或者引用外部存储系统中的数据集来创建它们,例如共享文件系统、HDFS、HBase 或任何提供 Hadoop InputFormat 的数据源。

关于 Spark,需要知道的非常重要的一点是,所有的转换(我们将很快定义它)都是懒惰的,这意味着它们不会立即计算出结果。相反,他们只记得应用于某个基本数据集(如文件)的转换。仅当动作需要将结果返回给驱动程序时,才会计算转换。

默认情况下,每次对变换后的 RDD 执行操作时,都会对其进行重新计算。然而,您也可以使用持久化(或缓存)方法在内存中持久化一个 RDD,在这种情况下,Spark 会将元素保留在集群上,以便下次查询时可以更快地访问。还支持在磁盘上持久化 rdd,或者跨多个节点复制 rdd。

如果您想了解 Spark 中 rdd 的转换和操作的更多信息,请查看官方文档:

[## RDD 编程指南- Spark 2.3.0 文档

Java、Scala 和 Python 中的 Spark 2.3.0 编程指南

spark.apache.org](https://spark.apache.org/docs/latest/rdd-programming-guide.html#transformations)

数据框架

From PySpark-Pictures by Jeffrey Thompson.

从 Spark 2.0.0 a 开始,数据帧就是一个组织成指定列的数据集。它在概念上相当于关系数据库中的一个表或 R/Python 中的一个数据框,但是在底层有更丰富的优化。

我们不会在这里讨论数据集,但是它们被定义为一个分布式的数据集合,可以从 JVM 对象中构造,然后使用函数转换进行操作。它们只在 Scala 和 Java 中可用(因为它们是类型化的)。

数据帧可以由各种各样的源构建,例如:结构化数据文件、Hive 中的表、外部数据库或现有的 rdd。

https://aspgems.com/blog/big-data/migrando-de-pandas-spark-dataframes

简而言之,Dataframes API 是 Spark 创造者简化框架中数据处理的方式。它们非常类似于 Pandas 数据帧或 R 数据帧,但有几个优点。首先,它们可以分布在一个集群中,因此可以处理大量数据;其次,它们经过了优化。

这是社区迈出的非常重要的一步。到 2014 年,将 Spark 与 Scala 或 Java 一起使用要快得多,因为性能的原因,整个 Spark 世界都变成了 Scala(顺便说一句,这是一种非常棒的语言)。但是有了 DF API,这不再是一个问题,现在您可以在 R、Python、Scala 或 Java 中使用它获得相同的性能。

负责这种优化的是催化剂。你可以把它想象成一个向导,他会接受你的询问(哦,是的!,您可以在 Spark 中运行类似 SQL 的查询,在 DF 上运行它们,它们也会被并行化)和您的操作,并创建一个优化的计划来分配计算。

过程没那么简单,但是作为程序员的你根本不会注意到。现在它一直在那里帮助你。

深度学习和 Apache Spark

https://becominghuman.ai/building-an-image-classifier-using-deep-learning-in-python-totally-from-a-beginners-perspective-be8dbaf22dd8

如果你想了解更多关于深度学习的知识,请在继续之前阅读这些帖子:

[## 深度学习的“怪异”介绍

有关于深度学习的惊人介绍、课程和博文。但这是一种不同的介绍。

towardsdatascience.com](/a-weird-introduction-to-deep-learning-7828803693b0) [## 我的深度学习之旅

在这篇文章中,我将分享我如何研究深度学习并使用它来解决数据科学问题。这是一个…

towardsdatascience.com](/my-journey-into-deep-learning-c66e6ef2a317)

为什么要在 Apache Spark 上做深度学习?

这是我在开始研究这个课题之前问自己的问题。对我来说,答案分为两部分:

  1. Apache Spark 是一个惊人的框架,它以一种简单的声明式方式在集群中分布计算。正在成为各行各业的标准,因此将深度学习的惊人进步加入其中将是一件好事。
  2. 深度学习有些部分计算量很大,非常大!分发这些进程可能是解决这个和其他问题的方法,Apache Spark 是我能想到的分发它们的最简单的方法。

使用 Apache Spark 进行深度学习有几种方法,我之前讨论过,我在这里再次列出(不详尽):

1.大象:分布式 DL 带 Keras & PySpark:

[## maxpumperla/elevas

elephas——使用 Keras & Spark 的分布式深度学习

github.com](https://github.com/maxpumperla/elephas)

2**。雅虎!Inc.** : TensorFlowOnSpark:

[## 雅虎/tensorflownspark

TensorFlowOnSpark 将 TensorFlow 程序引入 Apache Spark 集群

github.com](https://github.com/yahoo/TensorFlowOnSpark)

3。CERN 分布式 Keras (Keras + Spark):

[## cerndb/dist-keras

dist-keras——分布式深度学习,侧重于分布式培训,使用 Keras 和 Apache Spark。

github.com](https://github.com/cerndb/dist-keras)

4。Qubole (教程 Keras + Spark):

[## 基于 Apache Spark | Qubole 的 Keras 分布式深度学习

深度学习已经被证明可以在不同的领域产生高效的机器学习模型。一些…

www.qubole.com](https://www.qubole.com/blog/distributed-deep-learning-keras-apache-spark/)

5。英特尔公司:BigDL(Apache Spark 分布式深度学习库)

[## 英特尔分析/BigDL

BigDL:Apache Spark 的分布式深度学习库

github.com](https://github.com/intel-analytics/BigDL)

深度学习管道

Databricks

但是我将在这些文章中重点关注的是深度学习管道。

[## 数据砖块/火花深度学习

Spark-深度学习 Apache Spark 的深度学习管道

github.com](https://github.com/databricks/spark-deep-learning)

深度学习管道(Deep Learning Pipelines)是一个由 Databricks 创建的开源库,它使用 Apache Spark 为 Python 中的可扩展深度学习提供了高级 API。

这是一个令人敬畏的努力,它不会很久,直到被合并到官方的 API,所以值得一看。

与我之前列出的相比,这个库的一些优点是:

  • 本着 Spark 和 Spark MLlib 的精神,它提供了易于使用的 API,可以在很少的几行代码中实现深度学习。
  • 它侧重于易用性和集成,而不牺牲性能。
  • 它是由 Apache Spark 的创建者(也是主要贡献者)构建的,因此它比其他 API 更有可能被合并为一个官方 API。
  • 它是用 Python 编写的,所以它将与所有著名的库集成,现在它使用 TensorFlow 和 Keras 这两个目前主要的库来做 DL。

在下一篇文章中,我将完全关注 DL pipelines 库以及如何从头开始使用它。您将看到的一件事情是在简单的管道上转移学习,如何使用预先训练的模型处理“少量”数据并能够预测事情,如何通过在 SQL 中提供您创建的深度学习模型来增强公司中每个人的能力,等等。

此外,我将创建一个环境,在深度认知平台中使用这个库在笔记本上工作,这样您就可以测试一切。如果您还没有帐户,请创建一个免费帐户:

[## 深度认知——今天就成为一个人工智能驱动的组织

无需编码即可设计、训练和部署深度学习模型。深度学习工作室简化并加速了…

deepcognition.ai](http://deepcognition.ai)

哦!!顺便说一句,如果你想了解更多关于 Python 数据科学中的管道的知识,可以看看 Matthew Mayo 写的这些好文章:

[## 用 Scikit-learn 管道管理机器学习工作流第 1 部分:简介

你熟悉 Scikit-learn 管道吗?它们是管理机器的一个非常简单但非常有用的工具…

www.kdnuggets.com](https://www.kdnuggets.com/2017/12/managing-machine-learning-workflows-scikit-learn-pipelines-part-1.html) [## 使用 Scikit-learn 管道管理机器学习工作流第 2 部分:集成网格搜索

在我们的上一篇文章中,我们将 Scikit-learn 管道视为简化机器学习工作流程的一种方法。

www.kdnuggets.com](https://www.kdnuggets.com/2018/01/managing-machine-learning-workflows-scikit-learn-pipelines-part-2.html) [## 使用 Scikit 管理机器学习工作流-学习管道第 3 部分:多模型,管道…

首先,我知道我承诺过我们会在上一篇文章中讨论玩具数据集,但是为了便于比较,我们会…

www.kdnuggets.com](https://www.kdnuggets.com/2018/01/managing-machine-learning-workflows-scikit-learn-pipelines-part-3.html)

关于 Spark 管道的简介,请查看:

[## ML 管道- Spark 2.3.0 文档

估计器抽象了学习算法或任何适合或训练数据的算法的概念。技术上…

spark.apache.org](https://spark.apache.org/docs/latest/ml-pipeline.html)

一会儿见:)

如果您想联系我,请务必在 twitter 上关注我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

和 LinkedIn:

[## Favio Vázquez -数据科学家/工具经理 MX - BBVA 数据&分析| LinkedIn

查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 13 个工作职位列在…

www.linkedin.com](https://www.linkedin.com/in/faviovazquez/)

使用 Apache Spark 进行深度学习—第 2 部分

原文:https://towardsdatascience.com/deep-learning-with-apache-spark-part-2-2a2938a36d35?source=collection_archive---------1-----------------------

第二部分全面讨论了如何使用 Apache Spark 进行分布式深度学习。我将完全专注于 DL pipelines 库以及如何从头开始使用它。你将看到的事情之一是在一个简单的管道上转移学习,如何使用预先训练的模型来处理“少量”数据,以及能够预测事情等等。

By my sister https://www.instagram.com/heizelvazquez/

大家好,欢迎回来学习:)。在本文中,我将继续讨论 Apache Spark 的深度学习。这里可以看到第一部。

在这一部分中,我将完全专注于 DL pipelines 库以及如何从头开始使用它。

Apache Spark 时间表

Apache Spark 的不断改进让我们开始讨论如何利用它进行深度学习。我创建了一个详细的 Apache Spark 开发时间表,看看我们是如何走到这一步的。

很快我会写一篇文章来描述这个时间线,但是如果你觉得有什么遗漏,请告诉我:)

深度学习管道

Databricks

深度学习管道(Deep Learning Pipelines)是一个由 Databricks 创建的开源库,它使用 Apache Spark 为 Python 中的可扩展深度学习提供了高级 API。

[## 数据砖块/火花深度学习

Spark-深度学习 Apache Spark 的深度学习管道

github.com](https://github.com/databricks/spark-deep-learning)

这是一个令人敬畏的努力,它不会很久,直到被合并到官方的 API,所以值得一看。

与结合 Spark 和 DL 的库相比,这个库的一些优点是:

  • 本着 Spark 和 Spark MLlib 的精神,它提供了易于使用的 API,可以在很少的几行代码中实现深度学习。
  • 它侧重于易用性和集成,而不牺牲性能。
  • 它是由 Apache Spark 的创建者(也是主要贡献者)构建的,因此它比其他 API 更有可能被合并为一个官方 API。
  • 它是用 Python 编写的,所以它将与所有著名的库集成,现在它使用 TensorFlow 和 Keras 这两个目前主要的库来做 DL。

深度学习管道建立在 Apache Spark 的 ML 管道之上,用于训练,并使用 Spark 数据帧和 SQL 来部署模型。它包括深度学习常见方面的高级 API,因此可以在几行代码中高效地完成:

  • 图像加载
  • 在 Spark ML 管道中应用预训练模型作为变压器
  • 迁移学习
  • 大规模应用深度学习模型
  • 分布式超参数调整**(下一部分)**
  • 在数据框架和 SQL 中部署模型

我将通过例子详细描述这些特性。这些例子来自 Databricks 的官方笔记本。

深度认知的阿帕奇火花

要运行和测试本文中的代码,你需要在深度认知中创建一个账户。

非常简单,然后您就可以访问它们的所有功能。当您登录时,您应该会看到以下内容:

现在只需点击左边部分,笔记本按钮:

你将会在 Jupyter 笔记本上安装所有的软件包:)。哦!这里有一个说明:火花笔记本(DLS 火花)是一个即将到来的功能,将于下个月的某个时候向公众发布,并告知它仍处于私人测试阶段(仅为本文)。

您可以在这里下载完整的笔记本来查看所有代码:

https://github.com/FavioVazquez/deep-learning-pyspark

图像加载

对图像应用深度学习的第一步是加载图像的能力。深度学习管道包括实用功能,可以将数百万张图像加载到数据帧中,并以分布式方式自动解码,从而实现大规模操作。spark 的新版本(2.3.0)也有这个能力,但是我们将使用 sparkdl 库。

我们将使用 TensorFlow 策划的知识共享许可花卉照片档案来测试这一点。要获得花卉照片集,请从笔记本中运行以下命令(我们还将创建一个示例文件夹):

https://gist.github.com/FavioVazquez/33350294e31213ff761bf2ff51e25c4a

让我们从郁金香和雏菊文件夹中复制一些照片,创建一个小的照片样本。

https://gist.github.com/FavioVazquez/8ce726807f6074c05a779ee4e5e3a4d0

要在笔记本上查看这些图像,您可以运行以下命令:

https://gist.github.com/FavioVazquez/efaa901f85b51c77d520595136a2cb52

你应该看看这个

现在让我们使用 Spark 将这些图像作为数据帧加载。方法spark.readImage可以让你读取普通格式的图像(jpg,png 等)。)从 HDFS 存储器转换成数据帧。每个图像都以 imageSchema 格式存储为一行。递归选项允许您从子文件夹中读取图像,例如阳性和阴性标签样本。sampleRatio 参数允许您在使用完整数据训练模型之前使用较小的图像样本进行实验。

https://gist.github.com/FavioVazquez/85266329b7ef31411600f33c3b9eee1e

如果我们看一下这个数据帧,我们会看到它创建了一个列,称为“image”。

image_df.show()+--------------------+
|               image|
+--------------------+
|[file:/Users/favi...|
|[file:/Users/favi...|
|[file:/Users/favi...|
+--------------------+

image 列包含一个字符串列,该列包含一个 image 结构,schema == ImageSchema。

迁移学习

Databricks

深度学习管道提供了在图像上执行转移学习的实用程序,这是开始使用深度学习的最快(代码和运行时)方式之一。使用深度学习管道,只需几行代码就可以完成。

深度学习管道通过特征的概念实现快速迁移学习。下面的例子结合了 InceptionV3 模型和 Spark 中的逻辑回归,使 InceptionV3 适应我们的特定领域。deepimagefeaturezer 自动剥离预训练神经网络的最后一层,并使用所有先前层的输出作为逻辑回归算法的特征。由于逻辑回归是一种简单而快速的算法,这种迁移学习训练可以使用比从头开始训练深度学习模型通常所需的图像少得多的图像来快速收敛。

首先,我们需要为迁移学习创建训练和测试数据框架。

https://gist.github.com/FavioVazquez/84b0201f2ec0cbfc64fa3736bc7a76b5

现在我们来训练这个模型

https://gist.github.com/FavioVazquez/96e13301b6286eb7b52f34faedce4c24

让我们看看这个模型有多好:

https://gist.github.com/FavioVazquez/27fa7de28011d41b192d723a185a9b87

Test set accuracy = 0.9753086419753086

对于一个例子来说还不算太坏,而且根本没有调整!

我们可以看看我们在哪里犯了错误:

https://gist.github.com/FavioVazquez/dcd72fe4f0f4204736d46ba57112cb97

大规模应用深度学习模型

深度学习管道支持使用 Spark 以分布式方式运行预训练的模型,可用于批处理和流数据处理。

它包含一些最受欢迎的模型,使用户能够开始使用深度学习,而无需训练模型的昂贵步骤。当然,该模型的预测是与 Spark 带来的所有好处并行完成的。

除了使用内置模型,用户还可以在火花预测管道中插入 Keras 模型和张量流图。这将单节点工具上的任何单节点模型转变为可以在大量数据上以分布式方式应用的模型。

下面的代码使用 InceptionV3 创建了一个火花预测管道,这是一个用于图像分类的最先进的卷积神经网络(CNN)模型,并预测我们刚刚加载的图像中有哪些对象。

https://gist.github.com/FavioVazquez/b6e4ab8787f4bd4a7186d858a86c3521

让我们来看看预测数据框:

predictions_df.select("predicted_labels").show(truncate=False,n=3)+----------------+
|predicted_labels|                                                                                                                                                                                                                                                                                                                                            |                |
+----------------+
|[[n03930313, picket_fence, 0.1424783], **[n11939491, daisy, 0.10951301]**, [n03991062, pot, 0.04505], [n02206856, bee, 0.03734662], [n02280649, cabbage_butterfly, 0.019011213], [n13133613, ear, 0.017185668], [n02219486, ant, 0.014198389], [n02281406, sulphur_butterfly, 0.013113698], [n12620546, hip, 0.012272579], [n03457902, greenhouse, 0.011370744]]            ||**[[n11939491, daisy, 0.9532104]**, [n02219486, ant, 6.175268E-4], [n02206856, bee, 5.1203516E-4], [n02190166, fly, 4.0093894E-4], [n02165456, ladybug, 3.70687E-4], [n02281406, sulphur_butterfly, 3.0587992E-4], [n02112018, Pomeranian, 2.9011074E-4], [n01795545, black_grouse, 2.5667972E-4], [n02177972, weevil, 2.4875381E-4], [n07745940, strawberry, 2.3729511E-4]]||**[[n11939491, daisy, 0.89181453]**, [n02219486, ant, 0.0012404523], [n02206856, bee, 8.13047E-4], [n02190166, fly, 6.03804E-4], [n02165456, ladybug, 6.005444E-4], [n02281406, sulphur_butterfly, 5.32096E-4], [n04599235, wool, 4.6653638E-4], [n02112018, Pomeranian, 4.625338E-4], [n07930864, cup, 4.400617E-4], [n02177972, weevil, 4.2434104E-4]]                    |
+----------------+
only showing top 3 rows

请注意,predicted_labels列显示“雏菊”是使用此基础模型的所有样本花的高概率类别,由于某种原因,郁金香更接近于栅栏而不是花(可能是因为照片的背景)

然而,从概率值的差异可以看出,神经网络具有辨别两种花类型的信息。因此,我们上面的迁移学习示例能够从基础模型开始正确地学习雏菊和郁金香之间的差异。

让我们看看我们的模型如何辨别花的类型:

https://gist.github.com/FavioVazquez/271c069453b5917d85aeec0001d54624

对于 Keras 用户

为了使用 Spark 以分布式方式应用 Keras 模型,[KerasImageFileTransformer](https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/6026450283250196/3874201704285756/7409402632610251/link_here)在 TensorFlow 支持的 Keras 模型上工作。它

  • 通过将用户指定的图像加载和处理功能应用于包含一列图像 URIs 的输入数据帧,在内部创建包含一列图像的数据帧
  • 从给定的模型文件路径加载 Keras 模型
  • 将模型应用于图像数据帧

要使用 transformer,我们首先需要将 Keras 模型存储为一个文件。对于这款笔记本,我们将只保存 Keras 内置的 InceptionV3 模型,而不是训练模型。

https://gist.github.com/FavioVazquez/bc7d280cd98a7112cb96f13cded20259

现在我们将创建一个 Keras 转换器,但首先我们将预处理图像来使用它

https://gist.github.com/FavioVazquez/b1a43d8611e1fd2db9a3c61742156e97

我们现在将读取图像并将它们加载到 Spark 数据帧中,然后使用我们的转换器将模型应用到图像中:

https://gist.github.com/FavioVazquez/531c2852f936e4a2cbbe2f4afbad47d5

如果我们看一下这个带有预测的数据框架,我们会看到很多信息,这只是概念 3 模型中每一类的概率。

使用一般张量

深度学习管道还提供了应用具有张量输入(高达 2 维)的模型的方法,这些模型是在流行的深度学习库中编写的:

  • 张量流图
  • Keras 模型

在本文中,我们将只关注 Keras 模型。KerasTransformer将 TensorFlow 支持的 Keras 模型应用于高达 2 维的张量输入。它从给定的模型文件路径加载一个 Keras 模型,并将该模型应用于一列数组(其中一个数组对应一个张量),输出一列数组。

https://gist.github.com/FavioVazquez/bab4fbf9c39aade9b92dbbea95127cec

final_df.show()+-------------+--------------------+
|  predictions|            features|
+-------------+--------------------+
| [0.86104786]|[-0.76344526, 0.2...|
| [0.21693115]|[0.41084298, 0.93...|
|[0.057743043]|[0.062970825, 0.3...|
| [0.43409333]|[-0.43408343, -1....|
| [0.43690935]|[-0.89413625, 0.8...|
| [0.49984664]|[-0.82052463, -0....|
|  [0.6204273]|[-0.5075533, 0.54...|
|  [0.2285336]|[0.016106872, -0....|
| [0.37478408]|[-1.6756374, 0.84...|
|  [0.2997861]|[-0.34952268, 1.2...|
|  [0.3885377]|[0.1639214, -0.22...|
|  [0.5006814]|[0.91551965, -0.3...|
| [0.20518135]|[-1.2620118, -0.4...|
| [0.18882117]|[-0.14812712, 0.8...|
| [0.49993372]|[1.4617485, -0.33...|
| [0.42390883]|[-0.877813, 0.603...|
|  [0.5232896]|[-0.031451378, -1...|
| [0.45858437]|[0.9310042, -1.77...|
| [0.49794272]|[-0.37061003, -1....|
|  [0.2543479]|[0.41954428, 1.88...|
+-------------+--------------------+
only showing top 20 rows

在 SQL 中部署模型

将模型生产化的一种方法是将其部署为 Spark SQL 用户定义函数,这允许任何懂 SQL 的人使用它。深度学习管道提供了采用深度学习模型和注册Spark SQL 用户定义函数(UDF)的机制。特别是,深度学习管道 0.2.0 增加了对从处理图像数据的 Keras 模型创建 SQL UDFs 的支持。

得到的 UDF 接受一个列(格式化为图像结构“SpImage”)并产生给定 Keras 模型的输出;例如,对于 Inception V3,它在 ImageNet 对象类别上产生实值分数向量。

https://gist.github.com/FavioVazquez/3a36edf25a289f4ee31cff1bf3857467

在处理图像的 Keras 工作流中,在将模型应用于图像之前,通常会有预处理步骤。如果我们的工作流需要预处理,我们可以选择为 UDF 注册提供预处理功能。预处理器应该接收一个文件路径并返回一个图像数组;下面是一个简单的例子。

https://gist.github.com/FavioVazquez/a02094a5848ab1f7e42ce52820a09fbe

注册 UDF 后,可以在 SQL 查询中使用它:

https://gist.github.com/FavioVazquez/af566a98d19952eb0b61938c4752f7dc

这个很厉害。一旦数据科学家构建了所需的模型,深度学习管道就可以轻松地将其作为 SQL 中的函数公开,因此他们组织中的任何人都可以使用它-数据工程师、数据科学家、业务分析师,任何人。

sparkdl.registerKerasUDF("awesome_dl_model", "/mymodels/businessmodel.h5")

接下来,组织中的任何用户都可以在 SQL 中应用预测:

SELECT image, awesome_dl_model(image) label FROM images 
WHERE contains(label, “Product”)

在下一部分中,我将讨论使用 Spark 进行分布式超参数调优,并将尝试新的模型和示例:)。

如果您想联系我,请务必在 twitter 上关注我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

和 LinkedIn:

用数字海洋进行深度学习:Redux

原文:https://towardsdatascience.com/deep-learning-with-digitalocean-redux-e6f447e64c75?source=collection_archive---------6-----------------------

这篇文章会和我平时的商务类文章有点不一样。在最近的一篇文章中,我给人的印象是数字海洋不是部署深度学习系统的好地方。然而,有一些部署到 DigitalOcean 的良好用例可以节省成本和复杂性。

最近,一个客户让我们在云中部署一个回归模型。训练是在 K20 GPU 上进行的。

This is what the 1-click install button looks like in DigitalOcean

我们尝试在一个 2GB 内存的新 droplet 上使用 DigitalOcean 的“机器学习和人工智能”一键安装。结果相当惊人。

首先,我们用这个升级了 tensorflow:

**pip install --upgrade tensorflow** #to resolve *ImportError: 'load_weights' requires h5py.*
pip3 install --upgrade h5py

要升级 keras(可选),请使用以下命令:

**pip install keras --upgrade**

让代码在 Keras 2 上工作的现成问题。阅读文档的正确版本:【https://faroit.github.io/keras-docs/2.0.8/,用这个检查你的版本:

import keras
print(keras.__version__)

数字海洋的执行时间结果

一个DNN(MLP**)**在 11.4 秒内训练 7 层(针对 10000 个样本,20 个输入,10 个输出类)。对 1000 个样本的测试花费了 968 毫秒。真快。代码如下:

要计算 1000 个模型预测的时间,只需像这样:

一个**【LSTM】(**用于序列预测 ) 走得也真快。我们用这种模型来预测股票价格之类的东西。LSTMs 的另一个有趣的用途是回归,但让我们坚持这个例子。该示例对于 144 个数据点花费了 33.5 秒。**但是,**模型预测(不包括训练)只用了 16 毫秒!

The prediction output looks as expected for the LSTM. The real data (ground truth) is in blue, while the training result is in orange, and testing result is in green.

一个CNN(vgg 19**)**2GB 的内存不足以运行模型,所以我在 8GB 的实例上这样做。对于其他一些 2GB 的 CNN,我同样得到了 ResourceExhaustedError 和其他垃圾。没什么大不了的。在 8GB 内存的情况下,它的工作非常出色。加载模型并获得一个结果需要 8.6 秒,但模型预测本身要快得多。

处理 100 张图像并对每张图像进行模型预测需要 4 分 23 秒。所以,以秒计,就是 240+23 = 263 秒。除以图像的数量,就是 2.63 秒。不太好。下面是时间代码:

我的下一步是在 word2vec (Google news)中嵌入一个单词模型,但是,唉,我必须回到真正的工作中去了。嵌入模型有一个类似 CNN 的内存大小问题。

数字海洋的成本结果

在 AWS 上,在 2 个 20 美元/月的实例上运行 DNN 和 LSTM 要比 1 千美元/月的 p2 或 p3 实例便宜得多。对于这些较小的模型来说,这很有意义。对于更大的 CNN 和 word2vec 模型,没有足够的计算(没有 GPU)或 RAM(对于大型嵌入模型)来使 DigitalOcean 具有吸引力。这可能会改变,例如,如果有一种方法可以从 SSD 而不是 RAM 加载 word2vec 模型。我是说,为什么不呢?它基本上只是一个大的记忆垫。这就解决了单词嵌入的问题,但是 CNN 呢?那是一个更难的问题。我认为对于图像处理来说,GPU 在未来很长一段时间内仍将是顶级产品。

如果你喜欢这篇关于云中深度学习的文章,那么请尝试一下 clap 工具。轻点那个。跟着我们走。分享这篇文章的链接。去吧。我也很高兴在评论中听到你的反馈。你怎么想呢?

如果你喜欢这篇文章,可以看看我过去读过最多的文章,比如“如何给人工智能项目定价”和“如何聘请人工智能顾问”除了与业务相关的文章,我还准备了一些关于寻求采用深度机器学习的公司所面临的其他问题的文章,如“没有云和 API 的机器学习”

编码快乐!

-丹尼尔
丹尼尔@lemay.ai ←打个招呼。
LEMAY . AI
1(855)LEMAY-AI

您可能喜欢的其他文章:

  • 人工智能和不良数据
  • 人工智能:超参数
  • 人工智能:让你的用户给你的数据贴上标签

利用合成数据的深度学习将使人工智能能够为大众所用

原文:https://towardsdatascience.com/deep-learning-with-synthetic-data-will-make-ai-accessible-to-the-masses-15b99343dd0e?source=collection_archive---------6-----------------------

在人工智能的世界里,数据为王。它为深度学习机器提供了动力,这些机器已经成为解决许多具有挑战性的现实世界人工智能问题的首选方法。我们拥有的高质量数据越多,我们的深度学习模型的表现就越好。

科技五巨头:谷歌、亚马逊、微软、苹果和脸书都在利用这一点上处于有利位置。他们可以比其他任何人更高效、更大规模地收集数据,这仅仅是因为他们拥有丰富的资源和强大的基础设施。这些科技巨头正在使用从你和大多数你认识的使用他们服务的人那里收集的数据来训练他们的人工智能。富人越来越富!

Amazon.com Inc. employees shop at the Amazon Go store in Seattle

这些公司积累的大量图像和视频数据集已经成为一种强大的竞争优势,是阻止较小企业闯入其市场的护城河。对于资源少得多的初创公司或个人来说,即使他们的产品很棒,也很难获得足够的数据来竞争。获取高质量的数据在时间和金钱上都是昂贵的,这两种资源是较小的组织无法承担的。

这种优势将被合成数据的出现所颠覆。它正在被任何人创建和利用合成数据来训练计算机的能力所破坏,包括零售、机器人、自动驾驶汽车、商业等等。

合成数据是模拟真实数据的计算机生成的数据;换句话说,数据是由计算机而不是人类创造的。可以设计软件算法来创建真实的模拟数据或“合成”数据。你可能以前见过 Unity 或虚幻引擎,这些游戏引擎使得创建视频游戏和虚拟模拟变得容易。这些游戏引擎可以用来创建大型合成数据集。然后,合成数据可以用来训练我们的人工智能模型,就像我们通常处理真实世界数据一样。

Nvidia 最近的一篇论文展示了如何做到这一点。他们的一般程序如下图所示,他们通过随机化每个可能的变量生成合成图像,包括图像场景、物体、照明位置和强度、纹理、形状和比例。

Illustration of how to generate high quality and realistic synthetic data in a game engine, from the research paper: Training Deep Networks with Synthetic Data: Bridging the Reality Gap by Domain Randomization

能够如此快速、轻松地创建高质量的数据,让这些小家伙又回到了游戏中。许多早期创业公司现在可以通过创建数据模拟器来生成带有质量标签的上下文相关数据,以训练他们的算法,从而解决他们的冷启动问题(即在很少或没有数据的情况下启动)。

模拟的灵活性和多功能性使其在这些高度可变的条件下训练和测试自动驾驶汽车变得特别有价值和更加安全。模拟数据也更容易标记,因为它是由计算机创建的,因此节省了大量时间。它便宜、廉价,甚至允许人们探索通常难以获取数据的利基应用,例如健康或卫星成像领域。

初创公司与拥有固有数据优势的现有公司竞争的挑战和机遇是,利用带有正确标签的最佳视觉数据,为不同的用例准确训练计算机。模拟数据将在大型科技公司和创业公司之间建立公平的竞争环境。随着时间的推移,大公司也可能会创建合成数据来增加他们的真实数据,有一天这可能会再次倾斜竞技场。无论是哪种情况,技术都比以前进步得更快,人工智能的未来是光明的。

喜欢学习?

在 twitter 上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

推荐阅读

想了解更多关于深度学习的知识?用 Python 进行 深度学习 本书将教你如何用有史以来最简单的 Python 库:Keras 进行真正的深度学习!

提醒一句,我支持这个博客,因为分享好书对每个人都有帮助。作为一名亚马逊员工,我从合格购买中获得收入。

Tensorflow 深度学习:第 1 部分—理论和设置

原文:https://towardsdatascience.com/deep-learning-with-tensorflow-part-1-b19ce7803428?source=collection_archive---------6-----------------------

how does a deep learning network work?

大家好,欢迎来到这个关于 Tensorflow 的博客系列。在第 1 部分中,我会给你一些关于框架的基本信息,我会向你展示如何在 Windows 10 上设置你的编码环境。让我们深入研究一下。

Tensorflow 是最受欢迎的,显然也是最好的深度学习框架。这是为什么呢?

TensorFlow 是 Google 为创建深度学习模型而创建的框架。深度学习是一种使用多层神经网络的机器学习模型(=算法)。

机器学习使我们能够非常准确地构建复杂的应用程序。无论是与图像、视频、文本甚至音频有关,机器学习都可以从广泛的范围解决问题。Tensorflow 可以用来实现所有这些应用。

它受欢迎的原因是开发人员可以轻松地构建和部署应用程序。由于接下来的部分,我们将更仔细地研究 GitHub 项目,这些项目非常强大,但也很容易使用。此外,Tensorflow 是在考虑处理能力限制的情况下创建的。该图书馆可以在各种电脑上运行,甚至可以在智能手机上运行(是的,甚至可以在那种上面有半个苹果的高价电脑上运行)。我可以向你保证,使用 8 GB 内存的英特尔酷睿 i3 处理器,你不会遇到性能问题。

Deep learning concept of Tensorflow

但是在学习 Tensorflow 之前,我们要了解一个基本原理。如何才能让我们的机器“思考”?

人脑由数十亿个神经元组成,这些神经元通过突触相互连接。如果对神经元的“足够”突触输入触发,那么神经元也将触发。这个过程叫做思考。为了在计算机上复制这一过程,我们需要机器学习和神经网络。如果你对这些条款不满意,我会解释给你听。

机器学习:

很简单,机器学习让计算机‘学习’。传统上,我们总是通过提供一组严格的指令来让计算机做事情。机器学习使用一种非常不同的方法。我们不是给计算机一套如何做某事的指令,而是给它如何学习做某事的指令。例如:想象一个系统,它可以将动物的图片分类为“猫”、“狗”或“老鼠”。机器学习不是从这些动物的图像中手动找到独特的特征,然后将其编码,而是接受这些动物的图像,并自己找到特征和差异。这个教计算机的过程被称为训练。

深度学习:

深度学习是一种实现机器学习的技术。它使用神经网络进行学习,有时,使用决策树也可以称为深度学习,但在大多数情况下,深度学习涉及到神经网络的使用。

神经网络:

那么,什么是神经网络?这里有一个类比:把神经网络想象成一系列一个接一个的门,把你自己想象成神经网络的“输入”。每次你打开一扇门,你就变成了不同的人。当你打开最后一扇门的时候,你已经变成了一个完全不同的人。当你从最后一扇门出去时,你就成了神经网络的“输出”。在这种情况下,每扇门代表一层。因此,神经网络是以某种方式转换输入以产生输出的层的集合。

如果想了解更多,可以试试下面这篇文章:
https://medium . com/forward-data-science/tensor flow-for-absolute-初学者-28c1544fb0d6

足够的理论,让我们做设置和安装

本手册适用于使用 Python 3.6 的 Tensorflow 1.2.1。在跟随它之前,你可能也想看一看官方安装指南。

计算机编程语言

Tensorflow 程序是用 Python 写的,你可以在https://www.python.org/downloads/下载

您可以在 Python 3 和 Python 2 之间进行选择,但是我强烈建议您安装一个比 3.5 更新的版本,因为这些版本已经附带了一个集成的 PIP-Package。否则,您也必须安装它。

张量流

下一步是安装 Python。以管理员身份打开命令行。),并写下下面一行:

pip3 install --upgrade tensorflow

如果您想测试安装,请这样写:

python 
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, Tensorflow')
>>> sess = tf.Session()
>>> print(sess.run(hello))

您现在应该会看到一个“Hello,Tensorflow”输出。

结论

恭喜你!您刚刚学习了 Tensorflow 的理论基础,并设置了一切来更深入地研究这个问题。下一部分将是关于盗梦空间的图像处理和识别。敬请关注,直到下次!

__

第二部分链接:https://medium . com/@ m _ ko/deep-learning-with-tensor flow-Part-2-image-classification-58 fcdffa 7b 84

张量流深度学习:第二部分——图像分类

原文:https://towardsdatascience.com/deep-learning-with-tensorflow-part-2-image-classification-58fcdffa7b84?source=collection_archive---------5-----------------------

image classification

大家好,欢迎回到我的紧张流系列,这是第二部分。
我已经在第一部分描述了神经网络和 Tenserflow 的逻辑和功能,也向你展示了如何建立你的编码环境。如果你还没有检查过,在这里找到它。

图像识别和分类是这一部分的主题。使用 Inception-v3 模型,我们将开始使用 Google 预先训练的 ImageNet 数据集对图像进行分类,然后继续构建我们自己的分类器。我们开始吧。

什么是 inception-v3 模型?

Inception v3 模型是一个深度卷积神经网络,它已经使用 2012 年的数据为 ImageNet 大型视觉识别挑战进行了预训练,它可以区分 1000 个不同的类别,像“猫”、“洗碗机”或“飞机”。

TensorFlow 团队已经准备了关于如何在你的机器上执行图像分类的教程。不过,我还是会给你看的。

基于预训练 ImageNet 数据集的图像分类

因为我们不是从零开始,所以从克隆 GitHub 的 Tensorflow 模型 repo sitory 开始。运行以下命令:

git clone https://github.com/tensorflow/models.git
cd models/tutorials/image/imagenet
python classify_image.py

如果你还没有安装 Git,在这里下载。

当程序第一次运行时,从谷歌的后端下载训练好的模型。您的硬盘上需要大约 200 MB 的可用空间。

上述命令将对提供的熊猫图像进行分类。

如果模型正确运行,脚本将产生以下输出:

giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.88493)
indri, indris, Indri indri, Indri brevicaudatus (score = 0.00878)
lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00317)
custard apple (score = 0.00149)
earthstar (score = 0.00127)

如果您希望提供其他图像,您可以通过编辑--image_file参数来实现:

python classify_image.py --iAmAdifferentImage.jpg

这并不难,是吗?但是不要担心,它会变得更有挑战性。上面的脚本允许我们在 Google 团队预先训练的课程上对图像进行分类。但是如果你想为我们自己的课程重新培训盗梦空间呢?

针对特定类别重新培训 Inception 的最终层

Inception’s layer model

设置

我们将向初始模型添加四个新的类,称为“圆形”、“正方形”、“加号”和“三角形”。

首先从 GitHub 克隆我的存储库,键入:

git clone [https://github.com/koflerm/tensorflow-image-classifier.git](https://github.com/koflerm/tensorflow-image-classifier.git)

在您克隆了提到的存储库之后,我们必须以某种方式告诉 Inception 每个图像的正确标签是什么。

因为我们要对一个对象是三角形、正方形、加号还是圆形进行分类,所以我们需要添加一个“training_dataset”目录,并用四个子文件夹填充它,并以“class”标签命名。这些文件夹将包含要进行分类的受试者的数据集(图像)。

/
--- /training_dataset
|    |
|    --- /circle
|    |    circle1.jpg
|    |    circle_small_red.png
|    |    ...
|    |
|    --- /square
|         square.jpg
|         square3.jpg
|         ...

接下来,我们必须实际获取用于训练过程的数据集。由于手动下载每张图片非常耗时,我们使用了一个名为“ Fatkun 批量下载图片”的 Chrome 扩展。它允许我们从谷歌图片搜索中自动下载前 50 张图片。只需将它们复制到文件夹中(图像格式并不重要!)

exemplary training images for class “plus”

执行

设置好所有目录和数据集后,开始训练吧!双击执行train.sh脚本。该脚本安装初始模型(如果还没有安装的话),并为指定的图像数据集启动重新训练过程。

re-training process

一旦这个过程完成,它将返回大约 90%的训练准确率。

重新培训的标签、图表和培训总结将保存在名为tf_files的文件夹中,以备您查看。

在重新训练模型之后,现在是在我们自己的图像上测试模型的时候了。下载或绘制另一个图像,并将其复制到根目录。我下载了另一张“三角形”图片。通过键入以下命令执行测试:

python classify.py downloadedImage.jpg

left: downloadedImage.jpg | right: score for each class

太好了,我的三角形居然被归为三角形!

(可选):如果您已经为新类添加了一些图像或子文件夹,但是您不想调用train.shclassify.sh,您可以通过键入以下命令来合并输入:

python retrain.py — bottleneck_dir=tf_files/bottlenecks — how_many_training_steps=500 — model_dir=inception — summaries_dir=tf_files/training_summaries/basic — output_graph=tf_files/retrained_graph.pb — output_labels=tf_files/retrained_labels.txt — image_dir=training_dataset — eval_step_interval=100 & python classify.py image.jpg

注意:image.jpg 是您想要测试的图像

分类问题

尽管分类在大多数情况下确实有效,但还是有一些问题:

Gets recognized as a plus

Again, not recognized as a circle

Inception 是为单标签图像分类而训练的,这意味着多标签分类是不可能的。如果我仍然想将上面的图像归类为圆形,我只需为该类使用更准确的训练集。这实际上有点费时,单靠 Chrome 扩展无法为你提供所有最好的结果。

好了,我们已经看到程序做了它应该做的事情(至少大部分时间)。但是再培训过程是如何进行的呢?

基本上,该脚本加载预训练的 Inception v3 模型,移除旧的顶层,并在您想要添加的几何形状类上训练新的顶层。这就是所谓的迁移学习。再培训分为两个阶段——瓶颈和培训:

第一阶段分析磁盘上的所有映像,并计算每个映像的瓶颈值。“瓶颈”是一个非正式的术语,指的是实际进行分类的最终输出层之前的层。它将图像处理成有意义且简洁的图像摘要。

第二阶段是网络顶层的实际训练。您可以看到一系列的步骤输出,每个输出都显示了训练精度、验证精度和交叉熵。训练准确度显示了在训练中使用的图像的百分比被标记为正确的类别。验证准确度是从不同组中随机选择的一组图像的精确度。交叉熵是一个损失函数,它给出了学习过程进展如何的一瞥。

如果你想深入了解,请往这边走

结论

恭喜,你现在能够使用 Tensorflow 对图像进行分类。在第三部分,我将向您展示 Tensorflow 的一些其他用例。所以请继续关注,直到下一篇文章!

__

链接到第三部分:https://medium . com/forward-data-science/deep-learning-with-tensor flow-Part-3-music-and-text-generation-8 a3 FB FDC 5 e 9 b

使用 Tensorflow 进行深度学习:第 3 部分—音乐和文本生成

原文:https://towardsdatascience.com/deep-learning-with-tensorflow-part-3-music-and-text-generation-8a3fbfdc5e9b?source=collection_archive---------3-----------------------

text summarization: one example of generating text using Tensorflow

大家好,欢迎回到我的紧张流系列,这是第三部分。
我已经在的第一部分中描述了神经网络和 Tenserflow 的逻辑和功能,并在的第二部分向你展示了如何进行图像分类。在这一部分,我将向您概述 Tensorflow 应用程序,并向您展示如何生成音乐和文本。

Tensorflow 允许我们构建复杂的应用程序。在处理多个输入源时,几乎所有事情都可以用 Tensorflow 来实现,甚至特斯拉的自动驾驶仪也可以用它来制作。为了更好地了解 Tensorflow 的可能性,我收集了人们已经用它制作的例子的简短摘要:

Predicting college basketball results through the use of Deep Learning

  • 处理文本:垃圾邮件过滤器,电子邮件自动回答,聊天机器人,体育预测
  • 处理图像:自动癌症检测 n,街道检测
  • 处理音频和语音:声音生成,语音识别

接下来,我将更详细地解释音乐生成和文本生成。我们将开始研究音乐生成,今天生成音乐的可能性,我们将编写自己的流行音乐生成器。稍后,我们将看看文本生成,一个具体的例子,并建立我们自己的诗歌生成器。让我们开始吧。

🎵音乐一代

介绍

亲爱的歌曲作者,
我很抱歉地告诉你,但在未来几年内,你将被机器学习算法取代。为什么?因为现在音乐可以由电脑生成。想象一下这种工具的威力。与创作一首歌所需的数百个小时相比,在一个程序中点击“开始”根本不算什么。

我想这对一些人来说可能听起来有点奇怪,考虑到音乐通常被称为“情感”和“感觉”的东西,而不是“事实”或“数学”的东西,但机器学习使这成为可能。但是它是如何工作的呢?

所以,假设你想做一首特别的歌,一首“快乐”和“有趣”的歌。第一步是获得一组带有情感标签的歌曲数据。这个程序会把语音转换成文本。对于每个单词,程序会创建向量并训练模型。完成训练后,程序会找到你输入的相关向量(“快乐”和“有趣”),并将它们与之前创建的向量进行比较。输出将是一组代表你想要的情感的和弦。

生成音乐的可能性

Example song, generated with Magenta

Magenta 是目前最先进的机器学习音乐生成技术,但你自己听听。这是一个来自谷歌大脑团队的项目,它问:我们可以使用机器学习来创作引人注目的艺术和音乐吗?Magenta 建立在 TensorFlow 之上,使用 CNN 系统。

建造我们自己的音乐发电机

虽然 Magenta 非常强大,但我们将使用受限玻尔兹曼机器(RBM) 构建我们自己的简单音乐生成器来生成短序列的流行音乐。

我们将收到多个文件,如果您将它们链接在一起,听起来会像这样:

Transistions between the files aren’t smooth, that’s not because of the generated music itself!

我们的训练数据将在一百个流行歌曲的 MIDI 文件左右( MIDI 是一种直接编码音符的格式)。为了简单起见,我们不会像介绍中描述的那样给它们贴上情绪的标签,我们的输出将是另一种流行旋律,就像我们的训练文件一样。

RBM 是一个有两层的神经网络,可见层和隐藏层。每个可见节点都连接到每个隐藏节点(反之亦然),但没有可见-可见或隐藏-隐藏连接(节点只是进行计算的地方)。这就是限制。每个可见节点取一个弦。每个和弦乘以一个权重,然后是隐藏层节点的输出。与大多数神经网络不同,RBM 是直接对数据的概率分布建模的生成模型。为了从 RBM 采样,我们执行一种称为 吉布斯采样 的算法。如果你想了解更多关于 RBM 氏症的知识,请走这条路。

理论谈得够多了,让我们从从 GitHub 克隆我的 repo 开始构建吧。打开终端并键入:

git clone [https://github.com/koflerm/tensorflow-music-generator.git](https://github.com/koflerm/tensorflow-music-generator.git)

接下来,我们必须安装几个库:

pip3 install pandas
pip3 install msgpack-python
pip3 install glob2
pip3 install tqdm
pip3 install py-midi

我们将按如下方式使用它们:

  • 熊猫是我们的数据分析库
  • Midi 作为我们音乐文件的辅助库
  • TQDM,用于在进程中打印进度条。

set of pop song sequences

歌曲存储在Pop_Music_Midi文件夹中。你也可以使用你自己的训练数据,但是歌曲必须是 MIDI 格式的。).在这里找到一些。

基本上,这就是准备工作,你现在可以执行程序了。要运行该脚本,只需编写:

python rbm_chords.py

Training process

培训将需要 5-10 分钟。输出将是out文件夹中 MIDI 文件的集合,每个文件大约 10 秒长。如果你只想听“一首歌”,你也可以写一个脚本把它们连接起来。

output

就是这样,你成功创作了音乐。如果你没有理解我写的所有内容(对不起…),我强烈推荐你分别阅读和聆听这两个帖子:

  • https://www.youtube.com/watch?v=ZE7qWXX05T0&feature = youtu . be
  • http://danshiebler . com/2016-08-10-musical-tensor flow-part-one-the-RBM/

✍ 文字生成

介绍

如前所述,在不久的将来,算法可能会取代歌曲作者。嗯,这也适用于诗人。我们将编写一个程序,根据威廉·莎士比亚的戏剧生成一首诗。训练数据(诗歌)存储为文本文件,文件名也是标签。首先,我将向您展示另一个使用 Tensorflow 生成文本的示例。

谷歌收件箱中的智能回复

Smart Reply System, integrated in the Inbox app on Android

用手机回复电子邮件是一件非常痛苦的事情,即使是简短的回复。这就是谷歌在其收件箱应用中实现智能回复的原因。他们希望建立一个系统,可以自动确定电子邮件是否可以用简短的回复来回答(文本识别),并为其撰写一些合适的回复(文本生成)。

他们需要建立一个机器学习系统,因为想象一下使用一个依赖于手工制作的常见回复场景规则的系统。任何工程师发明“规则”的能力都会很快被大量不同的写作风格超越。相比之下,机器学习系统可以自己捕捉不同的情况。它比基于规则的系统更好地概括和处理新输入。

谷歌选择在一对循环神经网络 (RNN)的基础上建立智能回复系统,一个用于编码收到的电子邮件,一个用于预测可能的回复。编码网络一次提取一个新邮件的单词,并生成一个向量。这种所谓的“思维向量”抓住了所说内容的核心,而不会纠结于它是如何说的(例如,向量“你明天有空吗?”应该与“明天你方便吗?”的向量相同).第二个网络从这个思维向量开始,一次一个单词地做出语法正确的回复,就像在打字一样。每个网络的详细操作完全是通过训练模型来预测可能的反应而学习的。

对智能回复系统感兴趣?在这里阅读更详细的解释。

建造我们自己的诗歌生成器

是时候在威廉·莎士比亚的作品上建立我们的文本生成器了。我们将使用递归神经网络来训练我们的模型。在对它进行训练之后,我们的脚本将会生成一首诗,它既可以在终端中查看,也可以在文本文件中查看。

首先,我知道诗歌一点也不有趣。但是不用担心,你可以很容易地改变数据集;).让我们深入研究一下。

从从 GitHub 克隆我的库开始:

git clone [https://github.com/koflerm/tensorflow-shakespeare-poem-generator.git](https://github.com/koflerm/tensorflow-shakespeare-poem-generator.git)

data set consisting of multiple poems

你可以看到,有一个Shakespeare文件夹,里面有多首诗。简单地把你自己的 TXT 文件放在那里,如果你想改变话题。

现在是时候训练我们的语言模型了。

> python3 rnn_train.py

这需要几个小时,所以要小心!如果你没有那么多时间,你可以下载检查点文件(最终模型)。不用先训练模型!只需将文件解压到checkpoints文件夹中。

一切都设置好了,是时候生成一些文本了。键入以下行:

> python3 rnn_play.py

脚本 rnn_play.py 使用我们训练好的检查点生成一个新的“莎士比亚”剧本。你可以在终端和文件output_generated.txt中看到输出

这就是你自己的诗,用莎士比亚的方式写的。

结论

恭喜你,你现在可以创作你自己的音乐,也可以创作你自己版本的莎士比亚戏剧了。在下一部分,我可能会更深入地研究图像分类和物体检测。所以请继续关注,直到下一篇文章!


链接到第四部分:https://medium . com/forward-data-science/deep-learning-with-tensor flow-Part-4-face-class ification-and-video-inputs-fa 078 f 22 C1 e 5

Tensorflow 深度学习:第 4 部分—人脸分类和视频输入

原文:https://towardsdatascience.com/deep-learning-with-tensorflow-part-4-face-classification-and-video-inputs-fa078f22c1e5?source=collection_archive---------1-----------------------

Can we classify different people?

大家好,欢迎回到我的紧张流系列,这是第 4 部分。这可能是这个系列的最后一部分,因为我们已经学到了很多:

  • 第 1 部分全是理论,我们看了神经网络和张量流的逻辑和功能。
  • 在第二部分,我们用几何形状进行图像分类。
  • 在 part 3 中,我们成功生成了自己的音乐和文字。

由于图像分类是神经网络最有趣的部分(至少在我看来),我们将在这一部分再次进行。但是,在我们继续重建分类器以接收视频输入之前,我们将对人的图像进行分类,而不是几何形状。让我们去争取吧。

回顾我们在第 2 部分中构建的分类器

how did our classifier work?

你可能不记得第二部分是关于什么的,所以这里有一个简短的总结:

我们构建了一个程序,它加载了来自 Google 的预训练的 Inception v3 模型,移除了旧的顶层,并在我们想要添加的几何形状类上训练了一个新的顶层。再培训分为两个阶段——瓶颈阶段和培训阶段。瓶颈将我们的图像处理成一个有意义的和紧凑的摘要,训练实际上训练了我们神经网络的顶层。如果还是不清楚,请阅读第二部分;)

给人分类

上次,我们在初始模型中添加了四类几何形状。这一次,我们将对三个不同的人进行分类:“史蒂夫·乔布斯”、“比尔·盖茨”和“马克·扎克伯格”。让我们看看《盗梦空间》是否足以区分这些人的面孔:

首先从 GitHub 克隆我的存储库,键入:

git clone [https://github.com/koflerm/tensorflow-image-classifier.git](https://github.com/koflerm/tensorflow-image-classifier.git)

接下来,我们需要添加我们的训练图像并给它们贴上标签。建立一个这样的结构:

/
--- /training_dataset
|    |
|    --- /billgates
|    |    billy.jpg
|    |    bill_gates.png
|    |    ...
|    |
|    --- /stevejobs
|         stevejobs.jpg
|         jobs.jpg
|         ...
|    |
|    --- /markzuckerberg
|         zuckerberg46.jpg
|         zuckerberg2020.jpg
|         ...

为了下载图片,我使用了一个名为“批量下载图片”的 Chrome 扩展。这个扩展允许你自动下载谷歌图片到你的电脑上。图像格式不重要!

how images for the Steve-Jobs-class could look like

是时候训练我们的模型了

设置好数据后,让训练开始!双击执行train.sh脚本。该脚本安装初始模型,并为指定的图像数据集启动重新训练过程。

re-training process

一旦这个过程完成,我们的训练准确率应该在 90%左右。

在重新训练模型之后,现在是用其他图像测试模型的时候了。下载并复制到根目录,然后键入:

python classify.py downloadedBillGates.jpg

好吧,很好。但是我们的模型表现如何呢?

model works!

比尔·盖茨直视镜头,光线还不错,所以没问题。

success!

令人惊讶的是,合适的人又得到了认可。图像分辨率很差(300x300),扎克伯格甚至不在图像的中心。干得好,盗梦空间!

Both are recognized, but both can’t get a high score

这是一个棘手的问题!Inception 是为单标签图像分类而训练的,这意味着它的总得分为 1。多标签分类是不可能的,而且由于我们的两个类都显示在图像中,所以都不可能得到高分。如果我想让这张图片更像“史蒂夫·乔布斯”,我必须为他的班级使用更准确、更大的训练集。

Again, Gates over Jobs

这张图片再次被归类为盖茨胜于乔布斯,这一次是以巨大的优势。我猜,在准确的照明条件下,更准确的训练集和更多的训练数据可能会让史蒂夫·乔布斯赢得这场决斗。

All about Steve Jobs this time

最后,这个人被认出来了!但这对我们的模特来说并不难,不是吗(很棒的灯光,他直视镜头,…)

Testing on images with other, unknown people

盖茨被认出来了,马克·扎克伯格也是(尽管他不在照片上)。我猜《盗梦空间》把桑德罗·罗塞尔(左边)当成了马克·扎克伯格,但没错,肯定是不匹配!

(可选):如果您现在想要添加新的类,可以通过键入以下命令将培训和测试结合起来:

python retrain.py — bottleneck_dir=tf_files/bottlenecks — how_many_training_steps=500 — model_dir=inception — summaries_dir=tf_files/training_summaries/basic — output_graph=tf_files/retrained_graph.pb — output_labels=tf_files/retrained_labels.txt — image_dir=training_dataset — eval_step_interval=100 & python classify.py image.jpg

注意:image.jpg 是你想用来测试你的模型的图像

现在你知道了,我们可以用盗梦空间对人脸进行分类。但是现在,让我们继续为视频输入重建分类器。

重建我们的视频输入分类器

image classification using a video as input stream and analyzing it frame-by-frame

到目前为止,我们一张一张地下载了我们的测试数据,但是这很费力,不是吗?用视频输入来测试我们的模型会容易得多。我们只需要插入一个视频一次,但是分类是一帧一帧完成的。简单多了。因此,让我们建立这样一个系统:

我们的代码如何变化

基本上没什么变化。我们只需要触摸classify.py脚本。我将一步一步地引导你完成这些改变:

pip install opencv-py 

首先,打开一个终端并安装 OpenCV,一个用于视频处理和图像分析的库。

import cv2
import math

然后我们需要加载和处理我们的视频。我们通过导入 OpenCV 模块来做到这一点。数学包的导入实际上是可选的,只有当你不想处理每一帧时才需要它。

rewritten part of the code

这是代码的重要部分。如果你想更深入一点,请阅读评论,我认为他们自己说了算。原理很简单:当我们得到一个视频帧时,我们存储它并立即再次读取它用于分类目的,然后在一个单独的窗口中输出分数和帧本身。

现在,让我们用比尔·盖茨和史蒂夫·乔布斯的对话视频来测试我们的模型。

但首先,我认为你必须同时…执行train.sh并等待直到进程完成:)

然后,有趣的部分开始了。我将在下面的视频中测试我的模型:

Video does not contain Mark Zuckerberg

接下来,我们要等很长时间,直到比尔·盖茨第一次被拍摄。分类器有什么反应?

Gates gets recognized more or less

正如我们所看到的,模型实际上对他进行了正确的分类,尽管比尔·盖茨的头被切掉了一点。我们当然知道我们的模型现在确实适用于视频,但它也能识别史蒂夫·乔布斯吗?

Perfect recognition

是的。用乔布斯的话其实更好,分数大概是 0.9。但是有一个问题仍然悬而未决:如果两个人都在同一个框架里会发生什么?

Jobs over Gates here

这个框架被归类为“工作”。前面解释过,分数加起来一个,两个人都拿不到高分。

现在是时候接受新的挑战了:手绘。我们的模型能识别手绘物体吗?
我们将再次添加四个几何类“圆”、“三角形”、“正方形”和“加号”来完成:

让我们用手绘视频作为输入来测试我们的模型

因此,首先我们必须再次将我们的类添加到模型中,以防您在第 2 部分中删除了它们。最终,培训文件夹中应该会有这样的结构。

/
--- /training_dataset
|    |
|    --- /billgates
|    --- /stevejobs
|    --- /markzuckerberg
|    --- /circle
|    --- /square
|    --- /plus
|    --- /triangle

用训练图像填充所有这些文件夹。我将用谷歌搜索的图像填充它们,尽管这些图像不会是手绘!看事情如何发展会很有趣。

接下来,训练。在拍摄你自己的几何图形定制视频之前,运行train.sh脚本来添加新的类到模型中。你也可以用我的,在 GitHub 上我的回购里找到的math_own_old.mp4

那么,我们来对一些框架进行分类。在命令行输入python classify.py math_own_old.mp4,看看你的模型是否能够识别正确的形状。

Square gets classified correctly

多好的开始啊!正方形是成功的,但是其他的物体呢?

Our model mistakes triangle

好了,你知道了。我们的模型不识别手绘的三角形,它认为它是正方形。也许下一个…

Again, triangle not recognized

这值得一试,但它再次认为它是一个正方形。奇怪的是,加号似乎对模型也是不可见的。秘社是我们最后的希望!

Success!

是的,圆得到正确分类!但正如所见,对于一个由计算机生成的图像训练的模型来说,识别分辨率很差的手绘图片是非常困难的。

结论

所以,现在你知道了,用盗梦空间和张量流对人进行分类是可能的。此外,您还学习了如何重写一些代码来使用视频作为输入源。这是这个系列的最后一部分,我希望你喜欢这个旅程。我自己肯定学到了很多。如果你有任何类型的反馈给我,我会很感激的 ✌

深爱:现代爱情文章生成器

原文:https://towardsdatascience.com/deep-love-a-modern-love-article-generator-38acca77d05e?source=collection_archive---------3-----------------------

NYT 有一个名为“现代爱情”的每周专栏这是一系列关于各种形式的爱情的强烈个人化的文章,选自公众提交的作品。有一个故事是关于一个女人对当地面包师的迷恋,在故事中,她吃了很多烘焙食品,然后鼓起勇气约他出去。另一个描述了一个母亲的强烈的保护本能,当她把球直接扔向她年幼的儿子同样年幼的欺负者的头时,这种本能就表现出来了。这是一个迷人的、幽默的、真实的窗口,它向我们展示了一个激情战胜理智、尴尬和悔恨占据主导地位的世界。情感被暴露出来,然后通过后见之明的棱镜来审视,从而对人类的本质有所了解。

但是如果一个计算机程序可以生成这些文章呢?

LSTMs(长短期记忆)是一种用于预测序列的递归神经网络结构。他们擅长学习数据,如文本,具有长期依赖性,在预测时“记住”以前看到的信息。使用 Tensorflow 的 seq2seq 库,我在现代爱情文章的整个语料库上训练了一个单层 LSTM 和一个单词嵌入层。我用“我”这个词作为预测的引子,这样神经网络也可以讲述它关于爱和失去的故事。以下是生成文本的示例:

我又开始约会,一次又一次,不知道是否有人被我吸引:“你曾经想要他们孩子的注意力吗?”
对我来说是充实的一周,我设法让自己的沮丧一瘸一拐,然后我听到了对财务安全的不同理解?
在这个夜晚,他再次回到了摇摇欲坠的边缘,严厉的人们在激烈地进行着他们的比赛。我丈夫和虽然我们约会对方,并希望在犹豫不决的情况下,我的丈夫也是德鲁的,生母总是坚持要一份登记表。他的前额沐浴着。白人说,他可能经常振翅高飞。然后穿上它们,从未有过性的闪光是千变万化的,脆弱的和爱,我无法找到它,我甚至没有褪色,但我没有真正的朋友,我想知道发生了什么事的人,他现在用蹩脚的英语和后期。他们像那样重新体验自己的悲伤。
我们在公寓间接吻了。

可以说,NYT 专栏的人类作者目前是安全的。机器生成的文本可以捕捉句子的结构和一些主题。乍看之下,这看起来似乎有道理,但它基本上是无稽之谈。

在 Andrej Karpathy 的优秀博客中,他对保罗·格拉厄姆的论文、莎士比亚、维基百科、代数几何论文、Linux 源代码和婴儿名字进行了人物级的 RNN,得到了类似的无意义结果。

关于深度学习的深层误解

原文:https://towardsdatascience.com/deep-misconceptions-about-deep-learning-f26c41faceec?source=collection_archive---------2-----------------------

我开始写这篇文章,是希望对抗一些关于深度学习(DL)的误解,深度学习是一个机器学习领域,同时被称为银弹和研究炒作。真相在中间的某个地方,我希望我能把水搅浑——至少一点点。重要的是,我希望阐明解决 DL 问题的一些过程,并讨论为什么它在自然语言处理(NLP)、图像识别和机器翻译等领域表现如此好,而在其他领域却失败了。

深度学习不是黑暗艺术

媒体经常将深度学习描绘成世界末日的神奇配方或所有生活问题的解决方案。事实上,它绝不是。此外,尽管 DL 有其奇怪的行为和无法解释的结果,但它最终是由精英驱动的。通过在开发过程中要求证明和推理,您可以在无限数量的模型排列中构建一个健壮的框架。

https://xkcd.com/1838/

凡事都有目的(大多数时候)

我看到新从业者表现出的第一个问题是将几个 LSTM(长短期记忆)层、一个 GRU(门控循环单元)层和几个卷积层粉碎在一起,然后坐下来等待神奇的结果。然后沮丧地看着他们的模型 5%的精确度。正如我将在后面讨论的,DL 需要一个更加合理的方法。

通过采用基于整合数据、网络设计和好奇心的方法,你将能够产生惊人的结果。我每天都花时间阅读关于最新方法的新论文和文章,并不断看到推动新设计的巧妙想法。

在 DL 中,不同的层服务于不同的目的。这是一个简单的想法,但对于这个领域的新手来说,这种想法往往会被遗忘。此外,虽然我在设计过程中做了大量的实验,但我总是沿着一条思路进行测试。增加复杂性应该有一个理由(或者至少是一个假设)。它应该用一个可测量的标准来检查,只有这样我才能在最终的设计中接受它。此外,你应该偏爱简单的模型,而不是复杂的模型,因为它们可以达到相同的结果。我一直在测试更小的网络,或者更少的神经元或者更少的层,并将它们与我的最佳设计进行比较。更小的系统也意味着更快的训练(在某些情况下几个数量级),这意味着更多的迭代和更好的最终设计。

您可以创建一些工具来测试小型和大型网络上的新论点,这种理解将推动您对网络设计的全面了解。随着你越来越多地使用神经网络,你将会更好地理解是什么驱动它的行为来完成特定的任务。你开始在你的头脑中绘制一张地图,标明什么时候尝试什么,但前提是你有正确的度量标准和过程来理解。

设计流程

我认为设计过程就像一个孩子试图建造一座砖砌的塔,一路测试。戳,刺激,失败,但总是测试。塔的第二层是不是太不稳了?该不该换基地?考虑拥有有限数量的块是有帮助的。神经网络越小,你训练它的速度就越快,测试它的速度也就越快。仅在需要时增加复杂性。

在 DL 中,这个问题有无限多种可能的解决方案——因此,您处理的网络可以模拟几乎无限的公式集。虽然最终结果可能是离散的,但神经网络生活在一个连续数字的世界中。复杂性往往会迅速增加,而增加的复杂性需要更多的控制。我试着用建立一个新的数据项目的方式来建立我的网络。例如,一个简单的探索性数据分析管道可以是:

接收数据→清理数据→转换数据→呈现数据

所有这些模块都可能涉及许多不同的步骤。如果我在整个过程中没有确保上游过程的质量,整个系统将会失败。所以我一路测试。我测试一切——输入、输出、类、函数。我确保每样东西单独工作,然后一起工作。我知道这不是一个突破性的想法,但它值得指出。一旦我有了一个工作流程,我就会转移到下一个,并在此基础上继续工作。

在深度学习中,我从创建最简单的模型开始。在处理文本分类任务时,我将从最简单的嵌入-编码-参与-预测模型开始。在看到基础模型是如何工作的之后,我将开始在它的基础上进行构建。这可能包括增加隐藏层的大小,加深网络,合并新的网络,改变激活和初始化,用词性标签或其他数字数据增加文本。我可能会让几个神经网络互相反馈,以达到不同的目的,或者改变数据的处理方式,或者将文本矢量化。这样的例子不胜枚举。

对于每一步,我都将它与我的原始模型和我的迭代进行比较。这个过程允许我回顾我的模型的演变,理解它在哪里变得更好(或更差),并通知设计的未来迭代;总是越来越接近全局最小值。

成为数据的主人

在开始试验您的 DL 模型之前,有必要了解给定问题的价值所在。有一个简单的层次结构可以遵循:

数据大于模型设计,模型设计大于参数优化。

如果 A 公司有 B 公司十倍的数据,这个世界上没有一个模型会允许 B 公司胜过 A 公司的模型。同样的想法也适用于数据质量。

如果我花数周时间开发一个基于弱数据质量的模型,它的表现将不如我用几天时间构建的基于高质量数据的模型。在你花数周时间做模型之前,总是问自己是否能得到更多的数据。也许你可以改变你的预处理步骤来提高你已经拥有的数据的质量。这通常会比仅仅通过模型调整获得更快的性能提升。

不仅需要高质量的数据,还需要对数据的深刻理解。你应该花时间开发工具来分析、展示和研究你的输入数据。您应该构建度量和分析工具来理解您的模型的预测。避免将数据仅仅视为输入。所有数据都有隐藏的特征,如果你能提取出来,这些特征具有巨大的预测能力。有时您必须自己完成这项工作,其他时候您可以开发您的 DL 模型,让它自己完成这项工作。把你的数据想象成一种加密算法的输入——但它不是对文本或电子邮件进行加密,而是对世界的运行方式进行编码。每个数据点都是更好理解的线索。

自然语言处理中的文本分类就是一个很好的例子。给你一个几百或者几千字的语料库,每个文本有一个类或者多个类。也许这个类是积极的,消极的,或者中性的,也许你有数百个复杂而错综复杂的类。无论哪种方式,文本都是我们用来确定输出的代码。

当你不再认为你的输入只是文字时,它会变得非常有价值,并为你带来难以置信的结果。这种想法导致了从单词向量到单词级模型、句子级模型、段落级模型的发展。每一个实现都是基于人类理解的工作方式,并在性能增益中表现出来。

与领域专家共度时光

这与前一部分紧密相关,甚至可能更重要——花时间与具有领域知识的人交谈。和他们讨论你的结果,和他们讨论数据。让他们参与设计过程。

你会惊讶于讨论你的模型的设计哲学和你的模型的输出经常会带来快速的成功。这些立竿见影的效果往往转化为准确性的大幅提高。当然,这需要时间投资来教育他们对深度学习的直觉和概念理解,但对我来说这总是值得的。如果你没有领域专家,花时间自己学习。避免试图为你不理解的问题建立一个 DL 模型。

消除深度学习就像在没有灯的迷宫中摸索前进的想法。在现实中,你可以通过遵循正确的方法并试图解决正确的问题来处理深度学习。你应该经常问自己为什么。

虽然我将要描述的方法听起来可能与度量驱动设计的想法相反,但我发现它以最好的方式建立了理解;一直问为什么。

像孩子一样学习

也许我一直提到孩子是因为我和我的妻子在下个月左右就要有我们的女儿了,但是我发现他们是如何学习的一个很好的例子。孩子从子宫里出来就是小科学家。一切都是实验,任何抚养过孩子的人都记得他们的小探险家发出的无尽的一串“为什么”。数据科学家应该都有这种方法,但在实施深度学习时记住这一点尤其重要——深度学习是一个有着令人眼花缭乱的设计选择的领域,可能会导致最勤奋的数据科学家的思维变得迟钝。

一旦我测试了一个有积极效果的设计变更,我会试着找出它为什么有效。这个方法论让我不断提高自己的理解能力。今天,我可能不是某个特定领域的专家,但如果有足够的时间,我总能朝着成为专家的方向努力。

我一直在问为什么,直到我真正理解了选择一个设计决策的基础。通常一个问题引出另一个问题,三天后你对一系列有价值的概念有了新的深刻的理解。这是我最近去过的一个兔子洞的合法例子(如果这些术语对你没有任何意义,请不要担心):

  • 为什么我要用 LSTM 编码我的句子?
  • LSTM 是如何工作的?
  • 规范 LSTM 的最好方法是什么?
  • 我应该如何解码 LSTM 输出的序列?
  • 最大池与平均池或使用另一个 LSTM 作为我的解码器相比如何?
  • GRU 比 LSTM 表现得更好还是更快?为什么?
  • 我应该如何初始化我的 LSTM 层?为什么?
  • 这个 LSTM 太慢了,我能加速吗?
  • 为什么传统的 LSTM 在 GPU 上的运行速度比 Cuda 优化的 LSTM 层慢这么多?
  • 我可以使用较低精度的浮点来增加我可以在 GPU 上实现的网络大小吗?

我称之为兔子洞是因为学习路径从一开始就是随机的,不确定的。我只是允许自己探索我的问题。我不担心这是偶然的,而且我对每一个科目的兴趣倍增,我学习答案的速度和效果都很好。这个方法是我一生学习的方式,我发现它总能让我到达正确的地方(最终)。我也带着一套技能到达那里,否则,如果我只专注于预先设计的计划,我不会。这种方法的缺点是耗时,但大多数数据科学家天生就有这种好奇心。一旦我遇到问题,我必须找到答案。

“找到答案或者尝试而死”——平行宇宙中的 50 美分

结果是我现在对第一个问题有了回应;为什么我应该用 LSTM 来编码我的句子。此外,我有另一组半相关问题的答案,允许我进行新的调整和设计更改,以进一步优化。在测试这些调整时,我可能会得到新的和新奇的结果,所以我开始再次探索。如果你这样做的时间足够长,你可以从学习到实验,到设计,到专业知识。很快你就会发现自己正在尝试以前从未尝试过的全新想法。

这个特别的问题让我将我的神经网络在特定问题上的速度提高了四倍,同时提高了 3%的准确率(对我来说这是很大的一个进步)。在此过程中,我还学习了编码器-解码器的设计以及相当多的机器翻译知识。回答我的问题,而不是像传统方法那样预先设定的问题,可以让我连续几个小时保持专注,而不会耗尽我的意志力。

问正确的问题

识别正确的深度学习问题至关重要。DL 在语言任务、图像分类、语音翻译、机器翻译和玩游戏(即国际象棋、围棋、星际争霸)方面非常出色。在传统的机器学习任务中,如信用卡欺诈检测、资产定价和信用评分,它的性能较差。或许在未来,我们将调整我们的模型、优化方法和激活函数,使深度学习更加广泛适用,但目前,它仅限于非常复杂的领域。

DL 之所以表现出色,是因为它可以建模巨大的复杂性。在我确定的所有任务中,数据的不同部分之间有数千甚至数百万的细微差别和相关性。神经网络以一种人类无法做到的方式寻找并利用这些细微差别。此外,虽然传统的机器学习可以应用于这些领域,但它们在复杂性建模方面有很大的局限性。数据科学家通常需要花费数周时间进行特征提取和工程设计,才能让传统模型发挥作用。原因是该网络不具有深度学习网络的相同能力来独自获得特征。

人类设计师经常限制传统的机器学习模型。深度学习消除了很多人类的限制,让人类成为向导而不是老师。现在,在人类开发人员的帮助下,模型可以自由探索并找到解决方案的途径。我的工作是给神经网络提供正确的工具,将一个问题分解成数百万个子问题,然后将它们重新组合成一个解决方案。它的精彩之处在于它既简单又复杂。

一剂有益健康的偏执狂

作为最后,也可能是最重要的主题,您如何确保您的模型运行良好?不幸的是,没有单一的解决方案,但有一个适合我的系统。

当设计一个网络时,我怀疑它不能正常工作。我不断地想,是分数在愚弄我,还是有罕见的长尾事件让我的模型看起来很傻。一个可怕的预测会让你的模型在很多人眼里变得不准确。因此,我构建了以多种方式查看相同预测的工具,制作了图形工具以允许更快的迭代和更快的数据消化,并继续开发工具,直到那种不安的感觉消退到舒适的程度。

有时你永远也到不了那里。这就是为什么你不断调整,你不断寻找缺陷。像一个固执的侦探,不断刺激,测试和寻找漏洞。我向你保证,有比你原来的准确性指标可能会建议更多。单独看每节课,分组看,用精准,回忆,f1-score;见鬼,我甚至有一半时间都在编故事。

关键是要认识到你的模型是复杂的,你只能理解其决策过程的一部分。如果你知道走进去,你就更有可能成功走出去。您的度量导致设计变更,您的设计变更导致更好的模型。

有时,你会了解模型的小利基,以及如何控制它们。有时你不得不接受它并不总是有效。重点通常是缓解,而不是消除。任何一个好的深度学习系统,后台都有一个智能质量保证(QA)系统。这个问答系统是防止用户尴尬预测的最后一道防线。

通过使用适当的 QA 过程,您可以获得有目的地设计所需的度量,在过程中学习,并不断改进您自己和您的模型。在一天结束的时候,也许我们所做的只是搅动那个线性代数锅,但是通过一种由目的和理解驱动的方式去做,我们成功的几率会成倍增加。

在 BigQuery 上用纯 SQL 实现的深度神经网络

原文:https://towardsdatascience.com/deep-neural-network-implemented-in-pure-sql-over-bigquery-f3ed245814d3?source=collection_archive---------2-----------------------

在这篇文章中,我们将纯粹用 SQL 实现一个基本的深度神经网络。神经网络训练的端到端步骤(包括前向传递和反向传播)将作为 BigQuery 上的单个 SQL 查询来实现。由于它运行在 Bigquery 上,实际上我们是在 100 到 1000 台服务器上执行分布式神经网络训练。听起来很酷!对吗?

也就是说,请注意,这是一个有趣的项目,用来测试 SQL 和 BigQuery 的局限性,并从声明性数据转换的角度来看神经网络训练。这是在没有任何实际应用的情况下完成的,尽管我将在最后讨论一些实际的研究意义。让我们开始吧。

我们将从一个简单的基于神经网络的分类器开始。它的输入维数为 2,输出为二进制。我们将有一个 2 维的隐藏层和 ReLU 激活函数。输出层将有一个最终带有 softmax 函数的二维输出。我们在实现网络时将遵循的步骤是 Karpathy 的 CS231n 教程中所示的 Python 示例的基于 SQL 的版本。

模型

该模型具有以下参数:

输入隐藏

  • W : 2x2 权重矩阵(元素:w_00, w_01, w_10, w_11)
  • B : 2x1 偏置矢量(元素:b_0, b_1)

隐藏到输出

  • W2 : 2x2 权重矩阵(元素:w2_00, w2_01, w2_10, w2_11)
  • B2 : 2x1 偏置矢量(元素:b2_0, b2_1)

训练数据存储在 BigQuery 表中,其中列x1x2具有输入,y 具有输出,如下所示(表名:example_project.example_dataset.example_table)。

如前所述,我们将把整个训练作为一个 SQL 查询来实现。训练完成后,查询将返回参数值。正如您可能已经猜到的,这将是一个嵌套很深的查询。我们将逐步构建来准备这个查询。我们将从最里面的子查询开始,然后我们将一个接一个地添加嵌套的外层。

前进传球

最初,我们将为权重参数WW2分配随机正常值,并为偏差参数BB2分配零值。WW2的随机值可以在 SQL 本身中生成。为简单起见,我们将在外部生成这些值,并在 SQL 查询中使用。用于初始化参数的内部子查询是:

请注意,表example_project.example_dataset.example_table已经包含列x1x2y。模型参数将作为附加列添加到上述查询的结果中。

接下来,我们将计算隐藏层。我们将用包含元素d0d1的矢量D来表示隐藏层。我们需要执行矩阵运算:D = np.maximum(0, np.dot(X, W) + B),其中X表示输入向量(元素x1x2)。该矩阵运算首先将X乘以W中的权重,然后加上偏置向量B。然后,结果通过非线性ReLu激活函数,该函数将负值设置为 0。SQL 中的等效查询是:

上面的查询在前一个内部子查询的结果中添加了两个新列d0d1。上述查询的输出如下所示。

这就完成了输入到隐藏层的转换。现在我们将执行隐藏层到输出层的转换。

首先,我们将计算输出图层的分数。公式为:scores = np.dot(D, W2) + B2。然后,我们将对分数应用 softmax 函数,以获得每个类别的预测概率。SQL 中等效的内部子查询是:

这就完成了神经网络的正向传递。接下来,我们将基于预测输出(probs)与预期输出(Y)的比较,进行反向传播以调整模型参数。

首先,我们将计算当前预测导致的总损失。我们将使用交叉熵损失函数来计算损失。我们将首先计算每个例子中正确类别的预测概率的负对数。交叉熵损失只不过是在XY的所有实例中这些值的平均值。自然对数是一个递增函数。因此,直观地将损失定义为正确类别的预测概率的对数的负值。如果正确类别的预测概率很高,则损失会很低。相反,如果正确类别的预测概率较低,丢失率将会较高。

为了减少过度拟合的机会,我们还将添加 L2 正则化。在总损失中,我们将包括0.5*reg*np.sum(W*W) + 0.5*reg*np.sum(W2*W2),其中reg是一个超参数。在损失中包括这个函数将会惩罚权重向量中的高幅度值。

在查询中,我们还将统计训练示例的数量(num_examples)。这在以后计算平均值时会很有用。计算总损失的 SQL 查询是:

反向传播

接下来,对于反向传播,我们将计算每个参数相对于损耗的偏导数。我们将使用链式法则从最后一层开始逐层计算。首先,我们将通过使用交叉熵和 softmax 函数的导数来计算分数的梯度。与此对应的查询是:

回想一下,我们使用scores = np.dot(D, W2) + B2计算分数。因此,基于分数的导数(称为dscores,我们可以计算隐藏层 D 的梯度和模型参数W2B2。相应的查询是:

以类似的方式进行,我们知道D = np.maximum(0, np.dot(X, W) + B)。因此,通过使用D的导数,我们可以计算WB的导数。计算X的导数没有意义,因为它不是模型参数或使用任何模型参数计算。计算WB的导数的查询是:

最后,我们将使用它们各自的梯度更新模型参数W, B, W2B2。这可以通过param -= learning_rate * d_param来计算,其中learning_rate是一个参数。在dWdW2中还将增加一个额外的因子reg*weight,以将L2正则化合并到梯度计算中。我们还将删除临时列,如dw_00correct_logprobs等。它是我们在内部子查询中创建的,只保留训练数据(列x1x2y)和模型参数(权重和偏差)。相应的查询是:

这完成了正向传递和反向传播的一次迭代。上述查询将提供权重和偏差的更新值。样本结果如下所示:

为了进行更多的训练迭代,我们将递归地执行上述所有步骤。我们可以使用一个简单的 Python 函数来实现。该代码可在链接中找到。随着我们增加更多的迭代,查询得到了大量的嵌套。执行 10 次训练迭代的结果查询可在链接中获得。

由于大量的嵌套和查询的复杂性,当我试图在 BigQuery 中执行它时,遇到了多个资源限制。与遗留的 SQL 方言相比,Bigquery 的标准 SQL 方言具有更好的伸缩性。即使使用标准 SQL,对于具有 100k 个实例的数据集,也很难执行 10 次以上的迭代。由于资源的限制,我们将在一个简单的决策边界上评估这个模型,这样我们就可以通过少量的迭代获得相当好的精度。

我们将使用一个简单的数据集,其输入x1x2是从均值为 0、方差为 1 的正态分布中采样的。二进制输出 y 简单地检查x1 + x2是否大于零。为了在 10 次迭代内训练得更快,我们将使用 2.0 的高学习率(注意:在实践中不推荐这么高的值,因为学习可能会发散)。应用上述查询 10 次迭代,得到如下所示的学习模型参数。

我们将使用 Bigquery 的' save to table '功能将结果存储到一个新表中。现在,我们可以通过仅执行正向传递,然后比较预测结果和预期结果,来检查训练数据的准确性。这个查询片段在链接中。我们能够通过 10 次迭代获得 93%的准确度(在单独的测试数据集上准确度是相似的)。

如果我们能进行大约 100 次迭代,我们将获得超过 99%的准确率。

最佳化

这就结束了在 BigQuery 中使用纯 SQL 实现深度神经网络的有趣项目。我们将何去何从?正如我们看到的,资源限制是限制数据集大小和我们可以执行的训练迭代次数的因素。除了希望谷歌放松资源限制,我们可以做多种优化来解决这个问题。

  • 我们可以创建中间表和多个 SQL 查询来执行更多的迭代。例如,前 10 次迭代的结果可以存储在中间表中。现在可以在这个中间表上应用相同的训练查询来执行接下来的 10 次迭代。因此,实际上,我们已经执行了 20 次训练迭代。这可以重复多次,以执行大量的迭代。
  • 我们可以尽可能使用函数的函数,而不是在每一步都添加外部查询。例如,我们可以在一个子查询中计算scoresprobs,而不是两个嵌套的子查询。
  • 在上面的例子中,我保留了所有的中间列,直到最后一个外部查询。其中一些,比如correct_logprobs,可以提前删除(尽管 SQL 引擎可能会自动执行这种优化)。
  • 可以探索用户定义函数(UDF)的应用。如果感兴趣,您可以查看一个项目,其中使用 BigQuery UDF 进行模型服务(但是,不使用 SQL 或 UDF 进行训练)。

含义

现在,让我们看看深度学习环境中分布式 SQL 引擎的更深层含义。BigQuery 和 Presto 之类的仓库 SQL 引擎的一个局限性是查询处理是使用 CPU 而不是 GPU 来执行的。使用 GPU 加速的 SQL 数据库(如 blazingdb 和 mapd)检查结果会很有趣。一种简单的检验方法是使用分布式 SQL 引擎执行查询和数据分发,并使用 GPU 加速数据库执行本地计算。

退一步,我们可以看到,现在,执行分布式深度学习是很难的。几十年来,大量的研究工作已经深入到分布式 SQL 引擎中,从而产生了查询规划、数据分区、操作符放置、检查点、多查询调度等技术。其中一些可以纳入分布式深度学习。如果你对这些方面感兴趣,请看看这篇关于分布式数据库和深度学习的一般研究讨论的论文。

希望你和我一样开心!请在下面分享你的评论和想法。我很乐意回应。

回归问题的深度神经网络

原文:https://towardsdatascience.com/deep-neural-networks-for-regression-problems-81321897ca33?source=collection_archive---------1-----------------------

Image Source

神经网络在分类问题上是众所周知的,例如,它们被用于手写数字分类,但问题是,如果我们将它们用于回归问题,会有成效吗?

在本文中,我将使用一个深度神经网络,通过 Kaggle 的数据集来预测房价。

你可以从这里下载数据集

我强烈推荐你试着用我的笔记本在 Google colab [ 这里 ]上运行代码

内容:

1- Process the dataset 2- Make the deep neural network 3- Train the DNN 4- Test the DNN 5- Compare the result from the DNN to another ML algorithm

首先,我们将导入所需的依赖项:

首先:处理数据集

我们不会深入处理数据集,我们想要做的只是让数据集准备好输入我们的模型。

我们将去掉任何具有缺失值的特征,然后我们将对分类特征进行编码,就这样。

加载数据集:

  • 将训练和测试数据加载到 pandas 数据框架中
  • 组合训练和测试数据以一起处理它们
combined.describe()

让我们定义一个函数来获取没有任何缺失值的列

获取没有任何缺失值的列。

让我们看看有多少列

[out]:
Number of numerical columns with no nan values : 25 
Number of nun-numerical columns with no nan values : 20

Histogram of the features

特征之间的相关性

从上面的关联热图中,我们看到大约 15 个特征与目标高度相关。

一个热编码分类特征:

我们将使用一个热编码对分类特征进行编码。

[out]:
There were 45 columns before encoding categorical features 
There are 149 columns after encoding categorical features

现在,将组合数据帧拆分为训练数据和测试数据

第二:制作深度神经网络

  • 定义顺序模型
  • 添加一些密集层
  • 使用' relu '作为隐藏层的激活功能
  • 使用一个'普通的'初始化器作为内核初始化器

Initializers define the way to set the initial random weights of Keras layers.

  • 我们将使用平均绝对误差作为损失函数
  • 定义只有一个节点的输出层
  • 使用' linear '作为输出层的激活函数
[Out]:
_________________________________________________________________ Layer (type)                 Output Shape              Param #    ================================================================= dense_1 (Dense)              (None, 128)               19200      _________________________________________________________________ dense_2 (Dense)              (None, 256)               33024      _________________________________________________________________ dense_3 (Dense)              (None, 256)               65792      _________________________________________________________________ dense_4 (Dense)              (None, 256)               65792      _________________________________________________________________ dense_5 (Dense)              (None, 1)                 257        ================================================================= Total params: 184,065 Trainable params: 184,065 Non-trainable params: 0 _________________________________________________________________

定义检查点回调:

第三:训练模型:

[out]:
Train on 1168 samples, validate on 292 samples
Epoch 1/500
1168/1168 [==============================] - 0s 266us/step - loss: 19251.8903 - mean_absolute_error: 19251.8903 - val_loss: 23041.8968 - val_mean_absolute_error: 23041.8968  
Epoch 00001: val_loss did not improve from 21730.93555 
Epoch 2/500
 1168/1168 [==============================] - 0s 268us/step - loss: 18180.4985 - mean_absolute_error: 18180.4985 - val_loss: 22197.7991 - val_mean_absolute_error: 22197.7991  
Epoch 00002: val_loss did not improve from 21730.93555
.
.
.
Epoch 00500: val_loss did not improve from 18738.19831<keras.callbacks.History at 0x7f4324aa80b8>

我们看到最佳模型的验证损失是 18738.19

第四:测试模型

我们将把测试数据上的预测提交给 Kaggle,看看我们的模型有多好。

The result of the deep neural network’s submission on Kaggle

一点也不差,再做一些预处理和更多的训练,我们可以做得更好。

第五:尝试另一种 ML 算法:

现在,让我们尝试另一种 ML 算法来比较结果。

我们将使用随机森林回归器和 xgb 回归器。

将训练数据分割成训练和验证数据

我们先试试随机森林模式:

Random forest validation MAE =  19089.71589041096

制作提交文件,提交给 Kaggle 看结果:

The result of random forest’s submission on Kaggle

现在,让我们试试 XGBoost 模型:

[out]: 
XGBoost validation MAE =  17869.75410958904

制作一个提交文件,提交给 Kaggle 看结果:

The result of XGBoost’s submission on Kaggle

这不是一个惊喜吗,我真的不认为神经网络会击败随机森林和 XGBoost 算法,但让我们试着不要太乐观,记住我们没有在随机森林和 XGBoost 模型上配置任何超参数,我相信如果我们这样做,这两个模型会超过神经网络。

总结一下我们所做的事情:

  • 我们加载并处理数据集
  • 我们通过绘制一些直方图和特征的相关热图来熟悉数据集
  • 我们使用了具有三个隐藏层的深度神经网络,每个隐藏层具有 256 个节点。
  • 我们在输出层使用了线性激活函数
  • 我们训练了模型,然后在 Kaggle 上测试。
  • 我们还测试了另外两个模型
  • 我们的深度神经网络能够超越这两个模型
  • 我们相信,如果我们调整它们的超参数,这两个模型可以击败深度神经网络模型。

后续步骤:

  • 尝试在处理数据集上投入更多精力
  • 尝试其他类型的神经网络
  • 尝试调整我们使用的两个模型的超参数
  • 如果你真的想在回归问题上做得更好,遵循这个教程:

[ 累积回归:排行榜前 4% | ka ggle]

参考资料:

  • Python 中 Keras 深度学习库回归教程

可以在推特上关注我 @ModMaamari

您可能还喜欢:

  • AI 生成泰勒斯威夫特的歌词
  • 用 Python 介绍随机森林算法
  • 带 TensorFlow APIs 的机器学习速成班汇总
  • 如何用 Tensorflow 和 Keras 制作一个 CNN?
  • 如何选择最好的机器学习模型?

深层神经进化:遗传算法是用于强化学习的深层神经网络训练的竞争性替代方案——论文摘要

原文:https://towardsdatascience.com/deep-neuroevolution-genetic-algorithms-are-a-competitive-alternative-for-training-deep-neural-822bfe3291f5?source=collection_archive---------4-----------------------

Photo by veeterzy on Unsplash

2017 年 12 月,优步人工智能实验室发布了与神经进化相关的五篇论文,这是一种通过进化算法优化深层神经网络的实践。

本文是对题为“T4 深度神经进化:遗传算法是训练强化学习深度神经网络的一种竞争性选择”的论文的总结。它是为那些对机器学习相关主题有一些基本熟悉的人设计的。“遗传算法”和“梯度下降”等概念是前提知识。

优步人工智能实验室的五篇论文中的大部分研究,包括我正在总结的这篇论文,都是基于 OpenAI 在论文“进化策略作为强化学习的可扩展替代方案”中所做的研究。OpenAI 已经写了一篇博客文章来总结他们的论文。一个更短的总结(我写的)可以在这里找到。

本文实验所用代码可在找到,此处为。2018 年 4 月,该代码被优化为在一台个人电脑上运行。优步人工智能实验室的一篇博文描述了实现这一点的工作,具体代码可以在这里找到。

结果如何?

深度神经网络(DNN)通常使用基于梯度的方法(如反向传播)进行优化。本文表明,使用简单的遗传算法(g a)优化 dnn 是可能的,并且在应用于强化学习(RL)任务时,如学习玩雅达利游戏、模拟仿人运动或欺骗性迷宫问题时,GA 是基于梯度的方法的竞争替代品。

遗传算法的可伸缩性通过进化一个具有超过四百万参数的 DNN 来展示,这是有史以来用进化算法进化的最大的网络。并行化的能力意味着 GAs 的计算可以分布在许多 CPU 上,与基于梯度的方法相比,可以更快地训练 DNNs。此外,通过巧妙地将 DNN 参数表示为一系列随机种子,一个拥有超过 400 万个参数的网络可以在仅仅几千个字节内进行编码(小 1 万倍)。

新奇搜索 (NS),一种与 GAs 一起使用的技术,用于鼓励在具有欺骗性或稀疏奖励的任务中进行探索,在一个问题域(称为“图像硬迷宫”)中显示出优于其他仅针对奖励进行优化的基于梯度和进化的算法。

令人惊讶的是,在学习玩一些雅达利游戏时,随机搜索(RS)被发现是有竞争力的(尽管从未像 GAs 那样有竞争力)。这表明,在某些领域,围绕原点进行采样就足以找到合适的解决方案。

这些结果表明,GAs(和 RS)并不比其他优化 DNN 的方法更好或更差,但它们是一种“有竞争力的替代方案”,可以添加到他们的 RL 工具带中。

像 OpenAI 一样,他们指出,尽管 dnn 在监督学习中不会陷入局部最优,但由于欺骗性或稀疏的奖励信号,它们仍然会在 RL 任务中陷入困境。正是由于这个原因,与 RL 中其他流行的算法相比,基于非梯度的方法(如 GAs)可以执行得很好。

关于大会

关于天然气的介绍,我推荐 Vijini Mallawaarachchi 的博客文章。

RL 中流行的算法如 Q-learning 和策略梯度使用梯度下降。ES 也通过类似于有限差分的运算跟随梯度。与这些方法不同,遗传算法不遵循梯度,而是通过变异进行探索,通过选择进行开发来进化群体中的个体。

这项工作使用一个非常简单的遗传算法,目的是建立一个埃及艾滋病的基线。它非常简单,甚至没有使用交叉,这是一种在 GAs 中非常常见的技术,以至于一开始把这种算法称为 GA 都感觉很奇怪。

在初始化群体后,前 T 个个体(在这种情况下是神经网络参数向量)被选为潜在的亲本。然后从均匀随机(有替换)中选择这些个体,并通过添加高斯噪声使其变异,该高斯噪声具有为每个实验凭经验确定的标准偏差。每一代中得分最高的个体也被添加到下一代中(一个个体的精英主义)。

最先进的编码技术

我们提出了一种新的方法,通过将每个参数向量表示为初始化种子加上产生应用于 theta 的一系列突变的随机种子的列表,来紧凑地存储大的参数向量。这项创新对于使遗传算法能够在深度神经网络的规模上工作至关重要,因此我们称之为深度遗传算法。这种技术还具有提供最先进的压缩方法的优势。

在没有交叉的情况下,定义个体的种子列表等于代数。它具有降低内存和网络传输成本的优势。对于交叉,需要一种新的更复杂的方法来对个体进行编码。这种编码方法非常酷。用相对少量的种子代表数百万个神经网络参数。

新颖性搜索

[新奇搜索]是为欺骗性领域设计的,在这些领域中,基于奖励的优化机制会收敛到局部最优。NS 通过在进化过程中忽略奖励函数来避免这些局部最优,而是奖励代理执行以前从未执行过的行为(即,新颖的)。

NS 需要一个可以量化任意两个人行为差异的函数。在每一代之后,个人有小概率被添加到档案中。新个体的“新颖性”是通过与同代人以及档案中存储的人进行比较来确定的。

实验

实验集中在遗传算法在下列任务中的性能;从像素开始学习玩 Atari 游戏,连续控制模拟的人形学步车(MuJoCo),以及一个已知的欺骗性局部优化问题,称为“图像硬迷宫”。

雅达利

A simple genetic algorithm can evolve a deep neural network with 4M+ weights to play Frostbite well

13 款雅达利游戏入选。五个被选中是因为 ES 在他们身上表现很好。其他四个被选中是因为 ES 表现不佳。最后,从可用游戏的集合中按字母顺序选择四个。

雅达利游戏上的 GAs 性能与其他强化学习算法的性能进行了比较,如 DQN (Q-learning)、es 和 A3C (策略梯度)。ES 和 A3C 的结果都来自 OpenAI 的论文。为了便于比较,数据预处理和网络架构与 2015 年关于 DQNs 的论文中介绍的相同。自 2015 年以来,对 DQNs 进行了许多改进,但作者认为,将结果与香草 DQN 进行比较是有意义的,因为这项工作只使用了香草遗传算法。为了与 OpenAI 最近在 es 上的工作进行比较,代理在 GA 运行过程中经历的游戏帧数保持不变(10 亿帧),就像在 ES 实验中一样。这意味着代理将看到不同数量的帧(取决于它们的成功程度),并且 GA 运行中的代数是不固定的。

【本研究使用】Mnih 等人(2015) 提出的更大的 DQN 架构,由 3 个 32、64 和 64 信道的卷积层和一个 512 单元的隐藏层组成。卷积层使用跨度分别为 4、2 和 1 的 8 x 8、4 x 4 和 3 x 3 滤波器。所有隐藏层之后是整流器非线性(ReLU)。该网络包含超过 4M 个参数。

将遗传算法的结果与其他算法进行比较存在一些困难。不像 GA、ES 和 DQN 都是随机开始训练的,A3C 是使用人类开始样本的数据库来训练的。此外,DQN 的结果是使用大约 2 亿帧(由于计算时间过长)获得的,而 es、RS 和 GA 使用了 10 亿帧。

总的来说,遗传算法的性能与其他算法大致相当(见下表 1)。DQN、ES 和 GA 分别在三场比赛中获得最佳成绩,而 A3C 在四场比赛中获得最佳成绩。

对于某些游戏,GA 有时在一代或几十代内就胜过 DQN 和 es。在第一代中发现的那些解决方案本质上是随机的 dnn,因为甚至没有一轮选择。那么 GA 只是在做随机搜索吗?这里 RS 是 GA 的特例,代数等于 1。看结果,GA 总是胜过 RS。但是天哪,RS 可以在某些领域打败 DQN,A3C 和 ES。

A deep neural network found through random search plays Frostbite surprisingly well

RS 对 DQN、A3C 和 ES 的成功表明,许多基于领先的深度 RL 算法的低性能而看起来很难的 Atari 游戏可能没有我们想象的那么难,相反,由于某种原因,这些算法在实际上很容易的任务上表现极差。

Table 1. The Atari results reveal a simple genetic algorithm is competitive with Q-learning (DQN), policy gradients (A3C), and evolution strategies (ES). Shown are game scores (higher is better). Comparing performance between algorithms is inherently challenging (see main text), but we attempt to facilitate comparisons by showing estimates for the amount of computation (operations, the sum of forward and backward neural network passes), data efficiency (the number of game frames from training episodes), and how long in wall-clock time the algorithm takes to run. The GA, DQN, and ES, perform best on 3 games each, while A3C wins on 4 games. Surprisingly, random search often finds policies superior to those of DQN, A3C, and ES (see text for discussion). Note the dramatic differences in the speeds of the algorithm, which are much faster for the GA and ES, and data efficiency, which favors DQN. The scores for DQN are from Hessel et al. (2017) while those for A3C and ES are from Salimans et al. (2017).

人形运动

Humanoid locomotion, controlled by a deep neural networks trained with a simple genetic algorithm.

遗传算法接下来在一个连续控制问题上进行测试,其中一个模拟的人形机器人学习走路。使用的软件是MuJoCo(open Dai 健身房的 Humanoid-v1 环境)。

这个问题包括将描述人形机器人状态(例如,其位置、速度、角度)的 376 个标量的向量映射到 17 个关节扭矩。机器人会收到一个标量奖励,每个时间步长由四个部分组成。它的站姿和在 x 轴正方向的速度会得到正回报,消耗的能量越多,撞击地面的力度越大,得到的回报就越低。这四项在一集的每一个时间点上相加,计算出总奖励。

与 es 相比,GA 需要更多的计算来获得类似的结果,这是令人惊讶的,因为 GA 在 Atari 游戏上表现得非常好。

形象硬迷宫

The Image Hard Maze domain

图像硬迷宫是一个包含局部最优(陷阱)的问题,它欺骗贪婪地接近目标的代理。

查新没有这个问题,因为它忽略了奖励,鼓励代理人去新的地方。如前所述,NS 需要一个行为差异函数来确定“新颖性”。对于这个问题,该函数是最终位置之间的平方欧几里得距离。

神经网络看到迷宫的鸟瞰图,这是 84×84 像素的图像,有超过 400 万个参数。它通过速度和旋转输出来控制机器人在迷宫中的导航。前三帧也是提供时间信息的输入的一部分。

执行新颖性搜索允许遗传算法解决这个任务,而只为奖励(到目标的最小距离)优化的遗传算法和专家系统陷入局部最优。DQN 和 A2C(A3C 的源代码不可用)也无法进行足够的探索来与 GA-n 竞争。

How different algorithms explore the deceptive Image Hard Maze over time. Traditional reward-maximization algorithms do not exhibit sufficient exploration to avoid the local optimum (going up). In contrast, a GA optimizing for novelty only (GA-NS) explores the entire environment and ultimately finds the goal. All 3 evolutionary algorithms had the same number of evaluations. For DQN and A2C, we plot the end-of-episode position of the agent for each of the 20K episodes prior to the checkpoint listed above the plot.

结论

实验表明,与 DQN、A3C 和 ES 等其他众所周知的算法相比,遗传算法是 RL 中有竞争力的替代算法,有时性能更好,有时性能更差。这项工作只使用了简单的遗传算法,通过将遗传算法与其他已知在神经进化领域有效的技术相结合,或者将遗传算法与其他 RL 算法相结合,可能会发现新的结果。

虽然这些结果看起来很有希望,但也有可能采取稍微悲观一点的观点。2018 年 3 月,Ben Recht 与人合著了一篇名为简单随机搜索的论文,提供了一种增强学习的竞争方法,其中他的团队利用 RS 实现了 MuJoCo 行走任务的最先进水平。他的结论与本文中关于这些结果的结论相似,即 RS 在这些领域的成功表明这些问题并不像以前认为的那样困难。

然而,论文中的工作确实证明了一个简单的遗传算法可以优于 RS,并且通过继续在这个方向上的研究可能会有进一步的收获。它还表明,在当前流行的算法中,存在关于采样效率和计算时间的折衷。考虑到您的用例,这是可以考虑的。如果样品的成本很高,基于梯度的方法可能更好。如果时间是限制因素,遗传算法会更快地为你找到解决方案。也许在未来,我们将能够指定一个“速度与采样效率”的折衷方案,并找到一个同时使用 EAs 和基于梯度的方法的解决方案。

深度分位数回归

原文:https://towardsdatascience.com/deep-quantile-regression-c85481548b5a?source=collection_archive---------4-----------------------

深度学习尚未广泛探索的一个领域是估计的不确定性。大多数深度学习框架目前专注于给出由损失函数定义的最佳估计。偶尔需要一些超出点估计的东西来做决定。这就是发行版有用的地方。贝叶斯统计很好地解决了这个问题,因为可以推断出数据集的分布。然而,贝叶斯方法迄今为止一直相当慢,并且应用于大型数据集将是昂贵的。

就决策而言,大多数人实际上需要分位数,而不是估计中的真正不确定性。例如,当测量给定年龄的儿童的体重时,个体的体重会变化。有趣的是(为了便于讨论)第 10 和第 90 百分位。请注意,不确定性不同于分位数,因为我可以请求第 90 个分位数的置信区间。本文将纯粹专注于推断分位数。

分位数回归损失函数

在回归中,最常用的损失函数是均方误差函数。如果我们取这个损失的负值并对其求幂,结果将对应于高斯分布。该分布的模式(峰值)对应于均值参数。因此,当我们使用使这种损失最小化的神经网络进行预测时,我们预测的是可能在训练集中有噪声的输出的平均值。

单个数据点的分位数回归损失定义为:

Loss of individual data point

其中,alpha 是所需的分位数(0 到 1 之间的值),而

其中 f(x)是预测(分位数)模型,y 是相应输入 x 的观测值。整个数据集的平均损失如下所示:

Loss funtion

如果我们取个体损失的负值并对其取指数,我们得到的分布称为不对称拉普拉斯分布,如下所示。这个损失函数起作用的原因是,如果我们要找到图中零左边的面积,它将是α,即所需的分位数。

probability distribution function (pdf) of an Asymmetric Laplace distribution.

当α= 0.5 时的情况很可能更熟悉,因为它对应于平均绝对误差(MAE)。这个损失函数始终估计中位数(第 50 个百分位数),而不是平均值。

Keras 中的建模

正向模型与你做 MSE 回归时的模型没有什么不同。改变的只是损失函数。下面几行定义了上一节中定义的损失函数。

**import** **keras.backend** **as** **K****def** tilted_loss(q,y,f):
    e = (y-f)
    **return** K.mean(K.maximum(q*e, (q-1)*e), axis=-1)

当涉及到编译神经网络时,只需简单地做:

quantile = 0.5
model**.**compile(loss**=lambda** y,f: tilted_loss(quantile,y,f), optimizer**=**'adagrad')

完整的例子见[这个 Jupyter 笔记本](https://github.com/sachinruk/KerasQuantileModel/blob/master/Keras Quantile Model.ipynb),我在那里看了一段时间的摩托车碰撞数据集。结果如下,我显示了第 10、50 和 90 个分位数。

Acceleration over time of crashed motor cycle.

最终注释

  1. **注意,对于每个分位数,我必须重新运行训练。**这是由于每个分位数的损失函数是不同的,因为分位数本身就是损失函数的一个参数。
  2. 由于每个模型都是简单的重新运行,因此存在分位数交叉的风险。即第 49 个分位数可能在某个阶段超过第 50 个分位数。
  3. 请注意,分位数 0.5 与中位数相同,可以通过最小化平均绝对误差来实现,这可以在 Keras 中实现,与loss='mae'无关。
  4. 不确定性和分位数是而不是一回事。但是大多数时候你关心的是分位数而不是不确定性。
  5. 如果你真的想要深度网络结帐的不确定性http://mlg.eng.cam.ac.uk/yarin/blog_3d801aa532c1ce.html

编辑 1:

正如 Anders Christiansen (在回答中)指出的,我们可以通过设定多个目标一次获得多个分位数。然而,Keras 通过一个loss_weights参数组合了所有损失函数,如下所示:https://keras . io/getting-started/functional-API-guide/# multi-input-and-multi-output-models。在 tensorflow 中实现会更容易。如果有人捷足先登,我会很乐意改变我的笔记本/帖子来反映这一点。作为一个粗略的指导,如果我们想要分位数 0.1,0.5,0.9,Keras 中的最后一层将有Dense(3),每个节点都连接到一个损失函数。

编辑 2

感谢 Jacob Zweig 在 TensorFlow 中实现同时多个分位数:https://github . com/strong io/Quantile-regression-tensor flow/blob/master/Quantile % 20 loss . ipynb

思考后:

这些是我的一些想法,是我在一年前写这篇文章时补充的。

  1. 多个分位数:我想得越多,我就越确信你应该一次完成所有的分位数。例如,如果我们需要分位数 0.05、0.5 和 0.95,则有 3 个输出节点,每个节点有一个不同的损失函数(求和得到最终损失)。这确保了数据的结构在前几层是共享的。
  2. 分位数交叉:为了确保我们避免这种情况,非中位数分位数,例如 0.95,可以建模为(节点 0.5 + sigma * sigmoid(0.95 节点))。其中 sigma 是最大值,我们期望 0.95 分位数偏离中值。类似思想可以在 0.05 分位数上实施,而代之以 sigma * sigmoid(0.05 节点)上的负号。

看这里是我关于机器学习和深度学习的课程(使用代码 Deep school-三月到九折)。

张量流中的深度分位数回归

原文:https://towardsdatascience.com/deep-quantile-regression-in-tensorflow-1dbc792fe597?source=collection_archive---------6-----------------------

深度学习中的一个关键挑战是如何获得对预测器界限的估计。分位数回归最早由 Koenker 和 Bassett [1]在 70 年代引入,它允许我们估计潜在条件数据分布的百分位数,即使在它们不对称的情况下,也能让我们了解预测因子和反应之间的变异性关系。

如 Koeneker 和 Hallock [2]所述,OLS 回归的标准方法是通过绘制一条线来估计数据的条件平均值*,该线使该线和图上所有点之间的距离最小化。相反,分位数回归的目标是估计有条件的*中位数、或任何其他分位数。为此,我们根据所选的分位数对图表上的点和我们的回归线之间的距离进行加权。例如,如果我们选择第 90 个分位数进行估计,我们将拟合一条回归线,使 90%的数据点低于该线,10%高于该线。

张量流代码

Sachin Abeywardana 最近在 medium 上发表的一篇伟大的文章展示了如何使用 Keras 进行深度分位数回归。然而,这种实现的限制是,它需要每个分位数单独拟合模型。然而,使用 Tensorflow,我们可以同时拟合任意数量的分位数。

用于此实现的笔记本可以在 Strong Analytics github 上找到。

我们首先实例化一个简单的回归模型,并为我们想要估计的每个分位数添加输出

# Define the quantiles we’d like to estimate
quantiles = [.1, .5, .9]# Add placeholders for inputs to the model
x = tf.placeholder(tf.float32, shape=(None, in_shape))
y = tf.placeholder(tf.float32, shape=(None, out_shape))# Create model using tf.layers API
layer0 = tf.layers.dense(x, units=32, activation=tf.nn.relu)
layer1 = tf.layers.dense(layer0, units=32, activation=tf.nn.relu)# Now, create an output for each quantile
outputs = []
for i, quantile in enumerate(quantiles):
    output = tf.layers.dense(layer1, 1, name=”{}_q{}”.format(i, int(quantile*100)))
    outputs.append(output)

现在,我们为每个分位数创建损失

losses = []
for i, quantile in enumerate(quantiles):
   error = tf.subtract(y, output[i])
   loss = tf.reduce_mean(tf.maximum(quantile*error, (quantile-1)*error), axis=-1)
   losses.append(loss)

最后,我们合并损失并实例化我们的优化器

combined_loss = tf.reduce_mean(tf.add_n(losses))
train_step = tf.train.AdamOptimizer().minimize(combined_loss)

基本上就是这样了!现在,我们可以拟合我们的模型,同时估计所有指定的分位数:

for epoch in range(epochs):
   # Split data to batches
   for idx in range(0, data.shape[0], batch_size):
     batch_data = data[idx : min(idx + batch_size, data.shape[0]),:]
     batch_labels = labels[idx : min(idx + batch_size, labels.shape[0]),:] feed_dict = {x: batch_data,
                 y: batch_labels} _, c_loss = sess.run([train_step, combined_loss], feed_dict)

将这些数据拟合到摩托车碰撞的数据集上(从此处开始)得到以下输出:

Estimated quantiles

参考文献

1.回归分位数。罗杰·科恩克;吉尔伯特·巴塞特,《计量经济学》,第 46 卷,第 1 号。(1978 年 1 月),第 33-50 页。

2.分位数回归。罗杰·科恩克;凯文·f·哈洛克。《经济展望杂志》第 15 卷第 4 期,2001 年秋季。(第 143-156 页)。

想和芝加哥的顶级数据科学家团队一起从事各种行业中具有挑战性的机器学习和人工智能工作吗?我们正在招聘有才华的数据科学家和工程师!

在 strong.io 了解更多信息,并在 careers.strong.io 申请

新闻推荐的深度强化学习。第 1 部分:架构。

原文:https://towardsdatascience.com/deep-reinforcement-learning-for-news-recommendation-part-1-architecture-5741b1a6ed56?source=collection_archive---------8-----------------------

我将试着涵盖这篇文章的内容,如果你想了解更多细节,可以考虑阅读它。

.

.

.

重要说明

在这一点上,这篇文章已经过时了。它包含许多错误和不一致之处。我发表了另一篇 33 分钟(7k 字)的文章,对这个项目进行了深入的探讨。考虑改为阅读。附:绝对免费:链接

[## 用于新闻推荐的强化学习(DDPG 和 TD3)

强化学习是一个相当难的话题。当我开始深入挖掘时,我意识到需要一个好的…

towardsdatascience.com](/reinforcement-learning-ddpg-and-td3-for-news-recommendation-d3cddec26011)

.

.

.

大多数现有的推荐系统使用静态方法进行新闻预测,也就是说,它们不理解你的行为(新闻选择)是连续的。第二个问题是,以前的方法往往是短视的,这意味着它们不会关注长期回报。使用较高的 gamma 值可以很容易地解决这个问题,但通常情况并非如此。

嵌入概述

嵌入是一种工具,它允许我们对一些对象的含义进行编码,以便找出它们之间的相似程度。在下面的例子中,你可以看到托尔斯泰的书彼此之间非常相似,但与希区柯克的有很大不同。它们用向量表示,相似性用点积符号计算

**books = ["War and Peace", "Anna Karenina", 
          "The Hitchhiker's Guide to the Galaxy"]****books_encoded_ideal = [[0.53,  0.85],
                       [0.60,  0.80],
                       [-0.78, -0.62]]****Similarity (dot product) between First and Second = 0.99
Similarity (dot product) between Second and Third = -0.94
Similarity (dot product) between First and Third = -0.97**

强化学习回顾:

强化学习简介:我们有一个在环境中行动的代理。相应地,这些行为会以分数的形式得到奖励。环境为代理提供状态并采取行动,将他带到下一步。整个过程被称为马尔可夫决策过程(或简称为 MDP)。基本上,有两种类型的预测:政策和 Q 学习。Q-Learning 训练一个神经网络,试图估计下一步和未来步骤的最佳回报(记住,不同的行动可能会有不同的回报)。然而,政策学习试图学习下一步行动的概率。

马尔可夫表示:

  • 状态 s 是用户正面交互历史的表示
  • 动作 a。动作 a 是排名分数的向量。这个动作是用户想要阅读的理想新闻。
  • 状态被建模为用户的积极交互历史的表示。因此,一旦收集了用户的反馈,就定义了状态转换。
  • 给定基于动作 a 和用户状态 s 的推荐,用户将提供她的反馈,即点击、未点击或评级等。推荐者根据用户的反馈接收即时奖励 R(s,a)。
  • 贴现率γ。γ ∈ [0,1]是衡量长期报酬现值的一个因素。

以前的方法比较

Q-Learning 的问题是,由于对整体行动的评估,如果行动空间太大,这些方法可能会变得非常低效。尽管政策在更大的行动空间上更收敛,但它们不能理解序列特征。

介绍够了,我们来看看是什么样子的:

它是如何工作的

假设,我们观察了用户的行为,获得了他们点击的一些新闻帖子。它被输入到演员网络,演员网络决定我们接下来想读什么。它产生一个理想的新闻嵌入。可以和其他新闻嵌入进行对比,寻找相似之处。最匹配的会推荐给用户。评论家帮助判断演员,并帮助它找出错误。也有助于预测未来的行为。例如,推荐者建议用户购买一本书。它买它没有问题,并立即收到 100 英镑的奖励。但也可能发生的情况是,用户想要在未来归还这本书,惩罚我们-500。所有未来的行动都需要考虑在内。Q 网(评论家)也是如此,如前所述,政策方法往往是短视的,没有能力预测未来的回报。

体系结构

如你所见,这个网络由两层组成:演员和评论家。每一种都类似于不同的学习类型:行动者学习政策(下一步选择哪种行动的概率),而批评家关注回报(Q 学习)。首先,一堆新闻嵌入被馈入演员的状态表示模块,在那里被编码。然后做出决定(动作)(以向量的形式)。结合项目嵌入,行动被输入到评论家模块,该模块旨在评估奖励将有多好。

状态模块

首先是状态表示模块,“它显式地对复杂的动态用户-项目交互进行建模,以追求更好的推荐性能”。简单地说,你可以把它看作是捕捉句子中单词语义的嵌入,但是用新闻和客户代替。嵌入的嵌入,多么可悲。它起着两个关键作用:用于排名和作为评论家网络的输入与行动相结合。

演员网络(政策)

对于给定的用户,网络负责基于她的状态 s 生成动作。由她的 n 个最近的积极交互项目的嵌入所表示的用户状态被用作输入。它们被馈送到状态模块,以便为用户产生状态的概括表示。然后,表示被转换成动作,一个大小为 n 的向量,范围在(-1,1)之间。

正如你所看到的,作者没有使用 softmax 来排名分数:

注意,在我们的模型中,一个动作既不对应于推荐一个项目,也不对应于推荐一个项目列表。相反,动作是一个连续的参数向量。采取这样的动作,通过执行具有项目嵌入的乘积(多重向量),参数向量用于确定所有候选项目的排名分数。

下一步很重要:

批评家网络(Q 学习)

用来估计当前状态和动作的奖励会有多好:Qπ (s,a)。批评家网络的输入是用户状态表示模块产生的用户状态 s 和策略网络产生的动作,输出是 Q 值,Q 值是一个向量。根据 Q 值,演员网络的参数朝着提高动作 a 性能的方向更新,我不打算写所有的渐变,主要是因为我用的是 Pytorch。损失函数是简单的均方误差,因为我们要估计的是通常不归一化的实值回报,所以这是一个回归问题。

州立模块动物园

DRR-p-利用项目之间的成对依赖性。它通过使用元素级乘积运算符来计算 n 个项目之间的成对交互。(用户-项目交互被忽略!)

在 DRR 大学,我们可以看到用户嵌入也被纳入。除了项目之间的局部依赖,还考虑了用户-项目的成对交互。

当我们处理大量长期新闻时,我们并不期望立场有什么影响。但是,如果序列 H 是一个短期序列,记忆项目的位置可能会导致过拟合。由于采用了平均池层,我们将该结构称为 DRR-ave。从图 6 中可以看出,H 中的项目嵌入首先通过加权平均池层进行变换。然后,利用得到的向量来对与输入用户的交互进行建模。最后,嵌入的用户、交互向量和项目的平均池化结果被连接成一个向量来表示状态表示。

在下一篇文章中,我将尝试使用深度确定性策略梯度在 Pytorch 中实现这个网络,正如在原始论文中所描述的那样。如果这引起了足够的注意,我将详细解释算法。为它鼓掌,敬请关注!

Upd:开始了一个 github 项目(还不理想,但是模型正在学习)

经过处理的数据将很快上传,但现在需要几个小时来处理。需要的话就 Dm 我。我对下一篇文章有一些大的想法,这将是关于这个主题的最后一篇文章,但是非常大而且有解释性。别忘了开始!

https://github.com/awarebayes/RecNN

对一个不很深的神经网络的深入研究。第 1 部分:我们的数据中有什么

原文:https://towardsdatascience.com/deep-study-of-a-not-very-deep-neural-network-part-1-whats-in-our-data-7971356037a3?source=collection_archive---------5-----------------------

介绍

开始深度学习之旅的人经常被为他们的神经网络选择正确的配置和超参数的问题所困惑。各种课程、教程和教科书只是简要描述了可用的选项,并没有提供关于它们的适用性和性能的指导。在大多数教程中,都提到一些函数、优化器或初始化器比其他的更好,但没有解释为什么,或者在什么条件下。某些参数,如单位数或时期数,有时没有任何正当理由。学生们被告知在课余时间和他们一起“玩耍”,看看是否能提高成绩。许多作者将寻找神经网络最佳配置的过程称为一门艺术,并表示选择正确值的能力来自经验。我不相信它总是对的。一些常识应该让在这一领域迈出第一步的人容易获得,而不需要浏览数百篇研究论文。

所以我开始写一系列文章,描述我在过去几个月里进行的一项实验的结果。也就是说,我已经评估了一个非常简单的神经网络的几乎每一个可调位,以了解这些变化如何影响最终的精度。

具体来说,在这个系列中,我们将看到:

  • 训练数据的统计如何影响模型的质量;
  • 对于全连接神经网络,激活函数和优化器的哪种组合工作得更好;
  • 学习率过高有什么影响,如何处理;
  • 如何让训练更稳定、可复制;
  • 初始化器、正则化器和批处理规范化如何影响神经网络的内部结构;
  • 模型的性能如何取决于单元和层数。

在这个系列中,我将只关注一个全连接的神经网络,它被设计用来从著名的 MNIST 数据集中对手写数字进行分类。使用 MNIST 的原因很简单:它很均衡,所以我们可以确信测试结果是充分的;它不是太大,所以我们可以在合理的时间内训练各种参数组合的模型,它内置在所有主要的深度学习框架中。

全连接神经网络架构可能是最简单的一种,而且它通常是深度学习书籍和课程中介绍的第一种。尽管这种架构很简单,但它有如此多的参数和选项可供选择,以至于人们常常将一切都保留为默认值,希望这些值会产生可接受的性能。

当然,还有更合适的方法来处理 MNIST,比如使用卷积神经网络。但在这里,我们的任务不是要打破最先进的模型的分数。相反,我们关注的是网络的每个参数在最终精度中的作用。

这不是一个介绍性的教程,读者应该至少对神经网络有基本的了解,它们是如何工作的,如何构建和训练它们。为了建立网络,我将使用 Keras 与 TensorFlow 后端。

试验设计

我们实验的基线代码将取自 Keras 库的示例。在本系列的课程中,我们将稍微修改它,以便让我们看到它的各个部分的变化是如何影响测试集的准确性的。

配置将基于验证准确性值进行评估,因为这是我们案例中最客观的指标。损失分数不提供太多信息,并且由于可能的过度拟合,训练集的准确性不具有代表性。

每个配置将被测试 5 次(即,对于每个配置,将从头开始训练 5 个神经网络),以便减少不可避免的随机性的影响,然后将对训练这些配置的结果精度进行平均。这将有助于确保我们看到更有代表性的结果。

我们的神经网络最初将由两个各有 64 个单元的全连接层和一个有 10 个单元和 softmax 激活的输出层组成。

数据准备

本系列的第一部分讨论了在将数据输入神经网络之前用于转换数据的各种技术。

MNIST 数据集包含 60 000 幅训练图像和 10 000 幅测试图像,每幅图像为 28x28 像素。每个像素都有一个介于 0 和 255 之间的值,其中 0 表示完全黑色,255 表示白色。在数据科学中,数据通常被换算成小的实数。这样做的原因是为了使模型更快地收敛,并找到更好的极小值。

下面是 Geoffrey Hinton 如何表述这个问题:“当误差面是一个二次碗的时候”……“下坡减少了误差,但是最陡下降的方向并不指向最小值,除非椭圆是一个圆。”以下是他对这个问题的设想:

Fig.1 Error surfaces with shifted and scaled inputs. Source: http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf

有两种方法可以在将数据输入神经网络之前对其进行转换,并使误差曲面更加平滑。

一种是转换数据,使所有矢量分量都适合[0;1]范围。这叫正常化。这里,我们取输入向量的每个分量的最小值,从各自的分量中减去它们,然后除以每个分量的最大值。

另一种方法是使数据具有 0 均值和单位方差(等于 1)。它是通过计算每个分量的平均值和标准偏差,然后从每个分量值中减去平均值,再除以各个分量的标准偏差来实现的。有时这也被称为标准化,但是为了清楚起见,我们称之为标准化。

在处理 MNIST 时,我们使用 28x28 的图像,为了能够将其输入到一个完全连接的网络中,我们首先需要将它们展平,即将每个图像转换为 28x28 = 784 维的向量。在 MNIST,这个向量的所有分量都代表像素,像素的值只能在 0 到 255 之间。

因此,可以自然地假设每个图像应该具有至少一个完全黑色和完全白色的像素,并且只使用整个数据集的全局最小值和最大值,或者平均值和标准偏差值。实际上,数据集中的每个样本可能都有自己的统计数据,因此,如果使用全局值对它们进行变换,数据集作为一个整体将具有所需的统计数据,但每个单独的样本将会发生移位和缩放。为了说明这一点,让我们看看前 4 个 MNIST 样本:

Fig.2 MNIST Sample Images

几乎可以肯定,这些图像中的每一个都具有至少一个完全黑色的像素(即零值)。但是代表白色的值 255 可能不是这种情况。看看这些样品:

Fig.3 MNIST Sample Images

令人惊讶的是,这些样本没有完全白色的像素,即使你可能认为粗体白色区域应该是白色的。因此,如果您使用全局最小值和最大值对它们进行规格化,则这些图像的值范围会以不同于样本的方式进行缩放,样本的最小值和最大值等于全局值。对于我们的黑白图像来说,这不是一个大问题,人眼甚至不会注意到这样的变化。但在其他情况下,如彩色图像,这可能会完全转换图像,因此单独归一化每个样本总是更好的方法。

标准化也是如此。直观地,我们可以理解,对于每个图像,各种像素值的分布是不同的,并且使用全局平均值和标准偏差值来标准化它们可能会错误地转换样本,并且最终导致模型的较差性能。我们将很快验证这个假设。

现在让我们看一下归一化数据分布图(数据集和样本的归一化几乎相同,所以我只给出第一种情况):

Fig.4 MNIST data. Pixel values distribution after dataset-wise normalization.

该直方图显示了数据中每个离散值的计数。从左侧的直方图中,我们可以看到大部分数据为零。事实上,零值构成了我们的归一化数据中所有数据点的大约 20%,即我们的 MNIST 图像数据中 20%的像素是黑色的。如果我们绘制不带 0 的数据分布,下一个大组是 1,代表完全白色的像素。

标准化数据的统计数据:

数据集标准化数据的直方图是相同的,只是水平轴的范围现在为-0.424 到 2.822。

Fig.5 MNIST data. Pixel values distribution after dataset-wise standardization.

数据的形式没有改变,但它被移动和缩放了。现在让我们来看看数据集标准化数据的统计数据:

数据集现在作为一个整体被标准化了(数据集的平均值实际上是零),但是每个样本都有不同的平均值和方差。还要注意,数据分布形状的身份由与归一化数据相同的全局偏斜度和峰度来确认。

现在让我们对每个样本进行标准化。这是样本标准化数据的曲线图:

Fig.6 MNIST data. Pixel values distribution after sample-wise standardization.

统计数据是:

显著的差异。现在每个样本都是标准化的,但是整个数据集也是标准化的:平均值非常小,我们可以把它算作零,方差非常接近 1。

现在让我们来看看,这些转变是否真的有所不同。我们将使用所有四个转换数据集来训练我们的简单神经网络。

培训结果

示例代码最初使用 RMSProp 优化器和 ReLU 激活,所以我们将在第一个实验中使用它们。我们将比较在四种数据转换类型中的每一种上训练相同配置的神经网络的结果:标准化数据集和样本,以及标准化数据集和样本。

它们将通过以下方法进行比较:

  • 最后一个时期的平均值:第 100 个时期的验证准确度值在 5 次实验中取平均值;
  • 达到的平均最大值:5 次实验的平均训练统计的最高验证准确度值;
  • 最后一个时期的总最大值:5 次实验中第 100 个时期的最高验证准确度值
  • 达到的总最大值:在该激活的所有实验中观察到的最高验证准确度值;
  • 平均最大历元:达到平均最大值时的历元数。

注意:为了计算该实验和进一步实验中的平均最大精度,而不是找出特定配置的 5 个实验中每个实验的最大值,然后将它们除以 5,我对整个训练过程进行平均,即对于步骤 N,我取在步骤 N 的 5 个实验中的每个实验中观察到的精度,然后对它们进行平均。这样,我计算平均训练进度,并取其最大精度。我相信,这种方法更好地代表了特定配置下的典型训练结果。

很明显,在我们的网络配置中,标准化数据比标准化数据显示出更好的结果。从这些结果来看,不可能判断数据集的标准化是否优于样本的标准化,但这可能只是因为我们数据集的特殊性。最有可能的是,对于其他数据集,您将通过样本标准化获得更高的结果。

至于标准化,我们已经证实,使用全局值来标准化我们的训练数据是错误的。然而,在我们的实验中,样本标准化导致较低的准确性,这一事实并不意味着情况总是如此。在后面的部分中,我们将看到在一些特定的神经网络配置中,样本标准化可能会导致比标准化数据高得多的结果。

下图显示了四种数据在训练过程中的准确度变化:

Fig.7 Validation accuracy for dataset-wise and sample-wise input data transformations.

虚线代表单个实验,黑线代表这些实验的平均精度。以下是所有四个平均值的比较结果:

Fig.8 Average validation accuracy for networks trained on various transformations of the input data.

同样,根据标准化数据训练的网络彼此非常接近,样本标准化训练稍差,但不像数据集标准化那样差。此外,请注意,对于标准化数据,训练的稳定性稍差,即,随着训练的进行,精确度上下变化较大。这可以通过调整学习速率来部分解决,我们将在下一部分中尝试。

第一部分的学习要点:

  • 在建立你的神经网络和开始训练之前,看一下你的数据:统计数据和它的底层结构可能在实现你的模型的高性能方面发挥很大的作用;
  • 规范化或标准化数据组件的方式,而不是使用全局统计值,否则您可能会改变它,使一些有价值的信息隐藏您的数据可能会丢失或损坏。

实验的代码可以在我的 github 上找到。在下一部分我们将研究激活函数,它是神经网络的一部分,将你准备好的输入数据转化为输出。敬请期待!

我总是很高兴认识新朋友并分享想法,所以如果你喜欢这篇文章,可以考虑在 LinkedIn 上加我。

深度学习一个不是很深的神经网络系列:

  • 第 1 部分:我们的数据中有什么
  • 第二部分:激活功能
  • 第 3a 部分:优化器概述
  • 第 3b 部分:选择优化器
  • 第四部分:如何找到合适的学习率
  • 第 5 部分:压差和噪声
  • 第 6 部分:权重初始化
  • 第 7 部分:正规化
  • 第 8 部分:批处理规范化
  • 第 9 部分:大小很重要
  • 第 10 部分:将它们融合在一起

对一个不很深的神经网络的深入研究。第 2 部分:激活函数

原文:https://towardsdatascience.com/deep-study-of-a-not-very-deep-neural-network-part-2-activation-functions-fd9bd8d406fc?source=collection_archive---------4-----------------------

这是该系列的第二部分,这次我们将探讨激活函数。我假设你已经知道,什么是激活函数,以及它在神经网络中扮演什么角色。

在我们的实验中,我们将比较 Keras 中包含的激活功能,具体如下:

  • 线性;
  • 乙状结肠;
  • 硬乙状结肠;
  • TanH
  • 软设计;
  • ReLU
  • 漏水的 ReLU
  • 阈值 ReLU
  • ELU;
  • SELU;
  • 软加。

正如在上一部分中一样,这里我们将坚持使用 RMSProp 优化器。在本系列的后面部分,我们还将评估各种激活函数如何与不同的优化器一起工作,但现在让我们先来看看激活。至于数据,我们将在数据集标准化数据(因为它与样本标准化数据相比表现同样出色)和样本标准化数据(如果你读过前一部分,你就知道为什么)上训练我们的网络。

下面是对每个激活功能的一个简短且不太科学的描述,只是为了让你对每个有一个直观的了解。

线性的

线性激活(也称为恒等式)函数是最简单的激活函数之一。它将输入线性转化为输出。现在,无论是在隐含层还是在最终层,它几乎从未用于训练神经网络。它的值域和定义域等于[-Inf;+Inf]。

Fig.1 Linear activation

乙状结肠的

Sigmoid 激活函数翻译范围在[-Inf;+Inf]到(0;1),看起来像一条 S 形曲线。当开发用于学习目的的简单神经网络时,它通常是第一选择,但是到目前为止,它通常被避免,因为与其他激活函数相比,它的质量较低。

遭受消失梯度问题,当“在某些情况下,梯度将消失得很小,有效地防止重量改变其值”。

Fig.2 Sigmoid activation

硬乙状结肠

该函数是 sigmoid 函数的分段线性近似。在区间[-Inf 上等于 0;-2.5),然后在[-2.5;+2.5]并在范围(+2.5;+Inf] ( 来源)。计算硬 Sigmoid 被认为比计算常规 Sigmoid 更快,因为您不必计算指数,并且它在分类任务上提供了合理的结果。但是正因为它是一个近似值,它不应该用于回归任务,因为误差会比常规的 sigmoid 高得多。

Fig.3 Hard Sigmoid activation

双曲正切值

TanH 看起来很像 sigmoid 的 S 形曲线(其实只是一个缩放的 Sigmoid),但是它的范围是(-1;+1).在更复杂的激活函数出现之前,它已经相当流行了。简而言之,使用 TanH 代替乙状结肠的好处是(来源):

  1. 更强的梯度:如果数据以 0 为中心,导数更高。
  2. 避免由于包含范围(-1;0).

然而,与 Sigmoid 类似,TanH 也容易受到消失梯度问题的影响。

Fig. 4 Hyperbolic Tangent (TanH) activation

软设计

作为符号函数的连续近似,其图形看起来非常类似于 TanH。然而,TanH 是指数增长,而 SoftSign 是多项式增长。软签名的范围也是(-1;+1).

Fig.5 SoftSign activation

整流线性单元

一个非常简单而强大的激活函数,如果输入为正,则输出输入,否则输出 0。声称它是目前训练神经网络最流行的激活函数,并且产生比 Sigmoid 和 TanH 更好的结果。这种类型的激活函数不容易受到消失梯度问题的影响,但是它可能遭受“垂死的 ReLU 问题”。正如在维基百科中所说:“ReLU 神经元有时会被推入对几乎所有输入都不活跃的状态。在这种状态下,没有梯度回流通过神经元,因此神经元陷入永久不活动状态并“死亡”。“在某些情况下,网络中的大量神经元可能会陷入停滞状态,从而有效降低模型容量。当学习率设置得太高时,通常会出现这个问题。”下面是对这个问题的一个很好的描述:https://www . quora . com/What ' s-the-dying-ReLU-problem-in-neural-networks。

这个激活函数有参数 alpha,它控制 x < 0 and is set to 0.0. Setting this parameter to any value < 1.0 transforms this activation into Leaky ReLU and setting it to 1.0 makes this function work as Linear activation. What happens, when alpha is > 1.0 的直线的陡度,研究起来会很有趣。

Fig.6 Rectified Linear Unit (ReLU) activation

泄漏 ReLU

ReLU 函数的一个变体,允许输入< 0, which helps to 的梯度α的少量“泄漏”,克服了即将消失的 ReLU 问题。默认情况下,Keras alpha 设定为 0.3

Fig.7 Leaky ReLU activation with various alpha parameters

阈值 ReLU

ReLU 激活的另一个变体,其中 x < theta, and equals to x if x > = theta 的输出为 0。在 Keras 中,θ的默认值被设置为 1.0,而在原始论文中,据说 0.7 的值为他们的特定实验提供了最佳结果。

Fig.8 Thresholded ReLU activation

指数线性单位(ELU)

较少使用的 ReLU 修改,据说比传统的 ReLU 导致更高的分类结果。对于 x>= 0,它遵循与 ReLU 相同的规则,对于 x < 0,它按指数规律增加。ELU 试图使平均激活接近零,这加快了训练速度。

它只有一个参数 alpha,用于控制负声部的比例,默认设置为 1.0。

Fig.9 Exponential Linear Unit (ELU) activation

比例指数线性单位(SELU)

我们将在实验中评估的最后一个整流器。它用参数λ扩展了 ELU,负责缩放正负部分。如 Klambauer 等人在的论文中所建议的,该函数中的 Alpha 和 lambda 被硬编码为分别大约等于 1.67 和 1.05。他们还说,这个激活应该与“lecun_normal”初始化器和 AlphaDropout 一起使用,但是为了与本部分中的其他激活相比较,我们将使用默认初始化器和常规 Dropout。我们将在后面的系列文章中检查 SELU 的初始化和退出。

Fig.10 Scaled Exponential Linear Unit (SELU) activation

SoftPlus

SoftPlus 函数的图形看起来像平滑的 ReLU。我找不到为什么 SoftPlus 应该优于任何其他激活函数的确切原因,这一点得到了 Glorot、Bordes 和 Bengio 在深度稀疏整流器神经网络论文中的陈述的支持:“尽管硬阈值为 0,但用整流器激活函数训练的网络可以找到比用其平滑对应物 softplus 获得的质量更好或相同的局部最小值。”

Fig.11 SoftPlus activation

为了方便起见,这里将所有激活功能合并为两个图表:

Fig.12 Comparison of various activation functions

实验结果

当比较激活函数时,我们将考虑与先前实验中相同的指标。在我们用 RMSProp optimizer 对每个激活函数训练了我们的网络 5 次之后,下面是我们得到的归一化数据集(按达到的最大验证准确度排序):

这里有明显的表现不佳者:线性激活、具有默认 theta 值的阈值 ReLU 和具有非常大的 alpha 的泄漏 ReLU。线性激活在所有四项指标中都未能超过 93%的准确率。阈值 ReLU 在最终时期具有最低的精度值,并且是最低的最大实现精度之一,这意味着存在过拟合。广泛使用的 ReLU 显示了平均结果。这里明显的赢家是 ELU 和 SELU 的激活。

这是样本标准化数据的同一张表:

这里的排名基本上是一样的,只是在表的中间有一些小的变动。然而,一般来说,用标准化数据训练的网络的性能稍差。唯一的例外是阈值 ReLU,其结果有了显著的改善。

现在让我们更仔细地比较一下这两种数据转换方式:

(抱歉,桌子太宽了。向右滚动以查看其余部分。)

平均而言,使用标准化数据,您将能够获得稍微好一点的结果。有几个激活,它们(如果你出于某种原因决定使用它们)在标准化数据上表现得更好。然而,这里有一件有趣的事情需要注意:对于大量的激活,使用标准化数据比使用标准化数据更早达到最大准确度值。因此,如果为了您的特定实验,您可以牺牲一些准确性,以便更快地获得最大结果,那么标准化数据是一条可行之路。

现在让我们更仔细地研究用每个激活函数训练网络的细节,这样你可以清楚地看到它们训练行为的不同。(注意,很多图!)

线性的

线性激活显示了最坏的结果。从下图可以看出,训练一直很不稳定,尤其是对于标准化的数据。显示每次实验达到最大验证准确度的时刻的垂直线分布在整个 x 轴上。这意味着在某个点之后,优化器无法找到更好的局部最小值,来回跳跃。这可以通过降低学习率来解决(我们将在后面的系列文章中探讨),但这也是模型的线性问题,无法对过于复杂的依赖关系进行建模。

Fig.13 Validation accuracy for models trained with Linear activation

乙状结肠的

与线性模型相比,Sigmoid 激活产生了更稳定的模型,并且达到的最大验证准确度值更接近训练结束,但是验证准确度值是平均的。

Fig.14 Validation accuracy for models trained with Sigmoid activation

硬乙状结肠

与普通的 Sigmoid 非常相似,它具有较低的最终平均值和较低的最大平均值,但达到的最大验证精度与 Sigmoid 完全相同。因此,对于这种特殊的设置,我们可以说,硬乙状结肠表现不如乙状结肠。归一化数据上的最大值更接近训练结束,这告诉我们,如果调整学习率,可能会取得更好的效果。

Fig.15 Validation accuracy for models trained with Hard Sigmoid activation

双曲正切值

尽管与 Sigmoid 的最大验证精度大致相同,TanH 的稳定性稍差。大多数局部最小值已经接近训练的中间,优化器无法进一步改善结果。具有这种激活函数的模型也可以从降低学习速率中受益。有趣的是,尽管 TanH 被认为比 Sigmoid 更先进,并且现在使用得更频繁,但后者可能仍然更适用于某些网络设置和任务。

Fig.16 Validation accuracy for models trained with TanH activation

软设计

在标准化数据中,所有线都非常接近平均值。但是训练的结果也有些一般。使用标准化数据时,SoftSign 的稳定性要差得多,尽管最终精度稍高。

Fig.17 Validation accuracy for models trained with SoftSign activation

整流线性单元

这是我们在实验中第一次看到过度拟合。正如我们所看到的,模型在第 10 和第 40 个时期之间达到其峰值性能,然后开始缓慢下降。达到的最大验证准确度与标准化数据的 Sigmoid 相同,但低于标准化数据。因此,无需进一步微调,乙状结肠搏动 ReLU 在这里。

Fig.18 Validation accuracy for models trained with ReLU activation

泄漏 ReLU

Alpha = 0.3(默认)

泄漏 ReLU 的表现比它的传统变种 ReLU 更差。最大验证精度和最后时期的精度都低于 ReLU。这意味着即使过度拟合,ReLU 对于我们的情况也是更可取的。

Fig.19 Validation accuracy for models trained with Leaky ReLU activation with alpha = 0.3

阿尔法= 0.01

减少“泄漏”参数α有助于模型显著改善标准化和规范化数据的结果。

Fig.20 Validation accuracy for models trained with Leaky ReLU activation with alpha = 0.01

阿尔法= 1.5

将 alpha 设置为相对较大的值会导致我们实验中最差的性能之一。训练极不稳定,准确率很低。所以不要那么做。

Fig.21 Validation accuracy for models trained with Leaky ReLU activation with alpha = 1.5

阈值 ReLU

θ= 0.7

这是一个非常有趣的案例。用阈值 ReLU 和标准化数据训练的模型很快达到最大值,然后开始下降。所以这是一个明显的过度拟合,也是非常糟糕的整体性能。而在标准化数据上,尽管与其他激活相比仍然表现不佳,但根本没有过度拟合。我们看到,原始论文中提出的θ值对于归一化数据并不适用。这可能是对这两种数据转换方法的模型性能差异的最好证明。

Fig.22 Validation accuracy for models trained with Thresholded ReLU activation with theta = 0.7

θ= 1.0(默认)

这个θ值导致了更差的性能。这意味着你应该谨慎使用深度学习框架中内置的默认值,并始终检查更改它们是否会带来更好的结果。

Fig.23 Validation accuracy for models trained with Thresholded ReLU activation with theta = 1.0

θ=数据平均值

在精度和过拟合方面都有显著提高,但总体性能仍低于平均水平。这个例子演示了根据您输入的数据调整模型参数是非常重要的。

Fig.24 Validation accuracy for models trained with Thresholded ReLU activation with theta = data_mean

指数线性单位(ELU)

Alpha = 1.0(默认)

相当稳定,在最大验证准确度方面是最好的之一。最大值是在训练过程中达到的,因此它可以更快地达到最佳结果,并且通过对学习速率进行一些微调,这些结果可能会得到进一步改善。这种激活在标准化和规范化数据上都表现很高。

Fig.25 Validation accuracy for models trained with ELU activation with alpha = 1.0

阿尔法= 0.5

性能也非常好,至少在标准化数据上是这样。

Fig.26 Validation accuracy for models trained with ELU activation with alpha = 0.5

阿尔法= 1.5

在标准化数据中,alpha = 1.5 的 ELU 在所有激活函数中处于领先地位。它的表现几乎和 SELU 一样好。标准化数据的最大值非常接近训练结束,因此,如果进一步训练,可能会取得更好的结果。

Fig.27 Validation accuracy for models trained with ELU activation with alpha = 1.5

比例指数线性单位(SELU)

第二好的激活功能,相当稳定,表现出更高的性能。标准化数据稍不稳定。稍后,我们将检查是否有可能通过降低学习率和调整辍学来改善结果,以便稳定训练和实现更高的准确性。

Fig.28 Validation accuracy for models trained with SELU activation

SoftPlus

就标准化数据的最大验证精度而言,该函数排名第三(仅次于 SELU 和 ELU),但与领先者有很大差距。根据标准化数据,存在过度拟合和低于平均水平的性能。

如果我们将 SoftPlus 与 ReLU 的结果进行比较,我们可以看到,ReLU 与 SoftPlus 相比“质量更好或相当”的说法并没有在我们的特定设置中得到证实。它支持了一个被广泛接受的观点,即神经网络组件的基准测试是困难的,并且在不同的网络设置中会导致相互矛盾的结果。

Fig.29 Validation accuracy for models trained with SoftPlus activation

摘要

SoftPlus 击败 ReLU 的例子与深度学习之父在他们的论文中所说的相反,这意味着我们在这个实验中获得的激活函数的排名和结果只适用于我们正在考虑的神经网络的特定配置,并且通常不会告诉你一个激活函数比另一个更好。但至少对于在图像分类任务上具有 RMSProp 优化器的 3 层全连接网络,我们可以说,通过使用指数线性单元激活或其缩放变化,您将能够获得比其他激活更好的结果。

总而言之,本实验的主要学习点是,对于类似的任务和神经网络设置,您应该:

  • 为了达到更高的验证精度,对数据进行标准化,如果需要更快的结果,则进行标准化;
  • 使用 ELU 或 SELU 激活;
  • 尝试调整激活函数参数,看看它们是否能产生更好的结果;
  • 是的,永远不要使用线性激活。

你可以在我的 github 上找到实验和可视化结果的代码。在的下一部分中,我们将扩展我们的实验,并以同样的方式测试其他优化器,看看它们在与相同的激活函数组合时表现如何。

我总是很高兴认识新朋友并分享想法,所以如果你喜欢这篇文章,可以考虑在 LinkedIn 上加我。

深度学习一个不是很深的神经网络系列:

  • 第 1 部分:我们的数据中有什么
  • 第二部分:激活功能
  • 第 3a 部分:优化器概述
  • 第 3b 部分:选择优化器
  • 第四部分:如何找到合适的学习率
  • 第 5 部分:压差和噪声
  • 第 6 部分:权重初始化
  • 第 7 部分:正规化
  • 第 8 部分:批处理规范化
  • 第 9 部分:大小很重要
  • 第 10 部分:将它们融合在一起

深度监视

原文:https://towardsdatascience.com/deep-surveillance-6b389abeaf95?source=collection_archive---------4-----------------------

用神经网络检测暴力

根据 IHS Markit 关于视频监控的年度出版物,今年可能会有 1.3 亿台监控摄像机出货。[1]

英国安全行业协会 2013 年委托的一份报告得出结论,英国安装了 410 万至 590 万个闭路电视摄像机。[2]最高估计是每 11 个人有一台监控摄像机。

除了围绕国有和私营摄像头的政策问题,视频监控也给大数据和机器学习带来了挑战。

一份报纸估计,中国天津市的 60 万个摄像头每天产生 50pb 的数据。[3]

许多监控系统仍然需要人工监管。因此,计算机视觉的最新进展被视为视频监控的一个重要趋势,可能会带来显著的效率提升。

本文重点关注一个重要方面,探索最先进的深度神经网络可以在多大程度上“看到”图像和视频中的暴力。

在下面描述的模型中有两个反复出现的主题:首先,迁移学习用于提高以小训练集为特征的设置中的性能。第二,已经成功应用于图像分类和时间序列分析的构建块可以重新用于与视频相关的任务。

图像中暴力检测的迁移学习

Kalliatakis 等人(2017 年)[4]汇编了人权理解数据集。这个由 400 个手动标记的图像文件组成的集合包括儿童士兵的照片和警察与平民之间的暴力互动。

只有借助迁移学习,才能有效处理如此小规模的数据集。

为此,作者比较了 10 个已建立的卷积神经网络的性能。这些模型要么在 ImageNet 数据集上进行预训练,要么——在 8 层 Places 架构的情况下——针对 1000 万张场景照片的集合进行优化[5]。要将模型用作特征提取器,需要移除生成预测的图层。

该模型的第二部分是线性 SVM 分类器,其在 HRUN 数据集上被训练,并接受提取的特征作为输入。

Human rights violations recognition pipeline in Kalliatakis et al. (2017)

使用 50/50 分割的训练和测试图像,作者报告了极好的结果。迁移学习方法对儿童兵类别的平均准确率达到 90%,对警察与平民之间的暴力互动的平均准确率接近 96%。有趣的是,最好的结果是用位置架构实现的。

暴力视频的检测

当然,视频是图像序列。虽然大多数最先进的图像分类系统以某种形式使用卷积层,但顺序数据经常由长短期记忆(LSTM)网络处理。因此,这两个构件的组合有望在视频分类任务中表现良好。

一个这样的组合有一个自我描述的名字convltm[6]。标准 LSTM 使用简单的矩阵乘法来衡量不同门内的输入和先前状态。在 ConvLSTM 中,这些运算被卷积所取代。

Sudhakaran 和 Lanz (2017)的一篇论文测试了这种方法在检测视频内容中的暴力方面的效果如何[7]。

为了迫使网络模拟随时间的变化,作者使用两个相邻帧的差异作为每一步的输入。然后使用 AlexNet 架构生成一个向量表示,并发送给 ConvLSTM 实例。在所有帧被处理之后,最终的隐藏状态被转发到计算分类的完全连接的层序列。

Block diagram of the model proposed by Sudhakaran & Lanz (2017)

在小数据集上评估该模型。冰球比赛数据集由 500 个冰球比赛视频组成,显示比赛或其他内容。电影数据集包含 100 个打斗场景和 100 个没有暴力的场景。暴力流人群暴力数据集是 246 个视频的集合,描述了体育赛事中暴力和非暴力的人群行为。为了扩充数据,作者进行了随机裁剪和水平翻转。

该论文报告了在暴力流数据集上的第二名,冰球视频中暴力检测的最先进结果,以及在电影数据集上的完美结果。

对于曲棍球数据集,使用两个相邻帧的差异作为输入,并使用预训练的 AlexNet 进行特征提取,与使用单个帧作为输入的随机初始化网络相比,精确度从 94%提高到 97%。

考虑到暴力和非暴力场景可能表现出高度的特征重叠,这些结果是显著的。需要仔细观察一些较低层次的细节,例如,区分冰球比赛中的打斗和拥抱。

暴力是可以察觉的异常现象

在文明社会中,和平共处是常态,暴力是例外。这一幸运的事实允许 Sultani 等人(2018)[8]将智能监控视为异常检测问题。除了人际暴力,他们考虑的 13 种异常情况还包括其他纵火、盗窃和事故。

利用 YouTube 和 LiveLeak 上的搜索功能,研究人员汇编了一组显示真实世界异常情况的视频。只有监控摄像头拍摄的未经编辑的录像进入了 1900 个视频的最终集合。数据集在异常事件(标记为正)和正常事件(标记为负)之间保持平衡。

多示例学习

每个视频被表示为一包 m 个时间片段。在肯定的情况下,假定至少一个 m 段包含异常。在否定的情况下,没有一个段包含异常。

为了收集大量视频的例子,注释者在包的层次上提供标签,而不是在单个片段的层次上。换句话说,数据集告诉你一个给定的视频是否显示任何异常。它不会告诉你异常发生的时间。

以下符号指的是代表视频 V 的包 B 中的第 i 段。字母 an 分别用于表示异常和正常事件:

函数 f 为每个片段分配 0 到 1 之间的异常分数。

一个关键的想法是将得分最高的积极部分推得尽可能远离得分最高的消极部分。这一基本目标用以下铰链损失函数表示:

在最好的可能情况下,对于异常视频,最高分段分数是 1,对于正常视频,最高分段分数是 0。这会导致 0:

最差情况下,分数颠倒,损失为 2:

基于 C3D 的时空特征学习

评分函数 f 使用从预训练的卷积 3D (C3D)网络中提取的表示,这是一种专门针对迁移学习而设计的架构。

图像是二维的。视频分析是时空的:它增加了时间作为第三维。在 Tran 等人(2015)[9]描述的 C3D 网络中,视频的大小被调整为 128 x171(4:3 的纵横比),并被分成每个 16 帧的剪辑。使用三个颜色通道,输入的大小为 3x16x128x171。该网络中的卷积滤波器具有 d x k x k 格式,其中 d 指时间维度,而 k x k 指空间维度。经验结果表明,3x3x3 配置是一个合适的选择。

网络中的前五个块由一个或两个卷积层组成,随后是一个汇集操作。为了生成预测,计算由两个全连接层(标识为 fc6fc7 )的序列继续,并最终由 softmax 层完成。C3D 网络的作者在 Sports-1M 数据集上训练了该模型,该数据集收集了来自 487 个体育类别的超过 100 万个视频。

经过训练的模型的表达能力可以在其他任务中重复使用。来自不同数据集的视频首先被分割成所需格式的 16 帧长的剪辑。然后,对各个片段的 fc6 片段激活进行平均,以形成具有 4096 个条目的 L2 归一化特征向量。

实时处理

回到异常检测器,该特征向量被用作具有丢失的 3 层全连接神经网络的输入。该架构中的最后一层只有一个单元,通过将 sigmoid 激活函数应用于加权输入来计算异常分数。

Flow diagram of the anomaly detection approach proposed by Sultani et al. (2018)

该论文报告了对于 50%的分类阈值,接收器工作特性(ROC)的曲线下面积(AUC)值为 0.754,并且虚警率为 1.9。对于这两个指标,与其他三种方法相比,本系统获得了最高分。

要在现实世界的应用中可行,异常检测器需要计算效率高,并及时发出警报。在极端情况下,慢速和快速性能之间的差异可能是生死攸关的问题。使用 Nvidia Geforce GTX 1080 GPU 作为参考,作者报告说,该模型能够以每秒 367 帧的运行速度进行实时处理。

深度学习模型在图像分析方面取得的成功正在被复制到视频内容中。

暴力检测是一个重要的应用,但还有许多其他应用。神经网络已被用于检测跌倒,这是老年人的一个主要风险,可以通过智能家庭医疗保健系统来解决。[10]在灵长类动物学中,自动处理通过相机陷阱录制的视频可以帮助科学家全面研究我们进化亲属的行为[11]。

虽然可能有人会说这种技术天生就偏向某一方,但它既有做好事的潜力,也有做坏事的潜力。

智能监控可以被那些致力于确保公共安全、保护亲人和威慑罪犯的人所使用。或者它可能被那些试图建立或扩大警察国家的人滥用。

视频平台上的自动内容分类可以被视为维护社区标准的有效方式。或者,它可以被视为审查制度的一种手段,有可能扼杀挑战性和非传统的表达方式。

为了成功实现人工智能的大众化,我们需要探索并有可能促进双刃技术的防御用途。

感谢您的阅读!如果你喜欢这篇文章,请点击拍手按钮并关注我,以获得更多关于最新机器学习应用程序的信息。

参考

[1] *IHS Markit 的 2018 年顶级视频监控趋势。*检索到 108 年 3 月 23 日。

[2] 英国安全行业协会—概述。2018 年 3 月 23 日检索。

[3]肖军,廖,李,胡军,陈,杨,胡,2015 .利用大监控视频数据中的全局冗余进行高效编码。集群计算18 (2),第 531–540 页。

[4] Kalliatakis,g .,Ehsan,s .,Fasli,m .,Leonardis,a .,Gall,j .,McDonald-Maier,K.D .,2017 年。图像中人权侵犯的检测:卷积神经网络有帮助吗?。 arXiv 预印本 arXiv:1703.04103

[5]周,b .,拉佩德里扎,a .,科斯拉,a .,奥利瓦,a .,托拉尔巴,a .,2017。地点:用于场景识别的 1000 万图像数据库。IEEE 模式分析与机器智能汇刊*。*

[6]邢建华、陈志军、王、杨、黄伟光和吴伟光,2015 年。卷积 LSTM 网络:降水临近预报的机器学习方法。在神经信息处理系统的进展(第 802–810 页)。

[7] Sudhakaran,s .和 Lanz,o .,2017 年 8 月。学习使用卷积长短期记忆检测暴力视频。在基于先进视频和信号的监控(AVSS),2017 年第 14 届 IEEE 国际会议上(第 1–6 页)。IEEE。

[8]苏丹尼,w .,陈,c .和沙阿,m .,2018 年。监控视频中的真实世界异常检测。 arXiv 预印本 arXiv:1801.04264

[9] Tran,d .,Bourdev,l .,Fergus,r .,Torresani,l .和 Paluri,m .,2015 年 12 月。用 3d 卷积网络学习时空特征。在计算机视觉(ICCV),2015 IEEE 国际会议上(第 4489–4497 页)。IEEE。

[10]王,s,陈,l,周,z,孙,x,董,2016 .基于 PCANet 的监控视频中人体跌倒检测。多媒体工具与应用75 (19),第 11603–11613 页。

[11] Pebsworth,P.A .和 LaFleur,m .,2014 年。通过使用照相机陷阱推进灵长类动物的研究和保护:特刊介绍。《国际灵长类动物杂志35 (5),第 825–840 页。

面向自然语言处理的深度迁移学习——基于通用嵌入的文本分类

原文:https://towardsdatascience.com/deep-transfer-learning-for-natural-language-processing-text-classification-with-universal-1a2c69e5baa9?source=collection_archive---------2-----------------------

揭秘通用句子编码器指南

介绍

迁移学习是一个令人兴奋的概念,我们试图将一个领域和任务中的现有知识运用到另一个领域和任务中。灵感来自我们——人类,我们自己——我们有一种天生的能力,不需要从零开始学习一切。我们将过去学到的知识转移并加以利用,以解决各种各样的任务。有了计算机视觉,我们有了优秀的大数据集,如 Imagenet,在此基础上,我们可以获得一套世界级的、最先进的预训练模型,以利用迁移学习。但是自然语言处理呢?考虑到文本数据是如此多样、嘈杂和非结构化,这就是挑战所在。我们最近在单词嵌入方面取得了一些成功,包括像 Word2Vec、GloVe 和 FastText 这样的方法,所有这些都在我的文章 【文本数据的特征工程】 中有所涉及。

[## 理解特征工程(第 4 部分)——深度学习的直观实践方法…

驯服非结构化文本数据的更新、高级策略

towardsdatascience.com](/understanding-feature-engineering-part-4-deep-learning-methods-for-text-data-96c44370bbfa)

在本文中,我们将展示几种最先进的通用句子嵌入编码器,与单词嵌入模型相比,它们往往会提供令人惊讶的良好性能,特别是在迁移学习任务的少量数据上。我们将介绍以下型号:

  • 基线平均句子嵌入
  • Doc2Vec
  • 神经网络语言模型(动手演示!)
  • 跳过思维向量
  • 快速思考矢量
  • 推断
  • 通用语句编码器

我们将尝试涵盖基本概念,并展示一些利用 Python 和 Tensorflow 的实际例子,这是一个侧重于情感分析的文本分类问题!

为什么我们对嵌入如此着迷?

嵌入式背后突然出现的热潮是什么?我相信你们中的许多人可能在任何地方都能听到它。让我们先搞清楚基本情况,从炒作中切入。

嵌入是固定长度的向量,通常用于编码和表示实体(文档、句子、单词、图形!)

在我以前的一篇文章 中的 中,我谈到了在文本数据和 NLP 的上下文中嵌入的需要。但是为了方便起见,我在这里简单重申一下。关于语音或图像识别系统,我们已经获得了嵌入在高维数据集中的丰富密集特征向量形式的信息,如音频频谱图和图像像素强度。然而,当涉及到原始文本数据时,尤其是像单词包这样的基于计数的模型,我们处理的是单个单词,这些单词可能有自己的标识符,并且没有捕获单词之间的语义关系。这导致文本数据的巨大稀疏词向量,因此,如果我们没有足够的数据,我们可能最终会得到糟糕的模型,甚至由于维数灾难而过度拟合数据。

Comparing feature representations for audio, image and text

预测方法基于神经网络的语言模型 尝试通过查看语料库中的单词序列来预测单词,在此过程中,它学习分布式表示,给我们提供密集的单词嵌入。

现在你可能会想,没什么大不了的,我们从文本中得到一堆向量。现在怎么办?对嵌入的狂热在于,如果我们有一个很好的文本数据的数字表示,甚至可以捕捉上下文和语义,我们就可以用它来完成各种下游的真实任务,比如情感分析、文本分类、聚类、摘要、翻译等等。事实是,机器学习或深度学习模型在数字上运行,嵌入是编码这些模型将使用的文本数据的关键。

Text Embeddings

这里的一个大趋势是找出所谓的 【通用嵌入】 ,这些嵌入基本上是在巨大的语料库上训练深度学习模型获得的预训练嵌入。这使我们能够在各种各样的任务中使用这些预训练(通用)嵌入,包括缺乏足够数据等约束的场景。这是一个迁移学习的完美例子,利用来自预训练嵌入的先验知识来解决一个全新的任务!下图展示了通用词&句子嵌入的一些最新趋势,这要感谢 HuggingFace 的朋友们的一篇精彩文章!

Recent Trends in Universal Word & Sentence Embeddings (Source: https://medium.com/huggingface/universal-word-sentence-embeddings-ce48ddc8fc3a)

当然,上图中有一些有趣的趋势,包括谷歌的通用句子编码器,我们将在本文中详细探讨!我绝对推荐读者去看看 来自 HuggingFace 的关于通用嵌入趋势 的文章。

* [## 📚当前最好的通用单词嵌入和句子嵌入

单词和句子嵌入在过去的几个月里发展得非常快——关于发生了什么的简要介绍

medium.com](https://medium.com/huggingface/universal-word-sentence-embeddings-ce48ddc8fc3a)

现在,在深入研究通用句子编码器之前,让我们先简要了解一下单词和句子嵌入模型的趋势和发展。

单词嵌入模型的发展趋势

word 嵌入模型可能是从 2013 年的 Word2Vec 开始开发的一些更老、更成熟的模型。基于在基于语义和上下文相似性的连续向量空间中嵌入单词向量,利用深度学习(无监督方法)模型的三种最常见的模型是:

  • Word2Vec
  • 手套
  • 快速文本

这些模型是基于 分布语义学 领域中的 分布假说 的原理,它告诉我们,在同一语境中出现和使用的词在语义上彼此相似,并且具有相似的含义(【一个词由其所保持的伙伴来表征】)。如果你对血淋淋的细节感兴趣,请参考我的关于单词嵌入的文章,这篇文章详细介绍了这三种方法。

最近在这方面开发的另一个有趣的模型是【ELMo】。这是艾伦人工智能研究所开发的。ELMo* 是一个取自著名电视剧《芝麻街》的同名著名布偶角色,但实际上是一个缩写,代表“Embedings fromL语言Mo*dels”。

Elmo from Sesame Street!

基本上, ELMo 为我们提供了从深度双向语言模型(biLM)中学习的单词嵌入,该模型通常在大型文本语料库上进行预训练,使这些嵌入的迁移学习能够跨不同的 NLP 任务使用。艾伦·艾告诉我们,ELMo 表征是上下文相关的、深层的和基于字符的,它使用形态学线索来形成表征,即使是对于 OOV(词汇之外)表征。

通用句子嵌入模型的发展趋势

句子嵌入的概念并不是一个非常新的概念,因为当构建单词嵌入时,构建基线句子嵌入模型的最简单的方法之一是平均。

一个 基线句子嵌入模型 可以通过平均每个句子\文档的单个单词嵌入来构建(有点类似于单词袋,其中我们丢失了句子中单词的固有上下文和序列)。我们会在我的文章 中详细介绍 。下图显示了实现这一点的方法。

当然,还有更复杂的方法,比如以单词嵌入的线性加权组合对句子进行编码,然后去除一些共同的主要成分。一定要检查一下, 【一个简单但难以击败的句子嵌入基线】

*Doc2Vec 也是米科洛夫等人提出的一种非常流行的方法。艾尔。在他们的论文 【句子和文件的分布式表示】 *。在这里,他们提出了段落向量,这是一种无监督的算法,可以从可变长度的文本片段(如句子、段落和文档)中学习固定长度的特征嵌入。

Word2Vec vs. Doc2Vec (Source: https://arxiv.org/abs/1405.4053)

基于上述描述,该模型通过被训练来预测文档中的单词的密集向量来表示每个文档。唯一的区别是段落或文档 ID,它与常规单词标记一起用来构建嵌入。这样的设计使得该模型能够克服单词袋模型的弱点。

****【NNLM】**神经网络语言模型(Neural-Net Language Models)是基于 Bengio 等人提出的神经概率语言模型的一个非常早期的想法。在他们的论文【A Neural probability Language Model】中,他们在 2003 年谈到学习单词的分布式表示,这允许每个训练句子通知模型关于指数数量的语义相邻句子。该模型同时学习每个单词的分布式表示以及用这些表示表达的单词序列的概率函数。获得概括是因为如果从未见过的单词序列由与形成已经见过的句子的单词相似的单词组成(在具有邻近表示的意义上),则该单词序列获得高概率。

Google 已经建立了一个通用的句子嵌入模型,nnlm-en-dim 128,这是一个基于标记的文本嵌入训练模型,在英文 Google News 200B 语料库上使用了一个三隐层前馈神经网络语言模型。这个模型将任何文本映射成 128 维嵌入。我们不久将在实际操作演示中使用它!

跳过思维向量 也是基于无监督学习的通用句子编码器领域的首批模型之一。在他们提出的论文 【跳过思维向量】 中,他们利用书籍中文本的连续性,训练了一个编码器-解码器模型,试图重建编码段落的周围句子。共享语义和句法属性的句子被映射到相似的向量表示。

Skip-Thought Vectors (Source: https://arxiv.org/abs/1506.06726)

这就像 Skip-gram 模型,但是对于句子,我们试图预测给定源句子的周围句子。

*快速思维向量 是一种最近才出现的学习句子提示的无监督方法。详细内容在论文 【学习句子表征的高效框架】 *中有所提及。有趣的是,他们通过用常规编码器-解码器架构中的分类器替换解码器,将预测句子出现的上下文的问题重新表述为分类问题。

Quick Thought Vectors (Source: https://openreview.net/forum?id=rJvJXZb0W)

因此,给定一个句子和它出现的上下文,分类器根据它们的嵌入表示将上下文句子与其他对比句子区分开来。给定一个输入句子,首先使用某种函数对其进行编码。但是该模型不是生成目标句子,而是从一组候选句子中选择正确的目标句子。将生成视为从所有可能的句子中选择一个句子,这可以被视为对生成问题的一种有区别的近似。

推断 有趣的是,它是一种使用自然语言推断数据学习通用句子嵌入的监督学习方法。这是核心的监督迁移学习,就像我们在计算机视觉的 ImageNet 数据集上训练的预训练模型一样,他们使用斯坦福自然语言推理数据集的监督数据训练通用句子表示。详细内容在他们的论文中提到, 【从自然语言推理数据中监督学习通用句子表示】 。该模型使用的数据集是 SNLI 数据集,包括 570,000 个人工生成的英语句子对,人工标记为三个类别之一:蕴涵、矛盾和中性。它捕捉对理解句子语义有用的自然语言推理。

InferSent training scheme (Source: https://arxiv.org/abs/1705.02364)

基于上图所示的架构,我们可以看到它使用了一个共享的句子编码器,该编码器输出前提和假设 v 的表示。一旦生成了句子向量,就应用 3 种匹配方法来提取 u 和 v 之间的关系:**

  • 串联 (u,v)
  • 逐元素乘积*u∫v*****
  • 绝对元素差异*| u v |*****

然后将得到的矢量输入到一个三级分类器中,该分类器由多个完全连接的层组成,最终形成一个 softmax 层。

来自 Google 的 通用句子编码器 是 2018 年初发布的最新最好的通用句子嵌入模型之一!通用语句编码器将任何文本编码成 512 维嵌入,可用于各种 NLP 任务,包括文本分类、语义相似性和聚类。它在各种数据源和各种任务上接受训练,目的是动态适应各种各样的自然语言理解任务,这些任务需要对单词序列而不仅仅是单个单词的含义进行建模。

他们的主要发现是,使用句子嵌入的迁移学习往往优于单词嵌入水平迁移。请查看他们的论文, 【通用句子编码器】 了解更多详情。本质上,他们在 TF-Hub 中有两个版本的模型,即 通用语句编码器 。版本 1 利用基于变换器网络的句子编码模型,版本 2 利用深度平均网络(DAN ),其中单词和二元模型的输入嵌入首先被一起平均,然后通过前馈深度神经网络(DNN)产生句子嵌入。我们将很快在实际操作演示中使用版本 2。

理解我们的文本分类问题

**是时候通过动手演示将这些通用句子编码器付诸实践了!正如文章中提到的,我们今天演示的前提将集中在一个非常流行的 NLP 任务,文本分类——在情感分析的背景下。我们将使用基准测试 IMDB 大型电影评论数据集 。随意在这里下载或者你甚至可以从我的 GitHub 资源库 下载。

该数据集包括总共 50,000 条电影评论,其中 25,000 条具有正面情绪,25,000 条具有负面情绪。我们将在总共 30,000 条评论上训练我们的模型作为我们的训练数据集,在 5,000 条评论上验证,并使用 15,000 条评论作为我们的测试数据集。主要目标是正确预测每个评论的正面或负面情绪。

行动中的普遍句子嵌入

现在我们已经明确了我们的主要目标,让我们把通用句子编码器付诸行动吧!整篇教程可在 我的 GitHub 资源库 中作为 Jupyter 笔记本 。随意 下载吧 随便玩玩。我推荐使用一个基于 GPU 的实例来试验这一点。我喜欢使用paper space,在这里你可以在云端旋转笔记本,而无需担心手动配置实例。

** [## 图纸空间

云机器学习、人工智能和轻松的 GPU 基础设施

www.paperspace.com](https://www.paperspace.com)

我的设置是一个 8 CPU,30 GB,250 GB 的 SSD 和一个 NVIDIA Quadro P4000 ,它通常比大多数 AWS GPU 实例便宜(尽管我喜欢 AWS!).

**注意:**本教程完全是使用 TensorFlow 构建的,因为它们提供了对句子编码器的简单访问。然而,我不太喜欢他们的旧 API,我正在找人帮助我使用**tf.keras**API 而不是**tf.estimator**重新实现代码。如果你有兴趣投稿的话,请联系我,我们甚至可以在上面刊登你的作品!(我的个人资料和页脚中的联系链接)

加载依赖项

我们从安装**tensorflow-hub**开始,这使我们能够容易地使用这些句子编码器。

现在让我们加载本教程的基本依赖项!

**import** **tensorflow** **as** **tf**
**import** **tensorflow_hub** **as** **hub**
**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**

以下命令帮助您检查**tensorflow**是否将使用 GPU(如果您已经设置了一个!)

**In [12]: tf.test.is_gpu_available()
Out[12]: True****In [13]: tf.test.gpu_device_name()
Out[13]: '/device:GPU:0'**

加载和查看数据集

我们现在可以加载数据集,并使用**pandas** **查看它。**我在我的存储库中提供了数据集的压缩版本,您可以按如下方式使用。

**<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50000 entries, 0 to 49999
Data columns (total 2 columns):
review       50000 non-null object
sentiment    50000 non-null object
dtypes: object(2)
memory usage: 781.3+ KB**

我们将情感列编码为 1 和 0,只是为了在模型开发过程中使事情更容易(标签编码)。

Our movie review dataset

构建训练、验证和测试数据集

在开始建模之前,我们将创建训练、验证和测试数据集。我们将使用 30,000 条评论用于训练,5,000 条用于验证,15,000 条用于测试。您可以使用类似于scikit-learn中的train_test_split()的列车测试分割功能。我很懒,使用简单的列表切片对数据集进行了子集化。

**((30000,), (5000,), (15000,))**

基本文本争论

我们需要做一些基本的文本争论和预处理,以消除文本中的一些干扰,如缩写、不必要的特殊字符、HTML 标签等。下面的代码帮助我们构建了一个简单而有效的文本辩论系统。请务必安装以下库,以防您没有这些库。

下面的函数帮助我们构建我们的文本辩论系统。

现在,让我们使用上面实现的函数对数据集进行预处理。

构建数据摄取功能

由于我们将使用**tf.estimator** API 在**tensorflow**中实现我们的模型,我们需要定义一些函数来构建数据和特性工程管道,以使数据在训练期间流入我们的模型。以下函数将帮助我们。我们利用了**numpy_input_fn()**,它有助于将 numpy 数组的字典输入到模型中。

我们现在准备建立我们的模型!

用通用语句编码器构建深度学习模型

在构建模型之前,我们需要首先定义利用通用句子编码器的句子嵌入特性。我们可以使用下面的代码来实现。

**INFO:tensorflow:Using /tmp/tfhub_modules to cache modules.**

正如我们所讨论的,我们使用通用句子编码器版本 2,它作用于我们输入字典中的**sentence** 属性,这将是我们评论的**numpy**数组。我们将建立一个简单的前馈 DNN,现在有两个隐藏层。只是一个标准模型,没有什么太复杂的,因为我们想看看这些嵌入在一个简单的模型上表现如何。这里,我们以预训练嵌入的形式利用迁移学习。我们在这里不是通过设置**trainable=False**来保持嵌入权重固定来进行微调。

我们已经将我们的**batch_size**设置为 256 ,并且我们将在 1500 步256 记录中分批流入数据,这大致相当于12–13 个时期

模特培训

现在,让我们在训练数据集上训练我们的模型,并在步骤 100 在训练和验证数据集上进行评估。

--------------------------------------------------------------------
**Training for step = 0** Train Time (s): 78.62789511680603
**Eval Metrics (Train):** {**'accuracy': 0.84863335**, 'accuracy_baseline': 0.5005, **'auc': 0.9279859**, 'auc_precision_recall': 0.92819566, 'average_loss': 0.34581015, 'label/mean': 0.5005, 'loss': 44.145977, **'precision': 0.86890674**, 'prediction/mean': 0.47957155, **'recall': 0.8215118**, 'global_step': 100}
**Eval Metrics (Validation):** {**'accuracy': 0.8454**, 'accuracy_baseline': 0.505, **'auc': 0.92413086**, 'auc_precision_recall': 0.9200026, 'average_loss': 0.35258815, 'label/mean': 0.495, 'loss': 44.073517, **'precision': 0.8522351**, 'prediction/mean': 0.48447067, **'recall': 0.8319192**, 'global_step': 100}

--------------------------------------------------------------------
**Training for step = 100**
Train Time (s): 76.1651611328125
**Eval Metrics (Train):** {**'accuracy': 0.85436666**, 'accuracy_baseline': 0.5005, **'auc': 0.9321357**, 'auc_precision_recall': 0.93224275, 'average_loss': 0.3330773, 'label/mean': 0.5005, 'loss': 42.520508, **'precision': 0.8501513**, 'prediction/mean': 0.5098621, **'recall': 0.86073923**, 'global_step': 200}
**Eval Metrics (Validation):** {**'accuracy': 0.8494**, 'accuracy_baseline': 0.505, **'auc': 0.92772096**, 'auc_precision_recall': 0.92323804, 'average_loss': 0.34418356, 'label/mean': 0.495, 'loss': 43.022945, **'precision': 0.83501947**, 'prediction/mean': 0.5149463, **'recall': 0.86707073**, 'global_step': 200}

--------------------------------------------------------------------
...
...
...
--------------------------------------------------------------------
**Training for step = 1400**
Train Time (s): 85.99037742614746
**Eval Metrics (Train):** {**'accuracy': 0.8783**, 'accuracy_baseline': 0.5005, **'auc': 0.9500882**, 'auc_precision_recall': 0.94986326, 'average_loss': 0.28882334, 'label/mean': 0.5005, 'loss': 36.871063, **'precision': 0.865308**, 'prediction/mean': 0.5196238, **'recall': 0.8963703**, 'global_step': 1500}
**Eval Metrics (Validation):** {**'accuracy': 0.8626**, 'accuracy_baseline': 0.505, **'auc': 0.93708724**, 'auc_precision_recall': 0.9336051, 'average_loss': 0.32389137, 'label/mean': 0.495, 'loss': 40.486423, **'precision': 0.84044176**, 'prediction/mean': 0.5226699, **'recall': 0.8917172**, 'global_step': 1500}

--------------------------------------------------------------------
**Training for step = 1500**
Train Time (s): 86.91469407081604
**Eval Metrics (Train):** {**'accuracy': 0.8802**, 'accuracy_baseline': 0.5005, **'auc': 0.95115364**, 'auc_precision_recall': 0.950775, 'average_loss': 0.2844779, 'label/mean': 0.5005, 'loss': 36.316326, **'precision': 0.8735527**, 'prediction/mean': 0.51057553, **'recall': 0.8893773**, 'global_step': 1600}
Eval Metrics (Validation): {**'accuracy': 0.8626**, 'accuracy_baseline': 0.505, **'auc': 0.9373224**, 'auc_precision_recall': 0.9336302, 'average_loss': 0.32108024, 'label/mean': 0.495, 'loss': 40.135033, **'precision': 0.8478599**, 'prediction/mean': 0.5134171, **'recall': 0.88040406**, 'global_step': 1600}

我在上面的输出日志中突出显示了感兴趣的指标,如您所见,在我们的验证数据集上,我们获得了接近 87%的总体精度,以及 94%的 T21 AUC,这在这样一个简单的模型上是非常好的!

模型评估

现在,让我们评估我们的模型,并检查训练和测试数据集的整体性能。

根据我们之前在验证数据集上观察到的情况,我们获得了接近 87%的测试数据总体准确性,从而为我们提供了一致的结果!因此,这应该让您知道利用预先训练的通用句子嵌入是多么容易,而不用担心功能工程或复杂建模的麻烦。

额外收获:不同通用句子嵌入的迁移学习

现在让我们尝试基于不同的句子嵌入来构建不同的深度学习分类器。我们将尝试以下方法:

  • NNLM-128
  • 使用-512

我们还将在这里讨论两种最重要的迁移学习方法。

  • 使用冻结的预训练句子嵌入建立模型
  • 建立一个模型,我们在训练期间微调和更新预训练的句子嵌入

下面这个通用函数可以从**tensorflow-hub**开始即插即用不同的通用语句编码器!

我们现在可以使用上面定义的方法来训练我们的模型。

**====================================================================
Training with** [**https://tfhub.dev/google/nnlm-en-dim128/1**](https://tfhub.dev/google/nnlm-en-dim128/1) **Trainable is: False
====================================================================**
--------------------------------------------------------------------
**Training for step = 0**
Train Time (s): 30.525171756744385
**Eval Metrics (Train): {'accuracy': 0.8480667, 'auc': 0.9287864, 'precision': 0.8288572, 'recall': 0.8776557}**
**Eval Metrics (Validation): {'accuracy': 0.8288, 'auc': 0.91452694, 'precision': 0.7999259, 'recall': 0.8723232}**
--------------------------------------------------------------------
...
...
--------------------------------------------------------------------
**Training for step = 1500**
Train Time (s): 28.242169618606567
**Eval Metrics (Train): {'accuracy': 0.8616, 'auc': 0.9385461, 'precision': 0.8443543, 'recall': 0.8869797}
Eval Metrics (Validation): {'accuracy': 0.828, 'auc': 0.91572505, 'precision': 0.80322945, 'recall': 0.86424243}** **====================================================================
Training with** [**https://tfhub.dev/google/nnlm-en-dim128/1**](https://tfhub.dev/google/nnlm-en-dim128/1) **Trainable is: True
====================================================================**
--------------------------------------------------------------------
**Training for step = 0**
Train Time (s): 45.97756814956665
**Eval Metrics (Train): {'accuracy': 0.9997, 'auc': 0.9998141, 'precision': 0.99980015, 'recall': 0.9996004}
Eval Metrics (Validation): {'accuracy': 0.877, 'auc': 0.9225529, 'precision': 0.86671925, 'recall': 0.88808084}**
--------------------------------------------------------------------
...
...
--------------------------------------------------------------------
**Training for step = 1500** Train Time (s): 44.654765605926514
**Eval Metrics (Train): {'accuracy': 1.0, 'auc': 1.0, 'precision': 1.0, 'recall': 1.0}
Eval Metrics (Validation): {'accuracy': 0.875, 'auc': 0.91479605, 'precision': 0.8661916, 'recall': 0.8840404}** **====================================================================
Training with** [**https://tfhub.dev/google/universal-sentence-encoder/2**](https://tfhub.dev/google/universal-sentence-encoder/2) **Trainable is: False
====================================================================**
--------------------------------------------------------------------
**Training for step = 0** Train Time (s): 261.7671597003937
**Eval Metrics (Train): {'accuracy': 0.8591, 'auc': 0.9373971, 'precision': 0.8820655, 'recall': 0.8293706}
Eval Metrics (Validation): {'accuracy': 0.8522, 'auc': 0.93081224, 'precision': 0.8631799, 'recall': 0.8335354}**
--------------------------------------------------------------------
...
...
--------------------------------------------------------------------
**Training for step = 1500** Train Time (s): 258.4421606063843
**Eval Metrics (Train): {'accuracy': 0.88733333, 'auc': 0.9558296, 'precision': 0.8979955, 'recall': 0.8741925}
Eval Metrics (Validation): {'accuracy': 0.864, 'auc': 0.938815, 'precision': 0.864393, 'recall': 0.860202}** **====================================================================
Training with** [**https://tfhub.dev/google/universal-sentence-encoder/2**](https://tfhub.dev/google/universal-sentence-encoder/2) **Trainable is: True
====================================================================**
--------------------------------------------------------------------
**Training for step = 0** Train Time (s): 313.1993100643158
**Eval Metrics (Train): {'accuracy': 0.99916667, 'auc': 0.9996535, 'precision': 0.9989349, 'recall': 0.9994006}
Eval Metrics (Validation): {'accuracy': 0.9056, 'auc': 0.95068294, 'precision': 0.9020474, 'recall': 0.9078788}**
--------------------------------------------------------------------
...
...
--------------------------------------------------------------------
**Training for step = 1500** Train Time (s): 305.9913341999054
**Eval Metrics (Train): {'accuracy': 1.0, 'auc': 1.0, 'precision': 1.0, 'recall': 1.0}
Eval Metrics (Validation): {'accuracy': 0.9032, 'auc': 0.929281, 'precision': 0.8986784, 'recall': 0.9066667}**

我已经在上面的输出中描述了重要的评估指标,你可以看到我们的模型确实得到了一些好的结果。下表很好地总结了这些比较结果。

Comparing results from different Universal Sentence Encoders

看起来谷歌的带有微调的通用句子编码器在测试数据上给了我们最好的结果。让我们加载这个保存的模型,并对测试数据进行评估。

**[0, 1, 0, 1, 1, 0, 1, 1, 1, 1]**

评估模型性能的最佳方法之一是以混淆矩阵的形式可视化模型预测。

Confusion Matrix from our Best Model Predictions

我们还可以使用 scikit-learn 打印出模型的分类报告,以显示可以从混淆矩阵中获得的其他重要指标,包括精确度、召回率和 f1 分数。

Model Performance Metrics on Test Data

我们在测试数据上得到了整体模型精度f1-得分90% ,这真是太好了!去试试吧,也许会得到更好的分数,然后告诉我!

结论和未来范围

通用的句子嵌入无疑是在多样化的自然语言处理任务中实现迁移学习的一个巨大进步。事实上,我们已经看到像 ELMo,Universal Sentence Encoder,ULMFiT 这样的模型确实成为头条新闻,因为它们展示了预先训练的模型可以用于在 NLP 任务中实现最先进的结果。著名的研究科学家和博客 Sebastian Ruder ,根据他最近写的一篇非常有趣的文章 在他最近的推文中提到了同样的事情。

我对进一步推广 NLP,使我们能够轻松解决复杂任务的未来充满期待!**

本文中用于动手演示的代码可以在 我的 GitHub 资源库 中找到,作为一个 Jupyter 笔记本 你可以随便摆弄!

****需要帮助:正如我提到的,我正在找人帮我转换这段代码,以使用更新的**tf.keras**API,而不是**tf.estimator**。感兴趣吗?向我伸出手来!

有反馈给我吗?或者有兴趣与我一起从事研究、数据科学、人工智能甚至发表一篇关于TDS的文章?可以在LinkedIn上联系我。

** [## 人工智能顾问&数据科学导师-跳板| LinkedIn

查看 Dipanjan Sarkar 在世界最大的职业社区 LinkedIn 上的个人资料。Dipanjan 有 2 份工作列在…

www.linkedin.co](https://www.linkedin.com/in/dipanzan/)

感谢 Durba 编辑此文。***

深度、广度和廉价的机器学习

原文:https://towardsdatascience.com/deep-wide-cheap-machine-learning-905437615c09?source=collection_archive---------9-----------------------

在竞争的假设中,应该选择假设最少的一个。

以上引文是维基百科对奥卡姆剃刀的翻译。它也是计算机系统设计、分析建模和一般系统工程中通用原则的基础。换句话说:简单胜过复杂。

然而,在技术、数据、分析生态圈中,我们(包括我自己)对闪亮的新事物着迷。部分原因是,热门、时髦、闪亮的东西会获得大量关注,我们在招聘和工作中已经看到,在简历中加入最新的前沿技术专业知识对招聘蜜蜂来说就像蜂蜜一样(这也延伸到了虚高的薪酬)。这是一个循环!公司和招聘人员想要闪亮和时髦的技术技能,候选人被闪亮和时髦的技术吸引来充实他们的简历。在这种炒作周期中,简单战胜了复杂,管用且容易解释的旧袖手旁观被推到一边,取而代之的是最新、最棒、也最复杂的东西。

降低树来增加低垂的果实

对于面临业务问题的分析和数据科学领域的任何专业人士来说,这里有一个重要的启示:首先应用简单而不是复杂的东西!这并不意味着不去学习和跟上最新的技术、工艺、方法和应用。在一个关于廉价学习的重复演讲中,Ted Dunning 向与会者介绍了几个解决大问题的廉价学习技术的例子,值得注意的是——数据泄露网络攻击、商业金融服务欺诈。在这些例子中,Ted 展示了使用算术和基础代数进行大规模数据分析是如何产生显著有效的结果的。Ted Dunning 演讲的主要观点是,使用廉价的学习技术,我们可以降低树的高度,以增加业务问题树上的低挂果实。他建议使用大型数据集、可扩展架构和简单数学的组合来解决问题。一旦降低的采油树上的低悬挂问题得到解决,那么就只能使用一些更复杂和新兴的方法来解决采油树上更高层次的不可能解决的难题。

关于这个话题的另一个观点来自 Xavier Amatriain,他推荐了一个关于如何解决难题的平衡的观点,并且在追求最闪亮和最新的方法时不要忽略已经尝试、测试和证明的技术。他给出的一些反模式的例子是忽略元数据特征,直接跳到从图像中学习特征来进行活动识别。另一个反模式是不使用集成方法和更简单的可解释模型,而是支持复杂的多层网络。当心这个星球上只有少数专家能破译的复杂模型。

如何接受深度、广度和廉价的学习?

Source: Unsplash Map

总结分析领域两位领导者的观点,在进入复杂模型和尖端机器学习、深度学习和人工智能领域的世界时,请记住以下一些概念:

  • 不要忘记元数据中隐藏的特性。

  • 特征工程可能是繁重的,但是架构工程可能是正确的炼金术。
  • 如果你陷入了一个流血的边缘问题,你可能是孤独的,所以要做好准备,为深潜时间做好计划。
  • 模型、算法和结果的可解释性非常重要,尤其是在高度管制的领域,甚至在其他领域,这也是一种道德责任。

深度和广度学习

Source: Unsplash Grand Canyon

鉴于这些警告信号,没有理由放弃复杂建模领域的巨大进步——深度学习。这里有一个两全其美的方法,那就是深度&广泛学习。简而言之,在存在特征歧义的地方使用深度学习,将其与广泛学习相结合,以解决具有提供高预测能力的特征的问题。深度和广度学习也可能有助于处理小数据集时的一些冷启动问题。关于深度&广泛学习的进一步阅读,我建议你看一下这篇非常可读的文章,来自谷歌关于这个主题的研究。

如果你喜欢阅读这篇文章,并且对如何在你的企业中引入人工智能和深度学习感到好奇,请阅读我关于分析自动化的文章。

DeepClassifyML 第 1 周第 2 部分

原文:https://towardsdatascience.com/deepclassifyml-week-1-part-2-3b234ca3fcb4?source=collection_archive---------7-----------------------

这篇文章是“Hasura 实习”系列的一部分,详细介绍了应用程序的原型阶段。查看 第 1 部分 了解 app 理念和一些计算机视觉基础知识。

第一部分被数据科学精选推荐,这真的很酷,因为这是我的第一个博客。我会尽量让这些博客非常入门,因为我的目标是让深度学习和计算机视觉对于 it 经验很少并且想马上开始的人来说非常简单。但首先要做的是。

Hasura 实习的应用理念是一个使用 Hasura 后端部署的图像分类 web 应用。它会从用户那里获取一张图片,并使用预训练的 InceptionV3 模型将其分类为前 5 类。接下来是原型阶段。这是使用流行的原型工具 Proto.io 完成的。作为应用程序的指导方针/规则的一部分,应用程序必须不超过 3 个屏幕,并且在复杂性方面应该相当简单。但 DeepClassifyML 会更简单,因为应用程序的核心功能可能仅限于一个屏幕。不知何故,我决定把它分成 3 个屏幕,结果如下:

The basic landing page

现在第一个屏幕只是这个基本的登录页面。没什么好吹嘘的。这个登录页面将用户带到剩下的两个页面—

Using a link to upload the your image.

To upload the Image from your system.

第一页使用一个链接上传一张图片,第二页使用您系统中的一张图片对它们进行分类。老实说(正如你可以从这些快照本身看到的!),我真的没有为原型阶段做足够的工作,因为这个应用程序非常基础。我打算做的是深度学习部分。让我们从这个开始。

在这篇文章中,我将讨论作为深度学习基础的神经网络。

神经网络就像你大脑内部的连接。那么你的大脑是如何工作的呢?(神经科学来袭!!)

主要部分神经元,通过一系列被称为树突的精细结构收集来自其他神经元的信号。然后,这些神经元通过被称为轴突的细长支架发出电活动尖峰。**轴突分裂成上千个分支,如图所示。*突触,*每个分支末端的一种结构,将轴突的这种活动转化为电信号,抑制或兴奋相连神经元的活动。当一个神经元接收到的兴奋性输入与其抑制性输入相比足够大时,它会沿着轴突发出一个电活动尖峰。学习是通过改变突触的有效性,从而改变一个神经元对另一个神经元的影响而发生的。

类似地,人工神经网络是由互连单元组成,充当神经元。突触的功能由一个可修改的权重建模,该权重与每个连接相关联。每个人都查看输入数据,并决定如何对数据进行分类,即转换传入活动的模式。因此,一个简单的神经网络通过接收输入数据、处理该信息并最终以决策的形式产生输出来做出决策。简而言之,这可以通过以下两步完成:

  1. 将每个传入活动乘以连接上的权重,并将所有这些加权输入相加。这是总输入
  2. 然后,该单元(神经元)使用输入输出函数,将总输入转换为输出活动(决策)。

这取决于神经网络来学习什么是最重要的,并调整它如何考虑这些数据。因此,神经网络的行为取决于可修改的权重和输入输出函数(激活函数)。

这些权重和激活函数是什么?

让我们考虑一个典型的情况。一些输入数据(比如一个数字,可能同时有许多输入)进入神经网络。这将乘以一个权重值(可修改)。这些权重开始时是随机值,当神经网络知道哪种输入数据会产生正确的结果时,网络就会根据以前的权重导致的分类错误来调整权重。这些权重指定了输入数据的影响强度。这叫做训练神经网络。

较高的权重意味着神经网络认为该输入比其他输入更重要,而较低的权重意味着该输入被认为不太重要。这之后是加权输入数据的总和,以产生单个值。最终的输出值通过一个激活函数,它是神经元动作电位发放的速率。激活功能是在给定神经元输入的情况下,决定其输出应该是什么的功能。它决定实际输出,因此其输出通常被称为“激活”。

接下来我会举一个经典的例子。

假设你想知道哪种学生在学校考试中得分最高。你可能会考虑一些因素,比如一个人学习的小时数,他/她参考的书籍,他们的睡眠时间等等。这些因素将成为神经网络的输入。如果你能计算出每个因素对分数的影响程度,那就太好了。这是神经网络学习识别的内容。它通过更新每个特征的相应权重来学习哪些特征是最好的。权重会发生变化,以便下次对结果进行更准确的分类。

这就是我在这篇文章中的全部内容。下一次,我将深入探讨训练和*学习背后的数学和算法。*再加上深度学习非常酷的应用,比如这个:

【https://www.youtube.com/watch?v=Svk0SxyNdr8

编辑:你可以在 akshaybhatia10@gmail.com 找到我

DeepClassifyML 第 2 周第 1 部分

原文:https://towardsdatascience.com/deepclassifyml-week-2-part-1-1e1bafca79eb?source=collection_archive---------1-----------------------

这篇文章是“Hasura 实习”系列文章的一部分,涵盖了为其设置开发环境。查看 第一部分 第二部分 了解 app 想法和一些计算机视觉和神经网络基础知识。

前两篇帖子得到了很大的反响,第二部分**发表在 【走向数据科学】 上。这篇文章将讲述如何为图像分类应用程序设置开发环境。我使用的是 macOS X,但是这些说明适用于 Windows、Mac OS X 和 Linux 平台。这个项目的所有库都可以使用 pipbrew 安装。这个项目的主要库是 Keras (带 Tensorflow 后端)和 Flask 。如果想建立一个完整的机器学习环境,最好的办法就是安装 Anaconda 。它是一个开源平台,为数据科学和机器学习提供了 100 多个最流行的 Python 和 R 包。先从 这里 安装 Anaconda。确保选择适合您的平台(Windows、OSX 或 Linux)的下载选项和正确的 python 版本(2.7 或 3.5)。安装是一个快速简单的过程,应该不到 10 分钟(取决于您的连接),并占用大约 1 GB 的驱动器空间。Anaconda 附带了一套叫做 Anaconda Navigator 的图形工具。

深度学习部分,我推荐名为 conda 的 Anaconda 命令行环境。Conda 快速、简单,很难隐藏错误消息,并且您可以快速确认您的环境已安装并正常工作。接下来的几个步骤在 这里 下设置环境部分有很好的记录,所以我将跳过这一部分。另一个很棒的博文是 这里

现在你有了一个工作的 Python 环境,可以开始学习、实践、开发和解决机器学习和深度学习问题。你也可以在这里 阅读 Dat Tran 关于在 AWS 上建立深度学习环境的一篇很棒的帖子。

深度学习需要数学。因此,在开始构建我们自己的神经网络之前,理解基础知识非常重要。这篇文章旨在提供一个关于线性代数的 vert 简短复习,以及一些使用已经预装在 Anaconda 中的 NumPy 库的指导,以便在 Python 中有效地处理矩阵。那我们开始吧。(注:需要基本的 Python 编程)

Numpy

NumPy 为 Python 中的数学运算提供了快速的替代方法,因此被设计成可以有效地处理数字组,比如矩阵。你一定要花些时间探索它的 文档 来了解更多。我们在 NumPy 中处理数字最常见的方式是通过[ndarray](https://docs.scipy.org/doc/numpy/reference/arrays.html)对象。它们类似于 Python 列表,但是可以有任意数量的维度。ndarray支持非常快速的数学运算(这正是我们想要的),而使用 python 列表会非常慢,不适合这里。一个ndarray的元素是同质的(都是相同的dtype),并且由一个正整数元组索引。因为它可以存储任意数量的维度,所以您可以使用ndarray来表示我们之前讨论过的任何数据类型:标量、向量、矩阵或张量。我们可以从嵌套的 Python 列表中初始化 numpy 数组,并使用方括号访问元素:

*import numpy as npa = np.array([[0, 1, 2], [3, 4, 5]])   *# a 2D, 2 x 3, array*
a*

输出:

*array([[0, 1, 2],
       [3, 4, 5]])*

Numpy 还提供了许多创建数组的函数:

*import numpy as npa = np.zeros((2,2))   *# Create an array of all zeros*
print(a)              *# Prints "[[ 0\.  0.]*
                      *#          [0\.  0.]]"*b = np.ones((1,2))    *# Create an array of all ones*
print(b)              *# Prints "[[ 1\.  1.]]"*d = np.eye(2)         *# Create a 2x2 identity matrix*
print(d)              *# Prints "[[ 1\.  0.]*
                      *#          [ 0\.  1.]]"**

你可以在文档中阅读关于数组创建的其他方法。

标量

NumPy 中的标量比 Python 中的要复杂一些。而不是 Python 的基本类型像intfloat等。,NumPy 让我们指定有符号和无符号类型,以及不同的大小。所以除了 Python 的int,还有类似uint8int8uint16int16等类型。

我们可以创建一个 Numpy 标量,如下所示:

*a = np.array(5)*

不过,您仍然可以在ndarray、NumPy 标量和普通 Python 标量之间执行数学运算,您将在基于元素的数学课程中看到这一点。

您可以通过检查它们的shape属性来查看数组的形状。维数是数组的秩*;数组的形状是一个整数元组,给出了数组在每个维度上的大小。*

*a.shape*

即使标量在数组内部,你仍然可以像普通标量一样使用它们。所以你可以输入:

*n = a + 3*

并且n 现在将等于8。注意,n的类型是numpy.int64,因为它使用 NumPy 类型,而不是 Python 类型。

矩阵

我们使用 NumPy 的array函数创建矩阵,就像我们创建向量一样。然而,我们不是仅仅传入一个列表,而是提供一个列表的列表,其中每个列表代表一行。因此,要创建一个包含数字 1 到 9 的 3x3 矩阵,我们可以这样做:

*m = np.array([[1,2,3], [4,5,6], [7,8,9]])*

检查它的shape属性将返回元组(3, 3)以表明它有两个维度,每个长度为 3。

我们可以像访问向量一样访问矩阵的元素,但是使用额外的索引值。所以为了在上面的矩阵中找到数字6,我们将访问m[1][2]

Numpy 中的元素式操作

*values = [1,2,3,4,5]
values = np.array(values) + 5It now holds [6,7,8,9,10]*

因此,如果您已经有了一个名为valuesndarray,您可以只做:

*values += 5*

NumPy 实际上有加法、乘法等功能。但是它也支持使用标准的数学运算符。所以下面两行是等价的:

*x = np.multiply(array, 5)
x = array * 5*

需要注意的是*是元素式乘法,不是矩阵乘法。相反,我们使用dot 函数来计算向量的内积,将向量乘以矩阵,以及将矩阵相乘。dot既可以作为 numpy 模块中的函数,也可以作为数组对象的实例方法:

*x = np.array([[1,2],[3,4]])
y = np.array([[5,6],[7,8]])v = np.array([9,10])
w = np.array([11, 12])*# Inner product of vectors; both produce 219*
print(v.dot(w))
print(np.dot(v, w))*# Matrix / vector product; both produce the rank 1 array [29 67]*
print(x.dot(v))
print(np.dot(x, v))*# Matrix / matrix product; both produce the rank 2 array*
*# [[19 22]*
*#  [43 50]]*
print(x.dot(y))
print(np.dot(x, y))*

Numpy 为在数组上执行计算提供了许多有用的函数;其中最有用的是sum:

*import numpy as npx = np.array([[1,2],[3,4]])print(np.sum(x))  *# Compute sum of all elements; prints "10"*
print(np.sum(x, axis=0))  *# Compute sum of each column; prints "[4 6]"*
print(np.sum(x, axis=1))  *# Compute sum of each row; prints "[3 7]"**

除了使用数组计算数学函数之外,我们经常需要对数组中的数据进行整形或操作。这种操作最简单的例子是转置一个矩阵;要转置一个矩阵,只需使用数组对象的T属性:

*import numpy as npx = np.array([[1,2], [3,4]])
print(x)    *# Prints "[[1 2]*
            *#          [3 4]]"*
print(x.T)  *# Prints "[[1 3]*
            *#          [2 4]]"**# Note that taking the transpose of a rank 1 array does nothing:*
v = np.array([1,2,3])
print(v)    *# Prints "[1 2 3]"*
print(v.T)  *# Prints "[1 2 3]"**

矩阵积

要找到矩阵乘积,可以使用 NumPy 的matmul函数。

*a = np.array([[1,2,3,4],[5,6,7,8]])
a
# displays the following result:
# array([[1, 2, 3, 4],
#        [5, 6, 7, 8]])
a.shape
# displays the following result:
# (2, 4)b = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
b
# displays the following result:
# array([[ 1,  2,  3],
#        [ 4,  5,  6],
#        [ 7,  8,  9],
#        [10, 11, 12]])
b.shape
# displays the following result:
# (4, 3)c = np.matmul(a, b)
c
# displays the following result:
# array([[ 70,  80,  90],
#        [158, 184, 210]])
c.shape
# displays the following result:
# (2, 3)*

如果您的矩阵有不兼容的形状,您会得到一个错误,如下所示:

*np.matmul(b, a)
# displays the following error:
# ValueError: shapes (4,3) and (2,4) not aligned: 3 (dim 1) != 2 (dim 0)*

尽管理解 Numpy 的工作原理非常重要,但我想让这篇文章保持真正的介绍性,所以很明显 Numpy 中有很多操作没有在这里介绍。因此我在下面链接了一些很棒的资源。

最后让我们看看权重(你在第二部分 中学到的)如何将与 Numpy 矩阵和转置函数联系起来:

假设你有下面两个矩阵,叫做“输入”和“权重”。“输入”是传递给你的神经网络的数据,“权重”是你的神经网络学习修改以找到最佳可能的解决方案。

*inputs = np.array([[-0.27,  0.45,  0.64, 0.31]])
inputs
# displays the following result:
# array([[-0.27,  0.45,  0.64,  0.31]])inputs.shape
# displays the following result:
# (1, 4)weights = np.array([[0.02, 0.001, -0.03, 0.036], \
    [0.04, -0.003, 0.025, 0.009], [0.012, -0.045, 0.28, -0.067]])weights
# displays the following result:
# array([[ 0.02 ,  0.001, -0.03 ,  0.036],
#        [ 0.04 , -0.003,  0.025,  0.009],
#        [ 0.012, -0.045,  0.28 , -0.067]])weights.shape
# displays the following result:
# (3, 4)*

让我们试着把它们相乘,因为这就是我们如何得到神经网络的输出。

*np.matmul(inputs, weights)
# displays the following error:
# ValueError: shapes (1,4) and (3,4) not aligned: 4 (dim 1) != 3 (dim 0)*

如果你像他们现在这样尝试,你会得到一个错误。由于左矩阵中的列数4与右矩阵中的行数3不相等,导致形状不兼容,从而出现错误。

但是如果我们对“权重”矩阵进行转置,结果是:

*np.matmul(inputs, weights.T)
# displays the following result:
# array([[-0.01299,  0.00664,  0.13494]])*

如果你转置“输入”并交换它们的顺序,它也是有效的。

*np.matmul(weights, inputs.T)
# displays the following result:
# array([[-0.01299],# 
#        [ 0.00664],
#        [ 0.13494]])*

两个答案是彼此的转置,所以我们使用的乘法的顺序实际上取决于我们想要的形状。

在下一篇文章中,我们将把这些概念应用到一个神经网络问题中。

Numpy 链接:

这本 笔记本详细解释了许多操作。还要查看 Numpy 库文档:https://docs.scipy.org/doc/numpy-dev/user/quickstart.html。另一个很好的资源是关于这个主题的科学讲座系列。Numpy 章出自本本本。

DeepClassifyML 第 2 周第 2 部分

原文:https://towardsdatascience.com/deepclassifyml-week-2-part-2-1b65739c0f35?source=collection_archive---------5-----------------------

这篇文章是“Hasura 实习”系列的一部分,涵盖了git是什么。此外,我们开始实现和设计一个神经网络,根据学生的成绩来查找哪些学生被大学录取。还查看了我以前的帖子: 第一部分 第二部分 第三部分 对于 app 的想法以及一些计算机视觉和神经网络的基础知识。

Git 是一个版本控制系统,用于管理一个项目或一组文件,并随着时间的推移跟踪它们的变化。Git 是由 Linus Torvalds 开发的。它允许您将文件恢复到以前的状态,将整个项目恢复到以前的状态,比较一段时间内的更改,查看谁最后修改了可能导致问题的内容,谁在何时引入了问题,等等。使用 Git 或任何其他版本控制系统也意味着,如果你搞砸了事情或丢失了文件,你可以很容易地恢复它们。它有 3 种主要状态:提交、修改和暂存。提交是指所有数据都安全地存储在本地数据库中的状态。修改是指用户已经更新或更改了文件中的某些内容,但尚未提交到数据库。暂存意味着用户已在其当前版本中标记了一个修改过的文件,以便进入您的下一个提交快照。

Git 将这些信息存储在一个称为存储库的数据结构中。git 存储库包含以下内容:

  • 一组提交对象。
  • 提交对象的一组引用,称为 heads。

存储库存储在与项目本身相同的目录中,在一个名为. git 的子目录中。

  • 只有一个。git 目录,在项目的根目录下。
  • 存储库存储在项目旁边的文件中。没有中央服务器存储库。

提交对象包含三样东西:

  • 定义项目在给定时间点的状态的一组文件。
  • 对父提交对象的引用。
  • SHA1 名称,一个 40 个字符的字符串,唯一标识提交对象。

基本的 Git 工作流程可以用 3 个步骤来描述:

  • 修改/更新/更改项目存储库中的文件。
  • 暂存已修改的文件。
  • 提交暂存文件,并将它们永久存储到 Git 目录中。

修改文件但不添加它会导致 g it 将以前的版本(修改前)包括到提交中。因此,修改后的文件将保留在原处。

这篇 优秀的博文详细涵盖了你需要了解的关于 Git 的一切。 Hubspot 在 Git 和 Github 上的帖子 也是入门初学者的绝佳入门。

现在转到机器学习。上次我们用 Numpy 从基础数学开始。让我们看看如何应用它来解决问题。

神经网络从数据中学习的方式可以分为 3 个步骤:

  1. 我们为神经网络提供训练示例,它由输入单元的活动模式和输出单元的期望活动模式组成。
  2. 我们确定网络的实际输出与期望输出的匹配程度。
  3. 我们改变每个连接的权重,以便网络产生更好的期望输出的近似值。

A 3 layer Neural Network

这是一个 3 层神经网络。每一层都有独立的块,我们称之为神经元,这些是神经网络的基本单位。每个人都查看输入数据并决定如何对这些数据进行分类*。*箭头代表连接,可以想象为“重量”。

假设我们想知道一个学生是否能以他/她的 4 门学科的成绩进入大学。我们有他们的分数,也知道他们是否被录取。我们现在想知道当一个新学生进来时会发生什么。分数是我们网络的输入,被称为“特征”。输出层中的输出节点会给我们‘接受’或‘拒绝’,称为目标变量。总而言之,输入数据(分数)被输入到一个由相互连接的节点组成的网络中。现在,在上面的例子中,如果输入组合在一起并且超过了某个阈值,我们输出一个“是”,这个学生被大学录取了。网络决定一个学生的分数是否足够高,可以被大学录取。

现在你可能想知道它是如何知道哪些主题在做出接受决定时更重要的。一开始,当我们初始化神经网络时,我们不知道哪一个对决策最重要。这是使用“权重”完成的。网络的每个输入都有代表其重要性的相关权重,这些权重是在神经网络的学习过程中确定的。我们将权重表示为' W' ,将输入(科目等级)表示为' S '。 网络使用这些权重对输入进行求和,这一过程称为 **线性组合。**方程式如下:

x = w1 ⋅s1+w2⋅s2+w3 . S3+w4 . S4

但是对于这个例子,我们只有 4 个输入。一般来说,我们可能有许多科目,或者其他功能,如课外活动等。假设我们有 m 个不同的输入(特征),我们将它们标记为 s(1),s( 2),。….s( m )。我们也假设 s 1 对应的权重是 w 1 等等。在这种情况下,我们可以将线性组合简洁地表示为:

x =w1 ⋅s1+w2⋅s2+w3 . S3+w4 . S4+……..+ w m⋅sm

或者

x =(1∑m)[(wt39】I⋅sI)】

适马(≘)用来表示**求和。**这个表示我们多次向右计算等式,然后将结果相加。这里 1 ∑ m 表示迭代所有的 i 值,从 1 到 m

上面的等式意味着:

  • 我们从 1 号主题开始,即 i =1
  • 评估⋅s 1 号并记住结果
  • 移动到 i =2
  • 评估 w 2 ⋅s2 并将这些结果添加到 w 1 ⋅ xs 1
  • 重复上述过程,直到 i = m 为止,其中 m 为输入(对象)数。

(注意:你可以把从 1 到 m 的总和∑写成 ∑w i ⋅s i。)

还记得第二部分中的激活功能吗?给定神经元的输入,它们是决定神经元输出的函数。它决定实际输出,因此其输出通常被称为“激活”。

现在,通过将线性组合输入到激活函数,使用该激活函数将来自输入层的输出(求和)转换成最终输出,即“接受或“拒绝”。一些激活功能是tanhsoftmaxrelu 功能。我们将使用 sigmoid 给出的激活函数:

Sigmoid Function

sigmoid 函数介于 0 和 1 之间,输出以成功概率的形式给出。(1 代表“接受”,0 代表“拒绝”)。

我们还在线性组合中加入一个术语叫做' 偏差 '。偏置,在等式中表示为 b ,允许我们将激活功能向左或向右移动,这对于成功的学习可能是至关重要的。像“权重”一样,神经网络不会预先知道为偏差选择什么值。因此,偏差也可以在训练期间更新和改变。因此输入层输出变成

x = ∑w i ⋅s i +b

让我们使用 Numpy 来计算我们的神经网络的输出,该神经网络具有 4 个输入(受试者)节点和一个带有 sigmoid 激活函数的输出节点(“接受”或“拒绝”)。我们将此任务分为 3 个步骤:

  • 计算线性组合(输入层的输出)。
  • 应用激活功能。
  • 计算产量

为了计算线性组合或权重的和,我们将使用 Numpy 的点积函数,它允许我们执行元素级乘法和求和。

*import numpy as npdef sigmoid(x):
    return 1/(1 + np.exp(-x)) ##numpy's exponential function inputs = np.array([50, 60, 10, 45])
weights = np.array([0.1, 0.8, 0.02, -0.7])
bias = -0.1output = sigmoid(np.dot(weights, inputs) + bias)print('Output: {}'.format(output)) ##Output: 0.999999999584*

神经网络的这种操作称为“前向传播”,让我们观察我们的模型执行得如何。下一步是实际更新权重并进行预测。这被称为“反向传播”,是实际学习发生的阶段。我们从数据中学习权重,然后使用它们进行预测。

在下一篇文章中,我们将讨论'反向传播和'梯度下降',这是机器学习的主干和最重要的概念之一。

编辑:你可以在 akshaybhatia10@gmail.com 找到我

DeepClassifyML 第 2 周第 3 部分

原文:https://towardsdatascience.com/deepclassifyml-week-2-part-3-7c080af22f8a?source=collection_archive---------10-----------------------

这篇文章是“Hasura 实习”系列文章的一部分,讲述了如何为当地发展建立 Hausra。除此之外,我们终于看到‘神经网络如何学习’。还查看了我以前的帖子: 第一部分第二部分第三部分第四部分 对于 app 的想法以及一些计算机视觉和神经网络的基础知识。**

为本地开发设置 Hasura 非常简单,因为 Hasura 在这个 自述文件 中提供的指令都有很好的文档记录,并且非常容易实现。以下是我在我的系统上是如何做到的:

第一步: 安装virtualbox VirtualBox 是一款免费、开源、跨平台的应用,用于创建和运行虚拟机(VM)——其硬件组件由运行程序的主机计算机模拟的计算机。它允许在其上安装额外的操作系统,作为来宾操作系统,并在虚拟环境中运行。需要注意的是,主机应该至少有 4GB 的内存(因为虚拟机可能会占用高达 2GB 的内存)。还要确保你应该有一个 64 位操作系统。

**第二步: 安装 hasuractl。在我的系统(mac)上安装它的命令是:

**curl -Lo hasuractl https://storage.googleapis.com/hasuractl/v0.1.2/darwin-amd64/hasuractl && chmod +x hasuractl && sudo mv hasuractl /usr/local/bin/**

第三步: 安装 kubectl

要在 Hasura 上开始一个项目,在 beta.hasura.io 上创建一个帐户,然后运行以下命令:

**hasuractl login**

Hausra Login

登录后,运行以下命令(注意:如果您是第一次运行下一个命令,它将大致下载大约 1–1.5 GB 的 docker 映像。):

**hasuractl local start**

Starting a project

停止和删除 Hasura 项目的附加命令:

****hasuractl local stop**      ## To stop the running hasura platform.***hasuractl local clean    *** ## To clean up the incomplete setup.**hasuractl local delete**    ## To delete the underlying VM**

**让我们快速进入''反向传播'和''梯度下降'。在 第四部分 中,我们看到了神经网络如何在我们称之为“正向传播的过程中做出预测。我们根据一个学生以前的分数来预测他是否能进入大学。现在我们有了一个预测,我们如何知道它是否正确,以及我们离正确答案有多近。这是在“训练”或更新这些权重以进行预测的过程中发生的。

**我们想要的是一种算法,它能让我们找到这些权重和偏差,从而使网络的输出接近正确答案。(请记住,在培训期间,我们有他们的分数,也知道他们是否被录取,也就是说,我们事先知道正确答案。我们想知道当一个新学生进来时会发生什么。为了衡量这一点,我们需要一个指标来衡量预测的不正确程度。让我们称之为'误差'(你会注意到它也被称为'成本函数'或'损失函数')。该误差可以用下式表示:

Sum of Squared Errors (SSE)

我在这里使用的误差指标被称为误差平方和(SSE)。我决定选择这个(也有其他损失函数),因为平方确保误差总是正的,较大的误差比较小的误差受到更多的惩罚。此外,它使数学看起来很好,不那么吓人。这里 f(x) 是预测值,y 是真实值,然后我们对所有数据点 i 求和。这也是有意义的,因为最终我们想从正确的答案中发现我们的预测有多差。这意味着如果我们的神经网络做得不好,这个'误差'将会很大——这将意味着对于大量数据点来说 f(x) 并不接近输出 y 。此外,如果成本(误差)变小,即 SSE(f) ≈0,精确地说,当 y 近似等于预测值 f(x) 时,对于所有训练输入 I,我们可以得出结论,NN 已经做得很好。因此,我们的训练算法的目标将是最小化作为权重和偏差的函数的这个'误差'。换句话说,我们希望找到一组权重和偏差,使这个“误差”尽可能小。我们将使用一种叫做梯度下降的算法来实现。

梯度下降是执行优化的最流行算法之一,也是迄今为止优化神经网络的最常见方法。它要求我们计算损失函数(误差)相对于网络中所有权重的梯度,以执行权重更新,从而最小化损失函数。反向传播以系统的方式计算这些梯度。反向传播和梯度下降可以说是训练深度神经网络的最重要的算法,可以说是最近出现的深度学习的驱动力。

让我们通过一个经典的例子来理解这一点。假设你在一座山的山顶,想到达山脚(也就是山的最低点)。那么,你会怎么做呢?最好的方法是环顾四周所有可能的方向,检查你附近的地面,观察哪个方向最容易下降。这会给你一个方向的想法,你应该采取你的第一步。然后我们一遍又一遍地重复这个过程。如果我们继续沿着下降的路径,很可能你会到达底部。

Plot for the Loss Function

把大山想象成误差函数。该图表面上的随机位置是权重和偏差的当前值的成本。山的底部(也是图的底部)是最佳权重和偏差集的成本,加上最小误差。我们的目标是继续尝试这些权重和偏差的不同值,评估误差,并选择导致误差稍好(较低)的新系数。重复这个过程足够多次,就会到达山的底部。

我们朝着目标迈出了一小步。在这种情况下,我们希望逐步改变权重以减少误差。因为下山最快的路是在最陡的方向,所以应该在误差最小的方向走。我们可以通过计算平方误差的梯度找到这个方向。

**梯度(导数)是变化率或斜率的另一个术语。导数是微积分中的一个概念,指的是函数在给定点的斜率。我们需要知道斜率,以便知道移动系数值的方向(符号),从而在下一次迭代中获得更低的成本。

让我们找到一个函数的导数 f ( x )。我们取一个简单的函数 f(x) = x 。导数将给我们另一个函数f'(x),该函数返回 f ( x )在点 x 的斜率。 x 的导数为f'(x)= 2x。所以,在 x =2 时,斜率为f'(2)= 4。画出这个,看起来像:

Graph of f(x) = x² and its derivative at x = 2

梯度只是一个推广到具有多个变量的函数的导数。我们可以使用微积分来找到误差函数中任意一点的梯度,这取决于输入权重。你将在下一页看到梯度下降步骤是如何推导出来的。

权重将更新为:

W += ndelta*

**其中 n 称为“学习率”,δ是误差( y-f(x) )和激活函数的导数(f’(x))的乘积。梯度告诉我们函数具有最大增长率的方向,但是它没有告诉我们应该沿着这个方向走多远。由一个常数:学习率(或步长)决定,它是训练神经网络中最重要的超参数设置之一。

为此,我们再次使用 numpy:

**import numpy as np*## Sigmoid (Activation) function* **def sigmoid(x):                    
    return 1/(1+np.exp(-x))***## Derivative of the Sigmoid (Activation) function* **def sigmoid_derivative(x):
    return sigmoid(x) * (1 - sigmoid(x))***## Grades for single student in 4 subjects i.e only 1 data point* **inputs = np.array([50, 22, 10, 45])***## Correct answer (1 : admitted, 0: not admitted)* **y = np.array([1])** *## Initialise the weights and bias randomly* **initial_weights = np.array([0.01, 0.8, 0.02, -0.7])
bias = -0.1**## Set a value for learning rate
**learning_rate = 0.001***## Our Prediction (f(x))* **output = sigmoid(np.dot(weights, inputs) + bias)***## Calculate the error i.e how incorrect are we* **error = y - output****delta = error * sigmoid_derivative(output)***# Gradient descent step***change_in_weights = learning_rate * delta * inputs***## Updating our weights* **new_weights = initial_weights + change_in_weights****print ('Initial Weights: {}'.format(initial_weights))
print('Our prediction: {}'.format(output))
print('Amount of Error: {}'.format(error))
print('Change in Weights: {}'.format(change_in_weights))
print('New weights: {}'.format(new_weights))****

输出:

**Initial Weights: [ 0.01  0.8   0.02 -0.7 ] 
Our prediction: 1.6744904055114616e-06 
Amount of Error: [ 0.99999833] 
Change in Weights: [ 0.01249998  0.00549999  0.0025      0.01124998] New weights: [ 0.02249998  0.80549999  0.0225  -0.68875002]**

虽然理解反向传播背后的概念总是有帮助的,但是如果你发现数学很难理解,那也没关系。我们使用的机器学习和深度学习库(scikit-learn、Tensorflow 等。)有内置的工具为你计算一切。

(编辑:请在评论中报告任何错误或差异,或者您可以联系我:akshaybhatia10@gmail.com)

用 DeepGL 在 Neo4j 上提取图形数据的 ML 特征

原文:https://towardsdatascience.com/deepgl-on-neo4j-b27e8c64190f?source=collection_archive---------12-----------------------

图的深度特征学习

2013 年,托马斯·米科洛夫和他的谷歌同事发布了一篇描述 word2vec 的论文,并推广了生成嵌入来表示数据片段的想法。

什么是嵌入?

嵌入是一个数组或数字向量,用来表示某种东西,在 word2vec 中是一个单词。

Adrian Colyer 有一个很好的图表,展示了一个词汇的非常简单的 hot 编码表示(下面有一个元素“hot”):

One hot encoding of a vocabulary of words

在这个例子中,每个单词有一列,一个单词的向量在适当的列中为 1,在其他地方为 0。

使用这种简单的表示,我们实际上无法在我们的嵌入之间进行任何有意义的比较,但是 word2vec 比这更进一步,它为每个单词提供了一种表示,这是这些元素之间的权重分布。

例如,我们可能会以这样的单词表示法结束:

自从 word2vec 发布以来,其他人已经使用类似的方法为单词之外的东西提供了嵌入。Pinterest 创建了 pin2vec ,用于向用户推荐 pin,Airbnb 使用嵌入功能寻找相似的房产列表。

我们如何处理这些嵌入?

嵌入可以被认为是表征学习的一种实现,在这种情况下,我们会自动提出一些特征来输入我们的机器学习模型,而不是手动创建它们。

例如,这些算法的输出可以用作张量流模型的输入。

我们还可以使用图形算法库 3.4.7.0 版本中引入的余弦相似性过程从嵌入中构建一个 kNN 相似性图

然后,可以使用相似性图作为 k-最近邻查询的一部分来进行推荐。

图形嵌入

有几种算法可以用来生成图嵌入。这些是我们知道的:

  • 节点 2Vec
  • struc2vec:从结构同一性中学习节点表示
  • DeepWalk——在线学习社交表征

这个想法和单词嵌入算法是一样的。我们希望为图中的每个实体(通常是节点)确定一个向量表示,然后将这些表示输入到机器学习算法中。

列表中最近增加了一个由 Ryan A. Rossi、Rong Zhou 和 Nesreen K. Ahmed 创建的图形深度特征学习 (DeepGL)。

这个对我们来说非常有趣,因为它是专门设计来保持低内存使用率的,并且还返回它提出的功能的名称,这在机器学习模型可解释性和功能提取的这些天很有帮助。另一个很好的特性是,它允许你将数字节点属性传递给算法,而其他的只有依赖于图形结构。

DeepGL 是如何工作的?

提供初始功能

我们首先为每个节点构建一组基本特征:入度、出度和两个度。我们还可以选择包含节点的任何其他数字属性(或投影)。

这篇论文描述了更多可以通过本地 graphlet 分解生成的基本特性,但是我们还没有实现。

对于一个包含 4 个节点的非常简单的图形,这些基本特征可能如下所示:

Bin 值

然后我们对这些值按列应用对数宁滨。这导致以下嵌入:

对每个邻域的要素应用运算符

接下来,我们对每个节点的(入、出、整体)邻域的这组特征应用一组操作符。我们应用的运算符有

  • 哈达玛,
  • 意思是,
  • 总和,
  • 最大值,
  • L1·诺姆,
  • 和径向基函数。

这意味着,比方说,对于 sum 运算符,我们将为每个节点创建 9 个新列:

  • 在邻域中我们的入度之和
  • 我们的邻域的外向度之和
  • 我们的邻域中的双度之和
  • 我们的邻域的入度之和
  • 我们的 out 邻域的 out 度之和
  • 我们邻区的双度之和
  • 我们整个邻居的入度之和
  • 我们整个邻居的外向度之和
  • 我们的整体邻域的双度之和

让我们看看,如果我们将运算符应用于邻域中的**,会发生什么。我们以 3 个额外的列结束,汇总了每个节点的邻居对于入度出度双度的得分。**

我们得到的一组特征如下所示:

我们为我们的其他邻域以及所有其他操作符计算相同的值,这给我们一个 57 列 4 行的矩阵**。**

在邻居之间分配分数

然后我们应用一个扩散过程,其中每个节点将其分数分配给其邻居。我们实现这一点的方式是,每个节点为每个特征取其所有邻居的平均值。

扩散过程不包括基本特征,因此在我们的示例中,我们将只扩散输入求和输出求和输入和输出求和。

我们得到的一组特征如下所示:

在我们继续下一阶段之前,我们再次应用对数宁滨,从而产生这组特征:

修剪特征

在这一步之后,我们应用特征修剪,这包括在特征相似性图上运行弱连通分量算法,然后只保留每个连通分量的一列。

我们通过对每一列中的值进行逐项比较来计算特征的相似性。如果两列中的所有值都相同,则该列的相似性得分为 1。在我们的例子中,扩散入和扩散入和以及其他几对列就是这种情况。

假设剪枝λ为 0.7 以移除较低等级的关系,这是我们最终得到的特征图:

Our feature graph

连通分量算法将给出 3 个分量:

  • 累计金额
  • 两者相加入度出度和
  • 双学位双学位双学位双学位双学位

我们倾向于保留早期迭代中的特性,这意味着基础特性。我们为每个组件保留一个特性,这在本例中意味着我们保留:

  • 求和输入
  • 输入度数
  • 双学位双学位(我们在这两者之间随机选择)

反复重复该过程

我们根据需要重复这个过程。在第二次和随后的迭代中,我们将把操作符应用到上一次迭代留下的特征上,而不是再次应用到基础特征上。

结果

一旦算法完成,我们将为图中的每个节点获得等长的向量。

在我们的例子中,这些向量是:

因此,节点 0 的向量是*【0,0,0】,节点 1 的向量是【1,1,0】,节点 2 的向量是【2,0,2】,节点 3 的向量是【0,2,1】*

我如何使用 DeepGL?

在过去的几个月里 Pete Meltzer ,他作为研究助理在 BrainTree 工作,并且正在 UCL 攻读博士学位,我已经将这个算法作为 Neo4j 程序来实现,并且现在已经有了一个版本供您试用!

DeepGL 算法作为 ml-models 库的一部分可用。你会想抓住 1.0.2 版本。

一旦你安装了它(存储库中的指令),你会找到两个版本的算法供你使用:

  • embedding.deepgl —这将嵌入作为每个节点上的属性进行存储
  • embedding . deepgl . stream—返回节点的流,嵌入

当你在玩算法的时候,流式可能是有意义的,但是一旦你想在一个合适的数据集上使用它,我建议使用第一个版本。

这是算法的签名:

CALL embedding.deepgl("NodeLabel" ,"RelationshipType", {
  nodeFeatures: [string]
  pruningLambda: double,
  diffusions: integer, 
  iterations: integer,
  writeProperty: string
})
  • nodeFeatures —包含一个附加属性名的数组,您希望将其用作算法基本功能的一部分(默认为[])
  • pruningLambda —移除相似特征时算法应该有多严格。较低意味着积极修剪莫尔斯(默认为 0.7)
  • 扩散 —算法应该执行多少次扩散(默认为 10 秒)
  • 迭代 —算法应该运行多少次迭代(默认为 10 次)
  • writeProperty —将存储嵌入数组的属性的名称(默认为“deepgl”)

您还可以通过传递 graph: "cypher" config 参数并提供对节点 id 和关系列表的 cypher 查询来利用图形投影(视图),而不是节点标签关系类型。

我们设置的默认值似乎在我们测试的数据集上工作得很好,但它们与论文中建议的不同,所以 YMMV。

效果如何?

我们已经在论文中引用的 Enzyme 和 EU 网络数据集上测试了该算法,与使用其他算法创建的嵌入相比,它似乎工作得相当好。

F1 scores of graph embeddings on various datasets

后续步骤

我们希望这种算法是有用的,并且你能在你自己的数据集上使用它。

如果你对我们下一步应该做什么有任何问题或建议,请在评论中告诉我们,或者给我们发电子邮件到devrel@neo4j.com。您也可以在我们新的 Neo4j 社区论坛中提出任何问题。

如果你想和皮特·梅尔策联系,你可以在 p.meltzer@braintree.com 的找到他。

使用表格数据的深度学习:可视化、数据处理、分类嵌入

原文:https://towardsdatascience.com/deeplearning-with-tabular-data-data-processing-cd2e73908257?source=collection_archive---------4-----------------------

(寻求项目合作)

与其他机器学习算法一样,在建立深度学习网络时,理解你的数据很重要。让我们使用一个简单的表格数据集来可视化数据,得出结论,以及不同的处理技术如何提高您的深度学习模型的性能。

金县房价数据集有 21613 个数据点,涉及金县的房屋销售价格。它有大约 19 个专栏,如下所示。它是日期、数字和分类数据的混合。使用开箱即用的数据,我们将得到 **149167.61 的 MAE。**然而,通过一些数据处理,我们可以得到低至 69471.41 的平均汇率。这超过了 50%的改进。

数据可视化

让我们深入研究数据,看看在构建模型之前,我们是否能对数据有所了解。我们将使用 Python 统计可视化库 Seaborn ,它构建在 matplotlib 之上。下面是每种功能相对于价格的分布。

  • 销售年份数据是双峰数据,包含 2014 年和 2015 年的数据
  • 诸如卧室数量、浴室数量、客厅平方英尺、楼上平方英尺、地下室平方英尺、销售价格等数据是单峰的,我们已经可以看出,对于这些特征具有较高价值的房屋,该模型可能具有较高的平均误差。

让我们看看特征 w.r.t .标签栏的相关性,也就是房子的销售价格。

构建深度学习模型

我将使用 keras 2.0 库构建一个序列神经网络来学习预测房价的回归模型。

导入数据集,然后将其分为定型集、验证集和测试集。

该模型有两个隐藏的密集图层和一个最终的线性组合图层来生成回归输出。我们将使用均方误差作为损失函数。

使用现成的数据给我们提供了 149167.61 的 MAE。现在让我们看看一些数据处理技术,以及它们如何帮助提高性能。

白化数据

我们的一些特征是 0.1 的数量级,一些是 10 的数量级,一些是 100 的数量级,一些是 10000 的数量级。不同数值顺序的这种差异会导致较高顺序的值支配其他值。“白化”数据有助于规范化不同值的顺序。

白化操作采用本征基中的数据,并将每个维度除以本征值,以标准化尺度。这种变换的几何解释是,如果输入数据是多变量高斯,那么白化后的数据将是均值为零、协方差矩阵相同的高斯。假设我们的数据应该是高斯分布,我们将计算每列的 z 得分。

关于预处理,重要的一点是任何预处理统计(例如,数据平均值)必须只在训练数据上计算,然后应用于验证/测试数据。

一旦我们用标准化的数据重新运行模型,我们的 MAE 下降到 **99622.24。**这是对使用现有数据的巨大改进。

将“经度”和“纬度”转换为距离

虽然经度和纬度可以按原样使用,但我们可以通过将经度和纬度转换为房子与固定位置的距离以及表示房子相对于固定位置的方向的布尔值来获得更多的洞察力。

使用新的特征“距离”、“更长”、“更短”、“更长”和“更短”,我们在数据集上再次训练模型。训练集的结果 MAE 进一步下降到 87231.59。

处理分类数据

邮政编码是数据中的一个特征列。我们一直把它当作一个正常的数值,但是,不同的邮政编码值没有顺序关系。此外,它们编码一些更深层次的关系,例如,一些邮政编码有更昂贵的房子,因为它们更接近学校或交通等。

借助于嵌入,可以丰富地表达分类数据。你可以从 fast.ai 的这篇文章中阅读更多关于嵌入的内容。

为了在 Keras 2.0 中使用嵌入,我们必须使用函数式 API。输入之一将是邮政编码数据,我们将把它转换成一个嵌入。另一个输入将是其他特征的向量。

如果我们把模型打印出来并可视化,这个模型会更容易理解。

训练这个模型并在测试数据集上运行它,MAE 急剧下降到 69471.41。

让我们使用 TSNE 库来可视化 zipcode 嵌入,如下所示:

我们看到左侧有一组邮政编码,其中包含售价较高的房屋。

结论

因此,当我们从 MAE 为 **149167.61 开始,**在白化数据、处理数据、使用分类嵌入之后,我们将 MAE 减少到了 69471.41。

DeepMind 的游戏《用深度强化学习捕捉旗帜》

原文:https://towardsdatascience.com/deepminds-playing-capture-the-flag-with-deep-reinforcement-learning-a9f71256442e?source=collection_archive---------4-----------------------

#4 研究论文讲解

DeepMind 和其他大学发表了许多端到端强化学习论文,用于解决可以由单个代理解决的问题。端到端 RL 算法通过将像素作为输入并将控制作为输出来学习网络中的特征表示和决策制定。

Previous Work: Single player game Source

现实世界中存在一些问题,这些问题需要多个独立行动的个体共同协作来实现一个目标。从踢足球或打篮球到让火箭登陆月球,一组人按照一个策略一起工作,通过降低失败的风险来更快、更安全地完成任务。这张纸可以用来解决很多现实生活中的任务,所以让我们分解这张纸来了解它们的解决方案。

DeepMind 已经建立了一个端到端的基于群体的 RL 算法,该算法使用两层优化过程成功解决了这个问题&通过在基于团队的 3D 多智能体环境(捕捉旗帜)中训练个体,彼此独立地行动和学习,战略性地一起工作以实现单一目标。

这导致模型遭受学习问题的高度复杂性,该学习问题是由环境中其他学习代理的并发适应引起的。

游戏夺取旗帜具有上述问题的所有特征:

1。3D 第一人称视角多代理游戏。(由于 fpv 的相似性,也可以在机器人中实现)

2。在与对手或队友相同的环境中比赛时,代理不知道彼此的决定。

3。学习高级认知技能的基于策略的游戏*。*

此外,每个游戏的室内和室外主题地图都是随机生成的。由多名个人玩家组成的两个对立团队通过战略性地导航、标记和躲避对手来争夺对方的旗帜。五分钟后获得最多旗帜的队伍赢得比赛。

特设小组

为了开发能够获得通用技能的更通用的策略和学习代理,在固定地图上训练固定的代理团队减少了训练数据的多样性——相反,本文设计了一种算法和训练程序,使代理能够获得对地图、玩家数量和队友选择的可变性具有鲁棒性的策略,这是一种与特设团队 游戏密切相关的范例。

最终的赢/输是从环境接收到的延迟的偶发信号,使得在 5 分钟游戏结束时仅基于一个二进制信号来优化代理执行的 1000 个动作变得困难。

这使得我们很难从那些没有帮助的行为中辨别出哪些行为对赢得比赛是有效的。

我们可以通过增加游戏中的奖励数量来解决这个问题。通过使用更频繁的内部奖励,可以根据代理执行的操作给予奖励。

高级战略 CTF 游戏的记忆和长期时间推理要求通过引入一种代理架构来满足,该架构具有多时间尺度表示,令人想起在灵长类动物大脑皮层和外部工作记忆模块中观察到的情况,主要受人类情景记忆的启发。

这 3 项创新集成在一个可扩展的大规模分布式异步计算框架中。

在游戏中,代理在时间步长t接收来自第一人称视角的原始 RBG 像素输入**X***t*,产生控制动作**a***t* ,并接收游戏点数**ρ***t* 来训练代理的策略π

强化学习的目标是找到一个策略,使得在 T 个时间步的 CTF 博弈中期望的累积γ折扣奖励最大化。

Expected cumulative γ-discounted reward over a CTF game

π由具有外部记忆的多时间尺度递归神经网络参数化。

agent 的体系结构模型构建了一个时间层次的时间表示空间,并使用递归潜变量来促进顺序 agent 对记忆和时间连贯动作序列的使用。

(Figure S10 in paper) Network architectures of agents

获胜概率

对于****特设团队,代理人的策略πo 应该最大化其团队获胜的概率,{ π0, π1, π2, ……… , π(N-1/2) }及其队友的策略{ π1, π2, ……… , π(N-1/2) },对于游戏中总共 N 个玩家:

Ad-hoc probability of winning

其中,如果左边赢了,获胜运算符>返回 1,如果输了,返回 0,并随机打破平局。此外,ω代表游戏的特定地图。

团队中的 FTheW**——现在我们使用更频繁的内部奖励**r***t*, 我们可以通过基于可用的游戏点信号**ρ***t* 【点被注册为例如捕获旗帜的事件】指定**r***t =* w(**ρ***t*)并允许代理学习转换w来操作每个代理具有更密集的奖励函数的想法,从而内部奖励 r t 的策略优化优化 FThWin,给我们 FTW 代理

不支持用于在如此高的规模下一起训练 1000 个多智能体环境的传统方法,这使得这些方法不稳定。

可扩展性— 总人口**P** 通过在玩家中引入多样性来稳定训练,不同的代理被彼此并行地训练(54)。

配对— 为了提高代理的技能,从群体P中抽取队友&对手。由 ι 索引的代理为使用随机匹配方案mp(π) 的训练游戏,该随机匹配方案使合作玩家偏向于具有与玩家p相似的技能,增加了不确定性。

代理技能等级— 代理技能分数是根据训练游戏的输出,通过计算 Elo 分数 (15)在线估算的。

元优化— 用一种优化方法训练其他优化者的方法。本文使用群体来元优化 RL 流程本身的内部奖励&超参数。这可以看作是两层优化 RL 问题。内部优化又名JInner:内部优化由 RL 解决,它最大化 J inner,代理的预期未来贴现内部报酬。外部优化又名 J 外部 : 它是通过基于人口的训练(PBT)来解决的,并且它被最大化 w.r.t .内部奖励方案**w**p 和超参数**φ**p ,内部
优化提供元转换动态。

PBT 是一个在线进化过程,它适应内部奖励和超参数,并通过用更好的代理的变异版本替换表现不佳的代理来执行模型选择。

代理策略的这种联合优化有助于利用将学习和进化结合在一起的潜力,从而最大化:

训练期间的评估|锦标赛

为了评估训练期间代理人的综合表现,在程序生成的地图上进行一场比赛,其中包括三种类型的代理人的特别比赛。

  1. FTW 的烧蚀版本。
  2. 雷神之锤 3 竞技场脚本机器人
  3. 具有第一人称游戏经验的人类参与者。

结果

1。FTW 明显超过了人类在地图上的胜率,这是代理人和人类之前都没有见过的,即零射击一般化,两个人组成的团队平均每场比赛捕获 16 面旗帜,少于两个 FTW 代理人组成的团队。

2。 人-代理 v/s 代理-代理— 只有作为 h-a 团队的一部分,我们才观察到一个人赢了一个 a-a 团队(赢的概率为 5%)。

3。 职业游戏玩家 v/s FTW — 即使在 12 个小时的练习后,人类游戏测试员也只能在与代理团队的比赛中赢得 25%的胜利。

4。 特工 FTW 特工的标记准确率为 80%,而人类落后,只有 48%的成功率。即使他们的标记准确性被人为降低到人类的准确性,代理人还是赢得了比赛。

人类卓越的观察和控制分辨率帮助他们在成功远程标记中超过 FTW 代理 17% &代理 0.5%。

但 FTW 再次以 258 毫秒的短距离标记反应时间超过了人类,以 559 毫秒超过了人类。

点燃网络中的神经元!!!知识表示📺

研究网络是如何学习到具有如此高级丰富表征的技能的。网络询问游戏的过去、现在或未来状态。比如说—

  • 问:我有旗子吗?(目前)**
  • 问:**我最近见到我的队友了吗?(过去)
  • ****问:我会很快进入对手的基地吗?(未来)

类似地,基于游戏的特征,总共询问了 200 个二元问题,以观察网络的内部表现。

结果

根据作者的说法,如果对主体内部状态的逻辑回归准确地模拟了特征,那么主体就知道给定的特征。有趣的是,FTW 代理的表示被发现特别好地编码了与过去相关的特征:例如,FTW 代理能够以 91%的 AUCROC ( 在接收器操作特性曲线下的面积)对两个标志都偏离的状态进行分类(标志未落在基础),相比之下,自播放基线的分类率为 70%。

我鼓励你看看报纸,看看更详细的统计数据。

********

(Fig: S4 in paper) 40 Question on high-level game state feature(Columns) for different agents(Rows) for FTW agent

(英)可视化(= visualization)

论文中有更多的视觉化图像可以帮助你。我选择了几个不需要解释的:

(Fig: S7 in paper) Hilton Diagrams. At 450K the agent appears to have learned to read from near its own base and just outside the opponent base.

(Figure S6 in paper)Top two rows: Selected saliency analysis of FTW agent. Bottom: Saliency analysis of a single neuron that encodes whether an opponent is holding a flag.

(Fig:- S8 in paper) internal representations learned from playing CTF for the FTW and Self-play + RS agent

结论

在本文中,仅使用像素和游戏点数作为输入的人工智能体可以在丰富的多智能体环境中学习进行高度竞争性的游戏。这是通过将智能体训练中的许多创新(基于群体的智能体训练、内部奖励优化和时间分级 RL)与可扩展的计算架构结合起来实现的。

本文可用于解决您周围的其他问题,这些问题的解决方案中包含内存和临时扩展接口方面的困难。所以,我鼓励你们阅读这篇论文,从中获得乐趣&理解在我们关于机器学习的知识的边缘出现的方法,并通过实现这篇论文来突破边界,解决现实世界的问题,以生活在人类知识的边缘。

感谢您阅读文章。阅读更多你最喜欢的论文,并获得#PaperExplained 通知。在媒体和推特上关注我。

********

你会喜欢的以前的故事:

**** [## DeepMind 惊人的混搭 RL 技术

#1 研究论文解释

hackernoon.com](https://hackernoon.com/deepminds-amazing-mix-match-rl-techique-a6f8ce6ac0b4) [## 用 6 个神经元玩雅达利|开源代码

#2 研究论文解释

towardsdatascience.com](/playing-atari-with-6-neurons-open-source-code-b94c764452ac) [## Google X 在机器人领域使用视觉的深度强化学习

#3 研究论文解释

hackernoon.com](https://hackernoon.com/google-xs-deep-reinforcement-learning-in-robotics-using-vision-7a78e87ab171) [## 激活函数:神经网络

Sigmoid,tanh,Softmax,ReLU,Leaky ReLU 解释!!!

towardsdatascience.com](/activation-functions-neural-networks-1cbd9f8d91d6) [## 纪元与批量大小与迭代次数

了解您的代码…

towardsdatascience.com](/epoch-vs-iterations-vs-batch-size-4dfb9c7ce9c9)****

DeepSchool.io:深度学习学习

原文:https://towardsdatascience.com/deepschool-io-deep-learning-learning-ce4385a8978c?source=collection_archive---------3-----------------------

DeepSchool.io 是一个开源的、基于社区的项目,教授深度学习(DL)的基本知识。所有的课程都是互动的,(希望)有趣,偶尔会抨击特朗普先生(查看特朗普推特上的笔记本)。这个项目来自我作为数据科学家在 Arbor Networks 工作时每周上的一节课。

就我个人而言,我是在机器学习领域获得博士学位的。然而,随着 Keras 等工具的发展,DL 对于普通社区来说变得更加容易访问。这不再仅仅是学术上的好奇。

即使有这些可用的工具,教授深度学习也可能相当困难。我上的第一课完全是一场灾难。我忘记了我从哪里开始,直接跳进了一个多层的深网。我想当然地认为人们会理解什么是损失函数,什么是回归和逻辑回归。

相反,我也不想在数学上花太多时间。我想创造一些东西,让人们能够快速解决 DL 问题,而不是过于深入理论。我花了 6 个月左右的时间在吴恩达的 DL 课程上,这个课程确实是在实践这个理论。不幸的是,这并没有让我具备以任何有意义的方式舒适地使用 DL 所必需的工具。我们的目标是着眼于您可以用 DL 做些什么。

目标

  1. 让深度学习更容易(代码最少)。
  2. 最小化所需的数学。
  3. 让它变得实用(在笔记本电脑上运行)。
  4. 开源深度学习 Learning。
  5. 围绕 DL 发展一个协作实践社区
  6. 迷因:不认真。让 DL 变得有趣和互动,这意味着更多的特朗普推文。

假设您能够用 Python 编写代码。我把所有代码都放在 Jupyter 的笔记本上,唯一的原因是你可以和它互动。在单个 python 脚本上运行会降低这种交互性。

和 fast.ai 有什么不同?

一些差异,包括较短的视频和 Jupyter 笔记本电脑基本上是自给自足的。但我希望主要的区别是社区。我真正为 deep school 设想的是,这将在世界各地建立大量的 Meetup 节点,人们将在那里学习、指导和交流人工智能知识。

看这里是我关于机器学习和深度学习的课程(使用代码 DEEPSCHOOL-MARCH 到 85 折)。

使用深度学习的违约风险

原文:https://towardsdatascience.com/default-risk-using-deep-learning-6924cdada04d?source=collection_archive---------8-----------------------

由于信用记录不足或不存在,许多人很难获得贷款。不幸的是,这些人经常被不可信的贷方利用。像 Home Credit 这样的公司通过提供积极安全的借贷体验,努力扩大无银行账户人群的金融包容性。为了确保这些得不到充分服务的人群拥有积极的贷款体验,Home Credit 利用各种替代数据(例如,包括电信和交易信息)来预测其客户的还款能力。通过使用各种统计、机器学习和深度学习方法,我们释放了他们数据的全部潜力。这样做将确保有能力还款的客户不会被拒绝,并且贷款的本金、到期日和还款时间表将使他们的客户获得成功。

这个项目的目标是使用历史贷款申请数据来预测申请人是否能够偿还贷款。这是一个标准的监督分类任务:

  • **监督:**标签包含在训练数据中,目标是训练一个模型来学习根据特征预测标签
  • **分类:**标签为二元变量,0(会按时还贷),1(会有困难还贷)

在这个项目中,实现的目标是:

  • 数据探索例程被设计和实现来进行统计分析和可视化。
  • 建立分类模型朴素贝叶斯、逻辑回归、支持向量机(SVM)、决策树、随机森林、梯度推进机(GBM)深度学习来预测申请人是否能够偿还贷款。
  • 通过准确度、混淆矩阵、精确度、召回率、真阴性率(TNR)、假发现率(FDR)、增益图、提升图、K-S 图、ROC — AUC 图评估分类模型。
  • 将最终的解决方案部署为一个 Web 应用程序。

数据源

数据由 Home Credit ( Dataset )提供,这是一项致力于向没有银行账户的人群提供信贷额度(贷款)的服务。预测客户是否会偿还贷款或有困难是一项关键的业务需求,Home Credit 希望释放他们数据的全部潜力,看看可以开发什么样的机器学习/深度学习模型来帮助他们完成这项任务。

数据探索

数据探索是一个开放式的过程,在这个过程中,我们计算统计数据并制作图表,以发现数据中的趋势、异常、模式或关系。数据探索的目标是了解我们的数据能告诉我们什么。它通常从高层次的概述开始,然后缩小到特定的领域,因为我们发现了数据中有趣的领域。这些发现本身可能是有趣的,或者它们可以用于通知我们的建模选择,例如通过帮助我们决定使用哪些功能。

检查目标列的分布

目标是我们被要求预测的:要么 0 表示贷款按时偿还,要么 1 表示客户有支付困难。我们首先检查属于每个类别的贷款数量,并绘制计数百分比的饼图。

编码分类变量

我们对任何只有两个类别的分类变量使用标签编码,对任何有两个以上类别的分类变量使用一次性编码。标签编码的问题是它给了类别一个任意的顺序。分配给每个类别的值是随机的,并不反映该类别的任何固有方面。如果一个分类变量只有两个唯一值(比如男性/女性),那么标签编码就可以了,但是对于两个以上的唯一类别,一键编码是安全的选择。

最有价值图(MVP) —组合图

我们对数字和分类变量进行统计分析和可视化。我们生成描述性统计数据,总结数据分布的集中趋势、离散度和形状。

对于数值变量,我们绘制直方图,用一个 y 轴表示数值变量的分布,用于计算数值变量中的值,并用另一个 y 轴表示目标百分比=1(偿还贷款有困难)的线图。

Above Plot shows that as the count of numeric variable EXT_SOURCE_3 is increasing, the percent of Target=1 is decreasing, so with the increasing in EXT_SOURCE_3, more loans are being repaid. EXT_SOURCE_3 can be a potential feature for our predictive modeling

对于分类变量,我们绘制条形图以显示分类变量的分布,并用一个 y 轴按降序排序,y 轴表示类别值的计数,还用另一个 y 轴绘制线图,表示目标百分比=1(将难以偿还贷款)。

Above plot shows as the FLAG_OWN_REALTY is decreasing, the percent of Target=1 is increasing, so with the decrease in FLAG_REALTY, less loans are being repaid.

这个图叫做最有价值图(MVP),也叫组合图。组合图是展示预测者(X 轴)相对于目标(Y 轴)的可预测能力的最佳可视化方法。它们向我们展示了变量如何影响 Target=1 的百分比,从而证明了变量对我们预测建模的可预测性。从视觉上,我们可以说,随着变量的计数增加/减少,Target=1 的百分比根据直线的陡度而减少或增加,因此贷款的偿还或多或少分别取决于百分比的减少或增加。

数据建模

我们使用以下机器学习算法,并为我们的监督分类任务建立分类模型。

  1. 朴素贝叶斯
  2. 逻辑回归
  3. 随机森林
  4. 梯度推进机(GBM)
  5. 深度学习

在上述模型中,前三个是基线模型,后三个是改进模型。

深度学习

在我们将数据输入深度神经网络之前,我们对数据集执行特征缩放。我们把数据集做成 numpy 数组。我们使用最小最大缩放器进行预处理。我们拟合转换特征训练数据并转换特征测试数据。

4 层深度神经网络

具有 4 层的深度神经网络具有 2 个隐含层,每个隐含层具有 80 个神经元。在两个隐藏层之间以及第二个隐藏层和输出层之间添加了下降层,以防止过拟合。Binary_crossentropy用作损失函数,更新方法为ADAM. The number of Epochs is 500.

对于我们的数据,输入层具有 242 的维度,2 个隐藏层具有整流器作为其激活函数,每个层具有 80 个神经元。输出层具有 sigmoid 激活函数,因为我们正在进行二元分类。深度神经网络采用 Adam 优化器、二元交叉熵损失函数编译,评价指标为精度。

Confusion Matrix for Deep neural network with 4 layers

Summary of Deep neural network model with 4 layers summary

5 层深度神经网络

具有 5 层的深度神经网络具有 3 个隐含层,第一和第二隐含层具有 80 个神经元,第三隐含层具有 40 个神经元。在隐层之间和第三隐层与输出层之间增加了剔除层,在第三隐层与输出层之间插入了批量归一化层以防止过拟合。The number of Epochs is 400.

对于我们的数据,输入层具有 242 的维度,3 个隐藏层具有整流器作为其激活函数,第一和第二隐藏层具有 80 个神经元,第三隐藏层具有 40 个神经元。输出层具有 sigmoid 激活函数,因为我们正在进行二元分类。深度神经网络采用 Adam 优化器、二元交叉熵损失函数编译,评价指标为精度。

Confusion Matrix for Deep neural network with 5 layers

Summary of Deep neural network model with 5 layers

模型评估

通过准确度、混淆矩阵、精确度、召回率、真阴性率(TNR)、假发现率(FDR)、增益图、提升图、K-S 图、ROC-AUC 图评估分类模型。在对上述技术的性能进行比较后,的性能最好,其次是深度学习神经网络分类器,再次是随机森林。

我们使用 Python 内置的持久性模型(pickle 或 dill)将模型保存到磁盘,并使用该模型对新数据进行预测。

Python →机器学习/深度学习模型-> pickle 模型-> flask →在 Heroku 上部署

Flask 是 Python 的一个“微”框架。之所以称之为微框架,是因为他们希望保持核心简单但可扩展。虽然一开始会有些困惑,但使用 Jinja2 模板在 Flask 上建立一个网站还是相对容易的。

现在我们创建一个简单的 flask 应用程序。flask 应用程序由两个主要组件组成:python 应用程序(app.py)和 HTML 模板。虽然我们可以从 python 文件本身返回 HTML 代码,但是在 python 文件中将整个 HTML 编码为一个字符串会很麻烦。模板前来救援!

Heroku 是一个云平台即服务(PaaS ),支持多种编程语言。

点击查看应用的工作版本。本教程的代码可以在 Github 上找到。关于模型性能的更多信息在 GitHub 知识库的 pdf 报告中。

最后的话

我们基于 python ML 库制作了一个简单的基于 web 的预测应用程序。要查看默认风险应用程序的完整工作版本,请查看在 Heroku 云平台上部署为 Web 应用程序(Restful API)的最终解决方案,演示链接:http://default-risk.herokuapp.com

关于我:我热衷于通过使用数据科学和机器学习技术解释数据来推动和帮助有洞察力的商业决策。我的热情是用数据解决复杂的现实世界的问题。在 Linkedin 上与我联系。

查看我的作品集jayborkar . github . io。

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

Github:https://github.com/jayborkar

参考:

  1. AE Khan dani、AJ Kim 和 AW Lo 通过机器学习算法建立的消费者信贷风险模型研究论文
  2. Github 资源库
  3. 在生产中将机器学习模型部署为 API(使用 Flask)

数据艺术的防御:Python v/s R

原文:https://towardsdatascience.com/defence-against-the-data-arts-python-v-s-r-5f4529c1d90f?source=collection_archive---------7-----------------------

场景(哈利波特参考)- 邓布利多挥舞着一根带有抽象蟒蛇芯的魔杖,格林德沃使用一根带有经典 R 芯的魔杖。两者同样熟练。权杖核心会在数据世界中产生权力差异吗???让我们找出答案。

在我们开始防御数据艺术历史上最伟大的决斗之前,让我们检查一下他们各自的魔杖…

一边是 2 时代世界魔杖冠军(2007&2010)巨蟒。根据 TIOBE 指数,它目前排名第第第四,比 2017 年上升了一位。它是由一个名叫吉多·范·罗苏姆 (1991)的著名巫师创建的,以支持使用多种编程范例的魅力、可读性和支持高层次的抽象。

对于那些对巨蟒魔杖有兴趣的人->https://en.wikipedia.org/wiki/Zen_of_Python

另一个强大的元老权杖 R 在 TIOBE 指数中上升了 3 位,并在 2018 年 4 月占据了第 12 位。它是由两位巫师罗斯·伊哈卡&罗伯特·绅士创造的,唯一的目的是赢得一场统计决斗。它为统计计算和图形提供了魅力。它的特殊魅力使它能够执行统计建模、经典统计测试、时间序列分析、分类、聚类和图形技术。

第一轮:粉丝群&科学界

你基本上是跟着人群走。

当我在本文中谈到 Python 时,并不是指作为一个整体的通用语言能力(这是不公平的),而是指包的子集(numpy、scipy 等)..)构建,以满足大数据时代日益增长的统计问题的需求。

根据 TIOBE 评级,Python 比 R 更受欢迎。

让 python 更受欢迎的是它的通用编程风格(Python 之禅)更快的学习曲线,而最重要的原因是过量的高级包和机器框架&深度学习(SK-learn、Keras、Pytorch、Tensorflow 等)。您执行数据分析的最终目标是做出决策,因此,如果决策制定(DM)工具本身是用 Python 编写的,您会更喜欢用同样的语言来完成分析部分,因为这样将来更容易与 DM 算法集成。r 也有等价的框架,但是不太为人所知。

在这两种情况下,科学界都是好的。但是,受欢迎程度再次让我们像羊群一样涌向蟒蛇那一边。Python 赢了!!!

credits:xkcd

第二轮:初学者的运气

正如我前面提到的,Python 非常直观,而 as R 的学习曲线非常陡峭。我第一次使用 python 时,我喜欢上了它。一切都很容易。我以为我可以用它征服软件世界。但是我太天真了。下学期的 C 课让我看到了自己的位置。(谁刚学完 Python 就教 C?).

即使我碰到它的时候已经有了比较好的编程知识,R 还是很麻烦。一开始,编写一段代码(检查包和不同的构造是一件痛苦的事)所花的时间是编写一段同等 Python 代码所花时间的三倍。随着你熟悉 R 编码风格,它会变得更好,但我仍然因为 R 中的非直观构造而感到痛苦。这可能是因为我对 python 上瘾了。****

Ipython notebook 让编码更干净更简单(magic cmds)。它支持 R 和 Python 内核。

尽管如此,我还是倾向于 Python。

第三轮:美女与野兽

任何使用过 ggplot2(& others)和 matplotlib.pyplot 的人可能都会同意我的说法,与前者相比,后者是一只粗糙的野兽。还有其他 Python 可视化包,比如 seaborn,它们很好,但是没有达到 R 的标准。

R 横扫本轮!!!

第四轮:数据分析能力

如果我们谈论统计计算和建模能力的话,R 显然优于 Python。它有更多经过验证的统计计算包,还没有用 Python 实现。Python 每小时都在缩小差距。

那么问题就来了——R 是不是一种即将消亡的语言?

不,这不是真的。 R 是有学问的人的语言 - 统计学家、医学研究人员&生命科学研究人员等发现 R 是比 python 更好的工具。原因可以认为是优越的统计软件包和习惯的结果。

这个问题主要出现在我们的脑海中,因为围绕深度学习和神经网络产生的蓬勃发展的宣传,其中 Python 主导了该领域,并产生了一种感觉,即 R 正在失去其在该领域的地位,因为深度学习与数据科学密切相关(&分析)。这就像一个诱饵效果。

我在脸书(AI & DL 集团)进行了一次民意调查,以验证上述推理,结果统计数据与推理一致。

因此,R 在这一回合中设法战胜了 python。

决定谁是赢家?

就像巫师们自己一样(在著名的决斗——哈利·波特引用之前),没有明确的证据表明一个比另一个优越。

像一个外交政治家一样,我会说,如果你的目标是经典的统计分析,那么用 R,如果你的目标是机器学习,那么用 Python,因为支持更好,编码更容易。

但是我相信对于一个数据科学和 ML 爱好者来说,成为两个行业的杰克是很好的。

我试图融入虚构的元素,给这篇文章带来幽默。希望你喜欢它。如果我在上课时间写这篇文章时,遗漏了什么重要的特征,请评论。

传递简单的数据

原文:https://towardsdatascience.com/delivering-simple-data-b5db062edf49?source=collection_archive---------9-----------------------

Photo by Kelly Sikkema on Unsplash

这一课永远改变了我对如何交付数据的看法。

我一直喜欢信息,信息越多越好。从我十几岁开始,有了我的第一台电脑和最近的互联网接入,我总是喜欢手头有数据。这就是我从小喜欢玩模拟电脑游戏的原因,比如《席德·梅尔文明》、《模拟城市》、《主题公园》、《披萨大亨》、《帝国时代》和《命令与征服》。瞄准射击很有趣,尤其是前 2-3 个小时,但让我整晚睡不着的游戏是策略类的。在所有这些网站中,数据无处不在。例如,文明给了我关于我的城市生产的一切信息,公民有多幸福,生产能力,战争单位,技术输出能力,图表和图表,以帮助规划完美的战略和游戏。

“A man working on a computer while wearing red laser colored headphones” by Mark Cruz on Unsplash

我尽可能快地将这种思维方式引入商业智能。我想给我的客户提供过量的数据,这样他们也能体验到我玩游戏时的兴奋感。对我来说,BI 把世界变成了游戏,在游戏中我可以测量正在发生的一切。当我有信息要处理时,我的头脑总是充满了各种可能性。想法和策略来得很快,我可以将信息关联起来,看看什么可以做,什么不可以做。然而,数据过载并不适用于所有人。

随着我职业生涯的进展,很明显世界上的其他人看待数据的方式和我不一样。人们喜欢人们喜欢的东西,数据可能是有价值的,但你必须让它符合目的,以帮助它变得有意义。我发现最好的方法是简化,直到你确切知道人们真正需要什么才能前进。前进是这里的关键。向前发展意味着你提供的数据变成了同样的行动并产生了价值。

为了使我的观点更清楚,我喜欢用汽车仪表板作为例子。

“A shot of the front interior of a car against the blurred traffic in the background.” by Mark Cruz on Unsplash

如果你想一想,一辆汽车可以为司机产生大量的数据。你可以驾驶数以百万计的指标,告诉你有多好,汽车性能如何。然而,人们只关心三件事,速度,煤气表和是否有红灯闪烁。就是这样!人们想知道他们有多快,是否能到达他们想去的地方,以及是否一切运转良好。简单直接。如果其中任何一项显示有问题,就会立即采取行动/做出决定。

想想你在工作中已经提交的报告。我敢打赌,总有一两个表格/饼图吸引了 80%的注意力,而报告的其余部分只是“值得拥有”。这种事在我身上发生过太多次了。我总是喜欢做所有的事情,刚开始的时候,我会因为人们没有看到我想要了解的全貌而感到沮丧。后来,我想通了,我才是那个不了解全局的人。少即是多,简单产生行动,这是你应该争取的。

“A person holding a clapper board in a desert” by Jakob Owens on Unsplash

汽车仪表板告诉我们什么

简单来说,试着从汽车仪表板上吸取教训。专注于显示公司是否有“气”的指标,换句话说,是底线。试着理解哪些指标真正显示了公司的计划正在被执行,并且是以什么样的“速度”执行的。公司是有目标的,但是目标实现了吗?如果没有,则可能存在速度问题。最后,如果有什么不对劲,红灯就会闪烁。公司要正常运转,总有一些关键的运营方面需要顺利运作。监控这些问题,确保每个人都能看到它们是否需要修复。

当我在餐馆工作时,底线问题是老板最想知道的,也是最后一个。我试图实施一些运营指标,但大多数人关心的只是底线。

“Hand holds a plate of steak, soft boiled egg, and tomatoes” by Eduardo Roda Lopes on Unsplash

他们知道,如果他们没有达到预定的每日收入,整个运营就不会盈利。他们关注的是这个数字,所以每天第一件事就是交付它成为我们的首要任务。一旦他们拥有了,他们就快乐了。我时不时地试图提供更多的数据,但他们总是以谈论菜单上的新菜而告终。

Photo by chuttersnap on Unsplash

季度 KPI 至关重要,因为它们可以在很短的时间内显示出战略是否处于正确的位置。这种信息很容易被运营、战术团队和战略领导理解。如果做得正确,KPI 必须有一个度量标准,并且能够被不断地测量。我曾与非常关注这一点的汽车经销商合作过。他们想结交老客户,这些客户是来购买新车的。每辆行驶超过 50,000 公里的汽车都会得到一份特别的奖金。他们希望转换至少 15%的具有这种特征的客户。一旦指标清晰,我们就能显示是否达到目标,测量就变得简单了。在前两个季度,他们没有完成交易,但到了第三季度,事情开始变得可行,到那年年底,他们有了一个整合 CRM 工作的业务案例,以吸引更多的客户前来寻求服务和更积极的折扣。

“A smiling man holding a disc grinder” by David Siglin on Unsplash

货架上有些产品的缺失确实会影响一家店的经营。对于零售商来说,这是重要的一课。有些产品不仅能完成销售,也是交叉销售策略的关键。在建筑零售行业工作时,我看到了这种情况,并撰写了一份专注于库存管理的特别报告。他们有一个系统,但它侧重于管理库存,而不是销售。由于整合问题,销售和下架之间存在延迟。一旦整合到一份报告中,很明显,供应部门的人必须不断地关注销售情况,这样才不会出现中断。这成了报告中的一个小红旗,解决了一个巨大的问题。

在传递情报时,您不需要开发数百个表格、图表和报告。你只需要真正了解人们想做什么,并尝试找到简单的有用信息。

彻底实现深度计算机视觉的大众化——tensor cam

原文:https://towardsdatascience.com/democratizing-deep-computer-vision-for-once-and-for-all-tensorcam-3f94b09546eb?source=collection_archive---------4-----------------------

TensorCam 是来改变我们的生活的!在这篇文章中,我将描述我迄今为止见过的最强大的易于使用的深度学习相机。而且它对开发者开放,有了这款相机,所有技能水平的人都可以在不到 5 分钟的时间内开始深度学习。

https://www.wired.com/story/your-instagram-dogs-and-cats-are-training-facebooks-ai/

是时候在计算机视觉和深度学习的世界里有一个新的发展了,这就是 Deep Cognition 的人们为我们推出的东西。

如果你想练习你的深度学习技能,这是一个很好的开始,有了这个相机,你可以在几分钟内建立自己的计算机视觉应用程序。

这是一个很棒的系统介绍视频:

https://www.kickstarter.com/projects/deepconition/tensorcam-worlds-first-ai-camera-with-ptz-for-deve

最棒的部分是它完全连接了深度学习工作室(DLS),在那里你可以从一个简单而强大的 GUI 中进行选择,在那里你可以拖放神经网络并使用 AutoML 创建深度学习模型,到一个完全自主的 IDE,在那里你可以编码并与你最喜欢的库进行交互。

DLS 简化并加速了在 TensorFlow 和 MXNet 等流行框架中使用深度学习的过程。您将能够从深度学习工作室向 TensorCam 推送您的深度学习模型。而且 TensorCam 会自带全软件 SDK。

这将是您的工作流程:

如果你想更多地了解 DLS,看看这个:

[## 深度认知的视频漫游

大家好!在本文中,我将与您分享几个视频,带您浏览深度认知的平台…

towardsdatascience.com](/a-video-walkthrough-of-deep-cognition-fd0ca59d2f76)

以及 Rajat 的这篇伟大的文章:

[## 深度学习工作室让深度学习变得简单——完整指南

没有编程的深度学习可能吗?

towardsdatascience.com](/deep-learning-made-easy-with-deep-learning-studio-complete-guide-a5c5ae58a771)

特点:

  • 内置的 NLP 技术,这将允许您开发基于自定义语言的通知。这些通知将通过智能家居设备传递,如 Alexa
  • 内置最先进的深度学习芯片,这将允许你以惊人的 2.4 Terra-OPS 计算性能运行深度学习模型。
  • 它与深度学习工作室(DLS) 的紧密集成使其高度灵活和可定制,这将允许您在几个小时内运行自己的深度学习模型。

在这里你可以看到它是如何与 Alexa 一起工作的:

您可以创建一个货架库存监控模型:

当您的宝宝移动时,可以开始记录的模型(是的,您现在就可以这样做):

还有很多:)

与其他相机的比较

他们的深度学习芯片每秒 2.4 万亿次运算(TOPS),也是目前市场上最高的,如您在对比中所见:

不要误会我的意思,DeepLens 和谷歌视觉套件也很棒,我过去实际上用过谷歌视觉套件,我唯一希望它更容易的部分是编程和界面。我的意思是,你必须在 RaspberryPi 中拥有一切,然后创建一个模型,训练它,并希望它能在那里运行。另外,虽然相机非常好,但它没有移动。

这与 TensorCam 有很大的不同,因为它带有 PTZ ( 平移-倾斜-变焦),这意味着相机能够远程控制方向和变焦。这对于许多应用程序来说是非常棒和必要的。

这里有一个更深入的对比:

用 TensorCam 可以构建什么?

您可以从 TensorCam 示例项目开始,其中涵盖了一些最流行的计算机视觉用例。随着你的技能和想法的发展,你可以使用 Deep Learning Studio 的云或桌面版本来建立定制的深度学习模型。作为一名开发人员,以下是一些您可以在 TensorCam 上构建和部署的示例,只需编写最少的代码或无需编写代码:

如果你想了解更多的想法,请点击这里:

[## DIY 深度学习项目

受阿克谢·巴哈杜尔伟大工作的启发,在这篇文章中你将看到一些应用计算机视觉和…

towardsdatascience.com](/diy-deep-learning-projects-c2e0fac3274f)

在这里,您可以看到员工跟踪系统的完整视频示例(这样您就知道谁真正出现了):

哦,你还有夜视能力,如果你想知道:

KickStarter 活动

现在是最重要的部分,如果你很了不起(你应该),这些人需要我们的帮助来资助他们的项目。这是我第一次在 KickStarter 活动中看到这样的东西,所以请确保进入网页并支持该项目:

https://www . kickstarter . com/projects/deep conition/tensor cam-worlds-first-ai-camera-with-ptz-for-deve

如果你不能做到这一点,请告诉你的朋友和公司,如果你能马上作出承诺,你可以得到很大的折扣。创作者的最后一句话:

我们预计 TensorCam 将于 2019 年 3 月准时交付。我们正在结束主要功能的产品开发阶段,但我们仍然希望听到 Kickstarter 支持者的伟大想法,关于我们可以包括的一些额外功能(只要不影响交付日期)。我们已经为相机和 AI 板找到了可靠的制造合作伙伴,但即使有最好的制造流程设置,也可能会发生意想不到的问题。物流问题也正在得到解决,以确保顺利交货时,我们已经超过了我们的目标。

感谢你阅读这篇文章。我希望你在这里找到了一些有趣的东西:)如果你有问题,请在 Twitter 上关注我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

和 LinkedIn:

[## favio vázquez——science ia y Datos | LinkedIn 创始人

查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 16 个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/faviovazquez/)

那里见:)

揭秘:人工智能,机器学习,深度学习

原文:https://towardsdatascience.com/demystified-ai-machine-learning-deep-learning-c5259d38678e?source=collection_archive---------10-----------------------

很多人把人工智能(AI)、机器学习(ML)、深度学习(DL)这几个词当成同义词。这实际上与事实相差甚远,今天我们来揭开这些误解的神秘面纱。

AI、ML、DL 是各种数据分析模型和算法在不同行业各种用例的实际应用。虽然这些工具还不能做出道德选择或作为有意识的机器,但它们有潜力为任何企业创造更多价值。这是通过发现以前看不见的模式和预测某些行动的可能结果来实现的。我们希望这篇文章将提供对人工智能、ML 和 DL 能力的更好理解,并将成为你迈向人工智能驱动的数据分析之旅的起点。

沿着这条路的第一步是通过专家系统完成的,这是第一次尝试将数据分析的过程编码。专家解释了一些领域专业知识的规则,这些规则后来被编入规则引擎并用于回答问题。然而,这种结构只能根据这些预定义的规则工作,并且不能随着时间的推移而改进。随着新事实的增加,保持规则引擎的更新也是一项麻烦且费时的工作。然而,专家系统在医疗保健和金融领域仍然非常普遍。

机器学习的下一步是当现代计算机 CPU 架构被引入时,随后是图形处理器单元(GPU)。GPU 的核心优势在于,由于容纳了数千个较小的内核,它们能够进行并行数据处理,而不是在几个较大的 CPU 内核中进行串行处理。这项技术的进一步发展和所有数据密集型项目向云的过渡导致了人工智能开发的巨大繁荣。

此外,使用大数据工具,如 Hadoop、Spark、Flink、Map Reduce 和 Cassandra 确保企业最大限度地利用其大数据能力。以前,数据存储在某个地方,必须上传到其他地方进行处理。这导致数据传输速度成为瓶颈,而且非常昂贵。现代的方法意味着将数据存储在云中,并直接处理数据,而不是相反。这就划算多了,更别说快多了。

什么是人工智能:伟大的东西,只是还没有工作

我们已经发表了一篇文章解释说 AI 不会以有意识机器人的形式出现。事实上,自从引入了图灵测试,人工智能就成了一个总括术语和时髦词汇。科学家们努力在机器中创造智力,但这不应该是人类智力的复制品。

AI 是一组随着时间的推移而学习和进化的算法,在处理它们的任务时变得越来越好,但却无法进行道德选择(不知道什么是好什么是坏)或理解艺术的价值,或从音乐中获得审美愉悦。

事实上,人工智能现在更多的是人类头脑中一个新领域的代号。数学理论的每一个新方面都获得了实际的实现,不再是人工智能。MapR(企业 Hadoop 供应商)的首席应用架构师 Ted Dunning 博士描述了这一现象,他说“当某些东西不起作用时——我们称之为 AI。当它开始正常工作时,我们称之为其他东西

什么是机器学习:人工智能应用于大数据分析

机器学习是 20 世纪 80 年代左右蓬勃发展的人工智能技术的子集。其主要应用是不断提升的大数据分析质量和精度。ML 算法在历史数据中发现模式,训练的 ML 模型遵循这些模式来预测新数据中有价值的见解。

最大似然学习领域有两个主要的子域:监督学习和非监督学习。

  • 监督学习使用人类创建的数据标签(收入和输出数据都提供给算法)来构建数据。这个类别中的 ML 模型包括随机决策森林、朴素贝叶斯算法、SVM 和线性或逻辑回归训练。
  • 无监督学习使用未标记的数据,ML 模型必须按照自己的速度训练自己,或者根据反馈最大化回报。

机器学习主要用于数据分类,并广泛用于金融和银行业,以打击欺诈和风险管理。我们已经描述了银行业中机器学习的用例或者各种业务如何使用机器学习来改善金融服务。

深度学习:多层神经网络

深度学习算法使用多层不同权重的节点,即所谓的深度神经网络或 DNNs。有输入和输出节点,它们之间至少有 10 层。通过调整每个 DNN 节点的逻辑权重,数据科学家可以影响结果,从而训练模型以达到大规模所需的结果。由于数据大规模并行处理的发展和强大 GPU 的使用,数据科学家现在可以使用数千层的 DNNs。

逻辑权重的每次重新调整都会使模型更好地理解所需的对象特征。这个过程的优点是,在开始时可以不定义特征,并且模型将随着时间的推移学会自己识别最佳结果。

dnn 是深度学习中使用最广泛但不是唯一的 ML 算法类型。

我们已经解释了深度学习如何真正工作,以及涵盖了 2017 年在文本和语音应用、机器感知和 OCR 、增强学习和机器人运动应用等领域取得的多项深度学习进展。这些应用扰乱并改善了医疗保健、金融和零售行业,以及生活中的许多其他领域。

人工智能技术演进展望

因此,在过去的十年里,人工智能应用的有效性有了显著的提高。尽管深蓝在 20 多年前击败了加里·卡斯帕罗夫,但下一次这种类型的胜利只是最近才发生,当时谷歌 DeepMind 的 AlphaGo 在 2016 年战胜了现役围棋冠军 Lee Sedol 。这并不意味着人工智能的发展停滞不前——恰恰相反,它蓬勃发展。

从 20 世纪 50 年代初的科幻刺激和有意识机器人的梦想,我们开始意识到人工智能最适合用于大规模自动化费力耗时的任务,而不是模仿人脑的功能。自然智能和人工智能之间的某些相似之处仍然存在,比如英特尔的自我学习芯片 Loihi。然而,最近的技术进步巩固了采用最大似然算法进行大规模数据分析的趋势。

关于人工智能、机器学习和深度学习的最终想法

深度学习是 AI 进化的方向吗?我们认为不会,因为在技术的前沿不断出现令人兴奋的新应用,以及在以前没有数字化的行业中应用 ML 和 DL 的新可能性。随着越来越多的企业完成云转型,越来越多的在大数据分析中利用人工智能算法的前景向他们展现出来。

在伦敦举行的 AWS 2018 峰会期间,亚马逊首席技术官沃纳·威格尔博士透露,AWS 将集中精力为其产品提供人工智能功能和服务,以进一步增强其客户的价值交付。这导致在最近的 AWS re:Invent 2018 周期间出现了多个 AI/ML/DL 版本、公告和功能。

微软也是如此,在 R&D 有一个 8000 人的部门,专门致力于为 Azure 开发人工智能和人工智能服务。现在人工智能肯定比以往任何时候都热,并且在未来会变得更加有利可图和有用。

您是否已经在数据分析系统中实施了 ML 模型?你愿意做吗?如果是这样的话— IT Svit 可以帮助!

原载于 2018 年 12 月 20 日itsvit.com

揭开“混乱矩阵”混乱的神秘面纱

原文:https://towardsdatascience.com/demystifying-confusion-matrix-confusion-9e82201592fd?source=collection_archive---------4-----------------------

如果你对混淆矩阵感到困惑,那么我希望这篇文章可以帮助你理解它!快乐阅读。

我们将使用 UCI 钞票认证数据集来揭开混淆矩阵背后的混乱。我们将预测和评估我们的模型,并在此过程中发展我们的概念理解。也将在需要的地方提供进一步阅读的链接。

了解数据

数据集包含钞票 400x400 像素小波变换图像的属性,可以在这里找到。建议读者下载数据集并跟随学习。进一步参考,可以在这里找到 Kaggle 笔记本。

*#Skipping the necessary Libraries import* **#Reading the Data File** df = pd.read_csv('../input/BankNote_Authentication.csv')
df.head(5)

Sample Data (using Head)

**#To check if the data is equally balanced between the target classes** df['class'].value_counts()

Target Class is balanced enough

建立模型

将数据分为训练集和测试集,我们将在训练集上训练我们的模型,评估将在测试集上执行,由于简单和缺乏足够的数据,我们在这里跳过验证集。总的来说数据分为三组训练、测试和验证,这里阅读更多。

**#Defining features and target variable**
y = df['class'] #target variable we want to predict 
X = df.drop(columns = ['class']) #set of required features, in this case all**#Splitting the data into train and test set** 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)

接下来,我们将为我们的预测建立一个简单的逻辑回归模型。

**#Predicting using Logistic Regression for Binary classification** 
from sklearn.linear_model import LogisticRegression
LR = LogisticRegression()
LR.fit(X_train,y_train) *#fitting the model* 
y_pred = LR.predict(X_test) *#prediction*

模型评估

我们来绘制最混乱的混淆矩阵?开个玩笑,让我们有一个简单的混淆矩阵( Scikit-learn 文档用于下面的代码)。

Confusion Matrix for Binary Classification

**#Evaluation of Model - Confusion Matrix Plot**
def plot_confusion_matrix(cm, classes,
                          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`.*
 *"""*
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    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()

**# Compute confusion matrix**
cnf_matrix = confusion_matrix(y_test, y_pred)
np.set_printoptions(precision=2)

**# Plot non-normalized confusion matrix**
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=['Forged','Authorized'],
                      title='Confusion matrix, without normalization')

Confusion Matrix for the Binary Classification performed

**#extracting true_positives, false_positives, true_negatives, false_negatives**
tn, fp, fn, tp = confusion_matrix(y_test, y_pred).ravel()
print("True Negatives: ",tn)
print("False Positives: ",fp)
print("False Negatives: ",fn)
print("True Positives: ",tp)

我们的模型有多精确?

**#Accuracy**
Accuracy = (tn+tp)*100/(tp+tn+fp+fn) 
print("Accuracy {:0.2f}%:",.format(Accuracy))

准确性重要吗?

不总是这样,有时这可能不是正确的衡量标准,尤其是当你的目标阶层不平衡时(数据是有偏差的)。然后,您可能会考虑其他指标,如精确度、召回率、F 分数(组合指标),但在深入讨论之前,让我们先退后一步,理解构成这些指标基础的术语。

一些基本术语

真阳性 —被预测为阳性(在我们的场景中是认证的钞票)并且实际上是阳性(即属于阳性‘授权’类)的标签。

真阴性 —被预测为阴性(在我们的场景中是伪造的钞票)而实际上是阴性(即属于阴性‘伪造’类)的标签。

假阳性 —被预测为阳性,但实际上是阴性的标签,或者简单地说,被我们的模型错误地预测为真实,但实际上是伪造的票据。在假设检验中,它也被称为 1 型错误或对零假设的不正确拒绝,参考此阅读更多关于假设检验的信息。

假阴性 —预测为阴性,但实际为阳性的标签(预测为伪造的真实票据)。这也被称为第二类错误,它导致拒绝零假设的失败。

现在让我们看看每个机器学习从业者应该知道的最常见的评估指标!

Mathematical Definitions (Formulas)

指标超出准确度

精度

它是“精确性”,即模型只返回相关实例的能力。如果您的用例/问题陈述涉及最小化误报,即在当前场景中,如果您不希望伪造的纸币被模型标记为真实的,那么精确度是您需要的。

**#Precision** 
Precision = tp/(tp+fp) 
print("Precision {:0.2f}".format(Precision))

Precision is about Repeatability & Consistency

召回

它是“完整性”,模型识别所有相关实例的能力,真正的阳性率,也称为敏感度。在目前的情况下,如果你的重点是最大限度地减少假阴性,也就是说,你不会把真钞错误地归类为伪钞,那么召回就能帮你一把。

**#Recall** 
Recall = tp/(tp+fn) 
print("Recall {:0.2f}".format(Recall))

F1 测量

精确度和召回率的调和平均值,用于表示精确度和召回率之间的平衡,提供相等的权重,范围从 0 到 1。F1 分数在 1 时达到最佳值(完美的精确度和召回率),在 0 时达到最差值,在此阅读更多。

**#F1 Score**
f1 = (2*Precision*Recall)/(Precision + Recall)
print("F1 Score {:0.2f}".format(f1))

F-beta 测量

这是 F 值的一般形式——β0.5 和 2 通常用作度量,0.5 表示倾向于精确,而 2 表示倾向于回忆,给予它两倍于精确的权重。

**#F-beta score calculation**
def fbeta(precision, recall, beta):
    return ((1+pow(beta,2))*precision*recall)/(pow(beta,2)*precision + recall)

f2 = fbeta(Precision, Recall, 2)
f0_5 = fbeta(Precision, Recall, 0.5)

print("F2 {:0.2f}".format(f2))
print("\nF0.5 {:0.2f}".format(f0_5))

特异性

它也被称为“真阴性率”(正确识别的实际阴性的比例),即数据包含的真阴性越多,其特异性就越高。

**#Specificity** 
Specificity = tn/(tn+fp)
print("Specificity {:0.2f}".format(Specificity))

ROC(受试者工作特性曲线)

不同分类阈值下“真阳性率”(灵敏度/召回率)与“假阳性率”(1-特异性)的关系图。

ROC 曲线下面积(AUC)测量曲线下的整个二维面积。这是一个衡量参数如何区分两个诊断组的指标。通常用作分类模型质量的度量。

随机分类器的曲线下面积为 0.5,而完美分类器的 AUC 等于 1。

**#ROC**
import scikitplot as skplt #to make things easy
y_pred_proba = LR.predict_proba(X_test)
skplt.metrics.plot_roc_curve(y_test, y_pred_proba)
plt.show()

结论

由于选择用来说明混淆矩阵和相关指标的使用的问题很简单,您可以找到更高水平(98%或以上)的每个值,无论是精确度、召回率还是准确度;通常情况下不会这样,您将需要关于数据的领域知识来在一个度量或另一个度量(通常是度量的组合)之间进行选择。

例如:如果是关于发现“你邮箱里的垃圾邮件”,你的模型的高精度将是非常重要的(因为你不希望这个邮件被贴上垃圾邮件的标签),它将告诉我们被我们归类为垃圾邮件的邮件中有多少是垃圾邮件。真阳性(分类为垃圾邮件的单词,实际上是垃圾邮件)与所有阳性(分类为垃圾邮件的所有单词,无论其分类是否正确)的比率。在欺诈检测中,您可能希望您的回忆更高,以便您可以正确地分类/识别欺诈,即使您没有将一些非欺诈活动分类为欺诈,也不会造成任何重大损失。

揭秘卷积神经网络

原文:https://towardsdatascience.com/demystifying-convolutional-neural-networks-384785791596?source=collection_archive---------8-----------------------

Convolutional Neural Networks

简史

在过去的十年中,计算机视觉领域取得的进步确实令人惊叹,前所未有。机器现在可以识别视频中的图像和帧,准确率(98%)超过人类(97%)。这一惊人壮举背后的机械装置是受人类大脑功能的启发。

当时,神经学家正在对猫进行实验,他们发现图像的相似部分会导致猫大脑的相似部分变得活跃。换句话说,当猫看着圆圈时,大脑中的阿尔法区被激活。当它看着正方形时,大脑中的β区被激活。他们的发现得出结论,动物的大脑包含一个对图像的特定特征做出反应的神经元区域,即它们通过大脑中神经元的分层结构来感知环境。每一幅图像在进入大脑之前都要经过某种特征提取器。

受大脑功能的启发,数学家们囤积了一个系统来模拟不同组的神经元对图像的不同方面放电,并相互交流以形成更大的图像。

特征提取器

他们将一组被激活的神经元的想法具体化,提供特定的输入,成为多维矩阵的数学概念,代表特定特征集的检测器,也称为过滤器内核。每个这样的过滤器将用于检测图像中特定的东西,例如用于检测边缘的过滤器。然后,这些学习到的特征将通过另一组设计用于检测更高级特征的过滤器,即眼睛、鼻子等

Convolution of an image with Laplacian filter to detect edges

在数学上,我们将在给定输入图像(表示为像素强度矩阵)之间执行卷积运算,并进行滤波以产生所谓的特征图。该特征图将作为另一层过滤器的输入。

为什么卷积?

卷积是一个过程,在这个过程中,网络试图通过参考它在过去学习到的内容来标记输入信号。如果输入信号看起来像它以前见过的先前的猫图像,则“猫”参考信号将与输入信号卷积或混合到输入信号中。产生的输出信号然后被传递到下一层(这里,输入信号是根据 RGB 像素强度的输入图像的 3d 表示,而“猫”参考信号是用于识别猫的核心学习信号)。

Convolution operation of image and filter. Source

卷积运算的一个很好的性质是它是跨国不变量。这意味着每个卷积滤波器代表特定的特征集,例如眼睛、耳朵等。这也是 CNN 算法擅长的工作,它可以学习哪个特征集包含了结果参考,例如 cat。输出信号强度不取决于特征的位置,而仅仅取决于特征是否存在。因此,一只猫可以坐在不同的位置,CNN 算法仍然能够识别它。

联营

通过追踪大脑生物功能的轨迹,他们能够建立提取特征所需的数学装置。然而,在了解了为了跟踪复杂的几何形状而需要分析的级别和特征的总数后,他们意识到他们的内存不足以容纳所有这些数据。甚至处理所有这些所需的计算能力也会随着功能的增加而呈指数级增长。很快,他们想出了一种被称为池的技术来解决这个问题。它的核心思想非常简单。

如果一个区域包含强烈表达的特征,我们可以避免搜索该区域的其他特征。

Demonstration of max pooling

这种池操作,除了节省额外的内存和计算能力要求,还有助于消除图像中的噪声。

全连接层

到目前为止还不错,但是如果一个网络最终只能检测图像中的一组特征,那么它有什么用呢?我们需要一种方法,让网络能够将给定的图像分类到一些类别中。这就是可以利用传统神经网络设置的地方。特别是,从早期图层检测到的要素地图到用于分类的标注数量,我们可以拥有一个完全连通的图层。最后一层将为输出类别中的每个类别分配概率。基于这些输出概率,我们可以最终将图像分类到输出类别之一。

Fully Connected Layer. Source

最终建筑

剩下的唯一事情是将所有这些学到的概念结合到一个单一的框架中,我们称之为卷积神经网络又名 CNN 。本质上,CNN 由一系列卷积层组成,这些卷积层可选地与汇集层结合以生成特征图,该特征图然后被馈送到一堆完全连接的层以产生分类概率。反向传播输出的错误,我们将能够训练这个设置来生成准确的结果。

现在,功能性的观点被恰当地奠定,让我们稍微深入 CNN 的操作方面。

卷积神经网络

Convolution layer

卷积层是 CNN 的主要组成部分。每个这样的层由一组独立的过滤器组成,每个过滤器在给定的图像中寻找不同的特征集。

Convolution operation. Source

在数学上,我们采用固定大小的过滤器,并将其滑过完整的图像,在过滤器和输入图像块之间进行点积。这种点积的结果将是一个标量,它将进入结果特征图。然后,我们向右滑动过滤器,执行相同的操作,将结果添加到特征映射中。在用滤波器卷积完整的图像之后,我们最终得到一个表示不同特征集的特征图,该特征集再次作为进一步层的输入。

大步走

滤波器移动的量是跨距。在上面的图像中,我们用因子 1 滑动过滤器。这可能不是我们一直需要的。使用大于 1 的跨距背后的直觉是相邻像素是强相关的(特别是在最低层中),因此通过应用适当的跨距来减小输出的大小是有意义的。但是,大步长可能会导致大量信息丢失。所以,我们在选择步幅的时候一定要小心。

Example with a stride of 2. Source

填充

Padding of one layer. Source

步幅的一个不良影响是,随着我们一次又一次地执行卷积,特征图的大小随之减小。这可能不是我们想要的结果,因为这里的收缩也意味着信息丢失。要了解为什么会出现这种情况,请注意过滤器应用于中间单元格和角落单元格的次数差异。显然,没有什么特别的原因,来自中间细胞的信息比来自边缘细胞的信息更重要。为了保留先前层的有用信息,我们可以用零层包围给定的矩阵。

参数共享

当我们已经有一个很好的深度神经网络设置时,为什么还要 CNN 呢?有趣的是,如果我们使用深度神经网络进行图像分类,每一层的参数数量将是 CNN 的数千倍。

Parameter sharing in CNN

请通过你的评论让我知道这篇文章可以容纳的任何修改/改进。

基于 Python 的加密货币价格预测

原文:https://towardsdatascience.com/demystifying-cryptocurrency-price-prediction-5fb2b504a110?source=collection_archive---------3-----------------------

Photo by André François McKenzie on Unsplash

自从比特币的价格开始飙升以来,围绕加密货币市场的炒作一直在持续。备用硬币每天都在不断出现——有些是骗局,有些几个月内就登上了硬币排行榜的榜首。这个话题无处不在,无论是在电台、推特、脸书,还是在和你祖父的感恩节餐桌上。参与其中的人通常受到投机的刺激,希望从飙升的市场中获得一笔横财。我很好奇数据科学是否能揭示一些真相。这个项目使用历史价格、协整和宏观经济协变量来预测硬币的未来价格。样本外预测在前 100 小时是可以接受的。让我们深入研究一下。

当谈到经典时间序列分析时,我们认为一个观察到的时间序列是一个模式和一些随机变化的组合。使用这种方法,可以根据历史数据预测未来值。这种方法在大多数情况下都能很好地工作,但是如果我们看到的是一个比模式更随机的时间序列呢?如果一个时间序列纯粹是推测性的,并且大量基于当前事件,而不是一些节奏成分,会怎么样?你知道…类似于…密码流通价格。

那么,如果不只是一些简单的模式,是什么推动了加密货币的价格呢?投机?创新?法律问题?舆论?供给/需求?比特币普及?昨晚某个富人决定买一百万枚硬币?好了,推测够了。我就不说了,现在给你看数据。

那么是什么影响了加密价格呢?

大多数人认为比特币就是答案。区块链技术是一种去中心化的数据库系统,最早由比特币实现。随着比特币获得更多的牵引力,人们不断推出同样基于区块链技术的替代硬币。因此,几乎可以说比特币是所有加密货币之母,因为它们首先提出了这种很酷的技术。这就是为什么我认为当比特币飙升时,其他所有硬币都会飙升是有道理的。当它掉落时,其他硬币也会掉落。下图显示了比特币(绿色)和以太坊(蓝色)的缩放滚动平均值。

如你所见,这个声明看起来相当准确。但是没有统计方法,我们不会匆忙下结论。稍后,我们将更多地讨论使用格兰杰因果检验来识别“协整对”。

同样显而易见的是,法律问题或技术游戏规则改变者等时事也发挥了作用。还记得中国在 9 月禁止加密吗?价格迅速下跌,一切陷入混乱。为了捕捉像这样的重要事件,谷歌新闻搜索频率数据是从 Pytrends API 获得的。下图显示了随着 cryto 价格的下降,“加密货币”(红色)一词的搜索频率出现峰值。

有趣吧?本项目中使用的搜索词是使用谷歌关键词工具选择的。该工具不仅能让你知道一个搜索词有多受欢迎,还能给出相关关键词的列表。使用提供的列表和 Pytrend API,可以获得七个不同关键字的搜索频率数据。我将在后面的部分详细阐述这些术语。

对我来说,另一个突出的因素是公众的看法。买入越多,需求越多,价格也就越高。捕捉这些数据有点痛苦。付费的 Twitter API 是我需要的一切,但我是一名学生,所以我宁愿把钱存起来买杂货。取而代之的是,网站redditmetrics.com列出了世界上几乎所有子网站的历史订阅增长数据。所以网络抓取是!!!下图比较了 Nem subreddit 订阅增长(橙色)和 Nem 历史价格(蓝色)。

正如预期的那样,订阅增长和价格在高点和低点之间保持一致。

我希望这些图片会让你感兴趣。这只是让您开始了解一些领域知识,并向您介绍我们正在尝试解决的问题。如果介绍没有引起你的兴趣,请点击这里查看我的 GitHub 上的完整 EDA。接下来,我将直接进入用来建立一个预测硬币未来价格的模型的统计方法。

我是如何建立模型的?

在这一部分,我们将深入研究方法论。它只是每一步的总结。如果你想深入挖掘代码,请参考我的 GitHub 资源库这里。这将是技术性的,我会尽我所能让它变得有趣和容易消化。但是如果你对技术不感兴趣,可以直接跳到 TLDR 部分。

1。 识别协整对

通过 Cryptocompare API 获得了三个月内 12 种顶级硬币的历史价格。但是在我们对时间序列做任何事情之前,我们必须确保时间序列是平稳的。为了满足平稳性要求,时间序列必须具有恒定的均值、恒定的方差和恒定的自相关性。听起来要求很多,对吧?事实上,没有一个时间序列是完全静止的。但是不要担心我的朋友,迪基·富勒会支持你的!

**平稳性的增强 Dickey-Fuller 检验。**这是一个统计测试,允许您检查是否满足平稳性的预期。这是一个单位根测试,它决定了一个时间序列被趋势定义的程度。该测试使用自回归模型,并在不同的滞后值之间优化信息标准。零假设是时间序列可以用单位根来表示(意味着它不是平稳的)。一些统计学家提出了 0.05 的神奇阈值,许多人同意这个数字。所以如果你的 p 值小于 0.05,你可以拒绝零假设。但话又说回来,对于给定的问题,结果应该被解释为有意义的。结果是,假设阈值为 0.05,所有 12 种硬币的历史价格都没有通过平稳测试(惊讶吧!).在这种情况下,我们必须对时间序列进行平稳化,并重新测试它们。

**求差。**这是一种用于平稳化时间序列的流行方法。它可以用来消除趋势和季节性。取连续观测值的差值(滞后 1)用于本项目。如果时间序列有季节性成分,滞后值应该是季节性的周期。在我们的例子中,没有明显的季节因素。下面的方框图显示了以太坊每小时的平均值在一天的 24 小时中是相对恒定的。方差各不相同,但没有明显的模式。

在我们对时间序列执行滞后-1 差分后,所有 12 个时间序列都通过了 Dickey-Fuller 平稳测试!唷。

**格兰杰因果关系检验。**这是一个统计假设检验,用于确定一个时间序列在预测另一个时间序列时是否有用。如果 A 的滞后值提供了关于 B 的未来值的具有统计意义的信息,则时间序列 A 是时间序列 B 的“格兰杰原因”。在本项目中,我们使用该测试来确定一个协整对,即一对加密货币,其中一个硬币的滞后值可用于预测另一个硬币的未来值。

既然所有 12 个硬币的历史价格数据都是固定的,我们总共构建了 132 个数据框架,每个数据框架都是 12 个硬币历史价格的排列对(不要与组合对混淆)。呀,这真让人困惑。例如,假设我有联邦理工学院、BTC 和长期资本公司的历史价格数据。然后,我需要制作六个数据框架:ETH & BTC 历史价格、ETH & LTC 历史价格、BTC & ETH 历史价格、BTC & LTC 历史价格、LTC & ETH 历史价格和 LTC & ETH 历史价格。请注意,BTC 联邦理工学院和 BTC 联邦理工学院不是一回事!这只是为 StatsModels 的格兰杰因果检验准备我们的数据。测试的零假设是第二列中的时间序列不会对第一列中的时间序列产生格兰杰因果关系。我们需要测试是 ETC 导致了 BTH 还是 BTH 导致了 ETC。这就是为什么我们需要排列对而不是组合对!在进行了 132 次测试后,由于最强的相关性,DASH & BCH 对先前被选为协整对。然而,随着进一步的研究,事实证明,这种强相关性是由于韩国交易量的激增。由于这不是正常情况,我们选择 XEM 和 IOT (Nem 和 Iota)作为我们的协整对,因为它在正常情况下具有最强的相关性。就本项目而言,IOT 历史价格将被用作 XEM 未来价格预测指标之一。

2。 功能选择

**查询数据。**以下是获得的数据及其来源:

  • Cryptocompare API:以小时频率表示的 XEM 和 IOT 历史价格
  • Pytrends API:谷歌新闻搜索“加密货币”的频率
  • 抓取 redditmetrics.com: Subreddit“加密货币”、“Nem”和“Iota”订阅增长
  • Pytrends API: Google 搜索短语“Nem 钱包下载”、“Iota 钱包下载”、“Nem 价格”、“Iota 价格”、“比特币价格”、“用于挖掘的 GPU”的频率-这些关键字是使用 Google 关键字工具选择的
  • 雅虎金融 API: AMD 和 Nvidia 的股票价格——这是两大半导体公司用来挖矿的

**ElasticNet 正则化。**您可能已经注意到,查询的数据有些相关。例如,谷歌搜索“比特币价格”和“加密货币”的频率可能包含非常相似的信息。使用像这样的相关特征构建模型会产生冗余,这是不好的!就像人类因冗余而变得情绪不稳定一样,机器也会因多重共线性而变得不稳定。这时 ElasticNet 正则化就出现了。该算法线性结合了套索法和岭法的 L1 和 L2 罚函数。它将冗余预测器的系数“缩小”到零,因此它成为特征选择的行业标准方式。使用 ElasticNet 结果,将选择具有非零系数的特征。

在这个项目中,ElasticNet 是对上面获得的 13 个预测变量进行的,XEM 历史价格是因变量。运行该算法后,我们剩下三个具有非零系数的预测值。这些特征将用于构建最终模型。不管 ElasticNet 的结果如何,我还尝试使用所有 13 个预测值构建了一个模型,然后将结果与使用三个选定特征构建的模型进行了比较。结果表明,性能差异并不显著(所有 15 个特性的 MSE = 0.107,3 个特性的 MSE = 0.105)。然而,我仍然选择三个特征模型,因为我认为越精简越好。

3。 建筑模型

对于这个项目,我们将使用 ARIMAX 模型来预测 XEM 期货价格。就像 ARIMA 模型一样,ARIMAX 基于自回归(AR)和移动平均(MA)项进行预测。然而,ARIMAX 在模型中也包括外生变量。在这种情况下,这里将使用之前选择的三个预测变量。

数据预处理。由于我们在上一节已经讨论了静态测试和 Dickey-Fuller 测试,我将在此省略细节。获得的数据在 ElasticNet 之前已经标准化了,所以我们需要做的就是执行差分,然后确保它通过 Dickey-Fuller 测试。之后,数据被清理并分成测试集和训练集。

PACF 的 ACF。现在我们的数据已经准备好了,我们需要(1)确定时间序列是 AR 还是 MA 过程,以及(2)确定我们需要在模型中使用什么顺序的 AR 或 MA 过程。使用 ACF 可以回答第一个问题。对于 AR 系列,相关性逐渐下降,没有截止值。ACF 也可以用来确定 MA 系列的滞后阶数——这是截止值。然而,如果我们有一个 AR 系列,PACF 截止值将用于确定滞后阶数。下图是 XEM 历史价格的 ACF 和 PACF。

正如我们所看到的,这是一个 AR 过程,因为 ACF 没有临界值。然后,看看 PACF,它在滞后 1 处截止,这将是我们用于 ARIMAX 模型的参数。

**ARIMAX。**使用 AR 1 和 3 外生变量,下图是与实际值相比的拟合值。

利用拟合的模型,对 XEM 价格进行了预测。下图是 XEM 提前 600 步的样本外预测。

正如所料,该模型在开始时表现更好。这是因为随着时间的推移,预测误差不断复合。在大约 100 步之后,该模型表现不佳。步骤 1-100 的均方误差为 0.039,而步骤 101-600 的均方误差为 0.119。

TLDR

Iota 历史价格与其他宏观经济协变量(如“Nem 价格”一词的 Google 搜索频率和“Nem”subreddit 订阅增长数据)相结合,用于构建 ARIMAX 模型来预测 Nem 价格。前 100 小时的样本外预测性能是可以接受的。除此之外的都是垃圾。

这个项目是我的第一个数据科学项目,有很大的改进空间。获得付费 Twitter 数据或使用不同的机器学习模型可能会显著提高性能。到那个时候,我还不如想出一个交易信号算法,用它来自动化交易。但是现在,这个项目将继续作为投资组合的一部分。是的,我很失望我没有在这个项目结束时从加密交易中变得富有

我希望你和我一样喜欢这篇文章。留下你的评论,让我知道你的想法。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

揭秘无人机动态!

原文:https://towardsdatascience.com/demystifying-drone-dynamics-ee98b1ba882f?source=collection_archive---------3-----------------------

Demystifying Drone Dynamics!

  1. 虽然我们大多数人都知道四轴飞行器/无人机的样子,但上面显示的是一张无人机的普通图片(来自 bitcraze 的一架名为 Crazyflie 的无人机)。它由 4 个马达,中间的控制电路和安装在转子上的螺旋桨组成。由于下节所述的原因,2 个转子顺时针(CW)旋转,其余 2 个逆时针(CCW)旋转。顺时针和逆时针电机彼此相邻放置,以抵消它们产生的力矩(在下一节中描述)。螺旋桨有不同的配置,如顺时针或逆时针旋转,推进器或牵引机,具有不同的半径,螺距等。

2。力和力矩

Figure 2: Forces and Moments

每个旋转的螺旋桨产生两种力。当转子旋转时,它的螺旋桨产生一个向上的推力,由 F = K _ f * ω (如图 2 中的力 F1、F2、F3 和 F4 所示)给出,其中ω(ω)是转子的转速,单位为弧度/秒。常数 K_ f 取决于许多因素,如扭矩比例常数、反电动势、周围空气密度、螺旋桨扫过的面积等。K_ fK_m 的值(如下所述)通常根据经验获得。我们将电机和螺旋桨安装在称重传感器上,测量不同电机速度下的力和力矩。有关 K_ f 和 K_ m 测量的详细信息,请参考 Julian F \or ster 的“Crazyflie 2.0 Nano Quadrocopter 的系统识别”。
所有 4 个螺旋桨产生的总向上推力由产生的所有单个推力相加而得,对于 i= 1 至 4,其由
F _ I = K _ F *ω除了向上的力,旋转的螺旋桨还产生称为扭矩或力矩的反向旋转(如图 2 中的力矩 M1、M2、M3 和 M4 所示)。例如,沿顺时针方向旋转的转子将产生一个扭矩,该扭矩导致无人机的机身沿逆时针方向旋转。这种效果的演示可以在这里看到。该旋转力矩由下式给出:M=K_ m * ω
电机产生的力矩与其旋转方向相反,因此顺时针和逆时针旋转电机产生相反的力矩。这就是为什么我们有顺时针和逆时针旋转电机,以便在稳定的悬停状态下,来自 2 个顺时针和 2 个逆时针旋转转子的力矩相互抵消,无人机不会继续围绕其机身轴旋转(也称为偏航)。
力矩/扭矩 M1、M2、M3 和 M4 是由单个电机产生的力矩。围绕无人机 Z 轴(图 2 中的 Z_b)产生的总力矩是所有 4 个力矩的总和。记住顺时针和逆时针方向的力矩符号相反。
moment _ z = M1+M2+M3+M4,CW 和 CCW 力矩将再次具有相反的符号,因此在理想状态下(或者每当我们不希望任何偏航(绕 z 轴旋转)运动时) moment_z 将接近 0。
moment_z 相反,围绕 x 轴和 y 轴产生的总力矩/扭矩的计算略有不同。查看图 2,我们可以看到电机 1 和 3 位于无人机的 x 轴上。所以它们不会对围绕 x 轴的任何力矩/力矩有贡献。然而,我们可以看到,电机 2 和 4 产生的力的差异将导致无人机的机身围绕其 x 轴倾斜,这就是围绕 x 轴的总力矩/扭矩,由
moment _ x =(F2-F4) L*,给出,其中 L 是从转子旋转轴到四旋翼中心的距离。同样的逻辑,
moment _y =(F3—f1) l .* 总结起来,绕所有 3 个轴的力矩可以用下面的向量表示
moment=【moment _ x,moment _ y,moment_z]^T (^T 转置)

3。方向和位置

Figure 3: Orientation and position

无人驾驶飞机具有位置和方向属性,这意味着它可以是任何位置(x,y,z 坐标),并且可以相对于世界/惯性坐标系成某些角度(θ,φ和ψ)。上图更清楚地显示了θ、φ和ψ。

4。在 z 和 x 方向移动& y 方向移动

Figure 4: Moving in z and x & y direction

每当无人机静止时,它都与世界坐标系对齐,这意味着它的 Z 轴与世界重力场方向相同。在这种情况下,如果无人机想要向上移动,它只需要设置合适的螺旋桨转速,就可以根据方程产生的总力——重力开始在 z 方向移动。然而,如果它想在 x 或 y 方向移动,它首先需要确定自己的方向(形成所需的θ或φ角)。当这种情况发生时,四个螺旋桨产生的总推力(F_thrust)在 z 方向和 x/y 方向都有一个分量,如上图 2D 所示。对于上述示例,使用基本三角学,我们可以通过以下等式找到 z 和 y 方向力,其中φ是无人机机身 z 轴与世界坐标系夹角。
**f _ y=f_ 推力
罪恶
ϕ* f _ z=f_ 推力* cos ϕ**

5。世界和身体框架

Figure 5: World and Body frame

为了测量上述θ、φ和 psi 角度,通常使用无人机的机载 IMU 传感器。这个传感器测量无人机的身体围绕其身体框架旋转的速度,并提供角速度作为其输出。在处理这种 IMU 输出时,我们需要小心,并理解它发送的角速度不是相对于世界坐标系的,而是相对于其体坐标系的。上图显示了这两个框架,以供参考。

6。旋转矩阵

Figure 6: Rotation Matrix

为了将坐标从身体坐标系转换到世界坐标系,反之亦然,我们使用一个称为旋转矩阵的 3x3 矩阵。也就是说,如果 v 是世界坐标中的一个矢量,v '是用体固定坐标表示的同一个矢量,那么下面的关系成立:
V' = R * V 和
V = RT * V '其中 r 是旋转矩阵,RT 是它的转置。为了完全理解这种关系,让我们从理解 2D 的旋转开始。让矢量 V 旋转一个角度β,得到新的矢量 V’。设 r=|V|。然后,我们有下面的关系:
vx = rcosα和 vy = rsinα
v'x = rcos(α+β)和 v'y = rsin(α+β)。对此展开,我们得到
v'x = r * (cosα * cosβ — sinα * sinβ)和 V ' y = r (sinα cosβ+cosα* sinβ)
V ' x = VX * cosβ—vy * sinβ和 v'y = vy * cosβ + vx * sinβ
这正是我们想要的,因为期望点 V '是用原点 V 和实际角度β来描述的。作为结论,我们可以用矩阵符号写为

在旋转矩阵的情况下,从 2D 到 3D 相对简单。事实上,我们刚刚导出的 2D 矩阵实际上可以被认为是绕 z 轴旋转的 3D 旋转矩阵。因此,对于绕 z 轴的旋转,旋转矩阵为

最后一行和最后一列中的值 0,0,1 表示旋转点的 z 坐标(v'z)与原始点的 z 坐标(vz)相同。我们将这个 Z 轴旋转矩阵称为 Rz(β)。将相同的逻辑推广到围绕 x 和 y 轴的旋转,我们可以得到 RX(β)和 RY(β)的值,如下所示

并且 3D 运动旋转矩阵的最终值将只是上述三个旋转矩阵的交叉乘积。
R = Rz(ψ) x Ry(θ) x Rx(φ) 其中 psi (ψ),phi (φ,)和 theta (θ)分别是绕 z,y,x 轴的旋转。

7。状态向量及其导数 由于我们的无人机有 6 个自由度,我们通常通过监控这 6 个参数及其导数(它们如何随时间变化)来跟踪它,以获得对无人机位置和运动速度的准确估计。我们通过维护通常所说的状态向量 X = [x,y,z,φ,θ,ψ,x_dot,y_dot,z_dot,p,q,r] 及其导数 X_dot= [x_dot,y_dot,z_dot,θ_dot,φ_dot,ψ_dot,x_doubledot,y_doubledot,z_doubledot,p_dot,q_dot,r_dot] 来做到这一点,其中 X,y 和 zφ,θ,ψ表示世界坐标系中的无人机姿态/方向,而φ_dot,θ_dot,ψ_dot 表示该(欧拉)角度的变化率。p、q、r 是主体框架中的角速度,而 p_dot、q_dot 和 r_dot 是其导数(导数=变化率),也称为主体框架中的角加速度。x_doubledot,y_doubledot,z_doubledot 表示世界坐标系中的线性加速度。

8。线性加速度 如前所述,每当螺旋桨移动时,无人机将开始在 x、y 和 z 方向上移动(加速),这取决于其 4 个螺旋桨产生的总推力(由下面等式中的 Ftotal 表示)和无人机的方向(由旋转矩阵 R 表示)。我们知道力=质量加速度。忽略旋转矩阵 R,如果我们仅考虑 Z 方向上的加速度,它将由
Z_force =(质量
重力)—(质量* Z _ 加速度)
质量* Z _ 加速度=质量*重力— Z_force
给出,因此Z _ 加速度=重力— Z_force /质量 将其外推至 x 和 y 方向并包括旋转矩阵(出于第 4 和 6 节中描述的原因),描述无人机的线性加速度的方程由以下方程给出,其中 mF 中的负号表示我们认为重力在 z 轴的正方向。

Linear Acceleration

9。角加速度 除了直线运动,由于旋转螺旋桨及其方位,无人机也会有一些旋转运动。。虽然在惯性/世界坐标系中有线性运动方程很方便,但在体坐标系中旋转运动方程对我们很有用,因此我们可以表示绕四轴飞行器中心的旋转,而不是绕惯性中心的旋转。如第 4 节所述,我们将使用无人机的 IMU 来获得其角加速度。让我们考虑 IMU 的输出为 p、q 和 r,代表围绕无人机 x、y 和 z 体轴的旋转速度。
我们从刚体动力学的欧拉方程推导出旋转运动方程。用矢量形式表示,欧拉方程可写成

Euler’s equations for rigid body dynamics

其中ω = [p,q,r]^T 是角速度矢量,I 是惯性矩阵,力矩是第 2 节中开发的外部力矩/扭矩矢量。。请不要将本节中ω(作为角速度)的用法与它作为螺旋桨转速的用法混淆。在本节之后,我们将坚持使用ω作为旋转速率。我们可以将上述等式改写为

用[p,q,r]^t]代替ω,展开力矩矢量,重新排列上述等式,我们得到车身框架中的角加速度为

Angular Accelerations in Body Frame

10。欧拉角的变化率 虽然无人机的方位最初是在人体坐标系中观察到的,但是我们需要将它们转换到世界坐标系中。同样,我们根据下面的公式使用旋转矩阵来达到这个目的。这个公式的推导过程很简单,在参考文献[6]中提供了

Rate of Change of Euler Angles

11。回顾 让我们回顾一下到目前为止所学的内容
1。一架四轴飞行器有 4 个(2 个顺时针和 2 个逆时针)旋转螺旋桨
2。每个螺旋桨在垂直于其平面的方向上产生 F =K_f * ω 力和绕其垂直轴的力矩 M = K_m * ω
3。无人驾驶飞机可以处于任何 x、y、z 位置以及θ、φ和ψ方向。
4。当无人机想要在 z 方向(世界坐标系中)移动时,它需要在每个螺旋桨上产生适当的力(总推力除以 4)。当它想在 x 或 y 方向移动时(同样是世界坐标系),它在产生所需力的同时考虑θ/φ角
5。当跟踪无人机的运动时,我们需要处理世界和身体框架中的数据
6。为了将角度数据从身体坐标系转换到世界坐标系,使用旋转矩阵
7。为了跟踪无人机的运动,我们跟踪它的状态向量 X 及其导数 X_dot
8。旋转螺旋桨产生 x、y 和 z 方向的线性加速度,如第 8 节
9 所示。旋转螺旋桨在机身框架中产生绕 z、y 和 z 轴的角加速度,如第 9 节
10 所示。按照第 10 节中所示的等式,我们将体坐标系中的角速度转换为世界坐标系中的欧拉角速度。

12。参考文献 我不想只列出参考文献,而是想真诚地感谢个别作者的工作,没有他们的工作,这篇文章和我对无人机动力学的理解几乎是不可能的。
1。Julian Forster 对 Crazyflie 2.0 Nano Quadrocopter 的系统识别—http://Mike hamer . info/assets/papers/crazy flie % 20 modelling . pdf
2。丹尼尔·沃伦·梅林杰的四旋翼飞行器轨迹生成和控制—https://repository.upenn.edu/cgi/viewcontent.cgi?article = 1705&context = edisser stations
3。四轴飞行器动力学、模拟和控制作者 Andrew Gibiansky—http://Andrew . Gibiansky . com/downloads/pdf/quad copter % 20 Dynamics、%20Simulation、%20Control.pdf
4。绕 x 轴、y 轴或 z 轴基本旋转的简单推导—http://www.sunshine2k.de/articles/RotationDerivation.pdf
5。你如何得到旋转矩阵?—Quora—https://www . Quora . com/How-do-you-derive-the-rotation-matrix
6 .詹姆斯·迪贝尔的《表现姿态:欧拉角、单位四元数和旋转矢量》——https://www . astro . rug . nl/software/kapteyn/_ downloads/Attitude . pdf

如果你喜欢这篇文章,在推特上关注、转发或者鼓掌,媒体上的赞会鼓励我继续我的博客世界之旅。

直到下一次…干杯!!

揭开生成对抗网络的神秘面纱

原文:https://towardsdatascience.com/demystifying-generative-adversarial-networks-c076d8db8f44?source=collection_archive---------6-----------------------

在本教程中(源自我的原始帖子这里),你将学习什么是生成性对抗网络(gan ),而无需深入数学细节。之后,你将学习如何编写一个简单的可以创建数字的 GAN!

类似

理解什么是 gan 的最简单方法是通过一个简单的类比:

假设有一家商店从顾客那里购买某些种类的酒,然后他们再转卖。

但是,也有穷凶极恶的客户为了捞钱,卖假酒。在这种情况下,店主必须能够区分真假葡萄酒。

你可以想象,最初,伪造者在试图出售假酒时可能会犯很多错误,店主很容易识别出这种酒不是真的。由于这些失败,伪造者将继续尝试不同的技术来模仿真正的葡萄酒,有些人最终会成功。既然伪造者知道某些技术通过了店主的检查,他就可以开始在这些技术的基础上进一步改进假酒。

与此同时,店主可能会从其他店主或葡萄酒专家那里得到一些反馈,说她拥有的一些葡萄酒不是原创的。这意味着店主将不得不改进她如何确定一种酒是假的还是真的。伪造者的目标是创造出与真品难以区分的葡萄酒,而店主的目标是准确辨别一款葡萄酒的真假。

这种来回的竞争是 GANs 背后的主要思想。

生成性对抗网络的组成部分

利用上面的例子,我们可以得出 GAN 的架构。

GANs 中有两个主要组件:生成器和鉴别器。示例中的店主被称为鉴别器网络,通常是一个卷积神经网络(因为 gan 主要用于图像任务),它分配图像是真实图像的概率。

伪造器被称为生成网络,也是典型的卷积神经网络(具有反卷积层)。该网络采用一些噪声矢量并输出图像。当训练生成网络时,它学习图像的哪些区域要改进/改变,以便鉴别器将更难区分其生成的图像和真实的图像。

生成网络不断产生在外观上更接近真实图像的图像,而辨别网络试图确定真实图像和虚假图像之间的差异。最终目标是拥有一个生成网络,能够生成与真实图像无法区分的图像。

带有 Keras 的简单生成对抗网络

既然您已经理解了什么是 gan 以及它们的主要组成部分,我们现在可以开始编写一个非常简单的代码了。你将使用Keras,如果你不熟悉这个 Python 库,你应该在继续之前阅读本教程。这个教程就是基于这个很酷很好理解的甘开发的这里。

您需要做的第一件事是通过pip安装以下软件包:

- keras
- matplotlib
- tensorflow
- tqdm

您将使用matplotlib进行绘图,tensorflow作为 Keras 后端库,tqdm为每个时期(迭代)显示一个漂亮的进度条。

下一步是创建 Python 脚本。在这个脚本中,您首先需要导入您将使用的所有模块和函数。当它们被使用时,将给出每一个的解释。

您现在想要设置一些变量:

在开始构建鉴别器和生成器之前,应该首先收集和预处理数据。您将使用流行的 MNIST 数据集,该数据集包含一组从 0 到 9 的一位数的图像。

Example of MINST digits

请注意mnist.load_data()是 Keras 的一部分,允许您轻松地将 MNIST 数据集导入工作空间。

现在,您可以创建自己的生成器和鉴别器网络。您将为两个网络使用 Adam 优化器。对于发生器和鉴别器,您将创建一个具有三个隐藏层的神经网络,激活函数为 Leaky Relu 。你还应该为鉴别器添加脱落层,以提高其对不可见图像的鲁棒性。

终于到了把发生器和鉴别器合二为一的时候了!

为了完整起见,您可以创建一个函数,每隔 20 个时期保存您生成的图像。因为这不是本课的核心,所以您不需要完全理解该函数。

现在,您已经对网络的大部分进行了编码。剩下的就是训练这个网络,看看你创造的图像。

经过 400 个纪元的训练后,您可以查看生成的图像。查看第一个时期后生成的图像,您可以看到它没有任何真实的结构,查看 40 个时期后的图像,数字开始成形,最后,400 个时期后生成的图像显示清晰的数字,尽管有一对数字仍然无法识别。

Results after 1 epoch (left) | Results after 40 epochs (middle) | Results after 400 epochs (right)

这段代码在 CPU 上每个时期大约需要 2 分钟,这也是这段代码被选中的主要原因。您可以通过使用更多的历元以及向发生器和鉴别器添加更多(和不同的)层来进行试验。然而,当使用更复杂和更深入的架构时,如果只使用 CPU,运行时间也会增加。然而,不要因此而停止尝试!

结论

恭喜你,你已经完成了本教程的学习,在本教程中,你以直观的方式学习了生成性对抗网络(GANs)的基础知识!此外,您在 Keras 库的帮助下实现了第一个模型。

揭开超参数调谐的神秘面纱

原文:https://towardsdatascience.com/demystifying-hyper-parameter-tuning-acb83af0258f?source=collection_archive---------11-----------------------

它是什么,为什么是自然的

超参数结构每天都有许多过程,但很少有人意识到它们的存在。当你想买一双鞋的时候,你正在解决一个超参数优化问题。一旦你决定了要买哪种 类型 的鞋子(hyper-parameter)你就需要根据鞋子的 参数 来满足你的要求( 尺码、颜色、… )。你的可用预算也是一个超级参数,会影响你的选择。

An everyday hyper-parameter optimization problem

超参数调谐

如果你选择了一双适合你的鞋子,而且颜色也合适,你就能穿上它们。然而,如果你选择了一双红色高跟鞋,你可能会发现跑马拉松很有挑战性。超参数调整对于大多数用例来说可能并不重要,但会显著影响您的流程效率和您试图获得的结果的质量(例如,您可以穿着靴子跑步,但可能没有穿着运动鞋跑得快)。

数据科学中的超参数调整

大多数机器学习模型都有超参数。

例如,一个简单的随机森林算法会有相当多的:

Scikit-Learn implementation of a Random Forest Classifier

一旦用户指定了其超参数的值,该算法将在基础数据集上进行训练。超参数的选择将影响训练的持续时间和预测的准确性。不幸的是,选择超参数并不是直截了当的,因为可能的配置数量随着它们的数量而爆炸,并且配置的评估时间是模型复杂性和底层训练数据大小的函数。此外,这是一种有点黑暗的艺术,正如威廉·科尔森在他的媒体文章中所说:

超参数调整更多地依赖于实验结果而不是理论,因此确定最佳设置的最佳方法是尝试许多不同的组合来评估每个模型的性能。

面对如此多的不确定性,大多数数据科学家放弃超参数调整,坚持使用模型提供的默认值是可以理解的。这在大多数情况下是可行的,但是根据我的初步类比,你可能很难穿着高跟鞋跑马拉松。

在现实生活中你不会这样做(除非是为了一个好的理由),那么在数据科学领域你为什么会这样做呢?

第二种最流行的方法是通过 网格搜索 (评估每一个配置)找到最佳配置,这将最终导致一个答案。

但是你不会穿着你所有的每一双鞋跑完一场马拉松,从而得出结论说你穿着运动鞋跑得最好,那么你为什么要在数据科学领域做同样的事情呢?

第三种最流行的方法是通过 随机搜索 找到最佳配置,但这仅比网格搜索略好。我就不跟你打这个比方了,因为我希望现在你明白我的意思了。

那么如何更有效地进行超参数调优呢?

头脑铸造公司的推特粉丝似乎知道答案

贝叶斯优化

贝叶斯优化通过结合对解空间看起来像什么的“信念”,并通过从它评估的配置中“学习”,解决了网格和随机搜索的陷阱。这种信念可以由领域专家指定,但也可以在开始时是平的。如果当你尝试穿着细高跟鞋跑马拉松,你不会再穿你所有的其他高跟鞋了,因为你会知道这很痛苦。此外,如果你有先验知识,你可能从一开始就选择平底鞋!

我已经写了一篇更详细的文章(用更少的类比)来解释贝叶斯优化背后的直觉:

[## 高斯过程贝叶斯优化背后的直觉

在某些应用中,目标函数是昂贵的或难以评估的。在这些情况下,一般…

towardsdatascience.com](/the-intuitions-behind-bayesian-optimization-with-gaussian-processes-7e00fcc898a0)

可以在这里找到可下载的白皮书版本。

您可以在这里自动接收我们的贝叶斯优化器 OPTaaS 的 API 密钥!

更新:我开了一家科技公司。你可以在这里找到更多的

贝叶斯优化的扩展

如果你有可以尝试其他鞋子的朋友,你们会集体找到跑马拉松用得更快的最好的一双。同样可以在 BO 中通过智能配料实现。

如果你穿着高跟鞋跑马拉松,你应该(在理论上)很早就意识到这相当痛苦,你应该停下来换双鞋?

嗯,这在贝叶斯优化的某些实现中是可能的,在我的下一篇文章中,我将解释如何实现。

揭秘“EM 路由矩阵胶囊”

原文:https://towardsdatascience.com/demystifying-matrix-capsules-with-em-routing-part-1-overview-2126133a8457?source=collection_archive---------0-----------------------

最近,深度学习之父之一的杰弗里·辛顿(Geoffrey Hinton)发表了一项革命性的计算机视觉架构,在机器学习界掀起了波澜:胶囊网络。Hinton 自 2012 年以来一直在推动使用胶囊网络,此前他首次革命性地使用卷积神经网络(CNN)进行图像检测,但直到现在他才使它们变得可行。两周前发表的最初的成功方法名为“胶囊之间的动态路由”动态路由——我们将在本文中深入探讨——允许网络更直观地理解部分-整体关系。

在这篇论文发布后的三天内,另一篇关于胶囊网络中动态路由的论文被提交给 ICLR 2018 进行审查。这篇题为“EM 路由的矩阵胶囊”的论文被广泛认为是由 Hinton 撰写的,讨论了一种革命性的动态路由新方法,甚至与他的第一篇论文相比。尽管这种方法显示出巨大的前景,但迄今为止媒体对它的关注相对较少。由于作者身份的不确定性,我在这篇文章的其余部分提到了“作者”。

在这篇博文中,我将讨论 matrix capsules 动态路由背后的直觉和动态路由的机制。第一部分将概述胶囊网络的直觉,以及它们如何利用动态路由比传统 CNN 更有效。第二部分将深入研究 EM 路由的数学和技术细节。

(注:如果你读过 Sabour et。艾尔。“胶囊之间的动态路由”,直觉上是非常相似的,但是路由机制是非常不同的。)

CNN 怎么了?

自 2012 年 Hinton 合著了一篇介绍 AlexNet 的论文以来,CNN 在 ImageNet 的图像分类方面的表现优于任何以前的方法,CNN 一直是计算机视觉的标准方法。本质上,CNN 通过检测图像中特征的存在来工作,并使用这些特征的知识来预测对象是否存在。然而,CNN 只检测特征的存在——所以即使是右边的图像,包含错位的眼睛、鼻子和耳朵,也会被认为是一张脸,因为它包含了所有必要的特征!

A CNN would classify both images as faces because they both contain the elements of faces. Source.

CNN 未能处理此类图像的原因是辛顿在过去几年中批评 CNN 的原因。问题归结为 CNN 从一层到另一层传递信息的方式:最大池。最大池检查像素网格,并在该区域进行最大激活。该程序主要检测特征是否在图像的任何区域存在,但是会丢失关于该特征的空间信息。

Max Pooling preserves existence (maximum activation) in each region, but loses spatial information. Source.

胶囊网络试图通过捕捉部分-整体关系来解决 CNN 的局限性。例如,在一张脸上,两只眼睛都是前额的一部分。为了理解这些部分-整体关系,胶囊网络需要知道的不仅仅是某个特征是否存在——它需要知道该特征在哪里,它是如何定向的,以及其他类似的信息。胶囊网络以 CNN 没有的方式取得了成功,因为它们成功地捕捉了这些信息,并将信息从一部分传递到整体。

那么,胶囊网络到底是什么?

传统的神经网络由神经元组成。胶囊网络通过将神经元分组到称为胶囊的模块中,在 CNN 上强加结构。

是一组神经元,其输出代表相同特征的不同属性。通过对神经元进行分组,胶囊的输出是 4x4 矩阵(或 16 维向量),其条目表示诸如特征的 x 和 y 坐标、对象的旋转角度以及其他特征的信息。例如,在数字识别中,一层胶囊对应数字。输出层中的一个胶囊可以对应于 6。4×4 矩阵中的不同条目将对应于 6 的不同属性。如下所示,如果您修改矩阵的一个条目,6 的比例和厚度会发生变化,如果您修改矩阵的另一个条目,6 的顶钩也会发生变化。

This image, from Hinton’s first paper, shows what happens to numbers when perturbing one dimension of the capsule output. This demonstrates spatial information about the numbers stored in each entry. Source.

当想到神经网络时,我们会想到神经元之间的连接。虽然胶囊是由神经元组成的,但更容易(也更有效)的是将网络想象成由称为胶囊的组件组成。整个胶囊网络由多层胶囊组成。每层可由任意数量的胶囊组成(通常为 8-32 个)。

将胶囊与传统神经网络中的神经元进行比较在直觉上是有帮助的。神经网络中的单个神经元从(0,1)输出一个激活,并表示一个特征的存在。另一方面,胶囊输出关于特征的存在的逻辑单元(0,1)以及表示关于特征的附加信息的 4×4 矩阵。这个 4x4 矩阵被称为姿态矩阵,因为它代表了关于特征的空间信息。上图说明了修改姿势矩阵中的条目时会发生什么。

此外,我们可以考虑神经元-神经元连接与囊-囊连接,这在典型的图中用单个箭头表示。在神经网络中,一个神经元使用标量权重连接到下一个神经元。另一方面,两个胶囊之间的连接现在是一个 4x4 变换矩阵,因为一个胶囊的输入和输出都是 4x4 矩阵!

到目前为止,胶囊网络还没有做任何革命性的事情:毕竟,胶囊往往只是卷积层。胶囊网络的有效性来自于信息从一层传递到另一层的方式——这就是所谓的路由机制。与使用最大池路由信息的 CNN 不同,胶囊网络使用一种称为动态路由的新流程来捕捉部分-整体关系。

协议动态路由:从局部到整体

在本节中,我们将考虑如何将输出从层 (l) 路由到层 (l+1 )。此过程取代了 CNN 的最大池。请记住,正如我们之前所讨论的,我们的网络学习转换矩阵(类似于权重)作为胶囊之间的连接。然而,除了使用这些变换矩阵将信息从一层路由到另一层之外,每个连接还要乘以一个动态计算的路由系数**。如果这还不清楚,不要担心;我们将首先讨论这些路由系数背后的直觉,然后再讨论数学。**

为了使我们的分析更具体,我们考虑数字识别的例子,并且只对数字 2 和 3 进行分类。我们的隐藏层 (l) 由一个有六个胶囊的胶囊层组成,对应于特性,我们的最终层 (l+1) 由 2 个胶囊组成,对应于数字 2 或 3。层 (l) 中的特征代表数字 2 和 3 的不同部分。为了说明起见,假设我们的六个胶囊节点对应于以下特征。A 3 由前四个特征组成,a 2 由第一、第五和第六个特征组成。在我们的例子中,我们的网络将获取 3 的输入图像,并将尝试对其进行分类。

Capsules are shown as nodes, but output matrices. Arrows represent transformation matrices. Red capsules are active, and black capsules are inactive. The green capsules in the output layer have not yet been predicted.

直观上,我们知道层 (l) 中的每个对象都来自层 *(l+1)中的一个更高级别的对象。*我们知道第一个胶囊在我们的网络中是活跃的,因为它不是 a 2 就是 a 3。我们的目标是计算出我们的特征因下一层的每个特征而被激活的概率。基于我们认为层 (l) 中的胶囊被激活的原因,我们可以将我们的信息从层 (l) 引导到 (l+1)。

问题变成了我们如何决定这些概率。让我们以第一个胶囊特性为例,它可能是 a 2 或 a 3 的一部分。它的数量很大程度上取决于图层中第一个要素和其他要素之间的空间关系。在我们的示例中,图层 (l) 看到第一个要素(在图像中)位于第二个要素之上,第三个要素位于第四个要素之上。(*注意:我们的姿态矩阵输出可以捕捉这些特征之间的空间关系)。*因此,层 (l) 已经看到了关于具有正确关系的 a 3 的所有信息。如果是这样,那么在层 (l) 中存在显著一致的 a 3。与此同时,2 的另外两个节点并不活跃,因此,人们对图中有一个 2 的看法相对较少。基于这种一致,我们可以很大概率地说,第一个特性实际上来自于 a 3,而不是 a 2。

这个总体概念被称为协议路由。通过这样做,来自层 (l) 中的胶囊的信息仅被提供给层 (l+1) ,如果特征看起来来自后续层中的那个胶囊。换句话说,如果有更多关于 2 的一致,2 胶囊从第一个特征接收信息。这种动态计算向哪个更高级别的胶囊发送信息的过程被称为动态路由。通过将第一个特征(顶钩)动态地仅路由到 3,我们可以对我们的预测更有信心,并将低概率分配给 2。

Transformation matrices capture the fixed relationships between part and whole

这里是动态路由最棘手的部分:这些路由系数不是网络的学习部分!接下来的三段将解释为什么。我们在胶囊网络中学习到的权重是转换矩阵——类似于神经网络中的权重。这些变换矩阵可以捕捉每个特征如何与整体相关。例如,这可以告诉我们,第一个特征是 3 的顶部或 2 的顶部,第二个特征是 3 的中右,等等。

然而,给定单个图像,我们不知道第一特征是 a 3 还是 a 2 的一部分。如果 a 3 的不同部分与整体有着密切的联系,那么我们认为第一个特征应该被路由到 a 3。然而,其他时候,我们可能会认为这是二的一部分。因此,第一特征是 2 的一部分还是 3 的一部分取决于单个图像。因此,这些路由系数不是固定的权重;他们是学会了 的每一个单向前传递 的网络,并依赖于个人形象。这就是为什么这个过程被称为动态路由——它是正向传递的一部分。

A jumbled 3. It has all the features of a 3, but is not correctly aligned.

让我们考虑一下,当特性不在正确的位置时,这是如何修复这个例子的,这给 CNN 造成了一个问题。动态路由过程有助于解决这个问题。考虑当一个 3 的四个特征被随机放置在一个输入中时,如左边。卷积网络会认为这是 a 3,因为它有 a 3 的四个组成部分。然而,在胶囊网络中,“3 胶囊”将从隐藏层接收信息,表明 3 的各部分没有正确地关联到形成 3!因此,当第一个封装决定将其输出路由到哪里时,它不会看到 2 或 3 的协议,而是平等地发送其输出。结果,胶囊网络不能有把握地预测 2 或 3。希望这说明了为什么路由必须由动态,因为它取决于胶囊网络激活的特征的姿态

如上所述,这种路由是可行的,因为每个胶囊的输出是一个 4x4 矩阵。这些矩阵捕获了 a 3 的不同部分之间的空间关系,如果它们作为整体的一部分不正确地一致,胶囊网络就不能可靠地路由信息。另一方面,对于 CNN,标量激活不能捕捉每个部分和整体之间的关系。

构建动态路由的另一种方式是投票的概念。层 (l) 中的每个胶囊可以投票选择它认为来自层 (l+1) 中的哪个胶囊。胶囊总共获得一票,并且可以在所有随后的层胶囊中分配这一票。这种投票机制确保了基于空间关系的信息的有效路由。投票/路由机制来自下面讨论的过程。

EM 路由:总体思路

我们已经模糊地概述了动态路由背后的直觉,但是没有提到如何计算它。这个主题既冗长又复杂,将在本系列的下一部分中详细讨论。在这里,我将概述一下 EM 路由背后的基本思想。

本质上,当路由时,我们假设层 (l) 中的每个胶囊被激活,因为它是下一层中某个“整体”的一部分。在这一步,我们假设有一些潜在的变量来解释我们的信息来自哪个“整体”,并试图推断每个矩阵输出来自级别 (l+1) 中的高阶特征的概率。

这归结为一个无监督的学习问题,我们用一种叫做期望最大化的算法来解决它。本质上,期望最大化试图最大化我们的数据(层 (l) 的输出)被层 (l+1) 中的胶囊解释的可能性。期望最大化是一种迭代算法,包括两个步骤:期望和最大化。通常,对于胶囊网络,每个步骤执行三次,然后终止。

The output capsules converge toward the correct classes over the three iterations of EM. Source.

作者解释的步骤如下。期望分配层 (l) 中的每个胶囊被层 (l+1) 中的胶囊解释的概率。然后,最大化步骤决定层 (l+1) 中的胶囊是否是活动的,如果它们看到对它的输入的显著聚类(一致),并且通过对路由的输入取加权平均来决定对胶囊的输入是什么。

如果这没有意义,不要担心——我用很少的话解释了很多密集的数学。如果您想了解路由机制的深层技术,请继续关注本周晚些时候的下一篇博文。

胶囊网络架构

现在我们理解了胶囊网络背后的直觉,我们可以检查作者如何在他们的论文“带有 EM 路由的矩阵胶囊”中使用矩阵胶囊

本文在 SmallNORB 数据集上评估矩阵胶囊。该数据集由从不同角度和高度拍摄的五种类型的儿童玩具组成。数据集准确捕捉同一物体的不同视点。回想一下,由于胶囊的多维输出(姿势矩阵),胶囊在理解视点方面基本上更好——这就是为什么 SmallNORB 数据集是胶囊网络目标的优秀评估指标。

Example images from the SmallNORB dataset. The second row consists of photos taken from a different elevation from the first set. Source.

该架构包括一个卷积层,接着是两个胶囊层,最后是一个分类胶囊层,有五个胶囊,每个类一个。这种架构在数据集上的表现优于之前的任何模型,并将之前的最佳错误率降低了 45%以上!

Architecture in “Matrix Capsules with EM Routing.” See the paper for more details.

胶囊网络的优势

胶囊网络相对于 CNN 有四个主要的概念优势。

  1. 观点不变性。正如整篇文章所讨论的,姿态矩阵的使用允许胶囊网络识别对象,而不管它们是从哪个视点被观看的。
  2. 参数少。因为矩阵胶囊将神经元分组,所以层之间的连接需要较少的参数。实现最佳性能的模型仅包括 300,000 个参数,相比之下,其基线 CNN 包括 4,000,000 个参数。这意味着模型可以更好地概括。
  3. 更好地概括新观点。CNN 在被训练理解旋转时,通常会记住一个物体可以从几个不同的旋转角度被相似地观察到。然而,胶囊网络也可以更好地推广到新的视点,因为姿态矩阵可以将这些特征捕捉为简单的线性变换。
  4. 抵御白盒对抗性攻击。快速梯度符号法(FGSM)是攻击细胞神经网络的典型方法。它评估每个像素相对于网络损失的梯度,并且最多改变每个像素ε以最大化损失。虽然这种方法可以将 CNN 的准确率显著降低到 20%以下,但是胶囊网络可以保持 70%以上的准确率。

在这篇文章中,我将讨论一些关于基质胶囊的细节。在 EM 路由中使用矩阵胶囊而不是在初始论文中使用矢量胶囊的细节也呈现了三个主要优点。我将在下一篇文章中解释这三个好处的技术细节。

计算机视觉的未来

胶囊网络已经推出两周了,没有人知道它们是否是另一种人们会忘记的模式,或者它们是否会彻底改变计算机视觉。在目前的状态下,它们有很多缺点——最明显的是使用 EM 从一层到另一层动态路由需要大量的时间。当在 GPU 上并行化时,这可能会特别成问题。

不管怎样,这篇论文有效地充当了胶囊网络的概念证明,而且做得相当优雅。不过,在未来,它们的有效性必须在各种各样的数据集上进行测试,包括具有许多类的更适用的数据集,如 ImageNet。随着时间的推移,可能会引入新的路由机制,其他创新可能会使胶囊网络更有效(我们已经在“带 EM 路由的矩阵胶囊”中看到了这一点,它完全改变了路由机制!).然而,如果它们可行,应用将是无穷无尽的——图像分类、物体检测、密集字幕、生成网络和少镜头学习。

致谢——非常感谢舒邦德赛、阿迪加内什、张家瑞和乔丹亚力山大在这篇文章上给了我很好的反馈。查看原文这里和这里。

揭开机器学习优化的神秘面纱

原文:https://towardsdatascience.com/demystifying-optimizations-for-machine-learning-c6c6405d3eea?source=collection_archive---------3-----------------------

Gradient descent for machine learning

优化是机器学习算法配方中最重要的成分。它从定义某种损失函数/成本函数开始,以使用一个或另一个优化例程最小化 It 结束。优化算法的选择可以在几小时或几天内获得良好的精度。最优化的应用是无限的,是工业界和学术界广泛研究的课题。在本文中,我们将介绍深度学习领域中使用的几种优化算法。(可以通过 这篇文章 了解损失函数的基础知识)

随机梯度下降

随机梯度下降 (SGD)是最简单的优化算法,用于寻找最小化给定成本函数的参数。显然,对于收敛到最优最小值的梯度下降,成本函数应该是凸的。出于演示的目的,想象以下成本函数的图形表示。

Illustration of gradient descent

我们从定义一些参数的随机初始值开始。优化算法的目标是找到对应于成本函数最小值的参数值。具体来说,梯度下降从计算每个参数 w.r.t 成本函数的梯度(导数)开始。这些梯度为我们提供了需要对每个参数进行的数值调整,以便最小化成本函数。这个过程一直持续到我们达到局部/全局最小值(成本函数相对于其周围值最小)。数学上,

**for i in range(iterations_count):**          
    **param**_**gradients = evaluate_gradients(loss_function, 
                                         data, 
                                         params)** **params -= learning_rate * param_gradients**

Effect of learning rate on gradient descent

学习率定义每次迭代中参数应该改变多少。换句话说,它控制着我们应该以多快或多慢的速度收敛到最小值。一方面,小的学习率可能需要迭代才能收敛,大的学习率可能会超过最小值,如上图所示。

尽管在实践中很容易应用,但当涉及到深度神经网络时,它有相当多的缺点,因为这些网络有大量的参数要适应。为了说明梯度下降的问题,让我们假设我们有一个只有两个参数的成本函数。假设成本函数对其中一个参数的变化非常敏感,例如在垂直方向上,而对其他参数(即水平方向)不太敏感(这意味着成本函数具有高条件数)。

Zig zag motion with gradient descent

如果我们在这个函数上运行随机梯度下降,我们会得到一种锯齿形行为。实质上,SGD 正在缓慢地向不太敏感的方向发展,而更多地向高度敏感的方向发展,因此没有向最小值的方向调整。在实践中,深度神经网络可能有数百万个参数,因此有数百万个方向来适应梯度调整,从而使问题复杂化。

SGD 的另一个问题是局部最小值或鞍点的问题。鞍点是在所有方向上梯度为零的点。因此,我们的新加坡元将只停留在那里。另一方面,局部最小值是最小 w.r.t .周围的点,但总体上不是最小的。由于梯度在局部最小值处为零,所以当全局最小值在其他地方时,我们的梯度下降会将其报告为最小值。

为了纠正普通梯度下降的问题,近年来开发了几种先进的优化算法。我们将逐一查看。

带动量的随机梯度下降

为了理解高级优化背后的动力,我们首先必须掌握指数加权平均值的概念。假设我们得到了一年 365 天中任何一个特定城市每天的温度数据。绘制它,我们在左上角得到一个图表。

Demonstration of exponentially weighted average

现在,如果我们希望计算全年的当地平均温度*,我们将如下进行。*

**NOTE :-
     alpha = 0.9** is randomly chosen weight.        
     **t(i)**  is temperature at ith day.
     **v(i)**  is average temperature for ith day averaged over **1/(1 - alpha)** days.**v(0) = 0
v(1) = 0.9 * v(0) + 0.1 * t(1)
v(2) = 0.9 * v(1) + 0.1 * t(2)
...
v(i) = alpha * v(i-1) + (1 - alpha) * t(i)**

每天,我们都会计算前一天温度和当天温度的加权平均值。上述计算的曲线图显示在右上角。该图是过去 10 天的平均温度(α= 0.9)。左下角(绿线)显示的是过去 50 天的平均数据图(alpha = 0.98)。

这里需要注意的重要一点是,随着我们对更多天数进行平均,该图对温度变化的敏感度将会降低。相比之下,如果我们对更少的天数进行平均,则该图将对温度变化更加敏感,从而对蠕动行为更加敏感。

这种延迟的增加是由于我们给予前一天的温度比今天的温度更多的权重。

到目前为止一切顺利,但问题是这一切给我们带来了什么。非常类似地,通过平均过去几个值的梯度,我们倾向于减少更敏感方向的振荡,从而使其收敛更快。

实际上,基于动量的优化算法几乎总是比普通梯度下降法更快。数学上,

**moment = 0
for i in range(iterations_count):**          
    **param**_**gradients = evaluate_gradients(loss_function, 
                                         data, 
                                         params)
    moment = gamma * moment +** **param**_**gradients**
    **params** **+= learning_rate * moment
           (where *moment* is building moving average of gradients.
                 *gamma* gives kind of friction = 0.9 or 0.99).**

AdaGrad 优化

这个想法是,对于每个参数,我们存储其所有历史梯度的平方和。这个总数后来被用来衡量学习率。

注意,与之前的优化不同,这里我们对每个参数都有不同的学习率。

**squared_gradients = 0
for i in range(iterations_count):**          
    **param**_**gradients = evaluate_gradients(loss_function, 
                                         data, 
                                         params)
    squared_gradients += param**_**gradients * param**_**gradients
    params -= learning_rate * param**_**gradients/
                         (np.sqrt(squared_gradients) + 1e-8)
                           *{1e-8 is to avoid divide by zero}***

现在的问题是,当我们的损失函数有很高的条件数时,这个标度如何帮助我们?

对于具有高梯度值的参数,平方项将很大,因此除以大项将使梯度在该方向上缓慢加速。类似地,具有低梯度的参数将产生较小的平方项,因此梯度将在该方向加速更快。

但是请注意,由于梯度在每一步都是平方的,移动估计将随时间单调增长,因此我们的算法收敛到最小值所需的步长将越来越小。

从某种意义上说,这对凸问题是有利的,因为在这种情况下,我们应该向最小值减速。然而,随着陷入鞍点的机会增加,在非凸优化问题的情况下,同样的礼物变成了诅咒。

RMSProp 优化

这是 AdaGrad 的一个微小变化,在实践中效果更好,因为它解决了它遗留的问题。类似于 AdaGrad,这里我们也将保持平方梯度的估计,但是不是让平方估计在训练中累积,而是让该估计逐渐衰减。为此,我们将平方梯度的当前估计值乘以衰减率。

**squared_gradients = 0
for i in range(iterations_count):**          
    **param**_**gradients = evaluate_gradients(loss_function, 
                                         data, 
                                         params)
    squared_gradients = decay_rate * squared_gradients + (1 -  
                  decay_rate) * param**_**gradients * param**_**gradients
    params -= learning_rate * param**_**gradients/
                              (np.sqrt(squared_gradients) + 1e-8)**

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

这包含了 RMSProp 和带动量的梯度下降的所有优点。

具体而言,该算法计算梯度和平方梯度的指数移动平均值,而参数β_ 1β_ 2控制这些移动平均值的衰减率。

**first_moment = 0
second_moment = 0
for step in range(iterations_count):
**    **param**_**gradients = evaluate_gradients(loss_function, 
                                         data, 
                                         params)
    first_moment = beta_1 * first_moment + (1 - beta_1) *   
                                                    param**_**gradients
    second_moment = beta_2 * second_moment + (1 - beta_2) * 
                                  param**_**gradients * param**_**gradients**      **
    params -= learning_rate * first_moment/(np.sqrt(second_moment) + 
                                                              1e-8)**

请注意,我们已经将 second_moment 初始化为零。因此,一开始, second_moment 会被计算为非常接近零的某个值。因此,我们通过除以一个很小的数来更新参数,从而对参数进行大的更新。这意味着最初,算法会进行更大的步骤。为了纠正这一点,我们通过合并当前步骤来创建这些一阶和二阶矩无偏估计。然后我们基于这些无偏估计而不是一阶和二阶矩来更新参数。数学上,

**first_moment = 0
second_moment = 0
for step in range(iterations_count):
    param**_**gradients = evaluate_gradients(loss_function, 
                                         data, 
                                         params)
    first_moment = beta_1 * first_moment + (1 - beta_1) *   
                                                    param**_**gradients
    second_moment = beta_2 * second_moment + (1 - beta_2) * 
                                  param**_**gradients * param**_**gradients**      
    **first_bias_correction** = **first_moment/(1 - beta_1 ** step)
    second_bias_correction = second_moment/(1 - beta_2 ** step)
    params -= learning_rate * first_bias_correction/
                           (np.sqrt(second_bias_correction) + 1e-8)**

下图展示了每种优化算法在迭代过程中的性能。显然,增加动量有助于提高精确度。然而,在实践中,众所周知,Adam 在处理大型数据集和复杂特征时表现非常出色。

Performance measure for optimizations

资源

[## RMSprop -优化算法| Coursera

这个课程会教你让深度学习很好工作的“魔法”。而不是深度学习过程…

www.coursera.org](https://www.coursera.org/lecture/deep-neural-network/rmsprop-BhJlm)

更多数学背景可以找这个。请通过你的评论让我知道这篇文章可以容纳的任何修改/改进。

揭开平台运营模式的神秘面纱

原文:https://towardsdatascience.com/demystifying-platforms-operating-model-part-1-2a28108f6a3c?source=collection_archive---------13-----------------------

数据如何推动组织发展?

Photo by Israel Andrade on Unsplash

平台商业模式|是什么?

什么是平台业务?平台是一种商业模式,它通过促进两个或更多相互依赖的群体(通常是消费者和生产者)之间的交流来创造价值。平台企业的例子有优步、苹果、微软、阿里巴巴、脸书和腾讯。

传统企业遵循线性模式,拥有资产负债表中显示的库存,而平台运营模式(POM)只专注于建立和促进网络,而不拥有生产手段。

为什么传统企业如此难以改变?

虽然平台运营模式通过更好的客户体验、更快的交付速度、更短的系统停机时间以及最重要的潜在 10 倍增长,为客户提供了更大的价值,但传统企业在复制技术世界的运营模式时往往会面临一系列独特的挑战。

  • **首先,组织文化和心态可能没有改变。**在传统的直线型组织中,通常有自上而下的审批结构,记分卡分解也是如此。默认情况下,这种结构将组织按照功能&业务单元进行划分。虽然这种职能分离有利于长期规划&问责制,但也可能导致筒仓心态。例如,企业可能会将趋势上商业上可行的&产品概念化,但不一定能在短期内通过技术实现。到交货时,市场条件已经改变,导致资源浪费。
  • **其次,组织的技能&能力可能不适合平台运营环境。**在一些组织中,员工可能不具备为未来做好准备的软技能或硬技能。某些更适合平台模式的技能可能在传统组织中不容易获得。例如,虽然项目管理技能在组织中很常见,但产品管理技能远没有那么突出;产品管理需要从产品的概念化到交付的端到端所有权,这是领导平台所需的核心技能。从本质上讲,其他技能,如数据分析、跨职能协作、敏捷的工作方式,都是直线型公司可能缺乏的领域,但对平台型公司却很重要。
  • 第三,组织结构并不总是支持理想的行为类型。要使转型项目成功,流程&系统必须迎合最终状态目标。例如,如果我们需要业务单位&技术单位跨职能工作,KPI&结果必须在双方之间透明地共享。必须有共同的责任&愿景来推动长期观点&习惯的转变。本质上,如果旧的系统保持不变,它就会成为思维转变的阻碍,因为“正确的”行为不会得到奖励。

为了让飞机安全起飞和降落,生态系统中的各种组件,如机场、训练有素的飞行员、飞机控制、系统必须无缝协作。

同样,要使平台运营模式发挥作用,必须具备成功组织转型的要素,这 3 个关键领域是:

  • 人们:航空公司花费大量的时间&努力训练飞行员操作和驾驶飞机脱离危险的湍流并安全着陆 *。*同样,拥有平台领导者&团队拥有合适的能力、软硬技能来驾驭平台应对市场变化是至关重要的。然而,一个关键的阻碍因素是,在长期拥有中央集权的组织中。即使领导者愿意放弃控制和分散权力,团队也可能因为害怕承担后果而对行使额外的权力和责任感到不舒服。
  • 流程:航空公司对机场要求有国际标准&全球通用的机间通信—** *(如跑道长度要求&所有飞行员都懂的通用行话)。*同样,拥有标准化的交换模式&跨所有组织平台的互动形式,以相互汲取资源并创造价值,是可持续模式的关键。
  • 技术: 为了支持航空公司的日常运营,航空公司为机场的&飞机配备了必要的工具来降低日常风险——提高面对不利条件时的弹性***——(例如自动驾驶&天气预报工具)。*同样,包括技术堆栈在内的组织架构必须充分支持业务目标&在面临不确定性时具有足够的适应性。

从本质上来说,人员、流程和技术的到位是增加整个组织的信息流以改善业务决策的使能因素(外部)& 优化流程*(内部)。*

在本文的第二部分,我将详细阐述数据规范在实现这些目标中是如何重要的。

正确的数据工具如何推动转型?

有人可能会认为组织转型和数据之间没有直接的联系,但这种想法并不正确。**数据驱动转型如果执行得当,可以加速组织变革。**例如,通过测量敏捷指标作为团队绩效的代理,并将其嵌入到团队的 KPI 中,它迫使领导者&团队意识到他们是如何工作的,以及他们是否以有效的方式工作&敏捷。

此外,在整个公司的计划中使用数据工具标志着公司致力于数据驱动——间接来说,这有助于利用网络效应来逐渐改变心态——特别是对于 FOMO 的高管来说。

在大多数先进技术公司中,聊天机器人、网站可靠性工程、数据可视化、错误预算和网络分析等热门词汇经常被提及,产品是根据这些原则制造的。当整个公司的团队使用正确的语言时,这清楚地表明了对数据驱动的承诺。

**最后,拥有一个标准化的交换模式&跨平台交互以从彼此获取资源是极其重要的。**为了在平台世界中有效地创造价值,领导者需要对待办事项有一定的了解,以便根据平台业务目标对工作进行优先排序。透明度必须从团队级别开始,然后到平台级别,最后跨平台,以促进资源利用。有许多工具&方法有助于支持此类任务,例如(JIRA、计划者、看板板、Wonderwall)。当透明性存在时,组织就可以期待拥有正确的跨平台交互系统。

有了合适的人员、流程和技术,组织可以实现 3 个目标:

  1. 跨平台互动带来的一流产品创新&快速数据可用性。例如,亚马逊等领先的平台创新者正在通过测试车辆交付,优化向不断变化的地点的交付,将快速数据提升到一个新的水平。这涉及到高度关联的跨职能物流&分析团队的能力,以协调能够交付此类结果的流程。

  2. 管理良好的生态系统平衡供给&需求。拥有有效的流程在生态系统中构建了一个强大的反馈回路,可以自我优化&做出自动化决策。例如,优步的激增定价是一个很好的案例,通过在任何给定时间找到正确的定价模式来平衡消费者和司机。

  3. **最后,也许整个转变最重要的目标是改善客户体验。**通过干预来解决阻碍因素,it 寻求实现更高的客户满意度。例如,联邦快递使用交通数据来确定最佳递送路线,以便及时将包裹送到客户手中,从而减少延迟时间。

而平台业务模式有可能帮助传统业务实现 10 倍的增长。这需要对传统思维进行重大改造,包括打破功能孤岛,专注于产品并建立正确的架构,这对于转型团队来说绝非易事。

揭开量子门的神秘面纱——一次一个量子位

原文:https://towardsdatascience.com/demystifying-quantum-gates-one-qubit-at-a-time-54404ed80640?source=collection_archive---------2-----------------------

(我已经写了一篇关于量子计算的介绍,在这里可以找到。如果你是这个领域的新手,这将是一个更好的起点。)

如果你想进入量子计算领域,没有别的路可走:你必须掌握量子门的模糊概念。像量子计算中的一切一样,更不用说量子力学了,量子门被笼罩在一层不熟悉的术语和矩阵数学的迷雾中,这反映了量子的神秘。我在这篇文章中的目标是揭开这个神秘的面纱。不过我给你省点悬念:没人能完全摆脱。至少,2018 年不会。我们今天所能做的就是揭示经典门和量子门之间惊人的相似性和惊人的差异,并探索对计算的近未来和远未来的影响。

经典 vs 量子门:比较不可比?

惊人的相似

不说别的,经典逻辑门和量子逻辑门都是逻辑门。那我们就从这里开始吧。逻辑门,无论是经典的还是量子的,都是任何一种物理结构或系统,它接受一组二进制输入(无论是 0 和 1,苹果和橙子,自旋向上的电子和自旋向下的电子,随便你怎么说),并吐出一个二进制输出:1,橙色,自旋向上的电子,甚至是两个叠加态中的一个。控制输出的是一个布尔函数。这听起来很奇怪也很不祥,但相信我,不是的。你可以把一个布尔函数想象成仅仅是一个如何回答是/否问题的规则。就这么简单。然后,这些门被组合成电路,这些电路被组合成 CPU 或其他计算组件。无论我们谈论的是巴贝奇的差异引擎、 ENIAC 、退役国际象棋冠军深蓝,还是最新的满屋爆满、令人不寒而栗、头条新闻量子计算机,都是如此。

惊人的差异

经典门对经典位进行操作,量子门对量子位*(量子位)进行操作。这意味着量子门可以利用经典门完全无法实现的量子力学的两个关键方面:叠加纠缠*。这是你在量子计算环境中最常听到的两个概念,下面是为什么是。但是有一个不太为人所知的概念可能同样重要:可逆性。简单来说,量子门是可逆的。随着你对量子计算的深入研究,你会学到很多关于可逆性的东西,所以这是值得深入研究的。现在,你可以这样想——所有量子门都有一个撤销按钮,而许多经典门没有,至少现在还没有。这意味着,至少在原则上,量子门永远不会丢失信息。在进入量子门的过程中纠缠的量子位在出去的过程中保持纠缠,在整个转换过程中保持信息安全密封。另一方面,在传统计算机中发现的许多经典门确实丢失了信息,因此不能追溯它们的步骤。有趣的是,这些信息最终并没有消失在宇宙中,而是作为经典计算机中的热量渗透到了你的房间或膝盖上。

v 代表矢量

谈量子门不能不谈矩阵,谈矩阵不能不谈向量。所以让我们继续吧。在量子力学和计算的语言中,向量被描述在一个公认的非常奇怪的包中,称为 *ket,*它来自单词 *braket 的后半部分。他们看起来很像。这里有一个 ket 向量: **|u >,*其中 u 表示向量中的值。首先,我们将使用两个 kets, |0 >|1 > ,它们将代替处于自旋向上( |0 > )和自旋向下( |1 > )状态的电子形式的量子位。可以说,这些向量可以跨越任意数量的数字。但是在二进制状态的情况下,比如自旋向上/向下的电子量子位,它们只有两个。因此,它们看起来不像高耸的列向量,而是像两层堆叠的数字。下面是 |0 > 的样子:

*/ 1 *

\ 0 /

现在,门/矩阵所做的是这些状态、这些向量、这些数据集、这些数字列转换成全新的状态。例如,一个门可以像变魔术一样把一个上升状态( |0 > )变成下降状态( |1 > ):

*/ 1 * → */ 0 *

\ 0/\ 1/

m 代表矩阵

这种从一个向量到另一个向量的转换是通过矩阵乘法这种鲜为人知的魔法来实现的,这与我们在前量子学校学过的乘法完全不同。然而,一旦你掌握了这种数学的窍门,那将是非常有益的,因为你可以一次又一次地将它应用到无数原本难以理解的方程中,而这些方程会让门外汉们目瞪口呆。如果你需要更多的动力,只要记住海森堡是通过矩阵数学的语言解开了无所不包的测不准原理的秘密。

尽管如此,如果你不熟悉这个数学工具的喷射燃料,如果我在这里开始用大的数字方阵填充这个帖子,你的眼睛会变得呆滞。我们不能让这种情况发生。因此,让我们再等几段时间来学习矩阵数学和符号。现在可以说,我们通常用一个矩阵来代替量子门。矩阵的大小和完全的恐惧因素将取决于它所操作的量子位的数量。如果只有一个量子位需要转换,这个矩阵将会非常简单,仅仅是一个有四个元素的 2 x 2 阵列。但是矩阵的大小超过了具有两个、三个或更多量子位的。这是因为一个绝对值得记忆的指数方程决定了矩阵的大小(从而决定了量子门的复杂程度):

2^n x 2^n = the total number of matrix elements

这里, n 是量子门操作的量子位的数量。正如你所看到的,这个数字随着量子比特数(n)的增加而上升。一个量子位就是 4。加上两个,就是 16 个。加上三个,就是 64 个。有了四个,就…没希望了。所以现在,我坚持一个量子位,它上面写满了泡利

保利门

泡利门是以沃尔夫冈·泡利的名字命名的,他不仅有一个很酷的名字,而且成功地使自己在现代物理学的两个最著名的原理中永垂不朽:著名的泡利不相容原理和可怕的泡利效应。

泡利门基于更广为人知的泡利矩阵(又名泡利自旋矩阵),这对于计算单个电子的自旋变化非常有用。由于在今天的量子门中,电子自旋是量子位最受欢迎的属性,泡利矩阵和门正好符合我们的胃口。在任何情况下,对于空间中的每个轴(X、Y 和 Z ),本质上都有一个泡利门/矩阵。

所以你可以想象它们中的每一个都有能力改变电子在三维空间中相对应的轴的旋转方向。当然,像量子世界中的其他一切一样,这里有一个陷阱:这是而不是我们普通的 3D 空间,因为它包括一个虚拟维度。但是我们暂时不要去想它,好吗?

幸运的是,泡利门是你见过的最简单的量子门。(至少 X 门和 Z 门是。Y 有点奇怪。)所以即使你一生中从未见过矩阵,泡利也让它们变得可管理。他的门作用于一个量子位,而且一次只能作用于一个量子位。这转化为简单的 2 x 2 矩阵,每个矩阵只有 4 个元素。

泡利 X 门

对于那些害怕矩阵数学的人来说,Pauli X-gate 是梦想成真。没有虚数。没有负号。还有一个简单的操作:*否定。*这很自然,因为泡利 X 门对应的是经典的非门。由于这个原因,X 门通常也被称为量子非门。

在实际的真实世界设置中,X-gate 通常将电子的自旋向上状态 |0 > 变为自旋向下状态 |1 > ,反之亦然。

**|0>**   -->   **|1>**   OR   **|1>** --> **|0>**

大写的“X”通常代表泡利 X 门或矩阵本身。下面是 X 的样子:

*/ 0 1 *

\ 1 0 /

就正确的符号而言,将量子门应用于量子位就是将一个 ket 向量乘以一个矩阵。在这种情况下,我们将自旋 ket 矢量 |0 > 乘以泡利 X 门或矩阵 X 。下面是 X|0 > 的样子:

*/ 0 1 \ /1*

\ 1 0 / \0/

注意你总是把矩阵放在偈的左边。你可能听说过,矩阵乘法与普通乘法不同,它没有交换、,这违背了我们在学校里所学的一切*。就好像 2 x 4 是而不是*总是等于 4 x 2。但矩阵乘法就是这样,一旦你掌握了窍门,你就知道为什么了。与此同时,记住所有重要的元素排序,将量子非门应用于我们的量子位(在这种情况下是电子的自旋状态)的完整符号如下所示:

X | 0>=/0 1 /1 \ =/0 \ = | 1>

\ 1 0 / \0/ \1/

应用于 spin- down 向量,完整的符号如下所示:

X | 1>=/0 1 /0 \ =/1 \ = | 0>

\ 1 0 / \1/ \0/

尽管所有的外来符号,在这两种情况下,这里实际发生的是,单个电子形式的量子位通过量子门,从另一侧出来,自旋完全翻转。

泡利 Y 门和 Z 门

我就不跟你讲这两个的数学了。但你至少应该顺便了解一下他们。

在三个泡利门中,泡利 Y 门是最奇特的一个。它看起来很像 X 门,但是用一个 i (是的,疯狂的-1 的平方根)代替了常规的 1,并且在右上角有一个负号。这是 Y 的样子:

*/ 0 -i *

\ i 0 /

泡利 Z 门更容易理解。它看起来有点像上面 X 门的镜像,但是混合了一个负号。下面是 Z 的样子:

*/ 1 0 *

\ 0 -1 /

Y 门和 Z 门也改变了我们量子位电子的自旋。但是我可能需要深入到布洛赫球的深奥的秘密中去真正解释如何,而且我现在有另一个门要通过…

哈达玛门

虽然泡利门在某些方面很像经典逻辑门,但哈达玛门,或称 H 门,是真正的量子怪兽。它在量子计算中无处不在,而且理由充分。阿达玛门具有典型的量子能力,可以将一个确定的量子状态,比如自旋向上,转变成一个模糊的状态,比如同时自旋向上和自旋向下的叠加。

一旦你发送一个自旋向上或自旋向下的电子通过 H 门,它将变得像一枚竖立的硬币,当被倾倒和测量时,它将以 50/50 的概率结束正面(自旋向上)或反面(自旋向下)。这种 H-gate 对于执行任何量子程序中的第一次计算都非常有用,因为它将预设或初始化的量子位转换回它们的自然流体状态,以便利用它们的全部量子能力。

其他量子门

你肯定会遇到许多其他的量子门。它们中的许多一次操作几个量子位,导致具有复数元素的 4x4 甚至 8x8 矩阵。如果你还没有掌握一些重要的黑客帝国技能,这些就相当危险了。所以我就不告诉你细节了。

您希望熟悉的主要大门是我们在下图中介绍过的大门:

你应该知道存在其他的门,所以这里有一个最广泛使用的其他量子门的快速列表,这样你就可以对术语有一个感觉:

  • 托弗利门
  • 德国之门
  • 交换门(和交换门平方根)
  • 非门平方根
  • 受控非门和其它受控门

还有很多。但是不要让数字欺骗了你。正如你可以用 NOT +或= NOR 门AND + NOT= NAND 门的组合来执行任何经典计算一样,你可以将量子门的列表简化为一组简单的通用量子门。但是我们会把契约留到下一天。

透过量子门凝视未来

正如最近量子杂志的一篇文章指出的,2018 年的量子计算机还没有准备好迎接黄金时代。在他们步入拥有数十亿倍逻辑门的经典计算机的世界之前,他们需要面对一些自己的恶魔。最致命的大概就是退相干的恶魔了。现在,量子退相干将在“几微秒”内摧毁你的量子计算。然而,你的量子门执行操作的速度越快,你的量子算法就越有可能将退相干的恶魔击败到终点线,这场比赛就越长。除了速度,另一个重要因素是量子门完成一次计算所需的运算数量。这被称为计算的深度。因此,另一个当前的任务是深化量子领域。按照这种逻辑,随着快速发展的量子计算机变得更快,它的计算更深入,退相干倒计时更长,经典计算机最终会发现自己在(很可能)不太远的将来面临一个可怕的挑战者,如果不是继任者的话。

如果你喜欢这篇文章,我会非常兴奋,如果你点击拍手按钮:)或与你好奇的朋友分享。我在我的个人博客(jasonroell.com)上有更多类似的东西,或者你可以订阅我的媒体简介,让我一写完文章就发给你!(多牛逼?!)

无论如何,再次感谢你的阅读祝你有美好的一天!

揭开统计分析 1 的神秘面纱:一份方便的备忘单

原文:https://towardsdatascience.com/demystifying-statistical-analysis-1-a-handy-cheat-sheet-b6229bf992cf?source=collection_archive---------8-----------------------

选择使用的统计分析主要取决于数据集中的变量类型、需要进行分析的变量数量以及变量中的级别/类别数量。只要我们对正在处理的数据有很好的理解,选择使用的统计分析就不应该太令人生畏。

我一直想知道,为什么大多数统计教科书没有一个表格,汇总所有不同的统计分析,它们如何相互关联,以及何时使用它们。在互联网上快速搜索发现了许多类似的小抄,但没有一个以直观的方式呈现信息。

在我创建的备忘单中,行代表不同类型的自变量(也称为预测值或协变量),而列代表不同类型的因变量(也称为标准或测量值)。然后,行和列的交叉点指示要使用的适当分析,每个分析下面的小文本显示了在 SPSS 中执行分析的快速步骤。

这篇文章是揭开统计分析神秘面纱系列文章的第一篇,我希望通过描绘不同统计分析之间的联系以及解释它们之间的差异,帮助简化对统计分析的理解。

后续帖子已经在 媒体发布

[## 揭秘统计分析 2:用线性回归表示的独立 t 检验

组比较分析,如独立 t 检验和方差分析可能看起来与线性回归很不一样,但…

medium.com](https://medium.com/@wyess/demystifying-statistical-analysis-2-the-independent-t-test-expressed-in-linear-regression-434a3b302289) [## 揭秘统计分析 3:用线性回归表示的单因素方差分析

在本系列的前一部分中,我们研究了如何在线性回归中表达独立 t 检验…

medium.com](https://medium.com/@wyess/demystifying-statistical-analysis-3-the-one-way-anova-expressed-in-linear-regression-99269e84edd9) [## 揭秘统计分析 4:用线性回归表示的因子方差分析

本系列的前一部分介绍了单向 ANOVA,我解释了如何进行分析…

medium.com](https://medium.com/@wyess/demystifying-statistical-analysis-4-the-factorial-anova-expressed-in-linear-regression-2e1920893ff0) [## 揭秘统计分析 5:以线性回归表示的协方差

本系列的前一部分展示了当超过……时,如何在线性回归中表达阶乘方差分析

medium.com](https://medium.com/@wyess/demystifying-statistical-analysis-5-the-ancova-expressed-in-linear-regression-2996073f9f79)

原发布于:https://learn curily . WordPress . com/2018/08/23/statistical-analysis-cheat-sheet

揭秘统计分析 6:调节与调解

原文:https://towardsdatascience.com/demystifying-statistical-analysis-6-moderation-mediation-why-are-they-even-paired-together-2429466a54fa?source=collection_archive---------16-----------------------

为什么它们会配对在一起?!

区分“适度”和“中介”这两个词,是很多学生学习统计学的命根子。因为这两种分析处理的是无关变量,而且它们听起来非常相似,所以人们经常把它们混淆在一起。但是如果我们揭示了每种分析的本质,它们的差异会变得如此明显,以至于你甚至会想为什么它们总是被配对在一起。在我们深入分析每种分析的作用之前,我希望下面的句子有助于形成如何以最简单的方式区分它们的基础:

  • 信不信由你, 适度测试 仅仅是检查是否存在互动效应,仅此而已。
  • 另一方面,中介 测试 至少需要一个稍微复杂一点的模型比较方法来检查因果关系。

适度

“适度分析怎么会和互动效果测试一样呢?!"你可能会问,如果它们是相同的,那么为什么要有两个不同的术语呢?这种情况在统计术语中很常见,正如我们在 ANCOVA 关于预测值与协变量的讨论中所看到的。事实上,这篇文章阐述了我试图说明的同一点,即“关于统计分析,最令人困惑的事情之一是使用不同的词汇来描述相同的或几乎相同但不完全相同的概念”。

当我们说年龄是性别的调节变量时,无论我们使用年龄作为分类预测因子(儿童对成人)还是连续变量,我们期望看到的是性别对因变量ŷi的影响因年龄值的不同而不同(示例可在 ANCOVA 帖子中找到)。为了测试这种适度性,需要在分析中引入性别和年龄之间的交互变量。如果交互作用变量的斜率是显著的,年龄被认为是性别的调节变量。因此,测试适度性所需要的只是知道如何构建交互项,以及如何进行交互分析(例如,在多元线性回归中,因子 ANOVA 或 ANCOVA )。

实质上,“相互作用”这个术语是一个更广泛的概念,它没有定义不同自变量之间的关系。它没有区分感兴趣的预测因素、预测因素和协变量、或预测因素和调节因素之间的分析。然而,术语“调节”更具体地表明调节子是一个确定的无关变量,它与感兴趣的预测因子有一个假设的相互作用效应。通过这种推理,协变量和调节变量在某种意义上是不同的,虽然两者都是不需要的变量,但都被认为是存在的,调节变量被假设为与感兴趣的预测因子相互作用,但协变量可能会也可能不会。

调解

虽然中介分析也处理外来变量,但它采用了完全不同的方法,与交互分析没有什么关系。它的目的是在无关变量存在的情况下,确定自变量对因变量的因果关系。测试中介的最简单方法是通过 3 个模型的比较。

中介分析的典型场景通常始于已建立的显著关系,如因变量ŷi(c 路径)的简单性别回归,但年龄等外部变量被假设为中介变量(见下图,考虑中介时,c '-路径代表 c-路径)。

Path relationships in the analysis of independent variable “Gender” on dependent variable Ŷi, with “Age” as a mediating variable.

我们首先需要证明性别对年龄的简单回归(a 路径)是显著的,然后证明性别(c 路径)和年龄(b 路径)对因变量ŷi的多重回归导致 c 路径变得不显著,而 b 路径仍然是显著的。这被称为调解测试的偶然步骤程序,但是其结果具有非常低的效力,因为没有考虑 a 路径对 b 路径的间接影响,并且 c’路径仅在完全调解的情况下变得不重要。因此,该程序通常由其他统计测试来补充。

最容易进行的测试之一是 Sobel-Aroian 测试,它利用了 a 路径和 b 路径的回归系数( b )和标准误差(se)(当年龄随着因变量ŷi的性别而回归时)。使用以下公式计算 a 路径对 b 路径的间接影响的Z-得分:

如果p-Z-得分的值小于. 05,则存在 a 路径对 b 路径的间接影响,并且存在中介。为了方便起见,您可以使用这个计算器进行索贝尔-阿罗里安测试。

索贝尔-阿罗里安试验是一种快速简便的方法,只适用于大样本的简单调解。对于更复杂的中介分析,通常推荐使用自举或结构方程模型(SEM)。


我希望上面的解释有助于阐明“适度”和“调解”之间的明显区别,并一劳永逸地解决混淆。但是,除了理解这些术语的真正含义之外,研究人员能够用简单的术语解释他们选择的分析类型如何能够实现他们试图找到的结果,而不是随便抛出统计术语,试图听起来复杂,这也是有帮助的。事实上,通常最简单的分析类型会产生最有趣和最容易解释的发现。

最初发布于:https://learn culily . WordPress . com/2018/09/29/moderation-and-mediation

揭秘统计分析 7:数据转换和非参数检验

原文:https://towardsdatascience.com/demystifying-statistical-analysis-7-data-transformations-and-non-parametric-tests-7c02cc4c8168?source=collection_archive---------17-----------------------

在阅读这篇文章的标题时,有些人可能想知道为什么“数据转换”和“非参数测试”会在同一篇文章中同时出现。非参数测试通常与参数测试一起介绍,但是当我在本系列开始时分享了一个关于统计分析的备忘单时,我似乎把它们遗漏了。这种排除是有意的,我将在本帖中解释非参数测试实际上如何与数据转换相关联。

数据转换

进行参数测试时,通常假设:

  • 数据呈正态分布
  • 误差方差是常数
  • 误差是独立的
  • 预测值不相关
  • 数据中的关系是线性的

然而,这些假设并不总是适用于我们试图分析的数据,因此可以进行某些转换来帮助数据符合这些假设,以便使用通常的参数测试。

在之前关于单向方差分析的一篇文章中,展示了如何使用对比代码来测试有序分类预测符中潜在的多项式关系。因此,连续预测值也不一定与其因变量成线性关系也就不足为奇了。在这种情况下,可以使用电源转换。通过在回归模型中加入连续预测值的 Xi 项,b-系数将是对是否存在二次关系的检验;同样,增加的 Xi 项的b-系数将是对是否存在三次关系的检验。高阶项也可以包括在内,但它们变得越来越难以解释。

对于其他类型的场景,可以使用不同的转换:

Types of transformations with their respective formulae and type of data that they are used for.

到目前为止所描述的变换是在预测器上完成的,但是也可以变换因变量的值。从本质上讲,为数据集找到正确的转换是一个反复试验的过程。事实上,在每次转换后,重新绘制可视化数据并进行必要的统计测试以检查假设是否仍然违反,这是一个很好的实践。

非参数检验

当数据不是正态分布时,通常使用非参数检验。这些测试被认为是一种转换,因为除了数据被转换为从最低值到最高值的等级(1,2,3,…)之外,它们基本上等同于它们的参数对应项。然而,当数据经历等级变换时,诸如数据点的方差之类的重要信息会丢失。这就做了一个强有力的假设,即数据点是有意义地有序的,即使它们实际上彼此接近并且没有太大的变化。非参数检验也与均值和方差的报告不兼容,但这可以用中位数的报告来代替。

教材《数据分析:一种模型比较方法》的作者凯里·瑞安、查尔斯·m·贾德和加里·h·麦克莱兰甚至走得更远*“不推荐非参数程序”。他们认为“如果人们认识到大多数非参数程序只是应用于已进行秩变换的数据的参数程序,那么很明显,如果有更好的变换,在更可能处理非正态性和异质性方差问题的意义上更好,那么这些应该用来代替非参数统计程序”*。尽管如此,这篇博客概述了使用非参数测试的一些原因:

  1. 你的样本量很小。
  2. 您有无法移除的序数数据、等级数据或异常值。
  3. 你的研究领域最好用中位数来代表。

本质上,如果有可能通过其他类型的转换来解决假设违反,那么避免使用非参数测试可能会更好。但是由于在小样本的研究中我们无能为力,所以非参数检验常常成为唯一的选择。

为了那些仍然需要使用非参数测试的人,我创建了一个备忘单来为数据集中的每种类型的预测值选择非参数分析,在 SPSS 中执行分析的快速步骤,以及将非参数测试与它们的等效参数进行比较:


我希望这篇文章有助于解决非参数测试到底是什么,它们实际上如何与数据转换相关,以及为什么在数据不是正态分布的情况下没有必要使用它们。

有关参数测试的备忘单,请访问以下链接:

[## 揭开统计分析 1 的神秘面纱:一份方便的备忘单

统计分析方法的选择主要取决于数据集中变量的类型,变量的数量…

towardsdatascience.com](/demystifying-statistical-analysis-1-a-handy-cheat-sheet-b6229bf992cf)

最初发布于:https://learn curely . WordPress . com/2018/10/06/data-transformations-and-nonparametric-tests

登革热及如何预测

原文:https://towardsdatascience.com/dengue-fever-and-how-to-predict-it-a32eab1dbb18?source=collection_archive---------11-----------------------

介绍

作为我的期末项目,我决定用更先进的数据科学技能重新审视机器学习竞赛。我选择预测波多黎各圣胡安和秘鲁伊基托斯的登革热病例是因为它对全球健康的影响,部分原因是我想改进我在芝加哥的西尼罗河项目的方法。

那么,为什么是登革热呢?在全球健康范围内,登革热是一种重要但有时被忽视的疾病,估计每年影响5000-1000 万人,并在全球造成近 90 亿美元的损失。在秘鲁,2016 年报告的病例超过 27,000 例,在波多黎各,2010 年报告的病例超过 26,000 例。

使用神经网络和回归模型的组合,我能够适度地预测登革热病例,并对一些关键的预测因素有所了解。

数据

这个项目的数据是从 DrivenData.org 下载的,作为他们“邓艾:预测疾病传播”挑战的一部分。除了每个地点的病例数,数据还包括温度、降水、湿度、植被以及数据获取时间等信息(完整的特征列表可在此处找到)。在所提供的数据中,我需要仔细观察的唯一特征是卫星植被,我了解到这基本上是一个给定区域的“绿色”指数,基于对植物光辐射的卫星测量的计算。例如:

https://en.wikipedia.org/wiki/Normalized_difference_vegetation_index#/media/File:NDVI_062003.png

这些数据还包含大量的空值。我没有删除所有的空值,而是只删除了最差的列(ndvi_ne,城市质心东北方向的植被指数像素)中的空值,总共 1450 行中的大约 200 行,并用该列同一周的平均值填充其余的缺失数据。在这里,我假设,例如,1995 年的第 36 周在天气特征方面与 1998 年的第 36 周相似。

我还尝试根据城市将数据集分成两个不同的数据集,这样信息就不会从圣胡安流向伊基托斯,并假设每个城市相似的天气条件会导致蚊子的数量明显不同。不幸的是,分割数据实际上使我的预测更糟糕,可能是因为它将每个模型的可用数据减半。因此,我的最终模型使用了一个组合数据集,尽管使用更强的模型,我仍然想尝试分离城市,因为我认为这个假设仍然有效。

建模和结果

我在建模过程中的第一直觉是建立一个神经网络,这起初看起来几乎像是一颗银弹。但在我能为我的第一个模型打分之前,我遇到了一个障碍:

Submitting is as easy as 1, 2, 3… 4… 5… 6…

可怕的提交格式!幸运的是,由于我巨大的编码能力,我能够编写一个函数来接受一个模型,并以一个漂亮的、准备好提交的 CSV 格式输出预测。

解决了这个问题,我终于可以给我的神奇神经网络打分了。不幸的是,他们并不完全符合我自己的宣传。我的第一个模型是用 Keras 制作的,表现仅仅是 ok,产生一个平均绝对误差,MAE 从现在开始是 29.6(作为参考,DrivenData 上最好的分数是 13 MAE)。幸运的是,这个特别的项目受益于无限提交!嗯,有一点点限制,准确的说是每天 3 个。正因为如此,我不得不在如何生成预测时使用一点战术。那时我偶然发现了一个叫做 Talos 的 Python 包,它是专门为优化 Keras 中的超参数而构建的,本质上像神经网络的 GridSearch 一样工作。

Various neural nets and their scores

分数方面,我所有的神经网络都归结为“30 分左右”。对于标签上的一点澄清,“poly-weather”表示使用从天气预报器设计的多项式特征,“cleaning”表示 ndvi_ne 空值是填充(1)还是丢弃(2),“tuned/early”分别表示使用 Talos 和 early stopping,“adjusted”是指当我不科学地从每个预测中减去 1 时,因为我似乎无法让我的模型预测 0。总的来说,我创建的每个模型都是过度拟合的,测试 MAE 和维持 MAE 之间通常相差 15 个点。

在感觉我已经尝试了足够数量的神经网络预测以确保下一组预测也将具有“大约 30”的分数之后,我决定研究其他方法。虽然我肯定想努力提高我的分数,但我也想尝试一些更容易理解的东西;能够预测登革热病例是一回事,但下一步将是确定哪些特征对该疾病的发病率最重要。为了解决这个双重目标,我将 pipeline 与 GridSearch 结合起来,一次尝试多个不同的模型和参数:

Thanks to my friend William “Mac” McCarthy!

在这些新模型中,random forest 表现最佳,MAE 为 26.1,提高了四个百分点!紧随其后的是 bagging 回归因子,为 26.5,其次是 K 近邻,为 30.2。我最终没有提交 AdaBoost,因为训练/测试分割分数太差了,比其他人高 15 分左右。为了看一些更有解释力的东西,我决定把重点放在套索模型(得分 34.3)。

LASSO coefficients

值得一提的是,对于这些模型,我使用神经网络将各个植被指数合并成一个单一的(拼写错误的)预测指数。一般来说,系数较大的特征(因此预测能力较强)并不令人惊讶,因为年份、一年中的周数、降水量和最低气温对模型有重大影响。植被指数也是一个强大的预测因子,因此未来的一步可能是再次将其分离出来,并研究如何解释 NDVI 本身。众所周知,TDTR 代表时域热反射率,这是你可能必须亲自调查的事情。

最后的想法

虽然我对我在这个项目过程中所创造和学到的东西非常满意,但为了追求更准确的预测和更好的分数,仍然有很多东西要尝试,而且在撰写本文时比赛还剩 7 周,时间也很充裕!我认为首先要解决的最重要的问题是我的模型中大量的过度拟合,我可以通过限制神经网络特征的数量来解决这个问题。我还认为尝试提出一些基于人口密度、医疗保健支出或治疗方法数据的全新特征是值得的,看看它们是否会比一些较弱的预测指标更有效。

期待在几周内再次访问这个项目,但现在感谢阅读!

降噪自动编码器解释

原文:https://towardsdatascience.com/denoising-autoencoders-explained-dbb82467fc2?source=collection_archive---------2-----------------------

上个月,我写了关于变型自动编码器和它们的一些用例。这次,我将看看另一种类型的自动编码器:去噪自动编码器,它能够重建损坏的数据。

自动编码器是通常用于特征选择和提取的神经网络。然而,当隐藏层中的节点多于输入时,网络冒着学习所谓的“恒等函数”(也称为“空函数”)的风险,这意味着输出等于输入,标志着自动编码器无用。

去噪自动编码器通过随机将一些输入值归零来故意破坏数据,从而解决了这个问题。通常,被设置为零的输入节点的百分比约为 50%。其他资料显示,这个数字可能更低,比如 30%。这取决于您拥有的数据量和输入节点。

Architecture of a DAE. Copyright by Kirill Eremenko (Deep Learning A-Z™: Hands-On Artificial Neural Networks)

计算损失函数时,重要的是将输出值与原始输入进行比较,而不是与损坏的输入进行比较。这样,就消除了学习身份函数而不是提取特征的风险。

opendeep.org发布了一个很棒的实现,他们使用 Theano 构建了一个非常基本的去噪自动编码器,并在 MNIST 数据集上训练它。OpenDeep 文章非常基础,是为初学者编写的。因此,即使您没有太多关于神经网络的经验,这篇文章也绝对值得一读!

Original input, corrupted data and reconstructed data. Copyright by opendeep.org.

去噪自动编码器是特征选择和提取的重要和关键工具,现在你知道它是什么了吧!享受并感谢阅读!

用带交互代码的神经网络去噪 CT 扫描第 3 部分,卷积残差神经网络[带 TF 的手动反推]

原文:https://towardsdatascience.com/denosing-lung-ct-scans-using-neural-networks-with-interactive-code-part-3-convolutional-residual-6dbb36b28be?source=collection_archive---------9-----------------------

Image from Pixel Bay

因此,由于我将使用大量的图像数据,我将转移到 Tensorflow 来利用 GPU 的力量。不过,不用担心,我们将实现所有的反向传播。(也将最终结果与自动微分进行比较)。由于期中考试,我不能做太多,所以我想到了简单的卷积残差神经网络。

最后,为了好玩,让我们使用不同类型的反向传播来比较什么给我们最好的结果。我们将要使用的不同类型的反向传播是…

a.扩张反向传播

注:所有的 DICOM 图像均来自 癌症影像存档网 ,如果您打算使用这些数据,请查阅他们的数据使用年龄政策。具体来说,我将使用来自 的 DICOM 图像和【FDA】数据集。

残留块

Front and Side View of Residual Block

红圈 →输入到残差块
绿圈 →输入上的卷积运算
蓝圈 →卷积运算后应用的激活函数
黑圈 →激活层 后应用 残差函数并将值传递给下一个块。(这在输入值和计算值之间建立了直接联系。)

在深入研究网络架构之前,我将先解释一下我们网络的剩余块。我们的网络将会有剩余的块,在这些层里面将会看起来像上面一样。还有一件非常重要的事情我想在这里说明一下。

残差函数可以是 1。乘法 2。附加 3。两者的混合物。

记住这一点,让我们看看代码,下面是一个剩余块的屏幕截图,用乘法作为剩余函数。

网络架构/前馈操作

黑色方块 →带噪声的 CT 肺部扫描输入图像
粉色方块 →去噪后的 CT 肺部扫描输出图像
其他块 →不同通道数的剩余块

因此前馈操作非常简单易懂,没有什么特别之处。

剩余函数 1 2

Feed Forward Operation with Residual Function 1

Feed Forward Operation with Residual Function 2

如上所述,(也正如我提到的)我们可以使用乘法或加法或两者的结合。在这个实验中,我要么用乘法,要么用加法加乘法。

标准/扩张反向传播

Standard Back Propagation

Densely Connected Dilated Back Propagation

黄色箭头 →标准梯度流
隔色箭头 →扩张梯度流

这里我们将使用扩张反向传播,看看它如何影响整体去噪操作。并与自动微分反向传播算法进行了比较。

案例 1:手动 ADAM 反向传播残差函数 1

在这里,我使用了残差函数 1 和带有 ADAM 优化器的标准手动反向传播。网络似乎过滤掉了噪声,但是整体图像丢失了太多信息。

另外,请注意每张 GIF 都有不同数量的通道或激活功能,请点击这里进入我的 Github 页面。

情况 2:手动 ADAM 反向传播残差函数 2

在这里,我使用了残差函数 2 和 ADAM optimizer 的标准手动反向传播。我认为这是一个彻底的失败,因为图像的“去噪”版本只是一片漆黑。

另外,请注意每张 GIF 都有不同数量的通道或激活功能,请点击这里查看我的 Github 页面。

情况 3:手动扩张 ADAM 反向传播的残差函数 2

这里我使用了具有密集连接的扩张反向传播的剩余函数 2。现在最下面的 GIF 看起来效果还算不错。唯一的问题是,图像丢失了太多有用的信息。

另外,请注意每张 GIF 都有不同数量的通道或激活功能,请点击这里查看我的 Github 页面。

情况 4:具有自动差分反向传播的残差函数 2

奇怪的是,当让 Tensorflow 为我们做反向传播时。似乎这个模型什么也没做。相当奇怪的行为,或者我做错了什么。(如果你在我的代码中发现错误,请在下面评论。)

另外,请注意每张 GIF 都有不同数量的通道或激活功能,请点击这里查看我的 Github 页面。

互动码

我搬到了谷歌 Colab 寻找交互代码!所以你需要一个谷歌帐户来查看代码,你也不能在谷歌实验室运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要访问案例 1 的代码,请点击此处。
要访问案例 2 的代码,请点击此处。(注意,我无法在 Google Colab 上分配足够的内存,所以我无法在线训练。)
要访问案例 3 的代码,请点击此处。(注意,我无法在 Google Colab 上分配足够的内存,所以我无法在线训练。)
要访问案例 4 的代码,请点击此处。(注意,我无法在 Google Colab 上分配足够的内存,所以我无法进行在线训练。)

更新:3 月 1 日→所以忘了归一化最终输出 LOL 抱歉这是个如此业余的错误。这就是为什么图像看起来这么黑。我的主管建议查一下这个。通过适当的标准化,我能够获得扩张反向传播的结果。

最后的话

在此之前,我实际上尝试了不同的模型,如香草甘,自动编码器甘和所有卷积甘,但他们实际上没有一个好结果。但我会用剩余的积木试一下。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你希望看到我所有写作的列表,请在这里查看我的网站。

同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。

参考

  1. tf.nn.conv2d 在 tensorflow 中做什么?(未注明)。检索于 2018 年 2 月 26 日,来自https://stack overflow . com/questions/34619177/what-does-TF-nn-conv2d-do-in-tensor flow
  2. 在 TensorFlow / if 中编写分段函数,然后在 TensorFlow 中编写。(未注明)。检索于 2018 年 2 月 26 日,来自https://stack overflow . com/questions/37980543/writing-piece-wise-functions-in-tensor flow-if-then-in-tensor flow
  3. 《tf.cast | TensorFlow》, TensorFlow ,2018。【在线】。可用:https://www.tensorflow.org/api_docs/python/tf/cast.【访问时间:2018 年 2 月 26 日】。
  4. tensor flow type 错误:传递给参数输入的值的数据类型 uint8 不在允许值列表中:float16,float32。(未注明)。检索于 2018 年 2 月 26 日,来自https://stack overflow . com/questions/44822999/tensor flow-type error-value-passed-to-parameter-input-has-datatype-uint 8-not-in
  5. Pylab_examples 示例代码:subplots_demo.py。(未注明)。检索于 2018 年 2 月 28 日,来自https://matplotlib . org/examples/pylab _ examples/subplots _ demo . html
  6. [3]" TF . nn . conv 2d _ back prop _ filter | tensor flow ", TensorFlow ,2018。【在线】。可用:https://www . tensor flow . org/API _ docs/python/TF/nn/conv 2d _ back prop _ filter。【访问日期:2018 年 2 月 28 日】。
  7. " TF . nn . conv 2d _ back prop _ input(input _ sizes,filter,out_backprop,strides,padding,use_cudnn_on_gpu=None,data_format=None,name=None) | TensorFlow ", TensorFlow ,2018。【在线】。可用:https://www . tensor flow . org/versions/r 1.0/API _ docs/python/TF/nn/conv2d _ back prop _ input。【访问时间:2018 年 2 月 28 日】。
  8. 如何在 tensorflow 中置换 tranposition?(未注明)。检索于 2018 年 2 月 28 日,来自https://stack overflow . com/questions/38517533/how-to-permutate-transposition-in-tensor flow

使用交互式代码的神经网络对肺部 CT 扫描进行去噪—第 4 部分,卷积 ResNet

原文:https://towardsdatascience.com/denosing-lung-ct-scans-using-neural-networks-with-interactive-code-part-4-convolutional-resnet-74335714a4ae?source=collection_archive---------7-----------------------

Gif from here

对肺部 CT 扫描进行降噪的另一种尝试,这次我们将使用更复杂的卷积 ResNet 架构。具体来说,我们将使用本文提出的架构,“深度残差学习进行图像识别 ”。同样,像往常一样,让我们做手动反向传播来比较我们的结果。

网络架构(图像形式)

Image from this paper

我不会详细讨论这个,因为这个建筑本身已经很有名了。但作为一个高层次的概述,我们将对每一层进行两次卷积运算,并将输入与输出相加。

然而,一个不同之处是,我们将添加第三个卷积操作来创建一个 瓶颈层 。下面我来解释一下。

前馈操作/瓶颈层

蓝线→ 快捷层的前馈操作
红线→ 添加过程输入(layer1_2)和快捷层(layer1_s)

这是原始建筑和我们的建筑的唯一区别。完整的网络架构请见下文。我们只有 3 个休息区。

实验设置

同样,实验设置非常简单,左边是原始图像,右边是被污染的图像。更具体地说,我添加了均匀分布噪声,我们可以通过下面的代码做到这一点。

红线 →创建一个我们将要添加到图像中的均匀噪声。

结果(自动微分)

左侧 →原始肺部 CT 扫描图像
中间 →噪声分布均匀的污染图像
右侧 →去噪图像

总的来说,网络似乎正确地对图像进行了去噪,但是产生的图像具有一些尖锐部分,使得图像位合成。

结果(扩张反向传播)

左侧 →原始肺部 CT 扫描图像
中间 →噪声分布均匀的污染图像
右侧 →去噪图像

对于手动反向传播,图像没有填充空间。

近看

左→ 原始图像
中→ 自动微分的结果图像
右→ 扩张反向传播的结果图像

当我们看到每张照片的特写时,我们可以清楚地看到大部分清晰的边缘细节都消失了。因此,传奇仍在继续……

交互代码

对于 Google Colab,你需要一个 Google 帐户来查看代码,而且你不能在 Google Colab 中运行只读脚本,所以在你的游戏场上复制一份。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要访问自动差异化模型,请点击此处。
要访问扩张后支柱型号,请点击此处。

遗言

说实话,只要我能把这个帖子做成 LOL,我就想让这个传奇继续下去。我对新模型有一些想法

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。

同时,在我的推特这里关注我,访问我的网站,或者我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。

参考

  1. 只有 Numpy:扩张的反向传播和谷歌大脑的梯度噪声与交互代码。(2018).黑客正午。检索于 2018 年 3 月 30 日,来自https://hacker noon . com/only-numpy-expanded-back-propagation-and-Google-brains-gradient-noise-with-interactive-code-3a 527 fc 8003 c
  2. 贺,张,谢,任,孙,(2016)。用于图像识别的深度残差学习。IEEE 计算机视觉和模式识别会议论文集*(第 770–778 页)。*

DenseNet

原文:https://towardsdatascience.com/densenet-2810936aeebb?source=collection_archive---------1-----------------------

许多论文:

DenseNet 原纸:https://arxiv.org/pdf/1608.06993v3.pdf

DenseNet 语义分割:【https://arxiv.org/pdf/1611.09326v2.pdf

光流 DenseNet:【https://arxiv.org/pdf/1707.06316v1.pdf

DenseNet 架构是新的,它是 ResNet 的逻辑扩展。

ResNet 体系结构有一个基本的构建块(标识),您可以将以前的层合并(添加)到未来的层中。这里的推理是,通过添加加法合并,我们迫使网络学习残差(误差,即一些先前层和当前层之间的差异)。相比之下,DenseNet 论文提出连接来自先前层的输出,而不是使用求和。

DenseNet:

最近的工作表明,如果卷积网络在靠近输入的层和靠近输出的层之间包含较短的连接,则卷积网络可以训练得更深入、更准确和有效。在本文中,我们接受这种观察,并介绍了密集卷积网络(DenseNet),它以前馈方式将每一层与每一层连接起来。传统的 L 层卷积网络有 L 个连接——每层与其后续层之间有一个连接——而我们的网络有 L(L+1)/ 2 个直接连接。对于每一层,所有在前层的特征图被用作输入,并且它自己的特征图被用作所有后续层的输入。DenseNets 有几个引人注目的优点:它们缓解了消失梯度问题,加强了特征传播,鼓励特征重用,并大大减少了参数的数量。

这种密集连接模式的反直觉效果是,它比传统的卷积网络需要更少的参数,因为不需要重新学习冗余的特征映射。传统的前馈架构可以被视为具有状态的算法,该算法从一层传递到另一层。每一层从其前一层读取状态,并写入后续层。它改变了状态,但也传递了需要保存的信息。ResNets [11]通过附加的身份变换使这种信息保持显式化。ResNets [13]最近的变化表明,许多层贡献很小,实际上在训练期间可以随机丢弃。这使得 resnet 的状态类似于(展开的)递归神经网络[21],但是 resnet 的参数数量要大得多,因为每层都有自己的权重。我们提出的 DenseNet 架构明确区分了添加到网络中的信息和保留的信息。DenseNet 层非常窄(例如,每层 12 个特征图),仅将一小组特征图添加到网络的“集体知识”中,并保持其余的特征图不变,并且最终的分类器基于网络中的所有特征图做出决定。

除了更好的参数效率之外,DenseNets 的一大优势是改善了整个网络的信息流和梯度,这使得它们易于训练。每一层都可以直接访问损失函数和原始输入信号的梯度,从而实现隐含的深度监控[20]。这有助于训练更深层次的网络架构。此外,我们还观察到密集连接具有正则化效应,这减少了对较小训练集大小的任务的过度拟合。

连接由不同层学习的特征图增加了后续层输入的变化并提高了效率。这是 DenseNets 和 ResNets 的主要区别。与也连接来自不同层的特征的初始网络[35,36]相比,DenseNets 更简单和更有效。

每一层将它自己的 k 个特征地图添加到该状态。增长率决定了每一层对全局状态贡献多少新信息。全局状态一旦写入,就可以从网络内的任何地方访问,并且与传统的网络体系结构不同,不需要从一层复制到另一层

瓶颈层。虽然每个图层仅生成 k 个输出要素地图,但通常会有更多的输入。在[36,11]中已经指出,可以在每个 3×3 卷积之前引入 1×1 卷积作为瓶颈层,以减少输入特征图的数量,从而提高计算效率。我们发现这种设计对 DenseNet 特别有效,我们将具有这种瓶颈层的网络称为 DenseNet-B,即 h’的 BN-ReLU-conv(1× 1)-BN-ReLU-conv(3×3)版本。除非另有说明,否则在所有实验中,每个 1×1 卷积将输入减少到 4k 特征图。

压缩。为了进一步提高模型的紧凑性,我们可以减少过渡层的特征映射的数量。如果密集块包含 m 个特征映射,我们让下面的过渡层生成 bθmc 输出特征映射,其中 0 < θ ≤1 被称为压缩因子。当θ = 1 时,过渡层上的特征映射数保持不变。我们将θ <为 1 的 DenseNet 称为 DenseNet-C,我们在实验中设置θ = 0.5。当使用θ < 1 的瓶颈层和过渡层时,我们将我们的模型称为 DenseNet-BC。

从表面上看,DenseNets 与 resnet:Eq 非常相似。(2)不同于等式。(1)仅仅在于 h `()的输入被连接而不是求和。然而,这个看似很小的修改会导致两种网络体系结构的本质上不同的行为。

模型紧凑性。作为输入连接的直接结果,由任何 DenseNet 层学习的特征映射可以被所有后续层访问。这鼓励了整个网络中的特征重用,并导致更紧凑的模型。

隐性深度监管。对密集卷积网络精度提高的一种解释可能是,单个层通过较短的连接从损失函数接收额外的监督。人们可以将 DenseNets 解释为执行一种“深度监督”。深度监督的好处之前已经在深度监督网络(DSN[20]),其具有附加到每个隐藏层的分类器,加强中间层以学习区别特征。DenseNets 以隐含的方式执行类似的深度监督:网络顶部的单个分类器通过最多两到三个过渡层向所有层提供直接监督。然而,DenseNets 的损失函数和梯度基本上不太复杂,因为所有层之间共享相同的损失函数。

DenseNet 语义分段:

这篇论文有趣的标题是:一百层提拉米苏

语义图像分割的最新方法建立在卷积神经网络(CNN)的基础上。典型的分割架构包括(a)负责提取粗略语义特征的下采样路径,随后是(b)被训练以在模型的输出端恢复输入图像分辨率的上采样路径,以及可选的后处理模块(例如,条件随机场)以改进模型预测。最近,一种新的 CNN 架构,密集连接卷积网络(DenseNets),在图像分类任务上表现出了优异的结果。DenseNets 的想法是基于这样的观察,即如果每一层都以前馈方式直接连接到其他每一层,那么网络将更精确,更容易训练。在本文中,我们扩展 DenseNets 来处理语义分割问题

最近,在[12]中引入了一种新的 CNN 架构,称为 DenseNet。DenseNets 由密集块和池操作构建而成,其中每个密集块都是先前特征映射的迭代串联。这种架构可以看作是 ResNets [10]的扩展,它对以前的特征图进行迭代求和。然而,这个小的修改有一些有趣的含义:(1)参数效率,DenseNets 在参数使用上更有效;(2)隐式深度监督,DenseNets 由于到架构中所有特征地图的短路径而执行深度监督(类似于深度监督网络[17]);以及(3)特征重用,所有层可以容易地访问它们的前一层,使得重用来自先前计算的特征地图的信息变得容易。DenseNets 的特性使它们非常适合语义分割,因为它们自然地导致跳过连接和多尺度监督

在本文中,我们通过添加上采样路径来恢复完整的输入分辨率,从而将 DenseNets 扩展为 fcn。天真地构建上采样路径将导致在 softmax 层之前具有非常高分辨率的大量计算上难以处理的特征地图。这是因为人们会将高分辨率特征图与大量输入过滤器(来自下面的所有层)相乘,导致非常大的计算量和参数数量。为了减轻这种影响,我们仅对由前面的密集块创建的特征地图进行上采样。这样做允许在上采样路径的每个分辨率下具有多个密集块,而与汇集层的数量无关。此外,在给定网络架构的情况下,上采样的密集块组合了相同分辨率的其他密集块中包含的信息。借助于下采样和上采样路径之间的标准跳跃连接来传递更高分辨率的信息。

因此,本文的贡献可以概括如下:

  1. 我们小心地将 DenseNet 架构[12]扩展到全卷积网络进行语义分割,同时减轻了特征图爆炸。
  2. 我们强调,从密集块构建的建议上采样路径比具有更多标准操作的上采样路径执行得更好,例如[26]中的操作。
  3. 我们表明,这种网络可以在不使用预训练参数或任何进一步后处理的情况下,在城市场景理解的标准基准上胜过当前最先进的结果

fcn 由下采样路径、上采样路径和跳过连接构成。通过重用要素地图,跳过连接有助于上采样路径从下采样路径恢复空间详细信息。我们模型的目标是通过扩展更复杂的 DenseNet 架构来进一步利用特征重用,同时避免网络上采样路径的特征爆炸

全卷积密度网络

fcn 由下采样路径、上采样路径和跳过连接构成。通过重用要素地图,跳过连接有助于上采样路径从下采样路径恢复空间详细信息。我们的模型的目标是通过扩展更复杂的 DenseNet 架构来进一步利用功能重用,同时避免网络的上采样路径中的功能爆炸。

在我们的全卷积 DenseNet (FC-DenseNet)的下采样路径中。合并操作后,每个要素地图空间分辨率的降低会补偿要素数量的线性增长。下采样路径的最后一层被称为瓶颈。

为了恢复输入空间分辨率,FCNs 引入了由卷积、上采样操作(转置卷积或非卷积操作)和跳过连接组成的上采样路径。在 FC-DenseNets 中,我们用密集块和称为向上过渡的向上采样操作来代替卷积操作。向上过渡模块由转置卷积组成,该卷积对先前的特征图进行向上采样。然后,上采样的特征映射被连接到来自跳过连接的特征映射,以形成新的密集块的输入。由于上采样路径提高了特征地图的空间分辨率,因此特征数量的线性增长会对内存要求过高,尤其是对于 softmax 之前图层中的全分辨率特征。为了克服这个限制,密集块的输入不与其输出连接。因此,转置卷积仅应用于由最后一个密集块获得的特征图,而不是到目前为止连接的所有特征图。最后一个密集块以相同的分辨率总结了所有先前密集块中包含的信息。请注意,在向下转换时,由于池化操作,来自早期密集块的一些信息会丢失。然而,该信息在网络的下采样路径中是可用的,并且可以通过跳跃连接来传递。因此,使用给定分辨率下的所有可用特征图来计算上采样路径的密集块

语义分割架构

首先,在表 1 中,我们定义了该架构的密集块层、向下转换和向上转换。密集块层由 BN 组成,后面是 ReLU,一个 3 × 3 相同的卷积(无分辨率损失)和概率 p = 0.2 的 dropout。该层的生长率被设置为 k = 16。Transition down 由 BN、ReLU(1×1 卷积)、p = 0.2 的 dropout 和大小为 2 × 2 的非重叠最大池组成。向上转换由步长为 2 的 3 × 3 转置卷积组成,以补偿合并操作。

其次,在表 2 中,我们总结了所有 Dense103 层。这种架构由 103 个卷积层构成:第一层在输入端,38 层在下采样路径中,15 层在瓶颈处,38 层在上采样路径中。我们使用 5 个向下转换(TD ),每个包含一个额外卷积,以及 5 个向上转换(TU ),每个包含一个转置卷积。网络的最后一层是 1 × 1 卷积,之后是 softmax 非线性,以提供每个像素的每类分布。值得注意的是,如第 3.2 小节所述,所提出的上采样路径适当地缓解了 DenseNet 特征地图爆炸,导致合理的前 softmax 特征地图数量为 256。最后,通过最小化逐像素交叉熵损失来训练模型。

在本文中,我们扩展了 DenseNets 并使其完全卷积,以解决语义图像分割问题。DenseNets 背后的主要思想是在执行特征映射的迭代连接的密集块中捕获的。我们设计了一个上采样路径来缓解 DenseNets 的简单扩展中出现的特征图的线性增长。最终的网络非常深(从 56 层到 103 层),参数非常少,大约是最先进模型的 10 倍。此外,它提高了具有挑战性的城市场景理解数据集(CamVid 和 Gatech)的最新性能,既没有额外的后处理、预训练,也没有包括时态信息。

用于光流的 DenseNet:

FlowNetS 是一种传统的 CNN 架构,由收缩部分和扩展部分组成。给定相邻帧作为输入,收缩部分使用一系列卷积层来提取高级语义特征,而扩展部分试图通过连续的去卷积来预测原始图像分辨率下的光流。在这两者之间,它使用跳过连接[8]来提供来自较低层特征地图的精细图像细节。这种通用的管道、收缩、扩展、跳过连接被广泛用于每像素预测问题,例如语义分割[9]、深度估计[10]、视频着色[11]等。

然而,跳过连接是组合粗糙语义特征和精细图像细节的简单策略;他们不参与学习过程。我们所期望的是保持高频图像细节直到网络的末端,以便提供隐含的深度监督。简而言之,我们希望确保网络中各层之间的最大信息流。

DenseNet [12]是最近提出的 CNN 架构,它有一个有趣的连接模式:在一个密集的块中,每一层都与所有其他层相连。在这种情况下,所有图层都可以从其之前的图层访问要素地图,这有助于大量的要素重用。直接的结果是,模型更加紧凑,不容易过度拟合。此外,每个单独的层通过捷径路径接收来自损失函数的直接监督,这提供了隐含的深度监督。所有这些良好的特性使得 DenseNet 非常适合每像素预测问题。有一项并行工作使用 DenseNet 进行语义分割[9],它无需预训练或额外的后处理即可实现最先进的性能。然而,估计光流不同于语义分割。我们将在第 3 节说明不同之处。在本文中,我们提出使用 DenseNet 进行光流预测。我们的贡献是双重的。首先,我们将当前的 DenseNet 扩展到完全卷积网络。我们的模型是完全无监督的,并且实现了接近监督方法的性能。第二,我们根据经验表明,在扩展部分用密集块替换卷积会产生更好的性能。

**无监督运动估计:**监督方法采用 CNN 的合成数据集来学习光流预测。然而,合成的运动/场景与真实世界的运动/场景非常不同,因此限制了学习模型的可推广性。此外,即使构建合成数据集也需要大量的人工工作[3]。因此,无监督学习是自然病态运动估计问题的理想选择。回想一下,无监督方法[6]将光流估计视为图像重建问题。直觉是,如果我们可以使用预测的流量和下一帧来重建前一帧,我们的网络正在学习关于潜在运动的有用表示。具体来说,我们将重构的前一帧表示为 I 0 1。

目标是最小化前一帧 I1 和反向扭曲的下一帧 I 0 1 之间的光度误差:

CIFAR10 上的 DenseNet

原文:https://towardsdatascience.com/densenet-on-cifar10-d5651294a1a8?source=collection_archive---------11-----------------------

这篇文章可以在 PDF 这里下载。

这是关于 CNN 架构的系列教程的一部分。

主要目的是在应用于 CIFAR-10 数据集时提供理解 DenseNets 的洞察力。

  • 对于 DenseNets 应用于 ImageNet,这是一个更深入的教程,有另一个教程在这里。
  • 在这里找到构建这些架构的代码:

索引

  • 介绍
  • 结构
  • 卷积 1
  • 密集块
  • 过渡块
  • 致密层
  • 摘要

介绍

这项工作是之前教程的延续,在那里我们在原始论文之后揭开了 DenseNet 的神秘面纱。但是,这种结构是为了在 ImageNet 数据集上运行良好而构建的。

ImageNet 数据集由属于 1000 个不同类别的一组大小(224x224)的图像(作者使用了 128 万幅训练图像、5 万幅验证图像和 10 万幅测试图像)组成。但是,CIFAR10 由一组不同的映像(45k 训练映像、5k 验证映像和 10k 测试映像)组成,这些映像分布在 10 个不同的类别中。

因为输入体积(图像)的大小完全不同,所以很容易认为相同的结构不适合在该数据集上训练。我们无法在没有维度不匹配的情况下对数据集执行相同的缩减。

我们将遵循作者给出的解决方案(让 DenseNets 在 CIFAR10 上进行训练,以构建具有 100 个层和 12 的增长因子的 DenseNet-BC),这也像 ImageNet 数据集一样难以遵循。在论文[1]的第 3 节 DenseNet—实现细节 中,提供了为 CIFAR10 构建 dense net 的配置。

让我们按照他们给出的字面解释来构造 DenseNets。最重要的是,对于 CIFAR10 实施,有 3 个 DenseBlock,而不是 4 个,**,每个 dense block 中的 DenseLayers 数量相等。**因为作者给出的参数是网络的总层数 L ,所以我们计算每个密集块中需要包含多少个密集层才能达到该配置。被压缩系数为θ:

移除 4 层的原因是因为我们只需要考虑那些属于密集块的层。此外,压缩在过渡层引入了一种新的操作(第一个 1x1 卷积,如我们在原始作品中看到的)

因此,对于 100 层 DenseNet-BC,每个 DenseBlock 将由 16 个密集层组成。由于我们将在“DenseNet-Layers-GrowthRate”之后调用 DenseNet,因此本文中涉及的 DenseNet 对应于 dense net-100–12。

结构

遵循之前关于 DenseNets 工作的相同方法,让我们先看一下整体情况,然后再一层一层地深入细节。

Figure 1. Scheme DenseNet-100–12 on CIFAR10

揭开 ResNet-121 的神秘面纱后,图 1 看起来已经很熟悉了。我们可以观察到相同的模式,第一个单卷积层,然后是两对密集块—过渡块对,第三个密集块,然后是全局平均池,以将其减少到 1x1x342 矢量,从而提供给密集层。

卷积 1

在进入第一个密集块之前,DenseNet 的第一步是一个 3×3 卷积和一个批处理归一化操作。步幅为 1,填充为 1,以使输出大小与输入大小相匹配。请注意,我们与 DenseNet for ImageNet 的第一个重大区别是,我们没有在第一个块中包括 max pooling 操作,以减少输入卷的维数。

Figure 2. Conv1

我们可以从图 2 中看出,Conv1 的输出音量确实是 32x32x24。下一步是将这个新卷作为输入引入下面的密集数据块 1 (D1)。

密集块

致密块(DB)由 16 个致密层组成,如之前对 dense net-BC-100–12 的计算。

Figure 3. One level deeper look at Dense-100–12. Dense Block and Transition Block. DLx: Dense Layer x

图 3 表示了一个简化的版本,因为 16 个块在一个图像中压缩太多了,但是我们可以看到特征图的数量是如何以增长率增加的,每次 12 个(24、36、48……)。因为有 16 层,DB1 的最终体积将是 216。

过渡块

两个 db 之间的过渡块(TB)充当下采样,通过合并步幅= 2、核大小= 2 和填充= 1,将特征图的数量减少一半(θ= 0.5),并且还将特征图的大小减少一半。

致密层

我们只需要看看数据库中发生了什么,以确认为什么特征地图的大小增加了*(增长率密集图层的数量)/ 2 —查看 D1 是如何从 24 增加到 216 的—而特征地图的大小保持不变。

Figure 4. 2nd level deep. Full schematic representation of DenseNet-BC-100–12

可以检查每个密集层(DL)如何以 4 *过滤器数量的增长率执行 1x1 卷积。数字 4 是作者在论文中给出的,大多数知识库称之为 bn_size(瓶颈层数的乘法因子)。这个 1x1 卷积在 3x3 卷积之前应用线性变换,滤波器的数量是增长率。

查看第二个卷积如何唯一负责连接的过滤器贴图的数量,因此它在连接它们之后完美地匹配增长率配置。每个 DL 都向它们的输入卷添加 k 个新的特征地图。这再次证实了为什么致密块体增加了增长率致密层数*。

摘要

通过改变图 1 中 n 的值,遵循作者建立的解释规则的结果产生以下结构:

Table 1. DenseNets architectures for CIFAR-10

请注意,直观地说,这些架构与在 ImageNet 的工作结束时展示的 ImageNet 架构并不匹配。

在这里找到构建这些架构的代码:

一种基于密度的离群点检测算法

原文:https://towardsdatascience.com/density-based-algorithm-for-outlier-detection-8f278d2f7983?source=collection_archive---------2-----------------------

离群点检测(也称为异常检测)是发现行为与预期非常不同的数据对象的过程。这种对象被称为异常值或异常值。最有趣的物体是那些明显偏离正常物体的物体。离群值不是由与其余数据相同的机制生成的。
异常值检测在许多应用中非常重要,例如:

  • 通信网络中的入侵
  • 财务数据中的欺诈
  • 假新闻和错误信息
  • 医疗保健分析
  • 工业损伤检测
  • 安全和监控
  • 等等

离群点检测和聚类分析是两个高度相关的任务。聚类发现数据集中的大多数模式,并相应地组织数据,而异常值检测试图捕获那些与大多数模式有很大差异的异常情况。

在本文中,我将介绍离群点检测的基本方法,并重点介绍一类基于邻近度的方法。此外,我将提供一个 LOF 算法的代码实现。

Nassim taleb is an inventor of Black Swan theory — extreme impact of rare and unpredictable outlier event and the human tendency to find simplistic explanations for these events, retrospectively.

离群值和噪声数据

首先,你需要从嘈杂的数据中分辨出离群值。

在应用异常值检测时,应该去除噪声。它可能会扭曲正常对象,模糊正常对象和异常值之间的区别。这可能有助于隐藏异常值并降低异常值检测的有效性。例如,如果用户考虑购买比他以前通常购买的更贵的午餐,这种行为应该被视为“噪声交易”,如“随机误差”或“方差”。

异常值的类型

一般来说,离群值可以分为三类,即全局离群值、上下文(或条件)离群值和集体离群值。

  • 全局异常值-对象明显偏离数据集的其余部分
  • 上下文异常值—对象根据选定的上下文显著偏离。例如,28⁰C 是莫斯科冬天的异常值,但在另一种情况下不是异常值,28⁰C 不是莫斯科夏天的异常值。
  • 集体离群值—数据对象的子集集体显著偏离整个数据集,即使单个数据对象可能不是离群值。例如,一个小团体在短时间内大量交易同一只股票,可以被认为是操纵市场的证据。

Collective outlier.

通常,一个数据集可能包含不同类型的异常值,同时可能属于不止一种异常值。

离群点检测方法

在文献中有许多离群点检测方法,并在实践中使用。首先,离群点检测方法根据用于分析的数据样本是否具有领域专家提供的标签而不同,这些标签可用于建立离群点检测模型。第二,方法可以根据它们对正常对象和异常值的假设分成不同的组。

如果可以获得正常和/或异常对象的专家标记的示例,则它们可以用于建立异常检测模型。使用的方法可分为监督方法、半监督方法和非监督方法。

监督方法

我们将异常检测建模为一个分类问题。领域专家检查的样本用于培训和测试。

挑战:

  • 阶级不平衡。也就是说,异常值的总体通常比正常对象的总体小得多。可以使用处理不平衡类的方法,例如过采样。
  • 捕捉尽可能多的异常值,即召回比准确性更重要(即不要将正常对象误标为异常值)

无监督方法

在某些应用场景中,标记为“正常”或“异常值”的对象不可用。因此,必须使用无监督的学习方法。无监督的离群点检测方法做出了一个隐含的假设:正常对象在某种程度上是“聚集的”换句话说,无监督离群点检测方法期望正常对象比离群点更频繁地遵循一种模式。

挑战:

  • 正常对象可能不共享任何强模式,但是集体离群值可能在小区域中共享高相似性
  • 如果正常活动是多样的并且不属于高质量的聚类,则无监督的方法可能具有高的假阳性率,并且可能让许多实际的异常值未被检测到。

最新的非监督方法开发了智能思想,直接处理离群值,而无需显式检测聚类。

半监督方法

在许多应用中,虽然获得一些标记的例子是可行的,但是这种标记的例子的数量通常很少。如果一些带标签的正常对象可用:

  • 使用已标记的示例和最接近的未标记对象来训练正常对象的模型
  • 不符合正常对象模型的那些被检测为异常值

如果只有一些标记异常值可用,少量的标记异常值可能无法很好地覆盖可能的异常值。

统计方法

统计方法(也称为基于模型的方法)假设正态数据遵循某种统计模型(随机模型)。其思想是学习适合给定数据集的生成模型,然后将模型的低概率区域中的对象识别为异常值。

参数方法

参数方法假设正态数据对象是由具有参数𝜃.的参数分布生成的参数分布 f(x, 𝜃 ) 的概率密度函数给出了对象 x 由该分布生成的概率。该值越小, x 越有可能是异常值。

对于随机模型,正常对象出现在高概率区域,低概率区域的对象是异常值。

统计方法的有效性高度依赖于对分布的假设。

例如,考虑具有正态分布的单变量数据。我们将使用最大似然法检测异常值。

Maximum likelihood methods to estimate the parameter 𝜇 and 𝜎

对𝜇和𝜎求导,并求解一阶条件的结果系统,得到以下最大似然估计

Maximum likelihood estimates of 𝜇 and 𝜎²

偏离值最大的是 24⁰,偏离平均值 4.61。我们知道𝜇 +/- 3𝜎地区包含了正态分布假设下的 97%的数据。因为 4.61/1.54 > 3,我们认为 24⁰是一个异常值。

此外,我们可以使用另一种统计方法,称为格拉布斯检验,并计算 z 分数。

s — standart deviation

但是我们很少处理只有一个属性的数据。涉及两个或多个属性的数据称为多元数据。这些方法的中心思想是将多元数据转化为单变量异常检测问题。
一种流行的方法是𝜒 - 统计法。

Oi — the value of O in i-th dimension. Ei — the mean of the i-th dimension among all objects, n — dimensionality.

如果𝜒 -大,该对象是一个离群值。

参数模型的主要缺点是,在许多情况下,数据分布可能是未知的。

例如,如果我们有两个大的集群,关于正态分布的假设就不适用。

相反,我们假设正态数据对象由多个正态分布𝛩 (𝜇1,𝜎1)和𝛩 (𝜇2,𝜎2)生成,并且对于数据集中的每个对象 o ,我们计算由混合分布生成的概率。

pr(o|𝛩1,𝛩2)= f𝛩1(o)+f𝛩2(o)

其中f𝛩1(o)——分别为 𝛩1 和𝛩2 的概率密度函数。为了学习参数𝜇和𝜎,我们可以使用 EM 算法。EM 算法的一个例子可以在这里找到。

非参数方法

在用于异常值检测的非参数方法中,从输入数据中学习“正常数据”的模型,而不是先验地假设一个模型。非参数方法通常对数据做较少的假设,因此可以适用于更多的情况。例如,我们可以使用直方图。

在最简单的方法中,如果对象在直方图仓之一中失败,则认为它是正常的。缺点是很难选择箱子的大小。

基于邻近的算法

给定特征空间中的一组对象,可以使用距离度量来量化对象之间的相似性。直观上,距离他人较远的对象可以视为离群值。基于邻近度的方法假设离群对象与其最近邻居的邻近度明显偏离该对象与数据集中大多数其他对象的邻近度。

基于邻近度的算法可以分为基于距离的方法(如果一个对象的邻域没有足够的点,则该对象是异常值)和基于密度的方法(如果一个对象的密度比其邻域的密度相对低得多,则该对象是异常值)

基于密度

基于距离的离群点检测方法参考由给定半径定义的对象的邻域。如果一个对象的邻域没有足够多的其他点,则该对象被认为是异常值。

距离阈值可以被定义为对象的合理邻域。对于每个对象,我们可以找到一个对象的合理数量的邻居。

形式上,设 r(r > 0) 为距离阈值,𝜋 (0 < 𝜋 < 1) 为分数阈值。的一个对象 o 是 DB(r, 𝜋 )

距离 —距离测量。

简单的方法需要 O(n)时间。

挖掘基于距离的异常值的算法;

  • 基于索引的算法
  • 嵌套循环算法
  • 基于单元的算法

基于密度的方法

基于密度的离群点检测方法研究对象及其邻居的密度。这里,如果一个对象的密度比其邻居的密度相对低得多,则该对象被识别为异常值。

许多真实世界的数据集展示了更复杂的结构,其中对象可以被认为是关于它们的局部邻域的离群值,而不是关于全局数据分布的离群值。

考虑上面的例子,基于距离的方法能够检测到 o3,但是对于 o1 和 o2 就不那么明显了。

基于密度的思想是,我们需要将对象周围的密度与其局部邻居周围的密度进行比较。基于密度的异常检测方法的基本假设是,非异常对象周围的密度与其邻居周围的密度相似,而异常对象周围的密度与其邻居周围的密度显著不同。

dist _ k(o)-是对象 o 和 k 个最近邻之间的距离。o的 k 距离邻域包含所有到o的距离不大于*dist _ k(o)*oo的第 k 个距离的物体

我们可以用 Nk(o)中的物体到 o的平均距离作为 o 局部密度的度量。如果 o 具有非常接近的邻居o’**使得 dist(o,o’)非常小,则距离测量的统计波动可能会不期望地高。为了克服这个问题,我们可以通过添加平滑效果来切换到下面的可达性距离度量。

k 是用户指定的参数,控制平滑效果。本质上, k 指定了要检查的最小邻域,以确定对象的局部密度。可达性距离是不对称的。

一个对象 o 的局部可达性密度为

我们计算一个对象的局部可达性密度,并将其与其邻居的可达性密度进行比较,以量化该对象被视为离群值的程度。

局部离群因子是 o 的局部可达性密度与 o 的 k 个最近邻的局部可达性密度之比的平均值。 o 的局部可达性密度越低,o 的 k 最近邻的局部可达性密度越高,则 LOF 值越高。这准确地捕获了局部离群值,其局部密度与其 k 个最近邻居的局部密度相比相对较低。

LOF 算法

基于 data.csv 中的点击流事件频率模式,我们将应用 LOF 算法计算每个点的 LOF,初始设置如下:

  1. k = 2 并使用曼哈顿距离。
  2. k = 3 并使用欧几里德距离。

结果,我们将找到 5 个异常值和它们的 LOF_k(o)

数据可以从 github 库下载

参考文献

  • http://www . kdnugges . com/2017/01/3-methods-deal-outliers . html
  • https://www . analyticsvidhya . com/blog/2016/01/guide-data-exploration/
  • 韩佳玮,Micheline Kamber,JianPei 数据挖掘概念和技术-第 3 版-摩根-考夫曼-2011 【亚马逊】
  • https://towards data science . com/a-brief-overview-of-outlier-detection-techniques-1e 0 b 2c 19 e 561

MSBD 5002 HKUST 讲稿

使用 flask 部署机器学习模型

原文:https://towardsdatascience.com/deploy-a-machine-learning-model-using-flask-da580f84e60c?source=collection_archive---------1-----------------------

作为机器学习的初学者,对于任何人来说,获得关于机器学习和深度学习的所有算法的足够资源可能都很容易,但是当我开始寻找将 ML 模型部署到生产的参考资料时,我没有找到任何可以帮助我部署我的模型的好资源,因为我对这个领域非常陌生。因此,当我成功地使用 Flask 作为 API 部署我的模型时,我决定写一篇文章来帮助其他人简单地部署他们的模型。希望有帮助:)

在本文中,我们将使用简单的线性回归算法和 scikit-learn。为了简单起见,我们将使用 Flask,因为它是一个非常轻量级的 web 框架。我们将创建三个文件,

  1. model.py
  2. server.py
  3. request.py

在一个 model.py 文件中,我们将开发并训练我们的模型,在一个 *server.py 中,*我们将编码处理 POST 请求并返回结果,最后在 request.py 中,我们将向服务器发送带有特性的请求并接收结果。

让我们开始编码部分

  1. model.py

正如我上面提到的,在这个文件中我们将开发我们的 ML 模型并训练它。我们将根据员工在该领域的经验来预测他/她的工资。你可以在这里找到数据集。

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import pickle
import requests
import json

导入我们将用来开发模型的库。 numpypandas 分别操作矩阵和数据,sk learn . model _ selection将数据拆分为训练集和测试集, sklearn.linear_model 使用 LinearRegression 训练我们的模型。 pickle 将我们训练好的模型保存到磁盘,请求向服务器发送请求, json 在我们的终端打印结果。

dataset = pd.read_csv('Salary_Data.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 1].values

我们已经使用 pandas 导入了数据集,并将要素和标注从数据集中分离出来。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.33, random_state = 0)

在本节中,我们使用来自 sklearn 的 train_test_split 将我们的数据分为训练和测试大小分别为 0.67 和 0.33。

regressor = LinearRegression()
regressor.fit(X_train, y_train)y_pred = regressor.predict(X_test)

该对象被实例化为类 LinearRegression()回归变量,并使用 X_train 和 *y_train 进行训练。*后者预测结果存储在 y_pred 中。

pickle.dump(regressor, open('model.pkl','wb'))

我们将使用 pickle 库将训练好的模型保存到磁盘上。 Pickle 用于序列化和反序列化 Python 对象结构。其中 python 对象被转换成字节流。 dump() 方法将对象转储到参数中指定的文件中。

在我们的例子中,我们希望保存我们的模型,以便服务器可以使用它。因此,我们将把我们的对象回归器保存到名为 model.pkl. 的文件中

我们可以通过下面的方法再次加载模型,

model = pickle.load(open('model.pkl','rb'))
print(model.predict([[1.8]]))

pickle.load() 方法加载方法并将反序列化后的字节保存到*模型。*可以使用 model.predict()进行预测。

例如,我们可以预测有 1.8 年工作经验的雇员的工资。

在这里,我们的 model.py 准备训练并保存模型。 model.py 的完整代码如下。

# Importing the libraries
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import pickle
import requests
import json# Importing the dataset
dataset = pd.read_csv('Salary_Data.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 1].values# Splitting the dataset into the Training set and Test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 1/3, random_state = 0)# Fitting Simple Linear Regression to the Training set
regressor = LinearRegression()
regressor.fit(X_train, y_train)# Predicting the Test set results
y_pred = regressor.predict(X_test)# Saving model to disk
pickle.dump(regressor, open('model.pkl','wb'))# Loading model to compare the results
model = pickle.load(open('model.pkl','rb'))
print(model.predict([[1.8]]))

2。server.py

在这个文件中,我们将使用 flask web 框架来处理从 request.py 获得的 POST 请求。

导入我们将在代码中使用的方法和库。

import numpy as np
from flask import Flask, request, jsonify
import pickle

这里我们导入了 numpy 来创建请求数据的数组, pickle 来加载我们训练好的模型进行预测。

在下面的代码中,我们创建了 Flask() 的实例,并将模型加载到模型中。

app = Flask(__name__)model = pickle.load(open('model.pkl','rb'))

这里,我们用方法 predict()绑定了 /api其中 predict 方法从请求者传递的 json 中获取数据。 model.predict() 方法从 json 获取输入,并将其转换为 2D numpy 数组结果存储在名为的变量中,输出和我们在使用 flaks*json ify()*方法将其转换为 JSON 对象后返回此变量。

[@app](http://twitter.com/app).route('/api',methods=['POST'])
def predict():
    data = request.get_json(force=True)
    prediction = model.predict([[np.array(data['exp'])]])
    output = prediction[0]
    return jsonify(output)

最后,我们将通过下面的代码运行我们的服务器。这里我使用了端口 5000,并设置了 debug=True ,因为如果我们遇到任何错误,我们可以调试并解决它。

if __name__ == '__main__':
    app.run(port=5000, debug=True)

在这里,我们的服务器已经准备好为请求提供服务。下面是 server.py. 的完整代码

# Import libraries
import numpy as np
from flask import Flask, request, jsonify
import pickleapp = Flask(__name__)# Load the model
model = pickle.load(open('model.pkl','rb'))@app.route('/api',methods=['POST'])
def predict():
    # Get the data from the POST request.
    data = request.get_json(force=True) # Make prediction using model loaded from disk as per the data.
    prediction = model.predict([[np.array(data['exp'])]]) # Take the first value of prediction
    output = prediction[0] return jsonify(output)if __name__ == '__main__':
    app.run(port=5000, debug=True)
  1. request.py

正如我前面提到的, request.py 将向服务器请求预测。

下面是向服务器发出请求的完整代码。

import requestsurl = '[http://localhost:5000/api'](http://localhost:5000/api')r = requests.post(url,json={'exp':1.8,})
print(r.json())

我们已经使用请求库来发出 post 请求。 requests.post() 获取 URL 和 post 请求中要传递的数据,从服务器返回的结果存储到变量 r 中,并由 r.json()打印。

结论

我们创建了三个文件 model.py、server.py 和 request.py 来训练和保存模型,处理请求,分别向服务器发出请求。

在对所有这些文件进行编码之后,执行文件的顺序应该是 model.pyserver.py (在单独的终端中)以及最后 request.py

您可以将预测的结果与一个 model.py 进行比较,因为我们将结果打印在文件的末尾。

你可以在我的 Github 库 flask-salary-predictor 中找到所有的代码。

不要犹豫,在下面的评论区说出你的想法。

谢谢:)

将 Nodejs 微服务部署到 Docker Swarm 集群[Docker 从零到英雄]

原文:https://towardsdatascience.com/deploy-a-nodejs-microservices-to-a-docker-swarm-cluster-docker-from-zero-to-hero-464fa1369ea0?source=collection_archive---------0-----------------------

这是🖐🏽“构建 NodeJS 影院微服务”系列的第五篇文章。这一系列文章演示了如何使用 ES6,ES7 …8,用 expressjs设计、构建和部署微服务 ?,连接到 MongoDB 副本集,并将其部署到 docker 容器中,以模拟云环境的强大功能。

##快速回顾一下我们之前的章节

第一篇文章介绍了微服务架构模式,并讨论了使用微服务的好处缺点。在第二篇文章中,我们讨论了使用 HTTP/2 协议微服务安全性,并了解了如何实现它**。本系列的第三篇文章我们描述了微服务架构内通信不同方面,我们解释了关于设计模式NodeJS依赖注入、反转控制和**坚实的原理。在第四篇文章中,我们谈到了什么是 API 网关,我们看到了什么是网络代理ES6 代理对象。我们已经开发了 5 个服务,我们已经将它们归档,我们也做了很多类型的测试,因为我们是好奇的好开发者。

如果你没有读过前面的章节,你会错过一些很棒的东西👍🏽,所以我会把链接放在下面,这样你就可以看看了👀。

[## 构建 NodeJS 影院微服务并使用 docker 部署它—第 1 部分

这是“构建节点影院微服务”系列的第一章,该系列是关于构建节点影院微服务的

medium.com](https://medium.com/@cramirez92/build-a-nodejs-cinema-microservice-and-deploying-it-with-docker-part-1-7e28e25bfa8b) [## 构建 NodeJS 影院微服务并使用 docker 部署它(第 2 部分)

这是✌️“构建 NodeJS 影院微服务”系列的第二篇文章。

medium.com](https://medium.com/@cramirez92/build-a-nodejs-cinema-microservice-and-deploying-it-with-docker-part-2-e05cc7b126e0) [## 构建 NodeJS 影院预订微服务并使用 docker 部署它(第 3 部分)

你好社区这是🏰“构建 NodeJS 影院微服务”系列的第三篇文章。这一系列的…

medium.com](https://medium.com/@cramirez92/build-a-nodejs-cinema-booking-microservice-and-deploying-it-with-docker-part-3-9c384e21fbe0) [## 构建 NodeJS cinema API 网关并将其部署到 Docker(第 4 部分)

这是🏛“构建 NodeJS 影院微服务”系列的第四篇文章。这一系列文章…

medium.com](https://medium.com/@cramirez92/build-a-nodejs-cinema-api-gateway-and-deploying-it-to-docker-part-4-703c2b0dd269)

我们一直在开发,编码,编程,👩🏻‍💻👨🏻‍💻在最后几集中,我们对如何创建 nodejs 微服务非常兴奋,我们还没有时间谈论我们系统的架构,我们还没有谈论从第 1 章开始就一直在使用的东西,那就是 Docker

现在是人们见识力量的时候了💪🏽集装箱化的🗄.如果你想得到你的手🙌🏽肮脏和学习所有关于 Docker 的大惊小怪,然后抓住你的座位,系上你的安全带,因为我们的旅程将变得有趣。

##当前影院微服务架构

直到我们知道我们已经创建了 3 个**docker-machines** **,**我们创建了一个**mongo database replica set cluster**,在那里我们在每个 docker-machine 中放置了一个副本,然后我们创建了我们的微服务,但是我们一直只在**manager1** docker-machine 中手动创建和部署它,所以我们一直在浪费其他两个 docker-machine 中的计算资源,但是我们不再这样做了,因为我们将开始配置 Docker

我们将在本文中使用:

  • NodeJS 版本 7.5.0(针对我们的微服务)
  • MongoDB 3.4.2(针对我们的数据库)
  • Mac 版 docker 1 . 13 . 0 或同等版本(已安装,版本 1.13.1 与 dockerode 不兼容)

跟进文章的先决条件:

  • bash 脚本的基础知识。
  • 我已经完成了上一章的例子。

如果你还没有,我已经上传了一个 github 库,所以你可以在分支机构步骤 5 的回购链接处获得最新信息。

# Docker 是什么?

Docker 是一个开源项目,可以将任何应用程序作为一个轻量级容器来打包、运输和运行。

Docker 容器既与硬件无关,也与平台无关。这意味着它们可以在任何地方运行,从您的笔记本电脑到最大的云计算实例以及二者之间的任何东西,并且它们不需要您使用特定的语言、框架或打包系统。这使得它们成为部署和扩展 web 应用程序、数据库和后端服务的绝佳构建块,而无需依赖特定的堆栈或提供商。— @Docker

Docker structure

换句话说 docker 到底是什么?

换句话说,docker 让我们构建模板(如果我们可以称之为模板,这个模板是 docker 映像)来创建容纳虚拟机的容器(如果我们可以称之为虚拟机,因为它们不是),我们可以在其中包含我们的应用程序,安装它的所有依赖项,并作为一个独立的进程运行它,与主机操作系统或任何 IaaS 平台中的其他容器共享内核。

Virtual machine structure

和虚拟机有什么区别?

虚拟机包括应用程序、必要的二进制文件、库和整个客户操作系统,其容量可达数十 GB — @Docker

#什么是 Docker-Machine?

Docker Machine 让我们可以在自己的计算机、云提供商和数据中心内部创建 Docker 主机。它创建服务器,在服务器上安装 Docker,然后配置 Docker 客户机与服务器对话。— @Docker

Docker Machine 是一个让我们在虚拟主机上安装 Docker 引擎,并使用docker-machine命令管理主机的工具。您可以使用 Machine 在本地 Mac 或 Windows box、公司网络、数据中心或 AWS 或 Digital Ocean 等云提供商上创建 Docker 主机。Docker 引擎在 Linux 系统上本地运行。如果你有一个 Linux 系统作为你的主系统,并且想要运行docker命令,你需要做的就是下载并安装 Docker 引擎。

但是为什么我们甚至在 Linux 上也需要 Docker-Machine 呢?

如果我们想要高效地管理我们的 Docker 主机 在网络上、在云中甚至在本地,我们需要它,因为如果我们在本地进行测试,Docker-Machine 可以帮助我们模拟云环境。

#什么是 Docker Swarm?

Docker Swarm 是 Docker 的本地集群。它使用 API 代理系统将一个 Docker 主机池变成一个单独的虚拟主机。

让我们先理解集群是什么意思。

集群是一组紧密耦合的计算机,像单台机器一样运行。称为节点的单个机器通过非常快速的网络相互通信,并且它们在物理上非常接近,可能在同一个机柜中。通常他们有相同或几乎相同的硬件和软件。所有节点都可以处理相同类型的请求。有时,一个节点接受请求并将其分派给其他节点。— 菲尔·多尔蒂

好了,现在让我们看看创建 Docker Swarm 集群可以实现什么:

  • 多主机网络
  • 结垢
  • 负载平衡
  • 默认安全性
  • 集群管理

等等,现在我们已经获得了一些关于 Docker 生态系统的词汇和知识,是时候看看我们如何创建我们的架构并将我们的 cinema 微服务部署到 Docker Swarm 集群 ,该集群可以处理数百、数千或数百万的用户请求,如预订🎟,逛🕹,看🎥、或用户的任何动作👥在我们的电影系统中。

当不使用 swarm 模式运行 Docker 时,执行容器命令。当您在集群模式下运行 Docker 时,您编排了服务。您可以在同一个 Docker 实例上运行 swarm 服务和独立容器。— @Docker

#构建架构

步骤 1:创建并初始化 docker swarm 集群

我们将从零开始构建我们的影院微服务架构,所以让我们先来谈谈如何创建我们的**docker machines** 以及如何初始化一个**docker swarm cluster.**

首先,在开始创建和修改文件之前,我们需要在 cinemas 项目的根目录下创建一个名为**_docker_setup**的新文件夹,因此我们的项目需要如下所示:

*. 
|*--* ***_docker_setup*** 
|   `*-- ... here we are going to put our bash files* 
|*--* ***api-gateway***|   `*-- ... more files* |*--* ***booking-service***|   `*-- ... more files* |*--* ***cinema-catalog-service***|   `*-- ... more files* |*--* ***movies-service***|   `*-- ... more files* |*--* ***notification-service***|   `*-- ... more files* |*--* ***payment-service***|   `*-- ... more files**

因此,让我们在我们的**_docker_setup folder**中创建一个 bash 文件,名为**setup-swarm.sh**,这将创建并设置我们的**docker swarm cluster.**为什么是 bash 文件,因为一个好的开发人员可以自动完成很多这样的事情:

好吧,这是一个有点长的脚本,但我想把它全部写下来,因为它让我们更好地了解正在发生的事情,以及我们如何才能完成 docker swarm 集群设置自动化。

所以让我们分开剧本,谈谈那里发生了什么。

***# So first the basics, how do we create a docker-machine.**$ docker-machine create -d $DRIVER $ADDITIONAL_PARAMS $MACHINE_NAME*

这就是我们创建机器的基本方法,不管它们是管理节点还是工作节点,对两者来说都是相同的命令。驱动程序可能是 virtualbox、parallels、digital-ocean、AWS 等。

*一旦我们创建了我们的机器,它的时间 **初始化蜂群,*如下:

*$ docker-machine ssh manager1 docker swarm init --advertise-addr $(getIP manager1)*

它的一个 简单的 docker 命令 ,就这么简单,docker swarm init,初始化 swarm manager 配置。我们可以用两种方式来做这件事,像下面的eval docker-machine env manager1``一样 设置我们的环境 并执行docker swarm init命令或者 我们可以 ssh 到机器 像下面的docker-machine ssh manager1 {and here we pass the docker commands}一样,初始化 swarm 我们需要docker-machine ipip 可能会因驱动程序提供者而异,所以为了获取 ip,我做了一个 bash 函数,它将检索给定 docker-machine 的 IP。

一旦群管理器被启动,我们就准备添加工人节点,为此我们调用函数join_node_manager,它执行以下操作:

*$ docker-machine ssh {name of worker} docker swarm join --token $(get_worker_token) $(getIP manager1):2377*

我们将在脚本中使用给定数量的 workers 变量再次循环该命令,该命令首先调用函数get_worker_token,这将从管理器节点获取令牌,这是将 worker 节点注册到群集群所需的令牌,接下来它将再次调用检索给定 docker-machine 的 ip 的函数,并将 完成 docker 群集群配置 ,我们准备好部署我们的 cinema 微服务。

为了利用 swarm 模式的容错特性,Docker 建议您根据组织的高可用性要求实现奇数个节点。— @Docker

步骤 2:创建 docker 图像

容器是将 Node.js 应用程序部署到生产环境的最佳方式。容器提供了各种各样的好处,从在生产和开发中拥有相同的环境到为了速度和大小而简化部署。— 蒂尔尼·赛丽

目前我们有 5 个微服务和 1 个 api-gateway 服务,我们可以在 dev box 上运行,只要它安装了 Node.js 的兼容版本。我们想要做的是创建一个 Docker 服务( 我们将在后面的章节 ) 中看到这是什么,但是为此我们需要为我们拥有的每个微服务创建一个 Docker 映像

一旦创建了 Docker 映像 ,我们就能够在任何支持 Docker 的地方部署我们的服务。

我们创建一个 Docker 图像 的方法是先创建一个**Docker file(**模板 ) )。Docker 文件是一个告诉 Docker 引擎如何构建我们的图像的配方。

由于我们只开发了 nodejs 应用程序,我们可以在项目中的所有微服务中使用相同的 Dockerfile 规范, 但是我们是否尽了一切努力使这个过程尽可能可靠和有活力呢?

这是我们要查看的下一个文件,我们也将对其应用良好的实践。

现在我们可以用这个规范修改我们之前创建的所有微服务**docker files****,

让我们谈一点这是怎么回事,如果这个过程是可靠的。

默认情况下,Docker 容器中的应用程序进程作为根用户运行。这在生产运行时会造成 潜在的严重安全风险 。这个问题的一个简单的 解决方案 是在 Docker 映像的 中 创建一个新用户,并使用该用户来执行我们的应用程序。Docker 容器内的第一个进程 将是 PID 1 。Linux 内核给予 PID 1 特殊的待遇,许多应用程序并不是为处理 PID 1 带来的额外责任而设计的。当以 PID 1 的身份运行 Node.js 时,进程无法处理那些责任会有几种表现,其中最痛苦的是进程忽略了SIGTERM命令。dumb-init 被设计成一个超级简单的进程,无论它被告知启动哪个进程,它都负责作为 PID 1 运行。**

步骤 3:构建并运行我们的 docker 映像

要构建我们的 Docker 图像 ,我们需要运行以下命令:

***# This command will create a new docker image**$ docker build -t movies-service .*

让我们看看 build 命令。

  1. docker build告诉引擎我们想要创建一个新的图像。
  2. -t flag用标签movies-service给这个图像加标签。从现在开始我们可以通过标签来引用这张图片。
  3. .使用当前目录找到Dockerfile

现在我们已经准备好使用新的 docker 映像运行容器,为此我们需要以下命令:

*$ docker run --name movies-service -l=apiRoute='/movies' -p 3000:3000 -d movies-service*

让我们来看看 run 命令。

  1. docker run告诉引擎我们要启动一个新的容器。
  2. --name flag 为容器设置一个名称。从现在开始我们可以用这个名字来称呼这个容器。
  3. -l标志为容器设置元数据。
  4. -p flag 设置来自:的端口绑定
  5. -d标志在分离模式下运行容器,这保持了容器在后台运行。

所以现在让我们在我们的**_docker_setup** foleder 中创建一个 bash 文件,名为**create-images.sh**,来自动创建我们所有的微服务 docker 映像。

在执行这个脚本之前,我们需要修改每个微服务上的**start-service.sh** ,并将其重命名为**create-image.sh**,如下所示:

*#!/usr/bin/env bashdocker rm -f {name of the service}docker rmi {name of the service}docker image prunedocker volume prune**# the previous commands are for removing existing containers, 
# and image, then we clean our environment and finally 
# we creat or re-build our image**docker build -t {name of the service} .*

步骤 4:将我们的 docker 映像发布到 docker hub 存储库

发布我们的 docker 图像🤔?,Docker 维护着一个巨大的图像库,称为Docker Hub,您可以使用它作为起点或免费存储我们自己的图像。这是我们将**node:7.5.0-alpine**映像用于创建微服务映像的地方。 但是为什么我们需要发布我们的图片呢?

因为在本章的后面,我们将创建 Docker 服务 ,这些服务将在我们的 Docker Swarm 集群上部署和复制,为了启动我们的服务,集群节点需要服务的映像来启动容器,如果映像不在本地,它将在 docker hub 中搜索它,然后将它拉至主机,以便在本地拥有映像并能够统计我们的服务。

但是首先我们需要在 Docker Hub 网站 创建一个帐户,然后我们需要在我们的 shell 中登录,执行以下命令:

*$ docker login          
  Username: *****     
  Password: *****     
  Login Succeeded*

接下来,我们需要标记我们的图像,以便能够通过名称引用它们,并将它们推送到 docker hub。

docker tagging images structure

既然我们已经登录,我们现在知道了如何标记 docker 图像的结构,现在是修改我们的**create-images.sh**的时候了,所以它可以创建我们的图像,标记我们的图像,我们的图像推送到 docker hub ,所有这些都是自动完成的,我们的 bash 文件需要看起来如下。

步骤 5:设置我们的 mongodb 副本集集群

这是 docker 步骤的一个小主题,但我们需要一个数据库来保存我们的微服务使用的数据,在这一步中,我不会花时间来描述如何做到这一点,我已经写了一篇关于如何将 mongodb 副本集集群部署到 docker 的文章,我强烈建议您,如果您还没有,可以看看我的文章。

* [## 如何使用 Docker 部署 MongoDB 副本集

本文将介绍如何使用 docker 设置带身份验证的 MongoDB 副本集。

medium.com](https://medium.com/@cramirez92/how-to-deploy-a-mongodb-replica-set-using-docker-6d0b9ac00e49)

或者跳过这一步,等到阅读完第 7 步。
(又搞点暴徒生活😎)

步骤 6:在我们的 docker 集群中创建 docker 服务

做第 5 步是非常重要的,因为如果我们没有我们的数据库和运行我们的 docker 服务将无法正确启动。

现在让我们在我们的**_docker_setup** 文件夹中创建另一个名为**start-services.sh** 的文件。这个 bash 脚本将启动我们所有类型为 Docker 服务 的微服务,这样这些服务就可以根据需要扩大或缩小规模。

既然我们的服务规模将会扩大和缩小,我们在调用这些服务时会遇到麻烦,但亲爱的读者们,没有什么可害怕的,因为,我之前说过,创建Docker swarm 集群的好处之一是,它在幕后为我们设置了一个负载平衡器,Docker 负责在请求时处理要调用的服务。让我们回顾下一个文件。**

正如你所看到的,这个文件与我们的**create-images.sh** 非常相似,但是这次我们从每个服务中调用**start-service.sh** ,现在让我们看看**start-service.sh**文件是如何组成的。

**#!/usr/bin/env bashdocker service create --replicas 3 --name {service name} -l=apiRoute='{our api route}' -p {port binding} --env-file env {microservice image}**

让我们看一下服务命令:

  • docker service create命令创建服务。
  • --name标志为服务命名,例如movies-service
  • --replicas标志指定了 3 个运行实例的期望状态。
  • 我们可以附加元数据的-l标志物种,例如apiRoute="/movies"
  • -p标志指定主机和容器上的端口绑定。
  • -e标志指定了服务环境变量的 can 设置。

步骤 7:在一个命令中执行所有自动化文件

好啦好啦,是施展魔法的时候了🔮✨的人们。

为了执行我们已经创建的所有自动化文件,让我们创建最终的脚本来为我们做所有的事情,因为开发人员很懒🤓。

所以我们需要在 影院微服务 项目的根目录下创建这个文件,我们将把它命名为**kraken.sh** 🦑只是为了好玩,因为很强大😎。

它内部没有复杂的编程,但是它所做的,是为我们调用所有的自动化脚本并完成我们的工作。

最后让我们像下面这样执行它。

**$ bash < kraken.sh**

就这么简单,我们已经做了这么多模块化来简化创建 Docker 群集群 的过程,并自动启动我们的 Docker 服务。

“简单可能比复杂更难:你必须努力让自己的思维变得清晰,才能变得简单。但最终还是值得的,因为一旦你到了那里,你就可以移山。”—史蒂夫·乔布斯

我上传了一个视频演示,看看当我们执行**kraken.sh** 时会发生什么。我稍微加快了视频的速度,但 kraken 过程可能需要 10 分钟左右才能完成,这取决于主机的功率。

最后,我们可以检查 docker 环境执行以下命令的状态,如下图所示。

docker — bash output

正如所示,您可以看到我们的集群中已经复制了一些服务,其他的甚至还没有启动,这是因为机器正在获取我们的映像来启动我们的服务,一旦我们的映像被下载并且我们的服务被启动,我们应该会看到类似下图的内容。

docker service ls — bash output

**现在我们的架构看起来如下图所示,其中我们所有的微服务都是动态创建的,通过所有集群复制,并且可以根据需要进行扩展,唯一手动创建的服务是我们的 mongo 容器和 api-gateways 为什么因为它们与我们的主机服务器的规范相关,所以 mongo 需要持久存储,我们的 api 需要发现主机 docker 服务。

现在,让我们验证我们的服务当前已经启动并正在运行,因此我们需要执行如下图所示的命令。

docker service ps — bash output

如果我们运行 github 上的 Docker Swarm visualizer、 ,我们可以看到我们的服务(容器)是如何分布在我们的 Docker swarm 集群 上的,如下图所示。

Docker swarm visualizer

如果我们缩小一些服务,例如docker-machine ssh manager1 docker service scale movies-service=1,我们可以看到我们的服务是如何在我们的集群上重新分布的,如下图所示。

Docker swarm visualizer

***我们几乎完成了 *cinemas 微服务配置、以及 cinemas 微服务系统。

步骤 8:额外配置

这是一篇非常大的文章,但是我们已经学到了很多关于 docker 如何适应我们的开发,以及 docker 如何补充我们的系统使之更加健壮。

我们还需要做一些事情,正确设置并准备运行我们的影院微服务:****

  • 我们需要更新 api-gateway,,以便现在可以发现正在运行的 docker 服务,从而能够进行代理。
  • 我们需要填充我们的数据库,为此你可以去查看这里的 github 仓库自述文件中的命令。

在我们的 API 网关中,我们只需要修改我们的**docker.js** 中的几行代码,而不是调用listContainers()函数,我们会调用listServices()函数并用提供的服务设置我们的路线。

为了不使这篇文章变得更长,欢迎您在 github 仓库检查对 API 网关的完整代码更改,如果您有任何问题,一如既往地欢迎您给我发推文或在下面发表评论😃📝。

步骤 9:测试我们的设置

因为如果不对我们的系统进行一些测试,我们的文章是不完整的。测试从根本上来说是重要的,因为我们可以从不同的角度,用不同的视角来看待系统,并以不同的期望来测试它。软件测试的最终目的不是找到 bug,而是使产品定性。作为一名优秀的测试人员,我们正在为产品质量的提高做出贡献。

*****# we need to locate at the api-gateway folder and execute the test** $ npm run int-test***

我们将得到如下输出。

这里我们调用我们的 api 网关服务,正如你所看到的,我们调用不同的docker-machine ip,我们的 api 网关代理我们的请求到我们的 Docker 服务 ,最后我们的测试正确通过😎。

我还对部署在 docker swarm 集群中的 cinema 微服务系统进行了 jmeter 压力测试,因此您可以看到预期的结果。

#是时候回顾一下了

我们所做的…

我们见过很多码头工人🐋。我们讨论了 whale、 Docker、Docker-Machine、Docker-Swarm、Docker-Images、Docker-Hub、Docker-Services 是什么,以及如何进行适当的配置,如何设置自动化流程,以及如何与我们的 cinemas 系统相适应。

**借助 docker,我们使我们的影院微服务和系统更具动态性、容错性、可扩展性和安全性。 但是 docker 还有太多有趣的东西可以看,比如 ***Docker 网络、Docker 撰写、Docker 插件等等……*Docker 是一个不断扩展的 devops 世界。

我们已经看到了使用 NodeJS 的微服务的大量开发,并且我们已经看到了如何使用 Docker 生态系统来实现这种微服务,但是我们还可以做和学习更多的东西,这只是更高级的 Docker 平台的一个小高峰。我希望这已经展示了一些有趣和有用的东西,您可以在您的工作流中使用这些东西。

#还有一件事…

我知道这篇文章变得很长,但我认为值得再看一步,这将向我们展示如何监控我们的 docker swarm 集群。

步骤 9:监控 docker 集群

因此,要开始监控我们的集群,我们需要在我们的**manager1 docker-machine**中执行以下命令

**$ docker-machine ssh manager1 docker run --name rancher --restart=unless-stopped -p 9000:8080 -d rancher/server**

然后,当容器准备好了,我们需要在浏览器中访问下面的 url [http://192.168.99.100:9000](http://192.168.99.100:9000i)

然后,rancher gui 将向您介绍整个设置过程,最后我们将能够监视我们的群集。

Rancher UI of our cluster

如果我们单击其中一个主机,我们可以看到如下内容。

Rancher — Manager 1 logs

最后,我们录制了 super duper 压力集成测试,这样您就可以在视频中看到所有这些配置的结果,以及我们如何通过图形界面或控制台日志来监控我们的群集😎控制台日志晃动🤘🏽。

所以我们已经看到了超能力💪🏽蓝鲸🐋提供给我们的。

##最终意见

好了,我们的影院微服务系统已经接近完成,但还缺少一些东西,如果我们不开发出缺少的主要部分,我们的影院微服务系统就没有用了,我的朋友们,这是我们的最终用户将与我们的系统交互的前端服务😎,而 web 用户界面是我们系统中缺少的部分。

#感谢阅读

感谢阅读!希望你在文章中找到价值!如果你看过,按下推荐键,推荐给朋友,分享或者再读一遍。

如果你对这个系列的任何方面有疑问,或者需要我的帮助来理解某些东西,请随时给我发推特或者在下面留下评论。

让我记住你,这篇文章是“ 搭建 NodeJS 影院微服务 ”系列的一部分,所以,下周我会再发表一章。

与此同时,请继续关注,保持对✌的好奇🏼👨🏻‍💻👩🏻‍💻

再见了!😁

你可以在 Twitter @ crami rez _ 92
https://twitter.com/cramirez_92关注我
*

# Github 的完整代码

您可以在下面的链接中查看文章的完整代码。

** [## GitHub-Crizstian/cinema-微服务:影院微服务示例

电影院微服务-电影院微服务示例

github.com](https://github.com/Crizstian/cinema-microservice)

#进一步阅读||阅读互补

  • docker 服务如何工作
  • 码头工人群体概述**

参考数量

  • Docker GitHub
  • 来自开发者的定义:什么是集群?
  • 8 个 Protips 在 Dockerizing Node.js 时开始杀死它

在 Spark 上部署 Python 模型(更高效)

原文:https://towardsdatascience.com/deploy-a-python-model-more-efficiently-over-spark-497fc03e0a8d?source=collection_archive---------0-----------------------

更新:我写了关于 部署 Scikit 的另一种方式——通过 Spark 学习模型,避免了这种方法的一些问题。

我把这个贴出来,希望其他人可以避免一些我必须经历的痛苦。有时候我想在 scikit-learn 中训练一个模型,但是在 Spark 中为一个大型数据集中的所有记录建模结果。是的,我知道我可以使用 Spark MLlib,但我发现 scikit-learn 有一套更强大的产品,我理解 scikit 中的代码-learn 比我理解 MLlib 中的代码更好,我只是更熟悉 scikit-learn。然而,通过 PySpark UDF 调用 scikit-learn 的“predict”方法会产生一些问题:

  • 对于 Spark 数据帧的每一条记录,它都会导致对模型对象进行清理和拆包的开销。
  • 它没有利用 scikit-learn 的优化,这主要是由于对 NumPy 数组的矢量化函数调用。

我发现可以通过对 spark 数据帧进行分组来减轻一些开销,以便一次在多个记录上调用我的 Python 对象的方法。你可以这样做:

  1. 在 Spark 数据框中设置三列:

*一个唯一的 id。这可以是任何东西。只要它是独一无二的,你就可以去。

所有你的预测者。您可以使用 Structype 或 MLLib 的 VectorAssembler 将所有预测器放入一列。

***一组列。**你可以调用 row_number()按你想要的组数取模运算。我发现创建足够多的组,每个组包含 50-100k 条记录,这样做通常很有效。

2.调用 Spark SQL 函数“create_map ”,将您的唯一 id 和预测值列合并成一列,其中每条记录都是一个键值存储。

3.按 groups 列分组,并在 key-value 列上调用 Spark SQL 函数“collect_list”。这将把你的数据集合到字典列表中。

4.传播你的 scikit-learn 模型。

5.创建一个 UDF,将字典列表解包为一个键列表(您的唯一 id)和一个列表列表(您的预测值)。然后,您可以将列表列表直接输入到广播的 scikit-learn 模型的“predict”方法中。然后用您的键列表压缩该函数调用的结果,并转换成一个字典。udf 将返回一个 MapType,根据您的键所采用的格式以及您希望从 scikit-learn 函数调用返回的格式来适当地设置键和值的类型。

6.对 udf 的结果调用 explode,并包含两个别名—一个用于键,一个用于结果。然后,您将拥有一个新的数据框,其大小与原始(预分组)数据框相同,其中一列是您的结果,另一列是可用于将结果与原始数据连接起来的键。

这里有一个例子:

"""
assumes the following already exist within the environment:
`model`: a scikit-learn class that predicts probabilities for a two-class (0.0, 1.0) model
`sdf`: a spark dataframe with at least two columns: "unique_id" and "feature_list"
"""**import** pyspark.sql.functions as f
**import** pyspark.sql.types as t
**import** pyspark.sql.window.Window as w
**from** pyspark.context **import** SparkContextsc **=** SparkContext.getOrCreate()# broadcast model
model_broadcast **=** sc.broadcast(model)# udf to predict on the cluster
**def** predict_new(feature_map): ids, features **=** zip(*****[
        (k,  v) **for** d **in** feature_map **for** k, v **in** d.items()
    ]) ind **=** model_broadcast.value.classes_.tolist().index(1.0) probs **=** [
        float(v) **for** v **in** 
        model_broadcast.value.predict_proba(features)[:, ind]
    ] **return** dict(zip(ids, probs))predict_new_udf **=** f.udf(
    predict_new, 
    t.MapType(t.LongType(), t.FloatType()
)# set the number of prediction groups to create
nparts **=** 5000# put everything together
outcome_sdf **=** (
    sdf
    .select(
        f.create_map(
            f.col('unique_id'),     
            f.col('feature_list')
        ).alias('feature_map'), 
        (
            f.row_number().over(
                w.partitionBy(f.lit(1)).orderBy(f.lit(1))
            ) **%** nparts
        ).alias('grouper')
    )
    .groupby(f.col('grouper'))
    .agg(
        f.collect_list(f.col('feature_map')).alias('feature_map')
    )
    .select(
        predict_new_udf(f.col('feature_map')).alias('results')
    )
    .select(
        f.explode(f.col('results'))
        .alias('unique_id', 'probability_estimate')
    )
)

我希望能够展示一些图表,将上述方法的性能与在 PySpark UDF 中简单包装对模型的 predict 方法的调用的性能进行比较,但是我不能:我想出了这个方法,因为我无法让这个简单的方法完成。我有一个超过 1 亿条记录的数据集。我训练了一个朴素贝叶斯(使用 scikit-learn 的 MultinomialNB)分类器,根据散列的术语-文档矩阵(使用 scikit-learn 的 HashingVectorizer)来区分两个类——0 和 1。起初,我只是简单地广播了训练好的模型,然后编写了一个 UDF,它将一个预处理过的字符串作为参数。UDF 通过哈希矢量器运行字符串,然后将这些结果输入模型预测方法。然后,我运行脚本并监控 YARN。两天后,这个过程大约完成了 10%。然后,我按照我在这里概述的方法重新编写了这个过程:UDF 接受一个字符串列表作为参数,这个列表由哈希矢量器处理,结果提供给模型的 predict 方法。整个过程在 30 分钟内完成。

最后一点:不同的 scikit-learn 模型在内存中有很大的不同。朴素贝叶斯模型只需要为每个参数保留几个值。随机森林需要保留森林中的每一棵树。因为您需要将模型传播给每个执行者,所以您会很容易地发现,根据大量数据训练的模型需要大量内存。

部署张量流模型

原文:https://towardsdatascience.com/deploy-tensorflow-models-9813b5a705d5?source=collection_archive---------2-----------------------

Photo by SpaceX on Unsplash

了解如何将您的模型部署到生产中

更新至 tensorflow 1.7

好,你有一个模型,你想让它可以从网上访问。有几种方法可以做到这一点,但最快和最强大的是 TensorFlow 服务。

它是如何工作的?基本上 TensorFlow 服务创建了一个 gRPC 服务器,您可以在其中发送和接收来自模型的响应。你并不真正了解成为巫师背后的魔力。

这些是我们要做的步骤:

  • 做一个笨模型做例子,训练存储
  • 从存储的模型中获取您需要的变量
  • 从它们中建立张量信息
  • 创建模型签名
  • 创建并保存模型构建器
  • 下载已经编译了 TensorFlow 服务的 Docker 映像
  • 使用正确的配置运行 docker 映像
  • 创建客户端以发送 gRPC 请求
  • 制作一个 API
  • 测试一下

代码可以在这里找到。

制作一个愚蠢的模型作为例子,训练和存储它

我们只需要一个模型来玩。下面是一个非常基本的模型,它以两个随机数组作为输入和目标。

*import* tensorflow *as* tf
*import* numpy *as* np
*import* os, sys

DATA_SIZE = 100
SAVE_PATH = './save'
EPOCHS = 1000
LEARNING_RATE = 0.01
MODEL_NAME = 'test'

*if not* os.path.exists(SAVE_PATH):
    os.mkdir(SAVE_PATH)

data = (np.random.rand(DATA_SIZE, 2), np.random.rand(DATA_SIZE, 1))
test = (np.random.rand(DATA_SIZE // 8, 2), np.random.rand(DATA_SIZE // 8, 1))

tf.reset_default_graph()

x = tf.placeholder(tf.float32, shape=[*None*, 2], name='inputs')
y = tf.placeholder(tf.float32, shape=[*None*, 1], name='targets')

net = tf.layers.dense(x, 16, activation=tf.nn.relu)
net = tf.layers.dense(net, 16, activation=tf.nn.relu)
pred = tf.layers.dense(net, 1, activation=tf.nn.sigmoid, name='prediction')

loss = tf.reduce_mean(tf.squared_difference(y, pred), name='loss')
train_step = tf.train.AdamOptimizer(LEARNING_RATE).minimize(loss)

checkpoint = tf.train.latest_checkpoint(SAVE_PATH)
should_train = checkpoint == *None

with* tf.Session() *as* sess:
    sess.run(tf.global_variables_initializer())
    *if* should_train:
        print("Training")
        saver = tf.train.Saver()
        *for* epoch *in* range(EPOCHS):
            _, curr_loss = sess.run([train_step, loss], feed_dict={x: data[0], y: data[1]})
            print('EPOCH = {}, LOSS = {:0.4f}'.format(epoch, curr_loss))
        path = saver.save(sess, SAVE_PATH + '/' + MODEL_NAME + '.ckpt')
        print("saved at {}".format(path))
    *else*:
        print("Restoring")
        graph = tf.get_default_graph()
        saver = tf.train.import_meta_graph(checkpoint + '.meta')
        saver.restore(sess, checkpoint)

        loss = graph.get_tensor_by_name('loss:0')

        test_loss = sess.run(loss, feed_dict={'inputs:0': test[0], 'targets:0': test[1]})
        print(sess.run(pred, feed_dict={'inputs:0': np.random.rand(10,2)}))
        print("TEST LOSS = {:0.4f}".format(test_loss))

记住:如果你使用 tf.layers.dense,实际的输出是用你提供的名字+ 函数名(lol)来调用的

x = tf.placeholder(tf.float32, shape=[*None*, 2], name='inputs')...
pred = tf.layers.dense(net, 1, activation=tf.nn.sigmoid, name='prediction') 

如果您运行代码,它将创建./save文件夹(如果它不存在),或者如果已经有一个存储的实例,它将只评估测试集上的模型。

# training the model
...
EPOCH = 997, LOSS = 0.0493
EPOCH = 998, LOSS = 0.0495
EPOCH = 999, LOSS = 0.0497
saved at ./save/test.ckpt

如果我们再次运行脚本,我们会看到

Restoring
TEST LOSS = 0.0710

完美!现在我们有了保存的模型

从存储的模型中获取您需要的变量

让我们创建一个名为serve.py的文件,它将处理服务于我们的 TF 模型背后的逻辑。首先要做的是从存储的图中获取我们需要的变量。

*import* tensorflow *as* tf
*import* os

SAVE_PATH = './save'
MODEL_NAME = 'test'
VERSION = 1
SERVE_PATH = './serve/{}/{}'.format(MODEL_NAME, VERSION)

checkpoint = tf.train.latest_checkpoint(SAVE_PATH)

tf.reset_default_graph()

*with* tf.Session() *as* sess:
    # import the saved graph
    saver = tf.train.import_meta_graph(checkpoint + '.meta')
    # get the graph for this session
    graph = tf.get_default_graph()
    sess.run(tf.global_variables_initializer())
    # get the tensors that we need
    inputs = graph.get_tensor_by_name('inputs:0')
    predictions = graph.get_tensor_by_name('prediction/Sigmoid:0')

从它们中建立张量信息

现在我们有了我们的变量inputspredictions。我们需要从它们中构建张量信息,该信息将用于创建将被传递给 SavedModelBuilder 实例的签名定义。非常容易

# create tensors info
model_input = tf.saved_model.utils.build_tensor_info(inputs)
model_output = tf.saved_model.utils.build_tensor_info(predictions)

创建模型签名

现在,我们终于可以创建模型签名了,它标识了服务对客户端的期望。在我们的情况下

# build signature definition
signature_definition = tf.saved_model.signature_def_utils.build_signature_def(
    inputs={'inputs': model_input},
    outputs={'outputs': model_output},
    method_name= tf.saved_model.signature_constants.PREDICT_METHOD_NAME)

这里我们从 TF 中调用一个 utils 函数,它接受inputsoutputsmethod_name。最后一个只是一个常量,表示将要做什么,在我们想要预测的情况下,它们被定义为:

创建并保存模型构建器

创建一个 SavedModelBuilder 实例,并传递我们需要的所有信息。

builder = tf.saved_model.builder.SavedModelBuilder(SERVE_PATH)

builder.add_meta_graph_and_variables(
    sess, [tf.saved_model.tag_constants.SERVING],
    signature_def_map={
        tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
            signature_definition
    })
# Save the model so we can serve it with a model server :)
builder.save()

add_meta_graph_and_variables中,我们通过当前会话,一个我不知道为什么需要它们的tags数组,SERVING常量和signature_def_map。同样,对于最后一个,我不知道我们为什么需要它,但是基本上我们传递一个字典,在那里我们告诉DEFAULT_SERVING_SIGNATURE_DEF_KEY我们有那个签名定义(在前面的“创建模型签名”一节中定义的那个)。

完整剧本这里。

运行脚本,它会创建serve目录:

下载已经编译了 TensorFlow 服务的 Docker 映像

首先安装 docker 。

不要遵循 TensorFlow 文档,因为它们解释了如何设置 docker 映像和编译 TF serving,这需要花费很长时间。

现在单据坏了,查看这里:

https://github.com/tensorflow/tensorflow/issues/19006

有人制作了一个 docker 图像,上面已经编译了所有东西,所以我们将使用这个图像。图像链接:

https://hub.docker.com/r/epigramai/model-server/

使用正确的参数运行该命令

docker run -it -p <PORT>:<PORT> — name <CONTAINER_NAME> -v <ABSOLUTE_PATH_TO_SERVE_DIR>:<SERVE_DIR> epigramai/model-server:light-universal-1.7 — port=<PORT> — model_name=<MODEL_NAME> — model_base_path=<MODEL_DIR>

在我们的情况下

docker run -it -p 9000:9000 --name tf-serve -v $(pwd)/serve/:/serve/ epigramai/model-server:light-universal-1.7 --port=9000 --model_name=test --model_base_path=/serve/test

如果一切正常,您应该会看到类似这样的内容:

创建客户端以发送 gRPC 请求

怎么做呢?好吧,再说一次,医生真的不太好。所以我们将使用一个库,这将使事情变得更容易。

使用pip运行这个命令来安装它,在我的例子中,我使用的是 python3

pip3 install git+ssh://[git@github.com](mailto:git@github.com)/epigramai/tfserving-python-predict-client.git

让我们创建一个名为client.py的新文件

*import* numpy *as* np
*from* predict_client.prod_client *import* ProdClient

HOST = '0.0.0.0:9000'
# a good idea is to place this global variables in a shared file
MODEL_NAME = 'test'
MODEL_VERSION = 1

client = ProdClient(HOST, MODEL_NAME, MODEL_VERSION)

req_data = [{'in_tensor_name': 'inputs', 'in_tensor_dtype': 'DT_FLOAT', 'data': np.random.rand(1,2)}]

prediction = client.predict(req_data, request_timeout=10)

print(prediction)

在运行它之前,确保您已经启动了 docker 容器。午饭后你应该会看到这样的脚本:

{'outputs': array([[ 0.53334153]])}

outputs为关键字、以正确预测为值的字典

创建 API 端点

是时候最终让我们的模型可以从网上访问了。我们将使用 Flask 来创建 HTTP 服务器。让我们重构我们的client.py

客户端必须接受 HTTP 调用,将响应数据转换为 numpy 数组,调用模型并返回包含预测的 JSON。下面是的最终代码。

*import* numpy *as* np
*from* predict_client.prod_client *import* ProdClient
*from* flask *import* Flask
*from* flask *import* request
*from* flask *import* jsonify

HOST = 'localhost:9000'
MODEL_NAME = 'test'
MODEL_VERSION = 1

app = Flask(__name__)
client = ProdClient(HOST, MODEL_NAME, MODEL_VERSION)

*def* convert_data(*raw_data*):
    *return* np.array(*raw_data*, dtype=np.float32)

*def* get_prediction_from_model(*data*):
    req_data = [{'in_tensor_name': 'inputs', 'in_tensor_dtype': 'DT_FLOAT', 'data': *data*}]

    prediction = client.predict(req_data, request_timeout=10)

    *return* prediction

@app.route("/prediction", methods=['POST'])
*def* get_prediction():
    req_data = request.get_json()
    raw_data = req_data['data']

    data = convert_data(raw_data)
    prediction = get_prediction_from_model(data)

    # ndarray cannot be converted to JSON
    *return* jsonify({ 'predictions': prediction['outputs'].tolist() })

*if* __name__ == '__main__':
    app.run(host='localhost',port=3000)

测试一下

终于!我成功了!是时候尝试一下了,打开您最喜欢的 HTTP 客户端,在我的例子中是 postman ,尝试使用POST请求向localhost:3000/prediction发送一个以data为键、以矢量为值的 JSON

发送后,我们有了回应

完美!它工作了。

最终代码可以在这里找到

结论

我们已经看到了服务 TensorFlow 模型并使用 Flask 通过 HTTP 请求访问它的最佳方式。

也许你还可以找到值得一读的我的其他文章:

https://towards data science . com/reinforcement-learning-cheat-sheet-2f 9453 df 7651

https://towards data science . com/how-to-use-dataset-in-tensor flow-c 758 ef 9 e 4428

感谢您的阅读,

弗朗西斯科·萨维里奥

在 Python 中将 Keras 深度学习模型部署为 Web 应用程序

原文:https://towardsdatascience.com/deploying-a-keras-deep-learning-model-as-a-web-application-in-p-fc0f2354a7ff?source=collection_archive---------1-----------------------

(Source)

深度学习、web 应用、Flask、HTML 和 CSS 在一个项目中

建立一个很酷的机器学习项目是一回事,但归根结底,你希望其他人能够看到你的努力。当然,你可以把整个项目放在 GitHub 上,但是你的祖父母怎么知道呢?不,我们想要的是将我们的深度学习模型部署为世界上任何人都可以访问的 web 应用程序。

在本文中,我们将看到如何编写一个 web 应用程序,它采用一个经过训练的 Keras 递归神经网络,并允许用户生成新的专利摘要。这个项目建立在示例递归神经网络文章的基础上,但是知道如何创建 RNN 并不是必需的。我们现在只是把它当作一个黑盒:我们放入一个开始序列,它输出一个全新的专利摘要,我们可以在浏览器中显示它!

传统上,数据科学家开发模型,前端工程师向世界展示它们。在这个项目中,我们将不得不扮演这两个角色,并投入到 web 开发中(尽管几乎都是用 Python)。

该项目需要将众多主题结合在一起:

  • Flask: 用 Python 创建基本的 web 应用程序
  • Keras: 部署训练好的递归神经网络
  • 使用 Jinja 模板库进行模板化
  • HTML 和 CSS 用于编写网页

最终的结果是一个 web 应用程序,它允许用户使用经过训练的递归神经网络生成全新的专利摘要:

这个项目的完整代码可以在 GitHub 上找到。

方法

目标是让 web 应用程序尽快启动并运行。为此,我选择了 Flask,它允许我们用 Python 编写应用程序。我不喜欢弄乱样式(这很明显),所以几乎所有的 CSS 都是复制和粘贴的。Keras 团队的这篇文章对基础知识很有帮助这篇文章也是一个有用的指南。

总的来说,这个项目坚持我的设计原则:快速建立并运行一个原型——根据需要尽可能多地复制和粘贴——然后迭代开发出更好的产品。

带有 Flask 的基本 Web 应用程序

用 Python 构建 web 应用程序的最快方法是使用 Flask 。要制作我们自己的应用程序,我们可以使用以下代码:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1>Not Much Going On Here</h1>"app.run(host='0.0.0.0', port=50000)

如果您复制并粘贴这段代码并运行它,您将能够在 localhost:50000 上查看您自己的 web 应用程序。当然,我们想做的不止这些,所以我们将使用一个稍微复杂一点的函数,它基本上做同样的事情:处理来自浏览器的请求,并以 HTML 的形式提供一些内容。对于我们的主页,我们希望为用户提供一个表单来输入一些细节。

用户输入表单

当我们的用户到达应用程序的主页时,我们将向他们显示一个表单,其中有三个参数可供选择:

  1. 输入 RNN 的开始序列或随机选择
  2. 选择 RNN 预测的多样性
  3. 选择 RNN 输出的字数

为了用 Python 构建一个表单,我们将使用[wtforms](https://wtforms.readthedocs.io/)。制作表单的代码是:

这将创建一个如下所示的表单(样式来自main.css):

代码中的validator确保用户输入正确的信息。例如,我们检查所有的框都被填满,并且diversity在 0.5 和 5 之间。必须满足这些条件,表单才能被接受。

Validation error

Flask中,我们实际上提供表单的方式是使用模板。

模板

模板是一个具有基本框架的文档,我们需要在其中填入细节。对于 Flask web 应用程序,我们可以使用 Jinja 模板库将 Python 代码传递给 HTML 文档。例如,在我们的 main 函数中,我们将把表单的内容发送给一个名为index.html的模板。

当用户到达主页时,我们的应用程序将提供来自form的详细信息index.html。该模板是一个简单的 html 脚手架,其中我们使用{{variable}} 语法引用 python 变量。

对于表单中的每个错误(那些不能被验证的条目),一个错误将flash.除此之外,这个文件将显示如上的表单。

当用户输入信息并点击submit(一个POST请求)时,如果信息是正确的,我们希望将输入转移到适当的函数,用训练过的 RNN 进行预测。这意味着修改home()

现在,当用户点击submit并且信息正确时,根据输入,输入被发送到generate_random_startgenerate_from_seed。这些函数使用经过训练的 Keras 模型来生成一个由用户指定了diversitynum_words的新专利。这些函数的输出依次被发送到模板random.htmlseeded.html中的任一个,以作为网页。

使用预先训练的 Keras 模型进行预测

model参数是经过训练的 Keras 模型,加载如下:

(tf.get_default_graph()是基于此要点的变通方法。

我不会展示这两个util函数的全部内容(这里的是代码),您需要理解的是,它们使用经过训练的 Keras 模型和参数,并对新的专利摘要进行预测。

这两个函数都返回带有格式化 HTML 的 Python 字符串。该字符串被发送到另一个模板以呈现为网页。例如,generate_random_start返回进入random.html的格式化 html:

这里我们再次使用Jinja模板引擎来显示格式化的 HTML。由于 Python 字符串已经被格式化为 HTML,我们所要做的就是使用{{input|safe}}(其中input是 Python 变量)来显示它。然后,我们可以像处理其他 html 模板一样,在main.css中处理这个页面。

输出

函数generate_random_start选择一个随机的专利摘要作为开始序列,并根据它进行预测。然后,它显示启动序列、RNN 生成的输出和实际输出:

Random starting sequence output.

函数generate_from_seed采用用户提供的启动序列,然后使用训练好的 RNN 在此基础上构建。输出如下所示:

Output from starting seed sequence

虽然结果并不总是完全正确,但它们确实表明递归神经网络已经学会了英语的基础知识。它被训练来从前面的 50 个单词中预测下一个单词,并且学会了如何写一份稍微令人信服的专利摘要!根据预测的diversity,输出可能看起来完全随机或循环。

运行应用程序

要自己运行这个应用程序,你需要做的就是下载存储库,导航到deployment目录并输入python run_keras_server.py。这将立即使 web 应用程序在 localhost:10000 上可用。

根据您的家庭 WiFi 配置,您应该能够使用您的 IP 地址从网络上的任何计算机访问该应用程序。

后续步骤

在你的个人电脑上运行的网络应用程序非常适合与朋友和家人分享。不过,我绝对不建议向你家庭网络上的所有人开放这个!为此,我们希望在 AWS EC2 实例上设置应用程序,并向全世界提供服务(稍后推出)。

为了改进应用程序,我们可以改变风格(通过[main.css](https://github.com/WillKoehrsen/recurrent-neural-networks/blob/master/deployment/static/css/main.css))并可能增加更多的选项,例如选择预训练网络的能力。个人项目的伟大之处在于,你可以随心所欲地进行。如果你想玩这个应用,下载代码并开始使用。

结论

在本文中,我们看到了如何将经过训练的 Keras 深度学习模型部署为 web 应用程序。这需要将许多不同的技术结合在一起,包括递归神经网络、web 应用程序、模板、HTML、CSS,当然还有 Python。

虽然这只是一个基本的应用程序,但它表明您可以通过相对较少的努力使用深度学习开始构建 web 应用程序。没有多少人可以说他们已经将深度学习模型部署为 web 应用程序,但是如果您阅读了这篇文章,请将自己算作其中一员!

一如既往,我欢迎反馈和建设性的批评。可以通过推特 @koehrsen_will 或者通过我的个人网站willk . online找到我

submit = SubmitField("Enter")

在训练模型中加载

将机器学习模型部署为 REST API

原文:https://towardsdatascience.com/deploying-a-machine-learning-model-as-a-rest-api-4a03b865c166?source=collection_archive---------0-----------------------

Artwork by Igor Kozak

作为一名 Python 开发人员和数据科学家,我渴望构建 web 应用程序来展示我的工作。尽管我喜欢设计前端,但同时学习机器学习和应用程序开发变得非常困难。因此,我必须找到一种解决方案,能够轻松地将我的机器学习模型与其他开发人员集成,这些开发人员能够比我更好地构建一个健壮的 web 应用程序。

通过为我的模型构建 REST API,我可以将我的代码与其他开发人员分开。这里有明确的分工,这有利于定义责任,并防止我直接阻止不参与项目机器学习方面的队友。另一个优点是,我的模型可以被在不同平台上工作的多个开发人员使用,比如 web 或 mobile。

在本文中,我将构建一个简单的 Scikit-Learn 模型,并使用 Flask RESTful 将其部署为 REST API。本文特别面向没有广泛计算机科学背景的数据科学家。

关于模型

对于这个例子,我组装了一个简单的朴素贝叶斯分类器来预测电影评论中短语的情感。

数据来自 Kaggle 竞赛,影评情感分析。评论被分成单独的句子,句子被进一步分成单独的短语。所有的短语都有一个情感分数,这样就可以训练一个模型,根据这个模型,哪些词可以给一个句子带来积极的、中性的或消极的情感。

Distribution of ratings from the Kaggle dataset

大多数短语的评级都是中性的。首先,我尝试使用多项式朴素贝叶斯分类器来预测 5 个可能类别中的一个。但是,因为大多数数据的等级为 2,所以该模型的表现不是很好。我决定保持简单,因为这个练习的要点主要是关于作为 REST API 进行部署。因此,我将数据限制在极端类别,并训练模型仅预测消极或积极的情绪。

结果证明,多项式朴素贝叶斯模型在预测积极和消极情绪方面非常有效。你可以在这个 Jupyter 笔记本演练中找到模型训练过程的快速概述。在 Jupyter 笔记本中训练完模型后,我将代码转移到 Python 脚本中,并为 NLP 模型创建了一个类对象。你可以在这个链接找到我的 Github repo 中的代码。您还需要 pickle 或保存您的模型,以便您可以快速地将训练好的模型加载到您的 API 脚本中。

现在我们有了模型,让我们将它部署为一个 REST API。

REST API 指南

为 API 的 Flask 应用程序启动一个新的 Python 脚本。

导入库并加载 Pickles

下面的代码块包含许多 Flask 样板文件和加载分类器和矢量器 pickles 的代码。

from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
import pickle
import numpy as np
from model import NLPModelapp = Flask(__name__)
api = Api(app)# create new model object
model = NLPModel()# load trained classifier
clf_path = 'lib/models/SentimentClassifier.pkl'
with open(clf_path, 'rb') as f:
    model.clf = pickle.load(f)# load trained vectorizer
vec_path = 'lib/models/TFIDFVectorizer.pkl'
with open(vec_path, 'rb') as f:
    model.vectorizer = pickle.load(f)

创建参数解析器

解析器将检查用户发送给 API 的参数。参数将位于 Python 字典或 JSON 对象中。对于这个例子,我们将特别寻找一个名为query的键。查询将是一个短语,用户将希望我们的模型预测该短语是积极的还是消极的。

# argument parsing
parser = reqparse.RequestParser()
parser.add_argument('query')

资源类对象

资源是 Flask RESTful APIs 的主要构件。每个类都可以有对应于 HTTP 方法的方法,比如:GETPUTPOSTDELETEGET将是主要方法,因为我们的目标是服务于预测。在下面的get方法中,我们提供了如何处理用户查询以及如何打包将返回给用户的 JSON 对象的指导。

class PredictSentiment(Resource):
    def get(self):
        # use parser and find the user's query
        args = parser.parse_args()
        user_query = args['query'] # vectorize the user's query and make a prediction
        uq_vectorized = model.vectorizer_transform(
            np.array([user_query]))
        prediction = model.predict(uq_vectorized)
        pred_proba = model.predict_proba(uq_vectorized) # Output 'Negative' or 'Positive' along with the score
        if prediction == 0:
            pred_text = 'Negative'
        else:
            pred_text = 'Positive'

        # round the predict proba value and set to new variable
        confidence = round(pred_proba[0], 3) # create JSON object
        output = {'prediction': pred_text, 'confidence': confidence}

        return output

有一个很棒的教程是由 Flask-RESTful 提供的,他们在其中构建了一个待办事项应用程序,并演示了如何使用PUTPOSTDELETE方法。

端点

以下代码将设置情绪预测器资源的基本 url。您可以想象您可能有多个端点,每个端点都指向一个不同的模型,该模型将做出不同的预测。一个例子可以是端点'/ratings',它将用户引导到另一个模型,该模型可以预测给定类型、预算和制作成员的电影评级。您需要为第二个模型创建另一个资源对象。这些可以一个接一个地添加,如下所示。

api.add_resource(PredictSentiment, '/')

# example of another endpoint
api.add_resource(PredictRatings, '/ratings')

Name ==主块

这里不多说了。如果要将此 API 部署到生产环境中,请将 debug 设置为 False。

if __name__ == '__main__':
    app.run(debug=True)

用户请求

下面是一些用户如何访问你的 API 的例子,这样他们就可以得到预测。

Jupyter 笔记本中的请求模块:

url = '[http://127.0.0.1:5000/'](http://127.0.0.1:5000/')
params ={'query': 'that movie was boring'}
response = requests.get(url, params)
response.json()Output: {'confidence': 0.128, 'prediction': 'Negative'}

在终端中使用 curl:

$ curl -X GET [http://127.0.0.1:5000/](http://127.0.0.1:5000/) -d query='that movie was boring'
{
    "prediction": "Negative",
    "confidence": 0.128
}

在终端中使用 HTTPie:

$ http [http://127.0.0.1:5000/](http://127.0.0.1:5000/) query=='that movie was boring'HTTP/1.0 200 OK
Content-Length: 58
Content-Type: application/json
Date: Fri, 31 Aug 2018 18:49:25 GMT
Server: Werkzeug/0.14.1 Python/3.6.3{
    "confidence": 0.128,
    "prediction": "Negative"
}

现在,我的队友只需向这个 API 发出请求,就可以将情绪预测添加到他们的应用程序中,而无需将 Python 和 JavaScript 混合在一起。

完整的app.py代码

有时在一个地方看到所有代码会很有帮助。

文件结构

我想包括的最后一件事是这个简单 API 的文件结构的概述。

sentiment-clf/
├── README.md
├── app.py  **# Flask REST API script**
├── build_model.py  **# script to build and pickle the classifier**
├── model.py  **# script for the classifier class object**
├── util.py  **# helper functions**
├── requirements.txt
└── lib/
    ├── data/  **# data from Kaggle**
    │   ├── sampleSubmission.csv
    │   ├── test.tsv
    │   └── train.tsv
    └── models/  **# pickled models for import into API script**
        ├── SentimentClassifier.pkl
        └── TFIDFVectorizer.pkl

部署

一旦你建立了你的模型和 REST API,并完成了本地测试,你就可以像部署 Flask 应用程序一样部署你的 API 到网络上的许多主机服务上。通过部署在 web 上,任何地方的用户都可以向您的 URL 发出请求以获得预测。部署指南包含在烧瓶文档中。

关闭

这只是为情感分类器构建 Flask REST API 的一个非常简单的例子。同样的过程可以应用于其他机器学习或深度学习模型,只要你训练并保存了它们。

除了将模型部署为 REST API 之外,我还使用 REST API 来管理我从 web 上收集的数据的数据库查询。这让我可以与全栈开发人员合作,而不必管理他们的 React 应用程序的代码。如果一个移动开发者想要开发一个应用,那么他们只需要熟悉 API 端点。

如果你有任何反馈或批评,请随时与我分享。如果本演练对您有所帮助,请喜欢👏文章。干杯!🍻

在 AWS 上部署 Python Web 应用程序

原文:https://towardsdatascience.com/deploying-a-python-web-app-on-aws-57ed772b2319?source=collection_archive---------0-----------------------

(Source)

如何与世界分享您的 Python 项目

虽然我喜欢做数据科学和编程项目,因为我个人喜欢构建自己的东西,但与世界上的任何人在线分享您的项目也是一种快乐。幸运的是,多亏了亚马逊网络服务(AWS ),在几分钟内,我们就可以向全世界免费部署一个 Python 网络应用程序。

在本文中,我们将了解如何在免费的 EC2 实例上将深度学习 web 应用部署到 AWS。本文将使用内置于的应用程序,部署一个 Keras 深度学习模型作为 Python 中的 Web 应用程序,通过 Python 中的示例使用在递归神经网络中开发的模型。这两个都不是必需的,只需知道我们的应用程序使用 RNN 生成新颖的专利摘要。项目的所有代码都可以在 GitHub 上找到。

亚马逊网络服务 EC2

亚马逊网络服务是亚马逊云计算产品系列的总称。我们将使用亚马逊弹性计算云(EC2) ,这是一项服务,我们在云中租用虚拟计算机来运行应用程序。AWS EC2 提供了一个免费层,因此我们可以不花一分钱进行部署。

首先,创建一个 AWS 账户,然后前往位于https://console.aws.amazon.com/ec2的 EC2 控制台。点击 Launch Instance 按钮,选择一个Amazon Machine Instance(AMI)“包含启动实例所需的软件配置(操作系统)的模板”你可以使用任何你熟悉的操作系统(尽管有些不符合免费层的条件),但我将使用 Ubuntu Server 18.04:

AMI type (Ubuntu 18.04)

点击 Select,然后在下一页选择符合条件的 t2.micro 实例(实例是我们 AMI 的硬件)。这只有 1 个 CPU 和 1 GB 的 RAM,但实际上足以运行我们预先训练的递归神经网络应用程序!如果你期望更多的流量或者运行一个 cpu 密集型的应用程序,你可能不得不付钱。

安全组

选择所需的实例类型,然后转到选项卡 6。在页面顶部配置安全组。安全组过滤进出我们实例的流量——基本上,谁可以访问我们的虚拟计算机。

您(只有您)需要通过ssh访问实例,所以添加一个规则,允许 SSH 使用Source“My IP”。我们希望 others 能够在网络浏览器中访问我们的应用程序,所以添加一个规则来允许所有来源的 HTTP 访问。最终的安全配置是:

Security group rules

接下来,点击查看和启动,然后启动。这将显示使用密钥对的选项。你需要这个来通过ssh访问服务器,所以请确保创建一个新的密钥对,并将私钥保存在你记得的地方。如果丢失,您将无法再次访问您的实例!

最后,点击 Launch Instances,Amazon 将启动您自己的虚拟机,该虚拟机实际位于… 某处。等待几分钟,让实例启动,然后进入下一步:连接到实例。

通过 SSH 连接到服务器

一旦实例启动并运行,在 EC2 实例仪表板上选择它(服务> EC2 >运行实例)并点击 Connect。这将为我们提供连接到实例的确切命令。

Connect dialog from EC2 running instances dashboard.

复制示例代码,并将其粘贴到 Bash 中,或者粘贴到在带有您的私钥的文件夹中运行的命令提示符中(在启动您的实例时生成)。假设一切顺利,您将登录到您的实例并看到一个熟悉的终端命令提示符。

安装要求

这个 AMI 配备了 Python 3.6 ,所以我们只需要克隆存储库并安装应用依赖项。首先,获取存储库:

git clone [https://github.com/WillKoehrsen/recurrent-neural-networks.git](https://github.com/WillKoehrsen/recurrent-neural-networks.git)

然后安装pip,移入资源库,安装需求。

sudo apt-get update
sudo apt-get install python3-pip
cd recurrent-neural-networks
pip3 install --user -r requirements.txt

运行和访问 Web 应用程序

运行应用程序很简单(第二个命令可能需要sudo):

cd deployment
python3 run_keras_server.py

(如果你想了解 web 应用程序中发生了什么,看看以前的文章中的开发过程)。

您应该在终端中看到以下输出:

虽然看起来这个应用运行在 localhost:80/上,但那是在虚拟机上。为了访问 web 应用程序,我们必须使用实例的公共 DNS IPv4 ,它可以在正在运行的实例仪表板上找到。

Public DNS for running instance.

将地址复制并粘贴到您的浏览器中,您将看到该应用程序!

Homepage of the web application.

请随意使用递归神经网络应用程序。它所做的是用一个递归神经网络生成新的专利摘要,这个神经网络用关键词“神经网络”训练成千上万的摘要,你可以输入random作为随机的开始序列,或者你自己的序列。(要看发展,查看这篇文章或者这个笔记本)。

Keras recurrent neural network application.

现在,世界上任何人都可以通过 IPv4 访问您的应用程序。如果您想让应用程序在您注销实例后继续运行,请在屏幕会话中运行它。( Screen 是一个方便的程序,它可以让你使用虚拟控制台从一个终端窗口运行终端会话。)

# From within recurrent-neural-networks/deployment
screen -R deploy
python3 run_keras_server.py

我的(如果我没有关闭它或遇到错误)应用程序应该在http://54.173.255.177/运行。因为我使用的是 t2.micro 实例,所以永久运行这个 web 应用程序的成本正好是$0.00!如果你想要一个域名,你可以从域名注册商比如哈弗那里拿一个。

后续步骤

尽管这是一个快速部署个人项目的不错的解决方案,但这不是一个生产就绪的部署!为此,你要确保使用适当的安全措施(HTTPS 和认证证书)。您还需要确保您的应用程序能够处理预期的流量。仅将此特定解决方案用于没有敏感数据的小型项目。

结论

我们确实生活在一个不可思议的时代:使用 Flask,我们可以在几分钟内开发一个 Python web 应用程序,然后我们可以使用 AWS 将其免费部署到世界各地。我们遵循的一般流程是:开发一个 web 应用程序(最好用 Python),从云提供商那里租用商用硬件,然后向全世界部署一个 web 应用程序。

如果您能够遵循所有教程,从递归神经网络的实现到开发本地 web 应用到在 AWS 上部署,那么您将完成一个令人印象深刻的项目!从一个空白文件到一个正在运行的 web 应用程序的整个过程可能令人望而生畏,但是像大多数技术问题一样,如果你把它分解,每一步都不是压倒性的,有许多开源工具可以使这个过程变得容易。如果你是一个厌倦了在 Jupyter 笔记本上做独立分析的数据科学家,那就主动做一个可以作为应用程序部署的项目。扩展到其他学科是很好的,构建和部署 web 应用程序是学习一些新技能的好机会。

一如既往,我欢迎反馈和建设性的批评。可以通过 Twitter @koehrsen_will 或者通过我的个人网站 willk.online 找到我。

为您的小型企业部署人工智能—预算有限

原文:https://towardsdatascience.com/deploying-artificial-intelligence-for-your-small-business-on-a-shoestring-budget-1087cfe5dcc2?source=collection_archive---------5-----------------------

Photo by Felix Russell-Saw on Unsplash

像大多数成功的小企业主一样,你可能会雄心勃勃地实施新的想法和战略,以保证你的企业保持领先地位。新兴技术也不例外。因此,在花时间探索了一些人工智能(AI)的用例之后,您已经准备好尝试一下了。

当然,总会有人唱反调。“人工智能技术并不适合所有人,”一些人会说。“小公司缺乏部署人工智能工具的预算、资源和能力。”当然,像亚马逊、易贝和 UPS 这样的知名品牌主导了围绕人工智能的对话。随着数据科学家团队夜以继日地构建机器学习模型,以提高效率或找到最佳递送路线,他们不断地创造新闻。

但是人工智能技术并不仅仅适用于预算数十亿美元的公司。事实上,小型企业社区正在削减成本,并通过人工智能应用程序提供出色的客户体验——他们正在与大公司进行大规模竞争。

利用人工智能的力量远没有你想象的那么复杂。这里有一些让你开始的想法。

打造一个 简单的机器人——提高客户满意度,改善员工工作流程。

尝试人工智能的最简单方法之一是建立一个公司聊天机器人,并将其集成到您的客户服务流程中。定制的机器人可以通过提供 24 小时支持、处理简单的查询和实时回答问题来提高客户满意度,这对于没有耐心的客户来说是一大胜利。消费者不仅已经习惯了它们,还喜欢它们。

这也是一件好事,因为专家预测,“到 2020 年,超过 85%的客户互动将无人管理。”网站上一个友好、信息丰富的机器人会让您的客户高兴,同时为您的代理腾出时间来处理更独特、更具挑战性的需求。正确的机器人也是促进员工工作流程的一种聪明方式。公司机器人可以回答人力资源问题,推动入职,并为需要即时答案的忙碌员工提供详细信息。

开始使用聊天机器人很简单。有了各种各样的免费和付费解决方案,构建和运行机器人再简单不过了。

部署人工智能就绪型解决方案——另一个经济实惠的切入点。

即使没有花哨的数据仓库或预算来进行重大的基础设施大修,小公司仍然可以利用智能技术和使用人工智能的应用程序。

软件即服务提供商以低成本或零成本提供人工智能就绪的解决方案,即使在预算有限的情况下也能提供最先进的工具。例如,WorkFusion 帮助企业使用他们的 RPA Express 将人工智能工具插入到现有的工作流程中,这是一种免费下载,提供企业级自动化,不需要编码。实际上,只需几分钟,您就可以开始意识到效率的提高和工作流程的减少。

为了实现数字营销的成功,成千上万的小企业通过脸书和谷歌的广告平台利用人工智能。另一种进入人工智能技术的快速而肮脏的方法是,他们的算法通过锁定和匹配具有相似特征的人来创建相似的广告活动,从而优化广告活动。

有了多渠道营销活动,像acquisito这样的平台可以分析和管理点击付费成功案例,为优化营销支出提供明智的建议。

不要害怕尝试——但首先要制定战略。

小型企业人工智能成功的关键是将有前途的应用程序与业务目标结合起来。思考并定义技术的目的,并根据这些计划确定优先级。

例如,如果您经常使用复杂的数据,并且后端工作流也很复杂,那么考虑自动化如何能够收紧船只、提高效率并增强工作流。提高后端业务的自动化有助于您更加专注于提供客户渴望的获奖体验。

当你的营销团队的目标是优化广告定位时,人工智能驱动的预测分析可能是一个很好的起点。外卖?一旦人工智能功能被部署,就可以对其进行实验,但是没有计划就进行实验是疯狂的。

总之

有了比以往更多的选择,小企业正在建立强大的人工智能战略,而不必雇用数据科学家或昂贵的营销专家。通过轻松访问第三方工具和用户友好的应用程序,人工智能支持的功能正在使工作流程更加高效,客户更加满意,同时为企业主提供应对数据驱动型经济日益增长的挑战的能力。

无论你现在决定部署人工智能还是以后部署,了解你的选择是必不可少的。现在的明智决策将使你以后受益——这是人工智能旅程中良好的第一步。

部署深度学习模型

原文:https://towardsdatascience.com/deploying-deep-learning-models-e9e4d7dda3ff?source=collection_archive---------10-----------------------

创建模型是一回事,但是部署模型来解决业务问题是另一回事。看看部署深度学习模型的最佳选择之一。

什么是模型?

https://towardsdatascience.com/creating-intelligence-with-data-science-2fb9f697fc79

我们人类模拟这个世界,用我们的智慧去理解事物的运作方式,并用这种理解和知识去解决困难和复杂的问题。建模是理解“现实”,我们周围的世界,但创建一个更高层次的原型来描述我们看到的,听到的和感觉到的东西的过程,但它是一个代表性的东西,而不是“实际”或“真实”的东西。

在过去的一篇文章中,我谈到了用人工智能和数据科学解决商业问题的过程,

这里的模型是由像深度学习(DL)算法这样的人工智能创建的。如果您想了解更多关于 DL 的信息,您可以阅读以下内容:

[## 深度学习的“怪异”介绍

有关于深度学习的惊人介绍、课程和博文。但这是一种不同的介绍…

towardsdatascience.com](/a-weird-introduction-to-deep-learning-7828803693b0) [## 关于深度学习的对话

有人无意中听到两个人谈论深度学习,让我知道每一个小细节。其中一个完全…

towardsdatascience.com](/a-conversation-about-deep-learning-9a915983107)

好了,你刚刚创建了一个模型(比如说一个 DL 模型)来解决一个业务问题,现在你想把它投入生产。

什么是生产?

投入生产对你们每个人来说都有不同的意义。

对一些人来说,将模型投入生产意味着任何人都可以使用模型来计算、测量或观察某些东西。例如,这里一个闪亮的仪表板后面有一个简单的模型,业务分析师可以访问它,它可以是一个“生产化”的模型。

对其他人来说意味着让模型做一些事情或者与客户互动。就像在你的移动应用程序中让一个模型预测当人们向你借钱时你是否应该借钱给他们。

我创建了这个简单的图表来指定部署模型的不同方式:

在这里,我将教你如何通过深度认知将深度学习在线模型或 AaaS 模型部署到生产服务中。

部署您的 DL 模型

deepcognition.ai

如果你想了解更多关于深度认知和他们的深度学习工作室(DLS ),看看这个:

[## 深度认知让深度学习变得简单

在过去的一个月里,我有幸见到了 DeepCognition.ai 的创始人

becominghuman.ai](https://becominghuman.ai/deep-learning-made-easy-with-deep-cognition-403fbe445351) [## 深度认知的视频漫游

大家好!在本文中,我将与您分享几个视频,带您浏览深度认知的平台…

towardsdatascience.com](/a-video-walkthrough-of-deep-cognition-fd0ca59d2f76)

一旦模型构建完成,DLS 允许将模型部署为 REST API。除了部署 REST API 之外,还生成并部署了一个简单的基于表单的 Web 应用程序,用于快速测试和共享。

这些 REST API 或 Web app 可以用作在线模型或 AaaS。要部署您的模型,您有两种选择:

  • 上传您的 DL 代码(如 keras 或 TF),系统会识别它,您可以用 DLS 和您的数据训练它,然后您必须单击部署部分。
  • 从头开始用 DLS 创建你的模型,然后训练和部署它。

这里有一个视频来自过去的帖子,您可以从中了解如何部署它:

基本上这些是步骤:

  • 点击部署选项卡。
  • 选择训练跑步。
  • 输入服务名称。
  • 选择是否要在您的实例(可以是 web 或本地,如您的公司集群)或远程实例(如 AWS、GCP、Azure 等)中部署它。)
  • 点击部署按钮。

就是这样!如果你能以一种非常简单的方式免费完成,你就不必花几个小时去想如何去做。我使用这种方法的经验非常成功。

部分推荐:

  • 如果您想要高可用性,就有一个专用的实例来部署您的模型。
  • 确保您使用了良好的培训结果,并且在投入生产之前已经验证了您的参数。
  • 读读这个:

[## 操作机器学习:成功 MLOps 的七个考虑因素

机器学习无处不在。从广告到物联网到医疗保健等等,几乎所有行业都…

www.kdnuggets.com](https://www.kdnuggets.com/2018/04/operational-machine-learning-successful-mlops.html) [## 将机器学习模型转化为实际产品和服务的经验教训

人工智能仍处于初级阶段。今天,只有 15%的企业在使用机器学习,但是两倍…

www.oreilly.com](https://www.oreilly.com/ideas/lessons-learned-turning-machine-learning-models-into-real-products-and-services)

如果您有任何问题,请在 Twitter 上关注我:

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

和 LinkedIn:

[## favio vázquez——science ia y Datos | LinkedIn 创始人

查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 16 个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/faviovazquez/)

那里见:)

部署深度学习模型:第 1 部分概述

原文:https://towardsdatascience.com/deploying-deep-learning-models-part-1-an-overview-77b4d01dd6f7?source=collection_archive---------1-----------------------

Diagram overviewing the CI/CD deployment process with Kubernetes. Taken from Kubecon slideshow

最近,学术界和行业研究人员在深度学习领域进行了大量令人兴奋和开创性的研究。他们开发了许多功能强大得令人难以置信的新型号。然而,这种研究的大部分(少数科技巨头之外)仍然只是研究,而不是生产应用的一部分。尽管新论文不断涌现,但在生产中实际利用这些模型仍然非常困难(即使论文提供了代码)。部署机器学习模型仍然是一个重大挑战。在这篇文章中,我将概述“生产化”机器学习模型的各种方法,并权衡它们各自的利弊,而不会涉及太多细节。在后续文章中,我将通过实际代码和示例来探索这些方法。

挑战

我们将假设我们已经自己训练了模型,或者已经从互联网上获得了训练的权重。为了在应用程序中使用您的模型,您必须:

  1. 用模型的权重加载模型
  2. 预处理您的数据
  3. 执行实际预测
  4. 处理预测响应数据

听起来够简单吧?实际上,这个过程可能非常复杂。

像许多事情一样,关于将机器学习模型部署到生产环境的最佳方式,没有一个明确的答案。你应该问自己的问题是:

  1. 我的要求是什么?(例如,您预计每秒有多少请求,需要多长时间的延迟等等)
  2. 我将如何评估模型在生产中的表现?(我将如何收集和存储来自交互的额外数据)
  3. 我计划多长时间重新培训一次我的模型?
  4. 有哪些数据预处理需求?
  5. 生产输入数据的格式是否会与模型训练数据大相径庭?它会分批来还是一股一股来?
  6. 模型需要能够离线运行吗?

这些是您在尝试部署您的模型之前应该问的基本问题。

将模型直接加载到应用程序中

这个选项本质上将模型视为整个应用程序的一部分,因此将它加载到应用程序中。这种方法在某些情况下比其他情况更容易。

例如,如果核心应用程序本身是用 Python 编写的,这个过程可能会很顺利。总之,它通常需要在设置/配置文件中添加依赖项,并修改您的预测函数,以便通过适当的用户交互来调用。模型是作为应用程序的一部分加载的,所有依赖项都必须包含在应用程序中。

如果您的应用程序不是用 Python 编写的,这个过程会变得更加困难。例如,没有好的方法将 PyTorch 或 Caffe 加载到 Java 程序中。即使是有 Java 库的 Tensorflow,也需要编写大量额外的代码才能完全集成到应用程序中。最后,这并没有明确解决可伸缩性的问题。

然而,如前所述,当您想要快速部署用 Python 编写的应用程序时,这种方法仍然是有益的。它也是没有互联网连接的设备的较好选择之一。

调用 API

第二个选项包括创建一个 API 并从您的应用程序中调用该 API。这可以通过多种不同的方式来实现。我在这里详细介绍了最常见的方式。

Kubernetes

在许多方面,Docker 似乎是部署机器学习模型的自然选择。一个模型及其所有的依赖项可以整齐地打包在一个容器中。此外,服务器可以在需要时通过添加更多 Docker 容器来自动扩展。Kubernetes 是管理 Docker 容器的最佳方式之一,因此有利于机器学习。

最近,Kubernetes 发布了 Kubeflow ,旨在将机器学习引入 Kubernetes 框架。Kubeflow 试图使训练、测试和部署您的模型以及收集评估指标变得容易。我计划在以后的博客中介绍 Kubeflow,因为它可能非常复杂。现在只需要理解它是一个完整的软件包,旨在使大规模开发和部署机器学习微服务变得容易。

用 Flask/Django 定制 REST-API

另一个选择是根据您对制作 API 的熟悉程度,从头开始创建自己的 REST-API(这个选项也可以与 Docker 结合使用)。这可以使用烧瓶相对容易地完成。我不会详细讨论如何做到这一点,因为已经有很多教程详细介绍了这个主题。根据请求的数量,您通常可以轻松扩展 Flask。

然而,由于 ML 框架、加载时间和特定的模型预处理需求的差异,即使这样也会变得相当混乱。目前,我正在开发一个用于 Flask/Django 的模型不可知实例化类,以便更容易使用模型,并提供一个使用模型的标准化模板。因此,你可以调用model.preprocess()model.predict()而不用考虑后端,而不必记住并实现不同模型的不同函数(另一篇文章中也有更多相关内容)。

AWS Lambda/无服务器

AWS Lambda 是另一条可能的路线。你可以阅读 AWS 的文档来了解如何设置。在“机器学习”中有一篇关于使用 AWS lambda 和 Caffe2 的好文章

其他方法

Apache Beam —我不太了解这种方法,但该方法似乎涉及到使用 Beam 做模型预处理,然后 Tensorflow(目前只支持框架)做实际预测。查看这些幻灯片了解更多信息。

火花/火花

Spark 和 Flink 等几个主要的数据处理框架正在开发软件包,以帮助部署机器学习模型。Flink 有 Flink Tensorflow 旨在将 TF 模型集成到 Flink 流管道中。对于 Spark,有许多不同的包和集成深度学习的尝试。此外,雅虎最近发布了自己的 ,允许分布式训练和模型服务。

结论

在未来的文章中,我将更详细地介绍如何用 Kubeflow 构建一个 API 来服务模型,并讨论如何将深度学习模型加载到 Java 程序和 Flink 管道中。

使用 Flask 部署 Keras 深度学习模型

原文:https://towardsdatascience.com/deploying-keras-deep-learning-models-with-flask-5da4181436a2?source=collection_archive---------2-----------------------

Source: Wikimedia Commons

这篇文章演示了如何使用用 Keras 构建的深度学习模型来设置端点以服务于预测。它首先介绍了一个使用 Flask 来设置 Python 端点的例子,然后展示了在使用 Flask 为预测构建 Keras 端点时需要解决的一些问题。

将深度学习模型产品化具有挑战性,或者至少在过去对我来说是如此,原因有很多:

  • **模型序列化:**序列化模型的标准方法,比如 PMML,只有有限的支持。例如 keras2pmml 缺少 relu 激活,这意味着我在模型生产帖子中提出的数据流+ PMML 方法是不可行的。
  • **大型库:**在我过去的帖子中,我展示了如何使用 AWS lambda 函数来托管 scikit-learn 模型。这种方法对于 Keras 是有问题的,因为未压缩的 Keras 和 Tensorflow 库超过了 AWS lambda 的 256MB 文件上传限制。
  • **运行时间:**批处理和实时预测都很难伸缩,因为我的大部分模型预测经验都是用 Java 编写的。我之前在的博客中提到使用 Jetty 提供实时评估,使用 Google 的数据流提供批量评估。这篇文章展示了当你需要使用 Python 库进行估算时,如何使用 Flask 来代替 Jetty。

这篇文章的目的是展示如何使用 AWS 在 EC2 实例上设置一个 Keras 模型作为端点。我从探索下面的例子开始:

[## 构建一个简单的 Keras +深度学习 REST API

这篇文章中的例子将作为构建你自己的深度学习 API 的模板/起点…

blog.keras.io](https://blog.keras.io/building-a-simple-keras-deep-learning-rest-api.html)

我将讨论的一些问题包括在 Keras 中使用模型持久性时处理自定义指标,在 Keras 与 Flask 结合使用时处理多线程问题,以及让它在 EC2 实例上运行。这篇文章的完整代码清单可以在 GitHub 上找到。

这篇文章介绍了如何设置一个简单的 Flask 应用程序,然后展示了如何使用 Flask 来设置一个带有 Keras 模型的端点。它假设读者熟悉用 jupyter 设置 EC2 实例,这将在这里讨论。

带烧瓶的 Hello World

Flask 是一个 Python 库,它使得设置可以通过 web 调用的 Python 函数变得很容易。它使用注释来提供关于在哪些端点设置哪些功能的元数据。要使用 Flask,您首先需要安装模块:

pip3 install --user Flask

为了熟悉 Flask,我们将设置一个简单的函数来回显传入的参数。下面的代码片段首先实例化一个 Flask 应用程序,定义函数,然后启动应用程序。使用 Flask, app.route 注释用于指定在 web 上的何处使函数可用,以及允许哪些方法。使用下面的代码,该功能将在*location:5000/predict*可用。该函数检查request.jsonrequest.args对象的输入参数,这些参数的使用基于函数的调用方式(例如浏览器 get vs curl post )。如果一个消息参数已经被传递给该函数,当它被回显到该函数返回的 JSON 响应时。

**# load Flask** import flask
app = flask.Flask(__name__)**# define a predict function as an endpoint** [@app](http://twitter.com/app).route("/predict", methods=["GET","POST"])
def predict():
    data = {"success": False} **# get the request parameters**    params = flask.request.json
    if (params == None):
        params = flask.request.args **# if parameters are found, echo the msg parameter** 
    if (params != None):
        data["response"] = params.get("msg")
        data["success"] = True **# return a response in json format**    return flask.jsonify(data)**# start the flask app*, allow remote connections*** app.run(host='0.0.0.0')

当您运行python3 [Flask_Echo.py](https://github.com/bgweber/StartupDataScience/blob/master/DeepLearning/Flask_Echo.py)时,您将得到以下结果:

* Running on [http://127.0.0.1:5000/](http://127.0.0.1:5000/) (Press CTRL+C to quit)

我们现在可以连接到函数来测试它。为了支持远程连接,我加入了host='0.0.0.0',因为 Flask 应用程序运行在 EC2 实例上。如果您使用 EC2,您需要修改安全组以允许在端口 5000 上访问 Flask,类似于在 8888 上允许 Jupyter 访问。

Inbound rules for the EC2 instance.

可以使用 web 浏览器或 curl 调用该函数。我用的是 Windows 环境下的 curl,不然你可以用-d '{"msg":"Hello World"}'。两种方法的结果是一样的,来自客户端的 JSON 响应重复了传入的 msg 参数。

**# Browser** 
[http://](http://localhost:5000/predict?msg=HelloWorld1)[54.227.110.43](http://54.227.110.43:5000/predict?g1=1&g2=0&g3=0&g4=0&g5=0&g6=0&g7=0&g8=0&g9=0&g10=0)[:5000/predict?msg=HelloWorld](http://localhost:5000/predict?msg=HelloWorld1)**# Curl** >curl -X POST -H "Content-Type: application/json" -d "{ \"msg\":
\"Hello World\" }" [http://](http://localhost:5000/predict)[54.227.110.43](http://54.227.110.43:5000/predict?g1=1&g2=0&g3=0&g4=0&g5=0&g6=0&g7=0&g8=0&g9=0&g10=0)[:5000/predict](http://localhost:5000/predict)**# Response** {
  "response": "Hello World",
  "success": true
}

我们现在有能力将 Python 函数设置为 web 端点,下一步是让函数调用一个经过训练的深度网络。

弗拉斯克&克拉斯

要使用 Keras 进行深度学习,我们需要首先用 Keras 和 Tensorflow 库设置环境,然后训练一个模型,我们将通过 Flask 在 web 上公开该模型。

**# Deep Learning setup** pip3 install --user tensorflow
pip3 install --user keras
pip3 install --user  pandas

因为我使用了一个没有附加 GPU 的 EC2 实例,所以在 CPU 模式下运行 Keras 不需要额外的配置。

模型训练 我用一个简单的网络结构创建了一个二元分类器。模型的输入是描述用户以前玩过哪些游戏的特征数组,输出是玩家将来玩特定游戏的可能性。关于训练模型的更多细节可以在我过去关于深度学习的帖子中找到。

**# import panda, keras and tensorflow** import pandas as pd
import tensorflow as tf
import keras
from keras import models, layers**# Load the sample data set and split into x and y data frames** df = pd.read_csv("https://github.com/bgweber/Twitch/raw/
                      master/Recommendations/games-expand.csv")
x = df.drop(['label'], axis=1)
y = df['label']**# Define the keras model** model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10,)))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

**# Use a custom metricfunction** def auc(y_true, y_pred):
    auc = tf.metrics.auc(y_true, y_pred)[1]
   keras.backend.get_session().run(tf.local_variables_initializer())
    return auc **# Compile and fit the model** model.compile(optimizer='rmsprop',loss='binary_crossentropy',
              metrics=[auc])
history = model.fit(x, y, epochs=100, batch_size=100,
                    validation_split = .2, verbose=0) **# Save the model in h5 format** model.save("games.h5")

代码片段定义了一个自定义指标函数,用于训练模型以优化 ROC AUC 指标。这段代码的主要附加部分是最后一步,它将模型序列化为 h5 格式。我们可以稍后将这个模型加载到 Flask 应用程序中,以服务于模型预测。可以通过运行生成games.h5python3 [Flask_Train.py](https://github.com/bgweber/StartupDataScience/blob/master/DeepLearning/Flask_Train.py)来训练模型。

模型部署
用于模型预测的完整代码清单如下所示。代码的整体结构与我们前面的例子相同,但是主要的区别是在定义预测函数之前加载模型,并在预测函数中使用模型。为了重新加载模型,我们需要使用 custom_objects 参数将自定义度量函数作为输入参数传递给 load_model

**# Load libraries** import flask
import pandas as pd
import tensorflow as tf
import keras
from keras.models import load_model

***# instantiate flask*** app = flask.Flask(__name__)

***# we need to redefine our metric function in order 
# to use it when loading the model*** def auc(y_true, y_pred):
    auc = tf.metrics.auc(y_true, y_pred)[1]
   keras.backend.get_session().run(tf.local_variables_initializer())
    return auc

***# load the model, and pass in the custom metric function*** global graph
graph = tf.get_default_graph()
model = load_model('games.h5', custom_objects={'auc': auc})

***# define a predict function as an endpoint*** @app.route("/predict", methods=["GET","POST"])
def predict():
    data = {"success": False}

    params = flask.request.json
    if (params == None):
        params = flask.request.args

 ***# if parameters are found, return a prediction***    if (params != None):
        x=pd.DataFrame.from_dict(params, orient='index').transpose()
        with graph.as_default():
            data["prediction"] = str(model.predict(x)[0][0])
            data["success"] = True

 ***# return a response in json format***    return flask.jsonify(data)    

*#* ***start the flask app, allow remote connections*** app.run(host='0.0.0.0')

使用tf.get_default_graph()建立对张量流图的引用也是必要的。如果省略此步骤,预测步骤期间可能会发生异常。条件with graph.as_default()用于在进行预测时获取对图的线程安全引用。在预测函数中,请求参数被转换为数据帧,然后传递给 Keras 模型进行预测。关于使用传入参数的更多细节在我的模型即服务帖子中有所介绍。

可以通过运行python3 [Flask_Deploy.py](https://github.com/bgweber/StartupDataScience/blob/master/DeepLearning/Flask_Deploy.py)来部署 Flask app。你可以像以前一样连接到应用程序,但是你需要指定属性 G1G10 的值。我使用浏览器测试端点,结果如下:

**# Browser** [http://54.227.110.43:5000/predict?g1=1&g2=0&g3=0&g4=0&g5=0&g6=0&g7=0&g8=0&g9=0&g10=0](http://54.227.110.43:5000/predict?g1=1&g2=0&g3=0&g4=0&g5=0&g6=0&g7=0&g8=0&g9=0&g10=0)**# Response** {
 "prediction":"0.04930059",
 "success":true}
}

您现在有了一个 EC2 实例,可以在 web 上提供 Keras 预测服务!

结论

部署深度学习模型并不简单,因为您需要使用支持 tensorflow 运行时的环境。为了以服务的形式提供 Keras 模型,我展示了如何使用 Flask 来为预先训练好的模型提供预测服务。这种方法不如我在上一种方法中讨论的 AWS lambda 方法可伸缩,但可能更适合您的用例。在原型制作时,Flash 对于设置本地服务也很有用。

理想情况下,我希望能够将 Flask 中的注释与 AWS lambda 的可伸缩性结合起来,而不需要将库安装到目录中并上传结果的中间步骤。AWS SageMaker 有助于实现这一目标,我将在未来几周内更详细地探索这一工具。

本·韦伯是 Zynga 的首席数据科学家。我们正在招聘!

用 Java 部署 Keras 深度学习模型

原文:https://towardsdatascience.com/deploying-keras-deep-learning-models-with-java-62d80464f34a?source=collection_archive---------2-----------------------

Source: Wikipedia

Keras 库为深度学习提供了一个可接近的接口,使神经网络可以为广大受众所用。然而,我所面临的挑战之一是从在 Keras 中探索模型过渡到产品化模型。Keras 是用 Python 编写的,直到最近,在这些语言之外还只有有限的支持。虽然 Flask、PySpark 和 Cloud ML 等工具使得直接用 Python 将这些模型产品化成为可能,但我通常更喜欢用 Java 来部署模型。

像 ONNX 这样的项目正在走向深度学习的标准化,但支持这些格式的运行时仍然有限。一种常用的方法是将 Keras 模型转换成张量流图,然后在其他支持张量流的运行程序中使用这些图。我最近发现了 Deeplearning4J (DL4J)项目,该项目原生支持 Keras 模型,使得用 Java 进行深度学习变得很容易。

[## Keras 导入概述| Deeplearning4j

Keras 模型导入提供了导入最初使用 Keras 配置和训练的神经网络模型的例程…

deeplearning4j.org](https://deeplearning4j.org/docs/latest/keras-import-overview)

我一直在探索的深度学习的一个用例是使用 Keras 在 Python 中训练模型,然后使用 Java 将模型产品化。这对于需要直接在客户端进行深度学习的情况很有用,比如 Android 设备应用模型,以及想要利用现有的用 Java 编写的生产系统的情况。关于使用 Keras 的 DL4J 介绍可以在这里找到。

这篇文章概述了用 Python 训练 Keras 模型,并用 Java 部署它。我使用 Jetty 提供实时预测,使用 Google 的数据流构建批量预测系统。GitHub 上提供了运行这些示例所需的全部代码和数据。

[## bgweber/DeployKeras

GitHub 是人们构建软件的地方。超过 2800 万人使用 GitHub 来发现、分享和贡献超过…

github.com](https://github.com/bgweber/DeployKeras/tree/master)

模特培训

第一步是使用 Python 中的 Keras 库训练一个模型。一旦有了准备部署的模型,就可以将其保存为 h5 格式,并在 Python 和 Java 应用程序中使用它。在本教程中,我们将使用我在 Flask 上的博客文章中训练的预测哪些玩家可能会购买新游戏的相同模型。

[## 使用 Flask 部署 Keras 深度学习模型

这篇文章演示了如何使用 Keras 构建的深度学习模型来设置端点以服务于预测。它…

towardsdatascience.com](/deploying-keras-deep-learning-models-with-flask-5da4181436a2)

模型的输入是描述玩家已经购买的游戏的十个二元特征( G1,G2,…,G10 ),标签是描述用户是否购买了不包括在输入中的游戏的单个变量。培训过程中涉及的主要步骤如下所示:

import keras
from keras import models, layers**# Define the model structure** model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10,)))
...
model.add(layers.Dense(1, activation='sigmoid'))**# Compile and fit the model** model.compile(optimizer='rmsprop',loss='binary_crossentropy',
              metrics=[auc])
history = model.fit(x, y, epochs=100, batch_size=100,
                    validation_split = .2, verbose=0)**# Save the model in h5 format** model.save("games.h5")

这个过程的输出是一个 h5 文件,它表示我们可以在 Python 和 Java 应用程序中部署的经过训练的模型。在我过去的帖子中,我展示了如何使用 Flask 在 Python 中提供实时模型预测。在这篇文章中,我将展示如何用 Java 构建批处理和实时预测。

Java 设置

为了用 Java 部署 Keras 模型,我们将使用 Deeplearing4j 库。它为 Java 中的深度学习提供了功能,并可以加载和利用用 Keras 训练的模型。我们还将使用数据流进行批量预测,使用 Jetty 进行实时预测。以下是我在这个项目中使用的库:

  • deep learning 4j**:**为 Java 提供深度神经网络功能。
  • ND4J**:**为 Java 提供张量运算。
  • Jetty**:**用于设置 web 端点。
  • 云数据流: 为 GCP 上的批量预测提供自动缩放。

我使用下面显示的 pom.xml 将它们导入到我的项目中。对于 DL4J,使用 Keras 时需要核心库和模型导入库。

<dependencies>
  <dependency>      
    <groupId>org.deeplearning4j</groupId>      
    <artifactId>deeplearning4j-core</artifactId>
    <version>1.0.0-beta2</version>    
  </dependency>         
  <dependency>      
    <groupId>org.deeplearning4j</groupId>      
    <artifactId>deeplearning4j-modelimport</artifactId>      
    <version>1.0.0-beta2</version>    
  </dependency>                       
  <dependency>      
    <groupId>org.nd4j</groupId>      
    <artifactId>nd4j-native-platform</artifactId>
    <version>1.0.0-beta2</version>    
  </dependency>
  <dependency>      
    <groupId>org.eclipse.jetty</groupId>      
    <artifactId>jetty-server</artifactId>      
    <version>9.4.9.v20180320</version>   
  </dependency>  <dependency>      
    <groupId>com.google.cloud.dataflow</groupId>      
    <artifactId>google-cloud-dataflow-java-sdk-all</artifactId>  
    <version>2.2.0</version>     
  </dependency>
</dependencies>

我在 Eclipse 中设置了我的项目,一旦我正确配置了 pom 文件,就不需要额外的设置就可以开始了。

使用 DL4J 的 Keras 预测

现在我们已经建立了库,我们可以开始使用 Keras 模型进行预测。我编写了下面的脚本来测试加载 Keras 模型并对样本数据集进行预测。第一步是从 h5 文件中加载模型。接下来,我定义一个长度为 10 的 1D 张量,并生成随机的二进制值。最后一步是对模型调用 output 方法来生成预测。因为我的模型只有一个输出节点,所以我使用 getDouble(0) 来返回模型的输出。

**// imports** import org.deeplearning4j.nn.modelimport.keras.KerasModelImport;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.io.ClassPathResource;**// load the model** String simpleMlp = new ClassPathResource(
                          "games.h5").getFile().getPath();
MultiLayerNetwork model = KerasModelImport.
                    importKerasSequentialModelAndWeights(simpleMlp);**// make a random sample** int inputs = 10;
INDArray features = Nd4j.zeros(inputs);
for (int i=0; i<inputs; i++) 
    features.putScalar(new int[] {i}, Math.random() < 0.5 ? 0 : 1);**// get the prediction** double prediction = model.output(features).getDouble(0);

使用 DL4J 时需要熟悉的一个关键概念是张量。Java 没有高效张量选项的内置库,这就是为什么 NDJ4 是先决条件。它提供了用 Java 实现深度学习后端的 N 维数组。要在张量对象中设置一个值,需要传递一个整数数组,该数组为张量提供一个 n 维索引,并提供要设置的值。因为我用的是 1D 张量,所以数组的长度是 1。

模型对象提供了预测输出方法。predict 方法返回一个类预测(0 或 1),而 output 方法返回一个连续的标签,类似于 scikit-learn 中的 predict_proba

实时预测

现在我们已经有了一个用 Java 运行的 Keras 模型,我们可以开始为模型预测服务了。我们将采用的第一种方法是使用 Jetty 在 web 上设置一个端点来提供模型预测。我之前在关于跟踪数据和模型生产的帖子中提到过 Jetty 的设置。模型端点的完整代码可在这里获得。

模型端点被实现为加载 Keras 模型并提供预测的单个类。它实现 Jetty 的 AbstractHandler 接口来提供模型结果。下面的代码展示了如何设置 Jetty 服务在端口 8080 上运行,并实例化 JettyDL4J 类,该类在构造函数中加载 Keras 模型。

**// Setting up the web endpoint** Server server = new Server(8080);
server.setHandler(new JettyDL4J());
server.start();
server.join();**// Load the Keras model** public JettyDL4J() throws Exception {  
    String p=new ClassPathResource("games.h5").getFile().getPath(); 
    model=KerasModelImport.importKerasSequentialModelAndWeights(p); 
}

管理 web 请求的处理程序如下面的代码片段所示。传入的参数( G1,G2,…,G10 )被转换成 1D 张量对象,并传递给 Keras 模型的输出方法。然后,请求被标记为已处理,预测作为字符串返回。

**// Entry point for the model prediction request** public void handle(String target,Request baseRequest, 
    HttpServletRequest request, HttpServletResponse response) 
    throws IOException, ServletException { **// create a dataset from the input parameters** INDArray features = Nd4j.zeros(inputs);
  for (int i=0; i<inputs; i++) 
      features.putScalar(new int[] {i},  Double.parseDouble(
                          baseRequest.getParameter("G" + (i + 1)))); **// output the estimate** double prediction = model.output(features).getDouble(0);
  response.setStatus(HttpServletResponse.SC_OK);
  response.getWriter().println("Prediction: " + prediction);
  baseRequest.setHandled(true);
}

当您运行该类时,它会在端口 8080 上设置一个端点。您可以通过将浏览器指向以下 URL 来调用模型服务:

**// Request**[http://localhost:8080/?G1=1&G2=0&G3=1&G4=1&G5=0&G6=1&G7=0&G8=1&G9=1&G10=1](http://localhost:8080/?G1=1&G2=0&G3=1&G4=1&G5=0&G6=1&G7=0&G8=1&G9=1&G10=1)**// Result** Prediction: 0.735433042049408

结果是一个 Keras 模型,你现在可以实时调用它来从你的深度学习模型中获得预测。对于生产系统,您可能希望在 Jetty 端点前设置一个服务,而不是直接在 web 上公开端点。

批量预测

Keras 模型的另一个用例是批量预测,在这种情况下,您可能需要对数百万条记录应用估计量。您可以使用 Keras 模型在 Python 中直接实现这一点,但是这种方法的可伸缩性有限。我将展示如何使用 Google 的数据流,通过完全管理的管道将预测应用于海量数据集。我之前在关于模型制作和游戏模拟的帖子中提到过设置数据流。

使用数据流,您可以指定要在数据集上执行的操作的图形,其中源和目标数据集可以是关系数据库、消息服务、应用程序数据库和其他服务。这些图形可以作为批处理操作执行,其中基础架构启动以处理大型数据集,然后关闭;或者以流模式执行,其中维护基础架构并在请求到达时进行处理。在这两种情况下,服务将自动伸缩以满足需求。它经过全面管理,非常适合可以独立执行的大型计算。

DataFlow DAG for Batch Deep Learning

我的数据流流程中的 DAG 操作如上所示。第一步是为要评分的模型创建数据集。在本例中,我从示例 CSV 加载值,而实际上我通常使用 BigQuery 作为模型预测的源和同步。下一步是转换,将表行对象作为输入,将行转换为 1D 张量,将模型应用于每个张量,并使用预测值创建新的输出表行。DAG 的完整代码可在这里获得。

这个管道中的关键步骤是 Keras Predict 转换,如下面的代码片段所示。转换对对象集合进行操作,并返回对象集合。在转换器中,您可以定义诸如 Keras 模型之类的对象,这些对象在转换器中定义的每个流程元素步骤之间共享。结果是,模型为每个转换器加载一次,而不是为需要预测的每个记录加载一次。

**// Apply the transform to the pipeline** .apply("Keras Predict", new PTransform<PCollection<TableRow>, 
                                       PCollection<TableRow>>() {        **// Load the model in the transformer**  public PCollection<TableRow> expand(PCollection<TableRow> input) {                            final int inputs = 10;
    final MultiLayerNetwork model;       
    try {        
     String p= newClassPathResource("games.h5").getFile().getPath();
     model=KerasModelImport.importKerasSequentialModelAndWeights(p);
  }             
  catch (Exception e) {
     throw new RuntimeException(e);
  } **// create a DoFn for applying the Keras model to instances**  return input.apply("Pred",ParDo.of(new DoFn<TableRow,TableRow>(){
    @ProcessElement
    public void processElement(ProcessContext c) throws Exception {
 **...  // Apply the Keras model**    }}));         
}})

process element 方法的代码如下所示。它读取输入记录,从表行创建张量,应用模型,然后保存记录。输出行包含预测值和实际值。

 **// get the record to score** TableRow row = c.element(); **// create the feature vector** INDArray features = Nd4j.zeros(inputs);                 
  for (int i=0; i<inputs; i++)                   
    features.putScalar(new int[] {i}, 
          Double.parseDouble(row.get("G" + (i+1)).toString()));                                               **// get the prediction** double estimate = model.output(features).getDouble(0);               **// save the result** TableRow prediction = new TableRow();                    
  prediction.set("actual", row.get("actual"));                  
  prediction.set("predicted", estimate);                        
  c.output(prediction);

我在本文中排除了 CSV 加载和 BigQuery 编写代码块,因为您可能使用不同的端点。如果你想试着运行 DAG,可以在 GitHub 上找到代码和 CSV。要将结果保存到 BigQuery,您需要如下设置 tempLocation 程序参数:

--tempLocation=gs://your-gs-bucket/temp-dataflow-location

运行 DAG 后,将在 BigQuery 中创建一个新表,其中包含数据集的实际值和预测值。下图显示了我应用 Keras 模型的样本数据点。

Prediction results in BigQuery

将数据流与 DL4J 结合使用的结果是,您可以使用批量预测的自动缩放基础设施对数百万条记录进行评分。

结论

随着深度学习越来越受欢迎,越来越多的语言和环境支持这些模型。随着库开始标准化模型格式,使用不同的语言进行模型训练和模型部署变得可能。这篇文章展示了使用 Python 中的 Keras 库训练的神经网络如何使用 Java 中的 DL4J 库进行批量和实时预测。我第一次能够建立一个批处理过程,将深度学习应用于数百万个数据点。

本·韦伯是 Zynga 的首席数据科学家。我们正在招聘!