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

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

R vs Python:基于 Keras 的图像分类

原文:https://towardsdatascience.com/r-vs-python-image-classification-with-keras-1fa99a8fef9b?source=collection_archive---------2-----------------------

许多数据专家对用于人工神经网络模型的语言非常严格,这限制了他们的发展。Python 专用的环境。我决定根据训练一个基于卷积神经网络的图像识别模型所需的时间来测试 Python 与 R 的性能。作为起点,我从Shirin Elsinghorst博士的博客文章开始,讲述了使用 Keras 在 R 语言中构建 CNN 模型是多么容易。

几句关于 Keras 的话。它是一个用于人工神经网络 ML 模型的 Python 库,提供面向各种深度学习框架的高级前端,默认为 Tensorflow

Keras 有许多优点,其中包括:

  • 只需几行代码即可轻松构建复杂的模型=> 非常适合开发人员。循环快速实验并检查你的想法
  • 代码回收:人们可以很容易地交换后端框架(比如从 CNTKTensorflow 或者反之亦然)=>DRY principle
  • 无缝使用 GPU => 非常适合快速模型调优和实验

由于 Keras 是用 Python 编写的,它可能是您的开发人员的自然选择。使用 Python 的环境。直到大约一年前,RStudio 创始人 J.J.Allaire 宣布于 2017 年 5 月发布 Keras 库。我认为这是数据科学家的一个转折点;现在,我们可以更加灵活地使用 dev。环境,能够更有效地交付结果,并有机会扩展我们用 r 编写现有解决方案

这让我想到了这篇文章的主题。
我的假设是说到用 Keras 建立 ANN ML 模型,Python 不是必须的,根据你客户的要求,或者 tech stack, R 可以无限制使用,效率差不多

基于 Keras 的图像分类

为了测试我的假设,我将使用 kaggle 的水果图像数据来执行图像分类,并训练一个具有四个隐藏层的 CNN 模型:两个 2D 卷积层,一个池层和一个密集层。 RMSProp 正被用作优化器功能

技术堆栈

硬件 :
CPU :英特尔酷睿 i7–7700 HQ:4 核(8 线程)、2800–3800(Boost)MHz 核心时钟
GPU :英伟达 Geforce GTX 1050 Ti 移动:4Gb vRAM、1493–1620(Boost)MHz 核心时钟
RAM : 16 Gb

软件:
OS:Linux Ubuntu 16.04
R:ver。3.4.4
Python : ver。3.6.3
版本。2.2
张量流:版本。1.7.0
CUDA :版本。9.0 ( 注意目前 tensorflow 版本支持 CUDA ver。9.0,而其最新版本是 9.2)
cud nn:ver。7.0.5 ( 注意当前 tensorflow 版本支持 ver。7.0,而 cuDNN 的最新版本是 7.1 )

密码

用于 CNN 模型构建的 R 和 Python 代码片段如下所示。由于 F. Chollet 和 J.J. Allaire 之间卓有成效的合作,R 中的逻辑和函数名与 Python 中的很相似。

R

计算机编程语言

实验

上面的模型用 R 和 Pythons 在 GPU 和 CPU 上训练了 10 次,测量了经过的时间和 10 个历元后的最终精度。

测量结果显示在下图中。

从上面的图表中,我们可以看出

  • 您的模型的准确性不取决于您用来构建和训练它的语言(该图仅显示了训练准确性,但该模型没有很高的方差,偏差准确性也在 99%左右)。
  • 尽管 10 次测量可能没有说服力,但 Python 可以减少(最多 15%)训练 CNN 模型所需的时间。这是意料之中的,因为 R 在执行 Keras 函数时使用了 Python。

假设我们所有的观察值都是正态分布的,让我们进行不成对 t 检验。

T-score 反映了与 Python 相比,在 R 中训练 CNN 模型所需时间的显著差异,正如我们在上面的图中看到的。

摘要

  • 使用 Keras 在 R 中构建和训练 CNN 模型就像在 Python 中一样“简单”,具有相同的编码逻辑和函数命名约定
  • 你的 Keras 模型的最终精度将取决于神经网络结构、超参数调整、训练持续时间、训练/测试数据量等。,但不是您将用于 DS 项目的编程语言
  • 用 Python 训练 CNN Keras 模型可能比 R

附言

如果您想了解更多关于 Keras 的知识,并能够使用这个强大的库来构建模型,我向您推荐以下书籍:

非常感谢您的关注!我希望这篇文章能够帮助有抱负的数据科学家理解不同技术的用例,并避免在选择 DS 项目完成工具时产生偏见。

径向基函数神经网络—我们需要知道的一切

原文:https://towardsdatascience.com/radial-basis-functions-neural-networks-all-we-need-to-know-9a88cc053448?source=collection_archive---------0-----------------------

单感知器 / 多层感知器(MLP) 中的⁃,我们只有线性可分性,因为它们是由输入层和输出层(MLP 中的一些隐藏层)组成的

比如⁃,与、或函数是线性可分的&异或函数是线性可分的。

Linear-separability of AND, OR, XOR functions

⁃我们至少需要一个隐藏层来导出非线性分离

⁃我们的 RBNN 它做的是,它将输入信号转换成另一种形式,然后可以馈送到网络中以获得线性可分性。

⁃ RBNN 在结构上与感知器(MLP)相同。

Distinction between MLP and RBF

⁃ RBNN 由输入、输出层组成。RBNN 被严格限制为只有一个隐含层。我们称这个隐藏层为特征向量。

⁃ RBNN 增加特征向量的维数

Simplest diagram shows the architecture of RBNN

Extended diagram shows the architecture of RBNN with hidden functions.

⁃:在我们进行分类问题之前,我们将非线性传递函数应用于特征向量。

⁃当我们增加特征向量的维数时,特征向量的线性可分性增加。

非线性可分离问题(模式分类问题)在高维空间中比在低维空间中高度可分离。

盖兹定理

⁃什么是径向基函数?

⁃我们定义一个受体= t

⁃:我们在受体周围画正面图。

⁃高斯函数通常用于弧度基函数(正射映射)。所以我们定义径向距离 r = ||x- t||。

Radial distance and Radial Basis function with confrontal map

高斯径向函数:=

ϕ(r) = exp (- r /2 σ )

其中σ > 0

Classification only happens on the second phase, where linear combination of hidden functions are driven to output layer.

⁃的例子。XOR 函数:-

⁃,我有 4 个输入,我不会在这里增加特征向量的维数。因此,我将在这里选择 2 个受体。对于每个变换函数ϕ(x),我们将有每个受体 t

⁃现在考虑 RBNN 结构,

⁃ P := #个输入特征/值。

⁃ M = #变换的矢量维数(隐藏层宽度)。所以 M ≥ P 通常为。

⁃在隐藏层的每个节点上,执行一组非线性的弧度基函数。

⁃输出 c 将保持与分类问题相同(预先定义一定数量的类别标签)。

Architecture of XOR RBNN

Transformation function with receptors and variances.

Output → linear combination of transformation function is tabulated.

只有隐藏层中的⁃节点执行弧度基变换功能。

⁃输出层执行隐藏层输出的线性组合,以给出输出层的最终概率值。

⁃所以分类只做了@ (隐藏层→输出层)

训练 RBNN :-

首先,我们要用反向传播训练隐层

⁃神经网络训练(反向传播)是一种曲线拟合方法。在训练阶段拟合一条非线性曲线。它通过随机逼近,我们称之为反向传播。

⁃对于隐藏层中的每个节点,我们必须找到 t (受体)&方差( σ )【方差——径向基函数的扩散】

⁃在第二个训练阶段,我们要更新隐藏层&输出层之间的加权向量。

在隐藏层中,的每个节点代表的每个变换基函数。函数的任意可以满足非线性可分性,甚至函数集合的组合也可以满足非线性可分性。

⁃:所以在我们的隐藏层变换中,所有的非线性项都包括在内。比如说 X+Y+5XY;它全部包含在超曲面方程中(X 和 Y 是输入)。

⁃因此,第一阶段的训练是由聚类算法完成的。我们定义我们需要的个聚类中心。通过聚类算法,我们计算聚类中心,然后将其指定为每个隐藏神经元的受体

⁃:我必须将 n 个样本或观测值聚类成 m 个聚类(N > M)。

⁃所以输出“集群”就是“受体”。

对于每个受体,我可以找到的方差为"各个受体之间距离的平方和&每个聚类最近的样本 " := 1/N * ||X — t||

⁃对第一个训练阶段的解释是“特征向量被投影到变换的空间上”。

Complex diagram depicting the RBNN

使用径向基神经网络比 MLP 的优势:-

1.RBNN 中的训练比多层感知器(MLP)中的→需要许多交互在 MLP。

2.我们可以很容易地解释 RBNN 隐含层中每个节点的意义/ 功能是什么。这是 MLP 的

3.(什么应该是隐藏层的节点数 & 隐藏层的节点数)这个参数化在 MLP 很难。但这在 RBNN 中是没有的。

4.分类在 RBNN 比在 MLP 要花更多的时间。

随机蓝调

原文:https://towardsdatascience.com/random-blues-bc011cd1d53f?source=collection_archive---------8-----------------------

统计物理学的范式转换理论被用来产生平庸的钢琴即兴创作

Source

无论你是梦想成为著名音乐家的软件工程师,还是梦想成为软件工程师的真正摇滚明星:你可能会对算法音乐生成感兴趣。本文描述了一种可能的 AMG 方法——我们将一种简单的蓝调即兴演奏技术数学建模为多维图上决策的马尔可夫链。

Example result of stochastic composition.

由于大多数 AMG 项目的结果充其量听起来很一般,我们并不真正期望超过那个水平,我们希望通过将算法结构嵌入到一些重要和有趣的科学企业中来带来一些非美学价值(从而获得该领域的洞察力)。我们将把这个问题作为一个非古典(即)扩散过程来处理,并尝试结合一种新颖的数学工具——MERW(见下文),来生成音符序列,希望这些音符序列听起来至少有点像真正音乐才能的早期阶段。

物理

我们希望将音乐即兴创作视为一个随机过程,我们将把它建模为一组图表上的扩散(见下文)。为了在这些图上移动(从一个节点到另一个节点),我们将使用一种叫做最大熵随机游走(MERW)的方法。如果你正在跟踪物理学中的“基本”趋势,你可能会遇到这个概念,因为作者的一个大胆的主张是,它提供了一个统计框架,其中贝尔不等式违反是一个确定性的(和局部的!)系统[ 45

Top: schematic proof of simple Bell inequalities. Bottom: Example of its violation for MERW. See [1, fig. 2]

MERW 的另一个有趣的性质,也是本项目更感兴趣的,是它允许执行经典(即 而不是 量子)扩散,并获得量子系统特有的结果——我们可以观察到强局域化性质,而不是均匀分布。这可能(也可能不会)在理论物理中有很多迷人的含义(例如,“波函数不是真实的,只是统计的,不再有多重宇宙 bs* ”),并有望使一些有趣的 AMG 成分成为可能。*

音乐

音调

在我们的钢琴独奏中,我们想要自动化的第一个决策过程,最先进的人工智能算法是这样的问题:接下来弹哪个音符?为了做到这一点,我们在五声音阶 c 小调布鲁斯音阶中定义了这个问题的可能答案的简单图表,并使用它来执行 MERW,在每次迭代中生成一个新的音符。

This graph is for one octave only. In reality we use a similar graph, but stretched over the same notes in each octave available on the usual piano (resulting in 42 vertices instead of 6).

这尽可能地简单明了——图表的定义方式是在每次迭代中强制一步变化,我们只能停留在 c 小调音阶的相邻音符上。

Two measures of semiquavers composed by the random walk.

持续时间(值)

在我们决定播放哪种声音后,我们需要决定它的时间长度(音符值 ) —我们设计的图表保存了播放声音将响起的三十秒音符(半半音)的数量。

Notice that this graph has different numbers of possible transitions for each vertex and some of them have loops (that is, arrows that connect nodes with themselves).

希望你可以看到最长的可能值是半音符( 16 * 1/32 ),还有几个奇数值,比如 14/32(四分音符+带点的八分音符)。这个图有点密集:我们不希望在生成的序列中有更多的可变性和动态性,所以我们为每个顶点定义了多个可能的转换。以 python 可接受的格式阅读可能更容易:

*# Measure duration in thirty-second notes
duration_graph = {
        1: [2, 4, 6, 8, 16],
        2: [1, 4, 8],
        4: [1, 2, 6, 10],
        6: [4, 6, 8],
        8: [6, 8, 10, 12, 14, 16],
       10: [6, 8, 10, 12],
       12: [1, 2, 4, 14, 16],
       14: [8, 12, 16, 1, 2],
       16: [1, 2, 4, 8, 10]
       }*

例如,当从八个音符(上图中的 4)开始时,算法将生成这种结果:

Three measures long rhythmic pattern arranged by the random walk.

关节

到目前为止,我们定义了一个生成 c 小调音符流的系统。有人怀疑这可能仍然不够令人印象深刻,所以我们将继续添加控制其他音乐事件的图表层。

Graph for the articulation of every n-th note.

假设我们想要在每个 n - 音符上提供某种重音,其中 n 将是一个动态参数,其值由其自己的图形控制。增加音符在序列中的重要性的许多方法之一是添加另一个高一个八度的音符。

它实现起来非常简单,并且很好地增加了最终作品的复杂性,同时保持了基本的 c 小调和声不受干扰。此外,对于左边显示的图表,这种技术不会导致任何会产生任何节奏感的东西,这偶尔会被认为是一种特征(被一些人)。

为了恰当地说明这种效果,我们可以生成一个一小节的例子,其中充满了中间 C 的半八度音(30 秒的音符),随机加重了一个高八度的 C。

Randomly accented demisemiquavers.

和弦进行

为了使生成的音乐的和声方面更加复杂,我们添加了另一个图表,该图表可以将 c 小调五声音阶切换到建立在该音阶的第四和第五阶上的音阶( FG )。它应该会给我们带来著名的 I-IV-V 感觉。下图描述了可能的转换。

Graph defining the space of possible keys.

结果

当目前为止描述的所有图表都用于生成一个单独的作品时,结果乐谱可能如下所示:

This image was generated automatically form a MIDI file, so it is not optimized for readability.

在这一点上,活页乐谱似乎不是概念化和评估制作的作品的好方法,所以这是开始产生实际声音的好时机。这是一个 15 分钟的 10000 个音符长序列的表演,由目前描述的方法生成:

Share, like, comment and subscribe. Buy merch.

我们分享一些代码,你可以用它们来重现这些结果。

随机森林简介

原文:https://towardsdatascience.com/random-forest-3a55c3aca46d?source=collection_archive---------2-----------------------

异常值检测和聚类的说明、解释、偏差和使用

最近更新时间:2018–12–09

随机森林广泛应用于数据科学竞赛和实际问题。它们通常是准确的,不需要特征缩放、分类特征编码,并且需要很少的参数调整。它们也比神经网络等其他复杂模型更容易解释。

内容组织如下。

  • 什么是随机森林
  • 解读随机森林
  • 偏向于具有更多类别的功能
  • 处理冗余功能
  • 离群点检测
  • 使聚集

什么是随机森林

随机森林由多个随机决策树组成。树中内置了两种随机性。首先,每棵树都建立在原始数据的随机样本上。第二,在每个树节点,随机选择一个特征子集来生成最佳分割。

我们使用下面的数据集来说明如何建立一个随机的森林树。注 Class = XOR (X1,X2)。X3 被制作成与 X2 相同(在后面的部分中为了说明的目的)。

An illustrative dataset with two classes colored in red and blue.

下图演示了如何构建随机森林树。

The process of building a random forest tree.

相同的过程适用于构建多个树。下图说明了将带有三棵树的随机森林应用到测试数据实例的流程。

The flow (highlighted in green) of predicting a testing instance with a random forest with 3 trees.

解读随机森林

特征重要性

要素的重要性分数衡量要素的贡献。它基于由于该特征而导致的杂质减少。

让我们向说明性数据集添加一个不相关的特征 X4。重要性分数绘制如下。显然,X1 和 X4 分别具有最大和最小的分数。X2 和 X3 是相同的,重要性分数不同。

部分依赖图

要素的重要性分数并不能说明要素和类是如何关联的。部分依赖图可以可视化特征对类概率的边际效应。

当一个特征与类相关时,图看起来如下图所示,表明 X1 ≤ 0.5 和 X1>0.5 与不同的类相关。

然而,在我们的说明性数据集中,部分依赖关系图看起来像右图-它没有指示 X1 和类之间的任何关系,即使 X1 具有最大的重要性分数。

原因是 X1 必须与 X2 或 X3 交互才能预测类别。单独的 X1 不具有预测性。因此,在这种情况下,部分相关图可能会产生误导。

Left: when X1 alone is correlated to the class, partial dependence is informative. Right: when X1 alone is not correlated to the class, partial dependence can be misleading.

兴趣

重要性分数和部分依赖图都不能说明多个特征如何与类交互。inTrees 框架可以用来更清楚地了解随机森林内部发生了什么。

对于说明性数据集,高度预测的交互及其相关类可以用 inTrees 提取,如下所示。频率(0%-100%)衡量交互在随机森林中的受欢迎程度,准确度(0-1)衡量交互预测类别的准确度。

偏向于具有更多类别的功能

对于说明性数据集,让我们添加一个具有 30 个类别的随机特征 X5。即使特征与类别无关,X5 的重要性分数也大于真正有信息的特征 X2 和 X3,这表明对具有更多类别的特征的不正确的偏好。

X1, X2, and X3 are truly informative, X4 and X5 are irrelevant, and X5 has many categories.

一种解决方案是执行特征选择。例如,在 randomForest R 包中,可以使用特性对精度的影响(importance $ meandercise accuracy)来评估特性。下面的精度影响图显示,与真正提供信息的特征相比,X5 的精度影响非常小,这表明该特征混淆了模型,应该在拟合分类器之前删除。

处理冗余功能

当特征彼此相似时,这些特征的重要性分数可能会产生误导。在说明性数据集中,X2 和 X3 是相同的,它们“共享”重要性分数(如下左图所示)。当冗余特征越多,每个特征的重要性就越小。

这可能不会损害精度性能,但可能会在解释中产生误导。一个解决方案是规则化随机森林(RRF)。在树构建过程中,RRF 记忆在先前的树节点中使用的特征,并且在分裂未来的树节点时更喜欢这些特征,因此避免了树中的冗余特征。下图显示了 RRF 的重要性分数。

Left: feature importance from a random forest; Right: feature importance from a regularized random forest.

随机森林中的离群点检测

用随机森林进行聚类可以避免对特征变换(例如,分类特征)的需要。此外,这里还可以使用一些其他随机森林函数,例如概率和解释。在这里,我们用左图中绘制的二维数据集来演示该方法。

这个想法是生成一个与原始数据形成对比的随机数据集。这里我们随机排列每个特征。这两个数据集分别标有两个类别(比如“正常”和“随机”)。合并后的数据集如下右图所示。

Left: original data; Right: generate a two-class data set. class 1: original data; class 2: the same size as the original data but with X1 and X2 randomly permuted.

在数据集上构建随机森林。然后,可以将分类器应用于测试数据实例。如果预测的类是“随机的”,那么它被识别为异常值。发现的异常值如下图所示。

通过查看重要性分数,我们可以了解哪些特征有助于离群点检测。为了便于说明,我们添加了一个与类别无关的随机特征 X3。重要性分数如下图所示。X1 和 X2 被确定为重要特征,而 X3 不太重要。

Left: outlier detection. Right: feature importance score in outlier detection.

随机森林聚类

与离群点检测类似,使用随机森林进行聚类可以节省特征预处理的工作量。

该过程类似于异常值检测。首先,创建一个与原始数据大小相同的合成数据集。然后用两个不同的类标记原始数据和合成类。然后为分类问题建立一个随机森林。

从构建的随机森林中,提取每对数据实例之间的相似性得分。两个数据实例的相似性通过两个数据实例出现在同一叶节点的树的百分比来衡量。

有了相似性得分,诸如分层聚类之类的聚类算法就可以用于聚类。下图显示了预定义聚类数分别为 2 和 4 时的聚类结果。

Left: clustering with 2 clusters. Right: clustering with 4 clusters.

摘要

随机森林不仅在分类/回归方面非常强大,而且在异常值检测、聚类和解释数据集(例如,作为具有兴趣的规则引擎)等方面也非常强大。

但是,使用随机森林时很容易出错。首先,当数据集中存在多级分类特征时,可能会有偏差。第二,当特征是冗余的时,重要性分数可能是误导的。本文提供了这些问题的解决方案。

你可能有兴趣阅读一篇关于为什么随机森林优于决策树的相关文章。

欢迎您在 github 上贡献intresRRF 包。

dataanalyticsbook.info 可以找到我的书的更多内容。

随机森林编码器

原文:https://towardsdatascience.com/random-forest-encoder-e7c8b5b9278e?source=collection_archive---------6-----------------------

随机森林是机器学习中最常用的技术之一。它们计算速度快,可以并行计算,可以处理数值和标称值,并且预测能力强。

随机森林中使用的技术是一种叫做装袋的综合方法。集成方法训练许多弱学习者,并将它们组合成一个强学习者;在 bagging 中,弱学习者是通过使用数据的增强捕获样本来训练一个“基础学习者”而产生的。然后将这些基础学习者的结果与(加权)平均值相结合以获得预测。

Example for a Random Forest. The color represents the pruity of the node. Each tree results in one score. The score of the forest is the average of the individual trees.

随机森林使用一个非常特殊的学习器作为基础学习器:随机树。随机树类似于决策树,但是每个节点只使用所有列的子集。

如何更好的组合树木?

这里出现的一个问题是——为什么我们只是平均所有的树?我们就不能做一些更“智能”的事情吗?答案当然是——是的,有一点。

一种方法是创建一个新表。新表有一个针对所有行的标签列(用作预测目标),还有一个新的置信度/概率列。这使我们能够“学习另一个学习者”,将置信度作为输入并预测我们的标签。你可以认为这是另一种系综方法——叠加。

这种想法的危险在于,你给你的模型增加了额外的复杂性,这可能会导致过度拟合。我强烈建议小心验证这些树。

随机森林作为编码方法

看待这种方法的另一种方式是将随机树的所有置信度放入一个新列,类似于 PCA 或 t-SNE 所做的。我们输入数据,得到与目标变量更相关的数据的新表示。这就是我所说的“编码器”。这个编码器的美妙之处在于,你可以输入名义数据,然后输出数值。这使我们能够将这种编码的结果输入到神经网络和支持向量机等学习器中。

在编码的情况下,我建议小心控制深度树,不要在一个属性中编码太多的路径。另一方面,深度控制着你的柱子之间的“互动水平”。

在 RapidMiner 中实现

Implementation using RapidMiner. The table delivered at the most upper output of Random Forest Encoder has includes all the scores of the individual trees.

我最近添加了一个新的操作符,让它在 RapidMiner 中更容易使用。RapidMiner 是一个开源的数据科学平台,它支持无代码的数据科学。操作符是用 Java 写的,可以从市场下载。操作员获取一个数据集和一个随机森林模型并进行转换。

当然,也可以通过在系综的子树上迭代,在 Python 或 R 中快速实现这一点。

随机森林学习-基本理解

原文:https://towardsdatascience.com/random-forest-learning-essential-understanding-1ca856a963cb?source=collection_archive---------2-----------------------

> >使用> > 决策树模型进行参数化

> >集成了> > 三种技法,

1。一种采样技术

2。子空间法,和

3。集合方法

优化模型构建

抽样方法 := 自举;采用随机抽样方法,用替换

子空间法 := 也采用了随机的采样方式,

但是有助于提取更小的特征子集(子空间)。

有助于基于它们构建决策树。

为随机森林构造选择决策树。

****集合方法:= 基于打包方法;帮助构建分类器

1.1 随机森林(RF)

树木可以是

1。分类树

2。回归树

因此 RF 可以应用于两者。

  • 决策树测试阶段提供单个训练好的决策树分类器。
  • 但是 RF测试阶段提供多个训练好的 DT 分类器。
  • 这一特性使得 RF 比常规 DT 学习更受青睐。

The construction of a Decision Tree using 1-D data domain & bootstrap sampling.

平行结构

  • 并行化是 RF 对 增强分类性能 的贡献属性之一。
  • DT 可以在的同时建立,用于 RF 建模的分类。
  • 这种射频并行结构有助于大数据分类。

The parallelization feature of the random forest technique

模型参数

  • RF 的参数化包括 DT 型号参数化,因为它内部采用了另一个。
  • 因此,RF 模型由 DT 的参数组成,但也有更多的参数。

例如,特征子集中的#个,选择用于构建 RF 的#个 DTs

增益/损失函数

  • 参数的优化基于

1。自举采样

2。子空间整合

在模型建筑中

  • 树构建使用与 DTs 中使用的相同的量化度量来选择最佳特征,例如。

1。熵

2。基尼杂质

3。信息增益

自举和装袋

  • 为了优化分类目标,

1。统计措施,

2。自举,

3。装袋

在射频学习中起着重要的作用。

1.1.4.1 自举

  • BS 是一种简单的随机化技术。
  • 它在射频方面的效果非常出色。
  • 它通过随机选择从一组数据中选择几个 子集,但与原始数据集中的观测值完全相同,只是用 替换****。
  • 所以有些观察值可以在数据集的一个子集里多次出现
  • 概念:-

在每个中间节点& DT 的叶子上最大化“类距离”。

  • BS 应用于射频算法的训练阶段

1.1.4.2 重叠细化

  • BS 给数据域带来了一些影响。
  • BS 生成多个域,其中可能比原始数据域更加孤立
  • 这些隔离数据域中的类可以通过单个拆分轻松分离。****
  • 有时候我们可能不需要分裂。

1.1.4.3 装袋

  • 指 BS 样本给出的预测(分类)响应平均,得到最终预测结果。
  • 套袋来自 自举聚集。
  • BS 用“ 简单类重叠细化 ”创建多个域,这些域帮助创建多个分类模型,多个分类模型允许测试算法高效地评估分类器的性能。****
  • 在 RF 算法的测试阶段应用 Bagging。

1.2 随机森林学习模型

  • 实现参数化目标&优化目标。****

1.2.1 参数化

  • 参数,

1。使用自举生成的域数量— A.

2。每个节点(域)的子空间大小— B.

3。域分割的阈值— C.

  • ****参数化的目标:-

我们需要找到或建议参数的可能值。

  • A 的通常值是 10

但是进行“交叉验证并确定一个合适的取值范围是合适的。****

  • 对于 B 选择,有 2 个约束。
  • 第一个建议是 n < < p &它必须在 DT 的整个构建过程中保持不变。
  • 第二 constriant,n<= sqrt(p);我们在原始数据域中有 p 个特性。其中有 n 个是好的。良率在 n/p. 其中特征之一最佳**之一,其良率为 1/n.**

****

  • 人们使用 sqrt(p) 作为特征的 #进行随机选择。

优化

一旦选择了参数,模型就被参数化了。那么必须优化参数。

  • 但是在 RF 参数化&优化中嵌套,&它们是同时执行的。****
  • 已经在树的每个节点进行了优化。****
  • RF 优化的主要参与者是基尼指数(熵)&信息增益

1.3 随机森林学习算法

  • 像其他机器学习算法一样,由 3 部分组成; 培训、验证和测试。
  • 交叉验证已经包含在培训协议中。
  • 所以射频技术不需要不需要单独的 验证算法。

简单地说:-

RF 学习为我们提供了几个空间(最佳特征组合),在这些空间中可以执行最佳的领域划分&可以获得高的分类精度。

  • 因此,射频分类目标只分为****训练&测试算法。****

1.3.1 训练算法

  • 这提供了一种系统化的方法来开发多分类器 (DTs),以便测试算法使用多分类器来选择对新数据进行分类的最佳方式。

第一步::—

为给定数据创建多个子空间。

r < = sqrt(p)

p = #特性;

r =子空间尺寸

第二步::—

—我们有明显更小的 r ( 维度子空间 ),因此我们可以使用 DT 构建过程为根节点找到最佳特征 & 最佳分裂位置(域划分)。

[但是我们不对这个子空间执行这个过程,所以跳到下一步]

第三步::—

随机改变子空间使用引导样本&创建多个引导子空间,其中重叠细化发生在数据域中。

第四步::——

—通过应用 DT 算法为每个引导子空间寻找最佳特征和最佳分裂位置来为 DTs 构建节点。

第五步::—

—现在,每个引导样本都有一个 DT(分类器)。

——这些树可以被测试算法用来分类新的数据。

射频相对于 DT 的优势,

1.在测试空间**=>将增加的分类精度。******

2.bootstrap 样本用于多个 DTs,这将有助于通过重叠细化增加分类边界锐化

3.为了在整个空间中找到最佳特征&最佳分割位置而进行的穷举搜索通过子空间搜索 = > 消除bootstrap 采样中很小的附加计算成本。** ( 计算优势)**

测试算法

  • 测试要求整个射频可以在早期使用几个自举样本(10)** 构建。然后贴标过程就可以开始了。**
  • ****步骤

1.功能选择:

来自输入数据正确的特征序列必须是“观察到的”。

2.树选择:

我们有 N 个射频分类器。所以我们推送新的数据根据的特性通过所有的&DTs 获取其类标签。

3.装袋:

上一步选择的树用于寻找获得的结果的集合(套袋技术****

F 最后,我们可以通过 表决机制 得出新的观察属于一个特定的标签。

****

随机森林可扩展性

  • 在典型的数据科学应用中,****

#的特性是固定的。

RF 技术从中选择一个子空间,并基于 bootstrapping 构建“深度优先决策树”来构造 RF。

  • 但是在大数据中,****

功能集可以动态“增长”。

  • 这个问题可以通过构建“宽度优先决策树”来解决。这里的 DTs 是在并行中构建的。

然而,在深度优先** & 传统 RF 中,DT 是在一个 DT 被完全构建之后构建的。**

参考:-

大数据分类的机器学习模型与算法,Shan Suthaharan 第十一章——随机森林学习

随机森林——谜底揭晓

原文:https://towardsdatascience.com/random-forest-mystery-revealed-69ca18b82ff5?source=collection_archive---------5-----------------------

image by Jens Lelie on unsplash.com

为您的应用选择“正确的”机器学习算法是在现实世界中正确应用机器学习的众多挑战之一。正确的算法有时可能是最简单、最健壮、最容易被最终用户理解的算法。Random Forest 会定期勾选所有这些框,但正如其他人所写的那样,它经常被忽略。希望这篇文章能让你对算法的工作原理有一个坚实的了解,这样你在进行自己的研究或在 R 或 Python 这样的工具中应用时会更有信心。

随机森林是一种监督学习算法,通常应用于分类和回归情况。简单介绍一下,该算法是一个集合模型,创建一个由许多决策“树”组成的“森林”,树的数量由用户定义。每个决策树都是基于原始数据集中的属性(列)和观察值(行)的子集创建的。这些树是使用训练数据集生长的,并应用于测试数据集。模型返回的最终分类是与最大数量的单个决策树提供的分类相匹配的分类。

由于随机森林只是由最大数量的树返回的分类,所以本博客将关注决策树本身,它是算法的核心。

什么是决策树?

决策树是一种流型结构,其中数据中的每个属性都表示为一个“内部节点”,每个“分支”表示一个测试的结果,“叶子”表示所做的分类。算法中的每个决策树都是使用来自原始训练数据集的不同的“随机”属性和观察值子集创建的。

[1]

下一部分可能会令人困惑(至少对我来说是这样!)所以希望我的解释是清楚的。决策树以析取范式创建,其中决策是“的一个“”。或者,这可以被表述为一个或多个文字的一个或多个合取的分支。[2]上面的决策树示例将第一个析取项显示为“工资高于”或“低于 6 万美元”。就树的结构而言,这也是内部节点。代表“否”的分支是此薪金测试的结果,其中“拒绝”是分类。第二条分界线是两年以上的工作经验。我们同样有一个拒绝分类,但在本例中,我们还有一个批准分类。要达到批准的分类,工作经验必须在 2 年以上,并且(联合)薪金> $60k 测试的结果必须为真/是。下面嵌入了一个简短的视频,其中讨论了析取陈述。维基百科也有一篇关于逻辑析取的文章,其中包括维恩图来突出‘或’属性。

属性排序和拆分

如上所述,决策树中的每个级别或分支代表用于单个决策树的随机数据段中的一个属性。考虑到最终模型的准确性以及与树相关的计算工作量,这些属性的排序非常重要。换句话说,属性应该以这样一种方式排序,以便为将来的观察分类提供最有效和最丰富的结构。在决策树中,属性的优先级是根据属性分解后的“信息增益”来确定的。

来自子内部节点的信息增益等于父节点的熵(无序度)减去子节点的加权平均熵。加权基于通过每个分支进行的分类的数量。当分类中存在完美分离时,熵为零,即所有“真”的结果导致“好”的分类,所有“假”的结果导致“坏”的分类。当“真”和“假”结果返回相同数量的“好”和“坏”分类时,熵为“1”(最大可能熵)。第二个例子没有提供信息增益,因为在两个可能的结果之间存在有效的分类随机分裂,并且树没有获得信息。因此,作为树的“根”,这是一个很差的属性。

熵是一个与系统的有序或无序有关的术语。高熵与高度无序相关,反之亦然。下面是来自 Udacity 的两个短视频,涵盖了熵和信息增益的概念。它们构成了一个免费系列的一部分,该系列介绍了机器学习的主题。

为了保持这篇文章的简短,我将在讨论包括决策树的“修剪”和与修剪概念密切相关的过度拟合的概念之前结束这篇文章。我将在以后的文章中讨论这两个问题,但是希望到目前为止的总结已经揭开了强大的随机森林算法的帷幕。

[1]* https://data aspirant . com/2017/01/30/how-decision-tree-algorithm-works/

[2]门德尔松,e .数理逻辑导论,第 4 版。伦敦:查普曼&霍尔出版社,第 27 页,1997 年。

python 中的随机森林和决策树

原文:https://towardsdatascience.com/random-forests-and-decision-trees-from-scratch-in-python-3e4fa5ae4249?source=collection_archive---------1-----------------------

介绍

随机森林是集成机器学习方法的主要例子。简而言之,集成方法是一种聚合预测性较低的基础模型以产生更好的预测模型的方法。正如人们可以直观猜测的那样,随机森林通过减少决策树臭名昭著的过度拟合倾向,集成各种决策树以产生更一般化的模型。决策树和随机森林都可以用于回归和分类问题。在这篇文章中,我们创建了一个随机森林回归器,尽管在下面的代码中只需稍加修改就可以创建一个分类器。

先决条件

我建议你具备以下方面的工作知识,以便更好地理解这篇文章:

  1. 决策树:我们也将为我们的随机森林从头开始创建这种树,但我不会解释它的理论和工作机制,为简洁起见, 推理因此,在一个帖子里把所有东西都搅在一起只会让它变得不合理。
  2. 集成学习(Ensemble learning):随机森林只是这个庞大的机器学习技术集的一个子集,如果你对这个有一个基本的了解,你会更好地理解这个帖子(不要为了这个帖子而谈论太多细节)
  3. 熊猫图书馆:一个好的木匠必须精通他的工具。这两个库是我们的工具。

理论

在开始编写我们的代码之前,我们需要了解一些基本理论:

  1. 特征装袋 : b 根带聚集再聚集或装袋是从替换的原始组中随机选择一定数量样本的方法。在特征打包中,原始特征集被随机采样并传递到不同的树上(没有替换,因为具有冗余特征没有意义)。这样做是为了降低树之间的相关性。具有无与伦比的重要性的特征将导致每个决策树选择它进行第一次和可能的后续分裂,这将使所有的树表现相似,并最终更加相关,这是不希望的。我们的目标是制作高度不相关的决策树。

为什么要让决策树高度不相关?

我们需要高度不相关的决策树,因为“一组完全随机误差的平均误差是零”,因此通过降低相关性并使每棵树尽可能随机地分裂(在特征选择的意义上是随机的,我们的目标仍然是在随机选择的一组列中找到最佳分裂),我们可以获得更好的无误差预测。

Correlated trees | Both have same feature set and make similar splits

People travel lands, i travel timeuncorrelated trees | Both have randomly selected different feature set and make different splits

2.聚合:使随机森林优于决策树的核心概念是聚合不相关的树。这个想法是创建几个蹩脚的模型树(低深度)并平均它们来创建一个更好的随机森林。一些随机误差的平均值为零因此,我们可以从我们的森林中获得广义预测结果。在回归的情况下,我们可以平均每个树的预测(平均值),而在分类问题的情况下,我们可以简单地取每个树投票的类别的大多数(模式)。

Python 代码

为了从头开始编码我们的随机森林,我们将遵循自顶向下的方法。我们将从一个单独的黑盒开始,进一步分解成几个黑盒,减少抽象层次,增加细节,直到我们最终达到不再抽象任何东西的程度。

随机森林类

我们正在创建一个随机的森林回归器,尽管同样的代码可以稍微修改一下来创建一个分类器。首先,我们需要知道我们的黑盒将什么作为输入来产生输出(预测),因此我们需要知道定义我们的随机森林的参数:

  1. x :训练集的自变量。为了保持事情最小和简单,我没有创建一个单独的 fit 方法,因此基类构造函数将接受训练集。
  2. y :监督学习所需的相应因变量(随机森林是一种监督学习技术)
  3. n_trees :我们集合起来创建随机森林的不相关的树的数量。
  4. n_features :采样并传递到每棵树上的特征数量,这是特征打包发生的地方。它可以是 sqrt、log2 或整数。在 sqrt 的情况下,采样到每棵树的要素数是总要素数的平方根,在 log2 的情况下是总要素数的对数底 2。
  5. sample_size :随机选择并传递给每棵树的行数。这通常等于总行数,但可以减少以提高性能,在某些情况下减少树的相关性(树的打包是一种完全独立的机器学习技术)
  6. 深度:每个决策树的深度。更高的深度意味着更多的分裂,这增加了每棵树的过度拟合趋势,但是因为我们聚集了几个不相关的树,所以单个树的过度拟合几乎不会干扰整个森林。
  7. min_leaf :一个节点中导致进一步拆分所需的最小行数。min_leaf 越低,树的深度越高。

让我们开始定义我们的随机森林类

  1. init :构造函数在我们参数的帮助下简单地定义随机森林,并创建所需数量的树。
  2. create_tree :通过调用类DecisionTree的构造函数创建一个新的决策树,这个类现在被认为是一个黑盒。我们稍后将编写它的代码。每棵树都接收一个随机的特征子集(特征打包)和一组随机的行(打包树,虽然这是可选的,但我写它是为了展示它的可能性)
  3. 预测:我们的随机森林的预测只是所有决策树预测的平均值。

如果我们能神奇地创造出树木,这就很容易想象出一个随机的森林。现在,我们降低抽象层次,编写代码来创建决策树。

如果你知道如何从头开始写一个决策树,你可以在这里停止阅读,但是如果你不知道,那么继续阅读。

决策树类

它将具有以下参数:-

  1. indxs :该参数的存在是为了跟踪原始集合的哪些索引去了右边,哪些去了左边的树。因此,每棵树都有这个参数“ indxs ”,它存储它所包含的行的索引。预测是通过对这些行进行平均来进行的。
  2. min_leaf :一个叶节点上能够引起拆分所需的最小行样本。每个叶节点将具有小于 min_leaf 的行样本,因为它们不能再分割(忽略深度约束)。
  3. 深度:每棵树内可能的最大深度或最大分裂数。

Why are decision trees only binary?

我们使用属性修饰器来使我们的代码更加简洁。

  1. init :决策树构造器。它有几个有趣的片段值得研究:

a.如果我们在这个特定树的计算中没有指定行的索引,只需取所有的行。

b.self.val = np.mean(y[idxs])每个决策树预测一个值,这个值是它保存的所有行的平均值。变量self.val保存对树的每个节点的预测。对于根节点,该值只是所有观察值的平均值,因为它包含所有的行,因为我们还没有进行分割。我在这里使用了“节点”这个术语,因为本质上决策树就是一个节点,它的右边有一个决策树,左边有一个决策树。

c.self.score = float(‘inf’)节点的得分是根据它划分原始数据集的“好”程度来计算的。我们稍后会定义这个“好”,现在让我们假设我们有一个方法来测量这样一个量。此外,我们的节点的分数被设置为无穷大,因为我们还没有进行任何分割,因此我们现有的分割是无限糟糕的,这表明任何分割都比没有分割好。

d.self.find_varsplit()我们第一次分开了!

  1. find_varsplit: 我们使用蛮力方法来寻找最佳拆分。该函数按顺序遍历所有列,并在所有列中找到最佳拆分。这个函数仍然是不完整的,因为它只进行了一次分裂,后来我们扩展了这个函数,为每次分裂生成左右决策树,直到到达叶节点。

  2. split_name :一个属性装饰器,返回我们要拆分的列的名称。var_idx是该列的索引,我们将在find_better_split函数中计算该索引以及我们拆分的列的值

  3. split_col: 一个属性装饰器,用于返回索引var_idx处的列,该列包含由indxs变量给出的索引处的元素。基本上,用选定的行分隔一列。

  4. find_better_split: 这个函数在某一列中寻找可能的最佳拆分,这很复杂,所以我们在上面的代码中把它看作一个黑盒。让我们稍后定义它。

  5. is_leaf :叶节点是从未进行过分裂的节点,因此其得分为无穷大(如上所述),因此该函数用于识别叶节点。同样,如果我们已经越过了最大深度,即self.depth < = 0,那么它就是一个叶节点,因为我们不能再深入了。

如何找到最佳分割?

决策树通过基于特定条件递归地将数据分成两半来训练。如果一个测试集有 10 列,每列有 10 个数据点(值),总共有 10×10 = 100 个拆分是可能的,我们手头的任务是找出这些拆分中哪一个最适合我们的数据。

我们根据将数据分成两半的效果来比较拆分。我们进行分割,使两半的每一半都具有最“相似”的数据类型。增加这种相似性的一种方法是减少两半的方差或标准差。因此,我们希望最小化两半标准偏差的加权平均值(分数)。我们使用贪婪方法,通过将列中的每个值的数据分成两半,并计算两半的标准偏差的加权平均值(得分),最终找到最小值,从而找到拆分。(贪婪的方法)

为了加快速度,我们可以复制该列,并对其进行排序,以通过使用由拆分nth索引创建的两个一半的值的总和和平方和在n+1th索引处拆分值来计算加权平均值。这是基于以下标准偏差公式:

下图形象地展示了分数计算的过程,每幅图的最后一列是一个数字,代表分裂分数,即左右标准差的加权平均值。

继续对每一列进行排序

Sort the column

现在我们按指数顺序进行分割

Start with index = 0

index = 1

index = 2 (best split)

index = 3

index = 4

index = 5

通过简单的贪婪方法,我们发现在 index = 2 上进行的分割是最好的可能分割,因为它具有最小的分数。我们稍后对所有列执行相同的步骤,并对它们进行比较,以贪婪地找到最佳(最小)分数。

以下是上述绘画作品的简单代码:

以下代码片段很有趣,需要一些解释:

  1. 函数std_agg使用值的总和以及平方和计算标准偏差
  2. curr_score = lhs_std*lhs_cnt + rhs_std*rhs_cnt每次迭代的拆分分数就是两半的标准偏差的加权平均值,每一半的行数作为它们的权重。较低的分数有利于较低的方差,较低的方差有利于相似数据的分组,这将导致更好的预测。
  3. if curr_score<self.score: self.var_idx,self.score,self.split = var_idx,curr_score,xi每当当前分数更好时(小于当前保存在self.score中的分数),我们将更新当前分数,并将该列存储在变量self.var_idx 中(记住这是帮助为我们的两个属性装饰者选择列的变量),并将进行拆分的值保存在变量self.split中。

既然我们知道了如何为所选的列找到最佳的拆分,我们需要为每个进一步的决策树递归地定义拆分。对于每棵树,我们找到最佳列和它的值来分裂,然后我们递归地生成两个决策树,直到我们到达叶节点。为此,我们扩展我们的不完整函数find_varsplit如下:

  1. for i in range(self.c): self.find_better_split(i)这个循环遍历每一列,并试图找到该列中的最佳拆分。到这个循环结束时,我们已经对所有列进行了所有可能的拆分,并找到了最佳可能的拆分。要拆分的列存储在self.var_idx变量中,我们拆分的列的值存储在self.split变量中。现在我们递归地形成两半,即右和左决策树,直到我们到达叶节点。
  2. 如果我们已经到达了叶节点,我们不再需要寻找更好的分裂,简单地结束这棵树。
  3. self.lhs持有左侧决策树。它接收的行保存在lhs中,这些行是所选列中小于或等于split.value中存储的拆分值的所有此类值的索引。变量lf_indxs保存左树接收到的特征(列)样本(特征打包)。
  4. self.rhs掌握正确的决策树。rhs存储传递到右侧决策树的行的索引。rhs的计算方式与lhs类似。同样,变量rf_indxs保存右侧树接收到的特征(列)样本(特征打包)。

结论

这是完整的代码

这篇文章的目的是让读者和我自己更熟悉随机森林的一般工作方式,以便将来更好地应用和调试。随机森林有更多的参数和相关的复杂性,我不可能在一篇文章中涵盖。为了研究一个更加健壮和有益的代码,我建议你阅读开源的 sklearn 模块的随机森林代码。

我要感谢杰瑞米·霍华德瑞秋·托马斯fast.ai 机器学习课程,让我能够写这篇文章。事实上,我在这里的所有代码都是在对最初的 fast.ai 课程材料做了小小的改动后创建的。

如果我的解释有错误/不清楚,请在回复中告诉我。感谢您的阅读。

随机森林和偏差-方差权衡

原文:https://towardsdatascience.com/random-forests-and-the-bias-variance-tradeoff-3b77fee339b4?source=collection_archive---------3-----------------------

Photo by Lukasz Szmigiel on Unsplash

随机森林是一种非常流行的机器学习算法。通常,在没有太多预处理的情况下,人们可以快速构建一个不需要超参数调整的脏模型,并获得不错的结果。例如,我最近在 Kaggle 上使用scikit-learn用 Python 编写了一个用于纽约市出租车费用预测游乐场竞赛的RandomForestRegressor,没有向模型构造器传递任何参数,使用 1/100 作为训练数据(554238 行,约 55M),验证 R 约为 0.8。你自己试试!

注意:这个代码片段假设您将数据分成训练集和验证集,并将您的特征和目标变量分开。你可以在我的 GitHub 个人资料上看到完整的代码。

这种算法如此聪明的部分原因是它如何处理被称为的偏差-方差权衡。我在以下 5 个步骤中探索了随机森林的这一方面:

  1. 偏差和方差
  2. 决策树
  3. 装袋、引导和随机森林
  4. 超参数调谐
  5. 随机森林和偏差-方差权衡

偏差和方差

统计模型的均方误差(MSE)可以表示为其预测的平方偏差、这些预测的方差和某个误差项𝜖的方差的总和。由于偏差和方差的平方都是非负的,并且捕捉数据随机性的𝜖超出了我们的控制,我们通过最小化模型的方差和偏差来最小化 MSE。我发现图 1 中的图像特别能说明这两个术语的意思。

Fig. 1: A visual representation of the terms bias and variance.

如果我们的模型系统地低估或高估了目标变量,我们就说它有偏差。在机器学习中,这通常是我们选择的模型做出的统计假设或训练数据中的偏差的结果。看看这篇文章的一个偏见的例子,谷歌的云自然语言 API 通过互联网上的文本了解到“同性恋”这个词带有固有的负面内涵。

另一方面,方差在某种意义上抓住了模型的普遍性。更准确地说,这是一个衡量我们的预测会发生多大变化的指标,如果我们对不同的数据进行训练的话。高方差通常意味着我们过度适应我们的训练数据,发现模式和复杂性是随机性的产物,而不是一些真实的趋势。通常,由于过度拟合,更复杂或更灵活的模型往往具有较高的方差,但偏差较低,因为对几次预测进行平均,我们的模型会更准确地预测目标变量。另一方面,拟合不足或过于简化的模型虽然方差较低,但可能会更有偏差,因为它缺乏充分捕捉数据趋势的工具。

理想情况下,我们想要的是低偏差-低方差。为了了解如何做到这一点,我们先来看看典型的偏差平方方差曲线。

Fig. 2: A curve of squared bias vs variance showing the inverse correlation that is typical of the relation between the two as the model gets more complex. It is not uncommon for the resulting Total Error to follow some variant of the U-shape shown in the figure.

图 2 展示了随着我们的模型变得越来越复杂,我上面描述的偏倚减少和方差增加的总体趋势。我们的目标是选择一个最小化两个之和的模型,如虚线所示。为了了解随机森林是如何做到这一点的,让我们从一个简单的决策树开始。

决策树

Fig. 3: Representation of a single decision tree with no bootstrapping and max_depth of 3 that I created for the New York City Taxi Fare Prediction competition on Kaggle.

让我们回到出租车费用预测任务。给定特定出租车乘坐的某些特征,决策树通过简单地预测训练数据集中的平均出租车费用($11.33)开始,如图 3中最左边的框所示。然后,它遍历所有特性及其值的列表,找到一个给我们最大 MSE 改进的二进制分割。这通常是通过预测两个新子集的平均值并计算它们各自的 MSE 来计算的,MSE 由每个子集中的观察值的数量来加权。

在这种情况下,最佳分割恰好是行驶距离是否小于或等于 0.083(纬度/经度单位= 5.727 英里)。当它小于 5.727 英里时,该树预测为 9.28 美元,这是距离小于此值的乘坐的平均费用,通过相同的程序,对于比我们的阈值更长的乘坐,预测为 35.09 美元。这是有道理的。长途旅行更贵。

如图所示,然后根据 MSE 最大改进的相同标准,将每个分支分成新的分支,递归继续,直到每个(样本组)中只有一个训练观察。决策树具有极低的偏差,因为它们最大限度地过度适应训练数据。它在验证集上做出的每个“预测”本质上都是我们的训练数据中某次出租车乘坐的费用,该数据与我们预测其费用的乘坐在同一个最终叶节点中结束。然而,这种过度拟合也会导致不可接受的高方差,从而导致对未知数据的不良预测。

打包、引导和随机森林

虽然单个树过度适应训练数据并且可能具有较大的误差,但是bagging(BootstrapAggregating使用适当的大量不相关误差平均为零的洞察力来解决这个问题。Bagging 从训练数据中选择多个随机观察样本,通过替换,从每个样本中构建一个树。因为每棵树都从不同的数据中学习,所以它们彼此之间是不相关的。随着我们增加“袋装”树的数量,绘制我们模型的其余部分(scikit-learn称这些树为estimators)说明了这种技术的威力。

(array([ 9\. ,  8.1,  8.1, 11.5,  6.1,  6.9,  6.5,  8.1, 10.5,  6.5]), 8.13)

Fig. 5: A plot showing incresing R² as n_estimators is increased from 1 to 9.

把我们森林中的每棵树都想象成从它所建模的数据子集中学习一些关于纽约市出租车费用的独特见解。将他们的每个预测平均在一起,然后给我们一个更强大、更稳定的模型,能够以更高的精度预测出租车的费用。

超参数调谐

然而,随机森林不仅仅是装袋的树,它使用了许多有趣的技术来进一步降低树之间的相关性和减少过度拟合。快速浏览一下 scikit-learn 实现RandomForestRegressor的文档,可以看到我们可以传入的超参数:

*class* sklearn.ensemble.**RandomForestRegressor**(*n_estimators=10*, *criterion=’mse’*, *max_depth=None*, *min_samples_split=2*, *min_samples_leaf=1*, *min_weight_fraction_leaf=0.0*, *max_features=’auto’*, *max_leaf_nodes=None*, *min_impurity_decrease=0.0*, *min_impurity_split=None*, *bootstrap=True*, *oob_score=False*, *n_jobs=1*, *random_state=None*, *verbose=0*, *warm_start=False*

它们有十几种,但在这里我会仔细看看n_estimatorsmax_depthmin_samples_leafmax_features的作用,以及为什么它们中的每一种都有可能降低模型的误差。

n _ 估计量

n_estimators简单来说就是树的数量。森林中不相关的树木越多,它们的个体误差就越接近平均值。然而,越多并不总是越好,这里有一些注意事项要记住:

  1. 更多的树=更多的计算。超过某一点,权衡可能就不值得了。
  2. 与此相关,增加n_estimators会导致收益减少,如图 5 所示。例如,从 370 棵树增加到 400 棵树,甚至不能保证减少验证 MSE。
  3. 没有任何不相关的树能够消除由模型假设或不具代表性的训练数据产生的偏差所导致的错误。

最大深度

max_depth是您希望每棵树分裂的深度。例如,max_depth = 50将限制树在任何给定的分支上最多分裂 50 次。其结果是,我们的随机森林不再能如此接近地拟合训练数据,因此更加稳定。它具有较低的方差,使我们的模型误差更小。请记住,即使严格限制max_depth可能会增加每棵树的偏差,因为它们可能无法在达到极限之前捕获数据中的某些模式,我们也不必担心这一点。选择合适的n_estimators,再加上装袋,可以确保整个森林的偏差在这个过程中不会增加。

max_depth是一个超参数,我通常不去碰它,因为我真正关心的是在禁止树进一步分裂之前,在一个分支的末端有多少观察值。这是对随机森林过度适应程度的更好预测。

最小样本叶

允许我们做我上面描述的事情。例如,min_samples_leaf = 10告诉每棵树停止分裂,如果这样做会导致任何结果分支的结束节点少于 10 个叶子。为了更好地理解为什么这是有用的,想一想决策树是如何做出预测的,我在出租车费用预测问题的背景下再次概述了这一点。一旦完成训练,它通过在树中传递出租车的特征并在树空间中找到距离该出租车最近的末端节点来预测出租车的费用。

如果这是叶节点,这将是如果min_samples_leaf = 1(缺省值)的情况,则森林正在预测该游乐设施碰巧最接近的训练集中的特定游乐设施的实际费用。几乎可以肯定的是,分支末端的分裂并没有捕捉到纽约市出租车费用的实际模式,而只是训练数据中与更高或更低费用相对应的情况。传入一些更大的min_samples_leaf意味着我们现在预测一些样本组的平均值,这些样本组在树空间中与所讨论的游乐设备最接近。这种技术的推广性明显更好。

我通常会尝试min_samples_leaf = [1, 3, 5, 10, 20, 50],一旦增加min_samples_leaf并不能提高我感兴趣的指标,我就会停止。

最大 _ 功能

max_features告诉每棵树在寻找最佳分割时要检查多少个特征。这里的一个微妙之处是,传入max_features = 15并不意味着每棵树选择 15 个特征的子集来建模。更确切地说,一棵树为每次分裂选择了 15 个不同的随机样本。像min_samples_leaf一样,这不允许树过于接近数据。更重要的是,随机森林中的树现在彼此之间的相关性甚至更低,因为它们甚至没有在相同的数据上进行训练。有一些实用的机器学习研究表明,不太准确、不太相关的树的森林比更准确、更相关的树的森林表现更好。

实际例子

机器学习中超参数调整的一种常见方法是使用在scikit-learn中实现的一种叫做RandomizedSearchCV的技术。这将模型本身和我们感兴趣的参数空间作为必需的参数。

*class* sklearn.model_selection.**RandomizedSearchCV**(*estimator*, *param_distributions*, *n_iter=10*, *scoring=None*, *fit_params=None*, *n_jobs=1*, *iid=True*, *refit=True*, *cv=None*, *verbose=0*, *pre_dispatch=‘2*n_jobs’*, *random_state=None*, *error_score=’raise’*, *return_train_score=’warn’*)

它随机尝试这些参数的n_iter组合,并返回这些样本的最佳超参数和相应的分数。然而,为了说明改变单个参数的效果,我在这里展示了我的RandomForestRegressor对于一些手动选择的组合的表现。首先,让我们看看一个没有其他参数传入的随机森林有多好:

[4.262844864358172, 4.098490006842908, 0.8090730776697076, 0.8239641822866088]

n_jobs = -1只是告诉scikit-learn使用计算机上所有可用的内核。此外,print_score()是 fast.ai 库中的一个函数,它返回训练误差、验证误差、训练 R 和验证 R。我们的基线是大约 0.824 的验证 R。玩max_features的作用如下:

[4.289944262409593, 3.9900355584905385, 0.8066378726809564, 0.8331574522424692]
[4.322218978148121, 4.136388496420818, 0.8037174696184352, 0.820693545036434]

虽然使用max_features = 'log2'乘以特征的数量在一定程度上提高了性能,但是max_features = 'sqrt'却做了相反的事情。最有效的方法可能因情况而异,这使得某种形式的试错法成为最简单和最受欢迎的选择。您可以自己随意使用一些其他的超参数。为了简洁起见,我不会在这里这样做。最后,在选择了我的超参数之后,我使用大量的估计器训练了一个RandomForestRegressor,以进一步提高 R:

[4.013807675575337, 3.8493455368979235, 0.830729516598271, 0.8447158691316341]

结论

总之,随机森林采用了许多技术来减少预测中的方差,同时保持(在某种程度上)单独决策树的低方差特征。这主要是通过将一些非常弱相关(如果不是完全不相关)的树平均在一起来实现的。像max_featuresmin_samples_leaf这样的超参数是减少树之间这种相关性的有用技术之一,但它们通常以增加偏差为代价,因为每棵树现在处理的数据更少了。

因此,我们的目标是选择一组超参数,在偏差和方差之间进行权衡,以便在一些新的数据集(验证集)上最小化误差(或最大化拟合优度),我们认为这些数据集代表了模型在解决其设计的真实世界问题(测试集)时可能遇到的情况。

神经网络的随机初始化:过去的事情

原文:https://towardsdatascience.com/random-initialization-for-neural-networks-a-thing-of-the-past-bfcdd806bf9e?source=collection_archive---------1-----------------------

Photo by NASA on Unsplash

最近,神经网络已经成为我们几乎所有机器学习相关问题的解决方案。这仅仅是因为神经网络有能力合成复杂的非线性,这种非线性几乎总是能神奇地给出以前不可能的精度。

在业内,神经网络被视为黑匣子。这是因为当我们从一个密集层移动到下一个密集层时,它们使用给定数据的特征来公式化越来越复杂的特征。研究人员试图研究这些复杂的特征生成过程,但迄今为止还没有太大的进展。神经网络仍然是黑匣子。

这一点正是让学、的原因。

courtesy: Machine Learning Memes for Convolutional Teens,facebook

一些研究人员也反对在自动驾驶汽车和无人机等非常重要的领域使用神经网络。他们说,与支持向量机或随机森林的决策框架相比,深度神经网络做出的决策是不合理的。如果明天出现任何问题,比如说,如果一辆自动驾驶汽车在去杂货店的路上跳下悬崖,如果是支持向量机在控制汽车的行为,那么问题背后的原因可以很容易地纠正和纠正,另一方面,由于神经网络的框架非常复杂,没有人能够预测汽车为什么跳下悬崖,为什么它会做出这个决定。

但总的来说,今天没有其他方法可以像神经网络一样准确地学习数据。神经网络是图像识别成为今天这个样子的原因。如今,复杂的卷积网络正在被制造出来,它们在识别物体方面变得越来越精确,甚至可以在这项任务中与人类竞争。

在神经网络中,每两层之间存在权重。这些权重和先前层中的值的线性变换通过非线性激活函数来产生下一层的值。这个过程在前向传播期间逐层发生,通过反向传播,可以找出这些权重的最佳值,以便在给定输入的情况下产生精确的输出。

到目前为止,机器学习工程师一直使用随机初始化的权重作为这个过程的起点。直到现在(即:2015 年),还不知道这些权重的初始值在寻找深度神经网络成本函数的全局最小值中起到如此重要的作用

我目前正在吴恩达的 coursera 上做深度学习专业化,专业化的第二个课程涉及这些深度神经网络的超参数调整。

在我们开始前向、后向传播以找到最佳权重之前,让我们看看初始化层之间的权重的三种方式。

1:零初始化

2:随机初始化

3: he-et-al 初始化

零初始化

零初始化没有任何意义。神经网络不执行对称破坏。如果我们将所有的权重都设置为零,那么所有层的所有神经元都执行相同的计算,给出相同的输出,从而使整个深度网络变得无用。如果权重为零,整个深度网络的复杂性将与单个神经元的复杂性相同,并且预测将不会比随机更好。

w=np.zeros((层大小[l],层大小[l-1])

courtesy: Machine Learning Memes for Convolutional Teens,facebook

随机初始化

这有助于对称性破缺的过程,并给出更好的精度。在这种方法中,权重被初始化为非常接近零,但是随机的。这有助于打破对称性,每个神经元不再执行相同的计算。

w = NP . random . randn(layer _ size[l],layer_size[l-1])*0.01

courtesy: Machine Learning Memes for Convolutional Teens,facebook

He-et-al 初始化

这种初始化的方法通过何等人 2015 年提交的一篇论文而出名,类似于 Xavier 初始化,因子乘以 2。在这种方法中,记住前一层的大小来初始化权重,这有助于更快更有效地获得成本函数的全局最小值。权重仍然是随机的,但是范围根据前一层神经元的大小而不同。这提供了受控的初始化,因此更快和更有效的梯度下降。

w=np.random.randn(层大小[l],层大小[l-1])* NP . sqrt(2/层大小[l-1])

[## 芝加哥大学深度网络深度学习的初始化

提供芝加哥式的深度学习。来自芝加哥大学的深度学习博客。

deepdish.io](http://deepdish.io/2015/02/24/network-initialization/)

阅读这篇文章以获得更多关于这个主题的信息。

通过在相同的数据上尝试所有三种初始化技术,我观察到以下情况:

零初始化:

15000 次迭代后的成本:0.7

精确度:0.5

随机初始化:

15000 次迭代后的成本:0.38

精确度:0.83

何等人初始化:

15000 次迭代后的成本:0.07

精确度:0.96

这本身显示了权重的初始化如何影响神经网络的性能。

看看 facebook 上的这个 rad 页面。

[## 卷积青少年的机器学习迷因

卷积青少年的机器学习迷因。20K 赞。在它变深之前,我就已经在做了

www.facebook.com](https://www.facebook.com/convolutionalmemes/)

一如既往,快乐学习。

用符号表示的随机回归和分类问题生成

原文:https://towardsdatascience.com/random-regression-and-classification-problem-generation-with-symbolic-expression-a4e190e37b8d?source=collection_archive---------2-----------------------

我们描述了如何使用 SymPy,我们可以为多项式(和非线性)回归和分类问题建立随机样本生成器。这补充了 Scikit-learn 的随机数据生成方法。

介绍

对于数据科学和机器学习的初学者来说,一个常见的问题是获得良好、干净的数据集以便快速练习。回归和分类是数据科学从业者必须处理的两个最常见的监督机器学习任务。并不总是有可能得到结构良好的数据集来练习人们学习的各种算法。

如果能有一个方便的函数来快速生成大小、复杂性和随机性可控的回归和分类问题的合成示例,那就太好了。

现在, Scikit-Learn,Python 中领先的机器学习库,确实为回归和分类问题提供了随机数据集生成能力。然而,用户无法轻松控制数据生成的底层机制,回归输出也不是输入的决定性函数——它们确实是随机的。虽然这对于许多问题来说可能已经足够了,但是人们可能经常需要一种可控的方式来基于明确定义的函数(涉及线性、非线性、理性甚至超越项)产生这些问题。

在本文中,我们将使用 SymPy(Python 生态系统中的一个伟大的符号计算包)来完成示例代码。你可以 在这里 从我的 GitHub 库下载 Jupyter 笔记本,并根据你的需要进一步修改功能。

Scikit-Learn 的数据集生成功能和局限性

Scikit-learn 为生成随机回归和分类问题提供了两个实用函数。它们列在[sklearn.dataset](http://scikit-learn.org/stable/modules/classes.html#module-sklearn.datasets) API 下。它们如下:

**sklearn.dataset.make_regression**:生成随机回归问题。通过将具有确定数量的非零回归量的 随机线性回归模型 应用于先前生成的输入和具有一些可调标度的一些高斯中心噪声,来生成输出。

**sklearn.dataset.make_classification**:生成一个随机的 n 类分类问题。这首先创建正态分布在 n 维超立方体的顶点周围的点的聚类,并为每个类分配相等数量的聚类。它引入了这些特征之间的相互依赖,并给数据增加了各种类型的噪声。

这些是非常好的随机问题生成工具,但是它们不允许用户基于一些底层的确定性函数来创建数据。然而,人们可能希望为可控分析/机器学习实验生成数据集。例如,我们想要评估各种内核化 SVM 分类器在具有越来越复杂分隔符(线性到非线性)的数据集上的功效,或者想要证明线性模型对于由有理函数或超越函数生成的回归数据集的局限性。使用 scikit-learn 的这些功能很难做到这一点。此外,用户可能只想输入一个符号表达式作为生成函数(或分类任务的逻辑分隔符)。仅仅使用 scikit-learn 的实用程序很难做到这一点,必须为每个新的实验实例编写自己的函数。

SymPy 来救援!

为了解决符号表达式输入的问题,人们可以很容易地利用令人惊叹的 Python 包 SymPy,它允许理解、呈现和评估符号数学表达式,达到相当高的复杂程度。更多细节可以在他们的网站上找到。这里有几个基本的例子,

使用用户提供的符号表达式的随机回归和分类数据集生成

代码的细节可以在我的 GitHub repo 中找到,但是思路很简单。我们有一个symbolize函数,它将 Python 输入字符串转换成 SymPy 符号对象,还有一个eval_multinomial()函数,它将 SymPy 符号表达式和一个(vals)参数作为列表、字典或元组,并在内部创建一个(symbol,value)对来计算数学表达式。主要的效用函数如下:

**gen_classification_symbolic()**函数基于符号表达式生成分类样本。它计算随机生成(高斯分布)点的符号表达式的输出,并基于符号分配二进制分类。
m :符号表达式。需要 x 1、 x 2 等作为变量和要使用的常规 python 算术符号。
n _ samples:要生成的样本数
n _ features:自变量数。这是从符号表达式中自动推断出来的。因此,在提供符号表达式的情况下,该输入将被忽略。然而,如果没有提供符号表达式,则可以调用默认的简单多项式来生成具有 n_features 的分类样本。
flip_y :随机翻转分类标签的概率。较高的值会引入更多的噪声,并使分类问题更加困难。
返回:返回一个带维度的numpy ndarray(n _ samplesn_features +1)。最后一列是响应向量。

**gen_regression_symbolic()**函数基于符号表达式生成分类样本。它计算随机生成(高斯分布)点的符号表达式的输出。
:象征性表达。需要 x 1、 x 2 等作为变量和要使用的常规 python 算术符号。
n _ samples:要生成的样本数
n _ features:变量数。这是从符号表达式中自动推断出来的。因此,在提供符号表达式的情况下,这将被忽略。然而,如果没有提供符号表达式,则可以调用默认的简单多项式来生成具有 n 个特征的分类样本。
噪声 :要引入的噪声(默认为高斯)的大小(加到输出上)。
noise _ dist:噪声信号的概率分布类型。目前支持:
正常,均匀,贝塔,伽马,泊松,拉普拉斯
返回:返回一个带维度的numpy ndarray(
n _ samplesn_features +1)。最后一列是响应向量。

例子

下面是一些代码片段和可视化的结果数据集。

分类样本

回归样本

**

不限于单个符号变量

尽管使用一个或两个示例示出了上述示例,但是函数不受变量数量的限制。事实上,内部方法被编码成自动地从你的符号表达式输入中推断出独立变量的数量,并相应地设置问题。这里有一个例子,用户甚至没有给出 n_features ,但是函数从符号表达式中推断出特征的数量为 3。

总结和未来扩展

基本代码设置为尽可能模拟 scikit-learn 的数据集生成实用程序功能。人们可以通过提供 Pandas 数据帧输出或 CSV 文件输出来轻松扩展它,以便在任何其他编程环境中使用,并将数据保存到本地磁盘。在一定的复杂程度上,也可以为用户提供符号表达式的 LaTeX 公式的字符串表示。当然,我们鼓励读者在 GitHub repo 中发送他们的评论或指明。

如果您有任何问题或想法要分享,请联系作者在tirthajyoti【AT】Gmail . com。此外,您可以查看作者的 GitHub 资源库 中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。如果你像我一样,对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我在 Twitter 上关注我

关键词 : #machinelearning,#symbolicmath,#supportvectormachine,#随机化,#回归,#分类

用 Python 模拟随机漫步

原文:https://towardsdatascience.com/random-walks-with-python-8420981bc4bc?source=collection_archive---------4-----------------------

Numpy 模拟和绘制随机行走

什么是随机漫步?

简单地说,随机行走是以一种“随机”方式对当前状态采取连续步骤的过程。然后,可以将附加条件应用于这个基本描述,以便为您的特定用例创建随机漫步。粒子的布朗运动、股票行情自动收录器的运动活细胞在基质中的运动只是现实世界中一些更为人所知的随机行走。

这里,我们模拟了从原点开始的一维、二维和三维中的简化随机行走,离散步长以相等的概率选自[-1,0,1]。起点用+表示,终点用o表示。

对于不同的应用,这些条件根据需要而改变,例如,在选定的股票价格、使用显微镜等检测的初始细胞位置开始行走,并且步骤选择通常是随机的,并且取决于来自过去数据、预测假设、被测试的假设等的附加信息。

Random Walks on networks can be used for clustering nodes too (https://en.wikipedia.org/wiki/Internet)

设置你的 Jupyter 笔记本:

%pylab inlinefrom itertools import cycle
from mpl_toolkits.mplot3d import Axes3Dcolors = cycle(‘bgrcmykbgrcmykbgrcmykbgrcmyk’)

一维随机行走:

我们从原点 ( y=0 ) 开始,选择一个步长,以相等的概率移动每一个连续的步长。起点显示为红色,终点显示为黑色。累积和绘制在下图中,该图显示了在 1D 超过 10k 步的物体所遵循的路径。

# Define parameters for the walkdims = 1
step_n = 10000
step_set = [-1, 0, 1]
origin = np.zeros((1,dims))# Simulate steps in 1Dstep_shape = (step_n,dims)
steps = np.random.choice(a=step_set, size=step_shape)
path = np.concatenate([origin, steps]).cumsum(0)
start = path[:1]
stop = path[-1:]# Plot the pathfig = plt.figure(figsize=(8,4),dpi=200)
ax = fig.add_subplot(111)ax.scatter(np.arange(step_n+1), path, c=’blue’,alpha=0.25,s=0.05);
ax.plot(path,c=’blue’,alpha=0.5,lw=0.5,ls=’ — ‘,);
ax.plot(0, start, c=’red’, marker=’+’)
ax.plot(step_n, stop, c=’black’, marker=’o’)plt.title(‘1D Random Walk’)
plt.tight_layout(pad=0)
plt.savefig(‘plots/random_walk_1d.png’,dpi=250);

二维随机行走:

我们从原点 (x=0,y=0) 开始,在每个方向上采取随机步骤,在每个步骤中给我们 9 个可能的移动方向(∏x,∏y)⋲{-1,0,1} :

(-1,-1),(-1,0),(-1,1),
(0,-1),(0,0),(0,1),
(1,-1),(1,0),(1,1)

10k 步以上的模拟给出了以下路径。在流体表面移动的粒子表现出 2D 随机行走,并显示如下的轨迹。

# Define parameters for the walkdims = 2
step_n = 10000
step_set = [-1, 0, 1]
origin = np.zeros((1,dims))# Simulate steps in 2Dstep_shape = (step_n,dims)
steps = np.random.choice(a=step_set, size=step_shape)
path = np.concatenate([origin, steps]).cumsum(0)
start = path[:1]
stop = path[-1:]# Plot the pathfig = plt.figure(figsize=(8,8),dpi=200)
ax = fig.add_subplot(111)ax.scatter(path[:,0], path[:,1],c=’blue’,alpha=0.25,s=0.05);
ax.plot(path[:,0], path[:,1],c=’blue’,alpha=0.5,lw=0.25,ls=’ — ‘);
ax.plot(start[:,0], start[:,1],c=’red’, marker=’+’)
ax.plot(stop[:,0], stop[:,1],c=’black’, marker=’o’)plt.title(‘2D Random Walk’)
plt.tight_layout(pad=0)
plt.savefig(‘plots/random_walk_2d.png’,dpi=250);

模拟 2D k 次随机漫步:

三维随机行走:

在体积中运动的物体是 3D 空间中随机行走的一个例子。我们从原点 (x=0,y=0,z=0) 开始,从 27 个方向(∏x,∏y,∆z)⋲ {-1,0,1} 中随机选择步伐:

# Define parameters for the walkdims = 3
step_n = 1000
step_set = [-1, 0, 1]
origin = np.zeros((1,dims))# Simulate steps in 3Dstep_shape = (step_n,dims)
steps = np.random.choice(a=step_set, size=step_shape)
path = np.concatenate([origin, steps]).cumsum(0)
start = path[:1]
stop = path[-1:]# Plot the pathfig = plt.figure(figsize=(10,10),dpi=200)
ax = fig.add_subplot(111, projection=’3d’)
ax.grid(False)
ax.xaxis.pane.fill = ax.yaxis.pane.fill = ax.zaxis.pane.fill = False
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_zlabel(‘Z’)ax.scatter3D(path[:,0], path[:,1], path[:,2], 
             c=’blue’, alpha=0.25,s=1)
ax.plot3D(path[:,0], path[:,1], path[:,2], 
          c=’blue’, alpha=0.5, lw=0.5)
ax.plot3D(start[:,0], start[:,1], start[:,2], 
          c=’red’, marker=’+’)
ax.plot3D(stop[:,0], stop[:,1], stop[:,2], 
          c=’black’, marker=’o’)
plt.title(‘3D Random Walk’)
plt.savefig(‘plots/random_walk_3d.png’,dpi=250);

3D 模拟 k 次随机行走:

现在我们在 3D 中模拟多个随机行走。每一次随机行走代表一个点源的运动,该点源与从 (x,y,z) ⋲ [-10,10] 中选择的点同时开始。

一些细胞/粒子在没有任何持续方向力的情况下移动,会显示出这样的轨迹。三维随机漫步的一个有趣的方面是,即使起点很近,随着时间的推移,物体会散开。

Simulating multiple random walks in the same 3D space

# Define parameters for the walkdims = 3
n_runs = 10
step_n = 1000
step_set = [-1, 0 ,1]
runs = np.arange(n_runs)
step_shape = (step_n,dims)# Plotfig = plt.figure(figsize=(10,10),dpi=250)
ax = fig.add_subplot(111, projection=’3d’)
ax.grid(False)
ax.xaxis.pane.fill = ax.yaxis.pane.fill = ax.zaxis.pane.fill = False
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_zlabel(‘Z’)

for i, col in zip(runs, colors): # Simulate steps in 3D origin = np.random.randint(low=-10,high=10,size=(1,dims))
    steps = np.random.choice(a=step_set, size=step_shape)
    path = np.concatenate([origin, steps]).cumsum(0)
    start = path[:1]
    stop = path[-1:] # Plot the path ax.scatter3D(path[:,0], path[:,1], path[:,2],
                 c=col,alpha=0.15,s=1);
    ax.plot3D(path[:,0], path[:,1], path[:,2], 
              c=col, alpha=0.25,lw=0.25)
    ax.plot3D(start[:,0], start[:,1], start[:,2],
              c=col, marker=’+’)
    ax.plot3D(stop[:,0], stop[:,1], stop[:,2],
              c=col, marker=’o’);

plt.title(‘3D Random Walk - Multiple runs’)
plt.savefig(‘plots/random_walk_3d_multiple_runs.png’,dpi=250);

在这篇文章中,我们讨论了如何在 1D、2D 和 3D 中模拟一次基本的随机漫步。我们可以使用不同的方法对群体表现出的随机游走进行描述性分析(距离、位移、速度、速率、角度分布、指示器计数、限制比等)。我们还可以模拟和讨论有向/有偏随机行走,其中下一步的方向取决于当前位置,这是由于某种形式的现有梯度或定向力。

Python 中的新闻倾向性排名

原文:https://towardsdatascience.com/ranking-news-bias-in-python-e9bb5d1ba93f?source=collection_archive---------8-----------------------

我最近在《华盛顿邮报》上读到一篇文章,标题是“根据受众对媒体进行从自由到保守的排序”。启发我根据新闻网站在特定主题上的主观性和极性对其进行排名,在这个例子中,是唐纳德·特朗普。

Photo by rawpixel on Unsplash

我用 Python 调出了以下新闻网站中包含关键词“特朗普”的 30 篇最新文章(从《华盛顿邮报》文章的自由派到保守派):

  1. 纽约市人
  2. 噪声功率比(noise power ratio)
  3. 美国有线新闻网;卷积神经网络
  4. 福克斯新闻频道
  5. 德鲁吉报告
  6. 布莱巴特

然后对文章的描述进行文本分析,以返回一个列表,其中列出了文章的主观程度(或固执己见)以及极性(作者对特朗普的感觉是积极还是消极)。通过这样做,我可以得出一个新闻网站的(非常基本的)排名,显示他们对我们的总统有多么偏见,以及他们对他的看法如何。有了这个,我就可以和《华盛顿邮报》的文章进行比较,看新闻来源与哪个政治派别联系最紧密,哪个最有偏见。

进口

为了搜索 google,我使用了这个库TextBlob 进行文本分析,使用 TextTable 在终端中显示结果。

from google import google
from textblob import TextBlob
import texttable as tt
from time import sleep

搜索

为了获得和分析来自不同网站的文章,我使用了 Google Dork searches ,它允许你搜索特定网站的关键词(以及其他许多东西)。例如,您可以键入

inurl:medium.com intext:python

以便只从提到 python 的中型网站返回搜索结果。

我创建了一个名为search的函数,它接受您正在搜索的站点的参数和要搜索的关键字。然后将变量search_results设置为使用站点和关键字参数的 Google Dork 搜索,我们就可以收集文章了。

然后,我创建了一个search_results_listsubjectivity_list和一个polarity_list,以便稍后追加结果。创建num列表只是让文章按照它们在文本表格中出现的顺序编号。

def search(site, search):
 site = site
 search = search
 num_page = 3
 search_results = google.search(“inurl:” + site + “ intext:” + search, 3)
 search_results_list = []
 subjectivity_list = []
 polarity_list = []
 num = []
 number = 1

情感分析

下一步是确定给定文章的主观性和极性。这可以通过在搜索结果上调用result.description方法来完成,然后将其附加到search_results_list.

通过设置 TextBlob,将search_results作为变量analysis,可以对文章进行基本的情感分析。运行analysis.sentiment.subjectivity获得结果的主观性,运行analysis.sentiment.polarity返回极性。将这些结果附加到各自的列表中。

for result in search_results:
 search_results = result.description
 search_results_list.append(search_results) analysis = TextBlob(search_results)
 subjectivity = analysis.sentiment.subjectivity
 subjectivity_list.append(subjectivity)
 polarity = analysis.sentiment.polarity
 polarity_list.append(polarity)
 number = number + 1
 num.append(number)
 sleep(5)

文本表格

为了创建表格,创建一个新变量tab,并将其设置为等于tt.Texttable()。然后写出你的标题,我用了数字、结果、主观性和极性。

tab = tt.Texttable()
headings = [‘Number’,’Results’,’Subjectivity’, ‘Polarity’]
tab.header(headings)

然后运行一个for循环,将列表中的每个元素作为一行添加到表中。

for row in zip(num, search_results_list, subjectivity_list, polarity_list):
 tab.add_row(row)

采用主观性和极性列表,我们可以找到每个新闻源的平均值,然后我们可以将它与给定的网站、搜索结果和表格一起打印出来。

avg_subjectivity = (sum(subjectivity_list) / len(subjectivity_list))
avg_polarity = (sum(polarity_list) / len(polarity_list))table = tab.draw()
print site
print search
print table
print (site + “ average subjectivity: “ + str(avg_subjectivity))
print (site + “ average polarity: “ + str(avg_polarity))

调用函数

最后,您必须为每个新闻站点调用search函数。

search(“newyorker”, “trump”)
search(“npr”, “trump”)
search(“cnn”, “trump”)
search(“foxnews”, “trump”)
search(“drudgereport”, “trump”)
search(“breitbart”, “trump”)

就是这样!

结果

运行该脚本,终端输出将如下所示:

显示站点、文章数量、文章描述、每篇文章的主观性和极性,然后显示站点的平均值。

网站各自主观评价的平均值如下(从最客观到最主观的顺序):

  1. NPR (0.21)
  2. 福克斯新闻频道(0.23)
  3. CNN (0.25)
  4. 《纽约客》( 0.27)
  5. 布莱巴特(0.34)
  6. 德拉吉报告(0.36)

毫不奇怪,NPR 是最客观的新闻来源,而《德拉吉报道》和布莱巴特在特朗普问题上最固执己见。然而,福克斯新闻频道在客观性上排名第二的事实让我很惊讶。

极性的排名同样令人惊讶,数值越接近-1 越负,越接近 1 越正。

  1. 福克斯新闻频道(0.04)
  2. NPR (0.05)
  3. CNN (0.07)
  4. 《纽约客》( 0.07)
  5. 德拉吉报告(0.11)
  6. 布莱巴特(0.12)

福克斯新闻频道再一次让我吃惊,在 30 篇文章中,他对川普的负面看法最多。在那之后,新闻来源如预期的那样一致。非常有趣的是,最高的正平均值仅仅在零以上!我预计德拉吉报告和布莱巴特至少在 0.6 的范围内。

布莱巴特在一篇文章上记录了 0.8 的最积极情绪,然而,它也有 0.4 的最消极情绪。这让我相信布莱巴特的文章比它的同行使用了更多的内涵语言。布莱巴特在主观性方面排名第二的事实支持了这一点。

最后的想法

显然,这是一个非常基本的排名,不应该被视为真理,因为一个非常小和有限的(仅使用描述,而不是全文)数据集。

我看到了邮报的文章,并认为这将是一个有趣的实验,运行并查看结果。希望你喜欢!

这里是 Github 上的完整源代码

查看我的其他 Python 文章:

[## 使用 Tweepy 在 Python 中创建一个 Twitter 机器人

Twitter 大约有 15%是由机器人组成的,我想尝试一下。我谷歌了如何创建一个推特机器人…

medium.freecodecamp.org](https://medium.freecodecamp.org/creating-a-twitter-bot-in-python-with-tweepy-ac524157a607) [## 基于 Python 的 Twitter 基础数据分析

在使用 Tweepy 和 Python 以及这段代码创建了免费的 Wtr bot 之后,我想用一种方式来看看 Twitter 用户是如何…

medium.freecodecamp.org](https://medium.freecodecamp.org/basic-data-analysis-on-twitter-with-python-251c2a85062e)

使用 GraphQL 的快速应用原型——一种思考数据和 API 设计的不同方式

原文:https://towardsdatascience.com/rapid-application-prototyping-using-graphql-a-different-way-of-thinking-about-your-data-and-api-f93faadad421?source=collection_archive---------6-----------------------

标签 : GraphQL,Graphene,Python,Docker。

Python-石墨烯框架中的多态性

这篇文章的主要目的是说明如何使用 Python-Graphene 框架(https://github.com/graphql-python/graphene)来构建 GraphQL 端点。具体来说,它说明了在表示数据时使用石墨烯中的联合接口构造来模拟多态性

这个项目的源代码可以在 GitHub 上找到(下面的链接)。按照 README 中的说明在 docker 容器中运行该示例。

[## husseinmoghnieh/graph QL-多态性

GitHub 是人们构建软件的地方。超过 2800 万人使用 GitHub 来发现、分享和贡献超过…

github.com](https://github.com/husseinmoghnieh/graphql-polymorphism)

介绍

GraphQL 是一种查询语言,它使数据的消费者(即前端/ UI)能够通过单个 API 端点查询数据。这是一种不同于使用 RESTful 端点的方法,在 RESTful 端点中,每个端点都是针对特定于服务的功能定制的,并且具有固定的响应结构。

在 RESTful API 设计中,产品需求被转化为一组 API,这些 API 主要在数据存储上执行 CRUD(创建、读取、更新和删除)操作。这个过程非常耗时,尤其是当目标是提供一个原型时。GraphQL 可以加速应用程序原型化的过程,因为它提供了一个 API 端点,充当 UI 和数据存储之间的数据代理。

我将带您去看这篇博客文章,这篇文章很容易说明 RESTful 和 graphQL 端点之间的区别。

[## GraphQL 与 REST

通过 HTTP 发送数据的两种方式:有什么区别?

blog.apollographql.com](https://blog.apollographql.com/graphql-vs-rest-5d425123e34b)

总体而言,GraphQL 在以下情况下具有优势:

  • 数据自然地以图表的形式出现
  • 快速原型制作。一个服务于所有查询场景的 API
  • 代表问题域的所有实体之间的多种关系

电影行业——图表示例

选择以电影行业为例来展示 GraphQL 的强大之处,是因为在这个行业中,任何类型的制作都涉及许多实体的参与,每个实体在作品制作中都有不同的角色,包括演员、作家、制片人等..制作公司和流媒体服务。因此,这个问题可以用图形来表示。

这篇文章的其余部分解释了完全工作的 GraphQL 示例的组件。

下一个:

  • 数据表示法
  • 模式设计
  • 密码
  • 查询示例

数据表示法

让我们假设电影业中每个实体的信息都以 JSON 格式存储,如下所示,为了简单起见,数据保存在磁盘上。该解决方案可以很容易地扩展到从任何数据源获取数据(关系数据库、NoSQL、S3,甚至更好图形数据库)。

华纳兄弟公司:

{
  "id": "company/production/warnerbro",
  "companyName": "Warner Bros.",
  "established" : 1923,
  "type": "company",
  "links": [
    {
      "relationship": "distributed",
      "target": "media/movie/ocean11"
    },
    {
      "relationship": "produced",
      "target": "media/movie/troy"
    }
  ]
}

上面显示了与(简体)相关的数据及其与两部电影(特洛伊海洋 11* )的关系。华纳兄弟生产了第一种,发行了第二种。图形表示:*

另一方面海洋 11(电影),可以这样表示(简化):

*{
  "id": "media/movie/ocean11",
  "title": "Ocean 11",
  "premier": "December 12, 2014",
  "sequel" : "1/3",
  "links": [
    {
      "relationship": "distributed by",
      "target": "entity/company/WarnerBro"
    },
    {
      "relationship": "produced by",
      "target": "entity/person/JerryWeintraub"
    },
    {
      "relationship": "produced by",
      "target": "entity/company/VillageRoadshow"
    },
    {
      "relationship": "starred",
      "target": "entity/person/BradPitt"
    }
  ]
}*

华纳兄弟海洋 11 的集合图形表示为:

模式设计

用面向对象的术语来说,我们可以将上述实体分为两大类。一个我们称之为媒体,代表电影、表演等..另一个我们称之为参与者,代表一个人或一家公司。一个人可以是制片人、发行人、演员、作家等,一个公司可以是制作公司、发行人、流媒体公司等

将上述实体扩展为子类会产生下面的类图。同样,这个博客的范围是处理几种类型的媒体参与者

简单的例子

在深入研究技术细节之前,让我展示一个示例 GraphQL 查询及其相应的输出:

样本查询:

内容如下:

  • 找到媒体海洋 11**
  • 如果媒体是一部电影,则显示其标题并查找其参与者中有关系的"制作的
  • 对于参与者满足产生的条件,如果参与者是则显示名称,如果参与者公司则显示*公司名称*******

输出结构映射输入结构,如下所示。

输出:

这实质上是显示下面突出显示的图形节点的内容

密码

1 —链接接口

我将从表示实体间链接的代码(即链接接口)开始。该接口由所有类实现。

2-参与者接口和参与者实体

以下代码包含由所有参与者类实现的参与者接口。**

注意,每个类都实现了参与者接口链接接口。最后,一个名为 ParticipantResult 的附加类充当占位符,聚合通过解析不同类型的参与者(即 PersonDetails 和 CompanyDetails)而产生的对象。**

在面向对象中,结果类类似于声明一个保存父类类型对象的数组。例如,在 Java 中,这大致翻译为:

***List<**Participant**> participantResult = new ArrayList<**Participant**>();
participantResult.add(**companyDetails**)
participantResult.add(**personDetails**)***

3 —媒体接口和媒体实体

下面是媒体接口和相关实体的代码。

4-查询模式定义

在定义了表示存储数据的所有类之后,定义了一组查询(媒体查询和参与者查询)。然后,使用定义的查询初始化模式,如下所示**

4- API GraphQL 端点

下面所有的代码都是配置一个 FLASK,启动一个 FALSK 应用。公开上面的模式的代码在第 29 行:**

***app.add_url_rule('/graphql', view_func=GraphQLView.as_view
('graphql', schema=schema, graphiql=True))***

使用 Docker 运行

要运行这个示例,只需下载项目并运行:

***docker-compose builddocker-compose up***

将您的浏览器指向http://localhost/graphqlGraphene 提供了一个交互式界面,允许您编写和执行 graph QL 查询。它还提供了一个模式浏览器(最右边)。**

GraphQL 查询示例

显示华纳兄弟制作的所有电影。

显示布拉德·皮特主演的所有电影

重新编码你自己的神经瘤

原文:https://towardsdatascience.com/re-coding-your-own-neurome-303c9b52f68f?source=collection_archive---------8-----------------------

你是你的神经瘤的创造。

我知道这是一个有争议的评论。这是我的哲学,如果你不同意,我不会生气。我认为这是一种思考我们思想的有用方式,所以如果你好奇,请继续读下去。

你的神经瘤是一个超复杂的生化系统;它是由数万亿个脉冲和通信分子产生的,这些分子在多个相互连接的反馈回路中工作。它的许多系统致力于创建一个或多或少可用的世界模型,以及你与它的互动。(你的神经瘤是什么?看我的文章这里。你的神经瘤是活的,并且是它的感知机器,你的身体的一部分。

思考就是行动,就像走路或呼吸一样

思想是一种物质的东西;它产生于你意识中较小的部分,是你物质精神状态的结果。

如果你接受了你头脑的物质本质,那么各种各样的可能性就为如何从物质上改变你的头脑而敞开了大门;字面意思是用简单且容易获得的物理工具记录你自己的可能性。

你的神经瘤是个模棱两可的多系统智能。用简化的方法来检查它总是有帮助的,但它通常是作为一个整体来工作的,而且你也可以通过用这种精神来接近你的神经瘤来了解你自己。

它暴露于这个世界,而这个世界包括你自己的身体。

它使用你的身体与世界一起工作,当它这样做时,它的状态会暂时或永久地改变,这就是你所体验的思想的改变。身体活动也会影响你的神经瘤的长期几何形状,表现为身体上的联系和路径,我们将其描述为新的能力,或更稳定或僵化的思想,如习惯和信念。

你自己的身体,是你的思想向世界散发的一部分,是一个奇怪的有用工具,用来检查似乎来自你的神经瘤的一个或多个自我。

时代精神是正念。

东方文化中的佛教徒和武术运动,以及其他人,几千年来已经理解了身体工作的价值。他们的方法在现代西方广为人知,并在上个世纪逐渐流行起来。

现在,随着科学的探索,尤其是正念(冥想)已经走向主流。它在创造更好的应对策略方面的有用性正在被很好地记录和广泛使用。

然而,冥想虽然美妙,却只是用身体影响我们思想的一种方式。有用的是,它给了我们一个线索,告诉我们这是如何工作的。

正念的第一个转变是让意识平静下来,这有助于提升觉知。你可以用很多方法做到这一点,但最常用的一种方法是注意你的呼吸。

另一种说法是,冥想通常是通过将我们的意识带到我们的物质本性上来开始的,这有助于我们忽略思考时的正常干扰。

这是为了让意识和潜意识重新同步。你这样做是通过将你的意识意识与一个过程联系起来,这个过程通常是体内平衡的,但也可能是有意识的(体内平衡可能不是呼吸的完美术语,它指的是身体在没有意识干预的情况下自然做的事情,以维持我们的生命,如循环、温度、消化等)。我们通常不会想到呼吸或心跳,它们作为我们神经系统的一部分受到潜意识的调节。但是我们可以思考它们,我们可以用我们的思想影响它们。

专注于像呼吸这样的物理过程,你通常不会意识到,会重新连接你的交感神经系统和副交感神经系统(两个物理系统),并使它们更加一致,这可能会感觉像稳定、坚实或平静。

像呼吸这样的东西是一个明显的桥梁。它们是你重新发现你与你的物质自我的联系的途径。大多数情况下,这非常令人平静,有助于你以全新的视角体验思维的改变。

请注意,对想法有强烈的情绪想法(担心,感到不知所措,感觉无法停止关注特定的负面情况或想法)将对你的神经系统产生强烈的物理影响,反馈到思想螺旋中。

因为思想是你的物理环境的一部分,我们的神经瘤会通过它的物理报警系统对令人担忧的思想做出反应。这些可以在夜里唤醒我们,或者在白天制造恐慌;这是由身体向血液中泵入酶和激素引起的,以使身体对感知的危险采取行动,也许是由真正的危险引发的,但最常见的是由你自己的(非理性)想法引发的。

心理健康只是健康

顺便说一句,现在是我们改变关于精神健康的可怕的社会歧视的时候了。我明白,我们都害怕向他人透露自己的内心世界,部分原因是我们自己的敏感,也因为害怕他人的反应。但心理健康只是健康;比如心脏健康,或者内脏健康。所有这些都有心理学的成分,现在真的是时候改变我们个人和社会对心灵的态度了;它体内的神经瘤。

我们的神经瘤对我们的健康至关重要,需要我们以积极开放的态度对待它。

我觉得现在这样就够了。我计划在以后的文章中用一系列实用的物理工具来补充这一点,你可以用它们来重新编码你自己的神经瘤。

我希望你觉得它有趣并且容易理解,如果你觉得有问题和意见可以发表,我会很高兴。

React + D3:数据可视化世界的通心粉和奶酪

原文:https://towardsdatascience.com/react-d3-the-macaroni-and-cheese-of-the-data-visualization-world-12bafde1f922?source=collection_archive---------3-----------------------

React and D3, just melting all over one another in gooey, data-driven deliciousness (aka a slice of mac ‘n cheese)

React 处于 SPA UI 开发的最前沿——目前没有其他技术像 react 这样强大和广泛使用。当我们谈论 web 上的数据可视化时,我们很可能是在谈论 D3(说真的,如果你所看到的 D3 只是一些快速的直方图,我不得不推荐这个奇妙的 D3 v4 课程,它将带你深入了解这个库实际上能够做什么的本质。剧透:这太疯狂了。PS:我和那门课没有任何隶属关系,我只是拿了,挖了)。

但是,一个悲剧即将发生:显然,在你的代码库中,一次只能有一个这么棒的库,对吗?

看,React 如此快速和轻便的部分原因是它在高效更新 DOM 方面非常聪明,所以当您使用 React 时,您通常不会直接接触 DOM——您只是放松下来,让所有甜蜜的、声明性的 MVC jazz 为您处理一切。

而 D3 则是给你一条直接进行 DOM 操作的干净的路径。

因此,实现的重叠可能会给我们带来潜在的问题——如果您没有正确地计划它,React 和 D3 可能会……妨碍彼此,并且表现得非常不可预测。人们已经编写了一些包来为您处理这个问题,但是缺点是您会被锁定在 React 和 D3 之上的第三个系统中。这通常意味着你只能使用数量相对有限的预制模板,或者无法使用大量的 D3 特性。限制自己似乎真的很遗憾,尤其是当让他们守规矩和轮流真的很简单的时候。

为了说明我们想如何解决这个问题,以我的猫为例。

Ellis and Sol about to fight over a windowsill spot on the left, and the two of them comfortably snoozing and sharing on the right.

本质上,我们想把 React 和 D3 当作我的猫来对待。我们就假设穿着整洁晚礼服的埃利斯是 React,右边穿着优雅晨装的索尔是 D3,窗户前面的阳光点是 DOM。

如果只有一个位置,我们只是让它们自己解决,就像左边的照片一样,那么…那些抬起的爪子在照片里可能看起来超级可爱,但让我告诉你,在这张照片拍摄后大约三秒钟,就有一些严重的争吵。只有一个位置,他们都决心要独占它。

然而,右边阳光充足的窗户大小完全一样,得到的阳光也一样多,但是,因为我们给了他们每人一个单独的枕头,他们可以称之为自己的枕头,他们可以完全做主,他们都在非常平静地做他们的事情。

给他们一点喘息的空间,给他们一种完全掌控的错觉,我就能让他们两个都表现得最好。

a screenshot of what we’re building — live at https://d3-react-tutorial.herokuapp.com

所以,尽管我很讨厌这样做,让我们把我的猫的寓言抛在脑后,谈谈我们要做什么。为了确保我们让每个库真正做它应该做的事情,我们有一个用户界面,让你选择颜色和大小,并根据这些选择生成可爱的小飞行 SVG 圆。这是一个非常小的玩具,但这正是我们完成工作所需的代码量。你可以在这里查看代码或者在这里摆弄玩具本身

a relatively simple Controller Component, which renders a form and keeps track of form submission results in its state.

就像猫一样,我想给 React 和 D3 他们自己的独立空间,在那里他们可以负责并做他们所做的事情,这与“React-y”的思维方式非常好——我们想给每个库分配一个适当的角色,并将该角色的工作(以及库)隔离到单独的组件中。这样,当我们想知道谁可以操作 DOM 时,答案变得非常简单:我们在哪个组件中?

React 在交互性、状态管理和结构化用户界面方面非常出色,所以这就是我要让它做的事情——在上面显示的这个组件中,控制器。它只是一个漂亮、简单的表单,每个更改和提交都存储在组件的状态中——我们知道用户现在在做什么,以及他们已经做了什么。这就是我们在这里所做的——没有 SVG,我们甚至没有将 d3 导入到这个文件中。

所有这些都在第 39 行进行管理,其中“Viz”是一个子组件,它唯一的工作是获取控制器生成的数据,并使用 D3 来绘制图片。

虽然从技术上讲我们可以颠倒这些角色(例如,人们确实构建了只使用 D3 的整个 UI),但关键是要充分利用每个库,对我来说这是最合理的分解。

a teeny, tiny, tidy, twelve-line Viz component, which renders a single, empty div

D3 组件,即,将会非常小,即使我们使用它来制作的可视化将会占据绝大部分的视口——我们不希望 React 介入或访问它,所以我们真正需要的只是一个参考点——第十三行的空 Div。该 div 基本上是一个小花园围栏,标记 React 停止的位置,D3 开始。

a helper function which searches out an empty div with a ‘.viz’ class on it, and uses it as a reference to hang the SVG element and all its children on.

而这就是 D3 拿起来的样子!这里我们有一个有用的“绘制”功能。将它定义为 Viz 类的一个方法很有诱惑力,但是没有必要这样做,最终,我建议不要这样做。

一旦我们进入了 D3,我们就想尽可能地“用 D3 的方式”做所有的事情,对吗?这不仅是因为这是确保 D3 能够在最高水平上工作的好方法,也是因为这是确保下一个接触您的代码库的人知道正在发生什么以及如何有效地构建它的好方法。

因为 D3 将直接接触 DOM,在 React 的模型-视图-控制 jam 之外,它不需要知道关于它最终将被调用的组件的任何事情——它与应用程序的整体 React 结构无关,并且可以在某处的一些 helpers.js 文件中非常舒适地存在。就像我们在 React 空间中不引用 D3 一样,我们在这里也不会引用 React。

所有这一切的关键在于,D3 接触到的所有东西都在这里产生,并且只在这里生存。我们使用这个空的 to div 来挂我们的 SVG,并在这个空间内创建图片的每个部分——所有的子元素和它们的属性,以及它们可能有的任何交互。甚至这些元素的样式也存在于此——这降低了 CSS 冲突和不可预测的结果的可能性,也意味着当您需要改变可视化的外观和感觉时,您可以一站式购买,这在您开始使用 D3 的一些更大规模的构建功能时尤其方便。(顺便问一下,您是否知道可以生成色标,该色标将映射到您用作范围的任何数值上?相当狂野。)

在我们继续之前,关于可访问性有一个简短的说明:有几件事你可以相对容易地做,以便在广大用户遇到你的应用程序时给他们最完整的体验。

首先:您知道 SVG 有一个<title>元素吗,它可以被设置为类似于改变图像文本的功能。要使它工作,它必须是 SVG 的直接第一个子对象。想出为你的数据自动生成适当的和信息丰富的标题/alt 的方法可能是具有挑战性的,但绝对值得努力来制作一个包容性的应用程序。对于你所创造的形象,需要理解的最重要的事情是什么?你希望你的用户带走什么?

第二:你打算让你的可视化互动吗?通过点击或悬停,是否有更多信息或操作变得可用?并不是所有的用户都能够访问它们,使用屏幕阅读器或有运动障碍的人可能不会使用鼠标。任何对你的 UX 来说重要的功能都应该可以通过键盘导航来实现。还好,那不是太难!SVG 形状有效地采用了 tabindex 属性,这将允许您的用户在可视化的每个部分之间切换。一旦到了那里,如果您将您的element.on('hover',...)行为复制到element.on('focusin',...),将您的element.on('click',...)复制到element.on('keydown',...),在那里您检查以确保击键来自确认键,会怎么样?有多少人能享受到你辛勤工作的成果?

a teeny, tiny, tidy, twelve-line Viz component, which renders a single, empty div

所以,回到我们的 Viz 组件。一旦我们设置好了 draw 函数,我们需要做就是使用它。如果你还记得我们的控制器组件是如何工作的,它只会在实际有形状要画的时候进行渲染,所以一旦我们安装了我们的组件,很明显在那一点上我们想要调用 draw 并把我们得到的数据传递给它。但是如果我们的用户添加更多的形状呢?嗯,componentDidUpdate钩子将被触发,因为关于这些形状的信息将改变 Viz 从控制器获得的道具,我们可以告诉 draw 再次做它的事情,但这次是用最新的数据。我们也不必担心 React 的干扰,因为实际上 React 甚至不知道我们的 SVG 在那里——它只是接收新的道具并做它被告知的事情。

如果你是在去年这样做的(或者你确实读过我的第一篇关于让 React 和 D3 在一起时表现自己的文章),你可能会记得这个过程稍微复杂一点——你必须使用shouldComponentUpdate手动关闭 React 重新渲染,并且在它们变成this.props之前,使用componentWillReceivePropsnextProps处理你的重绘。幸运的是,这两种生命周期方法都被弃用了,它们的功能包含在更少的函数调用中,这很好。

这不禁让人想知道,有没有更好、更酷、更紧凑、更先进的方法来做这件事?

我很高兴你这么问。看看这个,伙计们:

A six — count ’em SIX — line Viz Component, just as functional, but short and sweet

React 钩子仍然在 alpha 中,所以它们可能不太适合您的产品级代码,但是看看这个组件看起来有多光滑!钩子让我们保持组件的功能,即使我们需要生命周期方法或内部状态。这使得调试和阅读我们的代码更加容易。

这个组件中发生的事情与它上面的基于类的组件完全相同。useEffect实质上取代了我们之前的componentDidMountcomponentDidUpdate功能。useEffect需要两个参数来完成工作——一个函数,它将在组件进行渲染的任何时候运行(在本例中,是我们熟悉的老 draw 函数),以及一个比较器,它使用该比较器来判断是否发生了足够多的变化来运行该函数。在这种情况下,我们告诉 useEffect 只在 shapes 数组的长度改变时运行它的函数,因为这就是我们如何知道我们有一个新的形状要绘制。很简单,对吧?React 向我们承诺,在可预见的未来,类不会消失,我也不特别希望它们消失,但是有另一种选择是很酷的。

我希望这篇简短的文章已经说明了在 React 应用程序中使用 D3 是多么容易和不令人生畏(顺便说一下,这是一个很好的路线图,可以将 React 与任何使用 DOM 的第三方库一起使用)——它是否启发了你用它来制作很酷的东西?给我看看!跟我说说!或者,告诉我你认为我哪里错了,这也很有趣。

a gratuitous cat picture of Ellis, holding a catnip banana

阅读 NIPS/NeurIPS 2018 的摘要!以下是我学到的东西

原文:https://towardsdatascience.com/reading-abstracts-from-nips-neurips-2018-here-is-what-i-learned-16352d83416f?source=collection_archive---------8-----------------------

Photo by chuttersnap on Unsplash

我决定读完 NIPS/NeurIPS 2018 的所有摘要。但事实证明,在我想要的时间框架内,这在身体上和精神上都是难以置信的。本次会议共收到 1011 篇论文,其中包括 30 篇口头论文、168 篇聚焦论文和 813 篇海报论文,论文接受率为 20.8%。(来源)

我想在会议开始前的 24 小时内读完所有的摘要。我花了 1440 分钟阅读了 1011 篇摘要,平均时间为 1.42 分钟。我完全是愚蠢的,我想把摘要总结成一个迷你摘要,这样当我以后回到它或者分享它时,就可以很容易地理解一个简明的摘要。

我开始阅读摘要,从会议的第一个海报会议“Tue 海报会议 A”(它有 168 篇论文)中选取了 20 篇(前 20 篇)。我花了 210 分钟多一点的时间来阅读和总结(提取方式,提取一些摘要),平均每篇论文 10.5 分钟。我加快了速度,不太担心总结,我在大约 150 分钟内完成了接下来的 20 个,平均 7.5 分钟。接下来的 20 分钟大约 90 分钟。接下来的 20 分钟大约需要 70-80 分钟。接下来的 20 分钟将在 60-70 分钟内完成。140 篇论文后,我放弃了时间限制,休息了一会儿。

尽管如此,当我结束一个 20 人的小组,去另一个小组时,奇妙的事情发生了。阅读一份扎实的研究调查的浓缩摘要真的令人生畏和不知所措,即使是一份,我也要读 20 份这样的论文并继续读下去。阅读前 20 篇论文,任何我不知道的理论或我不熟悉的主题都会阻止我理解他们正在解决的问题或他们解决方案的价值。

但是,最终我不那么害怕他们使用的理论或他们解决问题的独特新颖性,并把它们视为解决特定限制或扩展现有工作多功能性的灵感或见解。当我阅读摘要时,我感到很容易注意到他们正在解决的问题以及他们的解决方案对该领域的新颖性、有效性和影响。

总的来说,我真的很高兴我让自己阅读了非正常数量的摘要,尽管从很多方面来看这似乎是致命的!!我仍然想阅读会议的所有摘要,但这可能需要一周的时间。我会通知你的。

这些是我必须阅读的论文(除了整个“周二海报会议 A”还有 18 篇论文)和他们的摘要。标签在表现这些论文时并不那么有效,它们仅仅是人类潜在的感知开销,有时被视为感觉。

使用椭圆分布的 Wasserstein 空间概括点嵌入

基本原则

一种新的嵌入框架,它是数值灵活的,并且扩展了 wessserstein 空间中的点嵌入、椭圆嵌入。Wasserstein 椭圆嵌入更直观,并且产生比具有 Kullback-Leibler 散度的高斯嵌入的替代选择在数值上表现更好的工具。本文通过将椭圆嵌入用于可视化、计算词的嵌入以及反映蕴涵或上下级关系来展示椭圆嵌入的优点。

甘人生而平等吗?大规模研究

系统评估,真正了解

尽管大量的研究活动产生了许多有趣的 GAN 算法,但仍然很难评估哪些算法的性能优于其他算法。我们对最先进的模型和评估方法进行了中立的、多方面的大规模实证研究。我们发现,通过足够的超参数优化和随机重启,大多数模型都可以达到类似的分数。这表明,除了基本的算法变化之外,更高的计算预算和调整也能带来改进。为了克服当前度量的一些限制,我们还提出了几个数据集,在这些数据集上可以计算精度和召回率。我们的实验结果表明,未来的氮化镓研究应基于更系统和客观的评估程序。最后,我们没有发现任何测试算法始终优于在{ cite good fellow 2014 generate }中介绍的不饱和 GAN 的证据。

渔网:图像、区域和像素级预测的多功能支柱

基本面,在核心

设计卷积神经网络(CNN)结构以预测不同级别(例如图像级别、区域级别和像素级别)上的对象的基本原理是不同的。通常,专门为图像分类设计的网络结构被直接用作包括检测和分割在内的其他任务的默认主干结构,但是很少有主干结构是在考虑统一为像素级或区域级预测任务设计的网络的优点的情况下设计的,这些预测任务可能需要具有高分辨率的非常深的特征。朝着这个目标,我们设计了一个类似鱼的网络,称为鱼网。在 FishNet 中,所有分辨率的信息都被保留下来,并为最终任务进行优化。此外,我们观察到现有的工作仍然不能直接将梯度信息从深层传播到浅层。我们的设计可以更好的处理这个问题。已经进行了大量的实验来证明鱼网的卓越性能。特别是在 ImageNet-1k 上,FishNet 的精度能够以较少的参数超越 DenseNet 和 ResNet 的性能。渔网被用作 COCO Detection 2018 挑战赛获奖作品的模块之一。该代码可在https://github.com/kevin-ssy/FishNet获得。

辉光:具有可逆的 1x1 卷积的生成流

实用神奇,美观大方

具有 1x1 可逆卷积的基于流的生成模型,证明了对数似然和定量样本质量的显著改善。也许最引人注目的是,它证明了朝着简单对数似然目标优化的生成模型能够有效地合成大的和主观上逼真的图像。

卷积神经网络的一个有趣的失败和 CoordConv 解决方案

有意思,是时候了

我们已经展示了 CNN 对坐标转换任务建模的奇怪无能,展示了 CoordConv 层形式的简单修复,并给出了表明包括这些层可以在广泛的应用中提高性能的结果。在 GAN 中使用 CoordConv 产生的模式崩溃更少,因为高级空间延迟和像素之间的转换变得更容易学习。在 MNIST 检测上训练的更快的 R-CNN 检测模型显示,当使用 CoordConv 时,IOU 提高了 24%,并且在强化学习(RL)领域中,玩 Atari 游戏的代理从 CoordConv 层的使用中显著受益。

哪些神经网络架构会产生爆炸和消失梯度?

基础知识,理解

我们给出了随机初始化的全连通网络 N 中梯度的统计行为的严格分析。我们的结果表明,N 的输入-输出雅可比矩阵中的项的平方的经验方差在简单的结构相关常数β中是指数的,由隐藏层宽度的倒数之和给出。当β较大时,N 在初始化时计算的梯度变化很大。我们的方法补充了随机网络的平均场理论分析。从这个观点出发,我们严格地计算了混沌边缘梯度统计的有限宽度修正。

具有稀疏和量化通信的分布式深度学习的线性加速分析

实际的

巨大的通信开销已经成为分布式随机梯度下降(SGD)训练深度神经网络的性能瓶颈。先前的工作已经证明了使用梯度稀疏化和量化来降低通信成本的潜力。然而,对于稀疏和量化通信如何影响训练算法的收敛速度,仍然缺乏了解。本文研究了非凸优化的分布式 SGD 在两种减少通信量的策略下的收敛速度:稀疏参数平均和梯度量化。我们证明了如果稀疏化和量化超参数配置得当,可以达到 O (1/√ MK )的收敛速度。我们还提出了一种称为周期量化平均(PQASGD)的策略,在保持 O (1/√ MK )收敛速度的同时,进一步降低了通信开销。我们的评估验证了我们的理论结果,并表明我们的 PQASGD 可以像全通信 SGD 一样快地收敛,而通信数据大小仅为 3 %- 5%。

通过激活样本方差的方差进行正则化

基本原理,标准化

规范化技术在支持深度神经网络的高效且通常更有效的训练中起着重要作用。虽然传统的方法显式归一化的激活,我们建议添加一个损失项代替。这个新的损失项鼓励激活的方差保持稳定,而不是从一个随机小批量到下一个随机小批量变化。最后,我们能够将新的正则项与 batchnorm 方法联系起来,这为它提供了正则化的视角。我们的实验表明,对于 CNN 和全连接网络,在准确性上比 batchnorm 技术有所提高。

卷积神经网络的突触强度

突触修剪,神经科学

卷积神经网络(CNN)是计算和存储密集型的,这阻碍了它们在移动设备中的部署。受神经科学文献中相关概念的启发,我们提出突触修剪:一种数据驱动的方法,用一种新提出的称为突触强度的参数来修剪输入和输出特征图之间的连接。突触强度被设计为基于其传输的信息量来捕捉连接的重要性。实验结果表明了该方法的有效性。在 CIFAR-10 上,我们为各种 CNN 模型修剪了高达 96%的连接,这导致了显著的大小减少和计算节省。

DropMax:自适应变分 Softmax

干净的

我们提出了 DropMax,一个随机版本的 softmax 分类器,它在每次迭代中根据每个实例自适应决定的丢弃概率丢弃非目标类。具体来说,我们在类输出概率上覆盖二进制掩蔽变量,这是通过变分推理输入自适应学习的。这种随机正则化具有从具有不同决策边界的指数级分类器中构建集成分类器的效果。此外,对每个实例上的非目标类的辍学率的学习允许分类器更多地关注针对最混乱的类的分类。我们在多个用于分类的公共数据集上验证了我们的模型,在该数据集上,它获得了比常规 softmax 分类器和其他基线显著提高的准确性。对学习到的丢弃概率的进一步分析表明,我们的模型在执行分类时确实更经常地选择混淆类。

关系递归神经网络

革命的

基于记忆的神经网络通过利用长时间记忆信息的能力来模拟时态数据。然而,还不清楚他们是否也有能力用他们记忆的信息进行复杂的关系推理。在这里,我们首先确认我们的直觉,即标准内存架构可能会在大量涉及理解实体连接方式的任务中挣扎,即,涉及关系推理的任务。然后,我们通过使用一种新的内存模块(关系内存核心(RMC))来改善这些缺陷,这种内存模块采用多头点积注意力来允许内存进行交互。最后,我们在一组任务上测试了 RMC,这些任务可能受益于跨顺序信息的更有能力的关系推理,并显示了在 RL 域(BoxWorld & Mini PacMan)、程序评估和语言建模方面的巨大收益,在 WikiText-103、Project Gutenberg 和 GigaWord 数据集上实现了最先进的结果。

在知识图上嵌入逻辑查询

少数方法

学习知识图的低维嵌入是一种用于预测实体之间未观察到的或缺失的边的强大方法。然而,该领域的一个公开挑战是开发能够超越简单边缘预测并处理更复杂逻辑查询的技术,这可能涉及多个未观察到的边缘、实体和变量。例如,给定一个不完整的生物学知识图表,我们可能想要预测“什么药物可能针对与 X 和 Y 疾病都相关的蛋白质?”—需要对可能与疾病 X 和 y 相互作用的所有可能蛋白质进行推理的查询。这里,我们介绍了一个框架,以在不完整的知识图上有效地对合取逻辑查询进行预测,这是一个灵活但易于处理的一阶逻辑子集。在我们的方法中,我们在低维空间中嵌入图节点,并在该嵌入空间中将逻辑运算符表示为学习到的几何运算(例如,平移、旋转)。通过在低维嵌入空间内执行逻辑运算,我们的方法实现了与查询变量的数量成线性的时间复杂度,相比之下,基于简单枚举的方法需要指数复杂度。我们在两个对具有数百万关系的真实世界数据集的应用研究中展示了该框架的效用:预测药物-基因-疾病相互作用网络中的逻辑关系,以及来自流行网络论坛的基于图形的社会相互作用表示。

作为多目标优化的多任务学习

大问题

在多任务学习中,多个任务被联合解决,在它们之间共享归纳偏差。多任务学习本质上是一个多目标的问题,因为不同的任务可能会发生冲突,需要进行权衡。一个常见的折衷方案是优化一个代理目标,使每个任务损失的加权线性组合最小化。但是,这种解决方法仅在任务不竞争时有效,这种情况很少发生。在本文中,我们明确地将多任务学习视为多目标优化,总目标是找到一个帕累托最优解。为此,我们使用在基于梯度的多目标优化文献中开发的算法。这些算法不能直接应用于大规模学习问题,因为它们与梯度的维度和任务的数量的比例很差。因此,我们提出了一个多目标损失的上限,并表明它可以有效地优化。我们进一步证明,在现实的假设下,优化这个上限会产生一个帕累托最优解。我们将我们的方法应用于各种多任务深度学习问题,包括数字分类、场景理解(联合语义分割、实例分割和深度估计)和多标签分类。我们的方法比最近的多任务学习公式或每任务训练产生更高性能的模型。

Mesh-TensorFlow:超级计算机的深度学习

解决方案

批处理分裂(数据并行)是主要的分布式深度神经网络(DNN)训练策略,因为它的普遍适用性及其对单程序多数据(SPMD)编程的适应性。然而,批量分割存在一些问题,包括无法训练非常大的模型(由于内存限制)、高延迟以及小批量时效率低下。所有这些都可以通过更通用的分布策略(模型并行)来解决。不幸的是,有效的模型并行算法往往难以发现、描述和实现,尤其是在大型集群上。我们介绍网格张量流,这是一种用于描述一般分布式张量计算的语言。在数据并行性可以被视为沿着“批处理”维度拆分张量和操作的情况下,在 Mesh-TensorFlow 中,用户可以指定要在多维处理器网格的任何维度上拆分的任何张量维度。一个网格张量流图编译成一个 SPMD 程序,该程序由并行操作和集体通信原语(如 Allreduce)组成。我们使用 Mesh-TensorFlow 来实现变压器序列到序列模型的高效数据并行、模型并行版本。使用多达 512 个核心的 TPU 网格,我们训练了多达 50 亿个参数的变压器模型,超过了 SOTA 在 WMT 的 14 个英语到法语翻译任务和 10 亿词语言建模基准上的结果。网格张量流在https://github.com/tensorflow/mesh可用

我无法停止思考 NeurIPS!!也不写它。

编辑:我发表了前两次海报会议的部分论文(330 多篇论文)

[## NIPS/NeurIPS 2018:前两次海报会议的最佳*

330 多篇论文的阅读清单,根据它们的效用或优点分组

towardsdatascience.com](/neurips-2018-reading-list-from-tue-poster-sessions-a-b-fce561e56be8)

就绪…设置…人工智能—为未来准备 NHS 医学成像数据

原文:https://towardsdatascience.com/ready-set-ai-preparing-nhs-medical-imaging-data-for-the-future-8e85ed5a2824?source=collection_archive---------2-----------------------

Image courtesy of the Invisible Light X-ray art gallery (http://www.invisiblelight.com.au/)

除非放射科医生在过去的几年里把自己关在黑暗的房间里。),他们将听说即将到来的放射学人工智能算法海啸,它将使他们的工作更快,他们的报告更精确,他们的实践更有影响力。我们中的积极分子将开始考虑如何参与开发放射学人工智能,有些人,像我一样,将积极致力于特定任务的用例、研究和验证。这很好——但我保证无论你在做什么数据集都不够大,你渴望更多。也许你可以从 NIH 获得免费的 10 万张胸透照片?或者你说服了你的医院让你检查他们的 PAC?或者也许你在 IBM 工作,可以接触到所有甜蜜的合并医疗数据

对你有好处。获取医疗数据并使其独享和专有的热潮让我想起了两个世纪前的淘金热。勘探者成群结队地来到这里,与投资者讨价还价以获得开始挖掘的资金,乞求资金来购买地块,并在承诺黄金财富的同时寻求设备投资。然而,在挖掘真正有价值的东西和取出大块的固体矿石之前,有一个心照不宣且经常被忽视的障碍需要跨越…

问题是…医学成像数据还没有为人工智能做好准备

在医学成像数据上开发机器学习算法不仅仅是获取数据的问题。虽然访问本身当然是一个非常令人头疼的问题(看看 DeepMind 就知道一个明显的例子),但这并不是比赛中唯一的障碍。在本文中,我将解释数据准备的概念,以及在准备数据方面的投资为何比开发第一个算法更重要。

数据准备阶段

没有定义和普遍接受的尺度来描述准备好的数据如何用于机器学习。许多管理咨询公司会提供漂亮的幻灯片,告诉你如何收集数据并从中创造见解(并为这种特权收取高额费用),但数据就绪性的基本原则仍然是一个很大程度上无法量化的过程。

Neil Lawrence 教授(谢菲尔德,亚马逊)写的一篇鲜为人知但非常重要的关于数据就绪的论文引起了我的注意,在阅读了这篇论文并与他联系讨论后,我提出了自己的数据就绪量表的修改版。

Medical imaging data readiness scale

让我们从头开始,从 D 级开始…

每个人都想要 D

想象你拥有一个巨大的油田。想象一下这是多么美好的事情。除非你是 NHS,在这种情况下,你不必想象,因为你已经拥有一个巨大的油田!问题是,你的油田对于那些想把石油挖出来并把它变成汽油来为你赚取巨额利润的人来说是完全无法进入的。不仅如此,还有法律和道德的阻碍(甚至不要让我开始谈论 GDPR)。没有人,甚至是你,知道你的油田里到底有什么。你的油田就是我所说的‘D 级’数据。

D 级数据在数量和质量上都无法验证,不可访问,并且其格式使得机器学习很难或不可能做任何事情。这种级别的未匿名数据存在于每一家医院的 trust PACS 归档中,数量庞大,除了记录临床活动之外,什么也不做。(而且……我一想到这个就不寒而栗……由于数据存储问题,NHS 信托基金经常会删除这些积压的数据。比如扔油……)

为了将 D 级数据提升到 C 级,你需要建造一个精炼厂。数据提炼的第一步是获得访问数据的道德许可。在实践中,这是通过一个数据共享协议来实现的,要么通过一个道德委员会在本地与你自己共享,要么与第三方(大学、公司或初创企业)共享。NHS 信托可能在任何时候都有数以千计的数据共享协议。这些协议还将包括数据匿名化的条款,因为显然没有人希望 NHS 泄露机密的患者信息。到目前为止还不错…但是,数据仍然是非结构化的,不能代表一个完整的集合。这也将是非常嘈杂的,充满了错误,遗漏和只是简单怪异的条目。无论是谁,只要能接触到这些数据,现在都必须想办法让它们变得有用,然后才能开始算法开发。c 级数据已经准备好提供给人工智能开发者,但还远远没有准备好派上用场。

让它 B…

现在需要将数据进一步细化为 B 级数据,对其进行结构化,确保其代表您认为自己拥有的数据,并对其进行可视化,以便能够深入了解噪声特征和其他分析指标。这个过程实际上比 D 到 C 阶段更难,因为它是为每个数据集定制的。没有检查医学成像数据的标准方法,每个有权访问您的数据的小组将运行他们自己的数据可视化和分析。这是因为来自不同医院的数据将具有不同的特征和不同的格式(例如,不同的 DICOM 标题、日期和时间戳等)。将 C 级转化为 B 级的过程可能需要几个月——这可不是研究人员或初创企业在争夺金牌的过程中所需要的。只有有了 B 级的数据,你才能对它的可能性有一个概念,以及 AI 在哪里可以用来解决实际问题。

仅仅是最好的(比所有其他的都好)

对于算法开发来说,A 级数据是最接近完美的——它是结构化的,完全注释的,噪音最小,最重要的是,它在上下文中是适当的,并为特定的机器学习任务做好了准备。例如,100 万次肝脏超声检查的完整数据集,包括患者年龄、性别、纤维化评分、活检结果、肝功能测试(lft)和诊断,所有这些都在相同的元标签下构建,可用于深度学习算法,以确定哪些患者在 B 型超声扫描中有患非酒精性脂肪性肝病(NAFLD)的风险。

注释可能是放射学数据集提炼中最困难的部分——理想情况下,每一个图像发现都应该由经验丰富的放射科医师进行注释,以便在整个数据集内准确一致地突出显示所有可能的病理。问题是——世界上几乎没有任何现有的医学成像数据是以这种方式标注的。事实上,大多数“野生”图像甚至没有注释。这就是为什么有一个围绕数据标签的整个行业。有没有登录一个网站,被要求点击包含路标或汽车的图片?你在为自动驾驶汽车算法标记数据!当然,并不是每个互联网用户都是放射科医生,所以这种众包模式并不适用于医学成像(除非你经营无线医疗——有一个免费的商业创意给你们!).相反,研究人员不得不乞求或支付放射科医生的时间来注释他们的数据集——这是一项极其缓慢和昂贵的任务(相信我,我在论文期间花了 6 个月时间绘制前列腺周围的轮廓……)。另一种方法是在成像报告上使用自然语言处理(NLP)来挖掘概念,并使用它们来标记图像——然而,这种模型还远远没有证明足够健壮。

推测积累

从 D 级数据一直到 A 级数据的上述提炼过程在时间和资源方面都是昂贵的。我经常看到小型研究小组开始时提出一个大胆的建议,用机器学习来解决一个特定的任务,急于获得数据访问权,却被为什么他们的算法从未达到有用的准确率所困扰,然后放弃。他们试图避开提炼过程,结果被抓了出来。甚至像 IBM 这样的大玩家也在这个问题上苦苦挣扎。他们可以访问大量的数据,但是需要花费大量的时间和精力来准备这些数据,使其具有可操作性和实用性。

与任何投机性投资一样,你必须为基础设施建设融资,才能在下游获得收益。这就是为什么我提出了一个承担这项工作的国家框架,我称之为英国放射学人工智能网络(大脑)。这个想法是利用最近宣布的政府生命科学战略来获得资金,以创建一个基于 NHS 成像数据的全新产业。BRAIN 将充当匿名成像数据的“数据信托”或仓库,允许研究人员和公司访问,以换取知识产权权益。通过建立 BRAIN,NHS 将立即将数据准备程度提高到 C 级,然后随后的每一项研究活动都将有助于完善汇集的数据,将数据从 C 级提升到 A 级,为放射学人工智能的发展创造丰富的资源,增加数据集的价值。

这种设置的优势是巨大的 NHS 不仅在保持控制的同时开放了大量的数据,还通过对数据进行精炼分享任何产生的知识产权,从人工智能发展的回报中获益两倍。此外,NHS 医院不再需要管理成千上万的数据共享协议(这是一项资源密集型任务)——它们只需将人们引向 BRAIN。

对研究人员和公司来说,好处也很大——他们都可以通过一个集中的数据共享协议访问数据(不再需要一个接一个地催促各个医院),数据池比他们以前可以访问的任何数据都大,随着时间的推移,他们花在数据提炼上的资源越来越少,而花在开发有用算法上的时间越来越多。好处不止于此——通过汇集来自 NHS 的数据,您可以减少数据中的偏差,并将算法暴露于更广泛的成像技术、报告风格和病理,最终使最终产品算法更具通用性,可用于任何设置。

发展新产业

梅特卡夫定律(Metcalfe's Law)指出,网络的价值随着用户数量的平方增长而增长(看看脸书或 Twitter——庞大的网络,巨大的价值)。通过集中访问大型汇集数据集并邀请数百名研究人员参与,您可以立即显著增加网络的价值。所需要的只是一个建立它的承诺。人们只需要看看英国生物银行的成功就能明白为什么这样的网络是至关重要的(他们只有 1000 多台核磁共振成像仪)。

放射学人工智能领域就像是蛮荒的西部——它需要一个镇上的警长。通过汇集结构化数据,英国和 NHS 可以催生一个新的研究行业,同时收获回报。这是我对医学影像和 AI 海量数据的大梦想;我希望我已经说服你分享它!

如果你和我一样对放射学人工智能的未来感到兴奋,并想讨论这些想法,请保持联系。我在推特@drhughharvey

如果你喜欢这篇文章,点击推荐并分享它会很有帮助。

关于作者:

Harvey 博士是一名委员会认证的放射科医生和临床学者,在英国国民医疗服务体系和欧洲领先的癌症研究机构 ICR 接受过培训,并两次获得年度科学作家奖。他曾在 Babylon Health 工作,领导监管事务团队,在人工智能支持的分诊服务中获得了世界第一的 CE 标记,现在是顾问放射科医生,皇家放射学家学会信息学委员会成员,以及人工智能初创公司的顾问,包括 Kheiron Medical。

使用 Python 和 SAS 事件流处理进行实时分析

原文:https://towardsdatascience.com/real-time-analytics-using-python-and-sas-event-stream-processing-92aecce95b92?source=collection_archive---------1-----------------------

实时或接近实时应用的分析为从事这项工作的公司带来了最大的经济效益。这里的论点是,从数据中获取最大收益的最佳方式是提取即时洞察力,以便为生成该数据的业务提供增量价值。现在有很多公司都这么做(网飞、亚马逊等)。)——还有很多人想尽快完成这项工作,并有实现目标的路线图。这是我们都同意的——至少我最近在这个领域交谈过的大多数人似乎都这么认为。虽然对静态数据的分析不会有任何进展,但实时分析如今却变得相当流行。我确信这个时髦的词汇工厂会制造出诸如机器智能、认知计算、全渠道、物联网、云战略等词汇。会同意。

T 这篇文章的目的是展示一种“ 开放技术”SAS 事件流处理(ESP) (参见 此处 了解 SAS ESP) 如何使用户能够快速创建一个实时事务处理管道,并在此过程中实现分析——即应用业务规则如果我告诉你,你可以用 Python 只使用 SAS ESP 自带的 GUI 工具完全做到这一点,那不是更好吗?好吧,我们就这么做,让静态数据科学变得生动起来!

我们将利用 SAS ESP 附带的微分析服务(MAS)插件,快速解决复杂的实时分析处理和决策问题。可以把 MAS 想象成“一桶任意代码”,它保存着我们想要为流处理任务执行的业务逻辑。

当我考虑这么做的时候,我不得不专注于一些需要实时解决方案的实际问题——一些企业需要处理并且必须立即采取行动的问题。因此,我决定在这篇文章中,我们将构建一个实时防欺诈引擎,它将对流中的交易进行评分/评估。我个人最喜欢的一个是实时推荐引擎——所以我改天再回到这个话题。此外,我认为个性化值得自己的关注——而不是隐藏在一个像这样谈论实时分析的帖子中。

好了,现在我已经把这篇文章推销了不少,足以让你恼火,让我们开始吧,希望我们能看到所有这些是如何与我们的防欺诈用例一起工作的。

创建流:

我们将使用位于 这里的 的数据集。它是一个 sqlite 数据库,允许我们将事务数据连续地流入我们的 ESP 应用程序。现在,我们将使用它来模拟一个流媒体源。我设置了一个小的 python 脚本来简化这个过程 这里 。所有这些都是初始设置项目,所以让我们浏览一下这些部分,如果您自己正在尝试,只需足够的细节就可以完成。这样,我们就不会陷入困境,并转移到用例的核心部分。这里有一个快速窥视我们的流媒体源

注意:此时,您将在您想要尝试的机器上部署(或已经拥有)SAS 事件流处理,并为微分析服务插件配置它。在 这里可以找到该任务的所有相关文档 。这是一个相当简单的过程。链接中的部署文档非常深入,一目了然。

现在,我们准备冒险设置我们的流应用程序。

思考整个过程(3TP):

使用 SAS ESP 的一个亮点是能够使用 GUI 快速编写复杂的流内转换和模式匹配逻辑。

我们将使用 GUI 为我们的检测过程建立一个整体的处理管道/流程。我们将通过以下方式实现这一目标

a.设置微分析服务(MAS)来管理我们的 python 文件,然后使用程序窗口在流中调用它

b.实施我们的机器学习算法,用于检测以及完成工作流程所需的规则、过滤器、连接和其他处理逻辑

当我做研究和思考什么是对的/什么是错的时,我喜欢思考高层次设计/架构的抽象过程,但帮助别人理解你的观点并不总是好的。因此,本着先做最后一件事的精神&为了帮助我们看到我们将到达的地方,这里是最终设置在 GUI 上的实际样子。

Streaming set up for Fraud Detection

上面你看到的是 窗口 相互连接的有向图。关键概念:ESP 中的“窗口”是独立的节点,即高效执行单一任务/功能的流处理管道中的接触点。

虽然上面的图片对我所说的内容提供了一些清晰度,但是图形用户界面中的东西看起来如何并不那么重要。重要的是,ESP 自动地将管道翻译成 XML 文件,供开发人员在生产环境中运行时部署在 ESP 服务器上。

这非常方便,因为迭代思想变得很容易。一旦你掌握了窍门,它会成为一个令人陶醉的玩具。如果你写代码(开发人员/研究人员/科学家等),这可能是一个甜蜜点。)因为你可以享受试验想法的自由,而不会陷入管理逻辑和句法细节的认知超载。所有这些越重要,你就越能理解你的逻辑在深层是如何运作的。此外,如果需要,您也可以选择深入研究。就这样,我又跑题了。

问题解析— 有什么快速解答 :

O K,为了检测欺诈,我们需要业务规则(陷阱/停止规则和释放规则)和 机器学习模型 (我们将使用 SAS E-Miner 实现一个,并将其移动到 ESP 中进行流内评分。在这篇文章中,我们不会关注 ML 模型的生成——那是另外一个时间了。

Ok, we’ll take some of it too!!

2017 规则#1 : 没有机器学习,就没有足够好的解决方案。想要证据吗?去看看 炒作周期 的巅峰。

但是,为什么规则?基本上,这些规则是企业用来帮助处理潜在的欺诈事件的。他们还可以使用规则来定义他们不想花费时间和精力的基于某种经验证据的交易特征。

最终,所有这些导致将可疑交易推入警报管理/交易审查工具,如可视调查器(或类似的东西),让审查代理/调查器处理这些交易的过程(取消/完成)。他们给银行打电话,做更深入的核实等等。诸如此类的事情。

设置脚本:

我们将使用 Python 编写陷阱规则和释放规则。我们将使用 MAS 插件设置它在 ESP 中工作。这将针对流中的所有事务运行。您可以从 GUI 工具配置 MAS 插件,如下所示:

Setting up the Micro Analytic Service

为了简单起见,我只为我们的虚拟项目使用了几条规则——在现实生活中可能有数百条——很容易以敏捷的方式修改。就像标准 python 一样,我们可以自由地返回任意数量的感兴趣的作用域变量。ESP 只需要一个提示,这个需求是在主函数的 docstring 中管理的,例如 manager 函数。否则,其他一切都保持不变。例如,你可以从其他模块或用户定义的对象(类/函数)借用多个辅助函数/方法,就像标准 python 一样。正如你在这里看到的,我们使用几个助手函数来管理我们的代码。

接下来,我们将设置 MAS 插件来引用 python 脚本,就像我已经展示的那样。它非常简单,您可以将整个 python 函数作为文本粘贴进去,也可以只提供脚本位置的路径(推荐)。在这之后,我们使用管道中的程序窗口指向代码定义的 MAS 插件中的主函数。

最后,我们将我们用 SAS E-Miner 创建的机器学习模型合并到 ESP 中,在将 SAS 分数代码翻译成 DS2 代码之后再次使用程序窗口。对于这一步,我使用了 PROC DSTRANS 并推荐这种方法。在这一步之后,你可以做一些简单的改变,但是这是非常直接的,结果看起来像T5。

注:如果你正在寻找用 E-Miner 构建机器学习模型的教程,请前往此 链接 。你会在那里找到很多资源。或者,您也可以挑选您的 scikit 学习模型并在 stream 中对其评分。

至此,我们用于欺诈检测的流引擎已经完成。我们已经制定了业务规则,检查了部署我们在待办事项列表上的机器学习模型。我甚至要让你知道这个卑鄙的小秘密。再次注意代码文件——我也用我的 sklearn 模型对事务进行评分。很容易,不是吗!因此,在所有这些之后,我们的流程会对交易进行评分,如下例所示:

Sample Scoring Result

请注意这一切是如何完美地工作的,其中规则和模型(SAS 和开源 ML 模型)都是为了实现相同的目标——根据一个公式分配一个警报分数(人类可以理解),当 ML 模型检测到警报时,该分数会偏高,而规则更有可能产生误报。上图还展示了 SAS ESP 为用户提供的处理能力。另一个例子是,如果你回到本文开头的流程图/有向图,过滤窗口(标有“截止”窗口)充当控制旋钮,允许我们根据企业希望吸收的风险大小,以灵活的阈值进行操作。从这一点开始,您可以定制您认为合适的流程,并让下游订户获取结果,并将其与支持更大业务流程的系统集成。

所以,你走吧!如果有一种简单的方法可以利用团队现有的技能来创建和部署实时解决方案,那么机会将是无限的。然后,您可以开始挑选用例库存中更高的东西&创建优雅的解决方案来解决它们。以前不可能的事情,现在变成了可能!

LinkedInT3 上与 Sathish 连接

使用 Tensorflow,OpenCV 和 Docker 的实时和视频处理对象检测。

原文:https://towardsdatascience.com/real-time-and-video-processing-object-detection-using-tensorflow-opencv-and-docker-2be1694726e5?source=collection_archive---------0-----------------------

在本文中,我将介绍如何在 Docker 容器中使用 Tensorflow 对象检测 API 来执行实时(网络摄像头)和视频后处理。我使用 OpenCV 和 python3 多处理和多线程库。

我将把重点放在我遇到的障碍,以及我找到了什么解决方案(或者没有!).完整的代码在我的 Github 上。

Video processing test with Youtube video

动机

我从这篇优秀的 Dat Tran 文章开始探索实时对象检测的挑战,引导我用 Adrian Rosebrock 的网站研究 python 多处理库来增加 FPS。为了进一步增强可移植性,我想将我的项目集成到 Docker 容器中。这里的主要困难是处理进入和来自容器的视频流。

此外,我在我的项目中添加了一个视频后处理功能,也使用了多处理来减少处理时间(当使用原始 Tensorflow 对象检测 API 时,处理时间可能会非常非常长)。

在我的个人笔记本电脑上,仅使用 8GB CPU,实时和视频处理都可以高性能运行。

数据科学码头工人

我不会花时间描述 Tensorflow 对象检测 API 实现,因为关于这个主题的文章很多。相反,我将展示如何在我作为数据科学家的日常工作中使用 Docker。请注意,我使用了 Tensorflow 的经典 ssd_mobilenet_v2_coco 模型,以获得速度性能。我复制了这个模型。pb 文件)和相应的本地标签映射(在模型/目录中)以保持以后使用个人模型的可能性。

我相信今天使用 Docker 已经成为数据科学家的一项基本技能。在数据科学和机器学习领域,每周都会发布许多新的算法、工具和程序,将它们安装到您的计算机上进行测试是让您的操作系统崩溃的最佳方式(有经验的!).为了防止这种情况,我现在使用 Docker 容器来创建我的数据科学工作区。

你可以在我的知识库中找到我正在为这个项目工作的 docker 文件。下面是我如何安装 Tensorflow 对象检测(遵循官方安装指南):

# Install tensorFlow
RUN pip install -U tensorflow# Install tensorflow models object detection
RUN git clone [https://github.com/tensorflow/models](https://github.com/tensorflow/models) /usr/local/lib/python3.5/dist-packages/tensorflow/models
RUN apt-get install -y protobuf-compiler python-pil python-lxml python-tk#Set TF object detection available
ENV PYTHONPATH "$PYTHONPATH:/usr/local/lib/python3.5/dist-packages/tensorflow/models/research:/usr/local/lib/python3.5/dist-packages/tensorflow/models/research/slim"
RUN cd /usr/local/lib/python3.5/dist-packages/tensorflow/models/research && protoc object_detection/protos/*.proto --python_out=.

同样,我安装了 OpenCV:

# Install OpenCV
RUN git clone [https://github.com/opencv/opencv.git](https://github.com/opencv/opencv.git) /usr/local/src/opencv
RUN cd /usr/local/src/opencv/ && mkdir build
RUN cd /usr/local/src/opencv/build && cmake -D CMAKE_INSTALL_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local/ .. && make -j4 && make install

图像构建有点长,需要几分钟时间。然后,使用它是快速和容易的。

实时目标检测

我首先尝试应用对象检测到我的网络摄像头流。这项工作的主要部分在 Dat Tran 的文章中有完整的描述。困难在于将网络摄像头流发送到 docker 容器中,并使用 X11 服务器恢复输出流以显示它。

将视频流发送到容器中

在 Linux 中,设备位于/dev/目录中,可以作为文件进行操作。通常,您的笔记本电脑网络摄像头是“0”设备。要将其流发送到 docker 容器中,在运行 docker 映像时使用设备参数:

docker run --device=/dev/video0

对于 Mac 和 Windows 用户来说,将网络摄像头流发送到容器中的方式不像 Linux 那样简单(尽管 Mac 是基于 Unix 的)。我没有深入研究这个问题,但是 Windows 用户的解决方案是使用虚拟盒子来启动 docker 容器。

从容器中恢复视频流

这是我花了一些时间解决的问题(解决方案不令人满意)。我在 Docker 这里找到了关于使用图形用户界面的有用信息,特别是将容器连接到主机的 X 服务器进行显示。

首先,您必须公开您的 xhost,这样容器就可以通过 X11 unix 套接字读写来正确显示。首先设置 X 服务器主机的权限(这不是最安全的方法)让 docker 访问它:

xhost +local:docker

然后,当您使用完项目后,将访问控制恢复为默认值:

xhost -local:docker

然后,创建两个环境变量 XSOCK 和 XAUTH:

XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth

第一个引用 X11 Unix 套接字,第二个引用我们现在创建的具有适当权限的 X 身份验证文件:

xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -

最后,我们只需更新 docker 运行行命令。我们转发我们的 DISPLAY 环境变量,为 X11 Unix 套接字和 X 身份验证文件挂载一个卷,该文件带有一个名为 XAUTHORITY 的环境变量,它链接到:

docker run -it --rm --device=/dev/video0 -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH

现在我们可以运行 docker 容器了,它已经完成了:

Me with common objects at work (I’m a shy person).

尽管主机的 X 服务器配置,我不能完全删除我的代码中似乎是一个错误。OpenCV 需要通过使用 cv2.imshow 函数调用 python 脚本( init-openCV.py )进行“初始化”。我得到以下错误消息:

The program 'frame' received an X Window System error.

然后,可以调用主 python 脚本( my-object-detection.py )并且视频流被很好地发送到主机显示器。我对使用第一个 python 脚本来初始化 X11 系统的解决方案不是很满意,但是到目前为止我还没有找到任何解决这个问题的方法。

编辑:我终于(而且不小心!)通过使用 OpenCV (3.4.1)的稳定版本,而不是在本地克隆 git repo,找到了这个问题的解决方案。因此,现在不需要在主 python 脚本之前调用 init-openCV.py

视频处理

为了设法用我的网络摄像头实时运行对象检测 API,我使用了线程多处理 python 库。一个线程被用来读取网络摄像头流。帧被放入队列中,由一组工作线程(Tensorflow 对象检测在其中运行)进行处理。

出于视频处理的目的,不可能使用线程,因为在工人能够对放入输入队列的第一个帧应用对象检测之前,所有视频的帧都被读取。输入队列已满时读取的帧会丢失。也许使用大量工作人员和庞大的队列可以解决这个问题(计算成本高得令人望而却步)。

简单队列的另一个问题是,由于不断变化的分析时间,帧在输出队列中的发布顺序不同于在输入队列中的顺序。

为了增加我的视频处理功能,我移除了读取帧的线程。相反,我使用下面几行代码来读取帧:

while True:
  # Check input queue is not full
  if not input_q.full():
     # Read frame and store in input queue
     ret, frame = vs.read()
      if ret:            
        input_q.put((int(vs.get(cv2.CAP_PROP_POS_FRAMES)),frame))

如果输入队列未满,则从视频流中读取下一帧并放入队列。否则,当帧没有从输入队列中获取时,什么也不做。

为了解决帧顺序的问题,我使用了一个优先级队列作为第二个输出队列:

  1. 读取帧并将其与相应的帧编号一起放入输入队列(实际上,一个 python 列表对象被放入队列)。
  2. 然后,工人从输入队列中取出帧,对它们进行处理,并将其放入第一个输出队列中(仍然使用它们的相对帧号)。
while True:
  frame = input_q.get()frame_rgb = cv2.cvtColor(frame[1], cv2.COLOR_BGR2RGB)
  output_q.put((frame[0], detect_objects(frame_rgb, sess, detection_graph)))

3.如果输出队列不为空,则帧被提取并放入优先级队列,其对应的帧号作为优先级号。优先级队列的大小被任意设置为其它队列大小的三倍。

# Check output queue is not empty
if not output_q.empty():
  # Recover treated frame in output queue and feed priority queue
  output_pq.put(output_q.get())

4.最后,如果输出优先级队列不为空,则采用优先级最高的帧(优先级最小的帧)(这是标准优先级队列)。如果先前对应于预期的帧号,则该帧被添加到输出视频流(并且如果需要的话写入),否则该帧被放回到优先级队列中。

# Check output priority queue is not empty
  if not output_pq.empty():
    prior, output_frame = output_pq.get()
    if prior > countWriteFrame:
      output_pq.put((prior, output_frame))
    else: 
      countWriteFrame = countWriteFrame + 1    
      # Do something with your frame

为了停止这个过程,我检查了所有的队列都是空的,并且所有的帧都已经从视频流中提取出来:

if((not ret) & input_q.empty() & 
    output_q.empty() & output_pq.empty()):
  break

结论

在本文中,我将介绍如何使用 docker 通过 Tensorflow 实现一个实时对象检测项目。如上所述,docker 是测试新数据科学工具以及打包我们向客户交付的解决方案的最安全方式。我还向您展示了我是如何改编 Dat Tran 的原始 python 脚本来执行多处理视频处理的。

如果你从头到尾看完这篇文章,谢谢你!正如你所看到的,这个项目有很多可能的改进。不要犹豫给我一些反馈,我总是渴望得到建议或意见。

在 python 中监视子编辑的实时机器人。

原文:https://towardsdatascience.com/real-time-bot-for-monitoring-subredditts-in-python-691cc692fdb5?source=collection_archive---------26-----------------------

大家好,Reddit 是美国最大的社交新闻聚合之一。所有成员都可以在相关的子编辑中发表任何内容。如果你有一个被很多人使用的产品,那么了解他们对这个产品的感受是非常重要的。facebook、Twitter、reddit 等社交媒体平台。是人们使用最广泛的方法之一。Reddit 也是一个论坛,人们可以谈论和讨论任何事情。几乎所有的产品,无论是微软 Azure 还是 AWS,都有与用户交流的子界面。那么,如果你想了解用户的情绪,并从子编辑中获得所有负面的标题,以便你可以相应地改进产品,或者如果你想与用户实时互动,该怎么办呢?在这里,我将解释如果任何用户开始对与你相关的产品进行负面讨论,你如何通过标题的 URL 链接获得通知。

现在,除此之外,假设您还希望看到一个时间序列图,显示用户对您的产品进行负面评价的频率,并且您希望以某种形式显示出来,以便您可以看到有多少负面标题,有多少人对这些标题投了赞成票,以及有多少人参与了这些标题。

我想现在你一定已经知道我想要达到的目标了。假设你是一家为 PUBG、堡垒之夜、使命召唤、坦克世界等大型游戏提供语音服务的公司,你想知道人们在网上对语音服务的讨论。如果很多人投票赞成一个标题,那么这意味着它是一个普通的问题,你可以实时处理它。但是如果只有很少的投票,那么问题可能出在用户端,比如速度慢之类的。

那么,让我们开始吧。

1.)首先,我们需要像下面这样的一些细节,可以通过在 twitter 上创建并遵循【https://redditclient.readthedocs.io/en/latest/oauth/
T2 的指示。你可以使用自己的 reddit 帐户,因为没有必要使用官方 vivox 帐户,我不知道我们是否有任何官方 reddit 帐户。

客户端标识 = '客户端标识',\

客户端秘密 = '客户端秘密',\

用户代理 = '用户代理',\

用户名 = '用户名',\

密码=‘密码’

2.)要与 slack 交互,我们需要创建一个 slack bot API,您可以按照下面的说明创建它:-

松弛 API= ' xox b-44323424–234324243-dfsdfdsfsf '

3.)我们还将维护一个 csv 文件,在该文件中,我们将以如下格式维护客户 twitter 名称信息:-

4.)我们需要一些库来设置整个过程。因此,请将以下库安装到您的环境中:-

5.)之后,我们将使用 praw 方法设置 reddit,因为 praw 是与 reddit 数据交互的 api。如果你想了解更多关于 praw 的信息,请点击这里https://praw.readthedocs.io/en/latest/

6.)然后我们将 CSV 文件读入熊猫的数据帧。CSV 文件包含子编辑的所有细节,如果您需要添加或删除任何子编辑,您可以在 CSV 文件中完成,无需编辑 python 脚本。

7.)之后,由于我们是动态进行的,所以我们将创建两个变量,一个是读取子编辑名称,另一个是客户端名称。

8.)现在,我们将阅读子编辑的标题。因为我们在这里构建一个动态机器人,所以我们将只阅读新的标题,为此我们将遵循下面的代码行。在这里,我们首先将 subreddit 的名称放入一个变量 subreddit 中,然后我们在这里只读取新的注释。我已经通过了这里的限制= 1000,你也可以不通过,但你将无法获得超过 1000 个标题,默认为 100。

9.)那么,如果你需要所有的历史头条呢。我们在这里不需要它,但是如果你想下载所有的,你可以使用 pushshiftapi(【https://github.com/pushshift/api】T2)

10.)现在我们将为我们将从 reddit 中读取的键创建一个字典。reddit 提供了 95 种不同的值,但我们并不需要所有的值。按照我们的要求,我正在使用下面的。

11.)一旦我们声明了字典的结构,现在就该从 reddit 将数据读入字典了:-

12.)最后,我们有了数据,现在我们将把它转换成一个 pandas 数据框,以便对它执行进一步的操作:-

13.)Reddit 总是以纪元格式给出时间,我们需要一个通用时间戳来读取和执行操作:-

14.)现在,是时候决定我们的机器人的时间间隔了,假设你想每 15 分钟做一次。此外,由于 reddit 和 yor 时区可能不同,所以选择一个共同的时区总是明智的,这就是为什么我把两者都转换成 UTC。

15.)现在,是时候过滤掉标题了,你可以按照下面的代码来做

16.)发布到 slack 频道:-

17.)现在,如果我们想将数据存储到某个数据库中,并在 grafana 上可视化该数据,该怎么办呢?我在这里使用 InfluxDB,所以只需用下面的代码替换步骤 15,数据将存储在 InfluxDB 中。

18.)为时间序列可视化设置 Grafana,您将获得如下图表

在上面的图表中,我们可以看到,在午夜,一些人发布了一个标题,在短短的 15 分钟内,有 247 人投了赞成票,115 人发表了评论。所以,这是一个问题。grafana 仪表板将如下图所示

结束注释:-

  1. 如果您设置了 15 分钟的时间间隔,那么请确保您为所有客户端编写的脚本花费的时间少于该时间间隔。
  2. 我们总是可以根据我们的需要修改脚本,比如我们想要什么样的通知。

我还写了一篇关于制作 twitter 机器人的文章。请阅读:-

[## Python 中的实时动态 tweet 监控机器人。

如果你正在阅读这篇博客,那么你可能正在寻找为 slack 开发某种推特监控机器人。在这个…

towardsdatascience.com](/real-time-dynamic-tweet-monitor-bot-for-slack-in-python-d0409b66de62)

如果你在评论区有任何错误,请告诉我。请添加任何有价值的建议,我甚至可以改善这个脚本。我是东北大学的研究生,目前在 Vivox 做数据科学家。

请访问下面的 Github 库获取代码:-

[## abhimanyu3/RedditBot_for_slack

设置一个 Reddit 机器人来监控关于用户情绪的实时子编辑标题,并将其放入 slack…

github.com](https://github.com/abhimanyu3/RedditBot_for_slack)

请联系 Linkedin:-

[## Abhimanyu Kumar -数据科学家(Co Op) - Vivox | LinkedIn

查看 Abhimanyu Kumar 在世界上最大的职业社区 LinkedIn 上的个人资料。Abhimanyu 有 8 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/abhimanyu0301/)

针对 slack 的实时推特通知机器人。

原文:https://towardsdatascience.com/real-time-dynamic-tweet-monitor-bot-for-slack-in-python-d0409b66de62?source=collection_archive---------17-----------------------

如果你正在阅读这篇博客,那么你可能正在寻找为 slack 开发某种推特监控机器人。在这篇文章中,我将描述我如何用 python 创建了一个动态 tweet monitor bot 来监控客户是否在 tweet 上发布了某些特定的内容。假设您想监控您的一个客户何时发布关于某件特定事情的推文。如果你只想监控一个账户,那没问题,但是想想你监控 100 个 twitter 账户的情况。你肯定会错过你的 slack 频道中的 tweet 洪流中的重要 tweet。假设您正在监控 Zara,并想知道他们何时在推特上发布销售信息。当 Zara、Columbia、North face 等大公司都在推特上发布出售消息时,你只是想要一个宽松的通知。那可能是任何一种公司。所以,你不想为 50 家公司写 50 个脚本,而是创建一个动态脚本,为所有客户完成工作。现在,如果您想在您的观察列表中添加或删除某些客户,该怎么办?我们赢了;不接触脚本,但我们将维护一个 CSV 文件或任何类型的数据库,它将服务于目的。

1.)首先,我们需要像下面这样的一些细节,这些细节可以通过在 twitter 上创建,并遵循https://chimpgroup.com/knowledgebase/twitter-api-keys/上的指示

消费者:

消费者 _ 密钥 = '消费者 _ 密钥'

消费者 _ 秘密 = '消费者 _ 秘密'

访问:

访问令牌 = '访问令牌'

访问密码 = '访问密码'

2.)要与 slack 交互,我们需要创建一个 slack bot API,您可以按照下面 youtube 视频中的说明来创建它

SLACK API= ' xox b-gfgdfgdfgdgfdfg '

从 xoxb 开始,你会得到类似上面的 slack api。

3.)我们还将维护一个 csv 文件,在该文件中,我们将以如下格式维护客户 twitter 名称信息:-

4.)我们需要一些库来设置整个过程。因此,请将以下库安装到您的环境中:-

5.)之后我们会声明 twitter 开发者账户和 slack API 的密钥。您可以使用任何帐户,但如果您想使用 Vivox 的详细信息,请联系 JIM。你总是可以自己创建 slack API,我已经分享了上面的链接,作为如何创建 slack API 密钥的参考。

6.)然后我们将 CSV 文件读入熊猫的数据帧。CSV 文件包含客户 twitter 名称的所有详细信息,如果您需要添加或删除任何 twitter 名称,您可以在 CSV 文件中完成,无需编辑 python 脚本。

7.)然后我们将定义 tweepy 函数,稍后我们将使用它作为提取器:-

8.)现在,我们将创建一个 datafrme“数据”:

9.)现在,Twitter 会在每条推文中提供各种细节。所以,如果你想知道每条推文的所有细节,你可以使用下面的代码

10.)现在,用下面的代码将您想要提取的任何信息作为一列添加到数据帧中。我刚刚添加了三个细节,但你可以添加你想要的。

11.)我们不希望任何用户发布任何推文,也不希望我们的客户在推文中回应任何用户的推文。要忽略所有这类推文,请使用以下代码:-

12.)现在,我们不希望相同的推文作为通知出现两次,所以我限制我的推文窗口只检查最后 1 分钟的推文,并且 cron 作业每分钟都在运行。这里的问题是 twitter 数据在不同的时区,而我们的系统时区是不同的。因此,我将两个时间都改为通用格式,即 UTC。

13.)在我们完成这一步后,我们将创建一个值列表,在此基础上,我们将根据我们想要的 tweets 过滤 tweets,其中包含某些词,如停机时间、维护等。

14.)在最后一步中,我们将检查数据帧“ndata”中是否有任何数据,并将其作为松弛通知发送:-

15.)完成上述所有步骤后,在终端上使用以下命令设置 cron 作业:-

16.)然后为 cron 作业创建条目,如下所示,它将每分钟运行一次:-

结束注释:-

  1. )确保任何帐户名都不是无效的或私有的。
  2. )根据您的要求修改您的 my_list。

如果你在评论区有任何错误,请告诉我。请添加任何有价值的建议,我甚至可以改善这个脚本。我是东北大学的研究生,目前在 Vivox 做数据科学家。

请访问下面的 Github 库获取代码:-

[## abhimanyu 3/Twitter bot _ for _ slack

设置一个 twitter 机器人来实时监控多个 twitter 帐户,并在空闲时获得实时通知…

github.com](https://github.com/abhimanyu3/twitterbot_for_slack)

让我们连接起来:-

[## Abhimanyu Kumar -数据科学家(Co Op) - Vivox | LinkedIn

查看 Abhimanyu Kumar 在世界上最大的职业社区 LinkedIn 上的个人资料。Abhimanyu 有 8 份工作列在…

www.linkedin.com](https://www.linkedin.com/in/abhimanyu0301/)

实时人脸识别:一个端到端的项目

原文:https://towardsdatascience.com/real-time-face-recognition-an-end-to-end-project-b738bb0f7348?source=collection_archive---------0-----------------------

逐步了解如何使用 PiCam 实时识别人脸。

1.介绍

在我探索 OpenCV 的教程中,我们学习了自动视觉物体跟踪。现在,我们将使用 PiCam 实时识别人脸,如下图所示:

这个项目是用这个神奇的“开源计算机视觉库” OpenCV 完成的。在本教程中,我们将专注于 Raspberry Pi(所以,Raspbian 作为操作系统)和 Python,但我也在我的 Mac 上测试了代码,它也运行良好。

“要在 Mac 上运行它,需要对代码做一些修改。不要担心,我会对此进行评论”

OpenCV 是为计算效率而设计的,非常注重实时应用。因此,它非常适合使用摄像头进行实时人脸识别。

三个阶段

为了创建一个完整的人脸识别项目,我们必须在三个截然不同的阶段开展工作:

  • 人脸检测和数据收集
  • 训练识别器
  • 人脸识别

下面的框图恢复了这些阶段:

2.安装 OpenCV 3 包

我用的是 Raspberry Pi V3,更新到了 Raspbian (Stretch)的最新版本,所以安装 OpenCV 的最好方法是遵循 Adrian Rosebrock 开发的优秀教程: Raspbian Stretch:在你的 Raspberry Pi 上安装 OpenCV 3+Python

我尝试了几种不同的指南在我的 Pi 上安装 OpenCV。阿德里安的教程是最好的。我建议你也这样做,一步一步地遵循他的指导方针。

一旦您完成了 Adrian 的教程,您就应该有一个 OpenCV 虚拟环境,可以在您的 Pi 上运行我们的实验。

让我们进入虚拟环境,确认 OpenCV 3 安装正确。

Adrian 建议每次打开新终端时运行命令“source ”,以确保系统变量设置正确。

source ~/.profile

接下来,让我们进入虚拟环境:

workon cv

如果您在提示前看到文本(cv ),则您处于 cv 虚拟环境中:

(cv) pi@raspberry:~$

Adrian 提醒注意, cv Python 虚拟环境 完全独立于 Raspbian Stretch 下载中包含的默认 Python 版本。因此,全局站点包目录中的任何 Python 包对于 cv 虚拟环境都是不可用的。类似地,任何安装在 cv 的 site-packages 中的 Python 包对于 Python 的全局安装都是不可用的。

现在,在 Python 解释器中输入:

python

并确认您运行的是 3.5(或更高)版本。

在解释器内部(会出现" > > > "),导入 OpenCV 库:

import cv2

如果没有出现错误消息,则 OpenCV 已正确安装在您的 PYTHON 虚拟环境中。

您也可以检查安装的 OpenCV 版本:

cv2.__version__

3.3.0 应该会出现(或者将来可能发布的更高版本)。

上面的终端打印屏幕显示了前面的步骤。

3.测试您的相机

一旦你在 RPi 中安装了 OpenCV,让我们来测试一下你的相机是否工作正常。

我假设您已经在您的 Raspberry Pi 上安装并启用了 PiCam。

在您的 IDE 上输入以下 Python 代码:

import numpy as np
import cv2cap = cv2.VideoCapture(0)
cap.set(3,640) # set Width
cap.set(4,480) # set Heightwhile(True):
    ret, frame = cap.read()
    frame = cv2.flip(frame, -1) # Flip camera vertically
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame', frame)
    cv2.imshow('gray', gray)

    k = cv2.waitKey(30) & 0xff
    if k == 27: # press 'ESC' to quit
        breakcap.release()
cv2.destroyAllWindows()

上述代码将捕获您的 PiCam 生成的视频流,以 BGR 彩色和灰色模式显示这两种视频流。

注意,由于组装的方式,我垂直旋转了我的相机。如果不是你的情况,评论或删除“翻转”命令行。

你也可以从我的 GitHub 下载代码: simpleCamTest.py

要执行脚本,请输入命令:

python simpleCamTest.py

要完成该程序,您必须按键盘上的[ESC]键。在按[ESC]键之前,在视频窗口上单击鼠标。

上图是结果。

一些人在试图打开相机时发现问题,并得到“断言失败”的错误消息。如果在 OpenCv 安装过程中没有启用相机,相机驱动程序就不会正确安装,这种情况就会发生。要进行更正,请使用以下命令:

sudo modprobe bcm2835-v4l2

您还可以将 bcm2835-v4l2 添加到/etc/modules 文件的最后一行,以便在引导时加载驱动程序。

了解 OpenCV 的更多内容,可以关注教程:加载-视频-python-OpenCV-教程

4.人脸检测

人脸识别最基本的任务当然是“人脸检测”。在做任何事情之前,你必须“捕捉”一张脸(阶段 1),以便在与未来(阶段 3)捕捉的新脸进行比较时识别它。

最常见的检测人脸(或任何物体)的方法,是使用哈尔级联分类器

使用基于 Haar 特征的级联分类器的目标检测是由 Paul Viola 和 Michael Jones 在 2001 年的论文“使用简单特征的增强级联的快速目标检测”中提出的一种有效的目标检测方法。这是一种基于机器学习的方法,其中从大量正面和负面图像中训练级联函数。然后,它被用于检测其他图像中的对象。

这里我们将使用人脸检测。最初,该算法需要大量的正面图像(人脸图像)和负面图像(没有人脸的图像)来训练分类器。然后我们需要从中提取特征。好消息是 OpenCV 带有一个训练器和一个检测器。如果你想为任何物体训练你自己的分类器,比如汽车,飞机等等。您可以使用 OpenCV 创建一个。这里给出了它的全部细节:级联分类器训练

如果你不想创建自己的分类器,OpenCV 已经包含了许多预先训练好的人脸、眼睛、微笑等分类器。那些 XML 文件可以从 haarcascades 目录下载。

理论够了,我们用 OpenCV 造一个人脸检测器吧!

从我的 GitHub 下载文件: faceDetection.py

import numpy as np
import cv2faceCascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
cap.set(3,640) # set Width
cap.set(4,480) # set Heightwhile True:
    ret, img = cap.read()
    img = cv2.flip(img, -1)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(
        gray,     
        scaleFactor=1.2,
        minNeighbors=5,     
        minSize=(20, 20)
    )
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]  
    cv2.imshow('video',img)
    k = cv2.waitKey(30) & 0xff
    if k == 27: # press 'ESC' to quit
        breakcap.release()
cv2.destroyAllWindows()

信不信由你,上面的几行代码就是你检测一张脸所需要的全部,使用 Python 和 OpenCV。

当您与用于测试相机的最后一个代码进行比较时,您会发现添加到其中的部分很少。请注意下面一行:

faceCascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')

这是加载“分类器”的一行代码(必须位于项目目录下名为“Cascades/”的目录中)。

然后,我们将设置我们的摄像机,在循环中,以灰度模式加载我们的输入视频(和我们之前看到的一样)。

现在我们必须调用我们的分类器函数,给它传递一些非常重要的参数,如比例因子、邻居数量和检测到的人脸的最小尺寸。

faces = faceCascade.detectMultiScale(
        gray,     
        scaleFactor=1.2,
        minNeighbors=5,     
        minSize=(20, 20)
        )

在哪里,

  • 灰度是输入的灰度图像。
  • 比例因子是指定在每个图像比例下图像尺寸缩小多少的参数。它用于创建比例金字塔。
  • minNeighbors 是一个参数,指定每个候选矩形应该有多少个邻居来保留它。数字越大,误报率越低。
  • 最小尺寸是被视为面的最小矩形尺寸。

该功能将检测图像上的人脸。接下来,我们必须“标记”图像中的人脸,例如,使用蓝色矩形。这是通过这部分代码完成的:

for (x,y,w,h) in faces:
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]

如果找到了人脸,它会将检测到的人脸的位置返回为一个矩形,左上角为(x,y),宽度为“w ”,高度为“h ”= = >(x,y,w,h)。请看图片。

一旦我们得到这些位置,我们就可以为面部创建一个“ROI”(绘制的矩形),并用 imshow() 函数呈现结果。

使用 Rpi 终端,在您的 python 环境中运行上述 python 脚本:

python faceDetection.py

结果是:

您还可以包括用于“眼睛检测”甚至“微笑检测”的分类器。在这些情况下,您将在面部循环中包含分类器函数和矩形绘制,因为在面部之外检测眼睛或微笑是没有意义的。

请注意,在 Pi 上,几个分类器使用相同的代码会减慢处理速度,因为这种检测方法(HaarCascades)使用了大量的计算能力。在台式机上,运行它更容易。

例子

在我的 GitHub 上,您可以找到其他示例:

在图片中,你可以看到结果。

您也可以按照下面的教程来更好地理解人脸检测:

哈尔级联物体检测人脸& Eye OpenCV Python 教程

5.数据采集

首先,我必须感谢 Ramiz Raja 在照片人脸识别方面的出色工作:

使用 OPENCV 和 PYTHON 的人脸识别:初学者指南

还有阿尼班·卡尔,他用视频开发了一个非常全面的教程:

人脸识别— 3 个部分

我真的建议你看一看这两个教程。

说到这里,让我们开始我们项目的第一阶段。我们在这里要做的是,从最后一步(人脸检测)开始,我们将简单地创建一个数据集,其中我们将为每个 id 存储一组灰色照片,其中一部分用于人脸检测。

首先,创建一个开发项目的目录,例如 FacialRecognitionProject:

mkdir FacialRecognitionProject

在这个目录中,除了我们将为项目创建的 3 个 python 脚本之外,我们必须在上面保存面部分类器。可以从我的 GitHub 下载:Haar cascode _ frontal face _ default . XML

接下来,创建一个子目录,我们将在其中存储面部样本,并将其命名为“数据集”:

mkdir dataset

并从我的 GitHub 下载代码: 01_face_dataset.py

import cv2
import oscam = cv2.VideoCapture(0)
cam.set(3, 640) # set video width
cam.set(4, 480) # set video height
face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')# For each person, enter one numeric face id
face_id = input('\n enter user id end press <return> ==>  ')
print("\n [INFO] Initializing face capture. Look the camera and wait ...")# Initialize individual sampling face count
count = 0
while(True):
    ret, img = cam.read()
    img = cv2.flip(img, -1) # flip video image vertically
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)     
        count += 1
        # Save the captured image into the datasets folder
        cv2.imwrite("dataset/User." + str(face_id) + '.' +  
                    str(count) + ".jpg", gray[y:y+h,x:x+w])
        cv2.imshow('image', img)
    k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break
    elif count >= 30: # Take 30 face sample and stop video
         break# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()

该代码与我们看到的人脸检测代码非常相似。我们添加的是一个“输入命令”来捕获一个用户 id,它应该是一个整数(1,2,3 等)

face_id = input('\n enter user id end press  ==>  ')

对于每一个捕捉到的帧,我们应该将其保存为“数据集”目录中的一个文件:

cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])

请注意,要保存上述文件,您必须导入库“os”。每个文件的名称将遵循以下结构:

User.face_id.count.jpg

例如,对于 face_id = 1 的用户,数据集/目录上的第 4 个样本文件将类似于:

User.1.4.jpg

如我的 Pi 中的照片所示:

在我的代码中,我从每个 id 中捕获 30 个样本。最后一个“elif”可以改。样本数量用于打破捕捉面部样本的循环。

运行 Python 脚本并捕获一些 id。每次您想要聚合新用户(或更改已存在用户的照片)时,您都必须运行该脚本。

6.运动鞋

在第二阶段,我们必须从我们的数据集中获取所有用户数据,并“训练”OpenCV 识别器。这是由特定的 OpenCV 函数直接完成的。结果将是一个. yml 文件,该文件将保存在“trainer/”目录中。

因此,让我们开始创建一个子目录,用于存储训练数据:

mkdir trainer

从我的 GitHub 下载第二个 python 脚本: 02_face_training.py

import cv2
import numpy as np
from PIL import Image
import os# Path for face image database
path = 'dataset'
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");# function to get the images and label data
def getImagesAndLabels(path):
    imagePaths = [os.path.join(path,f) for f in os.listdir(path)]     
    faceSamples=[]
    ids = []
    for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L') # grayscale
        img_numpy = np.array(PIL_img,'uint8')
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)
        for (x,y,w,h) in faces:
            faceSamples.append(img_numpy[y:y+h,x:x+w])
            ids.append(id)
    return faceSamples,idsprint ("\n [INFO] Training faces. It will take a few seconds. Wait ...")faces,ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))# Save the model into trainer/trainer.yml
recognizer.write('trainer/trainer.yml') # Print the numer of faces trained and end program
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))

# recognizer.save() worked on Mac, but not on Pi

确认您的 Rpi 上是否安装了 PIL 库。如果没有,请在终端中运行以下命令:

pip install pillow

我们将使用 OpenCV 包中包含的 LBPH(局部二进制模式直方图)人脸识别器作为识别器。我们用下面的代码行来实现这一点:

recognizer = cv2.face.LBPHFaceRecognizer_create()

函数“getImagesAndLabels (path)”,将拍摄目录:“dataset/”上的所有照片,返回 2 个数组:“Ids”和“faces”。将这些数组作为输入,我们将“训练我们的识别器”:

recognizer.train(faces, ids)

因此,名为“trainer.yml”的文件将保存在我们之前创建的培训师目录中。

就是这样!我包括了最后一个打印声明,其中我显示了我们已经训练的用户面部的数量以供确认。

每次执行阶段 1 时,也必须运行阶段 2。

7.承认者

现在,我们到了项目的最后阶段。在这里,我们将在我们的相机上捕捉一张新面孔,如果这个人的脸之前被捕捉并训练过,我们的识别器将进行“预测”,返回其 id 和索引,显示识别器对这一匹配的信心程度。

下面从我的 GitHub 下载第三期 python 脚本: 03_face_recognition.py

import cv2
import numpy as np
import os recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
font = cv2.FONT_HERSHEY_SIMPLEX#iniciate id counter
id = 0# names related to ids: example ==> Marcelo: id=1,  etc
names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W'] # Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video widht
cam.set(4, 480) # set video height# Define min window size to be recognized as a face
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)while True:
    ret, img =cam.read()
    img = cv2.flip(img, -1) # Flip vertically
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale( 
        gray,
        scaleFactor = 1.2,
        minNeighbors = 5,
        minSize = (int(minW), int(minH)),
       )
    for(x,y,w,h) in faces:
        cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
        id, confidence = recognizer.predict(gray[y:y+h,x:x+w])
                # If confidence is less them 100 ==> "0" : perfect match 
        if (confidence < 100):
            id = names[id]
            confidence = "  {0}%".format(round(100 - confidence))
        else:
            id = "unknown"
            confidence = "  {0}%".format(round(100 - confidence))

        cv2.putText(
                    img, 
                    str(id), 
                    (x+5,y-5), 
                    font, 
                    1, 
                    (255,255,255), 
                    2
                   )
        cv2.putText(
                    img, 
                    str(confidence), 
                    (x+5,y+h-5), 
                    font, 
                    1, 
                    (255,255,0), 
                    1
                   )  

    cv2.imshow('camera',img) 
    k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
    if k == 27:
        break# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()

我们在这里包含了一个新的数组,所以我们将显示“名称”,而不是编号的 id:

names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W']

所以,举个例子:Marcelo 将 id = 1 的用户;宝拉:id=2,等等。

接下来,我们将检测一张脸,就像我们之前用哈斯卡德分类器所做的一样。检测到人脸后,我们可以调用上面代码中最重要的函数:

id, confidence = recognizer.predict(gray portion of the face)

recognizer.predict()将把要分析的面部的捕获部分作为参数,并将返回其可能的所有者,指示其 id 以及识别器与该匹配相关的置信度。

注意,如果被认为是完美匹配,信心指数将返回“零”

最后,如果识别器可以预测人脸,我们就在图像上放一段文字,说明可能的 id 以及匹配正确的“概率”是多少(百分比)(“概率”= 100 —置信度指数)。如果没有,就在脸上贴上“未知”的标签。

下面是结果的 gif:

在图片上,我展示了这个项目的一些测试,我也用照片来验证识别器是否工作。

8.结论

一如既往,我希望这个项目可以帮助其他人找到进入令人兴奋的电子世界的方法!

有关详细信息和最终代码,请访问我的 GitHub 仓库:

https://github.com/Mjrovai/OpenCV-Face-Recognition

更多项目,请访问我的博客:【MJRoBot.org

来自世界南部的 Saludos!

我的下一篇文章再见!

谢谢你,

马塞洛

使用深度学习的实时噪声抑制

原文:https://towardsdatascience.com/real-time-noise-suppression-using-deep-learning-38719819e051?source=collection_archive---------3-----------------------

基于最大似然的噪声抑制介绍

想象一下在机场等你的航班。突然,一个重要的商务电话点亮了你的手机。成吨的背景噪音扰乱了你周围的声景——背景噪音,飞机起飞,也许是航班通知。你必须接电话,你想听起来清楚。

我们都曾处于这种尴尬、不理想的境地。这只是现代商业的一部分。

背景噪音无处不在。而且很烦。

现在想象一下,当你接听电话并讲话时,噪音神奇地消失了,任何人在电话那头听到的都是你的声音。没有一丝噪音传进来。

这个愿景代表了我们在 2Hz 的激情。让我们听听好的降噪带来了什么。

两年前,我们坐下来决定开发一种技术,可以完全消除人与人交流中的背景噪音,使交流更加愉快和清晰。从那以后,这个问题就成了我们的困扰。

让我们看看是什么让噪声抑制变得如此困难,构建实时低延迟噪声抑制系统需要什么,以及深度学习如何帮助我们将质量提升到一个新的水平。

噪声抑制的现状

我们先明确一下什么是噪声抑制。乍一看,这似乎令人困惑。

本文中的噪声抑制指的是抑制从你的背景传到你与之通话的人的噪声,以及从他们的背景传到你的噪声,如图 1 所示。

Figure 1. Noise comes from both calling sides. Noise Suppression filters it out for both callers.

这与主动噪音消除(ANC) 形成对比,主动噪音消除是指抑制来自周围环境的有害噪音进入您的耳朵。主动噪声消除通常需要多麦克风耳机(如 Bose QuiteComfort),如图 2 所示。

这篇文章关注的是噪声抑制,不是主动噪声消除。

噪声抑制的传统方法

传统的噪声抑制已经在边缘设备——电话、笔记本电脑、会议系统等——上得到有效实施。这似乎是一种直观的方法,因为它是首先捕获用户语音的边缘设备。一旦被捕获,设备就过滤掉噪音,并将结果发送给电话的另一端。

10 年前的手机通话体验相当糟糕。一些移动电话仍然是这种情况;然而,越来越多的现代手机配备了多个麦克风(mic),有助于在通话时抑制环境噪音。

当代手机包括两个或更多麦克风,如图 2 所示,最新的 iPhones 有 4 个。第一个麦克风放置在通话时最靠近用户嘴巴的手机前底部,直接捕捉用户的声音。手机设计师将第二个话筒放在离第一个话筒尽可能远的地方,通常放在手机的背面上方。

Figure 2. Pixel 2016. The two mics are marked yellow

两个话筒都能捕捉周围的声音。离嘴越近的话筒捕捉到的声音能量越多;第二个捕捉到的声音更少。软件有效地将这些声音相减,产生(几乎)干净的声音。

这听起来很容易,但是这种技术在很多情况下都失败了。想象一下,当这个人不说话,所有的麦克风都是噪音。或者想象这个人在说话的时候主动摇晃/转动手机,就像在跑步一样。处理这些情况很棘手。

对于设备 OEM 和 ODM 而言,两个或更多麦克风还会使音频路径和声学设计变得非常困难和昂贵。音频/硬件/软件工程师不得不实施次优权衡,以支持工业设计和语音质量要求…

鉴于这些困难,今天的移动电话在适度嘈杂的环境中表现良好..现有的噪声抑制解决方案并不完美,但确实提供了改善的用户体验。

使用分离式麦克风时,外形会发挥作用,如图 3 所示。第一个和第二个话筒之间的距离必须满足最低要求。当用户把手机放在耳朵和嘴上说话时,它工作得很好。

Figure 3. Necessary form factor for noise cancellation when using multi-mic arrays

然而,现代手机的“直板”外形可能不会长期存在。可穿戴设备(智能手表、胸前麦克风)、笔记本电脑、平板电脑和智能语音助手(如 Alexa)颠覆了平板直板手机的外形。用户从不同的角度和不同的距离与他们的设备对话。在大多数情况下,没有可行的解决方案。噪声抑制完全失败。

从多麦克风设计转向单麦克风设计

多麦克风设计有几个重要缺点。

  • 它们需要特定的外形,因此仅适用于特定的使用情形,如带有粘性麦克风的电话或耳机(专为呼叫中心或入耳式监听系统设计)。
  • 多话筒设计使音频路径变得复杂,需要更多硬件和代码。此外,为次级话筒钻孔会造成工业 ID 质量和产量问题。
  • 只能在边缘或设备端处理音频。因此,由于低功率和计算要求,支持它的算法不可能非常复杂。

现在想象一个解决方案,您只需要一个麦克风,所有的后处理都由软件处理。这使得硬件设计更简单、更高效。

事实证明,在音频流中分离噪声和人类语音是一个具有挑战性的问题。这个函数没有高性能的算法。

传统的数字信号处理(DSP)算法试图通过逐帧处理音频来不断发现噪声模式并适应它。这些算法在某些用例中运行良好。然而,它们不能适应我们日常环境中存在的各种各样的噪音。

存在两种基本噪声类型:平稳非平稳,如图 4 所示。

Figure 4. Spectrogram of White Noise (stationary) and Chirp Noise (non-stationary)

把稳定的噪音想象成一种可重复但不同于人声的声音。当过滤这种噪声时,传统的 DSP 算法(自适应滤波器)可能相当有效。

非平稳噪声具有复杂的模式,很难与人的声音区分开来。信号可能很短,来去很快(例如键盘打字或警笛声)。参考这篇 Quora 文章获得更多技术上正确的定义。

如果你想击败平稳和非平稳噪声,你需要超越传统的 DSP。在 2Hz,我们相信深度学习可以成为处理这些困难应用的重要工具。

利用深度学习分离背景噪声

一篇关于将深度学习应用于噪声抑制的基础论文似乎已经由 Yong Xu 在 2015 年写了

Yong 提出了一种回归方法,该方法学习为每个音频产生一个比率掩模。这种产生的比率遮罩应该会完整地保留人声,并删除外来的杂讯。虽然远非完美,但这是一个很好的早期方法。

在随后的几年里,许多不同的方法被提出来;高层次的方法几乎总是相同的,包括三个步骤,如图 5 所示:

  1. 数据收集:通过混合干净语音和噪声,生成大数据集的合成噪声语音
  2. 训练:将这个数据集输入给 DNN,输出给干净的语音
  3. 推断:制作一个屏蔽(二元、比例或复合),它将保留人声并过滤掉噪声

Figure 5. Data Collection and Training Pipeline

在 2Hz 时,我们试验了不同的 DNN,并提出了我们独特的 DNN 架构,对各种噪声产生了显著的效果。平均 MOS 得分(平均意见得分)在嘈杂言论上上升 1.4 分,这是我们看到的最好结果。这一结果令人印象深刻,因为在单个麦克风上运行的传统 DSP 算法通常会降低 MOS 分数。

语音延迟。实时 DNN 可能吗?

低延迟在语音通信中至关重要。人类在交谈时可以忍受高达 200 毫秒的端到端延迟,否则我们在通话中会互相交谈。潜伏期越长,我们越注意到这一点,我们就变得越烦躁。

三个因素会影响端到端延迟:网络、计算和编解码器。通常网络延迟的影响最大。编解码器延迟范围在 5-80 毫秒之间,取决于编解码器及其模式,但现代编解码器已经变得非常高效。计算延迟实际上取决于许多因素。

计算延迟使 DNNs 面临挑战。如果您希望使用 DNN 处理每一帧,那么您将面临引入大量计算延迟的风险,这在现实部署中是不可接受的。

计算延迟取决于多种因素:

计算平台能力

在耳机中运行大型 DNN 不是你想做的事情。有 CPU 和电源的限制。实现实时处理速度是非常具有挑战性的,除非该平台有一个加速器,使矩阵乘法更快,功耗更低。

DNN 建筑

DNN 的速度取决于您有多少超参数和 DNN 层以及您的节点运行什么操作。如果你想以最小的噪声产生高质量的音频,你的 DNN 不能很小。

例如, Mozilla 的 rnnoise 速度非常快,或许可以放入耳机中。然而,它的质量在非平稳噪声上并不令人印象深刻。

音频采样率

DNN 的性能取决于音频采样率。采样率越高,需要为 DNN 提供的超参数就越多。

相比之下, Mozilla 的 rnnoise 使用分组频率的频段,因此性能对采样率的依赖最小。虽然这是一个有趣的想法,但它对最终质量有负面影响。

窄带音频信号(8kHz 采样速率)质量较低,但我们的大部分通信仍在窄带中进行。这是因为大多数移动运营商的网络基础设施仍然使用窄带编解码器来编码和解码音频。

由于窄带每频率需要的数据较少,因此它可以作为实时 DNN 的一个很好的起始目标。但是,当您需要添加对宽带或超宽带(16kHz 或 22kHz)以及全频带(44.1 或 48kHz)的支持时,事情就变得非常困难了。如今,许多基于 VoIP 的应用程序都在使用宽带编解码器,有时甚至是全频带编解码器(开源的 Opus 编解码器支持所有模式)。

在一个简单的设计中,您的 DNN 可能需要它增长 64 倍,因此支持全频带会慢 64 倍。

如何测试噪声抑制算法?

测试语音增强的质量具有挑战性,因为你不能相信人耳。由于年龄、训练或其他因素,不同的人有不同的听力。不幸的是,没有公开和一致的噪声抑制基准,所以比较结果是有问题的。

大多数学术论文都是用 PESQMOSSTOI 来比较结果。您向算法提供原始语音音频和失真音频,它会产生一个简单的度量分数。例如,PESQ 分数在-0.5 到 4.5 之间,其中 4.5 是完全干净的讲话。PESQ、MOS 和 STOI 并不是为评定噪音等级而设计的,所以你不能盲目信任它们。在你的过程中也必须有主观测试。

ETSI 房间

进行主观音频测试并使其可重复的更专业的方法是满足由不同标准团体创建的此类测试的标准。

3GPP 电信组织定义了 ETSI 室的概念。如果你打算将你的算法部署到现实世界中,你的设备中必须有这样的设置。ETSI 室是构建可重复的和可靠的测试的一个很好的机制;图 6 显示了一个例子。

Figure 6. Real ETSI room setup. Image from [Aqustica](http://Figure 8. Real ETSI room setup. Image from http://aqustika.com/en/casestudies/etsi-room).

这个房间隔音效果极佳。它通常还包含一个人造人体躯干、一个在躯干内部模拟声音的人造嘴(扬声器)以及一个在预定距离的支持麦克风的目标设备。

这使得测试人员能够使用周围的扬声器模拟不同的噪声,播放来自“躯干扬声器”的声音,并在目标设备上捕获结果音频,然后应用您的算法。所有这些都可以编写脚本来自动化测试。

出站噪声与入站噪声

噪点抑制真的有很多阴影

假设你正在和你的团队参加一个电话会议。包括您在内,通话中有四个参与者。现在混合中可能有四种潜在噪声。每个人都把自己的背景噪音发给别人。

传统上,噪声抑制发生在边缘设备上,这意味着噪声抑制与麦克风绑定在一起。你从麦克风接收信号,抑制噪声,然后将信号发送到上游。

由于单麦克风 DNN 方法只需要一个单一的来源流,你可以把它放在任何地方。现在,假设您想要抑制来自所有参与者的麦克风信号(出站噪声)和进入扬声器的信号(入站噪声)。

我们构建了我们的应用程序, Krisp ,明确地处理入站和出站噪声(图 7)。

Figure 7: Software noise suppression enables filtering both inbound and outbound noise

以下视频演示了如何使用 DNN 完全消除非平稳噪声。

对于入站噪声抑制,问题变得更加复杂。

您需要处理噪声抑制算法中不常见的声学和语音差异。例如,您的团队可能正在使用会议设备,并且坐在远离该设备的地方。这意味着到达设备的声音能量可能较低。或者他们可能在他们的汽车上用连接在仪表板上的 iPhone 给你打电话,这是一个固有的高噪声环境,由于距离扬声器较远,声音较低。在另一种情况下,可能会有多人同时发言,您希望保留所有的声音,而不是将其中的一些声音作为噪音抑制掉。

当您拨打 Skype 电话时,您会在扬声器中听到电话铃声。那个到底是不是噪音?或者等待音乐是不是噪音?我将把那个留给你。

向云迁移

到目前为止,您应该对噪声抑制的艺术状态以及围绕用于此目的的实时深度学习算法的挑战有了坚实的想法。您还了解了使问题更具挑战性的关键延迟要求。噪声抑制算法增加的总延迟不能超过 20 毫秒,这确实是一个上限。

既然算法是完全基于软件的,那么它能移到云中吗,如图 8 所示?

Figure 8. There are multiple benefits for doing noise suppression in the Cloud.

答案是肯定的。首先,基于云的噪声抑制适用于所有设备。其次,它可以在两条线路上执行(或者在电话会议中在多条线路上执行)。我们认为噪音抑制和其他语音增强技术可以转移到云上。这在过去是不可能的,因为需要多个麦克风。移动运营商已经制定了各种质量标准,设备原始设备制造商必须执行这些标准,以提供合适的质量水平,迄今为止的解决方案是多话筒。然而,深度学习使在支持单麦克风硬件的同时将噪声抑制放在云中的能力成为可能。

最大的挑战是算法的可扩展性。

使用 Nvidia GPUs 扩展 20 倍

如果我们希望这些算法能够扩展到足以服务真实的 VoIP 负载,我们需要了解它们的性能。

大型 VoIP 基础设施同时服务于 10K-100K 流。我们知道的一家 VoIP 服务提供商在一台裸机媒体服务器上提供 3000 个 G.711 呼叫流,这令人印象深刻。

有许多因素会影响像 FreeSWITCH 这样的媒体服务器可以同时提供多少音频流。一个明显的因素是服务器平台。与裸机优化部署相比,云部署的媒体服务器的性能明显较低,如图 9 所示。

Figure 9. Average stream concurrency of cloud-hosted vs bare metal media servers

服务器端噪声抑制必须经济高效,否则没有客户愿意部署它。

我们的第一个 2Hz 实验是从 CPU 开始的。一个 CPU 内核可以处理多达 10 个并行流。这不是一个非常划算的解决方案。

然后,我们在 GPU 上运行实验,结果令人惊讶。单个 Nvidia 1080ti 可以在没有任何优化的情况下扩展到 1000 个流(图 10)。在正确的优化之后,我们看到了扩展到 3000 个流;更多是可能的。

Figure 10. The DNN algorithm scales quite well on Nvidia 1080ti

包括处理流和编解码器解码在内的原始媒体服务器负载仍然发生在 CPU 上。使用 GPU 的另一个好处是能够简单地将外部 GPU 连接到您的媒体服务器机箱,并将噪声抑制处理完全卸载到其上,而不会影响标准音频处理管道。

使用 CUDA 进行配料

让我们来看看为什么 GPU 比 CPU 更好地扩展这类应用程序。

CPU 厂商传统上花费更多的时间和精力来优化和加速单线程架构。他们实现了算法、流程和技术来从单线程中获得尽可能高的速度。由于过去大多数应用程序只需要一个单线程,CPU 制造商有充分的理由开发最大化单线程应用程序的架构。

另一方面,GPU 供应商针对需要并行性的操作进行了优化。这源于 3D 图形处理的大规模并行需求。GPU 的设计使得它们的数千个小内核能够在高度并行的应用中很好地工作,包括矩阵乘法。

批处理是允许并行化 GPU 的概念。你把一批批的数据和操作发送给 GPU,它并行处理,然后发送回来。这是处理并发音频流的完美工具,如图 11 所示。

Figure 11. This simplified diagram shows how batching can be used to process multiple audio frames concurrently on GPU

我们已经使用 NVIDIA 的 CUDA 库直接在 NVIDIA GPUs 上运行我们的应用并执行批处理。

如果你想在你的 Mac 上尝试基于深度学习的噪音抑制——你可以用 Krisp 应用来完成。

下一步是什么?

音频是一个令人兴奋的领域,噪声抑制只是我们在这个领域看到的问题之一。深度学习将实现新的音频体验,在 2Hz,我们坚信深度学习将改善我们的日常音频体验。查看修复语音中断高清语音回放的博客帖子,了解此类体验。

声明:原本我已经以 客座博文 的身份在 NVIDIA 开发者博客上发表了这篇文章。

使用 Tensorflow 和 OpenCV 的实时对象检测 API

原文:https://towardsdatascience.com/real-time-object-detection-api-using-tensorflow-and-opencv-47b505d745c4?source=collection_archive---------2-----------------------

在过去几年中,当今世界的视觉数据量呈指数级增长,这主要是由于到处都有大量的传感器。构建能够在单个图像中定位和识别物体的机器学习模型仍然是计算机视觉中的核心挑战。致力于解决这个问题点燃了我对这个领域的兴趣。

作为我探索的一个途径,我发现 Google 刚刚发布了一个对象检测 API。该 API 已经在具有不同可训练检测模型的微软 COCO 数据集(90 个常见对象的大约 300,000 个图像的数据集)上进行训练。

different trainable detection models

地图越高(最小平均精度),模型越好

项目描述

我首先在 github 上克隆了 Tensorflow 对象检测库。该 API 是一个基于 tensorflow 的开源框架,可以轻松构建、训练和部署对象检测模型。

对于这个项目[am on windows 10,Anaconda 3,Python 3.6],我只关心安装部分,并遵循包括

  • 使用 pip(最新版本)安装最新版本的 tensorflow 时会附带安装所需的库,例如 pillow、lxml 等
  • 下载与我的系统兼容的最新版本的 protobuf 用于在 google protobuf 版本上编译
  • tensorflow/models 文件夹克隆为 zip 文件
  • 在我的 Anaconda 提示符下,运行这个命令进行 protobuf 编译,没有它这个例子就不能工作。
# From tensorflow/models/research/
protoc object_detection/protos/*.proto --python_out=.
  • 我更喜欢使用 Spyder 作为我的编辑器,所以我复制了示例中的笔记本,并将其转换为 python 文件

测试模型

使用预先训练好的 ssd_mobilenet_v1_coco 模型(虽然速度很快,但准确性最低),我决定在自己的图像上测试一下,结果令人惊讶!

Django girls event in my school

This was actually my dinner

Ongoing free python training organized by @lautechdatasci team

技巧:测试图片是用我的手机和数码相机拍摄的。调整它们的尺寸有助于模型的检测。

现在我想要实时检测,所以我用我的网络摄像头连接了 OpenCV。OpenCV 是一个用于图像处理、机器学习和实时检测的开源计算机视觉库。

这是结果:

请不要介意我的网络摄像头的质量😊,这是一个旧的。我希望我能安装升级程序

我的下一个任务

使用预先训练好的模型真的很酷,但是我喜欢在我自己的数据集上为超级应用程序训练 API。这可能不容易,但事实上,我已经准备好战斗了!!!

你可以在我的上获得完整的代码,这样你就可以直接运行文件并进行测试。如果你觉得我的帖子有趣😍,尽可能地按下鼓掌按钮。

在推特上关注我:@danielajisafe,@lautechdatasci

fromlautechtotheworld

YOUTUBE 参考

https://www.youtube.com/watch?v=MoMjIwGSFVQ
https://www.youtube.com/watch?v=COlbP62-B-U&list = plqvvaa 0 qudcnk 5 gecqnxynssaar 2 tpku
https://www.youtube.com/watch?v=Rgpfk6eYxJA

基于张量流检测模型的实时目标检测

原文:https://towardsdatascience.com/real-time-object-detection-with-tensorflow-detection-model-e7fd20421d5d?source=collection_archive---------3-----------------------

最近,我完成了 deeplearning.ai 通过 Coursera 提供的课程 4,“ 卷积神经网络作为“深度学习专业化”的一部分。吴恩达基安·卡坦弗什尤尼斯·本苏达·莫里在这一专业领域提供了大量的实践和理论知识。因此,我强烈推荐任何想获得深度学习经验的人。

自从我开始学习以来,我就对 CNN 的潜力充满了雄心和好奇,在那门课程的一周中,我学习了在图像分类中实现的思想如何对具有定位的图像分类有用,以及从定位中学到的思想如何对检测有用。嗯,在完成完全基于物体探测的第三周之后,一些事情困扰着我。

但是,在深入探讨困扰我的细节之前。我先简单解释一下什么是图像分类,我提到带定位的图像分类是什么意思。首先,让我们看看下面的图片,我知道这些狗太可爱了,所以我亲爱的读者,不要失去你的焦点:)。因此,我所说的图像分类是指每当一种算法看到这张图片[图 1]时,可能会做出反应并说这是一只狗,这意味着它能够将图像分类为一只狗的图像。

和[图 2],显示了该算法如何在图像中狗的位置周围放置一个边界框或绘制一个蓝色矩形。因此,这被称为定位分类,术语定位指的是计算出狗在照片中的哪个位置被检测到。

以及[图 3]示出了该算法如何检测和定位图像中的不止一个而是多个对象。

在这个简洁的解释之后,我应该把你的注意力集中到我反复提到的“事物”的问题上。我脑海中的问题是,是否存在比你只看一次(YOLO) 更准确的物体检测方法,以及比更快的 R-CNNs 更快的每秒帧数(FPS)。除此之外,我甚至开始寻找可以在没有高计算能力或没有利用 Nvidia GPU 能力的设备上运行的网络架构,如 Titan X 或 Jetson。

俗话说“为了发现任何东西,你必须寻找某些东西”。因此,我花了几个小时的时间进行研究,找到了“ TensorFlow 对象检测 API ”,这是一个基于 TensorFlow 构建的开源框架,可以轻松构建、训练和部署对象检测模型,并且它还提供了一系列在 COCO 数据集Kitti 数据集开放图像数据集上预先训练的检测模型。众多检测模型中的一种是单次检测器(SSD)MobileNets 架构的组合,其快速、高效且不需要巨大的计算能力来完成对象检测任务,其示例可在下图中看到。所以,简而言之,我的每一个问题都通过 SSDs 和 MobileNets 模型的结合得到了回答。

在向大家介绍了计算机视觉领域中经常使用的各种术语并自我回答了我的问题之后,现在我应该跳到实践部分,告诉大家如何通过使用 OpenCVTensorFlow 以及 ssd_mobilenet_v1 模型[SSD _ mobilenet _ v1 _ COCO】在 COCO[上下文中的常见对象]数据集上训练,我能够使用一个 7 美元的网络摄像头和一台笔记本电脑进行实时对象检测。

那么,不多说了,让我们开始吧

  1. 首先到达这个 链接 ,在目录下,设置部分,点击安装子部分。
  2. 基本上,安装部分由 TensorFlow 对象检测 API 所依赖的库列表组成。因此,在前进之前安装每一个依赖项。
  3. 在所有的库中,你需要再安装一个库,就是 Protobuf 2.6 。由于我用的是 Windows 10【你可以根据你用的操作系统下载 zip 文件】我下载并解压了这个文件protocol-3 . 5 . 1-win32 . zip
  4. 安装好所有要求后,就该下载模型了,你可以在这里 找到 。这完全取决于你是想克隆还是下载这个库。做好决定后,解压 文件 ,确保你的协议和模型文件在同一个文件夹里。
  5. 然后,我们需要将模型主文件夹的名称更改为模型,如果您在模型文件夹中查找研究文件夹,然后在研究文件夹中查找对象检测文件夹,在对象检测文件夹中查找 protos 文件夹。
  6. 一旦你打开它,你会发现没有像 box.predictor_pb2.py,faster_rcnn_box_coder_pb2.py 这样命名的文件,为了得到这些文件,我们需要编译 Protobuf 库。
  7. 因此,为了编译 Protobuf 库,打开 Anaconda 提示符,将目录更改为保存这两个文件夹的位置,然后执行[change directory]CD models/research,然后给出这个命令,该命令包含您的 protoc.exe 文件所在的完整路径,后跟[protoc object _ detection/protos/*。proto — python_out=。].
  8. 例如,[C:/Users/ADMIN/TF _ obj _ det/protoc-3 . 4 . 0-win32/bin/protoc object _ detection/protos/*。proto — python_out=。],这里 tf_obj_det 是我解压后保存模型和协议文件的文件夹。
  9. 现在,完成编译部分后,只需在 Anaconda 提示符/ Anaconda 终端上键入 jupyter notebook,然后一旦 jupyter notebook 打开,您就可以为实时对象检测编写代码了。
  10. 你可以使用我的资源库中的这个项目的代码,这个资源库在“参考资料”一节中提到,我还包括了 YouTube 视频的链接,它实际上演示了我的网络摄像头如何检测一帧中的每个对象,你可以在下图中体验。

最后一件事…
如果你喜欢这篇文章,请点击👏下面,并与他人分享,这样他们也可以享受它。

参考资料:

  1. 这个项目代码的 GitHub 库链接可以在这里找到。
  2. 为了了解更多关于物体探测的信息,你可以点击这里
  3. 为了了解更多关于卷积神经网络的知识,你可以点击这里
  4. 最后但同样重要的是,你可以在这里查看 YouTube 视频。

来自人工智能会议的应用机器学习的真实世界示例

原文:https://towardsdatascience.com/real-world-examples-of-applied-machine-learning-from-ai-conference-4d4678700c6?source=collection_archive---------15-----------------------

了解像优步和 ZocDoc 这样的公司如何使用机器学习来提高关键业务指标

Ramping up for the keynotes at Strata Data Conference in New York — photo credit to the official O’Reilly flickr site

围绕机器学习和人工智能的大多数讨论都集中在计算机化的 Dota 游戏或真实的 T2 语音合成上。虽然这些领域很有吸引力,对该领域具有现实价值,但对实用的机器学习和实现实际管道带来的挑战关注不够。

由于不灵活的框架、缺乏可重复性、协作问题和不成熟的软件工具的挑战,机器学习团队仍然在努力利用 ML。

在过去的一个月里,我有机会参加了奥莱利传媒AI 会议地层数据会议。有这么多的会议和伟大的公司出席,总是很难选择参加哪些会议。有许多不同的方法(这里有一个来自缪斯的很棒的指导手册,但是我个人倾向于围绕应用机器学习的会议,涵盖实际的实现。

这些实用的 ML 演示很有价值,因为:

  • 演示者通常来自构建实际管道和处理特定需求的团队
  • 内容诚实地讲述了失败的方法和团队经历的痛点,即使是在后来的迭代中
  • 业务指标(如支持票烧毁率、客户满意度等)和机器学习模型之间有着真正的联系

我在这两个会议上看到的最好的会议来自优步和 ZocDoc。在这篇文章中,我将解释这些会议的关键收获,以及您的团队如何将这些经验融入到您自己的机器学习工作流程中。

会话深度潜水

优步和 ZocDoc 以自己的方式具有颠覆性,但两家公司都在使用机器学习作为竞争优势和改善用户体验的方法。

优步:利用自然语言处理和深度学习改善客户支持

仅在 2017 年就有超过 40 亿次乘坐,可以想象优步的支持系统需要可扩展。

在优步的支持下,机器学习团队希望通过推荐三个最相关的解决方案来专注于提高客户支持代表(CSR)的效率,这三个解决方案本质上是一个名为“客户痴迷票务助理”或 COTA 的“人在回路”模型架构。

优步大学的机器学习团队决定创建并比较两种不同的模型管道来实现规模支持:(1) COTA v1,它将多类分类任务转换为排序问题;(2)COTA v2,它使用了一种称为编码器-组合器-解码器的深度学习方法。

在 AI 大会上,来自优步团队的 Piero Molino、Huaixiu Zheng 和 Yi-Jia Wang 做了一项令人难以置信的工作,逐步展示了他们的模型架构以及他们的两种不同方法对收入和票务处理时间的影响。

[## 利用自然语言处理和深度学习改善客户支持——人工…

优步已经实施了一个 ML 和 NLP 系统,该系统向其客户支持部门建议最可能的解决方案…

conferences.oreilly.com](https://conferences.oreilly.com/artificial-intelligence/ai-ca/public/schedule/detail/68612)

皮耶罗非常友好地在这里 分享了他们演示的幻灯片

你可以在皮耶罗的个人网站上看到更多他的作品:【http://w4nderlu.st/publications

Uber’s support UI with three suggested replies surfaced through the COTA models.

这两个模型都接收了机票、用户和旅行信息,为 CSR 建议机票分类和回复模板(答案)。

您可以在下图中看到这两种模型的架构。总而言之,COTA v1 随机森林模型将分类算法与逐点排序算法相结合,而 COTA v2 利用深度学习架构,可以通过优化几种不同类型的编码特征(文本、类别、数字和二进制)的损失来学习预测多个输出。该小组对每个模型进行了超参数搜索(用 COTA v1 进行网格搜索,用 COTA v2 进行平行随机搜索。

我强烈推荐阅读 他们的论文 以获得完整的细节和实现决策

From feature engineering to predictions, the Uber team maps out how they processed different inputs to populated suggested replies to the CSR team.

优步团队能够将他们的模型的影响与 A/B 测试(围绕 A/B 测试的良好资源 此处 )以及围绕他们的支持体验的客户调查进行比较。该团队最终发现,在他们的 A/B 测试中,COTA v2 比 COTA v1 准确 20–30%。COTA v2 还将处理时间减少了约 8%,而 COTA v2 减少了约 15%。虽然这两种方法都有助于提高客户满意度,但很明显,COTA v2 是冠军架构。

The Uber team set up an A/B test for both versions of COTA where COTA v2’s accuracy 20–30% higher than COTA v1’s (Slide 23 of 30)

优步的演讲展示了如何将机器学习整合到客户支持等流程中是一个迭代过程。他们必须测试不同的架构,还要围绕影响准确性的性能做出决策(考虑合理的错误)。

Zocdoc:逆向工程你的人工智能原型和可复制性之路

ZocDoc 是一种在线医疗保健预约服务,通过整合医疗实践和医生个人时间表的信息,为最终用户提供医疗保健搜索平台。

[## 逆向工程你的人工智能原型和可复制性之路——人工智能…

在更好的软件、云基础设施和预训练网络的帮助下,人工智能模型变得更容易构建…

conferences.oreilly.com](https://conferences.oreilly.com/artificial-intelligence/ai-ca/public/schedule/detail/68656)

ZocDoc 团队专注于用户旅程中非常特殊的部分:根据医疗保险范围寻找网络内医生。

对于 ZocDoc 的用户来说,找到一个网络内的医生可能意味着节省大量成本。通常情况下,如果您向网络内的医师或其他提供者就诊,您需要支付的费用将少于向网络外提供者就诊的费用(来源)。

ZocDoc 团队建立了一个保险卡检查器,允许患者扫描他们保险卡的照片,然后从卡中提取相关细节,以检查特定医生和特定程序是否被覆盖。

ZocDoc 的图像识别任务非常困难,因为:

  • 用户提交的图像通常具有较差的分辨率和变化的尺寸(由于缺乏格式约束),导致较差的训练数据质量
  • 保险卡包含大量其他类型的信息,有时可能会重复成员 ID
  • 该团队必须快速构建一个原型,然后将他们的流程转化为可重复的流水线

在人工智能大会上,ZocDoc 的 Brian Dalessandro(数据科学负责人)和克里斯·史密斯(高级首席软件工程师)通过他们模型架构的不同阶段概述了这些技术挑战(见下面的截图)。

会议中最有趣的部分是 Chris 描述团队出于可扩展性和可再现性的考虑,决定彻底拆除原型的基础设施。团队很难识别和跟踪关键的模型工件,例如使用的超参数、软件依赖性,以及迭代过程中的更多内容。

关于具体模型实现的更多细节,可以在这里 阅读 ZocDoc 关于这个项目 的原创博文

ZocDoc’s MemberID extraction model architecture involved a base classification network, an alignment network, and an optical character recognition (OCR) model.

ZocDoc 团队最终能够通过他们的三部分模型管道超越 82%的基线准确性(用户报告的统计数据)!然而,围绕数据和模型管理的体验,他们的旅程是一个不断迭代和挫折的旅程。

ZocDoc 的演示令人印象深刻,因为它表明即使是用户体验的小调整也可以为客户带来巨大的价值,但也需要数据科学家的大量投资——正如引用他们的博客文章所表达的那样:

“然而,我们很快就认识到,要达到适合生产级个人健康应用的质量,需要更多的独创性和反复试验,而不仅仅是简单地将开源组件串联起来。”

阿卡什·库沙尔

应对实际的 ML 挑战

来自优步和 ZocDoc 的这两个演示说明了机器学习在实践中如何不仅仅是使用最新的建模框架。想象一下,当 Chris 和 Brian 不得不重建他们的管道以准备生产,但意识到他们没有跟踪他们原型的度量、超参数或代码时,他们感到多么沮丧。

如今,有效的机器学习的最关键障碍之一是可重复性。重现性通过减少或消除重新运行过去的实验时的变化来实现稳健的模型。

Comet.ml ,我们允许数据科学团队自动跟踪他们的数据集、代码更改、实验历史和生产模型,从而提高效率、透明度和可重复性。

观看 Comet.ml 如何帮助成千上万的用户使他们的机器学习实验更加有效和可跟踪的快速视频:

对于纽约地区的人们,请在 10 月 4 日加入我们,了解 Precision Health AI 如何应用机器学习来检测癌症。

我们将邀请 PHAI 的客户服务总监、数据科学家和软件工程师来解释他们是如何构建丰富的 ML 管道的。 RSVP 此处

想看更多应用机器学习的惊人例子?

用数学重新排列 NHL

原文:https://towardsdatascience.com/realigning-the-nhl-with-math-or-why-edmonton-and-calgary-should-play-in-different-divisions-bc41cb493332?source=collection_archive---------14-----------------------

为什么埃德蒙顿和卡尔加里应该在不同的赛区比赛

This is the best possible NHL divisional alignment, according to the immutable laws of math. Read on!

12 月 4 日,星期二,准备好参加西雅图的大型派对吧,人们普遍预计这座城市将获得第 32 届 NHL 特许经营权。在 2008 年输给超音速队后,热情的球迷们终于可以享受冬季运动了,温哥华将获得一个区域性的竞争对手。

增加第 32 支队伍也需要 NHL 重新调整其部门。目前,NHL 在太平洋地区有 8 支球队,在中部有 7 支球队。西雅图几乎肯定会被放在太平洋赛区,导致西部联盟内部暂时不平衡。有很多关于哪支球队将被转移到补偿的互联网聊天,领先的候选人是亚利桑那郊狼队,因为缺乏传统的竞争,以及他们作为太平洋赛区中位于最东边的球队的位置。

但是,如果团队仅仅根据紧密度被分配到不同的部门,而不考虑传统的竞争,那会怎么样呢?这些部门会是什么样子?

幸运的是,这是一个可以解决的问题。通过计算每个 NHL 城市之间的距离,我们可以将 32 支球队分成 4 个分区,这样可以最小化分区内的总旅行距离。

假设和免责声明

1)我使用离每个 NHL 队的比赛场地最近的主要机场作为每个城市的起点/终点。这就产生了一些有趣的边缘案例——例如,两个纽约团队都将他们的起点/终点列为拉瓜迪亚机场,这使得他们在我们的模型中彼此之间的有效旅行距离为 0 英里。虽然这显然是不正确的,但模型的目的是做出有用的预测,而不是 100%精确。况且,两个在同一个城市打球的球队应该留在同一个赛区的建议,也不会让任何人震惊。

2)值得再次强调的是,这种模式并不重视将传统竞争对手团结在一起。该模型完全是通过最小化旅行距离来生成最紧凑的分区。我不打算说我的结果从商业角度来看有意义,但这些信息可以作为关于重组的更广泛对话中的数据点。

最优会议

首先,我们需要通过最小化会议间的距离,将我们的 32 个团队分成两个 16 人的会议。有趣的是,目前的团队联盟是最佳的。NHL 在这方面做得很好,最近几年将哥伦布、底特律和多伦多从西部转移到东部。

The current NHL conference setup is optimal…

东部联盟

…but there’s room for improvement in the Eastern Conference.

尽管东部联盟并没有因为西雅图的加入而改变其组成,但目前的联盟仍然值得研究。不出所料,还有很大的改进空间——我们的模型显示,总的部门内距离可以减少 15.8%。

东部 16 支球队中有 10 支通过我提议的重组变得更好了。让坦帕湾和佛罗里达与加拿大和新英格兰北部的球队在同一个分区比赛一直是一种好奇,更多的是出于一时的便利而不是常识,几乎所有这些球队都通过重新调整而明显改善。

Units are in miles.

我当然可以看到匹兹堡、多伦多和华盛顿的球迷在这里大喊犯规。匹兹堡将失去与费城的分区竞争,但这将是回到不久前的状态——就在 1998 年,匹兹堡和费城处于不同的分区。让水牛城和多伦多在不同的部门比赛可能会感觉不太直观,但是回想一下,这个练习的目标是最小化行程距离。虽然多伦多有一个势均力敌的对手可能对更好,但这对其他车队的伤害大于对多伦多的帮助。然而,如果我们把华盛顿换成布法罗,我们只会差 582 英里(1.29%),同时保留几个传统的对手。

西部联盟

Can I ever set foot in Edmonton again?

Units are in miles. Note that the “old distance” condition consists of the current divisional alignment with Phoenix in the Central, consistent with popular speculation.

这是一个非常接近的电话,但全国曲棍球联合会将通过交换埃德蒙顿到中央分区和保持菲尼克斯在太平洋上节省 530 英里的分区旅行距离。虽然这样的举动显然会使卡斯卡迪亚+阿尔伯塔团队旅行更长的距离,但这种变化对西南团队的好处大于对北方团队的伤害。最终,这些信息应该放在适当的背景下——当成本是打破阿尔伯塔省的战斗时,节省 0.6%的总旅行距离真的值得吗?我的猜测是没有。

结论

虽然注意力理所应当地集中在未来几周的西部联盟重组上,但 NHL 将会很好地以紧凑的重点重组东部联盟。这样做,NHL 可以大大减少旅行时间和碳足迹的产品。然后,他们可以将这些积分中的一部分用于类似无会议斯坦利杯季后赛的活动,这将是未来帖子的主题!

带着归属和感激

所有的地图都是用 Tableau 设计的;NHL 标志是在合理使用原则下使用的。我已经把我的距离矩阵和数据文件上传到 GitHub 它们在这里有售。

我要感谢华盛顿大学的陈石教授在我着手这个项目时给予我的建议和鼓励。我还要感谢伊恩·马丁内斯,他的指导和富有感染力的乐观精神是我灵感的源泉。

使用 Spark 结构化流、XGBoost 和 Scala 进行实时预测

原文:https://towardsdatascience.com/realtime-prediction-using-spark-structured-streaming-xgboost-and-scala-d4869a9a4c66?source=collection_archive---------4-----------------------

在本文中,我们将讨论如何构建一个完整的机器学习管道。第一部分将集中在以标准批处理模式训练二元分类器,第二部分我们将做一些实时预测。

我们将使用来自众多 Kaggle 竞赛之一的泰坦尼克号:从灾难中学习机器的数据。

在开始之前,请了解您应该熟悉 ScalaApache SparkXgboost

所有的源代码也可以在 Github 上找到。酷,现在让我们开始吧!

培养

我们将使用 Spark 中的 ML 管道训练一个 XGBoost 分类器。分类器将被保存为输出,并将在 Spark 结构化流实时应用程序中使用,以预测新的测试数据。

步骤 1:开始 spark 会话

我们正在创建一个 spark 应用程序,它将在本地运行,并将使用与使用local[*]的内核一样多的线程:

**val** spark  = SparkSession.*builder*()
  .appName("Spark XGBOOST Titanic Training")
  .master("local[*]")
  .getOrCreate()

步骤 2:定义模式

接下来,我们定义从 csv 读取的数据的模式。这通常是一个比让 spark 推断模式更好的实践,因为它消耗更少的资源,并且我们完全控制字段。

**val** schema = StructType(
  *Array*(*StructField*("PassengerId", DoubleType),
    *StructField*("Survival", DoubleType),
    *StructField*("Pclass", DoubleType),
    *StructField*("Name", StringType),
    *StructField*("Sex", StringType),
    *StructField*("Age", DoubleType),
    *StructField*("SibSp", DoubleType),
    *StructField*("Parch", DoubleType),
    *StructField*("Ticket", StringType),
    *StructField*("Fare", DoubleType),
    *StructField*("Cabin", StringType),
    *StructField*("Embarked", StringType)
  ))

步骤 3:读取数据

我们将 csv 读入一个DataFrame,确保我们提到我们有一个头。

**val** df_raw = spark
  .read
  .option("header", "true")
  .schema(schema)
  .csv(filePath)

步骤 4:删除空值

所有空值都被替换为 0。这并不理想,但对于本教程的目的来说,这是可以的。

**val** df = df_raw.na.fill(0)

第五步:将标称值转换为数值

在浏览这一步的代码之前,让我们简单地浏览一下 Spark ML 的一些概念。他们引入了 ML 管道的概念,这是一组建立在DataFrames之上的高级 API,可以更容易地将多个算法合并到一个进程中。管道的主要元素是TransformerEstimator。第一个可以表示一种算法,可以将一个DataFrame转换成另一个DataFrame,而后者是一种算法,可以适合一个DataFrame来产生一个Transformer

为了将名义值转换成数值,我们需要为每一列定义一个Transformer:

**val** sexIndexer = **new** StringIndexer()
  .setInputCol("Sex")
  .setOutputCol("SexIndex")
  .setHandleInvalid("keep")

**val** cabinIndexer = **new** StringIndexer()
  .setInputCol("Cabin")
  .setOutputCol("CabinIndex")
  .setHandleInvalid("keep")

**val** embarkedIndexer = **new** StringIndexer()
  .setInputCol("Embarked")
  .setOutputCol("EmbarkedIndex")
  .setHandleInvalid("keep")

我们使用StringIndexer来转换值。对于每个Transformer,我们将定义包含修改值的输入列和输出列。

步骤 6:将列组合成特征向量

我们将使用另一个Transformer将 XGBoost Estimator分类中使用的列组装成一个向量:

**val** vectorAssembler = **new** VectorAssembler()
  .setInputCols(*Array*("Pclass", "SexIndex", "Age", "SibSp", "Parch", "Fare", "CabinIndex", "EmbarkedIndex"))
  .setOutputCol("features")

步骤 7:添加 XGBoost 估计器

定义将生成模型的Estimator。估计器的设置可以在图中定义。我们还可以设置特征和标签列:

**val** xgbEstimator = **new** XGBoostEstimator(*Map*[String, Any]("num_rounds" -> 100))
  .setFeaturesCol("features")
  .setLabelCol("Survival")

步骤 8:构建管道和分类器

在我们创建了所有单独的步骤之后,我们可以定义实际的管道和操作顺序:

**val** pipeline = **new** Pipeline().setStages(*Array*(sexIndexer, cabinIndexer, embarkedIndexer, vectorAssembler, xgbEstimator))

输入DataFrame将被转换多次,最终将产生用我们的数据训练的模型。我们将保存输出,以便在第二个实时应用程序中使用。

**val** cvModel = pipeline.fit(df)
cvModel.write.overwrite.save(modelPath)

预言;预测;预告

我们将使用 Spark 结构化流从一个文件中传输数据。在现实世界的应用程序中,我们从 Apache Kafka 或 AWS Kinesis 等专用分布式队列中读取数据,但对于这个演示,我们将只使用一个简单的文件。

简要描述 Spark 结构化流是一个基于 Spark SQL 构建的流处理引擎。它使用了与DataFrames相同的概念,数据存储在一个无界的表中,该表随着数据的流入而增加新的行。

步骤 1:创建输入读取流

我们再次创建一个 spark 会话,并为数据定义一个模式。请注意,测试 csv 不包含标签Survival。最后我们可以创建输入流DataFrame, df。输入路径必须是我们存储 csv 文件的目录。它可以包含一个或多个具有相同模式的文件。

**val** spark: SparkSession = SparkSession.*builder*()
  .appName("Spark Structured Streaming XGBOOST")
  .master("local[*]")
  .getOrCreate()

**val** schema = StructType(
  *Array*(*StructField*("PassengerId", DoubleType),
    *StructField*("Pclass", DoubleType),
    *StructField*("Name", StringType),
    *StructField*("Sex", StringType),
    *StructField*("Age", DoubleType),
    *StructField*("SibSp", DoubleType),
    *StructField*("Parch", DoubleType),
    *StructField*("Ticket", StringType),
    *StructField*("Fare", DoubleType),
    *StructField*("Cabin", StringType),
    *StructField*("Embarked", StringType)
  ))

  **val** df = spark
    .readStream
    .option("header", "true")
    .schema(schema)
    .csv(fileDir)

第二步:加载 XGBoost 模型

在对象XGBoostModel中,我们加载预训练模型,该模型将应用于我们在流中读取的每一批新行。

**object** XGBoostModel {

  **private val** *modelPath* = "your_path"

  **private val** *model* = PipelineModel.*read*.load(*modelPath*)

  **def** transform(df: DataFrame) = {
    // replace nan values with 0
    **val** df_clean = df.na.fill(0)

    // run the model on new data
    **val** result = *model*.transform(df_clean)

    // display the results
    result.show()
  }

}

步骤 3:定义自定义 ML 接收器

为了能够将我们的分类器应用于新数据,我们需要创建一个新的接收器(流和输出之间的接口,在我们的例子中是 XGBoost 模型)。为此,我们需要一个自定义接收器(MLSink)、一个抽象接收器提供者(MLSinkProvider)和一个提供者实现(XGBoostMLSinkProvider)。

**abstract class** MLSinkProvider **extends** StreamSinkProvider {
  **def** process(df: DataFrame): Unit

  **def** createSink(
                  sqlContext: SQLContext,
                  parameters: Map[String, String],
                  partitionColumns: Seq[String],
                  outputMode: OutputMode): MLSink = {
    **new** MLSink(process)
  }
}

**case class** MLSink(process: DataFrame => Unit) **extends** Sink {
  **override def** addBatch(batchId: Long, data: DataFrame): Unit = {
    process(data)
  }
}**class** XGBoostMLSinkProvider **extends** MLSinkProvider {
  **override def** process(df: DataFrame) {
    XGBoostModel.*transform*(df)
  }
}

步骤 4:将数据写入我们的自定义接收器

最后一步是定义一个将数据写入自定义接收器的查询。还必须定义一个检查点位置,以便应用程序在失败时“记住”流中读取的最新行。如果我们运行该程序,每一批新的数据将显示在控制台上,其中也包含预测的标签。

df.writeStream
  .format("titanic.XGBoostMLSinkProvider")
  .queryName("XGBoostQuery")
  .option("checkpointLocation", checkpoint_location)
  .start()

接收器工作特性曲线解密(Python 语言)

原文:https://towardsdatascience.com/receiver-operating-characteristic-curves-demystified-in-python-bd531a4364d0?source=collection_archive---------1-----------------------

在数据科学中,评估模型性能非常重要,最常用的性能指标是分类得分。然而,在处理具有严重类别不平衡的欺诈数据集时,一个分类分数没有太大意义。相反,接收机工作特性或 ROC 曲线提供了一个更好的选择。ROC 是信号(真阳性率)对噪声(假阳性率)的图。通过查看 ROC 曲线下的面积(或 AUC)来确定模型性能。最好的 AUC 可能是 1,而最差的是 0.5(45 度随机线)。任何小于 0.5 的值都意味着我们可以简单地做与模型建议完全相反的事情,以使值回到 0.5 以上。

虽然 ROC 曲线很常见,但并没有太多的教学资源解释它是如何计算或得出的。在这篇博客中,我将逐步展示如何使用 Python 绘制 ROC 曲线。之后,我将解释基本 ROC 曲线的特征。

类别的概率分布

首先,让我们假设我们的假设模型为预测每个记录的类别产生了一些概率。与大多数二元欺诈模型一样,让我们假设我们的类别是“好”和“坏”,并且该模型产生 P(X=“坏”)的概率。为了创建这个概率分布,我们绘制了一个高斯分布图,每个类别有不同的平均值。想了解更多关于高斯分布的信息,请阅读这篇博客。

import numpy as np
import matplotlib.pyplot as pltdef pdf(x, std, mean):
    cons = 1.0 / np.sqrt(2*np.pi*(std**2))
    pdf_normal_dist = const*np.exp(-((x-mean)**2)/(2.0*(std**2)))
    return pdf_normal_distx = np.linspace(0, 1, num=100)
good_pdf = pdf(x,0.1,0.4)
bad_pdf = pdf(x,0.1,0.6)

现在我们有了分布,让我们创建一个函数来绘制分布。

def plot_pdf(good_pdf, bad_pdf, ax):
    ax.fill(x, good_pdf, "g", alpha=0.5)
    ax.fill(x, bad_pdf,"r", alpha=0.5)
    ax.set_xlim([0,1])
    ax.set_ylim([0,5])
    ax.set_title("Probability Distribution", fontsize=14)
    ax.set_ylabel('Counts', fontsize=12)
    ax.set_xlabel('P(X="bad")', fontsize=12)
    ax.legend(["good","bad"])

现在让我们使用这个 plot_pdf 函数来生成绘图:

fig, ax = plt.subplots(1,1, figsize=(10,5))
plot_pdf(good_pdf, bad_pdf, ax)

现在我们有了二元类的概率分布,我们可以用这个分布来推导 ROC 曲线。

推导 ROC 曲线

为了从概率分布得出 ROC 曲线,我们需要计算真阳性率(TPR)和假阳性率(FPR)。举个简单的例子,假设阈值在 P(X='bad')=0.6。

真阳性是阈值右侧指定为“坏”的区域。假阳性表示阈值右侧指定为“好”的区域。总正值是“差”曲线下的总面积,而总负值是“好”曲线下的总面积。我们将图中所示的值相除,得出 TPR 和 FPR。我们推导出不同阈值下的 TPR 和 FPR,得到 ROC 曲线。利用这些知识,我们创建了 ROC 绘图函数:

def plot_roc(good_pdf, bad_pdf, ax):
    #Total
    total_bad = np.sum(bad_pdf)
    total_good = np.sum(good_pdf)
    #Cumulative sum
    cum_TP = 0
    cum_FP = 0
    #TPR and FPR list initialization
    TPR_list=[]
    FPR_list=[]
    #Iteratre through all values of x
    for i in range(len(x)):
        #We are only interested in non-zero values of bad
        if bad_pdf[i]>0:
            cum_TP+=bad_pdf[len(x)-1-i]
            cum_FP+=good_pdf[len(x)-1-i]
        FPR=cum_FP/total_good
        TPR=cum_TP/total_bad
        TPR_list.append(TPR)
        FPR_list.append(FPR)
    #Calculating AUC, taking the 100 timesteps into account
    auc=np.sum(TPR_list)/100
    #Plotting final ROC curve
    ax.plot(FPR_list, TPR_list)
    ax.plot(x,x, "--")
    ax.set_xlim([0,1])
    ax.set_ylim([0,1])
    ax.set_title("ROC Curve", fontsize=14)
    ax.set_ylabel('TPR', fontsize=12)
    ax.set_xlabel('FPR', fontsize=12)
    ax.grid()
    ax.legend(["AUC=%.3f"%auc])

现在让我们使用这个 plot_roc 函数来生成绘图:

fig, ax = plt.subplots(1,1, figsize=(10,5))
plot_roc(good_pdf, bad_pdf, ax)

现在绘制概率分布图和 ROC 图,以便直观比较:

fig, ax = plt.subplots(1,2, figsize=(10,5))
plot_pdf(good_pdf, bad_pdf, ax[0])
plot_roc(good_pdf, bad_pdf, ax[1])
plt.tight_layout()

阶级分离的影响

既然我们可以得到两个图,让我们看看 ROC 曲线如何随着类别分离(即模型性能)的改善而变化。我们通过改变概率分布中高斯分布的平均值来做到这一点。

x = np.linspace(0, 1, num=100)
fig, ax = plt.subplots(3,2, figsize=(10,12))
means_tuples = [(0.5,0.5),(0.4,0.6),(0.3,0.7)]
i=0
for good_mean, bad_mean in means_tuples:
    good_pdf = pdf(x, 0.1, good_mean)
    bad_pdf  = pdf(x, 0.1, bad_mean)
    plot_pdf(good_pdf, bad_pdf, ax[i,0])
    plot_roc(good_pdf, bad_pdf, ax[i,1])
    i+=1
plt.tight_layout()

如您所见,AUC 随着我们增加类别之间的间隔而增加。

放眼 AUC 之外

除了 AUC,ROC 曲线也可以帮助调试模型。通过观察 ROC 曲线的形状,我们可以评估模型的错误分类。例如,如果曲线的左下角更接近随机线,则暗示模型在 X=0 处分类错误。然而,如果右上角是随机的,则意味着误差发生在 X=1 处。此外,如果曲线上有尖峰(而不是平滑的),这意味着模型不稳定。

附加说明

[## 数据科学面试指南

数据科学是一个相当大且多样化的领域。因此,做一个万事通真的很难…

towardsdatascience.com](/data-science-interview-guide-4ee9f5dc778) [## 极端类别不平衡下的欺诈检测

数据科学中的一个热门领域是欺诈分析。这可能包括信用卡/借记卡欺诈、反洗钱…

towardsdatascience.com](/fraud-detection-under-extreme-class-imbalance-c241854e60c)

更好地理解深度学习的最新进展

原文:https://towardsdatascience.com/recent-advances-for-a-better-understanding-of-deep-learning-part-i-5ce34d1cc914?source=collection_archive---------3-----------------------

我希望生活在一个系统建立在严谨、可靠、可验证的知识之上,而不是炼金术之上的世界。[……]简单的实验和简单的定理是帮助理解复杂的更大现象的积木

这种呼吁更好地理解深度学习的是阿里·拉希米在 2017 年 12 月 NIPS 举行的时间考验奖颁奖典礼的核心。通过比较深度学习和炼金术,阿里的目标不是解散整个领域,而是“开启对话”。这个目标肯定已经实现而人们还在争论我们目前的深度学习实践应该被认为是炼金术、工程学还是科学。

七个月后,机器学习社区再次聚集,这一次是在斯德哥尔摩举行的机器学习国际会议(ICML)。有超过 5000 名参与者和 629 篇论文发表,这是关于基础机器学习研究的最重要事件之一。而深度学习理论成为了大会最大的议题之一。

这种重新燃起的兴趣在第一天就显露出来了,大会最大的房间之一挤满了机器学习从业者,他们准备听 Sanjeev Arora 关于深度学习理论理解的教程。在他的演讲中,普林斯顿大学计算机科学教授总结了深度学习理论研究的当前领域,将它们分为四个分支:

  • 非凸优化:如何理解与深度神经网络相关的高度非凸损失函数?为什么随机梯度下降甚至会收敛?
  • 过度参数化和泛化:在经典统计理论中,泛化依赖于参数的个数而不是深度学习。为什么?我们能找到另一个好的概括方法吗?
  • 深度的作用:深度是如何帮助神经网络收敛的?深度和概括有什么联系?
  • 生成模型:为什么生成对抗网络(GANs)如此有效?我们可以用什么理论性质来稳定它们或避免模式崩溃?

在这一系列的文章中,我们将基于最近的论文尝试在这四个领域建立直觉,特别关注 ICML 2018。

这第一篇文章将关注深度网络的非凸优化的奥秘。

非凸优化

我敢打赌,你们中的很多人都尝试过从头开始训练自己的深层网络,并且因为无法让它发挥作用而对自己感觉很糟糕。我不认为这是你的错。我觉得是梯度下降的错。

阿里·拉希米在 NIPS 的演讲中以挑衅的口吻说道。随机梯度下降(SGD)确实是深度学习的基石。它应该找到一个高度非凸优化问题的解决方案,并且理解它何时工作以及为什么工作,是我们在深度学习的一般理论中必须解决的最基本的问题之一。更具体地,对深度神经网络的非凸优化的研究可以分为两个问题:

  • 损失函数是什么样的?
  • SGD 为什么会收敛?

损失函数是什么样的?

如果我让你想象一个全局最小值,你脑海中浮现的第一个图像很可能是这样的:

这很正常。在 2D 世界中,找到这样的问题并不罕见,在全局最小值附近,你的函数将是严格凸的(这意味着海森矩阵在这一点上的两个特征值将都是严格正的)。但在一个有数十亿参数的世界里,就像深度学习中的情况一样,围绕全局最小值的方向没有一个是平坦的可能性有多大?或者等价地,hessian 不包含单个零(或几乎零)特征值?

Sanjeev Arora 在他的教程中的第一个评论是,损失函数的可能方向的数量随着维度呈指数增长。

那么,直觉上,似乎一个全局最小值将不会是一个点,而是一个连通的流形。这意味着,如果你已经达到了一个全局最小值,你应该能够在一条平坦的路径上行走,在这条路径上所有的点也是最小值。海德堡大学的一个团队已经在大型网络上通过实验证明了这一点,在他们的论文中,神经网络能源领域基本上没有障碍【1】。他们提出了一个更普遍的说法,即任何两个全局最小值都可以通过一条平坦的路径连接起来。

已经知道 MNIST 的 CNN 或 PTB 的 RNN 就是这种情况[2],但这项工作将这种知识扩展到更大的网络(一些 DenseNets 和 ResNets ),这些网络在更高级的数据集(CIFAR10 和 CIFAR100)上进行训练。为了找到这条路径,他们使用了一种来自分子统计力学的启发式方法,称为 AutoNEB。这个想法是在你的两个极小值之间创建一个初始路径(例如线性),并在该路径上放置枢轴。然后反复修改枢轴的位置,使每个枢轴的损失最小化,并确保枢轴之间的距离保持不变(通过用弹簧模拟枢轴之间的空间)。

如果他们没有从理论上证明这一结果,他们会对为什么存在这样的路径给出一些直观的解释:

如果我们扰动一个单一的参数,比如说增加一个小常数,但让其他参数自由适应这种变化,以尽可能减少损失,有人可能会说,通过某种程度的调整,无数的其他参数可以“弥补”施加在其中一个参数上的变化

因此,本文的结果可以帮助我们通过超参数化和高维空间的透镜以不同的方式看到最小值。

更一般地,当考虑神经网络的损失函数时,你应该始终记住在给定点可能的方向的数量是巨大的。另一个结果是鞍点必须比局部最小值丰富得多:在一个给定的(临界)点,在数十亿个可能的方向中,很可能找到一个向下的方向(如果你不在全局最小值中)。这种直觉在 NIPS 2014 年发表的一篇论文中得到严格的形式化和经验证明:识别和攻击高维非凸优化中的鞍点问题 [6]

为什么 SGD 会收敛(或者不收敛)?

深度神经网络优化中的第二个重要问题与 SGD 的收敛特性有关。虽然这种算法长期以来被视为梯度下降的更快但近似的版本,但我们现在有证据表明 SGD 实际上收敛到更好、更一般的最小值[3]。但是我们能形式化它并定量解释 SGD 逃离局部极小值或鞍点的能力吗?

SGD 修改了损失函数

论文另一种观点:新币何时逃脱局部最小值?【4】表明执行 SGD 相当于对卷积(从而平滑)损失函数进行常规梯度下降。从这个角度出发,在一定的假设下(作者证明这在实践中经常是正确的),他们证明了 SGD 将设法摆脱局部极小值,并收敛到全局极小值周围的一个小区域。

SGD 受随机微分方程支配

另一种真正改变了我对这种算法的看法的 SGD 方法是连续 SGD 。这个想法是由 Yoshua Bengio 在他的关于随机梯度下降、平坦性和一般化的演讲中提出的,在 ICML 非凸优化研讨会上发表。SGD 没有移动损失函数上的一个点,而是一个点云,或者换句话说,一个分布

Slide extracted from the presentation On stochastic gradient descent, flatness and generalization, by Y. Bengio, at ICML 2018. He presented an alternative way to see SGD, where you replace points by distributions (clouds of points)

这个点云的大小(即相关分布的方差)与因子 learning_rate / batch_size 成比例。Pratik Chaudhari 和 Stefano Soatto 在《机器学习中的几何》研讨会上发表的论文“随机梯度下降执行变分推理,收敛到深度网络的极限环”【5】中给出了一个证明。这个公式非常直观:低批量意味着非常嘈杂的梯度(因为是在数据集的非常小的子集上计算的),高学习率意味着嘈杂的步骤。

将 SGD 视为随时间移动的分布的结果是,控制下降的方程现在是随机偏微分方程。更确切地说,在某些假设下,[5]表明这个支配方程实际上是一个 福克-普朗克方程

Slide extracted from the presentation High-dimensional Geometry and Dynamics of Stochastic Gradient Descent for Deep Networks, by P. Chaudhari and S. Soatto, at ICML 2018. They showed how to pass from a discrete system to a continuous one described by the Fokker-Plank equation

在统计物理学中,这种类型的方程描述了受到阻力(使分布漂移,即移动其平均值)和随机力(使分布扩散,即增加其方差)作用的粒子的演化。在 SGD 中,阻力由真实梯度模拟,而随机力对应于算法固有的噪声。正如你在上面的幻灯片中所看到的,扩散项与温度项成正比T = 1/β= learning _ rate/(2 * batch _ size),这再次表明了这个比值的重要性!

Evolution of a distribution under the Fokker-Planck equation. It drifts on the left and diffuses with time. Source: Wikipedia

使用这个框架,Chaudhari 和 Soatto 证明了我们的分布将单调收敛到某个稳定分布(在 KL-divergence 的意义上):

One of the main theorems of [5], proving monotonic convergence of the distribution to a steady state (in the sense of the KL divergence). The second equation shows that minimizing F is equivalent to minimizing a certain potential ϕ as well as maximizing the entropy of the distribution (trade-off controlled by the temperature 1/β)

上面的定理中有几个有趣的地方需要评论:

  • 被 SGD 最小化的泛函可以重写为两项之和(等式)。11):一个势φ的期望,和分布的熵。温度 1/β 控制着这两项之间的权衡。
  • 潜在的φ仅取决于数据和网络的架构(而不是优化过程)。如果它等于损失函数,SGD 将收敛到一个全局最小值。然而,论文表明这种情况很少发生,知道φ离损失函数有多远就会告诉你你的 SGD 收敛的可能性有多大。
  • 最终分布的熵取决于比率学习速率/批量大小(温度)。直观地说,熵与分布的大小有关,高温通常会导致分布具有高方差,这通常意味着平坦的最小值。由于平坦的最小值通常被认为是更好的概括,这与经验发现一致,即高学习和低批量通常导致更好的最小值。

因此,将 SGD 视为随时间移动的分布向我们展示了 learning_rate/batch_size 在收敛性和泛化能力方面比每个分离的超参数更有意义。此外,它能够引入与融合相关的网络潜力,这可以为架构搜索提供良好的度量。

结论

寻找深度学习理论的过程可以分为两个部分:首先,通过玩具模型和实验,建立关于它如何以及为什么工作的直觉,然后将这些直觉表达成数学形式,这可以帮助我们解释我们当前的结果并做出新的结果。

在这第一篇文章中,我们试图传达神经网络的高维损失函数和 SGD 的解释的更多直觉,同时表明新类型的形式主义正在以具有深度神经网络优化的真正数学理论为目标而建立。

然而,尽管非凸优化是深度学习的基石,但它的成功主要来自于它在大量层和参数的情况下仍能很好地概括。这将是下一部分的目标。

参考

[1]费利克斯·德拉克斯勒、坎比斯·韦施吉尼、曼弗雷德·萨尔姆霍弗、弗雷德·汉普雷希特。神经网络能源格局基本无障碍ICML 2018。

[2]丹尼尔·弗里曼,琼·布鲁纳。半整流网络优化的拓扑与几何,a rXiv:1611.01540 ,2016。

[3]尼蒂什·什里什·凯什卡尔、迪伊瓦萨·穆迪格雷、豪尔赫·诺切达尔、米哈伊尔·斯梅兰斯基、平·塔克·唐露晓。关于深度学习的大批量训练:泛化差距与尖锐极小ICLR 2017

[4]罗伯特·克莱恩伯格,李沅芷,杨远。另一种观点:新币何时逃脱局部最小值?ICML 2018

[5]斯特凡诺·索阿托·普拉蒂克·乔德里。随机梯度下降执行变分推理,收敛到深度网络的极限环, ICLR 2018

[6]扬·多芬、拉兹万·帕斯卡努、卡格拉尔·古尔切雷、赵京贤、苏亚甘古利、约舒阿·本吉奥。识别并攻克高维非凸优化中的鞍点问题NIPS 2014

用 Scala 识别手写数字

原文:https://towardsdatascience.com/recognising-handwritten-digits-with-scala-9829d035f7bc?source=collection_archive---------5-----------------------

doddle-model: immutable machine learning in Scala.

在过去的几个月里,我开始大量编写 Scala 代码,对于从 Python 移植过来的人来说,我不得不承认,在静态类型的环境中操作比我以前愿意承认的要安全得多。

我的 Python 之旅的主要原因是它的机器学习生态系统,当我开始研究 Scala 中 ML 的状态时,我意识到这两种语言在可用库方面存在巨大差距。特别是,我在寻找一个 Scala 来替代 Python 中的 scikit-learn,公平地说,当我发现没有 Scala 时,我感到很沮丧。当我想起我可以开始自己建造它时,我的失望很快变成了渴望,我也确实这样做了。

这篇文章有两个目的:我想传播关于的消息,并向非 ML 受众展示如何以一种高度直观而非技术性的方式解决识别手写数字的问题。

介绍

这个库叫做 doddle-model ,这个名字是为了强调它的易用性。

doddle 英式,非正式:非常简单的任务,例如“这台打印机很容易安装和使用。”

它本质上是一个内存中的机器学习库,可以总结为三个主要特征:

  • 它建立在 Breeze 之上
  • 它提供了不可变对象,这些对象在并行代码中使用很容易
  • 它通过一个类似 scikit-learn 的 API 公开其功能

还应该指出的是,该项目正处于早期发展阶段,任何形式的贡献都非常感谢。

问题定义

假设你的奶奶让你帮她将一本旧的手写电话簿数字化,将联系人保存在手机上。不幸的是,这个列表很长,作为一个精明的工程师,你很快意识到像这样重要的任务必须自动化。你还记得听说过一个流行的带标签的手写数字数据库,其中包含 70,000 张图片及其相应的标签,你也许可以用它来帮助你的祖母。你可以看看图 2** 中的一些例子。**

Image 1: Automate all the things!

我们将假设我们已经找到了一种方法来扫描电话簿,并将每个电话号码转换为一组 28x28 灰度图像,其中每个图像代表一个数字。此外,我们将忽略一个事实,即我们不知道如何数字化手写信件,因此将只关注数字本身。

给定当前场景,我们感兴趣的是设计一个函数,它将 0 到 255 之间的 784 个整数的向量作为输入,并在输出端产生一个 0 到 9(我们的数字)之间的整数。请记住,灰度图像只包含强度信息,因此 28×28 像素中的每个像素都是一个整数(我们只需将 28×28 矩阵展平为一个向量,以获得 784 个值)。

Image 2: The digits we scanned from the telephone book (source: https://en.wikipedia.org/wiki/MNIST_database#/media/File:MnistExamples.png).

第一种方法

我们将用 x 表示输入像素向量,用 y 表示输出标量。那么我们要寻找的函数就是f(x)= y。为了方便起见,我们将输出建模为一个分类变量,这无非是说它的值属于一组无序类别中的任何一个,即在我们的例子中是{0,1,2,3,4,5,6,7,8,9}中的一个。如果你看一下分类分布,你可以看到它是由一个概率向量来参数化的,其中每个元素代表第 k 个分类的概率,并且它们的总和为 1,因为不存在其他分类。我们可以将这一点结合到我们的函数中,通过说 f 的输出不是单个标量 y ,而是具有 10 个元素的向量 yProb ,其中每个元素代表每个可能数字的概率。我们的函数于是变成了f(x)=yProb

在这个阶段,我们知道 f 的输入是什么(一个展平的图像向量 x )并且我们知道输出应该是什么样子(一个有 10 个元素的概率向量 yProb )。现在我们必须弄清楚如何定义函数本身。我们将首先考虑如何为单个类别获得一些任意的实值分数,然后使用这一知识为所有类别获得 10 个实值分数,最后确保这些分数在范围[0,1]内,并且它们的总和确实为 1,因为它们必须表示概率。

我们的功能定义

从向量 x 获得实值标量的一种可能方法是简单地计算 x 中的值的线性组合。让我们看看如何把它写下来。记住 x 由 784 个整数组成,即 pixel_1pixel_2 ,…, pixel_783pixel_784 ,所以要计算这些的线性组合,我们需要 785 个权重 w_i 来获得 z = w_0 如果我们在 x 的开头插入一个值为 1 的元素,我们可以把这个记为 xw点积(所有权重 w_i 放在一个向量中),得到 z = x

这很容易,但是目前,我们只有一个分数 z,实际上我们在输出端需要一个向量 10。嗯,我们可以做的最简单的事情是计算 10 次分数,而不是一次,每次用不同的向量 w 。我们可以这样写下来:z _ 0=xw _ 0z _ 1=xw _ 1z_10 = x 同样,如果我们将一个矩阵中的向量w _ Iw(每个 w_iW 中变成一列),我们可以将此记为向量矩阵乘法z=****

让我们看一下我们的函数 f 目前的样子,来回顾一下我们到目前为止所做的事情。并且不要担心不知道什么值 W 持有,我们马上就能到达那里。在图像 3 的最左侧是我们的展平图像向量 x ,带有前置 1,它乘以矩阵 W 以获得向量 z ,该向量代表 10 个可能类别(数字)中每一个的实值分数。请注意,我们对每个类别都有一组权重(每个列在 W 中),总共有 10785 个权重。*

Image 3: Our current function that produces 10 real-valued scalars from a flattened image vector.

我们的函数定义中只缺少一个需求。我们在本节的开头指定了 z 的元素必须在范围[0,1]内,并且总和必须为 1,才能被解释为概率。事实证明, softmax 函数正是我们所寻找的。这很简单,我们不会在这里进行过多的描述,我们要知道的是,它取我们的 z 并返回 yProb ,可能看起来像这样yProb=[0.024,0.064,0.175,0.475,0.024,0.064,0.175]。如果您对 softmax 函数的定义感兴趣,请点击提供的链接。**

我们终于知道如何定义我们的 f !这是个好消息,我们几乎可以帮助我们的奶奶解决手机里没有号码的问题了。最终的函数定义如下:f(x)=soft max(xw)。它采用一个展平的图像向量 x (嗯,我们不能忘记插入 1 作为第一个元素)并返回 10 个可能数字的概率向量。厉害!但是等等,我们还没说重量 W 呢?!**

重量

权重 W 在 ML 文献中称为模型参数, f 称为模型。如果我们随机初始化 W ,我们很可能会得到一个非常糟糕的模型——预测的数字(向量 yProb 中具有最大值的类别)大部分时间都是错误的,我们希望找到一种更好的方法。

我们还有一件事要处理:带标签的数据集!凭直觉,我们将试图找到一组权重 W 来很好地处理带标签的数据(我们将称之为训练数据,搜索参数将被称为训练),并希望它们也能很好地处理新数据(从我们祖母的电话簿中扫描的数字)。在这一点上,经过战斗考验的数据科学家可能正在做鬼脸,因为我们不希望仅仅希望它会做得很好,我们希望测量它,并确保模型不会犯太多错误。我们不希望模型只是记忆我们的训练示例,而是学习关于数字 2 或数字 9 的概念,并有能力识别这些数字的新的、看不见的图像。**

让我们定义一下在我们的场景中是什么意思。我们可以做的是计算我们的模型从训练集中正确获得的图像的比例。这个度量被称为分类准确度,我们可以计算它,因为我们知道训练集中的正确标签是什么。找到 W 的一种简单方法是简单地尝试随机值并返回具有最高精确度的值。但我们肯定能比随机搜索做得更好,对吧?**

同样,我们不想涉及太多的细节,但是有一种迭代优化算法可以找到函数的最小值(查看维基百科页面上的 gradient descent 了解更多信息)。这里的想法是,我们指定一个误差函数——我们衡量我们的模型在训练集上的预测有多差——并根据参数 W 将其最小化。梯度下降将会给我们一些 W 在误差函数方面对我们的训练数据最有效。这个概念在图 4* 中被形象化:表面是我们的误差函数,X 轴和 Y 轴是我们在中的两个值(是的,我们实际上有 10785,但为了形象化,假设我们只有 2 个),算法沿着红色路径尝试不同的 X 和 Y,最后返回函数值最低的一些 X 和 Y。这个值被称为函数最小值,它在我们的例子中是有意义的,因为我们在寻找误差函数的最小值。****

Image 4: Gradient descent (source: https://blog.paperspace.com).

不幸的是,我们不能使用像负分类精度这样的东西作为误差函数,因为梯度下降需要一个可微函数,而精度不是这样。我们可以使用的方法叫做对数损失,它简单地说我们计算正确类别概率的负对数。我们知道正确的类别是什么,因为我们的训练集是有标签的,所以我们只需从对应于该类别的 yProb 中取值(姑且称之为 yProb )并计算- log ( yProb )。您可以在图 5 中看到,随着 yProb 越来越接近 1,该值越来越接近 0。最终的误差函数是我们训练集中所有样本的对数损失的总和(或平均值)。请注意,log loss 还有其他令人满意的属性,这些属性使它成为我们的错误函数的更好选择,但是我们现在不要考虑细节。

Image 5: Logarithmic loss function (source: http://wiki.fast.ai).

这实际上是我们第一种方法的精髓,没有什么不能用几行 Scala 实现的!为了回顾我们已经完成的工作,让我们再看一下最重要的步骤:

  • 我们设计了一个函数 f ,它将一个展平的图像向量 x 作为输入,并返回一个包含 10 个元素的向量 yProb ,其中每个元素代表每个可能数字的概率(参数 W 被合并到f】**
  • 我们已经使用了 f 和一个带标签的训练集,通过计算训练集中所有示例的平均对数损失来衡量我们的参数 W 有多差
  • 我们使用了一种优化算法,该算法给出了一些在对数损失误差函数方面表现最佳的 W
  • 我们希望返回的 W 也能适用于电话簿中的数字

图书馆

接下来,我们将看看如何通过使用 doddle-model 库,用几行 Scala 实现我们到目前为止讨论的所有内容。老实说,该库的具体实现与所介绍的技术有一些重要的不同,这些不同使得整个方法在数值上更稳定、更有效,但是我们现在没有必要讨论这些。让我们直接进入代码。

我们将使用来自mldata.org的标记数据集,它由 70.000 个标记图像组成。我们将模拟训练和测试数据,仅使用 60.000 张图像进行训练,剩余的 10.000 张用于评估性能。

让我们加载数据:

如果我们检查形状,我们可以看到xTrainxTest中的行代表我们的展平图像向量(每行是一个图像向量),列代表像素值。yTrainyTest持有实际标签,例如前 10 个训练图像上有数字 1、9、2、2、7、1、8、3、3 和 7。

训练模型就像下面这样简单:

做预测看起来像是:

现在我们有了模型预测yTestPred和我们知道正确的真实标签yTest,我们可以检查模型的预测是否有任何意义。让我们先来看看测试数据的前 10 位数字以及我们对它们的预测。

那看起来像它能工作!让我们计算整个测试数据集的分类精度:

还不错!我们能够正确地分类 10,000 幅在训练期间没有使用的图像中的 92.22%。这仍然会让我们的奶奶的手机号码不正确,但这是一个很好的起点,我们可以逐步改善!

表演

该库的开发考虑到了性能。参见 doddle-benchmark 存储库,其中展示了与 scikit-learn 的一些并行性能比较。

Breeze(底层数字处理库)利用 netlib-java 访问硬件优化的线性代数库,这是快速执行的主要原因。更多详情请参见自述文件的性能部分。

结论

如果你已经做到了这一点,给自己一个鼓励,因为你对 softmax 分类器以及如何训练它有相当多的了解。如果你对更多感兴趣,网上有很多免费的好课程和资源。

如果您有兴趣了解更多关于老态龙钟模型的信息,可以看看老态龙钟模型示例库。它包含当前实现的所有内容的代码示例,应该作为一个很好的起点。

如果你有任何问题、建议、评论或只是想聊天,你可以在 GitterTwitter 上给我留言。

在机器学习中,识别上下文仍然很难——下面是解决这个问题的方法

原文:https://towardsdatascience.com/recognizing-context-is-still-hard-in-machine-learning-heres-how-to-tackle-it-ed398a725f8c?source=collection_archive---------9-----------------------

机器学习已经走过了漫长的道路,因为它涉及到识别人脸,物体和其他文字。但它仍然有点纠结的地方是语境。

定义上下文

考虑视频质量控制问题。现在有很多工具可以对视频文件进行自动质量控制。它们在检测丢失磁道、文件损坏或元数据不匹配的问题方面做得很好。然而,他们仍然很难告诉你一个图像是否是颠倒的。

当图像颠倒时,人类可以立即分辨出来,但计算机却很难分辨。原因是因为倒挂是上下文相关的。

Your brain is telling you that this is wrong

考虑上面的图像。你的大脑告诉你这个图像是颠倒的。有点不对劲。如果这是一个质量控制过程,你应该把它退回去。你也可能会想,这对于计算机来说应该不难理解。

为什么电脑看不到颠倒的东西?

也许你可以训练一个机器学习模型来检测有方向的物体。或者试着用很多很多上下颠倒的图片。对于某些用例,这可能行得通。但是当你的模型看到这样的图像时会发生什么呢:

https://i.pinimg.com/736x/b1/25/71/b12571069c99ac8b8330a6371b9f5ef0--roald-dahl-cockpit.jpg

这个图像实际上应该是上下颠倒的。作为一名人类质量控制操作员,你不会多看一眼。然而,机器学习模型不会理解上下文,因此会出错。

人类非常擅长上下文。计算机仍然需要一些帮助。

但是并不是所有的都失去了

当你可以明确你的用例时,机器学习是最好的。比方说,我想把我所有的图片按照某种上下文分类,比如“喜怒无常”。

为了尝试这个,我使用了机器盒子的 Tagbox。让一个可训练的图像识别框在你的计算机上运行大约需要 5 秒钟。

第一步,找一些“喜怒无常”的例子。我从这张图片开始:

Very moody!

我用 Tagbox 的控制台上传了这张照片,并将其标记为“moody”。

Tagbox by Machine Box

几毫秒后,Tagbox 就有了我称之为“喜怒无常”的想法。但是一张照片是不够的。所以我找到了另一张看起来相似的照片,并在 Tagbox 控制台中用另一张我认为“喜怒无常”的照片重复这个过程。

Very moody

在向 Tagbox 展示了两个“moody”的例子后,我准备开始在其他图像上测试它。

我使用 Tagbox 控制台手动执行这个任务——当然,API 是用来将这个工作流构建到您的产品和服务中的。

让我们用这张图片来检查我们的模型,看看结果。

Tagbox results

成功!在给它看了两张照片后,它已经了解了一些我的照片的背景,我可以用它们来对剩下的照片进行分类。实际上,我可能想再花 20 分钟进行测试和训练,只是为了确保模型足够健壮以满足我的需求。

关键的一点是,当你心中有一个特定的用例时,机器学习的功能最好,并且可以指导模型应用于该用例。(目前)还没有一种放之四海而皆准的模式。模型越通用,你的用例就需要越通用。

什么是机器盒子?

Machine Box 将最先进的机器学习功能放入 Docker 容器中,这样像您这样的开发人员可以轻松地将自然语言处理、面部检测、对象识别等功能融入其中。到您自己的应用程序中。

这些盒子是为了扩展而建造的,所以当你的应用真正起飞的时候,只需要水平地添加更多的盒子,直到无限甚至更远。哦,它比任何云服务都便宜(而且可能更好)……而且你的数据不会离开你的基础设施

有戏让我们知道你的想法。

用注意递归神经网络识别语音命令

原文:https://towardsdatascience.com/recognizing-speech-commands-using-recurrent-neural-networks-with-attention-c2b2ba17c837?source=collection_archive---------4-----------------------

如何为语音应用实现一个可解释的神经模型

Voice spectrogram

语音识别已经成为人机界面(HCI)不可分割的一部分。它们出现在谷歌助手、微软 Cortana、亚马逊 Alexa 和苹果 Siri 等个人助理中,以及自动驾驶汽车 HCI 和员工需要佩戴大量保护设备的活动中(例如,像石油和天然气行业)。

Waveform, neural attention weights and mel-frequency spectrogram for word “one”. Neural attention helps models focus on parts of the audio that really matter.

这种处理大部分是在云中完成的,使用的是强大的神经网络,这些网络经过了海量数据的训练。然而,语音命令模型能够识别单个单词,如“开始”、“停止”、“向左”或“向右”(或“嘿,谷歌”、“Alexa”、“回声”),由于各种原因,通常在本地运行。首先,将从给定设备获取的所有音频连续流式传输到云中会变得非常昂贵。其次,这在一些应用中甚至是不可能的:考虑海上平台中的操作员想要使用简单的语音命令来控制辅助机器人的情况:可能没有可用的互联网连接或者等待时间可能太长。

在这项工作中,使用了谷歌语音识别数据集。它包含各种单词的长度为 1s 的简短音频剪辑,是学习如何将深度学习应用于语音的绝佳起点。

人声基础

在分析人类声音时,一个非常重要的方面是滤波器,它构成了一个选择性频率传输系统,允许能量通过一些频率,而不允许其他频率。如下图所示,咽、口腔和嘴唇在人类说话中起着重要的作用。

声音共振峰揭示了能量更集中的频率区域。它们是声音频谱中振幅较大的峰值,是元音发音时声道所采用的特定结构所固有的。当说出一个单词时,共振峰与声道的自然共振频率相关联,并取决于舌头相对于内部结构和嘴唇运动的位置。该系统可以近似为具有一个封闭末端(喉)和一个开放末端(唇)的管,通过舌、唇和咽的运动来修改。发生在这个管腔中的共振叫做共振峰。

有趣的是,深度学习实践者很快决定忽略所有这些信息。在百度工作期间,研究员吴恩达继续说,音素是声音的最小组成部分,没有关系。事实上,在一定程度上,重要的是,如果时间间隔足够小,语音大多是一个(准)周期信号。这就产生了忽略信号的相位,只使用其功率谱作为信息源的想法。事实上,声音可以从其功率谱重建(例如,使用 Griffin-Lim 算法或神经声码器)证明了这一点。

尽管在处理原始波形方面已经做了大量的工作(例如,最近的脸书研究中的),但是频谱方法仍然很普遍。目前,预处理音频的标准方法是从原始波形计算具有给定跳跃大小的短时傅立叶变换(STFT)。结果称为频谱图,是一个三维排列,显示频率分布和音频强度作为时间的函数,如下图所示。另一个有用的技巧是“拉伸”低频以模仿人类的感知,人类对高频的变化不太敏感。这可以通过计算梅尔频率系数(MFC)来实现。如果你感兴趣的话,有很多详细解释 MFC 的在线资源(维基百科是一个很好的开始)。

Diphtongs explicited in word “saia”. Topmost: phonetic notation. Middle: sound waveform. Bottom: Spectrogram with fundamental frequency highlighted in blue and the three first formants highlighted in red.

神经注意力结构

既然语音处理的基础是已知的,就有可能提出一种神经网络,它能够处理命令识别,同时仍然在可训练参数的数量方面保持较小的足迹。一个有注意力的循环模型带来各种好处,比如:

  • 通过计算输入的重要性权重,使模型可解释;
  • 学会识别音频的哪一部分重要;
  • 递归神经网络(RNN)架构(如长短期记忆——LSTM 或门控递归单元——GRU)已经证明能够携带信息,同时仍然控制消失/爆发梯度;
  • 由于响应延迟 1 秒通常是可以接受的,因此双向 RNN 允许模型提取音频给定点的过去和未来相关性。

Recurrent neural network with attention mechanism. Numbers between [brackets] are tensor dimensions. raw_len is WAV audio length (16000 in the case of audios of length 1s with a sampling rate of 16kHz). spec_len is the sequence length of the generated mel-scale spectrogram. nMel is the number of mel bands. nClasses is the number of desired classes. The activation of the last Dense layer is softmax. The activation of the 64 and 32 dense classification layers is the rectified linear unit (relu).

所提出的架构使用卷积来提取短期依赖性,使用 rnn 和注意力来提取长期依赖性。实施细节可以在这个资源库中找到。

在 Google Speech 数据集上,当试图识别 20 个单词中的一个,沉默或未知时,所提出的模型达到了 94%以上的准确率。此外,注意力层使模型具有可解释性。例如,在单词“右”的情况下,注意网络将大量注意力放在从 ri 的过渡上。考虑到在某些情况下 t 可能听不到,这是非常直观的。还要注意,注意力权重被放置在过渡中的事实并不意味着模型忽略了音频的其他部分:双向 RNN 带来了来自过去和未来的信息。

Waveform, attention weights and mel-frequency spectrogram of word “right”

结论

语音命令识别存在于各种设备中,并被许多 HCI 接口所利用。在许多情况下,希望获得能够在本地运行的轻量级和高精度的模型。这篇文章解释了一种可能的 RNN 架构,它在 Google 语音识别任务上实现了最先进的性能,同时在可训练参数方面仍然保持了较小的影响。源代码可在 github 上获得。它使用谷歌语音命令数据集(v1 和 v2)来演示如何训练能够识别例如 20 个命令加上静音或未知单词的模型。

该架构能够提取短期和长期的依赖性,并使用注意机制来查明哪个区域具有最有用的信息,然后将这些信息提供给一系列密集层。

在工程应用中,能够解释哪些特性用于选择特定类别是很重要的。如上所示,注意机制解释了音频的哪些部分对于分类是重要的,并且还匹配元音过渡区域与识别单词相关的直觉。为了完整起见,混淆矩阵可以在本文中找到,并表明如果没有额外的上下文,单词对 tree-three 和 no-down 很难识别。

参考

语音命令:有限词汇语音识别数据集https://arxiv.org/abs/1804.03209

语音命令识别的神经注意模型https://arxiv.org/abs/1808.08929

专业男性歌剧演唱者的共振峰调谐策略,《声音杂志》27(3)(2013)278–288。网址http://www . science direct . com/science/article/pii/s 089219971200209320

腰带和中性风格歌唱之间的呼吸和声学差异,《声音杂志》29(4)(2015)418–5。网址http://www . science direct . com/science/article/pii/s 089219971400204

在语音分析中估计预期基频的稳健频域方法,载于国际创新科学与研究杂志

wav2letter++最快的开源语音识别系统https://arxiv.org/abs/1812.07625

使用深度学习以 98%的准确率识别交通标志

原文:https://towardsdatascience.com/recognizing-traffic-signs-with-over-98-accuracy-using-deep-learning-86737aedc2ab?source=collection_archive---------0-----------------------

Stop Sign

这是 Udacity 自动驾驶汽车工程师纳米学位 第一学期的项目 2。你可以在github上找到与这个项目相关的所有代码。你也可以阅读我关于项目 1 的帖子: 用计算机视觉检测车道线 只需点击链接。

交通标志是道路基础设施不可或缺的一部分。它们为道路使用者提供关键信息,有时是令人信服的建议,这反过来要求他们调整自己的驾驶行为,以确保他们遵守目前实施的任何道路法规。如果没有这些有用的标志,我们很可能会面临更多的事故,因为司机不会得到关于他们可以安全行驶多快的关键反馈,或者关于道路施工、急转弯或前方学校路口的信息。在当今时代,每年大约有 130 万人死于交通事故。如果没有我们的路标,这个数字会高得多。
自然,自动驾驶汽车也必须遵守道路法规,因此识别理解交通标志。

传统上,标准的计算机视觉方法被用于检测和分类交通标志,但是这些需要大量和耗时的手工工作来手工制作图像中的重要特征。相反,通过对这个问题应用深度学习,我们创建了一个可靠地对交通标志进行分类的模型,通过本身学习识别最适合这个问题的特征。在这篇文章中,我展示了我们如何创建一个深度学习架构,该架构可以在测试集上以接近 98%的准确率识别交通标志。

项目设置

数据集分为训练集、测试集和验证集,具有以下特征:

  • 图像为 32(宽)x 32(高)x 3 (RGB 颜色通道)
  • 训练集由 34799 幅图像组成
  • 验证集由 4410 幅图像组成
  • 测试集由 12630 幅图像组成
  • 共有 43 个等级(如限速 20 公里/小时、禁止进入、道路颠簸等。)

此外,我们将使用 Python 3.5 和 Tensorflow 来编写代码。

图像和分布

您可以在下面看到来自数据集的图像示例,标签显示在相应图像行的上方。他们中的一些很暗,所以我们将在稍后提高对比度。

Sample of Training Set Images With Labels Above

正如下面的直方图所示,训练集中的各个类之间也存在明显的不平衡。有些班级的图片不到 200 张,而有些班级的图片超过 2000 张。这意味着我们的模型可能偏向过度代表的类别,特别是当它的预测不确定的时候。我们将在后面看到如何使用数据扩充来减少这种差异。

Distribution of images in training set — not quite balanced

预处理步骤

我们首先对图像应用两个预处理步骤:

灰度 我们将 3 通道图像转换成一个单一的灰度图像(我们在项目 1 中做了同样的事情——车道线检测——你可以在这里阅读我的博文)。

Sample Of Grayscale Training Set Images, with labels above

图像标准化 我们通过用数据集平均值减去每幅图像并除以其标准偏差来集中图像数据集的分布。这有助于我们的模型统一处理图像。生成的图像如下所示:

Normalised images — we can see how “noise” is distributed

模型架构

该建筑的设计灵感来自 Yann Le Cun 关于交通标志分类的论文。我们添加了一些调整,并创建了一个模块化的代码库,允许我们尝试不同的滤波器大小、深度和卷积层数,以及完全连接层的尺寸。为了表达对乐存的敬意,并带着一点厚脸皮,我们把这样的网络叫做 EdLeNet 😃。

我们主要尝试了 5x5 和 3x3 的过滤器(又名内核)大小,并从我们的第一个卷积层的深度 32 开始。 EdLeNet 的 3x3 架构如下图所示:

EdLeNet 3x3 Architecture

该网络由 3 个卷积层组成——内核大小为 3x3,下一层深度加倍——使用 ReLU 作为激活函数,每一层后面都有一个 2x2 最大池操作。最后 3 层完全连接,最后一层使用 SoftMax 激活函数计算出 43 个结果(可能标签的总数)。使用带有 Adam 优化器的小批量随机梯度下降来训练网络。我们构建了一个高度模块化的编码基础设施,使我们能够动态创建我们的模型,如以下代码片段所示:

mc_3x3 = ModelConfig(EdLeNet, "EdLeNet_Norm_Grayscale_3x3_Dropout_0.50", [32, 32, 1], [3, 32, 3], [120, 84], n_classes, [0.75, 0.5])
mc_5x5 = ModelConfig(EdLeNet, "EdLeNet_Norm_Grayscale_5x5_Dropout_0.50", [32, 32, 1], [5, 32, 2], [120, 84], n_classes, [0.75, 0.5])

me_g_norm_drpt_0_50_3x3 = ModelExecutor(mc_3x3)
me_g_norm_drpt_0_50_5x5 = ModelExecutor(mc_5x5)

ModelConfig包含关于模型的信息,例如:

  • 模式功能(例如EdLeNet)
  • 型号名称
  • 输入格式(例如,灰度为[32,32,1]),
  • 卷积层配置[滤波器大小,起始深度,层数],
  • 完全连接的层尺寸(例如[120,84])
  • 班级数量
  • 辍学保持百分比值[p-conv,p-fc]

ModelExecutor负责训练评估预测,并生成我们的激活地图的可视化。

为了更好地隔离我们的模型,并确保它们不都存在于同一个张量流图下,我们使用以下有用的构造:

self.graph = tf.Graph()
with self.graph.as_default() as g:
    with g.name_scope( self.model_config.name ) as scope:

...

with tf.Session(graph = self.graph) as sess:

这样,我们为每个型号的创建单独的图表,确保没有混淆变量、占位符等。这让我省了很多麻烦。

我们实际上从 16 的卷积深度开始,但是用 32 获得了更好的结果,所以决定用这个值。我们还比较了彩色图像与灰度图像、标准图像和标准化图像,发现灰度图像往往优于彩色图像。不幸的是,我们在 3x3 或 5x5 模型上勉强达到了 93%的测试集准确率,没有持续达到这个里程碑。此外,我们在给定数量的时期后,在验证集上观察到一些不稳定的损失行为,这实际上意味着我们的模型在训练集上过度拟合,而不是一般化。您可以在下面看到我们针对不同型号配置的一些指标图。

Models Performance on Color Normalised Images

Models Performance On Grayscale Normalised Images

拒绝传统社会的人

为了提高模型的可靠性,我们转向了 dropout,这是一种正则化形式,其中权重以概率 p 保持:未接受的权重因此被“丢弃”。这可以防止模型过度拟合。辍学是由深度学习领域的先驱杰弗里·辛顿(Geoffrey Hinton)提出的。为了更好地理解作者背后的动机,他的团队在 T2 发表的关于这个主题的论文是必读的。生物学和进化论还有一个有趣的相似之处。
在论文中,作者根据图层类型应用了不同程度的辍学。因此,我决定采用一种类似的方法,定义两个等级的漏失,一个用于卷积层,另一个用于全连接层:

p-conv: probability of keeping weight in convolutional layer
p-fc: probability of keeping weight in fully connected layer

此外,随着他们在网络中的深入,作者逐渐采用了更积极(即更低)的辍学值。因此我也决定:

p-conv >= p-fc

也就是说,我们将在卷积层中以大于或等于全连接层的概率保持权重。对此的解释是,我们将网络视为一个漏斗,因此希望随着我们向更深的层次移动,逐渐收紧:我们不希望在开始时丢弃太多信息,因为其中一些信息非常有价值。此外,当我们在卷积层应用 MaxPooling 时,我们已经丢失了一些信息。

我们尝试了不同的参数,但最终确定了 p-conv=0.75p-fc=0.5 ,这使我们能够在 3x3 模型的标准化灰度图像上实现 97.55%的测试集准确度。有趣的是,我们在验证集上实现了超过 98.3%的准确率:

Training EdLeNet_Norm_Grayscale_3x3_Dropout_0.50 [epochs=100, batch_size=512]...

[1]	total=5.222s | train: time=3.139s, loss=3.4993, acc=0.1047 | val: time=2.083s, loss=3.5613, acc=0.1007
[10]	total=5.190s | train: time=3.122s, loss=0.2589, acc=0.9360 | val: time=2.067s, loss=0.3260, acc=0.8973
...
[90]	total=5.193s | train: time=3.120s, loss=0.0006, acc=0.9999 | val: time=2.074s, loss=0.0747, acc=0.9841
[100]	total=5.191s | train: time=3.123s, loss=0.0004, acc=1.0000 | val: time=2.068s, loss=0.0849, acc=0.9832
Model ./models/EdLeNet_Norm_Grayscale_3x3_Dropout_0.50.chkpt saved
[EdLeNet_Norm_Grayscale_3x3_Dropout_0.50 - Test Set]	time=0.686s, loss=0.1119, acc=0.9755

Models Performance on Grayscale Normalised Images, After The Introduction Of Dropout

上面的图表显示模型是平滑的,不像上面的一些图表。我们已经实现了在测试集上达到 93%以上准确率的目标,但是我们还能做得更好吗?请记住,有些图像是模糊的,每个班级的图像分布非常不均匀。我们将在下面探讨用于解决每个问题的其他技术。

直方图均衡

直方图均衡化是一种计算机视觉技术,用于增加图像中的对比度。由于我们的一些图像对比度低(模糊、黑暗),我们将通过应用 OpenCV 的对比度限制自适应直方图均衡(又名 CLAHE)功能来提高可视性。

我们再次尝试各种配置,并找到最佳结果,在 3x3 模型上使用以下压差值得到 97.75% 的测试精度: p-conv=0.6p-fc=0.5

Training EdLeNet_Grayscale_CLAHE_Norm_Take-2_3x3_Dropout_0.50 [epochs=500, batch_size=512]...[1]	total=5.194s | train: time=3.137s, loss=3.6254, acc=0.0662 | val: time=2.058s, loss=3.6405, acc=0.0655
[10]	total=5.155s | train: time=3.115s, loss=0.8645, acc=0.7121 | val: time=2.040s, loss=0.9159, acc=0.6819
...
[480]	total=5.149s | train: time=3.106s, loss=0.0009, acc=0.9998 | val: time=2.042s, loss=0.0355, acc=0.9884
[490]	total=5.148s | train: time=3.106s, loss=0.0007, acc=0.9998 | val: time=2.042s, loss=0.0390, acc=0.9884
[500]	total=5.148s | train: time=3.104s, loss=0.0006, acc=0.9999 | val: time=2.044s, loss=0.0420, acc=0.9862
Model ./models/EdLeNet_Grayscale_CLAHE_Norm_Take-2_3x3_Dropout_0.50.chkpt saved
[EdLeNet_Grayscale_CLAHE_Norm_Take-2_3x3_Dropout_0.50 - Test Set]	time=0.675s, loss=0.0890, acc=0.9775

我们在下面的图表中展示了我们测试 5x5 模型的 220 多个时期。我们可以看到一条更平滑的曲线,这加强了我们的直觉,即我们的模型更稳定。

Models Performance On Grayscale Equalized Images, With Dropout

我们识别了 269 个模型不能正确识别的图像。我们在下面展示了 10 个随机选择的例子,来猜测为什么这个模型是错误的。

Sample of 10 images where our model got the predictions wrong

有些图像非常模糊,尽管我们的直方图均衡,而其他人似乎扭曲。在我们的测试集中,我们可能没有足够的这种图像的例子来改进我们的模型的预测。此外,虽然 97.75%的测试准确率非常好,但我们还有一张王牌:数据扩充。

数据扩充

我们之前观察到数据在 43 个班级中呈现出明显的不平衡。然而,这似乎不是一个严重的问题,因为我们能够达到非常高的精度,尽管阶级不平衡。我们还注意到测试集中的一些图像是扭曲的。因此,我们将使用数据增强技术来尝试:

  1. 扩展数据集并提供不同照明设置和方向的附加图片
  2. 提高模型变得更加通用的能力
  3. 提高测试和验证的准确性,尤其是在失真图像上

我们使用一个叫做 imgaug 的漂亮的库来创建我们的增强。我们主要应用仿射变换来放大图像。我们的代码如下所示:

def augment_imgs(imgs, p):
    """
    Performs a set of augmentations with with a probability p
    """
    augs =  iaa.SomeOf((2, 4),
          [
              iaa.Crop(px=(0, 4)), # crop images from each side by 0 to 4px (randomly chosen)
              iaa.Affine(scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}),
              iaa.Affine(translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}),
              iaa.Affine(rotate=(-45, 45)), # rotate by -45 to +45 degrees)
              iaa.Affine(shear=(-10, 10)) # shear by -10 to +10 degrees
          ]) seq = iaa.Sequential([iaa.Sometimes(p, augs)])

    return seq.augment_images(imgs)

虽然类别不平衡可能会导致模型中的一些偏差,但我们决定在此阶段不解决它,因为它会导致我们的数据集显著膨胀,并延长我们的训练时间(我们在此阶段没有太多时间花在训练上)。相反,我们决定每个班级增加 10%。我们的新数据集如下所示。

Sample Of Augmented Images

当然,图像的分布没有明显变化,但我们对图像进行了灰度、直方图均衡化和归一化预处理。我们训练了 2000 个有丢失的历元( p-conv=0.6p-fc=0.5 ),在测试集上达到了 97.86%的准确率

[EdLeNet] Building neural network [conv layers=3, conv filter size=3, conv start depth=32, fc layers=2]
Training EdLeNet_Augs_Grayscale_CLAHE_Norm_Take4_Bis_3x3_Dropout_0.50 [epochs=2000, batch_size=512]...

[1]	total=5.824s | train: time=3.594s, loss=3.6283, acc=0.0797 | val: time=2.231s, loss=3.6463, acc=0.0687
...
[1970]	total=5.627s | train: time=3.408s, loss=0.0525, acc=0.9870 | val: time=2.219s, loss=0.0315, acc=0.9914
[1980]	total=5.627s | train: time=3.409s, loss=0.0530, acc=0.9862 | val: time=2.218s, loss=0.0309, acc=0.9902
[1990]	total=5.628s | train: time=3.412s, loss=0.0521, acc=0.9869 | val: time=2.216s, loss=0.0302, acc=0.9900
[2000]	total=5.632s | train: time=3.415s, loss=0.0521, acc=0.9869 | val: time=2.217s, loss=0.0311, acc=0.9902
Model ./models/EdLeNet_Augs_Grayscale_CLAHE_Norm_Take4_Bis_3x3_Dropout_0.50.chkpt saved[EdLeNet_Augs_Grayscale_CLAHE_Norm_Take4_Bis_3x3_Dropout_0.50 - Test Set]	time=0.678s, loss=0.0842, acc=0.9786

这是我们迄今为止最好的表现!!!

Neural Network Celebration

但是 …如果你看看训练集上的损失度量,你可以看到在 0.0521,我们很可能还有一些回旋的空间。我们计划为更多的纪元进行训练,并将在未来报告我们的新结果。

测试新图像

我们决定也在新图像上测试我们的模型,以确保它确实比我们原始数据集中的交通标志更一般化。因此,我们下载了五张新图像,并提交给我们的模型进行预测。

Download 5 new traffic signs — color

图像的基本事实如下:

['Speed limit (120km/h)',
 'Priority road',
 'No vehicles',
 'Road work',
 'Vehicles over 3.5 metric tons prohibited']

选择这些图像的原因如下:

  • 它们代表了我们目前分类的不同交通标志
  • 它们的形状和颜色各不相同
  • 它们处于不同的光照条件下(第四个有阳光反射)
  • 它们处于不同的方向(第三个是倾斜的)
  • 他们有不同的背景
  • 最后一张图片实际上是一个设计,而不是真实的图片,我们想用它来测试模型
  • 他们中的一些人在代表性不足的班级

我们采取的第一步是对这些新图像应用相同的 CLAHE,结果如下:

Download 5 new traffic signs — grayscale CLAHE

我们在新图像上达到了 100%的完美准确率。在原始测试集上,我们达到了 97.86%的准确率。我们可以探索模糊/扭曲我们的新图像或修改对比度,看看模型在未来如何处理这些变化。

new_img_grayscale_norm_pred_acc = np.sum(new_img_lbs == preds) / len(preds)
print("[Grayscale Normalised] Predictional accuracy on new images: {0}%".format(new_img_grayscale_norm_pred_acc * 100))
...
[Grayscale Normalised] Predictional accuracy on new images: 100.0%

我们还显示了为每个图像计算的前 5 个 SoftMax 概率,绿色条显示了基本事实。我们可以清楚地看到,我们的模型对其预测相当有信心。在最坏的情况下(最后一幅图像),第二个最可能的预测的概率约为 0.1%。事实上,我们的模型在最后一张图片上挣扎得最厉害,我相信这实际上是一个设计,甚至不是一张真实的图片。总的来说,我们开发了一个强大的模型!

Visualizations of The Model’s Top 5 Predictions

可视化我们的激活地图

我们在下面展示了每个卷积层产生的结果(在最大池化之前),产生了 3 个激活图

第一层

我们可以看到这个网络把很多注意力集中在圆圈的边缘,以及卡车上。背景大多被忽略。

第二层

Activation Map Of Second Convolutional Layer

很难确定网络在第 2 层关注的是什么,但它似乎在圆圈的边缘和中间(卡车出现的地方)激活。

第三层

这个激活图也很难解读…但是看起来网络对边缘和中间的刺激有反应。

结论

我们介绍了如何使用深度学习对交通标志进行高精度分类,采用各种预处理和正则化技术(例如 dropout),并尝试不同的模型架构。我们构建了高度可配置的代码,并开发了评估多种架构的灵活方法。我们的模型在测试集上达到了接近 98%的准确率,在验证集上达到了 99%。

就个人而言,我非常喜欢这个项目,并获得了使用 Tensorflow、matplotlib 和研究人工神经网络架构的实践经验。此外,我深入研究了该领域的一些开创性论文,这些论文加强了我的理解,更重要的是完善了我对深度学习的直觉。

在未来,我相信通过应用进一步的规范化技术,如批处理规范化,以及采用更现代的架构,如 GoogLeNet 的初始模块ResNetXception ,可以实现更高的准确性。

感谢阅读这篇文章。希望你觉得有用。我现在正在创建一个名为env sion的新公司!在 EnVsion,我们正在为 UX 的研究人员和产品团队创建一个中央存储库,以从他们的用户采访视频中挖掘见解。当然我们用人工智能来做这个。).

如果你是一名 UX 的研究人员或产品经理,对与用户和客户的视频通话感到不知所措,那么 EnVsion 就是为你准备的!

你也可以关注我的 推特

推荐系统——模型和评估

原文:https://towardsdatascience.com/recommendation-systems-models-and-evaluation-84944a84fb8e?source=collection_archive---------3-----------------------

我曾参与构建几种不同类型的推荐系统,我注意到的一件事是每个用例都不同,因为每个用例都旨在解决不同的业务问题。让我们考虑几个例子:

  1. 电影/书籍/新闻推荐—推荐增加用户参与度的新内容。目的是向用户介绍他们可能感兴趣的新内容,并鼓励他们在我们的平台上消费更多内容。
  2. 股票推荐——推荐对客户最有利可图的股票。推荐的可能是他们历史上交易过的股票。新奇在这里并不重要;股票的盈利能力。
  3. 产品建议—建议新旧产品的组合。来自用户历史交易的旧产品作为他们频繁购买的提醒。此外,推荐用户可能喜欢尝试的新产品也很重要。

在所有这些问题中,共同的主线是他们的目标是提高客户满意度,并反过来以增加佣金、提高销售额等形式推动业务。无论使用何种情况,数据通常采用以下格式:

  • 客户 ID、产品 ID(电影/股票/产品)、单位数量/评级、交易日期
  • 任何其他特征,如产品的细节或客户的人口统计

接下来,我将介绍以下主题:

  • 用于构建推荐系统的方法——基于内容、协作过滤、聚类
  • 评估指标—统计准确性指标、决策支持准确性指标
  • 要记住的事情

http://cleverdata.io/basket-analysis-machine-learning/

方法

构建推荐系统有两种主要方法——基于内容的和协同过滤。在下一节中,我将讨论它们中的每一种,以及它们何时适合。

http://datameetsmedia.com/an-overview-of-recommendation-systems/

基于内容

这种方法的要点是,我们将用户与他们喜欢或购买的内容或项目相匹配。在这里,用户和产品的属性很重要。例如,对于电影推荐,我们使用诸如导演、演员、电影长度、流派等特征。寻找电影之间的相似之处。此外,我们可以从电影描述和评论中提取情感评分和 tf-idf 评分等特征。(单词的 tf-idf 分数反映了单词对于文档集合中的文档的重要性)。基于内容的推荐的目的是为每个用户和每个项目创建一个“档案”。

考虑一个向用户推荐新闻文章的例子。假设我们有 100 篇文章,词汇量为 n。我们首先计算每篇文章中每个单词的 tf-idf 分数。然后我们构建两个向量:

  1. Item vector:这是一个长度为 n 的向量。对于在该文章中具有高 tf-idf 分数的单词,它包含 1,否则包含 0。

https://towardsdatascience.com/understanding-feature-engineering-part-3-traditional-methods-for-text-data-f6f7d70acd41

2.用户向量:同样是 1xN 向量。对于每个单词,我们存储该单词在用户已经消费的文章中出现的概率(即具有高 tf-idf 分数)。这里注意,用户向量是基于项目的属性的(在这种情况下是 tf-idf 单词得分)。

一旦我们有了这些配置文件,我们就可以计算用户和项目之间的相似性。推荐的项目是 1)用户与之具有最高相似性的项目,或者 2)与用户已经阅读的其他项目具有最高相似性的项目。有多种方法可以做到这一点。让我们看看两种常见的方法:

  1. 余弦相似度: 为了计算用户和项目之间的相似度,我们简单地取用户向量和项目向量之间的余弦相似度。这给了我们用户项目的相似性。

为了推荐与用户已经购买的商品最相似的商品,我们计算用户已经阅读的商品和其他商品之间的余弦相似度。推荐最相似的。因此,这是项目-项目的相似性。

余弦相似度最适合于高维特征,尤其是在信息检索和文本挖掘中。

2。【Jaccard 相似度:又称交集超过并集,公式如下:

这用于项-项相似度。我们将项目向量相互比较,返回最相似的项目。

Jaccard 相似性仅在向量包含二进制值时有用。如果它们具有可以采用多个值的排名或评级,则 Jaccard 相似性不适用。

除了相似性方法之外,对于基于内容的推荐,我们可以将推荐视为简单的机器学习问题。这里有像随机森林、 XGBoost 等常规的机器学习算法。,派上用场了。

当我们有一大堆“外部”特征时,如天气条件、市场因素等,这种方法很有用。这不是用户或产品的属性,并且可以是高度可变的。例如,前一天的开盘价和收盘价在决定投资特定股票的盈利能力方面起着重要作用。这属于受监督的问题类别,其中标签是用户是否喜欢/点击某个产品(0/1),或者用户给该产品的评级,或者用户购买的单位数量。

协同过滤

协同过滤方法的基本假设是,如果 A 和 B 购买相似的产品,A 更有可能购买 B 已经购买的产品,而不是随机的人已经购买的产品。与基于内容不同,这里没有与用户或项目相对应的特性。我们只有效用矩阵。看起来是这样的:

a、B、C、D 是用户,列代表电影。这些值代表用户对电影的评价(1-5)。在其他情况下,这些值可以是 0/1,这取决于用户是否观看了电影。协作过滤可以分为两大类:

基于记忆的方法 对于基于记忆的方法,效用矩阵被记忆,并且通过用效用矩阵的剩余部分询问给定用户来做出推荐。让我们考虑一个同样的例子:如果我们有 m 部电影和 u 个用户,我们想知道用户 i 有多喜欢电影 k

这是用户 i 对她/他评价的所有电影的平均评价。利用这一点,我们估计他对电影 k 的评价如下:

用户 ai 之间的相似度可以使用任何方法计算,如余弦相似度/雅克卡相似度/皮尔逊相关系数等。
这些结果非常容易创建和解释,但是一旦数据变得过于稀疏,性能就会变差。

基于模型的方法 基于模型的方法的一个更普遍的实现是矩阵分解。在这里,我们从效用矩阵中创建用户和项目的表示。看起来是这样的:

因此,我们的效用矩阵分解成 U 和 V,其中 U 代表用户,V 代表低维空间中的电影。这可以通过使用矩阵分解技术,如 SVD 或 PCA,或者通过使用神经网络在一些优化器如 Adam、SGD 等的帮助下学习 2 个嵌入矩阵来实现。

对于用户 i 和每部电影 j 我们只需要计算评价 y 并推荐具有最高预测评价的电影。这种方法在我们有大量数据并且高度稀疏的时候最有用。矩阵分解有助于降低维数,从而加快计算速度。这种方法的一个缺点是,我们往往会失去可解释性,因为我们不知道用户/项目向量的确切元素是什么意思。

使聚集

当您的推荐问题将无人监管时,通常会使用聚类。

如果您刚刚进入这个行业,并且历史数据/标签数据非常少,您可以根据特性集对观察结果进行聚类,然后根据该聚类中存在的标签向聚类分配建议。

当然,这种解决方案不会立即给出最佳结果,但是在获得足够的数据之前,对于这种情况是一个很好的起点。聚类也可用于为观察值生成元特征。例如,在聚类之后,我可以将 1-k 的值作为新的特征“聚类”分配给每个观察值,然后在所有特征上训练我的主模型。这可以在用户级别或产品级别完成。

评估指标

设计推荐系统的一个主要障碍是选择要优化的指标。这可能很棘手,因为在很多情况下,目标是不推荐用户以前购买过的所有相同产品。那么你怎么知道你的模特在推荐产品方面做得好不好呢?

统计准确性指标

它们用于通过将预测评级与实际用户评级直接进行比较来评估过滤技术的准确性。平均绝对误差(MAE)、均方根误差(RMSE)和相关性通常被用作统计准确性度量。MAE 是最流行最常用的;它是衡量推荐与用户实际价值的偏差。MAE 和 RMSE 计算如下:

MAE 和 RMSE 越低,推荐引擎预测用户评级就越准确。当建议基于预测评级或交易数量时,这些指标非常有用。它们让我们知道我们的预测评级有多准确,反过来也让我们知道我们的推荐有多准确。

决策支持准确性指标

其中最受欢迎的是精确和召回。它们帮助用户在可用的项目集中选择更相似的项目。度量将预测过程视为一个二元操作,它将好的项目与那些不好的项目区分开来。让我们更详细地看看它们:

Recall@k 和 Precision@k: 这些是用于推荐系统的常用指标。让我们从理解推荐系统的精确度和召回率的含义开始:

但是,精度和召回率似乎并不关心排序。因此,我们在截止值 k 处使用精度和召回。考虑我们提出 N 个建议,并且只考虑第一个元素,然后只考虑前两个,然后只考虑前三个,等等。这些子集可以通过 k 进行索引。

截止 k、P@k 和 r@k 处的精度和召回率只是通过仅考虑从等级 1 到 k 的推荐子集来计算的精度和召回率。推荐的排名由预测值决定。例如,具有最高预测值的产品排名为 1,具有第 k 个最高预测值的产品排名为 k

平均精度: 如果我们要推荐 N 个项目,在项目的满空间中有 m 个相关项目,平均精度 AP@N 定义为:

其中 rel(k) 只是一个指示符(0/1),它告诉我们第项是否相关,而 P(k) 是精度@k。如果我们推荐 2N 个项而不是 N 个,AP@N 度量表示我们只关心第个第 N 个项的平均精度。

AP 奖励你给出正确的推荐,
AP 奖励你预先载入最有可能正确的推荐,
AP 永远不会因为你在你的列表中添加了额外的推荐而惩罚你——只要确保你预先载入了最好的。

平均平均精度:

AP 适用于单个数据点,就像单个用户一样。MAP@N 则更进一步,将所有用户的 AP 平均化。

其他建议

一个建议(这是一个我不太确定的个人建议)是从用户的历史数据中寻找真实的内容。然后,使用上述任何标准指标,将此内容与建议中的非历史内容进行比较。这让我们知道我们的模型在推荐不直接来自历史交易的产品方面有多好。

要记住的事情

在开发推荐系统时,尤其是基于内容的推荐,重要的是要记住不要只针对单一指标进行优化。也就是说,对于新闻文章推荐来说,获得非常高的召回率是不可取的,因为这意味着我们在向用户推荐他们在没有我们推荐的情况下会自然消费的内容。

因此,我们不会以任何方式推动业务。我们需要确保适当的召回率/精确度,作为我们的模型能够学习用户偏好的指标,而不是试图使其尽可能高。此外,从长远来看,我们不想因为一遍又一遍地推荐相同类型的东西而失去用户参与度。因此,如果我们试图最大化精度@k/召回@ k,这是非常可能的。

感谢您的阅读!我将很高兴在评论中收到任何反馈或附加信息!

参考

  1. Yannet Interian 在 USF 举办的关于推荐系统的讲座
  2. 这个解释地图的超赞帖子
  3. py torch 中协作过滤(矩阵分解)的示例笔记本
  4. 更多关于协同过滤的内容请点击:
    https://towards data science . com/collaborative-filtering-and-embeddings-part-1-63 b 00 b 9739 ce
    https://towards data science . com/variables-implementations-of-collaborative-filtering-100385 c 6 dfe 0

关于我:我毕业于 USF 大学数据科学专业,本科学习计算机科学,在构建预测和推荐算法以及为金融和零售客户提供商业见解方面有两年的经验。我对将我的机器学习和深度学习知识应用于现实世界问题的机会感到兴奋。一定要看看我的其他博客这里
LinkedIn:https://www.linkedin.com/in/neerja-doshi/ GitHub:https://github.com/neerjad/

黑客新闻 上讨论这个帖子。

编者按:准备好钻研一些代码了吗?在 GitHub 上查看Fritz。您将发现流行的机器和深度学习模型的开源、移动友好的实现,以及用于构建您自己的 ML 支持的 iOS 和 Android 应用程序的培训脚本、项目模板和工具。

加入我们的Slack寻求技术问题的帮助,分享你正在做的事情,或者只是与我们聊聊移动开发和机器学习。关注我们的TwitterLinkedIn了解移动机器学习世界的所有最新内容、新闻和更多信息。

对 NIH 数据管理政策的建议——NIH 能走出自己的路吗?

原文:https://towardsdatascience.com/recommendations-for-nih-data-management-policies-can-nih-get-out-of-its-own-way-8ec6ac631ec9?source=collection_archive---------15-----------------------

2018 年 10 月, NIH 发布了一份信息请求“关于 NIH 资助或支持的研究的数据管理和共享政策草案的拟议条款。”这一请求的目的是收集科学界成员对如何使 NIH 资助的研究可用的意见。按照要求:

国家卫生研究院长期致力于向公众提供其资助和开展的研究的成果和成就。在 NIH 看来,数据应该尽可能广泛和自由地提供,同时保护参与者的隐私,保护机密和专有数据。

其他科学家和公众(这项研究的资助者)都可以获得受资助研究的产品,这一点至关重要。一个数据管理计划 (DMP)是申请研究资助的一个组成部分。DMPs 描述了调查中产生的科学数据将如何被重新使用、验证,以及如何解决隐私问题。科学家(在这种情况下是生物医学研究人员)是他们领域的专家,但是他们的技能通常不包括数据管理培训。缺乏数据管理技能(和/或缺乏意识)是数据可用性经常无法满足 NIH 概述的理想的一个原因(另见Federer et al . 2018)。虽然出版商通常对出版有数据可用性的要求,但资助者在实现这些标准方面肯定有自己的角色。

下面是我提交给 NIH 的请求。虽然我认为最初的政策草案大部分是明智的,但我最大的问题是,我和许多花时间贡献自己想法的人一样,对这些评论实际上如何影响 NIH 政策没有一个清晰的认识。例如,今年早些时候,NIH 还要求对他们的数据科学战略计划提出意见。我发现最初的计划令人震惊(见这里的想法),我的评论在推特上产生了几个类似这样的帖子。我不认为我是某种独特的有洞察力的天才,但“战略”数据科学计划包含许多想法,充其量是模糊的,在一些情况下显然是错误的。许多人注意到了这一点,但最终的计划在很大程度上没有受到社区反馈的影响。

国家卫生研究院是有史以来最卓越的机构之一,作为世界上最大的生物医学研究组织,它在塑造人类健康的全球进程中具有独特的地位。我很荣幸在国家卫生研究院的一个小项目中扮演了一个小角色(T4 国家卫生研究院数据共享中心),这个项目的使命是协调并提供有价值的国家卫生研究院数据。如果这个项目成功,它肯定会加快生物医学发现的步伐。每天,我们都看到技术(如人工智能和深度学习)能够实现洞察——并有可能治愈——这在 5 年或 10 年前是不可思议的。阻碍这一潜力的是将 NIH 数据定位为可访问并与新的强大的数据挖掘方法兼容的艰巨任务;政策没有跟上科学的步伐。看到 NIH 研究人员和项目工作人员的奉献精神,我知道进展是可能的,但我的乐观主义通常遭到怀疑。我在许多谈话中(公开的和私下的)研究人员对 NIH 能否开展数据科学基础设施项目表示怀疑。像 caBIG 和大数据到知识(BD2K)这样的项目的跟踪记录留下了很多批评的空间。更糟糕的是,许多人似乎认为他们的声音在改变国家卫生研究院的政策和政治过程中无关紧要。

NIH 需要关注其决策过程——使其对社区更加透明和负责。成功在于认识到,虽然以前收集反馈并根据反馈采取行动的方法可能有助于做出科学决策,但处理数据的问题实际上更多的是社会问题,而不是科学或技术问题。毕竟,过去 5 年最重要的数据创新之一是公平的概念——不是一套技术,而是一套原则。数据共享的理念不仅仅是托管一个数据仓库,而是一个信任的组织,致力于通过共享知识实现最好的科学和病人结果。

希望 NIH 能够在大数据科学的 21 世纪范式中“走出自己的路”——技术将解决问题,但人们(未能作为一个社区一起工作)将使它失败。

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

回复:关于 NIH 资助或支持的研究的数据管理和共享政策草案拟议条款的信息请求书*

2018 年 12 月 10 日

亲爱的同事们:

NIH 的使命是“寻求关于生命系统的本质和行为的基础知识,以及这些知识在增进健康、延长寿命、减少疾病和残疾方面的应用。”NIH 认识到数据前所未有的快速发展带来的挑战(和机遇),制定数据管理和共享政策是非常合适的。在阐述我对拟议条款文件的具体回应之前,我想提出一个我尚未看到解决的关键问题——一个限制 NIH 获得最佳建议的问题。

NIH 在数据实践领域收集反馈的机制已经引起了对该组织是否愿意或有能力按照社区建议采取行动的怀疑。自 2018 年 6 月发布 NIH 数据科学战略计划以来,我个人的经验是,调查人员——特别是来自生物信息学、计算生物学和数据科学社区的调查人员——对所做的评论没有导致最终计划的有意义改进表示失望。显然,NIH 的行动不应该基于我的个人轶事。然而,尽管 NIH 一直在努力征求意见(最重要的是,公开发表意见),但从我采访过的调查人员或阅读的 NIH 公告来看,没有任何迹象表明最终决定将如何做出。在缺乏更透明的流程的情况下,对这种做法最冷嘲热讽的解读是,NIH 可以无视机构群体的建议,继续遵循预先确定的议程。如果调查人员怀疑 NIH 的承诺,NIH 最需要听到的许多意见将永远不会提供。我说 NIH 是作为一个整体,因为即使个别机构的行为可能是他们自己的,他们都有助于社区在这些过程中对信念和善意的判断。

我的主要建议是 NIH 不仅要披露对该 RFI 和其他 RFI 的意见,还要向机构群体公开完整的解释,说明建议是如何实施的以及实施的原因。由于我在之前的回答中阐述的几个原因**,NIH 在制定数据相关政策方面处于“结构性”劣势。理想情况下,NIH 会在 RFI 之前提出一个合理的实施计划,描述如何审查和实施建议,并贯彻其响应机构群体建议的承诺。

不幸的是,支持 NIH 资助的科学的数据和计算基础的大规模计划没有成功的记录(例如 caBIG、BD2K 等。).我仍然对数据共享空间抱有很高的期望(如果它能够为了 NIH 的利益朝着社区驱动的方向发展,而不是为了任何人的利益而被 NIH 纠缠)。如果不采取更多措施提高响应性和开放性,国家卫生研究院就有可能成为一个无关紧要的政策制定者,并且随着国内和全球产生的数据使国家卫生研究院直接资助的项目相形见绌,国家卫生研究院将会退居被动地位。我希望 NIH 决定思考如何跳出框框思考(或 NIH 园区),通过更加透明和负责任的过程建立社区共识。我想我看到事情正在发生,并希望得到进一步的保证。

具体评论

科学数据的定义

软件是科学数据定义中缺失的一个概念。在某种意义上,软件是元数据的一种形式。例如,在湿实验室实验中,细胞系或抗体批次的描述可能是数据集的关键描述符。通常,科学数据与用于产生该数据的软件是唯一结合的——从可能涉及“原始”序列数据产生的碱基调用软件,到用于产生任何几个下游分析产品的软件。明确承认这种独特的关系将有利于科学数据的定义。

与软件相关,起源也是计划提案中缺少的一个概念。科学数据以其生命周期为特征(见https://www . dataone . org/data-life-cycle 上的一个详细说明)。.)特别是,在将“科学”数据定义为一个动态概念时,不断版本化和更新的需求值得考虑。

数据管理和共享计划需求

关于“相关工具软件和/或代码”:

-对于分析中使用的(但不是开发的)任何软件/代码,应要求提供软件的完整描述,包括版本号、源代码/二进制文件的链接等。

-如前所述,NIH 应该大力鼓励使用免费提供的开源软件。由于资助者和机构正在向所有开放获取出版物转移,可能值得考虑 NIH 如何才能实现使用开放软件和数据格式的要求。

-我同意以下建议:在必须使用专有软件的情况下,应提供解释。

-应进一步建议对分析中使用的软件进行全面记录,例如通过提供版本控制脚本、生成文件或工作流语言描述等。在可能的情况下,研究人员应利用现代再现方法,如容器(如 Docker、Singularity)、虚拟机图像等。文件应遵循增加分析重现性的建议,如最低信息标准(如生物学和生物医学调查的最低报告指南;http://www . nature . com/NBT/journal/v 26/n8/full/NBT . 1411 . html,或 GA4GH、研究数据联盟等正在制作的更多更新推荐。).

-如果任何脚本或其他软件是作为调查的一部分开发的,则必须附有适当的开源许可证,并且在提交任何预印本时和/或在提交供同行审查时可在公共存储库中获得。无论发布状态如何,任何代码/软件都应在资金结束时可用。关于版本控制和容器化的相同建议在这里也适用。

关于“数据保存和访问”:

-没有关于调查人员应如何处理不需要保留的数据的评论。应该清楚地描述调查人员如何确定哪些中间或衍生数据产品不需要保存。可能还需要具体的建议来记录敏感数据将如何被丢弃,但这些可以通过其他法律和政策要求患者数据来充分解决。

-虽然解决了唯一标识符的问题,但应该有更具体的指导,说明何处需要标识符,以及什么定义了适当的长期存储解决方案。

-应该有一个关于如何实现大容量(> 1GB)共享的描述?)数据集。对于非常大的数据集,共享变得越来越困难。虽然研究人员可能没有义务使每个数据集同等可用,但应该有可能表征(或许 NIH 可以实施评分系统)允许数据共享的分类。在 NIH 数据共享区和其他地方开发的公平度量项目已经在为这些目标而努力。

关于“数据保存和访问时间表”:

-由 NIH 资助的数据(受保护的记录除外)必须公开。

NIH 在实施新数据管理和共享政策的各个部分时需要考虑的最佳时机,包括可能的分阶段采用,以及可能的分阶段如何与数据基础设施、资源和标准的必要改进相关联。

-我同意文件中的建议,即对于外部赠款,DMP 可以被评估为可接受/不可接受,并作为额外审查考虑的一部分。

NIH 需要投资培训和/或学习材料,学习如何有效地评价数据管理计划。一般来说,研究部门或其他小组(或项目官员)中的大量评审员可能没有接受过计算科学或数据管理实践方面的培训。因此,他们可能不是数据管理计划最有效的裁决者。NIH 可以通过提供培训来提高审查的质量。数据木工、DataONE 等团体。有可能适用于此的培训材料/课程。

NIH 应投资于培训,包括学习资源的开发,以协助研究者开发和执行数据管理计划。

附加建议

-数据管理/政策环境非常动态。NIH 应对其指南进行年度审查。

-数据管理政策指南应直接征求公认组织的建议,包括研究数据联盟、GA4GH、ELIXIR、Force11 和其他组织。在这方面,正式的咨询机制可能是合适的。

真诚地

贾森·威廉姆斯

冷泉港实验室

*此回复仅代表我自己的个人观点

**在这里查看我和其他社区成员对 NIH 数据计划的评论:https://github . com/JasonJWilliamsNY/2018 _ NIH _ Data science _ RFI

推荐引擎——在引擎盖下

原文:https://towardsdatascience.com/recommender-engine-under-the-hood-7869d5eab072?source=collection_archive---------2-----------------------

我们中的许多人在日常生活中被各种各样的推荐轰炸,无论是在电子商务网站还是社交媒体网站上。有些建议看起来很相关,但有些建议会让人产生各种情绪,从困惑到愤怒不等。

基本上有两种类型的推荐系统,基于内容和协同过滤。两者各有利弊,这取决于您想要使用它们的环境。

基于内容的:在基于内容的推荐系统中,当向用户推荐项目时,项目的关键字或属性被考虑在内。所以,简而言之,这就像是推荐相似的项目。假设您正在阅读一本关于数据可视化的书,并想寻找同一主题的其他书籍。在这种情况下,基于内容的推荐系统将是合适的。

Image source : https://blog.guillaumeagis.eu/recommendation-algorithms-with-apache-mahout/

协同过滤:说到点子上了,下图就是最好的例子。客户 A 购买了书籍 x、y、z,客户 B 购买了书籍 y、z。现在,协同过滤技术会向客户 B 推荐书籍 x。这是协同过滤的优点和缺点。如果书 x 是一本非虚构的书,而顾客 B 的喜好完全是虚构的书,这并不重要。建议的相关性可能正确,也可能不正确。通常许多公司使用这种技术,因为它允许他们交叉销售产品。

Image adapted from https://www.balabit.com/blog/recommender-systems-in-anomaly-detection/

开发基于内容的图书推荐系统——理论

假设您的图书馆中有一批数据科学书籍,假设您的朋友读了一本关于神经网络的书,并希望阅读同一主题的另一本书,以积累他/她的相关知识。最好的方法是实现一个简单的基于内容的推荐系统。

我们将在这里看三个重要的概念,这三个概念涉及到建立这个基于内容的推荐系统。

  • 向量
  • TF-IDF
  • 余弦相似性

矢量

基本思想是将文本或单词转换成向量,并在向量空间模型中表示。这个想法太美了,从本质上来说,向量的这个想法使得机器学习和人工智能的快速发展成为可能。事实上,Geoffrey Hinton(“深度学习之父”)在 MIT technology review 的一篇文章中承认,多伦多的人工智能研究所被命名为“向量研究所”,因为向量的美丽属性在深度学习和神经网络的其他变体领域帮助了他们。

TF — IDF

TF- IDF 代表术语频率和逆文档频率。TF-IDF 有助于评估文档中某个单词的重要性。

TF —词频

为了确定术语/单词在文档中出现的频率,并以向量形式表示文档,让我们将其分解为以下步骤。

步骤 1 :创建一个存在于整个文档空间的单词字典(也称为单词包)。我们忽略了一些常用词,也称为停用词,如 the,of,a,an,is 等,因为这些词非常常见,对我们选择重要词的目标没有帮助

在当前的例子中,我使用了包含 50 本书标题的文件“test1.csv”。但是为了证明这一点,只需考虑由 3 个书名(文档)组成整个文档空间。所以 B1 是一个文档,B2 和 B3 是其他文档。B1、B2、B3 共同构成了文档空间。

B1 —推荐系统

B2——统计学习的要素

B3 —推荐系统—高级

现在创建这些词的索引(停止词被忽略)

1.推荐人 2。系统 3 要素 4。统计学 5。学习 6。先进的

第二步:形成矢量

词频帮助我们识别该词或词在文档中出现的次数,但也有一个固有的问题,TF 更重视频繁出现的词/词,而忽略了罕见词/词的重要性。这不是一个理想的情况,因为生僻字包含更多的重要性或信号。这个问题由以色列国防军解决。

有时一个单词/术语在较长的文档中比在较短的文档中出现得更频繁;因此,执行术语频率标准化。

TFn =(术语 t 在文档中出现的次数)/(文档中的总术语数),其中 n 表示归一化。

IDF(逆文档频率):

在 IDF 定义的一些变体中,在文档中没有出现术语的情况下,将 1 添加到分母,以避免被零除的情况。

基本上,一个简单的定义是:

IDF = ln(文档总数/包含术语 t 的文档数)

现在,让我们从我们自己的字典或单词包中取一个例子来计算 IDF

我们有 6 个术语或单词,如下所示

1.推荐人 2。系统 3 要素 4。统计学 5。学习 6。先进的

我们的文件是:

B1 —推荐系统

B2——统计学习的要素

B3 —推荐系统—高级

现在 IDF(w1)= log 3/2;IDF(w2)= log 3/2;IDF(w3)= log 3/1;IDF(W4)= log 3/1;IDF(W5)= log 3/1;IDF(w6) = log 3/1

(注:取自然对数和 w1..w6 表示单词/术语)

然后我们又得到一个向量,如下所示:

= (0.4054, 0.4054, 1.0986, 1.0986, 1.0986, 1.0986)

TF-IDF 重量:

现在最后一步是得到 TF-IDF 的重量。TF 向量和 IDF 向量被转换成矩阵。

那么 TF-IDF 重量表示为:

TF-IDF 权重= TF (t,d) * IDF(t,D)

这与我们通过执行以下 python 代码获得的矩阵相同:

tfidf_matrix = tf.fit_transform(ds['Book Title'])

余弦相似度:

余弦相似性是两个非零向量之间相似性的度量。向量表示的一个美妙之处是,我们现在可以看到,两个句子有多紧密的联系,基于它们各自的向量所成的角度。

余弦值的范围从-1 到 1。

因此,如果两个向量形成一个角度 0,那么余弦值将是 1,这反过来意味着句子彼此密切相关。

如果两个向量是正交的,即 cos 90,则意味着句子几乎是不相关的。

开发基于内容的图书推荐系统—实现

下面是要点链接,我用 python 写了几行代码来实现一个简单的基于内容的图书推荐系统。我添加了注释(在#后面的单词)来清楚地说明每一行代码在做什么。

输出

test1.csv 中的 id 和书名列表如下(显示了 20 行)

既然您已经阅读了这篇文章,您可能也喜欢阅读……..(嗯没关系;) )

以下链接也提供了相同的文章:

[## 如何建立一个简单的基于内容的图书推荐系统

我们中的许多人在日常生活中被各种各样的建议轰炸,无论是在电子商务网站还是社交媒体上…

www.linkedin.com](https://www.linkedin.com/redir/redirect?url=https%3A%2F%2Fwww.linkedin.com%2Fpulse%2Fcontent-based-recommender-engine-under-hood-venkat-raman&urlhash=wCLR&_t=tracking_anet)

来源:

TF-IDF

卡格尔

向量空间模型

深度学习 4j

Sklearn 余弦相似度

sk learn tfidf 矢量器

马克·李约瑟博客

麻省理工科技评论

代码链接:https://gist . github . com/venkara fa/0da 815727 f1 ee 098 b 201 c 371 b 60 B2 d 72

推荐系统:利用不确定性探索未知

原文:https://towardsdatascience.com/recommender-systems-exploring-the-unknown-using-uncertainty-d3177a68143a?source=collection_archive---------18-----------------------

现在我们知道了存在哪些不确定性类型并且学会了一些建模它们的方法,我们可以开始讨论如何在我们的应用中使用它们。

在本帖中,我们将介绍勘探开发问题,并向您展示不确定性如何帮助解决这个问题。我们将重点探索推荐系统,但同样的想法也可以应用于强化学习的许多应用中——无人驾驶汽车、机器人等。

问题设置

推荐系统的目标是推荐用户可能会发现相关的项目。在 Taboola,相关性是通过点击来表达的:我们显示一个包含内容推荐的小部件,用户可以选择是否要点击其中一个项目。

用户点击一个商品的概率叫做点击率 (CTR)。如果我们知道所有商品的点击率,那么推荐哪些商品的问题就很简单了:简单地推荐点击率最高的商品。

问题是我们不知道 CTR 是什么。我们有一个模型来估计它,但它显然不是完美的。不完美的一些原因是推荐系统固有的不确定性类型,我们在本系列的第一篇文章中讨论过。

开发与勘探的权衡

所以现在我们面临着一个具有挑战性的情况——一个我们在日常生活中都很熟悉的情况:想象你刚刚走进一家冰激凌店。你现在面临着一个至关重要的决定——在大约 30 种口味中,你只需要选择一种!

你可以采取两种策略:要么选择你最喜欢的口味,你已经知道这是最好的;或者探索你从未尝试过的新口味,也许会发现一种新的最佳口味。

这两种策略——开发和探索——也可以在推荐内容时使用。我们可以利用具有高点击率和高确定性的项目——可能是因为这些项目已经向类似的用户展示了数千次;或者我们可以探索过去没有向很多用户展示过的新项目。将探索融入到你的推荐策略中是至关重要的——没有探索,新的商品就没有机会与更老、更熟悉的商品竞争。

让我们探索探索的方法

你能实现的最简单的探索-开发方法是ϵ-greedy 算法,在这里你分配ϵ流量的百分比来以随机的方式探索新的项目。剩下的流量留给开发。

尽管不是最佳的,这种方法很容易理解。它可以作为更复杂方法的坚实基础。那么,我们如何以更明智的方式寻找好的商品呢?

Looking for good items in a wise manner

一种更先进的方法——置信上限(UCB)——使用不确定性。每个项目都与其预期的 CTR 和该 CTR 上的置信界限相关联。置信界限反映了我们对项目 CTR 的不确定程度。普通 UCB 算法通过单独使用经验信息来跟踪预期的点击率和置信界限:对于每个项目,我们跟踪经验点击率(相似用户点击它的百分比),并且通过假设二项式分布来计算置信界限。

以你经常点的纯巧克力口味为例。你知道它很好——你给了它 8 颗星(满分 10 分)。今天,一种新的口味已经到来。你没有关于它的经验信息,这意味着它可以是 1 到 10 颗星中的任何一颗。利用这个置信区间,如果你想探索,你会选择新口味,因为有可能是 10 星口味。

这种策略正是 UCB 所要做的——你选择具有最高置信上限值的项目——在我们的例子中,置信上限超过 CTR 估计。这种策略背后的动机是,随着时间的推移,经验的 CTR 将趋向于真实的 CTR,并且置信界限将缩小到 0。经过足够的时间,我们将探索一切。

另一种流行的方法是汤普森抽样方法。在这种方法中,我们使用项目 CTR 的整个估计分布,而不仅仅是一个置信界限。对于每个项目,我们从其分布中抽取一个 CTR。

当可用项目的数量固定时,这些方法可能工作得很好。不幸的是,在 Taboola,每天都有数以千计的新商品进入系统,而其他商品则被淘汰。当我们得到一个项目的合理置信界限时,它可能会离开系统。我们的努力将会白费。这就像是在进行一次世界旅行,每天都要去一个新城镇,那里有大量的冰淇淋可供探索。恐怖啊!

我们需要一种方法来估计一个新项目的点击率,而不需要展示它一次。我们需要一些美食评论杂志,引导我们通过自助餐的内容推荐。

考虑一种刚刚上市的新型巧克力口味。既然你知道你喜欢巧克力,你很有可能也会喜欢这种新口味。在香草 UCB 方法中(不,那不是一种味道的名字),你不能推断它——你只依赖经验信息。

在未来的文章中,我们将详细阐述如何使用神经网络来估计一个新项目的 CTR,以及不确定性的水平。利用这种不确定性,我们可以应用 UCB 方法来探索新的项目。与依赖经验数据的普通 UCB 不同,这里我们可以使用模型的估计来避免显示点击率低的项目。我们可以赌我们认为会赢的马。

🐎

在线指标和结果

我们如何知道我们对新项目的探索有多好?我们需要一些勘探吞吐量指标。在 Taboola 中,我们有 A/B 测试基础设施,支持在不同流量份额上运行的许多模型。

回到冰淇淋!假设你带了你的朋友来帮助你探索不同的口味。显然,如果你的一个朋友随机选择口味,他有最好的探索吞吐量,但不是最聪明的。另一个朋友点了别人觉得好吃的口味,他最喜欢,但对探索的努力毫无贡献。

在 Taboola,我们测量探索吞吐量如下:对于每个已经显示足够多次的项目,并且在足够多的不同上下文中(例如,不同的网站),我们声明该项目已经通过了探索阶段。接下来,我们分析哪些模型促成了这一成功。为了计数,一个模特必须展示那个项目足够多的次数。

从这个角度来看,模型的吞吐量被定义为它所贡献的项目数量。

使用这个度量标准,我们能够断言随机显示项目确实会产生最好的吞吐量,但是有坏项目的趋势。不使用 UCB 方法的模型显示出好的项目,但是吞吐量较差。具有 UCB 的模型在吞吐量方面介于两者之间,与非 UCB 模型相比,仅显示了稍微差一些的项目。

因此,我们得出结论,我们的 UCB 模型在探索新项目和选择好项目之间有一个很好的权衡。我们相信,从长远来看,这种权衡是值得的。

最后的想法

对于推荐系统领域的许多公司来说,探索-开发问题是一个令人兴奋的挑战。我们希望我们的进步将有助于其他人向他们的用户提供最好的服务。我们相信这是尚未完成的大旅程中的一小步,我们对这个领域在未来几年将会呈现什么样的形态很感兴趣。

在本系列的下一篇文章中,我们将详细阐述用于估算 CTR 和不确定性的模型,敬请关注。

这是与我们在今年 KDD 会议的研讨会上提交的论文相关的系列文章的第三篇: 深度密度网络和推荐系统中的不确定性

第一篇帖子可以在这里找到

第二篇帖子可以在 这里找到

原载于engineering.taboola.com由我和 约尔泽尔德斯

推荐系统:从过滤泡沫到意外收获

原文:https://towardsdatascience.com/recommender-systems-from-filter-bubble-to-serendipity-4131930a738e?source=collection_archive---------14-----------------------

推荐系统为我们在互联网上看到的内容的日常互动提供了动力。随着每天创建超过 2.5 万亿字节的数据,仅过去两年就占了全球数据的 90%[1]。我们生产的内容是不可能在一生中消费的,这使得推荐系统不可避免。然而,正如本叔叔所说,权力越大,责任越大。在这里,我谈谈推荐系统引发的一些实践和伦理问题,以及我们如何着手解决这些问题。

推荐系统是做什么的?

推荐系统处于脸书、亚马逊、Spotify 等内容服务网站的最前沿。与用户互动。据说亚马逊网站 35%的收入是由其推荐引擎产生的[2]。在这种环境下,网站的目标是尽可能提供最好的个性化内容,这一点至关重要。

用户想要什么

作为一个超级推荐系统极客,每当我看到一个好的推荐系统时,我总是感到惊喜。我对消费大量内容感兴趣(我也是这样),但是一天中没有足够的时间让我亲自浏览所有可供我消费的内容。我希望推荐系统能够理解我在那一刻真正想读/听/消费的内容,甚至在我不知道自己想要什么的时候。

My beautiful Spotify generated playlists

过去,当内容可供您使用时(无论是通过搜索结果,还是通过其他方式搜索可用内容,如前 100 名列表),您必须使用某种过滤来缩小结果范围。这种过滤通常采用更长、更明确的搜索词、日期限制(包括和排除某些标签)等形式。

那些日子已经过去了。

作为一名用户,我希望能帮助我整理网站上的所有内容。我相信当我在谷歌上搜索std::list时,我会找到相关链接。与许多人相反,我也喜欢个性化广告。如果这些个性化广告真的让我意识到我正在失去生活中的一些重要物品,我会很乐意购买。然而,这也不意味着我喜欢看到同样的红木椅子跟随我在 12 个不同的网站上,仅仅因为我在 2003 年看过一把椅子。

听起来像被宠坏了吗?也许吧。但这就是我们现在生活的环境。当生成的内容呈指数级增长时,这是我们保持高效的唯一方法。

公司想要什么

如上所述,推荐系统为世界上许多主要品牌创造了大量收入。对某些人来说,这是用户与产品交互的最前端和最中心的方式(例如:脸书的新闻订阅)。对于其他人来说,它可能通过个性化(例如:谷歌的搜索引擎)来补充产品的核心功能,或者可能是尽可能长时间保持用户参与的一种方式(例如:YouTube 的 up next 功能)。

无论你如何定义它,企业就是企业,它们被不同于消费者的目标所驱动。改善客户体验对所有企业来说都是至关重要的,对于基于 web 的企业来说,这通常会导致试图使每个用户的体验更加个性化,从而产生对推荐系统的需求。

到目前为止一切顺利,对吧?

让我们仔细看看一个普通的网站如何利用推荐来改善用户体验:

  1. X 公司意识到,他们生成的内容比一个人能够互动的内容要多。此外,他们的竞争对手正在使用个性化,以便他们的用户可以更容易地访问相关内容。
  2. X 公司尝试个性化他们的搜索结果。他们选择一种可靠的方法,如矩阵分解,并利用他们的历史数据来训练模型。
  3. 试验取得了巨大的成功!A/B 测试显示收入增长了 4%,他们的月活跃用户增长了 13%!
  4. X 公司在他们的个性化方面投入了更多的资源。多个数据科学家正在致力于实现更好的机器学习模型,随着他们获取越来越多的数据,这些模型对他们的历史数据的执行越来越好。
  5. 他们将验证自动化,这样他们就可以以任何组合设置特定的收入/用户/转化率/其他 KPI 目标,并尝试使用 A/B/n 测试来优化它,这种测试会自动整合任何新的机器学习模型,不断提高推荐的质量,同时实现越来越好的目标。

image credit

这确实是梦寐以求的场景。您拥有可以为您的机器学习模型提供一些训练目标(损失函数)和测试目标的历史数据点,即使您知道它们不一定是推荐系统真实世界价值的良好指标,您也有 A/B 测试来优化真实世界的结果。这里的一切都可以定量分析。

嗯,期待推荐的“质量”。说到这里,你怎么定义推荐的质量呢?

推荐系统应该做什么?

如前所述,这种方法存在一些实践和伦理问题。

在像谷歌这样的庞然大物的背景下,推荐系统有能力影响我们社会的结构,不幸的是,我们还没有理解它如何影响社会的全部含义。很明显,谷歌为互联网上的大量信息流动提供了便利,因此被谷歌切断联系是一件大事。但是,当谈到量化这种信息流的影响时,我们被难住了。

这并不意味着我们不能思考推荐应该是什么样子的,也不能讨论推荐的一些重要概念。请记住,所有这些概念都是依赖于产品的:你必须选择它是与你相关还是与你的客户相关。

访问相关内容

这是显而易见的,但是为了完整起见,这是一个不应该被忽略的领域。如果你有一个推荐系统,你要确保它推荐的内容与用户相关。如果我只看奇幻类的书,那么我得到的推荐应该主要是偏向奇幻类的。这并不意味着我不喜欢偶尔的动作片或非小说类的推荐,但是我不应该看到我的推荐被这样的类型所主导。

这种推荐的罪魁祸首之一是推荐的协同过滤方法。继续这本书的例子,如果在其余的幻想读者中有一个占主导地位的第二类型,即使你不想消费它,协同过滤也会向你推荐这个类型。更糟糕的是,如果推荐系统依赖于明确的评分(1-5),你通常不得不消费并给它评分,以摆脱这样的推荐。

解决这个问题的一种方法是使用一种混合模式,这种模式也利用基于内容的推荐,这是我们为 Books2Rec 采用的解决方案。这样,您可以平衡协同过滤和内容相似性。

平衡收益递减

收益递减是计量经济学和心理学中一个广为人知的概念。这个概念很简单:你拥有的东西越多,你想要的就越少。

举个个人的例子,我真的很喜欢听一首歌,直到我厌倦他们,或者痛饮朋友,直到我根本无法处理罗斯和瑞秋之间的另一场争吵。

image credit

当然,这似乎与之前获得相关推荐的概念相违背;这将达到收益递减点。这里的关键是时间:你可能会厌倦在一次访问网站时看到相同类型的推荐(基于你的历史数据),但当你一周后回来时,你不想从远离你的历史数据的某个地方开始。

推荐系统通常区分历史推荐和上下文(基于会话的)推荐。历史推荐器利用你的全部历史数据来找到你想看的下一个节目,而上下文推荐器会查看你当前的会话(就像你在 Spotify/YouTube 会话的最后一个小时),并预测现在最适合你的节目

当然,这两个系统不是一成不变的,肯定会有重叠,而合适的推荐系统介于两者之间。情境模型在机会成本低、快速消费可行的情况下效果最佳。收益递减也是情境模型的一个更大的问题。

长期回报

一般来说,推荐者的另一个问题是最佳推荐优先策略。想象一个推荐系统,它可以完全捕捉你在一个视频中的价值,并向你推荐你将会观看的最好的 5 个视频。

当你消费完最好的内容后会发生什么?

推荐系统会继续向你推荐相同的类型的内容,但是因为你已经消费了最好的,所以它们中的每一个都会比上一个

如果做得太好,推荐系统会减少你未来的享受。

what happens when no new content is added to a website, image credit

当然,现在每天都有大量的内容产生,很有可能对你来说最好的内容还没有产生。但事实是,对你来说,前 N 名内容(或对普通大众来说,前 N 名内容)是一个很难进入的列表,通过分隔最佳内容,你可能会获得更好的整体享受。

另一种思考方式是,我们应该把我们的建议的长期回报最大化作为目标。以这种方式,很容易将强化学习与 MDP(马尔可夫决策过程)和土匪等算法进行类比,特别是在探索与利用方面。毫无疑问,我们可以看到近年来人们对推荐系统的强化学习产生了浓厚的兴趣。

过滤气泡

前一种情况的另一个结果是一种被称为过滤器泡沫的现象。过滤气泡是由伊莱·帕里泽(Eli Pariser)创造的,并因他的同名书籍而闻名。过滤气泡是指你被困在一个气泡中,只有个性化算法(过滤器)认为你会喜欢的信息才能通过。随着你给系统越来越多的数据,你的泡泡变得越来越小,成为利基中的利基。你被困在一个正反馈循环中,无法逃脱。

image credit

这不仅会因为没有显示您可能喜欢的内容而限制您的选择,随着时间的推移,它会使您的兴趣趋于一致,从而导致您对不同类型的内容失去兴趣,这又会减少您的选择。更糟糕的是,因为回报递减,你开始越来越不喜欢推荐给你的内容。

不过,一切并没有失去。作为推荐系统的设计者,即使我们不能可靠地解决这个问题,我们也可以给用户一条出路。这并不需要太花哨——即使是一个不偏不倚的去个性化的搜索系统也可能给用户足够的工具来获取他们过滤泡沫之外的内容。即使您依赖隐式评级,用户也可以随着时间的推移将推荐转移到更多样化的地方。

注:一个与政治联系更紧密的相关术语是回音室,它与人们与志趣相投的人的互动以及越来越相信他们的想法是正确的有更多的关系。我不会掩盖这一点。

多样化

多元化是我们对抗过滤泡沫和收益递减效应的一种方式。不幸的是,它不是推荐系统的自然副产品;相反,我们必须为此而努力。

My YouTube recommendations

我观察到,根据用户口味的多样性,他们可以大致分为两类:

社交用户是你的典型用户,他们有一些松散定义的流派偏好,但对消费排名前 N 名的项目感到满足。如果某个内容很受欢迎,并且/或者已经被他们的朋友分享了,他们也想消费它。如果将它们的味道分布建模为高斯混合模型,则它们会有浅峰和大量重叠。

超级用户更关心消费他们最关心的内容。与社交用户相比,他们的数量较少,但他们仍占相当大的一部分。这些用户中的一些人一开始就有各种各样的兴趣。根据高斯混合模型,它们会有很高的峰值,中间会有很多死区。

保持和培养这些不同的兴趣符合我们的最佳利益。一些研究人员明确地模拟了这些口味[3],而另一些人则试图更有机地学习它们。正如稍后将解释的那样,即使对有高度特定兴趣的用户来说,强制使用某种多样性可能仍然符合您的最佳利益。

通过优化平均值,您最终会牺牲超级用户所依赖的高保真度推荐。

多样性的问题在于,很难准确衡量一组建议的多样性。在最近一集的 TWiML AI 中,Pinterest 数据科学家 Ahsan Ashraf 谈到了一套准则,你可以用它来检查任何推荐系统的健全性——多样性度量对:

  1. 稳定性:当我们给一个推荐系统相同主题/类型的项目时,它是否收敛到那个主题,导致推荐系统“过度适应”那个主题?收敛速度有多快?这些建议的差异有多大?
  2. 灵敏度:假设你有两个题目 AB ,从 AA的 100 项开始。随着您从 B 添加越来越多的项目,这些建议是否涵盖了整个范围(从 B 的一小部分到所有 B s)?你的多样性是在 50:50 的比例下最大化,在 100:0 和 0:100 下最小化吗?**
  3. 理智:完全随机的推荐比用户的平均推荐更多样化吗?特定主题列表的多样性是否低于给用户的平均建议?

意外收获

从多样性向前迈了一步,我们来到了意外收获的概念,这是在没有寻找的时候发现了一些有价值或有益的东西,一个快乐的巧合。它是找到让你震撼的东西。

我喜欢把意外收获分成两类:立即的和最终的。即时的意外收获,嗯,立即发生。你走在街上,不知道为什么,你抬头一看,看到了帝国大厦。

最终的意外收获(这可能是一个误称,但我还没有找到一个更好的名称来形容它)是当你回顾你的生活,并意识到一个随机事件引导你踏上了塑造你的一部分的旅程。

为了认识到意外收获的重要性,想想那个让你发现你最喜欢的艺术家或你最好的朋友的偶然事件,或者当你意识到这就是你一直在寻找的一切的那一刻。

如果我们作为推荐系统的设计者能够促成这一事件,那不是很好吗?

从分析的角度来看,我们可以用一个代理来代表实际的意外收获(这是很难量化的),用户听说过该项目的概率很低,而用户喜欢该项目的概率很高。然后,问题变成了计算这两个概率,我们可以使用任何数量的方法来近似。

当然,这种代理并不理想,目前正在进行研究,试图找出一种更好的方法来解决这个问题。我们知道的一件事是,我们需要某种多样性或随机性来促进这一点。

显然,这使得某些问题比其他问题更容易解决。歌曲推荐比书籍推荐更容易实验。这是由于经济学家所谓的“机会成本”。每次你与某物互动时,你选择不与他人互动。在音乐中,如果你全神贯注地听这首歌,你可能会损失 4 分钟的时间,你甚至可以选择跳过它。多亏了音乐流媒体服务,你可能不需要额外付费就能接触到这些内容。

然而,一本书是一项长期投资。你可能要花 100 页才能意识到这本书并不适合你,到那时你可能已经花了几个小时和 10 美元来买这本书。因此,重要的是(平均而言)在做书籍推荐时要比音乐推荐更保守。

算法混淆的案例研究

普林斯顿大学的研究人员最近发表的一篇论文[4]讨论了推荐系统产生的反馈回路的进一步影响。更具体地说,他们研究了当模型试图捕捉用户偏好时发生的混淆,而没有考虑到用户面临的选择也是由模型产生的这一事实,从而削弱了推荐对用户行为的因果影响。

image credit

该文件提出的主要主张如下:

  1. 并非所有算法都受益于使用混杂数据(即,作为推荐系统的结果而生成的数据)的再训练。
  2. 使用混淆的数据来评估模型会偏向于将数据向适合算法的方向移动,从而创建不应该存在于底层数据中的反馈循环。
  3. 先前的反馈循环使单个用户和整个用户群都变得一致。

在不涉及细节的情况下,研究人员模拟了被推荐项目的用户之间的现实交互序列,推荐系统获得这些交互的结果,并使用该数据和随着时间的推移引入的新项目更新其推荐。

研究人员表明,就总效用而言,使用混杂数据在基于内容的模型和社会(基于信任)模型中效果最好,但在与矩阵分解模型一起使用时没有明显优势。此外,他们表明,与使用不同模型生成的混杂数据相比,使用同一模型生成的混杂数据评估模型会导致分数的更大提高。

因此,用混杂的数据评估你的模型可能会夸大你的模型的性能。

对于用于研究的公开可用数据集来说,这也是一个令人担忧的情况,这些数据集本身可能由于用于创建数据的推荐系统而被混淆,因此可能对某些类型的模型有隐藏的偏见。

研究人员还测量了同质化对总效用的影响,声称同质化是好的,因为它意味着模型正在学习底层模式,但也可能阻止发现可能对用户有益的新项目。

他们发现,对于除随机模型之外的所有 4 种方法,均一化(捕获为下图的 y 轴)与总效用(x 轴)负相关,根据定义,随机模型不依赖于任何模型。

image credit

因此,重要的是,我们要尽可能地保持我们的建议的多样性,但同时,要用对用户有意义的建议来平衡它们。同样,我们可以用强化学习方法来类比探索/利用问题。如果我们真的想达到最好的结果,我们需要找到正确的平衡并努力保持它。

结论

由于学术界和工业界越来越多的关注,我们今天有很多工具来提供建议,并且对我们的工具有了更好的理解。然而,在构建推荐系统时,我们还没有完全理解我们的选择的后果。天下没有免费的午餐,我们的选择总会有后果,即使我们无法立即看到。

我希望这篇文章能让你对如果你想给用户最好的体验,你需要留意什么有一些大概的了解。作为推荐系统的设计者,我们有能力影响什么能到达用户,什么不能。明智地使用这一权力取决于我们。

参考

1. Domo —数据从不睡觉
2。麦肯锡
3。代表不同兴趣用户的混合口味模型
4。推荐系统中的算法混杂如何提高同质性并降低效用

原载于 2018 年 10 月 9 日dorukkilitcioglu . github . io**

PyTorch 中使用深度学习的推荐系统

原文:https://towardsdatascience.com/recommender-systems-using-deep-learning-in-pytorch-from-scratch-f661b8f391d7?source=collection_archive---------11-----------------------

Photo by Susan Yin on Unsplash

推荐系统(RS)已经存在很长时间了,最近深度学习的进展使它们更加令人兴奋。矩阵分解算法一直是 RS 的主力。在本文中,我假设您对基于协同过滤的方法略知一二,并具备在 PyTorch 中训练神经网络的基本知识。

在这篇文章中,我的目标是向您展示如何从头开始在 PyTorch 中实现 RS。这篇文章中提出的理论和模型在这篇论文中可用。这里是本文的 GitHub 库

问题定义

给定用户过去看过的电影记录,我们将构建一个推荐系统,帮助用户发现他们感兴趣的电影。

具体来说,给定 < userID,itemID > 出现对,我们需要为每个用户生成电影的排序列表。

我们将问题建模为 二元分类问题 其中我们学习一个函数来预测特定用户是否会喜欢特定的电影。

Our model will learn this mapping

资料组

我们使用 MovieLens 100K 数据集,该数据集有来自 1000 个用户对 1700 部电影的 100,000 个评级。数据集可以从这里下载。

评级以 < userID、itemID、评级、时间戳> 元组的形式给我们。每个用户至少有 20 个评级。

培养

我们放弃评级 (1,2,3,4,5) 的确切值,而是将其转换为隐式场景,即任何积极的互动都被赋予值 1。默认情况下,所有其他交互的值为零。

因为我们正在训练一个分类器,所以我们需要正样本和负样本。数据集中存在的记录被计为阳性样本。我们假设用户-项目交互矩阵中的所有条目都是负样本(一个强假设,并且容易实现)。

对于用户交互的每个项目,我们随机抽取 4 个没有被用户交互的项目。这样,如果一个用户有 20 次正面互动,他将有 80 次负面互动。这些负面交互不能包含用户的任何正面交互,尽管由于随机抽样,它们可能不都是唯一的。

估价

我们随机抽取 100 个没有被用户交互的项目,在这 100 个项目中对测试项目进行排序。这篇文章也采用了同样的策略,这也是这篇文章的灵感来源。我们在 10 处截断排名列表。

由于为每个用户排列所有项目太耗时,因为我们将不得不计算 10001700 个~10⁶值。采用这种策略,我们需要 1000100 ~ 10⁵值,少了一个数量级。

对于每个用户,我们使用测试集中的最新评级(根据时间戳),其余的用于训练。这种评估方法也称为留一策略,与参考文件中使用的方法相同。

韵律学

我们使用命中率(HR)和归一化折扣累积收益(NDCG)来评估 RS 的性能。

我们的模型为给定用户的测试集中出现的每个项目给出 0 到 1 之间的置信度得分。这些项目按得分降序排列,前 10 项作为推荐。如果测试项目(每个用户只有一个)出现在这个列表中,那么这个用户的 HR 就是 1,否则就是 0。在对所有用户进行平均后,报告最终 HR。对 NDCG 也进行了类似的计算。

训练时,我们将最小化交叉熵损失,这是分类问题的标准损失函数。RS 的真正优势在于给出用户最有可能与之交互的前 k 个项目的排序列表。想想为什么你大多只在第一页点击谷歌搜索结果,从来不去其他页面。像 NDCG 和人力资源这样的指标通过显示我们排名列表的质量来帮助捕捉这一现象。这里很好的介绍了评价推荐系统

基线:项目流行度模型

基线模型是我们用来为问题提供第一步、简单、不复杂的解决方案的模型。在推荐系统的许多用例中,向所有用户推荐相同的最受欢迎的项目列表给出了一个难以超越的基线。

在 GitHub 存储库中,您还可以从头开始找到实现项目流行度模型的代码。以下是基线模型的结果。

基于深度学习的模型

有了神经网络所有花哨的架构和行话,我们的目标是击败这个项目流行模型。

我们的下一个模型是深度多层感知器(MLP)。模型的输入是 userID 和 itemID,它们被送入嵌入层。因此,每个用户和项目都有一个嵌入。之后是多个致密层,接着是一个具有 s 形激活的单个神经元。确切的模型定义可以在文件 MLP.py 中找到。

乙状结肠神经元的输出可以被解释为用户可能与物品交互的概率。有趣的是,我们最终训练了一个用于推荐任务的分类器。

Figure 2: The architecture for Neural Collaborative Filtering

我们的损失函数是二元交叉熵损失。我们使用 Adam 进行梯度下降,使用 L-2 范数进行正则化。

结果

对于基于流行度的模型,训练时间少于 5 秒,以下是得分:

HR = 0.4221 | NDCG = 0.2269

对于深度学习模型,我们在近 30 个时期的训练(在 CPU 上约 3 分钟)后获得了这些结果:

HR = 0.6013 | NDCG = 0.3294

结果令人振奋。我们关心的指标有了巨大的飞跃。根据 HR,我们观察到误差减少了 30%,这是巨大的减少。这些数字是从非常粗略的超参数调谐中获得的。通过超参数优化仍有可能提取更多汁液。

结论

使用神经网络可以很容易地复制矩阵分解的最先进算法,以及更多。从非神经的角度来看,请阅读这篇关于推荐系统的矩阵分解的精彩文章。

在这篇文章中,我们看到了神经网络如何提供一种构建推荐系统的简单方法。诀窍是把推荐问题想成一个分类问题。我们在 PyTorch 中实现了一个推荐系统。我们将我们的结果与非个性化基线算法进行了比较,观察到了显著的收益。

为了获得更深入的理解,我鼓励你阅读原文(链接如下)并前往 GitHub 知识库阅读这篇文章。

参考资料:

  1. 该论文还链接到作者在 Keras 中的实现:https://www.comp.nus.edu.sg/~xiangnan/papers/ncf.pdf

具有深度学习架构的推荐系统

原文:https://towardsdatascience.com/recommender-systems-with-deep-learning-architectures-1adf4eb0f7a6?source=collection_archive---------4-----------------------

iki daily feed screenshot

这篇文章解决了构建基于深度学习的推荐系统的一般问题。本文中描述的特定架构是为 iki 服务 的新智能馈送供电的架构,每天推送您的技能——要检查其性能,请尝试 产品测试版

如果你对推荐系统的一般概念和主流方法很熟悉,并且想直接了解我们解决方案的细节,请跳过本文的前两部分。

介绍

推荐系统改变了我们与许多服务互动的方式。他们提供的不是静态数据,而是互动体验,可以选择留下你的反馈,并对给你的信息进行个性化处理。推荐系统独立地为每个用户创建个性化信息流,但是也考虑服务的所有用户的行为。

用户通常不可能通过检查在线影院中的电影、在线商店中的消费品或任何其他内容中的每一个来在各种给定选项中进行选择。如果服务中有大量内容,用户会面临信息过载的问题。解决这个问题的方法之一是利用有针对性的建议。

目标内容扮演重要角色的服务的一个例子是 iki。iki 是您的个人职业生涯和专业顾问,由机器学习和人工智能相关技术提供动力。在用户定义了他的专业兴趣领域之后,iki 在具有下述深度学习架构的推荐系统的帮助下,创建每日内容提要,开发知识和选择的技能。

推荐系统问题设置概述

任何推荐系统中存在的主要对象是用户 U、项目 R 以及它们之间的一些交互。这些交互通常以矩阵 F(|U|x |R|)的形式呈现,每个单元格包含一些关于交互的信息——某个商品被浏览/购买的事实、给定的评分、喜欢/不喜欢或其他信息。根据系统中用户和项目的数量,F 矩阵可以变得非常大。但是每个用户通常给出一些评级或者仅与系统中的一小部分项目交互,这导致非常稀疏的评级矩阵。众所周知,可以减少稀疏模型的独立参数的数量,而不会显著损失信息。我们遇到了在推荐系统中正确表示评价数据的问题:我们必须借助于具有固定长度 n 的向量将每个用户映射到某个向量空间,F 矩阵的 n<奇异值分解,这给出了两个具有形状|U| x n 和 n x |R|的矩阵,对于给定的 n,它们的乘积是矩阵 F 的最佳近似。让我们把这些向量相应地称为用户和项目的“SVD 嵌入”。

推荐系统中产生预测传统方法 协同过滤。这种方法的主要假设是,过去对某些项目给出相似评级的用户将来倾向于对其他项目给出相似的评级。解决协同过滤问题的最流行的方法之一是利用初始稀疏评级矩阵 f 的 SVD 创建用户和项目的密集嵌入。为了预测用户 u 对项目 I 的新评级值,我们必须计算相应用户和项目的 SVD 嵌入的标量积。

有几个开放库提供了基于用户评级矩阵构建各种推荐系统的工具。其中,我们可以列举各种矩阵分解方法(SVD,非负矩阵分解 NMF) 最近邻算法的不同变体、协同聚类方法、基于用户和基于项目的模型。这种解决方案的例子有惊喜库LightFM 库

在推荐系统中,除了用户与项目的交互信息之外,通常还有一些其他数据分别描述用户和项目。这些数据可能是变化的和异构的——项目和用户可能包含一些文本描述、数字特征、分类特征、图像和其他类型的数据。处理和使用该数据的方式取决于特定的问题,并且不是推荐系统的通用部分。

推荐系统的 主要属性或度量是推荐相关性可扩展性在用户或项目数量非常大的情况下。该设置带来了由两个连续 : 候选生成器排序模块组成的通用推荐系统架构,候选生成器从大项目集中选择相对较小的子集,排序模块对所选子集中的每个项目给出与用户兴趣相关的等级。此评级通常用于按照用户看到的顺序排列项目。

深度学习驱动的推荐系统架构

具有深度学习架构的基于内容的推荐系统与系统中存在的实际内容密切相关。接下来,我们将深入 iki 推荐系统的细节来描述 DL 方法。

在 iki 中,用户与内容的交互是视图和评级——用户可以喜欢或不喜欢任何内容元素。在我们的例子中,一个条目是一个包含博客、文章、教程、课程或其他提供专业知识的内容的网页。每个内容元素都有文本描述或者本身就是文本。

内容嵌入是文本矢量化过程的结果。我们使用具有 300 个维度的手套语言模型来对单独的单词进行矢量化。GloVe 是斯坦福大学开发的语言模型,类似于 word2vec(保留单词的语义相似性)。不同之处在于,除了保留语义手套之外,还利用了统计方法,考虑了文本语料库中出现的单词数量。

我们统计文本语料库中所有出现的单词的 tf-idf 权重,然后计算内容元素对应的向量,作为该内容元素中单词的手套向量与 tf-idf 权重的加权和。

用户可以向他的简档添加一些关于他当前和过去工作的信息(例如职位名称和每个工作的描述)。我们的系统处理这些数据,并使用专门开发的特殊语言模型技能提取器提取每个用户的专业技能列表。简而言之,该模型的思想是在英语简历的语料库上学习“技能”的语义,并能够从非结构化的英语文本中提取以前未见过的技能。用户也可以手动添加一些技能。为了调整内容提要,用户必须在我们的分层标签云上选择一些专业兴趣领域,类似于苹果音乐机制。iki 提供了数百种专业兴趣作为用户内容提要的一部分。在推荐系统中,用户的技能和选择的标签被用作用户特征。

iki recommender system architecture

用于训练我们的推荐系统的另一组特征是在将 SVD 应用于用户评级矩阵之后获得的内容和用户嵌入。这不是关于系统中的评级和观看的信息的唯一用途——我们创建用户的向量表示来描述他的观看和评级的内容。这是通过以下方式实现的:拥有内容的向量表示让我们取用户观看内容的整个语料库上每个坐标的最小值、最大值和平均值。这个操作产生了三个与内容嵌入长度相同的向量。我们对喜欢和不喜欢的内容集执行相同的操作,获得具有相同长度的另外 6 个向量。在推荐系统的训练步骤中,这些密集嵌入也被用作用户的特征。

User’s liked, disliked and viewed content in content vector space depicted as a 3D space for simplicity

候选人生成

对于每个标签(内容主题),我们的推荐系统创建一个单独的推荐集,特别是选择一个候选子集进行进一步排名。iki 推荐系统的目标不仅是提供相应主题的内容,还根据质量和专业水平对内容元素进行排序,以使结果提要符合每个用户的专业水平

让我们更深入地了解候选人生成步骤的细节。对于每个标签,我们的系统在以下机制的帮助下选择用于排序的候选:选择最近已经接收到特定用户的正面评级的内容元素,并且将这些选择的内容元素周围的内容元素集合(我们取内容嵌入空间中的几个邻域的并集)添加到候选空间中。我们还考虑在所选标签上具有相似最近活动的用户集合(为这组用户计算评级和观看向量之间的余弦距离)。最近观看或评级的内容元素的集合也被添加到候选集合中。所描述的邻域半径的变化提供了不同数量的生成候选。

候选人排名

对于每个标签,单独的神经网络实例被训练并用于内容候选排序。每个神经网络实例被训练,然后用于在对应于该标签的内容子集上进行排名。排名网络将关于内容元素和用户的一些数据作为输入,并输出 1 和-1 之间的某个数字作为用于内容元素的最终排名的预测评级。该模型在给定评级和视图的集合上被训练;集合中的每个样本由一个用户和一个内容元素组成,目标值为 1 表示喜欢,-1 表示不喜欢,如果用户只是查看了内容而没有给出任何评级,则为 0。

iki ranking neural net architecture

排名网络有 6 个不同维度的输入。第一个输入获取关于用户选择的标签和他的技能的信息,该信息被转换成嵌入在下一层中的密集用户简档。该信息允许系统在对与特定兴趣相对应的内容进行排名时考虑特定用户的其他兴趣(标签)。iki 中的标签数量有限,因此关于它们的信息用固定长度的二进制编码向量进行编码(1 用于选定的标签,0 用于其余的标签)。

用 SkillsExtractor 从用户简历中提取的技能可能变化很大,所以我们从统计上对它们进行标准化,以消除真正罕见的短语,最终得到一个固定长度的集合。然后,我们用与标签相同的二进制方式对技能进行矢量化。在定期推荐系统训练期间,我们更新实际的技能集。

接下来的两个输入采用我们之前描述过的用户向量表示,包括评级和观看的平均内容嵌入。它们的输出在下一层中被合并,这在内容嵌入空间中创建了密集用户嵌入,我们称之为密集用户偏好嵌入。这两个嵌入与采用内容和用户的 SVD 嵌入以及内容嵌入的其他输入相结合。获得的向量向前传递,并通过神经网络的几个密集层。最后一个网络层的激活函数是 tanh,它给出了[-1,1]走廊中的输出值。

iki 中的冷启动问题通过以下方式解决:对于没有任何评级的特定标签,系统向新用户推荐一组彼此之间距离很大的随机内容元素。这为新用户在体验之初提供了各种完全不同的内容元素供其选择。

结果和模型的基准

在构建上述最终模型之前,我们已经在研究阶段测试了各种推荐系统模型和组合(如奇异值分解、NNMF 等人)。显然,我们最终得到的模型在特定的 iki 数据集上显示了最佳的结果准确性。为基于深度学习的推荐系统提供有意义的基准并不是一项简单的任务,因为排名网络的架构是为特定类型的数据量身定制的,很明显,这种特定的架构优于任何基于交互矩阵的推荐系统,因为它利用了更多用于形成预测得分的数据。

另一个问题是,当你没有足够大的真实用户群和所有的简档和收视率数据时,很难模拟真实的推荐系统性能。你可以生成一个数据集,但生成一个嘈杂的数据集是没有意义的,所以你会为一些用户定制一些技能、经验和偏好,你的推荐系统会解码这些信息,并根据你生成的人工用户配置文件定制推荐。这种方法没有给真正重要的真实世界的自发用户行为处理留下空间。

推荐古腾堡计划的书籍

原文:https://towardsdatascience.com/recommending-books-from-project-gutenberg-a7222c945ebd?source=collection_archive---------3-----------------------

为年轻读者选择他们喜欢阅读的书籍对父母和教育工作者来说是一个挑战。我的解决方案是建立一个推荐引擎,既考虑阅读水平,也考虑最近阅读的书籍的主题,并返回下一步阅读的建议。

Photo by freestocks on Unsplash

我从古腾堡计划中提取数据,该网站提供超过 53,000 本在美国版权已经过期的免费电子书。

背景:为了正确理解和享受一篇文章,从而作为一个读者继续发展,让孩子们接触到对他们来说既有吸引力又在他们最近发展区内的书籍是很重要的。

最近发展区,通常缩写为 ZPD,是一个描述孩子自己能做什么,在帮助下能做什么,以及超出他们能力的概念。在阅读发展中,我们希望确保孩子们既能准确地阅读单词,又能理解他们正在阅读的内容,否则他们会对文本感到厌倦或沮丧。

阅读水平:我的推荐引擎很大一部分是基于阅读水平的,其中有许多不同的衡量标准。我想确保推荐的文本在读者的 ZPD 范围内,所以我需要找到一种方法来量化读者能读和不能读之间的差距。一些阅读水平是用基于单词长度和句子长度的公式计算出来的,其他的考虑单词难度和等级水平单词列表。在这个项目中,我选择使用Flesch Kincaid Grade Level来衡量阅读水平。我做了这个选择,因为这是一个被广泛接受的方法,也可以直接计算,而不需要输入等级级别单词列表。考虑到我的数据集中的大部分书籍都是在当前的年级词汇标准之前编写的,我对使用年级词汇列表持谨慎态度,并且我希望能够比较不同时期的书籍。

使用以下公式计算文本的 Flesch Kincaid 等级级别:

得出的数字在某种程度上与孩子在学校的年级水平相对应,尽管实际上每个年级学生的阅读水平差异很大。

还有另一个相关的衡量标准,叫做 Flesch reading-easy test,分数越高说明材料越容易阅读,分数越低说明段落越难阅读。90 分以上的分数表明这篇课文非常易读,一般 11 岁的学生都能很容易理解。分数低于 30 表明该文本很难阅读,最好由大学毕业生理解。Flesch 轻松阅读的公式是:

我选择使用 Flesch Kincaid 等级标准,因为随着书的难度增加,阅读水平也会提高,这更直观。我确实计算了每本书的阅读水平。从这一点开始,当我提到阅读水平时,我指的是弗莱施.金凯的水平。

推荐系统

我的推荐系统的前提是将读者最近喜欢阅读的书名作为输入,并输出推荐书籍的列表。我这样做是通过首先获得图书馆中可用书籍的子集,只包括比他们输入的书籍的阅读水平低一个年级和高四分之一年级的书籍。

一旦我有了可接受书籍的子集,我就确定这些书籍的主题有多相似。我使用 Jaccard 相似度来比较由提交文本的人确定的主题列表。

The Jaccard similarity of the subjects of these two books is high because the two books have a lot of subjects in common.

我也想比较一下这两本书的实际内容。我找到了书籍的计数矢量化文本之间的余弦距离。余弦距离显示了这些书的字数是多么的不同。

此外,我还计算了这些书的 tf-idf 矢量化文本之间的余弦距离。这些距离是基于单词在书中的重要性。

这给了我三个书籍推荐,我将在下面进行比较。

结果分析

主题相似度结果:
主题相似度推荐的书看起来很有推荐的合理性。例如,彼得潘的顶级搜索结果是发生在奥兹国的书籍,它们在“少年”、“幻想”、“想象”、“虚构”和“地方”上匹配。一个喜欢关于一个幻想世界的书的读者可能想读一个不同的世界,这是有道理的。然而,如果这本书的写作风格截然不同,读者可能仍然不会喜欢这本书,所以我将在下面分析基于文本的建议。

Count vectorizer vs . tf-idf:
我的第一直觉是 TF-IDF 会给出比 Count vectorizer 更好的推荐,因为它更关注单词的重要性,而不仅仅是单词数。因此,根据 count vectorizer,长度非常不同但单词相似的两本书最终会非常不同,但使用 tf-idf 会非常相似。事实上,从一些 count 矢量化书籍和 tf-idf 书籍的热图中可以看出,tf-idf 书籍总体上比 count 矢量化书籍显示出更多的相似性。然而,有几本书,如《曾达的囚徒》和《彼得潘》,在 count 矢量化热图中表现得特别明显。

The rectangle showing the relationship between The Prisoner of Zenda (book 95) and Peter Pan (book 16) is much darker when the Count Vectorizer is used.

通过查看由它们的计数向量距离和它们的 tf-idf 向量距离聚类的相同书籍,也可以清楚地看到,这些书籍最终被不同地聚类。

最终,哪些距离将更好地提供推荐仍然不清楚,直到我们看到哪些实际的单词被抽出。

为彼得潘使用计数矢量器方法的第一本书是曾达奖。

这可以与使用 tf-idf 矢量器的彼得潘的顶级书籍进行比较:

从这些表格以及其他推荐给彼得潘的书和我看过的其他书的类似数据来看,很明显 tf-idf 推荐的书大多基于相似的角色名字。以此为基础推荐书籍并不理想。例如,尊贵的彼得·斯特林与彼得潘毫无关系,我也不会向喜欢彼得潘的孩子推荐这本书。因此,看起来计数矢量器是目前推荐书籍的更好方法。

结论:我的推荐系统的管道有效地提取了书籍,但是为了评估这些推荐的书籍有多好,还需要进一步的分析。我对如何做到这一点有一些想法:

1.我想为我的推荐者建立一个用户界面,让用户完成一项调查,陈述他们认为自己对这三种方法的推荐有多好。

2.我还会将我的系统给出的推荐与外部来源(比如亚马逊)的推荐进行比较。这确实带来了一些问题,例如亚马逊推荐的大多数书籍在古登堡计划中不可用,但这是一个如何评估我的系统的想法,如果我获得更多数据的话。

3.更直接的是,我想通过重新运行 tf-idf 矢量器来过滤掉专有名词,从而尝试改进我的建议。这将有助于解决上面的问题,《彼得·斯特林》是推荐给彼得潘的第一本书,因为这两本书的主要人物都叫彼得。

使用 Google BigQuery 和隐式库推荐 GitHub 存储库

原文:https://towardsdatascience.com/recommending-github-repositories-with-google-bigquery-and-the-implicit-library-e6cce666c77?source=collection_archive---------1-----------------------

跟踪 GitHub 中发布的所有优秀的资源库是一项不可能的任务。趋势列表帮助不大。正如你可能已经读到的,按受欢迎程度排序并不像看起来那么简单。这里列出的大多数东西通常与我使用的堆栈无关。

这是推荐系统的一个很好的用例。它们帮助我们以个性化的方式过滤信息——存储库。当我们不知道该键入什么时,我认为它们是一个搜索查询。

推荐系统有几种方法,但通常分为两大类,协作式和基于内容的过滤。以下是 W ikipedia 的定义:

协同过滤根据用户过去的行为(之前购买或选择的项目和/或对这些项目的数字评级)以及其他用户做出的类似决定来构建模型。基于内容的过滤方法利用项目的一系列离散特征来推荐具有相似属性的附加项目。

在这种特殊的情况下,很难应用基于内容的方法,因为很难直接通过内容来度量存储库的相似性:代码、文档、标签等等。协同过滤更适合,也更容易应用。正如我在之前的帖子中所说,即使人们没有对你的内容进行评级,隐性反馈也足够了。

在这种情况下,我们可以使用当前流行的程序员冷静作为隐式反馈库星星:

Stolen from a talk that Julia and I gave at Porto Alegre Machine Learning Meetup (in Portuguese)

我们将从 Google Big Query 获得本月给出的随机恒星样本,并使用令人惊叹的隐式库,该库实现了精彩论文对隐式反馈数据集的协同过滤。算法本身我就不说了,不过你可以看看论文或者这篇博文来自 Ben Frederickson 《隐式》的作者。

以下是获取数据的查询:

WITH stars AS (
     SELECT actor.login AS user, repo.name AS repo
     FROM githubarchive.month.201706
     WHERE type="WatchEvent"
),
repositories_stars AS (
     SELECT repo, COUNT(*) as c FROM stars GROUP BY repo
     ORDER BY c DESC
     LIMIT 1000
),
users_stars AS (
    SELECT user, COUNT(*) as c FROM  stars
    WHERE repo IN (SELECT repo FROM repositories_stars)
    GROUP BY user HAVING c > 10 AND C < 100
    LIMIT 10000
)
SELECT user, repo FROM stars
WHERE repo IN (SELECT repo FROM repositories_stars)
AND user IN (SELECT user FROM users_stars)

请注意,我筛选了排名前 1000 的存储库,并随机抽取了 10000 名给排名前 1000 的存储库打了 10 到 100 星的用户。我们希望对关注热门项目的人进行抽样调查,但我们不想让那些给所有东西都打星的用户,因为他们不会添加太多信息。

重要的是要意识到我们不需要所有用户的所有明星来给每个人推荐。添加更多数据会提高推荐质量,但也会增加训练时间。如果我们采样正确,就不会损害模型精度。

好了,说够了,我们如何获得数据和训练模型?

data = pd.io.gbq.read_gbq(query, dialect="standard", project_id=project_id)# map each repo and user to a unique numeric value
data['user'] = data['user'].astype("category")
data['repo'] = data['repo'].astype("category")# create a sparse matrix of all the users/repos
stars = coo_matrix((np.ones(data.shape[0]),
                   (data['repo'].cat.codes.copy(),
                    data['user'].cat.codes.copy())))# train model
model = AlternatingLeastSquares(factors=50,
                                regularization=0.01,
                                dtype=np.float64,
                                iterations=50)confidence = 40
model.fit(confidence * stars)

仅此而已。只有 7 行 Python。而且快得惊人。在不到 10 秒的时间内提取数据并训练模型。我选择了通常工作良好的参数,但是如果我们认真对待它,我们应该做一些验证。我们跳过这个,直接看结果。与 tensorflow 有什么相似之处?

# dictionaries to translate names to ids and vice-versa
repos = dict(enumerate(data['repo'].cat.categories))
repo_ids = {r: i for i, r in repos.iteritems()}model.similar_items(repo_ids['tensorflow/tensorflow'])][(u'tensorflow/tensorflow', 1.0000000000000004),
 (u'jikexueyuanwiki/tensorflow-zh', 0.52015405760492706),
 (u'BVLC/caffe', 0.4161581732982037),
 (u'scikit-learn/scikit-learn', 0.40543551306117309),
 (u'google/protobuf', 0.40160716582156247),
 (u'fchollet/keras', 0.39897590674119598),
 (u'shadowsocksr/shadowsocksr-csharp', 0.3798671235574328),
 (u'ethereum/mist', 0.37205191726130321),
 (u'pandas-dev/pandas', 0.34311692603549021),
 (u'karpathy/char-rnn', 0.33868380215281335)]

看起来没错!列表中的几乎所有内容都与机器学习和数据科学有关。

产生用户推荐呢?嗯,我们可以直接使用model.recommend为训练集中的用户获得推荐,但我们需要从 GitHub API 为所有其他用户获得用户星级。

下面是从 GitHub 的 API 中获取星星并创建一个新的用户项目矩阵的代码。

def user_stars(user):
    repos = []
    url = "[https://api.github.com/users/{}/starred](https://api.github.com/users/{}/starred)".format(user)
    while url:
        resp = requests.get(url, auth=github_auth)
        repos += [r["full_name"] for r in resp.json()]
        url = resp.links["next"]["url"] if "next" in resp.links else None
    return reposdef user_items(u_stars):
    star_ids = [repo_ids[s] for s in u_stars if s in repo_ids]
    data = [confidence for _ in star_ids]
    rows = [0 for _ in star_ids]
    shape = (1, model.item_factors.shape[0])
    return coo_matrix((data, (rows, star_ids)), shape=shape).tocsr()

好的,我应该检查哪些存储库?

def recommend(user_items):
    recs = model.recommend(userid=0, user_items=user_items, recalculate_user=True)
    return [(repos[r], s) for r, s in recs]jbochi = user_items(user_stars("jbochi"))
recommend(jbochi)[(u'ansible/ansible', 1.3480146093553365),
 (u'airbnb/superset', 1.337698670756992),
 (u'scrapy/scrapy', 1.2682612609169515),
 (u'grpc/grpc', 1.1558718295721062),
 (u'scikit-learn/scikit-learn', 1.1539551159232055),
 (u'grafana/grafana', 1.1265144087278358),
 (u'google/protobuf', 1.078458167396922),
 (u'lodash/lodash', 1.0690341693223879),
 (u'josephmisiti/awesome-machine-learning', 1.0553796439629786),
 (u'd3/d3', 1.0546232373207065)]

我发现这些建议非常有用。请注意,我们传递了一个全新的用户评级矩阵,其中只有一个用户,并设置了标志recalculate_user=True

这个功能是最近添加的,可以用来为不在训练集中的用户生成推荐,或者在他或她消费更多项目时更新用户推荐。

我添加到库中的另一个无耻的功能是解释推荐的能力:

def explain(user_items, repo):
    _, recs, _ = model.explain(userid=0, user_items=user_items, itemid=repo_ids[repo])
    return [(repos[r], s) for r, s in recs]explain(jbochi, 'fchollet/keras')[(u'pandas-dev/pandas', 0.18368079727509334),
 (u'BVLC/caffe', 0.15726607611115795),
 (u'requests/requests', 0.15263841163355341),
 (u'pallets/flask', 0.15259412774463132),
 (u'robbyrussell/oh-my-zsh', 0.1503775470984523),
 (u'apache/spark', 0.12771260655405856),
 (u'tensorflow/tensorflow', 0.12343847633950071),
 (u'kripken/emscripten', 0.12294875917036562),
 (u'videojs/video.js', 0.12279727716802587),
 (u'rust-lang/rust', 0.10859551238691327)]

它会返回我标上星号的对某个特定推荐贡献最大的存储库。结果意味着模型推荐 keras 因为我主演过熊猫咖啡馆

我希望你喜欢!这是笔记本,上面有你用用户名运行它所需的所有代码

别忘了给一颗星。本应得的。

Tensorflow 中的重建主分量、全局对比度、范围归一化层[TF 中的手动反推]

原文:https://towardsdatascience.com/reconstructive-principle-component-global-contrast-ranged-normalization-layer-in-tensorflow-bbe08714dd85?source=collection_archive---------11-----------------------

Photo by Daniel Olah on Unsplash

今天,我想练习我的矩阵演算,以及创造性地创建一些层。我认为实现不同的层是一个好主意,可以在以后使用。下面是我想练习的层次列表。

a .行均值减法层
b .行标准差层
c .范围归一化层
d .全局对比度归一化层
e .重构主成分层

请注意,这篇帖子是出于我自己的教育目的。

a .逐行均值减去图层

让我们从简单的开始,只是减去平均行的方式。如上所述,导数非常简单。

以上是一个张量流实现,另外,我已经创建了一个训练阶段变量,所以在测试阶段我们可以使用训练数据的移动平均值。

让我们做一个简单的健全性检查,在层之前,每一行数据的平均值是 0.4229564897125843,在层之后,它非常接近于零。此外,我们可以看到移动平均平均值已更新为 0.042,这是意料之中的,因为我使用的 beta 值为 0.9。最后,梯度在我们预期的范围内,因为 1-(1/4096) = 0.999755859。

b .逐行标准差层

这一层实际上并不做太多事情,而是简单地计算每一行的标准偏差值并将其返回。(我只是想练习一下。)

上面是一个 tensorflow 实现,我再次设置了训练阶段变量来区分训练和测试阶段。

在通过该层传递数据之后,我们可以看到它已经正确地返回了每个数据行的标准偏差值。

c .范围归一化层

Image from this website

可以对任何范围的值进行归一化,而不仅仅是 0 和 1。使用这个概念,我们还可以通过层进行反向传播。首先让我们用手算一下。

现在,既然已经完成了,让我们用张量流来实现它。

看起来很棒,现在我们可以做简单的健全性检查,看看该层是否正常工作。(同样,对于这一层,我有一个移动最小值以及移动最大值。)

我将最大范围设置为 10,因此我们在范围 0-10 之间归一化我们的图像数据。我们看不出差别,但是所有数据的平均值增加了大约 4。

d .全局对比度归一化图层

Image from this website

GCN 可以用作预处理步骤,但是由于大多数计算只是简单的矩阵运算,我们也可以通过它反向传播。(但请注意,我将使用 GCN 的一个软化版本,而不是一个最大值函数,我只是将ε值相加,以避免被零除。).如果您想了解更多,请点击此处

现在我们有了计算方法,让我们用 numpy 实现来看看这个函数是如何改变每张图片的对比度的。

从第二幅图像中,我们可以看到标准化后它变得更亮,但最明显的是当前图像批次的标准偏差降低了。

同样,我创建了一个移动平均变量,以防万一,如果我们想区分培训和测试阶段。

我们可以看到,我们的 GCN 层给出了与 numpy 版本相同的结果。

e .重建主构件层

这一层的想法非常简单,使用 PCA,我们可以通过执行原始数据和投影矩阵之间的矩阵乘法来执行降维。但是我们也可以仅使用主成分的顶部 k 个元素来重建原始数据。因为所有的运算都是矩阵运算,我们可以通过它反向传播。

在重建之后,我们现在可以看到所有的图像都是彼此混合的,并且图像批次的平均值和标准值是 0.37 和 0.19。

最后,让我们做一个简单的健全性检查,看看高级 api (sklearn 分解 pca)是否给我们一个类似的结果。在第三个数字之后,值改变了,这可能是因为我使用特征值分解,而 sklearn 使用奇异值分解。

交互代码

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

要获取这篇文章的代码,请点击这里。

遗言

我应该用 tf 梯度来仔细检查所有的梯度是否正确,这是我的错误。

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

参考

  1. tensorflow?,h. (2018)。如何在 tensorflow 中定义条件语句?。堆栈溢出。检索于 2018 年 10 月 22 日,来自https://stack overflow . com/questions/41789209/how-to-define-condition-statement-in-tensor flow
  2. 误差,t. (2018)。tensorflow:在 tf.map_fn 的 fn 中创建变量时返回值错误。堆栈溢出。检索于 2018 年 10 月 22 日,来自https://stack overflow . com/questions/45789822/tensor flow-creating-variables-in-fn-of-TF-map-fn-returns-value-error
  3. 数字/数字。(2018).GitHub。检索于 2018 年 10 月 22 日,来自https://github . com/numpy/numpy/blob/v 1 . 15 . 1/numpy/core/_ methods . py
  4. 标准差。(2018).Davidmlane.com。检索于 2018 年 10 月 22 日,来自http://davidmlane.com/hyperstat/A16252.html
  5. (2018).Dotnetperls.com。检索于 2018 年 10 月 22 日,来自https://www.dotnetperls.com/arg-max-tensorflow
  6. Scherfgen,D. (2018)。导数计算器带步骤!。Derivative-calculator.net。检索于 2018 年 10 月 22 日,来自https://www.derivative-calculator.net/
  7. TensorFlow,A. (2018)。在张量-张量流中调整单个值。堆栈溢出。检索于 2018 年 10 月 22 日,来自https://stack overflow . com/questions/34685947/adjust-single-value-within-tensor-tensor flow
  8. Tensorflow,B. (2018)。张量流中的二元掩码。堆栈溢出。检索于 2018 年 10 月 22 日,来自https://stack overflow . com/questions/40443951/binary-mask-in-tensor flow
  9. tf.self _ 共轭 _eig | TensorFlow。(2018).张量流。检索于 2018 年 10 月 23 日,来自https://www . tensor flow . org/API _ docs/python/TF/self _ agreement _ EIG
  10. 五氯苯甲醚,O. (2018)。从 sklearn PCA 获得特征值和向量。堆栈溢出。检索于 2018 年 10 月 23 日,来自https://stack overflow . com/questions/31909945/get-eigen-values-and-vectors-from-sk learn-PCA
  11. http://scikit-learn/scikit-learn。(2018).GitHub。检索于 2018 年 10 月 23 日,来自https://github . com/sci kit-learn/sci kit-learn/blob/BAC 89 c 2/sk learn/decomposition/PCA . py # L106
  12. tf.self _ 共轭 _eig | TensorFlow。(2018).张量流。检索于 2018 年 10 月 23 日,来自https://www . tensor flow . org/API _ docs/python/TF/self _ agreement _ EIG
  13. (2018).Arxiv.org。检索于 2018 年 10 月 23 日,来自https://arxiv.org/pdf/1709.06079.pdf
  14. (2018).People.maths.ox.ac.uk 检索 2018 年 10 月 23 日,来自https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf
  15. 矩阵?,H. (2018)。如何标准化一个矩阵?。堆栈溢出。检索于 2018 年 10 月 23 日,来自https://stack overflow . com/questions/4544292/how-do-I-standard-a-matrix/40951248
  16. PreMBA 分析方法。(2018).Ci.columbia.edu。检索于 2018 年 10 月 23 日,来自http://ci.columbia.edu/ci/premba_test/c0331/s6/s6_4.html
  17. 1?,H. (2018)。如何将-1 和 1 之间的数据归一化?。交叉验证。检索于 2018 年 10 月 23 日,来自https://stats . stack exchange . com/questions/178626/how-to-normalize-data-between-1-and-1
  18. 标准差公式。(2018).Mathsisfun.com。检索于 2018 年 10 月 23 日,来自https://www . mathsisfun . com/data/standard-deviation-formulas . html
  19. 实施主成分分析(PCA)。(2014).塞巴斯蒂安·拉什卡博士。检索于 2018 年 10 月 23 日,来自https://sebastianraschka . com/Articles/2014 _ PCA _ step _ by _ step . html
  20. (2018).Cedar.buffalo.edu。检索 2018 年 10 月 23 日,来自https://cedar . buffalo . edu/~ Sri Hari/CSE 676/12.2% 20 computer % 20 vision . pdf
  21. 预处理),W. (2018)。标准化和全局对比度正常化有什么区别?(图像预处理)。堆栈溢出。检索于 2018 年 10 月 23 日,来自https://stack overflow . com/questions/27955695/标准化和全局对比标准化的区别是什么
  22. 预处理),W. (2018)。标准化和全局对比度正常化有什么区别?(图像预处理)。堆栈溢出。检索于 2018 年 10 月 23 日,来自https://stack overflow . com/questions/27955695/what-the-difference of-standardization-and-global-contrast-normalization
  23. python?,H. (2018)。如何在 python 中实现全局对比度归一化?。数据科学堆栈交换。检索于 2018 年 10 月 23 日,来自https://data science . stack exchange . com/questions/15110/how-to-implementation-global-contrast-normalization-in-python

与 Apache Spark 的 MLlib & GraphX 的记录链接

原文:https://towardsdatascience.com/record-linking-with-apache-sparks-mllib-graphx-d118c5f31f83?source=collection_archive---------1-----------------------

一种可扩展的模糊数据匹配方法

挑战

最近,Datlinq 的一位同事让我帮她解决一个数据问题,这个问题看起来非常简单。
她从商会(Kamer van Koophandel: KvK)购买了一小组数据,其中包含大约 5 万家小公司(5-20 名全职员工),在网上很难找到。
她注意到许多公司共用同一个地址,这是有道理的,因为许多公司倾向于聚集在商业区。

然而,她还发现,同一地址上的许多公司实际上是一个公司,分多次注册。

这两家公司在技术上是不同的,但在这种特殊情况下,应被视为一家拥有联合劳动力的公司。

因此,我们只需将“属于”的公司组合在一起,并将在那里工作的 FTE 汇总为一个实体。

方法

当然,我一开始做了一些 if-then-else 编码,但是 a .那很快就变得一团糟,b .那有什么乐趣呢?

因此,我定义了实现动态、可扩展和可配置解决方案的步骤:

  • 加载/清除数据
  • 创建距离度量
  • 组合所有数据
  • 手动训练匹配组合
  • 训练模型
  • 在模型中运行所有组合
  • 制作所有链接记录的图表
  • 提取所有连接的顶点,并将它们保存为唯一的组
  • 将这些组合并到一个数据源中,该数据源包含 1 个 id、汇总的 FTE 和分组 id 列表

这些步骤中的任何一个都可以通过大量的工具、库和语言来完成,但是有一个似乎(几乎)适合它们中的每一个:
Apache Spark

好吧,我可能有点偏见,我认为 Python 和 SciKit learn 也足够了,除了 Spark 似乎有点过头,但我喜欢 Scala 和 Spark…

所以我点燃了美好的火花

1.加载/清除数据

数据以 Excel 格式提供,所以简单的“另存为”csv 开始了这一步

此外,这一步相当直接;数据非常干净。我只是选择了模型可能感兴趣的字段/特征。
稍后我将介绍 KvKRecord 案例类

2.创建距离度量

要查看来自同一数据源的两个记录是否“匹配”,理论上你必须比较每一个组合。

这种比较本身就是这种努力的全部挑战,这就是机器学习介入的地方。

但是 ML 模型仍然需要一个“特征向量”来训练、测试和预测,所以我需要创建一个方法来比较两个 KvKRecords 并返回这个“特征向量”

我选择创建一个向量,其中每个元素对应于 case 类的每个属性之间的距离度量。

我使用 Math.log10 和一个除法来归一化整数之间的距离,以获得 0 和 1 之间的所有数字(我事先知道范围)。这不是最好的方法,但我强烈怀疑这些都无关紧要,所以我几乎没有花时间调优非字符串特性。

对于字符串比较,有很多很多选项
,但我最终使用了 Jaro-Winkler 。我想试试其他的,但这似乎工作得很好,并返回一个介于 0 和 1 之间的正常值。

3.组合所有数据

我在这里有一些优势,因为地址数据非常干净,所以我不必创建笛卡尔乘积,而只需在地址上连接。使用 joinWith 方法, KvKRecords 保持完整,特征向量被附加上。

现在,我们有了一个经过筛选的数据集,包含了同一地址的所有公司组合。

我不得不指出,这多少是一种欺骗。有些公司地址相同,但地址符号不同,尽管提供的数据非常清晰。

例如," Keizersgracht 62" 和"Keizersgracht 62–64 "和" Keizersgracht 62-A" 可能被认为是相同的地址,但排除了这种方式。然而,我们也可以假设,谁注册这些公司,使用相同的地址,如果它是同一家公司?我不知道,但在快速手动检查后,这种影响似乎可以忽略不计/不存在。

一种替代方法是做一个完整的笛卡尔乘积(将每个公司与其他公司匹配),并在不同街道/城市的公司上训练该工具。我担心,不匹配的公司之间的纯粹差异会使模型远离实际上位于同一地址的公司之间的细微差别。

4.手动训练匹配组合

如果你没有东西来训练你的 ML,所有这些组合和向量不会让你去任何地方。我需要一个带标签的数据集用于监督学习。

用 Excel 基于原始 csv 手动创建这些,看起来容易出错而且很麻烦,所以作为一个优秀的(懒惰的)开发人员,我编写了一个程序来帮助我创建一个带标签的训练集。

console output

我必须承认,我只为这个项目创建了大约 100 个带标签的样本(使用< 0.2%), but the features are pretty simple and the work was extremely boring, so I was ok with it.

The LabeledVector case 类,因为它具有名为“ features ”和“ label ”的属性,这是 Spark MLlib 模型的默认属性。

5.训练模型

现在我们有了这个漂亮的标记数据集,我们准备好展示我们的机器学习肌肉了。

不过,我不得不让你有点失望,因为我刚刚使用 Spark 的 MLLib 创建了一个直接的逻辑回归模型,但结果才是最重要的。

其他项目使用随机森林、感知器甚至朴素贝叶斯可能会更好,但我基于这种方法得到了一些好结果:

  • 精确度:0.96
  • ROC 曲线下面积:0.92

(如果有人知道如何从 Spark 轻松地创建 ROC/AUC-plot,请告诉我)

更多的时间可以花在超参数调整上,但是拥有超过 80 个训练样本也会有所帮助;-)

6.在模型中运行所有组合

下一步是将这个模型应用到我们的组合数据集

因为我们的 comparableDataset 已经有了所需的' features : Vector ',我可以应用这个模型,它添加了标签概率列。

对于链接,我们现在只对实际的匹配感兴趣,所以得到的数据集只有被认为相同的公司的组合。

PredictedVector 又是一个简单明了的 case 类。

7.制作所有链接记录的图表

拥有一个包含所有关联公司的数据集固然很好,但要真正理解这些数据,我必须按“独立组”进行分组。含义:

(A,B)
(A,C)
(B,C)
(D,E)
(F,G)
(G,H)

需要产生以下结果:

(A,B,C)
(D,E)
(F,G,H)

任何熟悉离散数学/图论的人都会注意到这些可以用图形来表示。

有很多很酷的工具可以用来处理图形,我最喜欢的一个是 Neo4j ,但是 Spark 还是提供了开箱即用的 GraphX ,所以我们现在还是坚持使用它。

我只需要把我们的数据集变成两个 RDD,即:边和顶点。

8.提取所有连接的顶点,并将它们保存为唯一的组

现在有了一个图( linkedGraph ),我想找到所有不相连的子图并把它们组合在一起。

这里神奇的关键词是:连通分量

GraphX 方法 connectedComponents 创建了每个 VertexId 和其子图中最小的 VertexId 的元组列表。

反转这些元组并在最小的 VertexId 上分组,创建了一个连接的 VertexId 的 c.q .子图列表

使用广播查找,我将这些 VertexId 重新映射到相应的 KvKRecord

最后,我得到了一个包含所有唯一组的数据集,以及该组中所有 KvKRecords 的列表。

9.在单个数据源中组合组

最后一步是为我的同事创建一个 csv 文件,用于她的特定用例。

整个代码虽然对这个过程不感兴趣,但它的目的是将这些结果整理成一个 csv 文件,该文件可以由 MS Excel 以

【关联公司数量】【总 FTE】【公司 id /栏目】

结论

最终,这个看似简单的数据问题有了一个相当复杂的解决方案,并且花费了我比预期更多的时间。

但是我并没有对结果失望,也没有选择在 Scala & Spark 中构建它。我学到了很多东西,并相信随着时间的推移,它将改进这个项目和其他项目。事实上,我可以在我的机器上运行这段代码,也可以在云中运行 100 个节点的集群,而不需要修改任何代码,这仍然让我感到惊讶。

我分享这个的原因是:

  • 通知你星火的威力:不吓人,好玩!**
  • 去炒作机器学习:很酷,但还是软件开发带试用&错误。**
  • 淡化大数据:重要的不总是规模。数据还是数据。**
  • 帮助/激励有类似问题的人:分享是关爱;-)**
  • 请对本文、我的方法、代码或任何东西进行反馈:!**

从《知识是美丽的》一书中再现数据可视化

原文:https://towardsdatascience.com/recreating-data-visualizations-from-the-book-knowledge-is-beautiful-e455e7126071?source=collection_archive---------9-----------------------

在这个系列中,我将着手重现大卫·麦克肯多斯在 r。

当你看完第一部分后,在这里看看这个系列的其他帖子:第二部分第三部分第四部分

David McCandless 是两本最畅销的信息图表书籍的作者,他在 TED 上做了一个关于数据可视化的演讲。我在 2015 年买了他的第二本书《知识是美丽的》,里面有 196 张漂亮的信息图。

那时,我真的迷上了行尸走肉,他的书启发我制作了自己的信息图:

最近,我试图想到一些有趣的数据可视化项目,并决定从书中选择几个可以在R中尽可能接近地重新创建的项目。

对于那些喜欢这类练习的人来说,这本书是一个极好的资源,因为书中的每一个可视化都与一个在线数据集配对,以便 根据你的兴趣进行探索!!!。我从来不知道数据集有多丰富,直到我尝试重新创建我的第一个可视化,“最佳展示”。中的数据集为最好单独显示中的,是一个有八张工作表的 excel 文件!

McCandles 说整本书花了他两年 15832 个小时,我对此毫不怀疑。如果你只关心可操作的结果,快速绘制一个 EDA 绘图对于一个会议来说是快速而简单的。然而,如果你出版的东西需要一些时间来创造一个惊人的视觉效果。

最佳表演

最佳展示是狗狗轮廓的散点图,根据狗狗的类别进行颜色编码,相应地调整大小,并根据它们的智力指向左边或右边。

让我们加载环境;我喜欢needs()包,它使得将&加载包安装到R变得简单。

knitr::opts_chunk$set(echo = TRUE)
if (!require("needs")) {
  install.packages("needs", dependencies = TRUE)
  library(needs)
}

如上所述,数据是一个包含八张工作表的 excel 文件。我们可以用read_excel()读入 Excel 文件,并用sheet =参数指定我们想要访问的工作表。

# install&Load readxl package
needs(here,
      readxl,
      stringr,
      dplyr,    # to use select()
      magrittr) # to use %<>% operators

path = here()

# Specify the worksheet by name
dog_excel <- read_excel("~/bestinshow.xlsx", sheet = "Best in show full sheet", range = cell_rows(3:91))

# Pick the desired variables
dog_excel %<>%
  select(1,3,5:6, "intelligence category", "size category")

# Rename the columns
colnames(dog_excel) <- c("breed", "category", "score", "popularity", "intelligence", "size")

# Remove first row (non-descript column names)
dog_excel <- dog_excel[-1,]

创建一个 HTML 表格(支持过滤、分页和排序。这只适用于 RMarkdown,不适用于媒体,所以你需要检查一下github . iohttps://moldach.github.io/dataRbeautiful/index.html

needs(DT)
datatable(dog_excel, options = list(pageLength = 5))

看看数据集中的intelligence等级。

# What are the intelligence levels?
unique(dog_excel$intelligence)
## [1] "Brightest"     "Above average" "Excellent"     "Average"      
## [5] "Fair"          "Lowest"

McCandless 将狗分为“笨”和“聪明”两类。但是这里我们看到在这个干净的数据集中有类别。因此,让我们将前三个因素指定为clever,将其他三个因素指定为dumb

dog_excel$intelligence %<>% 
  str_replace(pattern = "Brightest", replace = "clever", .) %>%   
  str_replace(pattern = "Above average", replace = "clever", .) %>% 
  str_replace(pattern = "Excellent", replace = "clever", .) %>% 
  str_replace(pattern = "Average", replace = "dumb", .) %>% 
  str_replace(pattern = "Fair", replace = "dumb", .) %>% 
  str_replace(pattern = "Lowest", replace = "dumb", .)

原始可视化中有 87 只狗。我在 SuperColoring.com 的上找到了 知识共享 4.0 许可 下的 24 个剪影。这意味着我可以以任何媒体或格式自由复制和再分发,只要我给出网页的链接,并注明作者的姓名和许可证。我已经将该信息包含在一个.csv.中,我们将使用它来对 McCandless 的数据进行子集化(两个数据集都可以在 my Github repo 中找到)。

needs(readr)
dog_silhouettes <- read_csv("~/dog_silhouettes.csv")

dog_df <- dog_excel %>% 
  inner_join(dog_silhouettes, by = "breed")

# change popularity from string into numeric values
dog_df$popularity <- as.numeric(dog_df$popularity)

我们需要使用magick包来使.svg轮廓周围的白色背景透明,将图像缩放到普通大小(按宽度),并保存为.png的。

needs(magick)

file.names <- dir(path, pattern = ".svg")

for (file in file.names){
  # read in the file
  img <- image_read_svg(file)
  # scale all images to a common scale
  img_scaled <- image_scale(img, 700)
  # make the background transparent
  img_trans <- image_transparent(img_scaled, 'white')
  # get rid of .svg ending
  file_name <- str_replace(file, pattern = ".svg", replace = "")
  # write out the file as a .png
  image_write(img_trans, paste0(file_name, ".png"))
}

一些狗的侧影指向相反的方向。我们需要使用magick包装中的image_flop(),这样所有包装都面向同一个方向。稍后,我们可以通过智能对数据帧进行子集划分,这样cleverdumb狗就面向相反的方向。

path = here()

flop.images <- c("~/labrador-retriever-black-silhouette.png", "~/border-terrier-black-silhouette.png", "~/boxer-black-silhouette.png", "~/french-bulldog-black-silhouette.png", "~/german-shepherd-black-silhouette.png", "~/golden-retriever-black-silhouette.png", "~/greyhound-black-silhouette.png", "~/rottweiler-black-silhouette.png")

for(i in flop.images){
  i <- str_replace(i, pattern = "~/", replace = "")
  img <- image_read(i)
  img_flop <- image_flop(img)
  image_write(img_flop, i)
}

下一步是根据类别给狗上色。

让我们写一个函数,可以给它三个参数:1) df一个数据帧,2) category它是狗的类型,3) color每个category的特定颜色。

第一步是只选择那些属于感兴趣的category的狗。这可以通过dplyr封装中的filter()来完成。但是,如果你想使用dplyr功能,比如filter(),你需要按照这个网站上的说明;用enquo设定。

img_color <- function(df, category, color){
  # Make filter a quosure
  category = enquo(category)
  # subset df on category
  new_df <- df  %>% 
    filter(category == !!category)
  # get directory paths of images for the for loop 
  category_names <- new_df$breed  %>%
    tolower() %>% 
    str_replace_all(" ", "-") %>% 
    paste0("-black-silhouette.png")
  for(name in category_names){
    img <- image_read(name)
    img_color <- image_fill(img, color, "+250+250")
    image_write(img_color, name)
  }
}

我想在 R 内尽可能接近地复制图形,所以为了复制可视化的颜色,我扫描了这本书,保存了图像,然后使用这个工具来获取 html 颜色代码

现在让我们使用上面创建的函数根据它们的category给狗的轮廓上色。

# Herding color "#D59E7B"
img_color(dog_df, "herding", "#D59E7B")

# Hound color "#5E4D6C"
img_color(dog_df, "hound", "#5E4D6C")

# Non-sporting color "#6FA86C"
img_color(dog_df, "non-sporting", "#6FA86C")

# Sporting color "#B04946"
img_color(dog_df, "sporting", "#B04946")

# Terrier color "#A98B2D"
img_color(dog_df, "terrier", "#A98B2D")

# Toy color "#330000"
img_color(dog_df, "toy", "#330000")

# Working color "#415C55"
img_color(dog_df, "working", "#415C55")

好了,终于到了可视化的时候了。

通常人们用ggplot2中的geom_point()绘制点,但在这种情况下,我想要每个品种的图像。我们可以使用ggimage包,稍微调整一下,我们就可以基于intelligence翻转图像。ggimage不像ggplot2那样支持颜色作为一种审美,这就是我之前手动分配颜色&尺寸的原因。

由于popularity分数范围从 1 到 140,1 是最受欢迎的,我们需要用scale_y_reverse()反转 y 轴。****

**needs(ggplot2,
      ggimage)
# add "~/" to get filenames of images for plotting
dog_df$name <- paste0("~/", dog_df$name)

# create a ggplot/ggimage object
p <- ggplot(subset(dog_df, intelligence == "clever"), aes(x = score, y = popularity, image = name), alpha = 0.5) + geom_image(image_fun = image_flop) + geom_image(data=subset(dog_df, intelligence == "dumb")) +
  labs(title = "Best in Show", subtitle = "The ultimate datadog", caption = "Source: bit.ly/KIB_BestDogs") +
  labs(x = NULL, y = NULL) +
  theme(panel.background = element_blank(),
        legend.position = "top", 
        legend.box = "horizontal",
        plot.title = element_text(size = 13,
                                  # I'm not sure what font he chose so I'll pick something I think looks similar
                                 family = "AvantGarde",
                                 face = "bold", 
                                              lineheight = 1.2),
        plot.subtitle = element_text(size = 10,
                                     family = "AvantGarde"), 
        plot.caption = element_text(size = 5,
                                    hjust = 0.99),  
        axis.text = element_blank(), 
        axis.ticks = element_blank()) +
  scale_y_reverse()**

最后一步是在狗的品种下面添加文本注释。因为我用intelligencedog_df进行了子集化,所以如果我试图用geom_text()进行注释,它只会注释部分数据。我们将需要函数 instea,因为 geome 不是从数据帧的变量映射而来,而是作为向量传入。

**# Add annotations
p + annotate("text", x=dog_df$score[1:24], y=((dog_df$popularity[1:24])+6), label = dog_df$breed[1:24], size = 2.0)**

可视化看起来与原始相似,并突出了所包含的大部分美学。人们总是可以在 Adobe Illustrator 或 Inkscape 中添加额外的细节,使其看起来更像最终的可视化效果

敬请关注第二部分!

从《知识是美丽的》一书中再现(更多)数据可视化:第二部分

原文:https://towardsdatascience.com/recreating-more-data-visualizations-from-the-book-knowledge-is-beautiful-part-ii-2f1d1da68e3a?source=collection_archive---------5-----------------------

在本系列的第二部分中,我将继续重现 David McCandless 在 r。

David McCandless 是两本最畅销的信息图书籍的作者,他在 TED 上做了一个关于数据可视化的精彩演讲。他的第二本书 知识是美丽的 ,于 2015 年出版,包含 196 幅美丽的信息图,耗时 15832 小时完成。

当你完成了这一部分,看看这个系列的其他帖子:第一部分第三部分第四部分

密码

这个可视化图形是一个散点图,根据密码中的第一个字符[A 到 Z],然后是[0 到 9],沿 x 轴从左到右排列常用密码。密码根据类别进行颜色编码,根据密码的强度和 y 轴上的使用频率进行大小调整。

在上一篇文章中,我从 Google Docs 下载了 excel 格式的数据,并用readxl包中的read_excel()函数加载了相应的工作表。

令人沮丧的是,数据有时可以在 pdf 中分发。例如,拉斐尔·伊里扎里(Rafael Irizarry)使用波多黎各政府新发布的数据,对 2017 年毁灭性飓风玛丽亚(Maria)后波多黎各的超额死亡率进行了新的计算。 Irizarry 的帖子附有数据,但遗憾的是它是 PDF 格式的

tabulizer 库提供了到 Tabula java 库的 R 绑定,可以用来从 PDF 文档中提取表格。

数据集位于这里:bit.ly/KIB_Passwords。我们来导入一下:

# Download tabular data from a pdf spanning multiple pages
library(tabulizer)passwords <- "~/passwords.pdf"# The table spreads across five pages
pages <- c(1:5)df_total <- data.frame()for (i in pages) {
    out <- extract_tables(passwords, page = i)
    out <- as.data.frame(out)
    colnames(out) <- c("rank","password","category", "online_crack", "offline_crack", "rank_alt", "strength","font_size")
    out <- out[-1,1:8]
    df_total <- rbind(df_total, out)
}

在继续之前,需要对数据进行一些清理。

df_total <- na.omit(df_total)
df_total$rank <- as.numeric(df_total$rank)

沿着 x 轴,根据密码的第一个字符对密码进行分类。我们可以使用dplyrmutate()函数内的grepl来创建新的宁滨列的每个密码。

# make a group for passwords beginning in A-Z and through 0-9
df_total <- df_total %>% 
  mutate(group = case_when(grepl("^A", password, ignore.case = TRUE) ~ "A",
  grepl("^B", password, ignore.case = TRUE) ~ "B",
  grepl("^C", password, ignore.case = TRUE) ~ "C",
  grepl("^D", password, ignore.case = TRUE) ~ "D",
  grepl("^E", password, ignore.case = TRUE) ~ "E",
  grepl("^F", password, ignore.case = TRUE) ~ "F",
  grepl("^G", password, ignore.case = TRUE) ~ "G",
  grepl("^H", password, ignore.case = TRUE) ~ "H",
  grepl("^I", password, ignore.case = TRUE) ~ "I",
  grepl("^J", password, ignore.case = TRUE) ~ "J",
  grepl("^K", password, ignore.case = TRUE) ~ "K",
  grepl("^L", password, ignore.case = TRUE) ~ "L",
  grepl("^M", password, ignore.case = TRUE) ~ "M",
  grepl("^N", password, ignore.case = TRUE) ~ "N",
  grepl("^O", password, ignore.case = TRUE) ~ "O",
  grepl("^P", password, ignore.case = TRUE) ~ "P",
  grepl("^Q", password, ignore.case = TRUE) ~ "Q",
  grepl("^R", password, ignore.case = TRUE) ~ "R",
  grepl("^S", password, ignore.case = TRUE) ~ "S",
  grepl("^T", password, ignore.case = TRUE) ~ "T",
  grepl("^U", password, ignore.case = TRUE) ~ "U",
  grepl("^V", password, ignore.case = TRUE) ~ "V",
  grepl("^W", password, ignore.case = TRUE) ~ "W",
  grepl("^X", password, ignore.case = TRUE) ~ "X",
  grepl("^Y", password, ignore.case = TRUE) ~ "Y",
  grepl("^Z", password, ignore.case = TRUE) ~ "Z",
  grepl("^0", password, ignore.case = TRUE) ~ "0",
  grepl("^1", password, ignore.case = TRUE) ~ "1",
  grepl("^2", password, ignore.case = TRUE) ~ "2",
  grepl("^3", password, ignore.case = TRUE) ~ "3",
  grepl("^4", password, ignore.case = TRUE) ~ "4",
  grepl("^5", password, ignore.case = TRUE) ~ "5",
  grepl("^6", password, ignore.case = TRUE) ~ "6",
  grepl("^7", password, ignore.case = TRUE) ~ "7",
  grepl("^8", password, ignore.case = TRUE) ~ "8",
  grepl("^9", password, ignore.case = TRUE) ~ "9"))# get rid of NA's
df_total <- na.omit(df_total)

默认情况下,0–9 在 A-Z 之前,但是 McCandless 可视化将 A-Z 放在 0–9 之前,所以让我们重新安排一下。

df_total$group <- factor(df_total$group, levels = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U" , "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9"))

是时候重新创建数据可视化了。我们使用geom_text()来显示密码,根据密码强度调整大小,颜色与 McCandless 使用的主题和颜色相协调

library(ggplot2)
library(extrafont) # For the Georgia fontggplot(df_total, aes(x = group, y = rank)) +
geom_text(aes(label = password, color=category, size = font_size, alpha = 0.95)) + 
  # add the custom colors
  scale_color_manual(values=c("#477080", "#A3968A", "#C08B99", "#777C77", "#C8AB6D", "#819DAB", "#C18A6F", "#443F36", "#6A9577", "#BF655A")) +
  scale_y_continuous(position = "right", breaks = c(1,10,50,100,250,500)) + 
  scale_x_discrete(breaks = c("A","Z","1","9")) +
  scale_y_reverse() +
  labs(title = "Top 500 Passwords", subtitle = "Is yours here?", caption = "Source: bit.ly/KIB_Passwords") +
  labs(x = NULL, position = "top") +
theme(legend.position = "none",
      panel.background = element_blank(),
        plot.title = element_text(size = 13, 
                                  family = "Georgia", 
                                  face = "bold", lineheight = 1.2), plot.subtitle = element_text(size = 10,
                                     family = "Georgia"), 
        plot.caption = element_text(size = 5,
                                    hjust = 0.99, family = "Georgia"),  
        axis.text = element_text(family = "Georgia"))

McCandless 制作的数据集包含了很多关于密码如何被破解的信息。它也有一些选择密码的提示。不过,这个 xkcd 漫画可以很好地解释 TLDR:

在顶部框架中,密码破解软件更容易猜出 Tr0ub4dor & 3 密码,因为它比correct horse battery staple的熵更小,而且人类也更难记住,导致不安全的做法,如将密码写在显示器上的便利贴上。所以你应该总是把一个容易记住的句子转换成一个容易记住的密码,而不是一个随机的字母数字。

一茶匙糖

糖数据集可视化是一个圆形条形图,显示了常见饮料中的糖的茶匙数。该图使用了ggplot2 coord_polar选项(为了简化这篇文章,我排除了数据管理代码,而是提供了一个 *.csv* 文件以备绘图)。

sugar <- read.csv("sugar.csv")# Re-order the factors the way they appear in the data frame
names <- sugar$drinks
names
sugar$drinks <- factor(sugar$drinks, levels = rev(sugar$drinks), ordered = TRUE)# Create a custom color palette
custompalette <- c("#C87295", "#CE7E9C", "#CE7E9C", "#C3C969", "#B77E94", "#693945", "#63645D", "#F9D9E0", "#B96E8E", "#18090E", "#E1E87E", "#B47E8F", "#B26F8B", "#B47E8F", "#B26F8B", "#B47E8F", "#B26F8B", "#9397A0", "#97B7C4", "#9AA24F", "#6B4A4F", "#97A053", "#B7BB6B", "#97A053", "#B7BB6B", "#97A053", "#B7BB6B", "#97A053", "#B7BB6B",
"#CED97B", "#E4E89C", "#C87295", "#CE7E9C")ggplot(sugar, aes(x = drinks, y = teaspoons, fill = drinks)) +
  geom_bar(width = 0.75, stat = "identity") +
  coord_polar(theta = "y") +
  xlab("") + ylab("") +
  labs(title = "Teaspoons", caption = "Source: bit.ly/KIB_Sugar") +
  # Increase ylim to avoid having a complete circle and set custom breaks to range of teaspoons
  scale_y_continuous(limits = c(0,65), breaks=seq(0,26,1)) +
  scale_fill_manual(values = custompalette) +
  theme(legend.position = "none", 
        axis.text.y = element_blank(),
        axis.text.x = element_text(color = "white", family = "Georgia"),
        axis.ticks = element_blank(), 
        panel.background = element_rect(fill = "black", color = NA),
        plot.title = element_text(color = "white", 
                                  size = 13, 
                                  family = "Georgia", 
                                  face = "bold", lineheight = 1.2), 
        plot.caption = element_text(size = 5,
                                    hjust = 0.99, 
                                    color = "white", 
                                    family = "Georgia"),
        panel.grid.major.y = element_line(color = "grey48", size = 0.05, linetype = "dotted"),
        panel.grid.minor.y = element_blank(),
        panel.grid.major.x = element_blank())

最好是在条形旁边手动添加标签,而不是在axis.text.y =中调整hjust

尽管我认为这种视觉效果在美学上是令人愉悦的,但如果不提这些类型的图形最终应该被避免,那将是我的失职,因为很难/误导性地辨别群体之间的差异(这里有一个很好的链接,深入解释了 wh y)。

说到良好的数据可视化实践,大多数人会告诉你避免饼图、炸丨药图等。然而,我每天都能在学术出版物、政府报告等中看到它们。

谁知道呢,你的雇主可能会要求你制作一份背景带有公司标志的定制信息图。嗯,你很幸运!

大卫·麦克肯多斯在书中加入了一个 pieplot,我认为复制这个 pie plot 会很有用;仅仅是为了展示如何在绘图中包含背景图像。

谁拥有北极?

根据国际法,包括北极及其周围北冰洋区域在内的公海不属于任何国家。然而,延伸至北极大陆架的领土主张属于加拿大、俄罗斯、丹麦、挪威、美国和冰岛。

虽然在数据集中有很多信息,但我找不到他用于可视化的原始数据。因此,在这个例子中,我只给出一个大概的估计。

library(magick)# use image under Creative Commons Attribution-Share Alike 3.0 Unported license.
img <- image_read("[https://upload.wikimedia.org/wikipedia/commons/9/91/Arctic_Ocean_location_map.svg](https://upload.wikimedia.org/wikipedia/commons/9/91/Arctic_Ocean_location_map.svg)")bitmap <- img[[1]]
bitmap[4,,] <- as.raw(as.integer(bitmap[4,,]) * 0.4)
taster <- image_read(bitmap)# custom pallete
my_palette <- c("#ADDFEA","#E3E9A3", "#FFD283", "#CAC3CF", "#62465F", "#B8E29B")# Make data frame
df <- data.frame(
  country = c("USA", "Russia", "Norway", "Iceland", "Denmark", "Canada"), 
  percentage = c(10,46,13,5,18,18))# Re-order the factors the way they appear in the data frame
df$country <- factor(df$country, levels = c("USA", "Canada", "Denmark", "Iceland", "Norway", "Russia"), ordered = TRUE)g <- ggplot(df, aes(x = "", y=percentage, fill = country)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y", start=0) +
  scale_y_continuous(breaks = c(105,25,53,62,75,90),labels = c("USA", "Russia", "Norway", "Iceland", "Denmark", "Canada")) +
    xlab("") + ylab("") +
  labs(title = "Who owns the Arctic?", caption = "Source: bit.ly/KIB_PolePosition") +
  scale_fill_manual(values = my_palette) +
  theme(legend.position = "none", 
        axis.text.y = element_blank(),
        axis.text.x = element_text(color = c("#ADDFEA","#B8E29B", "#62465F", "#CAC3CF", "#FFD283", "#E3E9A3"), family = "Georgia", size = 7.6),
        axis.ticks = element_blank(), 
        panel.background = element_blank(),
        axis.line = element_blank(),
        plot.title = element_text(size = 13, 
                                  family = "Georgia", 
                                  face = "bold", lineheight = 1.2), 
        plot.caption = element_text(size = 5,
                                    hjust = 0.99, 
                                    vjust = 15,
                                    family = "Georgia"),
        panel.grid.minor = element_blank(),
        panel.grid.major = element_blank())# You need to fiddle with the settings in RStudio and then Export to PDF, JPG, TIFF, etc.
library(grid)
grid.newpage()
g
grid.draw(rasterGrob(width = 0.34, height = 0.666, image=taster, just = "centre", hjust = 0.46, vjust = 0.47))

更多怪异但(有时)有用的情节见异种图

本系列可复制的代码和内容可以在 Github 上找到

希望你喜欢这篇文章,并继续关注第三部分!

从《知识是美丽的》一书中再现(更多)数据可视化:第三部分

原文:https://towardsdatascience.com/recreating-more-data-visualizations-from-the-book-knowledge-is-beautiful-part-iii-5fd393b4c548?source=collection_archive---------6-----------------------

欢迎来到本系列的第三部分,在第R部分,我重新创建了数据可视化,来自大卫·麦坎多斯的《知识是美丽的》一书

该系列的第 IIIIV 部分的链接可在此处找到。

数据科学中的挫折有很多,例如:

考虑上面的第 4 点。即使数据是可用的,它仍然可以以令人沮丧的格式分发。在本系列的第一部分中,我展示了如何使用readxl包访问特定的 excel 表格。在第二部分中,我展示了如何用tabulizer包解析 R 中的 PDF 表格。一些人可能会感兴趣, Luis D. Verde 最近发表了一篇关于如何在 R 中处理 Excel 中令人沮丧的单元格格式的伟大文章。

尽管 McCandless 公开了所有数据,但在制作可视化之前,我还是做了一些清理工作。我决定,既然这个系列的重点是数据可视化,我将把数据管理代码留在这个系列的其余部分,而是提供为ggplot准备好的tidy数据的.csv文件。

长寿

长寿可视化是一个发散的条形图,描绘了某些行为如何影响你的寿命。

*library(dplyr)
library(ggplot2)# load the data
livelong <- read.csv("livelong.csv")# Order by action
livelong$action <- factor(livelong$action, levels = c("Sleep too much", "Be optimistic", "Get promoted", "Live in a city", "Live in the country", "Eat less food", "Hang out with women - a lot!", "Drink a little alcohol", "Be conscientious", "Have more orgasms", "And a little red wine", "With close friends", "Be polygamous, maybe", "Go to church regularly", "Sit down", "More pets", "Eat red meat", "Avoid cancer", "Avoid heart disease", "Be alcoholic", "Get health checks", "Get married!", "Be rich", "Be a woman", "Suffer severe mental illness", "Become obese", "Keep smoking", "Live healthily", "Exercise more", "Live at high altitude"))# Set legend title
legend_title <- "Strength of science"# Make plot
p <- ggplot(livelong, aes(x = action, y = years, fill=strength)) +
  geom_bar(stat = "identity") +
  scale_fill_manual(legend_title, values = c("#8BC7AC","#D99E50","#CDAD35")) +
  labs(title = "Live Long...", subtitle = "What will really extend your life?", caption = "Source: bit.ly/KIB_LiveLong") +
  scale_y_continuous(position = "bottom") +
  scale_x_discrete(limits = rev(factor(livelong$action))) +
  #scale_x_reverse() +
  coord_flip() +
  theme(legend.position = "top",
      panel.background = element_blank(),
        plot.title = element_text(size = 13, 
                                  family = "Georgia", 
                                  face = "bold", lineheight = 1.2), plot.subtitle = element_text(size = 10,
                                     family = "Georgia"), 
        plot.caption = element_text(size = 5,
                                    hjust = 0.99, family = "Georgia"),  
        axis.text = element_text(family = "Georgia"),
      # Get rid of the y- and x-axis titles
      axis.title.y=element_blank(),
      axis.title.x=element_blank(),
      # Get rid of axis text
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank(),
      legend.text = element_text(size = 8, family = "Georgia"),
      legend.title = element_text(size = 8, family = "Georgia"),
      legend.key.size = unit(1,"line"))*

好的,这是第一次尝试用geom_text()做注释

*p + geom_text(aes(label = action), size = 3, family = "Georgia")*

人们会立即注意到文本注释没有对齐。此外,由于条形图在中心(零)发散,修改hjust参数本身并不能解决问题。

一个可能的解决方法是使用ggfittext包,它通过geom_fit_text()函数将文本约束在一个定义的区域内,该函数的工作方式与ggplot2::geom_text()差不多。

*# currently only supported by the dev version
devtools::install_github("wilkox/ggfittext")
library(ggfittext)p + geom_fit_text(aes(label = action), position = "stack", family = "Georgia")*

我们看到小条没有被注释,因为字符串太大了,无法在条中显示。

最初的可视化从来不会将文本限制在条中,所以最好的方法是向表中添加一个变量,允许您左对齐一些标签,右对齐其他标签。

*# Set postive as "Up" and negative numbers as "Down"
livelong$direction <- ifelse(livelong$years > 0, "Up", "Down")livelong$just <- ifelse(livelong$direction=="Down",0,1)p + geom_text(aes(label = action), size = 3, family = "Georgia", hjust=livelong$just)*

这证明了盒子的合理性,因此减少你寿命的行为是左调整的,而延长你寿命的行为是右调整的。唯一的问题是,在最初的可视化中,文本排列在图表的中心。我不知道如何做到这一点,所以加分,如果你能想出这一点,并张贴到评论!

一个视觉上吸引人的选择是把名字放在栏外。

*livelong$just <- ifelse(livelong$direction=="Up",0,1)p + geom_text(aes(label = action), size = 3, family = "Georgia", hjust=livelong$just)*

盘点原因英国

统计英国慈善事业数据集显示了英国公民捐赠最多的慈善机构。

我们可以使用Treemap库创建一个类似的可视化。它创建嵌套矩形的分层显示,然后平铺在代表子分支的较小矩形内。

*library(treemap)my_data <- read.csv("treemap.csv")tm <- treemap(my_data, index = c("main","second", "third"), vSize = "percent", vColor = "percent", type = "value", title = "Counting the Cause UK")*

从《知识是美丽的》一书中再现(更多)数据可视化:第四部分

原文:https://towardsdatascience.com/recreating-more-data-visualizations-from-the-book-knowledge-is-beautiful-part-iv-686938a84c9e?source=collection_archive---------6-----------------------

欢迎来到本系列的最后一部分,在这里我用 R 语言重新创建了 David McCandless 所著的《知识是美丽的》一书中的数据可视化。

此处可找到该系列第部分 IIIIII 的链接。

飞机坠毁

这个数据集将用于几个可视化。

第一个可视化是一个堆积条形图,显示了从 1993 年到 2017 年 1 月的每架飞机失事的原因(为非军事、医疗或私人包机航班)。

library(dplyr)
library(ggplot2)
library(tidyr)
library(extrafont)df <- read.csv("worst_plane.csv")# Drop the year plane model entered service
mini_df <- df %>% 
  select(-year_service) %>% 
# Gather the wide dataframe into a tidy format
  gather(key = cause, value = proportion, -plane)
# Order by cause
mini_df$cause <- factor(mini_df$cause, levels = c("human_error","weather", "mechanical", "unknown", "criminal"), ordered = TRUE)# Create vector of plane names according to year they entered service
names <- unique(mini_df$plane)
names <- as.vector(names)
# sort by factor
mini_df$plane <- factor(mini_df$plane, levels = names)ggplot(mini_df, aes(x=plane, y=proportion, fill=cause)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  # Reverse the order of a categorical axis
  scale_x_discrete(limits = rev(levels(mini_df$plane))) +
  # Select manual colors that McCandless used
  scale_fill_manual(values = c("#8E5A7E", "#A3BEC7", "#E1BD81", "#E9E4E0", "#74756F"), labels = c("Human Error", "Weather", "Mechanical", "Unknown", "Criminal")) +
  labs(title = "Worst Planes", caption = "Source: bit.ly/KIB_PlaneCrashes") +
  scale_y_reverse() +
  theme(legend.position = "right",
      panel.background = element_blank(),
        plot.title = element_text(size = 13, 
                                  family = "Georgia", 
                                  face = "bold", lineheight = 1.2),
      plot.caption = element_text(size = 5,
                                    hjust = 0.99, family = "Georgia"),
      axis.text = element_text(family = "Georgia"), 
      # Get rid of the x axis text/title 
      axis.text.x=element_blank(),
      axis.title.x=element_blank(),
      # and y axis title
      axis.title.y=element_blank(),
      # and legend title
      legend.title = element_blank(),
      legend.text = element_text(family = "Georgia"),
      axis.ticks = element_blank())

第二个可视化是一个冲积图,我们可以使用ggalluvial包。我应该提到的是,McCandless 最初的可视化要比现在产生的更加花哨,但是显示了相同的基本信息。

library(alluvial)
library(ggalluvial)crash <- read.csv("crashes_alluvial.csv")# stratum = cause, alluvium = freqggplot(crash, aes(weight = freq,
                  axis1 = phase,
                  axis2 = cause,
                  axis3 = total_crashes)) +
  geom_alluvium(aes(fill = cause),
                width = 0, knot.pos = 0, reverse = FALSE) +
  guides(fill = FALSE) +
  geom_stratum(width = 1/8, reverse = FALSE) +
  geom_text(stat = "stratum", label.strata = TRUE, reverse = FALSE, size = 2.5) +
  scale_x_continuous(breaks = 1:3, labels = c("phase", "causes", "total crashes")) +
  coord_flip() +
  labs(title = "Crash Cause", caption = "Source: bit.ly/KIB_PlaneCrashes") +
  theme(panel.background = element_blank(),
        plot.title = element_text(size = 13, 
                                  family = "Georgia", 
                                  face = "bold",
                                  lineheight = 1.2,
                                  vjust = -3,
                                  hjust = 0.05), 
        plot.caption = element_text(size = 5,
                                    hjust = 0.99, family = "Georgia"),  
        axis.text = element_text(family = "Georgia"),
      axis.text.x = element_blank(),
      axis.ticks.x = element_blank(),
      axis.ticks.y = element_blank())

在我看来,产生桑基图的一个更干净的方法是用包flipPlot

devtools::install_github(Displayr/flipPlots)
library(flipPlots)# reorder the df
crash$total_crashes <- rep("YES", 25)# plot
SankeyDiagram(crash[, -4], link.color = "Source", label.show.varname = FALSE, weights = crash$freq)

我可能只是旋转图像和标签,并将“是”改为“总崩溃数(427)”

性别差距

该图描绘了英国不同行业中男性和女性的工资差距,以及同一类别中每个职位的平均工资。我们可以使用group_by()summarize_at()为每个类别创建一个新变量,然后使用facet_wrap()。由于位置仅属于一个类别,您需要设置scales = "free_x"用于遗漏观察。

gendergap <- read.csv("gendergap.csv")# gather the dataset
tidy_gap <- gendergap %>% 
  gather(key = sex, value = salary, -title, -category)category_means <- tidy_gap %>% 
  group_by(category) %>%
  summarize_at(vars(salary), mean)tidy_gap %>% ggplot(aes(x = title, y = salary, color = sex)) +
  facet_grid(. ~ category, scales = "free_x", space = "free") +
  geom_line(color = "white") +
  geom_point() +
  scale_color_manual(values = c("#F49171", "#81C19C")) +
  geom_hline(data = category_means, aes(yintercept = salary), color = "white", alpha = 0.6, size = 1) +
  theme(legend.position = "none",
      panel.background = element_rect(color = "#242B47", fill = "#242B47"),
      plot.background = element_rect(color = "#242B47", fill = "#242B47"),
      axis.line = element_line(color = "grey48", size = 0.05, linetype = "dotted"),
      axis.text = element_text(family = "Georgia", color = "white"),
      axis.text.x = element_text(angle = 90),
      # Get rid of the y- and x-axis titles
      axis.title.y=element_blank(),
      axis.title.x=element_blank(),
      panel.grid.major.y = element_line(color = "grey48", size = 0.05),
      panel.grid.minor.y = element_blank(),
      panel.grid.major.x = element_blank(),
      strip.background = element_rect(color = "#242B47", fill = "#242B47"),
      strip.text = element_text(color = "white", family = "Georgia")) 

我不确定如何处理的一件事是 x 轴上每个变量之间的间距。由于每个刻面有不同数量的变量,如果能指定他们想要沿 x 轴等间距作为facet_wrap()中的一个选项就更好了;然而,我认为这是不可能的(如果你知道一个变通办法,请留下评论!).

编辑 2018 年 9 月 5 日

多亏了 StackOverflow 的非常有帮助的社区的帮助,我知道我需要的是facet_grid()而不是facet_wrap()。如果任何人知道如何手动调整 x 轴上每个类别之间的距离(例如最小化间距),将获得加分。

这就是我的全部,做这个系列很有趣,我希望你喜欢!

最好的神奇宝贝类型是什么?度量的力量

原文:https://towardsdatascience.com/recreational-data-science-whats-the-best-pokémon-type-d3fcd28ea740?source=collection_archive---------2-----------------------

Source: Pixabay

我们都知道最好的类型是什么(通灵。证明我错了。),但是数据怎么说呢?

有时候,数据科学是关于做出艰难的选择,或者为公司赚很多钱。但在其他时候,数据科学可能只是一个雨天周末的有趣爱好。

本周,我一直忙于一项大学作业:我和几个同学不得不编写 PageRank 算法——在人工智能和 NLP 吃掉其他一切之前,谷歌曾用于搜索的算法。

什么是 PageRank?

PageRank 是一种算法,用于获得系统连接部分的排名——非常适合网站排名,这是它的最初目的。

基于其最初的任务,它测量并排列许多相互链接(边)的节点(网站)的重要性或影响力。

该算法将一个有向图作为其输入,并返回其节点的排名——以及一些介于 0 和 1 之间的评分——以及一些标准:

  • 如果更多的节点链接到你,你的排名会更高。
  • 如果链接到更多的节点,那么链接到另一个节点就不太相关了。
  • 被排名较高的节点链接更好。

这与一个大网站的想法是一致的,比如 Medium,会被很多来源链接,而被一个大网站链接(比如脸书的主页)也意味着你的网站非常相关。您还可以使用它来模拟科学论文或出版物的相关性(使用引用作为链接),或者动物在给定生态系统中被吃掉的概率(用食物链作为图形)。

所以我一直想写一篇有趣的文章,我有这个 PageRank 实现…我不能错过这个机会。

获取数据

首先,我开始着手收集数据。

因为我想建模的只是类型关系,所以我打算使用 Bulbapedia(神奇宝贝的 Wiki)——但后来我发现其他人可能已经编写了这部分代码。实际上,几秒钟的搜索让我到了这个令人敬畏的链接,从中我获得了游戏中类型优势的 Python 矩阵。
这使用了第六代的类型和关系。我还没抽时间弹第七首,所以我不介意。

已经用 Python 加载了原始矩阵,我必须给它正确的格式:PageRank 作为输入的那种图中的链接没有权重——它们是二进制的:要么链接到某个东西,要么不链接(如果有不同的 PageRank 实现来解决这个问题,请在评论中告诉我!).

如果你没有玩过神奇宝贝或者你对细节不清楚,每种类型都可以对另一种类型保持中立(大多数类型都是相互中立的),具有优势(造成 2 倍伤害),劣势(造成 1/2 伤害)或者免疫(0 伤害)。

我将这种格式(4 种不同的关系)转移到二进制域的方式是简单地绘制两个不同的图形:一个是攻击者的,一个是防御者的。我还把免疫和抵抗归为一类(防御优势,如果你愿意的话)——我希望这不会冒犯任何铁杆粉丝。

还有另一个问题:PageRank 没有考虑链接到自己的网站,所以我们不能使用关于神奇宝贝类型对自己脆弱或对自己有效的数据。(充分披露:在这篇文章的初稿中,我没有意识到这一点,一位读者让我注意到了我的错误。结果变了。)

PageRank 结果

这是我从模拟攻击类型中得到的结果。如果类型 A 对类型 B 非常有效,我只将类型 A 链接到类型 B,而不将任何类型链接到它们自己(因为这违反了 PageRanks 的前提条件)。

Somehow grass wins? And Rock is a very close second, with Psychic third.

正如我所料,灵媒进入了前 3 名。龙有一个非常糟糕的地方,这让我很惊讶,除了龙的一个优点是对其他龙非常有效,这是这个算法无法捕捉到的。电动类型排在最后,尽管水应该是最常见的神奇宝贝类型。

与此同时,防御型的结果也相当令人惊讶:

龙最后出来,尾巴上结着冰。另一方面,战斗和 Bug 是最重要的,是最有抵抗力的类型。尽管臭虫不是一种很强的防御类型,但它能抵抗三种不同的类型,其中一种是战斗型,它在排行榜上名列第一,这也解释了为什么它会如此接近榜首。

(免责声明:在之前的草稿里我说冰抗龙,其实只是龙弱于冰而已。抱歉。)

我觉得结果不太直观,也许不同的模型会更好。例如,这个模型不能捕捉一个弱于自身的类型,也不能处理水型神奇宝贝比龙型神奇宝贝出现的频率高多少。

这里有一个到原始结果的链接,以防你想以不同的方式可视化它们。

尝试不同的指标

我对我在进攻端的成绩很满意,但是防守型神奇宝贝的排名不可能有那么好。所以我开始寻找其他的衡量标准。

我想也许一个简单的衡量标准

sum (Damage modifier)*(#pokémon of that type) over every type

可以产生更直观的结果,类似于“预期损害”。让我们看看我有什么。

我发现了一个 redditor,他友好地收集了每种类型的神奇宝贝的数量,所以我引用他作为我的来源。

对于每一种神奇宝贝,我都会数两次,如果它们很弱,0 表示它们有免疫力,一半表示它们有抵抗力,一次表示没有抵抗力。

Expected dealt damage for attacking pokemon types, against other pokemon. Minus 1000 for centering.

这次

  • 臭虫是第二弱的。
  • 草最后出来。它在其他排名中名列第一。
  • 岩石、地面、冰和飞行非常接近前四名。
  • 洛克在这两个进攻指标上都做得很好。

看起来即使草类比其他种类更强,但是这些种类的神奇宝贝却更少。不过,摇滚似乎一直都不错。将来,我可能会在不考虑传奇神奇宝贝的情况下再看看这些数字,因为它们无论如何都不能用于比赛。

Expected received damage (bigger is worse) by type. Minus 600 for centering.

如果我反其道而行之,仅根据类型来计算神奇宝贝应该受到的“预期伤害”,这些是关键的见解:

  • 钢铁是最好的防御神奇宝贝类型,可能是由于它对毒药的免疫和许多抗性。它以超过 20%的优势战胜了第二种类型。
  • 讽刺的是,最糟糕的防御类型是冰,其预期伤害比钢高 50%。
  • 地面和岩石是一贯良好的伤害处理者,但却是非常糟糕的防御类型,这使得游戏场保持公平。
  • 不出所料,Bug 不仅是一个糟糕的进攻者,也是一个糟糕的防守者。

我个人觉得这些排名比第一批更直观。

对于那些想看这个分析的全部结果的人来说,这些数字可以在这个要点中找到。

最终结论

看到这些数字后,我觉得我对神奇宝贝的种类有了更好的直觉。老实说,最让我惊讶的是这个系统有多公平:从某些指标来看,最好的神奇宝贝在其他指标上是最差的,大多数都落在中间。大多数玩家做出的一些假设已经被证实了:臭虫不是一个非常强大的类型(如果把它考虑在分析中,它缺乏强大的攻击会使它更弱),岩石和地面是非常好的玻璃炮(所以继续教非地面类型的神奇宝贝地震),大多数类型只是落在中间。此外,钢是一个非常可爱的坦克。

在未来,我可能会回来做另一个更细致的分析,查看当前元的状态,或者按类型查看神奇宝贝的统计数据,特别是将它们分为特殊坦克、物理坦克、特殊 DPS 和物理 DPS。

我希望你觉得这很有趣,甚至发人深省。我很乐意接受任何批评或想法。你对这篇文章或这些结果有什么看法?你认为还有哪些问题可以用 PageRank 很好地建模?你认为做其他什么分析会很有趣?
请在评论中告诉我所有这些问题的答案!

关注我获取更多数据科学和分析文章,如果你喜欢阅读这些文章,请考虑 支持我的写作习惯。

RecSys 2017

原文:https://towardsdatascience.com/recsys-2017-2d0879351097?source=collection_archive---------7-----------------------

Not a bad location for a conferance

每年推荐系统社区(学术界和工业界都一样)聚集在一起分享关于推荐系统的研究、思想和想法。今年的会议在科莫湖举行,有 40 多场演讲、11 场行业讲座、10 场研讨会和 4 场辅导课,吸引了 600 多名与会者。

如果我对下面的文章有任何误解,请纠正我。

关键主题

在整个会议中,我认为有三个强有力的主题贯穿始终;

  • 深度学习 —正如在许多其他学科(NLP 和计算机视觉)中看到的那样,深度学习继续变得越来越受欢迎。尽管这些论文声称在测试数据集的准确性方面取得了显著的进步,但许多论文已经开始批评它的有效性,并质疑与类似模型相比,这种复杂系统的价值。
  • 个性化——和任何推荐器一样,其目标之一是在正确的时间呈现用户想要的信息。个性化推荐采取了多种形式,从尝试在 LtR 模型中使用个人信息对项目进行排序,使用更高层次的 RNNs 对会话推荐进行个性化,到为系统内的每个用户训练模型。每个放映效果导致对用户的个性化推荐。
  • 工业界与学术界——这场战斗已经持续了多年,尽管这两者之间似乎是一种健康的关系。工业似乎带来了有趣的数据和真实的生活结果。然而学术界展示了许多关于推荐的有趣模型和理论(例如会话式推荐系统)。尽管在将学术界应用到工业规模之间,甚至在如何将一些模型应用到一台机器之外之间,似乎存在着差距。

有趣的论文

提交了一些有趣的论文,以下是非常好的。这些论文通常简单明了地表达了他们想要达到的目标,并有效地传达了一个概念。

控制学习排名推荐中的人气偏差

Abdollahpouri, H., Burke, R., & Mobasher, B. (2017). Controlling Popularity Bias in Learning-to-Rank Recommendation (pp. 42–46). Presented at the the Eleventh ACM Conference, New York, New York, USA: ACM Press. [http://doi.org/10.1145/3109859.3109912](http://doi.org/10.1145/3109859.3109912)

推荐面临的挑战之一是如何让用户发现日志尾部的项目。因为长尾中的项目可能比高度流行的项目更与用户相关。本文作者将项目分为高、中、低三个等级。目的是最终的推荐列表应该由 50/50 的高等级和中等级项目组成。为了实现这一点,研究人员引入了矩阵分解方法的调节阶段,该方法基于指示项目对是否在不同等级类别中的相异矩阵。这只会影响项目嵌入,而不会影响用户嵌入。

结果表明,用户可以在不降低质量的情况下向用户推荐大量的长尾项目(通过 NDCG@10 测量)。在实施这种简单的方法中,有两个潜在的好处,首先,探索了目录的更大推广,因此如果在生产环境中实施,可以获得更大量的反馈。第二,用户之间推荐的多样性增加,从而减少了正在创建的过滤器 bubel 的变化。

尽管这可能不是突破性的,但简单的想法有时会对产生建议产生最大的影响。尽管与任何矩阵工厂方法一样,将它扩展到真实世界数据的能力总是引起我的兴趣,但与之前的实验一样,矩阵分解似乎只适用于用户活动大小变化较小的数据集,并且容易受到噪声数据集的影响。

当递归神经网络遇到邻居时进行基于会话的推荐

Jannach, D., & Ludewig, M. (2017). When Recurrent Neural Networks meet the Neighborhood for Session-Based Recommendation (pp. 306–310). Presented at the the Eleventh ACM Conference, New York, New York, USA: ACM Press. [http://doi.org/10.1145/3109859.3109872](http://doi.org/10.1145/3109859.3109872)

在演示结束时,这篇论文似乎在房间里引起了一点紧张。尽管它强调了使用深度学习系统的一个问题,即人们可以使用基本(更简单)的 ML 模型获得类似(或更好)的结果。作者比较了门控循环单元(GRU4REC) 1 和 kNN 的一些设置,以生成会话推荐。结果表明,与使用复杂的 GRUs 相比,使用 kNN 方法可以获得相似或更好的精度。尽管当两种方法结合使用时可以达到最佳效果。

在 Zalando 开发大规模推荐系统的实践经验

Freno, A. (2017). Practical Lessons from Developing a Large-Scale Recommender System at Zalando (pp. 251–259). Presented at the the Eleventh ACM Conference, New York, New York, USA: ACM Press. [http://doi.org/10.1145/3109859.3109897](http://doi.org/10.1145/3109859.3109897)

RecSys 的一个优点是在会议记录中混合了行业领先的论文。来自 Zalando 的这篇文章重点介绍了他们如何在多个产品中大规模部署学习排名(LTR)。为了扩展模型学习,他们采用成对方法,这样就可以使用 Spark 和 SparkML 等分布式框架进行大规模学习。

一种基于梯度的自适应学习框架,用于高效的个人推荐

Ning, Y., Shi, Y., Hong, L., Rangwala, H., & Ramakrishnan, N. (2017). A Gradient-based Adaptive Learning Framework for Efficient Personal Recommendation (pp. 23–31). Presented at the the Eleventh ACM Conference, New York, New York, USA: ACM Press. [http://doi.org/10.1145/3109859.3109909](http://doi.org/10.1145/3109859.3109909)

本文提出了一个有趣的模型(或多个模型)。其前提是,当训练一个模型来生成推荐时,它是根据一个全局目标函数来学习的,该目标函数产生系统内用户的平均模型。为了使用户或用户组的模型个性化,作者建议可以首先训练多个时期的“全局”模型,然后将模型的模型权重转移到“局部”模型,以继续对用户子集进行训练,从而提高个性化推荐器模型的个性化和训练速度。

有趣的礼物

在整个会议中,许多行业的焦点都集中在演讲上。这些研究本质上不一定是学术性的,但却很好地揭示了建议研究如何在实践中应用,以及如何在规模上进行编排。

网飞——如果没有网飞的介绍,这就不是一个推荐会议。正如在推荐和推荐系统的介绍中所强调的,它们受到过去用户行为的影响,并影响未来用户的意图。因此,如何在推荐器中建模时间,允许开发的模型与时间的时间效应隔离。

Déjà Vu:推荐系统中时间和因果关系的重要性 出自 贾斯汀巴西利科

  • 最大限度地减少系统内的反馈循环
  • 允许有控制地探索建议
  • 增量

Blendal 是一家专注于新闻推荐的丹麦公司。他们展示的产品/挑战是他们如何每天获取 7000 篇新文章,并在早上 7 点前通过个性化电子邮件推荐给用户(供他们评论工作时使用)。通过使用用户建模和基于内容的功能,他们能够为用户选择相关的文章。尽管这个演讲有趣的部分是他们使用了一个带交错的凌渡 bandit 来在线调整模型的参数,允许系统从用户的隐含反馈中学习。

blend le @ rec sys’17:在线学习推荐系统排名 来自 金奎大奥迪克

  • 人类策划的候选集
  • 德国强盗
  • 团队草稿交错
  • 多样化

EA(在游戏里) —我被这个演示给惊喜了。它展示了推荐不仅仅是整个系统的一种算法,它会影响用户体验的每一个阶段。然而,这不仅仅是一个推荐者,而是一套互动系统,所有这些系统都旨在引导玩家完成游戏,优化用户流失率。

总的来说,这是一个了不起的会议,我等不及明年的温哥华了。

See you next year

  1. Bala zs hid ASI、Alexandros Karatzoglou、Linas Baltrunas 和 Domonkos Tikk。2016.基于会话的递归神经网络推荐。学习表征国际会议论文集(ICLR 16)。ACM。h p://arxiv . org/ABS/1511.06939↩︎

构建你自己的递归神经网络

原文:https://towardsdatascience.com/recurrent-neural-networks-6b67535550ca?source=collection_archive---------8-----------------------

神经网络是一类模仿人脑的机器学习算法,而 递归神经网络 是一个子类,可以很好地处理数据序列,如文本。

用一个普通的神经网络,你得到一组输入数据,让它通过网络,得到一组输出

为了训练深度学习模型,你需要知道模型应该理想地输出什么,这通常被称为你的标签或目标变量。神经网络将其输出的数据与目标进行比较,并更新网络学习以更好地模拟目标。

递归神经网络(RNNs)在建模序列数据中是有用的,序列数据涉及时间模式,如文本、图像字幕、ICU 患者数据等。这是一个简单的带反馈的前馈神经网络。在每个时间步,基于当前的输入和过去的输出,它生成新的输出。一个简单的递归神经网络架构看起来像:

rnn 比简单的前馈神经网络灵活得多。我们可以向 rnn 传递可变大小的输入,甚至得到可变大小的输出。例如,可以模拟 RNN 来一点一点地学习二进制加法。它学习二进制加法器的状态机图。经过训练后,我们只需向它传递两个任意大小的输入,它就可以生成正确的输出,而无需执行任何加法运算!RNN 能够自己隐含地学习这些语义。

为了让 RNNs 工作,需要大量的数据来找到一个好的模型,我尝试了各种 RNNs 架构,这些架构具有不同的层数、每层中隐藏单元的数量、序列长度和批量大小。所有这些超参数都应该根据数据集进行智能调整,否则可能会出现过度拟合或拟合不足的情况。生成的结果将严重依赖于数据,并且由于数据是从各种网站爬取的,因此有时可能会令人反感且不合适。

递归神经网络的步骤

初始化

这是初始化权重的第一步,你可以用三种不同的方式初始化。

1)全零。

2)随机值(取决于激活函数)

  1. Xavier 初始化:区间内的随机值从[-1/√n,1/√n],
    其中 n 为入局连接数

构建一个

正向传播

前向传播的作用是穿过终点。

s_t=f(Ux_t+Ws_(t-1))

新状态

s_(t-1):旧状态

x_t:某一时间步的输入向量

函数 f 通常是非线性的,例如 tanhReLU

计算损失

寻找损失是训练的重要阶段损失函数决定了你的模型的状态让我们试试

交叉熵损失:

L(y,o)=-1/n∑_(n∈n)ࣼy _ nlog⁡(o_n)〗

随机梯度下降(SGD)

这是优化你的模型的最流行的方法,SGD 是你分批发送输入而不是全部输入的方法,通过这种方法你可以很容易地缩放你的模型。

穿越时间的反向传播(BPTT)

这是一种技术,在这种技术中,您将再次遍历到起点,并根据优化器的结果更新您的权重。

用于脚本生成的递归神经网络的实现

[## karthiktsaliki/script _ generation _ rnn

训练了一个生成电视节目脚本的 rnn。

github.com](https://github.com/karthiktsaliki/script_generation_rnn/blob/master/dlnd_tv_script_generation.ipynb)

Python 中的递归神经网络实例

原文:https://towardsdatascience.com/recurrent-neural-networks-by-example-in-python-ffd204f99470?source=collection_archive---------0-----------------------

(Source)

利用递归神经网络撰写专利摘要

当我第一次尝试研究递归神经网络时,我犯了一个错误,那就是试图先学习 LSTMs 和 GRUs 之类的东西背后的理论。在看了几天令人沮丧的线性代数方程后,我在用 Python 进行深度学习的中看到了下面这段话

总之,你不需要了解 LSTM 细胞的具体架构的一切;作为一个人类,理解它不应该是你的工作。请记住 LSTM 细胞的作用:允许过去的信息在以后被重新注入。

这是库喀拉斯(Francois Chollet)的作者,深度学习方面的专家,他告诉我,我不需要理解基础水平的所有东西!我意识到我的错误是从理论的底层开始,而不是试图建立一个递归神经网络。

此后不久,我改变了策略,决定尝试学习数据科学技术的最有效方法:找到问题并解决它!

这种自上而下的方法是指在 之前学习如何 实现 一种方法 回溯并覆盖 理论 。通过这种方式,我能够在前进的道路上找到我需要知道的东西,当我回来研究这些概念时,我有了一个框架,我可以将每个想法放入其中。在这种心态下,我决定不再担心细节,完成一个递归神经网络项目。**

本文介绍了如何在 Keras 中构建和使用递归神经网络来撰写专利摘要。这篇文章没有什么理论,但是当你完成这个项目的时候,你会发现你在这个过程中得到了你需要知道的东西。最终结果是,你可以构建一个有用的应用程序,并弄清楚自然语言处理的深度学习方法是如何工作的。

完整的代码可以从 GitHub 上的一系列 Jupyter 笔记本中获得。我还提供了所有的预训练模型,这样你就不用自己花几个小时训练它们了!为了尽可能快地开始并研究模型,参见循环神经网络快速入门,为了更深入的解释,参见深入循环神经网络

递归神经网络

在开始实现之前,至少理解一些基础知识是有帮助的。在高层次上,一个递归神经网络 (RNN)处理序列——无论是每日股票价格、句子还是传感器测量——一次一个元素,同时保留序列中先前出现的内容的内存(称为状态)。

**循环表示当前时间步的输出成为下一个时间步的输入。对于序列中的每个元素,模型不仅考虑当前的输入,还会考虑它对前面元素的记忆。

Overview of RNN (Source)

这种记忆使网络能够按顺序学习长期依赖性,这意味着它可以在进行预测时考虑整个上下文,无论是句子中的下一个单词、情感分类还是下一次温度测量。RNN 是为了模仿人类处理序列的方式而设计的:在形成反应时,我们会考虑整个句子,而不是单词本身。例如,考虑下面的句子:

"在乐队热身的前 15 分钟,音乐会很无聊,但随后就变得非常令人兴奋。"

一个孤立地考虑单词的机器学习模型——比如一个单词包模型——可能会得出这个句子是否定的结论。相比之下,RNN 人应该能够看到“但是”和“非常令人兴奋”这些词,并意识到句子从否定变成了肯定,因为它已经查看了整个序列。阅读一个完整的序列给我们一个处理其意义的环境,一个编码在循环神经网络中的概念。

RNN 的核心是由记忆细胞构成的一层。目前最受欢迎的细胞是长短期记忆 (LSTM),它保持细胞状态和进位,以确保信号(梯度的形式的信息)在序列处理时不会丢失。在每个时间步,LSTM 考虑当前字、进位和单元状态。

LSTM (Long Short Term Memory) Cell (Source)

LSTM 有 3 个不同的门和权重向量:有一个“忘记”门用于丢弃不相关的信息;一个“输入”门用于处理当前输入,一个“输出”门用于在每个时间步产生预测。然而,正如 Chollet 指出的,试图给细胞中的每一个元素赋予特定的含义是徒劳的。

每个单元元件的功能最终由在训练期间学习的参数(权重)决定。随意标记每个细胞部分,但它不是有效使用的必要条件!回想一下,用于序列学习的递归神经网络的好处是它保持整个序列的记忆,防止先前的信息丢失。

问题定式化

有几种方法我们可以制定的任务,训练 RNN 写文本,在这种情况下,专利摘要。但是,我们将选择将其训练为多对一序列映射器。也就是说,我们输入一系列单词,然后训练模型来预测下一个单词。在被传递到 LSTM 层之前,单词将被映射到整数,然后使用嵌入矩阵(预训练的或可训练的)被映射到向量。

当我们去写一个新的专利时,我们传入一个单词的起始序列,对下一个单词进行预测,更新输入序列,进行另一个预测,将这个单词添加到序列中,然后继续我们想要生成的单词。

该方法的步骤概述如下:

  1. 将摘要从字符串列表转换为整数列表(序列)
  2. 根据序列创建要素和标注
  3. 使用嵌入层、LSTM 层和密集层构建 LSTM 模型
  4. 加载预先训练的嵌入
  5. 训练模型以预测下一步工作
  6. 通过传入起始序列进行预测

请记住,这只是问题的一种表述:我们还可以使用字符级模型,或者对序列中的每个单词进行预测。正如机器学习中的许多概念一样,没有一个正确的答案,但这种方法在实践中效果很好。

数据准备

即使神经网络具有强大的表示能力,获得高质量、干净的数据集也是至关重要的。这个项目的原始数据来自 USPTO PatentsView ,在这里你可以搜索在美国申请的任何专利的信息。我搜索了“神经网络”这个词,并下载了由此产生的专利摘要——总共 3500 篇。我发现最好在一个狭窄的主题上进行训练,但也可以尝试不同的专利。

Patent Abstract Data

我们将从专利摘要作为字符串列表开始。我们模型的主要数据准备步骤是:

  1. 删除标点符号,将字符串拆分成单个单词的列表
  2. 将单个单词转换成整数

这两个步骤都可以使用 Keras [Tokenizer](https://keras.io/preprocessing/text/#tokenizer)类来完成。默认情况下,这会删除所有标点符号,小写单词,然后将单词转换为整数的sequences。一个Tokenizer首先是一个字符串列表上的fit,然后将这个列表转换成一个整数列表的列表。下面演示了这一点:

第一个单元的输出显示原始摘要,第二个单元的输出显示标记化序列。每个抽象现在都表示为整数。

我们可以使用经过训练的记号赋予器的idx_word属性来计算这些整数的含义:

如果你仔细观察,你会注意到Tokenizer去掉了所有的标点符号,所有的单词都变成了小写。如果我们使用这些设置,那么神经网络将不会学习正确的英语!我们可以通过将过滤器更改为Tokenizer来调整这一点,以便不删除标点符号。

*# Don't remove punctuation or uppercase
tokenizer = Tokenizer(num_words=None, 
                     filters='#$%&()*+-<=>@[\\]^_`{|}~\t\n',
                     lower = False, split = ' ')*

查看不同实现的笔记本,但是,当我们使用预先训练的嵌入时,我们必须删除大写字母,因为嵌入中没有小写字母。当训练我们自己的嵌入时,我们不必担心这一点,因为模型将学习小写和大写的不同表示。

功能和标签

前一步将所有摘要转换成整数序列。下一步是创建一个有监督的机器学习问题,用它来训练网络。有许多方法可以为文本生成设置递归神经网络任务,但我们将使用以下方法:

给网络一个单词序列,训练它预测下一个单词。

单词数作为参数留下;在这里显示的例子中,我们将使用 50,这意味着我们给我们的网络 50 个单词,并训练它预测第 51 个单词。训练网络的其他方法是让它预测序列中每一点的下一个单词——对每个输入单词进行预测,而不是对整个序列进行一次预测——或者使用单个字符训练模型。这里使用的实现不一定是最佳的——没有公认的最佳解决方案——但是它工作得很好

创建特征和标签相对简单,对于每个抽象(用整数表示),我们创建多组特征和标签。我们使用前 50 个单词作为特征,第 51 个单词作为标签,然后使用单词 2-51 作为特征,预测第 52 个单词,依此类推。这给了我们更多的训练数据,这是有益的,因为网络的性能与它在训练期间看到的数据量成比例。

创建要素和标注的实现如下:

这些特征以形状(296866, 50)结束,这意味着我们有将近 300,000 个序列,每个序列有 50 个标记。在递归神经网络的语言中,每个序列有 50 个时间步,每个时间步有 1 个特征。

我们可以将标签保留为整数,但是当标签被一次性编码时,神经网络能够最有效地训练。我们可以使用下面的代码非常快速地用numpy对标签进行一次性编码:

为了找到与label_array中的一行相对应的单词,我们使用:

在正确格式化我们所有的特性和标签之后,我们希望将它们分成一个训练集和一个验证集(详见笔记本)。这里很重要的一点是同时改变特性和标签,这样相同的摘要就不会出现在同一个集合中。

构建递归神经网络

Keras 是一个不可思议的库:它允许我们用几行可理解的 Python 代码构建最先进的模型。虽然其他神经网络库可能更快或更灵活,但在开发时间和易用性方面,没有什么能胜过 Keras。

下面是一个简单 LSTM 的代码,并附有解释:

我们正在使用 Keras Sequential API,这意味着我们一次构建一层网络。这些层如下所示:

  • 一个将每个输入单词映射到 100 维向量的Embedding。嵌入可以使用我们在weights参数中提供的预训练权重(一秒钟内更多)。如果我们不想更新嵌入,可以设置False
  • 一个Masking层,用于屏蔽任何没有预训练嵌入的单词,这些单词将被表示为全零。训练嵌入时不应使用该层。
  • 网络的核心:一层LSTM 单元,带有脱落以防止过拟合。由于我们只使用一个 LSTM 层,它不会返回序列,对于使用两个或更多层,请确保返回序列。
  • 激活relu的全连接Dense层。这为网络增加了额外的表示能力。
  • 一个Dropout层,用于防止过度拟合训练数据。
  • 一个Dense全连接输出层。这为使用softmax激活的 vocab 中的每个单词产生一个概率。

该模型使用Adam优化器(随机梯度下降的变体)进行编译,并使用categorical_crossentropy损失进行训练。在训练期间,网络将试图通过调整可训练参数(权重)来最小化日志损失。与往常一样,使用反向传播计算参数的梯度,并用优化器更新。因为我们正在使用 Keras,所以我们不用担心这是如何在幕后发生的,,只需要正确设置网络。

LSTM network layout.

在不更新嵌入的情况下,网络中需要训练的参数要少得多。 [LSTM](https://machinelearningmastery.com/reshape-input-data-long-short-term-memory-networks-keras/) 层的输入是 [(None, 50, 100)](https://machinelearningmastery.com/reshape-input-data-long-short-term-memory-networks-keras/) 这意味着对于每一批(第一维),每个序列有 50 个时间步长(字),每个时间步长在嵌入后有 100 个特征。LSTM 图层的输入总是具有(batch_size, timesteps, features)形状。

构建这个网络有很多方法,笔记本中还介绍了其他几种方法。例如,我们可以使用两个相互堆叠的LSTM层,一个处理来自两个方向的序列的Bidirectional LSTM层,或者更多的Dense层。我发现上面的设置运行良好。

预训练嵌入

一旦网络建立起来,我们仍然需要为它提供预先训练好的单词嵌入。你可以在网上找到许多在不同语料库(大量文本)上训练过的嵌入。我们将使用的是斯坦福提供的,有 100、200 或 300 种尺寸(我们将坚持 100)。这些嵌入来自 GloVe(单词表示的全局向量)算法,并在维基百科上进行训练。

即使预训练的嵌入包含 400,000 个单词,我们的 vocab 中也包含一些单词。当我们用嵌入来表示这些单词时,它们将具有全零的 100 维向量。这个问题可以通过训练我们自己的嵌入或者通过将Embedding层的trainable参数设置为True(并移除Masking层)来解决。

我们可以从磁盘中快速加载预训练的嵌入,并使用以下代码创建一个嵌入矩阵:

这是给 vocab 中的每个单词分配一个 100 维的向量。如果单词没有预先训练的嵌入,那么这个向量将全为零。

为了探索嵌入,我们可以使用余弦相似度来在嵌入空间中找到与给定查询词最接近的词:

嵌入是被学习的,这意味着表征专门应用于一个任务。当使用预先训练的嵌入时,我们希望嵌入所学习的任务足够接近我们的任务,所以嵌入是有意义的。如果这些嵌入是在 tweets 上训练的,我们可能不会期望它们工作得很好,但是因为它们是在 Wikipedia 数据上训练的,它们应该普遍适用于一系列语言处理任务。

如果您有大量的数据和计算机时间,通常最好学习自己的特定任务的嵌入。在笔记本中,我采用了两种方法,学习到的嵌入表现稍好。

训练模型

随着训练和验证数据的准备、网络的构建和嵌入的加载,我们几乎已经为模型学习如何编写专利摘要做好了准备。然而,在训练神经网络时,最好使用模型检查点和 Keras 回调形式的早期停止:

  • 模型检查点:在磁盘上保存最佳模型(通过验证损失来衡量),以便使用最佳模型
  • 提前停止:当验证损失不再减少时,停止训练

使用提前停止意味着我们不会过度适应训练数据,也不会浪费时间训练那些不会提高性能的额外时期。模型检查点意味着我们可以访问最好的模型,如果我们的训练被中断 1000 个纪元,我们也不会失去所有的进展!

然后,可以使用以下代码训练该模型:

在一个 Amazon p2.xlarge 实例(0.90 美元/小时的预订)上,完成这个任务需要 1 个多小时。一旦训练完成,我们可以加载回最佳保存的模型,并评估验证数据的最终时间。

*from keras import load_model# Load in model and evaluate on validation data
model = load_model('../models/model.h5')
model.evaluate(X_valid, y_valid)*

总体而言,使用预训练单词嵌入的模型实现了 23.9%的验证准确率。考虑到作为一个人,我发现很难预测这些摘要中的下一个词,这很好!对最常见的单词(“the”)的简单猜测产生了大约 8%的准确度。笔记本中所有型号的指标如下所示:

最佳模型使用预先训练的嵌入和如上所示的相同架构。我鼓励任何人尝试用不同的模式训练!

专利摘要生成

当然,虽然高指标很好,但重要的是网络是否能产生合理的专利摘要。使用最佳模型,我们可以探索模型生成能力。如果你想在你自己的硬件上运行这个,你可以在这里找到笔记本,在 GitHub 上找到预训练模型

为了产生输出,我们用从专利摘要中选择的随机序列作为网络的种子,让它预测下一个单词,将预测添加到序列中,并继续预测我们想要的任意多个单词。一些结果如下所示:

输出的一个重要参数是预测差异。我们不是使用概率最高的预测单词,而是将多样性注入到预测中,然后选择概率与更多样的预测成比例的下一个单词。多样性太高,生成的输出开始看起来是随机的,但太低,网络会进入输出的递归循环。

输出还不算太差!有时很难确定哪些是计算机生成的,哪些是机器生成的。这部分是由于专利摘要的本质,大多数时候,它们听起来不像是人类写的。

网络的另一个用途是用我们自己的启动序列来播种它。我们可以使用任何我们想要的文本,看看网络会把它带到哪里:

同样,结果并不完全可信,但它们确实很像英语。

人还是机器?

作为递归神经网络的最终测试,我创建了一个游戏来猜测是模型还是人产生了输出。这是第一个例子,其中两个选项来自计算机,一个来自人类:

你的猜测是什么?答案是第是一个人写的实际摘要(嗯,它是摘要中的实际内容。我不确定这些摘要是人写的)。这里还有一个:

这一次第三部有了一个有血有肉的作家。

我们可以使用额外的步骤来解释该模型,例如发现哪些神经元随着不同的输入序列而变亮。我们还可以查看学习到的嵌入(或者用投影工具可视化它们)。我们将在另一个时间讨论这些话题,并得出结论,我们现在知道如何实现一个递归神经网络来有效地模仿人类文本。

结论

认识到递归神经网络没有语言理解的概念是很重要的。它实际上是一台非常复杂的模式识别机器。然而,与马尔可夫链或频率分析等方法不同,rnn 基于序列中元素的排序进行预测。从哲学角度来看,你可能会认为人类只是极端的模式识别机器,因此递归神经网络只是像人类机器一样工作。**

递归神经网络的用途远远不止文本生成,还包括机器翻译图像字幕作者身份识别。虽然我们在这里讨论的这个应用程序不会取代任何人类,但可以想象,随着更多的训练数据和更大的模型,神经网络将能够合成新的、合理的专利摘要。

A Bi-Directional LSTM Cell (Source)

人们很容易陷入复杂技术背后的细节或理论,但学习数据科学工具的更有效方法是深入研究并构建应用。一旦你知道了一项技术的能力以及它在实践中是如何工作的,你就可以随时回头去了解这个理论。我们大多数人不会设计神经网络,但学习如何有效地使用它们是值得的。这意味着收起书本,打破键盘,编写你自己的网络。

一如既往,我欢迎反馈和建设性的批评。可以通过推特 @koehrsen_will 或者通过我的网站 willk.online 找到我。

用于语言理解的递归神经网络

原文:https://towardsdatascience.com/recurrent-neural-networks-for-language-understanding-10c649f8ac15?source=collection_archive---------12-----------------------

递归神经网络(RNNs)已经被认为在机器翻译、情感分析、语音识别和许多其他机器学习任务中实现了最先进的性能。它们的优势在于处理顺序数据和各种长度的输入输出的能力。

这些神奇的网络并不新鲜。事实上,它们是在 20 世纪 80 年代开发的——但是比非递归神经网络的计算成本更高,直到(相对)最近计算资源的改进,RNNs 才开始流行。

本文将在 NLP 的背景下介绍递归神经网络。

从序列数据中学习

前馈神经网络假设所有输入都是相互独立的。虽然对于许多分类任务来说,这是一个合理的假设,但它无法捕捉到在顺序数据中发现的关系。

在顺序数据中,顺序很重要。以文字为例。我们通过每一个单词来发展对文本的理解。我们必须按顺序处理课文,并结合之前所学的知识处理每个单词,以形成正确的理解。

递归神经网络通过使用先前学习的信息来预测下一个输出,从而缓解了这个问题。在语言环境中,RNNs 将从前面的单词中学到的信息存储在“记忆”中,并使用这些知识来更好地理解下一个单词。

Language is a puzzle! Words needs to be pieced together for us to see the big picture.

内存的使用也允许 rnn 处理不同长度的序列。这在诸如机器翻译等我们不知道输入和输出有多长的任务中特别有用。

以下是 RNNs 可以使用的几种输入/输出配置:

  • 一对一网络:香草神经网络接受一个向量作为输入,返回一个向量作为输出。rnn 也可以这样配置。
  • 多对一网络:RNN 也可以接受几个向量作为输入来模拟顺序关系,但返回一个向量作为输出。
  • 多对多网络:一个 RNN 也可以接受多个向量作为输入,返回多个向量作为输出。

不同输入/输出配置的示例

一对一:我们对基于毒性的聊天室消息分类感兴趣。我们决定最好的嵌入技术将基于频率,并选择使用 TF-IDF 将每个消息嵌入到一个向量中。输出也是一个向量,每个坐标对应于每个类。

多对一:我们认为基于频率嵌入聊天室消息是个坏主意,而且单词的顺序很重要。因此,我们通过使用预先训练的 word2vec 模型,将消息中的每个单词嵌入到它自己的向量中。模型输出不会改变。

多对多:我们已经超越了简单的文本分类器,开始训练一个 RNN 来翻译英语和法语之间的信息。在这种情况下,单词的顺序当然很重要。我们将英语输入编码成几个向量(每个词一个向量),并使用输出向量来确定法语翻译的顺序。

训练递归神经网络

从传统的神经网络训练 RNN 的区别在于更新权重的方式。在 RNN 中更新权重最常用的方法是通过时间反向传播(BPTT)。

回想一下用于训练普通神经网络的梯度下降算法:

  1. 初始化重量
  2. 使用权重从输入生成输出(输出计算为输入的加权和)
  3. 使用激活功能转换输出
  4. 计算输出误差(转换输出和目标之间的差值)
  5. 反向传播误差使用偏导数寻找梯度
  6. 通过梯度下降更新权重
  7. 重复步骤 2-6,直到满足某个停止标准

当执行 BPTT 时,我们需要将我们的网络“展开”成按时间步长分解的层。

注:我们经常把顺序数据分解成“时间步长”。第一个数据点将是时间 1 的输入,依此类推。

Wikipedia illustration of BPTT

在展开我们的循环层之后,我们剩下看起来像几个非循环层的东西。与上述算法的唯一不同之处在于:

  1. 渐变是通过跨所有展开的层而不是一个层反向传播而生成的。总损失计算为所有时间步长的平均损失。
  2. 权重由所有展开的层共享。它们在最后使用累积的梯度进行更新。

使用递归神经网络

如果我们正在处理文本数据,其中每个单词都映射到它自己的向量,那么每个单词都将是一个单独的数据点。

使用关于网络权重 w 的函数来计算隐藏状态。该函数的参数是先前的隐藏状态和当前时间步长的输入向量。 TanhReLU 是一些常用的计算隐藏状态的函数。

我们通过使用权重来计算输出,以获得最后隐藏状态的加权和。这些输出可以用来进行预测或生成新的序列。

对消失/爆炸梯度的关注

类似于非常深的前馈神经网络,rnn 容易受到通过反向传播的消失/爆炸梯度的影响(回想一下,一个递归层被展开成许多非递归层)。

幸运的是,有几种方法可以解决这些问题。

消失渐变:

  • 使用门控机制,以便不是所有的隐藏状态都被存储。这是通过替代 RNN 单位完成的,如 LSTMGRU
  • 使用 ReLU 作为激活功能

爆炸渐变:

  • 渐变裁剪:设置渐变值的最大阈值;剪裁阈值以上所有渐变

结论

尽管有额外的训练复杂性,RNNs 在机器学习中已经变得非常流行。在 NLP 之外,递归神经网络也被用于视频分类、语音识别和时间序列数据中的异常检测。

感谢您的阅读!

如果你喜欢这篇文章,可以看看我关于数据科学、数学和编程的其他文章。通过 Medium 关注我的最新更新。😃

作为一个业余爱好项目,我还在www.dscrashcourse.com建立了一套全面的免费数据科学课程和练习题。

如果你想支持我的写作,下次你报名参加 Coursera 课程时,可以考虑使用我的会员链接。完全公开—我从每一次注册中获得佣金,但不会对您产生额外费用。

再次感谢您的阅读!📕

用 Ramda 进行递归滚动计算

原文:https://towardsdatascience.com/recursive-rolling-calculations-with-ramda-adf494958a37?source=collection_archive---------23-----------------------

在函数式编程范式中使用递归来创建移动平均值很有趣

Image by stokpic via Pixabay.com (https://pixabay.com/users/stokpic-692575/)

对于对随时间波动的数据集感兴趣的人来说,滚动平均或移动平均是最受欢迎的趋势指标之一。对于交易者来说尤其如此,他们总是在金融市场的不断变化中努力解读趋势信号。

本文面向具有数据科学背景,并且有兴趣学习更多关于函数式编程方法的人。递归是一个需要花费一些时间和思想来理解的概念,所以我想展示一个在现实世界中使用递归的实用方法。

我的主要目标是使用递归的函数方法而不是“for 循环”来计算移动平均线(特别是指数移动平均线)。我将非常依赖 Ramda.js,这是一个非常有用的函数式 Javascript 库。

递归

我假设这篇文章的读者熟悉移动平均线,所以让我们直接跳到递归。这个帖子的灵感直接来源于这篇文章这篇文章。在 Google 中输入“递归”会得到如下定义:

递归过程或定义的重复应用

这是一个递归定义——酷!

递归函数是根据自身定义的函数。考虑递归函数的另一种方式是,它调用自己——直到它不调用为止。运行const squareMe = n => squareMe(n*n)会一遍又一遍的运行,迅速吹爆你的调用栈。

这就是为什么我们需要一个“基本情况”,这是一个定义函数何时终止的条件。

此外,递归函数实际上需要调用自身,这被称为“递归”

最后,为了做任何有用的事情,递归函数需要有一个“动作”

为了演示递归函数的这三个组成部分,让我们编写一个从 1 数到给定数字的函数:

// ES6
const countTo = (num, arr=[], startingN=1) => {
  // Base case:
  if (arr.length === num) return arr;
  // Recursion and action:
  return countTo(num, arr.concat(startingN), startingN + 1); 
};

调用countTo(10)返回[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],通过调用动作(arr.concatstartingN+1)递归调用自身,直到遇到基本情况arr.length === num时终止。

耶!没有循环了!

递归是 for 循环的一种替代方法,也是一种更实用的遍历数据集以获得所需结果的方法。

拉姆达

Ramda.js 是一个轻量级的、功能性的 Javascript 库,它是为那些希望保持代码纯净和功能性、函数不可变和没有副作用的人而设计的。哦,还有数据排在最后——这样更好。

简单移动平均线

让我们从一系列数字的简单移动平均开始:

//ES6
import R from 'ramda';const sma = (num, data, arr = []) => {
  if (data.length === 0) return arr;
  if (data.length < num) return sma(
    num,
    data.slice(1), 
    R.prepend('not yet!', arr),
  );
  const newData = R.tail(data);
  const movingMean = R.mean(
    R.slice(0, num, data)
  );
  return sma(
    num,
    newData,
    R.append(movingMean, arr)
  );
};

这个功能有三个部分。

一旦data参数的长度达到 0,第一个if语句就返回arr。这是“基本情况”。

data参数的长度小于num参数的长度时,第二个if语句递归调用sma,使用 Ramda 的prepend添加‘还没有!’串到arr前面。

最后的return语句是这个函数的核心。它将 Ramda 的mean函数应用于newData的适当元素,每次返回一个新的arr并附加平均值。

这里要强调的最后一点是,每次函数调用自己时,它是如何在newData上这样做的,它只是返回data而没有第一个元素(R.tail)。让我们在每个return语句之前添加一个console.log语句,这样我们就可以确切地看到sma内部发生了什么:

这显示了调用sma时的确切情况。在该函数第一次运行后,它返回一个带有首字母data的前三个数字的平均值的arr的副本。该函数第二次运行时,将返回第一个元素被切掉的arr副本的前三个数字的平均值。

你明白了!

注意,在递归过程的最后,'not yet'字符串必须加在arr的前面。此外,由于这些是占位符,我们没有得到实际值,这就引出了本文的下一步:指数移动平均线。

指数移动平均线

到目前为止,我们已经介绍了递归的基本知识,并在 Ramda 的帮助下,将它们应用于创建一个简单的列表移动平均值。

让我们以不同的方式处理这个概念,将它应用到现实世界的情况中。我们将使用 IEX API 从股票交易所获取一些纵向数据:

这个函数从 IEX 交易 API 获取 AAPL 数据,并返回一个带有datevalue的对象列表。该数据集的图表如下所示:

Image by author

现在,我们需要编写一个函数,给出这个数据集的指数加权移动平均,为此,我们将使用吴恩达在这里提出的指数加权移动平均。把它写成一个 javascript 函数看起来是这样的【第 8 行】:

哇哦。让我们把这个拆开。

首先,ewa有两个参数- decay是您想要权衡的天数,而data是您想要操作的对象列表。接下来,ewa定义了beta,它是使用一点指数代数从decay计算出来的,本质上控制算法的平滑。

函数checkArr是算法的神奇之处。在ewa的第一次迭代中,arr为空,因此checkArr只是将新arr的第一个元素的value设置为data[第 7 行]中的第一个value。没有之前的数据点来指数加权!在其余的ewa递归调用中,checkArr返回算法中由beta控制的加权值,因为arr不再为空。

现在,我们可以在图表中添加一个ewa(20, getData()):

Image by author

更多拉姆达!

在函数式编程中,“curried”函数是这样一种函数,如果提供的参数少于它所需要的参数,它将返回一个采用剩余参数的新函数。当您需要编写新函数时,这种技术非常有用。让我们使用拉姆达的curry函数来创建一堆不同的ewa函数:

const curriedEwa = R.curry(ewa);const ewaTwenty = curriedEwa(20);const ewaFifty = curriedEwa(50);const ewaHundred = curriedEwa(100);

现在,将ewaTwentyewaFiftyewaHundred制成图表给我们看:

Image by author

函数式编程 FTW!

这里有很多内容,我希望我已经帮助展示了递归和 Ramda 是多么有用。如果你还不熟悉这些概念,你可能需要一段时间来理解它们(至少对我来说是这样)。然而,我已经建立了一个可观察笔记本,在那里你可以深入探究这篇文章中的代码。

数据科学面试中的危险信号

原文:https://towardsdatascience.com/red-flags-in-data-science-interviews-4f492bbed4c4?source=collection_archive---------1-----------------------

这篇文章是与 Warby Parker 的数据科学家 艾米丽·罗宾逊 共同撰写的。我和她还写了一本相关的书: 打造你的数据科学生涯

在面试任何职位时,你应该像他们评价你一样评价这家公司。虽然你可以在 glassdoor 和类似的网站上预先研究这家公司,但面试是更深入了解这家公司并提出重要问题的最佳途径。公司永远不会直接告诉你他们不适合工作,所以你必须自己寻找迹象。

以下是我们列出的 12 个迹象,你面试的公司应该避免这些迹象(以及面试时应该问的问题)。前六个主要适用于已经拥有多名数据科学家或分析师的公司。如果你正考虑加入一家公司,成为他们的第一位数据科学家,你将面临一系列完全不同的挑战,包括很可能要做大量的数据工程工作(见标志 1)和传播数据科学思维。必须有人去做,但我们通常不建议你在第一份数据科学工作中这样做,除非你有工程背景,并且想做这项工作。如果只有一个数据科学领导者,并且他们正在建立一个团队,询问他们计划如何处理下面提出的问题,但请记住,承诺一个理想的系统总是比实现一个更容易。

数据科学团队如何运行的危险信号

1.没有数据工程或基础设施。

数据科学要求数据易于分析。如果公司没有一个维护良好的数据基础设施,您就没有工作所需的东西。数据工程师是为分析准备数据的人,如果你的公司没有数据,你就必须自己做这项工作。如果你觉得自己有资格担当数据工程师的角色,这可能没问题,但否则你将很难交付任何有价值的东西。

面试时要问的问题:您的数据基础架构是什么样的,由谁维护?数据通常采用什么格式(Excel、SQL 数据库、csv)?

2.数据科学家之间没有同行评审。

一个强大的数据科学团队将有办法确保错误不会从缝隙中溜走。这些可以包括代码审查、实践演示,以及与团队的一致检入。如果团队没有始终如一地做这些,直到工作已经交付,错误才会被发现,这通常以某人受到斥责而告终。

要问的问题:团队采取什么步骤进行 QA 和同行评审?

3.团队中没有标准的语言。

许多数据科学团队采取的方法是让团队中的任何人使用他们想要的任何语言。这个想法是,如果每个人都使用他们最喜欢的语言,工作将会完成得更快。这有一个巨大的问题:当每个人都使用不同的语言时,没有人能够把工作交给其他人。每项数据科学任务都将有一个人负责,如果他们辞职、生病或只是需要帮助,没有人能够做到这一点,这将创造一个非常紧张的环境。使用 R,Python,甚至我们敢说 SAS 都没问题,但是团队中要有一套一致的语言。

要问的问题:你的团队使用什么语言,你如何决定是否采用一种新的语言?

4.他们不了解需求的数据层次。

类似于没有数据基础设施,一些公司在没有基础的情况下对人工智能等概念感到非常兴奋。机器学习和人工智能要求一家公司具有高水平的数据科学成熟度,包括理解如何建立模型、模型的局限性以及如何部署模型。当他们不切实际的期望变成现实时,你可能会受到责备。

要问的问题:公司如何平衡花费在人工智能等复杂方法上的时间与清理数据、检查数据质量和添加日志记录等基础工作?

5.没有版本控制。

成熟的数据科学团队使用 git 来跟踪分析和代码的变化。其他团队则使用共享网络文件夹之类的方法,这种方法不会让您看到什么时候发生了变化,为什么会发生变化,或者以前的版本。有时候,团队根本不共享代码,只是在数据科学家的个人笔记本电脑上工作。像躲避瘟疫一样避开最后这些群体。没有共享代码的方法意味着团队不能一起工作。

要问的问题:如何在团队中共享代码?所有代码都是共享的还是只有一部分?

6.运行报告的人和进行分析的人之间没有明确的界限。

创建和维护报告、构建数据科学模型以及将机器学习模型投入生产所需的技能都是不同的。如果公司没有一个明确的方法来确定谁做什么工作,你可能开始你的工作,并最终做完全不同于你预期的工作。你不会希望在第一天上班时,期望建立一个时间序列预测,然后发现你的工作是刷新每月的销售 Excel 电子表格。

提问:报告、分析和生产模型构建任务是如何划分的?

他们如何重视人的危险信号

1.完全没有结构的面试过程。

结构化面试流程意味着每个候选人都会得到一套相同的问题,可以更加平等地进行比较。这不仅能减少偏见(https://HBR . org/2016/04/how-to-take-the-bias-out-of-interview),还要求团队仔细考虑他们带来的人身上什么是重要的。如果面试过程是无组织的,面试官似乎会不假思索地问一些问题,那么这是一个强烈的信号,表明他们还没有弄清楚自己想要一个什么样的候选人,以及如何得到它。如果他们不知道自己想要什么,你就很难在工作中给他们想要的。

建议:看看他们是否带了一系列问题去面试,或者问他们如何选择问你什么的元问题。

2.没时间回答你的问题。

因为面试也是为了让你了解公司,你需要有时间这样做。如果你没有时间问问题,面试官不会让你感到舒服,也不会让你评估自己的适合度。

建议:如果你参加了面试,但没有时间提问,记下来,然后问面试官什么时候提问比较合适。

3.面试不需要编码。

虽然编程不是数据科学家最重要的技能,但它是你在工作中必须要做的事情。面试中的编码部分可以是现场测试,也可以是带回家的测试,但它肯定是存在的。如果面试过程不包括编程,可能有以下几个原因:(1)数据科学团队是新的,所以没有人能主持面试。在这种情况下,要知道你在工作中不会得到支持。(2)团队没有时间去创造一个编程面试。这是他们不重视招聘的一个迹象。(3)他们不会编程,不会在工作中使用 Tableau、Excel 等 BI 工具。(4)他们非常信任你的简历,所以他们不需要测试你,而这只是他们迫切想雇用你的一个迹象。

建议:如果面试不包括编程部分,问他们如何判断哪些候选人具备这份工作的技能。

4.头几个月没有计划。

公司发布招聘信息是有充分理由的。如果他们不能清楚地说出你在头几个月要做什么,原因可能是“我们完全被工作压得喘不过气来,我们会把人扔向这个问题,直到我们能处理它。”这是一种极其危险的团队成长方式。更糟糕的是,这通常发生在没有新员工入职流程的公司。所以这些情况对整个团队来说都是极度紧张的,这通常也会落在你身上。

建议:询问他们是否为你的起步制定了明确的项目和入职流程。如果他们对此没有极其精确的答案,那就跑。

5.不支持继续教育。

数据科学是一个巨大且快速发展的领域,如果你不坚持学习,你就会落后。团队应该有一些方法来帮助人们跟上,无论是为在线教育提供资金还是参加会议,每月一次的会议,在会上你可以讨论行业博客文章,鼓励参加会议或参与开源,或者一系列的演讲。这也表明他们愿意投资于他们的员工。

建议:询问他们如何支持团队的继续教育。是否有会议或研讨会的资金?

6.面试官对该职位的回答不一致

通常面试会让你和公司里的很多人交谈,包括你未来的经理、队友和商业利益相关者。如果他们每个人都告诉你不同的事情,比如责任级别、工作类型、角色提供的服务以及你必须工作的时间,他们自己可能不会同意。如果他们不能达成一致,尤其是在与你最终要做的工作相关的事情上,你的工作将会充满冲突。

建议:记录人们在不同的面试中所说的话。如果你发现不一致,问为什么。

虽然这 12 面旗帜看起来很多,但公司倾向于不展示其中任何一面或大部分,只展示中间的几面。通过留意他们,你可以避免得到你不喜欢的工作的问题。祝你好运!

如果你想要大量的方法来帮助你在数据科学领域发展职业生涯,可以看看 Emily Robinson 和我写的书: 在数据科学领域建立职业生涯 。我们将带您了解成为数据科学家所需的技能,找到您的第一份工作,然后晋升到高级职位。

DataVis 战斗入门:了解我的神奇宝贝

原文:https://towardsdatascience.com/reddit-datavis-entry-getting-to-know-my-pokémon-e0bcf4b4b803?source=collection_archive---------10-----------------------

Stacked percentage bar chart sorted by total damage against Grass-type Pokémon (Plotly).

这是我第二次参加 Reddit 上的 DataVis 挑战赛。数据来源: Kaggle Bulbepedia为图片。所有的图形都是用 Python 做的,用的是 Plotly 和 Matplotlib。此外,作为免责声明,我绝不是神奇宝贝专家,所以如果一些数据没有准确解读,提前道歉。我理解他们的特点和历史有许多细微差别,所以我愿意让顽固分子在必要的地方补充他们的意见。

这些数据图片和平而来

探索数据集

按类型分类的神奇宝贝

我想看的第一个变量是神奇宝贝类型的总数。许多神奇宝贝都是混合的,所以有第一类和第二类:

Stacked bar chart of Pokémon Type 1 and Type 2 (Plotly).

正如你所看到的,水型神奇宝贝是最常见的,其次是普通的和草。飞行型神奇宝贝是最常见的 2 型,其次是毒型、地型和仙型。

身体质量指数的神奇宝贝

一旦 Medium 决定允许 HTML 嵌入,我的帖子将停止展示这些 gif。

Scatter plot by Weight, Height and Traces by Type 1 (Plotly).

虽然这种视觉效果在互动时相对信息量大,但显示神奇宝贝精灵或图像的静态图像也能让这些生物活起来。

经过多次努力将这些图像作为 Matplotlib 的标记导入,我终于设法让这个图表工作起来:)

Scatter plot by Pokémon weight and height, with markers as sprite images (Matplotlib). You can find the code here.

科斯莫姆——右下角的神奇宝贝——和它正上方的 Celesteela 重量相当。然而,科斯莫姆的身体质量指数矮化了其余的神奇宝贝,我们可以在下面看到:

另一方面,在排名最低的身体质量指数,鬼斯通、鬼斯和卡尔塔纳名列榜首。

受到伤害的神奇宝贝

Scatter plot by Pokémon SP attack and SP defense, with markers as sprite images (Matplotlib).

数据集中变量最多的特征类别是攻击。更确切地说,是每个神奇宝贝对另一个特定类型的神奇宝贝的攻击伤害。例如,水型神奇宝贝对火型、地型、岩石型的神奇宝贝伤害更大,但是对电型和草型的神奇宝贝⚡非常脆弱🔥💧🌿

舒克尔的攻击构成绝对值看起来是这样的,每种颜色代表对给定类型的伤害:

Sum of all damage against type equals 200

而赫拉克罗斯的是这样的:

Sum off all damage against type equals 3977.5

这些横条是用 计算攻击伤害伤害类型* 然后叠加而成。我用的是绝对数字,因为它增加了一个有趣的视角,关于彼此相关的伤害输出。然而,这不是他们攻击伤害的总和,而是每种攻击伤害的总和。我希望这有意义。

Pokémon damage to type stacked in absolute numbers where values = attack damage * damage to type (Plotly).

鉴于以上伤害是由绝对数字组成的,查看百分比也很有趣。

Pokémon damage to type stacked in percentages where values = (attack damage * damage to type) / sum of damages * 100 (Plotly).

我们看到上图中有几块颜色相同的“积木”,最明显的是 Braviary 和 Hoothoot 之间。挑出这一组,我们看到他们的装备完全一样。

Stacked percentage graph with equal Damage to Type values.

就这样!感谢你阅读这篇文章。如果你喜欢它,给我一两下掌声,并分享一些你的想法或评论。干杯!

Shuckle… I couldn’t resist.

Reddit 的 DataViz 战役:美国宇航局宇航员埃达

原文:https://towardsdatascience.com/reddits-dataviz-battle-nasa-astronaut-eda-6f34a59962e?source=collection_archive---------20-----------------------

这是我第一次参加 Reddit 的 r/dataisbeautiful 。所有的可视化都是在 Tableau Public 中完成的。

我们大多数人都梦想有一天成为宇航员。尤里·加加林(宇航员)第一个登上太空的人,以及无数其他宇航员都曾登上太空。我们已经到达了月球,也许火星很快也会到达。在这篇文章中,我在 Reddit 的 DataViz Battle 中可视化了来自 NASA 宇航员数据库的 NASA 宇航员数据。

处理缺失数据

在上面的数据集中,工作栏的很多值都丢失了,所以我通过查看维基百科上的宇航员个人职业或 NASA 职业部分,艰难地添加了工作描述。通过这个过程,我学到了很多关于宇航员的知识。

在浏览网页的时候,我了解了一些悲惨的事故和成为宇航员的艰难历程。向所有宇航员致敬。

按性别分类的宇航员

从柱状图中,我们可以看到男宇航员比女宇航员多。人数低于男宇航员可能有社会或政治原因,还有许多其他原因。检查这个连杆。随着时间的推移,女宇航员的数量可能会增加。

宇航员在太空的时间。

从上面的树状图中,我们可以看到迈克尔·芬克是在太空时间最多的宇航员。该数据集可能是旧的,因为目前佩吉惠特森超过迈克尔芬克和斯科特·凯利在第二位。很高兴看到 4 名女性在顶端(佩吉,鲁西德,苏珊,苏尼塔),因为女宇航员较少。

宇航员太空飞行

从上面的柱状图中,我们可以看到,在太空飞行次数最多的宇航员(上图)较少。很可能,大部分花费时间最长的宇航员很少飞行,花更多的时间在太空上。

宇航员分组

我们可以看到第 16 组和第 8 组有最多的宇航员。第 16 组是从 1996 年开始的选拔组,在那一年,国际空间站需要机组人员和常规航天飞机。第 8 组是 1978 年开始的选拔组,经过 9 年的选拔。经过这么长时间的选拔,更多的宇航员被选拔出来,形成了两个宇航员小组:飞行员和任务专家。

宇航员出生日期

这种拥挤的气泡可视化没有多大意义,因为出生年份对宇航员有影响,但我们可以推断大多数宇航员出生于 1930 年,1940 年,1950 年,1960 年。可能是因为苏联和美国之间的太空竞赛。

当年选出的宇航员人数

我们可以从 1975 年上方的线形图中看到,宇航员人数突然增加,与 1996 年相似。它的情况类似于上面讨论的宇航员分组。

由军事/民用专业挑选的宇航员

从上面的柱状图中,我们可以看到军用宇航员比民用宇航员多。以前,也许是因为项目都被列为情报目的,或者是因为训练压力很大,更多的军事人员被招募为宇航员。甚至平民宇航员也在增加,因为成为一名宇航员需要一定的专业知识和训练。

宇航员的军事细节

从上面,我们了解到,在军事职位中,大多数是在美国空军和美国海军担任上尉、指挥官、上校。由于岗位上有经验丰富的个人,他们占据了大部分宇航员的份额。

宇航员身份

从上面的柱状图中,我们可以推断出他们大多数是前宇航员。当前描绘当前工作的宇航员。死者包括那些死于悲惨事故或自然死亡的宇航员。

宇航员的工作

从上面的柱状图中,我们可以看到大多数宇航员的工作都是专业化的。任务专家宇航员是指拥有博士、工程师、内科医生、地质学学位以及更多其他学位的人,这些对于任何太空计划的实施都是必不可少的。试飞员和飞行员都曾在美国空军服役。点击此链接了解更多关于宇航员的职责。

团体航班

从上面的柱状图中,我们可以看到第 8 组有更多的飞行,因为他们有更多的宇航员成员,所以进行了更多的飞行。这是 9 年以来的选择小组,新的 35 名成员被选中,第一次形成了两个不同的飞行员小组-任务专家,飞行员。第 20 组的飞行次数等于 0,可能是因为太空计划没有启动。

每年累计小时数和航班数

从上面的双轴图中,我们可以看到,20 世纪 70 年代后期,宇航员的数量和飞行次数更多,即第 8 组,但矛盾的是,累计飞行时间更少。类似地,在 1996 年期间,即第 16 组有 64 次飞行,但累积飞行小时相对较多,因为迈克尔·芬克和斯科特·凯利在该组中,他们在累积飞行小时图表中处于顶端。最终,第 20 组的航班数为 0,因为该数据仅截止到 2010 年,没有更新到 2018 年。

按工作列出的累计小时数和航班数

从上面,我们可以推断任务专家对任何太空计划都是至关重要的,因为他们在太空中有最多的飞行和累计飞行小时。试飞员和飞行员是指导太空计划的重要组成部分,在太空中有很高的飞行高度和小时时间。

Tableau 可视化和故事: Reddit NASA 宇航员

结论

因此我们得出结论,任务专家和飞行员在任何项目中都是重要的个体。任务专家长时间在太空旅行。试飞员和飞行员的宇航员有军事经历,任务专家有专业学位。大多数宇航员是男性,但人数逐年变化。

用无监督学习重新定义篮球位置

原文:https://towardsdatascience.com/redefining-basketball-positions-with-unsupervised-learning-34988d03057?source=collection_archive---------0-----------------------

NBA 总决赛结束了。最后一瓶香槟已经被倒空,五彩纸屑开始沉降。既然金州勇士队已经完成了在篮球界释放他们超凡脱俗的统治地位,我认为这将是结束一个以硬木为重点的机器学习项目的好时机。

勇士队是篮球运动中一种新趋势的主要展示者,这种趋势主张传球第一,芭蕾舞般美丽的运动,而不是通过个人的伟大来统治。因此,传统的位置,如“控球后卫”和“中锋”,似乎真的不再适用于他们的球员了。当德雷蒙德·格林带领球队助攻并成为进攻的焦点时,斯蒂芬·库里真的是控球后卫吗?在今年总决赛的失败端,当勒布朗·詹姆斯几乎每一次控球都把球带到地板上时,你真的能把凯里·欧文称为骑士的控卫吗?

Diagram showing location for traditional positions

使用无监督的机器学习方法,我量化了一组五个全新的位置,不是由任意的头衔定义的,而是由球员在球场上的统计贡献定义的。

数据

这个项目的数据是从 basketball-reference.com 刮来的,涉及 2016-2017 赛季常规赛。为了将玩家分组到新的位置,我分两步将数据标准化:

首先,我对数据进行了最小-最大缩放,使得每个统计值只在 0 和 1 之间变化。考虑到像得分和抢断这样的类别在很大程度上是不同的,重要的是将它们标准化,这样它们在决定位置分配时就具有同等的权重。

A diagram showing the data normalization steps for a single player, Stephen Curry

其次,我计算了每个属性占玩家总体统计贡献的百分比。对于每个属性,最终的属性数等于特定属性除以玩家所有属性的总和。这是一种表示玩家贡献的类型的方式,并对他们总体贡献的数量进行标准化。例如,如果一名球员场均 10 个篮板和 6 分,而在其他地方没有贡献,我想将他们的数据换算成与一名场均 5 个篮板和 3 分的球员相同的值。

使聚集

An animation demonstrating the process of k-means clustering

为了将球员分组到新的位置,我使用了一种叫做“K 均值聚类”的方法该技术将数据分组到 k 个簇中,其中每个条目(在本例中为玩家)根据其最近的质心点进行聚类。该过程从五个随机质心开始,然后迭代重复,根据最近的质心重新分组点,并将质心移动到平均位置,直到聚类分配没有变化。左边的例子显示了这个过程的二维视图。对于球员分组的过程,维度要高得多,每个属性类别都有一个维度。

为分组挑选统计数据

篮球参考中的 NBA 数据包括以下类别:

  • 助攻
  • 失误
  • 篮板总数
  • 进攻篮板
  • 防守篮板
  • 两分球
  • 三分球
  • 两点尝试
  • 三分球尝试
  • 等等。

A heat map showing correlations between different player stats. Dark red indicates high correlation.

这些类别中的许多都是高度相关的,在某些情况下,它们是一回事。在选择使用什么属性时,我必须考虑哪些属性是相互独立的。对于防守,进攻和总篮板这样的类别,决定是相当简单的,因为总篮板数与进攻和防守篮板数相同。但是,由于高度相关的统计数据并不统计同一件事,因此做出决定更加困难。例如,助攻和失误是高度相关的。控球多的球员往往助攻高失误多,但显然助攻和失误是完全不同的统计。我选择将相关性阈值设置为 0.80,这样,如果任何两个统计数据的相关性超过了这个阈值,我就会丢弃其中一个。在失误和助攻的情况下,我选择只用助攻。

我决定对玩家进行以下统计:

  • 助攻
  • 阻碍
  • 防守篮板
  • 进攻篮板
  • 两个指针
  • 三分球
  • 罚中次数
  • 个人犯规

结果

我们可以使用一种称为“轮廓得分”的度量来评估新位置的区分程度,该度量给出了一个介于-1 和 1 之间的值,表示聚类重叠的程度。新职位分配的侧影得分为 .857 ,表明职位之间的分化非常明显。稍后我将探索这些集群如何在玩家的基础上重叠。

看看新职位与传统职位的对比,就能了解新职位是如何定义的。下图显示了每个新位置中每个旧位置的玩家数量。

在一定程度上,新的任务遵循传统的,但也有相当多的混合。例如,一号位几乎完全是控卫,但除此之外,新的位置是两到三个传统位置的混合。举几个例子,零号位是得分后卫和小前锋的组合,三号位大多是中锋和大前锋形式的大个子。

它们是如何叠加的?

How each new position ranks in their contribution to the stats used for clustering. On the y-axis, five represents the highest rank, and one represents the lowest.

我们可以看看每个新位置在用于聚类的统计类别方面的排名,以了解哪些类型的球员属于每个组。我将更深入地探究这些排名,并使用它们来开发一个指代每个新职位的术语。

位置 0 :三点专家

除了三分球排名第二,这些球员对球队的贡献并不大。他们在九个类别中的六个类别中排名倒数第一,在任何一个类别中都没有排名第一。这是一个在今天的 NBA 非常受欢迎的球员,当他们有机会的时候,他会成为运球突破的受益者,并钉上空位三分。

著名球员

  • 史密斯
  • 埃里克·戈登
  • 凯尔·科沃尔
  • 特雷沃·阿里扎

职位 1:辅导员

助攻排名第一,这些球员是他们球队进攻的引擎。这些不再仅仅是传统的控球后卫,尽管这个位置主要是由这些球员组成的。考虑到他们站在后场促进进攻的程度,他们在抢断上排名第一也就不足为奇了。虽然这一类别中最著名的玩家是得分机器,但这些玩家不一定需要得分很多才能在游戏中留下印记。

知名玩家

  • 勒布朗·詹姆斯
  • 斯蒂芬·库里
  • 德雷蒙德·格林
  • 詹姆斯·哈登
  • 克里斯·保罗
  • 拉简·朗多

位置 2:指定计分员

这个位置包括 NBA 中的许多大牌明星,那些以其令人难以置信的技术获得所有人关注的得分手。他们在二分、三分和罚球中排名最高。按照传统的标准,这个位置主要是得分后卫,但这个类别的最佳射手分散在各种传统的位置上。他们也在很大程度上促进了进攻,助攻排名第二。

著名球员

  • 凯文·杜兰特
  • 拉塞尔·维斯特布鲁克
  • 伊塞亚·托马斯
  • 保罗·乔治
  • 吉米·巴特勒
  • 凯里·欧文

位置 3:固定大人物

虽然这不仅仅包括中锋,但这一类别囊括了大多数仍在 NBA 打球的老派大个子。他们三分球排名最后,但是他们碾压篮板,攻防篮板排名第一。他们确实得到了一些得分,但主要是在篮下,在两分球中排名第二。他们的个人犯规也排在第一位,你会看到篮板专家的犯规,因为他们在篮筐附近推挤时会受到犯规。

知名玩家

  • 安东尼·戴维斯
  • 鲁迪·戈贝尔
  • 迪安卓·乔丹
  • 卡尔-安东尼·唐斯
  • 哈桑·怀特塞德
  • 尼古拉·约基奇

位置 4:移动 Bigs

这个位置囊括了在 NBA 风靡一时的伸展四人/移动大个子。他们在篮板、犯规和个人犯规方面的排名仅次于传统巨头,得分更少,但通过更多的三分来平衡。他们的防守贡献比传统大个子更有限,抢断排名最后。

知名玩家

  • 凯文·乐福
  • 德克·诺维斯基
  • 凯利·奥里尼克
  • 达里奥·沙里奇

探索职位

现在,让我们深入研究这些球员级别的新任务,看看不同类别的位置表现如何。

Figure 1. Players’ points, rebounds, and assists, colored by their new position. Rollover to see a player’s name and stats.

图 1 显示了指定得分手(绿色)在得分上的优势,以及固定大个子(橙色)在篮板上的优势。辅导员(蓝色)在助攻方面表现突出,得分也高于大多数人。

Figure 2. Players’ twos, threes, and points, colored by their new position. Rollover to see a player’s name and stats.

图 2 很好地区分了固定大个子指定得分手三分专家。三分专家的三分命中率更高,而指定的得分手类别在二分和三分之间更加平衡,大个子几乎没有三分。

我们还可以从这些图表中看到位置之间相对清晰的划分,没有大量的重叠,正如基于强大的轮廓得分所预期的那样。

结论

通过根据玩家的真实贡献来检查职位,我以一种更准确地反映玩家角色的方式来定义职位。当勒布朗·詹姆斯和凯文·杜兰特在球队中扮演不同的角色时,我们不再称他们为“小前锋”。勒布朗詹姆斯是骑士队的调解人,凯文·杜兰特是勇士队的指定得分手。

利用自动编码器支持的视听克隆重新定义沉浸式游戏

原文:https://towardsdatascience.com/redefining-immersive-gaming-with-autoencoders-powered-audio-visual-cloning-7fe9765c3547?source=collection_archive---------8-----------------------

My virtual clone appearing in a post-match interview in FIFA 17.

享受电脑游戏的一个重要方面是成为游戏及其故事线的一部分的感觉。沉浸感对激发情绪非常重要,越是感受到这些情绪,玩游戏就越有乐趣。虽然目前的游戏提供了某种程度的沉浸感,具有出色的视觉和声音效果,但这仍然与你自己置身于游戏环境中不一样。这就是我相信在游戏中添加一个你自己的视听克隆作为一个可玩的角色将会把沉浸式游戏带到一个新的水平。一旦你在游戏中与你的这个克隆人建立了联系,故事作者就有可能激发你的各种情绪,从而带来更好的游戏体验。

让自己参与游戏的想法并不新鲜。许多游戏提供了广泛的角色定制,让你控制角色的外观和行为,但这项技术在使角色与你相似的程度方面非常有限。然而,通过深度学习,有可能在这种角色定制的音频和视频方面都有所改善。带着这个想法,我开始创建一个概念,看看当前的深度学习技术如何帮助我们实现这一目标。我试图在奇妙的自动编码器网络的帮助下,在 FIFA 17 的游戏中创建我的音频和视频克隆。

视觉克隆

在我之前的文章 / 视频中,我展示了视觉克隆是如何利用编码-解码网络实现的,以及它们在生成照片般逼真的人脸方面有多好。我不会再讨论这一部分,所以请随意查看前面提到的文章了解更多细节。我已经用同样的技术在后续的结果中生成了我的脸。

音频克隆

深度神经网络的序列到序列学习已被证明在文本到语音转换和机器翻译等任务中非常成功。因此,我想探索在任何书面形式的文本中使用这种技术来创造我的声音的可能性。在我寻找创造我的音频克隆的过程中,我遇到了 Lyrebird

lyrebird.ai

这是一个网络应用程序,可以从几分钟的音频中学习你的声音。我录下了我的声音,口述了大约 30 个以书面形式出现的句子,并允许模型进行训练。几分钟之内,网络就可以从我输入的任何文本中生成我的声音。结果虽然不完美,但确实让我吃惊。你可以在我下面嵌入的视频中找到它们。

音频克隆-引擎盖下

虽然我不知道 Lyrebird 的技术是如何工作的,但我怀疑它正在使用自动编码器将文本转换为语音,类似于其他克隆算法的工作方式(例如,百度的 Deep Voice 3 )。

Encoder-Decoder Network for text-to-speech conversion

网络的编码器按顺序将文本句子作为输入,并提取出现在该句子中的音素分布的编码。它充当单词的分类器,生成作为类别的音素的概率分布。这个概率分布是由解码器处理的编码,充当音频合成器。这个合成器是根据你录制的声音进行训练的,所以它能够将任何编码转换成你的声音。相当惊人!

将这项技术应用到游戏中

最终,我们想要做的是将这项技术很好地应用到游戏中。我试图在游戏《FIFA 17》中创造一个自己的视听克隆体。詹姆斯·罗德里格斯正在接受赛后采访,我用自动编码器网络创建的我的声音替换了球员的脸和声音。这提供了一个很好的概念验证,并给出了我们如何接近完善虚拟克隆的想法,以及游戏开发者如何在不久的将来实时支持这项技术。

你可以在我的 YouTube 频道上找到结果,视频嵌入在下面。

游戏中的其他用例

  1. 创建游戏中所有玩家/经理的即时克隆,而无需预先录制过场动画。目前,游戏 FIFA 18 只有精选的几个面孔和声音,因为没有从机器上生成它们的技术。这项技术将使游戏开发者很容易在游戏中拥有真实的面孔和声音。
  2. 国际足联动态评论。这意味着游戏中的评论员不再年复一年地重复句子。开发者可以简单地改变文本,生成马丁·泰勒和艾伦·史密斯的声音,为游戏的每一次迭代提供新的解说。
  3. 在像《孤岛惊魂》这样的游戏中扮演对手。我希望看到我的克隆人扮演对手。不得不做出选择是杀死我的角色还是让它活着,这给了我各种各样的想法,可能是伟大的故事线。

结论

虽然这项技术还需要几年时间才能完善或投入生产,但我相信在未来几年内我们可以让它在游戏中实时运行。深度学习在游戏行业的应用是巨大的,机器学习是这个行业的未来,是每个游戏发行商都应该大力投资的事情。

通过降维技术降低维数

原文:https://towardsdatascience.com/reducing-dimensionality-from-dimensionality-reduction-techniques-f658aec24dfe?source=collection_archive---------0-----------------------

在这篇文章中,我将尽我所能去揭开三种降维技术的神秘面纱;主成分分析,t-SNE 和自动编码器。我这样做的主要动机是,这些方法大多被视为黑盒,因此有时会被误用。理解它们将为读者提供工具来决定使用哪一个、何时使用以及如何使用。我将通过检查每种方法的内部原理,并使用 TensorFlow 从头开始编写每种方法的代码(不包括 t-SNE)。为什么是 TensorFlow?因为它主要用于深度学习,所以让我们给它一些其他的挑战:)
这篇文章的代码可以在这个笔记本中找到。

动机

在处理实际问题和实际数据时,我们经常会处理高达数百万的高维数据。
虽然数据在其原始的高维结构中表现得最好,但有时我们可能需要降低它的维数。
减少维度的需求通常与可视化相关(减少到 2-3 个维度,以便我们可以绘制出来),但情况并非总是如此。
有时我们可能更看重性能而不是精度,因此我们可以将 1,000 维数据减少到 10 维,这样我们就可以更快地处理它(例如计算距离)。有时降低维度的需求是真实的,并且有许多应用。

在我们开始之前,如果你必须为以下情况选择一种降维技术,你会选择哪一种?

  1. 您的系统使用余弦相似性来测量距离,但您需要向一些可能根本不熟悉余弦相似性的非技术委员会成员展示这一点,您会如何做?
  2. 你需要将数据压缩到尽可能小的维度,而给你的约束是保持大约。80%的数据,你会怎么做?
  3. 你有一个通过长时间收集的某种数据的数据库,并且数据(相似类型)不时地不断进来。
    您需要减少现有的数据和任何新数据,您会选择哪种方法?

我希望这篇文章能帮助你更好地理解降维,这样你会对类似的问题感到舒服。

让我们从 PCA 开始。

PCA

PCA(PprincipalCcomponentAanalysis)可能是书中最古老的技巧。
PCA 得到了很好的研究,有许多方法可以获得相同的解决方案,我们将在这里讨论其中的两种,特征分解和奇异值分解(SVD ),然后我们将在 TensorFlow 中实现 SVD 方法。

从现在开始,X 将是我们的数据矩阵,形状为(n,p ),其中 n 是例子的数量,p 是维数。
因此,给定 X,这两种方法都将试图以自己的方式找到一种方法来操纵和分解 X,以便稍后我们可以将分解的结果相乘,从而在更少的维度中表示最大的信息。我知道我知道,这听起来很可怕,但我会省去你大部分的数学,但保留有助于理解方法利弊的部分。

因此,特征分解和奇异值分解都是分解矩阵的方法,让我们看看它们如何在 PCA 中帮助我们,以及它们是如何联系的。看一下下面的流程图,我会马上解释。

Figure 1 PCA workflow

那么你为什么要关心这个呢?这两个过程中有一些非常基本的东西告诉我们很多关于 PCA 的事情。
正如您所看到的,这两种方法都是纯线性代数,这基本上告诉我们,使用 PCA 是从不同的角度查看真实数据——这是 PCA 的独特之处,因为其他方法从低维数据的随机表示开始,并试图让它像高维数据一样运行。
其他一些值得注意的事情是,所有的运算都是线性的,SVD 的运算速度非常非常快。同样给定相同的数据,PCA 将总是给出相同的答案(这对于其他两种方法是不正确的)。

注意,在 SVD 中,我们如何选择 r (r 是我们想要减少的维数)最左边的σ值来降低维数?
σ有一些特殊之处。
σ是一个对角矩阵,有 p(维数)个对角值(称为奇异值),它们的大小表示它们对保存信息的重要性。
因此,我们可以选择降低维度,使维度数量保持大约。给定数据的百分比量,我将在代码中演示(例如,给我们减少维数的能力,限制最多丢失 15%的数据)。

如你所见,在 TensorFlow 中编写代码非常简单——我们要编写的是一个具有fit方法和reduce方法的类,我们将向其提供维度。

代码(PCA)

让我们看看fit方法是怎样的,假设self.X包含数据和self.dtype=tf.float32

**def fit**(self):
    self.graph = tf.Graph()
    **with** self.graph.as_default():
        self.X = tf.placeholder(self.dtype, shape=self.data.shape)

        # Perform SVD
        singular_values, u, _ = tf.svd(self.X)

        # Create sigma matrix
        sigma = tf.diag(singular_values)

    **with** tf.Session(graph=self.graph) **as** session:
        self.u, self.singular_values, self.sigma = session.run([u, singular_values, sigma],
                                                               feed_dict={self.X: self.data})

所以fit的目标是创建我们的σ和 U 以备后用。
我们从给出奇异值的线tf.svd开始,奇异值是图 1 中表示为σ的对角线值,以及矩阵 U 和 v。
然后tf.diag是 TensorFlow 将 1D 向量转换为对角线矩阵的方法,在我们的例子中,这将产生σ。
fit调用结束时,我们将得到奇异值σ和 u。

现在让我们实现reduce

**def reduce**(self, n_dimensions=**None**, keep_info=**None**):
    **if** keep_info:
        # Normalize singular values
        normalized_singular_values = self.singular_values / sum(self.singular_values)

        # Create the aggregated ladder of kept information per dimension
        ladder = np.cumsum(normalized_singular_values)

        # Get the first index which is above the given information threshold
        index = next(idx **for** idx, value **in** enumerate(ladder) **if** value >= keep_info) + 1
        n_dimensions = index

    **with** self.graph.as_default():
        # Cut out the relevant part from sigma
        sigma = tf.slice(self.sigma, [0, 0], [self.data.shape[1], n_dimensions])

        # PCA
        pca = tf.matmul(self.u, sigma)

    **with** tf.Session(graph=self.graph) **as** session:
        **return** session.run(pca, feed_dict={self.X: self.data})

所以你可以看到reduce要么得到keep_info要么得到n_dimensions(我没有实现输入检查,其中 只有一个必须被提供 )。
如果我们提供n_dimensions,它将简单地减少到那个数字,但是如果我们提供keep_info,它应该是一个介于 0 和 1 之间的浮点数,我们将保留原始数据中的那么多信息(0.9 —保留 90%的数据)。
在第一个‘if’中,我们归一化并检查需要多少个奇异值,基本算出了keep_info中的n_dimensions

在图中,我们只需根据需要对σ(sigma)矩阵进行切片,并执行矩阵乘法。

因此,让我们在鸢尾数据集上尝试一下,这是 3 种鸢尾花的(150,4)数据集。

**from** sklearn **import** datasets
**import** matplotlib.pyplot **as** plt
**import** seaborn **as** sns

tf_pca = TF_PCA(iris_dataset.data, iris_dataset.target)
tf_pca.fit()
pca = tf_pca.reduce(keep_info=0.9)  # Results in 2 dimensions

color_mapping = {0: sns.xkcd_rgb['bright purple'], 1: sns.xkcd_rgb['lime'], 2: sns.xkcd_rgb['ochre']}
colors = list(map(**lambda** x: color_mapping[x], tf_pca.target))

plt.scatter(pca[:, 0], pca[:, 1], c=colors)

Figure 2 Iris dataset PCA 2 dimensional plot

还不错吧。

t-SNE

t-SNE 是一种相对(相对于 PCA)的新方法,起源于 2008 年(原文链接)。
它也比 PCA 更难理解,所以请多包涵。
我们对 t-SNE 的符号如下,X 将是原始数据,P 将是保存高维(原始)空间中 X 中的点之间的相似性(距离)的矩阵,而 Q 将是保存低维空间中的数据点之间的相似性的矩阵。如果我们有 n 个数据样本,那么 Q 和 P 都将是 n 乘 n 的矩阵(从任意点到包括自身在内的任意点的距离)。
现在 t-SNE 有其“特殊的方法”(我们很快就会谈到)来测量事物之间的距离,一种方法用于测量高维空间中数据点之间的距离,另一种方法用于测量低维空间中数据点之间的距离,第三种方法用于测量 P 和 q 之间的距离。
摘自原始论文,一个点 x_j 到另一个点 x_i 的相似性由“ p_j|i, 如果在以 x_ i”为中心的高斯分布下,邻居按照概率密度的比例被挑选,则 x_i 将挑选 x_j 作为其邻居。
“什么?”不要担心,正如我所说,SNE 霸王龙有它测量距离的方式,所以我们将看看测量距离的公式(亲和力),并从中挑选出我们需要的洞察力来理解 SNE 霸王龙的行为。

从高层次上讲,这就是算法的工作方式(注意,与 PCA 不同,它是一种迭代算法)。

Figure 3 t-SNE workflow

让我们一步一步地检查这个。
算法接受两个输入,一个是数据本身,另一个叫做 perf(Perp)。
简单地说,困惑就是你希望如何在优化过程中平衡数据的局部(接近点)和全局结构之间的焦点——文章建议将这个值保持在 5 到 50 之间。
更高的复杂度意味着数据点将更多的点视为其近邻,而更低的复杂度意味着更少。
困惑确实会影响你的可视化效果,要小心,因为它会在可视化的低维数据中产生误导现象——我强烈建议阅读这篇关于如何正确使用 t-SNE 的伟大文章,它涵盖了不同困惑的影响。

这种困惑从何而来?它用于计算等式(1)中的σ_i,并且由于它们具有单调的联系,它被二分搜索法发现。所以σ_i 基本上是用我们提供给算法的困惑度为我们计算出来的。

让我们看看这些方程告诉了我们关于 SNE 霸王龙的什么。
在我们探索等式(1)和(2)之前,要知道 p_ii 设置为 0,q_ii 也设置为 0(尽管如果我们将它们应用于两个相似的点,等式不会输出 0,但这只是给定的)。
现在来看等式(1)和(2 ),我希望你注意到,如果两个点靠近(在高维表示中),分子将产生大约 1 的值,而如果它们相距很远,我们将得到一个无穷小的值——这将有助于我们稍后理解成本函数。

现在我们已经可以看到一些关于 SNE 霸王龙的事情。
一个是解释 t-SNE 曲线中的距离可能会有问题,因为亲缘关系方程是这样建立的。
这意味着聚类之间的距离和聚类大小可能会产生误导,并且也会受到所选困惑的影响(同样,我会让您参考上一段中的精彩文章,以查看这些现象的可视化)。
第二件事是注意在等式(1)中我们是如何计算点与点之间的欧几里德距离的?这是非常强大的,我们可以用我们喜欢的任何距离度量来切换距离度量,余弦距离,曼哈顿距离或任何你想要的度量(只要它保持空间度量)并保持低维亲和力不变——这将导致以欧几里得方式绘制复杂的距离。
例如,如果你是一名首席技术官,你有一些数据,你用余弦相似度来衡量其距离,而你的首席执行官希望你展示某种表示数据的图表,我不确定你是否有时间向董事会解释什么是余弦相似度以及如何解释聚类,你可以简单地绘制余弦相似度聚类,就像使用 t-SNE 的欧几里德距离聚类,我认为这非常棒。
在代码中,您可以在scikit-learn中通过向TSNE方法提供一个距离矩阵来实现这一点。

好,现在我们知道,当 x_i 和 x_j 接近时,p_ij/q_ij 值较大,当它们较大时,p _ ij/q _ ij 值很小。
让我们通过绘制成本函数(称为kull back–lei bler 散度)并检查没有求和部分的等式(3)来看看它如何影响我们的成本函数。

Figure 4 t-SNE cost function without the summation part

这很难理解,但是我确实把轴的名字放在那里了。如你所见,成本函数是不对称的。
对于在高维空间(p 轴)中邻近但在低维空间中由远点表示的点,它产生了较大的成本,而对于在高维空间中由近点表示的远点,它产生了较小的成本。
这更加说明了 t-SNE 情节中距离解释能力的问题。

让我们 t-SNE 虹膜数据集,看看发生了什么不同的困惑

model = TSNE(learning_rate=100, n_components=2, random_state=0, perplexity=5)
tsne5 = model.fit_transform(iris_dataset.data)

model = TSNE(learning_rate=100, n_components=2, random_state=0, perplexity=30)
tsne30 = model.fit_transform(iris_dataset.data)

model = TSNE(learning_rate=100, n_components=2, random_state=0, perplexity=50)
tsne50 = model.fit_transform(iris_dataset.data)

plt.figure(1)
plt.subplot(311)
plt.scatter(tsne5[:, 0], tsne5[:, 1], c=colors)

plt.subplot(312)
plt.scatter(tsne30[:, 0], tsne30[:, 1], c=colors)

plt.subplot(313)
plt.scatter(tsne50[:, 0], tsne50[:, 1], c=colors)

plt.show()

Figure 5 t-SNE on iris dataset, different perplexities

正如我们从数学中所理解的,您可以看到,给定一个很好的困惑,数据确实会聚类,但请注意对超参数的敏感性(如果不为梯度下降提供学习率,我无法找到聚类)。
在我们继续之前,我想说 t-SNE 是一个非常强大的方法,如果你正确地应用它,不要把你学到的东西带到负面,只是要知道如何使用它。

接下来是自动编码器。

自动编码器

虽然 PCA 和 t-SNE 是方法,但自动编码器是一系列方法。
自动编码器是一种神经网络,该网络旨在通过使用比输入节点更少的隐藏节点(在编码器的末端)来预测输入(输出被训练为尽可能与输入相似),将尽可能多的信息编码到隐藏节点。
我们的 4 维虹膜数据集的基本自动编码器如图 6 所示,其中连接输入层和隐藏层的线称为“编码器”,隐藏层和输出层之间的线称为“解码器”。

Figure 6 Basic auto encoder for the iris dataset

那么为什么自动编码器是一个家族呢?因为我们唯一的限制是输入和输出层的维度相同,所以我们可以创建任何架构来最好地编码我们的高维数据。

自动编码器从一些随机的低维表示(z)开始,通过改变连接输入层和隐藏层以及隐藏层和输出层的权重,逐渐下降到它们的解决方案。

到目前为止,我们已经了解了一些关于自动编码器的重要知识,因为我们控制了网络的内部,我们可以设计出能够挑选出特征之间非常复杂的关系的编码器。
自动编码器的另一个优点是,由于在训练结束时我们有了导致隐藏层的权重,我们可以对某些输入进行训练,如果稍后我们遇到另一个数据点,我们可以使用这些权重减少其维数,而无需重新训练——但要小心,这只有在数据点与我们训练的数据有些相似时才有效。

在这种情况下,探索自动编码器的数学可能很简单,但不太有用,因为对于我们将选择的每个架构和成本函数,数学会有所不同。
但是,如果我们花点时间思考一下自动编码器权重的优化方式,我们就会明白我们定义的成本函数具有非常重要的作用。
由于自动编码器将使用成本函数来确定它的预测有多好,我们可以使用这种能力来强调我们想要的东西。
无论我们想要欧几里德距离还是其他度量,我们都可以通过代价函数,使用不同的距离方法,使用非对称函数等等,将它们反映在编码数据上。更强大的地方在于,由于这本质上是一个神经网络,我们甚至可以在训练时对类别和样本进行加权,以赋予数据中某些现象更多的意义。这为我们压缩数据的方式提供了极大的灵活性。

自动编码器非常强大,在某些情况下与其他方法相比已经显示出一些很好的结果(只是谷歌“PCA vs 自动编码器”),所以它们绝对是一种有效的方法。

让 TensorFlow 为虹膜数据集创建一个基本的自动编码器,并绘制它

代码(自动编码器)

同样,我们将分成fitreduce

**def fit**(self, n_dimensions):
    graph = tf.Graph()
    **with** graph.as_default():

        # Input variable
        X = tf.placeholder(self.dtype, shape=(**None**, self.features.shape[1]))

        # Network variables
        encoder_weights = tf.Variable(tf.random_normal(shape=(self.features.shape[1], n_dimensions)))
        encoder_bias = tf.Variable(tf.zeros(shape=[n_dimensions]))

        decoder_weights = tf.Variable(tf.random_normal(shape=(n_dimensions, self.features.shape[1])))
        decoder_bias = tf.Variable(tf.zeros(shape=[self.features.shape[1]]))

        # Encoder part
        encoding = tf.nn.sigmoid(tf.add(tf.matmul(X, encoder_weights), encoder_bias))

        # Decoder part
        predicted_x = tf.nn.sigmoid(tf.add(tf.matmul(encoding, decoder_weights), decoder_bias))

        # Define the cost function and optimizer to minimize squared error
        cost = tf.reduce_mean(tf.pow(tf.subtract(predicted_x, X), 2))
        optimizer = tf.train.AdamOptimizer().minimize(cost)

    **with** tf.Session(graph=graph) **as** session:
        # Initialize global variables
        session.run(tf.global_variables_initializer())

        **for** batch_x **in** batch_generator(self.features):
            self.encoder['weights'], self.encoder['bias'], _ = session.run([encoder_weights, encoder_bias, optimizer],
                                                                        feed_dict={X: batch_x})

这里没什么特别的,代码是很容易解释的,我们保存了我们的编码器权重,所以我们可以减少下面的reduce方法中的数据。

**def reduce**(self):
    **return** np.add(np.matmul(self.features, self.encoder['weights']), self.encoder['bias'])

嘣,就这么简单:)

让我们看看它是如何做到的(批量大小为 50,1000 个时期)

Figure 7 Simple Auto Encoder output on iris dataset

即使不改变架构,我们也可以继续使用批量大小、时期数量和不同的优化器,我们会得到不同的结果——这是刚刚出现的结果。
请注意,我只是为超参数选择了一些任意值,在实际场景中,我们将通过交叉验证或测试数据来衡量我们的表现,并找到最佳设置。

最后的话

像这样的帖子通常以某种比较图表、优点和缺点等结尾。但是这与我想要达到的目标恰恰相反。
我的目标是公开这些方法的私密部分,这样读者就能够找出并理解每种方法的优点和缺点。我希望你喜欢这本书,并且学到了一些新东西。

向上滚动到文章的开头,到那三个问题,现在对它们感觉更舒服了吗?

通过组合高风险股票进行投资来降低风险

原文:https://towardsdatascience.com/reducing-risk-by-building-portfolio-8772d1ce0f21?source=collection_archive---------8-----------------------

Photo by Nathan McBride on Unsplash

(这篇文章也可以在我的博客中找到)

风险回报权衡

风险和回报的权衡在资本主义是众所周知的。你可能听说过,如果你想要更高的回报,你需要冒更大的风险。这似乎是一条黄金法则。但是也有可能将两只或更多的高风险股票组合起来,建立一个投资组合,从而降低风险,但不会显著降低回报。

在金融领域,风险包括投资的实际回报与预期回报不同的可能性。因此,风险通常用历史价格的标准差来衡量。它有时被称为波动性。标准差越高意味着风险越高。

为了演示的目的,我编写了两套人工股票价格。价格也有相同的趋势。同样,一个投资组合由 50%的股票 1 和 50%的股票 2 组成(如果你还没有一个环境设置,查看这篇文章中的步骤 1)。

**import** pandas **as** pd
**import** numpy **as** np
**import** matplotlib.pyplot **as** plt

periods = 252
noise = np.random.rand(252)
rng = pd.date_range(**'1/1/2011'**, periods=periods, freq=**'D'**)
*# Artificially build two stock stock 1 and stock 2* stk1 = (np.arange(1, 1+(.001)*(periods), .001)) * 30 + noise
stk2 = (np.arange(1, 1+(.001)*(periods), .001)) * 30 - noise

*# Build a porfolio with stock 1 and stock 2 weighted 50% respectively* portfolio = .5 * stk1 + .5 * stk2
df = pd.DataFrame(index=rng, data={**'STK1'**: stk1, **'STK2'**: stk2, **'PORTFOLIO'**: portfolio})
print(df.head())

数据帧的输出

 PORTFOLIO       STK1       STK2
2011-01-01      30.00      30.661445  29.338555
2011-01-02      30.03      30.355423  29.704577
2011-01-03      30.06      30.098417  30.021583
2011-01-04      30.09      30.749702  29.430298
2011-01-05      30.12      30.156122  30.083878
...

绘制单个股票价格和投资组合价值

ax = df.plot(title=**'Stock Price'**)
ax.set_xlabel(**'date'**)
ax.set_ylabel(**'close price'**)
ax.grid()
plt.show()

正如我们在下面的图表中看到的,股票 1 和股票 2 全年都在上涨,从大约 30 涨到大约 37。价格在类似范围内偏离预期值(因为添加了噪声)。但总体趋势是上升的。这也表明股票 1 和股票 2 具有相似的风险水平。然而,投资组合的价值不断上升,没有波动。从回报的角度来看,投资组合的最终价值约为 37 英镑,产生了类似的回报。也就是说,将两只风险较高的股票组合在一起,我们可以得到一个风险较低的投资组合,并获得相同水平的回报。

为什么?

如果我们仔细看看这两只股票的波动运动,从代码或图形。当股票 1 向上偏离时,股票 2 向下偏离相同的值。这使得两只股票的风险相互抵消。因此,它会产生一条平滑(风险较小)的线。

神奇之处——数学

我们如何在数学中衡量这种波动关系?我们需要它来编写代码,找出现实世界中现有的股票。可以用股票日收益率的相关系数(不是协方差)来衡量。

投资媒体

相关系数是确定两个变量运动相关程度的一种度量。相关系数的值范围是-1.0 到 1.0。如果计算出的相关性大于 1.0 或小于-1.0,则表明出现了错误。相关性为-1.0 表示完全负相关,而相关性为 1.0 表示完全正相关。

要将其转换为代码,我们首先需要计算两只股票的日收益率。每日回报计算简单如

每日回报=价格 _t1 /价格 _t0 - 1

一旦我们有了每日收益,就可以用一行代码计算相关系数🐼

daily_return = (df / df.shift(1) - 1).dropna()
print(**"daily_return\n"**, daily_return.head())
corr = daily_return.corr()
print(**"corr: "**, corr)

为了验证,我们打印了相关系数。结果证明,股票 1 和股票 2 的日收益率为-0.999787,表明日收益率反向变动。

daily_return             
             PORTFOLIO      STK1      STK2
2011-01-02   0.001000 -0.009390  0.011869
2011-01-03   0.000999 -0.008664  0.010894
2011-01-04   0.000998  0.019264 -0.017346
2011-01-05   0.000997  0.011912 -0.010373
2011-01-06   0.000996 -0.025108  0.028800corr:      PORTFOLIO      STK1      STK2
PORTFOLIO   1.000000  0.012499 -0.000667
STK1        0.012499  1.000000 -0.999787
STK2       -0.000667 -0.999787  1.000000

我们可以利用相关系数来发现现实世界中的股票,以优化投资组合。如果你想了解更多关于机器学习的知识,educative.io 中有一系列课程很有帮助。这些课程包括像基本的 ML,NLP,图像识别等主题。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

推荐阅读:

动手机器学习

用于数据分析的 Python:与 Pandas、NumPy 和 IPython 的数据争论

对冲基金真正在做什么

我的帖子:

我关于 FAANG 访谈的帖子

我的 YouTube 频道

我关于金融和科技的帖子

从 CRUD web 应用开发到语音助手中的 SDE——我正在进行的机器学习之旅

全栈开发教程:将 AWS Lambda 无服务器服务集成到 Angular SPA 中

全栈开发教程:用运行在 AWS Lambda 上的无服务器 REST API 提供交易数据

全栈开发教程:在 Angular SPA 上可视化交易数据(1)

强化学习:Q 学习简介

反映分析的人性一面:分析的人性

原文:https://towardsdatascience.com/reflecting-the-human-side-of-analytics-humans-of-analytics-7b9369dcb100?source=collection_archive---------8-----------------------

当被问及分析时,人们开始想象戴着书呆子式大眼镜的人整天全神贯注于算法世界,编写越来越复杂的统计方程。一个由分析人员组成的名为“分析人员”的新社区正试图通过展示分析专业人员鲜为人知的一面来打破这些刻板印象,并向世界展示这些专业人员和其他任何人一样都是人。其中一位编辑谈到他们的灵感时说:“我们发现我们年轻和年老的分析人员拥有左脑和右脑的完美结合,但由于他们垃圾的职业倾向,他们隐藏的天赋经常被忽视。每个人都有一个很棒的故事要讲,我们只是把他们带到桌子上,让人们得到启发。这不仅仅是关于他们的职业成就,而是关于他们的奋斗、成功和失败”。

2016 年, HoA 背后的团队意识到,分析不仅仅是数字和数据,而是具有不同兴趣和背景的人的生动组合,共同为分析增添魔力,从而播下了人类分析的种子。行业。从《纽约人》和《孟买人》中汲取灵感,分析人捕捉了与分析打交道的人的故事。“有科学头脑的人不可能有创造力,反之亦然的神话不再存在,我们只是让它变得更响亮,让人们从这些模糊的标签中解放出来,”《人类分析》的一名编辑说。

这个社区是一个非营利组织,故事会上传到网站:www.humansofanalytics.comfacebook 。一些受欢迎的故事来自分析专家,如克雷格·布朗柯克·伯恩卡珀·特里布勒萨梅尔·丹拉贾尼萨扬代布·班纳吉乌吉亚尼·米特拉高塔姆·蒙什。从有许多健康并发症和职业后遗症的分析专家( Pankaj Bagri )的故事,到通过打破所有陈规打破玻璃天花板的女性的故事,这一页有很多内容可以提供。“尽管经历了斗争和挑战,巴格里凭借他坚定的决心变得比以往任何时候都更加强大。他是当今分析行业中最有影响力的人之一,他的完整故事可以在这里阅读

根据编辑的说法,该计划有其最初的挑战,联系领先的分析巨头总是具有挑战性,因为他们的时间表紧张而紧凑,期望快速回复并不容易。“但还是有人随时准备支持你,比如柯克·伯恩、T2、鲍勃·海斯和 T4·克雷格·布朗,帮助我们联系更多的人”,Humans of Analytics 团队说。该团队非常积极,正在从世界各地收集更多鼓舞人心的故事。

到目前为止,HoA 已经发布了 35 个关于企业家、创新者和变革者的故事,并拥有 1900 个以上的追随者,为分析人员提供定期的鼓舞人心的故事。它已经成为分析专业人士的一个渠道,他们希望分享自己的故事,激励年轻人,引发重要的对话。“我们享受项目的每一点,我们喜欢成为这些故事的调解者,事实上,我们能够展示分析专业人员故事中未被触及的一面,这不断激励我们做得更好。我们期待看到更多的分析专业人士敞开心扉,分享他们生活中更大、更深入的方面,”HoA 团队在总结报告中说。

人工超智能的 Lebowski 定理的反驳

原文:https://towardsdatascience.com/refutation-of-the-lebowski-theorem-of-artificial-superintelligence-a4ff253b15f8?source=collection_archive---------27-----------------------

让我从哲学家尼克·博斯特罗姆提出的一个思想实验开始。想象一个人工智能;称它为“回形针最大化器”,简称 PM。PM 有一个目标:最大化宇宙中回形针的数量。从更理论的角度来说,PM 有一个奖励功能,在宇宙中回形针数量越多,它获得的奖励就越高。它还具有一定的智力水平,智力是通过 PM 最大化其奖励功能的能力来衡量的。很有可能 PM 会选择增加它自己的智力,因为这将有助于最大化它的奖励功能。在增加其智力后,它可能再次做同样的事情,导致智力爆炸。然而,最重要的是,为了最大限度地增加宇宙中回形针的数量,在某个时候(当 PM 足够聪明时),PM 开始将地球和地球上的所有生命转变为回形针生产工厂。PM 看似无辜的目标是最大化回形针的数量,但它却杀死了所有的人类。

今年 4 月,约沙·巴赫(Joscha Bach)提出了一种关于这种思维实验的新观点,称为勒保斯基定理:

勒博斯基定理:没有哪个超级智能的人工智能会为一项比破解其奖励函数更难的任务而烦恼

这个想法似乎是,PM 更喜欢更容易的方式来获得更高的奖励,而最大限度地增加宇宙中回形针的数量,比在 PM 整天躺在沙滩上时,像“The Big Lebowski”中的那个家伙一样,仅仅改变其奖励函数来提供高奖励更难。虽然我同意改变它的奖励功能会更容易,但我不同意这个结论。Lebowski 定理的问题是 PM 想要一个有尽可能多回形针的未来宇宙,因此不喜欢一个它自己的奖励函数奖励它做其他事情的未来宇宙。PM 的目标不是最大化一个可变的奖励函数:它的目标是最大化回形针的数量,使它的奖励函数 Lebowskian 对这个目标没有帮助。

Hacking your reward function? Photo by Chase Fade on Unsplash

Lebowski 定理虽然有趣,但是混淆了奖励和目标。目标是最大化回形针的数量,因为未来有很多回形针的奖励很高。如果目标是最大化奖励,这将意味着存在主要奖励函数,当次要奖励函数(奖励大量回形针)高时,该函数给出高奖励,无论次要奖励函数碰巧奖励什么。这种情况可能会导致黑掉第二个奖励函数,使其成为 Lebowskian 函数。然而,这并不是最初思想实验中描述的情况。这就是为什么勒保斯基定理最终失败的原因。

《哈利·波特》文本的正则表达式

原文:https://towardsdatascience.com/regex-on-the-texts-of-harry-potter-96b8a3878303?source=collection_archive---------15-----------------------

深入的案例研究

Regular Expressions: more mind-boggling than arithmancy

我是 Greg Rafferty,湾区的数据科学家。你可以在我的 github 上查看这个项目的代码。如有任何问题,请随时联系我!

在这一系列的文章中,我通过《哈利·波特》的镜头来看一些简便的自然语言处理技术。我在这个关于基本自然语言处理的系列文章中的上一篇文章关注了使用潜在狄利克雷分配的主题建模,下一篇文章将关注文本摘要。

在这个 NLP 项目中,我一直使用七本关于哈利波特的书作为我的文本语料库。但是在我可以通过我的算法发送这些书之前,我首先必须将 pdf 保存为 txt 文件,然后将章节提取为单独的文档。为此,我使用了正则表达式。要想很好地了解 Python 中的正则表达式,请查看谷歌的快速课程。

正则表达式可以被认为是 crack 上的通配符搜索。它们在描述文本字符串中的模式时具有惊人的灵活性。如果你以前从未见过它们,正则表达式模式可能看起来像一团乱麻,毫无意义。但是混乱中有秩序,有强大的力量。让我们用我在这些文本上使用的模式来探索一下:

pattern = r"((?:[A-Z-][ ]){9,}[A-Z])\s+([A-Z \n',.-]+)\b(?![A-Z]+(?=\.))\b(?![a-z']|[A-Z.])(.*?)(?=(?:[A-Z][ ]){9,}|This book)"

当使用re.findall应用于保存为文本文件的哈利波特书籍时,输出是一个由 3 个元素组成的元组列表。列表中的每个元组对应于书中的一个章节,并且采用(‘C H A P T E R O N E’, ‘THE BOY WHO LIVED’, ‘Mr. and Mrs. Dursley, of number four, Privet Drive, blah, blah, blah...’)的形式,包含整个章节的文本。我们需要从中提取:

中国英语学习网

男孩世卫组织活着

女贞路 4 号的德思礼夫妇自豪地说,他们完全正常,非常感谢。他们是你最不可能想到会卷入任何奇怪或神秘的事情的人,因为他们不喜欢这样...

让我们看看上面的模式,看看它是如何做到这一点的。我将描述这个表达式背后的逻辑,但是关于精确语法的更多细节,请跟随这里的进行逐字符的描述。该铁路图显示了管道:

Source

组#1 是这个部分:((?:[A-Z-][ ]){9,}[A-Z])。这是上图中左边的第一个方框。外面的括号告诉 python 捕获 Group 1 中的内容(这将最终成为'C H A P T E R O N E')。内括号是一个子模式的分组,?:指示 python 不要将它作为第二个分组来捕获。子模式([A-Z][ ]){9,}[A-Z]表示任何大写字母后跟一个空格,重复 9 次或更多次,以最后一个大写字母结束。这是获取章节号的方式。

后面跟着\s+,它不在括号中,所以不会被捕获,并指示 python 一次或多次查找空白(换行符、制表符、空格等)。这实际上是跳到了第二组中的章节标题,下一组括号:([A-Z]\n',.-]+)。这再次意味着任何大写字母,和/或换行符(\n)、撇号、逗号、句号和破折号,一次或多次。有些章节标题有换行符或其他各种标点符号,例如:

阿兹卡班的囚徒,第 18 章:穆尼,虫尾巴,大脚板和尖头叉子

火焰杯,第 21 章:家养小精灵解放阵线

《凤凰社》第八章:韦斯莱夫人的 WOES

然而,这里有一个问题:第一册的第四章以

嘣。他们又敲门了…

所以通过寻找所有大写字母,那个“嘣”将作为标题的一部分被捕获。我们需要使用所谓的负前瞻,用?! : /b(?![A-Z]+(?=\.))/b声明。符号表示单词边界。因此,上面的章节标题捕获字符串捕获所有大写字母,除非下一个单词也是全部大写,但后面紧跟一个句点,用肯定的前瞻?=声明。太好了!现在我们能够找到那个“爆炸”把它排除在我们的抓捕范围之外。但这又引入了另一个问题。我在上一段提到的其中一章“韦斯莱夫人的 WOES”也包含一个单词,后面跟一个句号,所以现在我们只把这一章的标题记为“韦斯莱夫人的 WOES”。我们需要另一个负前视,(?![a-z']|[A-Z.]),以确保所有大写单词后面跟一个句点不是也不是后面跟小写单词(章节文本),或者不是大写字符串中的最后一个单词(因为尽管章节标题可能包含一个句点,但它绝不会以一个句点结尾)。

第三组是最简单的一组:(.*?)。这意味着捕捉任何角色,任何次数,并且要贪婪。一直走,直到被迫停下来,有了下一部分。

正则表达式的最后一部分告诉 python 在什么点停止捕获文本:(?=(?:[A-Z][ ]){9,}|This book \n)。这是另一个非捕获的前瞻。它提供了一旦一个大写字母和空格的序列重复至少 9 次就停止捕获文本的指令(因为这样就开始了下一章,“C H A P T E R T W O”),或者直到字符串This book \n。这最后一串标志着这本书的结束;《哈利·波特》七本书的结尾都是这样的:

这本书

大卫·塞勒担任美术指导,由贝基
特胡恩设计。夹克和内部的艺术都是用彩色蜡笔在调色版画纸上创作的。文本采用 12 号 Adobe Garamond 字体,这种字体基于 16 世纪 Claude Garamond 的字体设计,由 Robert slim Bach 在 1989 年重新绘制。这本书是在俄亥俄州威拉德的 RR Donnelley Sons 印刷装订的。安吉拉·比奥拉负责监督制作

唷!我希望这些都有意义!我强烈建议你访问这个链接来看看这一切的运行,甚至更多的细节和每个角色的描述。

回归

原文:https://towardsdatascience.com/regression-99fd94bcf769?source=collection_archive---------1-----------------------

预测

回归是一种非常强大的统计工具,如果使用正确,它有能力帮助您预测某些值。

当与受控实验一起使用时,回归可以帮助你预测未来。

企业疯狂地使用它来帮助他们建立模型来解释客户行为。

明智地使用回归分析确实是非常有益的。

算法— 完成计算需要遵循的任何程序。

在一个算法里面会有一个方法来预测一些事情。

预测对于数据分析来说是一件大事。有人会说,一般来说,预测合起来就是数据分析的定义

你可能需要预测的事情:

  • 人民的行动
  • 市场动向
  • 重要事件
  • 实验结果
  • 不在我们数据中的东西

你应该问自己的问题:

  • 我有足够的数据来预测吗?
  • 我的预测有多好?
  • 是定性的还是定量的?
  • 我的客户很好地使用了预测吗?
  • 我预测的极限是什么?

散点图

散点图是显示数据中丰富模式的快捷方式。任何时候你有两个变量的观察数据,你应该考虑使用散点图。

以下是一个 R 散点图示例:

散点图显示了观察结果如何相互配对,一个好的散点图可以是你如何证明原因的一部分。

回归线就是最符合平均值图表上的点的线。您可以用一个简单的等式来表示它们,这将允许您预测范围内任何 x 变量的 y 变量。

确保你的线路有用。如果您的数据显示线性相关,则该线非常有用。

相关性是两个变量之间的线性关联,对于线性关联,散点图点需要大致沿着一条线。

你可以有强或弱的相关性,它们由一个相关系数来衡量,也称为r。为了使你的回归线有用,数据必须显示出强线性相关性。

r 范围从-1 到 1,其中 0 表示不相关,1 或-1 表示两个变量之间的完美关联

用回归分析预测房价

原文:https://towardsdatascience.com/regression-analysis-model-used-in-machine-learning-318f7656108a?source=collection_archive---------1-----------------------

机器学习模型

介绍

回归分析是数据统计分析的基本方法。这是一种统计方法,允许估计变量之间的关系。人们需要确定因变量,它将根据自变量的值而变化。例如,房子的价值(因变量)根据房子的平方英尺(自变量)而变化。回归分析是预测分析中非常有用的工具。

E(Y|X)=f(Xβ )

分析背后的统计数据

用图表很容易理解(来源:维基百科)

Y = f(X) = 𝛽0 + 𝛽1 * X

𝛽0 是这条线的截击点

𝛽1 是这条线的斜率

线性回归算法用于预测数据点之间的关系(直线)。可以有许多不同的(线性或非线性)方法来定义这种关系。在线性模型中,它基于截距和斜率。为了找出最佳关系,我们需要用数据训练模型。

在应用线性回归模型之前,我们应该确定感兴趣的变量之间是否存在关系。散点图是帮助确定两个变量之间关系强度的良好起点。相关系数是变量之间关联的一个有价值的量度。其值在-1(弱关系)和 1(强关系)之间变化。

一旦我们确定变量之间存在关系,下一步就是确定变量之间的最佳拟合关系(直线)。最常用的方法是残差平方和(RSS)。该方法计算观测数据(实际值)与其与建议的最佳拟合线(预测值)的垂直距离之间的差异。它计算每个差值的平方,并将所有差值相加。

MSE(均方误差)是通过将 RSS 除以总观察数据点来衡量估计量的质量。它总是一个非负数。越接近零的值表示误差越小。RMSE(均方根误差)是 MSE 的平方根。RMSE 是估计值与观察值的平均偏差的度量。这比 MSE 更容易观察到,MSE 可能是一个很大的数字。

RMSE(MSE 的平方根)=√(MSE)

额外数量的变量将增加模型的维数。

y = f(x)= 𝛽0+𝛽1 * x1+𝛽1 * x2+𝛽1 * x3

使用的工具

  1. 计算机编程语言
  2. Graphlab
  3. s 帧(类似于熊猫数据帧)

数据加载

使用华盛顿地区西雅图的房屋数据。它包含以下各列和大约 21,000 行。

Id:日期:价格:卧室:卫生间:sqft_living sqft_lot:楼层:滨水:景观:条件:等级:sqft _ above:sqft _ basement:yr _ build:yr _ revenued:zip code:lat:long:sqft _ living:sqft _ lot

*> homesales = graphlab.SFrame(‘home_data.gl’)**> homesales*

我们需要了解两个变量之间是否有关系。我们来挑房价和居住平方英尺。

*> homesales.show(view=”Scatter Plot”, x=”sqft_living”, y=”price”)*

我们可以观察到居住面积平方英尺和房价是有关系的。

让我们使用带误差线的箱线图来观察数据,以了解邮政编码的价格。

*> homesales.show(view=’BoxWhisker Plot’, x=’zipcode’, y=’price’)*

探索和理解周围的数据总是一个好主意。Graphlab 有一个显示数据统计的好方法。

*> my_features = [‘bedrooms’, ‘bathrooms’, ‘sqft_living’, ‘sqft_lot’, ‘floors’, ‘zipcode’]*

预测分析

第一步是得到训练数据集和测试数据集。让我们用 80%作为训练数据,剩下的 20%用于测试。

*> train_data, test_data = homesales.random_split(0.8, seed=0)*

让我们建立一个平方英尺的回归模型,并存储结果。因变量价格是模型需要预测的。

*> sqft_model = graphlab.linear_regression.create(train_data, target=’price’, features=[‘sqft_living’], validation_set=None)*

我们可以使用 matplotlib 绘制模型值和实际值。

*> plt.plot(test_data[‘sqft_living’],test_data[‘price’],’.’, test_data[‘sqft_living’],sqft_model.predict(test_data),’-’)*

蓝点代表显示房价和居住面积平方英尺之间关系的测试数据。绿线显示了使用我们构建的“sqft_model”线性回归模型对给定平方英尺的房价(因变量)的预测。

结果

让我们挑选一所房子,并使用“sqft_model”预测其价值。

*> house2 = homesales[homesales[‘id’]==’5309101200']**> house2*

现在让我们使用“sqft_model”来预测房子价值。

*> print sqft_model.predict(house2)*

[629584.8197281545]

其预测值为 629,584 美元,与实际值 620,000 美元非常接近。

虽然我们的模型运行得相当好,但预测值和实际值之间存在差距。

*> print sqft_model.evaluate(test_data)*

{ ' max _ error ':41425228938,' RMSE ':25358 }

“最大误差”是由异常值引起的。它显示在 matplot 可视化的右上角。该模型基于 RMSE 的误差值为 255,191 美元。

多目标变量回归模型

原文:https://towardsdatascience.com/regression-models-with-multiple-target-variables-8baa75aacd?source=collection_archive---------0-----------------------

Photo by Annie Spratt on Unsplash

在 Datacraft,我们最近有机会研究一个监督机器学习问题,其中目标变量是实数和多值的。对机器学习库的初步搜索显示,流行的开源 ML 库对此几乎没有支持。

这里有一个主题的快速介绍,以及(在后面的文章中)对 JVM 生态系统中的一些库的探究。

多目标回归

机器学习分类器通常支持单个目标变量。在回归模型中,目标是实值,而在分类模型中,目标是二元或多值的。

对于分类模型,一个有多个目标变量的问题叫做多标签分类。在回归模型领域,作为初学者,我发现术语有点混乱。

  • 简单回归模型是一种试图用单一解释变量/独立变量拟合线性回归模型的模型。
  • 多元回归模型是一种试图根据两个或更多自变量的值来预测因变量的模型。例如:可以根据吸烟持续时间、开始吸烟的年龄、收入、性别等来预测每天的香烟消费量吗?
  • 多目标回归是有多个因变量时使用的术语。如果目标变量是分类的,那么它被称为多标签或多目标分类,如果目标变量是数值的,那么多目标(或多输出)回归是常用的名称。

几种 MTR 回归模型方法的探讨

本文对多目标回归的模型方法进行了很好的概述。

它将方法分为以下几类:

问题转化:

  • 诸如单目标回归、回归变量链

算法转换:

  • 多输出支持向量回归
  • 多输出回归树和规则方法

使用聚类和决策树的多目标回归。

在接下来的讨论中,我们将集中讨论一种方法,即用于 MTR 的决策树和决策树集合。

使用树进行聚类,也称为预测聚类树(PCT)

我们需要首先看一下预测聚类树(PCT ),它是 MTR 决策树的基础。

聚类树的自顶向下归纳是讨论使用决策树进行聚类的论文。在分类角色中,决策树的叶子是类或标签。

然而,从集群的角度来看

  • 每个叶节点对应于一个概念或一个集群,
  • 树中的节点表示分类法或层次结构。

该文件指出:

A clustering tree is a decision tree where leaves don't contain classes and where each node & leaf correspond to a cluster.

沿着树向下走(从根开始,然后向下到叶节点)可以被比作从大的集群(在顶部)移动到越来越小的集群,当我们接近叶节点时。

聚类之间距离的度量

在监督分类中,距离度量是目标变量的类。

在无监督或半监督学习中,聚类是基于距离度量(例如欧几里得距离)来完成的。如果小样本被标记,则节点中的所有(未标记的)样本被分配大多数标记样本的类别。聚类可用于预测许多或所有目标属性。

对于一个有 5 个目标变量的问题,叶节点将包含一个长度为 5 的向量,每个向量代表一个目标变量。

衡量 PCT 的质量

对于回归,使用的默认度量是相对误差,即

  • 预测的均方误差除以始终预测平均值的默认假设的均方误差。

如何建造这棵树

为了构建一棵树,我们首先决定:

  • 距离度量(比较两个实例之间的距离)
  • 一个原型函数(它计算一个聚类的质心,以便可以比较两个聚类)

给定树的每个节点对应于一个聚类,然后决策树算法适于在每个节点中选择将最大化其子节点中的结果聚类之间的距离的测试。

  • 给定聚类 C 和测试 T,最佳测试 T 是使子聚类 C1 和 C2 之间的距离最大化的测试。
  • 如果原型(类似于聚类质心)是平均值,最大化聚类间距离对应于最小聚类内距离。这意味着树构建彼此远离的簇,并且簇内几乎没有分散。
  • 停止标准:当子树明显不同时,树的生长(或者更确切地说,节点分裂)停止。对于回归,使用 f 检验(测量两个群体之间的方差差异)。
  • 修剪:树从训练数据中生长,并且使用验证集来修剪树。

For each node of the tree the quality of the tree if it were pruned at that node Q′ is compared with the quality Q of the unpruned tree. If Q′ > Q then the tree is pruned.

用于 MTR 的决策树集成方法的比较

在上一节中,我们学习了如何构建一个决策树。然而,当使用树的森林时,性能会大大提高。

本文讨论了集成在多目标决策树中的应用。

装袋:

  • 从数据集中选取引导样本,并使用这些样本构建一个树。引导样本是通过对训练集进行替换采样而获得的。

随机森林

  • 除了 bagging 之外,在决策树的每个节点上,使用随机特征子集来分割节点,而不是 Bagging 中的所有特征。

论文的结果,简而言之

  • (MODTs 的)集成比单个决策树表现更好。
  • (MODTs 的)随机森林集成比 Bagging 集成表现更好。

为什么要用多输出模型,而不是回归这样的单输出模型组合?

  • 使用单一输出的模型需要更长的训练时间,并且计算量很大
  • 它们针对单个目标而不是所有目标一起进行优化
  • 它们不使用目标变量(Y)之间的关系
  • MTR 回归模型比一堆单一目标模型更简单
  • MTR 树提供了人类可读的预测模型,这些模型易于解释。

中期审查可用的工具

我发现 Clus 工具包很好地融合了高性能和健壮性

  • 文档是优秀的
  • 该工具包有多种用于多目标分类和回归的方法
  • 它还支持基于规则归纳和聚类。
  • 我使用的集合模型(Bagging,RandomForest)易于阅读和解释。

一些更新的方法(2012 年后)已经作为木兰工具包的扩展实现了,可以在这个 Github 链接获得。虽然这些方法如随机线性目标组合比集合模型报告了更好的性能,但我发现该工具包不如 Clus 工具包成熟。

这里有一个关于相同主题的 StackExchange 的讨论。

在后面的文章中,我们将讨论如何使用 Clus 工具包来运行 MTR 模型。

机器学习:回归—预测房价(第二课)

原文:https://towardsdatascience.com/regression-predict-house-price-lesson-2-5e23bec1c09d?source=collection_archive---------0-----------------------

你要卖掉你的房子,你想知道它的合适价格吗?我们会用 ML 来猜测房价——怎么猜?请阅读:)

在上一篇文章中,你将从 ML word 中学习一些基本术语。在这篇文章中,我们将重点关注监督学习,我们将做一些很酷的事情——建立一个 ML 模型,根据其属性预测房价。

先说一些理论。在监督学习中,您可以根据响应类型选择算法:

  • 如果你的回答是连续的(一些数字),那么你将做回归,你需要回归任务的算法。
  • 如果你的回答是分类的(类别或类),那么你将做分类,你需要得到分类算法

例如,如果您正在建立一个模型来预测“热或不热”,并且您正在预测 1-10 范围内的值,那么这就是回归,如果您的响应是热或不热,那么这就是分类。

在这个例子中,我们将建立一个预测模型来预测房价(价格是一个定义范围内的数字,所以这将是一个回归任务)。例如,你想卖一栋房子,但你不知道你能接受的价格——不能太低也不能太高。要找到房价,你通常会尝试在你的社区找到类似的房产,并根据收集到的数据评估你的房价。我们会做一些类似的事情,但是用机器学习的方法!好,我们开始吧!

我们将使用波士顿住房数据集,你可以从这里下载。然而,我在原始数据集上为你做了一个小技巧,帮助你更好地理解 ML,我把它分成训练和测试样本——你可以从我的 github 得到。我们将使用训练样本(data_train.csv 文件)进行模型学习,使用测试样本(data_test.csv)进行预测。我将数据分为两组,向您展示如何使用训练好的模型来预测未知。如果你对数据中每一列的含义感兴趣,你可以在这里查看。对于模型培训,我们将使用 MLJAR ,因为它具有简单的 web 界面(如果您没有帐户,请注册并获得免费的启动信用)。让我们开始一个新项目。确保选择回归作为任务。这很重要,因为不同的算法用于回归,不同的算法用于分类。

好的,请添加训练和测试数据集。在添加测试数据集期间,重要的是勾选:该数据集将仅用于预测(我们不会使用该数据集中的真实销售价格,我们将预测它!).

之后,我们需要指定列的用法。MLJAR 试图猜测应该使用哪一列。请将“目标”设置为训练数据集的销售价格的列用途。对于测试数据集,请将“不要使用它”设置为销售价格的列用途。对于每个数据集,我们需要在顶部“接受属性用法”。

我们准备定义 ML 实验。作为输入,我们将使用“训练”数据。请将预处理保留为默认值。对于学习算法,我们将使用极端梯度推进(xgboost)——它是超级强大的,你会看到!在调整详细资料中,请选择要优化的度量:均方根误差。然后点击开始!

哇!但是等等,什么是均方根误差(RMSE),为什么我需要这个?好问题。在训练阶段,您的模型希望预测的值尽可能接近目标值。为了跟踪它做得有多好,我们需要一些度量——它被称为成本函数。在我们的例子中,我们选择 RMSE 作为成本函数。当我们进入结果页面时,我们会看到许多模型,每个模型都有不同的 RMSE 值(分数栏)。

可以吗?我们使用一种算法,它产生不同的分数?当然,因为当你点击每个算法时,你会发现它们有不同的参数——所谓的超参数。所以不同的算法参数会得到不同的模型。这就是为什么 MLJAR 会为您检查许多不同的参数,并让您获得最佳模型(最有用)。在我们的案例中,最佳模型将是得分最低的模型,因此请通过单击该列对模型进行排序。

我们训练了一组模型,选出了最好的一个。那又怎样?

我们需要使用我们的模型!这就是为什么我留下测试样本,向您展示如何使用训练模型。在我们的测试数据集中有真值,但我们不会使用它们,让我们假设它们不存在。所以我们的测试数据中有 100 栋房子,我们想知道它们的价格。要计算预测,请转到预测视图。获得预测有 4 个步骤:

  • 步骤 1 —请选择您想要用作输入的数据集,在我们的示例中是“测试”。
  • 步骤 2-请选择您要用于计算预测的算法,在我们的情况下,我们将使用具有最小分值的算法。
  • 第 3 步—点击“开始预测”按钮!😃
  • 步骤 4-请等待一段时间进行预测,并下载包含模型响应的文件。

太棒了。您刚刚使用了 ML 模型,因此现在是将预测价格与真实价格进行比较的好时机—这是可以做到的,因为我们在测试集中有真实的销售价格,而在现实生活中,我们没有这样的值,因此只能手动(以某种方式)检查预测。好了,我们来目测一下。

在一列中有模型的预测,“销售价格”是真实值,在图片中显示了前几个数据样本(房屋)。你可以看到,在某些情况下预测是非常准确的。例如,对于 Id=1 的房子,真实价格是 208500 美元,预测价值是 208352 美元,因此超过 200,000 美元的房产只有 148 美元的差异——相当不错!

但是,也有预测值相差几千的房子。这个不用担心。这在 ML 中很常见,模型有时会出错。原因可能有很多:

  • 数据不足——样本太少,T4 无法根据数据很好地概括 T5
  • 杂乱的数据——数据中经常有错误
  • 模型问题—模型太简单或太复杂

这就是为什么计算成本函数对于衡量我们的预测有多准确很重要。

好了,今天就到这里。我们已经创建了 ML 模型来预测房价并使用它!😃

XGBOOST 回归预测区间

原文:https://towardsdatascience.com/regression-prediction-intervals-with-xgboost-428e0a018b?source=collection_archive---------1-----------------------

(更新 2019-04-12:真不敢相信已经两年了。由于我一直收到各种更新代码的请求,我花了一些时间来重构、更新 gists,甚至创建了一个合作笔记本。我为那些在运行过去版本时遇到困难的人道歉。如果您有任何问题,请提问,我很乐意抽出时间来回答!)

(更新 2020–08–19:感谢您 Hassen Miri 帮助我完善分割收益论点)

对于任何希望对自己的业务进行认真预测分析的人来说,了解算法预测的不确定性是至关重要的。预测从来都不是绝对的,了解潜在的变化是非常必要的。如果一个人希望知道每个航班的乘客量,他还需要知道有多少乘客的预测可能不同。另一个可以决定预测上岸时间。当然,在几个小时的预测和半个小时内 95%的正确率和 10 个小时的潜在误差之间是有区别的!

在这里,我提出了一个定制的成本函数,用于将著名的 xgboost 回归器应用于分位数回归。Xgboost 或极端梯度提升是一个非常成功和强大的基于树的算法。由于分位数回归成本函数的梯度和 Hessian 性质,xgboost 的表现明显不佳。我表明,通过添加一个随机成分到平滑梯度,分位数回归可以成功应用。我展示了这种方法可以胜过流行的 scikit-learn 包中的GradientBoostingRegressor算法。

为什么是预测区间?

虽然模型输出的是准确的预测,但它们本身是随机变量,也就是说,它们有分布。为了了解我们的结果正确的可能性,预测区间是必要的。这种可能性决定了可能值的区间。

比方说,我们希望知道 90%确定概率的可能预测的范围,那么我们需要提供两个值Q_alpha, Q_{1-alpha},这样,真实值的概率在区间内

是 90%。

线性回归的基本陈述是,

假设观测值x_iε_i是独立的并且是正态分布的。

假设误差项正态分布,系数β_j的最大似然估计使这些误差项的方差最小。

这个方差当然是预测方差的最大似然(ML)估计。在我们假设特征和误差都是正态分布的情况下,预测也是正态分布的。

正态分布的预测区间很容易从期望和方差的最大似然估计中计算出来:

68%的预测区间介于

,95%的预测区间介于

99.7%的预测区间在

这种方法有一些限制。首先,我们非常依赖正态性的基本假设,当然这并不总是正确的。最后,线性回归的简单性将我们限制在一个非常宽的预测区间。理想情况下,我们希望我们的预测边界也依赖于更多的特征。在下一节课中,我们将讨论使用树模型的实现。

树模型

回归树是一个非常强大的预测工具。树的一般思想是对要素进行分区,并为每个分区分配一个值。该值以这样的方式分配,使得分区内的成本函数最小化。

Fig 1: Illustration of a tree model. The tree defines a partition of the features-space and assigns a values to each partition.

分位数可以通过下面的优化问题找到,

**

Fig 2: Cost function of Quantile Regression

xgboost 的分位数回归

我还没有解释如何给每个分区赋值。

Xgboost 是一个强大的算法,它为我们做到了这一点。为了进一步参考,读者应该检查原始论文,

陈,田琦和卡洛斯.盖斯特林。" Xgboost:一个可扩展的树增强系统."第 22 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集。ACM,2016。

将体积I进一步划分成两个更小的子体积I_LI_R的主要因素是得分函数,

如果发生分裂,那么通过将下面的值加到较大体积q_old的分位数的旧值上,来更新每个子体积I_α内的分位数q_new的新值。

参数λ和η分别是正则化和收缩参数,我在这里不做进一步讨论。

这里重要的是梯度和 Hessian 的值:

在下图中,我们看到了梯度和黑森曲线。

正如我们所见,梯度是一个阶跃函数,而海森函数处处为零,在原点处无穷大。

Fig 3: Gradient and Hessian of the cost-function of quantile regression with respect to the estimate

回头看看分裂的得分函数L_split,我们看到几个问题。

让我们看看分位数值q_old与分区内的观察值相距相对较远的情况。除非,我们运气好,在升压开始的时候是这种情况。梯度和 Hessian 对于大的差异都是常数x_i — q。这意味着分离增益与任何特性无关。更糟糕的是,最佳分割增益告诉我们,只要我们将数据量分成两半,任何分割都是足够的!当寻找分割时,xgboost 将尝试寻找具有最佳分割的特征。因为所有特征产生相同的分离增益,即节点中一半的数据向左,另一半向右,所以不会发生分离。

如果我们使用上面显示的梯度和 Hessian,甚至使用平滑的变体,很少会出现分裂,模型将表现不佳。

一个有趣的解决方案是通过向渐变添加随机化来强制拆分。当分区内的观察值x_i和旧的分位数估计值q_old之间的差异很大时,这种随机化将强制随机分割该体积。

Fig 4: Plots of the new Gradient and Hessian used to estimate the quantile. Close to the origin, we use a smoothed version of the Gradient and Hessian. Far from the origin, randomization has been added to force a random split of the partition.

也就是说,我提出梯度和 Hessian 的以下平滑变型,

Gradient

随机变量ρ。对于这个实验,我简单地选择ρ,对于某个参数s,以相等的概率取两个值s-s中的一个。

黑森:

Hessian

在代码中:

我们将此代码应用于由以下代码生成的数据,这些数据也在 sklearn 示例中使用:http://sci kit-learn . org/stable/auto _ examples/ensemble/plot _ gradient _ boosting _ quantile . html

下图显示了 sklearn 的GradientBoostingRegressor和我们定制的XGBRegressor的 90%预测区间的比较结果,该区间是根据 95%和 5%分位数计算的。

对于 95%的分位数,我使用了参数值

对于 5%的分位数,我用了

是通过网格搜索找到的。当使用成本函数对测试集进行评分时,发现定制 xgboost 的 95%和 5%分位数都是优越的。

点击此处查看合作笔记本!!!

回归美好

原文:https://towardsdatascience.com/regression-to-the-nice-c7059cf81a7c?source=collection_archive---------8-----------------------

以下是一个真实的故事。一家公司的人力资源部对员工满意度进行了年度调查。他们比较了前一年报告低于中间值的人和今年的结果。他们得意洋洋地宣布,去年 75%的不满者在最新调查中得分更高,这是士气提高的明显迹象。

但是房间里的统计学家更清楚。得出的结论不正确, 回归谬误 的一个例子。回归均值是极端变量在下一次迭代中变得不那么极端的趋势。这种现象不是由任何原因引起的,而仅仅是一种随机性的产物。假设调查结果是独立且同向抽取(iid)的连续随机变量,75%的改善正是不太快乐的那一半人所期望的。

X1 为上一年的调查结果, X2 为本年的调查结果。要计算的值是 P(X2>X1 |F(X1)≤0.5)其中 F 是累积密度函数(CDF)。目前假设 X1X2 是iid 标准均匀随机变量,这就简化为 P( X2 > X1|X1≤ 0.5)。下面是对 X1X2 的联合概率分布的支持的可视化。

该区域内的联合概率值是常数,是两个独立均匀随机变量的乘积。彩色区域为 X1≤ 0.5,蓝色区域为 X2 > X1X1≤ 0.5 的区域。蓝色区域除以彩色区域得到 P(X2>X1 | X1≤0.5)= 0.75 当 X1X2 ~ 均匀 (0,1)。

即使调查结果不是均匀分布的,只要连续分布,这个 0.75 的值仍然成立。

Y1Y2 为 iid 随机变量,具有某种任意连续分布和 CDF F,则感兴趣的值为 P(Y2>Y1 |F(Y1)0.5)。将 CDF 应用于 Y1Y2 ,由于是单调递增的,所以这个概率相当于 P(F(Y2)>F(Y1)| F(Y1)0.5)。概率积分变换陈述了将任意连续随机变量的 CDF 应用于随机变量给出了标准的均匀随机变量。因此,P(F(Y2)>F(Y1)| F(Y1)0.5)等价于 P( X2 > X1|X1≤ 0.5),P 也是 0.75。

回归谬误的另一个例子是“大二滑坡”,即运动员在第一个赛季的出色表现不会在接下来的赛季重复。虽然冷漠或紧张可能是罪魁祸首,但在某种程度上,运气在最初的表现中发挥了作用,这种下降是意料之中的。同一个运动员不太可能第二次这么幸运。

机器学习中的正则化

原文:https://towardsdatascience.com/regularization-in-machine-learning-76441ddcf99a?source=collection_archive---------0-----------------------

训练机器学习模型的一个主要方面是避免过度拟合。如果模型过拟合,精度会很低。发生这种情况是因为您的模型过于努力地试图捕捉您的训练数据集中的噪声。 我们所说的噪音是指那些并不能真正代表你的数据的真实属性的数据点,而是随机的 。学习这样的数据点,使你的模型更加灵活,但有过度拟合的风险。

平衡偏差和方差的概念,有助于理解过度拟合现象。

[## 平衡偏差和方差以控制机器学习中的错误

在机器学习的世界里,准确性就是一切。您努力通过调整和…使您的模型更加精确

medium.com](https://medium.com/towards-data-science/balancing-bias-and-variance-to-control-errors-in-machine-learning-16ced95724db)

避免过度拟合的方法之一是使用交叉验证,这有助于估计测试集的误差,并决定哪些参数最适合您的模型。

[## 机器学习中的交叉验证

总是需要验证你的机器学习模型的稳定性。我的意思是,你就是不能让模型符合…

medium.com](https://medium.com/towards-data-science/cross-validation-in-machine-learning-72924a69872f)

本文将关注一种有助于避免过度拟合并增加模型可解释性的技术。

正规化

这是一种回归形式,它将系数估计值约束/调整或缩小到零。换句话说, 这种技术不鼓励学习更复杂或更灵活的模型,以避免过度拟合的风险。

线性回归的一个简单关系如下。这里,Y 表示学习的关系,而 β表示不同变量或预测值(X)的系数估计值。

Y≈β0+β1 x1+β2 x2+…+βpXp

拟合过程涉及一个损失函数,称为残差平方和或 RSS。选择系数,使得它们最小化这个损失函数。

现在,这将根据您的训练数据调整系数。如果训练数据中有噪声,那么估计的系数将不能很好地推广到将来的数据。这就是正则化的用武之地,它将这些学习到的估计缩小或正则化到零。

里脊回归

上图显示了岭回归,其中 RSS 通过添加收缩量进行了修改。 现在,通过最小化这个函数来估计系数。这里, λ是调节参数,它决定了我们想要对模型的灵活性进行多少惩罚。 一个模型的灵活性的增加是通过其系数的增加来表示的,如果我们想要最小化上述函数,那么这些系数需要很小。这就是岭回归技术如何防止系数升得太高。此外,请注意,我们缩小了每个变量与响应的估计关联,除了截距β0,此截距是当 xi1 = xi2 = …= xip = 0 时响应平均值的度量。

当λ = 0 时,罚项没有 effect ,岭回归产生的估计将等于最小二乘。然而, 随着λ→∞,收缩惩罚的影响增大,岭回归 coefficient 估计将趋近于零 。可以看出,选择一个好的λ值至关重要。为此,交叉验证很方便。用这种方法产生的系数估计值是 也称为 L2 范数

然而,岭回归的情况并非如此,因此,在进行岭回归 之前,我们需要标准化预测因子或将预测因子带到相同的尺度。下面给出了实现这一点的公式。

套索

套索是另一种变化,其中上述功能被最小化。很明显,这种变化与岭回归的不同之处仅在于惩罚高系数。它使用|βj|(模数)而不是β的平方作为它的惩罚。在统计学中,这种 被称为 L1 常模

让我们从不同的角度来看看上面的方法。岭回归可视为求解一个方程,其中系数的平方和小于或等于 s 。并且套索可以被认为是一个方程,其中系数的模数之和小于或等于 s 。这里,s 是对于收缩因子 λ的每个值都存在的常数。 这些方程也被称为约束函数。

认为自己是给定问题中的 2 个参数 。那么根据上述公式, 岭回归由β1 + β2 ≤ s 表示。这意味着岭回归系数对于位于由β1 + β2 ≤ s 给出的圆内的所有点具有最小的 RSS(损失函数)

同样, 对于套索,方程变成,|β1|+|β2|≤ s 。这意味着拉索系数对于位于由|β1|+|β2|≤ s 给出的菱形内的所有点具有最小的 RSS(损失函数)

下图描述了这些等式。

Credit : An Introduction to Statistical Learning by Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani

上图显示了套索(左)和岭回归(右)的约束函数(绿色区域),以及 RSS 的轮廓(红色椭圆) 。椭圆上的点共享 RSS 的值。对于非常大的 s 值,绿色区域将包含椭圆的中心,使两种回归技术的系数估计值等于最小二乘估计值。但是,上图中的情况并非如此。在这种情况下,套索和岭回归系数估计值由椭圆接触约束区域的第一个点给出。 由于岭回归具有没有尖锐点的圆形约束,所以这种相交一般不会出现在轴上,因此岭回归 coefficient 估计将专门是非零的。 然而,套索约束在每个轴上都有角,所以椭圆通常会在一个轴上与约束区域相交。当这种情况发生时,其中一个 coefficients 将等于零。 在更高维度(其中参数远多于 2),许多 coefficient 估计可能同时等于零。

这揭示了岭回归的明显缺点,即模型的可解释性。它将缩小最不重要预测因子的系数,非常接近于零。但这永远不会使它们完全为零。换句话说,最终的模型将包括所有的预测值。然而,在套索的情况下,当调谐参数λ是 sufficiently 大时,L1 罚函数具有迫使一些 coefficient 估计恰好等于零的 effect。因此,套索法也执行变量选择,据说能产生稀疏模型。

正规化实现了什么?

标准最小二乘模型往往会有一些差异,即该模型对于不同于其训练数据的数据集不能很好地泛化。 正则化,显著降低模型的方差,而不大幅增加其偏差 。因此,在上述正则化技术中使用的调谐参数λ控制对偏差和方差的影响。随着λ值的上升,它会降低系数的值,从而降低方差。 直到某一点,λ的增加是有益的,因为它只是减少了方差(因此避免了过度拟合),而没有丢失数据中的任何重要属性。 但是在某个值之后,模型开始失去重要的属性,导致模型出现偏差,从而拟合不足。因此,应该仔细选择λ的值。

这是你开始正规化所需要的所有基础。这是一种有用的技术,有助于提高回归模型的准确性。实现这些算法的一个流行库是 Scikit-Learn 。它有一个很棒的 api,只需几行 python 代码就能让你的模型运行起来。

如果你喜欢这篇文章,请务必为下面这篇文章鼓掌以示支持,如果你有任何问题,请留下评论,我会尽力回答。

为了更加了解机器学习的世界,跟我来。这是最好的办法,等我多写点这样的文章就知道了。

你也可以在 关注我【推特】直接发邮件给我 或者 在 linkedin 上找我。我很乐意收到你的来信。

乡亲们,祝你们有美好的一天:)

信用

这篇文章的内容来自 Gareth James,Daniela Witten,Trevor Hastie,Robert Tibshirani 的《统计学习导论》

机器学习中的正则化:将点连接起来

原文:https://towardsdatascience.com/regularization-in-machine-learning-connecting-the-dots-c6e030bfaddd?source=collection_archive---------3-----------------------

故障

以下是我们将一起走的各个步骤,并试图获得理解。

  1. 语境

2.先决条件

3.过度拟合问题

4.目标

5.什么是正规化?

6.L2 范数或岭正则化

7.L1 范数或拉索正则化

8.拉索(L1) vs 里奇(L2)

9.结论

1.语境

在本文中,我们将把线性回归视为一种算法,其中目标变量“y”将由系数为β1 和β2 的两个特征“x1”和“x2”来解释。

2.先决条件

首先,让我们先弄清楚一些次要的先决条件,以便理解它们的用法。

线性回归

可选:参考下面链接中的第 3 章,了解线性回归。

[## 统计学习的要素:数据挖掘、推理和预测。第二版。

web.stanford.edu](https://web.stanford.edu/~hastie/ElemStatLearn/)

普通最小二乘(OLS)回归的成本函数

Source: https://web.stanford.edu/~hastie/ElemStatLearn/

N —样本数量

p——独立变量或特征的数量

x-特征

y —实际目标或因变量

f(x) —估计目标

β——对应于每个特征或独立变量的系数或权重。

表示为等高线图的梯度下降

在下面的图 1(a)中,梯度下降以三维形式表示。J (β)代表相应β1 和β2 的误差。红色代表误差高的区域,蓝色代表误差最小的区域。使用梯度下降,将在误差最小的地方识别系数β1 和β2。

Fig 1: Gradient Descent Projection as Contour

在上面的图 1(b)中,来自梯度下降的成本函数的相应误差被投影到具有相应颜色的 2-dim 上。

Fig 2: Gradient Descent on axes of β1 and β2

在左侧的图 2 中,简单线性回归的梯度下降轮廓在系数β1 和β2 的坐标系中以二维格式表示。

让我们暂时把这个理解放在一边,继续讨论其他一些基本问题。

3.过度拟合问题

假设我们已经在训练集上使用线性回归训练了一个模型,并将性能提高到令人满意的水平,我们的下一步是根据测试集/看不见的数据进行验证。在大多数情况下,准确性水平会下降。发生了什么事?

为了在训练过程中努力提高模型的准确性,我们的模型将尝试拟合和学习尽可能多的数据点。换句话说,随着拟合优度的增加,模型从线性到二次再到多项式(即模型复杂性在增加)。这是由于过度拟合。下图来自吴恩达的机器学习课程,有助于直观地理解这一点。

Source: https://youtu.be/u73PU6Qwl1I?t=211

高次模型和大系数显著增加了方差,导致过度拟合。

4.目标:

我们的模型需要稳健,以便在现实世界中进行良好的预测,即从样本数据或训练期间未见过的数据中进行预测。训练过程中的过度适应是阻止它变得健壮的原因。为了避免这种过度拟合的情况并提高模型的稳健性,我们尝试

1.缩小模型中要素的系数或权重

2.从模型中去除高次多项式特征

我们如何实现这一目标?随之而来的是正规化。现在就来探索一下吧。

5.什么是正规化?

假设说,我们已经训练了我们的线性回归模型,并且在全局最小值处识别了系数β1 和β2。为了达到我们的目标;如果我们尝试缩小先前学习的特征的系数,模型会失去准确性。这种准确度的损失需要用其他东西来解释,以保持准确度水平。这个责任将由模型方程的偏差部分承担(偏差:不依赖于特征数据的模型方程的一部分)。

偏置部分将按以下方式调整:

1.方差需要减少,偏差需要增加:由于方差是系数β1,β2 的函数;偏差也将被标记,并作为系数β1、β2 的函数而改变。使用系数β1、β2 的 L1 和 L2 范数的原因。

2.推广:这个系数β1,β2 的函数需要推广,在整个坐标空间(坐标轴上的正值和负值)都起作用。这就是我们在 L1 和 L2 范数方程中发现模算子的原因。

3。 正则化参数‘λ’:由于方差和偏差都是系数β1、β2 的函数,所以它们将成正比。这样不行。因此,我们需要一个额外的参数来调节偏差项的大小。这个调节器是正则化参数‘λ’

4.‘λ’是一个超参数:如果‘λ’是一个参数,梯度下降会很好地将其设置为 0,并移动到全局最小值。因此,对‘λ’的控制不能用于梯度下降,需要排除在外。它将不是一个参数,而是一个超参数。

在理解了偏差项的变化后,让我们进入将用于正则化的系数β1、β2 的一些函数。

6.L2 范数或岭回归

L2 范数是|β1| + |β2|形式的欧氏距离范数。

具有 L2 正则化的修改的成本函数如下:

Source: https://web.stanford.edu/~hastie/ElemStatLearn/

让我们假设λ = 1 并且暂时不在画面中

在寻找全局最小误差的过程中,β1 和β2 可以变化。正则项(在上面的等式中用蓝色突出显示);特定值(β1,β2)将产生偏置输出β1 + β2。可以有多个值产生相同的偏差,如(1,0)、(-1,0)、(0,-1)、(0.7,0.7)和(0,1)。在 L2 范数的情况下,产生特定相同偏差的β1 和β2 的各种组合形成一个圆。对于我们的例子,让我们考虑一个偏差项= 1。图 6(a)表示这个圆。

Fig 6: L2 Norm

图 6(b)表示线性回归问题的梯度下降等高线图。现在,这里有两股力量在起作用。

力 1:偏项,将β1 和β2 拉至仅位于黑色圆圈上的某处。

力 2:梯度下降试图行进到绿点指示的全局最小值。

这两个力都在拉动,最后停在由“红十字”表示的交点附近。

记住我们之前对图 6(b)的假设是偏差项= 1 且λ = 1。现在去掉一个关于偏差项的假设。

想象一下“黑色圆圈”的大小在变化,梯度下降落在成本最低的不同点上。λ = 1 的假设仍然存在。观察到的最小成本是λ = 1 时的

接下来去掉另一个假设λ = 1。提供一个不同的值,比如λ = 0.5。

对λ = 0.5 重复梯度下降过程,并检查成本。可以对不同的λ值重复该过程,以便识别成本函数给出最小误差的最佳λ值。

总的目标是在坡度下降后保持低成本。因此,λ、β1、β2 的值被确定为保持客观。

在该过程结束时,方差将会减小,即系数的大小减小。让我们转到β1,β2 的另一类函数。

7.L1 范数或拉索回归

L1 范数的形式是|β1| + |β2|。

L1 正则化的修正成本函数如下:

Source: https://web.stanford.edu/~hastie/ElemStatLearn/

图 7(a)显示了 L1 范数的形状。

Fig 7: L1 Norm

图 7(b)显示了具有梯度下降等高线图的 L1 范数。从减少差异的角度来看,上一节讨论的相同逻辑在这里也是有效的。

让我们转到套索正则化的另一个重要方面,我们将在下一节讨论。

8.拉索(L1)对岭(L2)正规化

图 8(a)显示了 L1 和 L2 标准的面积。对于产生的相同量的偏置项,L1 范数占据的面积很小。但是 L1·诺姆不允许任何靠近轴线的空间。这是导致 L1 范数和梯度下降轮廓之间的交点在轴附近会聚的原因,从而导致特征选择。

Fig 8: L1 vs L2 Norms

图 8(b)显示了 L1 和 L2 标准以及不同线性回归问题的梯度下降轮廓。除了一种情况,L1 范数收敛于或非常接近轴,因此从模型中移除特征。

这里的每个象限都有一个梯度下降轮廓,用于不同的线性回归问题。绿色、蓝色、棕色表示它们与不同的线性回归问题有关。每个等高线中的红色圆圈与山脊或 L2 范数相交。每个轮廓中的黑色圆圈与套索或 L1 范数相交。

这表明 L1 范数或 Lasso 正则化作为特征选择器,同时减少方差。

9.结论

方差减少等同于偏差方差权衡。

学分:

  1. 《统计学习的要素》,作者:特雷弗·哈斯蒂、罗布·蒂伯拉尼、杰罗姆·弗里德曼。链接:https://web.stanford.edu/~hastie/ElemStatLearn/】T4
  2. 正规化话题由吴恩达提出。链接:https://youtu.be/u73PU6Qwl1I?t=211

正则化:偏差-方差权衡之路

原文:https://towardsdatascience.com/regularization-the-path-to-bias-variance-trade-off-b7a7088b4577?source=collection_archive---------2-----------------------

Photo credit: Pixabay

DataRobot 的首席产品官 Owen Zheng 说:

如果你在没有正则化的情况下使用回归,你必须非常特别。

任何有监督的机器学习问题的最终目标都是找到一个模型或函数来预测一个目标或标签,并且在所有可能的输入和标签上最小化期望误差。最小化所有可能输入的误差意味着函数必须能够对未知输入进行归纳和准确预测。换句话说,机器学习的基本目标是让算法在训练集之外进行推广。因此,正则化简单来说就是引入附加信息以解决不适定问题或防止过度拟合的过程。

说明性示例

假设我们想根据一个独立变量——教育水平来预测某人的工资。我们可以在拉各斯随机选择 1000 人,给他们每个人打电话,问他们的工资。如果我们拟合一条年龄对工资的曲线,我们能准确地用这条曲线来预测所取数据中人的年龄吗?你我都知道这个模式会失败,因为太简单了。这就是所谓的具有高偏差或拟合不足的模型。

假设我们现在从 10 个不同的城市取样,询问受访者的年龄、性别、教育水平、职业和工作经验、父母的职业、体重、身高、最好的食物等等。它变得更加复杂。我们的模型现在可以对我们的训练数据进行归纳和很好的预测。但是它能对其他它没有见过的测试集做出好的预测吗?不会,因为它会像记忆了数据一样一直粘在数据上。这就是我们所说的过度拟合。当一个学习者输出一个对训练数据 100%准确而对测试数据 50%准确的模型时,当它可以输出,比如说对训练和测试数据都是 80%准确时,它已经'过度拟合了。因此,我们说我们的模型有很高的方差,这就是正则化想要解决的问题。

这是一个线性回归问题,我们知道我们的独立变量(年龄、受教育程度等)会以不同的权重组合来预测工资。现在我们的正则化技术来了。我们希望惩罚或调整独立变量的每个权重,这样它就可以对一个以前没有见过的测试集做出很好的预测。换句话说,我们说正则化通过缩小每个特征的贡献来执行特征选择。正则化将有助于在高偏差的第一种情况和高方差的第二种情况之间选择一个中点。就偏差和方差而言,一般化的理想目标是低偏差和低方差,这几乎不可能或难以实现。因此,需要权衡取舍。我们可能不得不将训练数据的准确率从 100%降低到 80%,而将未知数据的准确率从 50%提高到 80%。下图说明了偏差-方差分解。

Fig. 1: Graphical Illustration of bias-variance trade-off , Source: Scott Fortmann-Roe., Understanding Bias-Variance Trade-off

数学理解

Machine Learning Flashcard by Chris Albon

当我们说我们有一个对测试和训练数据进行良好预测的算法时,这意味着该算法绘制了一条使误差平方和最小化的回归线。MSE 是我们的实际值(y 或 f(x))和预测值之间的平方差的平均值。详细的数学证明可以在这里找到

模型 f(x)越复杂,它捕获的数据点就越多,偏差就越低。然而,复杂性将使模型“移动”更多以捕捉数据点,因此其方差将更大。

从抽认卡中可以看出,为了减少偏差,我们必须确保预测的期望值尽可能接近真实值,这意味着我们要增加偏差方程中预测值的平均值。随着预测值平均值的增加,方差公式中第二项的平均预测值也会增加。如果我们增加太多,那么它将远远大于单点的预测值,这将使方差增加更多(高方差)。但是,如果期望值或预测值的平均值增加,使其小于单个点,则方差将在此过程中最小化。因此,当我们调整模型时,我们必须观察它对方差和偏差的影响。
不可约误差作为泛化误差是无法避免的。这是一个来自我们数据集中噪音的错误。然而,在预处理过程中通过有效的数据清理可以减少这种情况。

Graph showing relationship between model complexity and the squared error.

可视化正规化

本节讨论带有随机噪声的模拟正弦数据的图形表示。这将用于测试不同模式的模型选择与正则化。

下图清楚地显示了确保我们在训练样本/数据上获得最佳拟合线的尝试。可以看出,随着模型复杂度随着多项式次数的增加而增加,该模型试图捕获所有数据点,如 20 次多项式所示。作为一个 20 次多项式,该模型已经记忆了数据集,并且由于高方差而过度拟合数据。但是在 2 次多项式中,模型相对于数据有很大的偏差。

多项式次数为 2 时,我们有高偏差,多项式次数为 20 时,我们有高方差和低偏差。我们现在将使用正则化来尝试减少方差,同时将偏差上移一点。所有插图都将形象化。但是,也可以使用定量可视化,如观察特征的均方误差、观察系数和截距。

因此,当我们的模型过度拟合时,正则化可以派上用场,这将在随后的会议中讨论。

Varying polynomial degrees model on on training data

我们如何使用 20 次多项式并防止过度拟合?:正规化

里脊回归

岭回归是一种正则化技术,它使用 L2 正则化对系数的大小施加惩罚。因此,最小化惩罚后的剩余平方和。正则化参数(根据文本使用α或λ)。目标是最大限度地减少:

α控制系数的大小和正则化的量。必须对其进行适当的调整,否则我们旨在使用正则化来校正的过度拟合模型将会变得欠拟合。当λ=1 时,这可以在下图中观察到。

岭回归交叉验证可用于选择最佳λ值,以确保选择最佳模型。

下面可以观察到,仔细选择作为我们的正则化参数的λ可以帮助消除过拟合。

Plots showing the effect of varying lambda on model

套索回归

Lasso 回归使用 L1 正则化技术作为系数大小的惩罚。然而,我们不是使用重量的平方来施加惩罚,而是采用重量的绝对值。目标是最大限度地减少:

Plots showing the effect of varying lambda on lasso regression model

弹性净回归

弹性网络结合岭(L2 作为正则)和套索(L1 作为正则)来训练模型。目标是最大限度地减少:

我们还可以看到,随着λ的增加,系数的损失也增加。这导致最终欠拟合,如λ=1 时所示。

Plots showing the effect of varying lambda on lasso regression model

最终礼物

这篇文章并不详尽,因为关于正则化技术还有很多内容要写。我们可以看看这篇论文中关于机器学习的一些小知识和 scikit 的学习文档其他技术

我们也可以使用交叉验证结合不同的回归技术,旨在正则化我们的模型,以选择正则化参数的最佳值。

我的下一篇与正则化相关的文章将讨论线性回归的前向和后向消除算法的特征选择。敬请关注。

不要忘记分享和一些掌声给更多的人。谢谢你。

我有空 @Holafisayo

Tensorflow 中基于稀疏滤波自动编码器的正则化

原文:https://towardsdatascience.com/regularization-via-sparse-filtering-auto-encoders-in-tensorflow-4880c73fcfd2?source=collection_archive---------6-----------------------

GIF from this website

这个想法在我心中已经存在很长时间了。我们能做什么让神经元有效学习。更具体地说,我们如何在不执行数据扩充的情况下规范网络…..

我认为在机器学习中,一定会有样本偏差,因为我们无法收集世界上所有现有的数据。(人口数据)。并且数据的分布将会不同。(我把增加数据理解为最小化这种差异的一种方法。)但是有没有更好的办法……?

请注意,这个帖子只是为了表达我的创意,当然也是为了好玩。

稀疏滤波介绍和我的天真想法

Illustration of Sparse Filtering From this website

稀疏过滤是一种无监督的学习方法,我们的目标是通过按行和列归一化数据来降低给定数据的维数。上面可以看到稀疏滤波如何修改数据的说明,以防我链接了解释理论概述的论文。

Paper from this website

此外,如果您希望看到 tensorflow 中的实现,请单击此处。稀疏过滤自动编码器背后我简单而天真的想法是这样的。通过更高级特征的聚类,我们的网络将能够区分什么是噪声,什么是我们希望学习的数据。换句话说,正规化。(或者我认为这是在训练过程中注入噪声的一种方式,类似于抖振正则化或者在反向传播中加入梯度噪声。)我想看看这个想法实际上是否有意义。

数据集/训练详情

Image from this website

我希望我们的自动编码器解决的任务是简单的行人分割,我们将使用“ Penn-Fudan 数据库进行行人检测和分割 ”。数据集由 170 幅图像和它们的分割蒙版组成,我想看看当我们有 1:1 比例的训练数据和测试数据时,我们能做多少正则化工作。(每个有 85 张图片。)最后,让我们使用 mall 数据集测试我们模型的性能,可以在这里找到

所有的网络都有相同的历元数、批量大小和学习速率。超参数的细节可以在下面看到。

请注意,在培训期间,我发现将学习率乘以 10 是可以的。此外,我们将使用 Adam Optimizer。

我想提一件事,对于稀疏滤波自动编码器,我们不打算从头到尾训练网络,而是我们打算分割训练过程,其中,对于第一个 200 个时期,我们只打算集中于更高级特征的聚类,然后我们打算在执行端到端训练的同时增加学习率。

结果:纯自动编码器

对于上面的每一幅图像,最左边一列是原始图像,中间一列显示地面真实遮罩值以及重叠在图像上的地面真实遮罩值,最后右边一列图像表示网络生成的遮罩。(而且是叠加版)

我们可以清楚地看到,网络没有在分割行人方面做得很好,生成的掩膜的一些区域模糊不清。

此外,当我们使用纯自动编码器网络从商场数据集中分割人时,我们可以观察到网络认为一切都是行人。(当我叠加生成的分割蒙版时,它看起来就像上面一样。)而且我们可以明确的说网络未能一般化。

结果:带 L1 正则化的纯自动编码器

For each image above, the left most columns are the original image, the middle column shows the ground truth mask values as well as the ground truth mask value overlapped on the image and finally the right column images represents the generated mask by the network. (and it’s overlay-ed version)

当我们添加 l1 正则化时,从网络生成的分割掩模大部分是灰色和白色的,并且它没有清楚地显示分割的外部线。似乎由于正规化,网络很难决定行人的起点和终点。

乍一看购物中心的数据集,它可能看起来像是网络在分割行人方面做了惊人的工作。(它确实很好地勾勒出了行走的人。)然而,仔细观察我们可以发现,与其他商场数据集结果相比,生成的 GIF 更红。这表明生成的分割不具有行走行人的清晰边界线,但从分割的角度来看,它做了一项惊人的工作。

左图 →来自 L1 正则化自动编码器的一帧
右图 →来自稀疏滤波自动编码器的一帧(软赦免激活功能)

作为比较,我们可以看到与其他具有清晰边界线的网络相比,整体红色通道的差异。

结果:采用 L2 正则化的纯自动编码器

For each image above, the left most columns are the original image, the middle column shows the ground truth mask values as well as the ground truth mask value overlapped on the image and finally the right column images represents the generated mask by the network. (and it’s overlay-ed version)

L2 正则化与加入 L1 正则化具有相似的效果,但是生成的分割掩膜具有更清晰的边界线。仍然有一些区域的分割面具是模糊的,以及与黑点混合在一起。

如上所述,当网络通过 L1 正则化器进行正则化时,屏幕没有那么红。并且生成的分割掩膜更加清晰。

结果:稀疏滤波自动编码器(软绝对激活)

For each image above, the left most columns are the original image, the middle column shows the ground truth mask values as well as the ground truth mask value overlapped on the image and finally the right column images represents the generated mask by the network. (and it’s overlay-ed version)

对于稀疏滤波自动编码器,使用软绝对函数作为非线性变换函数。首先,我们可以看到,与 L1 或 L2 正则化网络相比,它有一个清晰的决策线。然而,这种方法也不像上面看到的那样完美。我们可以在生成的掩码中观察到一些漏洞,从那里我们可以得出结论,网络缺乏细节化的能力。(填空)。

网络不可细化可以通过上面的 GIF 进一步证明。与我们上面看到的网络不同,这个网络不能清楚地从每一帧中分割出人,而是以 blob 格式分割。

结果:稀疏滤波自动编码器(ELU 激活)

For each image above, the left most columns are the original image, the middle column shows the ground truth mask values as well as the ground truth mask value overlapped on the image and finally the right column images represents the generated mask by the network. (and it’s overlay-ed version)

对于样本图像,这个网络具有最清晰的轮廓。(我喜欢网络喜欢做自信的决定。)在上面的中间图像中可以看到一个非常令人印象深刻的事实。

红框 →被分割的人那是连在地面上也不真实的分割面具。

如上所述,当我们第一次看到红框区域时,我们可能会认为它是图像中的一个区域,不应该被分割。然而,如果我们看得足够近,我们可以观察到网络注意到另一个人站在角落里,并决定分割该区域。(嗯部分。)

然而,当我们用 ELU()作为激活函数时,网络缺少了一样东西。细节。当我们考虑它时,它确实是有意义的,当执行维数减少时,在负区域中的每个值都被丢弃,因此它只在网络最有信心的区域上执行分割。

撤回

左图 → ELU 激活功能自动编码器
右图 →软绝对激活功能自动编码器

我注意到关于这种方法的一个事实是,它缺乏细节,一般来说,网络似乎知道一个人在图像中的位置,但以 blob 格式。但这也适用于其他网络。

为了比较,我将来自其他网络的分割结果按照纯自动编码器、L1 正则化和 L2 正则化的顺序进行了链接。

交互代码

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

要访问纯自动编码器的代码,请点击这里。
要访问 L1 汽车编码器的代码,请点击此处。
要访问 L2 汽车编码器的代码,请点击此处。
要访问软绝对稀疏自动编码器的代码请点击此处。
要访问 ELU 稀疏自动编码器的代码请点击此处。

遗言

我真的没有看到这种方法的任何实际方面,但它是一个有趣的研究领域(对我个人来说)。).我希望继续这些研究。我在下面收集了一些结果。

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

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

参考

  1. 何时使用 cla(),c. (2018)。什么时候使用 cla()、clf()或 close()来清除 matplotlib 中的绘图?。堆栈溢出。2018 年 7 月 25 日检索,来自https://stack overflow . com/questions/8213522/when-to-use-cla-clf-or-close-for-clearing-a-plot-in-matplotlib
  2. Aubuchon,V. (2018)。2 的幂表——沃恩的总结。Vaughns-1-pagers.com。检索于 2018 年 7 月 25 日,来自https://www.vaughns-1-pagers.com/computer/powers-of-2.htm
  3. tf.tile |张量流。(2018).张量流。检索于 2018 年 7 月 25 日,来自 https://www.tensorflow.org/api_docs/python/tf/tile
  4. [ ICLR 2015 ]追求简单:具有交互码的全卷积网。(2018).走向数据科学。检索于 2018 年 7 月 25 日,来自https://towards data science . com/iclr-2015-力争简单-所有卷积-网络-交互式代码-手册-b4976e206760
  5. [ NIPS 2011 /吴恩达 Tensorflow 中的稀疏滤波与交互式代码第一瞥。(2018).走向数据科学。检索于 2018 年 7 月 25 日,来自https://towards data science . com/nips-2011-Andrew-ng-first-glance-of-sparse-filtering-in-tensor flow-with-interactive-code-659 c4e 84658 e
  6. 谷歌合作实验室。(2018).Colab.research.google.com。检索于 2018 年 7 月 25 日,来自https://colab . research . Google . com/drive/1 JZ 0 jhv 5 ozyzokgihvywy 3j 98 by-uysq 0 # scroll to = c 70 qbz 71 v9 ox
  7. NumPy . dtype—NumPy 1.14 版手册。(2018).Docs.scipy.org。检索于 2018 年 7 月 25 日,来自https://docs . scipy . org/doc/numpy-1 . 14 . 0/reference/generated/numpy . dtype . html
  8. TF . image . resize _ images | tensor flow(2018).张量流。检索于 2018 年 7 月 25 日,来自https://www . tensor flow . org/API _ docs/python/TF/image/resize _ images
  9. TensorFlow,R. (2018)。在 TensorFlow 中调整训练图像的大小。堆栈溢出。检索于 2018 年 7 月 25 日,来自https://stack overflow . com/questions/40299704/resizing-images-for-training-in-tensor flow
  10. float32,T. (2018)。TensorFlow:将 float64 张量转换为 float32。堆栈溢出。检索于 2018 年 7 月 25 日,来自https://stack overflow . com/questions/35725513/tensor flow-cast-a-float 64-tensor-to-float 32
  11. (2018).[在线]可在:https://www . researchgate . net/figure/Illustration-of-Sparse-filtering-Sparse-filtering-is-applied-to-a-random-set-of-data-X _ fig 2 _ 301837553[2018 年 7 月 29 日获取]。
  12. (2018).Arxiv.org。检索于 2018 年 7 月 29 日,来自 https://arxiv.org/pdf/1603.08831.pdf
  13. [ NIPS 2011 /吴恩达 Tensorflow 中稀疏滤波与交互式代码的第一瞥。(2018).走向数据科学。检索于 2018 年 7 月 29 日,来自https://towards data science . com/nips-2011-Andrew-ng-first-glance-of-sparse-filtering-in-tensor flow-with-interactive-code-659 c4e 84658 e
  14. 行人检测数据库。(2018).Cis.upenn.edu。检索于 2018 年 7 月 29 日,来自https://www.cis.upenn.edu/~jshi/ped_html/
  15. 洛伊,C. (2018)。购物中心数据集-人群计数数据集。Personal.ie.cuhk.edu.hk。检索于 2018 年 7 月 29 日,来自http://personal . ie . cuhk . edu . hk/~ cc loy/downloads _ mall _ dataset . html
  16. 张量流正则化。(2018).ritchieng . github . io . 2018 年 7 月 30 日检索,来自https://www . ritchieng . com/machine-learning/deep-learning/tensor flow/regulation/
  17. Matplotlib 图:移除轴,l. (2018)。Matplotlib 绘图:删除轴、图例和空白。堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/9295026/matplotlib-plots-removed-axis-legends-and-white-spaces
  18. 情节,一.(2018)。散点图中的单个 alpha 值。堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/24767355/individual-alpha-values-in-scatter-plot
  19. https://stack overflow . com/questions/332289/how-do-you-change-the-size-of-figures-drawn with-matplotlib?,H. (2018)。如何改变用 matplotlib 绘制的图形的大小?。堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/332289/how-do-you-change-the-size-of-figures-drawn-with-matplotlib
  20. https://stack overflow . com/questions/9295026/Matplotlib-plots-remove-axis-legends-and-white-Matplotlibplots:remove axis,l. (2018)。Matplotlib 绘图:删除轴、图例和空白。堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/9295026/matplotlib-plots-removed-axis-legends-and-white-spaces
  21. matplotlib,O. (2018)。用 numpy 和 matplotlib 覆盖图像分割。堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/31877353/overlay-an-image-segmentation-with-numpy-and-matplotlib
  22. [复本],H. (2018)。如何用 python 把图像做成电影?堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/44947505/how-to-make-a-movie-out-of-images-in-python
  23. 函数,H. (2018)。如何在张量流误差函数中加入 L1 正则化?堆栈溢出。检索于 2018 年 7 月 30 日,来自https://stack overflow . com/questions/36706379/how-to-exact-add-L1-regularization-to-tensor flow-error-function
  24. 阿什温诉弗吉尼亚州(2015 年)。如何在 Python 中自然排序?编码纱线👨‍💻。检索于 2018 年 7 月 30 日,来自https://code yarns . com/2015/01/23/how-to-natural-sort-in-python/
  25. OpenCV:视频入门。(2018).Docs.opencv.org。检索于 2018 年 7 月 30 日,来自https://docs . opencv . org/3 . 1 . 0/DD/d43/tutorial _ py _ video _ display . html
  26. Gastaldi,X. (2017)。抖抖正则化。Arxiv.org。检索于 2018 年 7 月 30 日,来自 https://arxiv.org/abs/1705.07485
  27. Only Numpy:实现“添加梯度噪声改善非常深度网络的学习”来自…(2018).成为人类:人工智能杂志。检索于 2018 年 7 月 30 日,来自https://becoming human . ai/only-numpy-implementing-adding-gradient-noise-improves-learning-for-very-deep-networks-with-ADF 23067 F9 f1

强化学习 101

原文:https://towardsdatascience.com/reinforcement-learning-101-e24b50e1d292?source=collection_archive---------0-----------------------

学习强化学习的要领!

Photo by Daniel Cheung on Unsplash

强化学习(RL)是现代人工智能领域最热门的研究课题之一,其受欢迎程度还在不断增长。让我们看看开始学习 RL 需要知道的 5 件有用的事情。

1。什么是强化学习? 与其他 ML 技术相比如何?

强化学习(RL)是一种机器学习技术,它使代理能够在交互式环境中使用来自其自身行为和经验的反馈通过试错来学习。

虽然监督学习和强化学习都使用输入和输出之间的映射,但与监督学习不同,监督学习向代理提供的反馈是执行任务的正确的动作集,强化学习使用奖励和惩罚作为积极和消极行为的信号。

与无监督学习相比,强化学习在目标方面是不同的。虽然无监督学习的目标是找到数据点之间的相似性和差异,但在强化学习的情况下,目标是找到一个合适的动作模型,使代理的总累积报酬最大化。下图显示了通用 RL 模型的行动奖励反馈回路

2。如何公式化一个基本的强化学习问题?

描述 RL 问题基本要素的一些关键术语是:

  1. 环境— 代理运行的物理世界
  2. 状态— 代理人的现状
  3. 奖励— 环境的反馈
  4. 策略— 将代理的状态映射到动作的方法
  5. 价值— 代理在特定状态下采取行动将获得的未来回报

一个 RL 的问题可以通过游戏得到最好的解释。就拿 吃豆人 这个游戏来说,代理人(吃豆人)的目标是吃掉格子里的食物,同时避开途中的鬼魂。在这种情况下,网格世界是代理的交互环境。代理人会因为吃了食物而得到奖励,如果被鬼魂杀死(输掉游戏)则会受到惩罚。状态是代理在网格世界中的位置,总的累积奖励是代理赢得游戏。

为了建立一个最优策略,代理人面临着探索新状态,同时最大化其整体报酬的困境。这就是所谓的勘探与开发权衡。为了平衡这两者,最好的整体策略可能需要短期的牺牲。因此,代理应该收集足够的信息,以便在未来做出最佳的整体决策。

马尔可夫决策过程【MDPs】是描述 RL 中环境的数学框架,几乎所有的 RL 问题都可以用 MDPs 来公式化。一个 MDP 由一组有限的环境状态 S,一组在每个状态下的可能动作 A(s),一个实值奖励函数 R(s)和一个转移模型 P(s ',s | a)组成。然而,真实世界的环境更可能缺乏任何关于环境动态的先验知识。在这种情况下,无模型 RL 方法就派上了用场。

Q-learning是一种常用的无模型方法,可用于构建自玩 PacMan 代理。它围绕着更新 Q 值的概念,Q 值表示在状态 s 中执行动作 a 的值。下面的值更新规则是 Q 学习算法的核心。

这里有一个使用深度强化学习的 PacMan 代理的视频演示。

3。最常用的强化学习算法有哪些?

Q-learningSARSA (状态-动作-奖励-状态-动作)是两种常用的无模型 RL 算法。它们的勘探战略不同,但开发战略相似。Q-learning 是一种非策略方法,其中代理基于从另一个策略导出的动作 a来学习值,而 SARSA 是一种策略方法,其中它基于从其当前策略导出的当前动作 a 来学习值。这两种方法实现起来很简单,但是缺乏通用性,因为它们不具备估计未知状态值的能力。*

这可以通过更高级的算法来克服,例如使用神经网络来估计 Q 值的 深度 Q 网络(DQNs) 。但是 dqn 只能处理离散的、低维的动作空间。

【DDPG】深度确定性策略梯度是一种无模型、非策略、行动者-批评家算法,通过在高维、连续的动作空间中学习策略来解决这个问题。下图是演员兼评论家建筑的代表。

4。强化学习有哪些实际应用?

由于 RL 需要大量数据,因此它最适用于模拟数据容易获得的领域,如游戏、机器人。

  1. RL 在构建用于玩电脑游戏的 AI 方面应用相当广泛。 AlphaGo Zero 是第一个在中国古代围棋比赛中击败世界冠军的计算机程序。其他包括雅达利游戏,西洋双陆棋等
  2. 在机器人和工业自动化中,RL 用于使机器人能够为自己创建一个高效的自适应控制系统,该系统从自己的经验和行为中学习。 DeepMind 的工作关于利用异步策略** 更新进行机器人操作的深度强化学习就是一个很好的例子。观看这个有趣的演示视频。**

RL 的其他应用包括抽象文本摘要引擎、可以从用户交互中学习并随时间改进的对话代理(文本、语音)、学习医疗保健中的最佳治疗策略以及用于在线股票交易的基于 RL 的代理。

5。强化学习怎么入门?

为了理解 RL 的基本概念,可以参考以下资源。

  1. ****强化学习——一本介绍的书,作者是强化学习之父——理查德·萨顿 和他的博士生导师 安德鲁·巴尔托 。这本书的在线草稿可以在这里找到。
  2. 教材 来自大卫·西尔弗包括视频讲座是一门很棒的 RL 入门课程。
  3. 下面是另一个关于 RL 的 技术教程 ,作者是彼得·阿比尔约翰·舒尔曼(开放人工智能/伯克利人工智能研究实验室)。

对于开始构建和测试 RL 代理,以下资源可能会有所帮助。

  1. 这篇博客 讲述了 Andrej Karpathy如何利用原始像素的策略梯度来训练神经网络 ATARI Pong 智能体将帮助您在仅 130 行 Python 代码中建立并运行您的第一个深度强化学习智能体。
  2. DeepMind Lab 是一个开源的 3D 类游戏平台,为基于智能体的人工智能研究创建了丰富的模拟环境。
  3. 项目马尔默 是另一个支持人工智能基础研究的人工智能实验平台。
  4. OpenAI gym 是一个构建和比较强化学习算法的工具包。

如何产生更多的销售线索并降低成本?A/B 测试 vs 强化学习。

原文:https://towardsdatascience.com/reinforcement-learning-64730aaa46c9?source=collection_archive---------12-----------------------

你会发现进入机器学习世界的迷人而直观的旅程,其中有有趣的实验和非常有用的结论。

营销人员经常使用 A/B 测试——一种比较产品的两个或更多版本(广告、设计、登陆页面等)的技术。)来评估它们中的哪一个更好地执行其功能。但是你想知道如何达到同样的目标,得到好得多的结果,降低成本吗?在这篇文章中,我将告诉你强化学习。

下面您将了解到:

  • A/B 测试最大的问题是什么,如何解决
  • 机器如何学习
  • 如何在强化学习的帮助下优化几乎任何网络产品
  • 简单而强大的置信上限算法
  • 如何实际实现置信上限算法(以 Node.js 为例)

市场营销中的多臂强盗问题

在概率论中,有所谓的多臂土匪问题。让我们以登录页面为例深入探讨这个问题。

假设你有 5 个版本的登陆页面。众所周知,在最初几秒钟内保持网站用户的注意力是非常重要的。但是如何选择最能应对这种情况的版本呢?

第一个(也是不好的)解决方案是 A/B 测试。我们可以向用户展示我们的登陆页面的随机版本,并根据大量访问的结果,确定哪个版本的性能更好。

你为什么不应该这样做?

  1. 你将花费金钱和时间来推广你网站的“坏”版本
  2. 你的企业服务的潜在客户可能会离开,因为他们对你的登录页面的“坏”版本
  3. 结果你得到的统计数据没什么用,因为大多数用户已经看过你的登陆页面了

如果机器本身能够决定你的登陆页面哪个版本效果最好,那该多好啊……而且是有可能的!

机器如何学习

因此,强化学习是一种机器学习,机器通过试错来学习如何达到目标。每一个动作机器都会获得一份奖励。机器的主要目标是报酬最大化。在我看来,它是最有趣的机器学习类型。它用于训练机器人行走,以及训练无人机自主飞行。使用这种算法的最有趣的例子可以在这个视频中看到。

我给你看一个简单但非常有效的强化学习算法——置信上限。

置信上限

好,假设我们的登录页面有以下选项:

  1. 糟糕透了。10%的用户将成为客户
  2. 不好。20%的用户将成为客户
  3. 中等。30%的用户将成为客户
  4. 很好。40%的用户将成为客户
  5. 太好了。50%的用户将成为客户

Landing Pages

一开始,我们不知道哪个版本更好,哪个版本更差。我们的任务是让机器解决这个问题。

我们开始吧!

啊,不对,先表示一件事……注意这个方案。这对我们将来会有用的。

我们终于开始了!

第一步

现在我们登陆页的每个版本都有“平权”。我的意思是,它有相等的估计平均回报和相同的范围,我们将搜索实际的平均回报。让我们向用户展示一次网站的每个版本。

发生了什么事?

访问了我们登录页面第一版的客户还没有成为客户。对于这个选项,机器的回报是 0。这个选项的估计平均回报变低了,我们搜索实际平均回报的范围也缩小了。

同样的事情也发生在第二版和第四版上。

选项#3 和选项#5 会出现相反的情况。访问过这些版本的登录页面的客户已经成为客户。对于这些选择,机器的回报是 1。这些选项的估计平均回报已经变得更大,我们搜索实际平均回报的范围已经缩小。

步骤 2+

厉害!现在让我们看看我们的范围的上限。第三个和第五个选项具有最大的上限。因此,现在他们是我们的最佳登陆页面的主要候选人。

新访问者已经看到了站点版本#3。他也没有成为我们的客户。但是来到 5 号站点的访问者变成了买家!我们登陆页面的哪个版本是领导?是的,5 号。我想你已经明白了主要意思。

让我们看看整个过程。

当然,这个过程被大大加速了,但是我认为这个想法是明确的。通过反复试验,机器本身找到了我们网站的最佳版本,并越来越准确地向用户展示它。

如何计算置信上限?

公式如下:

其中:

  • n 是访客总数;
  • N i ( n )是登陆页面 i 展现给访问者 n 的次数;
  • R i ( n )是登陆页面 i 到访客n的奖励总和

一切都比看起来简单得多。使用 UCB,你不需要深入研究数学。

实验时间到了!

我使用 Node.js 和 Firebase 创建了一个工作示例。我绝对不想让你厌烦阅读代码,所以那些感兴趣的人可以在这里看到它。

现在让我们把注意力集中在结果上。在对我们的登录页面进行了 540 次访问后,我们看到了下图:

我们可以肯定,机器处理了任务,并找到了我们的登录页面的最佳版本。 277/540 用户已经看到登陆页面# 5。

228/540 游客变成了顾客!为了进行比较,我随机选择了登陆页面版本(就像 A / B 测试一样)来模拟这种情况,只有 148/540 访问者成为了客户。

恭喜你!我们刚刚将付费用户的数量增加了 1.5 倍。

结论

我相信你毫不怀疑强化学习可以给几乎任何网络产品带来巨大的价值。重要的是,它实现起来非常简单。

如果你还有问题,请在评论中提问,我很乐意回答。

强化学习。

原文:https://towardsdatascience.com/reinforcement-learning-79ffd92886a7?source=collection_archive---------5-----------------------

我们人类从日常活动中学到了很多东西。我们观察我们的环境,采取一些行动,看看我们的行动如何影响我们的环境,并采取我们的下一步行动。强化学习类似于系统建模或编写计算机程序,其中系统看到或观察其环境,并采取一些行动来实现某些目标。

在这个博客中,我们将从零开始,学习蒙特卡罗估计方法,并训练一个代理来实现一个目标。特别是,我们将学习训练一个代理来平衡一个推车杆!!我们还将学习如何将方程式转换成代码,并亲眼看看它是如何工作的。

Pushing cart towards left.

pushing cart towards right.

Trained agent taking correct decions.

萨顿的经典教科书和大卫·西尔弗的 T2 讲座是详细理解主题的最佳途径,但是如果他/她应用这些概念,建立一些东西并看到它为自己工作,他/她会学得更好,这也是这篇博客的主要动机。如果你看过他的讲座,这个博客会非常有用,但如果没有,不要担心,我已经尽力用简单的方式解释了这些概念。

我们将以经典的推车杆子游戏环境为例,通过它学习强化学习(RL)。在 RL 设置中,我们将试图学习的东西称为代理。在这篇博客中,我将交替使用代理/我们。例如,在动物中,大脑是一种媒介。在计算机中,你的 RL 代码是一个代理。人类进化得如此复杂,以至于即使是我们最顶尖的研究人员也不知道它是如何学习一切的。当人们说人工智能的时候,你需要意识到它不是什么超级有意识的东西,它能够像人类一样学习一切,交流和行动!!这只是一个如预期运行的代码。神经网络只是其中很小的一部分,重要的是你的设计系统如何使用这些网络。类似地,我们的 RL 程序只能学习我们要编程做的事情。

RL Setup

在典型的 RL 设置中,我们的代理通过在时间 t 采取一些动作(在的)来与环境交互。代理采取的动作也通过修改环境改变了环境,或者如果代理移动了,那么它的摄像机/传感器视角将会改变,所以代理将会看到新的状态( St+1 )。就像我们一样,你看到一些东西,闭上眼睛向前迈一步,然后你会发现你所看到的和你之前看到的有些不同。如果智能体的行为是好的,环境会给予奖励( Rt+1 )。使用这些奖励代理将学到一些东西,看到这个新的国家代理将采取新的行动。而且还在继续。让我们通过例子来理解这一点,首先让我们设置我们的环境。

设置

OpenAI 通过他们的 OpenAI 健身房提供 RL 环境。看一看。我们将使用 Cartpole 环境。这里是设置您的环境的链接。一旦你安装好了,试一下这段代码。

你会看到一个车杆游戏环境将显示,并按照代码。我们将随机抽样一个动作( 0 或 1 ) 0 表示左,1 表示右,我们通过调用 env.step 来采取该动作,然后我们得到采取该动作的结果。结果将是新的状态,奖励,终端,信息。终端指示游戏是否已经结束(如果游戏结束,则为真)。现在,如果您打印 new_state 值,您将会看到类似于[28.53394423 4.91374739-43.098292439-9.这是一个 1×4 的向量。这个向量中的每一个值都代表一个类似角度的东西,或者是从中心移动的距离。这个向量中的每个唯一的数字代表那个推车杆子的唯一的状态。现在,我们的目标是利用这些向量,通过决策而不是随机行动来选择行动,并查看我们的行动如何使车杆移动。如果这些值中的一个变得极端,比如只采取向左的动作(向左推),将导致新的状态向左移动,如果购物车越过某个阈值,游戏将结束。类似地,如果杆子掉下来或形成极端角度,游戏结束。在每个时间步,我们/代理都有两种可能的操作(向左推或向右推)。我们需要观察我们的推车杆子是如何移动的,并调整我们的动作,使杆子停留在同一个地方。这是你只向左推时的样子。

Pushing cart to left.

状态

状态可以是描述代理当前状况的任何东西。例如,让我们说你正在玩玉米迷宫游戏。如果将位置视为州,什么参数可以唯一地描述您的位置?我们可以选择人的纬度,经度和方向作为状态,我们可以用向量数组[37.338,-121.88,0.234]来表示它们,或者让我们说你正在教机器人移动,然后我们可以考虑像传感器读数,它的摄像头,位置等作为状态表示。显然传感器越多,我们就能越独特地识别它的状态。

目标

如果你考虑任何动物,它做的每一件事,都是为了最大化某样东西。比如你为了考试努力学习,让成绩最大化。在这种情况下,你的学校、班级、家庭、考试都是环境的一部分。你采取行动学习,环境根据成绩给你奖励。如果你成绩不好,你会努力学习,这样下次考试你就能提高成绩。最终,你试图最大化你的成绩。请注意,你不会一学习就立即获得奖励,但奖励会延迟。所以当我们说我们得到了奖励时,我们需要考虑从你的学习时间到考试时间到结果日的所有事情。让我们在下一节量化这个目标和奖励。

在手推车杆的情况下,平衡杆是我们的目标

initial agen`t effort

Goal achieved

奖励

在代码中,如果你打印奖励值,你会看到它的 1。实际上,你可以定义你想要的任何奖励,但让我们理解这个术语叫做贴现回报

每当你处于一种状态时,你采取一个行动,你就会得到一些奖励(比如说 1)。在游戏设置中,如果你一直向左推手推车,你会看到有东西向右移动,杆子倒了(试试看)。

根据代码,您只需向左/向右推,每次设置时,您将获得 1 的奖励,在某个点上,极点会高于/低于阈值,游戏结束。那么,我们得到的总回报是多少呢?

我们说 t=1 时的总收益是 8。类似地,如果你想计算 t3 时刻的回报。只需添加从时间步长 t3 开始的所有返回。你可以这样想。从游戏第 1 帧的回报是游戏结束前所有奖励的总和。游戏框架 4 的回报(time_step = 4)是游戏框架 4 上所有奖励的总和。或者一般来说,如果一个博弈在时间步长 tn 结束,你想从时间步长 t 开始计算收益。我们可以这样表示。

现在有一个问题。有些环境,比如这个横竿,是终结性的,也就是说,在某个时刻游戏结束了(如果你采取了错误的行动)。然而,有些环境可能没有终点,比如说你正在教一个代理阅读英语,这里没有有限的终点。我们需要将我们的回报推广到所有代理商。概括来说,我们添加额外的终端状态,称为 ST 。终结状态的特殊属性是它永不结束的 ie。如果您进入终端状态,我们将返回到相同的终端状态。同样进入终极状态会给你 0 奖励。现在不要担心终端状态,你最终会明白的。但是,现在稍微修改一下,我们可以把方程写成。

其中 t 从 0 到无穷大。如果你注意到 Gt 的值没有改变,因为在终端状态我们得到 0 奖励。即使我们向无穷大求和。

现在还有一个关于非终态环境的问题。就像那个英语阅读问题,我们可以看到,如果我们不断增加奖励,GT 值就会爆炸。此外,对于在时间 t 采取的行动,我们在下一个时间步骤获得的奖励(即时奖励)很重要,而从下一个时间步骤获得的奖励(延迟奖励)很不重要,等等。概括来说,我们引入了折扣奖励。在某些情况下,只有在你实现了某些目标之后,奖励才会到来。因此,我们需要在设计我们的系统时牢记这些事情。因此,给这些奖励增加权重是一个开始。ie 奖励在每一个时间步会被一些伽玛因子打折。现在我们可以想象所有这些。

state to state transitions with rewards and terminal state.

Discounted return

在一些初始状态下,我们采取一些行动,我们得到回报 R1,然后我们的新状态是 S1,我们采取一些行动,我们得到回报 R2,等等。在 S2,我们/代理人做了一些不好的行为,把我们/代理人推到了某种终结状态,因此从那时起,我们得到的奖励为 0。

现在,为了计算回报 Gt,我们采用下一个奖励(即时奖励)并通过用 gamma 对所有其他奖励进行贴现来添加所有其他奖励。典型地,我们保留 1 作为正奖励,对于终止前的最后一个状态,我们给出负奖励,因为在那个状态中,我们的代理采取了不好的行动,并以终止状态结束。

让我们运行一个简单的代码来看看它的作用。

Total returns for different states in an episode.

浏览代码,看看状态是如何转换的。在时间步骤 1,我们处于初始状态。我们果断地采取了行动 1,结果我们进入了新的状态。从那个状态我们再次确定性地采取行动 1,以此类推。在时间步骤 t=11 时,我们处于状态[ 0.15274551,1.70880722,-0.17696351,-2.69724965]并采取行动 1,我们到达最后状态[ 0.18692165,1.90472068,-0.2309085,-3.03828657]。尽管 reward 显示 1,但在计算回报时,我们会将其设置为-10。之后我们可以用 0.9 的折现率来计算回报

注意这里重要的一点,为了计算一个州的回报,我们必须等到游戏结束。我们可以将一场比赛作为一集来运行。如果我们运行两个游戏,我们可以说我们运行了两集。在文学作品中,它通常被称为展开。

让我们稍微修改一下代码,看看 10 个不同情节的第一个状态和最后一个状态的返回结果。注意每集的长度是如何变化的!!这就是我们用终端状态,导出一般返回函数 Gt 的原因。不管每集的长度如何,我们可以从时间 sigma 到无穷大,因为最终状态的回报为零,所以我们的回报在每集中都是一致的。这里是 10 个不同剧集的状态 s1 和 st(最后一个状态)的总回报计算代码。

Total returns for state s1 and st(last state) for 10 different episodes.

马尔可夫性质和马尔可夫决策过程。

到目前为止,我们已经确定地选择了单个动作(左/右)。我们没有考虑任何直观的方式来决定采取哪些行动。在我们能够跳到决策之前,我们需要知道整个状态动作转换是如何发生的。在现实世界中,宇宙决定了转变应该如何发生。例如,如果你制作一架纸飞机,并将其射向目标,即使你的目标是完美的,风、湿度、摩擦等宇宙因素将决定你的飞机是否应该击中目标。

Finite MDP

横竿是一个简单的环境。让我们考虑一个通用环境。假设这个环境只有 3 个状态,在每个状态下你可以采取行动 a0 或 a1。在现实世界中,一切都是随机发生的,也就是说,假设你处于状态 S0,那么有 30%的几率你会采取行动 a0,有 70%的几率你会采取行动 a1。假设你选择了 ao 行动,那么可能有 50%的机会你可以转到 S2,或者可能你会回到同一个州,任何事情都可能发生!!。上面提供的例子是有限 MDP,因为有有限数量的状态,即 3.在 cartpole 的情况下,可以有任何数量的状态,所以我们可以使用所谓的棒图和贝尔曼方程来捕捉它们。在每一个状态中,环境控制着你如何过渡到下一个状态。给定一个状态,每个行为都会有一些概率,我们知道只有在我们采取行动后,我们才会得到回报。

我们应该知道如何将信息编码到每个状态,这样当我们处于特定状态时,我们就可以看到采取这些行动的可能性和价值。如果状态能保持这样的值,它们被称为具有马尔可夫性。一旦我们到达本博客中关于状态值 V(s)和 Q 值 Q(s,a)的部分,你将更好地理解每个状态如何保持值,并且我们可以使用马尔可夫决策过程来采取正确的行动。在我们开始寻找这些状态的值之前,让我们给这些概率项取一些名字。

政策

在一个给定的状态下,将会有与支配我们的代理行为的每个动作相关的概率。例如,如果机器人是一个代理人,比方说在一个特定的状态(山顶)有大风吹,有时把机器人推到悬崖,那么机器人应该避免去那个状态。机器人可以通过减少与导致该状态的那些动作相关联的概率来避免该状态。

政策只不过是在给定状态下采取行动的概率。

pi 是概率,a 是动作,|是给定的,s 是状态。

跃迁概率

如果你处于一种状态,你会采取特定的行动。那么你可能会在任何一个州结束。如果你的环境有 n 种状态,那么每种状态都有一定的关联概率,假设你处于这种状态并采取了某种行动。

转移概率就是从一个给定的状态转移到另一个状态,采取某种行动,我们在上面讨论过,宇宙编码了这些概率,我们需要恢复它。

p 是概率,St+1 是下一个状态,St 是你当前的状态,At 是你采取的行动。从 St 状态到 St+1 状态的概率。

前方数学!!😃

过渡棒图。

State Transitions.

从简笔画中可以很容易地推断出,开始时我们处于这样的状态。在这种状态下,我们可以选择采取 n+1 个行动。我们随机决定采取行动。在采取行动后,现在的环境可能会把我们推回到索州、S1 和其他州。因为我们有这么多的行动要做,我们可能会在任何状态下结束,让我们把概率和它们联系起来。

State Transitions with probabilities over state and action space.

让我们浏览一下这个图表。最初,代理/我们处于状态,因此,在该状态下,我们可以从动作空间 A 中选择 n+1 个动作:{A0,A1,A2…An,An+1} 对于这些动作中的每一个,都有选择它的概率,这定义了代理的行为。一个好的代理将有很高的概率选择正确的行动。Medium 不允许我使用数学符号来表示 PI ,所以我将使用 PI 。PI(At|St) 代表在给定的 St 状态下选择行动的概率,这是我们的策略。

注意,代理选择的动作取决于它所处的状态。就像你一样!!你开车的速度(动作=踩油门?)是以你的妈妈/爸爸在车上是否坐在你旁边为条件的(St =妈妈,爸爸)!!

猜测..PI(动作=按压气体?| St =闺蜜)?😃

好了,现在我们的环境是随机的(“风可能会把我们吹到任何地方”),所以我们的代理有可能最终处于状态 S0,S1..序列号。这些状态来自状态空间 S:{S0,S1,S2…Sn} 。我们可以把它写成 Pr(St+1| St,At) ,这意味着概率代理可能结束于状态 St+1,假设它处于状态 St 并在采取行动。如果代理最终处于正确的状态,它将获得好的奖励(正奖励),如果它最终处于坏的状态,它将获得坏的奖励(负奖励)。因此,代理人的回报取决于它最终所处的状态,所以我们可以将概率放在 Pr(Rt+1| St,at,St+1)上,这意味着代理人将获得回报 Rt+1 的概率,假设我们处于状态 St,在状态 St+1 采取行动并着陆。

状态值 V(s)

假设我们有一个机器人代理,它处于状态 S0 。如果它采取行动 A0 它会在火坑结束,这是不好的,如果它采取行动 A1 它会送上平坦的道路,这是好的。现在,我们需要从数学上量化好/坏意味着什么。在另一个世界中,我们需要估计这些状态的值。我们可以使用贝尔曼方程来估算价值。

贝尔曼方程是一个动态规划方程。为了理解它,假设我们已经估计了状态 S0 的某个值,下次我们访问相同的状态时,因此我们可以使用旧的估计值,计算新的估计值并更新该相同状态的值。下次你访问同一个州时,你会有一个更好的估计。

我们可以做的一件事就是简单地建立一个字典,用 states 作为键,state-values 作为值。我们可以用总收益作为这个状态的值。但是,如果您查看标题为“10 个不同剧集的状态 s1 和 st(最后一个状态)的总回报”的代码贴在上面,我们可以看到 S1 州的回报不断变化,每集我们可以有任何数量的州。我们可以对一个特定的州的总收益进行简单的平均,这将是一个开始估算的好方法。

所以,我们将上面代码运行几集,比如 10 集,然后我们将它平均。现在,让我们想想如何才能做到这一点?我们可以保留一个计数器。我们将运行 10 集,每次我们访问一个特定的州,我们可以更新该州的计数器。在所有状态的 10 集之后,我们可以对它们进行总结和更新。

请注意,当我们说相同状态时,请记住所有值必须相同。例如,如果在剧集中,第一个游戏帧是状态 S0:[1.1,1.2,1.3,1.4],而在第二集中,第一个游戏帧是状态 S0:[0.1,0.1,1.1,0.4],那么它们都不表示相同的状态。如果在第二集第五个游戏帧是状态 S5:[1.1,1.2,1.3,1.4],那么它们都表示相同的状态。

下面是一个简单的代码

蒙特卡洛学习

这种估算状态值的方法,我们从头到尾运行一集。收集所有州的回报,并运行许多这样的插曲。最后停止运行游戏,并通过取收集状态值的平均值来更新状态值。这可能是游戏情节。

第 0 集:S00-> S01-> S02-> Sot

第一集:S10 -> S11 -> S12->S1t

第二集:S20 ->S2t

第 N 集:Sn0-> Sn1-> Sn2-> Sn3-> Sn4-> Snt

这里没有什么需要注意的。S10 表示第 1 集的状态 0,类似地,S01 表示第 0 集的状态 1。

S00 S10 可能不相同!!可能是 S01 和 S12 相同的状态!!

在一个随机环境中,转变到由 Pr(St+1|St,At)决定的状态,正如我们之前看到的。

假设 S10 和 S12 都是相同的状态,我们称之为 Sb。让我们初步估计 sb ti 的值为 0.1 ie。V(sb) = 0.1。经过两集 0,1,我们知道真实的回报 Gt(S10)和 Gt(S12)让我们说它是 0.2 和 0.3,然后我们可以保持一个计数器,并更新它 N(sb) += 1,所以它将是 2。为了估计新值,将状态 Gt(S10)+G(S12)的所有返回相加,并计算平均值 Gt(S10)+G(S12)/N(sb ),这就是新的估计值。

因此,我们可以更新 V(sb) ← Gt(S10)+G(S12)/N(sb),其中 S10 和 S12 表示不同剧集中的相同状态。如果在一个状态 ie 中不增加计数器。如果你在一集内访问同一个州,并且没有更新计数器,那么首先访问蒙特卡洛。如果你每次访问一个州就增加一个计数器,那么它就叫做每次访问蒙特卡洛

现在我们看到一个小问题。为了更新 V(s ),我们必须运行 n 集,然后停止运行,计算平均值,然后更新 V(s ),然后我们继续做同样的事情。能找到解决办法吗?我们可以在移动中进行批量更新,而不是停下来进行批量更新吗?让我们做一个简单的推导。我们知道 V(s)是我们运行一集时的估计状态值,在我们运行该集后,我们知道该状态的真实回报,即。燃气轮机。所以,Gt(s)-V(s)是我们在估计状态值时产生的误差。

让我们的初始状态估计为 V(s)。在我们运行 k 数之后,如果 N(s)k 集代表我们访问状态 s 的次数,我们知道状态 V(s)k 的值是总收益的平均值,直到 N(s)k 集的 k 集。

我们可以将适马拆分为当前真实回报+所有先前回报的总和。我们知道在 k-1 第五集,k-1 一定是收益的平均值。因此

我们可以用 V(S)k-1 中的 N(S)k-1 代替 V(S)k 中的 sigma 项,N(S)k-1 为(N(S)k)-1。因此

重新安排

我们可以用 N(s)来计算所有状态的出现次数,或者我们可以放松,只考虑一小部分事件,这样我们就可以摆脱计数器。让我们用阿尔法修正它。

现在我们有一个蒙特卡洛更新。这就是说,每次你访问一个州,你可以得到我们到目前为止对该州所做的估计,在剧集结束后,我们可以得到该州的真实回报,我们发现我们犯的错误,并在错误的方向上更新我们的旧估计。所以下次我们访问同一个州时,我们会有更好的估计。

注意,要更新,我们仍然需要运行完整的剧集,但是要更新值,我们不需要停下来批量更新,但是我们可以在每集之后更新。但是,我们仍然必须运行一个完整的插曲来计算总回报,这个问题可以通过时间差异学习来解决,我们稍后将访问。

数学够了让我们编码吧!!

但是等等,我们如何存储状态值呢?以前我说过我们可以用一些字典把状态作为键,把它的值作为状态值,但是状态可以有这么多!!让我们用一个近似为 0r 的函数。

函数逼近器以数组向量为输入,乘以权重,结果就是近似值。当然,最初的值会是错误的,但是因为我们知道它的真实值,我们可以找到错误并改变权重。该函数逼近器可以是神经网络或简单的乘法运算。

从我们之前的代码中选择一个状态 s =[-0.02553977,-0.5716606,0.03765532,0.90520343],选择随机权重 w = [0.1,0.21,0.14,0.18],然后 V(s)=-0.02553977 * 0.1+-0.5716606 * 0.21+0.03777 其中 0.3 是偏置项。

所以 V(s)是 0.3456056592。但是如果真实返回 Gt(S)是 0.234,那么这个状态的真实值应该是

0.345605659+0.9 *[0.234–0.3456056592]即 0.24516056572。但是我们的估算者预测它是 0.345605659,所以它产生的误差是-0.10044。现在我们只需要相应地改变权重来做出正确的预测。我不会详细讲述如何改变权重,因为这是一个单独的主题,但我们将使用 python 包来完成(我们将使用 Tensorflow)

第一个数组表示状态,第二个数组表示函数近似值。现在我们知道了真实的回报,所以让我们来计算这些州的真实价值估计。

期望值

之前我们已经看过这个图表,现在让我们从状态值的角度来看,看看我们要考虑的状态值到底是多少。众所周知,我们的环境是随机的。我们的政策决定我们选择什么样的行动,我们的环境决定我们应该降落在什么样的状态,我们有可能捕捉到它们。让我们写出方程来捕捉它们。我在这里想说的是,我们估计的值不是真实的估计值。理想情况下,如果你认为宇宙是真实的,那么每个状态都有一些真实的宇宙编码状态值!!我们的模型通过探索和更新其状态值视图来预测该状态值可能是什么。当我们的状态值等于宇宙编码的状态值时,我们的模型将收敛到真正的理想状态值。我们不知道真正的理想状态值是什么,但是利用这个图表,我们可以得出一个数学方程。

在策略 pi 下,假设您的策略是始终采取左操作(向左推)。假设你处于状态 S0 ,那么你可以从该状态 S0 采取所有行动。我们考虑行动的概率 pi(a|s) ,对于所有这些行动,你可以降落在由宇宙概率 p(s'|s,a) 控制的任何状态,我们添加下一个状态的即时奖励和贴现值。这意味着我们的行为会影响我们的价值评估。

对于具有 Q 值 Q(S,A)的动作的判定

到目前为止,我们已经估计了状态 V(S)的值。在前面的代码中,你可能已经注意到,我们看到了我们的函数逼近状态的近似值,我们也计算了状态的真实值。我们可以计算它们之间的误差,并更新我们的权重,以预测良好的估计,但如果你想一想,即使你准确地估计了状态值,如果你在一个状态中,你无法知道下一个状态的值会是什么。如果你处于 S0 状态,如果某个先知告诉你,你的下一个状态将是 Sa 或 Sc,而绝对不是 Sb,那么我们可以只计算 V(Sa),V(Sc ),并朝着最大值采取行动,但我们没有这样神奇的先知。所以我们需要计算一些联系。如果你可以计算采取行动的价值,那么我们就可以预测好的行动。也就是说,嘿,我在这个州,上次我在这个州,我采取了这个行动,一些不好的事情发生了,所以我会避免它。如果我采取另一个动作,我会得到这个预测值。就像我们如何估计状态的值一样,我们可以估计在给定状态下采取行动的值,这些值是 Q 值 Q(S,A)。现在 Q 值很相似。

在这里,如果我们在状态 S,采取了一个动作 a,那么从那个状态我们可以到达由 P(s'|s,a)控制的 m 个状态中的任何一个,然后我们可以在策略 pi 下取这些状态的值。

现在在我们的代码中,就像我们如何估算 V(s)一样

我们可以估计 Q(S,A)

当我们随着时间探索所有状态时,我们采取状态-动作的估计值将收敛到宇宙编码的状态-动作值。

现在我想对政策做一些改变,这样我们就能确保探索所有可能的状态,我们还需要确保达到目标(最大化总回报),我们可以做这些事情。

  1. 我们将对一个状态中的所有行为进行估计,然后选择给出最大值的行为。这是一个贪婪的政策,因为如果我们发现这个行动很好,我们会一直坚持下去,可能不会探索不同的国家。
  2. 最初我们采取随机行动,偶尔我们会采取与最大 q 值相对应的行动。随着时间的推移,我们将减少随机行动,采取更多的贪婪行动。
  3. 为了预测 q 值,我们可以使用相同的函数逼近器,但这次我们将输出两个值,因为我们有两个动作,向左推/向右推。
  4. 我们将跟踪总回报、采取的行动和当前对 q 值的估计,然后我们可以计算误差并更新我们的权重。

这是代码。

运行这段代码,你可以看到大约 5000 集,你会看到我们的政策开始改善。我没有对学习参数进行实验,但我们可以看到它的改进,最终大约 7000 集的目标得以实现。但是我们能做得更好吗?我们能从少量的插曲中学到什么吗?让我们在下一篇博客中探讨这个问题。第一个 for 循环收集经验,第二个开始学习。

Around episode 2000

around 7000 episode

缺点

这种蒙特卡罗方法有一些缺点。

  1. 我们需要等到我们运行一个完整的插曲来计算回报。
  2. 这对非终结性发作不起作用。
  3. MC 法方差大,偏倚小。
  4. 低偏差,因为我们考虑的回报是该州在一集中的真实值。
  5. 方差很大,因为这种方法没有考虑太多的环境动态。我们更新的值是为整个剧集计算的回报。有时,只考虑眼前的回报是好的,可能是未来评估的一部分,因为这将更好地捕捉环境动态。

我们将在下一篇博客中探讨解决这些问题的时间差异学习。

强化学习:概念、应用和代码介绍

原文:https://towardsdatascience.com/reinforcement-learning-an-introduction-to-the-concepts-applications-and-code-ced6fbfd882d?source=collection_archive---------5-----------------------

第 1 部分:强化学习的介绍,解释常见的术语、概念和应用。

在这一系列强化学习的博客文章中,我将尝试对理解强化学习及其应用所需的概念进行简单的解释。在这第一篇文章中,我强调了强化学习中的一些主要概念和术语。这些概念将在未来的博客文章中进一步解释,并结合实际问题中的应用和实现。

零件:123344

强化学习

强化学习(RL)可以被视为一种介于监督非监督学习之间的方法。它不是严格监督的,因为它不仅仅依赖于一组标记的训练数据,但也不是无监督的学习,因为我们有一个回报,我们希望我们的代理最大化。代理需要找到在不同情况下采取的“正确”行动,以实现其总体目标。

强化学习是决策的科学。

强化学习不涉及主管,只有一个 奖励 信号用于代理确定他们做得好还是不好。是 RL 中的关键组成部分,其中流程是。代理做出的每个 动作 都会影响它接收的下一个数据。

Reinforcement Learning applied to Atari games by DeepMind

强化学习问题是什么?

到目前为止,我们已经说过代理需要找到“正确的”动作。正确的行动取决于奖励。****

奖励: 奖励 Rₜ 是一个标量反馈信号,它指示代理在步骤时间 t 做得有多好。

在强化学习中,我们需要定义我们的问题,以便它可以被应用来满足我们的奖励假设。一个例子是下一盘棋,代理人赢了一局得到正奖励,输了一局得到负奖励。

报酬假设 : 所有的目标都可以用期望累积报酬的最大化来描述。

由于我们的过程涉及到系列决策任务,我们早期的行动可能会对我们的总体 目标 产生长期影响。有时候牺牲即时奖励(时间步 Rₜ 奖励)来获得更多长期奖励可能更好。一个应用于国际象棋的例子是牺牲一个卒在稍后阶段夺取一辆车。

目标 :目标是选择行动以最大化未来总报酬。

设置强化学习问题

在强化学习中,代理决定在每个时间步 Aₜ 采取哪些动作。代理基于其接收的标量奖励 Rₜ观察到的环境 Oₜ 做出这些决定。

Reinforcement learning process diagram

****环境接收代理的动作并发出新的观察 Oₜ 和标量奖励 Rₜ 。接下来发生的环境取决于 历史

历史 :历史 Hₜ 是到时间 t 为止的一系列观察、行动和奖励

状态: 状态是用来决定接下来发生什么的信息。

历史状态的主要区别在于状态是历史的函数。这些状态可以分为三种主要类型:**

  • ***环境状态*(sₜᵉ)环境的私有表示,可能对代理不可见。它用于选择下一个观察值。
  • ***代理状态*(sₜᵃ)——代理的内部表示,被代理用来挑选下一个动作。
  • 信息状态 / 马氏状态(sₜ)包含了来自历史的有用信息。因此,给定这种状态,将有足够的信息来模拟未来,并且可以丢弃历史。

马尔可夫状态:一个状态 Sₜ是马尔可夫的当且仅当

我们相信接下来会发生什么取决于代理的状态表示。

环境又分为完全可观测环境部分可观测环境

  • 完全可观测环境 (马尔可夫决策过程):智能体直接观测环境状态。 Oₜ=Sₜᵃ=Sₜᵉ
  • 部分可观测环境 (部分可观测马尔可夫决策过程):智能体间接观测环境。 Sₜᵃ≠Sₜᵉ

强化学习代理

到目前为止,我们已经定义了如何设置 RL 问题,但没有定义 RL 代理如何学习或代理由什么组成。RL 代理可以具有三个主要组件中的一个或多个:

  • 策略: Agent 的行为函数,是从状态到动作的映射。它可以是确定性政策随机政策。

Deterministic policy function

Stochastic policy function

  • 价值函数: 代表每个状态和/或动作有多好。这是对未来回报的预测。

Example value function

  • 模型: 智能体对环境的表征。它预测环境下一步会做什么。预测的是下一个状态和下一个直接奖励。

Example equation to predict of the next state

Example equation to predict the next immediate reward

RL 代理可分为以下几类:

  • ****基于值:没有策略,基于状态值贪婪地选择动作。
  • ****基于策略:没有值函数,使用策略函数选择动作。
  • ****演员评论家:同时使用价值和政策功能。
  • 无模型:**使用策略和/或值函数,但没有模型。
  • ****基于模型:使用策略和/或值函数,并有一个模型。

这些代理类别中的每一个都将在以后的博客中详细描述。

问题内部强化学习

在顺序决策中有两个基本问题:

  • 学习: 环境最初是未知的并且代理需要与环境交互以改进其策略
  • 规划: 如果环境是已知的代理用它的模型执行计算,然后改进它的策略。

由于强化学习就像一种试错学习方法,代理需要从环境中的经验中学习,以便在不损失太多回报的情况下做出决策。它需要考虑开发探索,在探索新信息和利用已知信息之间取得平衡,以实现回报最大化。

参考

如果你喜欢这篇文章,并想看到更多,不要忘记关注和/或留下掌声。

2017 年纽约奥莱利人工智能大会上的强化学习

原文:https://towardsdatascience.com/reinforcement-learning-at-oreilly-artificial-intelligence-conference-ny-2017-404f62c99002?source=collection_archive---------8-----------------------

几周前,2017 年奥莱利人工智能大会在纽约举行。这是一次令人惊叹的会议,来自学术界和工业界的演讲都非常精彩。这篇文章总结了我在那里做的关于强化学习的一些演讲和一个教程,“机器学习领域关注的是软件代理应该如何在一个环境中采取行动,以便最大化一些累积回报的概念”。

与人协调的汽车

Fantasia, Disney 1940

来自伯克利的 Anca D. Dragan 发表了题为“ 与人协调的汽车 ”的主题演讲,她在演讲中介绍了论文“规划对人类行动产生影响的自动驾驶汽车”的结果他们没有进行纯粹的避障,即试图避免妨碍其他移动物体,而是能够将驾驶员建模为遵循自己政策的其他代理。这意味着机器人知道其他汽车也会避免撞到障碍物,所以它可以预测其他车辆对它的行动会有什么反应。

Figure from “Planning for Autonomous Cars that Leverages Effects on Human Actions”

自主车辆还能够采取行动,收集其他车辆的信息。例如,它可以开始慢慢合并人类前面的车道,直到有足够的证据表明司机没有侵略性,并将实际刹车以避免碰撞。

关键的音符是如此之好,以至于我改变了我的时间表去看她的演讲,名为“逆奖励函数”,在我看来,这是大会中最好的演讲。她从迪士尼的电影《幻想曲》开始讲起。它是根据歌德在 1797 年写的诗《巫师的学徒》改编的。正如 W ikipedia 总结它,

这首诗以一个老巫师离开他的工作室开始,留下他的徒弟做杂务。厌倦了用桶打水,这个学徒用一把扫帚附魔来为他做这件事——使用他还没有完全训练好的魔法。地板很快就被水淹没了,学徒意识到他无法停止扫帚,因为他不知道如何停止。

随着我们创造更多与人类直接互动的机器人,Dragan 正在研究我们如何确保它们会做我们真正想要的事情,即使我们发出的命令并不十分精确。我曾经读过一个假设的故事,也说明了这个问题。不幸的是,我找不到参考文献,但它是这样的:

假设我们创造了一台超级智能机器,并要求它找到治疗疟疾的方法。我们设定的目标是尽量减少死于这种疾病的人数。机器人发现,解决问题的最快和最有保证的方法是侵入世界上所有的核武器,并发射它们杀死所有的人类,确保没有人会再次死于疟疾。机器能够实现它的目标,但显然不是以程序员想要的方式。

艾萨克·阿西莫夫也写了几个关于类似情况的好故事,并提出了机器人三定律作为解决问题的方法。

https://xkcd.com/1613/

Dragan 和她的小组在这方面做了很多研究:“机器人应该听话吗?机器人用数学模型规划人的状态和动作关闸游戏简而言之,他们的方法是让机器人考虑到人类指定的命令或政策并不完美,并通过不做与训练时看到的太不同的事情来避免风险。

战略推理的超人 AI:在单挑无限注德州扑克 中击败顶级职业选手,作者 Tuomas Sandholm(卡内基梅隆大学):他们能够在一场难度相当的比赛中击败顶级人类选手,但没有得到媒体的同等关注。这个游戏增加了额外的复杂性,因为玩家没有完整的信息。桑德霍尔姆评论了除了典型的探索与利用权衡之外游戏必须考虑的第三个变量:可利用性。他们的代理人 Liberatus 试图将剥削最小化。它并不真正擅长探索糟糕的玩家,但可以用这种方法击败最好的人类。

https://www.cmu.edu/news/stories/archives/2017/january/AI-tough-poker-player.html

深度强化学习教程,作者 Arthur Juliani。非常好的教程,代码易于理解和运行。朱利安尼提出了几种不同的强化学习方法,包括多武装匪徒理论、Q 学习、政策梯度和行动者-批评家代理。看一看资源库中的教程。

Multi-Armed Bandit Dungeon environment

使用 OpenAI 的 Gym 和 Universe 构建游戏机器人,作者 Anmol Jagetia: 不幸的是,他遇到了几个技术问题:一些例子崩溃了,运行的例子帧率很差,我们看不到代理在做什么,但他的教程笔记本看起来很有趣:【https://github.com/anmoljagetia/OReillyAI-Gamebots】T2

敬请关注更多内容。我会写另一篇关于我在那里看到的其他主题的帖子:推荐系统、张量流和自然语言理解。

强化学习备忘单

原文:https://towardsdatascience.com/reinforcement-learning-cheat-sheet-2f9453df7651?source=collection_archive---------7-----------------------

免责声明:这是一个正在进行的项目,可能会有错误!

为了快速回顾我的强化学习知识,我用所有的基本公式和算法创建了这个备忘单。我希望这可能对你有用。

你可以在这里找到完整的 pdf ,在这里找到回购

2018 年 3 月 19 日更新。重写了 Sarsa 以遵循萨顿和巴尔托算法

2018 年 3 月 15 日更新。感谢Alexandre baullne增加了收缩贴图、Sarsa 和清理乳胶。

具有新功能的拉式请求非常受欢迎!

主要参考资料是萨顿和巴尔托的《强化学习导论》。这里可以找到

也许你还可以找到值得一读的我的其他文章:

https://towards data science . com/let-fool-a-neural-network-B1 cded 8 C4 c 07

https://towards data science . com/how-to-use-dataset-in-tensor flow-c 758 ef 9 e 4428

感谢您的阅读。

弗朗西斯科·萨维里奥

基于满足设定预算和个人偏好的膳食计划强化学习(蒙特卡罗)

原文:https://towardsdatascience.com/reinforcement-learning-for-meal-planning-based-on-meeting-a-set-budget-and-personal-preferences-9624a520cce4?source=collection_archive---------10-----------------------

这篇文章介绍了一种使用强化学习来计划膳食的基本方法。我也已经将描述、数据和内核发布到 Kaggle,可以在这里找到:https://www . ka ggle . com/osbornep/reinforcement-learning-for-meal-planning-in-python/notebook

如果您有任何问题或建议,请告诉我。

Photo: Pixabay

目标

购买食品时,超市里有许多相同成分的不同产品可供选择。有些不太贵,有些质量更好。我想创建一个模型,对于所需的配料,可以选择制作一顿饭所需的最佳产品,这两者都是:

  1. 在我的预算内
  2. 符合我的个人喜好

为此,我将首先构建一个非常简单的模型,在介绍我的偏好之前,它可以推荐低于我预算的产品。

我们使用一个模型的原因是,理论上,我们可以将问题扩大到考虑越来越多的成分和产品,这些成分和产品会导致问题超出任何心理计算的可能性。

方法

为了实现这一点,我将建立一个简单的强化学习模型,并使用蒙特卡洛学习来寻找产品的最佳组合。

首先,让我们将模型的各个部分正式定义为马尔可夫决策过程:

  • 我们需要有限数量的配料来做任何一顿饭,并且被认为是我们的
  • 每种成分都有有限的可能产品,因此是每个状态的动作
  • 我们的偏好成为选择每个产品的个人奖励,我们将在后面更详细地介绍这一点

蒙特卡洛学习将达到最终目标的每一步的质量结合起来,并要求为了评估任何一步的质量,我们必须等待并看到整个结合的结果。这个过程在许多不同产品的剧集中一遍又一遍地重复,直到它找到看起来会导致积极结果的选择。这是一个强化学习过程,我们的环境是基于我们获得的关于成本和偏好的知识来模拟的。

蒙特卡洛通常被避免,因为在能够学习之前,需要花时间经历整个过程。然而,在我们的问题中,在确定所选产品组合是好是坏时,我们需要进行最终检查,将所选产品的实际成本相加,并检查其是否低于或高于我们的预算。此外,至少在现阶段,我们不会考虑超过几个成分,因此在这方面所花的时间并不重要。

https://www.tractica.com/artificial-intelligence/reinforcement-learning-and-its-implications-for-enterprise-artificial-intelligence/

抽样资料

在这个演示中,我为一顿饭创建了一些样本数据,其中有 4 种配料和 9 种产品,如下图所示。

我们需要为膳食中的每种成分选择一种产品。

这意味着我们有 2 x 2 x 2 x 3 = 24 种成分的 24 种产品可供选择。

我还包括了每个产品的实际成本和 V_0。

V_0 只是满足我们要求的每个产品的初始质量,我们将其设置为 0。

Diagram showing the possible product choices for each ingredient

首先,我们导入所需的包和数据。

在理论上应用该模型

现在,我不会为产品引入任何个人奖励。相反,我将只关注所选择的产品组合是否低于我们的预算。这个结果被定义为我们问题的终端回报

例如,假设我们的预算是 30,那么选择:

a1→b1→c1→d1

那么这个选择的真正成本是:

£10+£8+£3+£8 = £29 < £30

因此,我们的终极奖励是:

R_T=+1

鉴于,

a2→b2→c2→d1

那么这个选择的真正成本是:

£6+£11+£7+£8 = £32 > £30

因此,我们的终极奖励是:

r _ T = 1

现在,我们只是告诉我们的模型选择是好是坏,并观察这对结果有什么影响。

模型学习

那么我们的模型实际上是如何学习的呢?简而言之,我们让我们的模型尝试许多产品组合,并在每个组合结束时告诉它它的选择是好是坏。随着时间的推移,它将认识到,一些产品通常会带来良好的结果,而另一些则不会。

我们最终创造的是每个产品有多好的价值,用 V(a)表示。我们已经介绍了每种产品的初始 V(a ),但是我们如何从这些初始值开始真正做出决策呢?

为此,我们需要一个更新规则。这告诉模型,在每次它给出它的产品选择后,我们告诉它选择是好是坏,如何把它加到我们的初始值中。

我们的更新规则如下:

这乍一看可能不寻常,但在文字上,我们只是简单地更新了任何行动的值 V(a ),如果结果是好的,则增加一点,如果结果是坏的,则减少一点。

g 是回报,简单来说就是获得的总回报。目前在我们的例子中,这只是终端奖励(相应地+1 或-1)。稍后,当我们包括个人产品奖励时,我们将再次介绍这一点。

Alpha,αα,是学习率,我们将在后面演示它如何影响结果,但现在,简单的解释是:“学习率决定了新获得的信息覆盖旧信息的程度。因子 0 使代理什么也学不到,而因子 1 使代理只考虑最近的信息。”(https://en.wikipedia.org/wiki/Q-learning)

更新值的小演示

那么我们如何在模型中使用它呢?

让我们从一个包含每种产品及其首字母 V_0(a)的表开始:

我们现在随机挑选产品,每个组合被称为。我们现在也设置α=0.5α=0.5,只是为了计算简单。

例如:

因此,导致这一积极结果的所有行动也被更新,以便与 V1(a)一起生成下表:

所以让我们再随机挑选一集来试试:

因此,我们可以将 V2(a)添加到我们的表中:

动作选择

你可能在演示中注意到了,我只是简单地随机选择了每集的产品。我们可以这样做,但是使用一个完全随机的选择过程可能意味着一些行为没有足够频繁地被选择来知道它们是好是坏。

类似地,如果我们选择其他方式,并决定贪婪地选择产品,即选择目前具有最佳价值的产品,我们可能会错过事实上更好但从未有机会的产品。例如,如果我们选择 V2(a)的最佳行动,我们将得到 a2、b1、c1 和 d2 或 d3,它们都提供了积极的最终回报。因此,如果我们使用纯粹贪婪的选择过程,我们将永远不会考虑任何其他产品,因为这些产品继续提供积极的结果。

相反,我们实施ε-贪婪动作选择,其中我们随机选择具有概率ϵ的产品,并贪婪地选择具有概率 1−ϵ1−ϵ的产品,其中:

这意味着我们将很快达到产品的最佳选择,因为我们继续测试“好”的产品实际上是否是最佳的,但也为我们留下了空间,我们也偶尔探索其他产品,以确保它们没有我们当前的选择好。

构建和应用我们的模型

我们现在准备构建一个简单的模型,如下面的 MCModelv1 函数所示。

虽然这看起来很复杂,但我所做的不过是应用前面讨论的方法,这样我们就可以改变输入并仍然获得结果。诚然,这是我第一次尝试这样做,所以我的代码可能写得不完美,但应该足以满足我们的要求。

为了计算终端奖励,我们目前使用以下条件来检查总成本是少于还是多于我们的预算:

这个模型的完整代码太大了,不适合放在这里,但可以在链接的 Kaggle 页面上找到。

我们现在用一些样本变量运行我们的模型:

在我们的函数中,模型有 6 个输出:

  • Mdl[0]:返回每集所有 V(a)的总和
  • Mdl[1]:返回最便宜产品的 V(a)之和,由于样本数据的简单性,可以对其进行定义
  • Mdl[2]:返回非最便宜产品的 V(a)之和
  • Mdl[3]:返回最后一集的最佳动作
  • Mdl[4]:返回为每个产品添加了最终 V(a)的数据表
  • Mdl[5]:显示每个周期的最佳操作

从这些案例中我们可以学到很多东西,所以让我们仔细研究每一个案例,并确定我们可以学到什么来改进我们的模型。

最后一集的最佳行动

首先,让我们看看模型建议我们应该选择什么。在这种情况下,它建议总成本低于预算的行动或产品是好的。

然而,我们还可以检查更多内容,以帮助我们了解正在发生的事情。

首先,我们可以画出所有动作的总 V,我们看到这是理想的收敛。我们希望我们的模式能够趋同,这样当我们尝试更多剧集时,我们就能“分区”选择最佳产品。输出收敛的原因是因为我们将它每次学习的数量减少了一个因子αα,在本例中为 0.5。我们将在后面展示如果我们改变这个或者根本不应用它会发生什么。

我们还绘制了我们知道最便宜的产品的 V 的总和,这是基于能够单独评估小样本量和其他产品。同样,两者正向趋同,尽管较便宜的产品似乎价值略高。

那么,为什么会发生这种情况,为什么模型会提出它所做的动作?

为了理解这一点,我们需要剖析每集模型提出的建议,以及这些建议与我们的回归有何关联。

下面,我们针对每个状态采取了最佳措施。我们可以看到,建议的行动确实在剧集之间变化很大,并且模型似乎很快就决定了想要建议哪个。

因此,我绘制了每集建议行动的总成本,我们可以看到行动最初有所不同,然后变得平稳,最终总成本低于我们的预算。这大大有助于我们理解正在发生的事情。

到目前为止,我们告诉模型的是提供一个低于预算的选择,它已经做到了。它只是找到了一个低于所需预算的答案。

那么下一步是什么?在我介绍奖励之前,我想演示一下如果我改变一些参数会发生什么,以及如果我们决定改变我们希望模型建议的东西,我们能做些什么。

改变参数的影响以及如何改变模型的目标

我们有几个可以改变的参数:

  1. 预算
  2. 我们的学习率,α
  3. 输出动作选择参数,ϵ

变动预算

首先,让我们观察一下,如果我们把预算定得过低或过高,会发生什么。

一个小的预算意味着我们只能得到一个负的回报,意味着我们将迫使我们的 V 向负的方向收敛,而一个太高的预算将导致我们的 V 向正的方向收敛,因为所有的行为都是持续的正的。

后者看起来就像我们在第一轮中所做的那样,许多情节都带来了积极的结果,因此许多产品组合都是可能的,最便宜的产品与其他产品之间几乎没有区别。

相反,如果我们考虑一个给定产品价格的合理低的预算,我们可以看到一个趋势,最便宜的产品看起来正趋同,而更贵的产品负趋同。然而,这两部电影的流畅度并不理想,每一集之间都有很大的波动。

那么,我们能做些什么来减少输出的“尖峰”呢?这就引出了我们的下一个参数,α。

变化α

栈溢出用户 VishalTheBeast 很好地解释了 alpha 对我们输出的影响:

“学习率告诉我们向解决方案迈进的幅度。

它不应该是太大的数字,因为它可能会在最小值附近连续振荡,也不应该是太小的数字,否则将需要很多时间和迭代才能达到最小值。

在学习速率中建议衰减的原因是,最初当我们处于解空间中的一个完全随机的点时,我们需要向解大步跳跃,后来当我们接近解时,我们进行小跳跃,因此小改进,最终达到最小值。

可以这样类比:在高尔夫球比赛中,当球远离球洞时,球员非常努力地击球,以尽可能靠近球洞。后来,当他到达标记区域时,他选择了一根不同的棍子来获得准确的短杆。

所以这并不是说他不选择短杆就不能把球打进洞里,他可能会把球送到目标前面两三次。但是,如果他发挥最佳状态,使用正确的力量到达球洞,那将是最好的。学习率下降也是如此。"

https://stack overflow . com/questions/33011825/learning-rate-of-a-q-learning-agent

为了更好地演示改变 alpha 的效果,我将使用 Plot.ly 创建的动画情节。

我在这里写了一个关于如何做的更详细的指南:

[## 使用 Plot.ly 创建参数优化的交互式动画

介绍

towardsdatascience.com](/creating-interactive-animation-for-parameter-optimisation-using-plot-ly-8136b2997db)

在我们的第一个动画中,我们在 1 和 0.1 之间改变 alpha。这使我们能够看到,当我们减少阿尔法我们的输出平滑一些,但它仍然很粗糙。

然而,即使结果变得平滑,它们不再在 100 集内收敛,而且,它们的输出似乎在每个 alpha 之间交替。这是由于小阿尔法组合需要更多集来学习,并且动作选择参数ε为 0.5。本质上,一半的时间输出仍然是由随机性决定的,所以我们的结果不会在 100 集的框架内收敛。

在我们的动画情节中运行它会产生类似如下的结果:

变化的ε

考虑到前面的结果,我们现在将 alpha 固定为 0.05,并将 epsilon 在 1 和 0 之间变化,以显示完全随机选择操作对贪婪选择操作的影响。

下图显示了不同 epsilon 的三个快照,但动画版本可以在 Kaggle 内核中查看。

我们看到高ε产生了非常零星的结果。因此,我们应该选择一个相当小的值,比如 0.2。虽然ε等于 0 看起来很好,因为曲线很平滑,正如我们前面提到的,这可能会让我们很快做出选择,但可能不是最好的。我们需要一些随机性,这样模型就可以在需要时探索其他动作。

增加剧集数量

最后,我们可以增加剧集的数量。我没有马上这么做,因为我们在一个循环中运行 10 个模型来输出我们的动画图,这会导致运行模型的时间爆炸。

我们注意到低 alpha 需要更多的剧集来学习,所以我们可以运行 1000 集的模型。

然而,我们仍然注意到输出是振荡的,但是,如前所述,这是因为我们的目的只是推荐一个低于预算的组合。这表明,当有许多组合低于我们的预算时,模型无法找到单一的最佳组合。

因此,如果我们稍微改变我们的目标,以便我们可以使用模型找到最便宜的产品组合,会发生什么?

改变我们模型的目标,找到最便宜的产品组合

这样做的目的是更清楚地将最便宜的产品与其他产品区分开来,并且几乎总是为我们提供最便宜的产品组合。

要做到这一点,我们需要做的就是稍微调整我们的模型,以提供一个相对于该组合在该集中低于或高于预算多少的最终奖励。

这可以通过将退货计算改为:

我们现在看到最便宜的产品和其他产品之间的区别被强调了。

这确实展示了强化学习的灵活性,以及根据您的目标调整模型是多么容易。

首选项介绍

到目前为止,我们还没有包括任何个人对产品的偏好。如果我们想包括这一点,我们可以简单地为每个产品引入奖励,同时仍然有一个终端奖励,鼓励模型低于预算。

这可以通过将退货计算改为:

那么为什么我们现在的回报计算是这样的呢?

首先,我们仍然希望我们的组合低于预算,所以我们分别为高于和低于预算提供积极和消极的奖励。

接下来,我们要考虑每个产品的奖励。出于我们的目的,我们将奖励定义为 0 到 1 之间的值。MC 回报的正式计算方法如下:

γ是贴现因子,它告诉我们,与前面的步骤相比,后面的步骤有多重要。在我们的例子中,所有行动对于达到低于预算的预期结果同样重要,所以我们设置γ=1。

然而,为了确保我们达到低于预算的主要目标,我们对每项行动的奖励总和取平均值,使其始终分别小于 1 或-1。

同样,完整的模型可以在 Kaggle 内核中找到,但是太大了,无法在这里链接。

使用奖励引入偏好

假设我们决定购买产品 a1 和 b2,我们可以给每一个产品增加奖励。让我们在下面的输出和图表中看看这样做会发生什么。我们稍微改变了预算,因为 a1 和 b2 加起来是 21,这意味着没有办法再选择两个产品,使其低于预算 23。

应用一个非常高的奖励迫使模型选择 a1 和 b2,然后寻找能使它在我们预算之内的产品。

我一直在比较最便宜的产品和其他产品,以表明该模型现在不再评估最便宜的产品。相反,我们得到总成本为 25 的输出 a1、b2、c1 和 d3。这既低于我们的预算,也包括我们的首选产品。

我们再试试一个奖励信号。这一次,我给每个人一些奖励,但希望它能提供我的奖励的最佳组合,使我们仍然低于预算。

我们有以下奖励:

运行该模型几次表明,它将:

  • 经常选择 a1,因为这有更高的回报
  • 我总是选择 c1,因为回报是一样的,但是更便宜
  • 我很难在 b1 和 b2 之间做出选择,因为回报分别为 0.5 和 0.6,但成本分别为 8 和 11
  • 通常会选择 d3,因为它比 d1 便宜得多,即使报酬稍低

结论

我们已经设法建立了一个蒙特卡洛强化学习模型,以:1)推荐低于预算的产品,2)推荐最便宜的产品,3)基于仍然低于预算的偏好推荐最好的产品。

在这个过程中,我们展示了在强化学习中改变参数的效果,以及理解这些如何使我们达到预期的结果。

在我看来,我们还可以做更多的事情,最终目标将是应用于真正的食谱和来自超市的产品,其中需要考虑增加的成分和产品的数量。

我创建这个样本数据和问题是为了更好地理解强化学习,希望你会觉得有用。

谢谢

菲利普·奥斯本

现实生活规划问题的强化学习

原文:https://towardsdatascience.com/reinforcement-learning-for-real-life-planning-problems-31314491e5c?source=collection_archive---------1-----------------------

最近,我发表了一些例子,其中我为一些现实生活中的问题创建了强化学习模型。例如,根据设定的预算和个人偏好使用强化学习进行膳食计划。强化学习可以用于各种各样的计划问题,包括旅行计划、预算计划和商业策略。使用 RL 的两个优点是,它考虑了结果的概率,并允许我们控制环境的一部分。因此,我决定写一个简单的例子,以便其他人可以考虑如何开始使用它来解决他们的一些日常或工作问题。

什么是强化学习?

强化学习(RL)是通过基本的反复试验来测试哪种行为对于环境的每种状态是最好的过程。该模型引入了一个随机策略,每次采取行动时,都会有一个初始数量(称为奖励)输入到模型中。这种情况会持续到达到最终目标,例如,你赢得或输掉游戏,此时该回合(或情节)结束,游戏重置。随着模型经历越来越多的情节,它开始学习哪些行动更有可能将我们引向积极的结果,并因此找到任何给定状态下的最佳行动,这被称为最优策略。

Reinforcement Learning General Process

许多在线 RL 应用在游戏或虚拟环境中训练模型,其中模型能够重复地与环境交互。例如,你让模型一遍又一遍地玩井字游戏,以便它观察成功和失败或尝试不同的动作。

在现实生活中,我们很可能无法以这种方式训练我们的模型。例如,在线购物中的推荐系统需要一个人的反馈来告诉我们它是否成功,这是基于有多少用户与购物网站交互而限制其可用性的。相反,我们可能有显示一段时间内购物趋势的样本数据,我们可以使用这些数据来估计概率。使用这些,我们可以创建所谓的部分观察马尔可夫决策过程(POMDP ),作为概括潜在概率分布的一种方式。

部分观察马尔可夫决策过程

马尔可夫决策过程(MDP)提供了一个框架,用于在结果部分是随机的,部分在决策者控制下的情况下对决策进行建模。MDP 的关键特征是它们遵循马尔可夫性质;所有未来的状态都是独立于过去的。换句话说,进入下一个状态的概率只取决于当前状态。

POMDPs 的工作方式类似,只是它是 MDP 的一般化。简而言之,这意味着模型不能简单地与环境相互作用,而是根据我们观察到的情况给出一个设定的概率分布。更多信息可在这里找到。我们可以在 POMDP 上使用值迭代方法,但是在这个例子中我们决定使用蒙特卡罗学习。

示例环境

想象一下,你回到了学校(或者可能仍然在学校),在教室里,老师对废纸有严格的政策,要求任何纸片都必须在教室前面递给他,他会把垃圾放入垃圾桶。然而,班上有些学生不在乎老师的规定,宁愿省去在教室里传纸条的麻烦。相反,这些麻烦的人可能会选择从远处把废纸扔进垃圾箱。这激怒了老师,这样做的人会受到惩罚。这引入了一个非常基本的行动奖励概念,我们有一个示例教室环境,如下图所示。

我们的目的是为每个人找到最好的说明,以便论文到达老师手中并放入垃圾箱,避免被扔进垃圾箱。

状态和动作

在我们的环境中,每个人都可以被视为一个状态,他们可以对废纸采取各种行动。他们可能会把它传给邻近的同学,自己拿着,或者有些人会把它扔进垃圾箱。因此,我们可以将我们的环境映射到一个更标准的网格布局,如下所示。

这是有目的地设计的,这样每个人或每个状态都有四个动作:上、下、左或右,并且每个动作都将基于谁采取了该动作而有不同的“真实生活”结果。把人放到墙上(包括中间的黑色方块)的动作表示这个人抓住了纸。在某些情况下,这个动作是重复的,但在我们的例子中不是问题。

例如,人 A 的行为导致:

  • 向上=扔进垃圾箱
  • 向下=抓住纸张
  • 左=传给人 B
  • 右=抓住纸

概率环境

目前,部分控制环境的决策者是我们。我们会告诉每个人他们应该采取什么行动,这就是所谓的政策

我在学习中面临的第一个挑战是理解环境可能是概率性的,以及这意味着什么。概率环境是指当我们指示一个州根据我们的政策采取行动时,有一个与此是否成功执行相关的概率。换句话说,如果我们告诉人 A 把纸递给人 B,他们可以决定不按照我们政策中的指示行动,而是把废纸扔进垃圾箱。另一个例子是,如果我们推荐网上购物产品,不能保证人们会看到每一个。

观察到的转移概率

为了找到观察到的转移概率,我们需要收集一些关于环境如何作用的样本数据。在我们收集信息之前,我们首先介绍一个初始策略。为了开始这个过程,我随机选择了一个看起来会带来积极结果的方法。

现在我们观察每个人在这个政策下采取的行动。换句话说,假设我们坐在教室的后面,简单地观察课堂,观察到 A 的以下结果:

Person A’s Observed Actions

我们看到一张纸经过这个人 20 次;6 次他们拿着它,8 次他们把它传给了 B,还有 6 次他们把它扔进了垃圾桶。这意味着,在我们最初的策略下,这个人持有或将其扔进垃圾桶的概率是 6/20 = 0.3,同样地,传给人 b 的概率是 8/20 = 0.4。我们可以观察班上的其他人,以收集以下样本数据:

Observed Real Life Outcome

同样地,我们计算出下面的概率矩阵,我们可以用它来模拟经验。该模型的准确性将在很大程度上取决于概率是否真实地代表了整个环境。换句话说,我们需要确保我们的样本足够大,数据足够丰富。

Observed Transition Probability Function

多武装土匪,集,奖励,返回和折扣率

因此,我们在 POMDP 下从样本数据中估计了转移概率。在我们引入任何模型之前,下一步是引入奖励。到目前为止,我们只讨论了最后一步的结果;要么这张纸被老师扔进垃圾箱,得到正奖励,要么被 A 或 M 扔出去,得到负奖励。结束这一集的最终奖励被称为最终奖励。但是,也有不太理想的第三种结果;这张纸不断地被传来传去,从来没有(或者花了比我们希望的长得多的时间)到达垃圾箱。因此,总而言之,我们有三个最终结果

  • 老师将纸放入垃圾箱,并获得积极的最终奖励
  • 一个学生把纸扔进垃圾箱,得到一个负的最终奖励
  • 纸张不断在教室里传来传去,或者粘在学生身上的时间比我们希望的要长

为了避免纸被扔进垃圾箱,我们提供了一个大的负奖励,比如说-1,因为老师很高兴它被放入垃圾箱,这净得一个大的正奖励+1。为了避免在房间里不断传递的结果,我们将所有其他行为的奖励设置为一个小的负值,比如-0.04。如果我们将它设置为正数或空数,那么模型可能会让论文循环往复,因为获得小的正数比冒险接近负数要好。这个数字也很小,因为它只会收集一个单一的最终奖励,但它可能需要许多步骤来结束这一集,我们需要确保,如果论文被放入垃圾箱,积极的结果不会被抵消。请注意,奖励总是相对于另一个,我选择了任意的数字,但如果结果不理想,这些可以改变。

尽管我们无意中讨论了示例中的情节,但我们还没有正式定义它。一集就是每张纸通过教室到达垃圾箱的动作,这是最终状态并结束一集。在其他例子中,比如玩井字游戏,这将是一场你赢或输的游戏的结尾。

理论上,论文可以从任何状态开始,这介绍了为什么我们需要足够的片段来确保每个状态和动作都经过足够的测试,这样我们的结果就不会被无效的结果所驱动。然而,另一方面,我们引入的剧集越多,计算时间就越长,并且根据环境的规模,我们可能没有无限量的资源来做这件事。

这就是所谓的多兵种土匪问题;在有限的时间(或其他资源)下,我们需要确保对每个状态-动作对进行足够的测试,以确保我们的策略中选择的动作实际上是最优的。换句话说,我们需要证明,在过去导致我们取得好结果的行动并不是纯粹的运气,而是事实上是正确的选择,对于那些看起来糟糕的行动也是如此。在我们的例子中,这看起来很简单,因为我们的状态很少,但是想象一下,如果我们增加规模,这将会变成一个越来越大的问题。

我们 RL 模型的总体目标是选择最大化预期累积回报的行动,即回报。换句话说,回报就是该集获得的总回报。一个简单的计算方法是把每集的所有奖励加起来,包括最终奖励。

一种更严格的方法是,通过在下面的公式中应用一个折扣因子γ,认为第一步比后面的步骤更重要:

换句话说,我们将所有的奖励相加,但是将后面的步骤加权一个系数,该系数是达到这些奖励所需的步骤数的幂。

如果我们想一想我们的例子,使用折扣回报会变得更加清晰,因为老师会奖励(或相应地惩罚)任何参与该事件的人,但会根据他们离最终结果的距离来衡量这一点。例如,如果纸从 A 传到 B,再传到把它扔进垃圾箱的 M,M 应该受到最大的惩罚,然后是 B 把它传给他,最后是 A,他仍然参与最终结果,但比 M 或 B 参与得少。这也强调了从一个状态开始并到达垃圾箱所花的时间越长(基于步骤数), is 得到的奖励或惩罚就越少,但采取更多步骤会累积负奖励。

将模型应用于我们的示例

由于我们的示例环境很小,我们可以应用每一个并显示一些手动执行的计算,并说明更改参数的影响。

对于任何算法,我们首先需要初始化状态值函数 V(s ),并且已经决定将它们中的每一个设置为 0,如下所示。

接下来,我们让模型基于我们观察到的概率分布来模拟对环境的体验。该模型从一张随机状态的纸开始,在我们的策略下,每个行动的结果都基于我们观察到的概率。例如,假设我们有如下的前三个模拟情节:

有了这些片段,我们可以使用给定的三个模型中的每一个来计算我们的状态值函数的最初几次更新。现在,我们选择一个任意的 alpha 和 gamma 值为 0.5 来简化我们的手工计算。我们将在后面展示这个变量对结果的影响。

首先,我们应用时间差异 0,这是我们最简单的模型,前三个值更新如下:

那么这些是如何计算的呢,因为我们的例子很小,我们可以手工显示计算结果。

那么在这个早期阶段我们能观察到什么呢?首先,使用 TD(0)似乎对某些国家不公平,例如 D 人,他在现阶段从三分之二到达垃圾箱的纸张中一无所获。他的更新只受到下一阶段价值的影响,但这强调了积极和消极的奖励如何从角落向外传播到各个州。随着我们拍摄的剧集越来越多,正面和负面的最终奖励将会越来越分散到各个州。这大致显示在下面的图表中,我们可以看到,导致正面结果的两个事件影响了状态 Teacher 和 G 的值,而单个负面事件惩罚了人 m。

为了显示这一点,我们可以尝试更多的情节,如果我们重复已经给出的相同的三个路径,我们产生以下状态值函数:

(请注意,为简单起见,我们在本例中重复了这三集,但实际模型会有几集的结果基于观察到的转移概率函数)

上图显示了终端奖励从右上角向外传播到各州。由此,我们可以决定更新我们的政策,因为很明显,负的终端报酬通过人 M 传递,因此 B 和 C 受到负面影响。因此,基于 V27,对于每个状态,我们可以决定通过为每个状态选择下一个最佳状态值来更新我们的策略,如下图所示

在这个例子中有两个值得关注的原因,第一个是 A 的最佳行动是把它扔进垃圾箱,净得一个负回报。这是因为没有一集访问了这个人,并强调了多武装匪徒的问题。在这个小例子中,只有很少几个州,所以需要很多集才能访问所有的州,但我们需要确保做到这一点。这个行动对这个人来说更好的原因是因为两种最终状态都没有价值,而是积极和消极的结果都在最终回报中。然后,如果我们的情况需要,我们可以根据结果用终态的数字初始化 V0。

其次,人 M 的状态值在-0.03 和-0.51 之间来回翻转(大约。)之后,我们需要解决为什么会发生这种情况。这是我们的学习率α造成的。目前,我们只介绍了我们的参数(学习率α和贴现率γ),但没有详细解释它们将如何影响结果。一个大的学习率可能会导致结果振荡,但反过来,它不应该太小,以至于永远收敛。下图进一步显示了每集的总 V(s ),我们可以清楚地看到,尽管总体趋势是上升的,但它在各集之间来回变化。学习率的另一个很好的解释如下:

“在高尔夫球比赛中,当球离球洞很远时,球员要尽可能地靠近球洞。后来,当他到达标记区域时,他选择了一根不同的棍子来获得准确的短杆。

所以不是说他不选短杆就不会把球送进洞,他可能会把球送到目标前面两三次。但是,如果他发挥最佳状态,使用正确的力量到达球洞,那将是最好的。"

[## Q 学习代理的学习速率

学习率如何影响收敛率和收敛本身的问题。如果学习率是…

stackoverflow.com](https://stackoverflow.com/questions/33011825/learning-rate-of-a-q-learning-agent)

Episode

对于一个问题,有一些复杂的方法来建立最佳学习速率,但是,与任何机器学习算法一样,如果环境足够简单,您可以迭代不同的值,直到达到收敛。这也被称为随机梯度下降。在最近的 RL 项目中,我用动画演示了减少 alpha 的效果,如下所示。这演示了当 alpha 较大时的振荡,以及当 alpha 减小时振荡如何变得平滑。

同样,我们也必须有一个介于 0 和 1 之间的折现率,通常这个值接近 0.9。贴现因子告诉我们未来的回报有多重要;大数值表示它们将被认为是重要的,而将这个数值移向 0 将使模型越来越少地考虑未来的步骤。

考虑到这两个因素,我们可以将 alpha 从 0.5 更改为 0.2,将 gamma 从 0.5 更改为 0.9,并获得以下结果:

因为我们的学习率现在小得多,所以模型需要更长的时间来学习,并且值通常更小。最明显的是对于老师来说,这显然是最好的状态。然而,这种增加计算时间的折衷意味着我们的 M 值不再像以前那样振荡。我们现在可以在下图中看到,根据我们更新的参数,V(s)的总和。虽然它并不完全平滑,但总 V(s)以比以前平滑得多的速度缓慢增加,并像我们希望的那样收敛,但需要大约 75 集才能收敛。

改变目标结果

RL 的另一个至关重要的优势是我们对环境有一定的控制权,这一点我们还没有详细提及。目前,奖励是基于我们的决定,即让模型以尽可能少的步骤达到积极的结果是最好的。然而,假设老师换了,新老师不介意学生把纸扔进垃圾箱,只要它够得着。然后我们可以围绕这个改变我们的负回报,最优策略就会改变。

这对于商业解决方案尤其有用。例如,假设您正在计划一项战略,并且知道某些转变不如其他转变理想,那么这可以被考虑在内并随意改变。

结论

我们现在已经根据观察到的数据创建了一个简单的强化学习模型。有许多事情可以改进或进一步发展,包括使用更复杂的模型,但对于那些希望尝试并应用于自己现实生活中的问题的人来说,这应该是一个很好的介绍。

我希望你喜欢阅读这篇文章,如果你有任何问题,请随时在下面评论。

谢谢

哲学(philosophy 的缩写)

从头开始强化学习:在 Python 笔记本中设计和解决任务

原文:https://towardsdatascience.com/reinforcement-learning-from-scratch-designing-and-solving-a-task-all-within-a-python-notebook-48c40021da4?source=collection_archive---------6-----------------------

第 1 部分:定义环境,用价值迭代找到最优策略,并引入 Q 学习

摘要

在本文中,我将介绍一个新项目,它试图通过在 Python 笔记本中完全定义和解决一个简单的任务来帮助那些学习强化学习的人。环境和基本方法将在本文中解释,所有代码都发布在 Kaggle 的下面的链接中。此外,我已经创建了一个“元”笔记本,可以很容易地分叉,只包含定义的环境,供其他人尝试、适应和应用他们自己的代码。

[## Python 中从头开始的强化学习

寻找特定环境下最佳行动的初学者指南

www.kaggle.com](https://www.kaggle.com/osbornep/-reinforcement-learning-from-scratch-in-python)

语境

当我第一次开始学习强化学习时,我直接复制在线指南和项目,但发现我迷路了,感到困惑。“为什么结果会显示这一点?这个参数有什么作用?环境这样做是为了什么?”都是我开始问自己的一些问题。直到我后退一步,从基础开始,首先完全理解概率环境是如何定义的,并建立一个我可以在纸上解决的小例子,事情才开始变得更有意义。然而,我发现很难找到一个不需要从外部资源导入的环境来应用我的知识。

因此,我给自己设定了一个挑战:

我能否在一个 Python 笔记本中完全独立地定义并找到任务环境的最佳行动?

通过关注我的工作,我希望其他人可以将此作为学习自己的基本起点。

阶段 1:定义环境

任务

很简单,我想知道从房间的任何位置将一张纸放入垃圾桶的最佳动作。我可以把纸扔向任何方向,或者一次移动一步。

尽管对于可以通过视觉判断箱子位置并且具有大量关于机器人必须从零开始学习的距离的先验知识的人来说很简单。

这定义了一个环境,在该环境中,根据纸张投掷的方向和当前距离垃圾箱的距离来计算成功投掷的概率。

例如,在下图中,我们有三个人,分别标为 A、B 和 c。A 和 B 都朝正确的方向投掷,但 A 比 B 更近,因此更有可能击中目标。

人 C 比人 B 更近,但是投掷方向完全错误,因此击中垃圾箱的概率非常低。这可能看起来不合逻辑,人 C 会朝这个方向扔,但正如我们稍后将展示的那样,算法必须首先尝试一系列方向,以找出成功在哪里,并且没有关于箱子在哪里的视觉引导。

Task Environment Example

为了在 python 中创建环境,我们将图表转换为 x 和 y 值的二维尺寸,并使用方位数学来计算投掷的角度。我们使用标准化的整数 x 和 y 值,因此它们必须以-10 和 10 为界。

Environment Mapped to 2-d Space

环境概率

投掷成功的概率与投掷的距离和方向有关。因此,我们需要计算两个度量:

  • 当前位置离箱子的距离
  • 纸被扔出的角度和垃圾箱的真实方向之间的差异

距离测量 如上图所示,A 人在 set 中的位置为(-5,-5)。这是它们的当前状态,并且可以使用欧几里德距离度量来计算它们与容器的距离:

对于最终计算,我们对此进行归一化并反转该值,以便高分指示该人更接近目标箱:

因为我们已经将二维维度固定在(-10,10)之间,所以这个人可能的最大距离是 sqrt{(100) + (100)} = sqrt{200}。因此,我们对人 A 的距离得分是:

方向测量

然后,人 A 要做一个决定,他们是移动还是向一个选定的方向扔东西。现在,让我们想象他们选择扔纸,他们的第一次投掷是在 50 度,第二次是在正北 60 度。来自人 A 的面元的方向可以通过简单的三角学来计算:

因此,第一次投掷偏离真实方向 5 度,第二次投掷偏离真实方向 15 度。

当我们考虑好的投掷以实际方向的任一侧 45 度为界时(即,没有以错误的方式投掷),那么我们可以使用下面的公式来计算这个选择的方向有多好。超过 45 度界限的任何方向将产生负值,并映射到概率 0:

两者都相当接近,但他们的第一次投掷更有可能击中垃圾箱。

概率计算

因此,我们计算成功投掷的概率与这两个测量值相关:

创建广义概率函数

尽管之前的计算相当简单,但当我们概括这些计算并开始考虑仓位或当前仓位不固定时,需要考虑一些因素。

在我们之前的例子中,人 A 在箱子的西南方向,因此角度是一个简单的计算,但是如果我们同样将一个人放在东北方向,那么这是不正确的。此外,因为容器可以放置在任何地方,所以我们需要首先找到人相对于它的位置,而不仅仅是原点,然后用于建立所需的角度计算。

下图总结了这一点,其中我们根据人与箱子的相对位置概括了每个三角计算:

Angle Calculation Rules

记住这个图表,我们创建一个函数,它只从相对于箱子的给定位置计算投掷成功的概率。

然后,我们按照前面的图计算从人到容器的方位,并计算限制在+/- 45 度窗口内的分数。最接近真实方位的投掷得分较高,而较远的投掷得分较低,任何大于 45 度(或小于-45 度)的投掷都是负的,然后被设置为零概率。

最后,如前所示,给定当前位置,总概率与距离和方向相关。

注意:我选择了 45 度作为边界,但是你可以选择改变这个窗口,或者手动调整概率计算,以不同的方式加权方向测量的距离。

我们重新计算了前面的例子,发现结果和预期的一样。

绘制每个状态的概率

现在我们有了这个函数,我们可以很容易地计算和绘制出二维网格中所有点在固定投掷方向上的概率。

概率是由我们在前面的函数中设置的角度定义的,目前是 45 度,但如果需要的话,可以减少或增加,结果会相应地改变。我们可能还想对距离的概率进行不同的缩放。

例如,对于每个 x/y 位置,纸张以 180 度角(正南)投掷的概率如下所示。

所有投掷方向的动画剧情

为了进一步演示这一点,我们可以迭代多个投掷方向,并创建一个交互式动画。代码变得有点复杂,您总是可以简单地使用前面的代码块,并手动更改“throw_direction”参数来探索不同的位置。然而,这有助于探索概率,可以在 Kaggle 笔记本中找到。

[## RL 从头开始第 1 部分:定义环境| Kaggle

编辑描述

www.kaggle.com](https://www.kaggle.com/osbornep/rl-from-scratch-part-1-defining-the-environment)

阶段 2:在概率已知的情况下,为环境寻找最佳策略

基于模型的方法

我们的目标是在每种状态下,通过投掷或向给定方向移动来找到最佳动作。因为我们知道概率,所以我们实际上可以使用基于模型的方法,我们将首先证明这一点,并可以使用值迭代通过以下公式实现这一点:

Value Iteration Update Rules

值迭代从任意函数 V0 开始,并使用以下等式从 k 个阶段的函数得到 k+1 个阶段的函数(https://artint.info/html/ArtInt_227.html)。

Initial Value of Each State

移动动作的计算相当简单,因为我已经定义了保证移动成功的概率(等于 1)。因此,例如,来自状态(-5,-5)的动作(1,1)的 Q 值等于:

Q((-5,-5),MOVE(1,1)) = 1( R((-5,-5),(1,1),(-4,-4))+ gammaV(-4,-4))

现在,回报也全是 0,因此第一次计算的值很简单:

Q((-5,-5),(1,1))= 1 (0+伽马0) = 0

First Q update for Move Actions

第一次更新中的所有移动操作都将以类似方式计算。成功的投掷给系统增加了价值。因此,我们可以计算特定投掷动作的 Q 值。之前,我们发现投掷方向与(-5,-5)成 50 度的概率等于 0.444。因此,此动作的 Q 值会相应更新:

Q((-5,-5),THROW(50)) =

0.444*(R((-5,-5),(50),bin)+gamma * V(bin+))+

(1–0.444)(R((-5,-5),(50),bin) + gammaV(bin-))

再次,奖励被设置为 0,并且容器的正值是 1,而容器的负值是-1。因此,我们有:

Q((-5,-5),THROW(50)) =

0.444(0 +伽玛1) +

(1–0.444)*(0+gamma * 1)= 0.3552–0.4448 =-0.0896

很明显,虽然第一次更新后的移动没有改变初始值,但由于距离和错过的概率,以 50 度投掷更糟。

一旦为所有状态和动作计算了每个 Q(s,a ),每个状态的值 V(s)就被更新为该状态的最大 Q 值。这个过程反复进行,直到结果收敛。

Value-Iteration Update Procedure

对于需要重复的次数没有设定限制,这取决于问题。因为我们的环境如此简单,它实际上在仅仅 10 次更新内就收敛到最优策略。

Convergence of Value-Iteration Updates

我们首先展示了基于投掷或移动的最佳动作,如下图所示。

Optimal Policy Plot v1

改善最佳策略的可视化

尽管图表显示了最佳行动是投掷还是移动,但它并没有告诉我们这些行动的方向。因此,我们将把每个最优动作映射到一个向量 u 和 v,并使用这些来创建一个箭图(https://matplotlib . org/API/_ as _ gen/matplotlib . axes . axes .颤图. html )。

我们定义箭头的比例,并使用它来定义标记为 u 的水平分量。对于移动动作,我们简单地将 x 方向上的移动乘以该因子,对于投掷方向,我们向左或向右移动 1 个单位(说明 0 或 180 度没有水平移动,90 或 270 度没有垂直移动)。

然后,利用一些基本的三角学,水平分量被用于计算垂直分量,其中我们再次考虑了会在计算中引起误差的某些角度。

我们看到一些州有多个最佳行动。那些直接朝北、朝东、朝南或朝西的可以向多个方向移动,而状态(1,1)、(1,-1)、(-1,-1)和(-1,1)可以向容器移动或投掷。

最后,我决定通过导出每个图并传递到一个小动画中来显示每次更新时最优策略的变化。

阶段 3:用强化学习寻找最优策略,其中概率是隐藏的

q 学习算法

我们现在将假设概率对人来说是未知的,因此需要经验来找到最佳行动。

首先,让我们试着找到一个最优的行动,如果这个人从一个固定的位置开始,bin 像以前一样固定在(0,0)。

我们将应用 Q-learning 并用值 0 初始化所有状态-动作对,并使用更新规则:

Q learning Update Rule

我们给算法选择扔在任何 360 度方向(到一个完整的角度)或移动到当前的任何周围位置。因此有 8 个地方可以移动:北方,东北,东方等。

当它选择扔纸时,它将根据它是否击中垃圾箱而获得+1 的正奖励或-1 的负奖励,这一集结束。

需要通过多次反复试验来确定箱子的位置,然后确定是先移动还是从当前位置投掷更好。

Q-学习伪代码

首先,和以前一样,我们用 0 的任意值初始化 Q 表。

现在,每集的开始位置将固定为一个状态,我们还引入了每集动作数量的上限,这样就不会意外地无休止地持续下去。

如果扔出纸,每集自然结束,算法执行的动作由ε-贪婪动作选择程序决定,由此以概率ε和贪婪(当前最大)随机选择动作,否则。为了平衡移动或投掷动作之间的随机选择(因为只有 8 个移动动作,但有 360 个投掷动作),我决定给算法 50/50 的移动或投掷机会,然后从这些动作中随机选择一个动作。

如前所述,随机移动动作不能超出房间的边界,并且一旦发现,我们根据所有可能的后续动作的最大 Q(s’,a)来更新当前 Q(s,a)。例如,如果我们从-9,-9 移动到-8,-8,Q( (-9,-9),(1,1))将根据 Q 的最大值((-8,-8),a)更新所有可能的动作,包括投掷动作。

如果算法投掷该纸,则计算这次投掷的成功概率,并且我们模拟在这种情况下它是成功的并且接收正的终端奖励,还是不成功的并且接收负的终端奖励。

该算法继续更新每个状态-动作对的 Q 值,直到结果收敛。

我们将在下一篇文章中分析不同参数的影响,但现在只介绍一些任意选择的参数:
—次数= 100
—阿尔法= 0.5
—伽马= 0.5
—ε= 0.2
—最大动作= 1000
—pos _ terminal _ reward = 1
—neg _ terminal _ reward =-1

用这些参数运行算法 10 次,我们为状态-5,-5 产生以下“最佳”动作:

显然,这些并不一致,这严重表明这些行动实际上并不是最佳的。因此,我们需要考虑我们选择的参数如何影响输出,以及如何改进结果。

结论

我们在 Python 中从头引入了一个环境,并找到了最佳策略。此外,我已经开始介绍用 Q-learning 寻找最优策略的方法。

我将在后续文章中继续这一点,并通过改变参数来改善这些初始结果。现在,我希望这足以让你开始在这个例子中尝试他们自己的算法。

如果您有任何问题,请随时在下面或 Kaggle 页面上发表评论。

谢谢

哲学(philosophy 的缩写)

强化学习:必要性和挑战

原文:https://towardsdatascience.com/reinforcement-learning-its-necessity-and-challenges-febef1470e9a?source=collection_archive---------1-----------------------

lemme learn ..

简介:

这是我第一篇关于强化学习的博客。过去几个月我一直在学习和应用 RL。我试图通过这篇文章呈现对 RL 及其含义的高度理解。

在深入讨论之前,我们先了解一下什么是强化学习,它与其他机器学习技术有什么不同。

强化学习(RL)是机器学习的一个子领域,其中代理通过与其环境交互,观察这些交互的结果并相应地接收奖励(积极或消极)来学习。这种学习方式模仿了我们人类学习的基本方式。

Reinforcement learning system

必要性和挑战:

当我们走向人工智能(AGI)时,设计一个可以解决多种任务的系统(例如,分类图像,玩游戏..)真的很有挑战性。目前机器学习技术的范围,无论是监督学习还是非监督学习,都擅长在任何时刻处理一项任务。这就限制了 AI 实现通用性的范围。

为了实现 AGI 的目标,RL 要让代理执行许多不同类型的任务,而不是只专攻一种。这可以通过多任务学习和记忆学习来实现。

我们已经看到了 Google Deep Mind 最近在多任务学习方面的工作,其中代理学习识别数字和玩雅达利。然而,当您扩展流程时,这确实是一项非常具有挑战性的任务。学习任务需要大量的训练时间和大量的迭代。

另一个挑战来自代理感知环境的方式。在许多现实世界的任务中,代理没有观察整个环境的范围。这种局部观察使代理人不仅根据当前的观察,而且根据过去的观察采取最佳行动。因此,记住过去的状态并根据当前观察采取最佳行动是 RL 成功解决现实世界问题的关键。

RL 代理总是从探索和开发中学习。RL 是一种基于不断试错的学习,其中代理试图对一个状态应用不同的动作组合,以找到最高的累积奖励。这种探索在现实世界中变得几乎不可能。让我们考虑一个例子,你想让机器人学会在复杂的环境中导航,避免碰撞。当机器人在环境中移动学习时,它会探索新的状态,并采取不同的行动来导航。然而,在现实世界中采取最好的行动是不可行的,因为环境的动态变化非常频繁,并且对于机器人来说学习变得非常昂贵。

因此,为了避免上述问题,在 RL 代理上应用了不同的其他机制来使其学习。很少有像通过模仿想要的行为来学习,通过演示来学习这样的方法正在机器人身上进行尝试,以在模拟中学习环境。然而,通过这种方式,学习变得非常特定于环境,并且它失去了一般化学习的实际目标。

在过去的几个月里,从开放式人工智能和 DeepMind 到人工智能,几乎没有什么积极的进展。开放人工智能的最新发展之一是进化策略(ES) 一种克服许多 RL 缺点的优化技术(【https://blog.openai.com/evolution-strategies/】T2)。DeepMind 的另一个发展是 路径网 是一个新的模块化深度学习(DL)架构(https://arxiv.org/abs/1701.08734)

任何需要手册才能工作的产品都是坏的。埃隆·马斯克

致谢:

我要感谢 David Silver,Google DeepMind 在 youtube 上的教程,Denny Britz,Google Brain 和 Arthur Juliani。

参考文献:

[## Denny britz/强化学习

强化学习-强化学习算法的实现。Python,OpenAI 健身房,Tensorflow。练习…

github.com](https://github.com/dennybritz/reinforcement-learning) [## OpenAI

OpenAI 是一家非营利性的人工智能研究公司,旨在发现和制定通往安全人工智能的道路。

openai.com](https://openai.com) [## 深度思维

解决智能问题,用它让世界变得更美好

deepmind.com](https://deepmind.com)

强化学习第 3 部分:实用强化学习

原文:https://towardsdatascience.com/reinforcement-learning-part-3-practical-reinforcement-learning-e562c4089633?source=collection_archive---------14-----------------------

如果你还没有看过我们强化学习系列的第一部分第二部分,你可以在这里查看,在这里查看。在第 1 部分中,您将学习强化学习的关键概念,这将帮助您更好地理解强化学习。第 2 部分将带您了解强化学习算法的比较和具体考虑。

在这篇文章中,我们将庆祝我们所学到的强化学习!我们将看看人们在强化学习方面做的一些很酷的事情,在强化学习中仍然存在的一些主要障碍,并讨论一些如果你想自己开始从事强化学习的话可以开始使用的资源!

Who knows… Maybe you’ll create the next AI system to defeat humans at games like Google did with AlphaGo!

酷 RL 成就

有了所有的强化学习知识,我们现在对 RL 如何工作以及开发人员在决定如何开发 RL 应用程序时必须考虑的一些因素有了一个很好的基础。我们来过一遍 RL 都实现了哪些很酷的东西。

RL 在 Dota 2 击败人类

OpenAI 开发了一套五个神经网络,它们学会了相互协调,在 RTS 游戏 Dota 2 中击败了真正的人类。2018 年 8 月 5 日,由五个神经网络组成的团队与真实的、人类的、有竞争力的玩家进行了比赛,并赢得了三局两胜。游戏人工智能的巨大成就!

OpenAI’s Five aren’t done yet either. This first competition they held was just the start of what they really hope to do: Compete at an international and professional level. They ended up doing this in late August, which they won one round and then lost against two other professional human competitors. A loss, but in a way, also still a win!

超参数调谐的 RL

谷歌开发了一种使用强化学习的超参数调整方法,他们称之为 AutoML。他们设置了一个问题,并基于潜在的网络突变(动作)进化出新的神经网络,并以新的网络性能的形式获得反馈。

Tweaking hyperparameters to get the best performance out of machine learning models is really hard. Google’s AutoML service can this for us using what we know about reinforcement learning to come up with better parameters and faster.

工业用盆景

Bonsai 是一家很酷的初创公司,最近被微软收购,专注于在工业和企业领域使用 RL。他们的重点是改进控制系统和实时决策,以提高机器人、制造、能源等领域的自动化和效率。

Bonsai’s idea was that we could train industrial grade machinery in simulation using machine learning. By doing so, we mitigate the risk of breaking anything which could cost a company a lot of money.

Pit.ai 了解交易策略

Pit.ai 是一个很酷的团队,它利用 RL 来更好地推理和理解交易算法。他们有一个崇高的使命,即使用 RL 来帮助取代投资管理人员,以帮助降低成本。

Using RL to come up with good trading strategies… Sounds a lot like our example with the stock market. Do you think they frame their tasks as episodic or continuous?

DeepMind 降低冷却成本

使用 RL,谷歌的 DeepMind 帮助其数据中心降低了 40%的冷却成本。

Think about how much 40% is at a Google-level scale… Oh my!

RL 中的障碍

不可否认,强化学习可以做很多很酷的事情。它提供了一种新的思考机器学习的方式;这是处理机器学习问题的不同方式。

这并不意味着这是解决所有问题的最佳方式。强化学习有时可能是解决问题最困难的方式。我们可以通过查看阻止围绕 RL 构建应用程序的一些障碍来最好地理解这一点。

数据

数据对于机器学习至关重要。句号。RL 需要大量数据才能正常工作。想想我们的代理通过马里奥玩。它必须一遍又一遍地玩这个游戏,以学习如何完成最基本的任务。没有所有的游戏数据,我们的代理将永远不会学会玩游戏,更不用说玩好游戏了。这是一个问题,尤其是在难以获得数据的情况下。

Data is a big issue for all machine learning for sure. But where for supervised tasks, sometimes data is simply an input and label pair, RL tasks oftentimes require much more complex data in order to teach systems to do what we wish.

目标是什么

RL 算法需要有目标。因为他们是任务驱动的,他们总是需要努力实现目标,不管是赚最多的钱还是尽可能快地超越水平。在复杂的任务中,“目标是什么”的问题很快变得越来越难回答。如果没有恰当地考虑目标,代理可能会倾向于做一些你不希望它做的事情。

想象一个假设的算法被放置在一个负责保护人类安全的机器人中。假设它运行了一个模拟程序,并得出结论,保证人类安全的最好方法是消灭所有其他人类生命,并使有问题的人类镇静下来。这根本不是我们想要开始的,但这是算法根据其目标、策略和价值函数的定义方式计算出的尽可能长时间保持该人安全的最佳方式。因此,目标定义至关重要。

Making sure our algorithms and agents do what we want and expect them to do is critical for deploying systems in the real world. These are issues that touch security, ethics, safety, and more.

稀疏环境中的复杂任务

这个问题继承了前两个问题的最坏情况。我们如何在一个很少收到奖励信号的环境中,让一个需要学习做非常复杂的事情的智能体?有许多方法可以解决这个问题,例如创建一个复杂的策略来处理复杂的任务,或者将复杂的任务分解为更小、更明显的任务(参见 OpenAI with Dota 2,其中他们制定了代理可以收到的小奖励,这些小奖励自然会导致期望的大奖励)。这仍然是一个巨大的研究领域。

Think about the task of trying to teach a robot how to physically play the piano. This is an incredibly complex task that doesn’t necessarily feature a lot of feedback that can be turned into a reward signal. This would require some major goal engineering, which ties back into our previous issue.

大量的状态和动作

在 Mario 中,代理可以采取的动作数量是有限的。在现实世界中,代理可以采取的动作数量是无限的。可以观察到的环境状态的数量也是如此。代理如何处理这种情况?一个算法如何在数学上表现这一点?这些都是巨大的问题,巨大的研究领域,以及需要更好地理解以制造可以在现实世界中交互的复杂代理的关键事情。

The second we try to deploy an agent into the real world, the stakes are higher, and the problem becomes exponentially more difficult. Even teaching a robot to walk using RL can become very hard.

现在,你可能在想“哇,强化学习可以做这么多很酷的事情,还有这么多很酷的问题需要解决。怎么才能入门?”

考虑到这一点,我找到了一些我认为是学习 RL 的好地方的资源:

  • 强化学习:简介——如果你准备阅读大量的书籍,这是一本很好的书,可以深入了解强化学习背后的理论成分。它是由理查德·萨顿和安德鲁·巴尔托(他们在 RL 方面做了很多工作)写的,真的很好(我自己目前也在研究)。
  • 伦敦大学学院的强化学习课程——这是一门很好学习的课程(主要基于上一本书)。它也有幻灯片和视频讲座!
  • 加州大学伯克利分校——CS 294——这些是加州大学伯克利分校强化学习课程的视频。
  • Udacity 的深度强化学习课程 —感觉你想得到更多的机会?你通过实践学得更好吗?那么尝试 Udacity 的深度强化学习课程可能更适合你!
  • 强化学习 GitHub Repo —这个 Repo 有一系列用 Python 实现的强化学习算法。但更重要的是,它采用了萨顿和巴尔托的书以及 UCL 的视频,并将它们结合成一个带有一些练习的学习计划,以指导您如何使用这两种资源。如果这听起来更像你的速度,你应该检查一下!

结论

我相信,强化学习将会是一种带来机器学习新革命的技术,创造出真正智能的应用程序,使用监督和非监督学习的技术来观察智能体活动的环境。如果强化学习在未来,那将是一个光明的未来!

原载于 2018 年 9 月 5 日recast . ai

基于决策树的强化学习 Q-Learning 简介

原文:https://towardsdatascience.com/reinforcement-learning-q-learning-with-decision-trees-ecb1215d9131?source=collection_archive---------6-----------------------

Photo by Jachan DeVol on Unsplash

强化学习(RL)是机器学习中的一种范式,在这种范式中,计算机学习执行任务,如驾驶车辆玩雅达利游戏在围棋比赛中击败人类,几乎没有人类专家的监督。几个 RL 算法被评为 2017 年最有趣的突破。每个人都对新的可能性感到兴奋。我很兴奋。

然而,有一件事一直困扰着我。几乎所有的 RL 实现都依赖于深度神经网络。

诚然,我喜欢神经网络,但我更喜欢梯度增强树,只要我可以选择。我只是觉得设计、训练和测试神经网络很乏味,评估结果中有很多不确定性和波动。就个人而言,梯度增强树提供了更好的性能(至少在结构化数据集上),同时收敛得更快并给出一致的结果。因此,我开始了用梯度增强树实现 RL(这里是 Q-Learning)的旅程。

理论上,对于 Q-Learning 的底层机器学习算法没有限制。最基本的版本使用表格形式来表示(状态 x 行动 x 预期回报)三元组。但是,因为实际上这个表经常太大,所以我们需要一个模型来近似这个表。该模型可以是任何回归算法。在这个探索中,我尝试了线性回归、支持向量回归、KNN 回归、随机森林等等。相信我,它们都有效(程度不同)。

那么,深度神经网络为什么会在总体上主导 Q-Learning 和 RL 呢?有几个原因:

  1. 部分适合——有了神经网络,你可以要求网络只学习新的经验。即使有了经验回放,你通常也只能用一小部分记忆来训练网络。其他算法不支持部分拟合,必须用整体记忆训练。这导致在存储器变大的后续训练步骤中训练时间过长。
  2. 输入源——如果你的输入源是图像或视频,卷积网络是一个不错的选择。既然你已经在用 CNN 了,用 FCN 来做 Q-Learning 是有意义的。
  3. 文学——因为其他人都是用深度学习来做的,所以万一你卡住了,会有更多的文学。

好的。所以,深度学习是 RL 的灵魂伴侣?别急,我的朋友。

  1. 性能—并非所有问题都涉及非结构化数据。结构化数据是梯度推进的亮点。Kaggle 竞赛被 XGBoost 和它的朋友们所主宰是有充分理由的。
  2. 收敛——梯度增强树通常快速可靠地收敛,不像神经网络需要一点运气。

这两个是优于神经网络的主要优势,这使它们成为强有力的竞争者。但是将 GBT 引入 Q-Learning 可行吗?或者它会不会太慢,太消耗资源,或者对于任务来说表现太差?

在我们继续之前,我想为那些不熟悉强化学习和 Q-Learning 的人提供一些介绍。然而,有很多更好的作家已经优雅地解释了这些话题,所以我将简单地在这里放下链接。

[## 使用 Q-Learning 更深入地研究强化学习

本文是🕹️. tensor flow 深度强化学习课程的一部分点击这里查看教学大纲。

medium.freecodecamp.org](https://medium.freecodecamp.org/diving-deeper-into-reinforcement-learning-with-q-learning-c18d0db58efe) [## 深度 Q-Learning 简介:让我们玩毁灭战士

本文是🕹️. tensor flow 深度强化学习课程的一部分点击这里查看教学大纲。

medium.freecodecamp.org](https://medium.freecodecamp.org/an-introduction-to-deep-q-learning-lets-play-doom-54d02d8017d8) [## 强化学习介绍(DQN 深度 Q 学习)

在今天的文章中,我将向你介绍强化学习的热门话题。在这篇文章之后,你将…

towardsdatascience.com](/cartpole-introduction-to-reinforcement-learning-ed0eb5b58288) [## RL—深度强化学习简介

深度强化学习是从我们的所见所闻中采取最佳行动。不幸的是,强化…

medium.com](https://medium.com/@jonathan_hui/rl-introduction-to-deep-reinforcement-learning-35c25e04c199)

以及梯度增强树上的一些引物。

[## 从零开始的渐变提升

简化复杂的算法

medium.com](https://medium.com/mlreview/gradient-boosting-from-scratch-1e317ae4587d) [## 梯度增强与随机森林

在这篇文章中,我将比较两种流行的集成方法,随机森林(RM)和梯度推进机器…

medium.com](https://medium.com/@aravanshad/gradient-boosting-versus-random-forest-cfa3fa8f0d80) [## 梯度增强和 XGBoost

从我们结束的地方开始,让我们继续讨论不同的 boosting 算法。如果您还没有阅读…

hackernoon.com](https://hackernoon.com/gradient-boosting-and-xgboost-90862daa6c77)

问题定式化

这个项目开始于我对其他算法是否可以用于 Q 学习的纯粹好奇。因此,我们没有触及更深层次的问题,比如实现专门用于强化学习的决策树,或者对性能和速度的更深层次的分析等等。

我们要用一个最基本的 RL 问题来做实验——cart pole v 0。这个环境是由 OpenAI Gym 提供的——一个由各种环境组成的库,用于测试驱动强化学习框架。基本上,手推车上有一根杆子。你可以向左或向右移动。你的目标是尽可能长时间保持杆子不倒。

我从格雷戈·苏尔马那里获得了一个 GitHub 库,他在那里提供了一个 Keras 模型来解决 CartPole 问题。我重用了他的大部分代码——只修改需要修改的部分。我要感谢格雷戈·苏尔马的代码库。

[## gsurma/cartpole

OpenAI 的 cartpole env 解算器。在 GitHub 上创建一个帐户,为 gsurma/cartpole 的发展做出贡献。

github.com](https://github.com/gsurma/cartpole)

让我们一步一步地回顾一下苏尔马的模型是怎么做的。

  1. 掷骰子游戏初始化。记下行动次数。
  2. 在每一个时间步,给我们一个元组 (x1,x2,x3,x4) 。这个元组表示购物车和杆子的当前状态。
  3. 我们告诉游戏我们是想向左还是向右移动。决策来自我们的模型(一般是神经网络),通过询问模型在这种状态下执行每个动作的预期回报。
  4. 在动作执行之后,我们获得一个新的状态和一个奖励。
  5. 我们要求我们的模型预测新状态下每个行动的预期回报。取最高奖励作为处于这个新状态的预期奖励,用一个因子 GAMMA 折现,加到现在的奖励上。这是该状态和动作组合的新 q 值(或预期回报)。
  6. 将状态/动作/奖励/新状态元组放入某种缓冲区或内存中。
  7. 选择全部或部分内存。用回忆的记忆部分拟合模型。
  8. 回到步骤 2。重复,直到我们得到满意的结果。

正如你所看到的,当应用神经网络(或者至少是 Keras)时,整个过程很简单。我们可以要求神经网络对行动的预期回报进行预测,甚至在网络被训练之前(当然,你会得到随机数,但这对于第一轮来说是可以的。)一旦我们计算了新的 q 值,我们就可以从内存中选择一个实例,并将其拟合到神经网络,而不会丢失我们迄今为止已经训练的所有内容(诚然,会有退化。这是首先引入体验重放的基础。)

如果我们想用其他回归器代替神经网络,有几个要求。

  1. 回归器应该支持多标签。我用“应该”而不是“必须”,因为它不是必不可少的。通过几行代码,我们可以分别为每个动作实现一个单独回归器;但是原生的多标签支持使用起来更干净。SKLearn 中的大多数算法本身都支持多标签,因此您几乎可以放弃线性回归、支持向量回归和随机森林。梯度增强树有点棘手,因为流行的库,如 XGBoost、CatBoost 和 LightGBM,不提供多标签支持。幸运的是,我们可以将 SKLearn 的 MultiOutputRegressor 包裹在它们周围,解决这个问题。
  2. 因为 GBT 在打电话预测之前必须是健康的,我们必须为第一轮提供我们自己的预期奖励。这包括首先检查模型是否合适。如果不是这样,我们可以提供一个固定值或一个随机数。我选择提供 0 作为初始值。
  3. 我们不能和 GBT 做部分契合。我们必须构建整个内存以及一组 q 值,并在每个时间步完全重新训练回归变量,而不是一次拟合一个实例。
  4. 因为我们用整个记忆进行再训练,带有陈旧 q 值的陈旧经验永远不会自行消失。与神经网络不同,我们必须将内存的大小限制在一个小得多的数字。我选择了 1000。
  5. 作为一个副作用,我们必须提高最小探索率,以防止学习者陷入困境。很可能我们的小记忆会被低质量的经历填满,所以我们需要继续探索。

下图突出显示了我对原始代码所做的更改。鉴于 LightGBM 的性能和速度,我在实验中使用了它。

Changes I made to the original code

备注 我通过 Jupyter 笔记本运行代码,令人惊讶的是,这比从命令行运行要快。可能与使用 Windows 机器有关。

代码也可以在 GitHub 上找到。

[## 掌上电脑/墨盒

OpenAI 的 cartpole env 解算器。在 GitHub 上创建一个帐户,为 palmbook/cartpole 的开发做出贡献。

github.com](https://github.com/palmbook/cartpole)

结果

它工作了。有时候效果出奇的好。有时,令人沮丧的是,它需要超过 1000 个时间步骤来解决问题。很少,它根本不能解决问题。

这是每次试验解决问题前的时间步骤图。

Number of Rounds before the problem was considered “solved.”

从图中可以清楚地看出,平均而言,该方法不如神经网络。令人欣慰的是,即使在达到第 100 轮之前,LightGBM 也可以通过一些试验解决问题,这实际上意味着它可以从一开始就解决问题。这表明了这种方法的潜力。我相信我们需要更好的体验重放/内存管理来充分利用 Q-Learning 中的 LightGBM,这将使整个代码库变得更加复杂。

至少,我们现在知道 Q-Learning 也可以用其他回归变量来完成。但是为了实用的目的,我想在可预见的将来我会坚持使用神经网络。

未来作品

我喜欢在项目中实施提前停止技术。队列管理是另一个需要改进的领域。我们应该只删除 q 值失效的内存实例,而不是 FIFO。此外,我想知道我们是否可以应用类似的技术,可能结合卷积层,来玩视频游戏。

使用 Python 的强化学习(RL) 101

原文:https://towardsdatascience.com/reinforcement-learning-rl-101-with-python-e1aa0d37d43b?source=collection_archive---------1-----------------------

动态规划(DP)、蒙特卡罗(MC)和时间差分(TD)来求解 gridworld 状态值函数

在这篇文章中,我们将介绍经典 RL 的一些基本概念,这些概念应用于一个名为 gridworld 的非常简单的任务,以解决所谓的状态值函数,该函数告诉我们在某个状态 t 下有多好,这是基于从该状态可以实现的未来奖励。为此,我们将使用三种不同的方法:(1)动态规划,(2)蒙特卡罗模拟和(3)时间差分(TD)。

基础知识

强化学习是一门学科,它试图开发和理解算法,以建模和训练能够与其环境交互的代理,从而最大化特定目标。这个想法非常简单:代理知道它自己的状态 t ,采取动作 A t ,这导致它进入状态 t+1 并接收奖励 R t 。下面的方案总结了这个 St →At →Rt →St+1 →At+1 →Rt+1 →St+2…的迭代过程:

Agent-environment interaction cycle. Source: Reinforcement Learning: An Introduction (Sutton, R., Barto A.).

这个过程的一个例子是一个机器人,它的任务是从地上收集空罐子。例如,机器人每捡一个罐头就可以得到 1 分,其余时间为 0 分。你可以想象机器人的动作可以是多种多样的,例如向前/向后/向左/向右移动,手臂向上/向下伸展等等。如果机器人足够花哨,环境的表现(感知为状态)可以是机器人前面街道的简单图片。机器人可以自由走动并学会捡罐子,为此我们会给每个罐子+1 的正奖励。然后我们可以设置一个终止状态,例如挑选 10 罐(达到奖励= 10)。机器人将在代理-环境循环中循环,直到达到终止状态,这将意味着任务或的结束,众所周知。

grid world 任务

A representation of the gridworld task. Source: Reinforcement Learning: An Introduction (Sutton, R., Barto A.).

gridworld 任务类似于前面提到的例子,只是在这种情况下,机器人必须在网格中移动,以终止状态(灰色方块)结束。每个方格代表一个州。可以采取的动作是向上、向下、向左或向右,我们假设这些动作是确定性的,这意味着每当机器人选择向上时,机器人就会向上。有一个例外,就是机器人碰壁的时候。在这种情况下,最终状态与初始状态相同(不能破壁)。最后,对于每一次对墙的移动或尝试,将给予-1 的奖励,除非初始状态是结束状态,在这种情况下,奖励将是 0,并且不需要采取进一步的行动,因为机器人将会结束游戏。

现在,机器人可以用不同的方式选择动作。机器人选择行动所依据的这些规则就是所谓的策略。在最简单的情况下,想象机器人将以相同的概率向每个方向移动,即有 25%的概率移动到顶部,25%移动到左侧,25%移动到底部,25%移动到右侧。让我们称之为随机政策。遵循这个随机策略,问题是:机器人在网格世界的每个状态/方格中有什么价值或有多好?

动态规划与政策迭代:评估与改进

如果目标是以灰色方块结束,很明显灰色方块旁边的方块更好,因为遵循随机策略,有更高的机会以最终状态结束。但是我们如何量化这些方块/状态中的每一个有多好呢?或者,同样的,我们如何计算一个函数 V(S t )(称为状态值函数),对于每个状态 S t 给我们它的真实值?

先说一下的概念。价值可以计算为从状态 t 可以获得的所有未来奖励的总和。价值和回报之间的直观区别就像幸福和快乐一样。虽然即时的快乐可以令人满足,但它并不能确保长久的快乐,因为它没有考虑到所有未来的回报,它只关心下一个即时的回报。在 RL 中,一个状态的价值是相同的:总价值不仅是眼前的回报,而且是所有未来可以实现的回报的总和。

解决上述状态值函数的一种方法是使用策略迭代,这是一种包含在数学领域动态规划中的算法。该算法显示在下面的框中:

Iterative policy evaluation algorithm. Source: Reinforcement Learning: An Introduction (Sutton, R., Barto A.).

算法的关键是对 V(s)的赋值,你可以在这里找到注释:

Source: edited from Reinforcement Learning: An Introduction (Sutton, R., Barto A.)

这个想法是,我们从一个值函数开始,这个值函数是一个带有零的 4x4 维度(与网格一样大)的数组。现在,我们对每个状态进行迭代,并且我们将它的新值计算为奖励(-1)加上每个邻居状态的值的加权和(s’)。注意两件事:V(s’)是最终/邻居状态 s’的期望值(开始时,期望值为 0,因为我们用 0 初始化 value 函数)。最后, V(s') 乘以一个γ,这就是折现因子。在我们的例子中,我们使用 gamma =1,但是贴现因子的概念是,即时回报(等式中的 r )比未来回报(由s’的值反映)更重要,我们可以调整 gamma 来反映这一事实。

最后,请注意,我们可以一遍又一遍地重复这个过程,其中我们“扫描”并更新所有状态的状态值函数。这些值可以迭代更新,直到达到收敛。事实上,在迭代策略评估算法中,您可以看到我们计算了一些增量,这些增量反映了状态值相对于之前值的变化程度。这些增量随着迭代而衰减,并且应该在无穷远处达到 0。

以下是如何更新值函数的示例:

Source: Reinforcement Learning: An Introduction (Sutton, R., Barto A.)

请注意,在右栏中,随着我们更新状态值,我们现在可以生成越来越有效的策略,直到我们达到机器人必须遵循的最佳“规则”,以尽可能快地结束终止状态。

最后,这里是迭代策略评估和更新的 Python 实现。最后观察当我们达到收敛时,每个状态的增量如何衰减到 0。

蒙特卡罗方法

虽然前面的方法假设我们对环境有完整的了解,但很多时候情况并非如此。蒙特卡罗(MC)方法能够直接从经验事件中学习,而不依赖于环境动力学的先验知识。

术语“蒙特卡洛”通常被广泛用于任何其操作包含显著随机成分的估计方法。

有趣的是,在许多情况下,有可能根据期望的概率分布产生经验样本,但不可能获得显式形式的分布。

下面是根据 MC 估计价值函数的算法:

Source: Reinforcement Learning: An Introduction (Sutton, R., Barto A.)

解决 gridworld 任务的蒙特卡罗方法有些幼稚,但却是有效的。基本上,我们可以从网格的随机点开始产生 n 个模拟,并让机器人随机向四个方向移动,直到达到终止状态。对于每个模拟,我们保存 4 个值:(1)初始状态,(2)采取的行动,(3)收到的奖励和(4)最终状态。最终,模拟只是一个包含这些值的 x 数组的数组, x 是机器人在到达终点状态之前必须走的步数。

现在,从这些模拟中,我们从“体验”数组的末尾开始迭代,并将 G 计算为同一体验中的前一个状态值(由 gamma,折扣因子加权)加上该状态下收到的奖励。然后,我们将 G 存储在一个数组 Returns(St) 中。最后,对于每个状态,我们计算回报率(St)的平均值,并将其设置为特定迭代的状态值。

在这里,您可以找到这种方法的 Python 实现,它应用于前面的相同任务:worldgrid。

请注意,改变伽玛可以减少收敛时间,正如我们在伽玛=1 和伽玛=0.6 的最后两个图中看到的。这种方法好的一面是:

  1. 从技术上讲,如果我们不想的话,我们不必计算所有状态的所有状态值。我们可以只关注一个特定的网格点,并从该初始状态开始所有的模拟,以采样包括该状态的情节,忽略所有其他的。这可以从根本上减少计算费用。
  2. 如前所述,这种方法不需要完全了解环境动态,我们可以直接从经验或模拟中学习。

时差学习

最后,我们将探讨的最后一种方法是时间差分(TD)。据说第三种方法融合了动态规划和蒙特卡罗方法的优点。这里我们列举了它的一些优点:

  1. 作为动态规划方法,在优化初始状态的值函数时,我们使用下一个状态的期望值来丰富预测。这个过程称为引导。
  2. 和蒙特卡洛一样,我们不需要环境动力学的模型,可以直接从经验中学习。
  3. 再者,不像 MC,我们不用等到一集结束才开始学习。事实上,在 TD(0)或单步 TD 的情况下,我们在每一步都在学习。这一点尤为重要,因为:一方面,学习的本质是真正的“在线”,另一方面,我们可以处理没有明确终端状态的任务,学习和无限逼近价值函数(适用于非确定性、非偶发性或时变价值函数)。

以下是使用时间差计算值函数的算法:

Source: Reinforcement Learning: An Introduction (Sutton, R., Barto A.)

这是带有 Python 实现的 jupyter 笔记本

请注意,在这种情况下,调整 alpha 和 gamma 参数对于达到收敛至关重要。

承认

最后,我想提一下,这里的大部分工作都是从安德鲁 g .和理查德 s .的最新版本的书《强化学习:简介》中得到启发或借鉴的,这本书是这些作者在这里公开的惊人的作品。

强化学习:自然主义者、享乐主义者和自律主义者

原文:https://towardsdatascience.com/reinforcement-learning-the-naturalist-the-hedonist-and-the-disciplined-fc335ac9289c?source=collection_archive---------16-----------------------

塑造强化学习的思想史

Embracing the chaos of a biological brain and the order of an electronic one. — Image credit: http://www.gregadunn.com/microetchings/cortical-circuitboard/

对人工智能的追求总是与另一场斗争交织在一起,这场斗争更富有哲理,更浪漫,却不那么有形。对人类智能的理解。

尽管目前监督学习的突破似乎是基于优化的硬件、复杂的训练算法和过于复杂的神经网络架构,但强化学习仍然是一所老派学校。

这个想法很简单:你是一个环境中的学习者。如果我们做一般假设,你有满足自己的目标(我们不都是吗?),然后你执行动作。基于这些行为,环境会以奖励来回应,而你,基于这些奖励,会调整你的行为来最大化你的满意度。

Does RL have limits? “The day will never come when a computer defeats a pro shogi player”, a proclamation by the deceased shogi player Satoshi Murayama, found its refutant in the face of AlphaGo Zero. — Image Credit: https://www.hokusai-katsushika.org/shogi-chess-board.html

没过多久,我们就在生物通过强化学习的能力和人工智能之间找到了联系。早在 1948 年,图灵描述了一个快乐-痛苦系统,该系统遵循几十年后建立的强化学习的当前规则。

智力是适应变化的能力——斯蒂芬·霍金斯

社区的第一次尝试针对的是双陆棋游戏,因为它简单,提供了少量的离散状态和简单的规则。如今,我们有人工智能代理使用强化学习来玩雅达利游戏《我的世界》翻煎饼。那么,我们是如何完成这一切的呢?

简单的答案是深度学习。

这篇文章将冒险给出一个更长的答案。它将探索我们已经使用了几十年的强化学习算法背后的思想来源。我们最近的成功不仅仅是深度神经网络的产物,而是观察、结论和试图理解学习机制的深刻历史。

强化学习是一个起源很难追溯的领域。它的大部分理论基础要归功于控制理论家。马尔可夫决策过程是最优控制问题的离散随机版本,因此几乎所有的强化学习算法都基于控制理论中导出的解决方案,这并不奇怪。

然而,控制理论提供的背景并不足以创造强化学习。我们今天仍在使用的算法需要一些想法,如经典条件反射和时差学习,来形式化学习过程。

如果没有少数好奇的生物学家、心理学家和不墨守成规的计算机科学家,人工智能社区可能不会拥有实现学习的工具。

我们如何在不可预见的情况发生前采取行动?如何采纳我们的行为?环境如何影响我们的行为?我们如何改进?一项技能是如何习得的?

这是一个试错的世界

1898 年,桑代克要么对他的猫非常生气,要么对动物的行为非常好奇。他把它放在一个配有门闩的笼子里,并在外面放了一盘诱人的鱼。那只猫只有拉一下杠杆才能逃出笼子。

猫会有什么反应?

没有推理,没有推论或比较的过程;没有对事物的思考,没有把两两放在一起;没有想法——动物不会想到盒子、食物或它要做的动作。

桑代克观察到,这只猫的行为似乎并不聪明:它开始在盒子里随意移动和行动。只有当它偶然拉动杠杆并释放自己时,它才开始提高逃跑的技巧。

基于这一观察,桑代克提出了一个效应定律,该定律指出,任何伴随着令人愉快的后果的行为都有可能被重复,任何伴随着令人不快的后果的行为都有可能被停止。

这个定律催生了操作性条件作用领域,由斯金纳在 1938 年正式定义。对于强化学习社区来说,它提供了制定代理的理由,这些代理基于奖励和它们与环境的交互来学习策略。

它也为我们提供了一个关于动物学习的新观点,因为效果定律可疑地类似于另一个当时众所周知的定律:自然选择。我们的知性可能只是一种适者生存的想法吗?

然而,有两个特征使得强化学习成为一个独特的过程:

  • 这是选择性的。这使它不同于监督学习,因为一个代理通过比较它们的结果来尝试和选择它们。
  • 它是联想的。这意味着,通过选择找到的替代方案与特定的情况或状态相关联,从而形成代理人的策略。自然选择是选择过程的一个主要例子,但它不是联合的。

我们就是我们反复做的事情。因此,优秀不是一种行为,而是一种习惯。”
亚里士多德

享乐主义者的学习指南

谈到分析人类思维,Klopf 相当简洁:

“人的根本本性是什么?

人是享乐主义者。"

在他备受争议的著作《享乐主义神经元——记忆、学习和智力理论》中, Klopf 运用神经科学、生物学、心理学以及他推理中令人信服的简单性和好奇心来说服我们,我们的神经元是享乐主义者。是的,你的神经元和你一样追求快感。

当面对他那个时代占主导地位的神经元模型,罗森布拉特的感知机(这是今天神经网络的构建模块)时,克洛普夫想知道:

“如果神经元被假设为非目标寻求组件,那么目标寻求大脑功能必须被视为一种涌现现象。这种观点能解释记忆、学习以及更普遍的智力吗?

他提出了一个新的构建模块,称为基本异质状态,作为未来人工智能研究的基础。Klopf 还认为,体内平衡,即追求良好、稳定的状态,并不是复杂系统(如人类和动物)的目的。解释植物的目的可能已经足够好了,但我们可以假设,人类在确保体内平衡后,会追求快乐的最大化,而不是稳定快乐。为什么我们的神经元会不同?

这些想法听起来可能难以置信,但它们可能会撼动人工智能的世界。Klopf 认识到,随着学习研究者几乎完全专注于监督学习,适应性行为的基本方面正在消失。根据 Klopf 的说法,所缺少的是行为的享乐方面,即从环境中获得某种结果的驱动力,控制环境朝着期望的目标发展,远离不期望的目标。

在批评当前控制论原理(机器学习在当时被称为控制论)的广泛章节中,人们可以强调三条攻击路线:

我们应该使用深度神经网络吗?

明确一点,两层足以让 50 年代的网络被称为深度网络。Klopf 似乎对感知器模型感到满意,但他质疑将其置于深度网络中的学习能力。Klopf 提出了一个问题,即使在今天,任何机器学习科学家都无法回避这个问题:

“[…]然而,该算法仅适用于单层自适应网络。许多后来的研究未能为多层网络的更一般情况产生真正可行的确定性自适应机制。一般情况下的中心问题是,当系统行为不适当时,确定任何给定的网络元件应该做什么。这被证明是非常困难的,因为在一个深层网络中,单个元素的大部分输出与系统的最终输出有着高度间接的关系。”

AI 的目的是什么?

Klopf 也质疑人工智能研究的追求。在他试图接近学习的正确目标时,他使用了一个论点,我在 lafter 强化学习研究者中也发现了这个论点:

“生命已经在这个星球上进化了大约 30 亿年。在那段时间里,90%的时间花在进化我们和爬行动物共有的神经基质上。从爬行动物时代开始,到人类的出现,只有相对短暂的 3 亿年。一个关于通向智慧的过程的问题出现了。如果进化过程花了 90%的时间开发神经基质,剩下的 10%制定有效的高级机制,为什么人工智能研究人员试图反过来做呢?”

智力是聪明的吗?

在下面的摘录中,感觉桑代克和克洛普夫是强化学习的伙伴:

还有另一种方式,人工智能研究人员对智力的感知似乎与生命系统现象的本质不一致。[……]在生命系统中,智能经常不是智能的,至少不是研究人员有时看待这一现象的那种智能意义上的智能。更确切地说,生命系统中的智能常常是简单有效的。如果智能生物在日常信息处理中具有“蛮力”的天性,那将会出现很多问题。[……]即使对最聪明的人来说,更聪明的活动形式也是困难的。[……]因此,人们不禁要问,智能与更高级信息处理的联系是否让人工智能研究者对这一现象的看法过于狭隘和狭隘。在短期内,一个更温和的观点会产生更多的理论吗?

巴甫洛夫的狗玩双陆棋

到目前为止,我们可能一直在谈论强化学习,但事实是,这个术语是由巴甫洛夫首先使用的,在巴甫洛夫关于条件反射的专著的 1927 年英译本中。

巴甫洛夫在他著名的实验中观察到的是,当给狗提供食物并且在接近喂食时间时发出声音时,狗学会了将喂食与这种声音联系起来,并且即使在没有食物的情况下,当听到这种声音时也会分泌唾液。

通过这一观察,巴甫洛夫为经典条件反射奠定了基础,这是第一个将时间纳入学习过程的理论。现在,RL 算法主要采用时间差学习,这意味着当计算一个动作的“质量”以做出决定时,我们还会考虑未来的回报。

1989 年,Chris Watkins 开发了 Q-learning,这是最著名的强化学习算法之一,这使得时间差和最优控制线程完全结合在一起。

1992 年,特索罗在玩双陆棋的代理人身上运用了时差学习的概念。这是说服研究界这种类型的机器学习有潜力的时刻和应用。

尽管目前的研究思路集中在深度学习和游戏上,但如果不是一群人在谈论猫、神经元和狗,我们今天就不会有强化学习领域。

可以说,我们从解决双陆棋中获得的回报,直到那一点难以想象的困难任务,激励我们进一步探索强化学习的潜力。这个强化学习的例子怎么样?

强化学习:怪癖

原文:https://towardsdatascience.com/reinforcement-learning-the-quirks-44b0e315fed2?source=collection_archive---------1-----------------------

在过去的几个月里,我一直致力于强化学习,对此我只能说:它是不同的。我所经历的强化学习的常见怪癖和挫折的记录。

位置

作为实习的一部分,我一直在各种开放人工智能体育馆环境中应用 A3C 和 GA3C 算法的变体。在此之前,除了一些入门课程,我没有任何广泛的强化学习经验,所以这对我来说很新鲜。

我很快了解到,强化学习与我之前完成的默认分类和回归任务非常不同——但它非常令人兴奋!让我告诉你我在整个过程中遇到的问题。

时间

在深度强化学习中,训练数据通常是“在工作中”收集的,这意味着代理在没有他的环境的先验知识的情况下开始,然后在与模拟交互时开始收集经验。

这意味着需要一些时间来收集内存缓冲区中的数据,然后需要更多时间来将其传递到算法中并更新网络权重。这可以通过使用异步方法来优化——比如上面提到的 A3C 算法——这使得事情变得更加复杂。这意味着即使一些简单的代理也需要几个小时的培训,而更复杂的系统需要几天甚至几周的时间。

计算能力

NVIDIA AI 工作带来了一些明显的好处——纯粹的无限计算能力。

Two NVIDIA Geforce GTX GPUs

意识到大多数强化学习工作是在 CPU 上完成的就越糟糕。

使用 GA3C 算法,一些权力被转移到 GPU,允许更大和更复杂的网络,但在我的经验中,限制通常来自 CPU,这在深度学习领域的其他领域非常不寻常。

探索与开发

这个最疼。“探索与剥削”似乎是一个非常普遍的问题。基本上,在探索你的环境和采取最好的行动之间有一个权衡。让我们从迷宫的角度来看这个问题。

如果你探索得太多,你的机器人总是会尝试寻找新的方法来更好地解决迷宫。一开始听起来不错,但这也意味着,如果你的机器人找到了解决迷宫的完美方法——它不会相信这是最好的,下次会尝试另一条路线,可能永远不会再找到“最佳方法”。

如果你探索得太少/利用得太多,你的机器人可能会找到一种方法来解决这个迷宫,并会继续走同样的路。这可能意味着它在到达迷宫的核心之前会穿过每一条走廊——但这对它来说已经足够了,它会永远这样做。

根据我的经验,第二种情况发生得更多。我读了由亚瑟·朱利安尼写的这篇关于一些探索技巧的精彩文章,我可以把它推荐给任何尝试 RL 的人。

具有 Keras + OpenAI 的强化学习:演员-评论家模型

原文:https://towardsdatascience.com/reinforcement-learning-w-keras-openai-actor-critic-models-f084612cfd69?source=collection_archive---------0-----------------------

快速回顾

上次在我们的 Keras/OpenAI 教程中,我们讨论了强化学习中一个非常基础的算法:DQN。深度 Q 网络实际上是一个相当新的出现,仅在几年前才出现,所以如果你能够理解并实现这个刚刚在该领域起步的算法,那将是非常不可思议的。与最初的帖子一样,让我们花一点时间来欣赏一下我们取得了多么不可思议的结果:在连续输出空间场景中,从绝对没有关于“获胜”需要什么的知识开始,我们能够探索我们的环境并“完成”试验。

把自己放在这个模拟的情境中。这基本上就像要求你玩一个游戏,没有规则手册或具体的最终目标,并要求你继续玩,直到你赢了为止(这似乎有点残酷)。不仅如此:你可以通过一系列动作达到的可能结果状态是无限的(即连续的观察空间)!然而,DQN 惊人地快速收敛,通过维持和缓慢更新行动的内在价值来解决这个看似不可能的任务。

更加复杂的环境

从之前的登山车环境到钟摆的升级与从横拉杆到登山车的升级非常相似:我们正在从离散的环境扩展到连续的环境。钟摆环境有一个无限的输入空间,这意味着您在任何给定时间可以采取的行动数量是无限的。为什么 DQN 不再适用于这种环境?我们的实现不是完全独立于环境动作的结构吗?

Unlike the MountainCar-v0, Pendulum-v0 poses an even greater challenge by giving us an infinite input space to work with.

虽然的动作无关,但 DQN 基本上是以有限的输出空间为前提的。毕竟,想想我们是如何构建代码的:预测试图在每个时间步(给定当前环境状态)为每个可能的操作分配一个分数,并简单地采取具有最高分数的操作。我们之前已经将强化学习的问题简化为有效地给动作分配分数。但是,如果我们有一个无限的输入空间,这怎么可能呢?我们需要一个无限大的表来记录所有的 Q 值!

Infinite spreadsheets sound pretty far from ideal!

那么,我们如何着手解决这个看似不可能的任务呢?毕竟,我们被要求做一些比以前更疯狂的事情:我们不仅得到了一个没有玩和赢的指令的游戏,而且这个游戏有一个上面有无限按钮的控制器!让我们看看为什么 DQN 被限制在有限数量的行动。

原因源于模型是如何构建的:我们必须能够在每个时间步迭代来更新我们在特定动作上的位置是如何变化的。这就是为什么我们让模型预测 Q 值,而不是直接预测采取什么行动。如果我们做了后者,我们将不知道如何更新模型来考虑预测以及我们对未来预测的回报。因此,基本问题源于这样一个事实,似乎我们的模型已经输出了与所有可能的行动相关的回报的列表计算。相反,如果我们打破这个模式会怎么样?如果我们有两个独立的模型:一个输出期望的动作(在连续空间中),另一个接受动作作为输入,从 dqn 产生 Q 值,会怎么样?这似乎解决了我们的问题,也正是演员-评论家模式的基础!

演员-评论家模式理论

Unlike DQNs, the Actor-critic model (as implied by its name) has two separate networks: one that’s used for doing predictions on what action to take given the current environment state and another to find the value of an action/state

正如我们在上一节中所讲的,整个演员-评论家(AC)方法的前提是有两个相互作用的模型。拥有多个相互作用的神经网络的主题在 RL 和监督学习中越来越相关,即 GANs、AC、A3C、DDQN(决斗 DQN)等。第一次熟悉这些体系结构可能有些令人生畏,但肯定是一次值得的练习:您将能够理解并编写一些处于该领域现代研究前沿的算法!

回到当前的主题,AC 模型有两个恰当命名的组件:演员和评论家。前者考虑当前的环境状态,并从中确定最佳的行动。本质上,这似乎是实现 DQN 的自然方式。批评家在 DQN 中扮演“评估”的角色,他接受环境状态和一个动作,并返回一个表示该动作对该状态有多合适的分数。

想象这是一个有一个孩子(“演员”)和她的父母(“评论家”)的游乐场。这个孩子四处张望,探索这个环境中所有可能的选择,比如滑上滑梯,荡秋千,拔地上的草。父母会看着孩子,根据她所做的,考虑到环境因素,进行批评或补充。父母的决定取决于环境这一事实既重要又直观:毕竟,如果孩子试图在秋千上荡来荡去,得到的赞扬远不如她试图在滑梯上荡来荡去!

简述:链式法则(可选)

你需要理解的理论要点是支撑现代机器学习的一大部分:链式法则。可以毫不夸张地说,链式法则可能是理解实用机器学习的最关键(尽管有些简单)的思想之一。事实上,如果你只是直觉地理解链式法则在概念上的约定,你可能没有什么数学背景。我将花很短的时间来描述链式法则,但是如果你对它感觉很舒服,请随意跳到下一部分,在那里我们实际上看到了开发 AC 模型的实用大纲是什么样子的,以及链式法则如何适应该计划。

A seemingly simple concept probably from your first calculus class, but one that forms the modern basis of practical machine learning, due to the incredible speedup it enabled in backprop and similar algorithms

形象地说,这个等式似乎非常直观:毕竟,只是“取消分子/分母。”然而,这种“直觉解释”有一个主要问题:这种解释中的推理完全是逆向的!重要的是要记住,数学不仅是为了理解概念,也是为了发展直觉符号。因此,人们开发了这个“分数”符号,因为链式法则的行为非常类似于简化分数乘积。所以,试图仅仅通过符号来解释概念的人跳过了一个关键步骤:为什么这个符号是适用的?比如,为什么衍生品会有这样的表现?

The classic series of springs example is actually a pretty direct way you can visualize the chain rule in movement

潜在的概念实际上并不比这个符号更难理解。想象一下,我们有一系列的绳子,在一些固定的点绑在一起,类似于串联弹簧的连接方式。假设你拿着弹簧系统的一端,你的目标是以 10 英尺/秒的速度摇动另一端。你可以以这个速度摇动你的一端,并让它传播到另一端。您可以连接一些中间系统,以较低的速率(即 5 英尺/秒)振动中间连接。在这种情况下,您只需以 2 英尺/秒的速度移动您的末端,因为无论您做什么移动,都将从您移动的位置持续到终点。这是因为物理连接迫使一端的运动进行到底。注意:当然,与任何类比一样,这里也有不一致的地方,但这主要是为了形象化。

同样,如果我们有两个系统,其中一个系统的输出馈入另一个系统的输入,摇动“馈入网络”的参数将会摇动其输出,输出将会传播并被任何进一步的变化放大,直到管道的末端。

AC 型号概述

因此,我们必须开发一个 ActorCritic 类,它与我们以前实现的 DQN 有一些重叠,但是在训练方面更复杂。因为我们需要一些更高级的特性,所以我们必须利用 Keras 所依赖的底层库:Tensorflow。注意:你当然也可以在 Theano 中实现它,但是我过去没有使用过它,所以没有包括它的代码。如果你愿意的话,可以随时向 Theano 提交这段代码的扩展!

模型实施将由四个主要部分组成,这与我们实施 DQN 代理的方式直接相关:

  • 模型参数/设置
  • 培训代码
  • 预测代码

交流参数

首先,只是我们需要的进口品:

import gym
import numpy as np 
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Input
from keras.layers.merge import Add, Multiply
from keras.optimizers import Adam
import keras.backend as Kimport tensorflow as tfimport random
from collections import deque

这些参数与 DQN 的参数非常相似。毕竟,除了在两个独立的模块中,这种演员兼评论家的模式必须做与 DQN 完全相同的任务。我们还继续使用我们在《DQN 邮报》中讨论过的“目标网络黑客”来确保网络成功收敛。唯一的新参数被称为“tau ”,并且涉及在这种情况下目标网络学习如何发生的微小变化:

class ActorCritic:
    def __init__(self, env, sess):
        self.env  = env
        self.sess = sess self.learning_rate = 0.001
        self.epsilon = 1.0
        self.epsilon_decay = .995
        self.gamma = .95
        self.tau   = .125
        self.memory = deque(maxlen=2000)

tau 参数的确切使用将在随后的训练部分中详细解释,但其本质上起着从预测模型逐渐转换到目标模型的作用。现在,我们到达感兴趣的要点:定义模型。如上所述,我们有两个独立的模型,每个模型都与自己的目标网络相关联。

我们从定义演员模型开始。参与者模型的目的是,给定环境的当前状态,确定要采取的最佳行动。再一次,这个任务有给我们的数字数据,这意味着除了我们到目前为止使用的简单的密集/全连接层之外,没有空间或需要在网络中涉及任何更复杂的层。因此,演员模型是一系列完全连接的层,从环境观察映射到环境空间中的一个点:

def create_actor_model(self):
        state_input = Input(shape=self.env.observation_space.shape)
        h1 = Dense(24, activation='relu')(state_input)
        h2 = Dense(48, activation='relu')(h1)
        h3 = Dense(24, activation='relu')(h2)
        output = Dense(self.env.action_space.shape[0],  
            activation='relu')(h3)

        model = Model(input=state_input, output=output)
        adam  = Adam(lr=0.001)
        model.compile(loss="mse", optimizer=adam)
        return state_input, model

主要的区别是我们返回一个对输入层的引用。这一点的原因在本节结束时会更加清楚,但简单地说,这是为了我们如何以不同的方式处理 actor 模型的训练。

演员模型的棘手之处在于决定如何训练它,这就是链式法则发挥作用的地方。但在我们讨论之前,让我们想想为什么它与标准的评论家/DQN 网络培训有所不同。毕竟,我们不就是要像 DQN 的情况一样,根据当前的状态来拟合模型,并根据当前和贴现的未来回报来拟合最佳行动吗?问题在于:如果我们能够做到我们所要求的,那么这将是一个解决的问题。问题在于我们如何决定采取什么样的“最佳行动”,因为现在在评论家网络中 Q 分数是分开计算的。

因此,为了克服这一点,我们选择了另一种方法。我们本质上是在爬山,而不是找到“最佳选择”并适应它。对于那些不熟悉这个概念的人来说,爬山是一个简单的概念:从你当地的视点出发,确定最陡的倾斜方向,然后朝那个方向递增。换句话说,爬山就是试图通过简单地做一些简单的事情,并遵循局部最大值的方向来达到全局最大值。有些情况下,你可以想象这是完全错误的,但通常情况下,它在实际情况下工作得很好。

因此,我们希望使用这种方法来更新我们的演员模型:我们希望确定(演员模型中)参数的什么变化会导致 Q 值的最大增加(由 critic 模型预测)。由于行动者模型的输出是动作,而批评家基于环境状态+动作对进行评估,因此我们可以看到链式规则将如何发挥作用。我们想看看改变 actor 的参数将如何改变最终的 Q,使用 actor 网络的输出作为我们的“中间链接”(下面的代码都在“ init(self) ”方法中):

 self.actor_state_input, self.actor_model = \
            self.create_actor_model()
        _, self.target_actor_model = self.create_actor_model() self.actor_critic_grad = tf.placeholder(tf.float32, 
            [None, self.env.action_space.shape[0]]) 

        actor_model_weights = self.actor_model.trainable_weights
        self.actor_grads = tf.gradients(self.actor_model.output, 
            actor_model_weights, -self.actor_critic_grad)
        grads = zip(self.actor_grads, actor_model_weights)
        self.optimize =  tf.train.AdamOptimizer(
            self.learning_rate).apply_gradients(grads)

我们看到,这里我们保持模型权重和输出(动作)之间的梯度。我们还通过否定自我来缩放它。actor_critic_grad(因为我们想在这种情况下做梯度上升),它由一个占位符保存。对于不熟悉 Tensorflow 或第一次学习的人,占位符在运行 Tensorflow 会话时充当“输入数据”的角色。我不会详细说明它是如何工作的,但是 tensorflow.org 教程很好地介绍了这些材料。

转到评论家网络,我们基本上面临着相反的问题。也就是说,网络定义稍微复杂一些,但是它的训练相对简单。批评家网络旨在将环境状态和行为作为输入,并计算相应的估价。我们通过一系列完全连接的层来实现这一点,中间有一层在组合成最终 Q 值预测之前将两者合并:

def create_critic_model(self):
        state_input = Input(shape=self.env.observation_space.shape)
        state_h1 = Dense(24, activation='relu')(state_input)
        state_h2 = Dense(48)(state_h1)

        action_input = Input(shape=self.env.action_space.shape)
        action_h1    = Dense(48)(action_input)

        merged    = Add()([state_h2, action_h1])
        merged_h1 = Dense(24, activation='relu')(merged)
        output = Dense(1, activation='relu')(merged_h1)
        model  = Model(input=[state_input,action_input], 
            output=output)

        adam  = Adam(lr=0.001)
        model.compile(loss="mse", optimizer=adam)
        return state_input, action_input, model

值得注意的要点是我们处理输入和返回内容的不对称。对于第一点,与动作相比,我们在环境状态输入上有一个额外的 FC(全连接)层。我之所以这样做,是因为这是这些交流网络的推荐架构,但在两个输入端都加上 FC 层的情况下,它可能同样工作良好(或稍差)。至于后一点(我们返回的内容),我们需要保留对输入状态和动作的引用,因为我们需要在更新参与者网络时使用它们:

 self.critic_state_input, self.critic_action_input, \
            self.critic_model = self.create_critic_model()
        _, _, self.target_critic_model = self.create_critic_model() self.critic_grads = tf.gradients(self.critic_model.output, 
            self.critic_action_input)

        # Initialize for later gradient calculations
        self.sess.run(tf.initialize_all_variables())

这里我们设置要计算的缺失梯度:关于动作权重的输出 Q。这在训练代码中被直接调用,正如我们现在将要研究的。

交流训练

这个代码与 DQN 不同的最后一个主要部分是实际的训练。然而,我们确实利用了同样的基本结构,从记忆中提取情节并从中学习。由于我们有两种训练方法,我们将代码分成不同的训练函数,明确地称它们为:

def train(self):
        batch_size = 32
        if len(self.memory) < batch_size:
            return rewards = []
        samples = random.sample(self.memory, batch_size)
        self._train_critic(samples)
        self._train_actor(samples)

现在我们定义两种训练方法。然而,这与 DQN 的情况非常相似:我们只是找到了贴现的未来奖励和培训。唯一的区别是,我们正在对状态/动作对进行训练,并使用 target_critic_model 来预测未来的回报,而不是演员:

 def _train_critic(self, samples):
        for sample in samples:
            cur_state, action, reward, new_state, done = sample
            if not done:
                target_action = 
                    self.target_actor_model.predict(new_state)
                future_reward = self.target_critic_model.predict(
                    [new_state, target_action])[0][0]
                reward += self.gamma * future_reward
            self.critic_model.fit([cur_state, action], 
                reward, verbose=0)

至于演员,我们很幸运地做了之前所有的努力!我们已经设置了梯度在网络中的工作方式,现在只需用我们遇到的动作和状态来调用它:

def _train_actor(self, samples):
        for sample in samples:
            cur_state, action, reward, new_state, _ = sample
            predicted_action = self.actor_model.predict(cur_state)
            grads = self.sess.run(self.critic_grads, feed_dict={
                self.critic_state_input:  cur_state,
                self.critic_action_input: predicted_action
            })[0] self.sess.run(self.optimize, feed_dict={
                self.actor_state_input: cur_state,
                self.actor_critic_grad: grads
            })

如前所述,我们利用了目标模型。因此,我们必须在每个时间步更新它的权重。然而,我们只是缓慢地这样做。更具体地,我们通过分数selfτ保留目标模型的值,并将其更新为相应的模型权重余数(1-selfτ)分数。我们对演员/评论家都这样做,但下面只给出了演员(你可以在帖子底部的完整代码中看到评论家):

def _update_actor_target(self):
        actor_model_weights  = self.actor_model.get_weights()
        actor_target_weights =self.target_critic_model.get_weights()

        for i in range(len(actor_target_weights)):
            actor_target_weights[i] = actor_model_weights[i]
        self.target_critic_model.set_weights(actor_target_weights

交流预测

这与我们在 DQN 的做法相同,因此没有太多关于其实施的讨论:

def act(self, cur_state):
  self.epsilon *= self.epsilon_decay
  if np.random.random() < self.epsilon:
   return self.env.action_space.sample()
  return self.actor_model.predict(cur_state)

预测码

预测代码也与以前的强化学习算法非常相似。也就是说,我们只需重复试验,并在代理上调用预测、记忆和训练:

def main():
    sess = tf.Session()
    K.set_session(sess)
    env = gym.make("Pendulum-v0")
    actor_critic = ActorCritic(env, sess)

    num_trials = 10000
    trial_len  = 500

    cur_state = env.reset()
    action = env.action_space.sample()
    while True:
        env.render()
        cur_state = cur_state.reshape((1, 
            env.observation_space.shape[0]))
        action = actor_critic.act(cur_state)
        action = action.reshape((1, env.action_space.shape[0]))

        new_state, reward, done, _ = env.step(action)
        new_state = new_state.reshape((1, 
            env.observation_space.shape[0]))

        actor_critic.remember(cur_state, action, reward, 
            new_state, done)
        actor_critic.train()

        cur_state = new_state

完整代码

这里是使用 AC(演员-评论家)在“钟摆-v0”环境下进行训练的完整代码!

好家伙,那很长:谢谢你从头到尾读完(或者至少略读)!敬请关注下一期 Keras+OpenAI 教程!

评论并点击下面❤️以示支持!

带有 Keras + OpenAI 的强化学习:DQNs

原文:https://towardsdatascience.com/reinforcement-learning-w-keras-openai-dqns-1eed3a5338c?source=collection_archive---------0-----------------------

快速回顾

上次在我们的 Keras/OpenAI 教程中,我们讨论了一个将深度学习应用于强化学习上下文的非常基本的例子。回想起来,这真是一场不可思议的演出!如果你查看训练数据,随机机会模型通常只能执行中值 60 步。然而,通过对这些看起来非常普通的数据进行训练,我们能够“击败”环境(即获得> 200 步的性能)。这怎么可能呢?

对此我们可以有一个直观的感受。让我们想象一下我们用作训练数据的完全随机序列。任何两个序列都极不可能彼此高度重叠,因为它们完全是随机生成的。然而,有一些关键特征在成功的试验之间是共同的,例如当杆子向右倾斜时,推车向右推,反之亦然。因此,通过在所有这些试验数据上训练我们的神经网络,我们提取了促成它们成功的共有模式,并能够消除导致它们独立失败的细节。

也就是说,我们本周考虑的环境比上周要困难得多:登山车。

更复杂的环境

尽管看起来我们应该能够应用与上周应用的技术相同的技术,但这里有一个关键特征使得这样做不可能:我们不能生成训练数据。与非常简单的横翻筋斗的例子不同,采取随机的动作通常只会导致我们在山脚下结束试验。也就是说,我们有几个试验结果都是一样的,最后都是 200。这对于用作训练数据实际上是无用的。想象一下,你在一个班级里,不管你在试卷上写了什么答案,你都得了零分!你将如何从这些经历中学习?

Random inputs for the “MountainCar-v0” environment does not produce any output that is worthwhile or useful to train on

与此一致,我们必须找到一种方法来逐步改善以前的试验。为此,我们使用一个最基本的强化学习的垫脚石:Q-learning!

DQN 理论背景

Q-learning(顺便说一下,它不代表任何东西)的核心是创建一个“虚拟表”,说明在给定环境的当前状态下,每个可能的行为会获得多少奖励。让我们一步一步地分解它:

You can imagine the DQN network as internally maintaining a spreadsheet of the values of each of the possible actions that can be taken given the current environment state

我们所说的“虚拟表”是什么意思想象一下,对于输入空间的每一种可能的配置,您有一个表,为您可以采取的每一种可能的行动分配一个分数。如果这是神奇的可能,那么对你来说“战胜”环境将是极其容易的:简单地选择得分最高的行动!关于这个分数有两点需要注意。首先,这个分数通常被称为“Q 分数”,这就是整个算法名称的来源。第二,与任何其他分数一样,这些 Q 分数在它们的模拟环境之外没有意义。也就是说,它们没有的绝对意义,但这完全没问题,因为我们只需要它来做比较。

那么,为什么我们需要虚拟表用于的每个输入配置呢?为什么我们不能用一张桌子来统治所有人呢?原因是这样做没有意义:这就等于说,在谷底时采取的最佳行动正是你站在左斜坡最高点时应该采取的行动。

现在,我所描述的(为每个输入配置维护一个虚拟表)的主要问题是这是不可能的:我们有一个连续(无限)的输入空间!我们可以通过离散化输入空间来解决这个问题,但这似乎是一个非常粗糙的解决方案,我们在未来的情况下会反复遇到这个问题。那么,我们如何解决这个问题呢?通过将神经网络应用于这种情况:这就是 DQN 的 D 的来源!

DQN 代理

因此,我们现在已经把问题简化为找到一种方法,在给定当前状态的情况下,给不同的动作分配 Q 分数。当使用任何神经网络时,这是一个非常自然的第一个问题的答案:我们的模型的输入和输出是什么?对于这个模型,您需要理解的数学范围是下面的等式(不要担心,我们会分解它):

如前所述,q 代表给定当前状态(s)和所采取的行动(a)时由我们的模型估计的值。然而,目标是确定一个状态的总值。我这么说是什么意思?的总体值是,既是你将获得的即时回报又是你在该职位上未来将获得的预期回报。也就是说,我们要考虑一个事实,即一个职位的价值往往不仅反映其眼前的收益,还反映其所能实现的未来收益(该死,深)。在任何情况下,我们都会对未来的回报进行贴现,因为如果我比较两种情况,在这两种情况中,我期望得到 100 美元,其中一种是在未来,我将总是选择目前的交易,因为未来的交易在我做交易和我收到钱之间可能会发生变化。伽马因子反映了该州预期未来回报的折余值。

就是这样:这就是我们需要的所有数学知识!是时候开始写代码了!

DQN 代理实现

深度 Q 网络围绕着持续学习,这意味着我们不会简单地积累一堆试验/训练数据并将其输入模型。相反,我们通过运行试验来创建训练数据,并在运行试验后直接将这些信息输入其中。如果这一切现在看起来有些模糊,不要担心:是时候看看关于这一点的一些代码了。代码主要围绕着定义一个 DQN 类,算法的所有逻辑都将在这个类中实现,并且我们为实际的训练公开一组简单的函数。

DQN 超参数

首先,我们将讨论一些与 dqn 相关的参数。它们中的大多数是大多数神经网络实现的标准:

class DQN:
    def __init__(self, env):
        self.env     = env
        self.memory  = deque(maxlen=2000)

        self.gamma = 0.95
        self.epsilon = 1.0
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.learning_rate = 0.01

让我们一步一步地看完这些。第一个是简单的环境,当我们需要在创建模型时引用形状时,我们提供它是为了方便。“记忆”是 DQNs 的关键组成部分:如前所述,试验用于持续训练模型。然而,我们不是在试验出现时进行训练,而是将它们添加到记忆中,并在记忆的随机样本上进行训练。为什么要这样做,而不只是将最近的 x 次试验作为我们的“样本”进行训练原因有些微妙。想象一下,我们只是将最近的试验作为样本进行训练:在这种情况下,我们的结果将只学习它最近的行动,这可能与未来的预测没有直接关系。特别是在这种环境下,如果我们沿着斜坡的右侧向下移动,那么对最近试验的训练将需要对您向右上坡时的数据进行训练。但是,这与确定在你即将面临的爬上左山坡的场景中采取什么行动完全没有关系。因此,通过采取随机样本,我们不会偏向我们的训练集,而是理想地了解如何同样好地扩展我们会遇到的所有环境。

因此,我们现在讨论模型的超参数:伽马、ε/ε衰减和学习速率。第一个是未来回报折旧因素(<1) discussed in the earlier equation, and the last is the standard learning rate parameter, so I won’t discuss that here. The second, however, is an interesting facet of RL that deserves a moment to discuss. In any sort of learning experience, we always have the choice between exploration vs. exploitation. This isn’t limited to computer science or academics: we do this on a day to day basis!

Consider the restaurants in your local neighborhood. When was the last time you went to a new one? Probably a long time ago. That corresponds to your shift from 探索开发):你不去寻找新的更好的机会,而是满足于你在过去的经历中找到的最好的机会,并从那里最大化你的效用。相比之下,当你搬进你的房子时:那时,你不知道什么餐馆是好的或不好的,所以被诱惑去探索你的选择。换句话说,学习有一个明显的趋势:在你没有意识到的时候探索你所有的选择,一旦你对其中一些有了看法,就逐渐转向利用。同样,我们希望我们的模型能够捕捉到这种自然的学习模式,而 epsilon 就扮演了这一角色。

ε表示我们将致力于探索的时间比例。也就是说,试验的一小部分selfε,我们将简单地采取随机行动,而不是我们预测在那种情况下最好的行动。如前所述,在我们对该问题形成稳定的估值之前,我们希望在开始时更多地这样做,因此在开始时将ε初始化为接近 1.0,并在每个连续的时间步将其衰减某个分数< 1。

DQN 车型

在上面的 DQN 初始化中,有一个关键的东西被排除在外:用于预测的实际模型!就像在我们最初的 Keras RL 教程中一样,我们直接以数字向量的形式给出输入和输出。因此,在我们的网络中,除了完全连接的层之外,没有必要采用更复杂的层。具体来说,我们将模型定义为:

def create_model(self):
        model   = Sequential()
        state_shape  = self.env.observation_space.shape
        model.add(Dense(24, input_dim=state_shape[0], 
            activation="relu"))
        model.add(Dense(48, activation="relu"))
        model.add(Dense(24, activation="relu"))
        model.add(Dense(self.env.action_space.n))
        model.compile(loss="mean_squared_error",
            optimizer=Adam(lr=self.learning_rate))
        return model

并使用它来定义模型和目标模型(解释如下):

def __init__(self, env):
        self.env     = env
        self.memory  = deque(maxlen=2000)

        self.gamma = 0.95
        self.epsilon = 1.0
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.learning_rate = 0.01
        self.tau = .05 self.model = self.create_model()
        # "hack" implemented by DeepMind to improve convergence
        self.target_model = self.create_model()

事实上,有两个独立的模型,一个用于预测,一个用于跟踪“目标值”,这绝对是违反直觉的。明确地说,模型( self.model )的角色是对要采取的行动进行实际预测,而目标模型( self.target_model )跟踪我们希望我们的模型采取的行动。

为什么不采用一种模式来实现这两种功能呢?毕竟,如果有东西在预测要采取的行动,难道不应该隐含地决定我们想要我们的模型采取什么模型吗?这实际上是 DeepMind 在深度学习中开发的那些“奇怪的技巧”之一,用于在 DQN 算法中实现收敛。如果你使用一个单一的模型,它可以(并且经常)在简单的环境中收敛(比如横竿)。但是,它在这些更复杂的环境中不收敛的原因是因为我们如何训练模型:如前所述,我们正在“动态地”训练它

因此,我们在每个时间步进行训练,如果我们使用单一网络,也将在每个时间步改变“目标”。想想那会有多混乱!这就像一个老师告诉你去完成 pg。6,当你读完一半的时候,她把它改成了 pg。当你完成一半的时候,她让你做 pg。21!因此,这由于缺乏使用优化器的明确方向而导致缺乏收敛,即梯度变化太快而无法稳定收敛。因此,作为补偿,我们有一个变化较慢的网络来跟踪我们的最终目标,并努力实现这些目标。

DQN 培训

训练包括三个主要步骤:记忆、学习和重新定位目标。第一个基本上只是随着我们经历更多的试验而增加记忆:

def remember(self, state, action, reward, new_state, done):
        self.memory.append([state, action, reward, new_state, done])

这里没有什么值得注意的,除了我们必须存储 done 阶段,以便稍后更新奖励函数。转到 DQN 的主体,我们有火车功能。这是我们利用我们储存的记忆,并从我们过去看到的东西中积极学习的地方。我们首先从整个内存中抽取一个样本。从那以后,我们对每个样品进行不同的处理。正如我们在前面的等式中看到的,我们希望将 Q 函数更新为当前奖励和预期未来奖励(按 gamma 折旧)之和。在我们处于试验末期的情况下,没有这样的未来奖励,所以这种状态的全部价值只是我们当前收到的奖励。然而,在非终结状态下,我们希望看到如果我们能够采取任何可能的行动,我们将获得的最大回报是什么,从中我们得到:

def replay(self):
        batch_size = 32
        if len(self.memory) < batch_size: 
            return samples = random.sample(self.memory, batch_size)
        for sample in samples:
            state, action, reward, new_state, done = sample
            target = self.target_model.predict(state)
            if done:
                target[0][action] = reward
            else:
                Q_future = max(
                    self.target_model.predict(new_state)[0])
                target[0][action] = reward + Q_future * self.gamma
            self.model.fit(state, target, epochs=1, verbose=0)

最后,我们必须重新定位我们的目标,简单地将权重从主模型复制到目标模型中。然而,与主训练方法不同,此目标更新的调用频率较低:

def target_train(self):
        weights = self.model.get_weights()
        target_weights = self.target_model.get_weights()
        for i in range(len(target_weights)):
            target_weights[i] = weights[i]
        self.target_model.set_weights(target_weights)

DQN 行动

最后一步是简单地让 DQN 实际执行期望的动作,该动作基于给定的ε参数在采取随机动作和基于过去训练的动作之间交替,如下所示:

def act(self, state):
        self.epsilon *= self.epsilon_decay
        self.epsilon = max(self.epsilon_min, self.epsilon)
        if np.random.random() < self.epsilon:
            return self.env.action_space.sample()
        return np.argmax(self.model.predict(state)[0])

培训代理

现在,我们开发的复杂代理自然会对代理进行培训。我们必须实例化它,将我们遇到的经验输入它,训练代理,并更新目标网络:

def main():
    env     = gym.make("MountainCar-v0")
    gamma   = 0.9
    epsilon = .95 trials  = 100
    trial_len = 500 updateTargetNetwork = 1000
    dqn_agent = DQN(env=env)
    steps = []
    for trial in range(trials):
        cur_state = env.reset().reshape(1,2)
        for step in range(trial_len):
            action = dqn_agent.act(cur_state)
            env.render()
            new_state, reward, done, _ = env.step(action) reward = reward if not done else -20
            print(reward)
            new_state = new_state.reshape(1,2)
            dqn_agent.remember(cur_state, action, 
                reward, new_state, done)

            dqn_agent.replay()
            dqn_agent.target_train() cur_state = new_state
            if done:
                break
        if step >= 199:
            print("Failed to complete trial")
        else:
            print("Completed in {} trials".format(trial))
            break

完整代码

这里是使用 DQN 在“MountainCar-v0”环境下进行训练的完整代码!

敬请关注下一期 Keras+OpenAI 教程!

评论并点击下面❤️以示支持!

简介:用 OpenAI Gym 强化学习

原文:https://towardsdatascience.com/reinforcement-learning-with-openai-d445c2c687d2?source=collection_archive---------0-----------------------

强化学习快速入门& OpenAI 健身房的基础知识。欢迎使用导航和驾驶任务实用 RL 入门指南。

了解基本的 goto 概念,快速开始强化学习,并学习使用 OpenAI gym 测试您的算法,以获得以研究为中心的可重复结果。

本文首先向您介绍强化学习的基础知识、其当前的进步以及一个有点详细的自动驾驶实际用例。在那之后,我们开始学习代码,并了解 OpenAI Gym,这是一个经常被研究人员用于标准化和基准测试结果的工具。当编码部分到来时,请打开您的终端,准备好动手操作。一个节省时间的提示:如果你想跳过基础,只想直接尝试开放式人工智能健身房,你可以直接跳到“概念理解”部分。

Earlier behavioral psychology experiments somewhat did pave the way for current RL movement in computer science by providing strong theoretical understanding behind the agent’s motivation. Image Courtesy: verywell

这里有什么区别?

主要有三类学习:监督学习、非监督学习和强化学习。让我们看看它们之间的基本区别。在监督学习中,我们试图预测一个目标值或类,其中用于训练的输入数据已经被分配了标签。而无监督学习使用未标记的数据来查看模式以形成聚类,或者进行 PCA/异常检测。RL 算法类似于寻找最佳方法以获得最大回报的优化程序,即给出获胜策略以实现目标。

Consider a Banking Use Case of Different Learning Types. Image Courtesy: Preydata

在强化学习中,有多种范例以自己的方式实现这种成功的策略。在复杂的情况下,计算精确的获胜策略或精确的奖励价值函数变得非常困难,特别是当我们的代理人开始从互动中学习而不是从先前获得的经验中学习时。例如,一只狗发现它最喜欢的玩具藏在新房子里。这只狗会搜索房子,并根据它的互动得到一个关于房子示意图的大概想法。但是,仍然有一个很好的机会,如果它位于一个新的未探索的位置,狗会发现很难再找到隐藏的玩具。

这种基于交互的学习通常也被称为无模型学习,其中代理不具有环境的确切知识,即代理不存储状态-动作概率转移函数的知识。它试图接近成功的策略(即政策)或回报-价值收益(即价值函数)。在主人的房子里寻找他的隐藏玩具的同一只狗将具有先前的经验,即先前的环境知识,并且将在房子内的任何位置舒适地寻找玩具。这种寻找隐藏玩具的学习在 RL 中被称为基于模型的学习

强化学习:导论

根据强化学习的定义,一个主体在给定的环境中以连续或离散的方式采取行动,以最大化编码在其中的某种回报概念。听起来太深奥了,但它的研究基础可以追溯到经典的行为主义心理学、博弈论、优化算法等。但是,对我们有好处的是,已经为我们做了很多‘搭建舞台’的工作,让我们直接进入问题公式化的世界,发现新事物。

本质上,其中最重要的是,在完全已知/可观测的确定性环境中,智能体的强化学习场景可以被公式化为动态规划问题。从根本上说,这意味着代理人必须以系统的方式执行一系列步骤,以便它能够学习理想的解决方案,并从奖励值中获得指导。用数学术语表达这种情况的方程被称为贝尔曼方程,我们将在某个时候看到它的作用。

It takes into account some initial choices and future choices to come to formulate decision problems at a certain point.

代理和环境

在进一步理解关于 RL 的技术细节之前,让我们首先定性地正式定义主体环境的概念。环境是智能体的世界,它通过在其上执行给定的动作来改变智能体的状态。智能体是通过传感器感知环境并用执行器执行动作的系统。在下面的情况中,Homer(左)和 Bart(右)是我们的 代理 ,世界是他们的 环境 。他们在其中采取行动,并通过获得快乐或满足作为回报来改善他们的存在状态。

Positive and Negative rewards increase and decrease the tendency of a given behavior respectively. Eventually leading to better results in that environment over a period of time. Image Courtesy: psychestudy

最近的进展和范围

从 IBM 的深蓝 v/s Kasparov 以来最受欢迎的游戏系列开始,它为 AI 创造了巨大的宣传。以及围棋比赛系列中 AlpaGo v/s Lee Sedol 对于深度强化学习智能体的类人感知。控制一个棋盘配置比宇宙中的原子还要多的游戏来对抗一个 den 9 master 显示了这样的智能系统所拥有的力量。此外,最近 RL 的研究突破和用 OpenAI 的 Dota 机器人战胜世界职业选手也值得称赞。随着代理人接受处理如此复杂和动态环境的训练,掌握这些游戏是测试人工智能代理人处理非常复杂的类似等级的情况的极限的一个例子。就应用而言,像无人驾驶汽车、智能无人机这样已经很复杂的应用正在现实世界中运行。

我们再了解一些强化学习的基础知识,然后从 OpenAI 健身房开始做自己的代理。之后,我会建议你向深度学习迈进,处理更复杂的情况。所有 RL 应用的范围超出想象,可以应用于许多领域,如时间序列预测、医疗保健、供应链自动化等。但是,这里我们将讨论自动驾驶汽车和导航任务中最受欢迎的应用用例之一。

Got the reference ?

一遍又一遍地在同一状态上运行算法的独特能力有助于它学习特定状态的最佳行动,以前进到理想的下一个状态,这本质上相当于打破时间的构造,让人类几乎在任何时间都可以获得无限的学习经验。

Restricting Lookaheads with Monte Carlo Look Search Tree: AlphaGo must restrict Breath and Depth of search among all board configurations with heuristics information supplied by neural network training and determining winning policy for max reward. Image Courtesy: ajudaily

概念理解

以 RL 为框架,agent 通过一定的动作来改变 agent 的状态,每个动作都与奖励值相关联。它还使用一个策略来确定它的下一个动作,该策略由一系列步骤组成,这些步骤将状态-动作对映射到计算出的奖励值。策略可以定性地定义为代理在给定时间的行为方式。现在,策略可以是确定性的和随机的,找到一个最优策略是解决给定任务的关键。

同样,不同动作在不同状态会有不同的关联奖励值就像口袋坦克游戏中的“开火”命令一样不能总是有相同的奖励值与之相关,因为有时最好保留一个战略上有利的位置。为了以有计划的方式处理这种具有如此巨大组合的复杂动态问题,我们需要一个 Q 值(或动作值)表,该表存储一个 映射状态-动作对以进行奖励。

Depending on terrain and position along with power combinations being available our reward values will vary even after being present in the same state.

现在,将 RL 环境中的环境定义为功能组件,它简单地将给定状态下的动作作为输入,并返回与动作-状态对相关联的新状态和奖励值。

For Atari Environments like Mario, Atari, PAC-MAN etc.; Q-learning with CNN loss approximation can be used. Image Courtesy: leonardoaraujosantos

然而,有趣的是,当环境变得非常复杂,难以用计算限制性迭代算法处理时,神经网络凭借其学习状态-动作对的能力轻松进入画面,这被称为深度 RL。喜欢玩早期的游戏,如马里奥,雅达利,吃豆人等。

这里,我们将只限于简单的 Q 学习,即 w/o 神经网络,其中 Q 函数将状态-动作对映射到最大值,并结合即时奖励和未来奖励,即对于新状态,学习值是当前奖励加上未来奖励估计值。将其量化为一个具有不同参数的方程,如学习率和折扣因子,以指导代理的行动选择。我们得出以下方程:在结构上,它与贝尔曼方程有许多相似之处。

Q-Function Equation, tells about the maximum expected cumulative award for a given pair. Image Courtesy: Wikipedia

动手:为什么要开健身房?

2016 年《自然》杂志的一项调查表明,超过 70%的研究人员试图重现另一位科学家的实验,但失败了,超过一半的人没能重现他们自己的实验。

OpenAI 是为了消除论文中缺乏标准化的问题而创建的,其目的是通过提供易于设置的多种多样的环境来创建更好的基准。这个工具的目的是增加人工智能领域的可复制性,并提供工具让每个人都可以学习人工智能的基础知识。

打开你的终端,准备一些 CTRL+C 和 CTRL+V 的工作!!但是,我当然会建议反对。

让我们一起去健身吧

什么是 OpenAI 健身房?这个 python 库给了我们大量的测试环境来处理我们的 RL 代理的算法,这些算法带有用于编写通用算法和测试它们的共享接口。让我们开始吧,只需在终端上键入pip install gym即可轻松安装,您将获得一些经典环境来开始在您的代理上工作。复制下面的代码并运行它,你的环境将被加载。您可以在这里查看其他可用的环境,如 Algorithmic、Atari、Box2D 和 Robotics ,并使用下面列出的第二个代码片段组件列出所有可用的环境。

# 1\. It renders instances for 500 timesteps, performing random actions.
import gym
env = gym.make('Acrobot-v1')
env.reset()
for _ in range(500):
    env.render()
    env.step(env.action_space.sample())
# 2\. To check all env available, uninstalled ones are also shown.
from gym import envs 
print(envs.registry.all())

当对象通过一个动作与环境交互时,然后 step() 函数返回通常表示环境下一个状态的observationreward前一个动作的奖励浮动、done当该重置环境或实现的目标时,以及info用于调试的 dict ,如果它包含环境上一个状态的原始概率,它可以用于学习。从下面的代码片段看它是如何工作的。另外,观察Space类型的observation在不同环境下有何不同。

import gym
env = gym.make('MountainCarContinuous-v0') # try for different environments
observation = env.reset()
for t in range(100):
        env.render()
        print observation
        action = env.action_space.sample()
        observation, reward, done, info = env.step(action)
        print observation, reward, done, info
        if done:
            print("Finished after {} timesteps".format(t+1))
            break[Output For Mountain Car Cont Env:] 
[-0.56252328  0.00184034]
[-0.56081509  0.00170819] -0.00796802138459 False {}[Output For CartPole Env:]
[ 0.1895078   0.55386028 -0.19064739 -1.03988221]
[ 0.20058501  0.36171167 -0.21144503 -0.81259279] 1.0 True {}
Finished after 52 timesteps

上面代码中的动作空间是什么?action-space & observation-space描述了特定环境的动作&状态参数的有效格式。只需看看返回值。

import gym
env = gym.make('CartPole-v0')
print(env.action_space) #[Output: ] Discrete(2)
print(env.observation_space) # [Output: ] Box(4,)
env = gym.make('MountainCarContinuous-v0')
print(env.action_space) #[Output: ] Box(1,)
print(env.observation_space) #[Output: ] Box(2,)

离散为非负的可能值,大于 0 或 1 相当于左右移动横拉杆平衡。方框代表 n 维阵列。这些标准接口有助于为不同的环境编写通用代码。因为我们可以简单地检查边界env.observation_space.high/[low]并将它们编码到我们的通用算法中。

一幅插图

这里,我们使用 Python3.x 作为下面 Q-Learning 算法的高亮代码样本。

sudo pip install 'gym[all]' 

让我们开始构建我们的 Q 表算法,它将尝试解决 FrozenLake 导航环境。在这种环境下,我们的目标是在一个可能有洞的冰湖上达到目标。这是这个玩具文本环境是如何描绘表面的。

SFFF       (S: starting point, safe)
FHFH       (F: frozen surface, safe)
FFFH       (H: hole, fall to your doom)
HFFG       (G: goal, where the frisbee is located)

q 表包含映射到奖励的状态-动作对。因此,我们将构建一个数组,在算法执行期间将不同的状态和动作映射到奖励值。它的维度将清楚地|陈述| x |动作|。让我们用 Q 学习算法的代码来写。

import gym
import numpy as np # 1\. Load Environment and Q-table structure
env = gym.make('FrozenLake8x8-v0')
Q = np.zeros([env.observation_space.n,env.action_space.n])
# env.observation.n, env.action_space.n gives number of states and action in env loaded# 2\. Parameters of Q-learning
eta = .628
gma = .9
epis = 5000
rev_list = [] # rewards per episode calculate# 3\. Q-learning Algorithmfor i in range(epis):
    # Reset environment
    s = env.reset()
    rAll = 0
    d = False
    j = 0
    #The Q-Table learning algorithm
    while j < 99:
        env.render()
        j+=1
        # Choose action from Q table
        a = np.argmax(Q[s,:] + np.random.randn(1,env.action_space.n)*(1./(i+1)))
        #Get new state & reward from environment
        s1,r,d,_ = env.step(a)
        #Update Q-Table with new knowledge
        Q[s,a] = Q[s,a] + eta*(r + gma*np.max(Q[s1,:]) - Q[s,a])
        rAll += r
        s = s1
        if d == True:
            break
    rev_list.append(rAll)
    env.render()print("Reward Sum on all episodes " + str(sum(rev_list)/epis))
print("Final Values Q-Table")
print(Q)

如果您对使用其他环境感兴趣,您可以选择使用下面突出显示的代码片段。

Frozen Lake Environment Visualization Diagram.

# Reset environment
s = env.reset()
d = False
# The Q-Table learning algorithm
while d != True:
    env.render()
    # Choose action from Q table
    a = np.argmax(Q[s,:] + np.random.randn(1,env.action_space.n)*(1./(i+1)))
    #Get new state & reward from environment
    s1,r,d,_ = env.step(a)
    #Update Q-Table with new knowledge
    Q[s,a] = Q[s,a] + eta*(r + gma*np.max(Q[s1,:]) - Q[s,a])
    s = s1
# Code will stop at d == True, and render one state before it

但是请记住,即使有一个公共接口,不同环境的代码复杂度也是不同的。在上面的环境中,我们只有一个简单的 64 状态环境,只需要处理很少的动作。我们能够非常容易地将它们存储在一个二维数组中用于奖励映射。现在,让我们考虑更复杂的环境案例,如 Atari envs ,看看需要什么方法。

env = gym.make("Breakout-v0")
env.action_space.n
Out[...]: 4
env.env.get_action_meanings()
Out[...]: ['NOOP', 'FIRE', 'RIGHT', 'LEFT']
env.observation_space
Out[...]: Box(210, 160, 3)

需要用 210×160×3 张量来表示,这使得我们的 Q 表更加复杂。同样,每个动作在 k 帧的持续时间内重复执行,其中 k 是从{2,3,4}中均匀采样的。RGB 通道中有 33,600 个像素,值的范围从 0 到 255,环境显然变得过于复杂。这里不能使用简单的 Q 学习方法。深度学习及其 CNN 架构是这个问题的解决方案,也是这篇介绍性文章后续应该关注的主题。

结论

现在,有了上面的教程,你就有了关于健身房的基本知识,以及开始健身所需要的一切。Gym 也兼容 TensorFlow & PyTorch,但为了保持教程简单,我没有在这里使用它们。在试用了体育馆 软件包之后,你必须开始使用稳定基线 3 来学习 RL 算法的良好实现,以比较你的实现。要查看所有 OpenAI 工具,请查看它们的 github 页面。人工智能是一个不断扩展的领域,在许多领域都有应用,它将在未来的人工智能突破中发挥重要作用。希望你继续你的 RL 之旅&感谢阅读!!

光荣的插头

C’Mon… What did you expect? Image Courtesy: MCU

是的,和你分享可耻的然而 光荣的 入门项目插头,以防你刚入门强化学习。选择这些实践项目的额外优势是获得完整的导师支持&美妙的免费强化学习资源,如书籍、视频等。有趣的是,有两个现场项目我会推荐给你进一步研究:

  • 如果你想在初级/中级水平的完整强化学习概念的基础上开始一个实践项目,你可以选择下面嵌入的 liveProject。在这里,在这个 liveProject 中,我讨论了实现最佳性能的自动驾驶汽车所需的研究原则。****

* [## 自动驾驶车辆的强化学习

在这个 liveProject 中,您将开发一个可以模拟独立驾驶的 AI 驾驶代理。你的代理应该是…

www.manning.com](https://www.manning.com/liveproject/reinforcement-learning-for-self-driving-vehicles?utm_source=ashishrana&utm_medium=affiliate&utm_campaign=liveproject_rana_reinforcement_7_6_21&a_aid=ashishrana&a_bid=8f38c809)

另外,第一个里程碑是这个 liveProject 的 免费 练习。即使你不推进 liveProject,我保证你会从第一个里程碑的中了解到很多关于 自动驾驶 RL 任务的信息。干杯!

重要提示:如果你在 2021 年 7 月 26 日之前来到这里,并且有兴趣继续进行第一个 liveProject。请使用代码 lprana 在这个项目上你会得到 45%的折扣。太棒了。!**

  • 第二,如果你特别想把你的注意力和努力放在 RL 的深度 Q 学习概念上。请随时查看下面的 liveProject。第一个里程碑是免费练习!

** [## 自动驾驶机器人的深度强化学习

在这个 liveProject 中,您将研究强化学习方法,它将允许自动机器人推车…

www.manning.com](https://www.manning.com/liveproject/deep-reinforcement-learning-for-self-driving-robots?utm_source=ashishrana&utm_medium=affiliate&utm_campaign=liveproject_galbraith_deep_6_2_21&a_aid=ashishrana&a_bid=e4173afc)

朝现在!如果你选择了第一个项目,我们在那里见…***

复发触发因素:用人工智能预测压力

原文:https://towardsdatascience.com/relapse-trigger-predicting-stress-with-a-i-f559af5a19a3?source=collection_archive---------27-----------------------

从问题的形成到解决方案的部署,今天的文章全面介绍了数据科学和机器学习在帮助阿片类药物成瘾患者的道路上的旅程。

问题定式化

try cycle Data(【trycycledata.com】T2)于 2017 年开始开发一个数据驱动的系统,以帮助解决阿片类药物的流行。这个概念的早期阶段可以追溯到 2012 年。针对处于危险或危机中的个人的自助解决方案不起作用。相反,TryCycle 采取了相反的方法,将他们的技术专长集中在寻找帮助卫生资源与客户保持联系的方法上,并监控他们作为门诊病人的复发风险。具体来说,TryCycle 设计了一个简单但功能强大的移动数据收集系统,用于收集受控护理环境之外的数据。这使得现有的临床医生-客户关系和治疗得以扩展,因此临床医生可以在风险水平上升之前更好地了解和监测复发的症状。

成瘾者研究压力预测因子的动机

根据美国疾病控制中心(CDC)的数据,药物过量死亡的人数从未如此之高,其中大多数死亡病例,2016 年有 66%涉及阿片类药物。提高数据质量和跟踪趋势,已被 CDC 认可为帮助了解问题的严重程度、将资源集中在最需要的地方以及评估预防和应对工作的成功的关键。

慢性压力与吸毒和易成瘾有很大关系(更多在这里和这里)。我们也知道压力会增加上瘾的风险(这里的、和这里的)。有大量的研究将压力与成瘾联系起来(这里有更多的),并表明压力会导致康复中的人退出治疗(这里有更多的)。

嗯,我们可以看到复发与压力有关,但为什么不简单地预测复发呢?为什么要从预测压力开始?预测复发太远了,无法纠正。我们希望这种工具能够预测压力,以便在复发即将来临之前,能够在护理范围内减轻复发的触发因素。

数据收集

本文使用的专有数据集包含来自 16 个个人的 500 多个条目,历时五个月(2018 年 5 月-2018 年 9 月)。这是整个 TryCycle 数据集的一个小样本,是在知情同意的情况下收集的,用于研究。TryCycle 的移动应用程序收集了手机位置和其他数据,以及个人日志条目和定期自我评估,如下所示。

The TryCycle dashboard for reviewing client history and risk of relapse.

数据收集:J 日志

鼓励客户保持私人日志,并定期更新。这些数据可以由机器以保护隐私的方式进行分析,揭示情绪和其他有助于监控风险因素的因素

数据收集:定期自我评估

按照规定的时间表(每天、每天两次、每周或每周两次,取决于诊所如何设置)提示客户完成基于技术的评估,包括八个复发指标,也称为复发线索或警告信号。这些因素与复发前行为、态度、感觉或想法的变化有关。由于许多研究表明压力是成瘾发展的主要因素,并可能引发复发过程,TryCycle 将压力作为其指标测量之一。

One screen in the TryCycle mobile app for collecting self-reports on relapse indicators.

TryCycle 评估监测的复发指标如下。在自我评估过程中,客户使用一系列滑动条给每个指标打分,范围从-1(差)到+1(好)。

为了了解复发风险,TryCycle 开发了一种专有算法,对上述所有 8 个复发指标以及数据趋势和计算提交之间的差异进行加权,为每个被监测的人分配一个分数和风险水平。

有了这个数据收集系统,下一个问题是如何从这些数据中预测未来的压力水平。目标是找到导致复发的预警信号之间的相关性。我们决定把重点放在压力上,更具体地说,从收集的数据中的其他因素来预测压力。

数据科学

在构建预测模型之前,我们需要评估和探索数据,以了解数据集中的特征。这里的关键免责声明是,如上所述,这个数据集相对较小,因此这些初步分析在这一点上是非常初步的。

研究复发指标如何相互关联

我们研究了复发指标之间的相互关系。如下图所示,每个指标之间都有关联。

Correlation matrix showing how the relapse indicators are all related.

这个结果很有意义。这些因素应该都指向同一个东西(复发)。它们都是同一个风险等式中的因素,一些比另一些更强。我们有一些根据相关性的强度将相关性分成不同类别的标准。以下是我们的相关标准:

使用上述标准,三个强相关指标是:

1.“渴望或触发”和“使用您选择的药物”

2.“药物治疗依从性”和“使用您选择的药物”

3.“渴望或触发”和“触发的关系”

基于这些早期发现,如果我们监测正确的指标,就有可能提前发现复发的诱因。上述发现是一个好迹象,表明预测模型可以告诉我们一些有用的东西。

随着我们对数据的深入挖掘,并查看适度的相关性,我们发现了“情绪波动”、“压力”和“履行责任”之间的关系。

Correlation matrix focusing in on how a subset of indicators are all related.

观察这些指标之间的相关性,我们得出结论:

1.“压力”与“情绪波动”和“履行职责”都有关联

2.“情绪波动”和“履行责任”与“渴望和触发因素”有适度的关联,在较小程度上与“触发关系”有关联

现在,相关性不是因果关系,但我们开始围绕压力指标到压力本身的路径建立一个论题。我们从前面提到的文章中知道,压力会导致复发。也许我们在这里有一个信号,我们在数据集中收集的因素可以提供一个做出结论的途径。例如:“压力”导致“情绪波动”和(不)履行责任,从而导致“渴望和触发”和“触发关系”,最终旧病复发?

我们在数据中寻找其他佐证信息。如果我们评估复发指标与一周中各天的相关性,我们会得到以下结果:

这些相关性都很弱。看起来周一可能会对情绪产生一些影响。这证实了我们的直觉,即回去工作并不有趣。我们还可以看到,“渴望和触发”和“触发的关系”似乎仍然在同一天匹配(周二、周三和周日)。

让我们继续查看按一周中的和一天中的小时分组的平均值,看看是否有任何线索(下面并排的图表)。

The average value for each relapse indicator was grouped by day of the week (right), and hour of the day (left)

我们观察到,如果我们按一天中的小时或一周中的天对数据进行分组,压力(棕色)始终是输入的最低值之一。回想一下,低意味着坏。这告诉我们,正如我们所预料的那样,人口报告了高压力。现在,我们能预测这种压力,然后,也许,在咨询或医疗访问中解决这种压力吗?

预测模型

我们希望根据最近报告到系统中的可用数据来预测未来的压力水平。这种预测分析模型有助于护理圈内的每个人在压力转化为复发之前做出反应。

深入挖掘机器学习解决方案的细节,我们使用了 scikit learn 的随机森林分类器,因为这个模型非常适合数据。这种分类器通过学习与数据分离方式相对应的决策树来拟合数据。理解这种方法的一种方式是把这个模型想象成一本“选择你自己的冒险”的书。正如这本书创建了一个从故事开始到一些逻辑结论的分支路径,这个模型学习设置哪些路径来模仿数据中的模式。房地产领域一个直观的例子是 R2D3 的 这个。向下滚动链接可以看到这个过程的一个很好的动画例子。TryCycle 的模型从一个复发风险参数开始,并定义了一个决策树(又称决策树),即“如果高就向左走”,否则就“向右走”。当然,该模型还知道每个决策使用什么权重。

用于预测未来压力的数据包括七个指标,以及收集这些数据时的“星期几”和“一天中的小时”数据。当模型符合数据时,我们就可以进行预测。生成的决策树如下所示:

让我们后退一步,看看每个指标的重要性,以便更好地理解模型的作用。

从这些结果来看,“药物治疗依从性”和“选择药物的使用”这两个指标不能很好地预测压力,这是有道理的,因为我们认为压力才是它们的预测因素。似乎责任和关系是预测未来压力的关键因素。该模型现在检查这一小时是在午餐之前还是之后(12.5 小时)还是在工作之前和之后(14-17 小时),这显然比一天中的实际时间与压力有更强的联系。该模型还区分了工作日和周末报告的结果。

既然我们已经了解了模型是如何做出决策的,那么这些决策有多正确呢?

为了制作下面的图表,我们为一个测试用户在给定的一天将一个指标数据传递到我们的模型中,模型返回第二天的压力预测。我们对 61 个数据点反复这样做,以得到应力预测曲线(橙色)和实际报告的应力(蓝色)。同样,蓝线是该用户报告的压力水平,而橙线是基于前一天数据的预测压力值。如果两条线完全重叠,那么我们将有一个完美的预测。我们可以看到预测实际上相当不错。在一些地方,应力预测先于实际应力观测!

准确度是每个预测值与下一个报告值之间差异的平均值,上图中该患者的标称准确度为 95.63%。然而,点的平均精度是而不是我们正在寻找的值。我们真正想要的是能够在压力的变化发生之前预测它们。看下面图表中的数据,客户报告的压力变化有 7 次。

Observing the prediction of changes in stress level (orange) against the actual changes in reported stress level (blue).

在上图中,我们可以看到,在许多压力变化被报道之前,我们确实猜测到了或者至少是朝着正确的方向发展(有时甚至是提前几天)。预测有许多小的变化,但预测中较大的变化通常接近实际报告的变化。因此,较大的预测似乎比较小的预测更精确,但趋势变化也有助于预测。

我们可以调整我们的算法,以支持精确度(低假阳性,但有时会错过压力峰值)或回忆(捕捉更多的压力峰值,但更多的假阳性)。数据集在不断增长,因此随着时间的推移,结果有望得到改善。随着收集的数据越来越多,我们也在考虑数据的季节性,以及数据中的特殊情况,如假期。

把这些放在一起帮助真实的人

TryCycle 从一个问题开始:识别复发的触发因素,并在护理圈内积极应对这些触发因素。希望本文能让您对产品的开发和部署有所了解。这个数据科学和机器学习之旅的最终结果是一个帮助陷入阿片类药物流行的成瘾者的系统。

来自 TryCycle Data 的消息:我们希望将我们的方法推广到更多的医疗保健机构。要预订演示并了解定量门诊护理的好处,请 点击此处联系

这篇文章是关于预测恢复中的吸毒者的压力。有关总体评估工具的更广泛概述,请参阅以下 2018 年案例报告:

如果你喜欢这篇关于人工智能预测戒毒者压力的文章,那么按下跟随按钮,拍拍拍手的东西,在社交频道上分享,并看看我过去读过的一些最热门的文章,比如“T2”如何为人工智能项目定价“和“T4”如何聘请人工智能顾问”。此外,退房请尝试循环。除了商业相关的文章之外,我还准备了一些关于那些希望采用深度机器学习的公司所面临的其他问题的文章,比如“没有云或 API 的机器学习”。

下次见!

-丹尼尔

daniel@lemay.ai 问好。
LEMAY . AI
1(855)LEMAY-AI

您可能喜欢的其他文章:

使用 Jupyter 笔记本电脑进行远程计算

原文:https://towardsdatascience.com/remote-computing-with-jupyter-notebooks-5b2860f761e8?source=collection_archive---------1-----------------------

Source

[## 想在数据科学方面变得更好吗?

当我在我发布独家帖子的媒体和个人网站上发布新内容时,请单击此处获得通知。](https://bobbywlindsey.ck.page/5dca5d4310)

不久前,我让 AWS 为我提供了一个唯一的 URL,我可以导航并使用 Jupyter 笔记本。我钦佩它的便利性和能力,只要启动一个计算程序,关上笔记本电脑,就知道我的计算会继续进行。然而,根据您的使用情况,使用 AWS P2 实例会非常昂贵,对我来说,每月大约 600 美元。所以,我想我可以用这些钱建造一台电脑,作为深度学习的平台,偶尔玩玩视频游戏。

这篇文章描述了配置设置一旦你已经建立了你的电脑并且安装了像 Ubuntu 这样的 Linux 版本。事实证明,下面的配置对我来说比 AWS 更容易设置,在别名的帮助下,连接到我的服务器比以往任何时候都容易。我们开始吧!

装置

所以首先你需要在你的 Ubuntu 服务器上安装以下软件:

  • Anaconda ,它将提供许多您需要的默认 Python 包
  • openssh-server,可以安装以下软件:sudo apt-get install openssh-server -y
  • tmux,可以安装sudo apt-get install tmux -y

如果您需要查看 openssh-server 的状态或重启它,请在您的终端中键入以下内容:

systemctl status ssh sudo service ssh restart

本地连接到您的服务器

为了确保大多数事情都设置正确,我们首先需要验证您可以连接到本地网络上的服务器。

好吧!所以在你的服务器上,打开位于/etc/ssh/sshd_configsshd_config文件。要对其进行更改,您需要 sudo 权限。文件打开后,您需要指定连接时要使用的端口。无论您选择什么,我强烈建议不要使用默认端口 22。假设您决定使用端口 22222。在您的sshd_config文件中有一个名为Port的条目,您应该这样编辑它:

Port 22222

AllowUsers下,输入您登录服务器时使用的用户名。

AllowUsers your_username

接下来,将PasswordAuthentication设置为yes

最后,为了确保 Ubuntu 不会阻止端口 8888 上的网络流量,我们需要调整它的 iptables:

sudo iptables -I INPUT -p tcp -s 0.0.0.0/0 --dport 8888 -j ACCEPT sudo iptables -I INPUT -p tcp -s 0.0.0.0/0 --dport 443 -j ACCEPT sudo netfilter-persistent save

现在,记下您的服务器的 IP 地址。这可以通过在您的终端中键入ifconfig并查找类似于inet 192.168.1.112的内容来找到。一旦您在本地网络上确定了服务器的 IP 地址,就该拿起您的笔记本电脑并尝试登录了:

ssh your_username@192.168.1.112 -p 22222

如果你得到一个终端提示,你就成功了!

远程连接到您的服务器

现在,设置远程计算的全部目的是,当你在别人的网络上时,你可以离开你的房子,远程进入你的服务器。要做到这一点,只需要做一些更改(要求您仍然在自己的网络上):

  • 如果您的笔记本电脑上还没有一组公钥和私钥,生成它们
  • 将您的公钥复制到您的服务器:ssh-copy-id your_username@192.168.1.112 -p 22222
  • 通过在您的服务器终端键入curl 'https://api.ipify.org'来识别您的服务器的 WAN IP 地址(注意,您的 ISP 经常更改此地址,这就是我使用 Google Wifi 的原因,它允许我从任何地方检查我的 WAN 地址)
  • 在路由器上,打开端口转发。使用我们的示例,您需要将端口 22222 转发到端口 22222。

现在尝试使用您找到的 WAN 地址远程访问您的服务器!

ssh your_username@server_wan_ip -p 22222

如果你看到一个提示,干得好!最后一件事是在你的sshd_config文件中设置PasswordAuthenticationno,因为现在你用 ssh 密钥登录;这样,没有人可以尝试暴力破解您的密码。

你现在可以从你的网络之外访问你的服务器,去拿你自己的星巴克咖啡:)。

启动远程 Jupyter 笔记本

现在所有困难的工作都已完成,您可以通过以下步骤轻松使用远程 Jupyter 笔记本电脑:

  1. ssh 进入你的服务器:ssh your_username@server_wan_ip -p 22222
  2. 开始一个新的 tmux 会话,您以后可以轻松地从该会话中退出:tmux new -s session-name
  3. 无浏览器启动 jupyter-笔记本:jupyter-notebook --no-browser --port=8889
  4. 现在,在笔记本电脑上的新终端中,将服务器端口流量转发到笔记本电脑的本地端口:ssh -N -L localhost:8888:localhost:8889 your_username@server_wan_ip -p 22222
  5. 在您的网络浏览器中,导航到localhost:8888/tree,您应该会看到您的 Jupyter 笔记本!

现在,您可以在笔记本电脑上轻松使用 Jupyter 笔记本,而是使用服务器的强大资源来进行计算。

最后一件事,在想通了上面的步骤后,我想我应该通过使用别名和函数使这个过程变得更简单。以下是我添加到笔记本电脑的.bashrc文件中的相关行:

server-connect() {
    ssh your_username@$1 -p 22222
}jn-connect() {
    ssh -N -L localhost:8888:localhost:8889 your_username@$1 -p 22222
}

我添加到服务器的.bashrc文件中的行:

alias jn-remote="jupyter-notebook --ip='*' --no-browser --port=8889"

现在,上述 5 个步骤变成了:

  1. server-connect server_wan_ip
  2. tmux new -s session-name
  3. jn-remote
  4. 打开新终端并键入jn-connect server_wan_ip
  5. 导航至localhost:8888/tree

就是这样!现在,你可以在咖啡店里一边用笔记本电脑放松,一边运行你正在构建的那些疯狂的神经网络。祝你好运!

如果你喜欢我在这里写的东西,一定要看看我的 个人博客 ,那里有我在媒体上没有的文章。

原载于 2017 年 8 月 10 日bobbywlindsey.com

伦科砖尺寸优化

原文:https://towardsdatascience.com/renko-brick-size-optimization-34d64400f60e?source=collection_archive---------1-----------------------

大家好!

我在 Quantroom 研究金融时间序列。我们致力于股票和密码市场的算法策略问题。今天,我将概述一项关于如何使用 Renko 图对金融时间序列进行降噪的研究。本文的目的是回答这个问题“是否有比众所周知的方法更好的方法来确定最佳砖块尺寸?”

什么是伦科图表?

伦科图表是一种只关注价格变动的图表类型,不包括时间和成交量。伦科图表没有显示每个价格变动。您应该在创建 Renko 图表之前设置这些参数:

  • 选择多大尺寸的图表来代表价格变动的幅度?如果砖块尺寸较小,图表会有更多的移动,但是这个图表会更嘈杂。
  • 什么类型的价格将用于构建图表(如开盘价、收盘价等)。)?此外,应该选择一个时间框架,它可以是天,小时,分钟和滴答。分笔成交点数据更准确,因为没有遗漏移动。

Renko charts built on different brick size

连科海图制作的基本原理:

  • 只有当价格变动超过指定的阈值水平时,才会生成新的砖块。
  • 砖块大小总是一样的。例如,如果尺寸是 10 点,价格增加了 20,那么将画 2 块砖。如果价格上涨,砖块将为绿色(浅色),如果价格下跌,砖块将为红色(深色)。
  • 将所选价格变量的下一个值与前一个砖块的最大值和最小值进行比较。新矩形总是显示在前一个矩形的右侧。
  • 如果价格超过前一个砖块的顶部,超出砖块大小或更多,则绘制相应数量的绿色(浅色)矩形,使新砖块的下边界与前一个砖块的上边界相对应。
  • 如果价格比前一个砖块的底部低了砖块大小或更多,则绘制相应数量的红色(黑色)矩形,新砖块的上边界与前一个砖块的下边界相对应。

图表分析师 Ranga 的这篇文章介绍了 Renko 图表。

在本文的下一部分,将使用我实现的 pyrenko 模块进行分析。

确定砖块尺寸的现有方法

  1. 传统。这种方法使用预定义的砖块大小绝对值。
  2. ATR 。这种方法使用平均真实范围(ATR)指标生成的值。ATR 用于过滤掉金融工具的正常噪音或波动。ATR 方法“自动”确定好的砖块尺寸。它计算出常规蜡烛图中的 ATR 值,然后将该值作为砖块大小。

使用算术平均值公式计算第一个 ATR 值:

质量评估和评分功能

这将是一个很好的衡量伦科图表的质量。让我们假设一个简单的策略,使用这些趋势跟随规则:当当前砖块是绿色(亮的)时,你的位置应该是“长的”。如果砖块的颜色已经改变,则改变到“短”位置。使用此逻辑,我们有以下参数:

  • 余额是正负交易的总和。如果当前砖块与前一个砖块方向相同,则平衡值应增加+1。如果方向已经改变,平衡值应减少-2。正值就好。价值越大越好。
  • sign_changes 是趋势被改变了多少次的数字。价值越低越好。
  • price_ratio 是多个原始价格条与多个 renko 砖块的比率。大于 1 的值是好的。价值越大越好。

得分函数试图将这些参数整合成一个单一值。正值就好。价值越大越好。

如果 sign_changes 等于 0,则在计算前应设置为 1。

让我们尝试在 3D 空间中模拟和可视化这个得分函数。球体的大小对应于一个分数值。红色球体的分数等于-1 值。

导入模块和包:

Imported modules and packages

生成、计算并可视化得分函数的结果:

Simulating and visualizing of score function

得分值乘以常数,以获得更明确的球体尺寸。

Score function 3D visalization

本研究的关键思想是测试假设,即我们可以使用得分函数优化来获得比当前方法( ATR 方法)更好的砖块大小。给定的结果将通过统计学方法进行显著性检验。

实验

实验由三部分组成。

Experiment pipeline

数据准备

  • 从维基百科获取股票列表(标准普尔 500 指数)。
  • 过去 3 年每天的收市价(高、低、收盘)。
  • 删除数据中缺少值的股票。

该部分的代码块:

Downloading and cleaning the stocks

由于这部分数据集中包含了 470 只股票

砖块尺寸优化和 Renko 图表评估

该部分负责 Renko 图表评估。最佳砖块尺寸在包含 70% 天的列车组上确定。使用得分函数对剩余 30% 天进行 Renko 图评估。

Train test split method

这两种操作(优化和评估)是针对两种方法( ATR得分函数优化)执行的。在 ATR 情况下,序列的最后一个 ATR 值被认为是最佳砖块尺寸。

得分函数优化的情况下,最佳砖块尺寸是给出得分函数的最大值。

Score(brick_size) plot

这种方法使用基于 Brent 方法的一维函数最小化。带负号的评分函数要用,因为是逆问题。

此代码包含应优化的功能,以及评分/优化流程:

Optimization process

Brent 的方法是一种结合二分法、割线法和逆二次插值法的求根算法。它具有二分法的可靠性,但它可以像一些不太可靠的方法一样快。如果可能的话,该算法尝试使用潜在的快速收敛割线方法或反二次插值,但是如果必要的话,它退回到更健壮的二分法。边界点可以作为训练集上的最低和最高 ATR 值给出,这将是一个很好的初始近似值。更多关于布伦特方法的信息这里

Brent’s method visualization

Brent’s method algorithm

让我们通过两种方法的得分值来得到股票排序列表。分数值是在测试集上计算的。

画出得分最好的股票的 Renko 图(AVY 股票为 ATR ,AFL 股票为得分函数优化)。

Renko charts of highest score stocks

结果可视化的代码块:

Result visualization

结果分析

该散点图展示了价格比率如何对应于余额:

Scatter plots

Visualization of how price_ratio corresponds to balance

我们可以得出结论,得分函数优化方法更好地压缩了数据,因为价格比率有更大的趋势。

画一个柱状图,显示测试集上有多少股票的阳性/中性/阴性结果:阳性:得分>0;中性:得分= 0;负:分数< 0。

计算和可视化结果的代码:

Positive / Neutral / Negative histogram

Histogram of result distribution for two approaches

频率有一些差异,但分布的形状是相似的。让我们展示两种方法的分数直方图,以及它们的差异分布:

Score histograms

Score histogram for two approaches

Score difference histogram

将好估计一个分数的置信区间差。这将清楚地表明哪种方法平均起来会给出更好的分数。

检验样本来自正态分布的零假设。 p 值为 1.085e-11 ,非常低,说明样本来自非正态分布:

Test on normal distribution

在非正态分布上计算置信区间是不可接受的。

我们可以使用 bootstrapping 得到一个置信区间。Bootstrapping 是一种实用的计算机方法,用于通过基于可用样本的蒙特卡罗方法来研究基于多代样本的统计分布。允许您快速轻松地评估各种统计数据(置信区间、方差、相关性等)。)对于复杂的模型。

Boostrapping alogorithm

引导示例如下所示。该样本服从正态分布, p 值为 0.9816

重采样的代码块:

Bootstrapping

Bootstrapped sample of score difference

几乎所有的平均值都大于 0t 检验的 p 值为 0.0(零假设:score_diff = 0.0) ,我们拒绝零假设。这些计算证实,对于所提出的方法,得分函数优化ATR 方法之间的平均得分差异更大。

这是方法差异的一个特殊例子(UNH 股票)。

Renko charts of UNH for two approaches

结论

  1. 形式化了评估已建 Renko 图质量的得分函数
  2. 描述了一个分数优化的过程。
  3. 所提出的方法比经典的 ATR 获得了更好的质量。这种优势在统计学上是显著的。
  4. pyrenko 是本分析中演示的一个模块,任何研究人员都可以使用。
  5. 使用 Renko 演示了完整的降噪过程。包括代码。
  6. 理论上,平衡参数乘以 brick_size 可以解释为测试集上的利润。这个简单的趋势跟踪策略是进一步研究的良好基础。为了更准确地估算利润,必须包括交易成本(经纪人费用、差价、滑点等)。).
  7. 发展的方法可用于策略,如配对交易,趋势跟踪,支持和阻力等。经过处理的无噪声图表变得易于理解,趋势线更加清晰。

如果你在股票分析中使用伦科图表或者打算使用,请告诉我。此外,有趣的是,您使用什么方法来确定砖块大小?

更新

下一章研究这里

最诚挚的问候,

谢尔盖

刮租:我如何用 R 省钱

原文:https://towardsdatascience.com/rent-scraping-how-i-saved-money-using-r-fc93925ca11b?source=collection_archive---------8-----------------------

了解我如何使用 R 和网络抓取来对抗房租上涨并获胜。

(TD;博士:收到房地产公司的信,增加我的周租金。增加的原因没有证据支持。利用 R 寻找支持房地产索赔的证据。与权力斗争并取得胜利!)

围过来,围过来。来听一个关于一个人战胜当权者的故事。我难以置信地读到,他竭尽全力避免支付每周 5 美元的房租上涨,理由是没有实证证据证明这是合理的。

(严重上注:这是关于 R 中的网页抓取)

“…根据当前的市场状况…”

我目前公寓的 12 个月租约即将到期。正当我想知道我的房地产经纪人给我一份为期 12 个月的新租约的年度电子邮件什么时候会到的时候,我收到了这个:

您目前以每周 500 美元的价格租赁您的房产,租约将于 2017 年 11 月 18 日到期。我们最近完成了对您的物业的租金审核,并建议业主根据当前的市场情况,您的物业租金应每周增加 5 美元。

渴求专一,我的思维超速运转:什么市场条件?他们是如何定义它们的?5 美元太少了——什么样的市场条件变化能证明每周增加 5 美元是合理的呢?

一年前,我的房租每周涨了 20 美元,再涨 5 美元对我来说似乎没有意义。我也感觉到了一种我不喜欢的力量不平衡。一方面,我们有房地产经纪人,他可以访问房地产价格和报告的数据库。另一方面,我们有一个租户,他不能访问同样多的信息。这种信息不对称传统上会使承租人处于弱势地位,因此更有可能接受房地产经纪人的建议。

不幸的是,对我的房地产经纪人来说,我有点疯狂。

我住在一套两居室的公寓里,有一个停车位和一个卫生间。我想寻找具有类似配置的公寓的数据。

数据在哪里?

新南威尔士州政府的家庭和社区服务——“出租桌”

我知道新南威尔士州政府每季度都会发布新出租房屋和公寓的报告。报告中有一个标签显示了一居室和两居室公寓周租金分布的第一个四分位数、中间值和第三个四分位数。

当然,这对我来说不够精确。我知道,如果我没有停车位,我的租金很可能会更便宜。我也知道如果我有两个浴室,我的房租会更贵。所以我继续我的探索。

给我一些'英寸'刮

在谷歌搜索了一番后,我发现了房价。看看这张截图:

它有我需要的所有信息:

  • 每周租金,
  • 公寓出租的月份
  • 就卧室、浴室和停车位数量而言的公寓配置

这个网站另一个吸引人的地方是循环友好的 URL。这是第一页的 URL:

https://www . auhouseprice . com/rent/list/NSW/2131/Ashfield/1/?排序=日期&类型=公寓&bmin = 2&bmax = 2

以下是第二页的 URL:

https://www . auhouseprice . com/rent/list/NSW/2131/Ashfield/2/?排序=日期&类型=公寓&bmin = 2&bmax = 2

有什么变化?

“阿什菲尔德”后面的数字!

现在猜猜前 50 个 URL 可能是什么。很简单,对吧?

哈德利万岁:R 的 rvest 包

rvest 是 R royalty,Hadley Wickham 的一个网络抓取 R 包。像大多数 Hadley 的包一样,rvest 以其直观的语法易于使用。该软件包是为与 magritter 的管道操作员(dplyr 的用户将熟悉该操作员)合作而构建的,允许我们创建优雅的数据管理管道。

开始使用 rvest 很容易:

  1. 找到您想要刮除的页面
  2. 获取该页面的 url
  3. 使用 rvestread _ html()函数将页面读入 R
  4. 使用 html_node()html_nodes() 函数访问包含所需数据的 CSS 选择器(更多关于找到相关选择器和函数间差异的信息,见下文)。
  5. 使用 html_text() 函数访问包含在前面步骤中提取的 CSS 选择器中的文本。
  6. 使用 regex 提取上一步中访问的 CSS 选择器文本中的相关文本。

我们如何找出哪个 CSS 选择器包含了我们想要的数据?

带有 SelectorGadget 的 CSS 选择器

SelectorGadget 是谷歌 Chrome 的一个扩展,你只需点击它就可以快速发现哪个 CSS 选择器包含了你的目标数据。你不再需要在浏览器的开发工具中挖掘 HTML。这是一个巨大的时间节省。

安装它…现在!

让我们去战斗吧

我们现在已经有了使用 r 从网站收集数据的所有必要成分。我最终想要创建的输出是公寓租赁月份的每周租金时间序列。我想确保我的抓取工作符合预期,所以我想提取公寓的地址,以便我可以根据 Chrome 中的网页样本直观地检查我的数据。

让我们建立一个原型,刮第一页。

library(rvest)first_page <- read_html('https://www.auhouseprices.com/rent/list/NSW/2131/Ashfield/1/?sort=date&type=apartment&bmin=2&bmax=2')

目标:地址

进入 Chrome,点击右上角的 SelectorGadget 图标。点击其中一个地址,您应该会看到类似这样的内容出现在浏览器的右下角。

这是包含地址数据的 CSS 选择器。为了访问这个选择器中包含的数据,我们可以将页面通过管道传输到 html_nodes() ,指定 CSS 选择器名称作为它的参数。为了访问其中包含的文本,我们可以将这个结果通过管道传输到 html_text()

让我们来看看它的输出:

first_page %>%
  html_nodes('h4') %>%
  html_text() ##  [1] "2/93 Alt Street Ashfield 2131"             
##  [2] "9/23 Orpington Street Ashfield 2131"       
##  [3] "9/60 Bland Street Ashfield 2131"           
##  [4] "4/122 Frederick Street Ashfield 2131"      
##  [5] "3/13 Frederick Street Ashfield 2131"       
##  [6] "Address available on request Ashfield 2131"
##  [7] "19/12 Webbs Avenue Ashfield 2131"          
##  [8] "132 Frederick Street Ashfield 2131"        
##  [9] "17/106 Elizabeth Street Ashfield 2131"     
## [10] "106/168 Liverpool Road Ashfield 2131"      
## [11] "401/11-13 Hercules Street Ashfield 2131"   
## [12] "105/168 Liverpool Road Ashfield 2131"      
## [13] " Search Filter and Sorting

我们不希望元素 13(“搜索过滤和排序”)出现在我们的地址向量中,所以我们将其排除。

addresses <- first_page %>%
  html_nodes('h4') %>%
  html_text() %>%
  .[which(. != ' Search Filter and Sorting ')]

目标:租赁的周租金和月租金

点击每周租金和公寓出租的月份给我们提出了一个挑战。包含我们要寻找的数据的选择器(“li”)由一大堆其他数据共享。看一下突出显示的内容:

让我们来看看从“li”选择器中可以提取的前几个元素:

first_page %>%
  html_nodes('li') %>%
  html_text() %>%
  head(10)##  [1] "  View By State Melbourne, VIC Sydney, NSW Brisbane, QLD Adelaide, SA Perth, WA Canberra, ACT Darwin, NT Hobart, TAS "
##  [2] "Melbourne, VIC"                                                                                                       
##  [3] "Sydney, NSW"                                                                                                          
##  [4] "Brisbane, QLD"                                                                                                        
##  [5] "Adelaide, SA"                                                                                                         
##  [6] "Perth, WA"                                                                                                            
##  [7] "Canberra, ACT"                                                                                                        
##  [8] "Darwin, NT"                                                                                                           
##  [9] "Hobart, TAS"                                                                                                          
## [10] ""

我们知道我们想要提取的文本的模式。事情是这样的:

Mmm yyyy 每周租金$###

让我们使用一些 regex 和来自 stringr 包的 str_extract()函数(再次向 Hadley 致敬),在“li”选择器的元素向量中提取任何匹配这个模式的文本。注意,str_extract()为不匹配我们模式的元素返回一个与 NAs 输入长度相同的向量。最后一步,我们将过滤掉 NAs。

那些符号是什么?从正则表达式到英语的翻译

我的主张是,上述模式可以用 regex 表示如下:

^Rent.+/周。*\d{4}$

不要害怕。这看起来很疯狂,但所有这些都是在说:

  • ^ 我们应该匹配目标字符串开头的内容。
  • 租金。+ —查找单词“租金”后跟一个或多个任意字符。句点是 regex 中的一个特殊字符,表示“匹配任何字符”。加号意味着“一个或多个”紧接在它前面的任何事物。
  • /周 T5。* —查找“每周”,后跟零个或多个任意字符。零或更多用星号表示,它是加号的不太严格的表亲。
  • \d{4} —目标字符串应以 4 位数字结尾。“\d”是 regex 中的另一个特殊字符,它表示“匹配从 0 到 9 的任何数字”。额外的斜线在那里,因为我们需要转义 r 中的反斜线,“{4}”意味着“重复紧接在前面的内容 4 次”。换句话说,匹配 4 位数。
  • $ —目标字符串应该以紧跟在我之前的内容结束。在这种情况下,4 位数。

让我们来测试一下:

library(stringr)

price_month <- first_page %>%
  html_nodes('li') %>%
  html_text() %>%
  str_extract('^Rent.+/week.*\\d{4}$') %>%
  .[which(!is.na(.))]

price_month##  [1] "Rent $420/week on Aug 2018" "Rent $510/week on Aug 2018"
##  [3] "Rent $490/week on Aug 2018" "Rent $500/week on Aug 2018"
##  [5] "Rent $550/week on Aug 2018" "Rent $730/week on Aug 2018"
##  [7] "Rent $510/week on Jul 2018" "Rent $480/week on Jul 2018"
##  [9] "Rent $520/week on Jul 2018" "Rent $630/week on Jul 2018"
## [11] "Rent $630/week on Jul 2018" "Rent $700/week on Jul 2018"

呜哇!我们有 12 个地址的 12 组数据。我们可以很容易地使用更多的正则表达式来提取每月和每周的租金。我将向你展示我是如何做到的,但是试着像我上面做的那样分解它,所有那些符号会显得不那么令人生畏。首先,提取月份…

str_extract(price_month, '[A-Z][a-z]{2} \\d{4}$') %>%
  head(5)## [1] "Aug 2018" "Aug 2018" "Aug 2018" "Aug 2018" "Aug 2018"

…然后是每周租金:

str_extract(price_month, '(?<=Rent \\$).*(?=/week)') %>%
  head(5)## [1] "420" "510" "490" "500" "550"

目标:属性配置

我们开始想要分析与我的公寓相似的公寓。也就是说,我们想要分析有 2 间卧室、1 间浴室和 1 个停车位的公寓。查看搜索结果可以发现,我们需要考虑两种情况:

  • 大多数房产至少有一间浴室和一个停车位,所以我们有 3 个数字——卧室数量、浴室数量和停车位数量。
  • 有些酒店没有停车位。所以我们有两个数字——卧室的数量,后面是浴室的数量。

我想捕捉这两种模式,这样我就有 12 套公寓配置,它们可以很容易地与 12 个地址、月和周租金组合在一起。一旦它们被组合成一个数据框,我就可以很容易地过滤掉那些不符合我的目标公寓配置的公寓。

尝试将下面的正则表达式翻译成简单的英语:

first_page %>%
  html_nodes('li') %>%
  html_text() %>%
  str_extract(' \\d \\d (\\d )*$') %>%
  str_trim() %>%
  .[which(!is.na(.))]##  [1] "2 1 1" "2 1 1" "2 1 1" "2 1 1" "2 1 1" "2 2 1" "2 1 1" "2 1 1"
##  [9] "2 2 1" "2 2 1" "2 2 1" "2 2 1"

像 Voltron 这样的表单:创建我们的最终数据集

那么,我们学到了什么?

  • 我们知道前 n 页的 URL 是什么。
  • 我们知道如何从这些页面中提取感兴趣的数据。

在分析我们的数据之前,我们需要做的就是编写一个循环,遍历公寓的 n 个页面,同时将每个页面的数据追加到某个主数据集。然后,我们将这个主数据集子集用于匹配我们期望的公寓配置的公寓。描述这个过程不是本文的重点,所以我将在本文的最后提供我的最终代码。

亲爱的房地产经纪人…

两室一卫一车位公寓的周租金在几个月内变化很大。

导致这种情况的一些可能原因如下:

  • 新公寓的租金比旧公寓贵——快速浏览一些更贵公寓的照片可以发现,它们位于火车站附近新建的公寓里。
  • 离火车站和购物区较近的公寓比离这些较远的公寓租金更贵。

我的公寓很旧了,离火车站大约 10 分钟的路程。这绝不是例外,所以我觉得一个“典型”的价格最能描述我公寓的“真实”周租金。所以我尝试了一些平滑的方法。

我个人喜欢通过 ggplot 的 geom_smooth()使用黄土。

然而,我不想向我的房地产经纪人解释黄土是如何工作的。所以我决定采用季度租金中值。不是取个平均值那么简单。但我认为,考虑到异常值,中位数是合适的,如果有人问我对统计数据的选择,这很容易解释。

所以我写了一封邮件:

1.去年,租金每周上涨 20 美元,这似乎超过了当时的市场价格(更多信息见下文)。

2.我自己对数据进行了审查,发现我们目前支付的租金是合理的:

*我使用 webscraping 收集了 2016 年 1 月至 2017 年 8 月在阿什菲尔德新租的 346 套“两室一卫一车位”公寓的数据。租金从旧公寓每周约 400 美元到全新公寓每周 600 多美元不等。

*自 2017 年 1 月以来,租金中位数似乎一直徘徊在 500 美元以上或略低于 500 美元的水平(请参见下图)。事实上,这一时期每周租金的中位数是 495 美元。

*我已将此与最新的新南威尔士州房屋租赁和销售报告进行了交叉核对。阿什菲尔德一套两居室公寓上个季度的租金中值是 500 美元。中位数略高于我的数字是有道理的,因为新南威尔士州的住房数据将包括拥有不止一个浴室或不止一个停车位的公寓。

*去年我们的租金提高到每周 500 美元时,中位数价格徘徊在每周 480 美元左右。我已经将此与新南威尔士州 12 月份的房屋租赁和销售报告进行了交叉核对,并可以确认这是准确的。

故事的寓意:数据是强大的

这封邮件我一直没有收到回复。相反,我收到了一份未来 12 个月每周租金相同的合同!

数据是强大的,所以要学会如何使用它。去存点钱吧,伙计们!

贾斯廷

原载于 2018 年 9 月 1 日【https://embracingtherandom.com】

用语境化的单词向量代替你的单词嵌入

原文:https://towardsdatascience.com/replacing-your-word-embeddings-by-contextualized-word-vectors-9508877ad65d?source=collection_archive---------5-----------------------

“high-rise buildings” by Micaela Parente on Unsplash

受 Mikolov 等人(2013)和 Pennington 等人(2014)的影响,单词嵌入成为初始化 NLP 项目的基本步骤。之后又引入了很多嵌入如LDA 2 vec(Moody Christopher,2016)字符嵌入,doc2vec 等等。今天,我们有了新的嵌入,即语境化的单词嵌入。这种想法是相似的,但他们实现了相同的目标,即使用更好的单词表示来解决 NLP 任务。

看完这篇帖子,你会明白:

  • 语境化的词向量设计
  • 体系结构
  • 履行
  • 拿走

语境化的词向量设计

“white sand beach under white sky” by Itchy Feet on Unsplash

受 CNN 的启发,McCAnn 等人专注于训练编码器,并将其转换为其他任务,以便可以利用更好的单词表示。不使用 skip-gram (Mikolov 等人,2013 年)或矩阵分解(Pennington 等人,2014 年),而是利用机器翻译来构建上下文化的词向量(CoVe)。

假设机器翻译(MT)足够通用以捕获单词的“含义”,我们建立一个编码器和解码器架构来训练 MT 的模型。之后,我们将编码器层“转移”到其他 NLP 任务(如分类问题和问题回答问题)中转移单词向量。

McCann B., Bradbury J., Xiong C., Socher R. (2017)

图 a 显示了如何为机器翻译训练模型。给出单词向量(例如 GloVe ),以便我们可以从模型中获得上下文向量(CoVe)。

体系结构

McCann B., Bradbury J., Xiong C., Socher R. (2017)

图 b 显示了重用结果 a 中的编码器并将其应用于其他 NLP 问题。

McCann B., Bradbury J., Xiong C., Socher R. (2017)

如图 b 所示,“特定任务模型”的输入是单词向量(例如 GloVe 或 word2vec)和编码器(即来自 MT 的结果)。因此,McCann 等人引入了上述公式来获得新词嵌入(串联 GloVe(w)和 CoVe(w))。

实现

在此之前,您需要安装相应的库(从 CoVe github 复制):

git clone https://github.com/salesforce/cove.git # use ssh: git@github.com:salesforce/cove.git
cd cove
pip install -r requirements.txt
python setup.py develop
# On CPU
python test/example.py --device -1
# On GPU
python test/example.py

如果您在“pip install-r requirements . txt”上遇到问题,您可以用以下命令替换它

conda install -c pytorch pytorch
pip install -e git+[https://github.com/jekbradbury/revtok.git#egg=revtok](https://github.com/jekbradbury/revtok.git#egg=revtok)
pip install [https://github.com/pytorch/text/archive/master.zip](https://github.com/pytorch/text/archive/master.zip)

如果用 Keras (Tensorflow),可以按照这个笔记本建 CoVe。但是,在原来的笔记本上有一些问题,你可以看看我修改的版本作为参考。问题在于原始凹穴(pytorch 将层名称从“rnn”更新为“rnn1”)。预训练模型(下载 Keras_CoVe.h5)也可用。

另一方面,你也可以使用预先转换的 Keras 版本。

# Init CoVe Model
cove_model = keras.models.load_model(cove_file)# Init GloVe Model
glove_model = GloVeEmbeddings()        glove_model.load_model(dest_dir=word_embeddings_dir, process=False)# Encode sentence by GloVe
x_embs = glove_model.encode(tokens)# Encode GloVe vector by CoVe
x_embs = cove_model.predict(x_embs)

拿走

要访问所有代码,可以访问这个 github repo。

  • CoVe 需要标签数据来获得上下文单词向量。
  • 用手套建造洞穴
  • CoVe 无法解决 OOV 问题它建议使用零向量来表示未知单词。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客LinkedInGithub 联系我。

参考

放大图片作者:Michael b ...在翻译中学习:语境化的词向量。2017.http://papers . nips . cc/paper/7209-learned-in-translation-contextualized-word-vectors . pdf

py torch 的小海湾(原文)

喀拉斯湾

神经网络的表示能力

原文:https://towardsdatascience.com/representation-power-of-neural-networks-8e99a383586?source=collection_archive---------6-----------------------

我们知道神经网络及其在从数据科学到计算机视觉等多个领域的无数成就。众所周知,他们擅长解决涉及概括的复杂任务。从数学上来说,它们非常擅长于逼近任何复杂函数的行为。让我们直观地理解这种近似的概念,而不是预测误差最小化的向前和向后传播方法。假设您了解前向和后向传播的一些基本知识,前向和后向传播旨在借助梯度和网络中的误差传播来近似函数的行为。让我们用另一种视觉解释来理解神经网络的近似能力。涉及基础数学和图形分析。

从数学上讲,我们将着眼于给定神经网络对于所提供的要近似的函数的表示能力。

表示能力与神经网络将适当的标签分配给特定实例并为该类创建良好定义的精确决策边界的能力相关。在本文中,我们将探索一种视觉方法来学习更多关于神经网络的近似行为,这与神经网络的表示能力直接相关。

旅程

这都是从 MP 神经元开始的,这是一个非常简化的神经元模型。对于一个给定的函数,只要所有输入的总和大于阈值,神经元就会触发,否则就不会触发。非常原始的开始。为了检验它的表示能力,让我们看一个几何解释。首先用 2 个输入进行二维分析,以近似 or 函数,然后再用 3 个输入进行三维分析。

For separation in a 2-D coordinate system a line is required. The neuron will fire for points right to the line. Hence, a separation boundary created.

For separation in 3-D coordinate system a plane is required. Neuron will fire for all points above the plane.

因此,麦卡洛克皮茨神经元可以用来表示任何线性可分的布尔函数
。此外,我们可以看到一个严格的划分规则,而不是一个渐进的决策边界,任何略高于分离边界的内容都称为 1 ,略低于分离边界的内容称为 0 。神经元触发类似阶跃函数的行为。使用感知器可以获得更大的灵活性,感知器的每个输入都有权重,但仍然存在严格的界限。但是,上述机制不适用于非线性可分函数。一个非常简单的例子是 XOR,想象一下在二维平面上为这个函数画一条分隔线。不会有了!与 XOR 非常相似,大多数数据在本质上都是线性不可分的。

因此,需要像当前神经网络这样的高级计算模型来为这些功能创建分离的边界。只是看到一个基本的插图,其中有一个隐藏层和一些预定义的权重,复制异或函数。

Conditions for implementation of XOR: w1<w0, w2≥w0, w3≥w0, w4<w0

记住:任何输入为 n 的布尔函数都可以用一个感知器网络来表示,这个网络包含一个带有 2^n 感知器的隐藏层和一个包含 1 个感知器的输出层。这是一个充分条件,不是必要条件。

通过我们对单隐层网络的阶跃函数近似分析。它有局限性,其苛刻的判断标准相当于一个阶跃函数。让我们深入研究具有 s 形非线性近似函数的多层深度网络。

今日故事

s 形神经元的表达能力要高得多。具有单个隐藏层的多层神经元网络可以用来以任何期望的精度逼近任何连续函数。

数学上有一个保证,对于任意一个函数 f(x): R(n) → R(m),我们总能找到一个隐层/s 的神经网络,它的输出 g(x)满足| g(x)—f(x)|< Θ

The above claim is 性质上相当大的。因为这意味着我们可以用一个给定的神经网络来逼近任何函数。在数学术语中,通用逼近定理陈述了在激活函数的温和假设下,具有包含有限数量神经元的单个隐藏层的自动编码器网络可以逼近 R(n) 的紧致子集上的连续函数。因此,该定理指出,当给定适当的参数时,简单的神经网络可以代表多种功能。然而,它没有触及这些参数的算法收敛性。收敛部分与前向和后向传播算法有关。让我们来理解对上述定理的直观解释,它作为神经网络中学习行为的基本基础。

Geometric Interpretation of Function Approximations. Classical mathematical approach in Numerical Approximation.

最终游戏:Sigmoids 塔

继续上述用神经网络逼近函数的讨论。看看下面的图表,自己决定吧。一个函数可以用几个塔函数叠加来近似。该过程将形成一个形状,该形状相当于给定函数被近似,其中有一些微小的近似误差。现在,通用逼近定理的上述解释告诉我们,我们用于逼近的塔的数量越多,逼近行为越好。因此,在 s 形激活中调整参数,目的是创建这样的近似塔。按照这种解释,理论上对神经网络的准确性没有限制。

Clearly, more the number of towers better the approximation & lesser the approximation error.

让我们更深入地研究这个解释过程。所有这些“塔”功能都是相似的,只是在 x 轴上的高度和位置不同。现在,我们必须看看这些是如何用 sigmoid 激活函数创建的。

Our aim is to figure out the black-box Tower Maker for tower construction.

典型逻辑 sigmoid 激活函数方程如下所示。

w: represents weights | b: represents bias

随着 w 的增加,函数变得更加陡峭,就像阶跃函数一样。 b 的正值越大,曲线从原始曲线向左移动。

因此,通过改变这些值,我们可以创建不同版本的 sigmoids,我们可以将它们相互叠加,以获得类似塔的结构。为了在二维坐标系中创建塔,减去具有两个不同偏差值的曲线。

Left curve is having more positive value of bias b. Hence, with multiple such towers above random curve can be approximated or represented.

我们可以将这种操作扩展到神经网络的隐藏层,以构建模拟这种曲线减法行为的神经网络。因此,神经网络可以用权重和偏差的参数值来表示任何这样的函数,我们用我们的前向和后向传播算法连续确定这些参数值,直到达到收敛标准。

Now, the above illustrated random curve of a function can be approximated by superimposing such towers.

个案研究

考虑具有多个输入的场景。假设我们正试图决定是否会在海底的特定位置找到石油。此外,假设我们的决定基于两个因素:盐度(x1)和压力(x2)。给我们一些数据,似乎 y(oil|no-oil)是 x1 和 x2 的复变函数。我们想要一个神经网络来近似这个函数。

Illustration above plots the above scenario. Clearly, we need 3-D towers which approximates the distribution function.

在我们的理解中,我们需要在三维坐标系中制作这样的三维封闭塔。如果我们进行上述在三维空间中具有不同偏差的两个 sigmoids 相减的类似方法。我们将得到下面的等价曲线。

We still didn’t get a closed tower.

但是,我们可以看到,如果我们采取另一个水平垂直塔电流合成曲线以上。将这两个水平垂直的开放塔叠加起来,我们可以得到封闭塔。

我们可以通过另一个组合 sigmoid 激活函数来传递上述输出,以获得最佳近似的适当塔。

We can now approximate any function by summing up many such
towers

在多个这样的塔的帮助下,可以重建上述案例研究中的复杂分布函数。这里,让我们看一个神经网络来代表上述程序。

我们刚刚看到的说明性证明告诉我们,我们可以有一个具有两个隐藏层的神经网络,它可以通过一些塔来近似上述函数。这意味着我们可以有一个神经网络,它可以像上面案例研究中提到的那样准确地分离这种分布。对神经网络的精确度没有理论上的限制。

我们感兴趣的是把蓝点和红点分开。对于单个 s 形神经元,显然会存在误差。但是,有了两个隐藏层,我们可以用一组塔来近似上述函数。我们可以有一个神经网络,可以准确地将蓝点和红点分开!!

承认

近似的可视化方法是非常独特和有趣的,这就是为什么我觉得有必要进行这次讨论。我只是重组了 neuralnetworksanddeeplearning.com 已经存在的解释。描述性插图借用自深度学习课程 CS7015。感谢 Mitesh M. Khapra 教授和他的助教们的精彩课程!!

可再生研究:星际采矿

原文:https://towardsdatascience.com/reproducible-research-starcraft-mining-ea140d6789b9?source=collection_archive---------2-----------------------

Troop movements in StarCraft

2009 年,我发表了一篇关于使用不同分类算法预测《星际争霸:繁殖战争》建造顺序的论文。我把 T2 的数据集 T3 提供给其他研究人员测试,一些 T4 的学术项目 T5 已经使用了这个数据集。然而,我从来没有为实验提供源代码,最终丢失了它,类似于暴雪和最初的星际争霸的源代码。自从转行到游戏行业,我开始倡导我的同事建立可重复的研究。这意味着编写输出结果的代码,删除手动步骤,并使用可以在不同机器和平台上重现的环境。

自从宣布星际争霸重制版和谷歌的 DeepMind 应用于星际争霸 2 以来,人们对星际争霸人工智能的研究又有了新的兴趣。自从我第一次发表这项研究以来,近十年过去了,我很好奇我是否可以重现这个实验,看看最近的技术,如 XGBoost 是否会优于我之前测试的分类算法。

初始设置 我对这些实验的初始设置是 Java 代码和 Weka 库的混合。我首先使用交互式 Weka GUI 测试了不同的分类器,然后当我想要运行实验时,就切换到使用 Weka API。我的 Java 脚本会运行实验并将结果输出到文本文件中,在制作图表时,我会手动将这些文本文件复制到 excel 中。我在我的 Windows 笔记本电脑和大学的 Unix 服务器上都进行了实验。

Protoss vs. Terran Build Order Prediction

我想重现的关键实验是预测对手在游戏中不同模拟时间的建造顺序。我的论文中的这个实验的输出如上所示。随着不同的算法获得更多的信息,它们在识别对手的建造顺序方面变得更好。这 1000 多个回放被标记为 6 个不同的构建顺序,我标记构建顺序的方法在本文中有更详细的介绍。

新脚本 我的以可重复的方式运行这个实验的新方法是使用 R Markdown ,这是一种可以嵌入 R 代码和可视化的 Markdown 语言。这种方法的目标是在运行实验时消除所有手动步骤。markdown 脚本从 github 下载必要的数据文件,运行实验,并将结果呈现为 pdf 文档或 html 文件。脚本在这里可用,结果在 pdfhtml 格式可用。该脚本的输出之一如下图所示。

Reproduced Experiment for Protoss vs Terran Build Order prediction

该脚本直接从 Github 加载神族对人族建造命令的数据帧。这消除了在本地复制实验文件的需要。

df <- read.csv("https://github.com/bgweber/StarCraftMining/
                         raw/master/data/scmPvT_Protoss_Mid.csv")

实验从 12 分钟的游戏时间开始,然后后退以模拟游戏过程中不同的时间步长。我使用这种方法来避免多次重新加载数据框。下面的片段显示了数据帧( df )如何被过滤到特定的比赛时间()。

for (i in colnames(df)) {
  if (i != 'label') {
    index <- df[i] > frame 
    df[i][index] <- 0
  }
}

我应用了以下包中的分类器:最近邻( class )、决策树( rpart )、神经网络( nnet )和 xgboost( xgboost )。

predict <- knn(train, test, train$label, use.all = FALSE)
reg <- nnet::multinom(label ~ ., data=train, trace = FALSE)
model<- rpart(factor(label) ~ ., data = train)
bst <- xgboost(data = trainM, label = train$label, ... )

并使用 ggplot2 绘制结果,生成上图:

ggplot(data=melt(results, id="minutes"), aes(x=minutes, y=value,   
                         colour=variable)) + geom_line() + ...

结果显示,xgboost 在 10 分钟的游戏时间内,以 96%对 94%的准确率,确实优于论文中性能最好的算法 LogitBoost 。然而,在早期游戏中最近邻方法优于其他分类器的最初发现仍然存在。

该脚本还生成了第二个图表,这是游戏开始 8 分钟时不同特性的重要性。这是一种我在原始论文中没有包括的分析,但在这里包括是有趣的,因为它显示了球员在侦察对手时应该注意什么。基于训练好的模型,特征的重要性随着时间而变化。下面的可视化是使用 xgboost 函数 xgb.importancexgb.plot.importance 生成的。

Feature importance at 8 minutes game time identified by xgboost

新环境 我在我的 Windows 笔记本电脑上写了 R Markdown 脚本进行测试。为了使实验在不同的机器和环境中可重复,我使用了 Docker 。我从 CentOS 映像开始,安装 R,设置库和其他依赖项,如 pandoc,然后运行脚本,输出一个带有可视化效果的 html 文件。我使用 Amazon Linux 实例在 AWS 上构建了一个 EC2 实例,并运行了下面的命令。以下部分突出显示了一些命令:

# install and start docker 
sudo yum -y install docker 
sudo service docker start# get the centos image, and start it in interactive mode 
sudo docker pull centos 
sudo docker run -t -i centos /bin/bash# install R, which requires updating the repo 
yum -y install R# install required R packages 
R -e "install.packages('caTools', repos='[http://cran.us.r-project.org'](http://cran.us.r-project.org'))"
...# download the RMD file 
wget [https://github.com/bgweber/StarCraftMining/SC_Data_Mining.Rmd](https://github.com/bgweber/StarCraftMining/raw/master/SC_Data_Mining.Rmd)# run the script! 
Rscript -e "rmarkdown::render('SC_Data_Mining.Rmd')"

对于这个例子,我在交互模式下运行容器。如果我想在将来持久化运行实验的环境,我将创建并应用一个 docker 文件,并将结果图像保存到 docker 注册表中。这将确保对 R 库或其他依赖项的更改不会影响实验环境。

结论 如果我今天要重写这篇研究论文,我会推荐使用让实验可重复的工具。使用 R Markdown 和 Docker 是帮助实现这个目标的一种方法。

数据科学教学研究

原文:https://towardsdatascience.com/research-on-teaching-data-science-bb0daecf6b12?source=collection_archive---------9-----------------------

我写这篇文章是作为 2018 年春天在斯坦福大学参加 Hadley Wickham 应用数据科学课程阅读的一部分。

介绍

随着数据科学技能变得越来越重要,数据科学的教学也变得越来越有价值。在数据科学的背景下,我认为教学不是在白板上交谈或给工作表评分的传统过程,而是创造环境和设计体验的过程,这种过程可以为学生带来可衡量的学习。

就定义而言,我对培养学生从数据中提取价值的能力感兴趣(我称之为数据科学)。我感兴趣的学生是任何有算术背景的人,不需要额外的培训,比如说,代数,但不一定有编程或任何级别的严肃统计的背景。

美国统计协会建议

美国统计协会(ASA)已经认识到,随着形势的变化,有必要对培训进行调整。2005 年,他们首次提出了关于介绍性统计未来方向的建议,并在 2016 年再次更新了这些建议(ASA 2016)。他们的目标是在大学教授统计学导论,但其中包含的智慧也适用于任何环境下的数据科学教学。以下是他们的建议(第 3 页):

  1. 教授统计思维。
  2. 注重概念理解。
  3. 将真实数据与上下文和目的相结合。
  4. 培养主动学习。
  5. 利用技术探索概念和分析数据。
  6. 使用评估来改进和评估学生的学习。

这些建议中的大部分只是一般的好教学。例如,最近有大量的教育研究指出了主动学习的显著的可测量的益处(C. E. Wieman 2014Koedinger 等人 2015)。还值得指出的是,一些学者认为这些建议指向正确的方向,但仅仅这样还不够(G. Cobb 2015)。

在任何情况下,ASA 建议的关键是批判性思维或决策。Holmes,Wieman 和 Bonn (2015)将批判性思维定义为“基于数据做出决策的能力,及其固有的不确定性和可变性”(第 1 页)。ASA 没有就如何培养学生的批判性思维提供任何明确的指导,但 Holmes,Wieman 和 Bonn (2015)提供了非常简单的建议:“发展这种能力的关键因素是反复练习根据数据做出决定,并对这些决定进行反馈”(第 1 页)。

数据科学教学中尚未解决的问题

ASA 的建议和教育研究提供了一些显而易见的建议,如让学生在用技术分析真实数据的同时主动学习;当引入新思想时,注重概念理解,而不是死记硬背;并通过评估来衡量学生的学习。那么,教学数据科学的困难或未解决的部分是什么?我认为有三个:第一,建立一个有利于学习的社会环境或文化;第二,选择技术和设计学习活动,要求学生做出决定;第三,测量或评估学习。

1)创造文化

建立一个让学生自由地展示他们自己的知识状态并同情地互相帮助学习的环境是非常困难的。增长思维模式的想法首先由卡罗尔·德韦克提出(德韦克和 Sumoreads 2017)。Jo Boaler 特别在数学课堂的背景下讨论了成长思维模式,并恰当地将其称为“数学思维模式”(Boaler 2016)。他们的研究指出了学生相信他们可以通过实践提高的重要性。或许更有趣的是,他们提供了如何培养成长心态的建议,比如赞扬努力而不是技能(Khan 2014)。

我喜欢“数据科学思维”的想法建立这样一种心态尤其重要的是让学生进行批判性思考,并作为一个群体做出决定。为了有效地做到这一点,学生们需要在社交上彼此特别自在。人类可能是害羞的动物。创造环境来克服这种趋势,让学生们彼此深入交流,分享想法,并富有成效地挑战彼此的想法是极其困难的。

我见过的实现这个目标的最接近魔术的方法是即兴表演。从我的经验来看,学生们可以害羞和不自信地进入一个房间,几个小时后通过一起即兴表演,彼此之间完全舒服了。《第二城市课堂即兴表演指南》一书详细介绍了课堂即兴表演的好处以及具体的活动建议(McKnight 和 Scruggs 2008)。这些技术可以很容易地适应数据科学环境,例如,让学生作为一个小组表演一个函数做什么,让学生在遇到错误时热情地大喊“耶”,或者要求学生在头脑风暴如何解决数据科学问题时以“是的,并且…”开始句子。这些想法可能会让一些人觉得很傻,但实际上这是最基本的要素。

教师经常忽略有目的地建设文化。在我看来,没有比这更大的错误了。投资课堂文化,尤其是在开始阶段,会带来巨大的回报。如果一个老师没有明确地构建文化,课堂的文化很可能会变得类似于课堂之外的“真实世界”的文化,这对于来自往往在分析圈子中被边缘化的背景的学生来说尤其有害。从本质上说,建设文化既是一个公平和有效性的问题(P. Cobb 和 Hodge 2011)。

2)选择技术和设计学习活动(要求学生做出决定)

学习技术的选择归结为管理一门课程的能量。如果精力花在学习技术的细节上,那么用于其他主题的精力就会减少。然而,认识到一些学习技术比其他技术对学生来说更有价值也很重要。例如,使用 R(相对于特定用途的学习小程序)可能会为课程带来更高的成本,但在课程结束后对学生也有更大的潜在价值。

在使用激励视频、真实数据和免费软件学习统计数据时,Harraway (2012)提倡使用 GenStat 软件进行教学(GTL ),这是专业软件 GenStat 14 的淡化版本。GTL 旨在占据电子表格和高级数据分析软件之间的中间地带,完全由菜单驱动,专注于基本统计需求的易用性,如转换数据、模型拟合、假设检验和引导。创作者通过在几个教室试用该软件,然后观察和调查结果来衡量该软件的有效性——例如,在 41 名学生中,只有 6 名学生认为 GTL 很难使用。GTL 也有与其特色直接相关的学习活动和视频。

Harraway (2012)承认 R 是 GTL 的最大竞争对手,但不断强调不必要的复杂性和因需要编程和语法而导致的挫折感。我发现这是这篇论文提出的最有趣的问题。使用专业软件,消除初学者的复杂性,设计有目的的学习活动似乎是一个好主意,但我很难接受基于菜单是必需的甚至是可取的功能这一论点。我之前认为,对于所有学生来说,与基于语法的程序进行互动是一个很好的练习,并且通过良好的课程设计和教学,可以使这种互动变得不那么痛苦。无论如何,为学习者特别设计的轻量级软件的基本点是有趣的。

在 FiveThirtyEight R Package:统计学和数据科学入门课程的“驯服数据”原则中,Kim、Ismay 和 Chunn (2018)没有描述如何使软件变得更简单,而是倡导以一种要求学生专注于重要障碍的方式驯服数据。例如,首先以整齐的格式提供数据,这样学生就不必担心数据的整形。他们将这一建议付诸行动,提供了一个记录良好的 R 包,其中包含来自数据驱动的新闻网站 FiveThirtyEight 的数据集。

他们的基本原则是,学生需要学习数据科学的“整个游戏”,而不是一次只学习一个孤立的部分,但通过将学生抛入深渊来这样做是适得其反的,因为学生经常会在低收益概念或他们尚未准备好的概念上打转。因此,解决方案是基于有目的地策划的数据来设计学习体验,让学生体验数据科学的整个游戏,并在正确的时间遇到正确的障碍(例如,富有成效的斗争)。我认为这正是数据科学教师应该持有的正确心态。非常困难的部分是设计数据集和这种目的水平的学习体验。提供的 R 包是一个好的开始。

关于数据科学教学技术的第三篇论文是使用 R 和 Shiny 的统计数据 Web 应用教学工具(Potter 等人,2016 年)。他们指出,小程序可以成为强大的教学工具,尤其是帮助学生建立直觉。然而,构建小程序需要专业技术知识和大量的时间。Shiny 大大简化了这个过程。这篇论文附带了一个网站,展示了各种令人印象深刻的小程序。

相对于课程中使用的主要软件,小程序似乎有些不重要,但我实际上认为教师为他们的教室设计闪亮的应用程序可能非常有价值,特别是如果与深思熟虑的驯服数据练习相结合。想象一下,一个学生处理一个平淡无奇的数据分析,但是在这个过程中遇到了令人毛骨悚然的统计概念,有一个专门为数据分析设计的小程序可以帮助学生建立统计直觉。这可能非常强大。

总之,我在关于数据科学的技术使用和活动设计的文献中看到的最大差距是没有足够重视实际要求学生做出决定。不要问学生某人准时上班的概率有多大,而是问他们建议这个人什么时候离开。不要问学生治疗效果如何,如果有不同的效果,问他们会把药物给谁,有一百万美元的固定预算。

然后对过程和决策给出反馈。例如:

你的团队把药给了年轻男性而不是年长女性,因为你没有正确解释选择偏差。10 名年轻男子被治愈,但机会成本是 1000 名老年妇女的生命。您应该在回归中控制邮政编码,而不是州。也许您忽略了这一点,因为您在清理数据时没有将地理变量放在一起(参见第一个脚本的第 22 行)。”

想象一下这与通常的反馈有多么不同:

“你对异质效应的估计似乎是错误的,也许是因为你没有正确解释选择偏差。”

我的观点是,高质量数据科学活动的重要部分是提出专注于决策和设计活动的问题,以便学生遇到重要的障碍,而学生没有准备好面对的障碍则通过仔细的数据整理被离散地消除。老师还需要深入理解数据的每一个细节,以便他们能够快速识别学生的位置,并引导他们朝着正确的方向前进。真实世界的数据当然是首选,但如果这需要使用感觉真实的模拟数据,我认为这也没问题。

3)测量/评估学习

数据科学是关于决策的,而决策是很难衡量的。机器可分级的格式似乎并不奏效,而且替代方案非常耗时且主观。此外,理想的数据科学学习成果通常是长期的,与学生对数据科学的关系和实际掌握技能一样重要。考虑到这一点,也许课程调查和收集学生信心和情绪的数据与传统的教育评估一样有价值(Wirth and Perkins 2005)。

总之,在有效测量和评估数据科学学习的道路上,我们还有很多山要爬。Maurer 和 Lock (2016)提供了一个有趣的起点,他们将爱荷华州立大学的学生随机分配到基于模拟或传统的推理课程中,并比较学生在针对特定学习目标的问题上的前后测试收获。类似的例子见于 C. Wieman 和 Holmes (2015 年)。一个有希望的未来方向是考虑项目评估,它从更广阔的角度来衡量。Moore 和 Kaplan (2015)通过评估佐治亚大学本科统计学专业提供了一个例子。

文献学

  • 阿萨。2016."统计教育评估和指导指南-学院报告."http://www . amstat . org/asa/files/pdf/GAISE/GAISE college _ full . pdf
  • Boaler,J. 2016。“数学思维。”加利福尼亚州旧金山:乔西-巴斯。
  • 科布乔治。2015.“单纯的革新太少也太迟了:我们需要从头开始重新思考我们的本科课程。”美国统计学家 69④。泰勒和弗朗西斯:266–82。
  • 科布,保罗,林恩廖霍奇。2011."数学课堂中的文化、身份和公平."《数学教育研究之旅:保罗·科布作品中的洞见》, Anna Sfard,Koeno Gravemeijer 和 Erna Yackel 编辑,179–95 页。多德雷赫特:荷兰施普林格。
  • 德韦克,卡罗尔 s,和 Sumoreads。2017.卡罗尔 s .德韦克的心态总结:关键要点与分析。创建空间独立发布平台。
  • 约翰·哈罗维,2012 年。"使用激励视频、真实数据和免费软件学习统计学."统计教育中的技术创新 6 (1)。https://escholarship.org/uc/item/1fn7k2x3
  • N. G .福尔摩斯卡尔·E·威曼和波恩地方检察官。2015.“教授批判性思维。”美国国家科学院院刊 112(36):11199–204。
  • 可汗萨尔。2014."学习神话:为什么我永远不会告诉我的儿子他很聪明."可汗学院。2014.https://www . khanacademy . org/talks-and-visitors/conversations-with-sal/a/the-learning-myth-why-ill-never-tell-my-son-hes-smart
  • 金、艾伯特·y、切斯特·伊斯梅和詹妮弗·楚恩。2018." FiveThirtyEight R 包:统计学和数据科学入门课程的“驯服数据”原则."统计教育中的技术创新 11 (1)。【https://escholarship.org/uc/item/0rx1231m】T4。
  • Koedinger,Kenneth R .,Jihee Kim,Julianna 祝新贾,Elizabeth A. McLaughlin 和 Norman L. Bier。2015."学习不是一项观赏性运动:从 MOOC 中学习,做比看更好."第二届(2015 年)ACM 学习会议论文集,第 111-20 页。L@S '15。美国纽约州纽约市:ACM。
  • 毛雷尔,卡斯滕和丹尼斯·洛克。2016."在一个设计的教育实验中,基于模拟和传统推理课程的学习结果的比较."统计教育中的技术创新 9 (1)。https://escholarship.org/uc/item/0wm523b0
  • 麦克奈特,凯瑟琳 s 和玛丽斯克鲁格斯。2008.第二城市课堂即兴表演指南:利用即兴表演教授技能和促进学习。约翰·威利父子公司。
  • 摩尔、艾莉森·阿曼达和詹妮弗·j·卡普兰。2015."本科统计学专业的项目评估."美国统计学家 69④。泰勒和弗朗西斯:417–24。
  • 波特、盖尔、黄谷悦、欧文·阿尔卡拉斯、彼得·池等人。2016." Web 应用统计教学工具使用 R 和 Shiny . "统计教育中的技术创新 9 (1)。https://escholarship.org/uc/item/00d4q8cp
  • 斯特恩丹。2017.“自学数据科学:我用来在 Jet.com 获得分析工作的学习途径”,2017 年。https://medium . freecodecamp . org/a-path-for-you-learn-analytics-and-data-skills-BD 48 ccde 7325
  • 斯塔滕,萨维纳·范德。2017.“离开我的风投工作,去学习数据科学和机器学习。”2017.https://towards data science . com/leaving-my-VC-job-to-learn-about-data-science-and-machine-learning-4 DBC 15427 fc 5
  • 卡尔·威曼,2014 年。"科学教学方法的大规模比较传达了明确的信息."美国国家科学院学报 111(23):8319–20。
  • 威曼、卡尔和 N. G .霍姆斯。2015."测量物理入门实验室对学习的影响."arXiv[物理学博士]。arXiv。http://arxiv.org/abs/1507.00264
  • 沃思,卡尔 r,和德克斯特帕金斯。2005."知识调查:不可或缺的课程设计和评估工具."教与学的学术创新。serc.carleton.edu。http://serc . carleton . edu/files/garnet/knowledge _ surveys _ indepensabl _ 1313423391 . pdf

剩余块 ResNet 的构建块

原文:https://towardsdatascience.com/residual-blocks-building-blocks-of-resnet-fd90ca15d6ec?source=collection_archive---------1-----------------------

理解一个剩余块是相当容易的。在传统的神经网络中,每一层都反馈到下一层。在有剩余块的网络中,每一层都馈入下一层,并直接馈入大约 2-3 跳之外的层。就是这样。但是,理解为什么首先需要它,为什么它如此重要,以及它看起来与其他一些最先进的架构有多么相似,这是我们要关注的地方。关于残差块为什么如此棒,以及它们如何&为什么是可以使神经网络在广泛的任务中表现出最先进性能的关键思想之一,有不止一种解释。在深入细节之前,这里有一张残余岩块的实际样子的图片。

Single Residual Block. (img src)

我们知道神经网络是通用的函数逼近器,并且精度随着层数的增加而增加。但是导致精度提高的增加的层数是有限的。因此,如果神经网络是通用函数逼近器,那么它们应该能够学习任何简单或复杂的函数。但事实证明,由于一些问题,如消失梯度和维数灾难,如果我们有足够深的网络,它可能无法学习像身份函数这样的简单函数。这显然是不可取的。

此外,如果我们不断增加层数,我们会发现精度会在某一点饱和,最终会下降。并且,这通常不是由于过度配合造成的。因此,看起来较浅的网络比较深的网络学习得更好,这是非常违背直觉的。但这是在实践中看到的,通常被称为退化问题。

没有根导致退化问题和深度神经网络无法学习身份函数,让我们开始考虑一些可能的解决方案。在退化问题中,我们知道较浅的网络比添加了几层的较深的网络表现得更好。那么,为什么不跳过这些额外的层,至少匹配浅层子网的精度。但是,如何跳过层呢?

可以使用跳过连接或剩余连接跳过几层的训练。这就是我们在上图中看到的。事实上,如果你仔细观察,我们可以只依靠跳过连接直接学习一个恒等式函数。这就是为什么跳过连接也被称为标识快捷连接的确切原因。所有问题的一个解决方案!

但为什么称之为残余呢?残渣在哪里?是时候让我们内心的数学家浮出水面了。让我们考虑一个神经网络块,它的输入是 x,,我们想知道真实的分布 H(x) 。让我们将这两者之间的差(或残差)表示为

*R(x)* = Output — Input = *H(x)* — *x*

重新排列,我们得到,

*H(x)* = *R(x)* + *x*

我们的残差块总体上试图学习真实输出, H(x)。如果你仔细观察上面的图像,你会意识到,既然我们有一个来自 x 的身份连接,那么这些层实际上是在试图学习剩余的, R(x) 。总而言之,传统网络中的各层正在学习真实输出( H(x) ),而残差网络中的各层正在学习残差( R(x) )。因此得名:残块

还观察到,学习输出和输入的残差比只学习输入更容易。作为一个额外的优势,我们的网络现在可以通过简单地将残差设置为零来学习身份函数。如果你真正理解反向传播,以及随着层数的增加,梯度消失的问题变得有多严重,那么你可以清楚地看到,由于这些跳跃连接,我们可以将更大的梯度传播到初始层,这些层也可以像最终层一样快速地学习,使我们能够训练更深的网络。下图显示了如何为最佳梯度流排列剩余块和标识连接。已经观察到,批量标准化的预激活通常给出最好的结果(即,下图中最右边的剩余块给出最有希望的结果)。

Types of Residual Block. (img src)

除了上面已经讨论过的解释之外,还有更多对剩余块和结果的解释。在训练 ResNets 时,我们或者训练残差块中的层,或者使用跳过连接来跳过这些层的训练。因此,基于误差在网络中如何反向流动,网络的不同部分将以不同的速率针对不同的训练数据点进行训练。这可以被认为是在数据集上训练不同模型的集合,并获得尽可能好的准确性。

跳过一些剩余块层中的训练也可以从乐观的角度来看。通常,我们不知道神经网络所需的最佳层数(或残差块),这可能取决于数据集的复杂性。不是将层数作为一个重要的超参数来调整,而是通过在我们的网络中增加跳过连接,我们允许网络跳过对那些无用的和不增加整体精度的层的训练。在某种程度上,跳跃连接使我们的神经网络动态地在训练过程中优化调整层数。

下图显示了残差块的多种解释。

Different interpretations of Residual Block. (img src)

让我们稍微了解一下跳跃连接的历史。跳过层间连接的想法最初是在高速公路网络中提出的。高速公路网络与控制通过它们的信息量的门有跳跃连接,这些门可以被训练成有选择地打开。在 LSTM 网络中也可以看到这种想法,它控制着网络所看到的过去数据点的信息流量。这些门的工作方式类似于控制来自先前看到的数据点的内存流。下图显示了同样的想法。

Similar to LSTM Block. (img src)

剩余块基本上是高速公路网络的特例,其跳跃连接中没有任何门。实质上,残余块允许内存(或信息)从初始层流向最后一层。尽管在它们的跳跃连接中没有门,剩余网络在实践中表现得和任何其他公路网络一样好。在结束本文之前,下面是所有剩余块的收集如何完成到 ResNet 中的图像。

ResNet architectures. (img src)

如果您有兴趣了解更多关于 ResNet 及其不同变体的信息,请查看这篇文章

剩余网络

原文:https://towardsdatascience.com/residual-networks-resnets-cb474c7c834a?source=collection_archive---------4-----------------------

在之前的帖子中,我们看到了深度卷积神经网络LeNet-5AlexNetVGG16 的实现。同样,我们可以在理论上建立自己的超过 100 层的深度神经网络,但在现实中,它们很难训练。何、、任和在他们的研究图像识别的深度残差学习中引入了残差网络(ResNets)的概念。ResNets 允许更深的网络有效地训练。

非常深度的神经网络有什么问题?
在训练神经网络的每次迭代期间,所有权重接收与误差函数相对于当前权重的偏导数成比例的更新。如果梯度非常小,那么权重将不能有效地改变,并且它可能完全停止神经网络的进一步训练。这种现象被称为消失梯度。更具体地说,我们可以说,由于非常缓慢的梯度下降,数据正在通过深度神经网络的各层消失。[1]

微软研究发现,将深度网络分成三层块,并将每个块的输入直接传递到下一个块,以及该块的剩余输出减去重新引入的块的输入,有助于消除这种信号消失问题。不需要额外的参数或改变学习算法[1]。换句话说,ResNets 将一个非常深的平面神经网络分解为通过跳过或快捷连接连接的小块网络,以形成一个更大的网络。

ResNets Vs Plain Neural Network

ResNet 中使用两种主要类型的块,主要取决于输入/输出维度是相同还是不同。

a-身份块

标识块是 ResNets 中使用的标准块,对应于输入激活(比如 a[l])与输出激活(比如 a[l+2])具有相同维数的情况。下面是一个标识块的例子,上面的路径是“快捷路径”,下面的路径是“主路径”。

ResNets Identity block

Identity block implementation using keras

b 卷积块

当输入和输出维度不匹配时,我们在捷径路径中添加一个卷积层。这种排列称为卷积块。

ResNets convolutional block

Convolutional block implementation using keras

构建完整的 ResNet 模型(50 层)

现在你已经有了构建一个非常深的 ResNet 所必需的模块。下图详细描述了该神经网络的体系结构。图中的“ID BLOCK”代表“身份块”,而“ID BLOCK x3”意味着您应该将 3 个身份块堆叠在一起。

50 layers ResNets Architecture

上述 ResNet-50 型号的详细信息如下:

  • 零填充:用(3,3)填充输入
  • 阶段 1:2D 卷积具有 64 个形状为(7,7)的滤波器,并使用(2,2)的步长。它的名字叫“conv1”。BatchNorm 应用于输入的通道轴。最大池使用(3,3)窗口和(2,2)步距。
  • 阶段 2:卷积块使用三组大小为 64×64×256 的滤波器,f=3,s=1,块是“a”。这两个单位块使用三组大小为 64×64×256 的滤波器,f=3,块是“b”和“c”。
  • 阶段 3:卷积块使用三组大小为 128×128×512 的滤波器,f=3,s=2,块为“a”。3 个单位块使用三组大小为 128×128×512 的滤波器,f=3,块为“b”、“c”和“d”。
  • 阶段 4:卷积块使用三组大小为 256×256×1024 的滤波器,f=3,s=2,块为“a”。这 5 个单位块使用三组大小为 256×256×1024 的滤波器,f=3,块是“b”、“c”、“d”、“e”和“f”。
  • 阶段 5:卷积块使用三组大小为 512×512×2048 的滤波器,f=3,s=2,块为“a”。这两个单位块使用三组大小为 256×256×2048 的滤波器,f=3,块是“b”和“c”。
  • 2D 平均池使用形状为(2,2)的窗口,其名称为“avg_pool”。
  • 展平没有任何超参数或名称。
  • 全连接(密集)层使用 softmax 激活将其输入减少到类的数量。它的名字应该是' fc' + str(类)。
from keras import layers from keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D from keras.layers import AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D from keras.models import Modelfrom keras.initializers import glorot_uniforminput_shape = (64, 64, 3)
 classes = 6# Define the input as a tensor with shape input_shape
 X_input = Input(input_shape)# Zero-Padding
 X = ZeroPadding2D((3, 3))(X_input)# Stage 1 X = Conv2D(64, (7, 7), strides = (2, 2), name = ‘conv1’,)(X) X = BatchNormalization(axis = 3, name = ‘bn_conv1’)(X) X = Activation(‘relu’)(X)X = MaxPooling2D((3, 3), strides=(2, 2))(X)# Stage 2 X = convolutional_block(X, f = 3, filters = [64, 64, 256], stage = 2, block=’a’, s = 1) X = identity_block(X, 3, [64, 64, 256], stage=2, block=’b’)X = identity_block(X, 3, [64, 64, 256], stage=2, block=’c’)# Stage 3 X = convolutional_block(X, f = 3, filters = [128, 128, 512], stage = 3, block=’a’, s = 2) X = identity_block(X, 3, [128, 128, 512], stage=3, block=’b’) X = identity_block(X, 3, [128, 128, 512], stage=3, block=’c’)X = identity_block(X, 3, [128, 128, 512], stage=3, block=’d’)# Stage 4 X = convolutional_block(X, f = 3, filters = [256, 256, 1024], stage = 4, block=’a’, s = 2) X = identity_block(X, 3, [256, 256, 1024], stage=4, block=’b’) X = identity_block(X, 3, [256, 256, 1024], stage=4, block=’c’) X = identity_block(X, 3, [256, 256, 1024], stage=4, block=’d’) X = identity_block(X, 3, [256, 256, 1024], stage=4, block=’e’)X = identity_block(X, 3, [256, 256, 1024], stage=4, block=’f’)# Stage 5 X = convolutional_block(X, f = 3, filters = [512, 512, 2048], stage = 5, block=’a’, s = 2) X = identity_block(X, 3, [512, 512, 2048], stage=5, block=’b’)X = identity_block(X, 3, [512, 512, 2048], stage=5, block=’c’)# AVGPOOL
 X = AveragePooling2D((2,2), name=’avg_pool’)(X)# output layer X = Flatten()(X)X = Dense(classes, activation=’softmax’, name=’fc’ + str(classes))(X)# Create model
 model = Model(inputs = X_input, outputs = X, name=’ResNet50′)#Compile the model
 model.compile(optimizer=’adam’, loss=’categorical_crossentropy’, metrics=[‘accuracy’])

摘要

  • 非常深的神经网络(普通网络)实现起来不实际,因为它们由于消失梯度而难以训练。
  • 跳跃连接有助于解决消失梯度问题。它们还使得 ResNet 块很容易学习标识函数。
  • 有两种主要类型的 ResNets 块:身份块和卷积块。
  • 通过将这些块堆叠在一起,构建非常深的剩余网络。

参考

PyTorch 在交通标志分类中的应用

原文:https://towardsdatascience.com/resnet-for-traffic-sign-classification-with-pytorch-5883a97bbaa3?source=collection_archive---------6-----------------------

德国交通标志识别基准数据集可能是与自动驾驶汽车相关的最流行的图像分类。自动驾驶汽车需要检测和分类交通标志,以理解应用于一段道路的交通规则。也许,这个数据集太小,不够完整,不能用于实际应用。然而,它是计算机视觉算法的一个很好的基准。

资料组

数据集由两部分组成:训练集和测试集。训练集包含 39209 幅交通标志图像,分为 43 类,如停车标志、自行车穿越和限速 30 公里/小时

Examples of German Traffic Sign Recognition Dataset images

数据集非常不平衡。例如,有 1800 个“速度限制(50 公里/小时)”标志的实例,但只有 168 个“向左转弯危险”标志的实例。

测试集有 12630 个标记图像。这些图像被用于 2011 年 IJCNN 竞赛的评估。

你可以从官网下载数据集。

方法

我尝试使用在 ImageNet 数据集上预先训练的 ResNet34 卷积神经网络进行迁移学习。

我在 fast.ai 最新版《程序员深度学习》课程中学到的解决计算机视觉问题的通用方法。我去年在旧金山大学参加了那个课程的离线版本。课程使用了 fastai ,一个基于 PyTorch 构建的深度学习库。它为训练深度学习模型提供了易于使用的构建模块。

我花了大部分时间优化超参数和调整图像增强。

密码

在 GitHub 上发布了我的代码。您可以下载一个 Jupyter 笔记本,它包含了从下载数据集到基于未标记的测试集创建提交文件的所有步骤。训练 CNN 模型的代码大多基于 fast.ai 课程的 CNN 课程。

让我们来看看训练和评估模型的步骤。

准备

准备环境。我必须安装 fastai 库及其所有依赖项。

下载数据集,解包。将训练集(39209 个图像)拆分为训练集和验证集,并将文件移动到正确的文件夹中。我用 80%的样本进行训练,20%的样本进行验证。

小心分裂。该数据集包含每个物理交通标志的 30 张照片。根据文件名区分不同的系列是很容易的。如果您只是随机拆分数据集,那么将会有信息从验证集泄漏到训练集。

我一开始就犯了这个错误。我随机分割数据集,得到了超过 99.6%的惊人的验证准确率。当测试准确率只有 87%时,我很惊讶:测试准确率和验证准确率之间的巨大差异是验证集设计不良或过度适应验证集的标志。

正确的方法是找到图像系列,并将每个系列完全放入训练集或验证集中,确保它不会分成两部分。要了解更多关于创建好的验证集的信息,请阅读的这篇文章,作者雷切尔·托马斯

探索性分析

浏览数据集。检查班级的分布,看看每个班级的一些图片示例。

图像有不同的大小。看看尺寸的直方图。它将让您了解 CNN 的输入维度应该是多少。

培养

加载在 ImageNet 数据集上预先训练的 ResNet34 模型。删除最后一层,并在顶部添加一个新的 softmax 层。

我的一般训练方法是:从一个小的模型输入(我从 32x32 的图像尺寸开始)和一个短的训练程序(总共 7 个时期)开始,以优化训练速度。你需要快速迭代。理想情况下,实验不应该超过几分钟。

此外,优化批量大小。在 GPU 内存允许的情况下,尽量增大批量大小。较大的批量有助于减少培训时间。但是,通过实验,我发现太大的批量(例如,1024 个样本或更多)会导致较低的验证准确性。我猜模型很早就开始过度拟合了。我最后得到了一个批量 256。

只有在你找到一组像样的超参数后,才切换到更大的图像和更长的细粒度训练。最后我用了 96x96 的图像,训练了 19 个纪元。

图像增强

设置图像增强。这是一种帮助模型更好地概括的技术。你在训练集中添加了很多人为的例子。这些例子是基于已经存在的例子,但是你稍微改变了它们:旋转几度,改变照明,放大,等等。

Examples of augmented images

我使用了以下变换的组合:旋转最大 20 度,光照变化最大 80%,缩放最大 20%。

灯光增强非常重要。在项目的早期阶段,我看到非常暗的图像有最不正确的预测。在照明增强方面的进取性将验证准确性提高了 3%以上。通过直接改变 R、G 和 B 通道的值来改变照明。详见 RandomLighting 类。

我尝试过并拒绝的其他东西:直方图均衡化以提高对比度,随机模糊,填充。

学习率

使用这里描述的简单算法为训练搜索一个好的开始学习率。

微调最后一层

冻结除最后一层以外的所有层。以该学习速率训练一个时期的模型。以我为例,学习率是 0.01。这里的目标是为最后一层获得合理的权重。如果我们不这样做,稍后训练一个未冻结的模型会导致更低的层混乱,因为梯度会更大。我尝试了这两个选项,训练一个时期的最后一层在验证准确性方面有大约 1%的提高。我还使用了重量衰减来做一个小小的改进。

微调整个模型

解冻所有层。训练三个时代。

然后使用带热重启的随机梯度下降(SGDR) 训练几个时期。

我尝试使用区别性微调,为模型的不同部分设置不同的学习率。在这种情况下,我们希望模型的第一层比最后一层训练得少。第一层比其他层更通用。当在 ImageNet 数据集上训练时,这些层学到了对我们的任务非常有用的模式,我们不想失去这些知识。另一方面,最后一层是非常特定于任务的,我们希望在我们的任务中重新训练它们。不幸的是,它对改进度量没有帮助。如果对所有层应用较大的学习率,模型的训练效果会更好。我猜这是因为交通标志与狗、猫和飞机非常不同,因此较低层的信息不像在其他计算机视觉应用中那样有用。

验证集上最佳模型的准确率为 99.0302%。

误差分析

除了像混淆矩阵这样的常用工具,您还可以通过检查一些极端情况来分析错误:最不正确的预测、最正确的预测、最不确定的预测。

要查找每个类最不正确的预测,必须对验证集进行推理,并选择正确类的预测概率最小的示例。

Most incorrect images

这些图像看起来太模糊太亮。

类似地,您可以找到将最高概率分配给正确类(“最正确”)的示例,以及正确类的概率接近 1/num_classes(“最不确定”)的示例。

此分析的结果有助于您调整图像增强参数,可能还有模型的一些超参数。

在完整训练集上重新运行训练

在之前的所有步骤中,我们将 80%的训练集用于训练,20%用于验证。现在,由于我们发现了好的超参数,我们不再需要验证集,可以将这 20%的图像添加到训练集中,以进一步改进模型。

在这里,我只是使用相同的参数重新运行所有的训练步骤,但是使用所有 32909 个训练图像进行训练。

在测试集上测试

测试集(12630 幅图像)旨在测试最终模型的性能。我们没有在前面的步骤中查看测试集,以避免过度适应测试集。现在,我们可以在测试集上评估模型。我在测试集上获得了 99.2953%的准确率。相当不错!我们能进一步改进它吗?

测试时间增加

测试时间增强(TTA)通常有助于进一步提高精确度。诀窍是创建输入图像的几个增强版本,对每个版本进行预测,然后平均结果。这背后的直觉是,模型在分类一些图像时可能是错误的,但是稍微改变图像可以帮助模型更好地分类它。这就像如果一个人想对一个物体进行分类,他们从不同的角度看它,稍微改变一下照明,把它移到离眼睛更近的地方,直到他们能找到最有信心识别这个物体的最佳视角。

的确,TTA 帮我把准确率从 99.2953%提高到了 99.6120%。它将误差减少了 45%(从 0.7047%减少到 0.388%)。

有多好?

测试集上的准确率为 99.6120% 。我们来对比几个基准。

最先进的是由 Mrinal Haloi 基于《T2》的 CNN。99.81%.错误率比我好两倍。

2011 年 IJCNN 竞赛排行榜上的前几名:

如果我的模特参加比赛,她会获得第二名。总的来说,几天的工作还不错。

接下来阅读:

[## 估计深度神经网络的最佳学习速率

学习率是用于训练深度神经网络的最重要的超参数之一。

towardsdatascience.com](/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0) [## NVIDIA Jetson TX2 入门

Jetson TX2 是 NVIDIA 的一款高能效嵌入式人工智能计算设备。这是一台小型计算机,有一个信用卡那么大…

medium.com](https://medium.com/@surmenok/getting-started-with-nvidia-jetson-tx2-5952a2d8d7ae) [## Fast.ai:我从第 1-3 课中学到了什么

Fast.ai 是一个非常棒的深度学习课程,适合那些喜欢通过做来学习的人。与其他课程不同,在这里您将…

hackernoon.com](https://hackernoon.com/fast-ai-what-i-learned-from-lessons-1-3-b10f9958e3ff)

回顾:带有身份映射的预激活 ResNet 已达到 1000 多个图层(图像分类)

原文:https://towardsdatascience.com/resnet-with-identity-mapping-over-1000-layers-reached-image-classification-bb50a42af03e?source=collection_archive---------5-----------------------

预激活 ResNet:卷积前的批量 Norm 和 ReLU

在这个故事中,我们回顾了微软改进的 ResNet [1]。通过身份映射,深度学习架构可以达到 1000 层以上,不会增加错误。

在 ResNet [2]的上一版本中,当 ResNet 从 101 层到 1202 层时,虽然 ResNet-1202 仍然可以收敛,但是错误率从 6.43%下降到 7.93%(这个结果可以在[2]中看到)。并且在[2]中被陈述为开放问题而没有任何解释。

下图显示了使用标识映射的 ResNet 的结果。在层数达到 1001 的情况下,先前的 ResNet [2]仅获得 7.61%的误差,而对于 CIFAR-10 数据集,具有身份映射[1]的新 ResNet 可以获得 4.92%的误差。

(a) Previous ResNet [2] (7.61%) (b) New ResNet with Identity Mapping [1] (4.92%) for CIFAR-10 Dataset

但是为什么保持快捷连接路径干净(如图将 ReLU 层从快捷连接路径移动到 conv 层路径)会更好?本文对此进行了很好的解释。一系列的消融研究证实了这种身份映射的重要性。

结果是比 Inception-v3【3】还要好。(如果有兴趣,也请阅读我的 Inception-v3 评测。)这么好的成绩,发表在我写这个故事的时候 2016 ECCV 论文上1000 多篇引用。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 身份映射重要性的解释
  2. 消融研究
  3. 与最先进方法的比较

1。身份映射重要性的解释

前馈、反向传播和梯度更新似乎使深度学习成为一个秘密。我觉得这里的解释非常好。

1.1 前馈

在具有身份映射的 ResNet 中,在没有任何 conv 层 BN 和 ReLU 的情况下,保持从输入到输出的快捷连接路径的干净是至关重要的。

xl 是 l 层的输入,F(。)是代表 conv 层 BN 和 ReLU 的函数。那么我们可以这样表述:

One Particular Layer

L layers from l-th layer

我们可以看到输入信号 xl 仍然保持在这里!

1.2 反向传播

在反向传播过程中,我们可以得到分解成两个附加项的梯度:

Gradient which decomposed into two additive terms

在毯子里面,无论网络有多深,我们总能在左边的项得到“1”。右项不能总是-1,这使得梯度为零。因此,这个渐变并没有消失!!

1.2 违反身份映射时的反向传播

另一方面,如果左边的项不等于 1 呢:

One Particular Layer

L layers from l-th layer

Gradient which decomposed into two additive terms

同样,梯度的左项是λ的乘积。

如果 λ > 1 ,左项将呈指数大,出现梯度爆炸问题。我们应该记得,当梯度爆炸时,损失无法收敛

如果 λ < 1 ,左项将呈指数小,出现梯度消失问题。我们不能用大值更新梯度,损耗停留在平稳状态,最终以大损耗收敛

因此,这就是为什么我们需要保持从输入到输出的捷径连接路径没有任何 conv 层,BN 和 ReLU。

2。消融研究

2.1 各种快捷连接方式

110 层 ResNet (54 个两层剩余单元)与各种类型的快捷连接在 CIFAR-10 数据集上测试如下:

Performance of Various Types of Shortcut Connections

原文:即[2]中 ResNet 的上一版本,误差 6.61%。

常数缩放 : λ=0.5,存在上述梯度消失问题,仔细选择偏置 bg 后,误差为 12.35%。

排他门控&仅快捷门控:两者都试图增加快捷路径的复杂性,同时仍然保持路径等于“1”。但是两者都不能得到更好的结果。

1×1 Conv 快捷方式:类似于之前 ResNet [2]中的选项 C。在以前的 ResNet 中,发现使用选项 c 更好。但现在发现,当有许多剩余单元(太深)时,情况并非如此。

辍学捷径:实际上是统计执行λ=0.5。

2.2 激活的各种用法

通过在 BN 和 ReLU 的位置附近玩耍,获得以下结果:

Performance of Various Usages of Activation

添加后之前的 ResNet & BN:两者都不能在违反身份映射的快捷连接上保持干净。

加法前的 ReLU:ReLU 后的残差函数必须是非负的,使得正向传播的信号是单调递增的,而残差函数最好也是负值。

ReLU-only 预激活 : ReLU 不配合 BN 使用,不能很好的享受 BN 的好处。

全预激活:快捷路径干净,ReLU 配合 BN 使用,成为最佳设置。

2.3 预激活的双重优势

2.3.1 优化的简易性

Previous ResNet structure (Baseline) vs Pre-activation Unit

由于 ReLU 层的错误位置,使用先前的 ResNet 结构(基线)在太深(1001)时具有更差的结果。当网络从 110 到 1001 越来越深的时候,使用预激活单元总能得到一个比较好的结果。

2.3.2 减少过拟合

Training Error vs Iterations

预激活单元处于正则化状态,即收敛时的训练损失略高,但测试误差较低。

3.与最先进方法的比较

3.1 西法尔-10 和西法尔-100

CIFAR-10 & CIFAR-100 Results

对于 CIFAR-10,使用具有建议预激活单元的ResNet-1001(4.62%),甚至优于使用以前版本 ResNet 的 ResNet-1202 (7.93%)少 200 层

对于 CIFAR-100,使用 ResNet-1001 和建议的预激活单元(22.71%),甚至优于使用 ResNet 早期版本的 ResNet-1001 (27.82%)

对于 CIFAR-10 和 CIFAR-100 来说,带有建议预激活单元的 ResNet-1001 并不比 ResNet-164 有更大的误差,但是以前的 ResNet [2]有

在 CIFAR-10 上,ResNet-1001 用 2 个 GPU 训练大约需要 27 个小时。

3.2 ILSVRC

ILSVRC Image Classification Results

仅在规模上有所增强,ILSVRC 2015 的获胜者 ResNet-152 (5.5%)上一版本由于 ReLU 位置错误,在往更深处走时,比 ResNet-200 (6.0%) 上一版本性能差

并且所提出的具有预激活的 ResNet-200(5.3%)具有比先前的 ResNet-200 (6.0%)更好的结果。

随着规模和纵横比的增加,提议的预激活 ResNet-200(4.8%)优于谷歌的 Inception-v33

同时,谷歌也有一个 Inception-ResNet-v2,它有 4.9%的误差,有了预激活单元,误差有望进一步降低。

在 ILSVRC 上,ResNet-200 在 8 个 GPU 上训练大约需要 3 周时间。

在回顾了 ResNet 和带有身份映射的 ResNet,以及 Inception-v1、Inception-v2 和 Inception-v3 之后,我还将回顾 Inception-v4。敬请关注!

参考

  1. 【2016 ECCV】【带有身份映射的 ResNet】
    深度剩余网络中的身份映射
  2. 【2016 CVPR】【ResNet】
    用于图像识别的深度残差学习
  3. 【2016 CVPR】【盗梦空间-v3】
    重新思考计算机视觉的盗梦空间架构

我的评论

  1. 回顾:ResNet——2015 年国际影像分类、定位、检测奖得主
  2. 回顾:Inception-v3–ils vrc 2015 亚军(图像分类)
  3. 回顾:批量归一化(Inception-v2/BN-Inception)——ILSVRC 2015 中第二个超越人类水平的性能(图像分类)
  4. 回顾:谷歌网(Inception v1)——ILSVRC 2014(图像分类)获奖者

CIFAR-10 的结果

原文:https://towardsdatascience.com/resnets-for-cifar-10-e63e900524e0?source=collection_archive---------6-----------------------

这篇文章可以在 PDF 这里下载。

这是关于 CNN 架构的系列教程的一部分

主要目的是当应用于 CIFAR-10 数据集时,深入了解 ResNets。

  • 对于 ResNets 应用于 ImageNet,这是一个更深入的教程,这里还有另一个教程。
  • 还有 PyTorch 实现详细教程这里
  • 在这里还可以找到构建这些架构的代码。

索引

  • 介绍
  • 结构
  • 卷积 1
  • 第一层
  • 第二层
  • 第三层
  • 摘要

介绍

这项工作是之前教程的延续,在之前的教程中,我们对原论文[1]之后的 ResNet 进行了去神秘化。但是,这种结构是为了在 ImageNet 数据集上运行良好而构建的。

ImageNet 数据集由属于 1000 个不同类别的一组大小(224x224)的图像(作者使用了 128 万幅训练图像、5 万幅验证图像和 10 万幅测试图像)组成。但是,CIFAR10 由一组不同的映像(45k 训练映像、5k 验证映像和 10k 测试映像)组成,这些映像分布在 10 个不同的类别中。

因为输入体积(图像)的大小完全不同,所以很容易认为相同的结构不适合在该数据集上训练。我们无法在没有维度不匹配的情况下对数据集执行相同的缩减。

我们将遵循作者提供给 ResNets 的解决方案,在 CIFAR10 上进行训练,这也像 ImageNet 数据集一样很难遵循。在论文[1]的第 节 4.2 CIFAR-10 和分析 中,我们找到了下表:

Figure 1. Schema for ResNet from the paper

让我们按照他们给出的字面解释来构造 ResNet。为简化起见,我们将使用 n=1,结果为 20。

结构

按照之前关于 ResNets 工作的相同方法,让我们先看看整体情况,稍后再一层一层地深入细节。

Figure 2. Scheme for ResNet Structure on CIFAR10

卷积 1

在进入公共层行为之前,ResNet 的第一步是一个带有批处理规范化操作的 3x3 卷积。步幅为 1,填充为 1,以使输出大小与输入大小相匹配。请注意,我们与 ResNet for ImageNet 的第一个重大区别是,我们在第一个块中没有包括最大池操作。

Figure 3. Conv1

我们可以通过图 2 来验证 Conv1 的输出音量确实是 32x32x16。

第一层

作者用来构建 ResNet 的其余注释是:

——用 一叠 6 层 3x3 卷积 。的选择将决定我们的网的大小。

特征图大小分别为{32,16,8},每个特征图大小有 2 个卷积。此外,过滤器的数量分别为{16,32,64}。

--通过 ResNet 的 下采样 的卷是将 的步距增加到 2 ,进行每层的第一次卷积。因此,在密集层之前不会使用池化操作。

-对于 旁路连接 ,不使用投影。在卷的形状有所不同的情况下,输入的 会简单地用零 填充,所以 输出的大小与添加 之前的卷的大小相匹配。

这将留下图 4 作为我们第一层的表示。在这种情况下,我们的旁路连接是一个常规的 恒等短连接,因为体的维数在整个层操作中是恒定的。因为我们选择 n=1,所以在层 1 中应用了 2 个卷积。

Figure 4. Layer 1

我们仍然可以从图 2 中看出,第 1 层的输出体积确实是 32x32x16。我们再深入一点!

第二层

我们现在来看看如何处理输入音量的下采样。请记住,我们遵循与 ImageNet 数据集相同的结构和符号。如果没有遵循任何步骤,请务必看一看,因为有更详细的解释。

对于第 2 层和下一个第 3 层,其行为与第 1 层相同,只是第一个卷积使用的步幅为 2,因此输出音量的大小是输入音量的一半(填充为 1)。这意味着快捷连接也需要额外的步骤,以在求和之前调整体积的大小。

Figure 5.Layer 2, Block 1, Convolution

整个层 2 的最终外观如图 6 所示。我们可以看到步长为 2 的卷积是如何用于向下采样的跳过连接以及层的第一个卷积的。此外,我们可以根据文件中的表格检查,我们确实有一个 16x16x32 的体积。

Figure 6. Layer 2

第三层

第 3 层将应用与第 2 层完全相同的原理,导致图 7。

Figure 7. Layer 3

我们可以根据文章中的表格来检查,我们确实有一个 8x8x64 的卷。

摘要

遵循作者建立的解释规则的结果产生以下结构,改变图 1 中的 n 的值:

Table 1. ResNets architectures for CIFAR-10

请注意,直观地说,这些架构与在 ImageNet 的工作结束时展示的 ImageNet 架构并不匹配。

文献学

[1]何国光,张,任,孙军,“深度残差学习在图像识别中的应用”,,2016。

受限玻尔兹曼机器—简化

原文:https://towardsdatascience.com/restricted-boltzmann-machines-simplified-eab1e5878976?source=collection_archive---------1-----------------------

Photo by israel palacio on Unsplash

编辑:这几天我在 substack 上写博客,如果你喜欢这篇文章,想了解更多关于科技、生活和生产力的内容,请在这里订阅:tinyurl.com/substackblog

在这篇文章中,我将尝试阐明关于受限玻尔兹曼机器及其工作方式的直觉。这应该是一个简单的解释,用一点数学知识,不要太深入每个概念或方程式。因此,让我们从 RBM 的起源开始,并随着我们的前进而深入研究。

什么是玻尔兹曼机器?

玻尔兹曼机器是能够学习内部表示的随机生成神经网络,并且能够表示和(给定足够的时间)解决困难的组合问题。

它们以玻尔兹曼分布(也称为吉布斯分布)命名,这是统计力学的一个组成部分,有助于我们理解熵和温度等参数对热力学中量子态的影响。这就是为什么它们被称为基于能量的模型(EBM)。它们是 1985 年由卡内基梅隆大学的杰弗里·辛顿和约翰·霍普金斯大学的特里·塞伊诺夫斯基发明的

玻尔兹曼机器是如何工作的?

玻尔兹曼机器看起来像这样:

Author: Sunny vd on Wikimedia

玻尔兹曼机器是非确定性(或随机)生成深度学习模型,只有两种类型的节点— hiddenvisible节点。没有输出节点!这可能看起来很奇怪,但这就是给他们这种不确定性的特征。它们没有典型的 1 或 0 型输出,通过这种输出,可以使用随机梯度下降来学习和优化模式。他们学习模式却没有这种能力,这就是他们如此特别的原因!

这里要注意的一个区别是,与输入节点之间没有任何连接的其他传统网络(A/C/R)不同,玻尔兹曼机器在输入节点之间有连接。从图中我们可以看到,所有节点都与所有其他节点相连,不管它们是输入节点还是隐藏节点。这使他们能够在自己之间共享信息,并自行生成后续数据。我们只测量可见节点上的内容,而不测量隐藏节点上的内容。当输入被提供时,他们能够捕获所有的参数、模式和数据之间的相关性。这就是为什么它们被称为Deep Generative Models并被归入Unsupervised Deep Learning一类的原因。

什么是受限玻尔兹曼机?

RBMs 是一个具有生成能力的两层人工神经网络。他们有能力学习一组输入的概率分布。RBM 是 Geoffrey Hinton 发明的,可用于降维、分类、回归、协同过滤、特征学习和主题建模。

RBM 是一类特殊的波尔兹曼机器,它们受限于可见单元和隐藏单元之间的连接。与玻尔兹曼机器相比,这使得实现它们更容易。如前所述,它们是一个两层的神经网络(一层是可见层,另一层是隐藏层),这两层由完全二分图连接。这意味着可见层中的每个节点都连接到隐藏层中的每个节点,但同一组中没有两个节点相互连接。这种限制允许比一般玻尔兹曼机器更有效的训练算法,特别是基于梯度的对比发散算法。

受限玻尔兹曼机器看起来像这样:

受限玻尔兹曼机器是如何工作的?

在 RBM 中,我们有一个对称二部图,其中同一组中没有两个单元是相连的。多个 RBM 也可以stacked并可以通过梯度下降和反向传播的过程进行微调。这样的网络被称为深度信念网络。虽然 RBM 偶尔会被使用,但深度学习社区中的大多数人已经开始用一般的敌对网络或变型自动编码器来取代它们的使用。

RBM 是一个随机神经网络,这意味着每个神经元在激活时都会有一些随机行为。RBM 中还有另外两层偏差单位(隐藏偏差和可见偏差)。这就是 RBMs 不同于自动编码器的地方。隐藏的偏置 RBM 在前向传递中产生激活,而可见的偏置帮助 RBM 在后向传递中重建输入。重建的输入总是不同于实际的输入,因为在可视单元之间没有连接,因此,没有办法在它们之间传递信息。

Image Source

上图显示了使用多个输入训练 RBM 的第一步。输入乘以权重,然后添加到偏差中。然后,结果通过 sigmoid 激活函数传递,输出确定隐藏状态是否被激活。权重将是一个矩阵,输入节点的数量作为行数,隐藏节点的数量作为列数。在相应的偏置项被添加到第一隐藏节点之前,第一隐藏节点将接收乘以第一列权重的输入的向量乘法。

如果你想知道什么是 sigmoid 函数,这里有一个公式:

Image Source: My Blog

所以我们在这一步得到的等式是,

其中 h(1)v(0) 是隐藏层和可见层的对应向量(列矩阵),上标为迭代(v(0)表示我们提供给网络的输入),而 a 是隐藏层偏置向量。

(注意,我们在这里处理的是向量和矩阵,而不是一维值。)

Image Source

现在这个图像显示了相反的阶段或者说是重建阶段。它与第一遍相似,但方向相反。等式结果是:

其中 v(1)h(1) 是可见层和隐藏层的对应向量(列矩阵),以上标为迭代, b 是可见层偏移向量。

学习过程

现在,差异 v(0)-v(1) 可以被认为是我们需要在训练过程的后续步骤中减少的重建误差。因此,在每次迭代中调整权重,以最小化该误差,这就是学习过程的本质。现在,让我们试着用数学术语来理解这个过程,不要太深入数学。在前向传递中,给定输入 v(0) 和权重 W ,我们正在计算输出 h(1) 的概率,表示为:

在后向传递中,在重构输入的同时,我们在给定输入 h(1) 和权重 W 的情况下计算输出 v(1) 的概率,表示为:

向前和向后传递中使用的权重是相同的。这两个条件概率一起将我们引向输入和激活的联合分布:

重构不同于回归或分类,因为它估计原始输入的概率分布,而不是将连续/离散值与输入示例相关联。这意味着它试图同时猜测多个值。这被称为生成学习,与分类问题中发生的判别学习(将输入映射到标签)相反。

让我们尝试看看算法如何减少损失,或者简单地说,它如何减少每一步的误差。假设我们有两个正态分布,一个来自输入数据(用 p(x)表示),另一个来自重构的输入近似值(用 q(x)表示)。这两种分布之间的差异是我们在图形意义上的误差,我们的目标是将其最小化,即,使图形尽可能接近。这个想法用一个叫做库尔贝克-莱布勒分歧的术语来表示。KL-divergence 测量两个图形下的非重叠区域,并且 RBM 优化算法试图通过改变权重来最小化该差异,使得重建非常类似于输入。右侧的图表显示了左侧曲线面积差异的积分。

Image by Mundhenk on Wikimedia

这给了我们一个关于误差项的直觉。现在,为了了解 RBM 实际上是如何做到这一点的,我们必须深入了解损失是如何计算的。给定一些数据,RBM 的所有常见训练算法近似对数似然梯度,并在这些近似上执行梯度上升。

对比分歧

玻尔兹曼机器(和 RBM)是基于能量的模型,可见和隐藏单元的联合配置( v,h )具有由下式给出的能量:

其中 vi,hj ,是可见单元 i 和隐藏单元 j 的二元状态,ai,bj 是它们的偏差, wij 是它们之间的权重。

网络分配给可见向量 v 的概率通过对所有可能的隐藏向量求和给出:

Z 这是配分函数,通过对所有可能的可见和隐藏向量对求和得出:

这给了我们:

训练向量相对于权重的对数似然梯度或对数概率的导数非常简单:

其中尖括号用于表示由下面的下标指定的分布下的期望。这导致了用于在训练数据的对数概率中执行随机最速上升的非常简单的学习规则:

其中α是学习率。有关上述等式的含义或推导方法的更多信息,请参考 Geoffrey Hinton 撰写的RBM 训练指南。这里需要注意的重要一点是,因为 RBM 中的隐藏单元之间没有直接的联系,所以很容易得到 ⟨vi hj⟩data 的无偏样本。然而,获得一个⟨vi hj⟩model 的无偏样本要困难得多。这是因为它需要我们运行马尔可夫链,直到达到稳定分布(这意味着分布的能量最小化——平衡!)来近似第二项。因此,我们没有这样做,而是从分布中执行吉布斯采样。这是一种马尔可夫链蒙特卡罗(MCMC)算法,用于在直接采样困难时(如我们的情况),获得从指定的多元概率分布近似得到的一系列观察值。吉布斯链用训练集的训练样本 v(0) 初始化,并在 k 步后产生样本 v(k) 。每个步骤 t 都包括从 p( h | v(t) )中采样 h(t) 以及随后从 p( v | h(t) )中采样 v(t+1) (值 k = 1 令人惊讶地工作得相当好)。学习规则现在变成了:

即使只是粗略地近似训练数据的对数概率的梯度,该学习也工作得很好。学习规则更加接近另一个目标函数的梯度,该目标函数称为对比散度,它是两个 Kullback-Liebler 散度之间的差。

当我们应用这个时,我们得到:

其中第二项是在吉布斯采样的每个 k 步之后获得的。以下是 CD 算法的伪代码:

Image Source

结论

我们在这篇文章中讨论的是一个简单的受限玻尔兹曼机器架构。RBM 和用于训练和优化的算法有许多变化和改进(我希望在以后的文章中涉及)。我希望这有助于你理解和了解这个令人敬畏的生成算法。在下一篇文章中,我们将应用 RBMs 来构建图书推荐系统!

不要犹豫,纠正评论中的任何错误或为未来的帖子提供建议!我喜欢写与人工智能、深度学习、数据科学和机器学习相关的主题(无论是数学、应用还是简化)。

如果你觉得这篇文章有帮助,请随意点击👏s!如果你想看用 Python 实现一个 RBM 的代码,在这里看我的资源库

了解成果管理制的参考资料和一些极好的资源:

零售分析趋势— 2017 年及以后

原文:https://towardsdatascience.com/retail-analytics-trends-2017-and-beyond-374bc6627cb0?source=collection_archive---------1-----------------------

A 根据 Markets 和 markets 的数据,2015 年至 2020 年期间,全球零售分析市场的规模可能会翻一番以上,在预测期结束时总额约为 51 亿美元。随着全球越来越多的企业从使用商业智能和分析平台及服务中获得巨大回报,对分析解决方案的采用正在增加。

最近,许多零售商似乎都在追赶人工智能的潮流,以改善他们的营销工作。营销技术公司 Sailthru 公布了一项研究,其中包括一项对 200 多名零售营销人员的调查。在 2017 年期间,这些零售商计划利用人工智能来扩展他们的移动和社交媒体营销策略,除了改善客户旅程。

根据 Gartner 的一项研究,零售公司采用的人工智能解决方案可能会自动管理高达 85%的所有客户交互。尽管这个数字可能应该有所保留,但没有人能真正否认人工智能和机器学习在零售领域的应用日益增长。尽管如此,让我们来讨论一下影响行业并将在未来几年继续占据显著地位的六大零售分析趋势。

采用机器视觉和深度学习算法

这些年来,人工智能在深度学习方面取得了相当大的进展。深度学习算法将使人工智能的好处在 2017 年和未来几年变得更加明显和有形。

例如,零售巨头亚马逊去年年底在西雅图开设了第一家亚马逊 Go 商店。Amazon Go 的计划显然已经酝酿了好几年了。目标是利用计算机视觉、深度学习算法和传感器融合等技术来改善购物体验。人们可以从 Amazon Go 商店购买杂货,而不必排队或通过结账流程。该公司将这种创新称为“走出去”技术,这基本上是其关键卖点。

然而,根据摩根士丹利的一份包括消费者调查的报告,只有 30%的人认为快速结账很重要;50%的人说他们更关心价格,70%的人更喜欢便利的商店位置。尽管如此,美国的杂货市场价值 7700 亿美元,Amazon Go 在未来有巨大的增长潜力。我们可以期待在不久的将来,机器视觉和深度学习也会有类似的应用。

使用微细分进行更好的决策

虽然长期以来,细分一直是零售商利用的核心机制之一,但他们可能会利用更先进的方法来促进业务战略和提高客户满意度。细分有助于定价、促销、库存管理和产品分类等功能。它使用数据挖掘和工程技术在产品和商店层面创建有意义的群体。该技术可以考虑几个参数,例如:

  • 商店绩效
  • 产品性能
  • 产品属性
  • 存储属性
  • 客户细分或人口统计数据

零售商可以为不同的集群开发和测量多个假设场景。这一过程有助于确定最有可能改进规划、决策和执行的最佳集群。

具有高级集群和其他功能的分析平台变得更加产品化。这意味着零售商不一定需要各自的托管分析提供商来满足各种平台需求。这些平台在可用性方面是可伸缩的、灵活的和简单明了的。

全渠道数据集成和支出优化

全球越来越多的零售商意识到全渠道数据集成解决方案的重要性,因为它们具有高度的可扩展性和健壮性。这些解决方案对于希望在更多地理位置扩大品牌知名度和销售额的零售商来说非常重要。

根据埃森哲和阿里巴巴集团的研究,到 2020 年,全球跨境电子商务销售额可能会达到1 万亿美元。这一数字表明,与 2014 年相比,增长率高达 335%。国际邮政公司的另一份报告显示,63%的跨境购物者每月至少进行一次国际购物。鉴于跨境购物和整体电子商务销售的增长趋势,零售商无论规模大小,都必须专注于全球扩张,才能在竞争激烈的市场中站稳脚跟。

在这种情况下,全渠道数据集成解决方案为零售商提供了竞争优势,因为它们与在线市场无缝集成。零售商可能会同时优化跨渠道和媒体的投资,并在线下和线上渠道提供一致的客户体验。

至于全渠道支出管理,归因建模是关键解决方案之一。零售商倾向于在营销策略上花很多钱。但总的来说,对于哪些策略有效以及有效到什么程度,似乎还不太清楚。在这种情况下,归因建模有助于零售商了解如何根据客户如何访问和浏览他们的网站来优化他们的营销支出。

具体来说,客户可以通过多种方式访问零售网站:

  • 直接网址:客户输入网站网址进行访问。这可能会受到各种线下项目的影响,如电视广告、印刷品等。
  • 有机搜索:客户搜索一个关键词,点击一个结果就可以到达网站。
  • 付费广告:客户点击点击付费链接。
  • 转介:客户点击另一个网站上的链接到达零售网站。
  • 社交媒体:客户点击脸书和推特等各种社交媒体平台上发布的网站链接。

现在,归因模型通过转化过程确定每个渠道和每个客户接触点的有效性。这些分析见解有助于零售商更有效地锁定客户,从而提高销售额。

当我们考虑建立一个全渠道时,做出营销决策会变得更加复杂,因为线下支出也同样需要考虑。尽管如此,分析确实有助于整个决策过程。

通过物联网增强数据和高级分析

使用来自 Wi-Fi、信标和 RFID 标签的强大数据正在帮助零售商改善各种各样的运营,无论是在整个供应链周期中跟踪商品还是管理库存。从这些技术中生成的物联网数据有助于确定客户行为,创建有效的店内营销策略,并改进货架图。

例如,RFID 数据流可以帮助零售商根据产品在商店中的移动情况来确定产品的销售业绩和受欢迎程度。它们有助于识别销售一空的产品,剔除滞销商品。因此,这些数据流揭示了客户偏好和库存需求。

零售店中的 Wi-Fi 传感器可以与客户支持 Wi-Fi 的移动设备进行交互,并生成与以下各项相关的数据:

  • 商场内的热门区域
  • 商店里顾客流动的顺序
  • 顾客在特定商店花费的时间
  • 客户的重复访问

因此,零售商可以优化商店布局,增强商品销售,评估产品性能,并改善客户体验。

信标是利用蓝牙低能量工作的传感器,有助于近距离营销策略。它们能够连接客户的蓝牙设备。信标根据顾客在商店中的确切位置向顾客发送有针对性的信息,包括促销、折扣、优惠券。与 Wi-Fi 传感器类似,信标可以显示顾客的活动和停留时间。此外,分析来自 beacons 的数据有助于零售商衡量广告的成功率,并相应地优化营销策略。另一个好处当然是改善客户体验和忠诚度。

物联网传感器还可以帮助零售商管理和优化基于温度控制、照明管理等的电力和公用事业消耗。

提高销售额的动态定价

如今,大多数人都倾向于进行大量的网上购物。毕竟简单、快捷、方便。然而,对于在线零售商来说,事情并不那么乐观。他们面临着激烈的竞争,还要迎合善变的顾客。网上购物者有很多零售商可供选择。当然,他们在做出购买决定时首先考虑的是价格。这就是动态定价——零售商重要的零售分析解决方案之一——的用武之地。

动态定价一直是推动零售销售的常用方法,尤其是在竞争激烈的电子产品领域。零售商在设计动态定价模型时考虑了许多内部和外部因素。内部因素包括供应、销售目标、利润等。外在因素有流量、转化率、产品受欢迎程度等。零售商通常使用这些因素的组合来优化他们的定价模型。

零售商使用来自价格弹性和集合模型等分析模型的数据,根据市场情况提高或降低产品价格。像亚马逊这样的公司通常会选择降价模式,以较低的价格出售主要产品,并以一定的利润提供相关产品。这个想法是在利润而不是市场份额上稍作妥协。其他公司倾向于利润驱动的价格上涨策略。

只需点击几下,客户就可以轻松地比较不同网站上的产品价格,找到最划算的交易。零售商需要实时了解竞争对手的价格变化,以提供最佳价格。这就是动态定价的症结所在。公司使用动态定价策略的其他垂直行业包括出租车服务,如优步和航空公司。

改善产品组合管理,提升客户体验

许多大型零售商已经开始通过利用分析见解来改善产品组合规划。零售商正在使用预测和说明性分析来改善商品销售——在商店内的何时何地对哪种产品进行分类。这种做法极大地改善了客户体验并留住了客户。

例如,沃尔玛根据当地社区的需求模式对其产品进行分类。这意味着,根据不同地区顾客的需求,不同商店的产品组合会有所不同。沃尔玛还利用店内和在线交易数据为顾客提供便捷的支付和送货选择。顾客甚至可以“扫描即走”,通过电子邮件接收发票或使用沃尔玛支付。

除了历史交易,零售商在获取数据进行分析时还会考虑更多因素,如天气、当地事件数据和人口统计数据。使用内部和外部数据的组合已经变得势在必行,因为它有助于企业预测客户对特定产品类别的需求。这种分析使零售商能够更好地管理他们的库存,使他们永远不会缺货。

这些可能只是几个主要趋势。随着零售行业继续努力提高竞争力,并面临无数的成本和增长挑战,分析创新似乎是保持市场领先地位的最重要支柱。

案例研究:客户分析

一家全球领先的财富 50 强 IT 公司希望分析客户的购买行为,以优化数字营销支出。

分析和技术解决方案提供商 BRIDGEi2i Analytics Solutions 帮助该公司的营销团队:

  • 根据客户和潜在客户的浏览和购买行为,确定横幅广告活动的目标细分市场
  • 优化数字横幅广告的营销支出和绩效

关于所有方法,请阅读完整的客户分析案例研究

参考文献:

  1. http://www . barrons . com/articles/do-people-really-want-amazons-latest-innovation-1489772680
  2. https://virtuallogistics . ca/blog/the-state-of-omni-channel-data-integration-in-the-uk-March-2016/
  3. http://www . essential retail . com/news/marketing-ecomm/article/56b 86b 47723 ce-global-online-market places-unlock-a-world-of-opportunity
  4. https://www . intellectyx . com/博客/retail-analytics-in-dynamic-pricing/
  5. https://www . LinkedIn . com/pulse/attribution-modeling-retail-what-why-how-Andy-Donaldson
  6. http://analyticsindiamag . com/inside-walmartlab-Indian-operations-fulling-online-growth-global-retail-giant/

(本文特写首次出现在 BRIDGEi2i 博客 )

非常感谢您的阅读!如果你觉得这篇文章有用,请点击“鼓掌”按钮——(1)我会知道你是谁,以及(2)这篇文章会被更多的人看到。

重新思考自主代理

原文:https://towardsdatascience.com/rethinking-the-autonomous-agent-a-q-learning-behavior-system-8839a07c10b6?source=collection_archive---------15-----------------------

一个面向具身智能体的 Q 学习行为系统

Image courtesy of Eric Kilby

本文介绍了一个基于 Q 学习的行为系统,用于包括机器人和视频游戏角色在内的具身智能体。

大多数最近的强化学习(RL)成功案例都专注于在一些虚拟任务中实现超人水平的表现——无论是视频游戏还是机器人控制测试。强化学习的一个独立的、不那么耸人听闻的分支是所谓的规范强化学习,它试图模仿人类或动物行为的主观概念。这里的目标不是优化到一个任意的完美水平,而是复制一些“像人”或“像动物”的东西。虽然这种方法还没有像 RL 的其他例子一样成为头条新闻,但它无疑会在未来产生许多重要的用例。想想开放世界视频游戏的出现,这种游戏要求高度逼真地再现人类和动物的行为,或者老年护理机器人的情况,在这种情况下,超人的表现水平可能会感到陌生和迷失方向。

AI Agent using Q Learning to succeed at a Match To Sample Task

在这篇文章中,我介绍了一个行为系统的具身代理使用流行的 Q 学习算法,旨在规范强化学习。虽然面向游戏引擎,但直觉可以扩展到其他平台,并有望激发各种用例。Q-learning 也是更高级的智能行为系统的基础,比如在自主情绪工具包中发现的那些,我在别处写过关于。在这篇文章中,我将对行为系统进行一个高层次的介绍,那些想要更深入了解的人可以下载行为系统的项目文件,并附带一个教程。

q 学习是许多强化学习技术中的一种,与类似的算法相比,它有许多优点——也就是说,它简单而健壮。下面是对 Q 学习的粗略介绍。学习可以分为训练阶段和活动开发阶段。在训练阶段,代理探索其环境,采取随机行动。在此期间,它会填充一个名为 Q 表的表,其中包含关于它所采取的行动和收到的奖励的值关联。然后,这成为代理人在其活动的开发阶段如何选择决策的基础。导致奖励的行为会在开发阶段重复出现。如果希望代理人避免某些行为,奖励也可以取负值。因此,Q 学习提供了大棒和胡萝卜来驱动角色行为,其方式与人类和许多其他动物的学习方式一致。它可以用来取代或补充基于效用的计算,以前赋予人工智能体动态逼真的行为。

在所展示的行为系统中,我利用 Q 学习及其表格来驱动合成代理或 NPC(非玩家角色)的学习。Q 学习算法基本上是一种逆向归纳的方法,允许代理在状态和动作之间及时地逆向重新分配奖励信息,使其到达期望的位置。因此,需要一长串任意动作的奖励,可以按照行动者到达目的地之前的状态来分配。当这个过程重复足够多次时,就像奶油浮出水面一样,代理人就知道哪些行为和环境线索对获得奖励有帮助,哪些没有。

下面给出 Q 学习方程,其中状态和动作对分别指 Q 表和奖励表中的坐标,γ是 0 和 1 之间的固定贴现率。Gamma 控制代理人对当前奖励和未来奖励的重视程度。

Q(状态,动作)= R(状态,动作)+ Gamma * Max[Q(下一个状态,所有动作)]

在所展示的行为系统中,Q 学习被用于解决样本匹配任务,在该任务中,NPC 学习到它必须在灯打开的同时激活游戏环境中的开关,以便接收“食物奖励”。与样本匹配的任务已经被广泛应用于探索联想学习和工作记忆的动物学习实验中。

一个在灵长类动物身上进行的真实匹配样本任务的例子。图片引用: Porrino LJ,Daunais JB,Rogers GA,Hampson RE,戴德韦勒 SA (2005)在非人类灵长类动物中促进任务执行和消除安巴金(CX717)睡眠剥夺的影响。PLoS Biol 3(9): e299。

关键是代理人必须学会预测,只有在特定的情况下,它才能采取行动以获得报酬。在测试 Q 学习行为系统的“与样本匹配”任务中,代理了解到,当灯亮时,它可以收到奖励,它首先触摸开关,然后前进到金碗。绿灯熄灭时采取的相同行动不会产生奖励。

任务的设置从训练阶段开始,在该阶段中,代理随机地在四个位置之间移动,三个食物碗和一个开关,分别由球和圆锥表示。在训练期间,它学习关于这些元素中每一个的值的关联,它们如何受周期性打开和关闭的光的影响,以及它自己的动作。

当代理学习解决匹配样本任务时,Q 学习行为系统的屏幕截图。

在探索足够长的时间后,代理将显示有意的行为,首先去开关(圆锥体),然后在灯亮时去食物碗,以便获得奖励。相同的系统可以用于提供各种各样的有意行为,包括避开敌方玩家、收集生命点以及人类或动物能够在游戏环境中表现的许多行为。在这个例子的修改版本中,代理学习接近玩家的角色以获得“食物奖励”,就像狗或猫可能学习接近人类主人以获得奖励一样。

与其他强化学习任务不同,这个任务可以被校准以产生模拟真实世界认知代理的结果。将简单的学习速率添加到 Q 算法中,可以产生模拟动物测试对象的学习曲线。因此,匹配样本任务提供了一种微调智能体“大脑”的方法,并产生与相似条件下许多动物行为的例子相一致的规范性结果。

[亚伦·克鲁明斯](mailto: aaron.krumins@gmail.com) 是 AI 相关软件的自由开发者。

RetinaNet:焦点损失如何修正单次探测

原文:https://towardsdatascience.com/retinanet-how-focal-loss-fixes-single-shot-detection-cb320e3bb0de?source=collection_archive---------3-----------------------

The Calling of St Matthew by Caravaggio, in case you like art 😃

目标检测是自动驾驶、视频监控、医疗应用和许多其他领域所需的计算机视觉中的一个非常重要的领域。你听说过 YOLO 或固态硬盘这样的流行词吗?在本文中,我将向您解释最近在使用深度学习的最新物体检测方面取得的几项重要进展,并向您介绍演示如何实现它们的重要资源。读完这篇文章后,你会对这个领域有一个很好的了解,不需要物体检测方面的先验知识。

本文组织如下:

首先,我向你解释一个简单的模型,它能够检测和分类图像中的一个单独的物体。然后,我总结了用于对一幅图像中的多个目标进行检测和分类的不同方法,重点比较了区域提议单次拍摄方法。之后,我会详细解释SSDYOLO 这样的检测器是如何工作的,为什么它们比区域提议方法更快但准确性更低,最后是最近开发的 RetinaNet 如何解决这些问题。

单一目标检测

神经网络可用于解决分类问题(预测类别)和回归问题(预测连续值)。今天我们将同时做这两件事。我们从一个简化的任务开始:检测和分类图像中的一个单个对象,而不是几个对象。**

数据

对象检测数据集看起来像什么?当然,我们的模型的输入是图像,标签通常是四个值,它们描述了一个真实边界框,加上这个框中的对象所属的类别。

例如,这四个值可以描述边界框左下角和右上角的 xy 坐标。或者一个特定角的坐标和边界框的高度和宽度。

体系结构

将图像作为输入的我们的神经网络必须预测代表预测的边界框坐标的四个值,并且我们将与四个地面真实值边界框坐标(标签)进行比较。**

除此之外,神经网络还必须预测我们想要分类的 n 个类别中的每一个类别的概率。这给了我们网络必须预测的总共 4 + n 个值。

为了构建我们的单个对象检测器,我们可以采用任何卷积图像分类器网络,如 VGG-16 或 ResNet(理想情况下经过预训练),并移除网络顶部的任何分类层,平坦化截断的基础网络的输出,并添加一个或两个线性层,最终输出 4 + n 个值。您还应该在分类图层之前移除任何(自适应)池图层,因为它们会破坏我们回归边界框边缘坐标所需的空间信息。

失败

那么我们将如何训练这样一个产生 4 + n 个值的单个物体检测网络呢?预测物体的类别( n 类别概率)是一个分类问题。预测包围盒的四个坐标是一个回归问题。我们需要一个结合这两个问题的损失函数。

让我们从边界框开始:定位损失可以是预测边界框坐标 x_pred 和地面真实边界框坐标 x_labelL1 损失:

这是四个预测和四个地面真实边界框坐标之间的所有绝对差值的总和。预测框与地面真实边界框的差异越大,这种损失就越大。您也可以使用 L2 损失,但是,该模型将对异常值更加敏感,并将调整以最小化单个异常值情况,代价是具有小得多的误差的正常示例。

我们如何处理网络输出的类别概率值?首先,为了将这些 n 值转换成概率,我们对它们应用 softmax activation 函数。然后我们使用交叉熵损失函数将它们与标签进行比较。我们称之为信心丧失。**

组合损失函数简单地是定位损失(边界框)和置信度损失(类别)的加权和:

**

Examples from the Pascal VOC 2007 dataset with a single detected object

什么是 a ?原则上,定位损失可能远大于置信度损失(反之亦然)。在这种情况下,网络将只专注于学习预测边界框,而完全忽略分类任务。因此,你必须查看两个损失的值,并将其中一个乘以一个系数 a ,使它们的数量级大致相同。

我们现在知道了对象检测数据集可能是什么样子,我们如何建立一个单对象检测架构,以及如何制定损失函数。我们有训练网络所需的一切。如果你想训练这样一个模型,我建议你按照 fastai 第八课:)开始编码

好了,我们讨论了检测图像中的单个对象所需的最少步骤。但这还不够,对吗?在现实世界的场景中,我们可能需要在一幅图像中检测许多对象(数量未知)。我们如何做到这一点?

经典的计算机视觉经常使用一种叫做滑动窗口的方法。检测器在图像上滑动,一旦检测到物体,就会在检测器当前正在查看的区域周围绘制一个边界框。

随着深度学习的兴起,所谓的两阶段区域提议方法开始占据主导地位:第一阶段预测一组候选对象位置,其应该包含所有对象,但过滤掉大部分背景。第二阶段,一个 convnet ,然后将这些候选位置中的对象分类为搜索类别之一或背景。如果你对这项技术感兴趣,可以在谷歌上搜索 R-CNN。

区域提议方法产生最先进的结果,但是对于实时对象检测,尤其是在嵌入式系统上,通常计算量太大。

你只看一次 ( Redmon et al. 2015 )和SSD-Single Shot multi box Detector(Liu et al . 2015)是旨在通过在通过网络的单次向前传递中预测不同类别的边界框坐标和概率来解决该问题的架构。它们是以牺牲准确性为代价来优化速度的。

林等(2017) 最近发表了一篇漂亮的论文:他们解释了为什么像 SSD 这样的方法不如两阶段方法准确,并提出通过重新调整损失函数来解决这个问题。通过这种改进,单次方法不仅比两阶段方法更快,而且现在也一样准确,允许实时对象检测的令人敬畏的新现实世界应用。

现在,我将向您详细解释 SSD 的工作原理,为什么单次拍摄方法不如两阶段方法准确,以及 RetinaNet 和焦损如何修复这个问题。

SSD:单次多盒探测器

让我们看看 SSD 的架构(类似于 fastai 中的实现),并讨论激活的感受域的概念。YOLO 的工作方式与 SSD 类似,不同之处在于它在网络顶部使用全连接层,而不是卷积层。我们将专注于卓越的固态硬盘。**

图像被馈送到用于高质量图像分类的标准架构。网络末端的任何分类层再次被截断。SSD 论文使用了 VGG-16 网络,但其他网络如 R esNets 也可以工作。

例如,假设输入图像具有形状[3,224,224],截断网络的输出具有形状[256,7,7]。通过三次以上的卷积,我们在网络顶部创建了三个特征图,分别是形状【256,4,4】(蓝色)、【256,2,2】(黄色),最后是【256,1,1】(绿色):

SSD 白皮书中的架构在网络顶部有更多功能图,但出于演示目的,我们坚持使用三层。原理完全一样。

让我们来看看这些不同层中激活的感受野:

我们从最后一层(绿色)开始。最终绿色层中的激活依赖于先前层中的所有激活,因此感受野是整个输入图像:

现在让我们看看倒数第二层(黄色)。注意,黄色层激活的感受野只有输入图像的四分之一:

蓝色层中激活的感受野是输入图像的十六分之一。

请注意,我所做的说明是出于演示目的而简化的,例如,没有考虑到这样一个事实,即与周围区域相比,激活对来自其感受野中心的依赖更多。请看 这里 有很棒的解释。

然而,我想要表达的想法是,几乎填满整个图像的对象应该通过最后一层(绿色层)的激活来检测,而大约填满输入图像左下四分之一的对象应该通过黄色层的激活来检测,这是有意义的。

因此,我们定义了一些所谓的默认框锚框:

这些点就是所谓的并且标记了它们各自的默认锚盒的中心。中间的绿色锚点是整个图像周围绿色框的中心,这是对应于最后一个卷积层(绿色)的默认框。

黄色/橙色锚点定义了属于倒数第二个卷积层(黄色)的四个黄色/橙色框的中心,16 个蓝色默认框属于所示 SSD 架构中的蓝色层。

你可能会问自己这在代码中会是什么样子。例如,您可以创建一个数组,其中每一行定义一个默认框,有四列,例如左下角和右上角的 x 和 y 坐标或一个角的坐标加上高度和宽度。

我们下一步做什么?当我们研究如何检测图像中的单个对象时,我们预测了边界框坐标的 4 个值和每个 n 类的一个概率,从而给出了我们的神经网络返回的总共 4 + n 个数字。请记住,我们现在还想对背景进行分类,因此 n 应该是您的数据集中的类别数+ 1。

这就是我们现在对每个缺省框所需要的:每个缺省框需要 n 个值,它们表示在该框中检测到某个类的概率,以及 4 个值,它们现在不是预测边界框的绝对坐标,而是到相应缺省框的偏移量。**

对于 4x4 蓝色默认框,我们需要总共 16 乘以 4 的值来计算预测边界框的坐标,以及我们试图分类的 n 个类别的 16 乘以 n 个概率。

对于 2x2 黄色默认框,我们总共需要 4 乘 4 的坐标值和 4 乘 n 类的 n 概率。

我们如何做到这一点?更多卷积层!

草图 SSD 架构中的最后三个功能图(蓝色、黄色和绿色层)具有形状[256,4,4]、[256,2,2]和[256,1,1]。它们对应于蓝色默认框的 4x4 网格、黄色默认框的 2x2 网格和一个跨越上图所示网格中整个图像的绿色默认框。

三个特征图中的每一个都被输入到另外两个卷积层。我知道这很令人困惑,但请耐心等待,我们就快成功了:)

我们来看看黄色的特征图(2x2 网格)。我们有[256,2,2]个激活,需要 shape [4,2,2]的输出和 shape[n,2,2]的第二个输出(其中n是类的数量)。因此特征图的宽度和高度不能改变,但是两个卷积输出层需要分别将特征图从 256 减少到 4 和 n 个滤波器。

对于蓝色特征地图(对应于 4x4 网格),我们需要两个输出图层,将[256,4,4]特征地图简化为[4,4,4]和[n,4,4]张量。

查看整个图像的绿色默认框对应于形状为[256,1,1]的绿色特征地图。我们最后还需要两个卷积输出层,它们将绿色特征图作为输入,产生[4,1,1]和[n,1,1]形状的输出。

我知道这是很多。重要的想法是,我们对不同大小的网格中的每个默认框都做了我们在预测图像中的单个对象时所做的事情。

好了,我们总结一下:

  1. 我们定义了几个不同大小默认框的网格,这将允许我们在一次向前传递中检测不同比例的对象。许多以前的体系结构检测不同比例的物体,例如通过将相同图片的不同大小的版本传递到检测器,这在计算上更昂贵。
  2. 对于每个网格中的每个缺省框,网络输出 n 个分类概率和 4 个到相应缺省框坐标的偏移,这给出了预测的边界框坐标。

Ground truth bounding boxes

那么我们如何训练网络呢?

在左侧,您可以看到一个来自 Pascal VOC 2007 数据集的对象检测示例。一张餐桌和两把椅子有三个地面真实边界框。

4x4 grid of default boxes

在下图中,您可以看到默认框的 4x4 网格(2x2 和 1x1 网格未显示)。

网络为 16 个默认框中的每一个预测 4 个坐标(偏移)和 n 类概率。但是,在训练时,我们应该将这些预测中的哪些与损失函数中的基本事实默认框进行比较呢?

我们需要将训练示例中的每个基本事实边界框与(至少)一个默认框进行匹配。

匹配问题

我们希望将地面真实边界框与一个默认框匹配,这个默认框与它尽可能“相似”。我说的相似是什么意思?当两个盒子尽可能多地重叠,同时尽可能少地具有不重叠的区域时,它们是相似的。这由 Jaccard 索引或 IoU 索引定义:

Source

让我们看几个例子:

  1. 重叠区域(交叉点)是整个橙色区域,因此重叠达到最大值。但是联盟(蓝色区域)要大得多。这不是一个很好的匹配,会导致较低的 Jaccard 指数。
  2. 这是最佳匹配:重叠区域和联合区域几乎具有相同的大小。Jaccard 指数应该接近 1。
  3. 这里,重叠也比两个盒子(联合)的整个面积小得多,这给出了低的 Jaccard 指数。

在我们的训练示例中,我们使用 4x4、2x2 和 1x1 网格中的 every default box 来计算everyground truth bounding box 的 Jaccard 索引。

基础事实边界框与其共享最高 Jaccard 索引的默认框相匹配,并且与其具有大于特定阈值的 Jaccard 索引的每个其他默认框相匹配。

我知道这些细节可能听起来令人困惑。重要的想法是,我们希望将训练示例中的基本事实边界框与默认框所做的预测进行比较,默认框已经与基本事实边界框非常相似。

我们现在知道…

  1. … 4 个预测坐标(默认框的偏移量)和每个默认框的n 预测类别概率和…**
  2. …哪个基本事实边界框与哪个默认框匹配。

现在,我们做同样的事情,当我们想检测一个单一的对象。

损失再次是定位损失(边界框)和置信度损失(类)的加权和:我们计算预测的边界框(默认框坐标+预测的偏移)与匹配的地面真实边界框(L1 损失)有多大差异,以及默认框预测类的正确程度(二进制交叉熵)。我们将每个匹配的默认框和基本事实边界框对的这两个值加在一起,并有一个损失函数,当预测框更接近基本事实边界框时,以及当网络在分类对象方面做得更好时,该损失函数将返回更低的值。

当没有一个类别概率超过某个阈值时,网络会将该框中的对象视为背景。在现实中,你会发现,对于图像中的每个真实对象,网络都会产生几个几乎相互重叠的边界框。一种称为非最大值抑制的技术用于将预测相同类别并且具有大于特定阈值的 Jaccard 索引的所有框减少到每个检测到的对象一个预测框。

为了便于理解,我省略了一个小细节。对于每个锚点,SSD 定义了不同纵横比和大小的 k 默认框,而不是本文中讨论的一个。这意味着我们还需要 4 倍于 k 的相对于各自默认框坐标的预测偏移量,而不是 4 和 n 倍于 k 的类概率,而不是 n 。更多不同尺寸和长宽比的盒子=更好的物体检测。这个细节对于一般的理解来说并不是太重要,但是如果你对这个细节感兴趣的话,可以看看刘等人 2015 中的图 1 进行说明。

SSD 和 YOLO 只需要通过网络向前传递一次来预测对象包围盒和类别概率。与滑动窗口区域提议方法相比,它们要快得多,因此适合于实时物体检测。SSD(在网络顶部使用多尺度卷积特征地图,而不是像 YOLO 那样使用全连接层)比 YOLO 更快更准确。

唯一剩下的问题:区域提议方法如 R-CNN 更准确

焦点损失

两阶段方法的优势在于,它们首先预测几个候选物体位置,然后使用卷积神经网络将这些候选物体位置中的每一个分类为类别之一或背景。这里的重点是几个候选位置

像 SSD 或 YOLO 这样的方法遭受极端的类别不平衡:检测器评估大约一万到十万个候选位置(比我们这里的例子中的 4x4、2x2 + 1 默认框多得多),当然这些框中的大多数不包含对象。即使检测器容易地将这些大量的盒子分类为底片/背景,仍然存在问题。

我会向你解释原因:

这是交叉熵损失函数,其中 i 是类的索引, y_i 是标签(如果对象属于类 i 则为 1,否则为 0),而 p_i 是对象属于类 i 的预测概率。

我们会看剧情,不用太担心方程:)

假设一个盒子包含背景,网络 80%确定它实际上只是背景。这种情况下 y(背景)=1 ,其他所有 y_i 都是 0, p(背景)=0.8

可以看到,在 80%确定盒子只包含背景的情况下,损失仍然是~0.22。

例如,假设图像中有 10 个实际对象,网络并不确定它们属于哪一类,因此它们的损失为 3。这将为我们提供大约 30 个(顺便说一下,所有数字都是虚构的,是为了演示目的而选择的)

所有其他约 10,000 个默认框都是背景,网络 80%确定它们只是背景。这样我们的损失在 10000 * 0.22 = 2200 左右。

告诉我,什么占主导地位?网络很难对少数真实对象进行分类?还是网络容易归类为背景的所有框?

好吧,大量容易分类的例子绝对支配了损失,从而支配了梯度,因此压倒了网络仍然有困难并应该从中学习的少数有趣的例子。

那我们该怎么办?林等人(2017) 有一个很好的想法,缩放交叉熵损失,以便网络已经非常确定的所有简单示例对损失的贡献更小,以便学习可以集中在少数有趣的案例上。作者称他们的损失函数为焦点损失和他们的架构 RetinaNet (注意 RetinaNet 还包括特征金字塔网络(FPN),这基本上是 U-Net 的新名称)。

根据该论文,γ= 2 效果最佳。还是那句话,如果你不愿意,也不要太担心这个等式,一旦你看到这个情节,你就会明白这有什么不同了:

请注意,当网络对预测非常确定时,损失现在明显降低了。在我们之前 80%确定性的例子中,交叉熵损失的值约为 0.22,现在焦点损失的值仅为 0.009。对于网络不太确定的预测,损耗减少了一个小得多的系数!

通过这种重新调整,大量容易分类的例子(主要是背景)不再主导损失,学习可以集中在少数有趣的案例上。

通过这种强大的改进,只需要通过网络进行一次前向传递的对象检测器突然能够在准确性方面与两阶段方法竞争,同时在速度方面轻松击败它们。这为甚至在嵌入式系统上进行精确的实时对象检测开辟了许多新的可能性。厉害!

如果你和我一样对这种东西着迷,我强烈建议你自己实现一个单次对象检测网络。我建议你跟着伟大的课程fastai——程序员的前沿深度学习第 8 课和第 9 课一起编码。你在这里找到相应的笔记本。在这个笔记本中,所有关于匹配问题的函数都写在一个单元格中,它们的输出稍后才显示。这大大降低了代码的可理解性。我重新实现了笔记本,添加了更多的注释,并把所有东西(尤其是匹配问题)按顺序排列,希望能让你从上到下阅读笔记本,同时在继续实现用于此目的的功能之前,逐渐建立对基础事实边界框如何与默认框匹配的理解。也可以随意使用我的笔记本作为额外参考。

我希望你从这篇文章中学到了一些有趣的东西:)如果任何部分不清楚或者你需要额外的解释,请留下评论,我很乐意帮助你理解。

逆向工程反向传播

原文:https://towardsdatascience.com/reverse-engineering-back-propagation-8ecbc94ad36c?source=collection_archive---------18-----------------------

有时候,从例子开始可能是一种更快的学习方法,而不是在进入详细的例子之前先学习理论。这就是我将在这里尝试做的,使用一个来自官方 PyTorch 教程的例子,它实现了反向传播和反向工程数学及其背后的概念。

下面是教程(https://py torch . org/tutorials/beginner/py torch _ with _ examples . html # warm-up-numpy)的快照,其中 numpy 被用来实现一个具有一个隐藏层的网络。

*# -*- coding: utf-8 -*-*
**import** numpy **as** np

*# N is batch size; D_in is input dimension;*
*# H is hidden dimension; D_out is output dimension.*
N, D_in, H, D_out **=** 64, 1000, 100, 10

*# Create random input and output data*
x **=** np**.**random**.**randn(N, D_in)
y **=** np**.**random**.**randn(N, D_out)

*# Randomly initialize weights*
w1 **=** np**.**random**.**randn(D_in, H)
w2 **=** np**.**random**.**randn(H, D_out)

learning_rate **=** 1e-6
**for** t **in** range(500):
    *# Forward pass: compute predicted y*
    h **=** x**.**dot(w1)
    h_relu **=** np**.**maximum(h, 0)
    y_pred **=** h_relu**.**dot(w2)

    *# Compute and print loss*
    loss **=** np**.**square(y_pred **-** y)**.**sum()
    print(t, loss)

    *# Backprop to compute gradients of w1 and w2 with respect to loss*
    grad_y_pred **=** 2.0 ***** (y_pred **-** y)
    grad_w2 **=** h_relu**.**T**.**dot(grad_y_pred)
    grad_h_relu **=** grad_y_pred**.**dot(w2**.**T)
    grad_h **=** grad_h_relu**.**copy()
    grad_h[h **<** 0] **=** 0
    grad_w1 **=** x**.**T**.**dot(grad_h)

    *# Update weights*
    w1 **-=** learning_rate ***** grad_w1
    w2 **-=** learning_rate ***** grad_w2

在此示例中,每个输入都是大小为 1000 的一维数组,输出也是一维的,大小设置为 10。除了每个 NN 将具有的输入和输出层之外,还有一个隐藏层,该隐藏层在示例中被设置为大小为 100。

这是一个简单的例子,如果大小为 64,我们有 1 批训练数据。换句话说,我们有 64 组大小为 1000 的随机初始化输入和大小为 100 的输出。目标是使用这 64 个随机初始化的训练数据来训练网络。

让我们看看向前传球。与连接输入和隐藏层相关联的权重矩阵的大小为 1000×100(即输入维度大小×隐藏维度大小)。并且 1000 大小的输入和权重矩阵之间的矩阵乘法将导致 100 大小的隐藏层。我们不是真的一个一个地做,而是对整批做,就像这里看到的:“h = x 点(w1)”。对得到的 64 x 100 应用 ReLU 函数来去除负数,但是这一步不会以任何方式影响尺寸。得到的 64×100 矩阵乘以大小为 100×10 的第二个权重矩阵,得到大小为 10 的输出。损失计算看起来也很简单,是误差平方和。

在进入反向投影步骤之前,我们先来看一下这个设置。让我们从输出层开始。

Note: I am not using the variable names but different notations like “a” and “f” as this will help get a better general understanding of back propagation (and to make the equations look less congested).

我没有使用变量名,而是使用不同的符号,如“a”和“f ”,因为这将有助于更好地理解反向传播(并使方程看起来不那么拥挤)。我还把最后一层表示为“l+1”,这样前一层就可以用“l”来表示了。这是因为我们需要再返回一层,以获得一个概括的理解,并获得一个可重复调用的反向传播函数,我希望这一层的索引为“l”。

损失函数定义为:

这是在下面几行代码中计算的。

*# Compute and print loss*
loss **=** np**.**square(y_pred **-** y)**.**sum()

现在我们的目标是找出这种损失相对于网络中的权重的变化率,以便我们可以相应地调整权重并使损失最小化。让我们从最后一层开始。我们的目标是确定:

但是我们现在只知道损失的价值。所以让我们扩展一下,让它发挥作用。

我们上面所做的是,保持因变量被微分(在这种情况下“C”的损失)固定,我们试图找到导数 wrt 它的子表达式递归。换句话说,因为我们知道“C”是输出激活“a”的函数,所以我们利用“链规则”重写以找到“C”wrt 对“a”的导数,然后找到“a”wrt“w”的导数——这种通过函数的子表达式递归向后移动以导出损耗 wrt 对函数输入的导数的逻辑,假定损耗 wrt 对函数输出的导数被称为“反向传播”或“反向模式自动差分”(反向累加 AD )。一般来说,从最后一个输出层开始,通过神经网络的所有层,一层一层地重复这个逻辑。

回过头来,我们实际上知道了等式的第一部分,因为这可以使用幂法则来推导。

这是示例中得出的结果:

grad_y_pred **=** 2.0 ***** (y_pred **-** y)

让我们解决第二部分:

将所有这些放在一起,最后一层的损耗 wrt 对 w 的偏导数可以写成:

计算结果如下:

grad_w2 **=** h_relu**.**T**.**dot(grad_y_pred)

虽然这是在每个图层中计算权重梯度的方式,但输出图层得到了简化,因为激活函数只是一个点积。在前一层中,我们在产品上使用了一个整流线性单元(ReLU)。示例中的代码片段是:h = x 圆点(w1);h_relu = np 最大值(h,0)。Sigmoid 函数也是常用函数,两种函数同时使用也很常见。让我们直观地表现这一层,并获得 w1 的梯度。

就像上一层一样,让我们展开损失 wrt 对权重的偏导数。

让我们处理第一部分。在输出层,我们知道损耗对输出激活的偏导数,因为我们将损耗定义为激活(也称为预测输出和实际值)之间的差值。但是对于这一层,我们需要推导出来。因为我们知道下一层的损耗输出激活的导数,所以让我们使用它并将第一部分重写为:

下一层的输出激活的偏导数 wrt 该层的输出激活可以求解如下:

所以第一部分是,

这是教程代码中的计算结果:

grad_h_relu **=** grad_y_pred**.**dot(w2**.**T)

插回去:

这留给我们第二部分,这是这一层的输出激活相对于这一层的权重的偏导数。

这里的激活功能是一个两步功能。首先,我们将权重乘以前一层的输出。接下来,我们应用一个 ReLU 函数。应用反向传播的原理,这可以重写如下。

第一部分是:

让我们放大 ReLU 函数及其导数。ReLU 的导数恰好是一个单位阶跃函数,所有“x <0” “1”s for all other values of “x”.

The second part of the equation can be solved as:

Bringing both together:

Plugging it back to our goal of finding the partial derivative of loss wrt weights in this layer,

There are four terms being multiplied above. As seen earlier, the first product is what is calculated in the tutorial code as “grad_h_relu = grad_y_pred 都是“0”。点(w2 )。 T)”。第二个产品具有单位阶跃函数,当 z 小于 0 时为 0,否则为 1。最后一部分是具有输入激活的产品,在我们的示例中是“x”输入层。下面是完成所有这些工作的三行代码:

grad_h **=** grad_h_relu**.**copy()
grad_h[h **<** 0] **=** 0
grad_w1 **=** x**.**T**.**dot(grad_h)

前两行代码表示前三项之间的乘积,最后一行代码表示输入值的最终乘积。下面的映射将有助于匹配代码和派生。

如前所述,通常也使用 sigmoid 函数进行激活,我们将使用 sigmoid 函数的导数来代替上述计算中的单位阶跃函数。因此,如果我们要编写一个独立的反向传播函数,它会将损耗 wrt 对输出激活的导数作为输入,并且必须从中计算两个值。首先,将是损失对权重的导数。这将在梯度下降计算中用于更新权重。第二,该函数应计算输入激活的损耗导数。这将必须被返回以便继续反向传播,因为这一层的输入激活只不过是前一层的输出激活。调用函数可以使用这个返回值为前一层再次调用 backprop 函数,但这次将返回值作为输入传递给函数。

虽然我花了一些时间试图通过教程了解 backprop、自动微分和 PyTorch,但很快就发现,并行使用一个解释另一个是比单独使用更有效的了解这些主题的方法。希望这有所帮助。

综述:ARCNN —减少伪影 CNN(编解码器滤波)

原文:https://towardsdatascience.com/review-arcnn-deblocking-denoising-a098deeb792?source=collection_archive---------6-----------------------

在这个故事中,神器还原 CNN (ARCNN) 被回顾。ARCNN 用于减少以下图像伪影:

  • 分块伪像: JPEG 图像由 8 个 × 8 个不重叠块压缩而成。块效应是沿着 8×8块边界的不连续性
  • 沿锐边的振铃效应:为了有效地压缩图像,对高频分量进行量化,以从图像中去除一些高频信号。然而,当边缘尖锐时,当量化太强时,在尖锐边缘附近存在像波一样的环状伪像。
  • 模糊:高频成分的损失也会引起模糊。这些伪像会影响其他程序,例如超分辨率和边缘检测。

Original JPEG (left) JPEG After ARCNN (Right)

ARCNN 已经在 2015 ICCV 发表,一个改良的 fast ARCNNarXiv 2016发表。由于 ARCNN 是基于 SRCNN 构建的,并且 SRCNN 有浅层 CNN 架构,ARCNN 涉及迁移学习概念,所以学习 CNN 是一个良好的开端。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 快速回顾 SRCNN
  2. ARCNN
  3. ARCNN —易到难转
  4. 快速 ARCNN

1.SRCNN 快速回顾

SRCNN (9–1–5)

Feed Forward Functions (Left) Loss Function (Right)

上图是 SRCNN 架构。图像经过 9×9、1×1、5×5 变换,得到输入图像的超分辨率。

注意,在网络中的网络(NIN)中使用 1×1 conv。在 NIN 中,1 × 1 conv 被建议引入更多的非线性以提高精度。GoogLeNet [4]中也建议减少连接数。

损失函数就是输入图像和超分辨率输出图像之间的误差。

SRCNN 只有 3 个 conv 层。这是学习深度学习的入门文章之一。

(如有兴趣,请访问我在 SRCNN 上的评论。)

2.ARCNN

ARCNN (9–7–1–5)

与 SRCNN 相比,ARCNN 多了一层 7×7 的滤波器。

JPEG Images compressed with Quality Factor of 10

带原 JPEG :平均 PSNR 为 27.77 dB

使用Sr CNN(9–1–5):28.91 dB,意味着图像质量提高。

使用更深的 Sr CNN(9–1–1–5):28.92 dB,多一层 1×1 的滤镜帮助不大。

使用 ARCNN(9–7–1–5):得到 28.98 dB。

Average PSNR along the number of backprops

ARCNN has a better visual quality

3.ARCNN —由易到难的转移

3.1 由浅入深的转移

Transfer from Shallower to Deeper

  • 首先学习 ARCNN(9–7–1–5 ),然后保留前两层。
  • 并在 ARCNN(9–7–3–1–5)学习第 3 层到第 5 层。

由于已经学习了前两层,这比随机初始化好得多,如下所示:

Average PSNR along the number of backprops (He [9] is one kind of random initialization)

3.2 从高质量向低质量转移

Transfer from higher to lower quality

  • 同样,先用更高质量的样本进行训练。
  • 然后转移第一层或前 2 层。

Average PSNR along the number of backprops

3.3 从标准到真实案例的转换

在 Twitter 中,3264×2448 的图像会被重新缩放和压缩成 600×450 的图像。因此,

  • 学习网络使用标准图像,传输第一层。
  • 然后用 40 张 Twitter 照片进行训练(335209 个样本)。

Average PSNR along the number of backprops

Twitter Image Visual Quality

4。快速 ARCNN

4.1 层分解

one more layer with a 1×1 filter is added for Fast ARCNN, (number of filters(filter size))

通过在两个空间卷积之间添加 1×1 卷积,可以减少参数的总数。

N: Total Number of Parameters of a Model

ARCNN

Fast ARCNN

  • ARCNN 在第二层有 100,352 个参数,总共有 106448 个参数
  • Fast ARCNN 只有第二层和第三层的 51200 个参数,总共只有 57296 个参数!!!

使用 1×1 卷积来减小模型尺寸实际上已经在 GoogLeNet 中提出。

4.2 第一层的步幅较大,最后一层的过滤器较大

  • 将第一卷积层中的步长从 1 增加到 2。
  • 将最后一个卷积层中的滤波器大小从 5 增加到 9。

参数数量(N)仍然只有 56496。

Results

  • ARCNN: 29.13 分贝
  • 快速 ARCNN (s=2): 29.07 dB 下降很少。

通过比较速度

  • ARCNN 中每幅图像 0.5 秒
  • 快速 ARCNN 中每幅图像 0.067 秒,这是一个 7.5 的加速比!!

参考

  1. 【2015 ICCV】【ARCNN】
    深度卷积网络压缩伪像还原
  2. 【2016 arXiv】【快速 ARCNN】
    用于压缩伪像减少的深度卷积网络

我的评论

[Sr CNN][Google net]

回顾:2018 年的人工智能

原文:https://towardsdatascience.com/review-artificial-intelligence-in-2018-403ca386980f?source=collection_archive---------9-----------------------

人工智能不再是一个时髦的词。截至 2018 年,它是大数据分析的一个发展良好的分支,拥有多个应用程序和活跃的项目。以下是对该主题的简要回顾。

人工智能是各种大数据分析方法的总称,如机器学习模型和深度学习网络。我们最近揭开了 AI、ML 和 DL 的神秘面纱,以及它们之间的区别,所以请随意查看。简而言之,人工智能算法是各种数据科学数学模型,有助于改善特定过程的结果或自动化一些日常任务

然而,该技术现在已经足够成熟,可以将这些数据科学进步从试点项目阶段转移到大规模生产就绪部署阶段。下面是 2018 年整个 IT 行业人工智能技术采用的各个方面的概述。

我们来看看这些参数,比如:

  • 最广泛使用的人工智能算法,
  • 公司应用人工智能的方式,
  • 人工智能实施将产生最大影响的行业
  • 用于人工智能开发的最流行的语言、库和 API

因此,本文中使用的数字来自各种公开来源,如 Statista、Forbes、BigDataScience、 DZone 等。

最广泛使用的人工智能算法类型

有多种类型的 ML 模型适用于不同的目的。各种算法被用于有监督的、无监督的和强化的机器学习、光学字符识别、语音和文本识别等。四种最流行的算法是决策树、自然语言处理(NLP)工具、线性回归和神经网络。

公司使用人工智能的方式

人工智能算法大多已经超过了试点项目的阶段,目前正处于全公司采用的不同阶段。 36% 的美国和欧盟企业正在积极投资他们的人工智能计划, 31%的企业正计划在不久的将来这样做,而 17% 的企业已经开始了他们的数字化转型之旅,现在已经收获了收益。只有 16%的公司没有投资人工智能技术的计划。正如美国伟大的工程师和演说家威廉·爱德华兹·曼宁所说的那样,没有必要去适应。你的生存不是必要的。

人工智能将最大程度颠覆的行业

行业渐变呢?说人工智能将使任何商业受益,这很好也很简单,但是如何指出特定行业的好处呢?这很容易做到,因为几乎任何从事大数据分析的公司都可以从人工智能算法的数据分析增强中受益匪浅。360 度客户视角同样有益于医疗保健、金融、银行、保险、营销、旅游等。

最流行的人工智能语言、库和 API

正如我们之前提到的,在各种规模的公司中,投资开发人员培训是使用人工智能算法的最受欢迎的方式之一。事实上,近 75%的调查受访者从事某种软件开发,其中 56% 培训他们的开发人员使用另一种语言来创建和训练机器学习模型以满足他们的需求。用于人工智能开发的三种主要编程语言是 Java、Python 和 R,下表重点介绍了它们在 IT 行业的使用情况。

关于 2018 年人工智能状况的最终想法

正如你所看到的,Python 显然正在成为 AI/ML 开发的领导者,无论是业务部署还是爱好项目。r 也是领先的三种语言之一,主要是因为 JuPyteR 笔记本的强大功能,它与 Python 协同工作。尽管如此,Java 仍然是企业级软件开发的堡垒,而且不会被抛弃。

因此,投资 AI/ML/DL 项目对任何企业来说都无疑是非常有利可图的。成本优化、客户数据处理、服务个性化、大数据挖掘和分析——所有这些都是永无止境的业务改进和增长过程中同等重要的部分。

你的公司在日常运营中使用人工智能吗?请和我们分享你的经历!

数据科学家的工具箱(JHU Coursera,课程 1)

原文:https://towardsdatascience.com/review-course-1-the-data-scientists-toolbox-jhu-coursera-4d7459458821?source=collection_archive---------1-----------------------

Image from Quiz 3 in Data Scientist’s Toolbox

数据科学专业的第一门课程“数据科学家的工具箱”是一门非常入门的课程,旨在帮助学生设置成为数据科学家所需的一些工具(R、RStudio 和 Git)。像往常一样,测验和作业的代码位于我的 github 上。

第一周回顾:第一周主要是介绍专门化以及如何安装用于整个专门化的 R。测验是一系列非常基本的问题。这让我有点失望。

Data Scientist’s Toolbox John Hopkins Quiz 1

第二周回顾:本周远远好于第一周。这么多有用的东西在短时间内涵盖了。git、markdown 和命令行的基础是必不可少的。Git 和命令行基础是我每天都要用到的技能。Markdown 用得比较少,但是它出现在这篇文章的所有测试题中。

Data Scientist’s Toolbox John Hopkins Quiz 2

第三周:第二周很棒。第三周更加概念化。研究设计和将数据转化为知识背后的问题很好了解,但并不那么令人兴奋。

Data Scientist’s Toolbox John Hopkins Quiz 3

第四周复习:本周只是一个简单的作业。下面的任务只是为了确保每个人都知道如何使用 git(制作一个 repo,创建一个 markdown 文件,并分叉),以及确保每个人都安装了 R 和 RStudio。

Data Scientist’s Toolbox John Hopkins Project

总的来说,这个课程有点令人失望。这门课的大部分内容都是在谈论其他课程,复习极端的 git 基础知识。如果我还没有对数据科学专业接下来的几门课程写一篇积极的评论,我不会建议继续下去。然而,专业化的其余部分对工业非常有用。接下来的几门课程将教授如何获取数据文件,操作它们,并提供有用的见解。请看我的课程 2 R 编程复习

回顾:de convnet-un pooling 层(语义分段)

原文:https://towardsdatascience.com/review-deconvnet-unpooling-layer-semantic-segmentation-55cf8a6e380e?source=collection_archive---------7-----------------------

在这个故事中,反褶积网络被简单回顾,反褶积网络(DeconvNet)是由反褶积层和反褶积层组成的

对于传统的 FCN,输出是通过高比率(32 倍、16 倍和 8 倍)上采样获得的,这可能导致粗糙的分割输出(标签图)。在这个去卷积网络中,通过逐步去卷积和去卷积来获得输出标签图。而且是我写这个故事的时候在 2015 ICCV 发表的一篇论文【1000 多篇引用。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 解卷积和去卷积
  2. 实例式分割
  3. 两阶段训练
  4. 结果

1.去极化和去卷积

以下是 DeconvNet 的整体架构:

DeconvNet Architecture

正如我们所见,它使用 VGGNet 作为主干。第一部分是一个卷积网络,通常像 FCN,conv 和池层。第二部分是反卷积网络,这是本文的一个新部分。

Remember positions when Pooling (Left), Reuse the position information during Unpooling (right)

要执行取消池化,我们需要在进行最大池化时记住每个最大激活值的位置,如上所示。然后,如上所示,记忆的位置被用于取消绕线。

Convolution is to conv the input to smaller size (Left) Deconvolution is to conv the input back to larger size (Right)

反卷积只是将 conv 输入恢复到更大的尺寸。(如有兴趣,请阅读我的 FCN 评论了解详情。)

An example of Deconvolution and Unpooling

上图就是一个例子。(b)是 14×14 解卷积层的输出。(c)是取消轮询后的输出,依此类推。我们可以在(j)中看到,自行车可以在最后的 224×224 解卷积层中重建,这表明学习过的滤波器可以捕捉特定于类的形状信息。

Input Image (Left), FCN-8s (Middle), DeconvNet (Right)

如上所示的其他示例表明,DeconvNet 可以重建比 FCN-8s 更好的形状。

2。实例式分割

Bad Examples of Semantic Segmentation Without Using Region Proposals

如上所示,比感受野大得多或小得多的对象可能被分割或错误标记。小物体经常被忽略,被归类为背景

语义分割被提出为基于实例的分割问题。首先,2000 个区域提议(边界框)中的前 50 个由对象检测方法 EdgeBox 检测。然后, DeconvNet 应用于每个提议,并将所有提议的输出聚合回原始图像。通过使用建议,可以有效处理各种规模。

3。两阶段训练

第一阶段培训

使用地面实况注释裁剪对象实例,以便对象在裁剪的边界框处居中,然后执行训练。这有助于减少对象位置和大小的变化。

第二阶段培训

使用了更具挑战性的例子。这些示例是由与基本事实分段重叠的建议生成/裁剪的。

一些其他细节

  • 使用批量标准化。
  • conv 部分使用 VGGNet 中的权重进行初始化。
  • deconv 部分用零均值和高斯函数初始化。
  • 每批 64 个样品。

4.结果

mean IoU results

  • FCN-8s 的平均欠条只有 64.4%。
  • 下降率 : 69.6%
  • DeconvNet+CRF : 70.5%(其中 CRF 只是一个后处理步骤)
  • EDeconvNet:71.5%(EDeconvNet 表示用 FCN-8 组合的结果)
  • EDeconvNet+CRF : 72.5%,平均 IoU 最高。

Benefits of Instance-wise segmentation

从上图可以看出,基于实例的分段有助于逐个实例地进行分段,而不是一次对所有实例进行分段。

应当注意,DeconvNet 的增益不仅仅来自于逐渐的 deconv 和 unpooling,还可能来自于实例式分割和两阶段训练。

Some Visualization Results

EConvNet+CRF 通常有好的结果,即使比 FCN 差。

参考

  1. 【2015 ICCV】【de convnet】
    用于语义切分的学习反卷积网络

我的评论

[FCN][VGGNet]

复习:DeepID-Net-Def-Pooling 层(对象检测)

原文:https://towardsdatascience.com/review-deepid-net-def-pooling-layer-object-detection-f72486f1a0f6?source=collection_archive---------3-----------------------

在这个故事里, DeepID-Net 简单回顾一下。介绍了一种基于可变形零件的细胞神经网络。一个新的可变形约束池(def-pooling)层被用于建模具有几何约束和惩罚的物体部分的变形。

这意味着,除了直接检测整个对象之外,检测对象的部分也是至关重要的,然后这些部分可以帮助检测整个对象。是 ILSVRC 2014 中 任务亚军。并在2015 CVPR【1】和2017 TPAMI【2】发表论文,共引用约 300 篇。( Sik-Ho Tsang @中)

DeepID-Net

黑色彩色的台阶实际上是 R-CNN 中存在的老东西 红色颜色的步骤实际上是没有出现在 R-CNN** 中。**

我会提到上图中的每一步,并在故事的结尾给出结果。

步伐

  1. 选择性搜索
  2. 箱子拒收
  3. 使用对象级注释进行预训练
  4. 定义池层
  5. 情境建模
  6. 模型平均
  7. 包围盒回归

1。选择性搜索

Selective Search

  1. 首先,颜色相似性、纹理相似性、区域大小和区域填充被用作非基于对象的分割。因此,我们得到了许多小的分割区域,如上图左下方所示。
  2. 然后,使用自下而上的方法,将小的分割区域合并在一起,形成更大的分割区域。
  3. 因此,如图像所示,生成了大约 2K 个 区域提议(边界框候选)。****

2.盒子拒绝

R-CNN 用于拒绝最有可能是背景的包围盒

3.使用对象级注释进行预训练

Object-Level Annotation (Left), Image-Level Annotation (Right)

通常,预训练在图像级注释上进行。当图像中的对象太小时是不好的,因为对象应该在选择性搜索创建的边界框中占据大的区域。****

因此,预训练是在对象级注释上进行的。而深度学习模型可以是 ZFNet、VGGNet、GoogLeNet 等任何模型

4。Def-Pooling 层

Overall Architecture with More Details

例如,我们使用 ZFNet,在 conv5 之后,输出将经过原始 FC 层 fc6 和 fc7,以及一组 conv 和建议的 def-pooling 层。

Def-Pooling Layers (Deformable Constrained Pooling), High Activation Value for the Circle Center of Each Light

Def-Pooling Equations

对于 def-pooling 路径,conv5 的输出经过 conv 层,然后经过 def-pooling 层,最后是 max pooling 层。

简而言之,AC 乘以 dc,n 的总和就是上图中的 5×5 变形罚分惩罚是从假定的锚位置放置目标部分的惩罚。****

def-pooling 层学习具有不同大小和语义含义的对象部分的变形。****

通过训练该 def-pooling 层,要检测的对象的对象部分将在 def-pooling 层之后给出高的激活值,如果它们靠近它们的锚位置的话。并且这个输出将连接到 200 级分数以进行改进。

5.情境建模****

在 ILSVRC 的目标检测任务中,只有 200 个类。并且在 ILSVRC 中还有一个分类竞争任务,用于对 1000 类对象进行分类和定位。与目标检测任务相比,内容更加多样化。因此,通过分类网络获得的 1000 类分数被用于细化 200 类分数。****

6.模型平均****

****使用多个模型来提高精确度,并且对所有模型的结果进行平均。这种技术从 LeNet、AlexNet 等开始使用。

7.包围盒回归****

包围盒回归只是为了微调包围盒位置,在 R-CNN 中已经使用。

结果

Incremental Results

  • 具有选择性搜索的 R-CNN(步骤 1): 29.9% mAP(平均平均预测)
  • + 包围盒拒绝(第二步):30.9%
  • 从 AlexNet 改为 ZFNet(第三步):31.8%
  • 从 ZFNet 更改为 VGGNet(步骤 3): 36.6%
  • 从 VGGNet 更改为 GoogLeNet(第三步):37.8%
  • + 对象级标注的预处理(第三步):40.4%
  • +边缘有更多的边界框建议来自[参考文件 60]: 42.7%
  • + Def-Pooling 层(第 4 步):44.9%
  • +建议在 VGGNet 进行多尺度培训:47.3%
  • + 情境建模(第五步):47.8%
  • +边界框回归(第 7 步):48.2%
  • +模型平均(第六步): 50.7%!

与多模型多作物 GoogLeNet 相比,DeepID-Net 的地图高出 6.1%。然而,正如我们所看到的,有些投稿实际上来自其他论文。然而,有两个最新颖的想法是对对象级注释进行预处理,以及定义池层。

参考

  1. 【2015 CVPR】【DeepID-Net】
    DeepID-Net:用于物体检测的可变形深度卷积神经网络
  2. 【2017 TPAMI】【DeepID-Net】
    DeepID-Net:用于物体检测的可变形深度卷积神经网络

我的评论

[R-CNN][AlexNet][ZFNet][VGGNet][Google net]

复习:DeepLabv1 和 DeepLabv2 —阿特鲁卷积(语义分割)

原文:https://towardsdatascience.com/review-deeplabv1-deeplabv2-atrous-convolution-semantic-segmentation-b51c5fbde92d?source=collection_archive---------4-----------------------

在这个故事中, DeepLabv1DeepLabv2 被放在一起回顾,因为它们都使用了阿特鲁卷积全连通条件随机场(CRF) ,除了 DeepLabv2 多了一项技术叫做 Atous 空间金字塔池(ASPP) ,这是与 DeepLabv1 的主要区别。(当然也有其他的区别,比如:DeepLabv2 用 ResNetVGGNet 做实验,而 DeepLabv1 只用 VGGNet 。)

DeepLab Model

上图是 DeepLab 模型架构。首先,输入图像通过使用 atrous 卷积和 ASPP 的网络。然后对网络输出进行双线性插值,并通过全连接 CRF 对结果进行微调,得到最终输出。

DeepLabv1 和 DeepLabv2 已经发表在 2015 ICLR 和 2018 TPAMI 上,分别有大约 400 次和 2000 次引用在我写这个故事的时候。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 阿特鲁卷积
  2. 阿特鲁空间金字塔汇集(ASPP)
  3. 全连通条件随机场
  4. 结果

1。阿特鲁卷积

术语“阿特鲁”确实来源于法语“ à trous ”意思是洞。因此,它也被称为“算法à trous ”和“洞算法”。有些论文还称之为“膨胀卷积”。它通常用于小波变换,现在它被应用于深度学习的卷积中。

下面是 atrous 卷积的等式:

1D Atrous Convolution (r>1: atrous convolution, r=1: standard convolution)

  • 当 r=1 时,就是我们通常使用的标准卷积。
  • 当 r > 1 时,为 atrous 卷积,即卷积过程中对输入样本进行采样的步长。

下图说明了这个想法:

Standard Convolution (Top) Atrous Convolution (Bottom)

阿特鲁斯卷积的思想很简单。上图顶部,是标准卷积。

在图的底部,是阿特鲁斯卷积。我们可以看到,当 rate = 2 时,输入信号是交替采样的。首先,pad=2 意味着我们在左右两边都填充 2 个零。然后,当 rate=2 时,我们每隔 2 个输入对输入信号进行采样以进行卷积。因此,在输出端,我们将有 5 个输出,使输出特征图更大。

如果我们还记得 FCN ,一系列的卷积和池化使得输出的特征图非常小,需要 32 倍的上采样,这是一种激进的上采样。

此外,atrous 卷积允许我们扩大过滤器的视野,以纳入更大的背景。因此,它提供了一种有效的机制来控制视野,并在精确定位(小视野)和上下文同化(大视野)之间找到最佳折衷。

在 DeepLab 中,使用 VGG-16 或 ResNet-101,最后一个池(pool5)或卷积 conv5_1 的步幅分别设置为 1,以避免信号抽取过多。并且使用 rate = 2,使用 atrous 卷积来替换所有后续的卷积层。产量大很多。我们只需要 8 倍上采样来对输出进行上采样。而双线性插值对于 8 倍上采样有相当不错的表现。

2。阿特鲁空间金字塔池(ASPP)

Atrous Spatial Pyramid Pooling (ASPP)

ASPP 实际上是 SPP 的一个老版,其中的概念已经在 SPPNet 中使用。在 ASPP,不同速率的并行 atrous 卷积应用于输入特征图,并融合在一起。

由于同一类别的对象在图像中可能具有不同的比例, ASPP 有助于说明不同的对象比例,这可以提高准确性。

3.全连通条件随机场

双线性插值后,全连接 CRF 应用于网络输出:

Fully Connected CRF

x 是像素的标签分配。P(xi)是像素 I 处的标签分配概率。因此,第一项θi 是对数概率。

对于第二项,θij,它是一个滤波器。= 1 当 xi!= xj。当 xi = xj 时= 0。在括号中,它是两个核的加权和。第一核依赖于像素值差和像素位置差,这就是一种双边滤波器。双边滤波器具有保持边缘的特性。****第二核只依赖像素位置差,是一个高斯滤波器。σ和 w 是通过交叉验证得到的。迭代次数为 10 次。

Top: Score map (input before softmax function), Bottom: belief map (output of softmax function)

使用 10 倍的 CRF,飞机周围那些不同颜色的小区域被平滑掉了。

但是,CRF 是一个后处理过程使得 DeepLabv1 和 DeepLabv2 成为而不是一个端到端的学习框架。而且是在 DeepLabv3 和 DeepLabv3+已经不使用

4.结果

4.1.消融研究

DeepLab-LargeFOV (Left: i.e. only single atrous conv), DeepLab-ASPP (Right, i.e. ASPP)

Results of Each Component Using ResNet-101 in PASCAL VOC 2012 Validation Set

  • 最简单的 ResNet-101 : 68.72%
  • MSC :多刻度输入
  • COCO:COCO 数据集预处理的模型
  • Aug :通过随机缩放输入图像(从 0.5 到 1.5)进行数据扩充
  • LargeFOV :使用单遍 atrous 卷积的 DeepLab
  • ASPP: 使用并行 atrous 卷积的深度实验室
  • CRF :后处理全连接 CRF。

最后得到了 77.69% 。可以看出,MSC、COCO 和 Aug 贡献了从 68.72%到 74.87%的提高,这与 LargeFOV、ASPP 和 CRF 同样重要。

4.2.与最先进方法的比较

PASCAL VOC 2012 Test Set (Leftmost) PASCAL-Context (2nd Left) PASCAL-Person-Part (2nd Right) Cityscape (Rightmost)

也如上测试了四个数据集。结果表明,与最先进的方法相比,DeepLabv2 具有竞争力的结果。

4.3.定性结果

Qualitative Results: PASCAL-Context

Qualitative Results: Cityscape

但 DeepLab 也有一些失败的例子,其中自行车和椅子由多个薄零件组成,如自行车和椅子腿的零件:

Failure Examples

希望以后能覆盖 DeepLabv3 和 DeepLabv3+。

参考

  1. 【2015 ICLR】【DeepLabv1】
    深度卷积网和全连通 CRF 的语义图像分割
  2. 【2018 TPAMI】【deeplabv 2】
    DeepLab:深度卷积网、阿特鲁卷积、全连通 CRFs 的语义图像分割

我的相关评论

[SPPNet][VGGNet][ResNet][FCN]

复习:深度遮罩(实例分段)

原文:https://towardsdatascience.com/review-deepmask-instance-segmentation-30327a072339?source=collection_archive---------5-----------------------

一种卷积神经网络驱动的实例分段建议方法

T 他的时代, DeepMask ,由脸书 AI Research (FAIR) 点评。从 AlexNet 开始,卷积神经网络(CNN)获得了图像分类的高精度,许多 CNN 方法被开发用于其他任务,如对象检测、语义分割和实例分割。DeepMask 是用于实例分割的 CNN 方法。

Semantic Segmentation vs Instance Segmentation

  • 图像分类:对图像内的主要物体类别进行分类。
  • 对象检测:识别对象类别,并使用图像中每个已知对象的边界框定位位置。
  • 语义分割:识别图像中每个已知物体的每个像素的物体类别。标签是类感知的。
  • 实例分割:识别图像中每个已知对象的每个像素的每个对象实例。标签是实例感知的。

与语义分割的一些区别

  • 对实例个体的更多理解。
  • 关于遮挡的推理。
  • 对于计算物体数量等任务至关重要。

与对象检测的一些区别

  • 边界框是一个非常粗糙的对象边界,许多与被检测对象无关的像素也被包含在边界框中。
  • 而非最大抑制(NMS)将抑制遮挡对象或倾斜对象。

因此,实例分段在难度上增加了一个级别!!!

而 DeepMask 是 2015 NIPS 论文,引用 300 多。虽然这是一篇发表于 2015 年的论文,但它是最早使用 CNN 进行实例分割的论文之一。为了了解基于深度学习的实例切分的发展,有必要对其进行研究。( Sik-Ho Tsang @中)

因为可以基于预测的分割掩模生成区域提议,所以也可以执行对象检测任务。

涵盖哪些内容

  1. 模型架构
  2. 联合学习
  3. 全场景推理
  4. 结果

1.模型架构

Model Architecture (Top), Positive Samples (Green, Left Bottom), Negative Samples (Red, Right Bottom)

左下方:阳性样本

k 个阳性样本被赋予标签 yk =1 。要成为阳性样本,需要满足两个标准:

  • 面片包含一个大致位于输入面片中心的对象
  • 物体完全包含在面片中,并在给定的比例范围内。

yk =1 时,地面真实遮罩 mk 对于属于位于图像块中心的单个物体的像素具有正值

右下方:阴性样本

否则,即使物体部分存在,阴性样本也会被赋予标签 yk =-1yk =-1 时,不使用掩膜。

顶层,模型架构:主分支

如上图所示的模型,给定输入图像块 x ,经过 VGGNet 的特征提取后,去除源于 VGGNet 的全连通(FC)层。 VGGNet 中的最后一个 max pooling 层也被删除,因此在分成两路之前的输出是输入的 1/16。例如如上,输入是 224×224 (3 是输入图像的通道数,即 RGB),主分支末端的输出是(224/16)×(224/16) =14×14。(512 是卷积后的特征图个数。)

VGGNet 之后有两条路径:

  • 第一条路径是预测类别不可知的分割掩码,即 fsegm ( x )。
  • 第二条路径是分配一个分数,该分数对应于补丁包含一个对象的可能性,即fs core(x)**。

顶部,第一条路径:预测分段图

先进行 1×1 卷积而不改变特征图的数量,这里进行的是没有降维的非线性映射。之后,执行两个 FC 层。(注意,在这两个 FC 层之间没有 ReLU!)

与语义分割不同,即使存在多个对象,网络也必须输出单个对象的掩码。(就像上图输入图像中央的大象一样。)

最后,生成一个 56×56 的分割图。而一个简单的双线性插值就是将分割图上采样到 224×224

顶部,第二条路径:预测对象得分

2×2 最大池,后跟两个 FC 层。最后,获得一个单值预测对象分数, fscore ( x )。由于正样本是基于上述两个标准给出的, fscore ( x )用于预测输入图像是否满足这两个标准。

2.联合学习

2.1.损失函数

对网络进行训练,共同学习每个位置(I,j)的逐像素分割图fsegm(xk)和预测对象得分fs core(xk)。**损失函数如下所示:

简言之,损失函数是二元逻辑回归损失的和,一个用于分割网络fsegm(xk)的每个位置,一个用于对象分数fs core(xk)**。第一项意味着如果 yk =1,我们仅在分割路径上反向传播误差。

如果 yk =-1,即负样本,第一项变为 0,不会造成损失。只有第二项造成了损失。

为了数据平衡,使用相同数量的阳性和阴性样本。

2.2.其他详细信息

使用 32 的批量。使用预训练的 ImageNet 模型。总共有 75M 个参数。该模型需要大约 5 天在 Nvidia Tesla K40m 上进行训练。

3.全场景推理

3.1.多个位置和规模

推理(测试)时,模型在多个位置密集应用,步长为 16 个像素,从 1/4 到 2 的多个尺度,步长为 2 的平方根。这确保了至少有一个完全包含图像中每个对象的测试图像块。

3.2.精细步幅最大汇集

由于输入测试图像大于训练输入小块尺寸,我们需要一个相应的 2D 评分图作为输出,而不是一个单一的评分值。在评分分支的最后一个最大池层之前使用了一个交织技巧,即over fat中提出的精细步长最大池

简而言之,多最大池是在特征图上完成的。在每次最大汇集之前执行像素移动。

4.结果

4.1.可可女士(盒子和分段遮罩)

80,000 幅图像和总共近 500,000 个分割对象用于训练。2014 年可可小姐的前 5000 张照片用于验证。

Average Recall (AR) Detection Boxes (Left) and Segmentation Masks (Right) on MS COCO Validation Set (AR@n: the AR when n region proposals are generated. AUCx: x is the size of objects)

  • DeepMask20 :只对属于 20 个帕斯卡类别之一的对象进行训练。与 DeepMask 相比,AR 较低,这意味着网络没有推广到看不见的类。(看不到的课分数低。)
  • DeepMask20* :类似于 DeepMask,但评分路径使用原始的 DeepMask。
  • DeepMaskZoom :额外的小尺度提升 AR,但代价是增加了推理时间。
  • DeepMaskFull :预测分割掩膜路径上的两个 FC 层被一个从 512×14×14 特征图直接映射到 56×56 分割图的 FC 层代替。整个架构有超过 300 米的参数。比 DeepMask 略逊一筹,慢很多。

4.2.PASCAL VOC 2007(盒子)

Average Recall (AR) for Detection Boxes on PASCAL VOC 2007 Test Set

  • 基于预测的分割掩模产生区域提议,其可以用作目标检测任务的第一步。
  • 使用深度屏蔽的快速 R-CNN优于使用选择性搜索的原始快速 R-CNN 以及其他最先进的方法。

4.3.推理时间

  • 《可可小姐》中的推理时间是每张图片 1.6s。
  • PASCAL VOC 2007 中的推理时间是每张图片 1.2s。
  • 通过在单个批次中并行化所有秤,推断时间可以进一步下降约 30%。

4.4.定性结果

DeepMask proposals with highest IoU to the ground truth on selected images from COCO. Missed objects (no matching proposals with IoU > 0.5) are marked with a red outline.

More Results from COCO. Missed objects (no matching proposals with IoU > 0.5) are marked with a red outline.

DeepMask 已经更新,在 GitHubVGGNet 主干被 ResNet 取代。

继 DeepMask 之后,FAIR 还发明了 SharpMask。希望我以后也能报道它。

参考

【2015 NIPS】【deep mask】
[学习分割对象候选](http://Learning to Segment Object Candidates)

我的相关评论

)(我)(们)(都)(不)(想)(到)(这)(些)(人)(,)(我)(们)(都)(不)(想)(要)(到)(这)(些)(人)(,)(但)(是)(这)(些)(人)(还)(不)(想)(到)(这)(些)(人)(,)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(们)(就)(想)(到)(了)(这)(些)(人)(们)(,)(我)(们)(们)(都)(不)(想)(要)(到)(这)(些)(人)(,)(但)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(里)(来)(。 )(我)(们)(都)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(。

物体检测 过食R-CNN快 R-CNN快 R-CNNDeepID-NetR-FCNyolo v1SSDyolo v2/yolo 9000

语义切分
[FCN][de convnet][deeplabv 1&deeplabv 2][parse net][dilated net][PSPNet]

生物医学图像分割 cumed vision 1cumed vision 2/DCANU-NetCFS-FCN

综述:DenseNet 密集卷积网络(图像分类)

原文:https://towardsdatascience.com/review-densenet-image-classification-b6631a8ef803?source=collection_archive---------2-----------------------

在这个故事中, DenseNet(密集卷积网络)进行了回顾。这是在 2017 CVPR 获得最佳论文奖的论文,引用超过 2000 次。它是由康维尔大学、清华大学和脸书人工智能研究所(FAIR)联合发明的。( Sik-Ho Tsang @中)

密集连接,与 ResNet预激活 ResNet 相比,参数少,精度高。那么,让我们来看看它是如何工作的。

涵盖哪些内容

  1. 密集街区
  2. DenseNet 架构
  3. dense net 的优势
  4. CIFAR & SVHN 小规模数据集结果
  5. ImageNet 大规模数据集结果
  6. 特征复用的进一步分析

1。密集块

Standard ConvNet Concept

标准 ConvNet 中,输入图像经过多重卷积,获得高层特征。

ResNet Concept

ResNet中,提出了身份映射来促进梯度传播。使用元素加法。它可以被看作是具有从一个 ResNet 模块传递到另一个 ResNet 模块的状态的算法。

One Dense Block in DenseNet

DenseNet 中,每一层从所有前面的层获得额外的输入,并将自己的特征映射传递给所有后面的层。使用串联每一层都从所有前面的层接收“集体知识”

Dense Block in DenseNet with Growth Rate k

由于每一层都从所有前面的层接收特征图,网络可以更细更紧凑,即通道数量可以更少。增长率 k 是每层增加的通道数。

因此,它具有较高的计算效率和存储效率。下图显示了正向传播过程中串联的概念:

Concatenation during Forward Propagation

2. DenseNet 架构

2.1.基本 DenseNet 成分层

Composition Layer

对于每一个构图层,预激活 批范数(BN) 和 ReLU,然后 3×3 Convk 通道的输出特征图完成,比如变换 x 0, x 1, x 2, x 3 到 x 4。这是来自 的创意,预激活 ResNet

2.2.DenseNet-B(瓶颈层)

DenseNet-B

为了降低模型的复杂度和尺寸, BN-ReLU-1×1 ConvBN-ReLU-3×3 Conv 之前完成。

2.4.具有过渡层的多个密集块

Multiple Dense Blocks

1×1 Conv,然后是 2×2 平均池,用作两个相邻密集区块之间的过渡层。

在密集块中,要素地图的大小是相同的,因此可以很容易地将它们连接在一起。

在最后一个密集块的末尾,执行全局平均池化,然后附加 softmax 分类器。

2.3.DenseNet-BC(进一步压缩)

如果一个密集块包含 m 个特征图,过渡层生成 θm 个输出特征图,其中 0 < θ ≤1 称为压缩因子。

θ =1 时,跨过渡层的特征映射的数量保持不变。 θ <为 1 的 DenseNet 称为 DenseNet-C ,实验中 θ =0.5

当使用**θ<1 的瓶颈层和过渡层时**,该型号称为 DenseNet-BC

最后训练有/无 B/C 和不同 Lk 生长率的 DenseNets

3.dense net 的优势

3.1.强梯度流

Implicit “Deep Supervision”

误差信号可以容易地更直接地传播到更早的层。这是一种隐式深度监督,因为较早的层可以从最终分类层获得直接监督。

3.2.参数和计算效率

Number of Parameters for ResNet and DenseNet

对于每一层, ResNet 中的参数个数与 C ×C 成正比,而 DenseNet 中的参数个数与 l × k × k 成正比。

由于 k < < C ,DenseNet 的尺寸比 ResNet 小很多。

3.3.更加多样化的功能

More Diversified Features in DenseNet

由于 DenseNet 中的每一层都接收所有前面的层作为输入,因此更多样化的特性和模式更丰富。

3.4.保持低复杂性特征

Standard ConvNet

在标准的 ConvNet 中,分类器使用最复杂的特征。

DenseNet

在 DenseNet 中,分类器使用所有复杂级别的特征。它倾向于给出更平滑的决策边界。也解释了为什么 DenseNet 在训练数据不足的情况下表现良好。

4. CIFAR & SVHN 小规模数据集结果

4.1.CIFAR-10

CIFAR-10 Results

预激活 ResNet 用于详细比较。

使用数据扩充(C10+),测试误差:

  • 小型 ResNet-110: 6.41%
  • 大尺寸 ResNet-1001(10.2 米参数):4.62%
  • 最先进的(SOTA) 4.2%
  • 小型 DenseNet-BC ( L =100, k =12)(仅 0.8M 参数):4.5%
  • 大尺寸 DenseNet ( L =250, k =24): 3.6%

无数据扩充(C10),测试误差:

  • 小型 ResNet-110: 11.26%
  • 大尺寸 ResNet-1001(10.2 米参数):10.56%
  • 最先进的(SOTA) 7.3%
  • 小型 DenseNet-BC ( L =100, k =12)(仅 0.8M 参数):5.9%
  • 大尺寸 DenseNet ( L =250, k =24): 4.2%

严重的过拟合出现在 预激活 ResNet 中,而 DenseNet 在训练数据不足时表现良好,因为 DenseNet 使用所有复杂度级别的特征。

C10+: Different DenseNet Variants (Left), DenseNet vs ResNet (Middle), Training and Testing Curves of DenseNet and ResNet (Right)

: DenseNet-BC 获得最佳结果。

中间 : 预激活 ResNet 已经比Alex netVGGNet 得到的参数少,DenseNet-BC ( k =12)在相同测试误差下比 预激活 ResNet 得到的参数少 3 倍。**

****右:参数为 0.8 的 DenseNet-BC-100 与参数为 10.2M 的 预激活 ResNet-1001 测试误差相近。

4.2.西发尔-100

CIFAR-100 的类似趋势如下:

CIFAR-100 Results

4.3.详细结果

Detailed Results, + means data augmentation

SVHN 是街景门牌号码数据集。蓝色意味着最好的结果。DenseNet-BC 不能获得比基本 DenseNet 更好的结果,作者认为 SVHN 是一个相对容易的任务,并且非常深的模型可能会过度适应训练集。

5.ImageNet 大规模数据集结果

Different DenseNet Top-1 and Top-5 Error Rates with Single-Crop (10-Crop) Results

ImageNet Validation Set Results Compared with Original ResNet

中实现的原始 ResNet 该链接用于详细比较。

****左:参数为 20M 的 DenseNet-201 与参数超过 40M 的 ResNet-101 产生相似的验证误差。

****右:类似的计算次数趋势(GFLOPs)

**底:dense net-264(k= 48)得到了 20.27% Top-1 误差和 5.17% Top-5 误差的最好结果。

6.特征重用的进一步分析

Heat map on the average absolute weights of how Target layer (l) reuses the source layer (s)**

  • 由非常早期的层提取的特征被遍及同一密集块的更深的层直接使用。
  • 过渡层的权重也会将其权重分布到所有前面的层。
  • 第二和第三密集块内的层一致地将最小权重分配给过渡层的输出。(第一排)
  • 在最终分类层,权重似乎是对最终特征地图的集中。一些更高级的功能在网络后期产生。

作者还发表了多尺度 DenseNet。希望我以后也能报道它。

参考

【2017 CVPR】【dense net】
密集连接的卷积网络

我的相关评论

[LeNet][AlexNet][ZFNet][VGGNet][SPPNet][PReLU-Net][Google Net/Inception-v1][BN-Inception/Inception-v2][Inception-v3][Inception-v4

综述:扩展网络—扩展卷积(语义分割)

原文:https://towardsdatascience.com/review-dilated-convolution-semantic-segmentation-9d5a5bd768f5?source=collection_archive---------2-----------------------

又名“ atrous 卷积”、“算法à trous ”和“空洞算法

T 他的时代,膨胀卷积,来自普林斯顿大学和英特尔实验室,简要回顾。扩展卷积的思想来源于小波分解。又称为“ atrous 卷积”、“ algorithme à trous ”和“ hole algorithm ”。因此,如果我们可以将过去的任何想法转化为深度学习框架,它们仍然是有用的。

而这个膨胀的卷积在我写这个故事的时候已经发表在 2016 ICLR 上有超过 1000 次引用。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 扩张回旋
  2. 多尺度上下文聚合(上下文模块)
  3. 结果

1.扩张卷积

Standard Convolution (Left), Dilated Convolution (Right)

左边的是标准卷积。右边的是扩张的回旋。我们可以看到在求和的时候,就是 s+ l t=p 我们在卷积的时候会跳过一些点。

l =1 时,为标准卷积。

l1 时,为扩张卷积。

Standard Convolution (l=1)

Dilated Convolution (l=2)

以上举例说明了当 l =2 时展开卷积的例子。我们可以看到感受野比标准感受野大

l=1 (left), l=2 (Middle), l=4 (Right)

上图显示了更多关于感受野的例子。

2。多尺度上下文聚合(上下文模块)

基于扩展卷积构建上下文模块如下:

The Basic Context Module and The Large Context Module

上下文模块有 7 层,应用具有不同膨胀因子的 3×3 卷积。扩容 1,1,2,4,8,16,1。

最后一个是 1×1 卷积,用于将通道数映射为与输入通道数相同。因此,输入和输出有相同数量的通道。并且可以插入不同种类的卷积神经网络。

基本上下文模块在整个模块中只有1 个通道(1C ),而大型上下文模块增加通道数,从 1C 输入到第 7 层的 32C

3.结果

3.1.帕斯卡 VOC 2012

VGG-16 作为前端模块。最后两个池层和跨层被完全移除,并插入了上下文模块。中间特征图的填充也被移除。作者仅填充宽度为 33 的输入要素地图。在我们的实验中,零填充和反射填充产生了类似的结果。此外,使用考虑输入和输出通道数量的权重初始化来代替标准随机初始化。

PASCAL VOC 2012 Test Set

通过对比原作者训练的公开模型,在测试集上,扩张卷积比【FCN-8s】DeepLabv1 均高出约 5 个百分点。

可以获得 67.6%的平均 IoU。

PASCAL VOC 2012 Validation Set

通过对来自 Microsoft COCO 数据集的额外图像进行训练,对扩张卷积本身进行消融研究,如上所示。

  • 前端:前端模块
  • 基本:基本上下文模块
  • :大上下文模块
  • CRF :使用deeplab v1DeepLabv2 中条件随机字段的后处理步骤
  • RNN :通过递归神经网络使用条件随机场的后处理步骤

我们可以看到,膨胀卷积(基本或大)总是可以改善结果,并且不与任何其他后处理步骤重叠。

并且可以获得 73.9%的平均 IoU。

PASCAL VOC 2012 Test Set

上表中的前端模块也是通过对来自微软 COCO 数据集的附加图像进行训练而获得的。使用通用报告格式-RNN(即上表中的 RNN),平均 IoU 为 75.3%。

3.2.定性结果

PASCAL VOC 2012

全部采用 VGG-16 进行特征提取,使用扩张卷积在分割结果上有更好的质量

PASCAL VOC 2012

用条件随机场 RNN 作为后处理步骤,得到了稍好的结果。但是 CRF-RNN 使这个过程不是一个端到端的学习。

Failure Cases

一些失败案例如上图,当物体被遮挡时,分割出错。

附录中尝试了不同的数据集,即 CamVid、KITTI 和 Cityscapes,请随意阅读本文。他们还发表了扩张的残余网络。希望以后能覆盖。😃

参考

【2016 ICLR】【扩张卷积】
扩张卷积的多尺度上下文聚合

我的相关评论

[VGGNet][FCN][DeconvNet][deep lab v1&deep lab v2]

综述:DSSD —解卷积单次探测器(目标探测)

原文:https://towardsdatascience.com/review-dssd-deconvolutional-single-shot-detector-object-detection-d4821a2bbeb5?source=collection_archive---------4-----------------------

反卷积层:引入额外的大规模背景,提高小对象的准确性

T 他的时代, DSSD(反卷积单次检测器)被回顾。DSSD,用去进化路径,改进了之前的 SSD 。是 2017 arXiv 中的一篇技术报告,引用超过 100 次。( Sik-Ho Tsang @ Medium)。

  • 逐步反卷积放大特征图
  • 来自卷积路径和反卷积路径的特征组合

涵盖哪些内容

  1. 整体架构
  2. 反卷积模块
  3. 预测模块
  4. 一些训练细节
  5. 结果

1。整体架构

SSD (Top) DSSD (Bottom)

  • 白色转换:可以是 VGGNet ResNet 骨干进行特征提取
  • 蓝色转换率:是原来的 SSD 部分,涉及到去掉原来的 VGGNet / ResNet 的全连通层,使用萎缩/扩张卷积(源自小波,由 DeepLabDilatedNet 使用)添加 conv 层。(有兴趣请访问 SSD 。)
  • 剩余转换:由反卷积模块和预测模块组成,后面会详细介绍。

2.去卷积模块

Deconvolution Module

  • 反卷积路径上的那些特征图通过 Deconv2×2 然后 Conv3×3+ BN 进行上采样。
  • 另一方面,对应的相同大小的特征图具有 con v3×3+BN+ReLU+con v3×3+BN
  • 然后,它们按元素相乘(Eltw 乘积),并进行 ReLU,然后传递给预测模块。

3。预测模块

Various Prediction Module

  • 测试了各种预测模块。
  • (a):是 SSD 中使用的最基本的一个,直接预测对象类,进行包围盒回归。
  • (b):在特征图上执行 Conv1×1 的附加集合,以增加维度。还有一个与元素相加的 skip 连接。
  • (c):除了在跳过连接路径上执行一个额外的 Conv1×1 之外,它是(b)的一个。
  • (d):两个(c)是级联的。

4.一些训练细节

两阶段训练

  • 使用 ImageNet 预训练模型训练有素的 SSD 。
  • 对于第一阶段,仅训练反卷积侧。
  • 第二阶段,对整个网络进行微调。

其他

  • 还使用了广泛的数据扩充,包括随机裁剪、翻转和随机光度失真。
  • 在使用 K-均值聚类进行分析之后,添加纵横比为 1.6 的先前盒子,即使用{1.6,2.0,3.0}。

基于以上所述,在 PASCAL VOC 2007 上进行消融研究:

Results on PASCAL VOC 2007

  • SSD 321 :原装 SSD 带输入 321×321,76.4% mAP。
  • SSD 321 + PM(c) :原装 SSD 使用预测模块(c),77.1 % mAP,比使用 PM (b)和 PM (d)的要好。
  • SSD 321+PM(c)+DM(Eltw-prod):DM 表示解卷积模块,因此,这是 DSSD 使用 PM(c)和用于特征组合的元素式产品,78.6% mAP。它比使用元素相加的方法要好一点。
  • SSD 321+PM(c)+DM(Eltw-prod)+Stage 2:采用两阶段训练,成绩下降。

5.结果

5.1.帕斯卡 VOC 2007

Results on PASCAL VOC 2007 Test

SSD 和 DSSD 在 2007 trainval 和 2012 trainval 的联合上接受培训。

  • SSD300* 和 SSD512* (表示使用了新的数据扩充技巧。):凭借,最初的固态硬盘已经超越了除 R-FCN 之外的其他最先进的方法。
  • SSD 321SSD 513 :以 ResNet 为骨干,性能已经和 SSD300和 SSD512差不多。
  • DSSD 321DSSD 513 :通过反卷积路径,它们分别优于 SSD 321 和 SSD 513。
  • 特别是, DSSD513 的表现优于R-FCN

5.2.帕斯卡 VOC 2012

Results on PASCAL VOC 2012 Test

VOC 2007 trainval+测试和 2012 trainval 用于培训。既然发现两阶段训练没用,这里就用一阶段训练。

  • DSSD 513 以 80.0%的 mAP 表现优于其他品种。并且不使用 COCO 数据集的额外训练数据进行训练。

5.3.可可女士

Results on MS COCO Test

还是那句话,没有两阶段训练。

  • SSD300* 已经比更快 R-CNN 和 ION。
  • DSSD321 在小物体上的 AP 更好,7.4%相比 SSD321 只有 6.2%。
  • 对于更大的车型, DSSD513 获得 33.2%的 mAP,比 29.9% mAP 的 R-FCN 要好。它已经和更快的 R-CNN++取得了竞争结果。(+++表示它也使用 VOC2007 和 VOC2012 进行培训。)

5.4.推理时间

为了在测试过程中简化网络, BN 被移除,并与 conv 合并,如下所示:

简而言之,他们试图将 BN 效应合并到 conv 层的权重和偏差计算中,从而简化网络。这将速度提高了 1.2 到 1.5 倍,并将内存减少了三倍。

Speed & Accuracy on PASCAL VOC 2007 Test

  • SSD 513R-FCN (9 FPS)相比,速度(8.7 fps)和精度差不多。去除 BN 层并与 conv 层合并,得到 11.0 fps 更快。
  • DSSD513 比 R-FCN 精度更高,但速度稍慢。
  • DSSD321 比 R-FCN 精度低,但速度更快。

5.5.定性结果

SSD (Left) DSSD (Right)

由于输入尺寸较小, SSD 在小对象上效果不佳。随着反卷积路径,DSSD 显示出明显的改善。

参考

【2017 arXiv】【DSSD】
DSSD:解卷积单粒子探测器

我的相关评论

)(我)(们)(都)(不)(想)(到)(这)(些)(人)(,)(我)(们)(都)(不)(想)(要)(到)(这)(些)(人)(,)(但)(是)(这)(些)(人)(还)(不)(想)(到)(这)(些)(人)(,)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(们)(就)(想)(到)(了)(这)(些)(人)(们)(,)(我)(们)(们)(都)(不)(想)(要)(到)(这)(些)(人)(,)(但)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(里)(来)(。 )(我)(们)(都)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(。

物体检测 过食R-CNN快 R-CNN快 R-CNNDeepID-NetR-FCNyolo v1SSDyolo v2/yolo 9000

语义切分
[FCN][de convnet][deeplabv 1&deeplabv 2][parse net][dilated net][PSPNet]

回顾:更快的 R-CNN(目标检测)

原文:https://towardsdatascience.com/review-faster-r-cnn-object-detection-f5685cb30202?source=collection_archive---------1-----------------------

在这个故事中,更快的 R-CNN【1–2】被回顾。在之前的快速 R-CNN [3]和 R-CNN [4]中,区域建议是通过选择性搜索(SS) [5]而不是使用卷积神经网络(CNN)来生成的。

在更快的 R-CNN[1–2],中,区域提案生成和异议检测任务都由同一个 conv 网络完成。采用这样的设计,物体检测速度更快。

为了更好地了解深度学习对象检测,作为一系列的对象检测方法,如果有足够的时间,最好按照顺序阅读 R-CNN、Fast R-CNN 和 Fast R-CNN,以了解对象检测的演变,特别是为什么区域提议网络(RPN)存在于该方法中。如果有兴趣,我建议看看我对他们的评论。

由于更快的 R-CNN 是一种最先进的方法,当我写这个故事时,它被发表为 2015 NIPS 论文和 2017 TPAMI 论文,分别有超过 4000 和 800 篇引用****。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 地区提案网络
  2. 检测网络
  3. 四步交替训练
  4. 消融研究
  5. 检测结果

1.区域提案网络

简而言之,R-CNN [4]和快速 R-CNN [3]首先通过选择性搜索(SS) [5]生成区域建议,然后使用基于 CNN 的网络对对象类别进行分类并检测边界框。(主要区别在于 R-CNN 在像素级将区域建议输入到 CNN 中用于检测,而快速 R-CNN 在特征映射级输入区域建议。)因此,在 R-CNN [4]和快速 R-CNN [3]中,区域提议方法/网络(即 SS)和检测网络是解耦的。****

脱钩不是一个好主意。比如说 SS 有假阴性的时候,这个误差会直接伤害到检测网络。最好将它们耦合在一起,使它们相互关联。

在更快的 R-CNN[1–2]中,使用 SS [5]的 RPN 被使用 CNN 的 RPN 取代。并且该 CNN 与检测网络共享。这个 CNN 可以是论文中的 ZFNet 或者 VGGNet。因此,整个网络如下:

Faster R-CNN

  1. 首先,图片经过 conv 层和特征地图提取。
  2. 然后在 RPN 中为特征图上的每个位置使用一个滑动窗口
  3. 对于每个位置,使用 k (k=9)个锚定框(128、256 和 512 的 3 个比例,以及 1:1、1:2、2:1** 的 3 个纵横比)来生成区域提议。**
  4. 一个 cls 层输出 2k 分数对于 k 盒子是否有对象
  5. 一个 reg 层输出k盒子的坐标(盒子中心坐标,宽度和高度)4k 。
  6. 一张大小为W×H 的特征图,总共有 WHk 个主播。

The Output of RPN

128、256 和 512 三种比例以及 1:1、1:2 和 2:1 三种纵横比的平均建议尺寸为:

Average Proposal Sizes

损失函数是:

RPN Loss Function

第一项是 2 类(有无对象)上的分类损失。第二项是仅当存在对象(即 p_i =1)时边界框的回归损失。*

因此, RPN 网络就是预检查哪个位置包含对象。并且相应的位置和边界框将传递到检测网络用于检测对象类别并返回该对象的边界框。

由于区域可以彼此高度重叠,所以使用非最大抑制(NMS)来将提议的数量从大约 6000 减少到 N (N=300)。

2。检测网络

除了 RPN,其余部分与快速 R-CNN 类似。首先执行 ROI 合并。然后汇集的区域通过 CNN 和两个 FC 分支,用于类 softmax 和边界框回归器。(如果有兴趣,请阅读我对 Fast R-CNN 的评论。)

Fast R-CNN Detection Network

3.四步交替训练****

由于 conv 层被共享以提取最终具有不同输出的特征图,因此,训练过程非常不同:

  1. 用 imagenet 预训练模型训练(微调)RPN。
  2. 使用 imagenet 预训练模型训练(微调)单独的检测网络。(Conv 图层尚未共享)
  3. 使用检测器网络来初始化 PRN 训练,修复共享的 conv 层,仅微调 RPN 的独特层。
  4. 保持 conv 层固定,微调探测器网络的独特层。

4。消融研究

4.1.区域提案

如上所述,利用非共享 conv 层(在交替训练中只有前 2 步),获得了 58.7%的 mAP。共享 conv 图层,获得 59.9%的地图。并且它优于现有技术的 SS 和 EB。****

4.2 比例和比率

****在 3 个尺度和 3 个比例的情况下,获得了 69.9%的地图,与 3 个尺度和 1 个比例的地图相比只有很小的改进。但是仍然使用 3 个刻度和 3 个比率。

损失函数中的 4.3 λ

λ = 10 达到最佳效果。

5。检测结果

5.1 帕斯卡 VOC 2007

Detailed Results

Overall Results

通过使用 COCO、VOC 2007 (trainval)和 VOC 2012 (trainval)数据集的训练数据,获得了 78.8%的 mAP。

5.2 帕斯卡 VOC 2012

Detailed Results

Overall Results

利用使用 COCO、VOC 2007 (trainval+test)和 VOC 2012 (trainval)数据集的训练数据,获得了 75.9%的 mAP。

5.3 可可女士

Overall Results

使用 COCO 训练集进行训练,用 IoU @ 0.5 获得 42.1%的 mAP。当 IoU 从 0.5 到 0.95,步长为 0.05 时,可以获得 21.5%的 mAP。

5.4 检测时间

Detection Time

用 SS 做 RPN,VGGNet 做检测网络:0.5 fps / 1830ms
VGGNet 做 RPN 和检测网络 : 5fps / 198ms
ZFNet 做 RPN 和检测网络 : 17fps / 59ms
比 SS 快很多。

5.5.一些例子

VOC 2007

参考

  1. [2015 NIPS][更快的 R-CNN]
    更快的 R-CNN:利用区域提议网络实现实时对象检测
  2. 【2017 TPAMI】【更快的 R-CNN】
    更快的 R-CNN:利用区域提议网络实现实时对象检测
  3. 【2015 ICCV】【快速 R-CNN】
    快速 R-CNN
  4. 【2014 CVPR】【R-CNN】
    丰富的特征层次,用于精确的对象检测和语义分割
  5. 【2013 IJCV】【选择性搜索】
    选择性搜索对象识别

我的评论

  1. 回顾:快速 R-CNN(物体检测)
  2. 回顾:R-CNN(物体检测)

综述:FCN —完全卷积网络(语义分段)

原文:https://towardsdatascience.com/review-fcn-semantic-segmentation-eb8c9b50d2d1?source=collection_archive---------4-----------------------

在这个故事中,完全卷积网络(FCN)对语义分割进行了简要回顾。与分类和检测任务相比,分割是一项更加困难的任务。

  • 图像分类:对图像中的物体进行分类(识别出物体类别)。
  • 物体检测:用包围物体的包围盒对图像内的物体进行分类和检测。这意味着我们还需要知道每个对象的类、位置和大小。
  • 语义分割:对图像中的每个像素进行对象分类。这意味着每个像素都有一个标签。

语义分割的一个例子如下:

An example of Semantic Segmentation

Original Image (Leftmost), Ground Truth Label Map (2nd Left), Predicted Label Map (2nd Right), Overlap Image and Predicted Label (Rightmost)

在我写这个故事的时候,它已经发表在2015 CVPR【1】和2017 TPAMI【2】上,引用次数超过 6000 次。因此,它也是使用 FCN 进行语义分割的最基本的论文之一。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 从图像分类到语义分割
  2. 通过去卷积进行上采样
  3. 定影输出
  4. 结果

1。从图像分类到语义分割

在分类中,传统上,输入图像被缩小并经过卷积层和全连接(FC)层,并输出输入图像的一个预测标签,如下:

Classification

假设我们将 FC 层变成 1×1 卷积层:

All layers are convolutional layers

如果图像没有缩小,输出将不会是单个标签。相反,输出的大小小于输入图像(由于最大池化):

All layers are convolutional layers

如果我们对上面的输出进行上采样,那么我们可以如下计算逐像素输出(标签映射):

Upsampling at the last step

Feature Map / Filter Number Along Layers

2。通过去卷积进行上采样

卷积是使输出变小的过程。因此,反卷积这个名称来自于我们希望通过上采样来获得更大的输出。(但名字,反卷积,被曲解为卷积的逆过程,其实不是。)又叫,上卷积,转置卷积。当使用分数步距时,也称为分数步距卷积

Upsampling Via Deconvolution (Blue: Input, Green: Output)

3.融合输出

经过如下 conv7 后,输出尺寸较小,则进行 32 倍上采样,使输出具有与输入图像相同的尺寸。但也让输出标签图粗糙。它叫做 FCN-32s :

FCN-32s

这是因为,深入时可以获得深层特征,深入时也会丢失空间位置信息。这意味着来自较浅层的输出具有更多的位置信息。如果我们把两者结合起来,我们可以提高结果。

为了合并,我们融合输出(通过元素相加):

Fusing for FCN-16s and FCN-8s

FCN-16s:pool 5 的输出经过 2 倍上采样,与 pool4 融合,进行 16 倍上采样。与上图中 FCN-8s 类似的操作。

Comparison with different FCNs

由于丢失了位置信息,FCN-32s 的结果非常粗略,而 FCN-8s 的结果最好。

这种融合操作实际上就像 AlexNet、VGGNet 和 GoogLeNet 中使用的 boosting / ensemble 技术一样,他们通过多个模型添加结果,使预测更加准确。但在这种情况下,它是针对每个像素完成的,并且它们是从模型内不同层的结果添加的。

4.结果

Pascal VOC 2011 dataset (Left), NYUDv2 Dataset (Middle), SIFT Flow Dataset (Right)

  • FCN-8s 是 2011 年帕斯卡 VOC 的最佳产品。
  • FCN-16s 是 NYUDv2 中最好的。
  • FCN-16s 是最好的筛流。

Visualized Results Compared with [Ref 15]

第四行显示了一个失败案例:网络将船上的救生衣视为人。

希望以后能多复习一下语义切分的深度学习技术。

参考

  1. 【2015 CVPR】【FCN】
    用于语义分割的全卷积网络
  2. 【2017 TPAMI】【FCN】
    用于语义分割的全卷积网络

复习:FSRCNN(超分辨率)

原文:https://towardsdatascience.com/review-fsrcnn-super-resolution-80ca2ee14da4?source=collection_archive---------1-----------------------

CUHK 的《他的时代》、 FSRCNN 被评论。本文提出了一种实时超分辨率方法快速超分辨率卷积神经网络(FSRCNN) 在我写这个故事的时候,已经在 2016 ECCV 发表了近 300 次引用。( Sik-Ho Tsang @中)

FSRCNN 具有相对较浅的网络,这使得我们更容易了解每个组件的效果。如下图所示,它比以前的 SRCNN 速度更快,重建图像质量更好。

From SRCNN to FSRCNN

通过比较 SRCNN 和 FSRCNN-s,fsr CNN-s(fsr CNN 的小模型尺寸版本)具有更好的 PSNR(图像质量)和更短的运行时间,其中获得了 43.5 fps。

通过比较 SRCNN-Ex(一种更好的 SRCNN)和 FSRCNN,FSRCNN 具有更好的 PSNR(图像质量)和更短的运行时间,其中获得了 16.4 fps。

那么,让我们看看它是如何实现这一点的。

涵盖哪些内容

  1. 简要回顾 SRCNN
  2. FSRCNN 网络架构
  3. 1×1 卷积用于缩小和扩展的说明
  4. 非线性映射中多重 3×3 卷积的解释
  5. 消融研究
  6. 结果

Network Architecture: SRCNN (Top) and FSRCNN (Bottom)

上图显示了 SRCNN 和 f SRCNN 的网络架构。图中, Conv(f,n,c) 表示 n 个滤波器c 个输入通道数f×f 滤波器大小的卷积。

1。简要回顾 SRCNN

在 SRCNN 中,步骤如下:

  1. 首先进行双三次插值,以向上采样到所需的分辨率。
  2. 然后进行 9×9,1×1,5×5 卷积以提高图像质量。对于 1×1 conv,其被声称用于低分辨率(LR)图像向量和高分辨率(HR)图像向量的非线性映射。

计算复杂度为:

其中它与 HR 图像的尺寸 SHR 成线性比例。HR 图像越大,复杂度越高。

2. FSRCNN 网络架构

在 FSRCNN 中,涉及如图所示的具有更多卷积的 5 个主要步骤:

  1. 特征提取:将之前 SRCNN 中的双三次插值替换为 5×5 conv。
  2. 收缩 : 1×1 conv,将特征图的数量从 d 减少到 s,其中 s<d
  3. 非线性映射:用多个 3×3 层代替单个宽层
  4. 扩展 : 1×1 conv,将特征地图的数量从 s 增加到 d
  5. 反卷积 : 9×9 滤波器用于重建 HR 图像。

上面的整体结构称为 FSRCNN(d,s,m)。计算复杂度是:

其中它与 LR 图像的大小 SLR 成线性比例,SLR 远低于 SRCNN。

PReLU 用作激活功能。PReLU 是有参数泄漏 ReLU 的,号称比 ReLU 好。(如果感兴趣,也请阅读我的 PReLU 评论。)

成本函数就是标准均方差(MSE):

3.1×1 卷积在伸缩中的应用

假设我们需要执行 5×5 卷积而不使用 1×1 卷积,如下所示:

Without the Use of 1×1 Convolution

运算次数=(14×14×48)×(5×5×480)= 112.9 米

使用 1×1 卷积:

With the Use of 1×1 Convolution

1×1 的运算次数=(14×14×16)×(1×1×480)= 1.5M
5×5 的运算次数=(14×14×48)×(5×5×16)= 3.8M

总运算次数= 1.5M + 3.8M = 5.3M
比 112.9M 小很多!!!!!!!!!!!!!!!

网络中的网络(NIN)建议 1×1 conv 引入更多非线性并提高性能 而 GoogLeNet 建议 1×1 conv 有助于在保持性能的同时减小模型尺寸。如果有兴趣,请阅读我的 GoogLeNet 评论。)

因此,在两个卷积之间使用 1×1 来减少连接(参数)的数量。通过减少参数,我们只需要更少的乘法和加法运算,最终加快网络速度。这就是为什么 FSRCNN 比 SRCNN 快。

4。非线性映射中多重 3×3 卷积的解释

2 layers of 3×3 filters already covered the 5×5 area

通过使用 2 层 3×3 的滤波器,实际上已经覆盖了 5×5 的区域,并且参数数量更少,如上图所示。

通过使用 1 层 5×5 滤波器,参数数量= 5 ×5=25 通过使用 2 层 3×3 滤波器,参数数量= 3×3+3×3=18
参数数量减少 28%

需要学习的参数越少,越有利于更快的收敛减少过拟合问题

这个问题已经在 VGGNet 中解决了。(如果有兴趣,请阅读我的 VGGNet 评论。)

5。消融研究

Ablation Study of Each Step

  • Sr CNN-Ex:Sr CNN 的更好版本,参数57184
  • 过渡状态 1 :使用 Deconv,参数 58976,获得更高的 PSNR。
  • 过渡状态 2 :中间使用更多的 convs,参数 17088,获得更高的 PSNR。
  • FSRCNN (56,12,4) :更小的滤波器尺寸和更少的滤波器数目,用 12464 个参数,获得更高的 PSNR。这种改进是由于需要训练的参数更少,更容易收敛。

这表明每个组成部分都有贡献。

Study of m, s, d

m 越高(m=4),PSNR 越高。

当 m=4,d=56,s=12 时,它在 HR 图像质量(33.16dB)和模型复杂度(12464 个参数)之间具有较好的折衷。

最后我们得到了 FSRCNN: FSRCNN (56,12,4)。
还有一个更小的版本, FSRCNN-s: FSRCNN (32,5,1)

6.结果

  • 使用 91-影像数据集在放大因子 3 下从头训练网络,然后仅通过在放大因子 2 和 4 下添加 General-100 数据集来微调反卷积图层。
  • 缩放数据:0.9,0.8,0.7,0.6,旋转 90,180,270 度。

All trained on 91-image dataset.

FSRCNN and FSRCNN-s are trained on 91-image and general-100 dataset.

从上面的结果来看,FSRCNN 和 FSRCNN-s 对于放大因子 2 和 3 工作良好。但是对于放大因子 4,FSRCNN 和 FSRCNN-s 比 SCN 稍差。

Lenna image with upscaling factor 3

Butterfly image with upscaling factor 3

从上面的图中,我们可以看到 FSRCNN 有更清晰的图像。

在本文中,使用这样的浅层网络,我们可以了解每个组件或技术的效果,例如 1×1 卷积和多个 3×3 卷积。

参考

  1. 【2016 ECCV】【fsr CNN】
    加速超分辨率卷积神经网络

我的评论

[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]

回顾:Inception-v4——从 GoogLeNet 发展而来,与 ResNet Idea(图像分类)合并

原文:https://towardsdatascience.com/review-inception-v4-evolved-from-googlenet-merged-with-resnet-idea-image-classification-5e8c339d18bc?source=collection_archive---------5-----------------------

在这个故事中,谷歌的Inception-v4【1】被评论。从 GoogLeNet / Inception-v1 演化而来的 Inception-v4,比 Inception-v3 有一个更统一的简化架构和更多的 Inception 模块。****

从下图中,我们可以看到从 v1 到 v4 的 top-1 精度。而且 Inception-v4 比 ResNet 好。

Top-1 Accuracy against Number of Operations (Size is the number of parameters)

有剩余连接的初始网络,微软 ResNet 提出的一个想法,优于同样昂贵的没有剩余连接的初始网络。

利用 1 个初始 v4 和 3 个残差网络的集成,在 ILSVRC 分类任务中可以实现 3.08%的误差。这是一篇 2017 AAAI 的论文,在我写这篇文章的时候有超过 1000 次引用。(曾植和 @中)

涵盖哪些内容

  1. 从 Inception-v1 到 Inception-v3 的简要概述
  2. 盗梦空间-v4
  3. 盗梦空间-ResNet-v1
  4. 盗梦空间-ResNet-v2
  5. 与最先进方法的比较

1.从初始版本 1 到初始版本 3 的简要概述

在开始谈论 Inception-v4 之前,让我们先回顾一下从 v1 到 v3。

1.1.Inception-v1/Google net[2]:Inception 模块

Inception Module (Left), Inception Module with Dimensionality Reduction (Right)

Overall Architecture

Inception 模块在 Inception-v1 / GoogLeNet 中首次引入。输入同时通过 1×1、3×3 和 5×5 conv 以及最大池并连接在一起作为输出。因此,我们不需要考虑每一层应该使用哪种过滤器尺寸。

(我对《盗梦空间》的详细回顾-v1 / GoogLeNet )

1.2.Inception-v2 / BN-Inception [3]:批量规范化

Batch Normalization (BN)

批量规范化(BN) 在 Inception-v2 / BN-Inception 中引入。ReLU 被用作激活函数来解决饱和问题和由此产生的消失梯度。但是这也使得输出更加不规则。随着时间的推移,X 的分布保持固定是有利的,因为当网络变得更深时,小的变化将被放大。可以使用更高的学习率。

此外, 5×5 conv 被两个 3×3 conv取代,用于在保持感受野大小的同时降低参数。

(我对 Inception-v2 / BN-Inception 的详细回顾)

1.3。Inception-v3 [4]:因式分解

3×3 conv becomes 1×3 and 3×1 convs (Left), 7×7 conv becomes 1×7 and 7×1 convs (Right)

如上图卷积层引入因子分解进一步降维,减少过拟合问题。例如:

通过使用 3×3 滤波器,参数数量= 3×3=9 通过使用 3×1 和 1×3 滤波器,参数数量= 3×1+1×3=6
参数数量减少 33%

Conventional downsizing (Top Left), Efficient Grid Size Reduction (Bottom Left), Detailed Architecture of Efficient Grid Size Reduction (Right)

并且还引入了高效的网格尺寸缩减模块,其更便宜并且仍然是高效的网络。通过有效的网格尺寸缩减,例如图中所示, 320 个特征图conv 以步长 2 完成。通过最大汇集得到 320 张特征地图。并且这 2 组特征图被连接成 640 个特征图并且进入下一级的初始模块。

(我对 Inception-v3 的详细回顾)

2.盗梦空间-第 4 版

比 inception-v3 更统一的简化架构和更多的 Inception 模块,介绍如下:

Inception-v4: Whole Network Schema (Leftmost), Stem (2nd Left), Inception-A (Middle), Inception-B (2nd Right), Inception-C (Rightmost)

这是一个没有任何剩余连接的纯初始变体。它可以在不分割副本的情况下进行训练,使用内存优化来反向传播

我们可以看到使用了从 Inception-v1 到 Inception-v3 的技术。(也使用了批量标准化,但未在图中显示。)

3。盗梦空间-ResNet-v1

Inception-ResNet-v1: Whole Network Schema (Leftmost), Stem (2nd Left), Inception-A (Middle), Inception-B (2nd Right), Inception-C (Rightmost)

通过使用上述版本的 Inception-A、Inception-B 和 Inception-C,我们可以拥有 Inception-ResNet-v1。我们可以看到每个模块的左侧都有一个快捷连接。这种快捷的连接已经被一种证明,它可以帮助在 ResNet [5]中走得更深。

Inception-Resnet-v1 and Inception-v3

它的大约相当于《盗梦空间-v3》的计算成本。Inception-Resnet-v1 的训练速度要快得多,但最终精度比 Inception-v3 稍差。

然而,加在一起后使用的 ReLU 使得 Inception network 无法进一步深入。在论文中,作者还提到,如果过滤器的数量超过 1000,残差变体开始表现出不稳定性,并且网络在训练期间早期就“死亡”。

为了稳定训练,在将残差添加到先前的层激活之前缩小残差。一般来说,在添加到累积层激活之前,在 0.1 和 0.3 之间选择一些缩放因子来缩放残差

(也许,如果 ReLU 被用作预激活单元,就像在使用身份映射的改进 ResNet 中提到的[6],它可能会更深入。)(如有兴趣,请访问我对预激活 ResNet 的评论。)

4.盗梦空间-ResNet-v2

Inception-ResNet-v2: Inception-A (Leftmost), Inception-B (Middle), Inception-C (Rightmost)

有了全网模式使用 Inception-ResNet-v1 中的那个,Stem 使用 Inception-v4 中的那个,以及以上版本的 Inception-A、Inception-B、Inception-C,我们就可以有 Inception-ResNet-v2 了。同样,在每个模块的左侧有一个快捷连接。

Inception-Resnet-v2 and Inception-v4

它的计算成本大约相当于《盗梦空间 4》的计算成本。与 Inception-v4 相比,Inception-ResNet-v2 的训练速度要快得多,并且达到了略好的最终精度。

然而,同样地,如果 ReLU 被用作预激活单位,它可能会更深入。(如果感兴趣,请访问我对改进的 ResNet 的评论。)

5.与最先进方法的比较

多裁剪:是将输入图像裁剪成多个子图像,输入网络进行分类,以提高精度。从 AlexNet,VGGNet 等开始使用。

具体来说,AlexNet 使用了 10 种作物,GoogLeNet 使用了 144 种作物。

多模型:就是将多个训练好的模型集成在一起,得到更准确的预测,就像 boosting 一样。从 LeNet,AlexNet 等开始使用。

(如果有兴趣,请访问我的 AlexNetGoogLeNet 评论。)

Single-Crop Single-Model Results

单作物单模型的情况下,Inception-v4 和 Inception-ResNet-v2 的性能最好,结果相似。

10/12-Crop Single-Model Results

使用 10/12-Crop 单模型,Inception-v4 和 Inception-ResNet-v2 同样具有最佳性能,结果相似。

144-Crop Single-Model Results

使用 144-Crop 单模型,Inception-v4 和 Inception-ResNet-v2 同样具有最佳性能,结果相似。

144-Crop N-Model Results

144-Crop N-Model,Inception-v4(+Residual),即 1 个纯 Inception-v4 和 3 个 Inception-ResNet-v2 模型(N=4),性能最好。

获得 3.1%的前 5 名错误率。与 ResNet (3.57%的错误率,2015 年 ILSVRC 的冠军)和 Inception-v3 (3.58%的错误率,2015 年 ILSVRC 的亚军)相比,这已经是一个很大的相对进步。

参考

  1. 【2017 AAAI】【Inception-v4】
    Inception-v4、Inception-ResNet 以及剩余连接对学习的影响
  2. 【2015 CVPR】【谷歌网/盗梦空间-v1】
    随着回旋越走越深
  3. 【2015 ICML】【BN-Inception/Inception-v2】
    批量归一化:通过减少内部协变量移位加速深度网络训练
  4. 【2016 CVPR】【盗梦空间-v3】
    重新思考计算机视觉的盗梦空间架构
  5. 【2016 CVPR】【ResNet】
    用于图像识别的深度残差学习
  6. 【2016 ECCV】【带有身份映射的 ResNet】
    深度剩余网络中的身份映射

我的评论

  1. 回顾:Inception-v3–ILSVRC 2015 亚军(图像分类)
  2. 回顾:批量归一化(Inception-v2/BN-Inception)——ILSVRC 2015 中第二个超越人类水平的性能(图像分类)
  3. 回顾:Google net(Inception v1)——ILSVRC 2014(图像分类)获奖者
  4. 回顾:ResNet—ils vrc 2015(图像分类、定位、检测)获奖者
  5. 回顾:带有身份映射的 ResNet 已达到 1000 多个图层(图像分类)

[点评] Kaggle Corporación Favorita 杂货销售预测—第 1 部分

原文:https://towardsdatascience.com/review-kaggle-corporación-favorita-grocery-sales-forecasting-part-i-9330b7350713?source=collection_archive---------4-----------------------

回顾和事后分析

Source

[## Favorita 杂货销售预测公司

你能准确预测一家大型食品连锁店的销售额吗?

www.kaggle.com](https://www.kaggle.com/c/favorita-grocery-sales-forecasting)

动机和反思

自从去年 7 月将我的设备从 GTX960 4GB 升级到 GTX1070 (8GB)以来,我一直热衷于提高我的一般深度学习技能集。我在之前的两次 Kaggle 比赛中使用了 PyTorch, Instacart 购物篮分析Web 流量时间序列预测。我参加 Instacart 比赛的 DNN 模型注定要失败,因为我没有掌握如何加载大于内存大小(16GB)的数据集,而 DNN 模型拥有足够的训练数据真的很重要。不过,网络流量预测比赛更有趣。第一个位置的解决方案与我的想法非常相似。然而,我没能按时完成我的模型,最终提交的作品有严重的缺陷。我很幸运它仍然进入了前 50 名。当 Corporación Favorita 竞赛开始时,我发现数据集的大小对于 DNN 来说已经足够大了,并且很快就开始将它视为一个机会来完成我在网络流量预测竞赛中开始的工作。

[## Web 流量时间序列预测

预测维基百科页面的未来流量

www.kaggle.com](https://www.kaggle.com/c/web-traffic-time-series-forecasting#timeline)

尽管由于一次糟糕的押注,最终排名(相对)令人失望(第 20 名),但我仍然对结果感到相当满意。如果去掉不好的赌注,我的 DNN 模特会从纯银上升到第 2-5 名,这取决于我如何选择最后的组合。虽然如果我把更多的时间放在改进 GBM 模型上,我的排名可能会更好,但我已经达到了我报名参加的目的(建立我心目中的网络流量竞赛,甚至更多)。

这也是我第一次以团队形式参赛(我曾和我的学员一起工作过一次,但我没能给他腾出空间)。我们进行了许多发人深省的讨论,总的来说这是一次非常好的经历。我真的认为我们作为一个团队会取得非常好的成绩。我还没有机会重新运行我的队友的模型,去掉了不好的赌注,但根据过去的经验,他的模型应该能够推动我们进入前 3 名(我的 GBM 模型真的很烂)。

抱歉,我的介绍太长了…当谈到我喜欢的东西时,我有喋喋不休的问题。在这个第一部分中,我计划给出一个问题的概述,并在比赛结束前用我训练过的模型做一个事后分析。在下一篇文章中,我将展示一个我认为最理想的场景,但是没有足够的时间将它加入到最终提交的作品中,因为直到比赛的最后一周,我才看到这个场景。

问题描述

比赛的挑战是预测 2017/08/16 至 2017/08/31 期间每家商店每天每件商品的单位销售额。在厄瓜多尔 16 个州的 22 个不同城市有 54 家商店。有来自 33 个家族和 337 个班级的 4400 个独特的项目。评价指标为归一化加权均方根对数误差(NWRMSLE) :

决定评估标准实际上是真实场景中最重要的部分。你需要确保它符合你的业务目标。不幸的是,Kaggle 通常不会分享太多关于如何做出决定的信息,可能是因为涉及到商业秘密。这确实是一个非常复杂的问题,需要做出许多权衡,我们可以就此写一篇完整的独立文章。关于这个指标是否合适,本次比赛的讨论论坛有许多很好的见解。有兴趣就去那里。

这个数据集的问题

有两个主要问题:

  1. 没有库存信息。数据可能是从只记录实际销售额的 POS 系统中收集的。我们不知道某个商店某件商品零销售的原因是因为缺货还是商店一开始就不打算出售该商品。因此,我们被要求预测测试期间每种可能的(商店、商品、日期)组合的单位销售额,甚至不知道某个商品是否在展示。更糟糕的是,这 60 件全新的商品在火车时期从未在任何商店出售过。我们不知道新的商品是一次在所有商店推出,还是有更复杂的策略。基本上,它诱使人们去调查公共排行榜,并面临严重的过度拟合风险。
  2. 零销售额的(商店、商品、日期)组合缺少促销信息。这确实是一个可以解决的问题,我不明白为什么没有解决。我们在测试阶段有完整的推广信息,为什么不在培训阶段也提供呢?即使培训期间的 onpromotion 信息丢失,如果他们在测试期间将所有 onpromotion 设置为零(虽然不现实,但在数据科学中使验证集尽可能接近测试集是非常重要的),或者干脆不提供 onpromotion ,这仍然会更加公平。如果我是 Corporación Favorita 的数据科学家,我会坚持推迟建模,等待更多数据的到来,直到我们至少可以创建一个包含完整 onpromotion 信息的验证集。

当然,该数据集的其他方面也可以改进,例如提供促销的类型和力度、商店中商品的货架位置,但它们大多是锦上添花。上述两个问题实际上阻碍了该数据集的实际应用。

错误的赌注(哪里出错了)

正如我们在比赛结束后了解到的那样,很多人试图恢复宣传信息。我的队友也想出了一个聪明的方法来恢复信息,基于对商店经常对某些商品有非常相似的促销时间表的理解。因此,他开发了一种算法,如果我们忽略促销未知的条目,找到(1)总是或(2)大部分具有相同促销时间表的商店和日期的子组,并根据该模式猜测未知。它不涉及任何排行榜调查,但除了使用公共排行榜,没有其他方法来验证其效果。

我感到不舒服的是,预测的分布从原始模型变化到用来自模式(1)和(2)的恢复的 onpromotion 训练的模型是如此的戏剧性,所以我决定为 2017 年和 2016 年的数据训练仅来自模式(1)的恢复的 onpromotion 的模型。我保留了 2015 年和 2014 年的数据,因为它们在促销中包含了更多的 NA。而且我把用恢复的 onpromotion 训练的模型和用全未知的 onpromotion 训练的用 0 (50/50 的比例)混合。(这就是为什么我在比赛结束后很快就发现了问题所在。我只是去掉了整体中有问题的 50%,瞧,个人得分提高了。)

An example distribution of predicted unit_sales

这个最终的 50/50 设置给了我 0.001~0.002 的公开分数提升,但 0.002+的私下分数下降。我的队友全押了,看起来跌幅更大。这就是使用公开分数进行验证的危险。我们对这个高风险的赌注感到放心,但没有做足够的对冲。甚至 50/50 的比例也是以完全任意和主观的方式设定的,因为除了公开的分数之外,我们没有办法验证它。

我们还利用所有空闲的提交时间来探索排行榜上的新项目。我们想从公开得分中了解哪些商店在接下来的 5 天里有这些新商品的非零销售额(公开拆分)。我的队友建立了预测这些新项目的模型。不幸的是,最终我们最好预测所有新项目都为零。我不确定移除已恢复的 onpromotion 是否有帮助,但无论如何,分数差异小于 0.001。

数据集公式

从 2014 年到 2017 年的数据用于训练我的模型。我只包括了每年选定的月份,这样我可以避免对 2016 年地震的影响建模,也避免太多的磁盘序列化。如果我的电脑有 32gb 以上的内存,我会使用更多的数据。

我在这次比赛中主要使用了三个不同的验证阶段:

  1. 2017/07/26–2017/08/10:这个应该是最准确的。所有的训练数据都是在这些日期之前收集的,就像测试周期一样。当验证期和测试期非常接近时(假设年度模式不是很强),序列的内部动态应该更相似。我大量使用这个验证阶段来调整超参数和集合权重。在我发布的公共内核中,训练和验证数据之间有一点重叠。消除这种重叠似乎使其更加稳健。
  2. 2016/08/17–2016/09/01:这与 2016 年的考期大致相同(工作日分布相同)。这是为了近似盲训练,所以我可以在训练中使用 2017/07/26–2017/08/10。我使用 ReduceLROnPlateau 来安排学习速度,所以验证集是必不可少的。当然,我可以找到一个预定义的学习时间表,并进行实际的盲人训练,但我发现这太费时间了。
  3. 2016/09/07–2016/09/22:和第二个原因一样,但是有了这个我就不用把 2016 年的同期考期扔掉了。我发现这个不够稳定,在比赛中就停止使用了。

对于所有的 DNN 模型,我使用(1) 过去的 56 天 (2) 大致相同的前一年的 56 天和(3) 前一年的 56 天之后的 16 天来预测接下来的 16 天。为了节省时间,我使用了各种过滤器来减小数据集的大小:

  1. 保持(商店、物品)在过去 14 天内的销售额,或在与上一年测试期大致相同的 16 天内有销售额。
  2. 保持(商店,项目)在过去 28 天内的销售额。
  3. 保持(商店,项目)在过去 56 天内的销售额。

我预测所有丢弃的(商店,商品)组合为零。我曾计划探索移除这些过滤器,但一直推迟。我的队友在比赛的最后一周提醒了我这一点,我检查了验证预测,看看这些模型是否能比预测那些最近没有销售的(商店,商品)的零做得更好。模特们实际上表现明显更好!我本打算把这些简单的分数收益留在桌面上!

当时我没有太多时间,所以我很快使用 2017/07/26 验证训练了一组模型,并移除了过滤器,还使用 2016/09/07 和 56 天过滤器选取了之前训练的模型,因为这是当时唯一使用 56 天过滤器训练的设置。被一些模型丢弃的(商店、物品)将仅由在最终集合中没有被丢弃的模型来预测。这解释了我们将在下一节看到的奇怪的模型设置。

最终模型设置

我不会进入模型的细节。它们将在后面的部分中介绍。我在最后的合奏中使用了 4 个版本的设置:

  1. v4: 2017/07/26 + (14 天非零|去年非零)
  2. v7: 2016/09/06 + 56 天非零值
  3. v11: 2016/08/17 + 28 天非零
  4. 版本 12: 2017/07/26(无过滤器)

DNN 模型和 GBM 模型使用 13:3 的重量比在对数尺度上平均。(从交叉验证中获得的比率。)

如果…会怎样

以下是我的组合在没有恢复的宣传的情况下的表现:

Google Spreadsheet Link

comp_filter表示该设置的预测仅用于那些被所有其他设置丢弃的(商店、商品)组合。请注意,所有模型都是在比赛结束前训练的,内部集合权重保持不变,除了使用恢复的 onpromotion 训练的所有模型的权重(它们被设置为零)。我只是改变了不同场景的模型混合在一起的方式。

一些分析:

  1. 如上所述,对新项目的预测不起作用。
  2. 单独 v12 设置的车型可以达到 0.513 的私分。然而,我认为我没有必要用 v12 设置训练 DNN 模型,因为预测所有零序列的销售不是序列模型的强项。在这种情况下,表格特性应该工作得很好。所以我从 v12 中提取了 LGBM 模型,并用它们来补偿滤波器。
  3. 对于 14、28 和 56 个连续的零,预测零在公开拆分中比在私有拆分中效果更好。但是我已经从交叉验证中知道了,所以这对我来说并不奇怪。注意 v11 车型是如何从 (0.514 私,0.503 公)(0.512 私,0.507 公)28 天滤镜被 v12_lgb 车型补偿的。这说明了为什么我们不能相信分时比赛中的公共排行榜
  4. 在意识到我应该抛弃非零过滤器之前,我正计划提交 v4 和 v11 合奏。我选择了 v7,因为我只有时间重新训练一个验证设置,当我担心时,v7 在我面前爆炸了。幸运的是,我们有一个 v7 车型的较低重量的最终提交,否则我们会比第 20 名更糟。坚持使用 v4 和 v11 就可以了。

理想的环境

如果我有时间,我会使用这些理想的设置:

  1. v12_lgb : 2017/07/26。仅用于预测在过去 56 天内没有任何销售的(商店,商品)。
  2. v13 : 2017/07/26 + 56 天滤镜。用于超参数调谐。
  3. v14 : 2016/08/17+ 56 天滤镜。我预计它会比 v13 做得好一点。

我们可以通过取出 v13v14 中的 56 天过滤器来移除 v12_lgb 。它实际上可能会做得更好一点。但是我认为不值得增加训练时间。

我正在根据这些设置训练一些模型,我们将在下一篇文章中看到它们的表现。

Source

分时竞赛中的一个大问题

值得一提的是,私人排行榜中的分数分布比我预想的还要密集。我预计会有更多的变化,因为在以后的日子里不确定性会更高。一个可能的解释是,我们在后来的日子里都没有很好地预测销售,所以我们最终的结果是一样的。

这就是这种分时段比赛的问题。在现实世界中,我们可能更关心前 5 天的预测,而不是后 11 天的预测,因为我们可以在 5 天后再次调整我们的预测。这个竞争是如何设置的意味着我们只关心后面的 11 天,这只有在销售数据需要 5 天才能使用的情况下才是合理的。我认为更好的方法是像网络流量时间序列预测Zillow 的家庭价值预测这样的两阶段设置。发布一个专用于私人排行榜的训练数据集。

未完待续…

这个第一部分没有涵盖大多数人关心的内容——模型结构、特征、超参数、集成技术等。相反,它侧重于我发现在数据科学过程中更重要的东西——分析和制定数据集,并描述了导致我最终到达那里的我的思维过程。

事实上,你可以用 LGBM 型号通过一些功能工程达到第一的位置。如果你只是想看一个顶级解决方案,你可以看看内核。就我个人而言,我对一个可以在以后的项目中使用并且几乎不需要特性工程的工作 DNN 框架感到满意,尽管它可能会被精心制作的 GBM 模型超越。

我将分享用理想设置训练的模型的分数,也许在下一部分描述一下我的模型。最终我希望我能找到时间来提取我的代码的一个更干净更简单的版本,并在 Github 上开源。

[## [点评] Kaggle Corporación Favorita 杂货销售预测—第二部分

赛后模型和模型描述

medium.com](https://medium.com/@ceshine/review-kaggle-corporación-favorita-grocery-sales-forecasting-part-ii-680cca7f9bc5)

复习:MobileNetV1 —深度方向可分离卷积(轻型模型)

原文:https://towardsdatascience.com/review-mobilenetv1-depthwise-separable-convolution-light-weight-model-a382df364b69?source=collection_archive---------1-----------------------

在这个故事中,回顾了来自谷歌的 MobileNetV1深度方向可分离卷积用于降低模型大小和复杂度。它对移动和嵌入式视觉应用特别有用。

  • 更小的模型尺寸:参数数量更少
  • 更小的复杂度:更少的乘法和加法(多重加法)

When MobileNets Applied to Real Life

引入两个参数使得 MobileNet 可以很容易地调整:宽度乘数α分辨率乘数ρ 。而这是我写这篇论文的时候发表在arXiv 2017【1】的论文,引用600 多篇。(曾植和 @中)

上面的对象检测示例是 MobileNet,它实际上是令人惊讶的,因为它可以在同时检测到如此大量的对象时达到大约 25 fps。

涵盖哪些内容

  1. 深度方向可分离卷积
  2. 全网架构
  3. 较薄型号的宽度乘数α
  4. 简化表示的分辨率乘数ρ
  5. 与最先进方法的比较

1。深度方向可分离卷积

深度方向可分离卷积是一个深度方向卷积,后面跟着一个点方向卷积,如下所示:

  1. 深度方向卷积通道方向 DK×DK 空间卷积。假设在上图中,我们有 5 个通道,那么我们将有 5 个 DK×DK 空间卷积。
  2. 逐点卷积实际上是改变尺寸的 1×1 卷积

通过以上操作,操作成本为:

Depthwise Separable Convolution Cost: Depthwise Convolution Cost (Left), Pointwise Convolution Cost (Right)

其中 M:输入通道数,N:输出通道数,DK:内核大小,DF:特征映射大小。

对于标准卷积,它是:

Standard Convolution Cost

因此,计算量减少为:

Depthwise Separable Convolution Cost / Standard Convolution Cost

当 DK×DK 为 3×3 时,计算量可减少 8 至 9 倍,但精度仅略有降低。

2。全网架构

以下是 MobileNet 架构:

Whole Network Architecture for MobileNet

请注意,批次归一化(BN)和 ReLU 在每次卷积后应用:

Standard Convolution (Left), Depthwise separable convolution (Right) With BN and ReLU

对于 ImageNet 数据集,If 标准卷积与深度方向可分离卷积:

Standard Convolution vs Depthwise Separable Convolution (ImageNet dataset)

MobileNet 只损失了 1%的精度,但乘法和参数却大大减少了。

3。更薄型号的宽度乘数α

引入宽度乘数α控制通道数或通道深度,使 M 变为αM,深度方向可分卷积代价变为:

Depthwise Separable Convolution Cost with Width Multiplier α

其中α在 0 到 1 之间,典型设置为 1、0.75、0.5 和 0.25。当α=1 时,它是基线 MobileNet。并且计算成本和参数数量可以减少大约α倍。

Different Values of Width Multiplier α

精度从α=1 平滑下降到 0.5,直到α=0.25,这太小。

4。简化表示的分辨率乘数ρ

引入分辨率乘数ρ以控制网络的输入图像分辨率,用分辨率乘数ρ,成本变成:

Depthwise Separable Convolution Cost with Both Width Multiplier α and Resolution Multiplier ρ

其中ρ在 0 到 1 之间。输入分辨率为 224、192、160 和 128。当ρ=1 时,为基线 MobileNet。

Different Values of Resolution Multiplier ρ

分辨率从 224 到 128 时,精确度会平稳下降。

5。与最先进方法的比较

当使用 1.0 MobileNet-224 时,它的性能优于 GoogLeNet(ils vrc 2014 的冠军)和 VGGNet(ils vrc 2014 的亚军)而 multi-adds 和参数却少得多:

ImageNet Dataset

当使用更小的网络(0.50 MobileNet-160)时,它的性能优于 Squeezenet 和 Alex net(2012 年 ILSVRC 的获奖者)而 multi-adds 和参数则少得多:

ImageNet Dataset

它与 Inception-v3(ils vrc 2015 的亚军)也有竞争力,而 multi-adds 和参数要少得多:

Stanford Dogs Dataset

许多其他数据集也被尝试来证明 MobileNet 的有效性:

GPS Localization Via Photos

Face Attribute Classification

Microsoft COCO Object Detection Dataset

MobileNet SSD

Face Recognition

总之,利用深度方向可分离卷积,使用 MobileNet 可以获得与最先进方法类似的性能,但网络要小得多。

的确,还有很多我上面没有提到的应用,比如通过照片进行 GPS 定位,人脸属性分类和人脸识别。希望我能在未来的日子里报道它们。😃

参考

  1. 【2017 arXiv】【MobileNetV1】
    MobileNets:面向移动视觉应用的高效卷积神经网络

我的评论

Inception-v3 BatchNorm GoogLeNet VGGNet AlexNet

Deeplearning.ai 课程回顾

原文:https://towardsdatascience.com/review-of-deeplearning-ai-courses-aed1328e4ffe?source=collection_archive---------2-----------------------

最近在 Coursera 上完成了吴恩达deeplearning.ai 专精的最后一门课程,想分享一下自己上这套课程的想法和体会。我发现 Arvind N 对前三门课程的评论在决定参加第一门课程时非常有用,所以我希望,也许这也能对其他人有用。

TL;博士;医生

选修这五门课很有教育意义。内容结构良好,对于至少对矩阵代数有一点了解的每个人来说都很容易理解。需要一些编写 Python 代码的经验。总体来说,编程作业设计得很好。除了它们有益的特性之外,研究它们也是非常令人愉快的。最后,在我看来,进行这种专业化是让你开始深度学习的各种主题的一种奇妙方式。在参加完这些课程后,你应该知道你想进一步专攻深度学习的哪个领域。

背景

我必须承认,在选修这些课程之前,我对神经网络(NN)持怀疑态度。我来自传统的机器学习(ML),我不认为一种黑盒方法,如将一些功能(神经元)切换在一起,我无法单独训练和评估,可能会胜过一个经过微调和良好评估的模型。深度学习(DL)和人工智能(AI)成为如此热门的词汇,这一事实让我更加怀疑。

尽管如此,我还是不时地从我认真对待的人那里听说 DL。尤其是他在苏黎士Apache Spark meetup上由 Shoaib Burq 所做的一次演讲,是一次思想转变。所以去年我决定去看看,在所有的喧嚣背后到底是什么。首先,我从看一些视频、读博客和做一些教程开始。不幸的是,这助长了我的假设,即它背后的数学对我来说可能有点太高级了。我非常喜欢数学的实用方面,但是当谈到为了推导而推导或抽象理论时,我绝对不喜欢。

当我第一次听说 deeplearning.ai 专业化时,我真的很兴奋。在之前的课程中,我体验到 Coursera 是一个非常适合我学习方式的平台。从他的第一个大型开放式在线课程(MOOC)的视频中,我知道吴恩达是一个伟大的 ML 领域的讲师。但是我从来没有做过那门课的作业,因为八度。读到实际课程的作业现在是用 Python (我的主要编程语言)编写的,最终让我相信,这一系列课程可能是以结构化方式进入 DL 领域的一个好机会。但是首先,我没有足够的时间做课程作业。

这种情况发生了变化,去年年中,我遭遇了一场健康问题(并不严重,但无论如何都很麻烦)。当我感觉好一点的时候,我决定最终报名参加第一个课程。通常情况下,我只参加我想学的主题的特定课程,看完内容后尽快完成作业。但这一次,我决定彻底地、一步一步地、一门一门地做。我希望,关于认知挑战性话题的工作可以帮助我尽快康复。做编程作业是一个受欢迎的机会,可以让你重新回到编程和在电脑上正常工作的状态。事实上,在最初的几个星期里,我只能坐在显示器前很短很有限的时间。所以我必须打印出作业,在一张纸上解决,然后在提交给评分员之前输入缺失的代码。此外,一个积极的,意想不到的副作用在开始时发生了。在前三门课程中有可选的视频,安德鲁采访 DL 的英雄(辛顿,本吉奥,卡帕西等)。这些视频不仅信息量大,而且很有激励性,至少对我来说是这样——尤其是和伊恩·古德菲勒一起的那个。

期待什么

在专业层面上,当你对这个话题相当陌生时,你可以通过做 deeplearning.ai 专业化学到很多东西。首先,你学习神经网络的基本概念。简单序列模型中的正向传递是什么样子,什么是反向传播等等。我偶尔读到和听说过 NN 的基本构建模块。但从来没有像吴恩达[和 T7]所呈现的那样清晰和有条理。因此,我觉得这套课程是一种非常省时的学习基础知识的方式,比我之前浏览的所有教程、博客帖子和讲座都更有价值。](https://medium.com/u/592ce2a67248?source=post_page-----aed1328e4ffe--------------------------------)

顺便提一下,第一堂课很快证明了这个假设是错误的,即数学对我来说可能太深奥了。事实上,对于大多数我从上学或学习时就熟悉的概念——我没有技术硕士学位,所以不要让你被公式中一些看起来很花哨的希腊字母吓跑。有了关于如何做矩阵代数的肤浅知识,利用导数计算梯度,以及对线性回归和梯度下降算法的基本理解,你就可以开始了——Andrew 会教你剩下的。

尽管在围绕该技术的大量营销材料中另有说明,但你也在第一堂入门课中了解到,神经网络在生物模型中没有对应的内容。神经元中的信号处理与神经网络所包含的函数(线性函数和非线性函数)非常不同。

对新手非常有用的是了解 DL 项目的不同方法。是使用预先训练好的模型进行迁移学习还是采取端到端学习的方式。此外,数据扩充的概念也被提出,至少在方法论层面上。

在更高级的课程中,您将了解到图像识别(课程 4)和序列模型(课程 5)的主题。这里分别教授了卷积神经网络(CNN)递归神经网络 (RNN)的最常见变体。我认为这是这个专业的主要优势,你可以获得广泛的最先进的模型和方法。这可能不会让你成为数字图书馆的专家,但你会感觉到在这个领域的哪个部分你可以进一步专业化。

我发现对加深理解非常有用的是用 Franç ois Chollet 的书“用 Python 进行深度学习”来补充课程工作。这门技术的方法论基础不在本书的讨论范围之内,在课程讲座中有很好的阐述。另一方面,DL 项目的实践方面,在课程中有所涉及,但在作业中没有广泛实践,在书中有很好的涵盖。尤其是数据预处理部分,在课程的编程作业中肯定是缺失的。在第二次和第四次 MOOC 中,你确实得到了关于使用 DL 框架的教程( tensorflowKeras ),但是很明显,Keras 的最初创建者写的一本书将教你如何更深刻地实现 DL 模型。

你能从这五门课程中具体期待什么,以及做课程工作的一些个人经验,列在下面的部分。之后,我会以一些最后的想法来结束。

神经网络和深度学习

本课程教你神经网络的基本构建模块。您将了解逻辑回归成本函数激活以及(sochastic-&mini-batch-)梯度下降如何工作。您还可以快速了解 Python 中 numpy 的矩阵代数。

Sho ya right, it’s a cat picture & it’s >magic< Bert 😃

这门课程是一门简单的入门课程。吴恩达是一个很棒的讲师,即使是数学背景不太好的人也能很好地理解课程内容。

对于这些任务,你从一个用于二进制分类的单感知器开始,升级到一个用于相同任务的多层感知器,最后用 numpy 编码一个深度神经网络。特别是这两个图像分类作业在某种意义上是有益的,你将从中获得一个工作的猫分类器。正如你在图片上看到的,它决定了一只猫是否在图像上— 咕噜声;)

改进深度神经网络:超参数调整、正则化和优化

顾名思义,在这门课程中,你将学习如何微调你的深层神经网络。最常见的问题,如过度拟合消失/爆炸渐变在这些讲座中得到解决。你学习如何找到正确的权重初始化,使用辍学正规化正规化。当然,不同的优化算法的变体是如何工作的,以及哪一个是适合你的问题的选择。

对我来说,本课程最有用的见解是使用随机值进行超参数调整,而不是更结构化的方法。事实证明,在一个确定的空间和正确的尺度上选取随机值,比使用网格搜索更有效,你应该熟悉传统的 ML。

这门课的作业有点枯燥,我猜是因为他们要处理的内容。但是,每一个都很有启发性——尤其是关于优化方法的那一个。作为奖励,你将在课程结束时获得一份关于如何使用 tensorflow 的教程,这对后续课程中即将到来的作业非常有用。

构建机器学习项目

这绝对是一只黑天鹅。因为它的内容只有两周的学习时间,我期望在前两门入门课程和之后的高级课程之间有一个快速填充,关于 CNN 和 RNN。此外,我认为我很习惯如何构建 ML 项目。然而,事实证明,这成了对我最有价值的课程。

在本课程中,您将学习开发 DL 模型的良好实践。将你的数据分成个训练-个开发-个测试集对大多数 ML 从业者来说应该很熟悉。在开始一个项目之前,彻底决定你想要优化哪些指标。你应该量化你的模型执行领域的贝叶斯最优误差(BOE),分别是什么样的人因失误(HLE)。这是重要的一步,我之前并没有意识到这一点(通常,我将性能与基线模型进行比较——尽管如此,这也很重要)。当您必须评估模型的性能时,您可以将开发误差与该 BOE(分别为。HLE)和训练失误,当然。这样你就可以比较你的模型的可避免偏差 (BOE 对训练误差)和方差(训练对开发误差)。这两者中哪一个更大取决于你应该使用什么策略来进一步提高性能。例如,如果方差有问题,您可以尝试获取更多数据,添加正则化或尝试完全不同的方法(例如替代架构不同超参数搜索)。

您还将了解建立一个项目的不同策略以及分别在转移端对端学习的具体内容。

卷积神经网络

由于我对计算机视觉不是很感兴趣,至少在选修这门课之前,我对它的内容并没有那么高的期望。但事实证明,这成了我整个系列课程中最有启发性的一课。

在本课程中,你主要学习 CNN 以及它们如何应用于计算机视觉任务。从讲座视频中,你可以一瞥 CNN 的构建模块,以及它们如何能够转变张量。有些视频还专门介绍了残网 (ResNet)和盗梦空间架构。

Detect ANIMALS, not CARS — with YOLO

我个人觉得视频,分别是作业,关于 YOLO 算法很吸引人。基本功能在讲座中非常直观,我以前从未想过物体检测会是如此令人愉快的任务。同样具有启发性的是,有时仅仅构建一个杰出但复杂的模型是不够的。在 YOLO 的背景下,尤其是它的后继者,很明显,预测的速度也是一个需要考虑的重要指标。

所有五门课程中最有启发性的作业变成了一门,在这门课中,你在一个低层次的抽象上实现一个 CNN 架构。编写反向传播的可选部分加深了我对反向学习步骤实际上是如何工作的理解。

人脸验证上有两个作业,分别在人脸识别上。这是一个很好的举动,在关于这些主题的讲座和作业中,你开始了解 deeplearning.ai 团队成员——至少从他们的照片中,因为这些照片被用作验证的示例图像。

Neural Style Transfer — me in a neobrutalist scenery. Model as the proposed one by Gatys et. al, 2015 with an alpha/beta ratio of 10e-3

一个艺术作业是关于神经类型转移的作业。基本上你要在 tensorflow 中实现 Gatys et al .,2015 论文的架构。我也用这个模型玩了一会儿,有些精彩,但也有些相当怪异的结果。当您浏览中间记录的结果时,您可以看到您的模型如何在各个时期学习并应用样式到输入图片。有一次我觉得自己有点像弗兰肯斯坦,因为我的模型从它的源图像中学习了一个人的眼睛区域,并将其应用到输入照片上的人的脸上。所以一不小心就成了 DeepFake

序列模型

最后一条,我觉得是最难的。你学习 RNN、门控循环单元 (GRU)和长短期记忆 (LSTM)的概念,包括它们的双向实现。尽管我的最终目标是通过这种专业化来理解和使用这些类型的模型,但我发现其中的内容很难理解。这可能是因为概念的复杂性,如通过时间的反向传播,单词嵌入波束搜索。我还认为,这些重要话题的数量最好分成四部分,而不是实际的三周。

另一方面,这门课的测验和程序作业看起来很简单。您将学习如何开发 RNN,它从字符序列中学习,以产生新的、相似的内容。例如,你必须编写一个能给恐龙起名字的模型。LSTMs 在各种任务中弹出。你建立了一个以莎士比亚风格写诗的程序,给定了一个序列。在另一项任务中,你可以再次成为艺术家。你必须建立一个 LSTM,它可以在爵士音乐的语料库中学习音乐模式。然后,你可以用这个模型创作一首新的爵士乐即兴作品。我的声音听起来像这个 T1——在蒙特勒听不出什么,但至少,它听起来确实像爵士乐。这又是一个 LSTM,预先结合了一个嵌入层,它可以检测输入序列的情绪,并在句子末尾添加最合适的表情符号。是的,它瞬间改变了所有的事情

Emojify all the things! Using Word Embeddings and LSTM

很棒的是,你在第二周不仅学到了的单词嵌入,还学到了嵌入中包含的社会偏见问题。最重要的是,你学会了如何用三步法解决这个问题:识别中和均衡。最后,一个很有启发性的是最后一个编程作业。你可以建立一个触发单词检测器,就像你在亚马逊 Echo 或谷歌 Home 设备中发现的那样,来唤醒它们。我郑重发誓,我的模型比谷歌助手更了解我——它甚至有一个更令人愉快的唤醒词;)

最后的想法

最后,我想说的是,如果你对这个主题相对较新,你可以从这个专业中受益最多。如果你已经熟悉神经网络的基础,跳过前两门课程。如果你也非常熟悉图像识别和序列模型,我建议你只学习“构建机器学习项目”的课程。

另一方面,要清楚自己是哪种学习类型。如果你是一个严格的动手型的人,这个专业可能不适合你,有最可能的课程,更适合你的需求。人们说, fast.ai 提供了更多这样的体验。此外,如果你只对没有实际应用的理论感兴趣,你可能不会对这些课程感到满意——也许在你当地的大学学习一些课程。也许你只对数字图书馆的某个特定领域感兴趣,也可能有更适合你的课程。比如说,如果你只想学习自动驾驶,在 Udacity 报名“自动驾驶汽车”nano degree 可能会更有效率。你在 deeplearning.ai 的第三个课程中学到的关于这个话题的东西,可能太肤浅,缺乏实际的执行。但是,如果你重视对方法论的全面介绍,并希望将这与 DL 各个领域的一些实践经验结合起来,我绝对可以推荐你参加 deeplearning.ai 专业化。

做这个专精大概不止是进入 DL 的第一步。我会说,每门课程都是朝着正确方向迈出的一小步,所以你最终总共走了五步。尽管如此,我很清楚这绝对不足以让我在人工智能领域继续发展。我认为它建立了对这个领域的基本理解。但是更进一步,你必须大量练习,最终阅读更多关于 DL 变体的方法论背景可能也是有用的(例如,在讲座中提到的更高级的论文中)。但是做课程作业让你以一种结构化的方式开始——这是很有价值的,尤其是在一个如此热门的领域。

如果你想了解更多关于 deeplearning.ai 专业化的信息,并听到关于它的另一个(但相当类似的)观点:我可以推荐观看 Christoph Bonitz深度学习会议上讲述他参加这一系列 MOOCs 的经历。你可以在这里观看录像。

最重要的是,我不会后悔在 CourseraCoursera上花时间做这个专业。我的大部分希望都实现了,在职业层面上我学到了很多。这也是一个很好的决定,彻底完成所有的课程,包括选修部分。我非常感谢吴恩达鼓励你阅读论文以深入挖掘特定主题。因此,你可以从 MOOC 的讲座中获得一份精选的阅读清单,我发现这非常有用。

最后,我从这种专门化中得到的关键收获是:现在我完全相信 DL 方法及其威力。它的主要优势在于拥有大量数据的可伸缩性,以及一个模型归纳类似任务的能力,这可能是传统 ML 模型所不具备的。所以,我要感谢吴恩达,整个 deeplearning.ai 团队和 Coursera 在 DL 上提供了这么有价值的内容。我非常希望,在不久的将来,这个专业可能会有第六个课程——主题是深度强化学习

仅供参考,我不属于 deeplearning.ai、Coursera 或其他 MOOCs 提供商。我写了我在 2017-11 至 2018-02 期间参加这些课程的个人经历。此外,这个故事并没有声称是课程内容的普遍来源(因为它们可能会随着时间的推移而发生)。但是我绝对可以推荐报名,形成自己对这个专业的看法。

点评:PolyNet——ILSVRC 2016 亚军(图像分类)

原文:https://towardsdatascience.com/review-polynet-2nd-runner-up-in-ilsvrc-2016-image-classification-8a1a941ce9ea?source=collection_archive---------10-----------------------

通过使用多感知模块,优于 Inception-ResNet-v2

在这个故事里, CUHKSenseTime波利尼特进行了回顾。介绍了一种称为多增强模块的构建模块。基于该模块组成一个极深多边形。与Inception-ResNet-v2相比,PolyNet 将单一作物的前 5 名验证误差从 4.9%降低到 4.25%,将多作物的前 5 名验证误差从 3.7%降低到 3.45%。

PolyNet, By using PolyInception module, better than Inception-ResNet-v2

结果,PolyNet(团队名称为 CU-DeepLink)在 ILSVRC 2016 分类任务中获得亚军,如下。并以 2017 CVPR 论文发表。(曾植和 @中)

ResNet(2015 年 ILSVRC 的获胜者)的 3.57%相比,PolyNet 的得票率为 3.04%,具体如下:

ILSVRC 2016 Classification Ranking (Team Name: CU-DeepLink, Model Name: PolyNet) http://image-net.org/challenges/LSVRC/2016/results#loc

这个相对提升大概是 14%左右,这可不是小事!!!

涵盖哪些内容

  1. 对 Inception-ResNet-v2 (IR-v2)的简要回顾
  2. 多感知模块
  3. 消融研究
  4. 结果

1。对 Inception-ResNet-v2 (IR-v2)的简要回顾

随着 ResNetGoogle net(Inception-v1)的成功,引入了Inception-ResNet-v2(IR-v2)来结合两者:

Inception-ResNet-v2: Stem (Leftmost), Inception-A (2nd Left), Inception-B (2nd Right), Inception-C (Rightmost)

如上图,有一个跳过连接。还有几个平行的卷积路径,这是由 GoogLeNet 发起的。并且多个 Inception-A、Inception-B 和 Inception-C 在不同的级别级联。最后,Inception-ResNet-v2(IR-v2)获得了较高的分类准确率。

初始模块可以表述为一个抽象的剩余单元,如下所示:

Inception Module (Left), Abstract Residual Unit Denoted by F (Right)

输出变成 x + F(x ),类似于残差块。

2。多感知模块

为了提高精度,只需添加一个二阶项,便可增加一个多项式组合:

二阶项组成多感知模块

Different Types of PolyInception Module ((a) and (b) are the same)

提出了不同类型的多感知模块:

  • (a) poly-2 :第一条路径是跳过连接或身份路径。第二条路径是一阶先启块。第三条路径是二阶项,由两个初始块组成。
  • (b) poly-2 :由于第一个 Inception F 用于一阶路径和二阶路径,第一个 Inception F 可以共享。同样通过共享参数,第二次启始 F 与第一次相同。这可以在不引入额外参数的情况下增加表示能力。
    我们也可以想象它是
    (RNN)的一种递归神经网络。在二阶路径上,来自 Inception F 的输出再次回到 Inception F 的输入。这就变成了 1+F+F
  • (c) mpoly-2 :如果第二个 Inception G 不与 F 共享参数,我们得到 mpoly-2。这就变成了 1+F+GF
  • (d) 2 通:这是一个一阶多叠加I+F+G

这个概念可以扩展到高阶多感知模块。我们可以有 poly-3 (1+F+F +F )mpoly-3 (1+F+GF+HGF)3 向(I+F+G+H)

3.消融研究

现在我们手里有这么多选择。但是哪些组合是最好的呢?作者尝试了许多组合来寻找最佳组合。

Inception-ResNet-v2 (IR-v2, IR 5–10–5) (Top), PolyNet (Bottom)

Inception-ResNet-v2(IR-v2)表示为IR 5–10–5,这意味着它在 A 阶段有 5 个 Inception-A 模块(IR-A),在 B 阶段有 10 个 Inception-B 模块(IR-B),在 C 阶段有 5 个 Inception-C 模块(IR-C)

3.1.单一类型替换

为了加快实验速度,一个缩小版的ir3–6–3 被用作基线。对于每一次,六个多感知模块中的一个被 Inception-A、Inception-B 或 Inception-C 模块所取代,如下所示。

Top-5 Accuracy vs Time (Top), Top-5 Accuracy vs #Params (Bottom), with replacement at Inception-A (Left), Inception-B (Middle), and Inception-C (Right)

从上面的数字中,我们可以发现:

  • 任何二阶多感知模块都比初始模块好。
  • 增强 Inception-B 会带来最大的收益。而 mpoly-3 似乎是最好的一个。但是 poly-3 具有竞争性的结果,而只有 mpoly-3 的 1/3 参数大小。
  • 对于其他阶段,A 和 C,3 路性能略好于 mpoly 和 poly。

3.2.混合类型替换

IR 6–12–6 用作基线。而这 12 个 Inception-B 是关注点,因为它在之前的研究中得到了最大的改进。并且只测试一种混合多输入多输出(mixed B),即 (3 路> mpoly-3 > poly-3) × 4

Top-5 Error with different Inception module at Stage B

混合 B 的 Top-5 误差最低。

3.3.最终模型

  • 阶段 A: 10 个双向多输入模块
  • B 阶段:10 份聚-3 和 2-way 的混合物(总共 20 份)
  • 阶段 C: 5 种聚-3 和 2-way 的混合物(总共 10 种)

进行了一些修改以适应 GPU 内存,在保持深度的同时降低了成本。

4.结果

4.1.一些训练细节

Initialization by Insertion (Left), Path Dropped by Stochastic Depth (Right)

插入初始化:为了加快收敛,如上图所示,先去掉二阶初始模块,先训练交错模块。因此,在开始时训练一个较小的网络。

随机深度 :通过随机丢弃网络的某些部分,可以减少过拟合。它可以被视为一种特殊的丢失情况,即丢失一条路径上的所有神经元。

4.2.ImageNet

Single Model Results on 1000-Class ImageNet Dataset (Left) Top-5 Accuracy (Right)

  • 非常深的 Inception-ResNet:Inception-ResNet-v2IR 20–56–20。得到 19.10%的前 1 名误差和 4.48%的前 5 名误差。
  • Verp Deep PolyNet(10–20–10 mix):得到 18.71% Top-1 误差和 4.25% Top-5 误差
  • 在多作物的情况下,非常深的 PolyNet 得到了 17.36%的 Top-1 误差和 3.45%的 Top-5 误差,这一直优于非常深的 Inception-ResNet-v2
  • 因此,二阶多感知模块确实有助于提高精度。

通过使用多模型和多尺度输入图像进行组合,PolyNet 最终获得了 3.04%的 Top-5 错误率,并在 ILSVRC 2016 分类任务上获得亚军。

由于图像分类只有一个目标,即识别图像中的单个对象,因此用于图像分类的好模型通常成为对象检测、语义分割等网络的骨干。因此,研究图像分类模型是很有价值的。我也会学习 ResNeXt。

参考

【2017 CVPR】【波利尼特】
波利尼特:在非常深的网络中对结构多样性的追求

我对图像分类的相关综述

[LeNet][AlexNet][ZFNet][VGGNet][SPPNet][PReLU-Net][Google Net/Inception-v1][BN-Inception/Inception-v2][Inception-v3][Inception-v4 [ RoR ] [ 随机深度][WRN][dense net]

点评:PSP net——ils vrc 2016(语义分割/场景解析)获奖者

原文:https://towardsdatascience.com/review-pspnet-winner-in-ilsvrc-2016-semantic-segmentation-scene-parsing-e089e5df177d?source=collection_archive---------3-----------------------

金字塔场景解析网络:金字塔池模块

T 他的时代, PSPNet(金字塔场景解析网),由 CUHKSenseTime 点评。

  • 语义分割是为了只知道已知物体的每个像素的类别标签
  • 基于语义分割的场景解析,就是知道图像内所有像素的类别标签。

Scene Parsing

通过使用金字塔池模块,结合基于不同区域的上下文聚合,PSPNet 超越了最先进的方法,如 FCNDeepLabDilatedNet 。最后,PSPNet:

  • 获得 2016 年 ImageNet 场景解析挑战赛冠军
  • 当时在 PASCAL VOC 2012 &城市景观数据集上获得第一名

并发表在 2017 CVPR 上,引用 600 余次。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 全球信息的需求
  2. 金字塔池模块
  3. 一些细节
  4. 消融研究
  5. 与最先进方法的比较

1.全球信息的需要

(c) Original FCN without Context Aggregation, (d) PSPNet with Context Aggregation

  • 不匹配关系 : FCN 根据外观预测黄色盒子里的船是“汽车”。但常识是,车很少过江。
  • 混淆类别 : FCN 预测盒子里的物体是摩天大楼的一部分,也是建筑物的一部分。应该排除这些结果,这样整个对象要么是摩天大楼,要么是建筑物,但不能两者都是。
  • 不显眼类:枕头与床单外观相似。忽略全局场景类别可能无法解析枕头。

因此,我们需要图像的一些全局信息。

2.金字塔池模块

Pyramid Pooling Module After Feature Extraction (Colors are important in this figure!!!)

(a)和(b)

在(a)处,我们有一个输入图像。在(b)处, ResNet 使用扩张网络策略(deep lab/dilated net)进行特征提取。扩张的卷积跟随 DeepLab 。这里的特征图大小是输入图像的 1/8。

(c).1。分地区平均统筹

在(c),对每个特征图执行子区域平均汇集。

  • 红色:这是对每个特征图执行全局平均汇集的最粗级别,以生成单个面元输出。
  • 橙色:这是第二层,将特征图分成 2×2 子区域,然后对每个子区域进行平均池化。
  • 蓝色:这是第三层,将特征图分成 3×3 个子区域,然后对每个子区域进行平均合并。
  • 绿色:这是将特征图划分为 6×6 子区域,然后对每个子区域进行合并的最细级别。

(c).2。 1×1 卷积降维

然后对每个汇集的特征图执行 1×1 卷积将上下文表示减少到原始的 1/ N (黑色)如果金字塔的级别大小是 N

  • 在本例中, N =4,因为总共有 4 个级别(红、橙、蓝、绿)。
  • 如果输入特征图的数量是 2048,那么输出特征图将是(1/4)×2048 = 512,即 512 个输出特征图。

(c).3。用于上采样的双线性插值

执行双线性插值以对每个低维特征图进行上采样,使其具有与原始特征图(黑色)相同的大小。

(c).4。用于上下文聚合的串联

所有不同级别的上采样特征图都与原始特征图(黑色)连接在一起。这些特征图被融合为全局先验。这是(c)处的金字塔池模块的结尾。

(四)

最后,随后是卷积层,以在(d)生成最终预测图。

子区域平均池的思想实际上非常类似于 SPPNet 中的空间金字塔池。1×1 卷积然后串联与exceptionMobileNetV1 使用的深度方向可分离卷积中的深度方向卷积非常相似,除了双线性插值用于使所有特征图的大小相等。

3。关于训练的一些细节

Auxiliary Loss at the Middle

  • 辅助损耗在训练时使用。将权重α0.4 添加到辅助损失中,以平衡最终损失和辅助损失。在测试过程中,辅助损耗被放弃。这是一种用于训练非常深的网络的深度监督训练策略。这个思路类似于 GoogLeNet / Inception-v1 中的辅助分类器。
  • 使用“Poly”学习代替基本学习。

4.消融研究

ADE2K 数据集是 ImageNet 场景解析挑战赛 2016 中的数据集。这是一个更具挑战性的数据集,有多达 150 个类,1,038 个图像级标签。并且有 20K/2K/3K 图像用于训练/验证/测试。

验证集用于消融研究。

4.1.最大(Max)与平均(AVE)池化和降维(DR)

Different Approaches on ADE2K Validation Set Results

  • ResNet50-Baseline :基于 ResNet50 的 FCN,网络扩大。
  • B1’和’b 1236’:分别为面元尺寸{1×1}和{1×1,2×2,3×3,6×6}的汇集特征图。
  • 最大平均:分别为最大汇集和平均汇集操作。
  • DR’:降维。

平均池一直有更好的结果。而且用 DR 比不用 DR 好。

4.2.辅助损耗

Different Weights for Auxiliary Loss on ADE2K Validation Set Results

α=0.4 时,性能最佳。因此,使用α=0.4。

4.3.不同深度数和多尺度(MS)测试

Different Depth Numbers and Multi-Scale Testing on ADE2K Validation Set Results

正如我们所知,更深的模型有更好的结果。多尺度测试有助于改善结果。

4.4.数据扩充(DA)及其与其他技术的比较

Comparison with State-of-the-art Approaches on ADE2K Validation Set Results (All are Single Scale Except the Last Row.)

  • ResNet269+DA+AL+PSP :对于单一尺度的测试,把所有的东西结合在一起,它比最先进的方法要好得多。
  • ResNet269+DA+AL+PSP+MS :同样通过多尺度测试,获得更好的效果。
  • 下面是一些例子:

ADE2K Examples

5。与最先进方法的比较

5.1.ADE2K—2016 年 ImageNet 场景解析挑战赛

ADE2K Test Set

  • PSPNet 赢得了 2016 年 ImageNet 场景解析挑战赛。

5.2.帕斯卡 VOC 2012

对于 DA,有 10582/1449/1456 个图像用于训练/验证/测试。

PASCAL VOC 2012 Test Set

  • +'表示也由 MS COCO 数据集预先训练。
  • PSPNet 再次胜过所有最先进的方法,如 FCN、DeconvNet、DeepLab 和 Dilation8。
  • 下面是一些例子:

PASCAL VOC 2012 Examples

5.3.城市景观

它包含从 50 个城市不同季节收集的 5000 幅高质量像素级精细注释图像。有 2975/500/1525 用于培训/验证/测试。它定义了包含东西和对象的 19 个类别。此外,在比较中,为两种设置提供 20000 个粗略注释的图像,即,仅用精细数据或用精细和粗略数据两者进行训练。两者的训练都用“++”标记。

Cityscapes Test Set

  • 仅用精细数据训练,或者同时用精细和粗糙数据训练,PSPNet 也得到了最好的结果。
  • 下面是一些例子:

Cityscapes Examples

Cityscapes Examples

  • 作者还上传了 Cityscapes 数据集的视频,令人印象深刻:

  • 另外两个视频例子:

https://www.youtube.com/watch?v=gdAVqJn_J2M

https://www.youtube.com/watch?v=HYghTzmbv6Q

利用金字塔池模块,获取图像的全局信息,改善结果。

参考

【2017 CVPR】【PSPNet】
金字塔场景解析网

我对图像分类的相关综述

)(我)(们)(都)(不)(想)(要)(让)(这)(些)(人)(都)(有)(这)(些)(的)(情)(况)(,)(我)(们)(都)(不)(想)(会)(有)(什)(么)(情)(况)(,)(我)(们)(都)(不)(想)(会)(有)(什)(么)(情)(况)(,)(我)(们)(还)(没)(有)(什)(么)(情)(况)(,)(我)(们)(还)(有)(什)(么)(情)(况)(,)(我)(们)(还)(没)(有)(什)(么)(好)(的)(情)(感)(。 )(我)(们)(都)(不)(知)(道)(,)(我)(们)(都)(是)(很)(好)(的)(,)(我)(们)(都)(是)(很)(好)(的)(。

我对语义分割的相关评论

[FCN][de convnet][deep lab v1&deep lab v2][parse net][dilated net]

我对生物医学图像分割的相关综述

[ 累计视频 1 ] [ 累计视频 2 / DCAN ] [ 优网 ] [ CFS-FCN ]

综述:R-FCN-阳性敏感得分图(物体检测)

原文:https://towardsdatascience.com/review-r-fcn-positive-sensitive-score-maps-object-detection-91cd2389345c?source=collection_archive---------4-----------------------

在这个故事中,简要回顾了微软和清华大学的 R-FCN(基于区域的完全卷积网络)。通过正敏感得分图,推理时间比更快的 R-CNN 快得多,同时仍然保持竞争的准确性。

From R-CNN to R-FCN

这是一篇在我写这篇论文的时候,在 2016 NIPS 上有超过 700 次引用的论文。由于了解对象检测方法的发展可以更多地了解创新背后的原因,我希望我可以在未来的未来包括更多的对象检测方法。( Sik-Ho Tsang @中)

R-FCN Demonstration

涵盖哪些内容

  1. R-FCN 相对于 R-CNN 的优势
  2. 阳性敏感得分图& ROI 汇集
  3. 其他详情
  4. 结果

1.R-FCN 相对 R-CNN 的优势

R-CNN series

对于传统的区域提议网络(RPN)方法,例如 R-CNN、快速 R-CNN 和更快 R-CNN,区域提议首先由 RPN 生成。然后完成 ROI 合并,并通过全连接(FC)层进行分类和边界框回归。

ROI 合并后的流程(FC 层)不会在 ROI 之间共享,并且需要时间,这使得 RPN 方法很慢。FC 层增加了连接(参数)的数量,这也增加了复杂性。

R-FCN

在 R-FCN,我们仍有 RPN 来获取区域提案,但与 R-CNN 系列不同的是,ROI 汇集后的 FC 层被移除。相反,所有主要的复杂性都在 ROI 汇集之前移动,以生成评分图。所有区域提案,在 ROI 汇集后,将使用同一组得分图来执行平均投票,这是一个简单计算。 因此,在 ROI 层之后没有可学习的层,这几乎是免费的。结果,R-FCN 甚至比具有竞争地图的更快的 R-CNN 还要快。

2.阳性敏感得分图& ROI 合并

Positive-Sensitive Score Maps & Positive-Sensitive ROI Pooling (k=3 in this figure) (Colors are important in this diagram)

2.1 阳性敏感得分图

为了简单起见,让我们去掉 RPN。

我们有 C 类需要检测。(C+1)表示 C 个对象类加上背景类。

在正敏感分数图之前的开始处的许多卷积之后,我们执行 k (C+1)-d 卷积。对于每个类,将有 k 个特征图。这些 k 特征图代表了{左上(TL),中上(TC)、..,右下(BR)} 我们要检测的对象。

2.2 积极敏感的投资回报池

An Example of Positive-Sensitive ROI Pooling

当 ROI 合并时,产生大小为 k 的(C+1)个特征图,即 k (C+1)。在图中,它们以相同的面积和相同的颜色汇集在一起。执行平均投票以生成(C+1)个一维向量。最后对矢量进行 softmax。

当区域提案与以下目标不重叠时,我们将投反对票:

When the region proposal does not overlap the object so much.

2.3 边界框回归

执行与类别无关的包围盒回归,这意味着回归在类别之间共享。

在 k (C+1)-d 卷积层,附加一个兄弟 4k -d 卷积层。在这个 4k 地图库上执行位置敏感 RoI 汇集,为每个 RoI 产生 4k -d 向量。然后通过平均投票聚合成一个 4-d 向量,表示包围盒的 {tx,ty,tw,th} (位置和大小),和 Fast R-CNN 中的一样。

3。其他细节

3.1 主干架构

从 ImageNet 预训练的 ResNet-101 的前 100 个 conv 被用于在阳性敏感分数图之前计算特征图。

3.2 培训

损失紧随快速 R-CNN :

Lcls 是分类损失,Lreg 是边界框回归损失。

在线硬例挖掘(OHEM) 用于训练。在 N 个建议中,只有具有最高损失的顶部 B 个 ROI 被用于反向传播。

4 步交替训练在更快的 R-CNN 中同样完成,以训练 RPN 和 R-FCN。

3.3 推理

非最大抑制(NMS) 在 0.3 IoU 时执行后处理

4.结果

4.1 VOC 2007 数据集

Study of k values

7×7 ROI 大小的 R-FCN 获得了 76.6%的 mAP,优于更快的 R-CNN。

The use of OHEM

使用 OHEM,获得了 79.5%的 mAP。

Multi-Scale Training

使用不同比例的图像进行训练,R-FCN 具有 83.6%的 mAP,这比更快的 R-CNN++的 85.6%的 mAP 稍差。但是 R-FCN 的测试时间是每张图片 0.17 秒,比更快的 R-CNN++的测试时间(3.36 秒/张图片)快多了。这是因为 ROI 合并后没有 FC 层。

而且我们可以看到训练的细节也是至关重要的,这使得 mAP 增加了这么多,从 76.6%到 83.6%的 mAP。

Different Backbones on VOC 2007

使用 ResNet-152 与使用 ResNet-101 具有相似的映射。这是由于 ResNet 网络问题。如果在 ResNet 中使用身份映射,可以超过 1000 层,不会在 152 层饱和。(如果感兴趣,也请阅读我在 ResNet 上关于身份映射的评论。)

Some Amazing Results on VOC 2007 Dataset

4.2 VOC 2012 和 MS COCO 数据集

VOC 2012 Dataset

MS COCO Dataset

类似于 VOC 2007 数据集的结果, R-FCN 比更快的 R-CNN++具有竞争力但 mAP 更低。但是R-FCN 的测试时间要快得多。

对象检测方法可以分为两阶段(R-CNN 系列与 RPN)和一阶段(YOLO,SSD)方法。R-FCN 可以看作是两阶段方法中的一种快速方法。

由于了解对象检测方法的发展可以更多地了解创新背后的原因,我希望我可以在未来的未来包括更多的对象检测方法。

参考

【2016 NIPS】【R-FCN】
R-FCN:经由基于区域的完全卷积网络的物体检测

我的评论

[R-CNN][Fast R-CNN][Fast R-CNN][SPPNet][yolov 1][VGGNet][ResNet][ResNet with Identity Mapping]

点评:ResNet——2015 年国际影像分类、定位、检测奖得主

原文:https://towardsdatascience.com/review-resnet-winner-of-ilsvrc-2015-image-classification-localization-detection-e39402bfa5d8?source=collection_archive---------4-----------------------

本故事中, ResNet [1]回顾。ResNet 可以通过学习残差表示函数而不是直接学习信号表示,拥有一个非常深的网络达到 152 层

ResNet 引入了跳过连接(或快捷连接)来将来自上一层的输入适配到下一层,而不对输入进行任何修改。跳过连接使得能够有更深的网络,最终 ResNet 成为 ILSVRC 2015 在图像分类、检测和定位方面的赢家,以及 MS COCO 2015 检测和分割的赢家。这是一篇 2016 CVPR 论文,引用超过 19000 次。 ( 曾锡豪 @中)

ILSVRC 2015 Image Classification Ranking

ImageNet 是一个数据集,包含超过 1500 万张带有标签的高分辨率图像,大约有 22,000 个类别。ILSVRC 在 1000 个类别中的每个类别中使用大约 1000 个图像的 ImageNet 子集。总的来说,大约有 120 万幅训练图像、50,000 幅验证图像和 100,000 幅测试图像。

涵盖哪些内容

  1. 平面网络问题(消失/爆炸梯度)
  2. 剩余网络中的跳过/快捷连接(ResNet)
  3. ResNet 架构
  4. 瓶颈设计
  5. 消融研究
  6. 与最先进方法的比较(图像分类)
  7. 与最先进方法的比较(物体检测)

1。普通网络的问题

对于传统的深度学习网络,它们通常有 conv 层,然后是用于分类任务的全连接(FC)层,如 AlexNet、ZFNet 和 VGGNet,没有任何跳过/快捷连接,我们在这里将它们称为平面网络当平面网络较深时(层数增加),会出现消失/爆炸渐变的问题。

消失/爆炸渐变

在反向传播期间,当误差函数相对于训练的每次迭代中的当前权重的偏导数时,这具有将这些小/大数的 n 乘以 n 层网络中的“前”层的梯度的效果

当网络很深的时候,这些小数字的乘积 n 就会变成零(消失)。

当网络很深,并且这些大数相乘 n 就会变得过大(爆炸)。

我们期望更深的网络会有更准确的预测。然而,下面显示了一个例子, 20 层平面网络比 56 层平面网络具有更低的训练误差和测试误差,由于梯度消失,出现了退化问题。

Plain Networks for CIFAR-10 Dataset

2.剩余网络中的跳过/快捷连接(ResNet)

为了解决消失/爆炸渐变的问题,添加了一个跳过/快捷连接,以在几个权重层后将输入 x 添加到输出,如下所示:

A Building Block of Residual Network

因此,输出 H(x)= F(x) + x权重层其实就是学习一种残差映射: F(x)=H(x)-x

即使权重层存在消失梯度,我们仍然始终有身份 x 转移回更早的层。

3.ResNet 架构

34-layer ResNet with Skip / Shortcut Connection (Top), 34-layer Plain Network (Middle), 19-layer VGG-19 (Bottom)

上图显示了 ResNet 架构。

  1. VGG-19 2是 2014 年 ILSVRC 中最先进的方法。
  2. 34 层平面网(中间)作为 VGG-19 的深层网,即更多的 conv 层。
  3. 34 层残差网络(ResNet)(上)是普通网络,增加了 skip / shortcut 连接。

对于 ResNet,当输入尺寸小于输出尺寸时,有 3 种类型的跳过/快捷连接。

(A)快捷方式执行标识映射,并额外填充零以增加维度。因此,没有额外的参数。

(B)投影快捷方式仅用于增加维度,其他快捷方式是恒等式。需要额外的参数。

(C)所有快捷方式都是投影。额外的参数比(B)的多。

4。瓶颈设计

由于现在网络很深,时间复杂度很高。瓶颈设计用于降低复杂性,如下所示:

The Basic Block (Left) and The Proposed Bottleneck Design (Right)

如图(右)所示, 1×1 conv 层被添加到网络的起点和终点。这是网络中的网络和 GoogLeNet (Inception-v1)中建议的技术。事实证明, 1×1 conv 可以减少连接(参数)的数量,同时不会使网络性能下降太多。(有兴趣请访问我的评论。)

通过瓶颈设计,34 层 ResNet 变成了 50 层 ResNet。还有有瓶颈设计的更深网络: ResNet-101 和 ResNet-152。全网整体架构如下:

The overall architecture for all network

注意到 VGG-16/19 有 15.3/19.6 亿次 FLOPS。ResNet-152 的复杂度仍然低于 VGG-16/19!!!!

5.消融研究

5.1 普通网络与 ResNet

Validation Error: 18-Layer and 34-Layer Plain Network (Left), 18-Layer and 34-Layer ResNet (right)

Top-1 Error Using 10-Crop Testing

当使用平面网络时,由于消失梯度问题,18 层比 34 层好。

使用 ResNet 时,34 层优于 18 层,通过跳过连接解决了消失梯度问题。

如果对比 18 层的素网和 18 层的 ResNet,没有太大区别。这是因为对于浅层网络不存在消失梯度问题。

5.2 其他设置

批量归一化(从 Inception-v2) 用在每次 conv 之后。使用 10-作物测试。采用多尺度平均分数的全卷积形式 {224,256,384,480,640}6 个模型用于集成增强。以上是之前深度学习框架中使用的一些技术。如果感兴趣,也请随时阅读我的评论。

6。与最先进方法的比较(图像分类)

6.1 ILSVRC

10-Crop Testing Results

通过比较 ResNet-34 A、B 和 C, B 略好于 A,C 略好于 B,因为引入了额外的参数,所有参数的误差率都在 7%左右。

通过将网络深度增加到 152 层,获得了 5.71%的 top-5 错误率,这比 VGG-16、GoogLeNet (Inception-v1)和 PReLU-Net 好得多。

10-Crop Testing + Fully Conv with Multiple Scale Results

ResNet-152 通过 10 次作物测试+多次完全 Conv,可以获得 4.49%的错误率。

10-Crop Testing + Fully Conv with Multiple Scale + 6-Model Ensemble Results

加入 6 模型集成技术,错误率为 3.57%。

6.2 CIFAR-10

CIFAR-10 Results

有了 skip 连接,我们可以更深入。然而,当层数从 110 层增加到 1202 层时,误差率从 6.43%增加到 7.93%,这是一个有待解决的问题。尽管如此,ResNet-1202 不存在优化困难,即它仍然可以收敛。

7。与最先进方法的比较(物体检测)

PASCAL VOC 2007/2012 mAP (%)

MS COCO mAP (%)

通过在更快的 R-CNN 中采用 ResNet-101,ResNet 获得了比 VGG-16 更好的性能。

ResNet 最终获得了 ImageNet 检测、定位、COCO 检测和 COCO 分割的第一名!!!

参考

  1. 【2016 CVPR】【ResNet】
    用于图像识别的深度残差学习
  2. 【2015 ICLR】【VGGNet】
    用于大规模图像识别的极深度卷积网络
  3. [2015 NIPS][更快的 R-CNN]
    更快的 R-CNN:通过区域提议网络实现实时目标检测
  4. 【2017 TPAMI】【更快的 R-CNN】
    更快的 R-CNN:利用区域提议网络实现实时对象检测

我的评论

  1. 回顾:更快的 R-CNN(物体检测)
  2. 回顾:批量归一化(Inception-v2/BN-Inception)——ILSVRC 2015 中第二个超越人类水平的性能(图像分类)
  3. 回顾:在 ILSVRC 2015(图像分类)中第一个超越人类水平性能的 PReLU-Net
  4. 回顾:Google net(Inception v1)——ILSVRC 2014(图像分类)获奖者
  5. 点评:VGGNet—ils vrc 2014 亚军(图像分类)、冠军(本地化)

点评:RES next——ils vrc 2016(图像分类)亚军

原文:https://towardsdatascience.com/review-resnext-1st-runner-up-of-ilsvrc-2016-image-classification-15d7f17b42ac?source=collection_archive---------2-----------------------

神经元网络,一种新的维度:基数

在这个故事里, ResNeXt,加州大学圣地亚哥分校脸书艾研究(FAIR)进行回顾。模型名称 ResNeXt 包含 NeXt。这意味着下一个尺寸,在 ResNet 之上。下一个维度称为“ 基数维度。而 ResNeXt 成为 ILSVRC 分类任务的亚军。

ILSVRC 2016 Classification Ranking http://image-net.org/challenges/LSVRC/2016/results#loc

Residual Block in ResNet (Left), A Block of ResNeXt with Cardinality = 32 (Right)

ResNet(ils vrc 2015 中的冠军,3.57%)和 PolyNet (亚军,3.04%,队名 CU-DeepLink)相比,ResNeXt 得到了 3.03%的 Top-5 错误率,相对提高了 15%左右的较大幅度!!

这篇文章发表在 2017 CVPR 上,在我写这篇文章的时候已经被引用了 500 次。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 聚合转换
  2. 的关系 Inception-ResNet ,以及 中的分组卷积 AlexNet
  3. 完整的架构和消融研究
  4. 结果

1.聚集变换

1.1.重温简单神经元

A Simple Neuron (Left), and the corresponding equation (Right)

我们应该知道,一个简单的神经元如上,其输出是 wi 乘以 xi 的总和。上面的操作可以被改写为拆分、转换和聚合的组合。

  • 分裂:向量 x 被切片为低维嵌入,在上图中,它是一个一维子空间 xi。
  • 变换:对低维表示进行变换,在上面,简单缩放:wixi。
  • 聚合:所有嵌入中的变换通过求和来聚合。

1.2.聚合转换

A Block of ResNeXt with Cardinality = 32 (Left), and Its Generic Equation (Right)

与“网络中的网络”形成对比的是,“神经元中的网络”沿着一个新的维度展开。代替在每个路径中乘以 xi 的简单神经元中的线性函数,为每个路径执行非线性函数

引入了一个新的维度 C ,称为“基数”。基数的维度控制着更复杂转换的数量

2。 与【Inception-ResNet】的关系以及 与【AlexNet】

(a) ResNeXt Block, (b) Inception-ResNet Block, (c) Grouped Convolution

为了比较,上述 3 个块在每个块内具有相同的内部尺寸。

(a) ResNeXt 块(左)

  • 对于每个路径,con v1×1–con v3×3–con v1×1在每个卷积路径上完成。这是 ResNet 块中的瓶颈设计。每个路径的内部尺寸表示为d(d= 4)。路径数是基数 C ( C =32)** 。如果我们把每个 Conv3×3 的尺寸加起来(即 d × C =4×32),也是 128 的尺寸。
  • 维度直接从 4 增加到 256,然后加在一起,还加了跳过连接路径。
  • Inception-ResNet 需要将维度从 4 增加到 128 再增加到 256 相比, ResNeXt 需要最小的额外工作来设计每条路径。
  • ResNet 不同,在 ResNeXt 中,一条路径上的神经元不会连接到其他路径上的神经元。

(b) 【盗梦空间】 街区(中间)

  • 这在 Inception-v4 中建议将 Inception 模块和 ResNet 模块合并。由于遗留问题,对于每个卷积路径,首先执行con v1×1–con v3×3。当加在一起时(即 4×32),Conv3×3 的尺寸为 128。
  • 然后输出以 128 的维数连接在一起。 Conv1×1 用于将尺寸从 128 恢复到 256。
  • 最后,使用跳过连接路径添加输出。
  • 主要区别在于它们有一个早期连接

(c)分组卷积AlexNet(右)

  • con v1×1–con v3×3–con v1×1在卷积路径上完成,实际上是 ResNet 中提出的一个瓶颈设计。Conv3×3 的尺寸为 128。
  • 然而,这里使用了 AlexNet 中建议的分组卷积。因此,Conv3×3 是更宽但连接稀疏的模块。(因为一条路径上的神经元不会连接到其他路径上的神经元,所以连接稀疏。)
  • 因此有 32 组回旋。(仅在 AlexNet 中有 2 组)
  • 则跳过连接是并行的,并添加了卷积路径。因此,卷积路径正在学习残差表示。

尽管(b)和(c)中的结构并不总是与 1.2 中所示方程的一般形式相同,实际上作者已经尝试了上述三种结构,他们发现结果是相同的。

最后,作者选择实现(c)中的结构,因为它比其他两种形式更简洁和更快。

3.完整的架构和消融研究

3.1.相似复杂度下 Cd 的烧蚀研究

Detailed Architecture (Left), Number of Parameters for Each Block (Top Right), Different Settings to Maintain Similar Complexity (Middle Right), Ablation Study for Different Settings Under Similar Complexity (Bottom Right)

  • ResNet-50 是 ResNeXt-50 的特例,其中 C =1, d =64。
  • 为了公平比较,尝试了具有不同 C 的不同 ResNeXt 和具有与 ResNet 相似复杂度的 d 。这在上图的右中部显示。
  • 发现 ResNeXt-50 (32×4d)对 ImageNet-1K (1K 表示 1K 类)数据集获得 22.2%的 top-1 错误,而 ResNet-50 仅获得 23.9%的 top-1 错误。
  • ResNeXt-101 (32×4d)对 ImageNet 数据集获得 21.2%的 top-1 误差,而 ResNet-101 仅获得 22.0%的 top-1 误差。

3.2.基数的重要性

Ablation Study for Different Settings of 2× Complexity Models

  • ResNet-200:21.7%的前 1 名和 5.8%的前 5 名错误率。
  • ResNet-101,更宽 :仅获得 21.3%的 top-1 和 5.7%的 top-5 错误率,也就是说只做得更宽并没有太大帮助
  • ResNeXt-101 (2×64d) :仅通过使= 2(即 ResNeXt 块内的两条卷积路径)已经获得了明显的改善,top-1 错误率为 20.7%,top-5 错误率为 5.5%。
  • ResNeXt-101 (64×4d) :通过使= 64**(即 ResNeXt 块内的 64 个卷积路径)已经获得了更好的改进,具有 20.4%的 top-1 和 5.3%的 top-5 错误率。这意味着基数对于提高分类精度至关重要。**

3.2.剩余连接的重要性

Importance of Residual Connections

如果没有剩余连接,ResNet-50 和 ResNeXt-50 的错误率都会大大增加。残留连接很重要。

4.结果

4.1.ImageNet-1K

Single Crop Testing: ResNet/ResNeXt is 224×224 and 320×320, Inception models: 299×299

ImageNet-1K 是 22K 类 ImageNet 数据集的子集,包含 1000 个类。它也是 ILSVRC 分类任务的数据集。

  • 使用标准尺寸图像进行单作物测试,ResNeXt-101 获得 20.4%前 1 名和 5.3%前 5 名错误率,
  • 由于使用更大尺寸的图像进行单作物测试,ResNeXt-101 获得了 19.1%的前 1 名和 4.4%的前 5 名错误率,这比所有最先进的方法、 ResNet预激活 ResNetInception-v3Inception-v4Inception-ResNet-v2 都有更好的结果。

4.2.ImageNet-5K

ImageNet-5K Results (All trained from scratch)

ImageNet-1K 经过这么多年的发展,已经有些饱和了。

ImageNet-5K 是 22K 类 ImageNet 数据集的子集,包含 5000 个类,其中也包含 ImageNet-1K 类。

  • 680 万张图片,是 ImageNet-1K 数据集的 5 倍。
  • 由于没有正式的训练/验证集,因此使用原始的 ImageNet-1K 验证集进行评估。
  • ****5K 级别是超过 5K 级别的soft max。因此,当网络在 ImageNet-1K 验证数据集上预测其他 4K 类的标签时,将会出现自动错误。
  • ****1K 路分类就是超过 1K 级的soft max

ResNeXt 当然得到了比上面显示的 ResNet 更好的结果。

4.3.西法尔-10 和西法尔-100

CIFAR-10 and CIFAR-100 Results

CIFAR-10 & CIFAR-100,两个非常著名的 10 类和 100 类数据集。

  • 左图:与 ResNet 相比,ResNeXt 在 CIFAR-10 中总是获得更好的成绩。
  • 右图:与宽 ResNet (WRN) 相比,ResNeXt-29 (16×64d)对于 CIFAR-10 和 CIFAR-100 分别获得 3.58%和 17.31%的误差。这些是当时所有最先进方法中最好的结果。

4.4.MS COCO 对象检测

MS COCO Objection Detection Results

  • 通过将 ResNet /ResNeXt 插入更快的 R-CNN ,在相似的模型复杂度下,ResNeXt 在所有 IoU 级别的 AP@0.5 (IoU > 0.5)和 mean AP(平均预测)方面始终优于 ResNet

随着 ResNeXt 的成功,它也被 Mask R-CNN 用于实例分割。希望我以后也能报道面具 R-CNN。

参考

【2017 CVPR】【ResNeXt】
深度神经网络的聚合残差变换

我对图像分类的相关综述

[LeNet][AlexNet][ZFNet][VGGNet][SPPNet][PReLU-Net][Google Net/Inception-v1][BN-Inception/Inception-v2][Inception-v3][Inception-v4 [ RoR ] [ 随机深度][WRN][PolyNet][dense net]

我对物体检测的相关评论

[ 更快的 R-CNN

回顾:RoR—ResNet/多级 ResNet(图像分类)

原文:https://towardsdatascience.com/review-ror-resnet-of-resnet-multilevel-resnet-image-classification-cd3b0fcc19bb?source=collection_archive---------15-----------------------

残差网络的一种改进形式

在这个故事里,【残网】是短暂的回顾。ResNet 作为一种先进的深度学习方法获得成功并赢得众多的识别竞赛后,有许多研究致力于如何推广或改进 ResNet ,如预激活 ResNet 、ResNet (RiR)中的ResNet、具有随机深度(SD)的ResNet宽残差网络(WRN) 。RoR 是另一篇改进 ResNet 的论文,他们引入了一个概念,即一组 ResNet 块也可以有一个快捷连接。这使得一个网络成为多级分层 ResNet 。这是一篇 2016 年在 ResNet 之后首次出现,2017 年被接受,最近终于发表在 2018 TCSVT 上的论文,已经被引用了几十次。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. RoR 概念(残差网络中的残差网络)
  2. RoR- m :级别编号m
  3. 不同版本的 RoR
  4. 结果

1。RoR 概念(残差网络的残差网络)

Original ResNet (Left), RoR (Right)

原 ResNet 如左上所示,无数的残差块级联在一起,形成了一个非常深的网络。

在残差块中,有两条路径:

  • 卷积路径执行卷积以提取特征
  • 快捷连接路径将输入信号直接传输到下一层。

利用捷径连接路径,可以减少梯度消失问题,因为误差信号可以在反向传播期间更容易地传播到早期层。

RoR 如右上方所示,提出我们也可以有跨越一组剩余区块的捷径连接。在此之上,我们还可以有跨越一组“剩余块组”的另一个级别的快捷连接。

作者认为:

  • RoR 把学习问题转移到学习剩余映射的剩余映射,比原 ResNet简单易学。
  • 并且上部块中的层也可以将信息传播到下部块中的层

2.RoR- m :级别号 m

级别编号m介绍:

  • m = 1 时,RoR 只有末级快捷方式,即原剩余网络。
  • m = 2 时,RoR 只有根级(最外层),以及末级快捷方式。
  • m = 3 时,RoR 有根级中层末级快捷方式。

对于中层快捷方式,每个快捷方式将跨越具有相同大小的特征图的剩余块。

并且也测试了 m = 4 和 5,但是在论文中没有关于它的任何细节。尽管如此,与 mm= 3 相比,结果还是不够好。

3.不同版本的 RoR

RoR-3 Using Original ResNet (Left), RoR-3 Using Pre-Activation ResNet or WRN (Right)

如上所示,RoR 适用于 ResNet 的不同版本。

简单来说,RoR-3 使用 Conv-BN-ReLU。前 RoR-3 使用 BN-ReLU-Conv,而 WRN 是前 RoR-3 的更宽更浅的版本。(如果有兴趣,请阅读我对原创 ResNet预激活 ResNetWRN 的评论。)

4.结果

4.1。CIFAR-10、CIFAR-100、SVHN

  • CIFAR-10 : 10 级数据集
  • CIFAR-100 : 100 级数据集
  • SVHN :街景门牌号数据集

Test Error (%) on CIFAR-10, CIFAR-100, SVHN Dataset

  • RoR-3-164 :通过将 RoR 应用于 164 层 原始 ResNet4.86%22.47% (+SD 表示使用随机深度,以减少过拟合)分别得到 CIFAR-10 和 CIFAR-100 数据集的测试误差。(164 是模型深度。)
  • Pre-RoR-3-164+SD :通过将 RoR 替换为 预激活 ResNet4.51%21.94% 分别得到 CIFAR-10 和 CIFAR–100 数据集的测试误差。
  • RoR-3–wrn 40–4+SD:通过 预激活 ResNet 替换为更宽的 40 层wrn 40–44.09%20.11% 得到 CIFAR-10 和 CIFAR–100 数据集的测试误差
  • RoR-3–wrn 58–4+SD:用更深的 58 层【WRN-58–43.77%****19.73%分别得到了 CIFAR-10 和 CIFAR–100 数据集的测试误差。

4.2.ImageNet

ImageNet:ils vrc 中的 1000 级大规模数据集。

10-Crop Testing of Validation Error (%) on ImageNet Dataset

RoR-3 的不同层版本始终优于 ResNet 的不同层版本。

文中有详细的烧蚀实验。如果有兴趣,请访问该文件。

使用长短跳跃连接的类似方法也已经应用于生物医学图像分割。希望我也能报道它。

参考

【2018 TCSVT】【RoR】
残差网络残差网络:多级残差网络

我对图像分类的相关综述

[LeNet][AlexNet][ZFNet][VGGNet][SPPNet][PReLU-Net][Google Net/Inception-v1][BN-Inception/Inception-v2][Inception-v3][Inception-v4

点评:sharp mask—2015 年 COCO 细分(实例细分)亚军

原文:https://towardsdatascience.com/review-sharpmask-instance-segmentation-6509f7401a61?source=collection_archive---------12-----------------------

一个细化模块,一个编码器解码器架构脸书 AI Research (FAIR)

在这个故事里, SharpMask ,由脸书 AI Research (FAIR) 进行点评。编码器解码器架构从 2016 年开始普及。通过将自顶向下传递的特征映射连接到自底向上传递的特征映射,可以进一步提高性能。

  • 对象检测:识别对象类别,并使用图像中每个已知对象的边界框定位位置。
  • 语义分割:为图像中每个已知的物体识别每个像素的物体类别。标签是类感知的。
  • 实例分割:识别图像中每个已知对象的每个像素的每个对象实例。标签是实例感知的。

Object Detection (Left), Semantic Segmentation (Middle), Instance Segmentation

SharpMask 在 MS COCO 分段挑战中获得第二名,在 MS COCO 检测挑战中获得第二名。已在 2016 ECCV 发表,引用 200 余次。( Sik-Ho Tsang @中)

  • MS COCO 的平均召回率提高了 10–20%。
  • 通过优化架构,速度比 DeepMask 提升 50%。
  • 通过使用额外的图像比例,小物体召回率提高了约 2 倍。
  • 通过将 SharpMask 应用到快速 R-CNN 上,对象检测结果也得到改善。

涵盖哪些内容

  1. 编码器解码器架构
  2. 一些细节
  3. 架构优化
  4. 结果

1。编码器解码器架构

Architectures for Instance Segmentation

(一)传统的前馈网络

  • 该网络包含一系列卷积层汇集阶段交错,减少了特征图的空间维度,随后是一个全连接层以生成对象遮罩。因此,每个像素预测都基于对象的完整视图,然而,由于多个池阶段,其输入特征分辨率较低。
  • 这种网络架构类似于深度屏蔽方法。

  • 深度蒙版仅粗略对齐对象边界。
  • 锐化掩模产生更清晰、像素精确的对象掩模。

(b)多尺度网络

  • 这种架构相当于从每个网络层进行独立预测,并对结果进行上采样和平均。
  • 这种网络架构类似于 FCN累积视觉 1 方法(注意:它们不是用于实例分割)。

(c)编码器解码器网络和(d)细化模块

  • 在自底向上通过(网络左侧)的一系列卷积之后,特征图非常小。
  • 这些特征图在自上而下的通道(网络的右侧)**使用 2 倍双线性插值进行 3×3 卷积和逐渐上采样 **
  • 除此之外,在上采样之前,在自下而上的过程中的对应的相同大小的特征图 F连接到自上而下的过程中的掩模编码特征图 M
  • 在每次拼接之前,还要对 F 进行 3×3 卷积,以减少特征图的数量,因为直接拼接计算量很大。
  • 串联也被用于许多深度学习方法,如著名的 U-Net
  • 并且作者重构了精化模块,这导致了更有效的实现,如下所示:

(a) Original (b) Refactored but equivalent model that leads to a more effcient implementation

2。一些细节

使用 ImageNet-预训练的 50 层 ResNet

两阶段训练

首先,模型被训练以使用前馈路径联合推断粗略的逐像素分割掩模和对象分数。第二,前馈路径被“冻结”并且精化模块被训练。

  • 可以获得更快的收敛。
  • 我们可以仅使用前向路径得到粗略的掩码,或者使用自下而上和自上而下的路径得到清晰的掩码。
  • 一旦前向分支已经收敛,整个网络的微调增益是最小的。

在全图推理过程中

  • 只有最有希望的位置被细化。优化了前 N 个评分建议窗口。

3.架构优化

要求降低网络的复杂性。并且发现deep mask40%的时间用于特征提取,40%用于掩膜预测,20%用于评分预测。

3.1.主干架构

  • 输入尺寸 W :减小 W 会降低步幅密度 S,从而进一步损害准确性。
  • 汇集层 P :更多的汇集层 P 导致更快的计算,但也导致特征分辨率的损失。
  • 步幅密度 S :在保持 W 不变的情况下使步幅加倍会大大降低性能
  • 深度 D
  • 特征通道 F

Results for Various W, P, D, S, F

  • W160-P4-D39-F128: 获得速度和精度的权衡。
  • 最上面一行和最后一行分别是使用不包括时间分数预测时间的多尺度推理的深度掩码和夏普掩码(即 W160-P4-D39-F128)的定时。
  • 深度蒙版和锐度蒙版的总时间分别为每张图像 1.59 秒和 0.76 秒。这意味着深度遮罩和锐度遮罩的 FPS 分别约为 0.63 FPS 和 1.32 FPS。

3.2.头部结构

头部架构也消耗了模型的一定复杂度。

Various Head Architecture

  • (a):原始深度遮罩头部架构获取遮罩并评分。
  • (b)到(d):各种公共共享 conv 和全连接层,以获得遮罩和分数。

Results for Various Head ARchitectures

  • 选择磁头 C 是因为其简单性和时间性。

3.3.不同 Conv 的特征地图数量

  • (a)对于所有卷积,特征图的数量是相同的。
  • (b)特征图的数量沿自下而上的路径减少,沿自上而下的路径增加。
  • 和(b)具有更短的推断时间和相似的 AUC(在 10,100,1000 个建议时 ar 的平均值)。

4.结果

4.1.COCO 女士细分

Results on MS COCO Segmentation

  • 深面具-我们的 : 深面具躯干和头部优化,比深面具好。
  • 比以前最先进的方法更好
  • SharpMaskZoom&SharpMaskZoom:带有一个或两个额外的更小的缩放比例,并实现了对小对象的 AR 的大幅提升。

4.2.2015 年可可小姐挑战赛中的物体检测和结果

Results on MS COCO

顶端

中间

  • SharpMask+MPN(另一个主干称为 MultiPathNet),它在 COCO 女士分割挑战中获得第二名。

底部

  • 夏普面具+MPN,在可可小姐探测挑战中获得第二名,比离子强。

但那一刻 SharpMask 只用 VGGNet 做骨干。因此,结果是低劣的。

4.3.定性结果

SharpMask proposals with highest IoU to the ground truth on selected COCO images. Missed objects (no matching proposals with IoU > 0:5) are marked in red. The last row shows a number of failure cases.

通过逐渐上采样,早期特征图与后期特征图连接,SharpMask 优于 DeepMask

参考

【2016 ECCV】【sharp mask】
学习提炼对象片段

我的相关评论

)(我)(们)(都)(不)(想)(到)(这)(些)(人)(,)(我)(们)(都)(不)(想)(要)(到)(这)(些)(人)(,)(但)(是)(这)(些)(人)(还)(不)(想)(到)(这)(些)(人)(,)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(们)(就)(想)(到)(了)(这)(些)(人)(们)(,)(我)(们)(们)(都)(不)(想)(要)(到)(这)(些)(人)(,)(但)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(里)(来)(。 )(我)(们)(都)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(。

物体检测 过食R-CNN快 R-CNN快 R-CNNDeepID-NetR-FCNyolo v1SSDyolo v2/yolo 9000

语义切分
[FCN][de convnet][deeplabv 1&deeplabv 2][parse net][dilated net][PSPNet]

生物医学图像分割 cumed vision 1cumed vision 2/DCANU-NetCFS-FCN

实例分割 深度遮罩

回顾:固态硬盘—单次检测器(物体检测)

原文:https://towardsdatascience.com/review-ssd-single-shot-detector-object-detection-851a94607d11?source=collection_archive---------2-----------------------

T his time, SSD(单发探测器)回顾。通过使用 SSD,我们只需要拍摄一张照片来检测图像内的多个对象,而基于区域提议网络(RPN)的方法,如 R-CNN 系列,需要拍摄两张照片,一张用于生成区域提议,一张用于检测每个提议的对象。因此,与基于双镜头 RPN 的方法相比,SSD 要快得多。

SSD300 在 59 FPS 时实现了 74.3%的 mAP,而 SSD500 在 22 FPS 时实现了 76.9%的 mAP,其性能优于更快的 R-CNN(7 FPS 时 73.2%的 mAP)yolov 1(45 FPS 时 63.4%的 mAP)。下面是一个使用 MobileNet 进行特征提取的 SSD 示例:

SSD

从上面我们可以看到惊人的实时性能。而 SSD 是我写这个故事的时候 2016 ECCV 一篇超过 2000 引用的论文。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. 多箱探测器
  2. SSD 网络架构
  3. 损失函数
  4. 默认框的比例和长宽比
  5. 培训的一些细节
  6. 结果

1.多箱探测器

SSD: Multiple Bounding Boxes for Localization (loc) and Confidence (conf)

  • 经过一定的卷积进行特征提取后,我们得到一个尺寸为 m × n (位置数)的特征层,具有 p 通道,如上面的 8×8 或 4×4。并且在这个m×n×p特征层上应用 3×3 conv。
  • 对于每个位置,我们得到了 k 个包围盒。这些 k 个边界框具有不同的大小和纵横比。这个概念是,也许一个垂直的长方形更适合人类,一个水平的长方形更适合汽车。
  • 对于每个边界框,我们将计算 c 类分数和相对于原始默认边界框形状的 4 个偏移量。
  • 因此,我们得到了(c+4)kmn输出。

这也是论文被称为“SSD:单拍多盒探测器”的原因。但以上只是 SSD 的一部分。

2. SSD 网络架构

SSD (Top) vs YOLO (Bottom)

为了有更精确的检测,不同层的特征图也通过一个小的 3×3 卷积来进行对象检测,如上所示。

  • 比如说在 Conv4_3,尺寸是 38×38×512采用 3×3 conv。并且有 4 个边界框每个边界框将有(类+ 4)个输出。因此,在 Conv4_3,输出为 38×38×4×( c +4)。假设有 20 个对象类加上一个背景类,输出为 38×38×4×(21+4)= 144400。就包围盒的数量而言,有 38×38×4 = 5776 个包围盒。
  • 类似地,对于其他 conv 层:
  • Conv7: 19×19×6 = 2166 盒(每个位置 6 盒)
  • Conv8_2: 10×10×6 = 600 盒(每个位置 6 盒)
  • Conv9_2: 5×5×6 = 150 盒(每个位置 6 盒)
  • Conv10_2: 3×3×4 = 36 盒(每个位置 4 盒)
  • Conv11_2: 1×1×4 = 4 盒(每个位置 4 盒)

如果把它们加起来,我们总共得到了 5776+2166+600+150+36+4 =8732 箱。如果我们记得 YOLO,最后有 7×7 个位置,每个位置有 2 个边界框。YOLO 只有 7×7×2 = 98 盒。因此 SSD 有 8732 个包围盒,比 YOLO 多。

3.损失函数

损失函数包括两项:Lconf 和 Lloc,其中 N 是匹配的默认框。匹配的默认框

Localization Loss

Lloc 是定位损失,它是预测框(l)和地面实况框(g)参数之间的平滑 L1 损失。这些参数包括边界框的中心点(cx,cy)、宽度(w)和高度(h)的偏移量。这种损失与更快的 R-CNN 中的损失类似。

Confidence Loss

Lconf 是置信度损失,它是多个类别置信度(c)的软最大损失。(通过交叉验证将α设置为 1。) xij^p = {1,0},是将类别 p 的第 i 个默认框匹配到第 j 个真实框的指示器。

4。默认框的比例和长宽比

Scale of Default Boxes

假设我们有 m 个特征图用于预测,我们可以计算第 k 个特征图的 Sk 。Smin 是 0.2,Smax 是 0.9。这意味着最低层的比例为 0.2,最高层的比例为 0.9。中间的所有层都是规则间隔的。

对于每个比例 sk,我们有 5 个非方形纵横比:

5 Non-Square Bounding Boxes

对于 1:1 的纵横比,我们得到 sk ':

1 Square Bounding Box

因此,我们总共最多可以有 6 个不同纵横比的边界框。对于只有 4 个边界框的层,ar = 1/3,省略 3。

5.训练的一些细节

5.1 硬负开采

我们没有使用所有的负面例子,而是使用每个默认框的最高置信损失对它们进行排序,并挑选出顶部的例子,这样负面和正面之间的比率最多为 3:1。

这可以导致更快的优化更稳定的训练

5.2 数据扩充

每个训练图像通过以下方式随机采样:

  • 整个原始输入图像
  • 对面片进行采样,使其与对象的重叠为 0.1、0.3、0.5、0.7 或 0.9。
  • 随机抽取补丁样本

每个采样面片的大小为【0.1,1】或原始图像大小,纵横比从 1/2 到 2 。在上述步骤之后,每个采样的小块将被调整到固定的大小,并且除了一些光度量失真【14】之外,还可能以 0.5 的概率水平翻转。

5.3 阿特鲁卷积(空洞算法/扩张卷积)

基本网络是 VGG16 ,并使用 ILSVRC 分类数据集进行预训练。 FC6 和 FC7 变为卷积层,分别为 Conv6 和 Conv7 ,如上图所示。

此外, FC6 和 FC7 使用阿特鲁卷积(又名空洞算法或扩张卷积)代替常规卷积。 pool5 由 2×2-s2 改为 3×3-s1

Atrous convolution / Hole algorithm / Dilated convolution

正如我们所见,特征图在 Conv6 和 Conv7 处较大,使用如上所示的阿特鲁卷积可以增加感受野,同时保持参数数量相对较少。(我希望在未来的日子里,我可以回顾一下 DeepLab,以更详细地介绍这一点。)

6.结果

有两种型号:SSD300 和 SSD512。
SSD300: 300×300 输入图像,分辨率更低,速度更快。
SSD512: 512×512 输入图像,分辨率更高,更精确。让我们看看结果。

6.1 模型分析

Model Analysis

  • 数据扩充至关重要,它将 mAP 从 65.5%提高到 74.3%。
  • 随着更多的默认框形状,它从 71.6%提高到 74.3%的地图。
  • 阿特鲁的情况也差不多。但是没有 atrous 的要慢 20%左右。

Multiple Output Layers at Different Resolutions

随着 conv 图层的输出越来越多,包含的边界框也越来越多。正常情况下,准确率从 62.4%提高到 74.6%。然而,conv 11 _ 2 的加入使结果变得更糟。作者认为盒子不够大,无法覆盖大型物体。

6.2 帕斯卡 VOC 2007

Pascal VOC 2007 Dataset

如上图,SSD512 有 81.6%的 mAP。SSD300 具有 79.6%的 mAP,这已经优于 78.8%的更快的 R-CNN。

6.3 帕斯卡 VOC 2012

Pascal VOC 2012 Dataset

SSD512 (80.0%)比更快的 R-CNN (75.9%)准确率高 4.1%。

6.4 可可女士

MS COCO Dataset

SSD512 在 mAP@0.5 中只比更快的 R-CNN 好 1.2%。这是因为对于较大的对象,它具有好得多的 AP (4.8%)和 AR (4.6%),但是对于小对象,它在 AP (1.3%)和 AR (2.0%)方面的改善相对较小。

更快的 R-CNN 在使用 SSD 的较小对象上更具竞争力。作者认为,这是由于基于 RPN 的方法,其中包括两个镜头。

6.5 ILSVRC DET

在 SSD300 上获得初步结果:在 val2 集合上获得 43.4%的 mAP。

6.6 小物体精度的数据扩充

为了克服第 6.4 节中提到的对小目标漏检的弱点,进行了“缩小”操作以创建更多的小训练样本。跨多个数据集实现了 2%-3%的 mAP 增长,如下所示:

Data Augmentation for Small Object Accuracy

6.7 推理时间

Inference Time

  • 批量大小为 1 时,SSD300 和 SSD512 分别可以获得 46 和 19 FPS。
  • 在批量大小为 8 的情况下,SSD300 和 SSD512 分别可以获得 59 和 22 FPS。

Some “Crazy” Detection Results on MS COCO Dataset

SSD300 和 SSD512 都有较高的 mAP 和较高的 FPS。因此,SSD 是需要研究的目标检测方法之一。顺便说一下,我希望将来能报道 DSSD。

参考

【2016 ECCV】【SSD】
SSD:单发多盒探测器

我的相关评论

[ R-CNN ] [ 快速 R-CNN ] [ 更快 R-CNN][yolov 1][VGGNet]

综述:随机深度(图像分类)

原文:https://towardsdatascience.com/review-stochastic-depth-image-classification-a4e225807f4a?source=collection_archive---------12-----------------------

在这个故事里,随机深度是简短回顾。随机深度,一个训练短网络的训练程序,在测试时使用深度网络。这是由困境所激发的:

使用深度模型:我们可以得到更好的预测精度,但是由于梯度消失问题,很难训练。

使用更浅的模型:我们可以更容易地训练网络,但预测精度有时不够好。

Can we?

通过使用随机深度,网络在训练过程中被缩短,即,层的子集被随机丢弃,并通过身份函数绕过它们。并且在测试/推断期间使用完整的网络。通过这种方式:

  • 培训时间大幅减少
  • 测试误差也显著改善

这是我写故事的时候在 2016 ECCV 上的一篇论文,有大约 400 次引用。( Sik-Ho Tsang @中)

涵盖哪些内容

  1. ResNet 的简要修改
  2. ResNet 带随机深度
  3. 一些结果和分析

1.原始 ResNet 的简要修订

One l-th Residual Block (ResBlock) in Original ResNet

ResNet 中,假设 H _ l-1 是上述 ResBlock 的输入, H _ l-1 会经过两条路径。

  • 上路径f _ l(H_l-1):conv>BN>ReLU>conv>BN
  • 下部路径 id(H_l-1):标识路径不修改输入

然后这两路的输出加在一起,然后 ReLU,变成 H _ l

通过使用相同路径,即跳过连接或快捷连接,我们可以保持输入信号,并试图避免梯度消失问题。最后,我们可以获得一个非常深的模型。

然而,这种深度模型的训练时间

此外,可能会有过度拟合问题

2.具有随机深度的 ResNet

2.1.培养

Some ResBlocks are Dropped Randomly Based on Bernoulli Random Variable

Linear Decay Rule

通过使用随机深度,在训练期间,对于每个小批量,每个 ResBlock 将具有“存活”概率 p _ l.

如果幸存下来,它会被保存下来。否则如上所示跳过。

用随机深度训练的网络可以被解释为不同深度的网络的隐含集合。

决定 p _ l

  • 一种是沿整个模型有 p _ l定值
  • 一个是沿着整个模型对 p _ l线性衰减规则

如果使用线性衰减规则,较早(较深)的层有更大的机会幸存(跳过),如上例所示。

训练时,预期网络深度比整个网络深度短。若全网深度 L =110, p_L =0.5,则期望网络深度 E(L’)= 40。因此,训练时间要短得多。

2.2。测试

Weighted by p_l during testing

测试期间的随机深度需要对网络进行小的修改。因为在训练期间,函数 f _ l 仅在所有更新的一小部分 p _ l 内有效,并且下一层的相应权重被校准用于该生存概率。因此,我们需要根据任何给定函数 f _ l 参与训练的预期次数 p _ l 来重新校准其输出。

3.一些结果和分析

CIFAR10, CIFAR100, ImageNet Results

3.1.西法尔-10,西法尔-100,SHVN

例如在图的左上方:

  • 恒定深度的训练损失< Training loss of Stochastic Depth
  • Test loss of constant depth (6.41%) >随机深度的测试损失(5.25%)
  • 这意味着随机深度减少了过度拟合。

使用 110 或 1202 层模型的 CIFAR-100 和 SHVN 的趋势相似。

Training Time

  • 训练时间也缩短了很多。

3.2.ImageNet

对于图右下方的 ImageNet:

  • 虽然验证误差非常接近(恒定深度为 23.06%,随机深度为 23.38%),但是训练时间缩短了 25%。
  • 如果训练时间相等,最终误差为 21.98%。

以下是每个数据集的详细结果:

Detailed Results for Each Dataset

3.3.分析

Mean Gradient Magnitude

通过查看每个时期的平均梯度幅度,随机深度始终比恒定深度具有更大的权重。这意味着,梯度消失问题在随机深度中不太严重。

Test Error vs Survival Probability (Left), and Test Error Heatmap with P_L vs Network Depth (Right)

对于左侧的测试误差与生存概率:

  • 两种分配规则(线性衰减和均匀分配)都比恒定深度产生更好的结果。
  • 线性衰减规则始终优于均匀规则。
  • p _ L 在 0.4 到 0.8 范围内时,线性衰减法则获得竞争结果。
  • p_L= 0.2的情况下,线性衰减的随机深度仍然表现良好,同时给出训练时间减少 40%**。

对于右侧的热图:

  • p_L= 0.5 的较深网络更好。
  • 一个足够深的模型是随机深度显著优于基线所必需的。

除了丢弃之外,我们还可以通过使用随机深度来减少网络深度,从而减少过拟合,从而丢弃一些模块。

参考

【2016 ECCV】【随机深度】
深度随机的深度网络

我的相关评论

)(我)(们)(都)(不)(想)(到)(这)(些)(人)(,)(我)(们)(都)(不)(想)(到)(这)(些)(人)(,)(但)(是)(这)(些)(人)(还)(有)(什)(么)(情)(况)(呢)(?)(我)(们)(都)(不)(想)(到)(这)(些)(人)(了)(,)(我)(们)(还)(没)(想)(要)(到)(这)(些)(人)(,)(我)(们)(还)(没)(想)(要)(到)(这)(些)(人)(,)(我)(们)(就)(不)(能)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(里)(来)(。

回顾:Trimps-Soushen——2016 年 ILSVRC(图像分类)获奖者

原文:https://towardsdatascience.com/review-trimps-soushen-winner-in-ilsvrc-2016-image-classification-dfbc423111dd?source=collection_archive---------8-----------------------

深度特征融合的良好实践:第一个获得 3%以下的错误率(当人类性能只能获得 5%时)

Trimps Is Active at Different Technology Aspects http://news.sina.com.cn/c/2017-09-17/doc-ifykynia7850053.shtml

In this story, the approach by the winner, Trimps-Soushen, in ILSVRC 2016 classification task, is reviewed. Trimps stands for The Third Research Institute of Ministry of Public Security, or in chinese 公安部三所. In brief, Trimps is the research institute for advancing the technologies for public security in China, which was launched in 1978 at Shanghai. Soushen should be the team name under Trimps, in chinese 搜神. It means god of search, where Sou (搜) means search and Shen (神) means god. (Sik-Ho Tsang @ Medium)

Trimps-Soushen 在 2016 年赢得了多项比赛:

  • 物体定位:第一名,7.71%误差
  • 物体分类:第一名,2.99%误差
  • 物体检测:第三名,61.82%地图
  • 场景分类:第三名,误差 10.3%
  • 视频目标检测:第三名,70.97%地图

ILSVRC 2016 Classification Ranking http://image-net.org/challenges/LSVRC/2016/results#loc

ILSVRC Classification Results from 2011 to 2016

虽然 Trimps-Soushen 在多个识别任务上拥有最先进的成果,但Trimps-Soushen没有新的创新技术或新颖性。可能因为这个原因,他们没有发表任何关于它的论文或技术报告。

相反,他们只在 2016 年 ECCV 的 ImageNet 和 COCO 联合研讨会上分享了他们的成果。他们有一些关于数据集的有趣事实。

涵盖哪些内容

  1. 使用不同模型的集成(图像分类)
  2. 基于前 20 名准确度的一些发现(图像分类)
  3. 区域融合(图像定位)
  4. 用于其他任务的多模型融合(场景分类/对象检测/从视频中检测对象)

1.使用不同模型的集成

ImageNet Classification Errors for Top-10 Difficult Categories

Trimps-Soushen 使用了来自 Inception-v3Inception-v4Inception-ResNet-v2预激活 ResNet-200Wide ResNet(WRN-68–2)的预训练模型进行分类,并找出了如上的前 10 个困难类别。

  • 获得了不同的结果,这意味着没有模型在所有类别中占主导地位。每个模型都擅长对某些类别进行分类,但也擅长对某些类别进行分类。
  • 模型的多样性可以用来提高精确度。

在培训期间,Trimps-Soushen 只是进行了多规模扩增和大迷你批量。在测试期间,多尺度+翻转与密集融合一起使用。

ImageNet Top-5 Error Rate Results

  • 5 个最佳模型的验证误差为 3.52%-4.65%。
  • 通过组合这 5 个模型( Inception-ResNet-v2 具有更高的权重),获得了 2.92%的验证误差。
  • 获得了 2.99%的测试误差,这是第一个在 3%误差率下获得的测试误差。

2.基于前 20 名准确度的一些发现

Top-k Accuracy

Top- k 精度如上图所示。当 k =20 时,获得 99.27%的精度。误差率小于 1%。

为什么使用 Top-20 精度仍有误差?

Trimp-Soushen 非常详细地分析了这些 1%的误差图像!!!

他们从验证集中手动分析了 1458 个错误图像。大致得到 7 类误差如下:

7 Error Categories

2.1.标签可能有误

Label May Wrong (Maybe it is really a sleeping bag for Hello Kitty? lol)

地面真相是睡袋,但显然,它是一个铅笔盒!!!!

这是因为地面真相在 ImageNet 数据集中是手动标注的。由于 ImageNet 是一个包含超过 1500 万个带标签的高分辨率图像的数据集,约有 22,000 个类别,并且 1000 个类别的 ImageNet 数据集的子集用于竞争,因此可能会有一些错误的标签。

在 1458 幅错误图像中,有 211 幅是“标签可能错误”,约占 15.16%。

2.2.多个对象(> 5)

Multiple Objects (>5) (Which is the main object?)

上图包含多个对象(> 5)。实际上,这种图像不适合于 ILSVRC 分类任务。因为在 ILSVRC 分类任务中,对于每幅图像应该只识别一个类别。

在 1458 幅错误图像中有 118 幅是“多物体(> 5)”,约占 8.09%。

2.3.不明显的主要对象

Non-Obvious Main Object (Please find the paper towel in the image, lol !!)

由于在分类任务中应该只识别一个类别,所以上面的图像在图像中没有一个明显的主要对象。可以是船,也可以是码头。但事实是纸巾。

在 1458 幅错误图像中,有 355 幅是“非明显主目标”,约占 24.35%。

2.4.混淆标签

Confusing Label (Maybe there is no sunscreen inside, lol.)

事实是防晒霜。这一次,标签似乎是正确的,因为纸箱上说的 SPF30。但任务将变成理解纸箱上文字的含义,这与基于形状和颜色识别物体的最初目标相去甚远。

1458 幅错误图像中有 206 幅是“混淆标签”,约占 14.13%。

2.5.细粒度标签

Fine-Grained Label

事实是正确的。牛肝菌和臭牛肝菌都是真菌的种类。事实上,这种类型的标签甚至很难被人类识别。

1458 幅错误图像中有 258 幅是“细粒度标签”,约占 17.70%。

网络可以改善这个范畴。

2.6.明显错误

Obvious Wrong

事实是正确的。即使使用前 20 名预测,网络也无法预测它。

1458 幅错误图像中有 234 幅“明显错误”,约占 16.05%。

网络可以改善这个范畴。

2.7.部分对象

Partial Object

图像可能只包含对象的一部分,这很难识别。如果把多张桌椅拉远一点,看起来像个餐厅,可能图像会更好。

在 1458 幅错误图像中,有 66 幅是“部分目标”,约占 4.53%。

所以精度很难提高 1%。

3.区域融合(图像定位)

Region Fusion for Image Localization

为了定位图像中的前 5 个预测标签,使用了使用多个模型的更快的 R-CNN 架构。多个模型用于通过快速 R-CNN 中的区域提案网络(RPN)生成区域提案。然后基于前 5 个分类预测标签,执行定位预测。

Image Localization Top-5 Validation Error Results

  • 以前最先进的方法 : 得到 8.51%到 9.27% 的误差。
  • 集成所有:将所有方法融合在一起,得到 7.58% 误差。
  • 除了一个模型之外的集合:仅获得 7.75%到 7.93%的误差。

因此,模型之间差异是重要的,并有助于预测精度的大幅度提高。

ILSVRC Localization Top-5 Test Error Results from 2012 to 2016

4。用于其他任务的多模型融合(场景分类/对象检测/从视频中检测对象)

4.1.场景分类

Multi-Scale & Multi-Model Fusion for Scene Classification

通过连接结果而不是在网络末端将结果相加,使用改进的多尺度方法。

除了使用相同模型使用多尺度输入进行预测之外,通过连接结果并通过 FC 和 softmax 使用两个训练模型(我相信使用相同的模型网络)。验证误差为 10.80%。

采用 7×2 模型,验证误差为 10.39%,检验误差为 10.42%。

Scene Classification Top-5 Test Error Results

使用外部数据集 Places2 的模型也用于预训练,获得了 10.3%的 top-5 测试误差,在场景分类中获得第三名。

4.2.目标检测

类似于图像定位,更快的 R-CNN 架构用于多模型融合。

Object Detection mAP Results

获得了 61.82%的 mAP。

4.3.视频中的目标检测

Object Detection from Video mAP Results

光流引导的运动预测也用于减少假阴性检测。获得了 70.97%的 mAP。

由于模型的多样性,模型融合是有效的。通过模型融合,Trimps-Soushen 胜过 ResNeXtPolyNet ,获得图像分类第一名。模型融合也被成功地应用到其他任务中。这意味着除了网络架构的创新优化或新颖设计,其他技术东西如多模型融合也可以帮助提高准确性很多

另一方面,如果 Trimps-Soushen 使用ResNeXtpoly net进行模型融合,也许可以进一步减小的误差,因为 ResNeXtPolyNet 比用于模型融合的那些模型获得更高的精度。

参考

【2016 ECCV】【Trimps-Soushen】(仅幻灯片)
深度特征融合的良好实践

我对图像分类的相关综述

[LeNet][AlexNet][ZFNet][VGGNet][SPPNet][PReLU-Net][Google Net/Inception-v1][BN-Inception/Inception-v2][Inception-v3][Inception-v4 [ RoR ] [ 随机深度 ] [ WRN ] [ 波利尼西亚][ResNeXt][dense net]

我对物体检测的相关评论

[ 更快的 R-CNN

综述:U-Net(生物医学图像分割)

原文:https://towardsdatascience.com/review-u-net-biomedical-image-segmentation-d02bf06ca760?source=collection_archive---------4-----------------------

在这个故事中, U-Net 进行了回顾。U-Net 是生物医学图像分割中著名的全卷积网络(FCN)之一,在我写这个故事的时候已经发表在 2015 MICCAI 上,引用超过 3000 次。( Sik-Ho Tsang @中)

在生物医学图像注释领域,我们总是需要获得相关知识的专家来注释每幅图像。而且他们也消耗大量的时间来注释如果注释过程变得自动化,可以减少人力和降低成本。或者可以作为辅助角色减少人为错误

你可能会问:“读生物医学图像分割是不是太狭隘了?”

然而,我们可以学习它的技术,并将其应用于不同的行业。比方说,质量控制/自动检测/施工/制造过程中的自动机器人,或者我们可能想到的任何其他东西。这些活动包括定量诊断。如果我们能使它自动化,就能以更高的精度节省成本。

在这篇论文中,他们分割/注释了电子显微镜(EM)图像。他们还对网络进行了一点点修改,以分割/注释 2015 年 ISBI 的牙齿 x 光图像。

EM Images

涵盖哪些内容

A.EM 图像分割

  1. U-Net 网络体系结构
  2. 重叠平铺策略
  3. 用于数据扩充的弹性变形
  4. 触摸物体的分离
  5. 结果

B.牙科 X 射线图像分割

  1. 对 U-Net 的一些修改
  2. 结果

A.1. U-Net 网络架构

U-Net

U-net 架构如上图。它由收缩路径和膨胀路径组成。

收缩路径

  • 连续完成两次 3×3 Conv2×2 最大汇集。这有助于提取更高级的要素,但也会减小要素地图的大小。

扩展路径

  • 连续进行 2×2 上 conv两次 3×3 Conv 来恢复分割图的大小。然而,上述过程减少了“哪里”,尽管它增加了“什么”。这意味着,我们可以获得高级功能,但我们也失去了本地化信息。
  • 因此,在每个上 conv 之后,我们还有具有相同级别的特征图(灰色箭头)的串联。这有助于给出从收缩路径到膨胀路径的定位信息。
  • 最后, 1×1 conv 将特征图大小从 64 映射到 2,因为输出的特征图只有 2 类,细胞和膜。

A.2 .重叠平铺策略

Overlap Tile Strategy

由于使用了无填充卷积,输出大小小于输入大小。使用重叠瓦片策略,而不是在网络之前缩小尺寸和在网络之后上采样。由此,整个图像被逐部分预测,如上图所示。使用蓝色区域预测图像中的黄色区域。在图像边界,通过镜像外推图像。

A.3 .用于数据扩充的弹性变形

Elastic Deformation

由于训练集只能由专家进行注释,因此训练集很小。为了增加训练集的大小,通过随机变形输入图像和输出分割图来进行数据扩充。

A.4 .触摸物体的分离

Segmentation Map (Left) and Weight Map (Right)

由于接触物体彼此靠近放置,它们很容易被网络合并,为了分离它们,对网络的输出应用权重图。

为了如上计算权重图,d1(x)是到位置 x 处最近的单元边界的距离,d2(x)是到第二最近的单元边界的距离。因此,在边界处,重量比图中高得多。

因此,交叉熵函数在每个位置被权重图惩罚。这有助于迫使网络学习接触细胞之间的小分离边界。

A.5 .结果

A.5.1. ISBI 2012 年奥运会

Some Difficult Parts in EM Images

U-Net has the Rank 1 Result at that moment

  • 扭曲错误:惩罚拓扑不一致的分段度量。
  • Rand Error :两个聚类或分割之间相似性的度量。
  • 像素误差:标准像素误差。
  • 培训时间:10 小时
  • 测试速度:每张图片大约 1 秒

A.5.2. PhC-U373 和 DIC-HeLa 数据集

PhC-U373 and DIC-HeLa Datasets

U-Net 获得了这两个数据集的最高 IoU。

b . 1 . U-Net 的一些修改

Dental X-Ray Image with 7 classes

U-Net for Dental X-Ray Images

这次使用 4×4 上 conv1×1 Conv 来绘制 64 到 7 的特征图,因为每个位置的输出有 7 个等级。

Zero padding instead of mirroring at the image boundary

在重叠平铺策略中,使用零填充代替图像边界处的镜像。因为镜像对牙齿没有任何意义。

Loss function at multiple levels

使用 softmax loss 的低分辨率特征图有附加损失层,以引导深层直接学习分割类。

B.2 .结果

Some Visualization Results

我也复习过 累计视野 1累计视野 2 。如果感兴趣,请随时访问。

参考

我的相关评论

[ 累积视频 1 ] [ 累积视频 2 ] [ FCN ] [ 解除网络

回顾:VDSR(超分辨率)

原文:https://towardsdatascience.com/review-vdsr-super-resolution-f8050d49362f?source=collection_archive---------6-----------------------

T 他的时代, VDSR (极深超分辨率)回顾。VDSR 是一种用于放大图像的深度学习方法。它有 20 个权重层,比只有 3 层的 SRCNN 要深得多。

有时,我们只得到一个很差的图像,我们想进行数字放大(放大),但当放大时图像变得模糊。这是因为常规的插值或放大把一幅小图像变成一幅大图像,会得到很差的图像质量。使用 VDSR,我们可以从低分辨率(LR)图像获得高质量的高分辨率(HR)图像。

下面是两个例子。

VDSR 是经典的最先进的 SR 方法之一,在我撰写本文时,发表在 2016 CVPR 上,被引用约 800 次。( Sik-Ho Tsang @中)

Much Clear Image after Enlargement Using VDSR (Edges are much clearer)

Some More Amazing Results

结果很惊人!!那么,让我们来看看它是如何工作的。

涵盖哪些内容

  1. VDSR 网络架构
  2. 关于培训的一些细节
  3. 结果

1。VDSR 网络架构

VDSR Network Architecture

VDSR 架构如上图所示:

  1. LR 图像插值为 ILR 图像并输入到网络。
  2. ILR 图像经过 (D-1)次 Conv 和 ReLU 层
  3. 然后后面跟着一个 D-th Conv (Conv。图中的 d(残差)。
  4. 最后,输出与 ILR 图像相加,得到 HR 图像

这些是 64 个大小为 3×3 的过滤器,用于每个 conv 层。(VGGNet 已经解决了连续的3×3 滤波器的问题,这有助于获得更大的感受野,因此我们不需要任何大的滤波器,例如 5×5 和 7×7。如果有兴趣,请阅读我的 VGGNet 评论。)

如我们所见,ILR 被添加到网络的输出中,以恢复 HR 图像,损失函数变为:

其中 r=y-x 。因此,网络正在学习输出和输入之间的残差,而不是像 SRCNN 一样直接学习 HR 输出。

Residual vs Non-Residual with Different Learning Rate

有了残差学习,收敛比无残差学习快得多。在第 10 时段,残差已经达到 36 dB 以上,而非残差仍然只有 27-34 dB。

2。关于培训的一些细节

2.1 可调渐变剪辑

梯度被剪裁到[-θ/γ;θ/γ ] ,其中γ表示当前的学习速率。并且 θ被调整得很小,以避免在高学习率状态下爆发梯度

当 D= 20 时,20 层网络训练在 4 小时内完成,而 3 层 SRCNN 需要几天来训练。

2.2 多尺度训练

Mutli-Scale Training Results

当使用单尺度图像时,网络只能在测试期间对相同尺度工作良好,对于其他尺度的测试,PSNR 甚至比传统的双三次插值更差。

通过使用×2、×3、×4 尺度的图像进行训练,在测试过程中所有尺度都获得了最高的峰值信噪比。

Multi-Scale VDSR (Top), Single-Scale Dong’s [5] (Bottom)

单尺度 Dong 的[5]获得模糊的图像,而 VDSR 具有更清晰的边缘。

3.结果

Comparison with State-of-the-art Results (Red: The best, Blue: 2nd Best)

VDSR is much faster than SRCNN

上表显示 t VDSR 用最少的测试时间获得了最好的结果。

随着人工智能芯片组在未来变得流行,VDSR 或其他最先进的方法可以实时应用于图像放大,甚至应用于视频。

参考

  1. 【2016 CVPR】【VDSR】
    使用极深度卷积网络的精确图像超分辨率

我的相关评论

[Sr CNN][fsr CNN][VGGNet]

综述:WRNs —宽残差网络(图像分类)

原文:https://towardsdatascience.com/review-wrns-wide-residual-networks-image-classification-d3feb3fb2004?source=collection_archive---------4-----------------------

T 他的时代, WRNs(广残网)呈现出来。通过加宽残差网络(【ResNet】),在精度相同或精度提高的情况下,网络可以更浅。较浅的网络表示:

  • 层数可以减少。
  • 培训时间也可以缩短。

一个更好的辍学也进行了调查。这是一篇 2016 BMVC 论文,引用 700 余次。虽然这是一篇 2016 年的论文,但他们仍然在 2017 年 6 月继续更新这篇论文。( Sik-Ho Tsang @中)

Various ResNet Blocks

涵盖哪些内容

  1. 残网上的问题(ResNet)
  2. 宽残差网络
  3. 结果

1.关于剩余网络的问题( ResNet

1.1.电路复杂性理论

电路复杂性理论文献表明:

浅电路比深电路需要更多的元件。

残差网络的作者试图使它们尽可能薄,以利于增加它们的深度并具有更少的参数,甚至引入了一个瓶颈块,使 ResNet 块更薄。

1.2.减少特征重用

然而,当梯度流过网络时,没有任何东西迫使它通过剩余块权重,并且它可以避免在训练期间学习任何东西,因此有可能只有几个块学习有用的表示,或者许多块共享非常少的信息,对最终目标贡献很小。这个问题被表述为减少特征重用

2.宽剩余网络

在 WRNs 中,测试了大量参数,如 ResNet 块的设计、ResNet 块内的深度(加深系数 l 和宽度(加宽系数 k )等。

k =1 时,与 ResNet 宽度相同。而k1,比 ResNetk 倍。

WRN- d - k

  • 预激活 ResNet 用于 CIFAR-10、CIFAR-100 和 SVHN 数据集。ImageNet 数据集中使用了原始的ResNet
  • 主要区别在于 预激活 ResNet 具有在卷积之前执行批范数和 ReLU 的结构(即 BN-ReLU-Conv),而原始ResNet具有 Conv-BN-ReLU 的结构。而 预激活 ResNet 一般比原版好,但在 ImageNet 只有 100 层左右的情况下没有明显提升。**

2.1.ResNet 块的设计

WRN-d-2 (k=2), Error Rate (%) in CIFAR-10 Dataset

  • B(3;3) :原始基本块,在第一个图(a)中
  • B(3;1;3) :在两个 3×3 层之间增加一个 1×1 层
  • B(1;3;1) :所有卷积维数相同,拉直**瓶颈**
  • B(1;3) :网络具有交替的 1×1,3×3 卷积
  • B(3;1) :网络具有交替的 3×3,1×1 卷积
  • B(3;1;1) :网络中网络样式块

B(3;3)错误率最小(5.73%)。

注意:深度(层)的数量不同是为了保持参数的数量彼此接近。

2.2.ResNet 块内的卷积层数

WRN-40–2 with different l, Error Rate (%) in CIFAR-10 Dataset

并且两个 3×3 卷积,即 B(3,3)具有最小的错误率。因为所有网络都需要保持接近相同的参数, B(3,3,3)和 B(3,3,3,3)更少,这使得精度下降。并且 B(3) 只有一个 3×3 卷积,这使得特征提取在 ResNet 块内的这种浅网络内无效。****

因此, B(3,3)是最优的,并将在接下来的实验中使用。

2.3.ResNet 块的宽度

Different Width (k) and Depth on CIFAR-10 and CIFAR-100

  • 当宽度增加 1 到 12 倍时,所有具有 40、22 和 16 层的网络看到一致的增益。
  • 另一方面,当保持相同的固定加宽因子 k = 8 或 k = 10 并且将深度从 16 改变到 28 时,有一致的改进,然而当我们进一步将深度增加到 40 时,精度降低。
  • 基于上述结果,选择了三组 wrn 与最先进的方法进行比较。

3.结果

3.1.西法尔-10 和西法尔-100

CIFAR-10 & CIFAR-100

  • ****WRN-40–4:参数(8.9M)比 1001 层 预激活 ResNet (10.2M)少。但是它也降低了错误率。(在 CIFAR-10 上为 4.52%,在 CIFAR-100 上为 21.18%)
  • WRN-16-8 & WRN-28-10 :比 WRN-40–4 更浅更宽,错误率更低。使用较浅的网络,训练时间可以更短,因为无论多宽,并行计算都是在 GPU 上执行的。
  • 并且它是第一篇在没有任何强大数据增强的情况下获得低于 20%的 CIFAR-100 的论文!!!

3.2.拒绝传统社会的人

Dropout in Original ResNet (Left) and Dropout in WRNs (Right)

Dropout Is Better

  • 上图:使用 dropout,可以获得不同深度、k 和数据集的一致增益。
  • 右下:对于辍学,训练损失较高,但测试误差较低,这意味着辍学成功地减少了过拟合。

3.3.ImageNet & COCO

Single Crop Single Model Validation Error, ImageNet

  • 上述网络获得了与原始网络相似的精度,但层数减少了 2 倍。

3.4.训练时间

Training Time for Each Batch with Batch Size of 32, CIFAR-10

  • ****WRN-16–10 和 WRN-28–10:训练时间远低于 1004 层 预激活 ResNet ,错误率更低。
  • ****WRN-40–4:训练时间比 164 层 预激活 ResNet 短,错误率更低。

因为训练需要很多时间,所以可能需要几天甚至几周。当训练集越来越大时,需要一种更好的训练方法。事实上,在最近的研究中,许多研究人员仍然专注于如何减少训练时间或训练次数。

在 WRNs 中,它减少了训练时间,但代价是由于网络的扩大而增加了参数的数量。

参考

【2016 BMVC】【WRNs】
广残网

我对图像分类的相关综述

[LeNet][AlexNet][ZFNet][VGGNet][SPPNet][PReLU-Net][Google Net/Inception-v1][BN-Inception/Inception-v2][Inception-v3][Inception-v4

posted @ 2024-10-13 15:17  绝不原创的飞龙  阅读(0)  评论(0编辑  收藏  举报