Keras的“嵌入”层如何工作?


69

需要了解Keras库中“嵌入”层的工作方式。我在Python中执行以下代码

import numpy as np
from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(5, 2, input_length=5))

input_array = np.random.randint(5, size=(1, 5))

model.compile('rmsprop', 'mse')
output_array = model.predict(input_array)

它给出以下输出

input_array = [[4 1 3 3 3]]
output_array = 
[[[ 0.03126476  0.00527241]
  [-0.02369716 -0.02856163]
  [ 0.0055749   0.01492429]
  [ 0.0055749   0.01492429]
  [ 0.0055749   0.01492429]]]

我知道input_array中的每个值都映射到output_array中的2个元素向量,因此1 X 4向量给出1 X 4 X 2向量。但是,如何计算映射值?


1
也许是一个好的开始:github.com/fchollet/keras/issues/3110
fnl

在此博客中,使用Keras
ФаильГафаров

Answers:


86

实际上,没有使用任何数学运算从输入中计算输出向量。而是将每个输入整数用作索引,以访问包含所有可能向量的表。这就是为什么需要将词汇表的大小指定为第一个参数的原因(以便可以初始化表)。

该层最常见的应用是文本处理。让我们看一个简单的例子。我们的训练集仅包含两个短语:

希望很快能见到你

很高兴再见到你

因此,我们可以通过为每个单词分配一个唯一的整数(例如,按照训练数据集中出现的顺序)来对这些短语进行编码。然后我们的短语可以改写为:

[0, 1, 2, 3, 4]

[5, 1, 2, 3, 6]

现在假设我们要训练一个网络,其第一层是嵌入层。在这种情况下,我们应该按以下方式对其进行初始化:

Embedding(7, 2, input_length=5)

第一个参数(7)是训练集中不同单词的数量。第二个自变量(2)表示嵌入向量的大小。的input_length argumet,当然,确定每个输入序列的大小。

训练好网络后,我们可以获取嵌入层的权重,在这种情况下,权重为大小(7,2),可以认为是用于将整数映射到嵌入向量的表:

+------------+------------+
|   index    |  Embedding |
+------------+------------+
|     0      | [1.2, 3.1] |
|     1      | [0.1, 4.2] |
|     2      | [1.0, 3.1] |
|     3      | [0.3, 2.1] |
|     4      | [2.2, 1.4] |
|     5      | [0.7, 1.7] |
|     6      | [4.1, 2.0] |
+------------+------------+

因此,根据这些嵌入,我们的第二个训练短语将表示为:

[[0.7, 1.7], [0.1, 4.2], [1.0, 3.1], [0.3, 2.1], [4.1, 2.0]]

乍一看似乎很不直观,但是底层的自动微分引擎(例如Tensorflow或Theano)设法优化与每个输入整数关联的向量,就像模型的任何其他参数一样。使用其他方法/人们在不同领域中学习到的嵌入也很有趣(请参阅https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html)作为在[1]中完成。

[1]López-Sánchez,D.,Herrero,JR,Arrieta,AG和Corchado,JM混合度量学习和基于案例的推理以进行自适应点击诱饵检测。应用智能,1-16。


4
谢谢你的回答。只需查询一下如何获得嵌入层的权重。像索引0一样,如何获得[1.2,3.1]。
prashanth

5
将与嵌入向量的索引相关的表的内容(即嵌入层的权重)随机初始化,然后通过训练算法(例如Gradient Descent)进行优化。
丹尼尔·洛佩兹

3
谢谢。我仍然不清楚优化器将针对哪个优化器?像什么,可以计算损失函数的“正确答案”是什么?或说另一种方式,前进和后退通行是做什么的?
bwest87 '17

2
所以...嵌入基本上是一个整体架构的子网从而降低任何一个热编码输入向下成更少的输入,AFAICT ..
麦克坎贝尔

1
由于嵌入层是可训练的,因此它对训练集中缺少的值有多敏感?假设我在训练集中有10个单词,在测试集中还有5个单词-我的词汇量为15 ...但是在训练过程中,该层实际上从未被这5个“测试”单词激活。您能解释一下这种情况吗?
mikalai

6

我也有同样的问题,在阅读了几篇文章和材料后,我想我已经弄清楚了嵌入层的作用是什么。

我认为这篇文章对理解也很有帮助,但是,我确实很容易理解Daniel的答案。但是我也主要通过理解嵌入词来理解它的想法。

我相信说嵌入层将一键编码输入减少到更少的输入是不准确的。毕竟,一热向量是一维数据,在我们的情况下,实际上它变成了二维。最好说

嵌入层提出了另一个维度的输入关系

无论是二维还是更高。

我还发现词嵌入到主成分分析之间的相似之处非常有趣。尽管名称看起来很复杂,但是这个概念很简单。PCA要做的是基于一些通用规则(所谓的主成分)定义一组数据。因此,这就像有一个数据,您想要描述它,但仅使用2个组件。从这个意义上讲,它与单词嵌入非常相似。他们在不同的背景下都做相同的工作。你可以在这里找到更多。我希望也许理解PCA可以通过类比帮助理解嵌入层。

最后,对帖子的原始问题“ 如何计算值? ” 的答案是:

  • 基本上,我们的神经网络捕获输入(我们的句子)的底层结构,并通过优化将词汇表中单词之间的关系放到更高的维度(比如说2)。
  • 更深入的理解是,每个单词与另一个单词的出现频率受我们的词汇影响(以非常幼稚的方式,我们可以手动计算出来)
  • 前述频率可能是NN可以捕获的许多基础结构之一
  • 您可以在youtube链接上找到解释单词嵌入的直觉

7
好的观点。但是,我认为值得注意的是,虽然诸如word2vec之类的词嵌入技术试图在最终的嵌入中捕获单词的全部含义,但在受监管的网络中的嵌入层可能无法学习到这种语义丰富且通用的表示形式。例如,如果您的网络受过训练以进行情感分类,则它可能只会根据其“情感”负载在嵌入中对单词进行分组/聚类。但是,根据我的经验,使用word2vec在大型语料库上学习到的权重来初始化嵌入层通常很有用。
DanielLópez'18年

2
一热向量不是一维数据。它的维度是词汇量。
Binu Jasim

2
@BinuJasim你是对的。在一个热载体表示词汇是不是一维数据。但是它代表的信息确实是一维的,词汇表中的每个实体都是一维的数据。的确,我们有n * w个元素(n =词汇量,w =位数),但是每个二进制值代表一个向量,该向量还是一维输入。
Novin Shahroudi,

@NovinShahroudi辉煌,感谢您的解释。
Benyamin Jafari
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.