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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

ACM 请求:第一次公开和可重复的锦标赛,以共同设计帕累托有效的深度学习(速度、准确性、能量、规模、成本)

原文:https://towardsdatascience.com/acm-request-1st-open-and-reproducible-tournament-to-co-design-pareto-efficient-deep-learning-ea8e5a13d777?source=collection_archive---------6-----------------------

第一届可再生的高质量系统锦标赛(ReQuEST)将在 ASP los’18(ACM 编程语言和操作系统架构支持会议,这是一个跨计算机架构和硬件、编程语言和编译器、操作系统和网络的多学科系统研究的首要论坛)上首次亮相。

ReQuEST 由领先的大学联盟(Washington、Cornell、Toronto、Cambridge、EPFL)和 cTuning 基金会组织,旨在提供一个开源锦标赛框架、一个通用的实验方法和一个开放的存储库,用于对整个软件/硬件堆栈中广泛的现实世界应用程序、模型和库的质量与效率进行持续评估和多目标优化。

ReQuEST 将使用已建立的工件评估方法以及在领先的 ACM/IEEE 会议上验证的集体知识框架来重现结果,在实时仪表板上显示结果,并与社区共享工件。优秀作品将在相关研讨会上展示,并在 ACM 数字图书馆中发表。为了获胜,参赛作品的结果不一定要位于帕累托边界,因为参赛作品也可以因其原创性、可再现性、适应性、可扩展性、可移植性、易用性等而受到称赞。

第一个请求竞赛将专注于图像识别的深度学习,其雄心勃勃的长期目标是建立一个可移植和可定制的“即插即用”AI/ML 算法的公共存储库,这些算法在从物联网到超级计算机的不同数据集、模型和平台上进行了优化(参见现场演示)。正如我们的行业顾问委员会所建议的那样,未来的竞争将考虑其他新兴工作负载。

欲了解更多信息,请访问http://cKnowledge.org/request

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

通过机器学习消除声学噪声

原文:https://towardsdatascience.com/acoustic-noise-cancellation-by-machine-learning-4144af497661?source=collection_archive---------1-----------------------

用 TensorFlow 制作的 DIY 噪声消除系统原型。

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

Image by TheDigitalArtist on Pixabay

在这篇文章中,我描述了我如何通过自己的神经网络建立一个主动噪声消除系统。我刚刚得到了我要分享的第一个结果,但是这个系统看起来像一堆脚本、二进制文件、电线、声卡、麦克风和耳机,所以我还不打算公布任何来源。可能以后吧。

使用 Tensorflow、ALSA、C++ & SIMD 和 Python 的 Pet 项目

在过去的一年里,我一直在构建一个基于人工神经网络的声学噪声消除系统。我是在业余时间做的,所以这就是为什么一个相对小的实验花了这么长时间。我建立的系统是一个概念验证,它显示了神经网络作为噪声消除器的一致性。

我对 ML 最近在像神经风格转移这样的图像处理方面的成就印象深刻。我想:“如果我们用重复的音频噪声模式来教 RNN,以便通过 ANC 来抑制它,会怎么样?”我之前已经在 DSP 上为一些雷达的东西实现了感知器,所以我不担心在实时软件中实现神经网络的必要性。虽然我以前没有和 tensorflow 和 gpu 打过交道,但我渴望用它们做点什么。到目前为止,在我看来,这是一次有趣的旅行,最后我取得了一些成果,并获得了许多开发人员的乐趣。

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

Artificial Brain Denoising

为什么我们需要 ML 来抑制噪声?

现代 ANC 系统成功地抑制了飞机中的平稳噪声。常见的方法包括自适应滤波器,如 LMSRLS 。这种方法的主要缺陷是,它们的核心只是 FIR 滤波器,其系数是不断调整的,并且它仅在几千个样本后才适合噪声。这意味着自适应滤波器开始重新适应环境噪声的每一个变化,即使它在几秒钟前听到了那个模式。由于神经网络能够适应内部结构非常复杂的信号,因此在 ANC 中使用 ML 方法可以提高其性能。

ANC 中的 NN 用于预测在黑噪声与麦克风位置的噪声相遇的时刻的噪声样本值。

我认为室外的噪音,比如大声的排气系统或洗碗机,从广义上来说不是静止的,而是相当重复的,可以相对容易地被神经网络学习到。

测试设置

我的宠物项目作为经典的噪音消除耳机,除了麦克风位于耳罩内**。测试设置看起来简单明了:**

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

我没有把麦克风放在外面(像所有降噪耳机一样),因为我想在更广泛的情况下解决 ANC 问题。这种设置让我可以轻松地根据房间或汽车环境调整代码,因为所有情况下的结构看起来都是一样的。

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

软件布局

该软件由三个进程组成:

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

  • C++程序进行实时信号处理,
  • 管理者是用 tensorflow 教 NN 的 Python 脚本,
  • 学习者是另一个管理整个过程的 Python 脚本。

管理器脚本通过 gprc 与他人通信。

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

DIY mic-preamp and my old and dirty audio-technica ATH-910PRO

麦克风前置放大器和耳机连接到声卡,声卡通过 USB 连接到装有 Linux Mint 17 的笔记本电脑。

麦克风测量噪声和黑噪声的组合。然后 C++程序做以下事情:

  1. 读取样本,
  2. 分离外部噪声和来自耳机的反信号,
  3. 将噪声样本传递到神经网络的前馈通道以获得黑噪声样本,
  4. 将 NN 产生的黑噪声样本回放到耳机,
  5. 通过管理器脚本将噪声样本传输到学习器脚本,从管理器获取新的神经网络系数。

我站在离耳机几米远的地方,用手机播放噪音。这种结构成功抑制了不同的噪音模式,甚至是像一束束鼻窦这样的非平稳信号,可以用手随意打开和关闭。

内部细节

输入声音以 48 kHz、16 位宽采样。它被代码向下采样 8x 倍,并被转发到分离器。

需要分离器将外部噪声与输入样本隔离,就好像没有信号反馈到耳机一样。

感知器是我自己用 C++实现的,为了满足实时处理的要求,内置了 SIMD 指令。感知器由两个隐藏层组成:

  • 输入层 tanh[304 x 64]采用之前隔离的外部噪声的最后 304 个样本。
  • 中间层 tanh[64 x 64]。
  • 输出图层是线性的[64 x 1]。

这是一个相对较小的网络,能够管理最近 304 个样本的范围。它实现简单,只需 30-60 秒就能学会。我要把它升级成某种递归变体,我已经在 Jupyter 笔记本上检查了 RNN 模型适应一些复杂声音的能力。它看起来很有希望,但需要更多的时间来收敛。希望以后写一篇关于这个笔记本的帖子。

输出信号被上采样 8 倍并发送给耳机。

与此同时,该程序正在向 python 脚本发送大量外部噪声样本,该脚本不断调整感知器的权重以适应新测量的噪声模式,并将其发送回 c++程序。我在带有 GPU 的虚拟机中的云中运行这个 python 脚本。顺便说一句,我发现 Paperspace 是最适合 ML 实验的!下面是我的推荐链接

结果

这是一些展示已有成果的图表。这个数据是来自 C++程序的一个日志,现在还没有客观的测量。然而,我试着把这个耳机戴在头上,它看起来就像剧情显示的那样工作。

条款

黑噪声是送到麦克风的信号。

纯噪声是被分离器隔离的外部噪声。

转换到麦克风输入端的黑噪声是分离器分离出的信号的剩余部分。

samples_in 是麦克风测得的原始声音样本(当然是 8 倍下采样)。

下面是感知器如何感知输入并开始操作的示意图。

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

Single sine-wave @ 880 Hz

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

Multiple sine-waves and longer period of time.

激活功能

原文:https://towardsdatascience.com/activation-functions-b63185778794?source=collection_archive---------5-----------------------

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

那么,为什么我们的神经网络中需要激活函数呢?

欢迎来到我的第一篇帖子!我是一名数据科学家,也是媒体博客的积极读者。现在,我正计划使用 Medium blog 来记录我在学习深度学习方面的旅程,并通过我一直在从事的项目来分享我的经验。希望通过分享我对这些主题的看法,我也可以从 Medium 上奇妙的数据科学/深度学习社区中学习!我很想听到你对我第一篇文章的反馈。说到这里,让我们开始吧…

神经网络如何学习的基本思想是——我们有一些输入数据,我们将其输入网络,然后我们逐层执行一系列线性操作,并得出一个输出。对于特定层的一个简单情况是,我们将输入乘以权重,添加偏差并应用激活函数,然后将输出传递给下一层。我们不断重复这个过程,直到我们到达最后一层。最终值是我们的输出。然后,我们计算“计算输出”和“真实输出”之间的误差,然后计算该误差相对于每层参数的偏导数,并相应地不断更新参数!

神经网络被称为通用函数逼近器。神经网络的主要潜在目标是学习复杂的非线性函数。如果我们在多层神经网络中不应用任何非线性,我们只是试图使用线性超平面来分离类别。正如我们所知,在现实世界中没有什么是线性的!

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

Source: Google

同样,假设我们执行如上所述的简单线性运算,即:将输入乘以权重,加上偏差,并对到达神经元的所有输入求和。在某些情况下,上面导出的输出可能会取较大的值。当这个输出被输入到下一层时,它们可以被转换成更大的值,使得计算变得不可控。这是激活函数发挥主要作用的地方,即把一个实数压缩到一个固定的区间(例如在-1 和 1 之间)。

让我们看看不同类型的激活函数以及它们之间的比较:

乙状结肠:

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

sigmoid 激活函数具有数学形式“sig(z) = 1/ (1 + e^-z)`.正如我们所看到的,它基本上接受一个实数值作为输入,并在 0 和 1 之间压缩它。它也经常被称为挤压功能。其目的是在输入空间中引入非线性。非线性是我们摇摆的地方,网络学习捕捉复杂的关系。从上面的数学表示可以看出,通过 sigmoid 函数的大负数变成 0,大正数变成 1。由于这一特性,sigmoid 函数通常有一个非常好的解释,即神经元的放电频率;从根本不触发(0)到以假定的最大频率完全饱和触发(1)。然而,随着时间的推移,由于以下两个主要缺点,sigmoid 激活函数变得不太流行:

  • 杀伤梯度:
    乙状结肠神经元在边界上饱和,因此这些区域的局部梯度几乎为零。为了让您更直观地理解这一点,请考虑 sigmoid 函数的输入为+15 和-15。sigmoid 函数的导数是‘SIG(z)*(1—SIG(z))’。如上所述,大的正值被挤压在 1 附近,大的负值被挤压在 0 附近。因此,有效地使局部梯度接近 0。结果,在反向传播期间,该梯度被乘以最终目标函数的该神经元输出的梯度,因此它将有效地“杀死”梯度,并且没有信号将通过神经元流向其权重。此外,我们必须注意初始化 sigmoid 神经元的权重以避免饱和,因为如果初始权重太大,那么大多数神经元将会饱和,因此网络将很难学习。
  • 非零中心输出:
    输出总是在 0 和 1 之间,这意味着应用 sigmoid 后的输出总是正的,因此,在梯度下降期间,反向传播期间权重的梯度将总是正的或负的,这取决于神经元的输出。结果,梯度更新在不同的方向上走得太远,这使得优化更加困难。

python 实现类似于:

import numpy as npdef sigmoid(z):
 return 1 / (1 + np.exp(-z))

谭:

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

Source: Google

双曲正切激活函数的数学形式为“双曲正切(z)=(ez-e-z)/(ez+e-z)`.)它基本上是一个移位的乙状结肠神经元。它基本上接受一个实数值,并在-1 和+1 之间压缩它。类似于乙状结肠神经元,它在大的正值和负值时饱和。然而,它的输出总是以零为中心,这是有帮助的,因为网络后面层中的神经元将接收以零为中心的输入。因此,在实践中,双曲正切激活函数在 sigmoid 上的隐藏层中是优选的。

 import numpy as npdef tanh(z):
 return np.tanh(z) 

ReLU:

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

Source: Google

ReLU 或整流线性单位表示为“ReLU(z) = max(0,z)”。它基本上将输入阈值设置为零,即 ReLU 神经元输入中的所有负值都设置为零。最近,它变得流行起来,因为发现与 Sigmoid 或 Tanh 激活函数相比,它大大加速了随机梯度下降的收敛。为了直观起见,梯度可以是 0 或 1,具体取决于输入的符号。让我们讨论一下 ReLU 的一些优点:

  • 激活的稀疏性 :
    正如我们上面所研究的,ReLU 和 Tanh 激活函数几乎总是在神经网络中被激发,导致几乎所有的激活都在计算网络的最终输出时被处理。这当然是件好事,但前提是我们的网络很小,或者我们有无限的计算能力。想象一下,我们有一个非常深的神经网络,其中有许多神经元,理想情况下,我们希望只有一部分神经元激活,并对网络的最终输出做出贡献,因此,我们希望网络中的一部分神经元是被动的。ReLU 给了我们这个好处。因此,由于 ReLU 的特性,有可能 50%的神经元给出 0 次激活,从而导致更少的神经元触发,结果网络变得更轻,我们可以更快地计算输出。

然而,它有一个缺点,即所谓的神经元死亡问题。

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

  • 死亡神经元:
    ReLU 单位在训练过程中可以很脆弱,可以“死亡”。也就是说,如果单元最初没有被激活,那么在反向传播期间零梯度流过它们。因此,“死亡”的神经元将停止响应输出误差的变化,因此,在反向传播期间,参数将永远不会更新。但是,有一些概念,如 Leaky ReLU,可以用来克服这个问题。此外,适当设置学习速率可以防止神经元死亡。
import numpy as npdef relu(z):
 return z * (z > 0)

泄漏的 ReLU:

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

Source: Google

漏 ReLU 只是传统 ReLU 函数的扩展。正如我们看到的,对于小于 0 的值,梯度为 0,这导致这些区域中的“死亡神经元”。为了解决这个问题,Leaky ReLU 就派上了用场。也就是说,我们不是将小于 0 的值定义为 0,而是将负值定义为输入的一个小的线性组合。常用的小值是 0.01。它表示为 LeakyReLU(z) = max(0.01 * z,z)。通过做一点小小的改变,漏 ReLU 的思想可以被进一步扩展。我们可以学习乘数,并将其作为我们过程中的一个附加超参数,而不是将“z”乘以一个常数。这就是所谓的参数 ReLU。在实践中,相信这比泄漏 ReLU 执行得更好。

import numpy as npdef leaky_relu(z):
 return np.maximum(0.01 * z, z)

感谢您的阅读。在这篇文章中,我试图放下我对一些最常用的激活函数的理解,为什么我们首先使用它们,以及应该使用哪种激活函数。不断寒心,不断创新!

杂项:

如果你在数据科学或深度学习领域工作,如果你认为有合作的机会,请不要犹豫。我正在寻找全职机会,并愿意讨论。

参考资料:

【2】:【http://www.deeplearningbook.org/

神经网络中的激活函数

原文:https://towardsdatascience.com/activation-functions-in-neural-networks-83ff7f46a6bd?source=collection_archive---------8-----------------------

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

动机、使用案例、优势和局限性

TL; 博士这篇文章讨论了深度学习和神经网络中使用的各种线性和非线性激活函数。我们还将研究每个函数在不同情况下的表现,每个函数的优缺点,然后以最后一个激活函数结束,该函数的表现优于自然语言处理应用程序中讨论的函数。

介绍

继续神经网络的话题。今天我们将讨论什么是激活函数,并尝试理解其基本概念。我们深入研究了这些函数的线性和非线性版本,并探索了它们在哪些方面表现最佳,在哪些方面表现不佳。

在我们继续讨论什么是激活功能之前,让我们先回顾一下神经网络是如何运作的。因此,神经网络是模拟大脑工作方式的人工神经元的复杂网络。他们接受输入参数及其相关权重和偏差,然后我们计算“激活”神经元的加权和。我们的激活函数决定哪些神经元将把值推进到下一层。它是如何工作的,是我们接下来将要看到的。

基本概念

在前向传播步骤中,我们的人工神经元接收来自不同参数或特征的输入。理想情况下,每个输入都有自己的值或权重和偏差,这些值或权重和偏差可以显示导致最终预测值发生变化的相互依赖性。这是一种被称为互动效应的现象。

一个很好的例子是在糖尿病患者数据集上尝试回归模型。目标是根据一个人的体重和身高来预测他是否有患糖尿病的风险。一些体重表明,如果一个人的身高比一个健康指数相对较高的人矮,那么他患糖尿病的风险更大。当然还有其他我们目前没有考虑的参数。我们说身高和体重之间有交互作用。

激活函数考虑了不同参数中的相互作用效应,并进行转换,然后决定哪个神经元将值向前传递到下一层。

线性函数

我们从最简单的函数开始。线性功能f(z) 的值与 z 的值成比例增加。输入值是层中神经元的权重和偏差的加权和。线性函数解决了二进制阶跃函数仅报告值 0 和 1 的问题。

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

Fig 1: Performance of Linear or Identity Activation Function

函数的输出不受任何范围的限制;也就是说, f(z) 的值可以从中得出,这不一定是一个问题,因为我们可以通过取 com 之后触发的神经元的最大值来进入下一层或最后一层。除此之外,线性激活函数有其一系列缺点,例如:

  • 我们观察到函数的导数是一个常数。这意味着存在恒定的梯度下降,因为与 z 值无关。
  • 我们的模型不是真正的学习,因为它没有改进误差项,这是神经网络的全部要点。
  • 由于激活是线性的,嵌套在 2 或 N 个具有相同功能的隐藏层中不会有实际效果。N 层基本上可以压缩成一层。

我们看到这个函数不适合处理复杂的。因此,为了解决这个问题,我们使用非线性函数来使我们的模型能够迭代学习。

Sigmoid 函数

Sigmoid 函数将一个值作为输入,并输出另一个介于 0 和 1 之间的值。当构建神经网络模型时,它是非线性的并且易于操作。这个函数的优点是在不同的 z 值上连续可微分,并且具有固定的输出范围。

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

Fig 2: Performance of Sigmoid Activation Function

通过观察,我们看到 f(z) 的值以非常慢的速率增加。数学上的原因是,随着 z (在 x 轴上)增加,e 指数-z 的值变得无穷小,并且 f(z) 的值在某个点变得等于 1。换句话说,这个函数容易受到我们在上一讲中讨论的消失梯度问题的影响。高层次的问题是,利用 sigmoid 激活的模型(我们的慢学习者和处于实验阶段的学习者)将生成具有较低准确性的预测值。

当我们的神经网络中有多个隐藏层时,这个函数会出现另一个问题。我们通过这个激活函数得到的所有值都是正的,sigmoid 在 0-1 范围内产生不同大小的值,因此很难优化。

除了缺点,我们确实看到 sigmoid 函数特别是在二进制分类模型中作为输出层的一部分使用,以捕捉从 0 到 1 的概率。在大多数情况下,我们通常会遇到涉及多个类的问题,对于这样的模型,我们使用 Softmax 函数(这个函数的细节在之前的讲座中有进一步的解释)。

Tanh 函数

双曲正切函数是 sigmoid 函数的修改版或放大版。我们在 Sigmoid 中看到的是 f(z) 的值有界在 0 和 1 之间;然而,在 Tanh 的情况下,值被限制在-1 和 1 之间。

从某种意义上说,这很简单,我们能够得到不同符号的值,这有助于我们确定在下一层要考虑哪些分数,忽略哪些分数。但是,该函数仍然存在 sigmoid 函数中出现的梯度消失问题。该模型在+2 和-2 范围之外以指数方式变慢。除了在这个狭窄的范围内,梯度的变化非常小。

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

Fig 3: Performance of Tanh Activation Function

关于双曲正切函数和 sigmoid 函数的最后一点,双曲正切函数的梯度或导数比 Sigmoid 函数更陡,我们可以在下面的图 4 中观察到。我们选择使用 Sigmoid 还是 Tanh 实际上取决于问题陈述对梯度的要求。

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

Fig 4: Comparision of Sigmoid and Tanh Activation Function

校正线性单位函数

整流线性单元或简称 ReLU 将被认为是深度学习模型中最常用的激活函数。如果接收到任何负输入,该函数简单地输出值 0,但是对于任何正值 z,,它像线性函数一样返回该值。所以可以写成 f(z)=max(0,z)

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

Fig 5: Performance of ReLU Activation Function

然而,应该注意,ReLU 函数仍然是非线性的,因此我们能够反向传播误差,并且具有多层神经元。这个功能很快被采用,因为 ReLU 解决了乙状结肠和 Tanh 面临的几个问题:

  • ReLU 函数在其跨越所有负数的范围的一半上具有 0 的导数。对于正输入,导数为 1。因此,我们已经纠正了“消失”梯度问题。
  • 一次只有少数神经元被激活,使得网络变得稀疏,从而变得高效(我们将会看到稀疏并不总是一件好事)
  • 与 Sigmoid 和 Tanh 相比,它在计算上是经济的。

尽管 ReLU 是比其它非线性替代物更好的激活函数,但是它有自己的一系列限制和缺点:

  • 该函数遇到了垂死的 ReLU 问题——对于对应于形成 y = 0 线的 z < 0, the gradient will be 0 because of which the weights will not get adjusted during the gradient descent in backpropagation. That means, such neurons will stop responding to variations in error/input, so the output network becomes passive due to added sparsity.
  • It is best used in between the input and output layers, more specifically within hidden

As a final note on ReLU, there is a way to counter the dying ReLU problem by using a modified version of the function called the ‘Leaky’ ReLU. To put it briefly, we take the z < 0 值的激活,通过添加小的非零恒定梯度α(通常,α=0.01)将其转换成非水平直线。所以我们对于z0 的新公式是 f(z) = αz

为了获得更多的信息,我已经附上了关于 Leaky ReLU 的研究论文:https://arxiv.org/abs/1502.01852

额外收获:非线性立方体激活功能

有一个有趣的激活功能应用于词性标注,它比文章中提到的所有其他功能都要好。曼宁和陈(2014)的论文提出了一种学习神经网络分类器的新方法,用于自然语言处理的贪婪的、基于转换的依存解析器。他们引入了由 z 表示的非线性立方函数,这在下面的隐藏层的方程中被进一步阐述:

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

Fig 6: Cube Activation function that takes weights of the words, tags, and labels along with its bias.

上面的等式表示输入单元的加权和,在这种情况下,输入单元是单词、标签和标记嵌入加上相关联的偏差。然后,总和的 3 次方被用来计算该迭代的输出值。

这个特定激活功能的性能可以在下面的图表中看到。这不是成比例的,但我们可以确定,在这种情况下,随着学习以指数速率( z )进行,误差项减少了。

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

Fig 7: Performance of Cube (z³) Activation Function

该论文在实验中是彻底的,其中该模型与其他最先进的模型进行了严格的测试,并且为了快速得出激活函数之间关于性能的比较,我们观察到:

非线性立方体> ReLU > Tanh > Sigmoid

为了更好地了解这个模型是如何运行的,我在下面附上了曼宁论文的链接。

一个使用神经网络的快速准确的依存句法分析器:【https://cs.stanford.edu/~danqi/papers/emnlp2014.pdf】T3

结论

我们学习了在 ML 模型中使用的许多激活函数。对于研究人员来说,这些函数用于比较在给定问题陈述的情况下什么是最好的。对于选择特定的激活功能,没有严格的规则。然而,这取决于模型的架构、超参数和我们试图捕捉的特征。理想情况下,我们在基本模型上使用 ReLU 函数,但是如果我们不能达到最佳结果,我们也可以尝试其他函数。

最后一点,请随意评论您自己设计的非线性激活函数版本、高级概述以及它在什么情况下性能最佳。

传播和分享知识。如果这篇文章激起了你的兴趣,请鼓掌,因为它总是激励我写出更多的信息内容。更多数据科技相关帖子关注我 这里
我在
Linkedin上也有空,偶尔tweet也有空。😃

神经网络中的激活函数

原文:https://towardsdatascience.com/activation-functions-neural-networks-1cbd9f8d91d6?source=collection_archive---------0-----------------------

Sigmoid,tanh,Softmax,ReLU,Leaky ReLU 解释!!!

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

什么是激活功能?

它只是一个东西函数,你用它来得到 node 的输出。它也被称为传递函数

为什么我们在神经网络中使用激活函数?

它用于确定神经网络的输出,如是或否。它将结果值映射到 0 到 1 或-1 到 1 等之间。(取决于功能)。

激活功能基本上可以分为两种类型

  1. 线性激活函数
  2. 非线性激活函数

仅供参考:备忘单如下。

线性或身份激活功能

如你所见,这个函数是一条直线或线性的。因此,函数的输出将不会被限制在任何范围之间。

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

Fig: Linear Activation Function

方程式: f(x) = x

范围:(-无穷大到无穷大)

它对输入神经网络的通常数据的复杂性或各种参数没有帮助。

非线性激活功能

非线性激活函数是最常用的激活函数。非线性有助于使图表看起来像这样

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

Fig: Non-linear Activation Function

这使得模型很容易概括或适应各种数据,并区分输出。

需要理解非线性函数的主要术语有:

**导数或微分:**y 轴的变化与 x 轴的变化。它也被称为斜坡。

**单调函数:**要么完全非增,要么完全非减的函数。

非线性激活函数主要根据它们的范围或曲线来划分

1。乙状结肠或逻辑激活功能

Sigmoid 函数曲线看起来像 S 形。

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

Fig: Sigmoid Function

我们之所以用 sigmoid 函数,主要是因为它存在于 (0 到 1)之间。因此,它特别适用于我们必须预测概率作为输出的模型。由于任何事情的概率只存在于 0 和 1 之间, sigmoid 是正确的选择。

该函数是可微的。这意味着,我们可以在任意两点找到 s 形曲线的斜率。

函数是单调的,但函数的导数不是。

逻辑 sigmoid 函数会导致神经网络在训练时停滞不前。

softmax 函数是一个更通用的逻辑激活函数,用于多类分类。

2。双曲正切或双曲正切激活函数

tanh 也像逻辑 s 形但更好。双曲正切函数的范围是从(-1 到 1)。tanh 也是 s 形的(s 形)。

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

Fig: tanh v/s Logistic Sigmoid

优点是负输入将被映射为强负输入,而零输入将被映射到双曲正切图中的零附近。

函数是可微的

函数是单调的,而它的导数不是单调的

双曲正切函数主要用于两类之间的分类。

双曲正切和逻辑 sigmoid 激活函数都用于前馈网络。

3。ReLU(整流线性单元)激活功能

ReLU 是目前世界上使用最多的激活函数。因为,它被用于几乎所有的卷积神经网络或深度学习。

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

Fig: ReLU v/s Logistic Sigmoid

正如你所看到的,ReLU 是半整流(从底部)。当 z 小于零时 f(z)为零,当 z 大于或等于零时 f(z)等于 z。

范围:【0 到无穷大】

函数及其导数都是 单调

但问题是,所有的负值立即变为零,这降低了模型根据数据进行适当拟合或训练的能力。这意味着给予 ReLU 激活函数的任何负输入都会在图形中立即将值变成零,这反过来会通过不适当地映射负值来影响结果图形。

4。泄漏的 ReLU

这是解决濒临死亡的 ReLU 问题的一次尝试

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

Fig : ReLU v/s Leaky ReLU

你能看到漏洞吗?😆

泄漏有助于增加 ReLU 功能的范围。通常情况下, a 的值在 0.01 左右。

a 不为 0.01 时,称为随机化 ReLU

因此,泄漏 ReLU 的范围为(-无穷大到无穷大)。

泄漏和随机化 ReLU 函数本质上都是单调的。同样,它们的导数在性质上也是单调的。

为什么要用导数/微分?

更新曲线时,根据坡度在中知道向哪个方向改变或更新曲线多少。这就是为什么我们在机器学习和深度学习的几乎每个部分都使用微分。

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

Fig: Activation Function Cheetsheet

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

Fig: Derivative of Activation Functions

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

乐意帮忙。支持我。

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

If you liked it

所以,跟着我上LinkedIn 看看类似的帖子。

任何评论或者如果你有任何问题,写在评论里。

鼓掌吧!分享一下!跟我来。

你会喜欢的以前的故事:

[## “TensorFlow”里的“Tensor”是什么鬼?

我不知道…

hackernoon.com](https://hackernoon.com/what-the-hell-is-tensor-in-tensorflow-e40dbf0253ee) [## 纪元与批量大小与迭代次数

了解您的代码…

towardsdatascience.com](/epoch-vs-iterations-vs-batch-size-4dfb9c7ce9c9) [## 蒙特卡罗树搜索

每个数据科学爱好者的 MCTS

towardsdatascience.com](/monte-carlo-tree-search-158a917a8baa) [## 强化学习中的政策网络与价值网络

在强化学习中,代理在他们的环境中采取随机决策,并学习选择正确的决策…

towardsdatascience.com](/policy-networks-vs-value-networks-in-reinforcement-learning-da2776056ad2) [## TensorFlow 图像识别 Python API 教程

在带有 Inception-v3 的 CPU 上(以秒为单位)

towardsdatascience.com](/tensorflow-image-recognition-python-api-e35f7d412a70) [## 如何使用 Python 发送电子邮件

使用 Flask 设计专业邮件!

medium.com](https://medium.com/@sagarsharma4244/how-to-send-emails-using-python-4293dacc57d9)

主动学习 MNIST——节省标签

原文:https://towardsdatascience.com/active-learning-on-mnist-saving-on-labeling-f3971994c7ba?source=collection_archive---------13-----------------------

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

标记数据的聪明方法是从决策边界开始

主动学习是一种半监督技术,允许通过从学习过程(损失)的角度选择最重要的样本来标记较少的数据。在数据量大且标记率高的情况下,它会对项目成本产生巨大影响。例如,对象检测和 NLP-NER 问题。
文章基于以下代码: 主动学习 MNIST

实验数据

*#load 4000 of MNIST data for train and 400 for testing*
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_full = x_train[:4000] / 255
y_full = y_train[:4000]
x_test = x_test[:400] /255
y_test = y_test[:400]
x_full.shape, y_full.shape, x_test.shape, y_test.shape

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

plt.imshow(x_full[3999])

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

<matplotlib.image.AxesImage at 0x7f59087e5978>

我将使用 MNIST 数据集的子集,这是 6 万张带标签的数字图片和 10K 测试样本。为了更快地训练,训练需要 4000 个样本(图片),测试需要 400 个样本(神经网络在训练过程中永远看不到)。为了标准化,我将灰度图像点除以 255。

模型、培训和标签流程

*#build computation graph*
x = tf.placeholder(tf.float32, [**None**, 28, 28])
x_flat = tf.reshape(x, [-1, 28 * 28])
y_ = tf.placeholder(tf.int32, [**None**])
W = tf.Variable(tf.zeros([28 * 28, 10]), tf.float32)
b = tf.Variable(tf.zeros([10]), tf.float32)
y = tf.matmul(x_flat, W) + b
y_sm = tf.nn.softmax(y)
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_, logits=y))
train = tf.train.AdamOptimizer(0.1).minimize(loss)
accuracy = tf.reduce_mean(tf.cast(tf.equal(y_, tf.cast(tf.argmax(y, 1), tf.int32)), tf.float32))

作为一个框架,我们可以使用 TensorFlow 计算图来构建十个神经元(每个数字)。w 和 b 是神经元的权重。softmax 输出 y_sm 将有助于数字的概率(置信度)。损失将是预测和标记数据之间典型的“软最大化”交叉熵。优化器的选择是一个流行的 Adam,学习率几乎是默认的— 0.1。作为一个主要的衡量标准,我将使用测试数据集的准确性。

**def** reset():
    *'''Initialize data sets and session'''*
    **global** x_labeled, y_labeled, x_unlabeled, y_unlabeled
    x_labeled = x_full[:0]
    y_labeled = y_full[:0]
    x_unlabeled = x_full
    y_unlabeled = y_full
    tf.global_variables_initializer().run()
    tf.local_variables_initializer().run() 

**def** fit():
    *'''Train current labeled dataset until overfit.'''*
    trial_count = 10
    acc = sess.run(accuracy, feed_dict={x:x_test, y_:y_test})
    weights = sess.run([W, b])
    **while** trial_count > 0:
        sess.run(train, feed_dict={x:x_labeled, y_:y_labeled})
        acc_new = sess.run(accuracy, feed_dict={x:x_test, y_:y_test})
        **if** acc_new <= acc:
            trial_count -= 1
        **else**:
            trial_count = 10
            weights = sess.run([W, b])
            acc = acc_new

    sess.run([W.assign(weights[0]), b.assign(weights[1])])    
    acc = sess.run(accuracy, feed_dict={x:x_test, y_:y_test})
    print('Labels:', x_labeled.shape[0], '**\t**Accuracy:', acc)

**def** label_manually(n):
    *'''Human powered labeling (actually copying from the prelabeled MNIST dataset).'''*
    **global** x_labeled, y_labeled, x_unlabeled, y_unlabeled
    x_labeled = np.concatenate([x_labeled, x_unlabeled[:n]])
    y_labeled = np.concatenate([y_labeled, y_unlabeled[:n]])
    x_unlabeled = x_unlabeled[n:]
    y_unlabeled = y_unlabeled[n:]

这里我定义了这三个过程,以便更方便地编码。
reset() —清空已标记的数据集,将所有数据放入未标记的数据集中,并重置会话变量

fit() —运行训练,试图达到最佳准确度。如果在前十次尝试中没有提高,训练将在最后一次最佳结果时停止。我们不能使用任何大量的训练时期,因为模型往往很快过拟合或需要一个密集的 L2 正则化。

label_manually() —这是对人工数据标注的模拟。实际上,我们从已经标注的 MNIST 数据集中获取标注。

地面实况; 真值(机器学习)

*#train full dataset of 1000*
reset()
label_manually(4000)
fit()

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

如果我们足够幸运,有足够的资源来标记整个数据集,我们将获得 92.25%的准确率。

使聚集

*#apply clustering*
kmeans = tf.contrib.factorization.KMeansClustering(10, use_mini_batch=**False**)
kmeans.train(**lambda**: tf.train.limit_epochs(x_full.reshape(4000, 784).astype(np.float32), 10))

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

centers = kmeans.cluster_centers().reshape([10, 28, 28])
plt.imshow(np.concatenate([centers[i] **for** i **in** range(10)], axis=1))

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

<matplotlib.image.AxesImage at 0x7f58d033a860>

在这里,我尝试使用 k-means 聚类来找到一组数字,并使用这些信息进行自动标记。我运行 Tensorflow 聚类估计器,然后可视化得到的十个质心。如你所见,结果远非完美——数字“9”出现了三次,有时与“8”和“3”混在一起。

随机标记

*#try to run on random 400*
reset()
label_manually(400)
fit()

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

让我们尝试只标记 10%的数据(400 个样本),我们将获得 83.75%的准确性,这与 92.25%的基本事实相差甚远。

主动学习

*#now try to run on 10*
reset()
label_manually(10)
fit()

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

*#pass unlabeled rest 3990 through the early model*
res = sess.run(y_sm, feed_dict={x:x_unlabeled})
*#find less confident samples*
pmax = np.amax(res, axis=1)
pidx = np.argsort(pmax)
*#sort the unlabeled corpus on the confidency*
x_unlabeled = x_unlabeled[pidx]
y_unlabeled = y_unlabeled[pidx]
plt.plot(pmax[pidx])

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

[<matplotlib.lines.Line2D at 0x7f58d0192f28>]

现在我们将使用主动学习来标记相同的 10%的数据(400 个样本)。为此,我们从 10 个样本中抽取一批样本,并训练一个非常原始的模型。然后,我们将剩余的数据(3990 个样本)通过该模型,并评估最大 softmax 输出。这将显示所选类是正确答案的概率(换句话说,神经网络的置信度)。排序后,我们可以在图上看到置信度的分布从 20%到 100%不等。这个想法是从信心不足的样品中选择下一批进行标记。

*#do the same in a loop for 400 samples*
**for** i  **in** range(39):
    label_manually(10)
    fit()

    res = sess.run(y_sm, feed_dict={x:x_unlabeled})
    pmax = np.amax(res, axis=1)
    pidx = np.argsort(pmax)
    x_unlabeled = x_unlabeled[pidx]
    y_unlabeled = y_unlabeled[pidx]

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

在对 40 个批次的 10 个样品运行这样的程序后,我们可以看到最终的准确度几乎是 90%。这远远超过在随机标记数据的情况下达到的 83.75%。

如何处理剩余的未标记数据

*#pass rest unlabeled data through the model and try to autolabel*
res = sess.run(y_sm, feed_dict={x:x_unlabeled})
y_autolabeled = res.argmax(axis=1)
x_labeled = np.concatenate([x_labeled, x_unlabeled])
y_labeled = np.concatenate([y_labeled, y_autolabeled])
*#train on 400 labeled by active learning and 3600 stochasticly autolabeled data*
fit()

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

传统的方法是通过现有模型运行数据集的其余部分,并自动标记数据。然后,在训练过程中推动它可能有助于更好地调整模型。然而在我们的例子中,它并没有给我们带来任何更好的结果。

我的方法是做同样的事情,但是,如同在主动学习中一样,考虑到信心:

*#pass rest of unlabeled (3600) data trough the model for automatic labeling and show most confident samples*
res = sess.run(y_sm, feed_dict={x:x_unlabeled})
y_autolabeled = res.argmax(axis=1)
pmax = np.amax(res, axis=1)
pidx = np.argsort(pmax)
*#sort by confidency*
x_unlabeled = x_unlabeled[pidx]
y_autolabeled = y_autolabeled[pidx]
plt.plot(pmax[pidx])

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

[<matplotlib.lines.Line2D at 0x7f58cf918fd0>]

*#automatically label 10 most confident sample and train for it*
x_labeled = np.concatenate([x_labeled, x_unlabeled[-10:]])
y_labeled = np.concatenate([y_labeled, y_autolabeled[-10:]])
x_unlabeled = x_unlabeled[:-10]
fit()

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

在这里,我们通过模型评估运行剩余的未标记数据,我们仍然可以看到剩余样本的置信度不同。因此,想法是采取一批十个最有信心的样本,并训练模型。

*#run rest of unlabelled samples starting from most confident*
**for** i **in** range(359):
    res = sess.run(y_sm, feed_dict={x:x_unlabeled})
    y_autolabeled = res.argmax(axis=1)
    pmax = np.amax(res, axis=1)
    pidx = np.argsort(pmax)
    x_unlabeled = x_unlabeled[pidx]
    y_autolabeled = y_autolabeled[pidx]
    x_labeled = np.concatenate([x_labeled, x_unlabeled[-10:]])
    y_labeled = np.concatenate([y_labeled, y_autolabeled[-10:]])
    x_unlabeled = x_unlabeled[:-10]
    fit()

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

这个过程需要一些时间,并给我们额外的 0.8%的准确性。

结果

实验准确率
4000 个样本 92.25%
400 个随机样本 83.75%
400 个主动学习样本 89.75%
+自动标注 90.50%

结论

当然,这种方法有其缺点,如计算资源的大量使用,以及数据标记与早期模型评估混合需要特殊过程的事实。此外,出于测试目的,数据也需要被标记。但是,如果标签的成本很高(特别是对于 NLP、CV 项目),这种方法可以节省大量资源,并推动更好的项目结果。

附言(同 postscript);警官(police sergeant)

如果你有私人问题,请在 Linkedin脸书联系我,我有时会在那里发布关于人工智能的简短新闻和想法。

我要感谢我的同事们亚历克斯·西姆基夫米科拉·科兹连科沃洛季米尔·森德茨基、维亚奇·博西和纳扎尔·萨维琴科富有成效的讨论、合作和有益的建议,以及整个 MindCraft.ai 团队的持续支持。
Andy Bosyi,
mind craft . ai 首席执行官
信息技术&数据科学

主动学习教程

原文:https://towardsdatascience.com/active-learning-tutorial-57c3398e34d?source=collection_archive---------0-----------------------

如今,我们接触到大量未标记的数据,这些数据要么来自互联网,要么来自其他来源,如学术界或商界。由于未标记的数据相对容易获得且标记昂贵,公司通常雇佣一名专家或几名员工来标记数据1。考虑以下情况,一家数据驱动的医疗公司有大量 MRI 扫描,他们需要雇用一名专家来帮助他们解释这些扫描。公司资源有限,他们无法解释或标记所有数据;这就是他们决定使用主动学习(AL)的原因。人工智能的承诺是,通过迭代增加我们精心选择的标记数据的大小,有可能实现与使用完全监督的数据集相似(或更好[2])的性能,而成本或时间只是标记所有数据所需的一小部分。就标记数据量而言,AL 被认为是一种半监督方法,介于无监督和完全监督之间,即,对于无监督数据,我们使用 0%标记样本,而对于完全监督,我们使用 100%标记样本。因此,使用多少数据或者模型需要多少性能的决策依赖于资源管理决策,换句话说,它可以是业务决策。

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

Shanghai early morning pollution — ori cohen 2017

AL 有三种场景:
1。成员查询合成,即将生成的样本发送给 oracle 进行标记。
2。基于流的选择性采样,即每个样本都被单独考虑——在我们的例子中是标签查询或拒绝。类似于在线学习,数据不被保存,没有关于数据分布的假设,因此它可以适应变化。
3。基于池的采样,即从未标记的数据池中选择样本用于标记[3]。
在本教程中,我们使用第三种场景。

下面的伪算法表示学习过程,如代码中所写的,用于基于池的采样:
1 .将数据分成一个“池”和一个测试集
2。从初始训练集的池中选择“k”个样本并标记它们,剩余的数据将成为验证集
3。将所有集合
4 标准化。使用具有平衡权重的训练集训练模型。
5。使用经过训练的模型和验证集,获得每个样本的概率。
6。将训练好的模型与测试集一起使用,获得性能度量。
7。根据每个样本的概率,选择“k”个最具信息性的样本,即模型对其标签最不确定的样本。
8。将这些“k”个样本从验证集移动到训练集,并查询它们的标签。
9。所有数据集的逆归一化
10。根据停止标准停止,否则转到 3。

往前走之前有几点需要注意:
1。所选算法的全监督性能通常是上限,因此建议尝试几种算法。
2。在我们从验证集中移除样本后,所有集合的归一化必须被反转并再次归一化,因为我们的样本分布在新的验证和新的训练集中均发生了变化。
3。样本选择函数依赖于来自训练模型的测试样本概率,因此我们只能使用提供样本概率的算法。
4。“k”是一个超参数

我们在 AL 方法中最重要的工具是样本选择功能,这是我们影响学习过程的唯一点,使用正确的方法至关重要。这个领域是一个热门的研究课题,有许多研究提出竞争选择函数。
在本教程中,我提出了四个已知的选择函数。随机选择—我们从验证集中选择“k”个随机样本。
2。熵选择—我们选择具有最高熵的“k”个样本。
3。边际选择—我们选择两个最高类别概率之间差异最小的“k”个样本,即模型对单个类别非常确定的样本的数值较高,而类别概率非常相似的样本的数值较低。

这里提供的代码在选择各种学习算法和选择函数方面利用了模块化架构,并且可以用作其他模型-函数比较的基础。

我们比较了几种学习算法,如线性核支持向量机(SVM)、随机森林(RF)和逻辑回归(LOG)。每个算法都使用所有的“k”=[10,25,50,125,250]的选择函数来执行,总共累积了 80 次实验。由于某些算法和选择函数的随机性质,建议在代码中重复运行实验,以便计算出具有统计意义的结果。然而,运行时间很长,我选择对(模型、函数、k)的每个组合只运行一次实验。

下面是对代码及其类架构的解释。

我们首先下载我们的数据,并根据 MNIST 已知的 60K/10K 分割定义,将其分割为训练和测试。稍后,该列车组将被拆分以进行训练和验证。

我们创建了一个模块化的类表示,“BaseModel”是类架构的一个基础模型,你可以实现新的模型,并且可以互换使用它们,或者与所有其他模型一起使用。我们当前的实现包括 SVM、逻辑回归、随机森林和梯度推进。

我们的“TrainModel”类接受先前定义的学习算法之一,使用训练集进行训练,并从测试集中获取性能测量。

我们创建一个模块化的选择函数类表示,“BaseSelectionFunction”是各种样本选择方法的基类。使用这种架构,您可以实现新的选择方法,并使用它们来补充或代替以前的方法,以达到实验的目的。我们当前的实现包括随机选择、熵选择、边际抽样选择和最小标准差选择。

我们有一个类,用于使用[0,1]范围内的最小最大值缩放器进行归一化。

最初,我们希望从未标记的数据池中随机抽样,这是使用 random.choice 完成的,没有替换。

这是根据引言中描述的算法启动主动学习过程的主类。简而言之,我们选择“k”个随机样本,训练模型,选择信息最丰富的样本,从验证集中移除,查询它们的标签,并使用这些样本重新训练,直到达到停止标准。

在脚本的主要部分,我们下载数据,分为训练验证和测试,我们通过迭代所有的训练算法 X 所有的选择函数 X 范围[10,25,50,125,250]内所有可能的 k 来运行实验。准确性结果保存在字典中,并在模型完成训练后立即保存到一个独特的文件中,这在使用 Google Colaboratory 时至关重要,因为它往往会不时断开连接。我们还将我们的培训限制在最多 500 个查询样本。

独立地,我们使用 60K-10K 的训练测试分割训练了几个模型,结果表明 RF、SVM 和 LOG 的上限是 97。, 94.和 92.47。

下图显示随机森林分类器与边缘选择方法配对,k=10 是最佳配置。

对于前面提到的停止条件和超参数,性能最好的模型是随机森林算法!

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

A comparison of accuracy between a fully supervised & active-learning approaches, comparing random-forest, SVM and logistic regression, using all sampling methods and K=[10,25,50,125,250]. The y-axis represents the accuracy and the x-axis the amount of samples in each iteration.

我们进一步看到,最佳采样函数是边缘采样!

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

A comparison of accuracy between a fully supervised & active-learning approaches, using a random-forest classifier, all sampling methods and K=[10,25,50,125,250]. The y-axis represents the accuracy and the x-axis the amount of samples in each iteration.

最后,k=10 是最佳选择参数。

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

A comparison of accuracy between a fully supervised & active-learning approaches, using a random-forest classifier, Margin-Sampling and K=[10,25,50,125,250]. The y-axis represents the accuracy and the x-axis the amount of samples in each iteration.

我们已经看到,通过使用主动学习方法,我们可以使用一小部分标记数据,与完全监督的方法相比,可以获得非常接近的准确性。事实上,如果您选择使用 1000 个样本,准确率甚至会攀升到约 95%。此外,非常有趣的是,作为一种样本选择方法,边际抽样试探法优于熵。最后,我希望这篇教程对你有所启发,你可以考虑在你的下一次学习中使用这种方法。

我要感谢 Moshe Hadad 对 PEP8 的宝贵评论和 Shay Zweig 的校对和评论。

Ori Cohen 在机器学习、脑机接口和神经生物学领域获得了计算机科学博士学位。

参考资料:

1 Shay Yehezkel,高维统计过程控制与应用,理学硕士论文。

[2] Ilhan、Hamza Osman 和 Mehmet Fatih Amasyali。 主动学习作为提高准确率的一种方式 。”国际计算机理论与工程杂志 6,第 6 期(2014): 460。

[3] Stefan Hosein 主动学习:好奇 AI 算法

使用智能手机的活动识别—机器学习应用

原文:https://towardsdatascience.com/activity-recognition-using-smartphones-machine-learning-application-a10e7b5578f9?source=collection_archive---------3-----------------------

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

“white building with data has a better idea text signage” by Franki Chamaki on Unsplash

当我第一次开始探索机器学习时,我阅读了大量的文章和研究论文。我最初发现的一篇论文涉及使用机器学习对活动进行分类。尽管当时实现似乎是一个遥不可及的目标,但我还是被这个应用程序吸引住了。从那天起,我获得了一些经验,我相信今天我可以应用我的机器学习知识来识别现在的活动。

对于数据集,我从 Kaggle 竞赛中选择了training.csvtest.csv文件。我在这个项目中使用了一个 Jupyter 笔记本,在我的活动识别中使用了机器学习报告

顺便提一下,现在通过谷歌数据集搜索在线查找数据集变得容易多了。这是我找到这个项目数据集的地方。

因此,在这篇文章中,我将解释我在这个项目中采取的步骤,以及我如何使用机器学习以超过 96%的准确率对活动进行分类。分叉存储库,打开笔记本,开始吧。

导入库

在这个项目中,我们将需要许多存储库。

  1. numpy 和 pandas: numpy 使我们能够高效地使用数组。Pandas 用于读取数据集文件并将其作为 dataframe 导入,data frame 类似于包含行和列的表。
  2. matplotlib: matplotlib 是一个高度可定制的包,它有一个子包pyplot,可以让我们绘制图表、柱状图、饼状图等等。我们可以选择添加图例、轴标题、改变线条粗细等。cm包(colormap)允许我们为图表获取颜色。
  3. sklearn: 这个机器学习库包括许多已经内置的机器学习算法,其中某些参数设置为默认参数,因此它们开箱即用。

如果你注意到了,我加了一行%matplotlib inline。这将 matplotlib 的后端更改为 Jupyter 笔记本,因此,所有绘图现在都将显示在 Jupyter 笔记本本身中。

在这个项目中,我使用了四种算法,即支持向量分类器作为SVC,逻辑回归作为LogisticRegression,K 近邻分类器作为KNeighborsClassifier,随机森林分类器作为RandomForestClassifier。为了计算精度,我导入了accuracy_score

了解数据集

Person walking up the stairs

首先我们将使用read_csv()方法将训练和测试文件导入笔记本,并保存在变量training_datatesting_data中。

我们使用shape方法来寻找数据集的大小。其结果是输出为(rows, columns)。训练数据集中有 7352 行和 563 列,测试数据集中有 2947 行和 563 列。我们必须确保数据集没有任何空值。我们使用isnull().values.any()来检查是否有单元格是空的。我们打印输出,看到输出是False,意味着没有空值。所以,我们可以继续。

我们可以使用head(5)方法来获得训练数据的前 5 行。我们看到有 563 列,最后一列为活动,它将作为我们的标签。在剩下的专栏中,subject 对于我们的机器学习应用程序没有特别的用途,因为我们想要探索活动,而不是谁执行了它。我们可以删除该列,剩下的 561 列将成为我们的功能。测试数据也是如此。

按照惯例,小写字母y充当标签集,大写字母X充当特征集。因此,这些名称是y_trainX_trainy_testX_test。我们将在机器学习分析中使用这些变量。

可视化数据集

处理数据的关键之一是确保所有类的大小大致相等。这是必不可少的,这样机器学习算法就不会偏向任何一个类。

让我们借助一个例子来理解这一点。比方说,数据集包含 30 项活动,其份额百分比各不相同。数据集包含 99%的活动 1 数据和 1%的其余活动数据。在这种情况下,机器学习将永远不会学习关于数据的任何模式。它会认为 100 个案例中有 99 个案例的活动是活动 1。因此,它将总是输出 Activity 1,而不考虑任何数据,并且仍然可以达到 99%的准确率。这种模型是不正确的,因此必须确保不同数据类别的份额大致相等。

我们首先在count_of_each_activity变量中获得每种类型活动的记录数。value_counts()给出计数,np.array将其转换成一个数组。计数按活动名称的字母顺序显示。

unique()y_train给了我们独特的价值观。我们必须对其进行排序,以便它们与上面收集的计数值保持一致。rcParams帮助我们为我们的图表定义某些样式。我们使用figure.figsize定义图形大小,使用font.size定义字体大小。

我们现在已经为饼图准备好了数据。pie()方法创建饼图。第一个参数是每个活动的计数,第二个参数是由labels表示的相应活动名称,第三个参数autopct计算每个活动的百分比。

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

Pie chart for share of each activity in dataset

观察上面的饼图,您可以看到每项活动的份额几乎相等。数据集的格式非常好,可以直接使用。

接下来,我观察 datatset 中的读数类型。如果您查看列标题,您会发现这些列要么有文本Acc来指代加速度计读数,要么有文本Gyro来指代陀螺仪值,要么两者都没有来指代所有其他值。

我首先遍历列名,检查它们是否包含“Acc”或“Gyro”。基于变量值,我使用pyplot子包的bar()方法绘制了一个条形图。第一个参数是 X 轴标签,第二个参数是 Y 轴值的数组,color参数分别为三个条形定义了颜色红色蓝色绿色。我再次为这个条形图定义了图形大小和字体大小。

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

Bar plot of column types

检查某项活动

为了更好地了解数据,我知道我必须看一看这些活动。因此,我决定尝试探索更多关于“站立”的活动。

这是我开始之前知道的所有信息:

  1. 该数据集具有 30 个人的活动记录,并且一些个人进行了站立活动。
  2. 收集到的数据会连续记录每个人,尤其是每个活动。这意味着任何给定活动的记录实际上都是时间序列。
  3. 每个记录中有许多特征,但是我不能一次包含所有的特征,因为这可能会使数据的理解更加困难。

根据我所掌握的信息,我决定绘制一个线图,显示在一段时间内执行站立活动的所有人的特征。我把这个特征作为 X 和平均重力之间的角度,除了由于人为误差造成的微小变化,这个角度应该保持不变。

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

“man standing on road” by Anthony Tori on Unsplash

我首先从数据集中选择所有“活动”标签为“站立”的行,并将其存储在standing_activity中。这里,我们必须确保我们重置了索引。这是必要的,因为当我们选择上面的行时,被删除的行确实被删除了,但是其余行的索引没有改变,它们不再是连续的。

为每个个体收集的数据是连续的时间序列,并以相同的速率记录。因此,每次主题改变时,我可以简单地从0开始为每个活动分配时间值。对于每个主题,持续活动记录将以时间值0开始,并以1递增,直到前一行的主题与当前行的主题相匹配。我将所有的时间序列存储在变量time_series中,并使用 pandas 方法DataFrame()将其转换为数据帧,然后存储在变量time_series_df中。最后,我使用 pandas concatenate()方法将记录和时间序列变量组合在一起。axis = 1告诉该方法组合两个数据帧,并将它们作为列追加。

np.zeros()创建一个由零组成的 numpy 数组,其大小等于括号内的数字。对于一个数据帧,如果我们在括号内分别使用01,在shape的末尾添加一个方括号有助于我们获得行或列。

现在,当数据准备好被绘制时,我使用 matplotlib 的cm子包通过rainbow方法获得一个颜色列表。

然后,我遍历standing_activity_df中的主题列表。我使用rcParams指定图形的大小。在绘图方法中,第一个参数是 X 轴值,在我们的例子中是Time列。第二列是 Y 轴值,所以我输入了angle(X, gravityMean)值。颜色在c中定义,主题编号设置为label,线条宽度在linewidth中设置为 4。然后,我指定绘图的 X 轴标签、Y 轴标签和标题。legend()方法在图上显示图例。

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

Angle between X and mean Gravity v/s Time graph

如果我们仔细观察图表,我们可以看到平均每条线在 0.2–0.3 值的最大范围之间转换。这确实是预期的行为,因为微小的变化可能是由微小的人为错误造成的。

将活动分类

现在是我们过程中的最后一步,实际使用机器学习算法并进行分类。

我们创建一个大小为 4 的零数组来存储每个算法的精度。我们将在创建条形图时使用它。

accuracy_scores = np.zeros(4)

每一个的过程都是一样的,因为我将使用各种参数的默认值。让我们借助支持向量分类器来理解一下。首先,我把算法的名字写成 imported SVC()。随后是fit()方法,该方法根据提供的数据对算法进行建模。我输入参数作为训练数据,因此,X_trainy_train

接下来,我使用predict()方法预测测试数据X_test的输出,并将其存储在prediction变量中。然后我使用accuracy_score函数来计算精度,它将第一个参数作为真值,第二个参数作为预测值。我把它乘以 100 转换成百分比。我们对每个算法都执行相同的步骤。

从上面的输出值可以看出,逻辑回归算法表现最好,准确率超过 96%。我们也可以将输出可视化为条形图。

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

Classifiers accuracy bars

结论

在本文中,我讨论了活动识别,从数据集绘制了可视化效果,并使用机器学习算法对活动进行分类。从结果来看, Logistic 回归的准确率最高。

我希望你喜欢我的作品。从未来的角度来看,您可以尝试其他算法,或者选择不同的参数值来进一步提高精度。请随时分享你的想法和想法。

利用 Catboost 和 LightGBM 进行广告需求预测

原文:https://towardsdatascience.com/ad-demand-forecast-with-catboost-lightgbm-819e5073cd3e?source=collection_archive---------11-----------------------

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

Photo credit: Pixabay

预测在线分类广告的需求,特征工程

Avito.ru 是一个俄罗斯分类广告网站,有出售一般商品、工作、房地产、个人、出售汽车和服务等板块。

它是俄罗斯最受欢迎的分类广告网站,也是仅次于 Craigslist 和中国网站 58.com 的世界第三大分类广告网站。2016 年 12 月,它的独立月访问量超过 3500 万。平均而言,Avito.ru 的用户每天发布超过 500,000 条新广告,整体广告约为 3,000 万个活跃列表。

我们希望帮助 Avito.ru 根据在线广告的特征(如类别、标题、图像、上下文(发布的地理位置)以及在类似上下文中对类似广告的历史需求)来预测对在线广告的需求。有了这些信息,Avito 可以通知卖家如何最好地优化他们的列表,并提供一些他们实际上应该期望收到多少兴趣的指示。

数据

训练数据包含以下特征:

  • item_id -广告 id。
  • user_id -用户 id。
  • region——公元地区。
  • city - Ad 城。
  • parent_category_name-Avito 广告模型分类的顶级广告类别。
  • category_name-Avito 广告模型分类的精细颗粒广告类别。
  • 【Avito 广告模型的可选参数。
  • 【Avito 广告模型的可选参数。
  • 【Avito 广告模型的可选参数。
  • title -广告标题。
  • description -广告描述。
  • price -广告价格。
  • item_seq_number -用户的广告序列号。
  • activation_date -投放广告的日期。
  • user_type -用户类型。
  • image -图像的 Id 代码。绑定到 train_jpg 中的 jpg 文件。不是每个广告都有图像。
  • image_top_1 - Avito 对图像的分类代码。
  • deal_probability -目标变量。这是一个广告实际卖出东西的可能性。这个特性的值可以是从零到一的任意浮点数。
df = pd.read_csv('train_avito.csv', parse_dates = ['activation_date'])
df.head()

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

Figure 1

由于deal_probability是我们的目标变量,我们想更详细地研究它。

import seaborn as sns
import matplotlib.pyplot as plt
pd.set_option('display.float_format', '{:.2f}'.format)
plt.figure(figsize = (10, 4))
n, bins, patches = plt.hist(df['deal_probability'], 100, facecolor='blue', alpha=0.75)
plt.xlabel('Ad price')
plt.xlim(0, 1)
plt.title('Histogram of deal probability')
plt.show();

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

Figure 2

plt.figure(figsize = (10, 4))
plt.scatter(range(df.shape[0]), np.sort(df['deal_probability'].values))
plt.xlabel('index')
plt.ylabel('deal probability')
plt.title("Deal Probability Distribution")
plt.show();

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

Figure 3

几乎一百万个广告的概率为 0,这意味着它没有卖出任何东西,很少有广告的概率为 1,这意味着它确实卖出了一些东西。其他广告的概率在 0 到 1 之间。

CatBoost

Yandex 研究人员和工程师开发的 CatBoost 是一种在决策树上使用梯度推进的机器学习算法。它是一个开源库。听了很多关于 CatBoost 的好东西,我们应该试一试。

特征工程

缺失值

以下是要素中缺失值的数量。

null_value_stats = df.isnull().sum()
null_value_stats[null_value_stats != 0]

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

Figure 4

我们决定用-999 来填充这些缺失值,通过从它们的分布中填充缺失值,模型将能够很容易地区分它们并将其考虑在内。

df.fillna(-999, inplace=True)

日期时间特征

在删除此列之前,我们使用原始的activation_date列创建了几个新的日期时间特性。

df['year'] = df['activation_date'].dt.year
df['day_of_year'] = df['activation_date'].dt.dayofyear
df['weekday'] = f['activation_date'].dt.weekday
df['week_of_year'] = df['activation_date'].dt.week
df['day_of_month'] = df['activation_date'].dt.day
df['quarter'] = df['activation_date'].dt.quarterdf.drop('activation_date', axis=1, inplace=True)

我们的特征有不同的类型——一些是数字的,一些是分类的,还有一些是文本的,比如titledescription,我们可以把这些文本特征当作分类特征。

categorical = ['item_id', 'user_id', 'region', 'city', 'parent_category_name', 'category_name', 'param_1', 'param_2', 'param_3', 'title', 'description', 'item_seq_number', 'user_type', 'image', 'image_top_1']

我们不需要对分类特征进行编码。CatBoost 支持数字和分类特征。然而,我们确实需要确定分类特征指数。

X = df.drop('deal_probability', axis=1)
y = df.deal_probabilitydef column_index(df, query_cols):
    cols = df.columns.values
    sidx = np.argsort(cols)
    return sidx[np.searchsorted(cols, query_cols, sorter=sidx)]categorical_features_indices = column_index(X, categorical)

CatBoost 模型训练

X_train, X_valid, y_train, y_valid = train_test_split(
    X, y, test_size=0.25, random_state=42)model=CatBoostRegressor(iterations=50, depth=3, learning_rate=0.1, loss_function='RMSE')
model.fit(X_train, y_train,cat_features=categorical_features_indices,eval_set=(X_valid, y_valid),plot=True);

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

Figure 6

一个基本模型给出了一个公平的解决方案,训练和测试误差几乎是同步的。我们将尝试调整模型参数和功能来改善结果。

CatBoost 模型调整

  • iterations是解决机器学习问题时可以建立的最大树数。
  • learning_rate用于减少梯度步长。
  • depth是树的深度。使用 CPU 时,最大为 16 的任何整数。
  • 我们用公制计算 RMSE。
  • bagging_temperature定义贝叶斯自举的设置,值越高,装袋越积极。我们不希望它太高。
  • 我们将使用过拟合检测器,因此,如果发生过拟合,CatBoost 可以在训练参数指示之前停止训练。过拟合检测器的类型是“Iter”。
  • metric_period是计算目标和指标值的迭代频率。
  • od_wait,认为模型过拟合,从具有最优度量值的迭代开始,在指定的迭代次数(100)后停止训练。
  • eval_set是用于过拟合检测器、最佳迭代选择和监控指标变化的验证数据集。
  • use_best_model=True如果输入了一个验证集(定义了eval_set参数),并且该集中至少有一个对象的标签值与其他不同。

CatBoost.py

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

Figure 7

CatBoost 功能重要性

fea_imp = pd.DataFrame({'imp': model.feature_importances_, 'col': X.columns})
fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]
fea_imp.plot(kind='barh', x='col', y='imp', figsize=(10, 7), legend=None)
plt.title('CatBoost - Feature Importance')
plt.ylabel('Features')
plt.xlabel('Importance');

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

Figure 8

CatBoost 功能重要性排名的结果显示,属性“价格”对交易概率的影响最大。另一方面,日期时间特征对交易概率的影响很小。

LightGBM

LightGBM 是一个基于决策树算法的快速、分布式、高性能梯度提升框架。它隶属于微软的 DMTK 项目。

我们将训练一个 LightGBM 模型来预测交易概率。我们将经历与训练 CatBoost 模型时相似的特征工程过程,此外,我们还将对分类特征进行编码。

特征工程

lightGBM_feature_engineering.py

将数据转换为 LightGBM 数据集格式。这是 LightGBM 培训的必修内容。

X_train, X_valid, y_train, y_valid = train_test_split(
    X, y, test_size=0.25, random_state=42)

# LightGBM dataset formatting 
lgtrain = lgb.Dataset(X_train, y_train,
                feature_name=feature_names,
                categorical_feature = categorical)
lgvalid = lgb.Dataset(X_valid, y_valid,
                feature_name=feature_names,
                categorical_feature = categorical)

LightGBM 模型训练

  • num_leaves是控制树模型复杂度的主要参数。当试图调整num_leaves时,我们应该让它小于2^(max_depth) (225)。
  • 我们使用max_depth来限制深树的生长。
  • 为了更精确,我们用大的num_iterations代替小的learning_rate
  • 为了加快训练速度和处理过拟合,我们设置了feature_fraction=0.6,即在训练每棵树之前选择 60%的特征。
  • Set verbosity = -1,eval set 上的 eval metric 在每个详细增强阶段打印。
  • early_stopping_rounds = 500,模型将进行训练,直到验证分数停止提高。验证分数需要至少每 500 轮提高一次才能继续训练。
  • verbose_eval = 500,每 500 个升压阶段打印一个评估指标。

lightGBM_model_training.py

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

Figure 8

LightGBM 功能重要性

fig, ax = plt.subplots(figsize=(10, 7))
lgb.plot_importance(lgb_clf, max_num_features=30, ax=ax)
plt.title("LightGBM - Feature Importance");

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

Figure 9

看到价格仍然处于最高水平并不奇怪。有趣的是,在 lightGBM 模型中,item_seq_number对交易概率的影响最大,但在 CatBoost 模型中,它仅是第 12 个特征。

今天就到这里, Jupyter 笔记本可以在 Github 上找到。新年快乐

参考:卡格尔

傻瓜 Adaboost:将数学(及其方程)分解成简单的术语

原文:https://towardsdatascience.com/adaboost-for-dummies-breaking-down-the-math-and-its-equations-into-simple-terms-87f439757dcf?source=collection_archive---------2-----------------------

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

Learning machines is a long walk up the stairs. But we can shorten the path. (Photo by Gabriel Izgi on Unsplash)

Adaboost 是 Adaptive Boosting 的缩写,是一种机器学习方法,在概念上容易理解,但在数学上不太容易掌握。部分原因是由于方程和公式没有被分解成简单的术语,用基本的数学作为方程的演示。本文旨在通过 Adaboost 实现这一目标,将数据科学领域的新手作为主要目标受众。

有许多精彩的讲座、视频和论文有效而简洁地解释了 Adaboost 背后的概念。简而言之,这种想法是为分类器和数据点(样本)设置权重,迫使分类器专注于难以正确分类的观察值。该过程按顺序完成*,因为随着算法迭代的进行,在每一步都调整两个权重。这就是 Adaboost 被称为顺序集成方法的原因——集成是指一种结合几个模型以提高最终预测性能的学习类型。*

这一概念很容易理解,但是一旦我们试图更深入地理解支持这一概念的数学,我们就会面对许多具有类似景象的文章和讲座:

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

对于那些没有数学学术背景的人和/或非数学类型的人来说,随着最近的机器学习热潮,现在正在学习数据科学,光是符号就显得非常令人生畏。本文旨在通过分解符号和公式,并使用简单的数学来解释 Adaboost 的工作原理,从而消除混淆和恐惧。

基本术语

首先,让我们复习一些基本术语。

增强:结合许多弱(简单)学习者来创建高度准确的预测。

弱学习者:产生比随机猜测略好的预测的分类器。随机猜测相当于 50%,像抛硬币一样。熟悉信息论,尤其是香农熵概念的人对此会很熟悉。

假设:我们的分类器,也就是我们的机器学习算法用来逼近未知函数的函数,目标(真实)函数,它模拟输入值 x 和输出值 y 之间的关系。

Adaboost:第一个实用的 boosting 算法,由 Freund 和 Schapire (1995)发明。它基于 Vapnik 和 Chervonekis 的想法,即一个经过训练的分类器要在其预测中有效和准确,它应该满足以下三个条件:

1)应该在“足够”的训练样本上训练分类器

2)它应该通过产生低训练误差来提供对这些例子的良好拟合

3)它应该简单(因为简单的模型比过于复杂的模型更好)

解释 Adaboost,一步一步来

让我们回顾一下迭代公式,将每一步的每一个符号分解成一个粒度级别,以便于理解。

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

1) 给定(x1,y1),……,(x_m,y_m)其中 x_i ∈ X,y_i ∈ {-1,+1}

有用的符号

∑:“元素”

{}:设置

ex: 如果 A = {1,2,3,7},2 ∈ A

(x_1,y_1):第一个训练样本,(x_m,y_m) =第 m 个训练样本

既然我们已经记下了所有的符号,我们可以将公式的第一部分读作:

“给定包含 m 个样本的训练集,其中所有 X 个输入是总集 X 的元素,y 个输出是仅包含两个值的集的元素,-1(负类)和 1(正类)…”

2)初始化:对于 i = 1,…,m,D1(I)= 1/m

这里,D =样本的权重,i =第 I 个训练样本。在其他论文中,D 将被写成 w。因此,下一个语句是:

“…将样本的所有权重初始化为 1 除以训练样本数…”

3)对于 t=1,…,T:

*使用分布式 Dt 训练弱学习者。

*得到弱假设 h_t: X -> {-1,+1}

*目标:选择加权误差低的 h_t:

ε = Pr_i~Dt [h_t(xi)不等于 y_i]

*选择α_t = 1/2 * ln(1-ε / ε)

*更新,对于 i = 1,…,m:

Dt+1(I)= Dt(I)exp(-αt * y _ I * h _ t(x _ I)/Zt

有用的符号

Pr =概率

假设/分类器

ε =模型的最小错误分类误差

α =分类器的重量

exp =欧拉方程 e: 2.71828

Zt =归一化因子,用于确保权重代表真实分布

有了这些符号,我们可以阅读下一部分:

对于 t=1 到 T 个分类器,使其适合训练数据(其中每个预测为-1 或 1),并选择加权分类错误最低的分类器

正式计算 ε 的公式如下:

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

让我们来分解这个特定的模型。

有用的符号

σ=总和

如果分类错误,y_i 不等于 h_j = 1,如果分类正确,y _ I 不等于 0

重量指数=重量

因此,公式为:“误差等于错误分类率的总和,其中训练样本 I 和 y_i 的权重不等于我们的预测 h_j(如果错误分类,则等于 1,如果正确分类,则等于 0)。”

让我们用简单的数学来理解这个公式。假设有 4 个不同的样本,权重分别为 0.5、0.2、0.1 和 0.04。想象一下,我们的分类器 h 预测值为 1,1,-1 和-1,但实际输出值 y 为-1,1,-1,1。

预测时间:1 1 月 1 日

实际值:-1 1 -1 1

重量:0.5 0.2 0.1 0.04

1 或 0: 1 0 0 1

这导致错误分类率的以下计算:

误分类率/误差=(0.5 * 1+0.2 * 0+0.1 * 0+0.04 * 1)/(0.5+0.2+0.1+0.04)

误差= 0.64285714285

接下来,通过公式 1/2 * ln(1- error / error)为分类器选择权重α。

在这里,简单的数学可能比语言解释得更清楚。例如,假设我们有 0.30,0.70,0.5 的误差。

我们的分类器权重计算如下:

ε = 0.3

α = 1/2 * ln(1- 0.3 / 0.3) = 0.42365

ε = 0.7

α = 1/2 * ln(1- 0.7 / 0.7) = -0.42365

ε = 0.5

α = 1/2 * ln(1- 0.5 / 0.5) = 0

注意三个有趣的观察结果:1)准确度高于 50%的分类器导致该分类器的正权重(换句话说,如果ε < = 0.5) ,则 α >为 0),2)准确度为 50%的分类器为 0,因此对最终预测没有贡献,以及 3)误差 0.3 和 0.7 导致符号相反的分类器权重。

现在是等式中非常重要的部分:更新每个样本的权重。我在上面提到过,更新的重点是迫使分类器专注于难以正确分类的观察值。这是通过在迭代后用增加的权重更新错误分类的案例来实现的。增加权重将使我们的学习算法在下一次迭代中更加关注这些观察结果。相反,在下一次迭代中,正确分类的案例将接收到降低的权重,并减少我们的分类器的注意力。

再一次,用简单的数字作为示范,信息吸收是没有痛苦的。让我们用上面 0.3 的误差率代入公式。请记住,我们正在寻找低加权误差。换句话说,我们不应该使用 0.5 及以上的错误率。在低错误率的情况下,让我们检查当案例被错误分类时和当案例被正确分类时会发生什么。

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

misclassified

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

correctly classified

现在你知道了!在不正确分类的情况下,exp 项变得大于 1,而在正确分类的情况下,exp 项变得小于 1。因此,不正确的分类将获得更高的权重,促使我们的分类器在下一次迭代中更加关注它们,而正确分类的相反情况将导致相反的结果。

我们继续这种迭代,直到 a)实现低训练误差,或者 b)已经添加了预设数量的弱学习者(这是在我们控制之下的参数)。然后,我们通过将每个分类器的加权预测相加得到最终预测。

摘要

我们已经看到了 Adaboost 是如何通过分解公式中的每一个符号在粒度级别上工作的。然后,我们应用简单的数学来理解公式的每个组成部分是如何工作的。这种通过分解的部分来处理公式的实践对于理解机器学习算法是一种有用的实践。

Adam——深度学习优化的最新趋势。

原文:https://towardsdatascience.com/adam-latest-trends-in-deep-learning-optimization-6be9a291375c?source=collection_archive---------1-----------------------

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

Adam 1是一种自适应学习率优化算法,专门为训练深度神经网络而设计。Adam 于 2014 年首次发布,在深度学习实践者的一个非常著名的会议上亮相— ICLR 2015 。该论文包含一些非常有前途的图表,显示了在训练速度方面的巨大性能增益。然而,过了一段时间,人们开始注意到,在某些情况下,亚当实际上找到了比随机梯度下降更差的解决方案。已经做了很多研究来解决亚当的问题。

该算法利用自适应学习速率方法的能力来为每个参数找到单独的学习速率。它还具有 Adagrad [10]和 RMSprop [11]的优点,Adagrad[10]在具有稀疏梯度的设置中工作得非常好,但在神经网络的非凸优化中很困难,rms prop[11]解决了 Adagrad 的一些问题,并且在在线设置中工作得非常好。根据Andrej Karpathy的文章《机器学习趋势一瞥】, Adam 的受欢迎程度呈指数增长。

在这篇文章中,我首先介绍了在原始论文中提出的 Adam 算法,然后介绍了围绕它的最新研究,展示了这些算法在某些领域不如经典 SGD 的一些潜在原因,并提供了几种解决方案,缩小了 SGD 和 Adam 之间的差距。

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

Adam 可以看作是 RMSprop 和带动量的随机梯度下降的组合。它使用平方梯度来缩放学习速率,如 RMSprop,并通过使用梯度的移动平均值而不是梯度本身来利用动量,如 SGD 使用动量。让我们仔细看看它是如何工作的。

Adam 是一种自适应学习率方法,这意味着它计算不同参数的个人学习率。它的名字来源于自适应估计,之所以这么叫是因为 Adam 使用梯度的一阶和二阶矩的估计来适应神经网络的每个权重的学习速率。现在,什么是瞬间?随机变量的 n 阶矩定义为该变量的期望值的 n 次方。更正式地说:

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

m — moment, X -random variable.

第一次理解这个想法可能相当困难,所以如果你不能完全理解,你仍然应该继续,你将能够理解算法是如何工作的。注意,神经网络成本函数的梯度可以被认为是随机变量,因为它通常在一些小的随机批数据上评估。一阶矩是均值,二阶矩是无中心方差(意思是我们在方差计算的时候不减去均值)。我们稍后会看到如何使用这些值,现在,我们必须决定如何得到它们。为了估计力矩,Adam 利用指数移动平均值,根据当前小批量评估的梯度进行计算:

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

Moving averages of gradient and squared gradient.

其中,m 和 v 是移动平均值,g 是当前小批量的梯度,β是新引入的算法超参数。它们分别有非常好的默认值 0.9 和 0.999。几乎没有人会改变这些价值观。移动平均的向量在第一次迭代时被初始化为零。

要了解这些值如何与第一个等式中定义的时刻相关,让我们看看移动平均线的预期值。由于 m 和 v 是一阶矩和二阶矩的估计值,我们希望具有以下性质:

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

估计量的期望值应该等于我们试图估计的参数,碰巧的是,在我们的例子中,参数也是期望值。如果这些性质成立,这将意味着,我们有无偏估计量。(要了解更多关于不同估计量的统计特性,请参考伊恩·古德费勒的深度学习书籍,第 5 章关于机器学习基础知识)。现在,我们将看到这些对我们的移动平均线不成立。因为我们用零初始化平均值,所以估计量偏向于零。让我们证明对于 m(对于 v 的证明是类似的)。为了证明这一点,我们需要用公式计算 m 的第一个梯度。让我们尝试展开 m 的几个值,看看我们要使用的模式:

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

正如你所看到的,我们把 m 的值扩大得越多,梯度的第一个值对整体值的贡献就越小,因为它们会乘以越来越小的β。捕捉到这种模式,我们可以改写均线的公式:

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

现在,让我们看看 m 的期望值,看看它与真正的一阶矩有什么关系,这样我们就可以校正两者的差异:

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

Bias correction for the first momentum estimator

在第一行中,我们使用移动平均的新公式来展开 m。接下来,我们用 g[t]来近似 g[i]。现在我们可以把它从 sum 中取出来,因为它现在不依赖于 I,因为正在进行逼近,所以误差 C 出现在公式中。在最后一行中,我们只使用了有限几何级数求和的公式。从这个等式中我们应该注意两件事。

  1. 我们有偏倚的估计量。这不仅仅适用于 Adam,同样适用于算法,使用移动平均线(SGD with momentum,RMSprop 等)。).
  2. 除非是训练的乞求,否则不会有太大的作用,因为β的 t 次方的值很快就趋向于零。

现在我们需要修正估计量,使期望值是我们想要的。这一步通常被称为偏差校正。我们的估计量的最终公式如下:

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

Bias corrected estimators for the first and second moments.

剩下要做的唯一事情就是使用这些移动平均值来分别衡量每个参数的学习率。在 Adam 中完成的方式非常简单,要执行权重更新,我们执行以下操作:

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

其中 w 是模型权重,eta(看起来像字母 n)是步长(它可以取决于迭代)。就这样,这就是亚当的更新规则。对于一些人来说,用代码来理解这些概念可能更容易,所以下面是 Adam 在 python 中的可能实现:

在 Adam 上有两个小的变化,我在实践中没有看到太多,但它们在主要的深度学习框架中实现了,所以有必要简要地提到它们。

第一个名为 Adamax 是 Adam 的作者在同一篇论文中介绍的。Adamax 的想法是将值 v 视为单个当前和过去梯度的 L2 范数。我们可以将其推广到 Lp 更新规则,但对于 p 的大值,它会变得非常不稳定。但如果我们使用L-无穷范数的特例,它会产生一个令人惊讶的稳定且性能良好的算法。以下是如何用 python 实现 Adamax:

第二个有点难懂,叫做那达慕【6】。《那达慕》由蒂莫西·多扎特在《将内斯特罗夫的动力融入亚当》一文中发表。顾名思义,这个想法是用内斯特罗夫动量项来表示第一条移动平均线。让我们来看看 SGD 的更新规则:

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

SGD with momentum update rule

如上图,更新规则相当于在动量向量方向上走一步,然后在梯度方向上走一步。但是动量步长不依赖于当前的梯度,所以在计算梯度之前,我们可以通过用动量步长更新参数来获得更高质量的梯度步长方向。为此,我们对更新进行了如下修改:

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

f — loss function to optimize.

所以,对于内斯特罗夫加速动量,我们首先在之前累积的梯度方向上做一个大的跳跃,然后测量我们结束的梯度,做一个修正。从 cs231n 的课堂笔记中可以看到一个很好的形象化的例子:

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

sourec: cs231n lecture notes.

同样的方法可以纳入亚当,通过改变第一移动平均线到内斯特罗夫加速动量。这里可以应用一个计算技巧:代替更新参数以产生动量步长并再次变回来,我们可以通过仅应用时间步长 t + 1 的动量步长一次来实现相同的效果,在先前时间步长 t 而不是 t + 1 的更新期间。使用此技巧,Nadam 的实现可能如下所示:

亚当的属性

这里我列出了亚当的一些特性,为了证明这些特性是正确的,请参考这篇论文。

  1. Adam 在每次迭代中采用的实际步长近似受限于步长超参数。这一特性增加了对先前非直观学习率超参数的直观理解。
  2. Adam 更新规则的步长对于梯度的大小是不变的,这在穿过具有微小梯度的区域(例如鞍点或峡谷)时很有帮助。在这些领域,SGD 很难快速浏览。
  3. Adam 的设计结合了 Adagrad 和 RMSprop 的优点,前者适用于稀疏渐变,后者适用于在线设置。拥有这两者使我们能够将 Adam 用于更广泛的任务。Adam 也可以看做是 RMSprop 和 SGD 与 momentum 的结合。

亚当的问题

当亚当第一次被介绍时,人们对它的力量感到非常兴奋。论文中包含了一些非常乐观的图表,显示了在训练速度方面取得的巨大成绩:

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

source: original Adam paper

然后,Nadam paper 展示了显示更好结果的图表:

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

source: Nadam paper

然而,过了一段时间后,人们开始注意到,尽管训练时间很长,但 Adam 在一些领域并没有收敛到最优解,因此对于一些任务(如在流行的 CIFAR 数据集上的图像分类),最先进的结果仍然只能通过应用 SGD with momentum 来实现。不止是威尔逊等人。al [9]在他们的论文“自适应梯度方法在机器学习中的边际价值”中表明,当在一组不同的深度学习任务上进行测试时,自适应方法(如亚当或阿达德尔塔)的泛化能力不如 SGD,这阻碍了人们使用流行的优化算法。自那以后,人们做了大量的研究来分析 Adam 的不良概括,试图让它缩小与 SGD 的差距。

Nitish Shirish Keskar 和 Richard Socher 在他们的论文“通过从 Adam 切换到 SGD 来提高泛化性能”[5]中也表明,通过在训练期间切换到 SGD,他们能够获得比单独使用 Adam 更好的泛化能力。他们提出了一个简单的解决方案,使用了一个非常简单的想法。他们已经注意到,在训练的早期阶段,亚当仍然比 SGD 表现更好,但后来学习饱和了。他们提出了一个简单的策略,他们称之为 SWATS ,其中他们开始用 Adam 训练深度神经网络,但当某些标准达到时,就切换到 SGD。他们成功取得了与 SGD 相当的成绩。

论亚当的收敛性

找出 Adam 的问题在于分析它的收敛性。作者在他们最初的论文中证明了 Adam 在凸集上收敛到全局最小值,然而,后来几篇论文发现他们的证明包含一些错误。Block et。al [7]声称他们在最初的收敛分析中发现了错误,但仍然证明了该算法收敛,并在他们的论文中提供了证明。谷歌员工最近的另一篇文章在 ICLR 2018 上发表,甚至获得了最佳论文奖。为了深入他们的论文,我应该首先描述 Adam 作者用来证明它收敛于凸函数的框架。

2003 年 Martin Zinkevich 介绍了在线凸规划问题[8]。在所呈现的设置中,我们有一系列凸函数 c1、c2 等(在深度学习优化的情况下,在第 I 个小批量中执行的损失函数)。在每个时间戳 t 中解决问题(Adam)的算法选择点 xt,然后接收当前时间戳的损失函数 c。这种设置转化为许多现实世界的问题,例如阅读论文的介绍。为了理解算法工作得有多好,T 轮后算法的后悔值定义如下:

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

Regret of the algorithm in the online convex programming

其中 R 是遗憾,c 是关于第 t 个小批量的损失函数,w 是模型参数(权重)的向量,w 星是权重向量的最优值。我们的目标是证明算法的后悔是 R(T) = O(T)或更小,这意味着平均起来模型收敛到一个最优解。Martin Zinkevich 在他的论文中使用凸函数的性质证明了梯度下降在这种情况下收敛到最优解:

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

Well-known property of convex functions.

相同的方法和框架使用 Adam 作者来证明他们的算法收敛到最优解。Reddi 等人[3]在他们的证明中发现了几个错误,主要错误出现在 Adam 和 Improving Adam 的收敛证明论文中:

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

其中 V 被定义为一个抽象函数,它对每个算法不同的参数的学习速率进行缩放。对于 Adam,它是过去平方梯度的移动平均值,对于 Adagrad,它是所有过去和当前梯度的总和,对于 SGD,它只是 1。作者发现,为了证明有效,这个值必须是正的。很容易看出,对于 SGD 和 Adagrad,它总是正的,然而,对于 Adam(或 RMSprop),V 的值可以出乎意料地起作用。他们还提出了一个亚当未能收敛的例子:

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

Adam fails on this sequence

对于这个序列,很容易看出最优解是 x = -1,然而,作者如何显示,亚当收敛到 x = 1 的高度次优值。该算法每 3 步获得一次大的梯度 C,而在另外 2 步中,它观察梯度-1,这使算法朝错误的方向移动。由于步长值通常会随着时间的推移而减小,因此他们提出了保持最大值 V 的解决方案,并使用它来代替移动平均值来更新参数。由此产生的算法被称为 **Amsgrad。**我们可以用这个我创作的小本子来证实他们的实验,它展示了不同的算法收敛于上面定义的函数序列。

Amsgrad without bias correction

它对现实世界数据的实际应用有多大帮助?可悲的是,我还没有看到一个案例比亚当更有助于获得更好的结果。在的 Filip Korzeniowski 在他的帖子中描述了 Amsgrad 的实验,该实验显示了与 Adam 相似的结果。西尔万·古格和杰瑞米·霍华德在他们的文章中显示,在他们的实验中,Amsgrad 实际上比亚当表现得更差。该论文的一些评论者还指出,问题可能不在于 Adam 本身,而在于我在上面描述的用于收敛分析的框架,该框架不允许太多的超参数调整。

亚当的体重下降

Ilya Loshchilov 和 Frank Hutter 的论文“修正 Adam 中的权重衰减正则化”[4]实际上对 Adam 有帮助。这篇论文包含了很多对亚当和体重衰减的贡献和见解。首先,他们表明,尽管普遍认为 L2 正则化不同于权重衰减,尽管它对于随机梯度下降是等价的。1988 年引入重量衰减的方式是:

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

其中 lambda 是要调整的权重衰减超参数。我稍微改变了一下符号,以便和文章的其余部分保持一致。如上所述,当进行权重更新时,权重衰减应用于最后一步,惩罚大的权重。SGD 的传统实现方式是通过 L2 正则化,我们修改成本函数以包含权重向量的 L2 范数:

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

历史上,随机梯度下降方法继承了这种实现权重衰减正则化的方式,Adam 也是如此。然而,L2 正则化并不等同于亚当的权重衰减。当使用 L2 正则化时,我们用于大权重的罚值通过过去和当前平方梯度的移动平均来缩放,因此具有大的典型梯度幅度的权重通过比其他权重更小的相对量来正则化。相比之下,权重衰减通过相同的因子来调整所有权重。要对 Adam 使用权重衰减,我们需要修改更新规则,如下所示:

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

Adam update rule with weight decay

已经显示了这些类型的正则化对于 Adam 是不同的,作者继续显示了它们的工作情况。论文中的图表很好地显示了结果的差异:

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

The Top-1 test error of ResNet on CIFAR-10 measured after 100 epochs

这些图表显示了学习率和正则化方法之间的关系。颜色代表这对超参数的测试误差的高低。正如我们在上面可以看到的,不仅 Adam 与重量衰减得到更低的测试误差,它实际上有助于解耦学习率和正则化超参数。在左图中,我们可以看到,如果我们改变参数,比如学习率,那么为了再次达到最佳点,我们还需要改变 L2 因子,这表明这两个参数是相互依赖的。这种依赖性导致超参数调整有时是一项非常困难的任务。在右图中,我们可以看到,只要我们保持在某个参数的最佳值范围内,我们就可以独立地改变另一个参数。

该论文作者的另一项贡献表明,用于权重衰减的最佳值实际上取决于训练期间的迭代次数。为了解决这个问题,他们提出了一个简单的自适应公式来设置重量衰减:

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

其中 B 是批量大小,B 是每个时期的训练点总数,T 是时期总数。这将使用新的 lambda 归一化参数来替换 lambda 超参数 lambda。

作者甚至没有就此停止,在修复体重衰减后,他们试图将学习率计划与新版 Adam 的热重启一起应用。热重启对随机梯度下降有很大帮助,我在我的帖子中谈到了更多关于提高学习率的方法。但是之前亚当落后 SGD 很多。随着新的体重下降,亚当在重新开始时取得了更好的成绩,但仍然不如 SGDR。

第二代亚当

张等人提出了另一种修正亚当的尝试,这种尝试我在实践中并不多见。al 在他们的论文“规范化的方向保持亚当”[2]。这篇论文注意到了 Adam 的两个问题,这两个问题可能会导致更糟糕的概括:

  1. SGD 的更新存在于历史梯度的跨度中,而 Adam 则不是这样。在已经提到的论文[9]中也观察到了这种差异。
  2. 第二,虽然 Adam 参数更新的幅度对于梯度的缩放是不变的,但是更新对同一整体网络函数的影响仍然随着参数的幅度而变化。

为了解决这些问题,作者提出了他们称之为规范化方向保持亚当的算法。算法以下列方式调整亚当。首先,不是估计每个单独参数的平均梯度幅度,而是估计梯度向量的平均平方 L2 范数。因为现在 V 是标量值,M 是与 W 方向相同的向量,所以更新的方向是 M 的负方向,因此在 W 的历史梯度的跨度内。对于第二种情况,在使用梯度之前,算法将其投影到单位球上,然后在更新之后,权重通过它们的范数被归一化。更多细节请关注他们的论文。

结论

Adam 绝对是深度学习的最佳优化算法之一,其受欢迎程度增长非常快。虽然人们已经注意到在某些领域使用 Adam 的一些问题,但研究人员仍在继续努力寻找解决方案,使 Adam 的结果与 SGD 的结果不相上下。

参考

  1. 迪德里克·p·金马和吉米·巴雷。亚当:一种随机优化的方法。2014.arXiv:1412.6980v9
  2. 张子君等人归一化保向亚当。2017.arXiv:1709.04546v2
  3. 萨尚克·雷迪萨延·卡莱桑基夫·库马尔论亚当的趋同与超越。2018.
  4. 伊利亚·洛希洛夫弗兰克·赫特修正 Adam 中的权重衰减正则化。2017.arXiv:1711.05101v2
  5. 尼提什·希里什·凯斯卡尔,理查德·索彻通过从 Adam 切换到 SGD 来提高泛化性能。2017 arXiv:1712.07628v1
  6. 蒂莫西·多扎特。将内斯特罗夫的动力融入亚当。2016.
  7. 塞巴斯蒂安·博克约瑟夫·戈波尔德马丁·韦奥ADAM 优化器收敛证明的改进。2018.arXiv:1804.10587v1
  8. 马丁·津克维奇。在线凸规划和广义无穷小梯度上升。2003.
  9. 阿希娅·c·威尔逊丽贝卡·鲁洛夫斯米切尔·斯特恩内森·斯雷布罗本杰明·雷希特机器学习中自适应梯度方法的边际价值。2017.arXiv:1705.08292v2
  10. 约翰·杜奇,埃拉德·哈赞,约拉姆·辛格。在线学习和随机优化的自适应次梯度方法。机器学习研究杂志,12:2121–2159,2011。
  11. 提门·提勒曼和杰弗里·辛顿。讲座 6.5-rmsprop: 将梯度除以其最近震级的移动平均值。COURSERA:用于机器学习的神经网络,4(2):26–31,2012。

坚定不移。

原文:https://towardsdatascience.com/adamant-3d87e8d98b83?source=collection_archive---------6-----------------------

又见面了。我的互联网昨天莫名其妙地出了问题,我没有机会写一点我的一个启示!在过去的几天里,我一直在为这个项目收集数据,我发现了一种使用预测分析的新方法。这对我来说不一定是新的,但有时当你开始做一个项目时,你可以如此坚定地坚持一种方式,以至于你忘记了一个项目有许多角度需要解决。

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

以上是一个片段 CSV 文件,我创建了包括每个场馆的功能。目前,我们正在试验每项功能,以及它们预测客户偏好的能力。回到启示,在过去的几天里,我一直在从每个场馆的网站和每个不同的社交媒体页面提取信息(客户评论、评级和评论)。一些特征是你的典型特征——场地类型、氛围、菜单风格、位置等等——但后来我决定找点乐子。

神奇宝贝

我的第一个“为了好玩”的测试是在附近的 Pok 和 mon stops 和顾客去那个地方的可能性之间的相关性。它可能有也可能没有任何显著的相关性或商业价值,但是,如果这个特性吸引客户的可能性微乎其微,我会测试一下。我知道我又要遵循统计学的黄金法则"*相关性并不意味着因果关系,"*然而,这是一个有趣的项目,如果它带回了任何有价值的东西,我会与你们所有人分享(我想我刚刚打破了另一条黄金法则…得克萨斯州的规则是说 ya 'll 而不是 you all…whatev)。

相似性测试

好了,回到正题。因此,对于我给定的集合,我将执行余弦相似性/相似性分析测试(类似于亚马逊和网飞向我们推荐类似产品的做法)。然而,在我开始之前,我必须扩展我的数据集,包括那些还没有被访问过的场馆,以便创建一个排名系统,并查看哪些企业在与已经签约的场馆的相似性方面排名最佳。

机器学习

我最初的方法是使用离散变量对不同的场馆进行分类——签约的和未签约的——然后检查这是否是一个很好的预测器/指示器,如果一个场馆是否会与in choices 做生意。

学校的领导团队有一个理论,强大的社交媒体存在等同于理想的工作场所;给出这些信息后,我还会运行一个逻辑回归(LogReg)来测试这个假设的有效性。我已经将我的数据集按照已经签约的和潜在的地点(我的训练和测试数据集)进行了划分。从那里开始,我将在训练集上使用我与社交媒体相关的功能,并计算酒吧是否会签名。

网页抓取

网络抓取将允许我提取评论并建立一个文本分析器,以真正了解客户体验并区分每个场馆的优势。我使用图书馆 BeautifulSoup ,一个去图书馆,从不同的网站提取内容。下面是第一步,在我进入实质部分之前。马上我就能看到大多数的评论都与早餐的选择有关。下一步是进一步分析其余的评论,并根据这些信息做出明智而恰当的决定。

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

结论

我知道我没有对我的方法做太多的详细说明,主要是因为我将为每种不同的方法写个人博客,并进一步详细说明。目前,这是总体计划。在一个小的创业公司工作很辛苦,但是非常有益。它挑战了我,让我用我所有的知识从不同的角度来处理每一项任务。我掌握的信息越多,领导团队对他们的业务就越有信心。我将在接下来的几天内回来,并带来项目的最新进展。

自适应认证和机器学习

原文:https://towardsdatascience.com/adaptive-authentication-and-machine-learning-1b460ae53d84?source=collection_archive---------2-----------------------

“我们打个比方:你家的前门有一个把手,很容易转动就能进出。它有一把安全锁,”Nuro Secure Messaging 的联合创始人 Omri Sigelman 说。“你加的锁越多,开门就越费力.”

如今,随着技术时代的发展,在保持高安全性标准的同时确保用户工作效率的双重挑战已经成为一个相当关键的挑战。尽管对安全性的关注并不一定会损害可用性,但人们仍在努力实现这样的动机。

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

自适应身份验证的概念在传统的身份验证控制框架中充满了复杂性,并消除了用户工作效率的障碍。在认证控制过程中加入额外的风险因素(如位置、网络类型或操作系统)的效率低下,使得传统框架越来越过时。

简单地说,自适应身份认证是一种可以配置和部署双因素身份认证或多因素身份认证的方式。这是一种根据用户的风险状况和倾向选择正确的身份认证因素的方法,用于根据具体情况调整身份认证类型。

Adaptive Authentication 的功能非常强大,可以识别相关的风险级别,并在现实场景中提供适当的身份验证级别。与可能对可用性、安全性、效率和合规性造成负面影响的“一刀切”等标准不同,Adaptive Authentication 在另一方面避免了低风险活动变得过于费力或高风险活动变得过于容易。

简而言之,这种非静态身份验证方法采用请求访问系统的代理的概况来确定与该交易相关的风险概况。之后,风险状况将用于确定挑战的复杂性。如前所述,这种方法适用于为高风险档案提供经受更强挑战的可行性的情况,而静态用户名/密码对于低风险档案可能就足够了。

当谈到在工业环境中实现自适应认证时,很明显,已经采用了不同的方法来实现自适应认证过程的不同变体。然而,考虑到手头问题的性质,基于机器学习的模型可以被识别为实现的有效机制。

OneLogin 已经采用这种实现方法来迎合他们“可用性驱动安全性”的动机。他们的自适应身份验证使用机器学习来确定是否提示用户进行多因素身份验证。为了使流程更加突出,它使用广泛的输入来计算风险分值,并为给定情况确定最合适的安全措施。以下是 OneLogin 在其基于机器学习的自适应身份验证模型中使用的输入类型的概述。

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

在 OneLogin 的 Adaptive Authentication 模型中,将根据将获得的风险分值执行以下操作。

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

很明显,通过这种基于机器学习的自适应身份认证模型,OneLogin 为其客户提供了无缝、安全的用户体验,可以跟上当今不断发展的安全风险。

在传统的环境中,很明显,当涉及到安全研究和安全系统开发时,人的因素和可用性问题被经验性地忽略了。在安全性和可用性之间总是有一个重要的权衡。然而,这种争论在商业系统中不会持续太久,因为在现代,一切都同等重要。这就是为什么像 Adaptive Authentication 这样的方法需要进入身份和访问管理领域的原因。

参考

  1. https://www . onelog in . com/product/multi-factor-authentic ation

2.https://news . hitb . org/content/RSA-更新-自适应-认证-解决方案-高级-威胁

3。https://www . onelog in . com/blog/what-is-adaptive-authentic ation

自适应元启发式智能粒子(AMI-P)

原文:https://towardsdatascience.com/adaptive-meta-heuristically-intelligent-particle-ami-p-4badd123b3a2?source=collection_archive---------8-----------------------

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

Red Stars — Track of best solutions. Blue Star — AMI-Particle

AMI 粒子

AMI-P 是我新发现的优化方法。AMI 粒子使用单个粒子迭代地搜索全局最优,该单个粒子智能地学习并适应凸和非凸 n 维搜索空间。

如下所示,AMI-P 在单峰和多峰目标函数中都收敛到全局最优。这项研究部分是因为我发现了一个数学恒等式。这个恒等式通过在目标函数的可行搜索空间内请求自适应 n 维旋转,赋予了 AMI 粒子探索和开发的平衡。

AMI 粒子的一个独特但值得注意的特征是它不含导数;因此,AMI-P 是无梯度的。这允许 AMI 粒子在相对于维度的线性时间中在更高维度中收敛。动画性能部分下面是 100,000- & 1,000,000 维单峰和多峰函数的性能结果。

下面显示的所有结果都是使用 Matlab 在 MacBook Pro 上运行 200 次后的最差性能。这些对于应用数学领域来说是非常有希望的结果。数学优化方法是 人工智能(神经网络)、力学、分子工程、土木工程、运筹学、地球物理学、控制工程、电气工程以及最后但并非最不重要的经济学和金融学中的关键因素。

粒子动画表演

对于每个测试函数,使用 Matlab 生成二维动画性能图。动画显示了粒子探索搜索空间,同时保持*‘吸引’到它学习利用*的区域。

粒子每次收敛到全局最优小于~ 0.1/s;然而,出于演示的目的,我放慢了动画 gif 的速度。

动画图下方是针对球体RastriginGriewank 函数的 100,000 维和 1,000,000 维测试中的 AMI-Particle 性能结果。

粒子-球函数

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

https://www.sfu.ca/~ssurjano/griewank.html

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

AMI Particle Sphere Test — 2-D where xi ∈ [-100, 100], for all i = 1, …, D (100 epochs)

AMI 粒子— Rastrigin 函数

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

https://www.sfu.ca/~ssurjano/rastr.html

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

AMI Particle Rastrigin Test — 2-D where xi ∈ [-5.12, 5.12], for all i = 1, …, D (100 epochs)

AMI-Particle — 格里万克函数

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

https://www.sfu.ca/~ssurjano/griewank.html

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

AMI Particle Griewank Test — 2-D where xi ∈ [-600, 600], for all i = 1, …, D (250 epochs)

粒子——戈尔茨坦价格函数

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

https://www.sfu.ca/~ssurjano/goldpr.html

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

AMI Particle Goldstein-Price Test — 2-D where xi ∈ [-2, 2], for all i = 1, 2 (300 epochs)

AMI 粒子——维度测试

10 万维收敛测试

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

AMI-Particle 100,000-d Sphere Test — Worst-Case Performance Results of 200 Runs (~ 3/s)

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

AMI-Particle 100,00-d Rastrigin Test — Worst-Case Performance Results of 200 Runs (~ 3/s)

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

AMI-Particle 100,000-d Griewank Test — Worst-Case Performance Results of 200 Runs (~3/s)

1,000,000 维收敛测试

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

AMI-Particle 1,000,000-d Sphere Test — Worst-Case Performance Results of 200 Runs (~ 9/s)

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

AMI-Particle 1,000,000-d Rastrigin Test — Worst-Case Performance Results of 200 Runs (~ 9/s)

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

AMI-Particle 1,000,000-d Griewank Test — Worst-Case Performance Results of 200 Runs (~ 9/s)

下一步是什么?

随着使用不同的数学优化方法解决的过多现实世界问题的增加,自适应元启发式智能粒子方法的有希望的结果激励着我继续我的研究。我相信这种方法可以大幅提高性能,并减少人工智能深度学习中神经网络所需的计算资源。

使用 CustomVision.ai 和 Microsoft bot Framework 为您的聊天机器人添加图像识别功能

原文:https://towardsdatascience.com/add-image-recognition-to-your-chatbot-with-customvision-ai-and-microsoft-bot-framework-d0f8b30dba50?source=collection_archive---------6-----------------------

在我之前的博客文章中,我已经分享了关于如何使用 CustomVision.ai 创建自定义图像分类器。一旦您能够使用自定义视觉创建图像分类器,您可能会尝试将图像分类器添加到您的应用程序中,如手机、网络或聊天机器人。

在本教程中,我将向你展示如何使用你的自定义视觉图像分类器,到你的使用 Node.js 的聊天机器人。

设置您的聊天机器人

我们要做的第一步是使用微软机器人框架创建我们的聊天机器人。

  1. 为你的聊天机器人创建一个项目文件夹
  2. 在您的终端中执行npm init来创建package.json
  3. 安装将用于项目npm i --save botbuilder restify的节点模块
  4. 在您的项目文件夹中创建一个app.js

在你的app.js文件中,添加我们聊天机器人工作所需的初始代码。

获取自定义视觉的预测 API 端点

下一步将是获得自定义视觉的预测 API 端点,我们稍后将用于我们的聊天机器人。(注意:这里假设您已经在 Custom Vision 中创建和训练了您的分类器)

  1. 前往https://www . custom vision . ai
  2. 选择您已经创建或想要使用的项目
  3. 转到“性能”选项卡
  4. 点击“预测 URL”
  5. 记下“图像文件”端点 URL 和“预测关键字”

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

使用自定义视觉的预测 API 到我们的聊天机器人

一旦您做好了一切准备,我们现在将使用来自自定义视觉的预测 API 到我们的聊天机器人。

让我们的聊天机器人读取图像附件

这里我们需要做的第一件事是通过编程使我们的聊天机器人能够读取来自用户的图像附件。

  1. 在中创建一个utils.js文件,我们将在其中包含读取图像附件的实现
  2. 运行npm i needle --save
  3. 实现utils.js的代码

4.将utils.js代码导入app.js

5.向bot.dialog()添加一些测试代码,看看我们的聊天机器人现在是否可以确定它是否从用户那里接收到图像附件

现在你可以在你的 Bot 框架模拟器上测试它,它至少应该是这样的:

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

创建一个使用自定义视觉预测 API 的服务

既然我们的聊天机器人可以确定用户是否发送了图像附件,那么下一步就是将来自用户的图像附件发送到定制的视觉预测 API。

  1. 在聊天机器人的项目文件夹中创建customVisionService.js文件
  2. 运行npm i request-promise --save
  3. 执行customVisionService.js的代码

4.导入并使用customVisionService.js到你的app.js

现在,您可以在您的 bot 框架模拟器上再次测试这一点,并尝试向您的 Bot 发送一个图像附件,看看它将如何工作。

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

非常简单明了,对吗?如果想看完整个项目做参考,可以查看 GitHub 库这里

给深度学习增加不确定性

原文:https://towardsdatascience.com/adding-uncertainty-to-deep-learning-ecc2401f2013?source=collection_archive---------0-----------------------

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

如何使用 Edward 和 TensorFlow 构建深度学习模型的预测区间

统计建模和机器学习之间的区别日益模糊。他们都从数据中学习并预测结果。主要的区别似乎来自于不确定性估计的存在。不确定性估计允许假设检验,尽管通常以可伸缩性为代价。

机器学习=统计建模-不确定性+数据

理想情况下,我们通过向机器学习添加不确定性来融合两个世界的优点。最近在变分推理( VI )和深度学习( DL )方面的发展使这成为可能(也叫 贝叶斯深度学习 )。VI 的好处在于,它可以很好地随数据大小伸缩,并且很好地适应允许模型合成和随机优化的 DL 框架。

向模型添加不确定性的一个额外好处是,它促进了 基于模型的机器学习 。在机器学习中,预测的结果是你的模型的基础。如果结果没有达到标准,策略就是“向问题扔数据”,或者“向问题扔模型”,直到满意为止。在基于模型(或贝叶斯)的机器学习中,您被迫指定数据和参数的概率分布。想法是首先明确地指定模型,然后检查结果(比点估计更丰富的分布)。

贝叶斯线性回归

这是一个给简单的线性回归模型增加不确定性的例子。简单的线性回归预测标签 Y 给定数据 X 权重 w.

Y = w * X

目标是通过最小化损失函数找到未知参数 w 的值。

(Y - w * X)

让我们把这个转换成一个概率。如果假设 Y 为高斯分布,则上述等价于最大化以下相对于 w 的数据似然:

p(Y | X,w)

到目前为止,这是传统的机器学习。要给你的体重估计增加不确定性,并将其转化为贝叶斯问题,只需在原始模型上附加一个先验分布即可。

p(Y | X,w) * p(w)

请注意,这相当于通过贝叶斯规则反演原始机器学习问题的概率:

p(w | X,Y) = p(Y | X,w) * p(w) /常数

给定数据的权重的概率( w )就是我们对于不确定性区间所需要的。这是重量 w后验分布

尽管添加先验在概念上很简单,但计算通常很难;也就是说,常数是一个很大的、不好的积分。

蒙特卡罗积分

概率分布的积分近似值通常是通过抽样来完成的。对分布进行采样和平均将得到期望值的近似值(也称为蒙特卡罗积分)。所以让我们把积分问题重新表述成一个期望问题。

上面的常数从数据和权重之间的联合分布中整合出权重。

常数= ∫ p(x,w) dw

要将其重新表述为期望值,引入另一个分布, q ,并根据 q 取期望值。

∫ p(x,w) q(w) / q(w) dw = E[ p(x,w) / q(w) ]

我们选择一个 q 分布,这样就很容易从中取样。从 q 中抽取一串 w ,取样本平均值得到期望值。

E[ p(x,w) / q(w) ] ≈样本均值[ p(x,w) / q(w) ]

这个想法我们以后会用到变分推理。

变分推理

变分推理的思路是,你可以引入一个变分分布, q ,带变分参数, v ,把它变成一个优化问题。分布 q 将近似于后验分布。

q(w | v) ≈ p(w | X,Y)

这两个分布需要接近,一个自然的方法将最小化它们之间的差异。通常使用 Kullback-Leibler 散度( KL 散度)作为差分(或变分)函数。

KL[q || p] = E[ log (q / p) ]

KL 散度可以分解为数据分布和证据下界( ELBO )。

KL[q || p] =常数- ELBO

常量可以忽略,因为它不依赖于 q 。直觉上, qp 的分母相互抵消,剩下 ELBO。现在我们只需要在 ELBO 上进行优化。

ELBO 只是具有变化分布的原始模型(在这里详细计算)。

ELBO = E[ log p(Y | X,w)*p(w) - log q(w | v) ]

为了获得对 q 的期望值,使用蒙特卡罗积分(取样并取平均值)。

在深度学习中,通常使用随机优化来估计权重。对于每个小批,我们取损失函数的平均值来获得梯度的随机估计。类似地,任何具有自动微分的 DL 框架都可以将 ELBO 估计为损失函数。唯一的区别是你从 q 中取样,平均值将是期望值的一个很好的估计,然后是梯度。

构建预测间隔的代码示例

让我们对一些生成的数据运行贝叶斯简单线性回归示例。以下内容也适用于 DL 模型,因为它们只是简单的线性回归。我们使用一个名为 Edward (基于 TensorFlow )的贝叶斯深度学习库来构建模型。

Gist 上有完整的代码。

第一步是定义权重的先验分布。

weight = ed.models.Normal(mu=tf.zeros(1), sigma=tf.ones(1))

在深度学习中,weight将是点估计。在贝叶斯 DL 中,weight是一个分布,它的后验概率由下面的变分分布来近似。

qw_mu = tf.get_variable(tf.random_normal([1]))
qw_sigma = tf.nn.softplus(tf.get_variable(tf.random_normal([1]))
qweight = ed.models.Normal(mu=qw_mu, sigma=qw_sigma)

注意,变化参数qw_muqw_sigma是估计的,而weight不是。从qweight采样将给出weight的后验不确定性区间(假设方差参数固定)。

我们将线性回归定义为预测模型。任何 DL 型号都可以替代。

nn_mean = weight * x + bias

数据似然性的构造类似于先验分布(假设方差参数固定)。

nn = ed.models.Normal(mu=nn_mean, sigma=tf.ones(1))

ELBO 度量取决于数据似然性和先验。数据似然性由标签数据绑定。每个先验分布必须由变分分布约束(假设变分分布之间是独立的)。

latent_vars = {weight: qweight, bias: qbias}
data = {nn: y}

运行推理优化很容易,因为:

inference = ed.KLqp(latent_vars, data)
inference.run()

为了提取不确定性区间,我们直接对变分分布qweight进行采样。这里,前两个矩是在采样 100 次后提取的。

mean_, var_ = tf.nn.moments(qweight.sample(100))

我们还可以将不确定性区间添加到预测中(也称为后验预测区间)。这可以通过复制模型并用所有后验概率替换先验来完成(本质上是在对数据进行训练之后更新模型)。

nn_post = ed.copy(nn, dict_swap={weight: qweight.mean(), bias: qbias.mean()})

再次运行图表 100 次,我们得到预测的不确定性区间。

mean_, var_ = tf.nn.moments(nn_post.sample(100), feed_dict={x: data})

现在我们有了整个分布,假设检验就容易了。

tf.reduce_mean(nn_post.sample(100) > labels)

但是等等,还有更多,辍学间隔!

如果完全贝叶斯是一个太多的投资,不确定性区间可以计算从神经网络通过辍学层。

机器学习模型的正则化和贝叶斯模型中的先验分布之间有很强的联系。例如,经常使用的 L2 正则化本质上是高斯先验(更多细节在此)。

Dropout 是一种根据伯努利分布随机清除神经元的技术。这可以通过 KL 散度标准下的高斯过程来近似(这里有更多细节,因为我不确定数学上的)。

在实践中,这意味着我们在漏失层打开的情况下运行模型 100 次,并查看结果分布。

# keep the dropout during test time
mc_post = [sess.run(nn, feed_dict={x: data}) for _ in range(100)]

mc_post的样本均值是估计值。对于不确定性区间,我们简单地计算样本方差加上以下反精度项:

def _tau_inv(keep_prob, N, l2=0.005, lambda_=0.00001):
    tau = keep_prob * l2 / (2\. * N * lambda_)
    return 1\. / tau

这给了我们原则上的不确定性区间,而不需要太多投资。

np.var(mc_post) + _tau_inv(0.5, 100)

摘要

要获得不确定性区间,您可以:

  1. 在模型中加入一个先验,通过变分推理逼近后验,然后从后验中取样
  2. 运行现有模型很多次,并打开丢弃层

混合解决方案是在感兴趣的特定参数上增加不确定性。在自然语言建模中,这可能只是将单词嵌入作为潜在变量。

AddressNet:如何使用递归神经网络构建一个健壮的街道地址解析器

原文:https://towardsdatascience.com/addressnet-how-to-build-a-robust-street-address-parser-using-a-recurrent-neural-network-518d97b9aebd?source=collection_archive---------5-----------------------

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

Australian Postage stamps, image by author

街道地址是复杂的野兽;它们被设计成对我们人类来说是系统的和明确的,但对机器来说却是一场灾难。事实上,你将为谷歌的每 1000 次地址查询支付5 美元,澳大利亚邮政将为你提供一批经过认证的“解决方案提供商”,同时还为那些预先分拣邮件并为其贴上条形码的人(即做艰苦工作的人)提供折扣。

维护结构化地址数据的价值超出了过去的邮资。将地址简化为地理坐标(地理编码)的能力可以为一些看似简单的问题提供答案,比如“我在哪里的销售额最高?”,但不需要太多的想象力就能看出如何从一个人的位置得出各种各样的关联,例如公共卫生部门的(我目前工作的行业)。

当然,从一开始就以结构化的方式收集这些信息是有意义的,但是如果您有一个手动输入且未经验证的地址记录的遗留数据集,该怎么办呢?如果你在 StackOverflow 上问…的无辜的问题

寻找一种快速而简单的方法将澳大利亚的街道地址解析成各个部分:
3A/45 Jindabyne Rd, Oakleigh, VIC 3166

…您将很快被告知"您将获得完全无用的数据",然后您将看到一个类似于的正则表达式:

(?P<Unit_Number>\d*)\s*[\/,\,]\s*(?P<Street_Number>\d*)\s*(?P<Street_Name>[a-zA-Z\s]*),?\s*(?P<State>NSW|ACT|NT|QLD|SA|TAS|VIC|WA)\s*(?P<Post_Code>\d{4})| (?P<street_number>\d*)\s*(?P<street_name>[a-zA-Z\s]*),?\s*(?P<state>NSW|ACT|NT|QLD|SA|TAS|VIC|WA)\s*(?P<post_code>\d{4})

对复杂和无情的正则表达式感到沮丧和悲伤,你会偷偷溜走,在 instagram 上查找#ferrets,因为这才是互联网的真正目的。

我是来告诉你不要难过的。我的意思是,观察雪貂;毕竟他们很可爱…我不想剥夺你的可爱。但是一旦你完成了,回来。我将向您展示如何构建自己的地址解析机器。

遵循传统的神经网络命名法[Thing]+Net 的 address Net 是一个漂亮的模型,它通过给地址的位标上22 个可能组成部分中的任何一个来整理它们,并且基于GNAF 数据库。这是我在 TensorFlow 上花了大约一周时间研究的成果(也让我自己从机器学习的间隙中解脱出来)——我确信一个更有才华的人可以在更短的时间内完成这个(现在的孩子们)。

TL;dr:如果你想要一个 Python API 来分割你的澳大利亚街道地址,试试吧。

>>> from addressnet.predict import predict_one
>>> print(predict_one("3A/45 Jindabyne Rd, Oakleigh, VIC 3166"))
{'flat_number': '3', 'flat_number_suffix': 'A', 'number_first': '45', 'street_name': 'JINDABYNE', 'street_type': 'ROAD', 'locality_name': 'OAKLEIGH', 'state': 'VICTORIA', 'postcode': '3166'}

嘣。

那么这个诡计是如何运作的呢?很抱歉,我不能公正地对待这个理论;许多比我更聪明的人在这些话题上写了很多。因此,我将从较高的层面解释 AddressNet 中使用的过程,并链接到我最喜欢的作者,他们优雅的解释不值得在此复制。

address net 模型的核心是一个递归神经网络 (RNN),它们非常擅长模拟序列数据(在这种情况下,是一系列字母)。这种神经网络通常用图表表示为:

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

A typical representation of RNNs (left and right are equivalent)

在上图中, x 是输入数据序列中的一项, y 是某个目标的估计或输出。左边的环形箭头,以及右边同样标有“ h ”的水平箭头,代表一种“隐藏状态”每个输入都有下标( t -1、 tt +1 等)。)指示特定序列元素起源的点,这通常被称为“时间步长”(尽管这通常不是字面意义上的时间,而是通过元素的“定向行进”)。中间的大 ol’圆形斑点包含产生 y s 和 h s 的所有矩阵运算,但是一定要注意每个斑点都是相同的;完全相同的内部参数被应用于每个输入的 hx ,从而使它们重复

【推荐阅读:递归神经网络的不合理有效性

RNNs 的工作方式可以简单地解释如下:对于序列中的每一项数据,使用前一步的隐藏状态以某种方式对其进行转换,以估计目标输出,同时更新隐藏状态以移交给下一步。这种神秘的隐藏状态可以被认为是“扫描序列时收集的知识”,它的功能是一种记忆。RNN 体系结构的许多变体都围绕着如何管理隐藏状态,最常见的类型是 LSTM 和 GRU 类型的 rnn(address net 使用 GRU 类型的 RNN)。

【推荐阅读:了解 LSTM 网络了解 GRU 网络

能够将序列中较早的信息向前传递是 RNNs 的关键优势。例如,在自然语言处理中,诸如复数和性别之类的语法概念以及相应的词的变化经常是远距离链接的。想象一下,一个 RNN 被设计用来识别不恰当的动词形式;一个简单的语法检查器,如果你愿意:

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

A hypothetical NLP RNN to detect grammar issues. Long distance dependencies highlight the importance of “memory”

每个 x 代表句子的一个单词,如果没有错误,每个 y 产生 0,如果有错误,产生 1。这里,动词“is”实际上应该是“are ”,因为名词“diagrams”是复数。保留先前元素的一些记忆的能力允许这个假设的网络生成被框定为“的结果鉴于我到目前为止所看到的,当前元素是错误的概率是多少?”

RNN 可以扩展为多层(每一步的输出作为另一个 RNN 的输入输入),它们也可以与一个等效的 RNN 配对,其中水平箭头处于相反的方向,向后传递隐藏状态,有效地查看“未来”以了解“过去”后者被称为双向 RNN。

【推荐阅读:双向递归神经网络 / PDF

AddressNet 基于每个字符使用多层双向 RNN。双向性是特别重要的:考虑一下地址“10 24–26 高街路,芒特韦弗利”给每个角色分配一个类别,而对于第一个角色来说,仅仅向前看几乎是不可能的!是的,可能单位/平号是最常出现的第一个字,可能整体来说单位比单机多,所以我们可能统计上有机会,但真的只是瞎猜。类似地,在没有任何预见未来的能力的情况下,“街道”很可能是指街道的类型…但是当我们遇到“道路”时,才发现我们犯了一个错误,这个名称实际上是“道路”类型的“高街”在 AddressNet 实现中,与上面的图表不同的一点是,AddressNet RNN 的输出不是直接的预测,而是向前和向后传递连接在一起,并通过最终的“完全连接”神经网络-这些是标准的教科书网络,在谷歌图像搜索中排名第一。如果你想了解这个网络的具体实现,请查看这部分代码。

**但是人物首先是怎么表现出来的呢?**什么的‘A’?我们如何将字母“A”塞进这个神奇的数学包中呢?在神经网络中有两种主要的方法可以表示文本数据:“一键”向量方法和密集的“嵌入向量”方法。前者由一个和我们的词汇一样长的向量组成(可以是一系列单词、字符,甚至是表情符号🤷‍♀️),在对应于我们的字典中的项目的索引处包含“1 ”,在其他地方包含“0 ”,而嵌入向量方法是通过任意长(但通常比词汇表短得多)的向量来实现的,该向量具有由模型学习的参数;也就是说,即使是表象本身也随着我们的训练而优化。历史上,嵌入向量已经被用于导出语义单词关系,但是这里我只是将它们用于降维(并且我通常喜欢优化输入参数的想法)。AddressNet 使用嵌入方法,每个字符有八个单位的短向量。

【推荐阅读: TensorFlow docs ,以及任何关于单词嵌入的东西(例如米科洛夫的 word2vec 论文)】

**我们来谈谈训练数据。**唉,我过去没有——现在也没有——任何标记过的、精选过的真实地址数据。相反,我的方法是综合生成尽可能多的随机排列(在某些情况下几乎无法理解),这些排列仍然在合理的范围内。有代码的大杂烩,可以被破译以理解我屠杀 GNAF 数据集的精确方式,但本质上代码为 GNAF 数据集中的每条记录做出以下决定:

  1. 保留还是放弃郊区?
  2. 保持还是放弃状态?
  3. 缩写州名?(例如将“维多利亚”改为“维克”)
  4. 保留还是删除邮政编码?
  5. 保留还是放弃街道号码?
  6. 简称街道类型?(例如将“道路”改为“道路”)
  7. 保留还是删除单位类型?
  8. 把等级数转换成序数或基数词?(例如,将“1”更改为“1st”或“first”)

然后,这些组件以一种特殊的方式被打乱(例如,将州和邮政编码之类的东西放在靠近末尾的地方),然后每个组件都受到一些随机破坏,这有点像人类可能犯的错别字。错别字包括:

  1. 字符替换(使用键盘上邻近的字符)
  2. 删除
  3. 调换
  4. 复制

最后,使用一些随机分隔符将每个组件缝合在一起。这些可能是空格、破折号、斜线或句号(取决于地址的部分)。

但是为什么呢?有两个原因:首先,这些很可能会在现实世界中发生,模型应该足够健壮来处理这些。其次,这种额外的噪声旨在作为一种正则化的形式,正则化是一个术语,指的是降低模型过度拟合可能性的方法。

正确地改变和破坏数据是当务之急!在开发这个模型的时候,我敏锐地意识到我没有测试数据;我无法通过先验的方式知道这个模型在现实世界中的表现如何。理想情况下,我会有一个从手动输入的地址完全标记的测试集,但我只是一个人在业余项目工作。因此,对我来说,关键是要确保输入数据中有如此多的可变性,以至于模型复杂性不能开始“学习噪音”训练有素的模型的经验表明,我击中了目标,但我会喜欢你,读者,给它一个机会,让我知道它如何进行。我知道,我知道,没有测试数据是我的耻辱😔。

**准备好试试了吗?**我敢肯定你说是。只是皮普安装它,看看你怎么想:https://github.com/jasonrig/address-net

欢迎投稿、反馈、指正和建议。如果你在自己的项目中使用 AddressNet,或者对其进行修改,请告诉我。希望您的地址数据永远不需要正则表达式。🙏

调整 Python 与熊猫合并的价格以适应通货膨胀

原文:https://towardsdatascience.com/adjusting-prices-for-inflation-in-pandas-daaaa782cd89?source=collection_archive---------5-----------------------

几年来,我管理着一家小型初创投资基金。虽然华尔街分析师在分析公司时通常只回顾一两年,但我经常会追溯到 20 年或 30 年前。我甚至会偶尔翻阅上世纪 50 年代、20 年代或罕见的 19 世纪的经济和价格数据,以便更好地理解市场周期。然而,当你进行这种深度长期历史分析时,你会遇到一个问题: 名义价格可能非常具有欺骗性

以谷物价格为例。我们有谷物生产者价格指数追溯到 1926 年 1 月,当时该指数在 20 世纪 20 年代的繁荣时期为 37.9。2018 年 4 月,同一指数为 151.5。因此,在 92 年的时间框架内,谷物价格上涨了 4 倍。如果我们从 1933 年大萧条的底部开始衡量(当时指数为 11.0),价格已经上涨了 15 倍!

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

这是一张非常容易误导人的图片,仅仅从上面的图表很难看出这一点。一旦我们对通货膨胀进行调整,我们就会得到下面这张看起来完全不同的图表。

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

随着时间的推移,谷物价格不仅没有上涨,实际上还在下跌。经 CPI 通胀调整后,如今的谷物价格比 1926 年低了 71%。今天的价格甚至比大萧条时期的低点低 24%。

随着时间的推移,谷物变得越来越便宜,实际农产品价格的下降缓解了世界大部分地区的贫困状况。你可能从来没有通过简单地看顶部图表中的名义价格而获得这种洞察力。你必须根据通胀进行调整,才能获得这种视角。

美国的通货膨胀

在过去的一个世纪里,美国的通货膨胀出现了戏剧性的循环。在第二次世界大战中,通货膨胀率飙升至 10.5%。到 1953 年,通货膨胀率一路下降到 0.8%。1980 年,通货膨胀率高达 13.5%,之后美联储对其进行了打击。2005 年,官方 CPI 通胀率为 3.4%,但美国最大的 20 个大都市区的房价却上涨了 14%!2017 年,通胀相对温和,为 2.0%(但随着劳动力和投入成本继续上升,通胀开始再次回升)。

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

通货膨胀调整让你对实际价格有更好的理解。这个分析可以很有见地。事实上,我最成功的投资论文之一围绕着考察日本资产泡沫期间经通胀调整的铜价,并将其与 2000 年代末/2000 年代初的铜价泡沫进行比较。

然而,如果你在一个熊猫数据框架中工作,通货膨胀调整在 Python 中似乎是一个棘手的问题。您可能有数千行“数据点”,其日期分散在数据框的整个范围内。然而,通货膨胀数据往往是连续月度数据的形式。你如何将两者联系起来?

寻找你的消息来源

首先要说的是来源。你用什么数据来调整通货膨胀?你在哪里找到通货膨胀的数据?

并不总是有一个“正确”的答案,但是如果你住在美国或者正在处理美国的价格数据,那么美联储经济数据(通常缩写为“FRED”)应该是你的首选来源之一。有几十种通货膨胀衡量方法,但我最常用的一种叫做“ CPIAUCNS ”。这个通胀数据集可以一直追溯到 1913 年,这就是为什么它往往是我最喜欢的长期分析。

还有许多其他数据集。例如,如果你正在查看明尼阿波利斯的房价数据,你可能更喜欢查看房价指数,如全交易房价指数Case-Shiller 明尼阿波利斯房价指数。然而,通常情况下,CPI 的某个变量就是你要用的指数。

设置您的索引

CPI 通胀指数和房价指数已经以某种方式进行了指数化,但是你可能需要重新对数据进行指数化以适应你自己的目的。例如,如果您的通货膨胀数据在 1982 年 1 月的指数为 100,而您的数据集处理的是 2004 年到 2017 年的数据,您可能希望根据 2004 年的价格(开始)或 2017 年的价格(结束)来索引您的数据。

我们可以用 Excel 或者 Python 来做这个。诚然,我发现在 Excel 中调整数据通常更容易,但如果我们有一个特别大的数据集,Python 可能是一个更好的选择。

在 Python 中,我们可以通过加载通胀数据并为“指数乘数”创建一个新列来实现这一点。然后,我们只需将名义价格乘以“指数乘数”。

# load inflation data
inflation = pd.read_excel(‘inflation_data.xls’, sheetname=’Data’)# create index multiplier
inflation[‘CPI_Multiplier’] = inflation[‘CPI’].iloc[-1] / inflation[‘CPI’]

注意在这个例子中,我使用最后一个数据值来创建指数,因此价格将被索引到今天的价格。如果我们使用第一个数据点基于开始的起始点进行索引,我们将选择第一个值而不是最后一个值。

现在我们有了一个调整价格的指数。我们需要合并两个数据集来执行操作。

匹配日期

然而,在我们合并之前,我们必须处理这个练习中最棘手的部分:日期。日期可能是编程中的一大难题。有几种方法可以处理它们。

在最近的数据集中,我发现月份和年份在不同的列中,如下例所示。

Month Year
01    2008
04    2012
09    2016

同时,我的通货膨胀数据上的日期被识别为 yyyy/mm/dd 格式,如下所示:

Date          CPI_Multiplier
2008/01/01    1.000
2008/02/01    1.003
2008/03/01    1.005
2008/04/01    1.011

两者如何对齐?

答案有很多,但我创建了一个“日”列,并将其赋值为 1(以匹配通货膨胀数据中的日期),并使用 pd.to_datetime 在原始数据集中创建一个“日期”列。

# load data set
df = pd.read_excel('training_data.xlsx')# create new day column for 'day'
df['day'] = 1#create new dataframe to store date info
new_df = df[['year', 'month', 'day']]# create new column 'Date' in original data w/ datetime conversion
df['Date'] = pd.to_datetime(new_df)

在 Pandas 中,pd.to_datetime()是一个强大的工具,但是您必须让您的数据恰到好处地工作。

合并数据

最后,我们加载膨胀数据,并使用 pd.merge 来合并两个数据帧。“how”参数指定联接的类型。在这种情况下,我将“df”(我的主数据集)设置为第一个参数,将“inflation”(通货膨胀数据)设置为第二个参数,并使用“left”连接在“Date”进行合并。

# merge dataframe
df = pd.merge(df, inflation, how='left', on='Date')

现在,有了合并的数据框架,创建索引就很容易了。

df[‘CPIAdjPrice’] = df[‘SalePrice’] * df[‘CPI_Multiplier’] 

维奥拉。我们现在可以看到实际价格了!

结论

在长期数据序列中,通货膨胀调整对理解数据至关重要。通过使用名义价格,它也可以使预测变得更加棘手。

通货膨胀调整可以用于观察商品价格或零售价格,但也可以与住房价格指数一起使用,以调整动荡市场中的住房价格。这样,我们可以将“市场波动”和“通货膨胀”作为预测模型的一部分。

高级数据扩充策略

原文:https://towardsdatascience.com/advanced-data-augmentation-strategies-383226cd11ba?source=collection_archive---------14-----------------------

深度学习模型热爱数据。除了向深度学习模型添加更多的训练数据,没有更好的方法来快速提升你的深度学习模型的性能。

然而,收集和标注数据可能非常耗时且昂贵。因此,许多深度学习研究人员对数据增强技术感兴趣,以便为这些庞大的数据饥渴模型综合添加训练数据。

对于图像数据,有许多经典的/易于实现的数据扩充方法。最流行的方法之一是水平翻转图像。水平翻转图像、裁剪图像同时保留图像中的感兴趣对象以及增加颜色空间是最常用的经典数据扩充方法,这些方法很可能会提高最终模型的性能。

许多图像处理功能,如平移、剪切、旋转等。可用作经典的数据扩充功能。您还可以使用随机区域锐化、弹性变换、随机擦除图像的补丁等等来增加数据和创建新的训练实例。

在许多研究中,这些经典增强已被证明能够提高图像数据的性能。也有新的方法正在研究,似乎很有前途。这些方法包括对抗训练、生成对抗网络、风格转移以及使用强化学习来搜索增强可能性的空间。

对抗训练

对抗性训练是深度学习中一个非常令人兴奋的话题。对抗训练是生成对抗网络的基础,但它们也可以用于学习噪声增强,这可能有助于模型表现得更好。在对抗训练中,一个模型对实例进行分类,另一个模型获取实例并向其添加噪声,以试图欺骗另一个分类器。然后,分类模型为这个对立模型提供损失函数,使得它可以优化自身以产生更好的噪声。添加通过对抗性训练产生的图像可能有助于模型学习更强大的不受噪声失真影响的特征。

生成对抗网络

生成对抗网络是深度学习中最热门的话题之一。通过使用生成器网络将噪声向量映射到宽度 x 高度 x 颜色通道图像张量,该模型能够生成看起来像原始训练图像的图像。这种方法的主要问题是很难用 GANs 产生高分辨率的输出图像。在 MNIST(28 x 28 x 1)、CIFAR-10 (32x32x3)数据和 DCGAN(添加到生成器网络的深度卷积层)上,使用 GANs 进行数据扩充已被证明是有效的,并产生了(64x64x3)图像。产生比这更高分辨率的输出需要非常复杂的网络和技术。

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

MNIST ‘3’ I was able to make using a DCGAN with Python/Keras

神经类型转移

神经类型转移是深度学习中另一个令人难以置信的令人兴奋的话题。通过卷积神经网络的过程,这些网络能够惊人地将风格与内容分开。样式表示被格式化为“gram matrix ”,并且由此导出损失函数,以将一个图像的样式转移到另一个图像,同时保留内容。这可以产生诸如使普通图片看起来像是文森特·范·高夫所画的效果。风格增强在数据增强中是一个相当新的主题,但是我希望随着对这个主题的研究越来越多,它会做得越来越好。

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

Neural Style Transfer

离散空间搜索的强化学习

对于所有这些进行数据扩充的潜在方法,很难找到最佳组合。传统上,这种可能性树可以通过深度或广度优先搜索来天真地探索,一旦达到期望的性能就停止。然而,随着围绕深度强化学习的所有兴奋,已经有一些研究探索学习增强策略的可能性。这样做也是希望这些数据扩充策略能够在图像数据域中推广。

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

Discrete Space Search Illustration

结论

总之,所有这些的目的是尝试向我们的训练集添加数据,从而产生更好的深度学习模型。在深度学习研究的广度中,存在许多进行数据增强的创造性方法。数据扩充的研究对于构建更好的模型和创建系统非常重要,这样您就不必收集大量的训练数据来获得可靠的统计模型。感谢您的阅读!

CShorten

Connor Shorten 是佛罗里达大西洋大学计算机科学专业的学生。对计算机视觉、深度学习和软件工程感兴趣。

高级 DQNs:用深度强化学习玩吃豆人

原文:https://towardsdatascience.com/advanced-dqns-playing-pac-man-with-deep-reinforcement-learning-3ffbd99e0814?source=collection_archive---------3-----------------------

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

art by Yojama

2013 年,DeepMind 发布了第一个版本的 Deep Q-Network (DQN),这是一个能够在许多经典的 Atari 2600 游戏上表现出人类水平的计算机程序。就像人类一样,算法根据它对屏幕的视觉进行游戏。从零开始,它发现了让它满足(在许多情况下,超过)人类基准的游戏策略。在此后的几年里,研究人员做出了许多改进,超级充电性能和解决游戏的速度比以往任何时候都快。我们一直致力于在 Keras(开源、高度可访问的机器学习框架)中实现这些进步,在这篇文章中,我们将详细介绍它们如何工作以及如何使用它们来掌握 Pac-man 女士。

强化学习简介

DQN,以及类似的算法如 AlphaGo 和 TRPO,都属于机器学习的子集强化学习 (RL)的范畴。在强化学习中,一个主体存在于一个环境中,并寻求某种回报的最大化。它采取行动,改变环境,并给予环境与改变相关的回报。然后,它查看自己的新状态,并决定下一个动作,无休止地重复这个过程,或者直到环境终止。这个决策循环更正式地称为马尔可夫决策过程 (MDP)。

很容易看出像《吃豆人》这样的雅达利游戏是如何融入 MDP 框架的。玩家看着游戏屏幕,从不同的按钮和操纵杆位置中进行选择,以增加他们的分数。但这种简单性可能隐藏了一项艰巨的任务,任何玩过视频游戏的人可能都认为这是理所当然的,这是一个根据几乎无限的像素组合之一做出即时决定的过程,这些像素组合可以在任何给定的时间显示在屏幕上,而且是你以前不太可能遇到的。如果这还不够困难的话,视频游戏在技术上是部分可观察的 MDPs,在这个意义上,你被迫基于游戏的间接表示(屏幕)而不是代码/内存本身做出选择,隐藏了一些你需要做出完全知情决定的信息。幸运的是,像吃豆人这样的视频游戏确实提供了两个有用的简化:帧速率和控制器。有限数量的按钮和操纵杆位置让我们可以将观察空间映射到离散和可管理的行动空间,当你意识到它不需要连续完成时,这种心理功能会进一步简化,因为你只能在每一帧按下一个按钮(大多数 RL 代理会更进一步,每 3 或 4 帧才做出新的决定)。接下来的挑战是困难但可定义的:我们如何利用我们玩游戏的经验做出增加分数的决策,并将决策过程推广到我们从未经历过的新位置?

深度 Q 网络的基础知识

dqn 利用神经网络令人难以置信的成功来解决这一挑战。该架构可以分为两部分。首先,一系列卷积层学会检测游戏输入屏幕越来越抽象的特征(我们稍后将详细讨论这是如何工作的以及它学会检测什么)。然后,密集分类器将当前观察中存在的那些特征的集合映射到输出层,对于控制器上的每个按钮组合有一个节点。

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

Neural network schematic from DeepMind’s 2015 paper

这些输出值是代理在采取行动时对预期回报的最佳预测。这种“状态到预测奖励”的方法被称为基于值的学习,并以行动值函数 Q( s,a )为中心,表示在状态 s,中采取行动 a 的总价值,它是未来奖励 r 的总和,通过贴现因子γ进行调整,指示代理预期计划未来多远。最优策略被写成:

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

也就是说,在每一步中,我们都在采取导致最高奖励分数的行动。一旦我们可以计算出这些 Q 值,这就非常简单了,但是当然我们的 Pac-man 代理不能真正看到未来,也不能给每个可能的状态分配一个唯一的 Q 值。这就是深度学习的用武之地。通过将像素图像映射到 Q 值,我们的神经网络充当了 Q 函数逼近器,因此尽管它看不到未来,但通过足够的训练,它可以学会预测未来。

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

该训练是使用上述损失函数的梯度下降来完成的,该损失函数是时间差的变化。这可以被认为是“真实”或目标 Q 值和我们当前对它们的估计之间的差异,其中目标值是即时奖励加上我们在下一个状态将采取的行动的 Q 值。当然,这个值也是由我们的网络计算出来的,但由于它至少可以访问第一个奖励项,所以整体表达式本质上更准确。即便如此,这在数学上绝对等同于试图击中移动目标,因为真实值是由我们正在训练的同一个网络计算的。这是监督学习(机器学习的另一个子集,包括图像分类和情感分析等任务)和强化学习之间的巨大差异。监督学习使用带标签的数据集,这意味着目标值由人类手动设置,并假设是准确和不变的。强化学习创建它自己的、不断变化的数据集,这既是因为网络生成它自己的目标值,也是因为网络的动作选择直接影响它将到达其环境中的哪个状态,因此它必须学习什么。为了帮助管理,我们实际上采取了两个额外的稳定措施。首先,我们复制神经网络,使用第二个副本或目标网络来生成目标值,使用原始网络或在线网络来生成估计值。只有在线网络被训练,但是我们经常把它的权重复制到目标网络,用更优化的参数刷新它。第二,我们使用一种叫做体验缓冲的东西。缓冲区是我们的代理过去经历的数据集,其中经历被定义为( s,a,r,t,s’ ),其中 s,ar 保持它们先前的定义, t 是一个布尔值,它让代理知道这是否是该事件的最终状态,而 s’ 表示当代理采取行动时跟随 s 的状态您会注意到一个经验条目包含了计算损失函数所需的所有变量。因此,代理不是在玩吃豆人游戏时学习,实际上只是根据它已经学习的东西在屏幕上移动吃豆人,而是将所有这些经验添加到缓冲区中。然后,我们可以从存储中获取经验,并将其回放给代理,以便它可以从中学习,并在未来采取更好的行动。这在概念上类似于人类重放记忆以便从中学习,这个过程被恰当地命名为经验重放*。最重要的是,它确保代理从它的整个历史中学习(或者至少是在我们开始覆盖最老的数据之前我们实际上可以存储的尽可能多的历史),而不是从它最近的轨迹中学习。*

值得注意的是,这些架构决策将 DQN 归类为非策略、无模型算法*。*无模型,因为它学习预测与位置相关联的值,但不试图建立其环境的内部工作的模型,以便预测它将看到的下一个状态,以及无策略,因为它的训练样本是由它自己的过去版本生成的(因此是它的决策策略的过去版本)。

还有一个更重要的细节需要回避,那就是探索问题。在 Markov agents 内部,关于冒险探索新想法和利用已知事物哪个更好的争论从未停止过。想象一下,如果算法总是按下它认为会导致最高奖励的按钮,会发生什么?它很可能每一次都做同样的动作,从不尝试其他任何事情,因此永远不会进一步学习和提高。例如,它可能在第一次尝试时就知道从起始区域向右走可以得到几分,然后不管有多少鬼魂或墙壁挡在它的路上,它都继续向右走;它从未尝试过向左走,因此没有办法准确估计这样做会产生的回报。最初的 DQN 以一种武断但惊人有效的方式解决了这个问题。我们将变量ε初始化为 1.0。对于每一步,我们都会生成一个介于 0 和 1 之间的随机数。如果这个数字小于ε,我们完全随机地采取一个行动,不管代理人对这个行动的 Q 值说了什么。因为ε是 1,我们 100%的时间都这样做。但是随着训练的进行,我们将ε降低到 0.1 左右,这意味着我们在 90%的时间里采取最佳行动,而在另外 10%的时间里探索一个新的随机方向。有趣的是,我们在实践中从未让 epsilon 达到 0(即使在测试/评估期间,我们通常使用. 05);这确保了吃豆人女士永远不会被困在角落里或无限期停止移动。这种方法被称为ε贪婪。

既然我们已经进入了实验/代码,现在可能是时候提及所有这些结果(包括所有训练模型的权重文件),以及生成它们的脚本可以在这个项目的 GitHub repo 上找到。DQN 算法的内部工作是在开源库 keras-rl 中实现的。然而,在我们一直在研究并将在下面描述的更高级的技术被批准合并到主版本中之前,可能还需要一段时间。与此同时,您可以在我们的论坛上访问它们。

关于 dqn(以及一般的 RL 算法)需要知道的是,它们的采样效率很低,训练成本也很高。DQN 文献中的标准方法是进行 2 亿次框架训练。这相当于在一个 P4000 GPU 上进行大约 930 小时的人类速度游戏或大约 20 天的训练(至少对于我们将看到的最终 DQN 版本来说)。我们没有足够的资源为算法的每个版本完成这样的事情。相反,我们选择对 1000 万帧进行这些比较实验(足以突出差异),并训练我们最终表现最好的代理进行更长的 4000 万步运行。

这样一来,是时候看看我们所描述的算法是如何执行手头的任务的了。

香草 DQN 挑战吃豆人小姐

在培训期间监控和分析代理成功的一个有效方法是在每集结束时绘制其累积奖励。

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

奖励函数与游戏中的分数成比例(但不等于,实际上比游戏中的分数小得多),所以它本身并不意味着什么。然而,代理显然能够学习一些关于游戏的知识,以便随着时间的推移不断改进。还要注意投资回报的递减,就像任何学习曲线一样——人类或机器。

让我们来看看一些游戏,看看它是如何做的。

令人惊讶的是,代理已经学会了在迷宫中导航。当仍然有密集的口袋需要收集时,它甚至可以很好地清理大面积区域。然而,它很难找到回到溜走的孤独的几个点的路,每当它发现自己被困在两个口袋中间,必须决定先去哪一个时,它似乎都彻底崩溃了(像在 0:29)。当鬼魂变得脆弱时,它似乎也不会主动追捕它们,只会在收集迷宫每个角落的所有点的过程中偶然触发这种行为。

双 Q 学习

2015 年, van Hasselt 等人双 q 学习应用于 DQN,这一修改提高了一些游戏的性能。请注意,在上面的损失函数中,我们使用目标网络来计算下一个状态中每个动作的 q 值,并选择我们想要采取的动作(最高的一个)。事实证明,这可能导致一些高估问题,特别是当目标网络和在线网络之间的差异导致它们在给定相同状态的情况下推荐完全不同的动作时(与 q 值略有不同的相同动作相反)。为了解决这个问题,我们取消了目标网络确定最佳行动的责任;它只是生成 Q 值,我们让在线模型决定使用哪一个。更正式地说,双 DQN 根据以下公式生成目标值:

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

决斗建筑

RL 理论的一个重要细节是,Q 函数实际上可以分解为两个独立项的总和:价值函数 V( s ),它表示处于当前状态的价值,以及优势函数 A( s,a ),它表示每个动作的相对重要性,并有助于确保代理采取可能的最佳动作,即使该选择可能不会对游戏分数产生任何直接影响。

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

2016 年,王等人发表了决斗网络架构,将神经网络分成两个流,共享一个卷积基,每个流用于估计一个函数。

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

Vanilla DQN architecture (top) vs. Dueling DQN (bottom). Dueling estimates the action and value functions separately, before combining them to arrive at the overall Q function.

上面架构示意图中的绿色箭头代表我们用来组合它们的方法。不幸的是,天真的解决方案(将 A( s,a )添加到 V( s ))是无效的,因为网络没有被激励来独立地优化 V 和 A,因此我们根本不能保证这些就是它正在学习的。相反,我们使用另一种方法:

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

其中αβ分别代表优势流和价值流的参数。现在网络可以使用其所选动作的知识将优势函数推至 0,使得 Q( s,a )近似等于 V( s )。

优先体验回放

当人们回顾过去,从我们的错误中学习时,我们会优化过程,把时间花在最需要的地方。当你期中考试不及格,决定期末考试要做得更好时,你会去专门检查你做错的问题;你不会浏览页面或者只是检查 3 的偶数倍。到目前为止,我们的代理一直从重放缓冲区中均匀随机地进行采样。在《吃豆人》的上下文中,这意味着我们的代理人在没有敌人的直道上滑行的情况比它进入三面都有幽灵的四向交叉路口、选择错误并付出代价的情况多得多。但是,如果它能从自己最错误的经历中吸取教训,那会怎么样呢?

Schaul 等人在 2016 年的论文中提出了一个解决方案,被称为优先化体验回放 (PER)。在 PER 中,我们使用一个额外的数据结构来记录每个转换的优先级。然后按照优先顺序对经验进行抽样:

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

其中 alpha 是一个超参数,表示我们希望这个采样偏差有多大。优先级本身只是代理上一次在该经验上训练时的时间差异误差。通过这种方式,我们的代理更有可能从最不准确的预测中学习,消除其故障点,并且通常更加高效。

还有重要性采样权重的细节,这是为了补偿这样一个事实,即我们现在有意提供网络数据,这将导致异常大的梯度更新。

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

这些重要性权重由一个超参数 *beta、*控制,该参数控制我们想要补偿它们的力度。该β值通常在整个运行过程中保持稳定,从初始化的~ 0.6 上升到 1.0(完全补偿)。即便如此,每个装备的代理倾向于使用较低的学习率(通常大约 0.25 倍)来防止灾难性崩溃。

优先双人决斗 vs 吃豆人

虽然这三个改进中的每一个都可以单独做出重大改进,但它们的伟大之处在于它们可以存在于同一个算法中,有点牵强地称为优先双决斗 DQN (PDD)。这是学习曲线,与我们之前的版本相对照:

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

虽然在最初几千集的繁重探索阶段,他们的表现同样不佳,但 PDD 在 2k 集时开始脱离。虽然这种差距似乎很难区分,但游戏视频讲述了一个更好的故事:

新增加的功能使我们的代理人能够有明确意图地寻找孤立的破折号——不再在迷宫中随机徘徊。它似乎还把在角落里捡起能量丸和获得更高的奖励联系起来,很可能是因为偶然遇到鬼魂,一旦这种行为使他们变得脆弱。有趣的是,它并没有完全取消这种策略,因为它通常会直接进入迷宫的每个角落,甚至不会等待其无敌过期,也不会针对逃跑的鬼魂,而一个有经验的人类玩家可能会在可怕的情况下保留这些能力,或者至少将它们间隔开,以最大化它们的效果。

用于探索的嘈杂网络

之前,我们谈到了勘探和开采之间的争论,以及有点武断的解决方案,称为 epsilon Q greedy。这种方法的问题是它依赖于预定的超参数。我们怎么知道我们需要多少探索来解决一个像吃豆人女士这样的游戏?找出答案的唯一真正方法是测试一大堆不同的值,这是一个耗时且昂贵的过程。如果智能体能够学会控制其探索,就像它学会控制其决策的其余部分一样——通过梯度下降——那就好得多了。2017 年, Fortunato 等人发布了让这成为可能的解决方案:嘈杂的网络。

因为我们正常计算 Q 值,但是对我们的动作选择进行随机化(添加噪声),所以εQ 贪婪方法属于动作空间噪声探索方法的范畴。在有噪声的网络中,我们将噪声注入到神经网络本身的权重中(参数空间*)。因此,代理将始终如一地推荐它不“打算”采取的行动,确保探索,并且我们可以仅基于最高 Q 值输出来做出行动决策。*

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

The difference between action and parameter space noise, from a very similar technique released by Open AI around the same time.

具体而言,噪声网络用噪声密集层替换模型中的密集分类器,由以下操作定义:

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

其中除了ε项之外,所有参数都是可学习的,ε项是在每个训练和推断步骤之前使用分解的高斯噪声生成的。然后,代理可以学习操纵其他变量,特别是两个变量,但它可以按照环境的要求,不受我们的干扰。为了说明这一点,我们可以绘制一段时间内的平均西格玛权重图。这是 1000 万步训练跑的结果,我们稍后会详细介绍:

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

因为噪声注入是按元素乘以该项,所以代理可以通过将 sigma 设置为 0 来学习忽略噪声。有趣的是,这种方法倾向于自然降至 0 以上,就像我们设计 epsilon 计划一样——确保在培训期间至少有一定程度的探索。

N 步 TD

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

我们要做的最后一个改进是在我们的损失函数中引入一个新项,这有助于代理人更接近理论上的累积折扣奖励。基本上,这:

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

变成了这样:

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

为了效仿这一点:

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

其中 n 是通常设置为 3 或 5 的超参数。这里的想法是通过从转换序列中引导来提高目标精度,这是一种位于时间差异中间的方法- >蒙特卡罗谱。你可以在这本教科书的第七章的中读到更多这方面的内容。

最终结果

同样,这些变化最好的部分是我们可以将它们堆叠到同一个超级充电算法中,大概称为 NoisyNet N 步优先化双决斗深度 Q 网络,这真的很棒。去年年底,当 DeepMind 在此基础上增加了一个东西时,他们开始将其称为“彩虹”,要么是因为他们在整个名称堆叠问题上认输,要么是因为一群博士坐在会议室里看着这张图表上的颜色,在创造力上出现了不幸的失误:

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

from Rainbow: Combining Improvements in Deep Reinforcement Learning

需要说明的是,这个额外的特性是distribution RL*,其中代理学习预测每个动作的奖励分配。我们希望将来回到这个问题上来。*

这是我们最终的 DQN 变体的学习曲线,根据之前的迭代绘制:

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

这最后几个扩展对提高整体性能和样品效率大有帮助——线对线地战胜了前两个版本。最后提醒一下:1000 万步并不足以对 dqn 的整体性能做出任何明确的评价。然而,我们引用/实现的所有论文都显示了在更长的时间范围内推断的类似结果,我们更短的实验表明,即使在更易管理的训练运行中,层次结构也是成立的。

我们让 NoisyNstepPDD 总共运行了 4000 万步。现在让我们看看它是怎么玩的。

我们现在一直在清理第一关,并在幽灵之间进行严密的机动,同时有目的地向左侧破折号导航,并充分利用屏幕两侧的捷径出口。最常见的死亡原因是遇到看不见的鬼魂,这是雅达利严格的精灵渲染限制造成的“小故障”。

DQN“看到”了什么?

玩 Atari 的 dqn 在卷积神经网络* (CNN)的帮助下理解屏幕,这是一系列卷积层,学会从一堆像素值中检测相关的游戏信息。不幸的是,我们没有给它直接从游戏屏幕学习的机会——计算资源需要一些捷径。相反,我们通过将原始尺寸缩小到更易于管理的 84 x 84 并转换为灰度来预处理原始输入。*

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

What we would see (left) vs. what our agent sees (right)

当然,这并不意味着我们丢弃了可能有用的颜色信息。例如,《吃豆人》中的每个彩色幽灵都有自己的人工智能,专业玩家可以利用这些差异来预测它们的去向,但我们的代理人不太可能区分它们。这样做是为了切断 RGB 图像的两个通道,从而大大减轻 CNN 的负担。还要注意,调整大小操作甚至设法删除了重影开始框左右两边的点的位置;幸运的是,这些通常是在吃豆人女士移动到迷宫的任何一边时偶然发现的。这些预处理步骤是 Atari RL 领域的一个非常标准的实践,所以我们决定在这里继续它们,即使它们没有针对这个特定的游戏进行优化。

我们用 4 个最近的帧的堆栈来填充现在空的第三维;这让代理了解每个精灵的速度和方向。

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

The stack of frames that makes up one complete input.

在上面的例子中,代理知道它正逆时针绕过一个拐角,并且知道一个水果最近出现并正在远离它。一堆帧也增加了对精灵闪烁效果的一些保护,因为假设每个幽灵至少每 4 帧渲染一次(这似乎并不总是如此)。

我们所有的实现都使用 DeepMind 从 2015 年开始的 CNN 架构,由三层组成。第一个学会识别 32 个低级特征。从概念上讲,我们可能期望一个特征通道跟踪剩余的点,一个跟踪鬼魂,另一个跟踪玩家,等等。通过访问该层的输出,并将其激活放置在输入堆栈中最近的帧上,我们可以了解他们实际上可能正在学习什么。可能我们发现的最令人惊讶的事情是我们经纪人的幽灵和球员追踪系统;我们的特工没有使用一个频道持续监视幽灵,而使用另一个频道来获得 Pac-man 女士在迷宫中的位置,而是学会了一种按委员会排列的雷达方法,其中一个频道可能一次跟踪一个幽灵,甚至根据画面切换幽灵。

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

Ghost-busting by committee: the agent uses an ensemble of feature channels to determine the position of the game’s sprites. Bright white spots indicate areas of high activation. The maze background is added for context.

在这个例子中,通道 13 和 16 似乎跟踪单个幽灵,而通道 22 跟踪玩家,通道 1 一次看到多个精灵。该系统远非完美,因为似乎没有一个特征地图来拾取中心开始区附近的幽灵。这个幽灵很可能会在未来的一帧中被识别出来,而代理人在任何一集的成功似乎都与这些“盲点”持续的时间有关。

尽管人类很难将这些特征概念化,但还有其他渠道可以获得非常具体的特征:

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

The agent has learned a number of well-defined features that are difficult to conceptualize and vary by frame. In this case, 29 and 0 might both be looking at the player; 28 and 11 are anyone’s guess.

更没用的是总噪音通道,40 米后仍有令人失望的数量。随着训练的继续,这可能会变得清晰,嘈杂的通道变窄,从上面看起来更像 11 和 28,而 11 和 28 本身可能会发展成更有用的表示。

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

High-noise activations

CNN 的伟大之处在于,随着你深入网络,它们的特征变得越来越抽象。我们可以在第三个也是最后一个卷积层的输出上使用 gradient-ascent 来生成类激活图*,指示图像的哪些部分对代理的决策贡献最大。这种技术与跟踪玩视频游戏或看电影的人的眼球运动/注意力有一些相似之处。结果揭示了一个人类玩家可能认识到的决策过程。*

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

The class activation map for the agent’s decision.

在这里,位于(20,30)的代理正来到一个十字路口,需要决定下一步去哪里。热图显示代理人的注意力集中在屏幕的左侧,并且非常紧密地聚集在剩余的点的路径周围。它还注意到(25,40)和中上部的鬼影,以及最右侧的小点群。它最终决定向右和向上,这相当于在这两个方向之间对角推动 Atari 操纵杆。有趣的是,与四个标准方向相比,我们的代理似乎更喜欢这些中间输入,这可能是因为迷宫的墙壁通常会使其中一个方向无效,所以同时尝试两个方向会更有效。也可能是因为这让吃豆人女士能够在没有完美画面输入的情况下绕过急转弯(游戏迫使她向右,直到第一帧没有墙在头顶上,然后通常让她向上),这是一个有用的策略,因为代理人每 4 帧只能做一次决定。

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

在这个例子中,从第一级的末尾,我们得到了一些经验证据,证明了我们第一次添加 PER 时所怀疑的东西——代理能够找出孤立的点。它知道从左边的三个幽灵那里是安全的,并且只关注最后剩下的点。

虽然他们的决策策略在表面上可能是相似的,但重要的是要记住,DQN 不像人类那样处理信息。它学习识别某些像素组是“好”还是“不好”。它避不了鬼,因为它连鬼是什么都不知道;它学会避免矩阵中的数字串,这些数字串与过去给它带来负面回报的数字串相似。一个人可以依靠过去的经验和外界的概念(“鬼是坏的,我应该跑”),DQN 什么都没有。最近的研究已经显示了这可以带来多大的优势,以及它可能是 RL 算法学习进度缓慢的一个重要原因。借用那篇论文中的一个图表,想象一下如果一个游戏看起来像这样,玩起来会有多困难:

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

这是怎么回事?我在控制什么?目标是什么?找到答案的唯一方法是尝试一些事情,看看会发生什么。欢迎来到你电脑看到的世界。

它将何去何从?

尽管 DQN 很伟大,但它仍有改进的空间和拓展的方向。首先,它学得非常慢。已经有很多关于快速启动 RL 算法的工作,使用来自模仿和少量学习的技术。直觉告诉我们,记忆机制也有优化的空间;我们已经根据重要性进行了抽样,但我们可以使用类似的指标来决定哪些体验应该保存,哪些应该覆盖。自 2015 年发布以来,广泛使用且我们在本文中保持不变的卷积架构基本上停滞不前;计算机视觉领域的最新进展会提高我们的特工理解周围环境的能力吗?此外,DQN 还得从头开始学习每一款新游戏;如果它可以从不同但相似的任务中获取知识,比如另一款基于迷宫的雅达利游戏《巫师世界》,并将其中一部分转移到《吃豆人》中,会怎么样?这将把我们从复制人类的表现带到复制人类的学习过程——利用一生的持续学习来应对全新的挑战。

——————

杰克·格雷斯比与扎比·优素福共同撰写

弗吉尼亚大学骑士机器学习

www.cavml.com

【2018 年 6 月

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值