Keras嵌入层:它们如何工作?

时间:2017-03-13 11:45:36

标签: python machine-learning neural-network keras embedding

我开始使用Keras构建神经网络模型。

我有一个分类问题,其中的功能是离散的。 为了管理这种情况,标准程序包括使用单热编码转换二进制数组中的离散特征。

然而,似乎使用Keras这一步骤不是必需的,因为可以简单地使用嵌入层来创建这些离散特征的特征向量表示。

如何执行这些embeddings

我的理解是,如果离散要素f可以采用k值,则嵌入图层会创建一个包含k列的矩阵。每次我收到该功能的值时,请说i,在培训阶段,只会更新矩阵的i列。

我的理解是否正确?

4 个答案:

答案 0 :(得分:4)

正如人们可能很容易注意到的那样 - one-hot向量与Embedding矩阵的乘法可以在一个恒定的时间内有效地执行,因为它可以被理解为矩阵切片。这正是Embedding层在计算过程中所做的事情。它只是使用gather后端函数选择适当的索引。这意味着您对Embedding图层的理解是正确的。

答案 1 :(得分:2)

假设您有N个不直接具有数学表示形式的对象。例如单词。

由于神经网络只能使用张量,因此您应该寻找将这些对象转换为张量的方法。 该解决方案位于一个巨型矩阵(嵌入矩阵)中,该矩阵将对象的每个索引及其平移与张量相关联。

object_index_1: vector_1
object_index_1: vector_2
...
object_index_n: vector_n

选择特定对象的向量可以通过以下方式转换为矩阵乘积:

enter image description here

v 是确定一个单词需要翻译的单向矢量。而 M 是嵌入矩阵。

如果我们建议使用通常的管道,则将是以下内容:

  1. 我们有一个对象列表。
objects = ['cat', 'dog', 'snake', 'dog', 'mouse', 'cat', 'dog', 'snake', 'dog']
  1. 我们将这些对象转换为索引(我们计算唯一对象)。
unique = ['cat', 'dog', 'snake', 'mouse'] # list(set(objects))
objects_index = [0, 1, 2, 1, 3, 0, 1, 2, 1] #map(unique.index, objects)

  1. 我们将这些索引转换为一个热矢量(请记住,索引所在的位置只有一个)
objects_one_hot = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], 
     [0, 0 , 0, 1], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0]] # map(lambda x: [int(i==x) for i in range(len(unique))], objects_index)
#objects_one_hot is matrix is 4x9
  1. 我们创建或使用嵌入矩阵:
#M = matrix of dim x 4 (where dim is the number of dimensions you want the vectors to have). 
#In this case dim=2
M = np.array([[1, 1], [1, 2], [2, 2], [3,3]]).T # or... np.random.rand(2, 4)
#objects_vectors = M * objects_one_hot
objects_vectors = [[1, 1], [1, 2], [2, 2], [1, 2], 
    [3, 3], [1, 1], [1, 2], [2,2], [1, 2]] # M.dot(np.array(objects_one_hot).T)

通常在相同的模型学习过程中学习嵌入矩阵,以适应每个对象的最佳矢量。我们已经有了对象的数学表示!

正如您所看到的,我们使用了一种热门产品,后来使用了一种矩阵产品。您实际上要做的是代表该单词的 M 列。

在学习过程中,此M将用于改进对象的表示,因此损失减少。

答案 2 :(得分:1)

Keras中的Embedding层(通常也是)是一种创建密集单词编码的方法。您应该将其视为乘以一热编码(OHE)矩阵的矩阵,或者简单地视为OHE矩阵上的线性层。

它始终用作直接附加到输入的图层。

稀疏密集单词编码表示编码效果。

单热编码(OHE)模型是稀疏字编码模型。例如,如果我们有1000次输入激活,则每个输入要素将有1000个OHE向量。

比方说,我们知道一些输入激活是依赖的,并且我们有64个潜在功能。我们将进行以下嵌入:

e = Embedding(1000, 64, input_length=50)

1000表示我们计划总共编码1000个单词。 64告诉我们使用64维向量空间。 50个告诉输入文档,每个文档有50个字。

嵌入层将随机填充非零值,并且需要学习参数。

here中创建嵌入层时还有其他参数

嵌入层的输出是什么?

Embedding层的输出是2D向量,每个单词在输入单词序列(输入文档)中都有一个嵌入。

注意:如果希望将密集层直接连接到嵌入层,则必须首先使用Flatten layer将2D输出矩阵展平为1D向量。

答案 3 :(得分:0)

在处理任何区域(例如NLP)中的单词和句子时,我们都希望以矢量的形式表示单词和句子,以便机器可以轻松识别单词并将其用于数学建模。例如说我们的词汇中有10个单词。我们想要唯一地代表每个单词。最简单的方法是为每个单词分配一个数字,并创建一个包含10个元素的向量,然后仅激活具有该数字的元素,然后停用所有其他元素。例如,说在词汇中,我们将dog作为一个单词,并将数字3赋给它,因此矢量将类似于

{0,0,1,0,0,0,0,0,0,0}

换句话说,它将激活其他元素。 上面的例子很简单,但是效率很低。假设我们在词汇中有100000个单词。为了表示100000个单词,我们将有100000 [1 * 100000]个向量。因此,为了有效地完成此任务,我们可以使用嵌入。它们以密集(例如仅包含32个元素的向量)的形式表示单词。狗可以表示为

{0.24,0.97}

在数学建模方面更高效,更好