TowardsDataScience 博客中文翻译 2019(二百九十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

面向 Noobs 的自然语言处理介绍

原文:https://towardsdatascience.com/introduction-to-natural-language-processing-for-noobs-8f47d0a27fcc?source=collection_archive---------14-----------------------

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

Photo by fabio on Unsplash

使用 Kaggle 竞争的 NLP 及其基本流水线概述

这篇文章是我试图给出一个可能对新手有帮助的基本概念的概述。为了更好地理解,我将关注一个完整的 Kaggle 竞赛 Quora 虚假问题分类。在这里,我们提供了 131 万个带标签的问题和 37.6 万个问题,我们必须预测这些问题的标签。这个竞赛是一个二元分类问题的例子。我已经包含了可以用来解决这个问题的 python 代码示例。代码使用了 Keras 库,非常容易理解。这场竞赛的基线解决方案是在 Kaggle 内核上。

所以先从基础开始吧。

介绍

NLP 是计算机科学的一个分支,它用自然语言处理人和机器之间的交互。它是语言学和计算机科学的交叉,因此它使机器能够理解并以自然语言回复人类的查询。自然语言处理的主要问题是人类语言是不明确的。人类非常聪明,能够理解上下文和单词的意思,但对计算机来说,这个问题完全是另一个层面,因为计算机既不理解概念也不理解上下文。为了让计算机理解概念,它们需要对世界、语言句法和语义有一个基本的理解。

文本表示

我们可以理解和阅读一段文本,但对计算机来说,每段文本都是一系列数字,不代表任何概念。一个简单的例子,字母“A”在英语中有特殊的含义,它被认为是所有字母表中的第一个字母。但是计算机认为它是 65(因为 65 是字母“A”的 ASCII 码)。ASCII 是基于英文字符的传统编码系统。这些字符的集合在 NLP 中通常被称为标记

一个标记是某个特定文本中的一个字符序列的实例,这些字符被组合在一起以在自然语言中产生某种意义。

在 NLP 管道中表示任何文本的最简单方法是通过一键编码的向量表示法。如果一个句子包含某个单词,那么向量中相应的条目表示为“1”,否则为“0”。例如,让我们考虑下面两句话:

  1. “自然语言处理是最好的领域”
  2. “我是自然语言处理的新手”

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

Table 1. One hot encoding of all words in sentence 1 and 2

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

Table 2. Collapsed One hot encoded vector for sentence 1 and 2

一种流行的编码是将分类变量表示为二进制向量。一种单词的热编码用于对文本进行编码,其中除了当前单词之外,每个单词都用零表示。如果我们有一千个唯一单词的语料库,那么每个单词表示将需要大小为 1000 的向量。尽管大小依赖于词汇,但即使在今天,一键编码表示仍在产品中使用。

表 1 显示了句子 1 和 2 中所有单词的一次性编码。表 2 所示的表示称为折叠或“二进制”表示。

现代 NLP 系统有一个单词字典,其中每个单词都有一个整数表示。所以那句“自然语言处理是最好的领域!”可以表示为“2 13 6 34 12 22 90”(忽略标点符号,将每个单词都视为小写)。这种表示在内存使用方面更有效,并且还保留了语言语义。

基本 NLP 流水线

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

Figure 1: Basic NLP pipeline

NLP 中有很多任务可以使用上面显示的管道。大多数 Kaggle 比赛都清理了数据,这在现实生活中不会发生,因为这些数据集是由比赛协调员收集和预处理的。在现实世界的场景中,我们必须总是假设数据需要一些预处理。预处理之后,我们需要将文本分解成记号句子。在分解文本之后,我们使用预先训练的嵌入来初始化我们的模型。

为了这篇文章的简单,我从我们的管道中跳过了文本分析。文本分析是任何 NLP 管道中非常重要的一部分。根据分析的见解,可以修改管道流程以提高应用程序的性能。

文本预处理

文本数据可能非常混乱。所以大多数时候我们需要对文本进行预处理。预处理可以包括去除最常见的拼写错误、替换文本中的数字、替换俚语词、消除常见的语法错误、匿名化数据、去除停用词等。

代码示例:

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

Code sample 1: Replacing empty records

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

Code sample 2: Declaring function to clear text

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

Code sample 3: Cleaning question text

在上面的代码样本中 train_df、 test_df 是熊猫 dataframe。首先,我们使用fillna()函数删除数据集中的空记录。然后我们声明 clean_text 函数来分离令牌。在代码示例 3 中,我们通过使用 pandas dataframe 的 apply() 函数,调用 clean_text 函数将其应用于我们的训练和测试数据集。

文本规范化

文本规范化是将文本转换成单一规范形式的过程。

有许多文本规范化技术,如标记化、词条化、词干化、句子分割、拼写纠正等。其中,标记化是最常用的文本规范化方法。

标记化是将一段文本转换成在自然语言中有意义的一系列单词或特殊字符的过程。

例如文本“NLP 是最好的!”可以转换成列表“NLP”、“is”、“the”、“best”和“!”(注意特殊字符"!"与“最佳”分开,因为它在英语中有特殊的含义)。像中文这样的一些语言没有用空格分隔的单词,所以这些语言的标记化就更加困难。

词汇化是确定两个单词是否有相同词根的任务。例如,单词“got”和“gone”是动词“go”的形式。词干化类似于词汇化,但它只是从单词的末尾剥离。使用词汇化或词干化意味着从数据中丢弃一些信息。拼写校正可以在你的自然语言处理系统中使用,以消除输入错误,提高自然语言处理系统的性能。然而,NLP 系统被假定为对由于未知令牌引起的输入的小变化是鲁棒的。

代码示例:

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

Code sample 4: Declaring and fitting tokenizer on training data

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

Code sample 5: Using trained tokenizer to tokenize all questions

在上面的代码示例中,我们通过使用一个标记器对象的 fit_on_texts() 函数来训练一个标记器。该对象可用于将文本转换为输入数据的整数表示形式。之后,我们可以通过使用 Keras 包中的 pad_sequences() 函数来限制输入序列的大小。

单词嵌入

单词嵌入是文档词汇在向量空间中的表示。嵌入向量的大小范围从 50 到 600,可以捕获语法和语义信息。如果有足够的计算资源可用,那么甚至可以使用更大的向量大小。单词嵌入的性能可能因为所使用的不同算法或嵌入向量的大小而不同。但是在某些时候,增加嵌入大小并不能提高性能。

语言模型可以代替自然语言处理系统中的单词嵌入。LM 不同于单词嵌入,因为它们可以在语料库上被训练和微调。单词嵌入被视为单个层,不能进一步调整。统计语言模型是单词序列的概率分布。一个这样的例子是 N-gram 模型。N-gram 模型计算单词“w”出现在单词“h”之后的概率。

代码示例:

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

Code sample 6: Reading embedding file format

为了在代码中使用单词嵌入,我们读取并处理嵌入文件。在每一行中,嵌入文件包含一个单词及其嵌入向量。在代码示例 6 中,我们拆分了这一行,并创建了一个字典来存储每个单词的嵌入向量。

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

Code sample 7: Extracting embedding vectors and calculating mean and standard deviation

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

Code sample 8: Recreating embedding matrics

在读取嵌入文件后,我们可以创建一个使用单词和嵌入矩阵的列表。注意,代码示例 8 使用标记器*对象来访问词汇单词。这里,我们使用正态分布重新创建嵌入矩阵。这有助于初始化字典 embeddings_index 中不存在的单词向量。*

* [## 单词嵌入和 Word2Vec 简介

单词嵌入是最流行的文档词汇表示之一。它能够捕捉…的上下文

towardsdatascience.com](/introduction-to-word-embedding-and-word2vec-652d0c2060fa)

要详细了解单词嵌入和 word2vec,请阅读上面的文章。*

建筑模型

机器学习管道中的模型是一系列数学运算,可以学习估计未知数据的输出。选择您的型号非常重要,因为它可以决定您系统的性能。

新手的话可以从非常基础的机型入手。但是您应该至少用几个模型进行试验,看看哪个参数设置能得到最好的结果。一旦你有了六个或更多运行良好的模型,你就可以把它们整合成一个巨大的模型。

最初,您可以选择使用双 LSTM 或 GRU 层和平均池层进行测试。实验之后,您可以通过使模型更深入或使用更先进的模型来对模型进行更改。为了跟踪 NLP 的进展,你可以访问这个站点,看看哪个模型在特定的任务中表现得更好。

下图给出了我们为第一个测试选择的模型的概念表示。

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

Figure 2: Conceptual representation of our model

在上图中,您可以看到我们模型的概念性布局。模型中的层代表特定的数学运算。一个模型至少可以有两层,输入层和输出层。Keras 中的输入层用于实例化一个张量。模型中的输出层是具有多个节点的神经网络。

模型中的嵌入层对输入序列和嵌入矩阵进行点积,将每个词索引转换成对应的嵌入向量。

丢弃层以给定的百分比随机丢弃输入。这一层将输入单位转换为零。这个过程有助于防止过度拟合。

门控递归单元是一种不存在消失梯度问题的递归层。双向 GRU 的输出是前向和后向 GRU 的组合

汇集操作通过执行数学平均、最大值等来减小输入序列的大小。因此,平均池层执行平均池,同时最大池层执行最大池。级联层组合不同的输入序列。

密集层是一个简单的神经网络,具有固定的节点数和指定的激活函数。

为了完全理解递归神经网络和 GRU 网络的工作原理,你可以阅读下面的文章。

* [## 递归神经网络图解指南

理解直觉

towardsdatascience.com](/illustrated-guide-to-recurrent-neural-networks-79e5eb8049c9) [## 了解 GRU 网络

在这篇文章中,我将试图给出一个相当简单和易懂的解释,一个真正迷人的类型…

towardsdatascience.com](/understanding-gru-networks-2ef37df6c9be)

代码示例:

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

Code sample 9: Model definition code

在代码示例 9 中,输入层接受大小等于 ques_len 的输入。嵌入层以嵌入矩阵及其维数为参数。嵌入层的输出大小为ques _ lenxembedding _ matrix . shape[1]空间丢弃层随机丢弃嵌入层的输出,分数为 0.2。

接下来的两层是双向 GRU,这是一种递归神经网络。全局平均池 1D全局最大池 1D 从第二双向 GRU 层的输出中提取平均和最大特征。输出 *avg_pool、*和 max_pool 被连接以馈入密集层。最后一层是输出层,给出一个介于 0 和 1 之间的数字。

初始化模型

迁移学习是通过从已经学习过的相关任务中迁移知识来提高在新任务中的学习。

在这一阶段,我们试图在我们的自然语言处理系统中利用以前的知识。使用在不同设置中训练的独立模型可以提高我们的模型的性能。这个过程被称为知识转移。在 NLP 系统中初始化神经网络的最流行的方法是单词嵌入。

NLP 的最新发展清楚地表明迁移学习是前进的方向。使用预先训练的 LMs,新的最先进的模型变得越来越好。LMs 是在一个巨大的数据集上预先训练的,它们也基于 Transformer 架构。

如果你想了解更多关于变压器模型的信息,请阅读下面的文章。

[## 你需要的只是关注

主导序列转导模型是基于复杂的递归或卷积神经网络在一个…

arxiv.org](https://arxiv.org/abs/1706.03762)

在编码样本 9 中,我们使用嵌入 _ 层初始化我们的模型,它被初始化为嵌入 _ 矩阵的权重。

培训模式

在您决定第一次使用哪个模型后,您可以训练您的模型。您应该总是在十分之一的训练数据集上开始测试您的模型,因为这会使测试更快。有些问题是,不同的预处理方法可能会产生不同的性能。

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

Code sample 10: Training our model using model.fit() method

在代码示例 10 中,我们添加了每次保存模型的功能,如果它的验证准确性增加的话。最后,我们调用函数 *fit(),*来使用 train_X,train_y (我们的特征和标签)和一系列其他参数训练模型。如果我们想以更快的速度进行训练,我们可以随时增加批量。历元的数量表示相同的训练数据将被输入模型的次数。

测试和评估模型

在训练模型之后,我们必须测试我们的模型的准确性,并评估它在看不见的数据上的表现。为此,我们预测结果并与实际标签进行比较。如果模型的性能不符合我们的预期,我们需要在我们的管道中做出改变。在 Kaggle 比赛中,排行榜分数是评估我们模型的一个很好的方式。*

自然语言处理(NLP)简介

原文:https://towardsdatascience.com/introduction-to-natural-language-processing-nlp-323cc007df3d?source=collection_archive---------6-----------------------

你有没有想过你的私人助理(比如 Siri)是怎么打造的?你想自己做吗?超级!先说自然语言处理。

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

Source: http://www.contrib.andrew.cmu.edu/~dyafei/NLP.html

那么,什么是自然语言处理(NLP)?

NLP 是一个跨学科领域,涉及计算机和自然人类语言(例如英语)——语音或文本之间的交互。NLP 支持的软件在日常生活中以各种方式帮助我们,例如:

  • 个人助理 : Siri、Cortana、谷歌助理。
  • 自动完成:在搜索引擎中(例如谷歌)。
  • 拼写检查:几乎无处不在,在你的浏览器,你的 IDE ( Visual Studio),桌面应用(微软 Word)。
  • 机器翻译:谷歌翻译。

好了,现在我们明白了,NLP 在我们日常的计算机交互中扮演着重要的角色;让我们来看一些 NLP 的业务相关用例示例:

  • 快餐连锁店每天都会收到大量的订单和投诉;手动处理这将是令人厌倦的和重复的,并且在时间、劳动和成本方面效率低下。由于最近在对话式人工智能方面的进步,他们可以建立虚拟助手来自动化这些过程并减少人工干预。
  • 品牌推出新产品,并在社交媒体平台上营销;他们可以使用覆盖范围和互动次数等指标来衡量活动的成功率。然而,他们不能自动理解消费者的公众情绪。这项任务可以使用 情感分析 来自动化,这是一项文本分类任务,其中机器学习模型被训练来量化情感状态和主观信息。

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

Source: https://clevertap.com/blog/natural-language-processing

NLP 主要分为两个领域:语言学和计算机科学。

语言学方侧重于理解语言的结构,包括以下子领域[ Bender,2013 ]:

  1. 语音学 :研究人类语言的声音。
  2. 音系学 :研究人类语言中的声音系统。
  3. :研究词的构成和内部结构。
  4. 句法 :研究句子的构成和内部结构。
  5. 语义学 :对句子意义的研究。
  6. :研究句子及其语义用于特定交际目的的方法。

****计算机科学方面是在子领域如人工智能的帮助下,将语言知识和领域专长转化为计算机程序。

让我们谈谈科学

NLP 的科学进步可以分为基于规则的系统、经典的机器学习模型和最近的深度学习模型。

  • 基于规则的系统**在很大程度上依赖于制作特定领域的规则(例如正则表达式)。它可以自动执行简单的任务,例如从非结构化数据(例如网页、电子邮件)中提取结构化数据(例如日期、姓名)。然而,由于人类语言的复杂性,基于规则的系统不够健壮,难以维护,并且不能跨不同领域通用。
  • 经典的机器学习方法可以解决更具挑战性的问题(例如垃圾邮件检测)。使用特征工程(例如单词包、词性标签)来构建机器学习模型(例如朴素贝叶斯)。这些模型利用训练数据中的系统模式,可以对看不见的数据进行预测。
  • 深度学习模型是目前 NLP 研究和应用中最流行的。它们甚至比经典的机器学习方法更能概括。它不需要手工制作的特征或特征工程,因为它们自动作为特征提取器工作,实现端到端的模型训练。深度学习模型的学习能力比浅层/经典的 ML 模型更强大,这为在各种具有挑战性的 NLP 任务中获得最高分数铺平了道路(例如机器翻译)。

计算机如何理解文本?

计算机理解数字,但不能理解字符、单词、或句子,所以在建立 NLP 模型之前需要一个中间步骤,就是文本表示。我将把重点放在单词级的表达上,因为它们很容易理解。使用其他表示技术,例如字符或子词。

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

在经典的 NLP/ML 时代(深度学习之前),文本表示技术主要建立在一个基本思想上: one-hot encodings ,其中一个句子由一个形状矩阵( N x N )表示,其中 N 是句子中唯一记号的数量。例如,在上图中,句子(猫坐在垫子上)被表示为一组稀疏向量(大部分为零)。这种方法有两个的显著缺点:**

  • 巨大的存储容量问题,因为稀疏表示矩阵。
  • 缺乏语义理解。它不能理解单词之间的关系(学校和书)。

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

2013 年,来自谷歌的研究人员推出了一种新的文本表示模型,这在 NLP 中是革命性的,命名为word 2 vec**[miko lov 等人,2013 。这种浅层深度学习模型可以在密集向量中表示单词,并捕捉相关术语之间的语义(例如巴黎和法国、马德里和西班牙)。进一步的研究建立在 word2vec 之上,如GloVePennington 等人,2014fast text**Bojanowski 等人,2016 。****

2018 年末,来自谷歌的研究人员再次提出了另一个模型( BERT ),它被认为是当今最先进的 NLP 研究的基础[ Devlin 等人,2019 ],完全基于 Transformer 架构[ Vaswani 等人,2017 ]。

任务和研究

让我们看看一些 NLP 任务,并根据对英语语言的研究进展对它们进行分类(阅读: #BenderRule )。

1.大部分已解决:

  • 文本分类(例如 Gmail 中的垃圾邮件检测)。**
  • 词性(词性)标注:给定一个句子,确定每个单词的词性标注(名词、动词、ADV、ADJ)。
  • 命名实体识别( NER ):给定一个句子,确定命名实体(例如人名、地点、组织)。

2.稳步前进:

  • 情感分析:给定一个句子,确定它的极性(积极、消极、中性),或情绪(高兴、悲伤、惊讶、愤怒等)
  • 共指解析:给定一个句子,确定哪些词(“提及”)指的是相同的对象(“实体”)。例如(曼宁是一位伟大的 NLP 教授,在这个领域工作了二十多年)。
  • 词义消歧( WSD ):很多词有不止一个意思;我们必须根据上下文选择最有意义的意思(例如我去银行取些钱,这里的银行是指金融机构,而不是河边的土地。
  • 机器翻译。

3.仍然具有挑战性:

  • 对话代理和聊天机器人,尤其是开放域的。
  • 问题回答。
  • 抽象概括。
  • 低资源语言的 NLP(如非洲语言,参见马萨坎∀等人,2020 )。

NLP 实时演示

在线综合学习计划

1。基础:

  • 学习用 Python 编程( Udacity 课程)。
  • 数学基础(线性代数,概率,统计),可汗学院曲目就足够了。我在这篇文章中更详细地讨论了如何为机器学习学习数学。

2。机器/深度学习:

3。自然语言处理:

4。语言学:

  • Emily Bender 的语言学书籍(上册:词法和句法,下册:语义和语用)。
  • YouTube 上的语言学速成班。
  • 莱顿大学:人类语言的奇迹:语言学导论,Coursera 的在线课程。

5.杂项主题:

更喜欢书吗?

让我们破解一些代码!

现在我们已经讨论了什么是 NLP,以及它背后的科学,让我们进入实用部分。这里列出了在您的下一个项目中使用的最广泛的开源库(排名不分先后):

我希望这篇文章能让你对这个激动人心的领域有一个大致的了解。如果您有任何建议或问题,请在回复中留言或联系我[Ibrahim sharaf . github . io]。

自然语言处理和人工智能中的偏见介绍

原文:https://towardsdatascience.com/introduction-to-natural-language-processing-nlp-and-bias-in-ai-877d3f3ee680?source=collection_archive---------13-----------------------

人工智能中处理自然数据和消除偏差的实用指南

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

Photo by Bewakoof.com Official on Unsplash

自然语言处理(NLP)是一个正在被深度学习革命的领域。从语音助手到 Gmail 的 Smart Compose,深度学习已经使机器能够以更直观的方式理解我们。

当然,处理自然数据与处理表格数据有很大不同,因为我们现在需要用机器可以理解的方式来表示单词和句子。

在这篇文章中,我将介绍 NLP 的关键概念,如单词嵌入,我们将看到算法如何变得有偏差,以及我们如何消除这种偏差。

我们开始吧!

关于机器学习、深度学习和人工智能的实践视频教程,请查看我的 YouTube 频道

So much talking!

如何表示文字?

通常,当使用 NLP 应用程序时,我们会访问包含数千个不同单词的词典。现在,我们需要用神经网络可以理解的方式来表达每个单词。

一键向量

使用一键编码是在字典中表示单词的一种常见方式。例如,如果您有一个 10 000 个单词的字典,并且“King”是第 4914 个单词,那么它的独热向量表示将是填充有 0 的 10000×1 向量,但是在位置 4914 是 1。

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

One-hot vector representations of possible words in a dictionary. Source

这种表示法的缺点是它将每个单词单独作为一个独特的元素。这意味着它不会识别苹果和桔子都是水果,或者国王和王后是相关的单词。因此,它不允许算法容易地概括单词的意思。

为什么?

假设你有线性代数的基础知识,你意识到上面给出的任意两个向量之间的点积都将是 0!因此,算法没有办法理解某些词是相关的。

单词嵌入

将单词表示为特征的集合,而不是一个热点向量,会很有用。例如,可以有“性别”特征、“食物”特征、“年龄”特征等。

这形成了单词嵌入的基础。这允许建立矩阵,该矩阵展示不同的单词,每个特征有相应的分数。

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

Example of word embedding

这样,每个单词现在都是一个向量,其中每个值都是某个特征的分数。

从上图来看,我们来考虑一下“君主”和“国王”。它们各自的向量是[0.5,0.5,1]和[0,0,1]。现在,我们知道这些词是相关的,两个向量之间的点积不再是 0!于是,算法现在可以理解“君主”和“国王”是有关系的,就像“君主”和“人”没有关系一样。

我们可以使用 t-SNE 进一步简化这种表示,并将维度空间减少到 2D。

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

Example of reducing the dimension space with t-SNE. Source

正如您所看到的,相似的单词被分组在一起,这显示了使用单词嵌入的优势。

使用自然语言处理进行词语类比

现在,让我们将 NLP 应用于单词类比。在继续之前,如果你想继续编码,你可以找到完整的笔记本。

单词类比任务看起来像:

男人对女人就像国王对 _____(女王)

为了完成这样的任务,算法必须有办法理解两个单词是相似的。

一种简单的方法是应用余弦相似性。这度量了两个嵌入向量之间的相似程度。数学上,余弦相似性表示为:

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

Cosine similarity equation

根据上面的等式,如果两个向量非常相似,值将接近 1。否则,它将呈现较小的值。然而,如果向量相似但方向相反,则值将更接近-1。

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

Cosine similarity between different words. Source

在 Python 中实现余弦相似性:

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

现在,我们可以用它来计算不同单词之间的余弦相似度:

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

上面的单元格输出以下内容:

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

如你所见,父亲母亲是关联词,而鳄鱼不是。同样,巴黎罗马相似,但相反,所以余弦相似度给出一个接近-1 的负数。

太好了!有余弦相似度工作,如何应用于单词类比?

如前所述,单词类比包括根据两个其他单词的关系找到与另一个单词相关的单词。例如:

男人对女人就像国王对王后一样

从数学上来说,这意味着每对字向量之间的差大致相等。所以每个差的余弦相似度也要相等。

将每个单词向量定义为 e ,下面的等式描述了单词类比的逻辑:

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

The math of word analogy

将此写入代码:

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

现在,我们可以运行下面的代码单元格,我们得到:

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

厉害!看来算法只用余弦相似度就能有效理解基本的单词类比!

花些时间去体会这种方法是如何简单、直观、高效地表示单词和理解它们的意思。

消除偏见

我们有一个算法可以进行单词类比。然而,事实证明,我们的单词表征是有偏差的。

查看性别向量的一种方法是,我们可以从女人向量中减去男人向量:

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

我们得到了:

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

这就是性别的编码方式。现在,让我们通过输出不同姓名之间的余弦相似度和性别向量来进一步探究性别偏见:

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

如您所见,女性名字的余弦相似度为正,男性名字的余弦相似度为负。

现在,让我们运行相同的操作,但是使用其他随机单词:

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

可以看到,工程师技术更接近男人,而前台文学更接近女人

很明显,我们的算法有偏差,我们需要修正它。

为此,我们需要识别偏差分量,并将其从单词向量中移除。偏置分量只是单词向量在偏置向量上的投影:

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

Bias component equation, where g is the gender vector. Source

然后,我们简单地从单词向量中减去它,以获得无偏的单词表示:

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

代表 2D 平面中的矢量,这是消除偏差前后的样子:

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

Word vectors before and after removing bias. Source

对上述逻辑进行编码,我们首先定义一个消除性别偏见的函数:

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

现在,我们可以使单词对相等:

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

让我们看看我们是否成功地消除了偏见:

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

我们得到了:

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

太神奇了!我们确实在我们的文字表述中消除了任何性别偏见!

在这篇文章中,您了解了自然语言处理中单词是如何表示的,您了解了如何构建一个可以执行单词类比的简单算法,您了解了如何消除算法中的性别偏见。

人工智能算法中的偏见有时可能是一个大问题,社区越来越意识到这一点。当你开发一个算法的时候要小心,确保它尽可能的中立。

干杯!

神经网络导论

原文:https://towardsdatascience.com/introduction-to-neural-networks-1d81f471a803?source=collection_archive---------19-----------------------

什么是神经网络?

引用人类所有知识的宝库“人工神经网络[……]是受构成动物大脑的生物神经网络启发的计算系统。”

生物神经元和人工神经网络中的“神经元”都从其他神经元接收信号,并相应地产生一些输出。这两种神经网络的力量都不是来自单个神经元单独行动,而是来自许多神经元一起的累积效应。但相似之处仅限于此。生物神经元包含非常复杂的分子机制,而人工神经网络神经元包含一些简单的数学运算。

人工神经网络已经成功地应用于图像、音频、文本和医学数据。这篇文章将向你介绍人工神经网络是如何计算的。

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

概述

假设您想要建立一个模型,根据患者的医疗记录来预测其住院风险。您可以为医疗记录的不同组成部分分配数值以构建风险模型,例如,您可以将糖尿病诊断的权重设为“2”,将流感诊断的权重设为“1.5”,将第 4 阶段肺癌诊断的权重设为“10”,以获得以下“模型方程”:

2 *糖尿病+1.5 *流感+10 *癌症=风险。

例如,Fred 患有糖尿病和流感,但没有癌症,因此他的风险是(21) + (1.51)+ (10*0) = 3.5。

但是,您如何知道每个诊断应该具有什么样的权重(即,在这个等式中使用什么系数)?糖尿病实际上应该有 2 的权重吗?可能权重应该是 1.63,或者 6,或者 0.0001。

这就是机器学习方法可以发挥作用的地方。在受监督的机器学习中,您提供一个具有输入/输出对的模型(例如,输入= Fred 的病史,输出= Fred 是否去过医院),该模型学习将输入的每一部分分配什么权重,以便最好地预测所需的输出。换句话说,该模型计算出每个输入部分(不同的诊断)对于预测输出(未来住院)有多重要或不重要。

神经网络有很多种。最简单的神经网络是前馈神经网络,这意味着信息只通过神经元向前流动。在这篇文章的剩余部分,我将描述前馈神经网络的监督学习。

数据

如果您想要预测患者入院的风险,您可以从该患者的病历中提取诊断、程序、药物和实验室值(输入“X”),然后检查该患者后来是否入院(输出“y”,正确答案)。你想用“X”来预测“y”,也就是用他们的病历来预测他们会不会去医院。你还需要许多训练样本,也就是说,你需要成千上万的样本病人,而不仅仅是一个。

前馈神经网络的剖析

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

这个神经网络有三层:输入层、隐藏层和输出层。输入和输出之间的一切都被称为“隐藏层”如果你愿意,你可以建立一个有数百个隐藏层的神经网络。

输入层只接受输入数据的一个例子:例如,一个病人的病历。在这里,从上到下的原始输入值以红色显示为 0.5、2.8、0 和-0.1,对应于我标记为 A、B、C 和 d 的输入神经元。这些输入值有一个含义。根据您正在解决的问题和使用的数据,其含义是不同的。或许在这里,输入 A、B 和 C 是特定的实验室值,而 D 是过去一年中体重变化的百分比(例如-0.1 表示患者在过去一年中体重减轻了 10%)。)

输入可以是任何正数或负数。通常,原始值被“归一化”以将值压缩为小值,因为如果一些输入是巨大的(例如 183 cm 的身高)而一些输入是微小的(例如 0.6 mg/dL 肌酸酐),则神经网络具有更难的学习时间。)

隐藏层可以被认为是在神经网络的计算中捕捉一些中间值。如果你听到人们谈论输入数据的“隐藏表示”(或“潜在空间”),他们通常指的是神经网络的隐藏层。在这幅图中,“潜在空间”是三维的,因为有 3 个隐藏的神经元:E、F 和 g。如果你制作了一个有 300 个隐藏神经元的神经网络,你可以说有一个“300 维潜在空间”关键是隐藏层捕获一些介于输入和输出之间的中间数字表示。

输出层输出最终答案。这里只显示了一个输出神经元。也许这个输出节点产生了一个入院概率。如果你想同时预测许多不同的事情,你也可以有多个输出节点。例如,您可能有两个输出节点:一个预测住院风险,另一个预测死亡率。

**权重:**连接神经元的蓝线就是神经网络的权重。它们代表乘法运算。我用红色写下了第一批重量的值。请注意,该图中没有写出通向输出层的权重的示例值。将节点 A 连接到节点 E 的权重值“3”表示您获取节点 A 中的当前值,将其乘以 3,并将结果用作节点 E 的值的分量。

**偏差:**标有“偏差”的绿线是神经网络的偏差。它们代表加法运算。应用于节点的偏移值“6”意味着您获取该节点的值,并向其添加“6”。

权重和偏差最重要的区别是,权重表示乘法,偏差表示加法。

“机器学习”的“学习”部分指的是用于计算出权重和偏差的良好设置的算法。权重和偏差是“可训练参数”,因为我们使用神经网络训练过程来计算权重和偏差的良好值。

网络结构从何而来?

当你在设计一个神经网络时,你选择它的结构。

您可以根据数据的大小选择输入图层的大小。如果您的数据每个示例包含 100 条信息,那么您的输入层将有 100 个节点。如果您的数据每个示例包含 56,123 条数据,则您的输入层将有 56,123 个节点。

您还可以选择隐藏层的数量,以及每个隐藏层中的节点数量。通常,一个好的经验法则是,输入层中的节点数和隐藏层中的节点数之间不应有太大差异。例如,您不希望输入大小为 300,000,隐藏层大小为 2,因为这将导致丢弃大量信息。一些神经网络有数百个隐藏层,但使用只有 1 或 2 个隐藏层的神经网络来解决许多有趣的问题是可能的。

您可以根据想要预测的内容选择输出图层的大小。如果您想要预测糖尿病的风险,您将有 1 个输出节点。如果您想要预测 10 种疾病的风险,您将有 10 个输出节点。

训练网络

训练神经网络包括查看数据集中的所有训练示例,以学习权重和偏差的良好值。培训可以分为几个具体步骤:

**(1)初始化:**为模型中的每个权重和偏差选择随机数。在这一点上,模型什么都不知道。

(注意:在实践中,权重的随机初始化不是完全随机的。您不会将一个权重初始化为 99,003,而将另一个权重初始化为 0.000004。以有原则的方式设置随机初始化对成功的神经网络训练很有帮助。一种流行的权重初始化方法称为“Glorot”或“Xavier”初始化。每个权重被设置为一个小的随机数,例如在-0.01 和+0.01 之间。这个数字是从基于神经网络结构的具有零均值和方差的正态分布中提取的。)

**(2)正向传递:**给神经网络一个训练示例:例如,输入“X”可以是来自单个患者病历的数据,对应的正确答案“y”可以是该单个患者后来是否入院。对于这个训练示例,神经网络将使用随机初始化的权重来计算它自己的答案。神经网络的答案很可能不会与正确答案“y”匹配,因为神经网络还没有学到任何东西。

**(2)反向传递:**在你刚刚给出的例子上,量化你的网络有多错误。这就涉及到一个“损失函数”——比如【输出答案——正确答案】2(这是一个平方误差损失)。如果您的网络计算出“0.4”作为其输出答案,但正确答案是 1(即患者入院),那么损失将是[0.4–1]2 = 0.36。

一旦你知道了损失,你就可以计算神经网络所有权重的导数,告诉你如何调整权重,这样神经网络下次就不会出错。回想一下微积分,导数可以被认为是测量曲线上特定位置的斜率。这里我们关心的斜率是损失函数的斜率,因为损失函数告诉我们我们有多错。我们想知道如何“下坡”——也就是说,如何“下坡”以使我们的损失函数更小。计算导数(斜率)告诉我们如何将每个权重推向正确的方向,以使神经网络在未来减少错误。

注意:(a)如果你正在使用 Tensorflow 这样的流行机器学习框架,你实际上并没有自己计算任何导数——导数的计算已经内置在软件中。(b)在大多数其他关于反向传播的在线资源中,导数通常被称为“梯度”“梯度”只是一个多变量的导数。

该方法被称为“反向传播”,因为你正在通过你的整个神经网络“反向传播错误”,以找出如何使神经网络变得更好。在下一次向前传递/向后传递之前,每个权重和偏差将被稍微修改。

(3)重复向前传球和向后传球进行数千次训练示例。对于每个训练示例,神经网络的权重都会变得更好一点。最终,有了足够多的训练样本,神经网络变得非常擅长使用输入来预测输出,你就有了一个有用的模型!

详细例子:向前传球

这是一个向前传递的详细示例,其中神经网络使用一些输入数据来计算答案。

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

上图显示了导致隐藏节点 E 的所有权重,以金色突出显示。权重的当前值从上到下是 3、1、5 和-4。在右下角,您可以看到输入到节点 E 的值是如何计算的。您将输入值 0.5(对应于输入节点 A)乘以链接输入节点 A 和隐藏节点 E 的权重,在本例中值为 3。将输入值 2.8(对应于输入节点 B)乘以链接输入节点 B 和隐藏节点 E 的权重。对所有输入节点执行此操作,并将结果相加:(0.5 来自节点 A)(3 来自 A-E 权重)+ (2.8 来自节点 B)(1 来自 B-E 权重)+ (0 来自节点 C)(5 来自 C-E 权重)+ (-0.1 来自节点 D)(-4 来自 D-E 权重)= 4.7。

“偏向”的绿线呢?回想一下,偏见意味着加法。分配给该层的偏移值为-2。这意味着我们从刚刚计算的值中减去 2:4.7–2 = 2.7。因此,值 2.7 是我们提供给隐藏节点 e 的最终值

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

在上图中,导致隐藏节点 F 的权重都用金色突出显示。这些权重的值从上到下依次是-1.5,-3,7.1,5.2。我们执行与之前相同的计算:(a)将输入值(红色)乘以相应的权重值(金色);(b)将这些相加;添加偏差项(绿色)。

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

在上图中,我们看到了导致隐藏节点 G 的权重以金色突出显示,以及提供给节点 G 的值的计算。

非线性

到目前为止,我们只做过乘法和加法运算。然而,仅使用乘法和加法会限制我们从输入到输出的转换种类。我们假设输入和输出之间的关系是线性的。在对真实世界建模时,拥有更大的灵活性是件好事,因为输入和输出之间的真实关系可能是非线性的。我们如何让神经网络代表一个非线性函数?

我们加入“非线性”:每个神经元对它接收的值应用一个非线性函数。一个流行的选择是 sigmoid 函数。因此,在这里,节点 E 将对 2.7 应用 sigmoid 函数,节点 F 将对-11.67 应用 sigmoid 函数,节点 G 将对 1.51 应用 sigmoid 函数。

这是 sigmoid 函数:

关键点:

(sigmoid 函数不是线性的,这有助于神经网络学习输入和输出之间更复杂的关系

(sigmoid 函数将其输入值压缩到 0 和 1 之间。

将神经网络表示为矩阵

如果你在网上阅读有关神经网络的内容,你可能会看到“Wx+b”形式的矩阵方程,用来描述神经网络的计算。原来我刚才描述的所有加法和乘法都可以用矩阵乘法来概括。

概述如何执行矩阵乘法:

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

矩阵乘法应用于我们的例子:

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

这里,我将所有第一层权重排列在标有 w 的金色矩阵中。我将输入 x 排列为红色向量。偏置单位显示为绿色,对于给定的层都是一样的(在这种情况下,它们都是-2)。

如果通过矩阵乘法和偏置加法,您会看到我们获得了与之前完全相同的答案:节点 E 为 2.7,节点 F 为-11.67,节点 g 为 1.51。

回想一下,这些数字中的每一个随后都被 sigmoid 函数压缩在 0 和 1 之间:

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

获得输出

这里显示了输出的最终计算结果。节点 E 输出值 0.937,节点 F 输出值 0.000009,节点 G 输出值 0.819。按照与前面相同的方式,我们将每个数字乘以相应的重量(黄金),将它们相加,加上偏差,然后应用非线性,得到最终输出 0.388。

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

这就是“正向传递”:神经网络如何根据输入数据计算输出预测。

后传呢?

在这里,我会向你推荐马特·马祖尔的精彩文章“一步一步反向传播的例子”如果你完成了他的反向传播的例子,我保证你会对反向传递的工作原理有很好的理解,也就是说,神经网络如何调整每一个权重以在下一次得到更正确的答案。

修改神经网络以获得更正确答案的过程也称为“梯度下降”“梯度”只是损失函数的导数,“下降”表示我们试图“下降导数”,或者使损失函数变小。如果你把损失函数想象成一座小山,我们正在努力“下山”,这样我们的损失就更小,我们的答案就更少错误(更正确)。

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

滑雪下降损失功能

结束了!敬请关注未来关于多类与多标签分类、不同种类的非线性、随机与批量、小批量梯度下降的帖子!

原载于 2019 年 1 月 17 日http://glassboxmedicine.com

用张量流进行神经类型转换的介绍

原文:https://towardsdatascience.com/introduction-to-neural-style-transfer-with-tensorflow-99915a5d624a?source=collection_archive---------18-----------------------

学会复制 Prisma 背后的逻辑,生成艺术!

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

Photo by Juan Di Nella on Unsplash

神经风格转移是卷积神经网络最具创造性的应用之一。通过拍摄内容图像和风格图像,神经网络可以将内容和风格图像重新组合,有效地创建艺术图像!

这些算法非常灵活,内容和风格的几乎无限可能的组合产生了非常有创意和独特的结果。

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

Source: Deeplearning.ai

事实上,一家公司优化了算法,并发布了一款名为 Prisma,的移动应用程序,该程序使用神经风格转移将艺术风格应用到从您的手机拍摄的图片上!

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

Example of generated images using Prisma

在这篇文章中,我们将重新创建由 Gatys 等人 提出的算法,以实现如上所示的类似结果。请注意,我是在笔记本电脑上工作的,因此,如果您在 CPU 更好的台式机上工作,结果可能会略有不同。

一如既往,随时查阅完整笔记本你有没有被卡住过。

我们开始吧!

关于机器学习、深度学习和人工智能的实践视频教程,请查看我的 YouTube 频道

Let’s make some art!

第一步:装载 VGG-19

从头开始构建算法将需要大量的时间和计算能力,这不是每个人都可以轻易获得的。

相反,我们将加载现有网络的权重来实现神经类型转移。

将神经网络用于不同目的的过程被称为迁移学习

让我们像这样加载模型:

model = load_vgg_model(“pretrained-model/imagenet-vgg-verydeep-19.mat”)

太好了!现在,我将使用卢浮宫的一张图片作为内容图片。您可以加载任何您想要的图片,但请确保图片不要太大:

content_image = scipy.misc.imread(“images/louvre.jpg”)imshow(content_image)

在我的例子中,输出如下:

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

步骤 2:定义内容成本函数

为了让我们的算法生成漂亮的图像,我们需要确保生成图像的内容与输入图像的内容相匹配。

换句话说,生成的图像还应该有金字塔、周围的建筑、云彩、太阳等。

因此,我们希望生成的图像和内容图像的层激活相似。因此,内容成本函数可以定义为:

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

Content cost function

根据上面的等式,n_H 和 n_W 分别是图像的高度和宽度,其中 n_c 是隐藏层中的通道数。

为了计算成本,更有效的方法是将 3D 体积展开成 2D 矩阵,因为这将加速计算。

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

Unrolling the convolution layer to compute the cost. Source

现在,我们编码这个逻辑:

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

步骤 3:定义风格成本函数

现在,我们需要一个风格的图像。就我而言,我将使用莫奈的印象派作品,但也可以随意使用任何其他类型的艺术作品:

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

Can someone tell me the name of this painting?

定义风格成本函数比定义内容成本函数稍微复杂一些。让我们把它分解成更小的部分。

步骤 3.1:定义 Gram 矩阵

样式矩阵也被称为 Gram 矩阵,它代表一组向量的点积。

这捕获了每个向量之间的相似性,因为如果两个向量彼此相似,那么它们的点积将会很大,因此克矩阵将会很大。

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

Gram matrix. Source

这就是 Gram matrix 如何有效地测量图像的风格。

将它写入代码:

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

步骤 3.2:定义风格成本

现在,我们要确保生成的图像和样式图像的样式是相似的。

换句话说,我们希望最小化两个 Gram 矩阵之间的距离。这表示为:

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

Style cost function

逻辑编码:

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

步骤 3.3:分配样式权重

在上一步中,我们只获取了单一图层的样式成本。将所有图层的样式成本结合起来以生成更好的图像将是有用的。

从数学上讲,风格成本变成了:

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

Combined style cost for all layers

其中λ是每层的权重。

因此,我们添加了这个代码单元:

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

第 3.4 步:结合一切

现在,我们简单地将所有内容合并到一个单一的风格成本函数中:

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

步骤 4:定义总成本函数

现在我们有了内容和样式的成本函数,我们可以将两者结合起来,以获得将被优化的总成本函数:

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

Total cost function

其中αβ是任意权重。

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

第五步:解决优化问题并生成图像

现在,最精彩的部分!一切就绪,就可以解决优化问题,生成艺术形象了!

在我的例子中,我得到以下结果:

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

Content image to generated image

当然,如果你训练网络的时间更长,学习率更小,你可以得到好得多的结果。

恭喜你!你刚刚在 TensorFlow 里进行了神经风格转移!可以随意改变内容和样式图像,可以随意调整迭代次数和学习率。

下次见!

来源: Deeplearning.ai

OpenVINO 简介

原文:https://towardsdatascience.com/introduction-to-openvino-897e705a1f0a?source=collection_archive---------6-----------------------

理解 OpenVINO 工具包功能的综合指南

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

Photo by Christian Wiediger on Unsplash

OpenVINO 代表开放视觉推理和神经网络优化。它是英特尔提供的一个工具包,用于促进深度学习模型的更快推理。它帮助开发人员创建具有成本效益且健壮的计算机视觉应用。它在边缘实现深度学习推理,并支持跨计算机视觉加速器(CPU、GPU、英特尔 Movidius 神经计算棒和 FPGA)的异构执行。它支持大量开箱即用的深度学习模型。你可以查看这个链接来了解更多关于模型动物园的信息。

先决条件

如果您想运行本文末尾提供的代码示例,那么请确保您已经正确下载并配置了 OpenVINO toolkit。

[## 开始使用|英特尔发布的 OpenVINO 工具包

使用该计算机视觉工具包的资源和培训材料快速上手。

software.intel.com](https://software.intel.com/en-us/openvino-toolkit/documentation/get-started) [## 选择并下载|英特尔发布的 OpenVINO 工具包

下载英特尔发布的 open vino toolkit for Linux、Windows 或 macOS 版本。

software.intel.com](https://software.intel.com/en-us/openvino-toolkit/choose-download)

概观

执行过程如下—

  • 我们将预先训练好的模型输入到模型优化器中。它优化模型并将其转换为中间表示形式(。xml 和。bin 文件)。
  • 推理机有助于模型在不同设备上的正确执行。它管理在不同平台上正确运行代码所需的库。

OpenVINO 工具包的两个主要组件是模型优化器和推理引擎。因此,我们将深入了解它们的细节,以便更好地理解它们的角色和内部工作方式。

模型优化器

Model optimizer 是一个跨平台的命令行工具,有助于在培训和部署环境之间进行转换。它调整深度学习模型,以便在端点目标设备上实现最佳执行。

工作

模型优化器将模型加载到内存中,读取它,构建模型的内部表示,优化它,并产生中间表示。中间表示是推理机接受和理解的唯一格式。

模型优化器不推断模型。它是一个离线工具,在推理发生之前运行。

模型优化器有两个主要目的:

  • 产生一个有效的中间表示。模型优化器的主要职责是生成两个文件(。xml 和。bin),它们形成中间表示。
  • 产生优化的中间表示。预训练模型包含对训练很重要的层,例如下降层。这些层在推理过程中没有用,可能会增加推理时间。在许多情况下,这些层可以从生成的中间表示中自动移除。但是,如果一组层可以表示为一个数学运算,因此可以表示为一个层,则模型优化器可以识别这种模式,并用一个层来替换这些层。结果是一个比原始模型层数更少的中间表示。这减少了推断时间。

操作

  1. 重塑
  • 模型优化器允许我们重塑输入图像。假设您已经使用 256 * 256 的图像大小训练了您的模型,并且您想要将图像大小转换为 100 * 100,那么您可以简单地将新的图像大小作为命令行参数传递,模型优化器将为您处理剩下的工作。

2.配料

  • 我们可以在推理时改变模型的批量大小。我们可以将批处理大小的值作为命令行参数传递。
  • 我们也可以像这样传递我们的图像大小[4,3,100,100]。这里,我们指定需要 4 个尺寸为 1001003 的图像,即具有 3 个通道且宽度和高度为 100 的 RGB 图像。这里需要注意的重要一点是,现在的推断会更慢,因为我们使用一批 4 张图片进行推断,而不是只使用一张图片。

3.修改网络结构

  • 我们可以修改我们网络的结构,也就是说,我们可以从顶部或底部去掉一些层。我们可以指定一个特定的层,从这里开始执行,或者从这里结束执行。

4.标准化和规模化

  • 我们可以对输入数据执行标准化(均值减法)和标准化等操作。

量化

这是优化过程中的重要一步。大多数深度学习模型通常使用 FP32 格式作为输入数据。FP32 格式消耗大量内存,因此增加了推断时间。因此,直觉上我们可能认为,我们可以通过改变输入数据的格式来减少我们的推理时间。还有各种其他格式,如 FP16 和 INT8,我们可以使用,但我们需要小心执行量化,因为它也可能导致精度损失。

使用 INT8 格式可以帮助我们显著减少推理时间,但目前只有某些层与 INT8 格式兼容:卷积、ReLU、池化、Eltwise 和 Concat。因此,我们本质上执行混合执行,其中一些层使用 FP32 格式,而一些层使用 INT8 格式。有一个单独的层来处理这些转换。也就是说,我们不必明确指定从一层到另一层的类型转换。

校准层处理所有这些复杂的类型转换。它的工作方式如下—

  • 最初,我们需要定义一个阈值。它决定了我们愿意接受的准确度下降。
  • 然后,校准图层获取数据的子集,并尝试将图层的数据格式从 FP32 转换为 INT8 或 FP16。
  • 然后检查精度下降,如果低于指定的阈值,则进行转换。

推理机

在使用模型优化器创建中间表示(IR)之后,我们使用推理引擎来推理输入数据。

推理机是一个 C++库,有一组 C++类来推断输入数据(图像)并得到一个结果。C++库提供了一个 API 来读取中间表示,设置输入和输出格式,并在设备上执行模型。

由于推理机的存在,模型的异构执行成为可能。它为不同的设备使用不同的插件。

异构插件

  • 我们可以在多个设备上执行相同的程序。我们只需要将目标设备作为命令行参数传入,推理引擎会处理剩下的事情,也就是说,我们可以在 CPU、GPU、VPU 或任何其他与 OpenVINO toolkit 兼容的设备上运行相同的代码。
  • 我们还可以在不同的设备上执行程序的各个部分,即程序的某些部分可能在 CPU 上运行,而其他部分可能在 FPGA 或 GPU 上运行。如果我们指定 HETERO: FPGA,CPU,那么代码将主要在 FPGA 上运行,但是如果它遇到与 FPGA 不兼容的特定操作,那么它将切换到 CPU。
  • 我们还可以在特定设备上执行某些层。假设你想只在你的 GPU 上运行卷积层,那么你可以明确地指定它。
  • 这里需要注意的重要一点是,在指定不同的硬件时,我们需要注意数据格式。并非所有设备都支持所有数据类型。例如,配备 Movidius 芯片的神经计算棒 NCS2 不支持 INT8 格式。你可以查看这个链接来获得关于支持的设备及其各自格式的完整信息。

代码示例

英特尔提供的原始代码样本可以在这里找到。
我修改了代码样本,使其更简单,我的版本可以在这里找到。

这里我只解释 OpenVINO 的具体代码。

# Initialize the classinfer_network = Network()# Load the network to IE plugin to get shape of input layern, c, h, w = infer_network.load_model(args.model, args.device, 1, 1, 2, args.cpu_extension)[1]

我们正在初始化网络类,并使用load_model函数加载模型。
load_model函数返回插件和输入形状。
我们只需要输入形状,这就是为什么我们在函数调用后指定了[1]。

infer_network.exec_net(next_request_id, in_frame)

exec_net函数将启动一个异步推理请求。
我们需要传入请求 id 和输入框。

res = infer_network.get_output(cur_request_id)for obj in res[0][0]: if obj[2] > args.prob_threshold: xmin = int(obj[3] * initial_w) ymin = int(obj[4] * initial_h) xmax = int(obj[5] * initial_w) ymax = int(obj[6] * initial_h) class_id = int(obj[1])

这是代码中最重要的部分。
get_output函数将给出模型的结果。
每个检测用以下格式表示—
[image_id,class_label,confidence,x_min,y_min,x_max,y_max]

这里,我们已经提取了边界框坐标和类 id。

[## dhairya 10/人数-葡萄酒

这个项目使用 Python 和 OpenVINO toolkit 来计算给定帧中的人数。OpenVINO toolkit 是…

github.com](https://github.com/Dhairya10/people-count-vino)

参考

该项目大量借鉴了英特尔 IOT 开发套件的商店通道监视器 python 项目。

[## 英特尔-物联网-开发套件/商店-过道-监视器-python

这个参考实现在 C++中也是可用的。这个参考实现计算人数…

github.com](https://github.com/intel-iot-devkit/store-aisle-monitor-python)

要探索英特尔的其他激动人心的项目,请查看英特尔物联网开发套件。

[## 英特尔物联网开发套件

用 C 语言编写的用于低速 IO 通信的 Linux 库,绑定了 C++、Python、Node.js 和 Java。支持通用 io…

github.com](https://github.com/intel-iot-devkit)

说到这里,我们已经到了这篇文章的结尾。非常感谢你的阅读。

我的 LinkedInTwitterGithub
你可以查看我的网站了解更多关于我和我的工作。

造纸厂简介

原文:https://towardsdatascience.com/introduction-to-papermill-2c61f66bea30?source=collection_archive---------3-----------------------

如何将您的 Jupyter 笔记本转变为工作流程工具

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

Figure 1. Papermill and Jupyter Project logos

1.介绍

Jupyter 笔记本是探索性数据分析(EDA)的黄金标准,也是记录数据科学项目的绝佳工具。虽然数据科学家通常在其中迭代工作(不遵循自上而下的单元顺序),但它可以从第一个到最后一个单元运行,逐步再现数据分析。

使用 Jupyter 笔记本执行重复性任务和 ETL 时出现的一个问题是,它缺乏自动化和日志记录功能。缺乏自动化意味着您必须在需要时打开相应的笔记本并手动运行它,并且缺乏日志记录,您无法控制执行过程中可能出现的错误和异常。

1.1 进入造纸厂

Papermill 是一个可以让我们参数化执行笔记本的工具。它在数据工作流工具上通过顺序执行每个单元格来转换您的 Jupyter 笔记本,而无需打开 JupyterLab(或笔记本)。它试图填补自动化和日志记录的空白,为我们提供了一种将笔记本作为文件执行的方式,并为每次执行生成一份报告。

目标:本文的目标是集成 Papermill 和 Jupyter 笔记本来创建数据工作流。为了说明这一点,我们将开发一个 Python 笔记本,使用天气预报 API ( PyOWM )运行一个简单的分析,执行数据辩论,生成一些可视化结果,并创建一个最终报告。

Jupyter 笔记本和其他具有更多数据分析细节的文件可以在 GitHub 项目资源库 **中找到。**要重现分析,您需要安装paper mill _ env . YAML上列出的库。

2.配置我们的开发环境

2.1 安装 Papermill 和 JupyterLab

我们将首先使用 Conda (1,2) 创建一个开发环境,并安装 JupyterLab 和其他用于分析的库 (3)

**# 1) Create a conda environment** conda create -n papermill python=3.7**# 2) Activate it** conda activate papermill **# 3) Install the libraries using pip (or conda)** pip install papermill pyowm jupyterlab pandas seaborn boto3 pdfkit

有关如何使用 conda 和其他开源工具来组织您的项目的更多信息,请查看我以前的文章 “创建坚实的数据科学开发环境”。

安装 Papermill 后,我们可以通过终端 (4) 获得更多信息。

**# 4) Papermill Documentation** papermill -hUsage: papermill [OPTIONS] NOTEBOOK_PATH OUTPUT_PATHThis utility executes a single notebook in a subprocess.Papermill takes a source notebook, applies parameters to the source
  notebook, executes the (4)notebook with the specified kernel, and saves the
  output in the destination notebook.The NOTEBOOK_PATH and OUTPUT_PATH can now be replaced by `-` representing
  stdout and stderr, or by the presence of pipe inputs / outputs. Meaning
  that`<generate input>... | papermill | ...<process output>`with `papermill - -` being implied by the pipes will read a notebook from
  stdin and write it out to stdout.Options:
  -p, --parameters TEXT...        Parameters to pass to the parameters cell.
  -r, --parameters_raw TEXT...    Parameters to be read as raw string.
  -f, --parameters_file TEXT      Path to YAML file containing parameters.
  -y, --parameters_yaml TEXT      YAML string to be used as parameters.
  -b, --parameters_base64 TEXT    Base64 encoded YAML string as parameters.
  --inject-input-path             Insert the path of the input notebook as
                                  PAPERMILL_INPUT_PATH as a notebook
                                  parameter.
  --inject-output-path            Insert the path of the output notebook as
                                  PAPERMILL_OUTPUT_PATH as a notebook
                                  parameter.
  --inject-paths                  Insert the paths of input/output notebooks
                                  as
                                  PAPERMILL_INPUT_PATH/PAPERMILL_OUTPUT_PATH
                                  as notebook parameters.
  --engine TEXT                   The execution engine name to use in
                                  evaluating the notebook.
  --request-save-on-cell-execute / --no-request-save-on-cell-execute
                                  Request save notebook after each cell
                                  execution
  --prepare-only / --prepare-execute
                                  Flag for outputting the notebook without
                                  execution, but with parameters applied.
  -k, --kernel TEXT               Name of kernel to run.
  --cwd TEXT                      Working directory to run notebook in.
  --progress-bar / --no-progress-bar
                                  Flag for turning on the progress bar.
  --log-output / --no-log-output  Flag for writing notebook output to the
                                  configured logger.
  --stdout-file FILENAME          File to write notebook stdout output to.
  --stderr-file FILENAME          File to write notebook stderr output to.
  --log-level [NOTSET|DEBUG|INFO|WARNING|ERROR|CRITICAL]
                                  Set log level
  --start_timeout INTEGER         Time in seconds to wait for kernel to start.
  --report-mode / --no-report-mode
                                  Flag for hiding input.
  --version                       Flag for displaying the version.
  -h, --help                      Show this message and exit.

正如我们从 Papermill 文档 中看到的,基本用法非常简单,我们只需要提供目标 Jupyter 笔记本的路径和输出笔记本的名称(作为日志工作)。我们将在本文后面探讨一些额外的选项。

2.2 安装 Jupyter 内核

尽管 Jupyter 笔记本以运行 Python 而闻名,但我们可以通过安装不同的内核来使用几乎任何编程语言。有了特定的内核,我们可以在 Papermill 定义的环境中运行我们的笔记本,避免了缺少库的问题 (5)

**# 5) Install Jupyter kernel for papermill environment** pip install ipykernelipython kernel install --user --name=papermill-tutorial

3.创建工作流

我们将使用 Jupyter 笔记本进行天气预报数据分析。其想法是创建一个简单的工作流,使用名为 的 Python API 获取特定城市的数据,执行数据争论,创建一些图表并在 pdf 报告上组织信息。

3.1 使用 PyOWM 天气 API

库主页所述,“PyOWM 是 OpenWeatherMap web APIs 的客户端 Python 包装库”。它通过提供一个“简单的对象模型”来方便访问天气数据。使用这个库的唯一要求是一个 API 密匙,可以在 OpenWeather 链接上免费获得。

3.2 工作流第 1 部分:使用 PyOWM API 获取天气数据

工作流的第一部分包括使用 PyOWM 库获取关于预定义的city(圣保罗,BR 在原始笔记本上)的信息。我们迭代forecast对象,在 DataFrame 上组织返回的信息,使我们在接下来的步骤中更加轻松。

3.3 工作流第 2 部分:使用 PyOWM API 获取天气数据

在工作流程的第二部分,我们将汇总白天的数据,并在一个图中绘制温度信息,在另一个图中绘制降雨、湿度和云量百分比信息。

3.4 工作流程第 3 部分:创建 PDF 格式的天气报告

在我们工作流程的最后一部分,我们将使用为城市和地块收集的数据创建天气报告。我们将使用库 pdfkit 将我们的 HTML 模板转换成 pdf 文件。

3.5 使用造纸厂前的最终测试

在我们的 Jupyter 笔记本上完成分析后,建议通过重启内核并运行所有单元来测试工作流( Run > Run all cells )。如果我们观察到所有的单元都被成功地执行了,并且输出完全符合我们的预期,那么我们的笔记本就可以和 Papermill 一起使用了。我们的工作流 can 生成的圣保罗市(巴西)的预期天气报告如图 2 所示。在接下来的会话中,我们将配置 Jupyter 笔记本,以接受任何城市作为工作流的参数,并使用 Papermill 自动执行它。

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

Figure 2. The weather forecast report created with our workflow for the city of Sao Paulo, BR.

4.为 Papermill 配置笔记本

现在我们已经为生产准备好了笔记本,我们只需要对配置进行一些更改,就可以在 Papermill 中使用它了。您可以选择使用 Jupyter Lab 或与 Papermill 集成的 Jupyter Notebook。对于每个平台,带有参数的单元的配置是不同的,因此我们在进行这一步时需要注意。

4.1 在 Jupyter Lab 上定义参数

当使用 Jupyter Lab 运行笔记本时,我们必须为工作流中使用的参数创建一个缺省值的单元格。接下来,我们选择带有参数的单元格,单击笔记本工具(左侧面板上的扳手图标)和高级工具(图 3)

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

Figure 3. Configuring a notebook cell to receive the parameters from Papermill on JupyterLab.

单元元数据框中,我们需要添加以下描述:

{
    "tags": [
        "parameters"
    ]
}

不要忘记点击方框上方的勾号图标保存它。现在,您的 Jupyter 实验室笔记本已准备好接收来自 Papermill 的参数。

4.2 在 Jupyter 笔记本上定义参数

要在 Jupyter 笔记本上配置参数单元格,我们需要点击*视图>单元格工具栏>标签。*然后将标签parameters写入并添加到相应的笔记本单元格中(图 4)。

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

Figure 4. Configuring a notebook cell to receive the parameters from Papermill on JupyterNotebook.

5.执行 Papermill

我们可以通过命令行或者使用 Python API 来执行 Papermill 为了使用终端运行 Jupyter 笔记本,我们运行命令 (6):

**# 6) To execute Papermill from the terminal** papermill weather_forecast_using_pyowm.ipynb \
          weather_forecast_using_pyowm_output.ipynb \
          -p city 'Sao Paulo,BR' \
          -k papermill-tutorial

前两个参数是目标 Jupyter 笔记本的名称(来自会话 3)和输出笔记本的名称(输入的执行版本)。-p代表参数,所以我们描述每个参数的名称及其各自的值(在我们的例子中,我们只有city)。最后,-k代表内核,我们选择在第 5 步中创建的papermill-tutorial内核。

如果我们想要使用 Papermil Python API 来运行相同的过程,我们必须键入以下命令:

5.1 输出笔记本

Papermill Python API 可用于将笔记本的执行与其他操作集成在一起。例如,如果在执行过程中出现错误,我们可以解析输出文件,识别问题并将其保存在数据库结构中。

朱庇特笔记本文件(。ipynb 扩展)是 JSON 文件,包含每个单元格文本、源代码、输出和元数据的信息。Papermill 会创建一个输出文件,该文件对应于使用用户指定的参数执行的输入笔记本。它基本上包含了记录流程所需的所有信息,这意味着我们可以将它作为类似日志的数据来记录我们的工作流执行。因此,保存输出 JSON 文件的一种方法是使用 NoSQL 键值数据库( Amazon DynamoDBMongoDBCassandraDBBigTable 等)。

6.最后的想法

Papermill 是一个简单方便的工具,可以将 Jupyter 笔记本转换为数据工作流。它扩展了笔记本电脑的使用可能性,打破了可视化/文档环境的障碍,成为一个生产就绪的平台。在创建最终的 ETL 以在更复杂的数据管道工具如 AirflowLuigi 上运行之前,它可以作为一个快速便捷的工具用于数据工作流的原型化。

我们试图向读者简单介绍 Papermill,但是将该工具与其他资源集成的可能性是无限的。我们相信一个活跃的社区将围绕它成长,将这个项目转化为一个更成熟的工具。

非常感谢你阅读我的文章!

  • 你可以在我的个人资料页面 找到我的其他文章🔬
  • 如果你喜欢并且想成为中级会员,你可以使用我的 推荐链接 来支持我👍

其他资源

[## 创建可靠的数据科学开发环境

如何使用 Conda、Git、DVC 和 JupyterLab 来组织和复制您的开发环境。

towardsdatascience.com](/creating-a-solid-data-science-development-environment-60df14ce3a34) [## 使用 Jupyter 笔记本自动生成报告(使用 Jupytext 和 Papermill)

Jupyter 笔记本是交互式运行代码和用数据编写叙述的最佳可用工具之一…

medium.com](https://medium.com/capital-fund-management/automated-reports-with-jupyter-notebooks-using-jupytext-and-papermill-619e60c37330) [## 使用 Papermill 自动化 Jupyter 笔记本

Jupyter 笔记本是探索数据、测试假设、协作和报告发现的绝佳方式。与 Jupyter 一起…

medium.com](https://medium.com/y-data-stories/automating-jupyter-notebooks-with-papermill-4b8543ece92f) [## 数据管道、Luigi、气流:你需要知道的一切

这篇文章是基于我最近给同事们做的关于气流的演讲。

towardsdatascience.com](/data-pipelines-luigi-airflow-everything-you-need-to-know-18dc741449b7)

主成分分析(PCA)简介-使用 Python 代码

原文:https://towardsdatascience.com/introduction-to-principal-component-analysis-pca-with-python-code-69d3fcf19b57?source=collection_archive---------15-----------------------

PCA 介绍——原因、时间和方式

动机

想象一个有 100000 个句子的文本数据。文本中唯一单词的总数是 10000(词汇量)。如果每个句子由长度等于词汇大小的向量表示。在这个长度为 10000 的向量中,每个位置属于一个唯一的单词。对于我们这个句子的向量,如果某个词出现 k 次,那么这个词的索引对应的向量中元素的值就是 k 。对于词汇表中没有出现在我们句子中的每一个单词,向量元素是 0。这被称为一键编码。

现在,如果我们为这些句子中的每一个创建向量,我们有一组 100000 个向量。在矩阵形式中,我们有一个 100000*10000 大小的矩阵。这意味着我们的矩阵中有 10⁹元素。在 python 中,要估计占用的内存,

import numpy as np
import sys
sys.getsizeof(np.zeros((100000,10000)))
>>> 8000000112

这个数字以字节为单位,转换成 8000 兆字节。

如果我们能够在一个更小的矩阵上工作,一个具有更少但更重要的特征的矩阵,会怎么样?比方说,大约 100 个特征可以捕获数据的大部分信息。拥有更多功能通常是好事。但是更多的特征通常也包括噪声。噪声会降低任何机器学习算法的鲁棒性,尤其是在小数据集上(阅读维度的诅咒了解更多)。此外,我们将节省 100-1000 倍的内存消耗。当您将应用程序部署到生产环境中时,这一点非常重要。

带着这个目的,我们来讨论一下 PCA 是如何帮助我们解决这个问题的。

方差作为信息

在机器学习中,我们需要算法的功能来找出有助于区分数据类别的模式。特征的数量越多,差异(数据的变化)就越大,因此模型发现很容易做出“分割”或“边界”。但并不是所有的功能都能提供有用的信息。他们也会有噪音。如果我们的模型开始适应这种随机噪声,它将失去其鲁棒性。事情是这样的— 我们希望从可用的特征空间中组合出 m 个 特征,以获得最大的方差。注意,我们要组合而不是仅仅选择 m 特征。

从数学角度来说

假设一个数据点由矢量 x 表示,原本具有 n 特征。

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

vector x

我们的工作是将它转换成一个向量 z ,维数比n 少,比如说 m

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

vector z

这是通过线性变换实现的。具体来说,我们将一个矩阵乘以 x ,将其映射到一个 m- 维空间。考虑一个大小为 nm 的矩阵*。使用 W ,我们希望将 x 转换为 z 为—**

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

PCA transformation. Wt is the transpose of W

对上述等式的简单解释—假设您有一个包含列的原始数据框—

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

Original Dataframe

在 PCA 之后,如果我们选择,比方说 3 个分量,数据帧看起来像这样—

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

在哪里,

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

c1,c2,…而 d1,d2,…是标量。w 矩阵是

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

W — a 5*2 matrix

考虑下面的示例图。指向东北的轴沿其方向覆盖了更多的分布。那么第二大“覆盖”轴指向西北。

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

Image credits: https://i1.wp.com/enhancedatascience.com/wp-content/uploads/2017/05/PCA1.png?resize=629%2C424

如何获得 W?

上面的描述对于一个关于 PCA 的小对话来说已经足够好了。但是如果你对 W 的计算很好奇,这一节是给你的。如果你对数学不感兴趣,你可以跳过它。

我们讨论过 PCA 是关于计算方差最大化的轴。考虑一个单轴 w** ,我们希望沿着它最大化方差。数学上,**

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

*为了计算方差,我们需要均值。在统计学中,最好称之为期望,用 E 表示。随机变量的期望就是它的均值。在我们的例子中,我们将原始特征的期望值 x 表示为μ。对于我们转换后的特征, z 我们的期望值是 wt μ(见下图)

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

如果你感到困惑,参考下面的等式,取 LHS 和 RHS 的平均值

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

matrix multiplication is commutative

设变换特征的平均值为

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

随机变量 z 的样本方差由下式给出:

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

用期望和从期望操作中取出 w 来表示(因为它是一个常数,不依赖于 z

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

原来, z 的方差就是wt * x(sigma) w的协方差。协方差是多维随机变量的方差,在我们的例子中是 x 。它是一个大小为 kk 的方阵,其中 kx 的尺寸。是一个对称矩阵**。关于协方差矩阵的更多信息**

在我们最大化方差之前,我们对我们的 w 矩阵的范数施加一个重要的条件。标准应该是 1

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

Norm = 1

为什么?否则,最大化方差的简单方法就是增加范数,而不是以最大化方差的方式重新调整主轴。这个条件包括使用拉格朗日乘数

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

如果我们对上面的表达式求导,我们得到—

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

看看最后一个表情。协方差矩阵乘以 w 等于标量α乘以 w 。这意味着, w 是协方差矩阵的特征向量**,α是对应的特征值。利用这个结果,**

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

var(z) is the eigenvalue

如果要使 var(z) 最大化,那么α必须是所有特征值中最大的。并且对应的特征向量是主分量

这为我们提供了第一个主成分,与任何其他成分相比,沿着该主成分解释的方差是最大的。以上是第一个轴的推导。类似地导出其他轴。重点是深入研究 PCA 背后的数学。

数学说够了!给我看看代码

我们使用的数据集是 Coursera 的课程评论,可在 Kaggle 上获得。这个练习的代码可以在我的 GitHub repo 上找到。

顾名思义,由评论(句子)和评分(1,2,3,4,5)组成。我们收集了 50,000 条评论,使用 TF-IDF 对它们进行清理和矢量化。

TF-IDF 是一种给句子中的每个单词分配分数的评分方法。如果该词在所有评论中不常出现,但在总体上频繁出现,则得分高。比如课程这个词出现频率很高,但是几乎每隔一个复习就出现一次。所以这个词的 TF-IDF 分数会在下面。另一方面,这个词出现频率很高,而且只针对负面评论。所以它的分数更高。**

因此,对于每次审查,我们有固定长度的 TF-IDF 向量。向量的长度就是词汇量的大小。在我们的例子中,TF-IDF 矩阵的大小为 50000*5000。而且 99%以上的元素都是 0。因为如果一个句子有 10 个单词,5000 中只有 10 个元素是非零的。

我们使用主成分分析来降低维数。但是怎么决定要带多少组件呢?

让我们来看一下解释的方差图与组件或轴数的关系

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

Variance explained vs the number of components

如您所见,前 250 个组件解释了 50%的变化。前 500 个组件占 70%。如您所见,增量收益减少了。当然,如果你取 5000 个组件,解释的方差将是 100%。但是那么做 PCA 有什么意义呢?

— — — —

我已经开始了我的个人博客,我不打算在媒体上写更多令人惊叹的文章。通过订阅帮助空间来支持我的博客

主成分分析导论

原文:https://towardsdatascience.com/introduction-to-principle-component-analysis-d705d27b88b6?source=collection_archive---------15-----------------------

由 In Visal,Yin Seng,Choung Chamnab & Buoy Rina 撰写—本文于 2019 年 7 月 20 日提交给“脸书开发商圈:金边”小组。这里是原幻灯片包—

为什么是 PCA?

据 DataCamp 称,可通过以下方式查看五氯苯甲醚:

  • 应用线性代数中更有用的方法之一
  • 从混乱的数据集中提取有意义信息的非参数方法
  • 揭示数据背后隐藏的低维结构
  • 这些结构更容易可视化,并且通常可以被内容专家解释

形式定义

根据维基百科:

“主成分分析(PCA)是一种统计过程,它使用正交变换将一组可能相关的变量(每个变量都具有不同数值的实体)的观察值转换为一组称为主成分的线性不相关变量的值。”

对上述定义的第一反应是“管它呢?”。

从我的经验来看,任何数学或统计定理的正式定义一开始都是难以理解和令人生畏的。这并不是因为这些定义含糊不清,而是因为我们最初缺乏对主题的理解。在掌握和理解了这个主题之后,我们将会体会到形式定义的简洁。

正交投影

在深入 PCA 的计算之前,让我们回顾一下作为 PCA 支柱的正交投影概念。

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

Illustration of orthogonal projection

  • Ai 向量在主分量上的投影通过勾股定理将剩余方差与残差平方联系起来。
  • 选择最大化方差的分量与选择最小化残差平方和的分量是一样的。

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

Maximising variance = minimizing the residuals

  • 分量 x 上的投影具有比 分量分量 y. 更小的损失方差
  • 分量 y 上的投影比 分量分量 x. 具有更高的损失方差

计算主成分

根据下面的散点图,X1 和 X2 是数据集的特征。这个数据集的主要成分的方向是什么?

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

Raw dataset

可通过以下步骤计算 PCA:

  1. 从质心(Xavg,Yavg)开始
  2. 确定投影误差/残差之和最小化的方向。我们称之为“第一”主成分。
  3. “第二”主分量是与第一主分量正交的方向。

这是一个 顺序 算法。

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

Step-1 & Step-2

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

Step-3

还有另外两种更好的算法来计算 PCA:

  1. 样本协方差矩阵的特征分解
  2. 数据矩阵的奇异值分解(下一节)

在 Scikit Learn 中计算 PCA

使用 sklearn.decomposition 包中的 PCA 函数可以很容易地计算 PCA。

我们首先从 sklearn.decomposition 导入 PCA,并初始化数据 2D numpy 数组。

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

Import PCA function and initialize data array

接下来,我们通过设置 n_components = 2 来创建一个名为“pca”的 PCA 对象。需要数据作为输入参数的 Fit()方法执行 PCA 计算。

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

一旦“pca”对象适合输入数据,它现在可以用于通过“变换”功能将数据变换成主成分。

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

The principal components of the data

我们可以通过提取已解释的方差来对分量的显著性进行排序。

  • 解释的方差越高,该成分越重要。
  • 具有较小解释方差的分量可以被丢弃,而不会丢失重要信息。

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

Extracting the components ‘ explained variance

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

Histogram of the components’ explained variance

从 Numpy SVD 计算 PCA

计算 PCA 的另一种方法是使用 Numpy 对原始数据执行奇异值分解(SVD)。

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

SVD

我们首先导入整个 Numpy 库,并应用线性代数模块中的‘SVD’函数。“svd”函数返回三个矩阵 U、S 和 Vt。

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

主成分是通过取 U 和 s 的点积得到的。

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

The principal components = dot product of U and S

应用程序

MNIST 数据集的 2D 可视化

  • 数据集包含手写数字的图像:10 个类别,每个类别指一个数字。
  • 代表数字的 8×8 图像的 1797 个样本和 64 个特征

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

MNIST images

因为有 64 个特征,所以不可能可视化特征关系。PCA 通过将 64 维特征空间减少到 2D 空间(2 个主成分)来拯救我们。

为此,我们从 sklearn.datasets 导入 load_digits 并创建一个名为“pca”的 PCA 对象。n_components 设置为 2。通过调用“fit_transform”函数来获得主分量,该函数执行计算并返回主分量。然后,将得到的主成分进行交会图。

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

Performing PCA on MNIST dataset

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

Cross-plot of principal component 1 and 2

MNIST 数据集的降维

为了证明主成分分析在降低特征空间维数方面的鲁棒性,我们在 MNIST 数据集上执行了两种情况的 SVM 分类,并比较了结果的准确性。

  • 情况 1:使用原始的 64 个特征来分类 MNIST 数字。
  • 案例 2:使用 10 个主成分对 MNIST 数字进行分类。

如下图,精度差只有~1%。

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

SVM classification — Case 1

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

SVM classification — Case 2

图像压缩

PCA 的另一个有趣的应用是图像压缩(有损!).如下图,400*600 像素的图像需要 240000 字节来存储。

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

240,000 bytes required to store an image of 400*600 pixels

我们可以对原始图像应用 SVD,并截断不太重要的分量。在这种情况下,400 个主成分中只有 50 个被保留,其余的被截断。

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

Applying SVD on the original image and keeping only the top 50 components

通过仅使用前 50 个组件,存储压缩图像所需的存储器仅为 50,050 字节。

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

Only 50,050 bytes required to store

下面给出了使用 SVD 执行图像压缩的 Python 代码:

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

Image compression with SVD

下图显示了随着保留组件数量(k)的增加,图像质量的变化。正如所料,k 越高,图像质量越好,所需内存也越高。保留组件的最佳数量(k)是一个主观问题,并且是特定于应用的。

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

总结

PCA 是应用线性代数的迷人案例之一,它在数据科学中有更多的应用,超出了本文的范围。我们不太可能需要从头开始编写 PCA 代码;然而,当我们需要使用机器学习库来使用 PCA 时,对 PCA 如何工作有一个坚实的理解将是有用的。

特别感谢主要贡献者 Visal 的、Yin Seng、Choung Chamnab ,是他们使这项工作成为可能。**

PyTorch 简介

原文:https://towardsdatascience.com/introduction-to-py-torch-13189fb30cb3?source=collection_archive---------7-----------------------

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

(source: https://pytorch.org)

PyTorch 是一个开源的机器学习库,用于开发和训练基于神经网络的深度学习模型。它主要由脸书的人工智能研究小组开发。PyTorch 可以和 Python 以及 C++一起使用。自然,Python 的接口更加完善。Pytorch(由脸书、微软、SalesForce、优步等巨头支持)在研究实验室非常受欢迎。Pytorch 在许多生产服务器上还没有,这些服务器由 TensorFlow(由 Google 支持)这样的 fromeworks 控制,它正在快速发展。

与大多数其他流行的深度学习框架不同,如 TensorFlow ,它们使用静态计算图,PyTorch 使用动态计算,这允许在构建复杂架构时有更大的灵活性。Pytorch 使用了 Python 的核心概念,如类、结构和条件循环——这些概念对我们来说非常熟悉,因此理解起来更加直观。这使得它比 TensorFlow 等引入自己编程风格的其他框架简单得多。

为了对这个库有所了解,让我们来看看 PyTorch 的一个基本实现。

安装 PyTorch

PyTorch 有一个 Windows 版本,但我宁愿远离它。事实上,如果你真的感兴趣,你最好不要再看窗外了。跳到 SageMaker 。而如果你不想花一分钱,就试试 Google Colab

但是如果必须的话,可以在 Anaconda 上安装 PyTorch,使用

现在,让我们从构建神经网络开始。让我们拿起我们的好老 MNIST 数据集。

导入模块

第一步当然是导入相关的库。

收集数据

当然,这个过程的第一步是收集训练模型所需的数据。这里,我们将使用打包到 PyTorch 中的 MNIST 数据集。

这两行是打包了功能的代码。本质上,它从 torchvision.dataset 模块中选取数据集。该数据被归一化,然后加载到张量中。在此基础上,将其装入数据加载器。

建立网络

做完这些,我们从真正的代码开始。如前所述,PyTorch 使用基本的、熟悉的编程范例,而不是发明自己的范例。PyTorch 中的神经网络是一个对象。它是定义这个网络的类的一个实例,继承自 torch.nn 模块

torch.nn .模块提供开发和训练、测试和部署神经网络所需的核心功能。当我们子类化它时,我们通常会覆盖其中的两个方法。框架会处理剩下的事情。

我的意思是。

正如我们所看到的,上面的两种方法给了我们定义神经网络所需要的一切。这个网络有四层(两层隐藏)。前两个是卷积,接下来的两个是线性的、完全连接的层。前三层的激活函数是 Relu,最后一层是 SoftMax。

构造者构建网络。forward()方法定义了它如何向前移动。

训练网络

既然模型已经准备好了,我们就必须使用现有的数据来训练模型。这是通过方法训练()完成的

接收的参数是模型(我们实例化的网络模型)、设备(运行负载的设备 gpu/cpu 的种类)、train_loader(用于训练数据)、优化器(用于训练模型)以及纪元编号(仅用于显示在日志中)。

上面方法中的第一行调用 model.train() —一个从 nn.Module 继承的方法。接下来,我们对从加载器中提取的训练数据批次进行循环。

然后我们初始化优化器。下一行负责正向传播——我们根据当前模型计算输入数据的输出。

接下来的两行负责向后传播。我们通过比较输出和目标来计算损失。然后,我们基于这个损失更新模型。我们对整个数据集都这样做。

测试网络

同样,我们有一个测试方法,可以根据给定的测试数据集来验证网络的性能。

本质上,这种方法只是在整个测试数据中循环,找出所有的损失。它计算正确和错误预测的数量,并打印格式化的日志。

放在一起

有了框架后,我们必须开始将这些片段拼接成一个应用程序,该应用程序可以构建、训练和验证神经网络模型

我们从播种模块开始。

当然,PyTorch(或任何 ML 库)是为 GPU 设计的,但它也可以为 CPU 设计。为了指示执行模式,我们需要实例化设备

下一步是创建我们上面定义的神经网络模型的实例。

下一步是创建一个优化器实例。对于这个例子,我们将使用随机梯度下降来训练这个模型。我们使用 0.01 的学习率和 0.9 的动量

有了舞台设置,剩下的就是用我们拥有的数据来训练网络。

正如我们在教科书中所学的,这是一个 for 循环,它一遍又一遍地向前和向后传播。在每个时期,我们测试我们生成的模型。

与张量流相比,这当然更直观。它的性能成本较低,但研究人员更喜欢 PyTorch 提供的清晰度。

当我们运行上面的代码时,我们得到类似如下的输出:

我们可以看到传入数据的模型训练。我们还可以注意到,该模型在第 9 步之前一直在改进,然后就饱和了——可能过度适应了训练集。我们可以调整超参数来改进这个模型。但我猜 99%对我们的目的来说应该是好的。我们可以使用“提前停止”在步骤 9 中获取模型。

最后,我们保存训练好的模型,以便在现场部署。

当然,这只是一瞥。PyTorch 为不同类型的模型和网络以及不同类型的用例加载了功能。大量的书籍、博客和视频可以给你更多更详细的信息。

他们自己的网站对学习这门学科很有帮助。

PyTorch BigGraph 简介—带示例

原文:https://towardsdatascience.com/introduction-to-pytorch-biggraph-with-examples-b50ddad922b8?source=collection_archive---------6-----------------------

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

Network Photo by Alina Grubnyak on Unsplash

PyTorch BigGraph 是一个为机器学习创建和处理大型图形嵌入的工具。目前在基于图的神经网络中有两种方法:

  • 直接使用图形结构,并将其输入神经网络。然后在每一层都保留图形结构。graphCNNs 使用这种方法,例如参见我的帖子这篇文章
  • 但是大多数图表都太大了。所以创建图的大嵌入也是合理的。然后把它作为传统神经网络的特征。

PyTorch BigGraph 处理第二种方法,下面我们也将这样做。仅供参考,让我们先讨论一下尺寸。图通常由它们的邻接矩阵编码。如果你有一个有 3000 个节点的图,每个节点之间有一条边,那么你的矩阵中就有大约 10000000 个条目。即使这很少,但根据上面链接的论文中的,这显然会使大多数 GPU 崩溃。

如果你想一想推荐系统中常用的图表,你会发现它们通常要大得多。现在已经有一些关于 BigGraph 的方式和原因的优秀帖子,所以我不会在这方面花更多时间。我对将 BigGraph 应用于我的机器学习问题很感兴趣,为此我喜欢举最简单的例子并让事情运转起来。我构建了两个例子,我们将一步一步来看。

整个代码都经过了重构,可以在 GitHub 获得。它改编自 BigGraph 存储库中的示例。

第一个示例是 LiveJournal 图表的一部分,数据如下所示:

# FromNodeId ToNodeId0 1
0 2
0 3
...
0 10
0 11
0 12
...
0 46
1 0
...

第二个例子是简单的带边的 8 个节点:

# FromNodeId ToNodeId
0   1
0   2
0   3
0   4
1   0
1   2
1   3
1   4
2   1
2   3
2   4
3   1
3   2
3   4
3   7
4   1
5   1
6   2
7   3

嵌入 LiveJournals 图形的一部分

BigGraph 是为机器的内存限制而设计的,所以它是完全基于文件的。您必须触发进程来创建适当的文件结构。如果你想再次运行一个例子,你必须删除检查点。我们还必须预先分成训练和测试,再次以文件为基础。文件格式为 TSV,用制表符分隔值。

让我们开始吧。第一段代码声明了两个助手函数,取自 BigGraph 源代码,设置了一些常量并运行文件分割。

helper functions and random_split_file call.

这通过创建两个文件 data/example_1/test.txttrain.txt 将边分成测试和训练集。接下来,我们使用 BigGraphs 转换器为数据集创建基于文件的结构。我们将“分区”成 1 个分区。为此,我们已经需要部分配置文件。这是配置文件的相关部分,I/O 数据部分和图形结构。

entities_base = 'data/example_1' def get_torchbiggraph_config(): config = dict(       
         # I/O data
        entity_path=entities_base,
        edge_paths=[],
        checkpoint_path='model/example_1', # Graph structure
        entities={
            'user_id': {'num_partitions': 1},
        },
        relations=[{
            'name': 'follow',
            'lhs': 'user_id',
            'rhs': 'user_id',
            'operator': 'none',
        }],
...

这告诉 BigGraph 在哪里可以找到我们的数据,以及如何解释我们的制表符分隔的值。有了这个配置,我们可以运行下一个 Python 代码片段。

convert data to _partitioned data.

结果应该是数据目录中的一堆新文件,即:

  • 两个文件夹 test_partitioned,train_partitioned
  • h5 格式的边缘每个文件夹一个文件,用于快速部分读取
  • dictionary.json 文件包含“user_ids”和新分配的 id 之间的映射。
  • entity_count_user_id_0.txt 包含实体计数,在本例中为 47。

dictionary.json 对于稍后将 BigGraph 模型的结果映射到我们想要的实际嵌入非常重要。准备够了,我们来训练嵌入。看一下 config_1.py ,它包含三个相关的部分。

 # Scoring model - the embedding size
        dimension=1024,
        global_emb=False, # Training - the epochs to train and the learning rate
        num_epochs=10,
        lr=0.001, # Misc - not important
        hogwild_delay=2,
    ) return config

为了进行训练,我们运行以下 Python 代码。

train the embedding.

通过这段代码,我们可以根据测试集上预先安装的一些指标来评估模型。

evaluate the embedding.

现在让我们尝试检索实际的嵌入。同样,因为一切都是基于文件的,所以它现在应该位于 models/ 文件夹中的 h5 位置。我们可以通过在字典中查找用户 0 的映射来加载用户 0 的嵌入,如下所示:

output the embedding.

现在让我们转到第二个例子,一个构造好的例子,我们希望可以在这个例子上做一些有用的事情。liveJournal 数据实在太大了,无法在合理的时间内浏览一遍。

对构建示例的链接预测和排序

好的,我们将重复第二个例子的步骤,除了我们将产生一个 10 维的嵌入,所以我们可以查看和使用它。此外,对我来说,10 维对 8 个顶点来说已经足够了。我们在 config_2.py 中设置这些东西。

entities_base = 'data/example_2'
 def get_torchbiggraph_config():
     config = dict(
        # I/O data
        entity_path=entities_base,
        edge_paths=[],
        checkpoint_path='model/example_2', # Graph structure
        entities={
            'user_id': {'num_partitions': 1},
        },
        relations=[{
            'name': 'follow',
            'lhs': 'user_id',
            'rhs': 'user_id',
            'operator': 'none',
        }], # Scoring model
        dimension=10,
        global_emb=False, # Training
        num_epochs=10,
        lr=0.001, # Misc
        hogwild_delay=2,
    )
     return config

然后,我们像以前一样运行相同的代码,但是一次完成,处理不同的文件路径和格式。在这种情况下,我们在数据文件顶部只有 3 行注释:

作为最终输出,你应该得到一堆东西,特别是所有的嵌入。让我们做一些嵌入的基本任务。当然,我们现在可以使用它,并将其加载到我们喜欢的任何框架中, kerastensorflow ,但是 BigGraph 已经为常见任务带来了一些实现,如链接预测排名。所以让我们试一试。第一个任务是链路预测。我们预测实体 0-70-1的得分,因为我们从数据中知道0-1的可能性更大。

作为比较器,我们加载了“DotComparator ”,它计算两个 10 维向量的点积或标量积。结果显示输出的数字很小,但至少 score_2 比 score_1 高得多,正如我们所预期的那样。

最后,作为最后一段代码,我们可以生成一个相似项目的排名,它使用与前面相同的机制。我们使用标量积来计算嵌入到所有其他实体的距离,然后对它们进行排序。

在这种情况下,顶级实体的顺序是 0、1、3、7……如果你观察数据,就会发现这似乎非常正确。

更有趣

这是我能想到的最基本的例子。我没有在 freebase 数据或 LiveJournal 数据上运行原始示例,只是因为它们需要相当长的训练时间。您可以在这里找到代码和参考资料:

你可能遇到的问题

我在 mac 上运行代码,遇到了三个问题:

  • 说明*“lib …”的错误…原因:未找到映像:“解决方案是安装缺少的部分,例如使用“brew install libomp”
  • 然后我遇到了一个错误*“attribute error:模块‘torch’没有属性’ _ six '”*,这可能只是因为不兼容的 python & torch 版本。反正我是从 python 3.6 &火炬 1.1=>python 3.7&火炬 1。X 解决了我的问题。
  • 在您继续之前,检查 train.txt 和 test.txt,我在测试时看到那里有一些丢失的新行。

希望这有所帮助,并且玩起来很有趣!

量子编程导论

原文:https://towardsdatascience.com/introduction-to-quantum-programming-a19aa0b923a9?source=collection_archive---------0-----------------------

从量子位到运行真正的量子程序的量子编程演练!

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

Quantum Computer — Courtesy of Rigetti

问终极电脑存在!量子编程也是!在本文中,我将带您了解开始量子编程所需要知道的一切。我将从一些关于量子计算机与你的笔记本电脑等计算机有何不同的背景开始,然后解释量子编程的基础,并以你今天如何在真正的量子计算机上免费运行程序结束。

在我们开始之前,请注意这篇文章是为那些想学习量子编程全部技术细节的人准备的。这篇文章建立在量子位、量子门和量子电路图的数学基础之上。本文将不解释量子算法或它们的优点,因为那些主题值得它们自己的文章。

因为我们将通过量子编程的基础数学,读者将需要知道什么是向量、矩阵、线性组合和复数。我推荐 3Blue1Brown 学习线性代数,推荐 BetterExplained 学习什么是复数。

量子计算机

让我们从理解量子计算机到底是什么以及它们与其他计算机有何不同开始。

量子计算机是一种使用量子力学进行计算的机器。

那么这和其他电脑有什么不同呢?嗯,计算机,就其最基本的形式而言,只是一种执行计算的机器。有许多不同类型的计算机。在计算机的早期,我们实际上有机械计算机——查尔斯·巴贝奇在 1837 年设计了这样一台机器来执行通用计算。如今,我们的计算机是基于数字电子技术,使用比特和逻辑门操作。相反,量子计算机使用量子力学来执行计算。量子计算机使用的不是比特和逻辑门,而是量子比特和量子门。

那么什么是量子位和量子门呢?在物理上,它们可以是许多不同事物中的任何一种——谷歌、IBM、微软和 Rigetti 都有自己的量子位和量子门实现。目前,我们不会担心量子位和量子门的物理性质,因为在最初学习量子编程时这是不必要的。

量子编程

在我们开始之前,我强烈推荐你在 干净的精神石板 上接近量子编程。不要去寻找如何声明和设置变量,循环代码,创建函数等。你对编程的任何先入之见可能 不会 有用。量子编程不仅仅是让我们现有的程序运行得更快的某种方式——量子编程与当代编程有着根本的不同。

理解量子位

先说 什么是 一个量子位。

一个量子位是两个单位长度复数的向量。

让我们看看 为什么 量子位是这样的,以及的真正含义。量子位与比特有很大不同。对于初学者来说,一个位要么是 0,要么是 1。这里没有概率,要么已知是 0,要么已知是 1。相反,一个量子位天生就是概率性的,这意味着两个 相同的 量子位一旦被测量,可能会有 不同的 值!花点时间认真考虑一下这件事的严重性。这意味着量子计算天生就是概率性的。

这是第二个关键区别。有了位,我们可以任意多次读取该位,而不会影响该位的状态。但是有了量子比特,一旦被测量,它 解聚 (失去量子属性),坍缩到两个可测量状态中的一个(因此才有了‘量子比特’中的‘比特’)。因此,我们不能“不测量”一个量子位;一旦测得,量子性质为 被破坏 无法恢复。我们使用两个数字来量化测量量子位的概率性质:|𝛼|,量子位被测量为 0 的概率,和|𝛽|,量子位被测量为 1 的概率。

尽管|𝛼|和|𝛽|反映了量子位将被 测量为 的概率,我们认为一个量子位的内部状态是两个“概率振幅”,𝛼和𝛽.这些是复数,定义了 0 和 1 之间的叠加(叠加是线性组合),不能测量*。***

换句话说,我们把一个量子位想象成两个单位长度复数的向量(向量的长度等于 1)。我们可以简明地用下图所示的数学来表达这一点(包含α和β的向量就是量子位;α和β上方的柱表示复共轭):

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

概括地说,量子位是两个复数的向量,𝛼和𝛽,其中向量有单位长度。量子位被测量为 0 的概率等于|𝛼|𝛼的平方。量子位被测量为 1 的概率等于|𝛽|𝛽的平方。一个量子位的状态,𝛼和𝛽,是无法测量的。只有一个量子位坍缩成的值才能被测量。

量子位符号

我们经常用 狄拉克符号 来表示量子位,也称为 布拉基特符号 。这种符号只是写向量的一种方便的方法。bra 表示行向量,记为⟨ ∣;ket 代表列向量,被标为∣ ⟩。例如,我们可以用 Bra-ket 符号写一个量子位的‘0’和‘1’状态如下(注意不要把 bra/ket 里面的东西和 vector 里面的东西搞混了!):

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

量子位既可以处于 纯态 也可以处于 混合态 。如果一个量子位的状态可以用∣0⟩∣1⟩的线性组合来完全描述,那么我们说它处于纯态。我们通常用以下符号表示纯态量子位:

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

这里有一些纯态量子位的例子和表示它们的常用简写。

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

其他量子比特需要纯态的混合才能完整描述,所以我们称之为混合态量子比特。换句话说,混合态量子位由纯态的概率分布来描述。我们将在本文后面看到一个混合态量子位的例子(我会指出来)。

多量子位

到目前为止,我们只定义了单个量子位的状态。多个量子位 的组合 态是什么样子的?

多个量子位的组合状态是所有量子位的张量积。

不知道张量积是什么也不用担心;我们将通过一个例子(⊗是张量积运算的符号)。

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

一般来说,我们可以通过以下两个步骤来张量积任何两个矩阵:

  1. 标量将第一个矩阵中的每个元素乘以整个第二个矩阵
  2. 根据元素的原始位置组合生成的矩阵

下面是第二个例子,说明它如何适用于二维矩阵:

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

例如,我们也可以用 Bra-ket 符号表示多个量子位为∣0⟩⊗∣1⟩。作为速记,我们可以省略⊗,只写∣0⟩∣1⟩。作为更短的速记,我们可以只写一个偈,∣01⟩

理解量子门

现在让我们考虑一下 什么是 量子门。

量子门是酉矩阵。

让我们来了解一下 为什么 量子门是酉矩阵。首先,量子门将由物理设备实现,因此它们必须遵守量子物理定律。一个相关的物理定律是,当在过去和未来之间转换时,信息不会丢失。这就是所谓的单一性。既然我们的量子门定义了我们如何在状态间转换,它们也必须遵守么正性。

其次,注意我们的量子门将应用于量子比特。我们之前了解到量子位实际上只是向量,因此这意味着量子门必须以某种方式对向量进行操作。幸运的是,我们记得矩阵实际上只是向量的线性变换!

结合这两个想法,我们把量子门想象成 酉矩阵 。酉矩阵是任意复数方阵,使得 共轭转置 等于其 。快速复习一下,矩阵的共轭转置是通过取矩阵中每个元素的共轭(a + bia — bi),然后取矩阵的转置(元素 ij →元素 ji)得到的。我们通常用匕首表示共轭转置。

关于酉矩阵的一个关键观察是,它们 保持范数 (向量的长度)。假设我们允许改变常态的门,那麽我们量子位元的机率总和可能不是 1!这没有意义,因为所有概率的总和必须总是等于 1。

还要注意,根据定义,酉矩阵有一个逆。这意味着我们不能将量子比特“分配”到任意的状态。为了理解为什么不能,让我们假设我们确实有一个量子门,可以“分配”值,因此,将两个复数的任何向量转换为两个复数的特定向量。这个量子门将会有一些作为酉矩阵的基本表示,而这个矩阵将会有一个逆,能够将一个特定的向量转换回运算前量子位的任何状态!但是量子位在手术前可能处于任何状态,没有办法知道是哪种状态!因此,我们无法将量子位元「指派」到任意的状态。在更高的层面上,所有量子门都是可逆的事实,就是为什么我们经常把量子计算看成是 可逆计算 的一种形式。

最后,请注意,因为我们的量子门是酉矩阵,根据定义,它们是 ,所以我们的量子门必须具有 相等的 个输入和输出量子位(因为方矩阵将 n 个标准基向量映射到 n 列)!这与大多数逻辑门大相径庭;例如,门接受两个输入并产生一个输出。

H 和 CNOT 量子门

现在我们知道了一点我们正在做的事情,让我们考虑一个例子, 哈达玛门 ,h

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

我们可以通过检查共轭转置等于其逆矩阵来检查 H 是否是酉的,或者换句话说,H 乘以其共轭转置等于单位矩阵:

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

另一个重要的量子门是 受控非门 ,也被称为 CNOT。CNOT 作用于两个量子位,一个控制量子位和一个目标量子位。我们可以把 CNOT 想象成一个*‘if 语句’*——如果控制量子位等于 1,那么 CNOT 对目标量子位应用 NOT(逆门)(因此得名,受控 NOT)。

这是代表 CNOT 的矩阵。这个矩阵将控制量子位视为 ket 中最右边的值,将目标量子位视为最左边的值。

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

我们来看看它对∣00⟩的影响。

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

在这个例子中,我们看到 CNOT 没有修改∣00⟩的值。这是预期的行为,因为 CNOT 只在控件为 1 时反转目标。

让我们看看它对∣01⟩的影响。

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

在这里,我们可以看到控制等于 1,所以 CNOT 反转目标。因此,结果是∣11⟩

试着解决另外两种情况,∣10⟩∣11⟩。你应该发现 CNOT 有以下行为:

  • ∣00⟩ -> ∣00⟩
  • ∣01⟩ -> ∣11⟩
  • ∣10⟩ -> ∣10⟩
  • ∣11⟩ -> ∣01⟩

请注意,当控制位为 1 时,这正是对目标位应用 NOT 的行为。

概括地说,我们可以把量子门想象成酉矩阵。这种单一性加强了一个量子位的概率总和为 1 的约束,并使量子计算是可逆的。由于酉矩阵是正方形的,我们发现量子门必须有相等数量的输入和输出量子位。我们学习了哈达玛和 CNOT,这是两个重要的量子门。存在更多的量子门。

量子电路图

现在我们知道了量子位和量子门的基础知识,让我们来看看我们的第一个量子电路图。

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

量子电路图是我们思考量子“程序”的方式。我们将量子位定义为行,从左到右依次应用量子门。

让我们看一下这张图的每一部分。首先,我们有两个量子位。每行对应一个量子位。顶行对应于名为 x0 的量子位,而底行对应于名为 x1 的量子位。我们认为 x0 是第 0 个量子位,因为我们从 0 开始计数(与编程的其余部分相同)。我们将x0 : ∣0⟩x1 : ∣0⟩ 写成表示x0x1从状态∣0⟩开始。

H是 Hadamard 门,被应用于量子位 x0。●-⊕是 CNOT 门,是控制量子位,是目标量子位。-只是帮助我们看到哪两个量子位受到影响。换句话说,我们正在应用 CNOT,其中控制是量子位 x0,目标是 x1。注意,我们应用这些门的顺序很重要。在这个图表中,我们首先应用了 H,然后应用了 CNOT。

翻译量子电路图

量子电路图只是我们程序的一种表示。它帮助我们思考我们的量子计算,但其他表示也可能是有用的。我们可以把我们的图表翻译成一串符号,这有助于我们准备把它写成计算机代码。以字符串的形式存在也使得它很容易转化为底层的数学。这个数学将告诉我们程序的预期输出。

让我们从将图表转换成一串符号开始。我们将使用 Bra-ket 符号,而不是将量子位写成行。第 0 个量子位将是∣00⟩中最右边的量子位,就像写出二进制数时一样。这意味着量子位 x1 是∣00⟩中最左边的量子位。(注意,量子物理的人倾向于颠倒这种顺序。总是检查量子位排序,因为它是 难以置信的 常见错误来源。)

我们还需要翻译大门。由于我们将H应用于量子位 x0,而不对量子位 x1 应用任何东西(这相当于应用了身份门I),我们将把它写成(I⊗H)。最后,我们翻译 CNOT,指定哪个量子位是控制,哪个是目标。结果是CNOT[control=0, target=1] (I⊗H) ∣00⟩ (注意,这个字符串是从右向左读取的)。太好了!这在编写量子计算机上运行的代码时会很有用。

写出潜在的数学

有了量子电路图的字符串表示,就很容易把我们的程序翻译成底层的数学。有三件,CNOT[control=0, target=1](I⊗H)∣00⟩。每个片段都可以转换成矩阵,如下图的第一行所示:

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

我们甚至可以将矩阵相乘来找到结果状态向量,如上所示。这个状态向量就是量子计算完成后,我们两个量子位的预期状态。或者,我们可以认为它是我们程序的输出。它告诉我们每个可测状态的概率幅度。

还有,还记得我们的混合态量子比特吗?注意,我们不能再写纯态的量子位 x0 和 x1,因为没有办法用张量积分解矢量。所以我们的量子位处于混合状态!

测量状态向量

如果我们现在测量我们的量子位会怎么样?我们会收到什么?我们可以通过将状态向量分解成每个可测状态来找出答案。我们将在 标准基 中测量我们的量子位,也称为∣0⟩∣1⟩(我们可以在其他基中测量,但现在不用担心)。因此,我们的两个量子位系统的可测量状态是∣00⟩∣01⟩∣10⟩∣11⟩

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

我们可以确定测量值的概率,就像我们 used|𝛼|确定单个量子位的∣0⟩的概率一样。由于∣01⟩∣10⟩的概率幅度为 0,我们知道我们永远无法测量那个状态。并且我们将以概率(1/sqrt(2)) = 1/2 来度量∣00⟩∣11⟩

现在,假设我们把这两个量子位分开一个很大的距离,然后我们测量其中一个。当我们测量它的时候,我们也会知道另一个量子位的值!这是因为我们知道量子位只能是∣00⟩或者∣11⟩

这就是爱因斯坦所说的‘幽灵般的超距作用’,也被称为 量子纠缠 。我们认为信息是相互关联的,而不是相互传播的。如果它在旅行,那么它可能会比光速更快,这打破了物理定律。

运行在量子计算机上

现在我们已经了解了量子位、量子门和量子电路图的幕后发生的事情,让我们看看如何在真正的量子计算机上运行。我将使用 Rigetti 的量子计算机,因为他们目前正在向 beta 用户发放免费积分。或者,我们也可以使用 IBM 的量子计算机

以下是 Rigetti 量子编程过程的基本概述:

  1. 写一个 Python 程序,指定你的量子电路和任何必要的附加代码
  2. 使用量子模拟器测试 Python 程序
  3. 在里盖蒂的量子计算机上预留时间
  4. 把你的程序发送到里盖蒂的服务器上
  5. 在 Rigetti 的服务器上执行你的程序(他们会把你的量子程序发给他们的量子计算机)

这是我们上面的量子电路图的 Python 版本。

结果将与此类似:

**[(0, 0), (1, 1), (1, 1), (0, 0), (0, 0), (0, 0), (1, 1), (0, 0), (0, 0), (1, 1)]
[(0, 0), (0, 1), (1, 1), (1, 1), (1, 1), (0, 0), (0, 0), (1, 1), (1, 0), (0, 0)]**

第一行对应于模拟器,结果似乎是合理的——大约一半时间我们得到[0,0],其余时间得到[1,1]。但是,用真正的量子计算机,除了预期的[0,0]和[1,1],我们还接收到[0,1]和[1,0]。根据数学,我们应该只接收[0,0]和[1,1],那么这是怎么回事呢?

问题是今天(2019 年 7 月)真正的量子计算机仍然很容易出错。⁴举例来说,当我们试图将量子位初始化为 0 时,我们可能会看到 2–3%的错误率。每一个单量子比特的门操作可能会有 1-2%的错误率,而两量子比特的门操作可能会有 3-4%的错误率。在测量量子位时,我们甚至有误差率!实际上,这些误差累积起来会导致不正确的值。

关闭

在这篇文章中,我们了解到量子计算机今天确实存在并工作,尽管错误率相当高。虽然这些机器的物理实现在不同的公司之间有很大的不同,但是对它们进行编程的许多概念是相同的。

我们认为量子位是两个单位长度的复数的向量,我们认为量子门是酉矩阵。我们记得量子计算是概率性的,因为两个相同的量子位一旦被测量就可能有不同的值。由于量子门是酉的,我们知道量子计算本质上是可逆的。在高层次上,我们可以将量子编程视为复数上的应用线性代数。

我们使用量子电路图来表示我们的量子程序,然后将其转换为 Python,以便在真实的量子计算机上运行。

我希望你学到了一些东西,我很高兴听到你的任何意见或建议!

常见问题解答

问:我用谷歌搜索了 CNOT 的矩阵表,它看起来和你的不一样,为什么?

a)如果你在看[[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]],这是因为他们颠倒了目标和控制量子位的排序。如果你看到的不是我在上面或者这篇文章里写的,那么它就是错的。

问:那么我们有了常规计算机的比特和三比特,量子比特是否存在类似的东西?

a)是的,qutrits。量子位是两能级量子系统的一部分。量子是三能级量子系统的一部分。还有 qudits,它概括了级别的数量。

参考

[1] L. Susskind,第一讲量子纠缠,第一部分 (2008)

[2]Qiskit 中的基向量排序 (2019),Qiskit

[3]r·史密斯,有人大喊“01000”!谁激动了? (2017),arxiv

[4] 量子比特质量 (2019),量子计算报告

推荐系统简介

原文:https://towardsdatascience.com/introduction-to-recommender-systems-6c66cf15ada?source=collection_archive---------0-----------------------

几种主要推荐算法综述。

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

Credit: StockSnap on Pixabay

本帖与 约瑟夫·罗卡 共同撰写。

介绍

在过去的几十年里,随着 Youtube、亚马逊、网飞和许多其他类似的网络服务的兴起,推荐系统在我们的生活中占据了越来越多的位置。从电子商务(向买家推荐他们可能感兴趣的文章)到在线广告(向用户推荐合适的内容,符合他们的偏好),推荐系统在我们日常的在线旅程中是不可避免的。

一般来说,推荐系统是一种算法,旨在向用户建议相关的项目(项目可以是要看的电影、要读的文本、要买的产品或任何其他取决于行业的东西)。

推荐系统在一些行业中非常重要,因为当它们有效时,可以产生大量的收入,或者是从竞争对手中脱颖而出的一种方式。作为推荐系统重要性的证明,我们可以提到,几年前,网飞组织了一次挑战(“网飞奖”),目标是产生一个比自己的算法性能更好的推荐系统,并赢得 100 万美元的奖金。

在这篇文章中,我们将介绍推荐系统的不同范例。对于它们中的每一个,我们将介绍它们是如何工作的,描述它们的理论基础并讨论它们的优点和缺点。

概述

在第一部分,我们将概述推荐系统的两个主要范例:协作和基于内容的方法。接下来的两节将描述各种各样的协同过滤方法,比如用户-用户、项目-项目和矩阵分解。下一节将专门介绍基于内容的方法及其工作原理。最后,我们将讨论如何评估一个推荐系统。

协作与内容

推荐系统的目的是向用户推荐相关的项目。为了完成这个任务,存在两大类方法:协同过滤方法和基于内容的方法。在深入研究特定算法的细节之前,让我们简单讨论一下这两个主要范例。

协同过滤方法

用于推荐系统的协作方法是仅基于用户和项目之间记录的过去交互来产生新推荐的方法。这些交互存储在所谓的“用户-项目交互矩阵”中。

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

Illustration of the user-item interactions matrix.

然后,规则协作方法的主要思想是,这些过去的用户-项目交互足以检测相似的用户和/或相似的项目,并基于这些估计的接近度做出预测。

协同过滤算法类分为两个子类别,一般称为基于记忆和基于模型的方法。基于记忆的方法直接与记录的交互值一起工作,假设没有模型,并且本质上基于最近邻居搜索(例如,从感兴趣的用户中找到最近的用户,并且在这些邻居中建议最受欢迎的项目)。基于模型的方法假设一个潜在的“生成”模型,该模型解释用户-项目交互并试图发现它以便做出新的预测。

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

Overview of the collaborative filtering methods paradigm.

协作方法的主要优点是它们不需要关于用户或项目的信息,因此,它们可以在许多情况下使用。此外,用户与项目的交互越多,新的推荐就越准确:对于一组固定的用户和项目,随着时间的推移记录的新交互会带来新的信息,并使系统越来越有效。

然而,由于它仅考虑过去的交互来进行推荐,协同过滤遭受“冷启动问题”:它不可能向新用户推荐任何东西或向任何用户推荐新项目,并且许多用户或项目具有太少的交互而不能被有效地处理。这个缺点可以用不同的方式来解决:向新用户推荐随机项目或者向随机用户推荐新项目(随机策略),向新用户推荐流行项目或者向最活跃的用户推荐新项目(最大期望策略),向新用户推荐一组各种项目或者向一组各种用户推荐新项目(探索策略),或者最后,在用户或者项目的早期使用非协作方法。

在下面的章节中,我们将主要介绍三种经典的协同过滤方法:两种基于记忆的方法(用户-用户和项目-项目)和一种基于模型的方法(矩阵分解)。

基于内容的方法

与仅依赖于用户-项目交互的协作方法不同,基于内容的方法使用关于用户和/或项目的附加信息。如果我们考虑电影推荐系统的例子,这个附加信息可以是例如用户的年龄、性别、工作或任何其他个人信息,以及电影(项目)的类别、主要演员、持续时间或其他特征。

然后,基于内容的方法的思想是试图建立一个模型,基于可用的“特征”,解释观察到的用户-项目交互。仍然考虑用户和电影,我们将尝试,例如,模拟年轻女性倾向于更好地评价一些电影,年轻男性倾向于更好地评价一些其他电影,等等。如果我们设法得到这样的模型,那么,为用户做出新的预测是相当容易的:我们只需要看看这个用户的个人资料(年龄、性别等),并根据这些信息,确定相关的电影建议。

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

Overview of the content based methods paradigm.

基于内容的方法比协作方法更少遭受冷启动问题:新用户或项目可以通过它们的特征(内容)来描述,因此可以为这些新实体提供相关建议。只有新用户或具有以前看不到的功能的项目才会在逻辑上遭受这种缺点,但是一旦系统足够老,这种情况就很少或没有机会发生。

在这篇文章的后面,我们将进一步讨论基于内容的方法,并看到,根据我们的问题,可以使用各种分类或回归模型,从非常简单到复杂得多的模型。

模型、偏差和方差

让我们更关注前面提到的方法之间的主要区别。更具体地说,让我们看看建模水平对偏差和方差的影响。

在基于记忆的协作方法中,没有假设潜在模型。该算法直接处理用户-项目交互:例如,用户通过他们与项目的交互来表示,并且使用对这些表示的最近邻搜索来产生建议。由于没有假设潜在模型,这些方法理论上具有低偏差但高方差。

在基于模型的协作方法中,假设了一些潜在的交互模型。该模型被训练成从其自己的用户和项目的表示来重建用户-项目交互值。然后可以根据这个模型提出新的建议。由该模型提取的用户和项目潜在表示具有人类难以解释的数学含义。由于假设了用户-项目交互的(相当自由的)模型,这种方法在理论上比假设没有潜在模型的方法具有更高的偏差但更低的方差。

最后,在基于内容的方法中,还假设了一些潜在的交互模型。然而,在这里,模型提供了定义用户和/或项目的表示的内容:例如,用户由给定的特征来表示,并且我们尝试为每个项目建模喜欢或不喜欢该项目的用户简档的种类。这里,对于基于模型的协作方法,假设了用户-项目交互模型。然而,该模型更受限制(因为用户和/或项目的表示是给定的),因此,该方法倾向于具有最高的偏差但最低的方差。

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

Summary of the different types of recommender systems algorithms.

基于记忆的协作方法

用户-用户和项目-项目的主要特征在于,它们仅使用来自用户-项目交互矩阵的信息,并且它们假设没有模型来产生新的推荐。

用户-用户

为了向用户做出新的推荐,用户-用户方法粗略地尝试识别具有最相似的“交互简档”(最近邻居)的用户,以便建议在这些邻居中最受欢迎的项目(并且对我们的用户来说是“新的”)。这种方法被称为“以用户为中心”,因为它基于用户与项目的交互来表示用户,并评估用户之间的距离。

假设我们想为一个给定的用户做推荐。首先,每个用户都可以通过其与不同项目的交互向量来表示(交互矩阵中的“其行”)。然后,我们可以计算我们感兴趣的用户和其他用户之间的某种“相似性”。该相似性度量使得对相同项目具有相似交互的两个用户应该被认为是接近的。一旦计算了与每个用户的相似性,我们可以保留与我们的用户最近的 k 个邻居,然后推荐其中最受欢迎的项目(只查看我们的参考用户还没有与之交互的项目)。

请注意,当计算用户之间的相似性时,“共同交互”的数量(多少项目已经被两个用户考虑过?)要慎重考虑!事实上,大多数时候,我们希望避免与我们的参考用户只有一个共同交互的人可能有 100%的匹配,并被认为比有 100 个共同交互并“只”同意其中 98%的人“更接近”。因此,我们认为两个用户是相似的,如果他们以相同的方式与许多共同的项目交互(相似的评级,相似的时间悬停…)。

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

Illustration of the user-user method. The same colour code will be used in the remaining of the post.

项目-项目

为了向用户进行新的推荐,项目-项目方法的思想是找到与用户已经“积极地”交互过的项目相似的项目。如果与两个项目交互的大多数用户以相似的方式进行交互,那么这两个项目被认为是相似的。这种方法被称为“以项目为中心”,因为它基于用户与项目的交互来表示项目,并评估这些项目之间的距离。

假设我们想为一个给定的用户做推荐。首先,我们考虑这个用户最喜欢的项目,并通过它与每个用户的交互向量(交互矩阵中的“它的列”)来表示它(和所有其他项目一样)。然后,我们可以计算“最佳项目”和所有其他项目之间的相似性。一旦计算出相似性,我们就可以保留对我们感兴趣的用户来说是新的所选“最佳项目”的 k 个最近邻居,并推荐这些项目。

请注意,为了获得更多相关的推荐,我们可以不仅仅针对用户最喜欢的项目进行这项工作,而是考虑 n 个首选项目。在这种情况下,我们可以推荐与这些首选项目中的几个接近的项目。

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

Illustration of the item-item method.

比较用户-用户和项目-项目

用户-用户方法基于在与项目的交互方面搜索相似的用户。因为,一般来说,每个用户只与几个项目交互,这使得该方法对任何记录的交互非常敏感(高方差)。另一方面,由于最终推荐仅基于为与我们感兴趣的用户相似的用户记录的交互,所以我们获得了更个性化的结果(低偏差)。

相反,条目-条目方法基于在用户-条目交互方面搜索相似条目。一般来说,由于许多用户已经与一个项目进行了交互,所以邻域搜索对单个交互的敏感度要低得多(方差更低)。作为对应,来自各种用户(甚至是与我们的参考用户非常不同的用户)的交互在推荐中被考虑,使得该方法不那么个性化(更有偏见)。因此,这种方法没有用户对用户的方法那么个性化,但是更加健壮。

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

Illustration of the difference between item-item and user-user methods.

复杂性和副作用

基于记忆的协同过滤的最大缺陷之一是它们不容易扩展:对于大型系统来说,生成一个新的推荐是非常耗时的。事实上,对于具有数百万用户和数百万项目的系统,如果不仔细设计,最近邻居搜索步骤会变得难以处理(KNN 算法的复杂度为 O(ndk ),其中 n 是用户数量,d 是项目数量,k 是考虑的邻居数量)。为了使大型系统的计算更易处理,我们可以在设计算法时利用交互矩阵的稀疏性,或者使用近似最近邻方法(ANN)。

在大多数推荐算法中,有必要非常小心,以避免流行项目的“越来越丰富”效应,并避免让用户陷入所谓的“信息限制区”。换句话说,我们不希望我们的系统倾向于推荐越来越多的流行项目,我们也不希望我们的用户只收到与他们已经喜欢的项目非常接近的项目的推荐,而没有机会了解他们可能也喜欢的新项目(因为这些项目不够“接近”以至于不能被建议)。正如我们提到的,如果这些问题会出现在大多数推荐算法中,那么对于基于记忆的协作算法来说尤其如此。事实上,由于缺乏“规范化”的模式,这种现象可能会更频繁地被强调和观察。

基于模型的协作方法

基于模型的协作方法仅依赖于用户-项目交互信息,并假设一个潜在模型来解释这些交互。例如,矩阵分解算法包括将庞大且稀疏的用户-项目交互矩阵分解成两个更小且密集的矩阵的乘积:用户因素矩阵(包含用户表示)乘以因素-项目矩阵(包含项目表示)。

矩阵分解

矩阵分解背后的主要假设是,存在一个非常低维的特征潜在空间,其中我们可以表示用户和项目,并且用户和项目之间的交互可以通过计算该空间中相应密集向量的点积来获得。

例如,考虑我们有一个用户电影评级矩阵。为了对用户和电影之间的交互进行建模,我们可以假设:

  • 存在一些很好地描述(和区分)电影的特征。
  • 这些特征也可以用于描述用户偏好(高值表示用户喜欢的特征,低值表示用户不喜欢)

然而,我们不想给我们的模型显式地提供这些特性(因为对于我们将在后面描述的基于内容的方法,这是可以做到的)。相反,我们更喜欢让系统自己发现这些有用的特性,并对用户和项目做出自己的表示。由于它们是习得的而不是给定的,单独提取的特征具有数学意义,但没有直观的解释(因此,很难(如果不是不可能的话)被人类理解)。然而,从这种算法中产生的结构非常接近人类可以想到的直觉分解,这并不罕见。事实上,这种分解的结果是,就偏好而言接近的用户以及就特征而言接近的项目最终在潜在空间中具有接近的表示。

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

Illustration of the matrix factorization method.

矩阵分解的数学

在这一小节中,我们将给出矩阵分解的一个简单的数学概述。更具体地说,我们描述了一种基于梯度下降的经典迭代方法,这种方法可以获得非常大的矩阵的分解,而无需将所有数据同时加载到计算机的存储器中。

让我们考虑评级的交互矩阵 M (nxm ),其中只有一些项目被每个用户评级(大多数交互被设置为无以表示缺少评级)。我们想分解这个矩阵

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

其中 X 是“用户矩阵”(nxl),其行代表 n 个用户,Y 是“项目矩阵”(mxl),其行代表 m 个项目:

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

这里 l 是潜在空间的维度,其中用户和项目将被表示。因此,我们寻找矩阵 X 和 Y,它们的点积最接近现有的相互作用。表示 E 对(I,j)的系综,使得 M_ij 被设置(不是没有),我们想要找到最小化“评级重构误差”的 X 和 Y

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

添加正则化因子并除以 2,我们得到

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

矩阵 X 和 Y 可以通过梯度下降优化过程获得,我们可以注意到两件事。首先,不必在每一步计算 E 中所有对的梯度,我们可以只考虑这些对的一个子集,这样我们可以“分批”优化我们的目标函数。第二,X 和 Y 中的值不必同时更新,梯度下降可以在每一步在 X 和 Y 上交替进行(这样做时,我们认为一个矩阵是固定的,并在下一次迭代中进行相反的操作之前为另一个矩阵进行优化)。

一旦矩阵被因式分解,我们就有更少的信息来操作以做出新的推荐:我们可以简单地将用户向量乘以任何项目向量,以估计相应的评级。请注意,我们还可以使用用户-用户和项目-项目方法来表示用户和项目:(近似)最近邻搜索不会在巨大的稀疏向量上进行,而是在小的密集向量上进行,这使得一些近似技术更容易处理。

矩阵分解的扩展

我们最终可以注意到,这种基本分解的概念可以扩展到更复杂的模型,例如,更通用的神经网络,如“分解”(我们不能再严格地谈论“分解”)。我们能想到的第一种直接适应关系到布尔交互。如果我们想要重建布尔交互,简单的点积并不适合。然而,如果我们在点积的基础上添加一个逻辑函数,我们会得到一个取值为[0,1]的模型,因此,更适合这个问题。在这种情况下,要优化的模型是

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

用 f(。)我们的后勤职能。在复杂的推荐系统中,更深层次的神经网络模型经常被用来实现接近现有技术水平的性能。

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

Matrix factorization can be generalized with the use of a model on top of users and items embeddings.

基于内容的方法

在前两节中,我们主要讨论了用户-用户、项目-项目和矩阵分解方法。这些方法仅考虑用户-项目交互矩阵,因此属于协同过滤范例。现在让我们描述一下基于内容的范例。

基于内容的方法的概念

在基于内容的方法中,推荐问题被分为分类问题(预测用户是否“喜欢”某个项目)或回归问题(预测用户对某个项目的评分)。在这两种情况下,我们都将设置一个基于用户和/或项目特征的模型(我们的“基于内容”方法的“内容”)。

如果我们的分类(或回归)是基于用户的特征,我们说这种方法是以项目为中心的:建模、优化和计算可以“按项目”进行。在这种情况下,我们基于用户特征逐个项目地构建和学习一个模型,试图回答“每个用户喜欢这个项目的概率是多少?”(或者“每个用户给这个物品的评分是多少?”,用于回归)。与每个项目相关联的模型自然地在与该项目相关的数据上被训练,并且一般来说,它导致相当健壮的模型,因为许多用户已经与该项目进行了交互。然而,被考虑来学习模型的交互来自每个用户,并且即使这些用户具有相似的特性(特征),他们的偏好也可能不同。这意味着,即使这种方法更健壮,它也可以被认为比以用户为中心的方法更不个性化(更有偏见)。

如果我们正在处理项目特征,那么这个方法就是以用户为中心的:建模、优化和计算可以由“用户”来完成。然后,我们根据项目特征按用户训练一个模型,试图回答问题“这个用户喜欢每个项目的概率是多少?”(或者“这个用户给每个项目的评分是多少?”,用于回归)。然后,我们可以为每个接受数据训练的用户建立一个模型:由于该模型只考虑了被考虑用户的互动,因此比以商品为中心的模型更加个性化。然而,大多数时候,用户与相对较少的项目进行交互,因此,我们获得的模型远不如以项目为中心的模型健壮。

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

Illustration of the difference between item-centred and user-centred content based methods.

从实践的角度来看,我们应该强调的是,在大多数情况下,向新用户询问一些信息(用户不想回答太多问题)比询问大量关于新项目的信息(添加他们的人有兴趣填写这些信息,以便将他们的项目推荐给正确的用户)要困难得多。我们还可以注意到,根据要表达的关系的复杂性,我们建立的模型可以或多或少地复杂,范围从基本模型(用于分类/回归的逻辑/线性回归)到深度神经网络。最后,让我们提一下,基于内容的方法也可以既不以用户为中心也不以项目为中心:关于用户和项目的信息都可以用于我们的模型,例如通过堆叠两个特征向量并使它们通过神经网络架构。

以项目为中心的贝叶斯分类器

让我们首先考虑以项目为中心的分类的情况:对于每个项目,我们希望训练一个贝叶斯分类器,它将用户特征作为输入,输出“喜欢”或“不喜欢”。因此,为了完成分类任务,我们需要计算

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

具有给定特征的用户喜欢所考虑的项目的概率和不喜欢它的概率之间的比率。定义我们的分类规则(具有简单阈值)的条件概率的比率可以按照贝叶斯公式来表示

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

在哪里

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

先验是从数据中计算出来的

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

假设可能性遵循高斯分布,参数也由数据确定。可以对这两种似然分布的协方差矩阵进行各种假设(无假设、矩阵相等、矩阵相等和特征独立),从而产生各种众所周知的模型(二次判别分析、线性判别分析、朴素贝叶斯分类器)。我们可以再次强调,在这里,可能性参数必须仅基于与所考虑的项目相关的数据(相互作用)来估计。

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

Illustration of the item-centred content based Bayesian classifier.

用户为中心的线性回归

现在让我们考虑以用户为中心的回归的情况:对于每个用户,我们希望训练一个简单的线性回归,它将项目特征作为输入,并输出该项目的评级。我们仍然将 M 表示为用户-项目交互矩阵,我们将表示要学习的用户系数的 X 行向量堆叠成矩阵,并将表示给定项目特征的 Y 行向量堆叠成矩阵。然后,对于给定的用户 I,我们通过求解以下优化问题来学习 X_i 中的系数

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

我们应该记住,I 是固定的,因此,第一次求和只针对与用户 I 相关的(用户,项目)对。我们可以观察到,如果我们同时为所有用户解决这个问题,优化问题与我们在“交替矩阵分解”中解决的问题完全相同,当我们保持项目固定时。这种观察强调了我们在第一部分中提到的联系:基于模型的协作过滤方法(例如矩阵分解)和基于内容的方法都假设用户-项目交互的潜在模型,但是基于模型的协作方法必须学习用户和项目的潜在表示,而基于内容的方法基于用户和/或项目的人类定义的特征建立模型。

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

Illustration of the user-centred content based regression.

推荐系统的评价

至于任何机器学习算法,我们需要能够评估我们的推荐系统的性能,以便决定哪个算法最适合我们的情况。推荐系统的评价方法主要可以分为两类:基于良好定义的度量的评价和主要基于人的判断和满意度估计的评价。

基于度量的评估

如果我们的推荐系统是基于输出数值的模型,例如评级预测或匹配概率,我们可以使用误差测量度量,例如均方误差(MSE ),以非常经典的方式评估这些输出的质量。在这种情况下,模型仅在一部分可用的交互上被训练,并在剩余的交互上被测试。

然而,如果我们的推荐系统基于预测数值的模型,我们也可以用经典的阈值方法将这些值二进制化(阈值以上的值为正,阈值以下的值为负),并以更“分类的方式”评估模型。事实上,由于用户-项目过去交互的数据集也是二进制的(或者可以通过阈值化来二进制化),因此我们可以在不用于训练的交互的测试数据集上评估模型的二进制化输出的准确性(以及精度和召回率)。

最后,如果我们现在考虑一个不基于数值的推荐系统,它只返回一个推荐列表(例如基于 knn 方法的用户-用户或项目-项目),我们仍然可以通过估计真正适合我们用户的推荐项目的比例来定义一个类似精度的度量。为了估计这个精度,我们不能考虑用户没有与之交互的推荐项目,我们应该只考虑来自测试数据集中有用户反馈的项目。

基于人的评估

在设计推荐系统时,我们感兴趣的不仅仅是获得能够产生我们非常确定的推荐的模型,我们还可以期待其他一些好的特性,比如推荐的多样性和可解释性。

正如在协作部分提到的,我们绝对希望避免让用户陷入我们之前称之为信息封闭的区域。“意外发现”的概念经常被用来表达一个模型有或没有创建这样一个限制区域的趋势(推荐的多样性)。可以通过计算推荐项目之间的距离来估计的意外收获,不应该太低,因为这会产生限制区域,但也不应该太高,因为这意味着我们在进行推荐时没有充分考虑用户的兴趣(探索与开发)。因此,为了在建议的选择中带来多样性,我们想要推荐既非常适合我们的用户又彼此不太相似的项目。例如,与其向用户推荐“开始战争”1、2 和 3,不如推荐“星球大战 1”、“开始黑暗之旅”和“印第安纳琼斯和夺宝奇兵”:后两者可能会被我们的系统视为用户不太感兴趣,但推荐看起来太相似的 3 个项目并不是一个好的选择。

可解释性是推荐算法成功的另一个关键点。事实上,已经证明,如果用户不理解他们为什么被推荐为特定项目,他们倾向于对推荐系统失去信心。因此,如果我们设计了一个可以清楚解释的模型,我们可以在推荐时添加一个小句子,说明为什么推荐了一个项目(“喜欢这个项目的人也喜欢这个”,“你喜欢这个项目,你可能会对这个项目感兴趣”,…)。

最后,除了多样性和可解释性本质上难以评估的事实之外,我们可以注意到,评估不属于测试数据集的推荐的质量也是相当困难的:如何在实际向用户推荐之前知道一个新的推荐是否相关?出于所有这些原因,在“真实条件”下测试模型有时会很有诱惑力。由于推荐系统的目标是生成一个动作(看电影、购买产品、阅读文章等),我们确实可以评估它生成预期动作的能力。例如,系统可以按照 A/B 测试方法投入生产,或者可以只在用户样本上进行测试。然而,这种过程要求对模型有一定程度的信心。

外卖食品

这篇文章的主要观点是:

  • 推荐算法可以分为两大类:仅基于用户-项目交互矩阵的协作方法(如用户-用户、项目-项目和矩阵分解)和使用关于用户和/或项目的先验信息的基于内容的方法(如回归或分类模型)
  • 基于记忆的协作方法不假设任何潜在模型,因此具有低偏差但高方差;基于模型的协作方法假设一个潜在的交互模型,该模型需要从零开始学习用户和项目表示,因此具有较高的偏差但较低的方差;基于内容的方法假设围绕明确给出的用户和/或项目特征建立潜在的模型,因此具有最高的偏差和最低的方差
  • 推荐系统在许多大型行业中越来越重要,在设计系统时必须考虑一些规模因素(更好地使用稀疏性、因子分解或优化的迭代方法、最近邻搜索的近似技术……)
  • 推荐系统很难评估:如果可以使用一些经典的度量标准,如 MSE、准确度、召回率或精确度,人们应该记住一些期望的属性,如多样性(意外发现)和可解释性不能以这种方式评估;真实条件评估(如 A/B 测试或样本测试)最终是评估新推荐系统的唯一真实方式,但需要对模型有一定的信心

我们应该注意到,在这篇介绍性的文章中,我们没有讨论混合方法。这些方法结合了协同过滤和基于内容的方法,在许多情况下获得了最先进的结果,并且因此被用在当今许多大规模推荐系统中。在混合方法中进行的组合可以主要采取两种形式:我们可以独立地训练两个模型(一个协作过滤模型和一个基于内容的模型)并组合它们的建议,或者通过使用先验信息(关于用户和/或项目)以及“协作”交互信息作为输入来直接构建统一两种方法的单个模型(通常是神经网络)。

正如我们在这篇文章的引言中提到的,推荐系统在许多行业中变得越来越重要,因此,在最近几年里受到了越来越多的关注。在本文中,我们介绍了更好地理解与这些系统相关的问题所需的基本概念,但我们强烈鼓励感兴趣的读者进一步探索这一领域…讽刺的是,没有给出任何具体的阅读建议!

感谢阅读!

约瑟夫·罗卡一起写的最后一篇文章:

[## 整体方法:装袋、助推和堆叠

理解集成学习的关键概念。

towardsdatascience.com](/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205) [## 马尔可夫链简介

定义、属性和 PageRank 示例。

towardsdatascience.com](/brief-introduction-to-markov-chains-2c8cab9c98ab)

恐龙递归神经网络(RNN)简介

原文:https://towardsdatascience.com/introduction-to-recurrent-neural-networks-rnn-with-dinosaurs-790e74e3e6f6?source=collection_archive---------18-----------------------

了解关于 RNNs 的一切,并构建一个恐龙名称生成器

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

Photo by Daiga Ellaby on Unsplash

递归神经网络(RNN)是称为序列模型的更大算法组的一部分。序列模型在语音识别、音乐生成、DNA 序列分析、机器翻译等领域取得了巨大的进步。

在这篇文章中,介绍了 RNN 的理论,我们将通过建立一个能产生新恐龙名字的模型来巩固一切。

我们走吧!

对于机器学习、深度学习和人工智能的实践视频教程,请查看我的 YouTube 频道

Now, that’s a specie I don’t know about…

为什么要使用递归神经网络?

假设你想建立一个神经网络来识别句子中的人名。

在这种情况下,传统的神经网络不适合这种类型的应用。首先,输入和输出不会有相同的长度,因为一个人的名字可能有很大的不同。第二,学习到的特征不会在文本的不同位置共享,导致低于标准的性能。

这就是为什么 rnn 非常受序列数据的欢迎,比如句子或音乐。

一种递归神经网络的结构

在 RNN 中,输入被馈送到网络的一个层,并且它输出预测。然后,第二输入被馈送到另一层,并且网络输出预测。然而,它也使用从前一层计算的信息。

重复该过程,直到获得最终输出。

因此,典型的 RNN 看起来是这样的:

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

Left: folded schema of an RNN. Right: unfolded schema of an RNN. Source

这种结构允许 rnn 将信息从早期步骤链接到当前步骤。然而,如果 RNN 很深,意味着它有许多层,它将容易出现消失爆发渐变。

当渐变接近 0 时,渐变消失,因此权重不再更新。另一方面,爆炸梯度是当梯度太大时,并且永远不会达到优化函数的全局最小值。当然,有办法防止爆炸和消失的梯度,我们会看到当我们编码一个 RNN。

对 RNN 进行编码以生成新的恐龙名称

概观

现在,我们将使用 Python 编写一个 RNN,它将为我们生成新的恐龙名称。我们将学习如何:

  • 存储文本数据,并使用 RNN 对其进行处理
  • 如何合成数据
  • 如何生成文本
  • 如何裁剪渐变以避免渐变爆炸

我们的 RNN 将会是这样的:

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

RNN schema. Source

当然,如果你想继续写代码的话,可以使用全笔记本。您还将找到复制结果所需的所有实用工具。

步骤 1:导入库并浏览数据集

我们首先导入必要的库和实用程序,并查看我们将使用的数据。

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

你应该看到我们有相当多的恐龙名字,我们也有 27 个独特的角色。它们对应于字母表中的每个字母,我们有一个特殊的字符“\n”来定义一个新行。这将是我们的句尾字符( EOS )。

步骤 2:定义渐变裁剪函数

如前所述,rnn 容易消失或爆炸梯度,所以我们将实现梯度裁剪,以防止梯度“爆炸”。

渐变裁剪非常简单:如果计算出的渐变大于某个阈值,我们将它缩放回阈值。否则,我们就让它保持原样。像这样,我们将确保我们的优化函数会收敛。

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

Gradient descent with and without clipping. Source

在代码中:

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

步骤 3:定义采样函数

一旦我们的模型被训练,我们将需要一个函数来选择最有可能生成一个似乎合理的恐龙名字的角色。

换句话说,它需要从字符库中抽取一个字符并生成一个单词。

在代码中:

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

步骤 4:构建模型

现在,我们准备好构建模型了。首先,我们实现一个函数,该函数执行带有梯度裁剪的随机梯度下降的一个步骤:

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

完美!现在我们可以编写并训练我们的模型:

现在,我们只需要运行下面的单元格来获得新的恐龙名称:

parameters = model(data, ix_to_char, char_to_ix)

你应该看到算法在生成更可信的恐龙名字方面变得越来越好。我得到的几个例子是:

  • Trokalenator
  • 尼沃龙
  • 卢特龙

如果您有更多的时间和计算能力,请随意调整模型并训练它更长时间,因为它应该会生成更好的名称。

就是这样!您学习了 RNNs 的基础知识,并应用它们来生成新的恐龙名称!

在未来的帖子中,我们将讨论长短期记忆(LSTM)单位,这是另一种类型的循环网络,我们将生成爵士乐。

敬请期待!

来源: Deeplearning.ai

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值