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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

卷积神经网络— I

原文:https://towardsdatascience.com/cnn-part-i-9ec412a14cb1?source=collection_archive---------1-----------------------

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

在我们进入完整的卷积神经网络之前,让我们先了解基本的底层概念,然后在此基础上进行构建。

本帖将解释以下内容:

  • 卷积概念
  • 卷积神经网络
  • 交错回旋

卷积概念

对于那些上过数字信号/图像处理课程的人来说,他们应该对协解的概念比较熟悉。对于我们其他人,让我们快速浏览一下这个概念,这样我们就可以深入到实际的cnn实现中。

如果你有一个城市的图像,有很多如下的建筑,你想从图像中提取所有的边缘,你会怎么做?

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

Fig 1. Edge detection on an image using convolution. Note how all the edges separating different colours and brightness levels have been identified

每当需要修改一个信号以从中提取一组所需的特征时,该过程被称为滤波。现在,为了进行滤波,需要另一组信号,我们以某种方式将其施加/应用于原始信号 S,称为滤波器 (F)。这些滤镜也可以称为遮罩,因为它们帮助我们“遮罩”除了我们想要的图像特征之外的所有图像特征!

现在,所有的遮罩都可以显示出图像所需的效果,如果它们以下面动画演示的方式与图像像素卷积的话。

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

Fig 2. GIF demonstrating result of filter convolution on an image. Source

为了更好地理解卷积,请参考这篇文章

卷积神经网络

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

Fig 3. Architecture of LeNet a Convolutional Neural Network here for digits recognition. Each plane is a feature map ie a set of units whose weights are constrained to be identical. Source

上图来自[Prof Yann Lecun](http://yann.lecun.com/)的原始论文,展示了卷积网络中的所有基本组件和数据流。

以可量化的形式来说,每个 CNN 都有以下组件/层:

  • 输入图像
  • 卷积层
  • 池层(最大池或平均池)
  • 变平
  • 完全连接层(默认神经网络)

我们将在随后的文章中更深入地探讨以上每一层的细节。

交错回旋

当我们处理非常大的图像的卷积时,并不总是需要对图像的每个像素进行卷积。因此,我们可以将后续卷积设置为在垂直轴或水平轴上移动一个以上的像素。

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

Fig 4. Effect of strided convolutions on an image dimensions

在随后的回旋中的这种移动被称为stride,因此命名为跨步回旋。

如果我们有一个尺寸为n x n的图像,带有一个填充p,它与尺寸为f x f的滤波器进行卷积,步长为s,那么输出尺寸可以使用下面的通用公式来确定:

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

Fig 5. Equation governing the resultant image/signal dimension after applying a filter (f x f) with padding § and stride (s)

PS:在数学卷积运算中,我们翻转一个被卷积的信号,就像在镜子里看到的一样。我们上面使用的运算实际上是互相关,但一般在深度学习卷积中是用于它的术语!

结论

在这篇文章中,我们已经理解了帮助我们建立整个卷积神经网络的基本概念。我们讲述了卷积如何使用不同的过滤器或遮罩处理图像数据。此外,我们还谈到了 CNN 的各种构件,以及步长卷积如何影响图像/数据的维度。

在下一篇文章中,我将更详细地介绍卷积,以及它如何应用于具有许多过滤器的体积。

原载于 2017 年 11 月 10 日mandroid 6 . github . io

在推特上关注我:https://twitter.com/mandroid_6

查看我关于机器学习和深度学习的其他帖子:https://medium.com/@razzormandar

Code2Pix —面向图形用户界面的深度学习编译器

原文:https://towardsdatascience.com/code2pix-deep-learning-compiler-for-graphical-user-interfaces-1256c346950b?source=collection_archive---------7-----------------------

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

你好!我叫诺亚·冈多拉,是加州大学伯克利分校的二年级学生。我现在展示的是加州大学伯克利分校统计学本科生协会( SUSA )与 Uizard 合作的原创研究。

在 SUSA,我带领另外 4 名加州大学伯克利分校的本科生在 2018 年春季学期开展了这个项目。接下来的作品是我们小组许多看不见的工作、失败和乐趣的高潮。我们希望你会喜欢阅读我们的研究!

这篇博客分为 6 个部分,还有一个简短的致谢部分。

TL;DR —摘要

我们为从文本描述生成图形用户界面(GUI)的问题提供了深度学习解决方案。这项研究可用于提高 pix 2 代码的准确性,以及从图形用户界面生成代码的未来模型(相反的任务);这个问题在人机交互文献中被称为用户界面逆向工程。此外,中间工作暗示了跨多个平台工作的单一文本到 GUI 编译器的可能性。

1 —简介

当我第一次读到 Pix2Code paper 的时候,我震惊了。托尼·贝尔特拉梅利(Tony Beltramelli)一个人提出了深度学习的新应用,实现了一种方法,并将其开源。该论文提出了一种深度学习模型,能够将图形用户界面的草图转化为实际代码。这对我来说似乎是革命性的。我想这是我看到的事情之一,突然我明白了为什么这么多人对机器学习感兴趣——我真的觉得这是“人工智能”

Pix2Code 是机器学习工程的一个非常了不起的壮举。为了改善它,托尼建议试验一个补充项目。称为 Code2Pix,它的作用与 Pix2Code 相反。Pix2Code 来自 GUI,并把它们转换成特定领域语言(DSL)的文本描述。Code2Pix 接受 DSL 中的文本描述并生成 GUI。因此,Code2Pix 实际上是一个能够呈现接口的深度学习“编译器”。为了避免与真正的编译器混淆,我们将它称为深度学习渲染器

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

Simplified visual description of code2pix’s inputs and outputs. This particular example is from the iOS dataset provided in the original pix2code repo.

本着 Pix2Code 的精神,我们正在发布与这个项目相关的所有代码。我们希望我们能激励其他工程师参与这个项目,并通过对社区的贡献来帮助这个领域向前发展。

2 —为什么选择 Code2Pix?

我们开始通过建立一个生成式对抗性神经网络(GAN)来改进 Tony 的模型 Pix2Code。最近在这一领域的 工作表明,相互竞争的神经网络(GANs)可以为图像提供比标准模型更好的字幕。这就需要一个 发生器 模型和一个 鉴别器 模型来工作。Pix2Code 可用于生成用户界面的代码(DSL ),我们可以使用 Code2Pix 来查看字幕与真实图像的接近程度。Pix2Code 是生成器,Code2Pix 是鉴别器。它们一起可以形成一个 GAN,它能够比 Pix2Code 本身更准确地为 GUI 生成代码。

Code2Pix 的工作与任何普通的渲染器一样。事实上,任何处理用户界面代码的渲染器都是“代码到像素”系统。但是 Code2Pix 不一样,因为它是可微的。这意味着我们可以使用我们的深度学习渲染器 Code2Pix,通过其各层传播错误信号来训练其他深度学习模型。这对于标准渲染器是不可能的。

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

Pix2Code GAN architecture. This is an example of how Code2Pix could be used in conjunction with Pix2Code to improve Pix2Code accuracy in subsequent research.

3 —解决代码 2 修复

这是领导这个项目最有趣也是最令人羞愧的部分。我们最初的方法花了我们 2-3 个月的时间来构建和迭代,但是最后一步没有使用我们之前的任何工作。最终的工作模型被证明是一个非常简单,几乎是幼稚的方法。尽管如此,我认为我们的过程值得分享,出于教育目的,以及展示一个有趣的和相对较新的应用程序,使用深度学习进行跨平台用户界面设计。此外,我们相信这个项目是一个很好的例子,简单优雅的解决方案往往比复杂的解决方案表现得更好。

方法

把代码变成图片的问题可以分解成三块。首先,我们需要使用 DSL 来捕获用户界面,以降低问题的复杂性,并使使用深度学习系统变得可行。其次,我们将为每个数据集创建一个自动编码器。第三,我们将使用 Code2Pix 模型中自动编码器的解码器部分,将编码空间转换为呈现 GUI 的像素。

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

Our approach to building code2pix. Separate the model into two distinct portions. One for handling the textual information, and the other for constructing the GUI. We refer to these respectively as the “token encoder” and the “image decoder.”

幸运的是,Tony 已经创建了一种领域特定语言(在这种情况下,DSL 可以被视为用户界面的伪代码),可以将编译为每个数据集的实际代码(即原生 iOS、原生 Android、web HTML/CSS)。Pix2Code 和 Code2Pix 使用相同的领域特定语言,捕捉每个数据集的基本特性。这解决了我们的第一步。如果你想知道这是怎么做到的,看看这里。

我们的下一步是训练自动编码器,目标是使用自动编码器模型的一部分作为 Code2Pix 中的“图像解码器”。

自动编码器

这些是深度学习中的特殊模型,在数据集上训练,作为解决该数据上的任务的先驱。自动编码器学习将数据压缩为低维编码,然后还学习将编码解压缩为原始数据。它们是了解数据重要特征的好方法。编码器部分通常会被导入到其他深度学习架构中,以传输它学习编码的特征。这就是所谓的迁移学习。我们对解码器部分特别感兴趣,因为它学习解释抽象的有意义的编码,并将它们转换成用户界面的图片。

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

If we train an autoencoder that can compress and decompress GUIs, then we get a free “image decoder” to use in code2pix.

我们尝试了标准的自动编码器架构来解决这一任务,但学到的解码器在解决我们的任务时不是很有用。因此,我们设计了一个新的架构:一个多头模型来同时解决所有三个数据集(Android、iOS 和 Web)的任务。在这个被称为“Hydra”的模型中,解释图像编码的解码器依赖于图像来自的数据集。例如,要通过模型传递 Android 图像,我们将手动选择通过 Android 解码器头来获得最终结果。

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

The specific autoencoder design we used shared the same image encoder between all three image decoders. This ended up being a very efficient model, and produced generalizable image decoders.

我们在 Code2Pix 模型设计中使用解码器头。为了查看编码器和解码器头的具体底层架构,我们将读者引向我们的 Github repo

走向通用的跨平台用户界面

我们的 Hydra autoencoder 学习了嵌入技术,这使我们相信系统可以编译通用用户界面。根据我们的 autoencoder,下面的图片是 3 张图片在不同平台上的样子。例如,最左边的一栏是 Android GUI 在 iOS 和 Web 上的样子。

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

Three different images in three columns being interpreted similarly between each platform. The left column is an Android image, middle is an iOS image, and the right column is a Web image. Each row represents what that image would look like on a different platform.

左右两栏显示出惊人的结构相似度。在左栏中,iOS 头看到的 Android 按钮为橙色框,web 头看到的按钮与绿色按钮相同。在右栏中,我们可以看到 Android 和 iOS head 都捕捉到了 Web GUI 的基本分段结构,使用按钮和滑块的组合来复制 Web 的 div 元素。

每个图像在解释到新平台时仍然保留结构的事实给了人们希望,有一天可能会有一个深度学习编译器,能够在 Android、iOS 和 Web 后端之间无缝翻译用户界面代码。这是一个非常简单、不完善的模型,但是随着时间和经验的增加,它可能会产生更复杂的结果。这些结果表明,由自动编码器学习的编码空间具有足够的结构,在未来的应用中是有用的。

为了验证嵌入空间的结构,我们查询模型以在不同的图像之间进行插值。借鉴著名的“国王男人+女人=王后” 的论文,我们做了自己的“用户界面代数”

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

“A is to B as C is to D.” Here we compute B — A + C = D in order to obtain the result above. The main difference between B and A is the toggle in the second row. By adding B — A to C, we can see D now has a button in the second row.

我们注意到,并不是所有的图像组合都像上面的例子一样清晰。然而,这只是更大目标的第一步:真正的用户界面代数和跨 Android、iOS 和 Web 界面工作的 GUI 编译器。

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

More Eyecandy: Using the Web decoder to translate between two different Web GUIs.

Code2Pix 模型设计

在分析了自动编码器的编码之后,我们准备进入最后一步。我们希望将模型设计过程构建为一个编码器-解码器的动态过程。必须有一部分模型来解释代码标记,并且它必须与一个模型进行通信,该模型再次将编码解码成实际的图片。

我们一开始试图从 Pix2Code 模型中导入预训练的 LSTMs(深度学习层,非常擅长学习顺序数据),但这并没有显示出任何前景。然后我们对卷积层进行了实验,最后使用 1D 卷积层对来自特定领域语言的代码标记进行编码。我们通过将序列的每个 DSL 令牌转换为一个 hot 表示来训练我们的模型,然后将它们连接起来以创建一个矩阵,然后我们可以将这个矩阵提供给 Code2Pix 模型。我们将填充序列归零,这样它们都具有相同的长度。

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

Final architecture for the Code2Pix model.

4-代码 2 修复结果

该模型训练速度非常快,并且为所有三个图像产生令人惊讶的干净输出图像。为单个数据集训练 Code2Pix 大约需要 55 个历元,在两个英伟达 GTX 1080 上大约需要 30 分钟。有趣的是,该模型在 iOS 和 Web 数据集上表现同样出色,但难以为 Android 数据集生成细粒度的细节。

这个最终架构的一个令人惊讶的结果是,预训练的图像解码器根本没有帮助训练 Code2Pix 模型。事实上,在没有预训练重量的情况下训练模型和在有预训练重量的情况下训练一样快。一个自然的结论是,对于这个任务和数据集,这是一个非常稳定的模型架构。下一个假设是,像素到像素问题的编码向量空间实际上不同于文本到像素问题的编码向量空间。因此,在 GUI 到 GUI 问题上使用预先训练的权重并不能为模型提供有价值的信息来更快地学习 DSL 到 GUI 问题。

以下图片是从我们的验证数据集中选择的示例。

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

(Web) Corresponding code: header { btn-inactive btn-active btn-inactive btn-inactive btn-inactive } row { quadruple { small-title text btn-green } quadruple { small-title text btn-red } quadruple { small-title text btn-red } quadruple { small-title text btn-orange } } row { single { small-title text btn-green } } row { double { small-title text btn-red } double { small-title text btn-green } }

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

(Android) Corresponding code: stack { row { radio } row { label slider label } } footer { btn-notifications btn-home btn-notifications btn-home }

我们看到这个的时候真的很开心。为这个模型给出的文本描述相对复杂,图片也相对复杂——但是模型抓住了这一点。鉴于 Code2Pix 模型是如此简单,它能够达到如此高的分辨率这一事实是非常令人惊讶的。

Code2Pix 在生成 Android 图像的清晰分辨率图像时遇到了最大的麻烦。Android 图像可能比其他 GUI 有更复杂的细节,比如滑块上的点。

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

(iOS) Corresponding code: stack { row { label btn-add } row { label btn-add } row { label slider label } row { label slider label } row { label switch } row { label slider label } row { label slider label } } footer { btn-download btn-search btn-search }

iOS 的图像比 Android 的干净得多。此外,iOS Code2Pix 模型能够处理更复杂的文本描述。

5 —限制

我们的深度学习渲染器的表达能力受到数据集和领域特定语言的限制。DSL 必须与合成数据集一起手工制作,以扩展深度学习编译器可以支持的 UI 元素的数量和种类。此外,深度学习编译器生成的图像不如真实图像清晰。我认为这与模型学习在一些看起来模糊的 UI 元素上“对冲赌注”有关,比如滑块。有可能这只是一个假象,可以通过一些微调或更多数据来消除。

但问题是,这些实验只是开始。从事这些项目感觉就像学习如何进行化学实验。现在,我们只是把氢和氧结合起来制造水,但是我们还有很长的路要走。我们甚至还没有开始研究火箭燃料。如果说 Uizard 的演示向我们展示了什么,那就是未来有太多的东西等待着我们。

6-回顾:犯过的错误,吸取的教训

在这个项目中,我们重新认识到了基础知识的重要性。在解决 Code2Pix 的过程中,我们进行了自底向上的开发,构建了最终在最终模型中不一定需要的自动编码器。我们可以从构建 Code2Pix 的基线模型开始。这可以加速我们的模型开发过程。

此外,我个人犯的最大错误是一个技术上的失误。在开发最终的 Code2Pix 模型时,我未能验证数据是否被正确加载。结果是(x,y)对在加载时不匹配。这花费了我们 2-3 周的宝贵模型设计和应用程序优化时间。我学到了什么?对数据管道流程进行单元测试,或使用其他验证流程。例如,我可以只导入 Pix2Code 的数据管道过程。相反,我们的研究代码有 3-4 种不同的数据加载方式,不幸的是只有 2-3 种有效。不要再犯同样的错误。

总的来说,我学到的更重要的经验教训是那些难以表达的软经验教训,它们现在已经融入了我的职业道德。调整我的沟通技巧,减少微观管理,有时不均衡的信任发展,以及控制我在团队会议中的冗长设置。这些都是有趣的课程!

承认

非常感谢我在 SUSA 的团队对我的领导能力的信任,以及为此投入的大量工作。感谢 Samyak Parajuli、Luke Dai、Ajay Raj、Aismit Das、Dennis Yang 和 jap jot Singh——感谢你们,与你们一起工作充满了乐趣。

没有 Tony Beltramelli 的大力指导和指导,我们不可能完成这个项目。感谢托尼对我们的指导!

感谢您的阅读!如果您对我们的研究有更多问题,请随时发送电子邮件至noah.gundotra@berkeley.edu。如果你有兴趣在 Uizard 工作,看看他们的职业页面

整理您的工作流程

原文:https://towardsdatascience.com/codify-your-workflow-377f5f8bf4c3?source=collection_archive---------14-----------------------

设计和数据科学

从长远来看,对我的工作流程进行编码可以节省时间和精力,但这也要求我首先明确我的工作流程是什么。

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

编辑:我最近重构了这篇文章的代码,并将其发布为python 包。

我想我和大多数数据科学家一样,在项目中我倾向于重复做某些事情:我检查某些模式,或者我绘制某些东西,或者我试图理解某些关系。有时是因为我犯了足够多的错误,所以我发现自动防范它是值得的。有时候是因为我发现,就我个人而言,看待问题的某些方式有助于我理解这个问题。在任何情况下,我的任何给定项目的大部分工作流经常看起来非常类似于我以前项目的大部分工作流。毫不奇怪,我发现减少这些重复活动的开销很有用。

虽然自从我学会如何编码以来,我已经理解了通过自动化减少开销的价值,但是我从来没有得到多少关于如何做的建议。这只是我得到的一些东西。在这篇文章中,我试图总结我学到的一些东西,并且我将使用我工作流程中最近自动化部分的一些代码作为例子。

逻辑美

好的设计建议至少在维特鲁威写了十本关于建筑的书(仍然值得一读)之后就已经存在了,他在书中说好的设计实现了稳固、有用和愉悦。将前两个理念转化为工作流自动化设计是相对容易的:无论我们构建什么,它都应该以我们需要的规模、速度和质量一致地完成我们希望它做的工作。但是我认为最后一个理想——快乐——通常会决定一个可行的设计和一个好的设计。 Fred Brooks 认为在技术设计的背景下,愉悦应该被认为是“逻辑美”,并且认为 一个逻辑美的产品是一个最小化脑力劳动的产品。

我认为最小化脑力劳动是数据科学工作流的一个有趣的目标,因为数据行业最近的许多尴尬似乎都是由从业者没有花费足够的脑力思考他们的设计决策的潜在后果而引起的。 所以我们需要仔细选择哪些区域的脑力劳动要最小化 。这意味着一个好的设计的第一步是,不管听起来有多老套,决定我们想要完成什么。

想想开车吧。我尽可能高效地开车去我要去的地方。一辆设计良好的汽车应该能够让我尽可能地将注意力集中在与实现我的目标最直接相关的事情上。这意味着尽量减少其他事情上的精神负担。换句话说,当我开车时,我应该能够集中精力在正确的地方转弯,避开行人或灯柱之类的东西。我不应该专注于确保发动机运转,或者换挡,或者刹车如何工作。如果我把车用于其他目的,我可能会专注于这些事情,但它们对于完成我选择的特定目的来说并不合适。一个好的设计不应该分散我的注意力,也不应该阻止我去关注那些可能妨碍我实现目标的事情。

得体是谈论相关性的一种有点过时的方式。布鲁克斯将设计中的得体定义为“不要引入无关紧要的东西。”我发现根据我在类比中使用的权衡来考虑适当性是很有用的。如果做某件事能确保我不被阻止实现我的目标,那么它对那个目标来说是恰当的。如果做某件事只是为了达到目的,那对这个目的来说是不合适的。如果不能避开行人或灯柱,我将无法到达我想去的地方。如果我乘汽车、步行、滑板、自行车、飞机或火车旅行,那是真的。没有内燃机不一定会阻止我去我想去的地方;因此,这种设计是不合适的,不管它在实现上有多方便。所以在我们定义了我们的目标之后,定义什么是适合这个目标的:作为一个经验法则,如果它能让我们前进,它可能是也可能不是合适的;如果能阻止我们前进,那就是正当的。 好的设计能最大限度地减少不符合我们预期目的的任务所耗费的脑力

正交性是逻辑美的另一个组成部分。布鲁克斯对此总结为“不要把独立的东西联系起来”。换句话说:我避开行人和灯柱的能力部分取决于能否看到这些东西,部分取决于能否操纵汽车避开它们。挡风玻璃的功能和方向盘的功能应该相互独立。一个不能保持独立性的设计将是一个糟糕的设计。因此,在我们定义了工作流的适当组件之后,我们将依赖性最小化。 好的设计会将合适的组件与不合适的组件分开,这样我们就不会不小心将花费在真正需要我们全神贯注的事情上的精力减到最少。同样,好的设计让不合适的组件相互隔离,这样我们就不会意外地以我们没有预料到的方式减少脑力劳动。

通用性是我在继续讲这个例子之前要讲的最后一个原则。布鲁克斯将其总结为“不要限制固有的东西。”换句话说,轮胎(或引擎或电线等。如果没有一个很好的理由,就不应该设计成只适合那辆车。 好的设计在限制一个功能可以应用的用例之前需要一个理由。 这使得我们更容易适应意料之外的需求,而无需重新构建整个产品。

所以,总结一下:

  1. 决定我们想要达到什么目的。
  2. 确定哪些任务适合完成该目的。
  3. 通过将适当的任务与不适当的任务分开,以及将不适当的任务彼此分开,来最小化依赖性。
  4. 在保持适当性或正交性的同时,尽可能将每个任务规划为通用的。

遵循上述原则的设计往往在逻辑上是美丽的,因为它们在所有正确的地方最小化了我们的精神努力。

工作流设计的一个极简例子

我经常处理地理位置数据,并且经常需要绘制这些数据。有时我需要绘制形状,有时我需要点。有时我需要在卫星图像的背景下看到这些物体,以获得一些粗略的背景,有时我需要道路或标签的更详细的背景。我通常不得不一周几次使用这种工作流程。有时候我一天要经历上百次。无论如何,我必须经常这样做,这是减少脑力劳动的好方法。所以我只有一个目的:在一张图片上用图形表示经度和纬度对,这张图片表示这些坐标的真实环境。这个目的定义了适当性:任何实际上没有在图片上放置形状的东西对我的目的来说都是不适当的,因此花费在那件事情上的精神努力应该被最小化。就目前的例子而言,界定目的和正当性相对容易。情况并非总是如此。

现在我需要担心正交性。想象一下,和一个完全没有技术专长的人说话。我通常会想象,要么是我最早的一位经理将所有涉及代码的事情都描述为“新奇”,要么是我母亲仍然拒绝得到电子邮件地址,要么是一名主修人文学科的大学新生。你明白了。我的任务创造了一系列问题,我想象中的新手会认为这些问题对于创造我想要的结果是必要的和充分的。如果我想象中的新手可以说“但是你为什么需要 X 的答案?”,这意味着我包含了一个不必要的问题。如果我想象中的新手可以说“但是我不明白 X,Y,Z 的答案将如何导致结果”,那意味着我要么错过了一个问题,要么没有问对问题。我喜欢用一个虚构的新手作为共鸣板的原因是,当我试图设计所有东西时,我往往会变得太专业太快。因为我知道如何实现事情,所以我的大脑比它应该做的更快地跳到实现问题上。如果你有一个真正有血有肉的新手愿意并且能够成为你的传声筒,那就用那个人,而不是一个想象出来的人。

如果我的目标是在图片上得到形状,那么我只有三个问题:

  • 我在哪里得到形状?
  • 我在哪里得到照片?
  • 我如何得到图片上的形状?

很基本的问题,对吧?但是这些基本问题迫使我从基本构件的角度来思考,这使得保持正交性变得更加容易。如果我最终构建的任何东西的运行方式是,在不改变我如何将这些形状放在图片上的情况下,我无法改变我如何获得这些形状,那么我可能构建的东西是错误的。功能的不同部分应该尽可能的独立。

现在我有了正交分量,我想让它们尽可能通用。为此,我需要用例。在我需要做的三件事情中,我已经偏向于偏好的方式,但是从长远来看,如果我能想出尽可能多的方式——偏好的或不偏好的——我会更好。我可能不会实现对我列出的所有用例的支持:这将取决于项目的约束(主要是我有多少时间、多少资源和多少竞争优先级)。最好还是预先知道尽可能多的用例——通常,在实现对关键用例的支持的过程中,支持额外的、还不需要的用例只是理所当然的事情。这可以减少沮丧和路上浪费的时间。以下是当前示例的一些用例:

我从哪里得到这些形状?

从哪里获取图片?

我如何得到图片上的形状?

当然,这个列表并不详尽。如果我有更多的时间来考虑,我可以建立一个更完整的清单,可能会更好。但是由于我的时间有限,还有其他事情要做,我很满足于每个问题至少有两个答案。我真正想做的是避免只关注眼前需求的短视行为。

从设计到实施

您可以跳到这一节的底部来查看我实现的完整代码,但是先通读一下这个讨论来理解我做了什么可能会有所帮助。

我选择完全依靠散景库来绘制图片上的形状,因为我已经知道并喜欢这个库——它很容易快速启动并运行。同样,我选择完全依靠谷歌地图来获取图片,因为它为卫星图像、地图和这两种东西的注释版本提供了单一来源,还因为 Bokeh 已经提供了一种调用谷歌地图 API 的便捷方式。

我很少在工作流程的这些部分上花费精力,因为精心制作可视化的外观和感觉——选择背景图像,决定绘制什么形状,以及设计和注释这些形状——都符合我的目的,所以我想尽可能地保持对这些事情的细粒度控制。

我实现的 Python 类有一个“prepare_plot”方法,它在很大程度上只接受传递给该方法实例化的 Bokeh“gmapplot”对象的可选关键字参数:

该类还有一个“add_layer”方法,用于在图片上放置形状:

这个方法调用只有两个必需的参数。一个是标签,告诉该方法该形状应该引用什么数据源(同样,稍后会详细介绍)。另一个是散景模型——我最常用的两个模型是“面片”,用于绘制多边形,和“圆”,用于绘制坐标对。有一个可选的“工具提示”参数,它采用一个字符串或一个元组列表来创建当鼠标悬停在一个形状上时应该出现的工具提示。所有其他关键字参数都被传递给散景模型,这让我可以更好地控制形状的外观。大多数散景模型允许形状的边框和区域采用不同的样式。例如,如果我想要一个带有黑色边框的红点,我会将“填充颜色”设置为红色,将“线条颜色”设置为黑色。同样,如果我想填充 50%透明,但边框是 0%透明,我会设置’填充阿尔法’为 0.5 和’线阿尔法’为 1.0。通常,我希望填充和线条的样式相同,所以“add_layer”方法接受额外的关键字。如果我将‘alpha’设置为 0.5,那么‘fill _ alpha’和‘line _ alpha’都将被设置为 0.5。这是脑力劳动的一个小小的减少,但这种减少足以方便。

然而,我所做的大部分脑力劳动都与准备绘图数据有关。我提到的获取形状的所有四个用例——经度/纬度对、知名文本、shapely 对象和 geo hashes——是我在日常工作中经常遇到的用例。我发现我研究数据的很多时间并没有花在真正理解情节上,而是花在将数据转换成我需要的格式上。当我不得不在分析过程中中途切换数据源类型时,我尤其会产生大量开销(例如,我可能设置了一个工作流来绘制地理坐标对,然后突然发现我需要绘制地理散列;这要求我重组我的部分工作流程)。

“添加源”方法需要数据和标签:

数据可以是包含我提到的四种输入值之一的列表,也可以是一个数据帧,其中一列包含这些输入值(并且必须明确指定该列)。该方法执行四个基本功能:

  • 它调用_process_input_value,自动验证输入类型(geohash vs. coordinate pair 等。)并将其格式化为一个 x 坐标列表和一个 y 坐标列表。在众所周知的文本或表示多重多边形或一些其他多重几何图形集合的有形状的对象的情况下,它将格式化列表的列表。` _process_input_value '方法作为一个切换面板,完全消除了适当格式化输入值的开销,假设值是受支持的类型之一。
  • 它向输入值追加元数据。在数据帧输入的情况下,不包含输入值的数据帧的每一列都将被用作元数据。在列表输入的情况下,任何关键字参数都将被用作元数据(假设参数是与输入值列表长度相同的列表。
  • 它扩展了源数据帧以适应多种形状。如果输入值类似于一个多面,它会将其分割成单独的面,并将多面的元数据追加到每个单独的面。这类似于 SQL 中分解数组的概念。
  • 完成上述所有处理后,它调用_set_coordinate_bounds,更新绘图边界(最小和最大 x 和 y 值)。确定谷歌地图缩放级别时会参考这些界限。

这个类还做了很多其他的事情,但是在大多数情况下,这个类本身的结构只不过是我的工作流程的三个关键部分的实例化:获取形状,获取图片,将形状放到图片上。因为我使用一些合理的设计原则(目的→适当性→正交性→一般性)来编写工作流,所以扩展该类以适应新的需求相对容易。例如,我想扩展这个类来使用 WMTS 地图而不是谷歌地图。由于该类的设计方式,我可以或多或少地只对“prepare_plot”方法进行修改,而不做其他任何事情。如果我想使用传单或 Matplotlib 或其他东西来渲染情节,这将需要一些更广泛的更新,但效果仍然不会波及整个代码库。

然而,最大的好处不在于我如何编写代码,而在于我是否编写了任何代码。是的,从长远来看,对我的工作流程进行编码可以节省时间和精力,但是 它也要求我首先明确我的工作流程是什么 。在编写这段代码的过程中,我发现了工作流中让我不开心的几件事。例如,当我想要绘制多边形而不是点(或点而不是多边形)时,我讨厌花费大量时间来管理数据,所以我将“add_source”方法更改为始终假定多边形,并将“add_layer”方法更改为每当使用假定点数据但引用包含多边形数据的数据源的散景模型时自动计算质心并更新数据源。我在没有意识到的情况下,将关于数据的多边形与点结构的假设融入到了工作流中。通过整理我的工作流程,我认识到了这个假设,决定不喜欢它,并删除了它。

整理我的工作流程会让我的工作流程更好,而让我的工作流程更好会让我成为更好的程序员。在明确考虑代码和工作流的设计时,我让旧的工作更容易用于新的问题,并与同事分享我的工作。

代码

我想不言而喻,这段代码并不是我之前概述的设计原则的完美体现。设计是一个方向,而不是终点。我痛苦地意识到代码有多少需要改进的地方!

初学者的深度学习编码——线性回归(第三部分):梯度下降训练

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-linear-regression-gradient-descent-fcd5e0fc077d?source=collection_archive---------6-----------------------

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

Source: https://reconsider.news/2018/05/09/ai-researchers-allege-machine-learning-alchemy/

这是系列“初学者深度学习编码”的第 5 篇文章。你可以在这里找到所有文章、链接,以及第一篇文章* 底部关于下一篇文章 *预计发布日期的一般信息。*它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

目标

在本文中,我将解释用梯度下降训练机器学习算法的概念。大多数监督算法都在利用它——尤其是所有的神经网络。这是一个至关重要的话题,也是开始机器学习的人需要克服的最大障碍之一。这是因为它是基于微积分的**,有些人在学校没有学过,或者他们的知识生锈了。**

但是不要担心,即使你对数学不熟悉或者根本不懂微积分,你仍然可以理解它,学习它,并使用它。我会告诉你怎么做!

靠蛮力训练

由于上一篇文章中介绍的成本函数,已经可以训练模型来预测克拉科夫公寓的价格。模型只使用了公寓的尺寸,所以它的形式并不太复杂:

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

其中:

  • ŷ —预测房价,
  • x—户型,
  • w —分配给公寓大小的重量,
  • b —偏置。

下标“0”代表特征在数据集 X 的每个矢量中的位置,为了提高可读性,省略了该下标。

训练过程的目标是找到 wb 参数的组合,为此成本函数返回尽可能小的误差

为了提高模型性能,会做一些非常幼稚的事情。在许多迭代中,参数将通过一个小的固定步长改变,并且不知道参数值是否应该改变以及在哪个方向上改变。因此,将计算所有可能组合的成本值,以找到最佳修改,这就是为什么它被称为“暴力训练”在每次训练迭代中,可以对参数执行三个动作:增加、减少、不变。两个参数,这意味着每次迭代将有 3 = 9 组参数来检查,并对其进行预测,计算成本。模型将使用成本最低的设置进行更新。

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

Training with Brute Force — diagram showing how to train model with two parameters (w and b) without using Gradient Descent algorithm.

让我们实现它,看看结果。大多数操作已经在上一篇文章中编码了,因此只剩下训练循环需要实现。

Full code available under this link.

只有两个参数,代码已经足够复杂,可以省略一些部分来提高可读性。隐藏部分的实现与图中所示非常相似——唯一的区别是数学运算符从+=变为-=,或者有时根本不使用。

代码片段以从copy模块导入deepcopy函数开始。需要复制存储在model_parameters字典中的模型参数及其内容。在任何训练发生之前,函数predictmse使用model_parameters通过计算其初始误差来测量模型的潜力。

然后model_parameters被复制九次。每个副本都以不同的方式(加法、减法、无变化)被step值修改,然后用于预测。根据candidate_pred的正确性,副本具有作为candidate_error变量分配给它的成本值。误差和参数存储在candidateserrors列表中。在计算了每个候选项并测量了它们的性能后,使用成本最低的一组参数来代替model_parameters。它发生iterations次,默认设置为 100。请注意,函数train没有返回任何结果,并且model_parameters被就地修改。

在所有这些之后,可以对加载的数据和初始化的模型参数使用train函数,以便找到将误差最小化的值:

可以将简单的print函数添加到train函数体中,并显示训练过程如何改变模型参数(如果您以前没有这样做,请查看此链接以获得完整代码):

Initial state:
 - error: [75870.4884482]
 - parameters: {'w': array([0.]), 'b': 0.0}

Iteration 0:
 - error: [73814.2609893]
 - parameters: {'w': array([0.1]), 'b': 0.1}

Iteration 20:
 - error: [38764.28631114]
 - parameters: {'w': array([2.1]), 'b': 2.1}

Iteration 40:
 - error: [15284.92972772]
 - parameters: {'w': array([4.1]), 'b': 4.1}

Iteration 60:
 - error: [3376.19123904]
 - parameters: {'w': array([6.1]), 'b': 6.1}

Iteration 80:
 - error: [1753.32046443]
 - parameters: {'w': array([7.1]), 'b': 8.1}

Final state:
 - error: [1741.85716443]
 - parameters: {'w': array([7.1]), 'b': 10.0}

**误差随着每次迭代而减小。这是因为所有的训练样本都在每次迭代中使用——但是在以后的文章中会有更多的介绍。另一个重要的观察结果是训练结束后误差值不等于零。**仅仅用线性函数是不可能遍历所有的点的。

最后,可以显示训练的结果,并查看模型如何能够估算公寓价格:

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

Model projection after training. Code used to create the chart is available here.

结论

训练这样一个简单的模型并找到可以在给定数据上表现良好的参数,不需要任何复杂的技术。但是目前的方法有很多局限性:

  • 一大堆样板代码
  • 在每次迭代中需要测试太多的组合。这个模型只使用了两个参数。想象一下在像神经网络这样的模型中会发生什么,其中参数的数量有时以百万计——3⁰⁰⁰⁰⁰⁰不是一个好数字…
  • 改变参数的步骤对于每个参数是固定的**。**其值的范围也是未知的,有时 0.1 可能太大,有时可能太小。
  • **每个参数应该改变的方向是未知的,**这就是为什么必须尝试所有可能的改变。它需要大量的计算能力,并且非常慢。

衍生工具的作用

矛盾的是,当涉及到重用已经发明的涉及梯度下降的机器学习概念时,理解哪些导数可以用于比能够计算它更重要。 Andrew Trask 在他的书“探索深度学习”中提供了非常好的关于什么是衍生品以及它如何运作的直觉。本文的解释将使用类似的推理。

直觉

想象有两根杆子伸出墙外。让我们将它们命名为杆 A 和杆 b。杆 A 比杆 b 短两倍。为了了解杆之间的关系,进行了两个实验:

  • 首先,杆 A 被推入墙中。可以观察到的是,木棒 B 的长度随着木棒 A 一起缩短,但是缩短了两倍。
  • 其次,杆 A 被拉出墙壁,其长度增加。结果,杆 B 也伸长了,但速度快了两倍。

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

现在让我们试着**用数学方程的形式描述两杆之间的关系。**在两种情况下,都可以观察到杆 B 的长度总是杆 A 的两倍:

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

其中:

  • l_A —杆 A 的长度,
  • l_B —杆 B 的长度

稍等片刻,想想**数字 2 在这个等式中的作用。**是 l_B 相对于 l_A 的导数,可以写成:

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

从中可以学到什么?

  • **导数描述了一个变量被修改时,另一个变量是如何变化的。**那么在这种情况下,当杆 A 的长度被修改时,杆 B 的长度以什么因子延伸或收缩。
  • 计算两个变量之间的导数。
  • 当导数为正值时,两个值的变化方向相同。如果杆 A 延伸,那么杆 B 也延伸,因为 2 是正数。反之亦然,如果导数为负值,则值向相反方向变化。

请记住:

对于可微函数,有可能找到两个变量之间的关系——当一个变量通过使用导数被修改时,一个变量改变了多少以及在什么方向上改变。

考虑到之前关于“暴力学习”的问题,导数有一些有趣的性质可以用来解决这些问题。

梯度下降

凸函数 最小值的一种迭代优化算法。它基于微积分— 依赖于一阶导数的性质来寻找在什么方向和用什么幅度系数来修改函数。****

在之前的文章中提到,用于测量机器学习模型性能的成本函数需要是可微分的。如果不是这种情况,那么梯度下降算法不能应用。

让我们以均方误差函数为例,它被广泛用作回归模型的成本函数。

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

  • i —样品指数,
  • ŷ —预测值,
  • y —期望值,
  • m —数据集中的样本数量。

预测值 ŷ 可以用公寓价格近似模型的公式代替。让我们也稍微调整一下使用的命名法,如用大写字母 J 来命名机器学习模型的错误非常流行。

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

现在很容易看出误差值取决于 wb 系数。参数 mxy 可以被视为常量,其值是已知的,并由训练模型的数据集确定。

已经说过,计算任何两个函数参数之间的导数是可能的,并且它将提供当一个参数改变时另一个参数改变的信息。 J 的派生结果:

  • 关于参数 w 提供了如何调整参数 w 的值以最小化或最大化 *J、*的值的信息

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

  • 关于参数 b 提供了如何调整参数 b 的值以最小化或最大化 J. 的值的信息

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

如果模型有更多的参数,那么需要计算更多的导数。这就是微积分派上用场的时刻。在大多数情况下,使用梯度下降算法不需要数学。机器学习、详细计算或代码实现中使用的各种函数的衍生物 在 web 中全局呈现。

首先,在网上查找答案是很好的。使用微积分的能力肯定会导致更好地理解各种机器学习机制是如何工作的。它还将提供检查其他人的代码的能力。

如果你想知道这两个导数是如何计算出来的,那么试试这篇博文或者看看伊恩·古德菲勒的书《深度学习》的第 106 页(T2)。

几何解释

可以考虑在给定点处曲线切线的斜率的导数。“梯度”一词的同义词是“坡度”

模型参数值通常在开始时是随机的。它们的值误差曲线**(对于一个参数的模型)误差曲面(对于两个参数的模型)或误差超平面(对于两个以上的参数)上强加点的位置。梯度下降算法的目标是找到参数值,因此该点总是出现在最低区域**,因为那里的误差值最低。

以下是展示单参数模型如何根据随机生成的数据进行迭代改进的可视化效果。有两种情况:

  • 随机化的权重值太小,需要增加,

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

  • 随机权重值太大,需要减小。

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

有一些重要的观察结果:

  • 请注意,权重值太小,则导数为负,而权重值太大,则导数为正。因此,为了最小化误差函数,需要从权重中减去导数,以使该点更接近全局最小值。如果加上导数,误差反而会增加。
  • 随着权重更新使误差值更接近全局最小值,导数值正在减少。从几何角度来看,这也是正确的,因为切线的**“斜率”也随着每次迭代变得不那么陡**。
  • 点与点之间的距离称为梯度步长。请注意,导数值远大于 x 轴上的重量值。如果第一个陈述为真,从重量中减去导数值不会以如此小的数字改变重量值。这是因为当使用梯度下降更新参数时,只需要使用导数的很小一部分来保持数值稳定性,并且不会跳过全局最小值。应该使用导数的哪一部分或者梯度步长应该有多大由学习速率超参数决定。

当学习率太大时,数值开始从曲线反弹,误差无限增加:

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

如果模型依赖于两个参数而不是一个参数,那么为了显示误差值,需要额外的轴(用于附加参数)。这自动将可视化从 2D 平面带到 3D 表面。下面是在网上找到的一个很好的例子,说明这种错误表面可能是什么样子:

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

Source: https://towardsdatascience.com/improving-vanilla-gradient-descent-f9d91031ab1d

对于两个以上的参数,可视化是非常困难和棘手的。通常,依靠诸如 PCA 等降维方法是很重要的。幸运的是,数学与此非常相似,可以扩展到任意数量的参数。

更新规则

为了更新模型参数,从而实现收敛,必须迭代应用以下数学公式:

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

其中:

  • w’—新重量值,
  • b’—新偏差值,
  • w —当前重量值,
  • b —电流偏置值,
  • α —学习率,
  • dJ(w_0,b)/dw_0—J 关于 w _ 0 的导数,
  • dJ(w0,b)/db—J 相对于 b 的导数。

应该更新参数,直到成本函数值不再降低,并且如果当前模型状态已经令人满意,则可以停止整个过程。

实施

让我们编写使用梯度下降算法的新train函数:

由于仅使用特定点的导数值0.0005,参数变化很小。它接管20000迭代以获得好的结果。如果输入数据事先经过标准化,则整个过程可以加速。

在每次迭代期间,计算每个数据样本的部分梯度,并对整个数据集求和。此后,累积的梯度被平均并用于在梯度步骤结束时更新参数(参数被更新的迭代)。

现在新的train功能可以像以前一样使用**😗*

这产生以下结果:

Initial state:
 - error: [75870.4884482]
 - parameters: {'w': array([0.]), 'b': 0.0}

Iteration 0:
 - error: [13536.3070032]
 - parameters: {'w': array([10.17501967]), 'b': array([0.17843399])}

Iteration 4000:
 - error: [1737.28457739]
 - parameters: {'w': array([7.09101188]), 'b': array([10.96966037])}

Iteration 8000:
 - error: [1707.33242182]
 - parameters: {'w': array([6.9583785]), 'b': array([18.67110985])}

Iteration 12000:
 - error: [1692.21685452]
 - parameters: {'w': array([6.86415678]), 'b': array([24.14215949])}

Iteration 16000:
 - error: [1684.5886765]
 - parameters: {'w': array([6.79722241]), 'b': array([28.02875048])}

Final state:
 - error: [1680.73973307]
 - parameters: {'w': array([6.74968272]), 'b': array([30.78917543])}

比较这两种训练方法没有意义。蛮力训练的主要问题是效率低下。在梯度下降算法的情况下,模型迭代地达到收敛 ,不需要检查所有可能的修改。在处理复杂的问题——高维数据时,这将带来巨大的不同。

最后让我们看看模型投影:

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

Model projection after training. Code used to create the chart is available here.

摘要

我们非常接近创建我们的第一个机器学习模型——线性回归,用 Python 从头开始编写,能够预测克拉科夫公寓的价格。利用已经提供的知识,你可以自己创造最终的解决方案!

在本文中,我已经向您展示了训练循环如何工作以及如何使用成本函数来找到模型的最佳参数。然后指出了现有方法的诸多缺点。在下一部分,我们解释了什么是导数,以及它在中的用途。我已经从理论、数值和几何角度告诉过你什么是**梯度下降算法,**使用均方误差函数示例作为解释的帮助。最后,我已经把解释过的概念变成了代码,并用它来训练我们的模型的单一特征——公寓大小。

我们现在缺的是… 泛化。所有的概念和代码片段都是针对一维数据的简单问题而提出的。这种简化当然是有意的。在下一篇文章中,,我将向你展示如何重构所有这些概念,使它们适用于任何数量的特性,并且永远不需要再次编辑!通过矩阵乘法可以实现,整个过程称为向量化

下一篇文章

期待下一篇2018 年 8 月 30 日左右

初学者的编码深度学习—线性回归(第一部分):初始化和预测

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-linear-regression-part-1-initialization-and-prediction-7a84070b01c8?source=collection_archive---------2-----------------------

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

这是“初学者深度学习编码”系列的第 3 篇文章。在这里,你可以在第一篇文章 的底部找到所有文章议程的链接,以及关于下一篇文章* *预计发布日期的一般信息。*它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

你也可以在我的个人网站上阅读这篇文章,为了提高可读性(支持代码语法高亮、LaTeX 方程式等等),我的个人网站由 Jekyll 主办。

为什么是线性回归?

你们中的一些人可能想知道,为什么关于解释和编码神经网络的系列文章是从基本机器学习算法开始的,比如线性回归。从那里入手是很有道理的。首先,它是一个非常简单的算法,因此读者可以掌握对基本机器学习概念的理解,例如监督学习成本函数梯度下降。此外,在学习线性回归之后,理解逻辑回归算法是非常容易的,不管你信不信,可以将它归类为小型神经网络。在接下来的几篇文章中,您将会看到所有这些,甚至更多!

工具

让我们介绍一下最流行的库,它们可以在每一个基于 Python 的机器学习或数据科学相关项目中找到。

  • NumPy —一个科学计算库,非常适合多变量微积分&线性代数。提供 ndarray 类,可与 Python 列表进行比较,可被视为矢量或矩阵
  • Matplotlib数据可视化工具包,允许创建各种 2d 和 3d 图形。
  • 熊猫—这个库是 Matplotlib 和 NumPy 库的包装器。它提供了数据帧类。它将 NumPy 矩阵视为表,允许通过附加的名称访问行和列。在数据加载、保存、争论和探索过程中非常有帮助。提供一个功能接口,使部署更快。

使用 Python PyPi 可以单独安装每个库。它们将以下列别名导入到每篇文章的代码中。

什么是线性回归?

这是一个监督学习算法,其目标是基于给定的数据输入预测连续的数值。从几何角度来看,每个数据样本都是一个点。线性回归试图找到线性函数的参数,因此所有点与直线之间的距离尽可能小。用于参数更新的算法称为梯度下降

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

Training of Linear Regression model. The left graph displays the change of linear function parameters over time. The plot on the right renders the linear function using current parameters (source: Siraj Raval GitHub).

例如,如果我们有一个由某个特定区域的公寓属性及其价格组成的数据集,可以使用线性回归算法来查找一个数学函数,该函数将尝试根据其属性来估计不同公寓(在数据集之外)的价值。

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

另一个例子是根据销售数据预测杂货店的食品供应量。这样,企业可以减少不必要的食物浪费。这种映射对于任何相关的输入输出数据对都是可以实现的。

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

数据准备

在编码线性回归部分之前,最好有一些问题要解决。在像 UCI 知识库Kaggle 这样的网站上可以找到很多数据集。在经历了许多之后,没有一个适合本文的研究案例。

为了获得数据,我进入了波兰网站 dominium.pl ,这是一个在我居住的克拉科夫市寻找公寓的搜索引擎。我完全随机选择了 76 套公寓,写下它们的属性并保存到**。csv 文件**。目标是训练能够预测克拉科夫公寓价格的线性回归模型

数据集在我的 Dropbox 上的这个链接下。

加载数据

让我们从读取数据开始。csv 文件转换为熊猫的 DataFrame 对象并显示一些数据行。为了达到这个目的,将使用 read_csv 函数。数据用冒号分隔,这就是添加sep=","参数的原因。函数 head 以易读的 HTML 表格的形式呈现前五行数据。

代码的输出如下所示:

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

DataFrame visualisation in Jupyter Notebook.

如表中所示,有四个特征描述公寓属性:

  • distance _ to _ city _ center-步行从住所到克拉科夫主广场的距离,用谷歌地图测得,
  • 房间 -公寓房间数,
  • 面积 -户型面积以平方米计量,
  • 价格 -目标值(需要模型预测的),以波兰国家货币计量的公寓成本——兹罗提

可视化数据

始终理解数据的结构非常重要。功能越多越难。在这种情况下,散点图用于显示目标和训练特征之间的关系。

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

Charts show whole data from cracow_apartments.csv. It was prepared with Matplotlib library in Jupyter Notebook. The code used to create these charts can be found under this link.

根据需要显示的内容,一些其他类型的可视化(例如盒状图)和技术可能是有用的(例如聚类)。这里,可以观察到特征之间的线性相关性——随着 x 轴上值的增加,y 轴上的值也相应地线性增加或减少。这很好,因为如果不是这样(例如,关系将是指数的),那么将很难拟合一条穿过所有点的线,并且应该考虑不同的算法。

公式

线性回归模型是一个数学公式,它以的数值向量(单个数据样本的属性)作为输入,并使用它们进行预测

将相同的陈述映射到所呈现的问题的上下文中,有 76 个样本包含 Cracow 公寓的属性,其中每个样本从数学角度来看都是向量。每个特征向量与目标值配对(公式的预期结果)。

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

根据该算法,每个特征都分配有一个权重参数。表示其对模型的重要性。目标是找到权重值,因此每个公寓数据都满足以下等式。

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

等式的左侧是一个线性函数**。如操纵权重值可以改变线条的角度。虽然,还是缺少了一个元素。当前函数总是通过坐标系的(0,0)点。为了解决这个问题,增加了另一个可训练参数。**

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

该参数被命名为偏差,它赋予公式在 y 轴上上下移动的自由度**。**

紫色参数属于模型,用于预测每个传入的样本。这就是为什么找到一种对所有样品都最有效的解决方案是必要的。形式上,该公式可以写成:

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

初始化

这是一个创建第一个模型版本的阶段**。初始化后的模型已经可以用于预测,但如果没有训练过程,结果将远远不是好的。有两件事要做:**

  • ****在代表权重和偏差参数的代码中创建变量,
  • 决定模型参数的初始值

模型参数的初始值对于神经网络来说是非常重要的。在线性回归的情况下,参数值可以在开始时设置为零**。**

函数init(n)返回包含模型参数的字典。根据数学公式下方图例中的术语, n 是用于描述数据样本的特征数。NumPy 库的 zeros 函数使用它来返回一个 ndarray 类型的向量,该向量有 n 个元素,每个元素都赋有零值。Bias 是一个设置为 0.0 和的标量,将变量保持为浮点数而不是整数是一个好习惯。相应地,权重和偏差都可以在“w”和“b”字典键下访问。

对于 Cracow 公寓数据集,有三个特征描述每个样本。下面是调用init(3)的结果:

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

预言;预测;预告

模型可以使用创建的模型参数进行预测。公式已经显示出来了。现在是时候把它变成 Python 代码了。首先,每个特征都必须乘以其相应的权重并求和。那么偏差参数需要加到前面操作的乘积上。结果是一个预测。

函数predict(x, parameters)有两个参数:

  • 代表数据样本的特征向量x(例如单身公寓),
  • Python 字典parameters存储了模型的参数及其当前状态。

组装

让我们将创建的所有代码部分放在一起,并显示在结果中。

****只有一个特征用于预测什么简化公式形成:

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

这是有意为之,因为显示超过 1-2-3 维的数据的结果变得很麻烦**,除非使用降维技术(例如 PCA )。从现在起,出于学习目的,所有代码开发将只在尺寸特征上进行。当线性回归代码完成时,将显示使用所有功能的结果。**

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

Line used to fit the data by Linear Regression model with current parameters. Code for visualisation is available under this link.

模型参数用零值初始化,这意味着公式的输出将总是等于零。因此,prediction是一个包含 76 个零值的 Python 列表,它们分别是每套公寓的预测价格。但是现在没关系。使用并解释梯度下降训练后,模型行为将会改善。

代码片段的额外收获是:

  • 模型使用的特征和目标值存储在featurestarget Python 列表中。由于这一点,如果要使用一组不同的特性,就不需要修改整个代码。
  • 使用 as_matrix 函数可以将 DataFrame 对象解析为 ndarray。

摘要

在本文中,我介绍了我将在整个文章系列中使用的工具。然后我提出了我要用线性回归算法解决的问题。最后,我展示了如何创建线性回归模型并使用它进行预测。

在下一篇文章中,我将解释如何比较参数集和测量模型性能。最后,我将展示如何用梯度下降算法更新模型参数。

下一篇

下一篇文章可点击这里

初学者深度学习编码—线性回归(第二部分):代价函数

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-linear-regression-part-2-cost-function-49545303d29f?source=collection_archive---------1-----------------------

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

Evaluating model performance during training process. (Source http://neuralnetworksanddeeplearning.com/)

这是“初学者深度学习编码”系列的第 4 篇文章。在这里,你可以在第一篇文章 的底部找到所有文章议程的链接,以及关于下一篇文章* *预计发布日期的一般信息。*它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

你也可以在我的个人网站上阅读这篇文章,为了提高可读性(支持代码语法高亮、LaTeX 方程式等等),我的个人网站由 Jekyll 主办。

概述

上一篇文章介绍了线性回归实施完成后将要解决的问题。目标是预测克拉科夫公寓的价格。数据集由三个特征描述的样本组成:到城市中心的距离房间大小。为了简化可视化并提高学习效率,将只使用尺寸特征。

此外,给出并解释了线性回归模型背后的数学公式。为了使方程完整,它的参数需要有指定的值。然后,该公式准备好返回任何给定输入样本的数值预测。

这里描述的两个步骤称为初始化预测。两者都被转化为独立的 Python 函数,并用于创建线性回归模型,其中所有参数都被初始化为零,并用于根据大小参数预测公寓价格。

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

Code used to prepare the graph is available under this link.

下一个要解决的问题

由于模型的所有权重和偏差都等于零,具有当前参数的模型将为面积参数的每个值返回零。现在让我们修改参数,看看模型的投影是如何变化的。

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

Code used to prepare these graphs is available under this link.

有两组参数会导致线性回归模型为每个大小要素值返回不同的公寓价格。由于数据具有线性模式,在适当校准参数后,模型可以成为价格的精确近似值。

要回答的问题

对于哪一组参数,模型返回更好的结果?

  • 橙色:w = 3b = 200
  • 石灰:w = 12b = -160

即使有可能通过视觉判断正确猜出答案,计算机也不会想象——它会比较这些值。这就是成本函数的用处。

价值函数

这是一个函数,测量机器学习模型对于给定数据的性能。成本函数量化了预测值和期望值之间的误差,并且以单个实数的形式呈现。根据问题的不同,成本函数可以用许多不同的方法来构成。成本函数的目的是:

  • 最小化——那么返回值通常称为成本损失错误。目标是找到成本函数返回尽可能少的模型参数值。
  • 最大化——然后它产生的价值被命名为奖励。目标是找到返回数尽可能大的模型参数值。

对于依赖梯度下降优化模型参数的算法,每个函数都必须是可微分的。

剪裁成本函数

给定一个使用以下公式的模型:

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

其中:

  • ŷ -预测值,
  • 用于预测或训练的数据的 x 向量,
  • 重量级。

注意偏置参数被故意省略。让我们试着找出权重参数的值,所以对于下面的数据样本:

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

模型的输出尽可能接近:

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

现在是时候为权重参数分配一个随机值,并可视化模型的结果。让我们暂时选择w = 5.0

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

Code used to prepare the graph is available under this link.

可以观察到模型预测与预期值不同。怎么用数学表达?最直接的方法是将两个值相减,看运算结果是否等于零。任何其他结果都意味着值不同。接收数字的大小提供了关于错误有多严重的信息。从几何角度来看,可以说误差是坐标系中两点之间的距离。让我们将距离定义为:

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

根据公式,计算预测值和期望值之间的误差:

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

如前所述,成本函数是描述模型性能的单一数字。因此,让我们总结错误。

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

然而,现在想象有一百万个点而不是四个。对于在较大数据集上进行预测的模型来说,累积误差会比在较小数据集上进行预测的模型大。因此,这些模型无法进行比较。这就是为什么它必须以某种方式缩放。正确的想法是将累积误差除以点数。这样陈述成本是模型对给定数据集产生的误差的平均值。

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

不幸的是,这个公式还没有完成。在此之前,所有情况都必须考虑,所以现在让我们尝试选择较小的权重,看看创建的成本函数是否有效。现在,权重即将被设置为w = 0.5

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

Code used to prepare the graph is available under this link.

预测又一次落空了。然而,与前一种情况相比,不同之处在于预测点低于预期点。数字上的预测更小。成本公式将出现故障,因为计算出的距离为负值。

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

成本值也是负的:

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

说距离可以有负值是不正确的。可以对高于或低于预期结果的预测附加更大的惩罚(一些成本函数就是这样做的,例如 RMSE),但值不应为负,因为它会抵消正误差。那么将不可能适当地最小化或最大化成本函数。

那么用距离的绝对值来修正问题怎么样?在将距离表示为:

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

每个重量值的成本为:

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

现在,权重w = 5.0w = 0.5的成本都计算正确了。可以比较这些参数。成本值越小,模型对w = 0.5的效果越好。

创建的函数称为 平均绝对误差

绝对平均误差

测量一组预测中平均误差大小的回归度量,不考虑它们的方向。换句话说,它是预测和预期结果之间绝对差异的平均值,其中所有个体偏差都具有同等重要性

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

其中:

  • i -样本索引,
  • ŷ -预测值,
  • y -期望值,
  • m -数据集中的样本数。

有时可能会看到预测值和期望值互换的公式形式,但工作原理是一样的。

让我们把数学变成代码:

该函数将两个相同大小的数组作为输入:predictionstargets。公式的参数m是样本数,等于发送数组的长度。由于数组具有相同的长度,因此可以同时迭代两个数组。计算每个predictiontarget之间的差值的绝对值,并加到accumulated_error变量上。在收集了所有对的误差后,累加的结果由参数m平均,该参数返回给定数据的平均误差。

均方误差

最常用和最先解释的回归指标之一。**预测和预期结果之间的均方差。**换句话说,MAE 的一种变化,其中不是取差值的绝对值,而是取它们的平方。

在 MAE 中,部分误差值等于坐标系中点之间的距离。**关于 MSE,每个部分误差相当于由测量点之间的几何距离产生的正方形的面积。**所有区域面积相加并平均。

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

Code used to prepare the graph is available under this link.

MSE 公式可以写成这样:

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

  • i -样本索引,
  • ŷ -预测值,
  • y -期望值,
  • m -数据集中的样本数。

MSE 公式有不同的形式,其中分母中没有除以 2。它的存在让 MSE 推导演算更干净。

使用绝对值计算方程的导数是有问题的。MSE 代之以使用指数运算,因此具有良好的数学性质,这使得与 MAE 相比其导数的计算更容易。当使用依赖于梯度下降算法的模型时,它是相关的。

MSE 可以用 Python 编写如下:

与上一段中介绍的mae(predictions, targets)功能的唯一区别是:

  • predictiontarget之差的平方,
  • 2在求平均分母中。

MAE 和 MSE 的区别

有更多的回归度量可以用作成本函数,用于测量试图解决回归问题的模型的性能(估计值)。MAE 和 MSE 看起来比较简单,很受欢迎。

为什么有这么多指标?

每个指标都以独特的方式处理观察结果和预期结果之间的差异。例如,不同的指标,如 RMSE,对低于预期值的预测比高于预期值的预测惩罚力度更大。它的使用可能会导致创建一个返回夸大估计值的模型。

MAE 和 MSE 是如何对待这两点之间的差异的?为了验证这一点,我们来计算不同重量值的成本:

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

Table presents the errors of many models created with different weight parameter. Cost of each model was calculated with both MAE and MSE metrics.

并显示在图表上:

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

The graphs show how metric value change for different values of parameter w. Code used to prepare these graphs is available under this link.

可以观察到:

  • MAE 不会给点与点之间的距离增加任何额外的权重——误差增长是线性的。
  • MSE 误差随着距离值的增大呈指数增长。这是一个度量标准,即对远离的点增加一个巨大的惩罚,而对接近预期结果的点增加一个最小的惩罚。误差曲线具有抛物线形状。

此外,通过检查各种重量值,有可能发现误差等于零的参数。如果使用w = 2.0来构建模型,那么预测看起来如下:

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

Code used to prepare the graph is available under this link.

当预测和预期结果重叠时,则每个合理的成本函数值等于零

回答

是时候回答这样一个问题了,哪一组参数,石灰能更好地估计克拉科夫公寓的价格。让我们用 MSE 来计算两个模型的误差,看看哪个更低。

在前一篇文章中解释了大部分代码。不是调用init(n)函数,而是手动创建参数字典用于测试目的。注意,这一次两个模型都使用了偏差。函数predict(x, parameters)用于不同parameters参数的相同数据。然后名为orange_predlime_pred的结果预测成为mse(predictions, targets)函数的参数,该函数分别返回每个模型的误差值。

结果如下:

  • 橙色: 4909.18
  • 石灰: 10409.77

这意味着 orange parameters 以更小的成本创造了更好的模型

摘要

在本文中,我解释了成本函数的概念——一种允许我们评估模型参数的工具。我已经向您介绍了两个最常用的回归度量 MAE 和 MSE。

在下一篇文章中,我将向您展示如何使用梯度下降算法来训练模型参数。

下一篇文章

下一篇文章可从这里获得。

面向初学者的编码深度学习—开始!

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-start-a84da8cb5044?source=collection_archive---------0-----------------------

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

基于直觉的一系列关于神经网络的文章,献给希望理解代码背后的基本数学的程序员和希望知道如何将数学转化为代码的非程序员。

这是“初学者深度学习编码”系列的第一篇文章。你可以在这里找到到所有文章日程的链接,以及底部关于下一篇文章 预计发布日期的一般信息。它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。

你也可以在我的个人网站上阅读这篇文章,该网站由 Jekyll 主办,目的是提高可读性(支持代码语法高亮显示、LaTeX 方程式等等。

如果你读了这篇文章,我假设你想了解最有前途的技术之一——深度学习**。声明 艾是新电 最近越来越流行了。科学家们认为,随着蒸汽发动机发动机,后来的电力以及最后的电子已经彻底改变了这个行业,后来的一个人工智能即将再次改造它。几年后,机器学习的基础知识将成为任何开发人员的必备技能。即使是现在,我们也可以观察到编程语言越来越受欢迎,这些语言主要用于机器学习,如 Python 和 r。**

具有魔力的技术

在过去的几年里,深度学习的应用在许多领域取得了巨大的进步,引起了人们的惊讶,他们没有想到技术和世界变化如此之快。

让我们从 2016 年 3 月超级计算机 AlphaGo 与最强围棋选手之一、18 次世界冠军李·塞多尔之间的历史比赛说起。人工智能以 4 比 1 的结果结束了胜利。这场比赛对围棋界产生了巨大的影响,因为 AlphaGo 发明了全新的棋步,让人们试图理解和再现它们,并创造了如何玩游戏的全新视角。但这还没完,2017 年 DeepMind 推出了 AlphaGo Zero 。已经不可战胜的机器的新版本能够在没有任何初始数据或人类帮助的情况下学习一切。所有这些的计算能力比它的前身少 4 倍!

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

AlphaGo versus Ke Jie in May 2017 (source: The Independent)

可能你们中的许多人已经听说过无人驾驶汽车项目,该项目已经开发了几年,由像 Waymo (谷歌)特斯拉丰田沃尔沃等公司开发。还有自动驾驶卡车已经在美国的一些高速公路上使用。许多国家都在慢慢准备在自己的道路上引入自动驾驶汽车,但预计未来十年将达到高峰。

但是自主飞行汽车怎么样呢?就在最近,Udacity 宣布了他们新的 Nanodegree 项目,开发者可以学习如何成为飞行汽车工程师并创造自动飞行汽车!

[## 飞行汽车和自主飞行| Udacity

掌握工作就绪的自主飞行软件工程技能,因为你处理先进的挑战,写真正的代码…

www.udacity.com](https://www.udacity.com/course/flying-car-nanodegree–nd787)

最近,由于人工智能语音识别的改进,像 Google Home 或 Google Assistant 这样的语音界面成为全新的开发分支。

Google Advertisement on Google Assistant product.

未来,人工智能将通知你因为交通而提前离开家,购买电影票,重新安排日历会议,控制你的家等等,比你想象的更近。

当然,这个列表还可以更长:人工智能能够用多种方言复制人类语言人工智能比人类更擅长诊断癌症人工智能开创哈利波特新篇章

提到所有这些的关键点是让你明白,这些发明中的每一项都使用了深度学习技术。总而言之,深度学习目前在以下任务中表现出色:

  1. 图像识别
  2. 自动驾驶汽车
  3. 像围棋、象棋扑克这样的游戏,但最近还有电脑游戏
  4. 语言翻译(但仅限几种语言)
  5. 语音识别
  6. 手写文本分析

这仅仅是个开始,因为技术每天都在变得大众化,随着越来越多的人能够使用它,越来越多的研究被完成,越来越多简单的想法被测试。

那么什么是深度学习呢?

这是基于学习数据表示的机器学习算法的子集,称为神经网络。基本想法是这样一个算法以数字数据的形式显示现实的一部分。在这个过程中,它在积累经验,并试图对给定的数据建立自己的理解。这种理解具有层次结构,就像算法具有一样。第一层学习最简单的事实,并连接到下一层,下一层使用前一层的经验来学习更复杂的事实。层数称为模型的深度。图层越多,模型可以学习的数据表示就越复杂。

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

Neural Network that is used for face detection. It learns hierarchy of representations: corners in first layer, eyes and ears in the second layer, and faces in the third layer (source: strong.io)

深度学习真的是新技术吗?

你们中的一些人可能认为深度学习是最近开发的技术。那不完全正确。深度学习有非常丰富的历史,并且根据哲学观点有各种各样的名称。一百多年前,在第一个数学概念建立之前,人们就梦想着智能机器。经历了三次发展浪潮。

在第一波浪潮中,深度学习被称为控制论。现代深度学习的第一个前辈是受神经系统研究启发的线性模型——神经科学。神经元(1943 年)的第一个概念,即神经网络的最小部分,是由麦卡洛克-皮特提出的,试图实现大脑功能。几年后,弗兰克·罗森布拉特将这个概念变成了第一个可训练的模型——马克 1 感知机。

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

Mark 1 Perceptron (source: Wikipedia)

但是人们很难用当时可用的理论来描述大脑行为。这就是为什么在接下来的 20 年里人们对它们的兴趣下降了。

第二次浪潮始于 80 年代,名为连接主义,但术语神经网络也开始被更频繁地使用。主要的想法是,当神经元大量聚集在一起时,可以实现更智能的行为。这个概念是由 Hinton 提出的,被称为分布式表示(1986) 。它仍然是今天深度学习的核心。第二次浪潮的另一个伟大成就是 Yann LeCun (1987) 发明的反向传播——这是一种核心算法,直到今天仍用于训练神经网络参数。同样在 1982 年约翰·霍普菲尔德发明了递归神经网络,在 1997 年 LSTM的额外介绍后,今天被用于语言翻译。这几年对神经网络的大肆宣传已经结束,因为各种投资者对在产品中实现人工智能的期望没有实现。

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

Image of LSTM cell based Recurrent neural Network (source: http://colah.github.io/posts/2015-08-Understanding-LSTMs/)

第三次浪潮始于 2006 年。那时,电脑成了每个人都能买得起的更普通的东西。得益于各种群体,例如游戏玩家,强大的 GPU 市场不断增长。每个人都可以上网。公司开始更加关注分析——以数字形式收集数据。作为一个副作用,研究人员有更多的数据和计算能力来进行实验和验证理论。因此,由于 Geoffrey E. Hinton 成功训练了多层神经网络,这又是一个巨大的进步。从那时起,许多不同的多层神经网络结构的建议开始出现。科学家将神经网络的层数称为“深度”——层数越多,就越深。非常重要的是在图像分类竞赛 ILSVRC-2012 中使用了卷积神经网络 AlexNet 。它为许多行业提供了可靠的图像检测机制,使许多机器能够看到自动驾驶汽车,从而彻底改变了许多行业。

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

Structure of AlexNet CNN (source: Alex Krizhevsky, Ilya Sutskever, Geoffrey E. Hinton, “ImageNet Classification with Deep Convolutional Neural Networks”, 2012)

2014 年,Ian Goodfellow 引入了一种新型的神经网络,称为生成对抗网络。在这种结构中,两个神经网络相互竞争。第一个网络试图模仿一些数据分布。第二个网络的作用是辨别它收到的数据是真是假。第一个网络的目标是欺骗第二个网络。竞争提高了第一网络的性能,并使任何类型的数据——图像、音乐、文本、语音——的生成成为可能。

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

GAN used to transfer style of one image into another (source: https://github.com/lengstrom/fast-style-transfer)

我想就这样了。第三波持续到今天,这取决于我们能走多远!

我为什么要创作这个系列的文章?

我真的对机器学习,尤其是深度学习充满热情。我的梦想是成为机器学习专家——与人合作解决问题并使知识大众化的人。我每天都在努力达到这个目标,这个博客是其中的一部分。所以跟我一起学习吧!

在我看来,获得这项技术的最大问题是,它是在大学和实验室由高水平的博士科学家开发的,并且仍然部分停留在那里。这是可以理解的,因为一切都强烈基于线性代数概率信息论、 数值计算。但是为了成为一名车手,你不需要了解发动机,对吗?人们仍然相信,要在这个领域工作,你需要有博士学位,但是在软件工程方面,这种观念已经开始改变。

对拥有这些技能的人的需求将会变得如此之大,以至于不可能让每个人都拥有博士头衔。这就是为什么为了让人们使用它,必须有人能把它翻译给别人,同时跳过复杂的证明,科学的符号,并增加更多的直觉。

我希望向你展示的是

我的目标是对与深度学习相关的大多数热门话题提供强有力的理解。在挑选内容的时候,我不想保护你——我想向你展示更复杂的东西,同时,尽我所能为你提供理解它们的直觉。我的主要任务是让你理解这些算法是如何工作的,并教你如何从头开始编码。就像 Mark Dao ust(tensor flow 的开发者项目工程师)曾经对我说的那样:

每个人都应该从头开始编写一次神经网络代码…但只能编写一次…

所以会有很多代码我打算仔细解释。在这些主题中,你可以期待我将向你展示如何使用我们所学的迷你项目。知识跟随着实践真的很重要。

这种方法将是自下而上的:

  • 底层——基础(和解释的)数学变成 Python NumPy 代码,
  • 中级——tensor flow(TF . nn 和 tf.layer 模块),我已经向您展示的大部分内容都可以在一行代码中自动完成,
  • 高层——非常流行的框架,可以让你非常快速地创建神经网络——Keras。

这个项目将只关注多层感知器。已经有很多工作要做了。如果它成功了,我可能会考虑对卷积神经网络、递归神经网络和生成对抗神经网络进行扩展。

议程

将来,您可以看到涵盖以下主题的文章(顺序可能会改变):

  1. 【25 . 07 . 2018】机器学习的类型
  2. 【1 . 08 . 2018】线性回归(第一部分):初始化和预测
  3. 【8 . 08 . 2018】线性回归(第二部分):成本函数
  4. 【23 . 08 . 2018】线性回归(第三部分):梯度下降训练
  5. [30.08.2018]线性回归(第四部分):矢量化
  6. [06.09.2018]线性回归(第 5 部分):可重复使用的分类器的创建

要涵盖的概念:

  • 逻辑回归和激活函数
  • 多层感知器的思想
  • 用例子详细解释反向传播
  • 梯度检查
  • 为神经网络准备数据—标准化、规范化
  • 激活功能及其背后的直觉
  • Softmax,一个热编码
  • 权重初始化、消失渐变、爆炸渐变
  • 随机梯度下降,小批量,批量梯度下降
  • 乐观主义者
  • 调谐超参数
  • 学习曲线、过度拟合、偏差
  • 正规化的方法——退出、批量正规化

面向初学者的编码深度学习

原文:https://towardsdatascience.com/coding-deep-learning-for-beginners-types-of-machine-learning-b9e651e1ed9d?source=collection_archive---------2-----------------------

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

Image source: http://www.cognub.com/index.php/cognitive-platform/

机器学习的类型

这是系列“初学者深度学习编码”的第二篇文章。在这里,你可以在第一篇文章 的底部找到所有文章议程的链接,以及关于下一篇文章* *预计发布日期的一般信息。*它们也可以在我的开源文件夹— MyRoadToAI 中找到,还有一些迷你项目、演示、教程和链接。*

你也可以在我的个人网站上阅读这篇文章,为了提高可读性(支持代码语法高亮、LaTeX 方程式等等),我的个人网站由 Jekyll 主办。

目标

进入机器学习领域并不是一件容易的事情。我很想爱护读者。这就是为什么有时你会看到只关注理论的文章。因为长文章不鼓励学习,所以我会把它们保持在5-8 分钟的阅读时间。我不能把所有东西都放在一篇文章里——代码片段、数学、术语——因为那样会减少对基本概念的解释。我相信将知识分成更小的部分并扩展到更多的文章中会使学习过程更顺利,因为没有必要停下来走弯路。

机器学习模型

从“模型”的定义开始,这个定义从现在开始会经常出现。如线性回归逻辑回归决策树等名称。只是算法的名字。那些只是理论上的概念,描述了为了达到特定的效果应该做些什么。模型是一个数学公式,它是机器学习算法实现的一个结果(在这些文章的情况下——在代码中)。它有可测量的参数,可用于预测。可以通过修改模型的参数来训练模型,以便获得更好的结果。可以说,模型是机器学习系统从训练数据中学到的东西的表示。

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

Diagram visualising difference between Machine Learning Algorithm and Machine Learning Model.

机器学习的分支

机器学习有三个最常见的类别:

  • 监督学习
  • 无监督学习
  • 强化学习

监督学习

需要由示例输入输出对组成的 数据集的算法组。每一对由用于进行预测的数据样本和被称为标签的预期结果组成。“受监督的”一词来源于标签需要由人类管理者分配给数据的事实。

在训练过程中,样本被反复输入到模型中。对于每个样本,模型使用参数的当前状态并返回预测。预测与标签相比较,其差异称为误差。**误差是对模型的反馈,说明哪里出了问题,以及如何自我更新,以减少未来预测中的误差。**这意味着模型将根据其创建所基于的算法改变其参数值。

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

Diagram demonstrating how Supervised Learning works.

监督学习模型试图找到参数值,使它们能够在历史数据上表现良好。然后,它们用于对未知数据进行预测,这些数据不是训练数据集的一部分。

监督学习可以解决两个主要问题:

  • 分类为输入的数据样本分配类别的过程。示例用途:预测一个人是否生病,检测欺诈交易,人脸分类器。
  • 回归预测输入数据样本的连续数值的过程。示例用途:评估房价,预测杂货店食品需求,温度预测。

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

Example of Classification and Regression models.

无监督学习

试图从非标记数据中得出推论的一组算法(不参考已知或标记的结果)。在无监督学习中,没有正确答案。基于这种算法的模型可以用来发现未知的数据模式和数据结构本身。

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

Example of Unsupervised Learning concept. All data is fed to the model and it produces an output on it’s own based on similarity between samples and algorithm used to create the model.

无监督学习最常见的应用是:

  • 模式识别和数据聚类将相似数据样本划分并分组在一起的过程。组通常被称为簇。示例用途:超市分割、用户群分割、信号去噪。
  • 降低数据维度 -数据维度是描述数据样本所需的特征数量。降维是一个过程,将特征压缩成所谓的主值,简洁地传达相似的信息。通过仅选择几个组件,减少了特征的数量,并且在此过程中丢失了一小部分数据。示例用途:通过减少计算次数来加速其他机器学习算法,在数据中找到一组最可靠的特征。

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

Dividing data from various countries around the world into three clusters representing Developed, Developing and Underdeveloped nations (source: Tableau blog).

强化学习

机器学习算法的分支,产生所谓的代理。代理角色与经典模型略有不同。它从环境中接收信息,并通过执行动作对其做出反应。信息以数字数据的形式提供给代理,称为状态,状态被存储,然后用于选择正确的动作。因此,代理人会收到一个奖励,奖励可以是正的,也可以是负的。奖励是代理可以用来更新其参数的反馈。

代理人的培训是一个试错的过程。为了学习,它需要在各种情况下找到自己,并在每次采取错误行动时受到惩罚。优化目标可以根据强化学习方法以多种方式设定,例如基于价值函数梯度策略环境模型

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

Interaction between Agent and Environment.

强化学习的应用范围很广。他们中的大多数是发明,经常被认为是人工智能最具创新性的成就。

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

Example of solutions where Reinforcement Learning is used. From self-driving cars through various games such as Go, Chess, Poker or computer ones — Dota or Starcraft, to manufacturing.

模拟 3D 模型的运动是一项复杂的任务。这种模型需要在给定的环境中与不同的模型进行交互。强化学习正越来越多地被用作解决这一问题的工具,因为它产生的结果对人眼来说似乎非常可信,并且算法能够自动适应描述环境的规则。

Main video accompanying the SIGGRAPH 2018 paper: “DeepMimic: Example-Guided Deep Reinforcement Learning of Physics-Based Character Skill”.

总结

仅此而已。在下一篇文章中,我将解释线性回归算法的基础和实现,这是一种基本的监督学习算法。

下一篇文章

下一篇文章可在这里

公开编码

原文:https://towardsdatascience.com/coding-in-the-open-349e07d25898?source=collection_archive---------6-----------------------

2017 年图灵节上你应该从全栈工程中知道的 3 件事

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

Coding in the open

艾瑞克·阿特罗斯科

今年图灵节的工程赛道挤满了令人惊叹的演讲者,涵盖了广泛的主题,从英国政府如何免费提供他们的一些服务代码,如何在开源项目中做更好的贡献者,到云的发展方向以及它可以解决什么问题。

我想谈谈三个与开源项目、内部项目和软件开发相关的会议。

公开编码

这一天开始于来自政府数字服务 (GDS)的安娜·希普曼分享她的故事,当用户报告一个问题时,从长达 18 个月的等待获得代码修复,到能够在不到一周的时间内发布用户贡献的代码修复。这是通过取得平台代码的所有权以及公开代码以使每个人都可以对其做出贡献的组合来实现的。由于默认为开源项目,可见性增加,这也意味着服务/代码可以在 GDS 的不同项目中重用。与任何足够大的公司一样,你会有不一定经常在一起工作的人和项目,但是他们都面临类似的问题,并且很可能会针对这些问题制定自己的解决方案。在许多情况下,重复的努力是一种浪费,通过公开代码,他们能够防止这样的情况经常发生。

Skyscanner 我们鼓励内部对项目做出贡献,这样当你发现有些事情不太对劲,或者你看到你可以为之做出贡献的改进时,你就能够并被鼓励采取行动。通过遵循开源项目的原则,我们鼓励每个项目都有一个自述文件,包含入门步骤和投稿指南。通过降低其他人开始工作的门槛,我们增加了人们和团队之间的协作,这些人和团队通常不会在日常基础上相互交流。

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

Anna Shipman (GDS), Turing Fest 2017

演讲中提到的另一点是,通过公开代码,您可以获得新的反馈。这也导致人们更加关注并质疑他们是否愿意接受某些设计和实现决策,因为这些决策将会向更广泛的受众发布。

为了保持建设性的反馈流,并增加让遇到类似问题的其他人意识到您正在解决或已经解决了这个问题的机会,我们有专门设计的论坛来呈现、回顾、讨论和提供反馈。

贡献

开源也是接下来演讲的主题。Mike McQuaid 谈到了有效的开源交互。我们讨论了与您的操作系统交互的三种不同人群:

  1. 用户
  2. 贡献者
  3. 保持器

我们讨论了每个群体的典型需求,以及人们如何在这些群体之间移动。我们讨论了围绕维护人员的部分职责引入过程如何能够为技术工作腾出时间。我们看了一些为自制软件(迈克是维护者)管理和获取贡献的过程的例子,以及如何减少贡献的摩擦,无论是通过提交错误报告、功能请求还是实际的代码贡献。这是通过为如何恰当地提交错误报告提供清晰的步骤来实现的,自动化了贡献所需的一些令人困惑的(对于经验不足的用户)和耗时的步骤。OSS 项目的关键成分是社区,你希望你的社区积极参与并做出贡献。您的社区中的大多数人将是用户,您将有一些贡献者,维护者的百分比通常会更小。我相信 Mike 称之为追加销售。通过接触用户来吸引你的社区,让他们更多地参与进来,允许他们挠痒痒,并为修复他们发现的问题做出贡献——甚至改善他们已经想了一段时间的事情。

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

Mike McQuaid talked about effective open source interactions

和任何项目一样,不管是内部的还是其他的,你都会从处理用户反馈、特性请求和用户贡献的过程中受益。当开始一个新项目时,重要的是要考虑你创建的产品/服务/工具是否是你希望人们为之做出贡献的东西。也许这将是他们生产道路的一部分。如果是这样的话,你应该创建一个清晰的贡献指南以及一套规则,在项目生命周期的早期设定对贡献的期望。这样你就可以把最大的时间花在软件本身上,而不是(例如,当项目获得牵引力时)处理不断涌入的需要你宝贵注意力的请求。

这是我们想要做好的事情。我们有许多项目,合并请求源源不断地到来。在许多情况下都有很好的支持文档,而且投稿过程通常都经过了深思熟虑。但这并不意味着我们不能变得更好,无论是涉及架构的变化以确保迭代可以更快更容易地实现,还是改变团队处理外部请求的方式,同时照顾他们自己的 backlog。

在更个人的层面上,几年前我曾经嘲笑通过写文档、投稿指南和仔细考虑这些问题来开始一个项目的想法。我想从架构的角度解决一个问题,弄清楚实现将从哪里开始,以及什么是难点。我的现实检查是我的团队第一次继承了一个在生产中运行的服务——没有文档和指南,基本上除了远程访问操作基础设施和源代码什么都没有。当然,我们遇到了一些直接影响生产的问题,上周就需要解决了!所以我们需要问问以前的房主。问题是,最初负责编写服务的工程师已经在三年前离开了公司。

事情在发生,人们在移动,项目在易手,服务经常被遗忘,在后台运行,直到出现问题。问题不在于“是否”会出错,而在于“何时”会出错,因此重要的是要腾出时间来编写文档,并确保未来的项目移交是无痛和无缝的——而不是在项目结束时疯狂地匆忙或事后思考(因为让我们面对现实吧,如果在长期运行或延迟的项目结束时要删除一些东西,那肯定是文档)。

炉边谈话

当天的第三场会议是与迈克尔·普赖尔(Fog Creek Software、Trello 和 Stack Overflow 的创始人)和约翰·皮布尔斯(爱丁堡创业公司行政的首席执行官)的炉边聊天。作为一个每天与 Stack Overflow 和 Trello 打交道的人,我发现听一听参与创建这两家公司的人说些什么很有意思。

对话把我们带回到博客还不存在的时候,也没有一种简单的方法来为开发者分享想法和经验。虽然当时有一些公司关注这一点,但数量非常少。开发人员主要履行支持角色,这导致了不满——但最终也认识到事情可以(并且应该)以更好的方式完成。

就在那时,迈克尔和乔尔·斯波尔斯基决定创办自己的公司,并弄清楚怎样才能建立一家工程师们希望 T1 去工作的公司。聆听他们使用 Fog Creek 软件的历程、他们学到的经验、犯过的错误以及他们设法学到的东西,也是一次令人谦卑的经历。

我最喜欢的一句话是:

“我们经历了十年的失败,建立了堆栈溢出.”

人们往往倾向于认为那些已经取得很大成就的人并没有犯很多错误,他们只是第一次尝试就把事情做对了。那里躺着疯狂;很容易给自己施加巨大的、不必要的压力,消耗时间、理智和生产力。许多成功人士犯了错误,但仍然继续做着伟大的事情,那么为什么要陷在没有结果的事情上呢?我从这次演讲中得到的主要启示是,要预料到会犯错误,不要担心会犯错误,而是要从中吸取教训……下次做得更好,不管你在做什么。

那么……判决。

我参加了这两天的会议,参加了所有专题(战略、产品、工程和营销)的混合会议,很容易说这是一次精彩的会议,有强大的阵容和出色的演讲者。讨论的话题范围很广,这意味着每个人都有感兴趣和有价值的东西。

与我们合作

我们在 Skyscanner 以不同的方式做事,我们正在全球办事处寻找更多的工程团队成员。看看我们的 Skyscanner 职位寻找更多空缺。

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

Team in Action

关于作者

我是 Irek Atroszko,是 Skyscanner 的软件工程师。我主要从事后端服务。工作之余,我的兴趣主要在于上好的咖啡、书籍、锋利的日本刀和定期的苏格兰徒步旅行。

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

Irek Atroszko, Skyscanner

编码神经网络—辍学

原文:https://towardsdatascience.com/coding-neural-network-dropout-3095632d25ce?source=collection_archive---------3-----------------------

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

Figure 1: Dropout

辍学是一种正规化技术。在每次迭代中,我们随机关闭每层上的一些神经元(单元),并且在前向传播和反向传播中都不使用这些神经元。由于在每次迭代中被丢弃的单元将是随机的,学习算法将不知道在每次迭代中哪些神经元将被关闭;因此,强制学习算法分散权重,而不是专注于某些特定特征(单元)。此外,退出有助于通过以下方式改善泛化误差:

  • 因为我们在每次迭代中丢弃一些单元,这将导致更小的网络,这反过来意味着更简单的网络(正则化)。
  • 可以看作是装袋技术的近似。每一次迭代都可以被看作是不同的模型,因为我们在每一层随机放置不同的单元。这意味着误差将是来自所有不同模型(迭代)的误差的平均值。因此,平均来自不同模型的误差,特别是如果这些误差是不相关的,将减少总误差。在误差完全相关的最坏情况下,在所有模型中求平均值根本没有帮助;然而,我们知道在实践中,误差在某种程度上是不相关的。因此,它总是会改善泛化误差。

我们可以在每一层使用不同的概率;然而,输出层将总是具有keep_prob = 1,而输入层具有高keep_prob,例如 0.9 或 1。如果一个隐藏层有keep_prob = 0.8,这意味着;在每次迭代中,每个单元有 80%的概率被包含,20%的概率被删除。

在计算机视觉问题中经常使用 Dropout,因为我们有很多特征,但没有很多数据。此外,相邻的特征(像素)通常不会增加很多信息。所以,模型总是会出现过拟合的情况。

为了说明 dropout 如何帮助我们减少泛化错误,我们将使用我们在以前的帖子中使用的相同数据集。该数据集有猫和非猫的图像。我们将尝试建立一个神经网络来分类图像是否有猫。每幅图像的 RGB 比例为 64 x 64 像素。让我们导入数据,看看形状以及来自训练集的猫图像样本。

# Import training data
train_dataset = h5py.File("../data/train_catvnoncat.h5")
X_train = np.array(train_dataset["train_set_x"])
Y_train = np.array(train_dataset["train_set_y"])

# Plot a sample image
plt.imshow(X_train[50])
plt.axis("off");

# Import test data
test_dataset = h5py.File("../data/test_catvnoncat.h5")
X_test = np.array(test_dataset["test_set_x"])
Y_test = np.array(test_dataset["test_set_y"])

# Transform data
X_train = X_train.reshape(209, -1).T
X_train = X_train / 255
Y_train = Y_train.reshape(-1, 209)

X_test = X_test.reshape(50, -1).T
X_test = X_test / 255
Y_test = Y_test.reshape(-1, 50)

# print the new shape of both training and test datasets
print("Training data dimensions:")
print("X's dimension: {}, Y's dimension: {}".format(X_train.shape, Y_train.shape))
print("Test data dimensions:")
print("X's dimension: {}, Y's dimension: {}".format(X_test.shape, Y_test.shape))Training data dimensions:
X's dimension: (12288, 209), Y's dimension: (1, 209)
Test data dimensions:
X's dimension: (12288, 50), Y's dimension: (1, 50)

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

Figure 2: Sample image

现在,我们将编写在前向传播和反向传播上应用压差所需的函数。请注意,我们将利用我们在以前的帖子中编写的函数,如initialize_parameters

def drop_out_matrices(layers_dims, m, keep_prob):
    np.random.seed(1)
    D = {}
    L = len(layers_dims)

    for l in range(L):
        # initialize the random values for the dropout matrix
        D[str(l)] = np.random.rand(layers_dims[l], m)
        # Convert it to 0/1 to shut down neurons corresponding to each element
        D[str(l)] = D[str(l)] < keep_prob[l]
        assert(D[str(l)].shape == (layers_dims[l], m))
    return D

def L_model_forward(
   X, parameters, D, keep_prob, hidden_layers_activation_fn="relu"):
    A = X                           # since input matrix A0
    A = np.multiply(A, D[str(0)])
    A /= keep_prob[0]
    caches = []                     # initialize the caches list
    L = len(parameters) // 2        # number of layer in the network

    for l in range(1, L):
        A_prev = A
        A, cache = linear_activation_forward(
            A_prev, parameters["W" + str(l)], parameters["b" + str(l)],
            hidden_layers_activation_fn)
        # shut down some units
        A = np.multiply(A, D[str(l)])
        # scale that value of units to keep expected value the same
        A /= keep_prob[l]
        caches.append(cache)

    AL, cache = linear_activation_forward(
        A, parameters["W" + str(L)], parameters["b" + str(L)], "sigmoid")
    AL = np.multiply(AL, D[str(L)])
    AL /= keep_prob[L]
    caches.append(cache)
    assert(AL.shape == (1, X.shape[1]))

    return AL, caches

def L_model_backward(
   AL, Y, caches, D, keep_prob, hidden_layers_activation_fn="relu"):
    Y = Y.reshape(AL.shape)
    L = len(caches)
    grads = {}

    # dA for output layer
    dAL = np.divide(AL - Y, np.multiply(AL, 1 - AL))
    dAL = np.multiply(dAL, D[str(L)])
    dAL /= keep_prob[L]

    grads["dA" + str(L - 1)], grads["dW" + str(L)], grads[
        "db" + str(L)] = linear_activation_backward(
            dAL, caches[L - 1], "sigmoid")
    grads["dA" + str(L - 1)] = np.multiply(
        grads["dA" + str(L - 1)], D[str(L - 1)])
    grads["dA" + str(L - 1)] /= keep_prob[L - 1]

    for l in range(L - 1, 0, -1):
        current_cache = caches[l - 1]
        grads["dA" + str(l - 1)], grads["dW" + str(l)], grads[
            "db" + str(l)] = linear_activation_backward(
                grads["dA" + str(l)], current_cache,
                hidden_layers_activation_fn)

        grads["dA" + str(l - 1)] = np.multiply(
            grads["dA" + str(l - 1)], D[str(l - 1)])
        grads["dA" + str(l - 1)] /= keep_prob[l - 1]

    return grads

def model_with_dropout(
        X, Y, layers_dims, keep_prob, learning_rate=0.01, num_iterations=3000,
        print_cost=True, hidden_layers_activation_fn="relu"):
    # get number of examples
    m = X.shape[1]

    # to get consistents output
    np.random.seed(1)

    # initialize parameters
    parameters = initialize_parameters(layers_dims)

    # intialize cost list
    cost_list = []

    # implement gradient descent
    for i in range(num_iterations):
        # Initialize dropout matrices
        D = drop_out_matrices(layers_dims, m, keep_prob)

        # compute forward propagation
        AL, caches = L_model_forward(
            X, parameters, D, keep_prob, hidden_layers_activation_fn)

        # compute regularized cost
        cost = compute_cost(AL, Y)

        # compute gradients
        grads = L_model_backward(
            AL, Y, caches, D, keep_prob, hidden_layers_activation_fn)

        # update parameters
        parameters = update_parameters(parameters, grads, learning_rate)

        # print cost
        if (i + 1) % 100 == 0 and print_cost:
            print(f"The cost after {i + 1} iterations : {cost:.4f}.")
        # append cost
        if i % 100 == 0:
            cost_list.append(cost)

    # plot the cost curve
    plt.plot(cost_list)
    plt.xlabel("Iteration (per hundreds)")
    plt.ylabel("Cost")
    plt.title(f"Cost curve for the learning rate = {learning_rate}")

    return parameters

最后,我们准备好建立我们的神经网络。首先,我们将建立一个完全连接的网络,没有掉线。也就是说,keep_prob = 1。接下来,我们将建立另一个网络。最后,我们将比较两个网络的泛化误差,并看看丢弃技术如何帮助我们改善泛化误差。

# setup layers dimensions, number of examples, and keep probabilities list
m = X_train.shape[0]
keep_prob = [1, 1, 1, 1]
layers_dims = [m, 10, 10, 1]

# train NN with no dropout
parameters = model_with_dropout(X_train, Y_train, layers_dims,      keep_prob=keep_prob, learning_rate=0.03, num_iterations=1000, hidden_layers_activation_fn="relu")

# print the test accuracy
print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "relu")[-7:]))
print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "relu")[-7:]))The cost after 100 iterations : 0.6555.
The cost after 200 iterations : 0.6468.
The cost after 300 iterations : 0.6447.
The cost after 400 iterations : 0.6442.
The cost after 500 iterations : 0.6440.
The cost after 600 iterations : 0.6440.
The cost after 700 iterations : 0.6440.
The cost after 800 iterations : 0.6440.
The cost after 900 iterations : 0.6440.
The cost after 1000 iterations : 0.6440.
The training accuracy rate: 65.55%.
The test accuracy rate: 34.00%.

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

Figure 3: Cost curve with no dropout

# setup keep probabilities list
keep_prob = [1, 0.5, 0.5, 1]

# train NN with no dropout
parameters = model_with_dropout(X_train, Y_train, layers_dims,      keep_prob=keep_prob, learning_rate=0.03, num_iterations=1000, hidden_layers_activation_fn="relu")

# print the test accuracy
print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "relu")[-7:]))
print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "relu")[-7:]))The cost after 100 iterations : 0.6555.
The cost after 200 iterations : 0.6467.
The cost after 300 iterations : 0.6445.
The cost after 400 iterations : 0.6437.
The cost after 500 iterations : 0.6412.
The cost after 600 iterations : 0.6338.
The cost after 700 iterations : 0.6108.
The cost after 800 iterations : 0.5367.
The cost after 900 iterations : 0.4322.
The cost after 1000 iterations : 0.3114.
The training accuracy rate: 74.16%.
The test accuracy rate: 44.00%.

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

Figure 4: Cost curve with dropout

以上结果表明,有丢包的网络测试准确率提高了 30%。请注意,这只是一个说明性的例子,以显示辍学技术的有效性。在这个例子中,我们选择了任意的概率;然而,我们可以调整每一层上的丢弃概率,以产生最佳的验证损失和准确性。

结论

Dropout 是一种非常有效的正则化技术,在卷积神经网络中被大量使用。以下是一些要点:

  • 使用梯度检测时设置keep_prob = 1;不然就不行了。
  • 辍学仅在培训期间使用。不要在测试/预测新示例时使用它。
  • keep_prob越低→神经网络越简单。随着keep_prob的减少,偏差增加,方差减少。因此,具有更多神经元的层预期具有较低的keep_prob以避免过度拟合。
  • 在计算上,这是一种改善泛化误差和帮助解决过度拟合的廉价方法。
  • 人们可以调整keep_prob来获得手头任务的最佳结果。

创建这篇文章的源代码可以在这里找到。帖子的灵感来自 deeplearning.ai 课程。

原载于 2018 年 5 月 20 日imaddabbura . github . io

编码神经网络——前向传播和反向传播

原文:https://towardsdatascience.com/coding-neural-network-forward-propagation-and-backpropagtion-ccf8cf369f76?source=collection_archive---------1-----------------------

为什么是神经网络?

根据通用逼近定理,给定足够大的层和期望的误差范围,神经网络可以逼近、学习和表示任何函数。神经网络学习真正功能的方式是在简单的基础上建立复杂的表示。在每个隐藏层上,神经网络通过首先计算给定输入的仿射(线性)变换,然后应用非线性函数来学习新的特征空间,该非线性函数又将成为下一层的输入。这一过程将继续下去,直到我们到达输出层。因此,我们可以将神经网络定义为从输入端通过隐含层流向输出端的信息流。对于一个三层神经网络,学习的函数将是: f(x) = f_3(f_2(f_1(x))) 其中:

  • f1(x):在第一个隐藏层学习的函数
  • F2(x):在第二隐藏层学习的函数
  • F3(x):在输出层学习的功能

因此,在每一层上,我们学习不同的表现,随着后面的隐藏层变得更加复杂。下面是一个 3 层神经网络的例子(我们不考虑输入层):

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

Figure 1: Neural Network with two hidden layers

比如计算机不能直接理解图像,不知道如何处理像素数据。然而,神经网络可以在识别边缘的早期隐藏层中建立图像的简单表示。给定第一个隐藏层输出,它可以学习拐角和轮廓。给定第二个隐藏层,它可以学习鼻子等部位。最后,它可以学习对象身份。

由于真相从来都不是线性的并且表示对于机器学习算法的性能非常关键,神经网络可以帮助我们建立非常复杂的模型,并将其留给算法来学习这种表示,而不必担心特征工程,这需要从业者花费非常长的时间和精力来策划一个好的表示。

这篇文章有两部分:

  1. 神经网络编码:这需要编写所有的助手函数,使我们能够实现一个多层神经网络。在这样做的时候,我会尽可能地解释理论部分,并给出一些实现上的建议。
  2. 应用:我们将实现我们在第一部分中编写的关于图像识别问题的神经网络,看看我们构建的网络是否能够检测图像中是否有猫或狗,并看到它在工作:)

这篇文章将是一系列文章中的第一篇,涵盖了在 numpy 中实现神经网络,包括梯度检查,参数初始化,L2 正则化,丢失。创建这篇文章的源代码可以在这里找到。

# Import packages
import h5py import
matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

I .神经网络编码

正向传播

输入 X 提供初始信息,然后传播到每层的隐藏单元,并最终产生输出 y^.。网络的架构需要确定其深度、宽度和每层使用的激活函数。深度是隐藏层数。宽度是每个隐藏层上的单元(节点)数量,因为我们不控制输入层和输出层的尺寸。有相当多组激活函数,如整流线性单元、Sigmoid、双曲线正切等。研究已经证明,更深的网络优于具有更多隐藏单元的网络。因此,培养一个更深层次的关系网(收益递减)总是更好,也不会有坏处。

让我们首先介绍一些将在本文中使用的符号:

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

接下来,我们将以通用形式写下多层神经网络的维度,以帮助我们进行矩阵乘法,因为实现神经网络的主要挑战之一是获得正确的维度。

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

我们需要实现前向传播的两个方程是:这些计算将发生在每一层上。

参数初始化

我们将首先初始化权重矩阵和偏差向量。值得注意的是,我们不应该将所有参数初始化为零,因为这样做会导致梯度相等,并且每次迭代的输出都是相同的,学习算法不会学到任何东西。因此,将参数随机初始化为 0 到 1 之间的值很重要。还建议将随机值乘以小标量,如 0.01,以使激活单元处于活动状态,并位于激活函数导数不接近零的区域。

激活功能

对于哪种激活功能在特定问题上效果最好,没有明确的指导。这是一个反复试验的过程,人们应该尝试不同的功能集,看看哪一个最适合手头的问题。我们将介绍 4 种最常用的激活功能:

  • 乙状结肠函数(σ):g(z)=1/(1+e^{-z})。建议仅在输出图层上使用,这样我们可以很容易地将输出解释为概率,因为它将输出限制在 0 和 1 之间。在隐藏层上使用 sigmoid 函数的一个主要缺点是,在其域的大部分上,梯度非常接近于零,这使得学习算法学习起来缓慢且困难。
  • 双曲正切函数:g(z)=(e^z -e{-z})/(ez+e^{-z})。它优于 sigmoid 函数,在 sigmoid 函数中,其输出的平均值非常接近零,换句话说,它将激活单元的输出集中在零附近,并使值的范围非常小,这意味着学习速度更快。它与 sigmoid 函数共有的缺点是在域的好的部分上梯度非常小。
  • 整流线性单元(ReLU):g(z)**= max { 0,z} 。接近线性的模型易于优化。由于 ReLU 与线性函数有许多相同的性质,它在大多数问题上都表现得很好。唯一的问题是导数没有定义在 z = 0 ,我们可以通过在 z = 0 将导数赋值为 0 来解决这个问题。然而,这意味着对于 z ≤ 0,梯度为零,再次无法学习。
  • 漏整流线性单元:g(z)=max {α z,z}* 。它克服了 ReLU 的零梯度问题,并为 z ≤ 0 指定了一个小值 α

如果你不确定选择哪个激活函数,从 ReLU 开始。接下来,我们将实现上面的激活函数,并为每个函数绘制一个图表,以便更容易地看到每个函数的域和范围。

正向输送

给定来自前一层的输入,每个单元计算仿射变换 z = W^Tx + b ,然后应用激活函数 g(z) ,例如 ReLU 元素方式。在这个过程中,我们将存储(缓存)在每一层上计算和使用的所有变量,以便在反向传播中使用。我们将编写将在 L 模型正向传播中使用的前两个助手函数,以使其更易于调试。请记住,在每一层上,我们可能有不同的激活函数。

费用

我们将使用二元交叉熵成本。它使用对数似然法来估计其误差。代价是:上述代价函数是凸的;然而,神经网络通常会陷入局部极小值,不能保证找到最优参数。我们将在这里使用基于梯度的学习。

反向传播

允许信息通过网络从成本回溯,以计算梯度。因此,以相反的拓扑顺序从最终节点开始循环遍历节点,以计算最终节点输出相对于每条边的节点尾部的导数。这样做将帮助我们知道谁对最大的错误负责,并在那个方向上改变参数。下面的导数公式将帮助我们编写反向传播函数:因为 b^l 总是一个向量,所以总和将是跨行的(因为每一列都是一个例子)。

二。应用

我们将要处理的数据集有 209 张图片。每幅图像的 RGB 比例为 64 x 64 像素。我们将建立一个神经网络来分类图像是否有猫。因此,{ 0,1}* 。*

  • 我们将首先加载图像。
  • 显示猫的样本图像。
  • 改变输入矩阵的形状,使每一列都成为一个示例。此外,由于每张图片的大小为 64 x 64 x 3,因此每张图片有 12,288 个特征。因此,输入矩阵应为 12,288 x 209。
  • 将数据标准化,这样梯度就不会失控。此外,它将有助于隐藏单位有类似的价值范围。现在,我们将每个像素除以 255,这应该不成问题。但是,最好将数据标准化为平均值为 0,标准差为 1。
*Original dimensions:
--------------------
Training: (209, 64, 64, 3), (209,)
Test: (50, 64, 64, 3), (50,)New dimensions:
---------------
Training: (12288, 209), (1, 209)
Test: (12288, 50), (1, 50)*

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

Figure 3: Sample image

现在,我们的数据集已准备好用于测试我们的神经网络实现。先写多层模型函数,用预定义的迭代次数和学习速率实现基于梯度的学习。

接下来,我们将训练两个版本的神经网络,其中每个将在隐藏层上使用不同的激活函数:一个将使用整流线性单元( ReLU ),第二个将使用双曲正切函数( tanh )。最后,我们将使用从两个神经网络中获得的参数对训练示例进行分类,并计算每个版本的训练准确率,以查看哪个激活函数在这个问题上效果最好。

*# Setting layers dims
layers_dims = [X_train.shape[0], 5, 5, 1]# NN with tanh activation fn
parameters_tanh = L_layer_model( X_train, y_train, layers_dims, learning_rate=0.03, num_iterations=3000, hidden_layers_activation_fn="tanh")# Print the accuracy
accuracy(X_test, parameters_tanh, y_test, activation_fn="tanh")The cost after 100 iterations is: 0.6556 
The cost after 200 iterations is: 0.6468
The cost after 300 iterations is: 0.6447
The cost after 400 iterations is: 0.6441
The cost after 500 iterations is: 0.6440
The cost after 600 iterations is: 0.6440
The cost after 700 iterations is: 0.6440
The cost after 800 iterations is: 0.6439
The cost after 900 iterations is: 0.6439
The cost after 1000 iterations is: 0.6439
The cost after 1100 iterations is: 0.6439
The cost after 1200 iterations is: 0.6439
The cost after 1300 iterations is: 0.6438
The cost after 1400 iterations is: 0.6438
The cost after 1500 iterations is: 0.6437
The cost after 1600 iterations is: 0.6434
The cost after 1700 iterations is: 0.6429
The cost after 1800 iterations is: 0.6413
The cost after 1900 iterations is: 0.6361
The cost after 2000 iterations is: 0.6124
The cost after 2100 iterations is: 0.5112
The cost after 2200 iterations is: 0.5288
The cost after 2300 iterations is: 0.4312
The cost after 2400 iterations is: 0.3821
The cost after 2500 iterations is: 0.3387
The cost after 2600 iterations is: 0.2349
The cost after 2700 iterations is: 0.2206
The cost after 2800 iterations is: 0.1927
The cost after 2900 iterations is: 0.4669
The cost after 3000 iterations is: 0.1040 'The accuracy rate is: 68.00%.'*

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

Figure 4: Loss curve with tanh activation function

*# NN with relu activation fn
parameters_relu = L_layer_model( X_train, y_train, layers_dims, learning_rate=0.03, num_iterations=3000, hidden_layers_activation_fn="relu")# Print the accuracy
accuracy(X_test, parameters_relu, y_test, activation_fn="relu")The cost after 100 iterations is: 0.6556
The cost after 200 iterations is: 0.6468
The cost after 300 iterations is: 0.6447
The cost after 400 iterations is: 0.6441
The cost after 500 iterations is: 0.6440
The cost after 600 iterations is: 0.6440 
The cost after 700 iterations is: 0.6440 
The cost after 800 iterations is: 0.6440 
The cost after 900 iterations is: 0.6440 
The cost after 1000 iterations is: 0.6440 
The cost after 1100 iterations is: 0.6439 
The cost after 1200 iterations is: 0.6439 
The cost after 1300 iterations is: 0.6439 
The cost after 1400 iterations is: 0.6439 
The cost after 1500 iterations is: 0.6439 
The cost after 1600 iterations is: 0.6439 
The cost after 1700 iterations is: 0.6438 
The cost after 1800 iterations is: 0.6437 
The cost after 1900 iterations is: 0.6435 
The cost after 2000 iterations is: 0.6432 
The cost after 2100 iterations is: 0.6423 
The cost after 2200 iterations is: 0.6395 
The cost after 2300 iterations is: 0.6259 
The cost after 2400 iterations is: 0.5408 
The cost after 2500 iterations is: 0.5262 
The cost after 2600 iterations is: 0.4727 
The cost after 2700 iterations is: 0.4386 
The cost after 2800 iterations is: 0.3493 
The cost after 2900 iterations is: 0.1877 
The cost after 3000 iterations is: 0.3641'The accuracy rate is: 42.00%.'*

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

Figure 5: Loss curve with ReLU activation function

请注意,上述准确率预计会高估概化准确率。

结论

这篇文章的目的是一步一步地编写深度神经网络,并解释其中的重要概念。我们现在并不关心准确率,因为我们可以做很多事情来提高准确率,这将是后续帖子的主题。以下是一些要点:

  • 即使神经网络可以表示任何函数,它也可能因为两个原因而无法学习:
  1. 优化算法可能无法找到期望(真实)函数的参数的最佳值。它会陷入局部最优。
  2. 由于过拟合,学习算法可能发现不同于预期函数的不同函数形式。
  • 即使神经网络很少收敛,总是陷入局部极小值,它仍然能够显著降低成本,并以高测试精度提出非常复杂的模型。
  • 我们在这篇文章中使用的神经网络是标准的全连接网络。然而,还有另外两种网络:
  1. 卷积神经网络:不是所有的节点都连接在一起。图像识别类最好。
  2. 递归神经网络:有一个反馈连接,模型的输出反馈到它自己。它主要用于序列建模。
  • 完全连接的神经网络也会忘记前面步骤中发生的事情,并且也不知道关于输出的任何事情。
  • 我们可以使用交叉验证来调整许多超参数,以获得最佳的网络性能:
  1. 学习率(α):决定每次参数更新的步长。

A.小α会导致收敛缓慢,并且可能会在计算上变得非常昂贵。

B.大的α可能会导致超调,我们的学习算法可能永远不会收敛。

2.隐藏的层数(深度):隐藏的层数越多越好,但是要付出计算的代价。

3.每层隐藏单元的数量(宽度):研究证明,每层大量的隐藏单元并不能改善网络。

4.激活函数:在不同的应用程序和领域中,在隐藏层上使用的函数是不同的。这是一个反复试验的过程,尝试不同的功能,看看哪一个效果最好。

5.迭代次数。

  • 标准化数据将有助于激活单元具有相似的值范围,并避免梯度失控。

原载于 2018 年 4 月 1 日imaddabbura . github . io*。*

编码神经网络—梯度检验

原文:https://towardsdatascience.com/coding-neural-network-gradient-checking-5222544ccc64?source=collection_archive---------4-----------------------

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

在之前的帖子编码神经网络——前向传播和反向传播中,我们在numpy中实现了前向传播和反向传播。然而,从头开始实现反向传播通常更能减少错误。因此,在对训练数据运行神经网络之前,有必要检查我们的反向传播实现是否正确。在我们开始之前,让我们重温一下什么是反向传播:我们从最后一个节点开始,以相反的拓扑顺序遍历节点,计算成本相对于每条边的节点尾部的导数。换句话说,我们计算成本函数相对于所有参数的导数,即∂J/∂θ,其中θ表示模型的参数。

测试我们实现的方法是计算数值梯度,并与反向传播(分析)的梯度进行比较。有两种计算数值梯度方法:

  • 右侧表格:

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

  • 双面形式(见图 1):

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

Figure 1: Two-sided numerical gradients

近似导数的双侧形式比右侧形式更接近。让我们用下面的例子来说明,使用函数 f(x) = x ,在对 x = 3 求导。

  • 分析导数:

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

  • 双侧数值导数;

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

  • 右手数值导数:

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

如上所述,解析导数和双边数值梯度之间的差异几乎为零;但是解析导数和右侧导数相差 0.01。因此,我们将使用双边ε方法来计算数值梯度。

此外,我们将标准化数值之间的差异。使用以下公式的梯度和分析梯度:如果差值≤ 10e-7,那么我们的实现是好的;否则,我们会在某处出错,不得不返回并重新访问反向传播代码。

以下是实施梯度检查所需的步骤:

  1. 在计算数值梯度和分析梯度时,从训练数据中选择随机数量的示例来使用它。
  • 不要使用训练数据中的所有示例,因为梯度检查非常慢。

2.初始化参数。

3.计算前向传播和交叉熵成本。

4.使用我们的反向传播实现来计算梯度。

5.使用双边ε方法计算数值梯度。

6.计算数值梯度和分析梯度之间的差异。

我们将使用我们在*“编码神经网络-前向传播和后向传播”*帖子中编写的函数来初始化参数,计算前向传播和后向传播以及交叉熵成本。

我们先导入数据。

# Loading packages
import sys
import h5py
import matplotlib.pyplot as plt
import numpy as np
from numpy.linalg import normimport seaborn as sns sys.path.append("../scripts/")
from coding_neural_network_from_scratch import (initialize_parameters, L_model_forward, L_model_backward, compute_cost)# Import the data
train_dataset = h5py.File("../data/train_catvnoncat.h5")
X_train = np.array(train_dataset["train_set_x"]).T
y_train = np.array(train_dataset["train_set_y"]).T
X_train = X_train.reshape(-1, 209)
y_train = y_train.reshape(-1, 209)X_train.shape, y_train.shape((12288, 209), (1, 209))

接下来,我们将编写帮助器函数,帮助将参数和梯度字典转换成向量,然后再将它们转换回字典。

def dictionary_to_vector(params_dict):
L = len(layers_dims)
parameters = {}
k = 0
for l in range(1, L):
# Create temp variable to store dimension used on each layer
w_dim = layers_dims[l] * layers_dims[l - 1]
b_dim = layers_dims[l]
# Create temp var to be used in slicing parameters vector
temp_dim = k + w_dim
# add parameters to the dictionary
parameters["W" + str(l)] = vector[ k:temp_dim].reshape(layers_dims[l], layers_dims[l - 1]) 
parameters["b" + str(l)] = vector[ temp_dim:temp_dim + b_dim].reshape(b_dim, 1)
k += w_dim + b_dim
return parametersdef gradients_to_vector(gradients):
# Get the number of indices for the gradients to iterate over valid_grads = [key for key in gradients.keys() if not key.startswith("dA")]
L = len(valid_grads)// 2
count = 0
# Iterate over all gradients and append them to new_grads list
for l in range(1, L + 1):
if count == 0:
new_grads = gradients["dW" + str(l)].reshape(-1, 1)
new_grads = np.concatenate((new_grads, gradients["db" + str(l)].reshape(-1, 1)))
else:
new_grads = np.concatenate((new_grads, gradients["dW" + str(l)].reshape(-1, 1)))
new_grads = np.concatenate( (new_grads, gradients["db" + str(l)].reshape(-1, 1)))
count += 1
return new_grads

最后,我们将编写梯度检查函数,它将计算解析梯度和数值梯度之间的差异,并告诉我们反向传播的实现是否正确。我们将随机选择一个例子来计算差异。

def forward_prop_cost(X, parameters, Y, hidden_layers_activation_fn="tanh"):
# Compute forward prop
AL, _ = L_model_forward(X, parameters, hidden_layers_activation_fn) # Compute cost
cost = compute_cost(AL, Y)
return cost def gradient_check( parameters, gradients, X, Y, layers_dims, epsilon=1e-7, hidden_layers_activation_fn="tanh"):
# Roll out parameters and gradients dictionaries
parameters_vector = dictionary_to_vector(parameters) gradients_vector = gradients_to_vector(gradients)
# Create vector of zeros to be used with epsilon
grads_approx = np.zeros_like(parameters_vector)
for i in range(len(parameters_vector)):
# Compute cost of theta + epsilon
theta_plus = np.copy(parameters_vector)
theta_plus[i] = theta_plus[i] + epsilon
j_plus = forward_prop_cost( X, vector_to_dictionary(theta_plus, layers_dims), Y, hidden_layers_activation_fn)
# Compute cost of theta - epsilon
theta_minus = np.copy(parameters_vector)
theta_minus[i] = theta_minus[i] - epsilon
j_minus = forward_prop_cost( X, vector_to_dictionary(theta_minus, layers_dims), Y, hidden_layers_activation_fn)
# Compute numerical gradients
grads_approx[i] = (j_plus - j_minus) / (2 * epsilon)# Compute the difference of numerical and analytical gradients numerator = norm(gradients_vector - grads_approx)
denominator = norm(grads_approx) + norm(gradients_vector)
difference = numerator / denominatorif difference > 10e-7:
print ("\033[31mThere is a mistake in back-propagation " +\ "implementation. The difference is: {}".format(difference))
else:
print ("\033[32mThere implementation of back-propagation is fine! "+\ "The difference is: {}".format(difference))return difference# Set up neural network architecture
layers_dims = [X_train.shape[0], 5, 5, 1]# Initialize parameters parameters = initialize_parameters(layers_dims)# Randomly selecting 1 example from training data
perms = np.random.permutation(X_train.shape[1])
index = perms[:1]# Compute forward propagation
AL, caches = L_model_forward(X_train[:, index], parameters, "tanh") # Compute analytical gradients
gradients = L_model_backward(AL, y_train[:, index], caches, "tanh") # Compute difference of numerical and analytical gradients difference = gradient_check(parameters, gradients, X_train[:, index], y_train[:, index], layers_dims)There implementation of back-propagation is fine! The difference is: 3.0220555297630148e-09

恭喜你!我们的实现是正确的:)

结论

以下是一些关键要点:

  1. 双侧数值梯度比右侧形式更接近解析梯度。

2.因为梯度检查非常慢:

  • 将它应用到一个或几个训练例子中。
  • 在确定反向传播的实现是正确的之后,在训练神经网络时关闭它。

3.应用退出方法时,梯度检查不起作用。使用 keep-prob = 1 检查梯度检查,然后在训练神经网络时更改它。

4.ε= 10e-7 是用于分析梯度和数值梯度之差的常用值。如果差值小于 10e-7,则反向传播的实现是正确的。

5.感谢 Tensorflow 和 Pytorch 等深度学习框架,我们可能会发现自己很少实现反向传播,因为这样的框架为我们计算;然而,要成为一名优秀的深度学习实践者,了解幕后发生的事情是一个很好的实践。

创建这篇文章的源代码可以在[这里](http://(https://github.com/ImadDabbura/blog-posts/blob/master/notebooks/Coding-Neural-Network-Gradient-Checking.ipynb)找到。

原载于 2018 年 4 月 8 日imaddabbura . github . io

编码神经网络——参数初始化

原文:https://towardsdatascience.com/coding-neural-network-parameters-initialization-f7c2d770e874?source=collection_archive---------4-----------------------

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

在机器学习/深度学习的背景下,优化是改变模型参数以提高其性能的过程。换句话说,它是在预定义的假设空间中寻找最佳参数以获得最佳性能的过程。有三种优化算法:

  • 非迭代优化算法,仅求解一个点。
  • 本质上是迭代的优化算法,并且收敛到可接受的解决方案,而不管参数初始化,例如应用于逻辑回归的梯度下降。
  • 本质上是迭代的优化算法,应用于一组具有非凸损失函数的问题,如神经网络。因此,参数的初始化对于加快收敛速度和降低错误率起着至关重要的作用。

在这篇文章中,我们将看看参数初始化的三种不同情况,看看这是如何影响错误率的:

  1. 将所有参数初始化为零。
  2. 将参数初始化为标准正态分布或均匀分布的随机值,并乘以一个标量,如 10。
  3. 基于以下内容初始化参数:
  • 泽维尔推荐。
  • 何推荐。

我们将使用我们在 “编码神经网络-正向传播和反向传播” 帖子中编写的函数来初始化参数,计算正向传播和反向传播以及交叉熵成本。

为了说明上述情况,我们将使用猫和狗的数据集,该数据集由 50 幅猫的图像和 50 幅狗的图像组成。每幅图像的 RGB 色标为 150 像素 x 150 像素。因此,我们将拥有 67,500 个特征,其中输入矩阵中的每一列都是一幅图像,这意味着我们的输入数据将具有 67,500 x 100 的维度。

在启动辅助函数之前,让我们先加载数据并展示两幅图像的样本。

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

Figure 1: Sample images

我们现在将编写所有帮助函数,帮助我们基于不同的方法初始化参数,并编写 L 层模型,用于训练我们的神经网络。

将所有参数初始化为零

在这里,我们将初始化所有的权重矩阵和偏差为零,看看这将如何影响错误率以及学习参数。

# train NN with zeros initialization parameters
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="zeros") accuracy(X, parameters, Y,"tanh")The cost after 100 iterations is: 0.6931471805599453
The cost after 200 iterations is: 0.6931471805599453
The cost after 300 iterations is: 0.6931471805599453
The cost after 400 iterations is: 0.6931471805599453
The cost after 500 iterations is: 0.6931471805599453
The cost after 600 iterations is: 0.6931471805599453
The cost after 700 iterations is: 0.6931471805599453
The cost after 800 iterations is: 0.6931471805599453
The cost after 900 iterations is: 0.6931471805599453
The cost after 1000 iterations is: 0.6931471805599453 The accuracy rate is: 50.00%.

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

Figure 2: Cost curve using zero intialization method

如成本曲线所示,神经网络什么都没学到!这是因为所有神经元之间的对称性导致所有神经元在每次迭代中都具有相同的更新。因此,不管我们运行优化算法多少次迭代,所有的神经元仍然会得到相同的更新,并且不会发生学习。因此,在初始化参数时,我们必须打破对称性,以便模型在梯度下降的每次更新时开始学习。

用大随机值初始化参数

如果从标准正态分布或均匀分布初始化随机值,没有很大的区别,所以我们将在我们的例子中使用标准正态分布。此外,我们将随机值乘以一个大的数,比如 10,以表明将参数初始化为大值可能会导致我们的优化具有更高的错误率(在某些情况下甚至会发散)。现在让我们训练我们的神经网络,其中所有的权重矩阵已经使用下面的公式初始化:np.random.randn() * 10

# train NN with random initialization parameters
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="random") accuracy(X, parameters, Y,"tanh")The cost after 100 iterations is: 1.2413142077549013
The cost after 200 iterations is: 1.1258751902393416
The cost after 300 iterations is: 1.0989052435267657
The cost after 400 iterations is: 1.0840966471282327
The cost after 500 iterations is: 1.0706953292105978
The cost after 600 iterations is: 1.0574847320236294
The cost after 700 iterations is: 1.0443168708889223
The cost after 800 iterations is: 1.031157857251139
The cost after 900 iterations is: 1.0179838815204902
The cost after 1000 iterations is: 1.004767088515343 The accuracy rate is: 55.00%.

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

Figure 3: Cost curve using random initialization method

这里的随机初始化是有帮助的,但是损失函数仍然具有很高的值,并且可能需要很长时间来收敛并达到非常低的值。

基于 He 和 Xavier 的建议初始化参数

我们将探讨两种初始化方法:

  • 当应用于隐藏层的激活函数是校正线性单元(ReLU)时,明凯 He 方法是最好的应用。因此每个隐藏层上的权重将具有以下方差:var(W^l )= 2/n^(l-1).我们可以通过将标准正态分布的随机值乘以

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

  • 当应用于隐藏层的激活函数是双曲正切时,最好应用 Xavier 方法,使得每个隐藏层上的权重具有以下方差:var(W^l )= 1/n^(l-1).我们可以通过将标准正态分布的随机值乘以

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

我们将使用这两种方法训练网络,并观察结果。

# train NN where all parameters were initialized based on He recommendation
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="he") accuracy(X, parameters, Y,"tanh")The cost after 100 iterations is: 0.6300611704834093
The cost after 200 iterations is: 0.49092836452522753
The cost after 300 iterations is: 0.46579423512433943
The cost after 400 iterations is: 0.6516254192289226
The cost after 500 iterations is: 0.32487779301799485
The cost after 600 iterations is: 0.4631461605716059
The cost after 700 iterations is: 0.8050310690163623
The cost after 800 iterations is: 0.31739195517372376
The cost after 900 iterations is: 0.3094592175030812
The cost after 1000 iterations is: 0.19934509244449203The accuracy rate is: 99.00%.

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

Figure 4: Cost curve using He initialization method

# train NN where all parameters were initialized based on Xavier recommendation
layers_dims = [X.shape[0], 5, 5, 1]
parameters = model(X, Y, layers_dims, hidden_layers_activation_fn="tanh", initialization_method="xavier") accuracy(X, parameters, Y,"tanh")accuracy(X, parameters, Y, "tanh")The cost after 100 iterations is: 0.6351961521800779
The cost after 200 iterations is: 0.548973489787121
The cost after 300 iterations is: 0.47982386652748565
The cost after 400 iterations is: 0.32811768889968684
The cost after 500 iterations is: 0.2793453045790634
The cost after 600 iterations is: 0.3258507563809604
The cost after 700 iterations is: 0.2873032724176074
The cost after 800 iterations is: 0.0924974839405706
The cost after 900 iterations is: 0.07418011931058155
The cost after 1000 iterations is: 0.06204402572328295The accuracy rate is: 99.00%.

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

Figure 5: Cost curve using Xavier initialization method

应用这四种方法的结果表明,参数的初始值在实现低成本值以及收敛和获得较低的训练错误率方面起着巨大的作用。如果我们有测试数据,这同样适用于测试错误率。

结论

深度学习框架可以更容易地在不同的初始化方法之间进行选择,而不用担心我们自己实现它。尽管如此,理解参数初始值在网络整体性能中的关键作用还是很重要的。以下是一些关键要点:

  • 精心选择的参数初始化值导致:
  1. 加速梯度下降的收敛。
  2. 增加梯度下降的可能性,以找到更低的训练和泛化错误率。
  • 因为我们处理的是非凸损失函数的迭代优化算法,不同的初始化会导致不同的结果。
  • 随机初始化用于打破对称性,确保不同的隐藏单元可以学习不同的东西。
  • 不要初始化太大的值。
  • 明凯 He (He)初始化适用于具有 ReLU 激活函数的神经网络。
  • Xavier 初始化适用于具有双曲正切激活函数的神经网络。

创建这篇文章的源代码可以在这里找到。

原载于 2018 年 4 月 20 日imaddabbura . github . io

编码神经网络—正则化

原文:https://towardsdatascience.com/coding-neural-network-regularization-43d26655982d?source=collection_archive---------3-----------------------

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

Source

偏差-方差权衡

泛化(测试)误差是机器/深度学习中最重要的度量。它为我们提供了对未知数据的模型性能的估计。测试误差被分解为 3 个部分(见图 1): 方差、平方偏差和不可约误差

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

Figure 1: Bias and variance as a function of model complexity (flexibility). Source

具有高偏差的模型对于数据来说不够复杂(太简单),并且往往不适合。最简单的模型是取目标变量的平均值(模式)并将其分配给所有预测。相反,具有高方差的模型通过紧密跟随(模仿)训练数据来过度拟合训练数据,其中学习算法将跟随信号和噪声。请注意,随着模型的复杂性(灵活性)增加,⟹模型将变得更难解释,如神经网络。下面是偏差-方差分解:

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

其中:

  • var(ε):由每个例子中省略的特征和不可测量的变化引起的不可约误差。
  • 偏差( ):用简单模型近似现实生活中的问题而引入的误差。
  • var( ):如果我们使用不同的数据集进行估算, 将发生变化的量。

因此,我们只能控制的方差和偏差,而不能控制不可约误差。因此,我们的工作是尝试估计正确的复杂度水平,以实现最低的测试误差。

正规化

正则化通过使学习算法对训练数据和过程不太敏感来增加学习算法的稳定性。由于我们不知道也无法访问可用于比较估计函数的真实函数,因此最佳策略是构建一个非常复杂的模型,该模型非常适合训练数据(过度拟合),并对其进行调整,使其具有良好的泛化(测试)误差。当使用正则化时,我们试图减少泛化误差,这可能会导致过程中训练误差的增加,这是可以的,因为我们关心的是模型泛化的程度。通过正则化,我们试图通过增加偏差和减少方差,将过度拟合的非常复杂的模型恢复为良好的模型。这建立在复杂模型具有大参数而简单模型具有小参数的假设上。

以下是用于正则化的一些方法:

  1. L2 参数正则化:又称权重衰减。该方法在目标函数中加入 L2 范数罚函数,使权值向原点移动。即使该方法将所有权重以相同的比例向零收缩;然而,它永远不会使任何权重恰好为零。
  2. L1 参数正则化(Lasso) :可以看作是一种特征选择方法,因为;与 L2 正则化相反,一些权重实际上为零。它通过在目标函数中加入 L1 范数惩罚,将所有权重缩小相同的量。
  3. 辍学:辍学可以被视为一种近似套袋技术。在每次迭代中,我们随机关闭每层上的一些神经元,并且在前向传播和反向传播中都不使用这些神经元。这将迫使神经网络分散权重,而不是专注于特定的神经元,因为它永远不会知道哪些神经元会在每次迭代中出现。因此,它可以被视为在每次迭代中训练不同的模型。此外,由于我们在每次迭代中丢弃了一些神经元,这将导致更小的网络,这反过来意味着更简单的网络。
  4. 增强:通过使用训练样本添加虚假数据,并在图像识别的情况下对其添加扭曲,如重新缩放和旋转图像。这里的想法是,最好根据更多的数据来训练模型,以获得更好的性能。请注意,扩充示例不会像独立示例那样为模型添加太多信息,但当收集更多数据不可行时,它仍然是一种有效的替代方法。
  5. 提前停止:该方法试图优化代价函数并使其正则化,从而使其具有更低的泛化误差。它的工作方式是,在每次迭代中,我们记录验证错误。如果验证误差有所改善,我们将存储参数的副本,并将继续下去,直到优化算法终止。如果计算时间和资源对我们来说是个问题,这是个好方法。

在这篇文章中,我们将讨论 L2 参数正则化。

L2 参数正则化

我们通常不正则化偏差,只正则化权重。我们可以使用 hessian 矩阵及其特征值和特征向量来查看权重对权重衰减的敏感度。权重 wi 将使用(λi/λi + α) 进行重新调整,其中λi(特征值)测量 hessian 矩阵在该方向(特征向量)上的灵敏度,而 α 是正则化超参数。因此,

  • 如果λi ≫ α ,则成本函数在该方向上非常敏感,并且相应的权重显著降低了成本,⟹不会衰减(收缩)太多。
  • 如果λi≪ α ,则成本函数在该方向不敏感,并且相应的权重不会显著降低成本,⟹向零衰减(收缩)。

目标函数(二进制交叉熵)将从:

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

收件人:

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

此外,新的梯度和更新方程将是:

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

注意,这里 α 是学习率,λ是正则化超参数。随着λ增加,偏差增加(模型变得不太灵活),出现以下极端情况(见图 2):

  • λ = 0,无正则化。
  • λ → ∞时,模型变得非常简单,所有权重基本为零。在回归的情况下,我们最终得到的截距只等于目标变量的平均值。

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

Figure 2: Model complexity (underfitting/overfitting) as a function of regularization parameter λ

有时,使用法线方程来了解 L2 参数正则化是如何工作的可能会有所帮助。正常方程是:

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

这意味着:

  • 将λ加到方差上会降低权重,因为

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

  • 即使 X^TX 不可逆,给每个特征加λ也会使其满秩矩阵⟹可逆。

为了说明正则化如何帮助我们减少概化错误,我们将使用 cats_vs_dogs 数据集。该数据集包含猫和狗的图像。我们将尝试建立一个神经网络来分类图像中是否有猫或狗。每幅图像的 RGB 比例为 64 x 64 像素。

我们将使用我们在 “编码神经网络-前向传播和反向传播” 帖子中编写的函数来初始化参数,计算前向传播、交叉熵成本、梯度等。

让我们导入数据,看看形状以及来自训练集的猫图像样本。

Training data dimensions:
X's dimension: (12288, 209), Y's dimension: (1, 209)
Test data dimensions:
X's dimension: (12288, 50), Y's dimension: (1, 50)

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

Figure 3: Sample image

训练集有 209 个示例,测试集有 50 个示例。让我们首先编写所有能帮助我们编写多层神经网络的辅助函数。

现在我们准备训练神经网络。我们将首先建立一个没有正则化的神经网络,然后建立一个正则化的神经网络,以查看哪一个具有更低的泛化误差。请注意,应该调整λ以获得最佳结果,但是我们将在这里选择一个任意值来说明这个概念。两个神经网络都有 2 个隐藏层,每个隐藏层有 5 个单元。

# set up layers dimensions
layers_dims = [X_train.shape[0], 5, 5, 1]# train NN
parameters = model_with_regularization(X_train, Y_train, layers_dims, learning_rate=0.03, num_epochs=2500, print_cost=True, hidden_layers_activation_fn="tanh", lambd=0)print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "tanh")[-7:]))print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "tanh")[-7:]))The cost after 100 iterations: 0.6555634398145331
The cost after 200 iterations: 0.6467746423961933
The cost after 300 iterations: 0.6446638811282552
The cost after 400 iterations: 0.6441400737542232
The cost after 500 iterations: 0.6440063101787575
The cost after 600 iterations: 0.6439697872317176
The cost after 700 iterations: 0.6439570623358253
The cost after 800 iterations: 0.6439491872993496
The cost after 900 iterations: 0.6439407592837082
The cost after 1000 iterations: 0.6439294591543208
The cost after 1100 iterations: 0.6439131091764411
The cost after 1200 iterations: 0.6438883396380859
The cost after 1300 iterations: 0.6438489715870495
The cost after 1400 iterations: 0.6437825798034876
The cost after 1500 iterations: 0.6436617691190204
The cost after 1600 iterations: 0.6434191397054715
The cost after 1700 iterations: 0.642864008138056
The cost after 1800 iterations: 0.6413476000796884
The cost after 1900 iterations: 0.6360827945885947
The cost after 2000 iterations: 0.6124050450908987
The cost after 2100 iterations: 0.511236045905345
The cost after 2200 iterations: 0.5287658028657057
The cost after 2300 iterations: 0.43124104856359174
The cost after 2400 iterations: 0.38213869447364884
The cost after 2500 iterations: 0.3386708692392079The training accuracy rate: 82.30%.
The test accuracy rate: 78.00%.

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

Figure 4: Cost curve with no regularization

训练准确率为 82.30%,测试准确率为 78%。训练和测试精度之间的差别并不大,也就是说,我们没有太多的过度拟合。所以稍微正则化一点可能会有帮助比如λ= 0.02。从业者推荐的λs 值有:0.02,0.04,0.08,0.16,0.32,0.64,1.28,2.56,5.12,10.24。

# train NN with regularization
parameters = model_with_regularization(X_train, Y_train, layers_dims, learning_rate=0.03, num_epochs=2500, print_cost=True, hidden_layers_activation_fn="tanh", lambd=0.02)

print("The training accuracy rate: {}".format(accuracy(X_train, parameters, Y_train, "tanh")[-7:]))print("The test accuracy rate: {}".format(accuracy(X_test, parameters, Y_test, "tanh")[-7:]))The cost after 100 iterations: 0.6558634554205135
The cost after 200 iterations: 0.6470807090618383
The cost after 300 iterations: 0.6449737235917311
The cost after 400 iterations: 0.6444519406797673
The cost after 500 iterations: 0.6443191828114609
The cost after 600 iterations: 0.6442831256251426
The cost after 700 iterations: 0.6442705985766486
The cost after 800 iterations: 0.6442628048800636
The cost after 900 iterations: 0.6442544325786784
The cost after 1000 iterations: 0.6442432311807257
The cost after 1100 iterations: 0.6442270988055475
The cost after 1200 iterations: 0.6442027847231018
The cost after 1300 iterations: 0.6441643410411311
The cost after 1400 iterations: 0.6440998547029029
The cost after 1500 iterations: 0.6439832000181198
The cost after 1600 iterations: 0.6437505375793907
The cost after 1700 iterations: 0.6432228625403317
The cost after 1800 iterations: 0.6417982979158361
The cost after 1900 iterations: 0.6369273437378263
The cost after 2000 iterations: 0.6152774362019153
The cost after 2100 iterations: 0.5207828651496548
The cost after 2200 iterations: 0.5145012356446598
The cost after 2300 iterations: 0.40757220705507585
The cost after 2400 iterations: 0.517757346098386
The cost after 2500 iterations: 0.4574831239241244 The training accuracy rate: 65.55%.
The test accuracy rate: 80.00%.

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

Figure 5: Cost curve with regularization

如以上结果所示,我们通过将测试精度从 78%提高到 80%来改善泛化误差。另一方面,训练准确率从 82.30%下降到 65.55%。

结论

正则化是解决过拟合的有效技术。由于我们不知道数据的真实分布,基于经验分布的经验风险容易过度拟合。因此,最佳策略是很好地拟合训练数据,然后使用正则化技术,以便模型能够很好地推广。L2 参数正则化和丢失是机器学习中最广泛使用的两种正则化技术。

  • 诸如 L2 和 L1 参数正则化的正则化技术的隐含假设之一是参数的值应该为零,并且试图将所有参数收缩为零。这意味着避免很好地遵循训练数据,这使得学习算法挑选一些在应用于看不见的数据时没有帮助的噪声。
  • λ的值应该被调整以获得最佳的泛化误差。当比较具有λs 值的模型时,我们通常使用验证集,并选择具有最低验证误差的模型。
  • 如果模型遭受过拟合,即训练误差≪validation 误差,则仅使用正则化。
  • 如果使用正则化后验证误差仍然很高,那么我们很可能处于欠拟合区域。换句话说,我们的模型仍然过于简单,已经有很高的偏差。因此,增加模型的复杂性,然后使用正则化。
  • 由于我们试图解决的大多数任务没有足够的数据(或者收集更多数据的成本很高),鉴于神经网络的复杂性,过度拟合将比欠拟合在深度学习中更普遍。

创建这篇文章的源代码可以在这里找到。帖子的灵感来自 deeplearning.ai 课程。

原载于 2018 年 5 月 8 日imaddabbura . github . io

从头开始编写神经网络分类器

原文:https://towardsdatascience.com/coding-up-a-neural-network-classifier-from-scratch-977d235d8a24?source=collection_archive---------0-----------------------

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

A single-layer fully-connected neural network used for classification

TensorFlow、Keras 和 Pytorch 等高级深度学习库通过隐藏神经网络的许多繁琐的内部工作细节,在使深度学习从业者的生活变得更容易方面做了出色的工作。尽管这对深度学习很有好处,但它也有一个小缺点,那就是让许多基础知识不足的新手去别处学习。我们在这里的目标是简单地提供一个从零开始编写的 1 隐藏层全连接神经网络分类器 (没有深度学习库),以帮助消除您可能对神经网络的神秘黑盒感觉。该项目的 Github repo 位于:

【https://github.com/ankonzoid/NN-scratch】T5T6

所提供的神经网络对描述属于三类小麦的谷粒的几何属性的数据集进行分类(您可以很容易地用您自己的定制数据集替换它)。假设 L2 损失函数,并且在隐藏层和输出层中的每个节点上使用 sigmoid 传递函数。权重更新方法使用德尔塔规则,该规则是具有 L2 范数的梯度下降。

在本文的剩余部分,我们将概述我们的代码构建和训练用于类预测的神经网络的一般步骤。更多我关于深度学习和强化学习的博客、教程、项目,请查看我的Medium和我的 Github

我们从零开始构建单层神经网络分类器的步骤

1.设置多重交叉验证

对于我们的 N 重交叉验证,我们随机排列所有 N 个示例索引,然后将大小为~N/n 的连续块作为我们的折叠。每个折叠充当许多交叉验证实验之一的测试集,而补体指数充当训练集。

2.建立和训练神经网络模型

我们有两个完全连接的权重层:一个连接输入层节点和隐藏层节点,另一个连接隐藏层节点和输出层节点。如果没有任何偏差项,这应该总计为网络中的(n _ input * n _ hidden+n _ hidden * n _ output)个权重。我们通过对正态分布进行采样来初始化每个权重。

每个节点(神经元)有 3 个属性存储在内存中:一个将自身连接到其输入节点的权重列表,一个通过前向传递一些输入计算的输出值,以及一个代表其在输出层的后向传播分类不匹配误差的增量值。这三个属性相互交织,并通过以下三个过程循环进行更新:

(A)向前传递训练示例,以在给定当前节点权重的情况下更新节点输出**。每个节点输出计算为其前一层输入(无偏置项)的加权和,后跟一个 sigmoid 传递函数。**

(B)在给定当前节点权重的情况下,反向传递分类错误以更新节点增量**。为了更多地了解这些德尔塔,我们建议阅读https://en.wikipedia.org/wiki/Delta_rule,因为我们使用的德尔塔规则方程是从对 L2 损失函数应用梯度下降得到的。**

©我们使用更新的节点输出增量来执行前向传递以更新当前的权重**。**

对于每个训练时期,对每个训练实例执行(A ) → ( B ) → ( C)的训练循环过程。

3.进行班级预测

经过训练后,我们可以简单地使用该模型,通过将文本示例向前传递到训练好的神经网络中,获得输出的 argmax,来对我们的测试示例进行分类预测。准确度分数是网络正确分类的实例数除以实例总数的直观分数(在来自 n 重交叉验证的训练和测试集中)。

咖啡,伟大的连接器!

原文:https://towardsdatascience.com/coffee-the-great-connector-69b4eaf99b58?source=collection_archive---------21-----------------------

使用 Python 和图论分析面包店的交易数据

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

Image from pexels.com

面包店有一种魔力。咖啡和面包的味道,温暖,色彩,数据!人们来来去去,再回来买咖啡、面包、糕点等各种组合。我们能否利用这些交易数据来发现模式,并深入了解哪些项目在我们的烘焙食谱中更为重要?

我使用了一个面包店的交易数据集和一些图论来可视化经常一起购买的物品,看看我是否能提取出任何见解。

数据集

我使用了一个名为“面包店交易”的数据集的数据,出于我不知道的原因,这个数据集在 Kaggle 中不再可用。数据集包含了从 2016 年 10 月 30 日到 2017 年 4 月 9 日这段时间内苏格兰一家面包店的每笔交易的数据。总共有 94 个不同项目的 9,531 个交易。

图论方法

每个交易可以包括多个项目。我的方法是基于数据集中的所有交易创建一个数学图。如果事务包括面包和咖啡,我在面包节点和咖啡节点之间添加了一个连接(即边)。如果面包和咖啡同时出现在不止一个交易中,我会为每个交易增加一个面包-咖啡边缘的权重。如果一个事务包含 3 个项目,那么我为每个(无序的)项目对添加一条边。

在上述过程的最后,我得到了一个无向加权图,其中的节点代表了数据集中观察到的所有唯一项目。节点 x 和节点 y 之间的边表示项目 xy 在同一事务中出现的次数。请注意,该图还包括在交易中单独出现的项目的自身边。最后,直觉上,两个节点之间的边的权重越高,这两个项目就越“接近”。我也通过为每条边分配一个距离来捕捉它,这个距离是边的权重的倒数。因此,两个项目一起出现的事务越多,该边的权重就越大,这两个节点之间的距离就越小。

因此,如果面包和咖啡一起出现在 10 个交易中,面包-咖啡边的权重将是 10,其距离将是 0.1。

利用图论中的一些基本概念,我的目标是发现在图结构中处于中心位置的商品,希望中心位置能告诉我们一些关于顾客如何购买这些商品的有意义的信息。

代码

我使用了 python 包 networkx ,这是我在用 python 创建和分析图形时最喜欢的选择。你可以在这里找到包含所有代码的 jupyter 笔记本。

结果

就像我上面提到的,我检查了每一笔交易,并为交易中出现的每一对商品添加了一条无向边。只有一个项目的事务在图中为该项目添加了一个自边。得到的图有 94 个节点(等于数据集中出现的唯一项目的数量)和 1104 条加权边(包括自边)。这里有一些有趣的花絮。

  1. **图形连接。**如果您忽略交易中出现的几个“项目”,如“调整”,但显然不是实际项目,则生成的图表是连接的。
  2. 咖啡和面包可以搭配任何食物。 在计算唯一邻居时,Coffee 有 79 个唯一邻居,这意味着它至少出现在一个交易中,数据集中有 94 个唯一条目中的 79 个。如果不算咖啡的话,93 分之 78。面包以 75 度紧随其后。茶、蛋糕和果汁的度数分别为 68、64 和 58。
  3. 但是咖啡什么都配它的加权度为 7,285,而面包的加权度为 4,722。茶和蛋糕仍然排在第三和第四位(分别是 2572 和 1997),但现在我们的糕点排在前五位,果汁勉强进入前十。
  4. 果汁有更多的朋友,但糕点是更好的朋友,因为它的种类更少。 从上面的第 2 点和第 3 点我们可以看出,尽管糕点在交易中伴随着较少的项目(糕点在图中具有更少的唯一邻居),但是糕点具有更高的加权度。这意味着糕点可以搭配很少的食物,但是可以很好的搭配这些食物。
  5. 咖啡的介数中心性最高。 手中有了一个结构良好的图,我们就可以计算出各种节点的中心性度量。这里我只阐述中间中心性和**特征向量中心性的结果。**让我们从中间性开始(见下面的特征向量中心性)。中间中心性大致意味着一个节点在两个其他节点之间充当桥(或桥的一部分)的次数。对于图中的每两个节点,我计算了它们之间的 Dijkstra 最近路径,其中“最近”意味着最小化路径中边的距离之和的路径。这产生了一组 4,186 条路径(92 选择 2 种组合。我们只有 92 个项目,而不是 94 个,因为那是最大连接组件的大小)。然后我数了每一项在这些最接近的路径中出现了多少次。这个数字大致代表了每个节点的介数中心性。到目前为止,咖啡的中间中心度最高,出现在 3950 条路径中,而面包的中间中心度为 1012 条。茶,斯堪的纳维亚和艺术托盘分别以 529,190 和 182 的路径关闭了前 5 名。
  6. 咖啡具有最高的特征向量中心性。 也许图中最广泛使用的中心性概念是特征向量中心性。这个中心性粗略地指示了所有其他节点该节点在图中的中心程度。因此,这不仅是关于你在图中的中心位置,也是关于你的邻居 T21 的中心位置。这是谷歌最初的 PageRank 算法背后的主要思想。计算事务图的特征向量中心性向我们显示,Coffee 具有最高的中心性,但是与中间中心性相比,前 5 名更加接近。面包、茶、蛋糕和果汁是前五名中剩下的不到 0.2 个单位(这个指标从 0 到 1)。

这种图论方法还可以应用于哪些数据集,它能告诉我们什么?

你可以在这里 找到 jupyter 笔记本的所有代码和数据集

感谢阅读!

认知机器人:学习环境感知

原文:https://towardsdatascience.com/cognitive-robotics-learning-environment-perception-9f13ebfd89be?source=collection_archive---------3-----------------------

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

Image source: Autonomous Intelligent Systems Group, University of Bonn

为了让机器人成功地感知和理解它们的环境,必须教会它们以目标导向的方式行动。虽然绘制环境几何图形是许多移动机器人应用的必要先决条件,但理解环境的语义将使新的应用成为可能,这需要更高级的认知能力。

波恩 大学 自主智能系统组的负责人斯文·贝恩克,正在通过结合密集几何建模和语义分类来解决机器人学的这一领域。通过这个,环境的 3D 语义地图被建立。Sven 的团队已经展示了认知机器人在多个具有挑战性的应用领域中的语义环境感知的效用,包括家政服务、太空探索、搜索和救援以及捡垃圾箱。

在 6 月 28 日至 29 日在阿姆斯特丹 举行的 机器智能峰会上,Sven 将分享他和他的团队为学习任务开发的方法的专业知识,如表面分类、物体的检测、识别和姿态估计,以及将操作技能转移到新物体。为了了解更多信息,我在峰会前问了他几个问题。

你能告诉我们更多关于你的工作吗?

波恩大学的自主智能系统小组研究认知机器人和深度学习。我们为半结构化领域开发了多个机器人系统,如家政服务、搜索和救援、空中检查、太空探索、捡垃圾和踢足球。我们工作的主要重点是感知,即解释 3D 激光扫描仪和 RGB-D 相机等机器人传感器的测量结果,以获得适合规划机器人行动的环境模型。

我们还研究了机器人系统中运动和操纵以及学习的有效规划。我们将我们的开发集成到自主执行复杂任务的系统中。我们团队 NimbRo 的机器人在多个机器人比赛和挑战中表现出色,包括 DARPA 机器人挑战赛、RoboCup 足球和@Home、欧洲机器人挑战赛、亚马逊采摘挑战赛、DLR SpaceBot 杯和 MBZIRC。

您认为是什么主导因素推动了认知机器人技术的最新发展和普及?

传感方面的进步,如负担得起的 RGB-D 相机和小型 3D 激光扫描仪,以及计算方面的进步,如微型电脑和可编程图形处理器,构成了环境语义感知的基础。语义感知是通过收集大型注释数据集和执行例如图像分类、对象检测、姿态估计、语义分割等的深度学习方法来实现的。这些语义感知与高效的同步定位和地图创建方法(SLAM)相结合以获得 3D 语义地图。

另一个有利因素是更轻、更顺从的驱动,这允许人-机器人协作和身体接触。规划方面的进步,例如通过分层的、组合的方法,使得实时的自适应机器人动作的鲁棒生成成为可能。最后,更好的连接和云服务将认知机器人嵌入更大的基础设施。

认知机器人的哪些现在或未来潜在的应用最让你兴奋?

目前,高级驾驶辅助系统和自动驾驶汽车肯定是影响最大的认知机器人应用。使用协作机器人的灵活工业自动化正在获得动力。我最感兴趣的是认知服务机器人,它结合了半结构化环境中的鲁棒移动性、类似人类的操纵技能和直观的多模态人机交互。这种机器人可能会彻底改变餐馆和医疗保健等专业服务行业,但也可以在日常环境中提供帮助和做家务。

你觉得未来哪些行业会被认知机器人最大程度地颠覆?

所有人类重复劳动的行业都会受到影响。工业生产、农业、交通和物流领域的自动化程度将大幅提高。还有专业服务,如清洁、转售、餐馆、护理设施等。会越来越依赖认知机器人助手。一旦认知机器人变得负担得起,它们也将在我们的家中提供帮助。

在接下来的五年里,我们可以期待看到认知机器人技术的哪些发展?

我期待着功能的增加和成本的降低,这将使越来越多的应用领域成为可能,并创造一个认知机器人产业。

另一个令人兴奋的发展可能是人类和认知机器人系统之间更紧密的共生关系,这不仅是为了补偿身体或认知缺陷,也是为了提高生活质量和增强人类能力。

Sven Behnke 将在 6 月 28 日至 29 日在阿姆斯特丹举行的机器智能峰会上发表讲话,同时还将举行 自动驾驶汽车机器智能峰会 。会见领先的专家并向他们学习人工智能将如何影响交通、制造、医疗保健、零售等领域。现在门票有限,在这里注册参加。

其他确认的演讲者包括 Roland Vollgraf,研究负责人,Zalando Research;Neal Lathia,高级数据科学家,Skyscanner;科学主任 Alexandros Karatzoglou,télefonica;Ingo Waldmann,高级研究科学家,UCL;以及深度学习能力中心主任 Damian Borth, DFKI 。点击查看更多演讲者和话题。

机器智能峰会和自动驾驶汽车中的机器智能峰会也将于 11 月 9 日至 10 日在香港举行。

本次采访中表达的观点可能不代表 RE WORK 的观点。因此,有些观点甚至可能与 RE WORK 的观点相左,但发布这些观点是为了鼓励辩论和全面的知识共享,并允许不同的观点呈现给我们的社区。

口红推荐的协作嵌入

原文:https://towardsdatascience.com/collaborative-embeddings-for-lipstick-recommendations-98eccfa816bd?source=collection_archive---------8-----------------------

Sephora SEA 机器学习案例研究

对于一家电子商务公司来说,花时间和精力去了解客户行为,对客户和公司本身来说都是一种双赢的策略。

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

Embeddings: turning beauty products into vectors

例如,执行良好的产品策划是销量和多样性关键驱动力,也是客户参与品牌的关键驱动力。它还能让购物者花更少的时间浏览他们真正想要的东西。

在我的公司 Sephora SEA,我们利用客户生成的数据来更好地了解我们的业务,并为我们的客户创造愉快的购物体验。

在这个故事中,

  • 我演示了如何将来自自然语言处理 (NLP)的研究思想,更准确地说是来自手套论文【1】的研究思想,移植到项目到项目** 产品推荐系统中。**
  • 我展示了如何利用丝芙兰电子平台上的顾客浏览数据了解美容产品的 密集表示,也就是又名。嵌入。
  • 我用嵌入的可视化基础代数研究了通过算法学到了什么。
  • 我介绍了推荐系统离线评估的度量标准,并给出了不同方法的基准。

在行业中已经有相当多的嵌入式应用记录[4][5]。本案例研究旨在补充那些特别关注产品发现嵌入代数的案例。

这篇文章的布局是

  • 0 |单词嵌入入门
  • 1 |构建协同推荐系统
  • 2 |离线基准
  • 3 |产品发现的嵌入代数
  • 4 |视角

0 |单词嵌入入门

NLP 中的一个主要挑战在于文本数据的数学表示。

一个产生有趣结果的简单方法在于单词的一键编码:对于给定的词汇集***【V******| V |***,每个单词都用它在 V 中的位置来表示。

反过来,一个文档***【d】*由它的字 W 中的 V 中的位置来表示。结果是一个长度为“在 V 中的字数”的稀疏向量,除了在 W 的位置之外,所有系数都为零。

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

Example of one-hot encoding of a sentence. Semantic and syntactic similarities are omitted.

一键编码的问题是,它认为单词是完全离散的实体,完全由其拼写定义:它忽略了单词的语义和句法相似性

例如,在这个模型中,“狗”与“拉布拉多”的不同之处就像它与任何其他单词的不同之处一样,比如“滑板”。

提出密集(≠稀疏),低维(∼30 到 300)单词表示,具有语义和句法规则,在 2001 年首次成为感兴趣的领域[2],并在 2013 年开始广泛流行[3]。

这些表示被称为 嵌入

这个想法在于使用巨大的文本语料库来学习那些嵌入,目的是在相同上下文中经常出现的单词应该具有相似的向量

特别是,GloVe 算法[1]因其简单性和有效性而脱颖而出:它建议将问题视为矩阵分解问题。

要分解的矩阵是单词到单词共现矩阵:a |V|×|V| 矩阵,其中每个系数是两个单词在同一上下文中出现的次数。

“词汇和美容产品都是可以放入语境中的独立实体.”

注意:上下文的定义取决于用户。例如,可以使用 3 个单词的滑动窗口。

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

Context generation with 3-word-long sliding window

词语和美容产品都是可以放入语境中的独立实体。

对于电子商务中的美容产品,上下文可以由以下内容组成:

  • 结账篮
  • 意愿列表共现
  • 产品浏览会话上的滑动窗口
  • 和许多其他信号

听起来手套的原理可以用来衍生产品的密集表示。让我们看看如何做到这一点。

1 |建立协同推荐系统

在本案例研究中,我们的输入信号将完全来自客户浏览会话,其中产品上下文由滑动窗口生成。

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

How contexts can be derived from browsing sessions

从这个上下文生成方案中,我们可以导出一个产品共现矩阵 X

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

The co-occurrence matrix

该矩阵是输入数据的汇总,也是我们将使用的唯一信号。

直觉上,

  • 强相关产品应具有高共现编号
  • 强相关产品出现在相似语境中。它们与产品目录中的产品的共现特征应该相似。
  • 非常受欢迎的产品可能会与目录中的许多产品出现强烈的同现号。但这并不意味着它们与所有产品都相关。这相当于 NLP 中的 停用词

模型

GloVe 建议的是将 log(X) 分解为具有加性偏差的嵌入矩阵的点积。关于这个模型的细节和原因的更多信息,我强烈建议你参考最初的论文

在本案例研究中,我们选择考虑一个与要学习的参数密切相关的分解模型:

  • 嵌入矩阵 E ,大小为|VDD 是嵌入物的尺寸。注意,t39】dt41】≪|t43】vt45】|。
  • 偏置向量 b ,大小为| V |。我们稍后会看到,这是一种产品流行偏见,它有助于应对过度流行产品的影响。

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

The factorisation model

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

Representation as a (very) shallow neural network

相应的目标函数(损失最小化)为:

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

Objective function

参数***【E】***和 b 可以通过例如小批量随机梯度下降来学习:该算法将迭代地查看小批量的产品对,并相应地利用同现计数来优化它们相应的嵌入和偏差。

一旦嵌入被学习,向量相似性的一个普通度量余弦相似性

因此,它可以用于导出完全协作的项目到项目推荐系统。

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

Cosine similarity for embeddings

可视化

Tensorboard 投影仪这样的工具可以帮助可视化 2D 或 3D 投影中的嵌入。

这里有一些关于你如何自己使用它的提示

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

Tensorboard projector for 3D embeddings visualisation. Each point is a product. Its colour corresponds to its highest-level category.

另一个我个人喜欢的可视化是在色标上绘制嵌入系数值。以某种方式订购产品有助于展示有趣的图案。

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

On the top plot, the products are randomly ordered. On the bottom plot, they are ordered according to brand. The latter exhibits horizontal patterns and shows how brand information was implicitly learnt. Note that the bottom ruler indicates brand.

偏见 b 怎么样?这些对应什么?

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

当绘制学习偏见与产品受欢迎程度(在视图中)的关系时,有一个明显的相关性。手套策略允许将流行性从嵌入中抽象出来,这确实是一个很好的特性。

定性示例

一些单品对单品推荐示例:

更进一步:加入边信息

嵌入成功地学习了一些产品关联。特别是,推断出了产品元数据(品牌、类别、范围、属性、益处……)。如果该信息已经可用,则可以将其集成到学习逻辑中。

例如,在美容产品的情况下,我们可以查看产品的品牌及其类别

举个例子,

这些元数据的嵌入也可以被学习并用于丰富产品向量表示。

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

GloVe for product representation learning, with side-information. The mean layer following the category embedding layer is to manage multi-category products.

注意,每种元数据类型的影响都可以通过为它们各自的嵌入选择维度来监控(维度越高,影响越强)。

这种架构在非常稀疏的共生矩阵或冷启动 ( *ie)的情况下非常有用。*新引入)项,因为它弥补了缺乏与产品元数据的协作数据

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

Embeddings learnt with a GloVe-like strategy with side-information. Products are ordered by brand. The bottom ruler represents brand. The concatenated brand and category embeddings are clearly visible.

另一种方法[6]是将元数据实体视为产品本身:具有相同品牌的产品更接近于相同的品牌嵌入。优点是预测时的架构类似于没有边信息的网络。

2 |离线基准测试

为了评估推荐的性能,没有什么比现场测试更好的了,无论是通过 A/B 测试(见我的前一篇)还是强化学习。

尽管如此,你仍然可以通过分割你的训练集并尝试预测下一次购买/观看来验证你的算法。

虽然这些基准测试的准确性很重要,但一个经常被忽略的考虑因素是推荐项目的多样性。

关于长尾产品

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

Illustration of a long tail (from wikipedia). In our current context, X-axis: products ordered by descending popularity. Y-axis: popularity

在绝大多数零售公司中,受欢迎程度(例如以购买数量来衡量)远远不是同质的。

相对较少的产品会占据销售额的大部分。

其余产品不常购买,代表收入机会(长尾产品)。

可发现性的度量

应对这类产品的一种方法是通过推荐来确保它们的可发现性。因此,我们着眼于系统对每个产品的公平性。

为此,对于给定的推荐系统 R ,我们为每个产品 i 引入一个可发现性评分( dscore )。

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

This dscore measures how well product i is being represented in the other products’ recommendations. The rank function is the rank of product i in recommendations coming from j, under system R.

人们可以查看目录中所有产品的 dscore 的重新分配,按降序 dscore 排序。再一次,再分配很可能是尾巴形的,但是尾巴越重,所有产品的代表就越公平

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

Repartition of dscores for all products, ordered in descending dscore, given different recommender systems

评论

  • 天真的一起购买/观看推荐系统简单地包括,对于一个产品,查看在相同的收银台/观看环境中出现最多的产品。
  • 包含了一个随机推荐系统的基线曲线。毫无意外,它实现了最佳发现性能,代价是大部分不相关的推荐。它提醒我们不能只考虑这个评估指标。
  • 一起购买实现最差的发现性能,主要是因为在考虑篮子时,共生矩阵的稀疏性更大。在这种情况下,冷启动产品更有可能出现。
  • 一起看一起买获得更好的发现性能,这要归功于更密集的同现矩阵。但是,它受到产品流行偏见的限制。
  • GloVe 实现了更好的发现性能,这要归功于在学习算法中集成了流行度偏差(如上所示)。此外,注入产品元数据使冷启动产品更容易被发现。

在前面的定性例子中,你可能会认为推荐大多来自同一个品牌。

虽然按品牌购买美容产品并不罕见,但这些建议可能会让顾客保持循环,并影响其他品牌的发现。

让我们看看解决这个问题的方法。

3 |产品发现的嵌入代数

嵌入有一个令人惊讶的特性,基本代数(平均值、和、差)可以用它们来执行,同时使人类理解。

这是令人惊讶的,因为这种考虑没有出现在模型中。

让我们看几个美容产品的例子。

产品超群

从学习到的产品嵌入中,你实际上可以通过平均来自同一品牌的产品向量来导出品牌的嵌入。

品牌相似性和品牌映射可以从那里计算出来。

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

Brand embeddings visualised in Tensorboard Projector (2D t-SNE projection)

与品牌无关的表述

如果我们只对产品的功能和好处感兴趣,而对品牌不感兴趣,那会怎样?我们能想出品牌不可知的向量表示和品牌不可知的推荐器吗?

实现这一点的一个方法是,对于一个给定的产品,从它的嵌入中提取它的品牌向量表示。

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

3D projection of the original embeddings. Each colour corresponds to a product’s highest-level category.

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

3D projection of brand-agnostic embeddings. Notice how their were shifted to a more spherical catalogue projection.

让我们看一些定性的例子。

相同的产品,但来自另一个品牌

如果您已经熟悉了嵌入,那么您很可能在 NLP 中遇到过几乎太常用的例子

“国王”——“男人”+“女人”=“女王”

是的,嵌入可以用于某种类型的问题回答。在前面的例子中,什么是“女人”什么是“国王”什么是“男人”?→《女王》

以丝芙兰 SEA 为例,是否可以利用嵌入来推荐类似的产品,但在丝芙兰(丝芙兰系列)的品牌中?

即。

“Fenty Beauty Pro Filt ’ r Soft Matte Longwear 粉底”——“Fenty Beauty”+“丝芙兰系列”=?

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

In practice, it really outputs interpretable results!

和以前一样,一些定性的例子,

4 |候选人

我在这个案例研究中提出的框架实际上对许多情况非常适用。你所需要的就是为你要嵌入的对象导出同现上下文

最重要的是,上下文的定义可以像您希望的那样灵活。在这里,我只考虑了浏览会话,但也可以混合其他信号。

此外,我只展示了单品到单品的推荐,但是通过平均嵌入输入产品,来自客户过去购买或当前购物篮的推荐是完全可以实现的。

参考

[1] Pennington 等人,GloVe:Global Vectors for Word Representation,2014
【2】Bengio 等人,一种神经概率语言模型,2001
【3】miko lov 等人,Vector Space 中单词表示的高效估计,2013
【4】Mihajlo Grbovic列出搜索排名中的嵌入 (Airbnb 用 Uber Eats 发现食物:构建查询理解引擎,2018 年 6 月
【6】Vasile 等人, [Meta-Prod2Vec -产品嵌入使用边信息进行推荐](http://Product Embeddings Using Side-Information for Recommendation),2016

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值