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

Python Keras嵌入层:它们是如何工作的?,python,machine-learning,neural-network,keras,embedding,Python,Machine Learning,Neural Network,Keras,Embedding,我开始使用Keras建立神经网络模型 我有一个分类问题,特征是离散的。 为了处理这种情况,标准程序包括转换二进制数组中的离散特征,使用一个热编码 然而,对于Keras,这一步似乎是不必要的,因为可以简单地使用嵌入层来创建这些离散特征的特征向量表示 这些是如何执行的 我的理解是,如果离散特征f可以假定k值,那么嵌入层将创建一个包含k列的矩阵。在培训阶段,每当我收到该功能的值时,比如说I,只有矩阵的I列将被更新 我的理解正确吗?正如人们很容易注意到的那样,一个热向量与嵌入矩阵的乘法可以在恒定的时间内

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

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

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

这些是如何执行的

我的理解是,如果离散特征
f
可以假定
k
值,那么嵌入层将创建一个包含
k
列的矩阵。在培训阶段,每当我收到该功能的值时,比如说
I
,只有矩阵的
I
列将被更新


我的理解正确吗?

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

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

它始终作为直接连接到输入的图层使用。

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

一种热编码(OHE)模型是稀疏字编码模型。例如,如果我们有1000个输入激活,每个输入特征将有1000个OHE向量

假设我们知道一些输入激活是依赖的,我们有64个潜在的特性。我们会有这样的嵌入:

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

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

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

嵌入层的输出是什么

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


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

假设有N个对象没有直接的数学表示。例如单词

由于神经网络只能处理张量,你应该寻找一些方法将这些对象转化为张量。 解决方案是在一个巨大的矩阵(嵌入矩阵)中,它将对象的每个索引与其到张量的转换联系起来

object_index_1: vector_1
object_index_1: vector_2
...
object_index_n: vector_n
选择特定对象的向量可以通过以下方式转换为矩阵积:

其中,v是确定需要翻译哪个单词的一个热向量。M是嵌入矩阵

如果我们提出通常的管道,将是:

  • 我们有一个物品清单
  • 我们将这些对象转换为索引(我们计算唯一对象)
  • 我们将这些索引转换为一个热向量(记住索引所在的位置只有一个热向量)
  • 我们创建或使用嵌入矩阵:
  • 通常情况下,嵌入矩阵是​​在同一模型学习过程中学习,以适应每个对象的最佳向量。我们已经有了对象的数学表示

    正如你们所看到的,我们使用了一个热的矩阵积。你真正要做的是把代表这个词的M列取下来


    在学习过程中,此M将被调整以改善对象的表示,因此损失会减少。

    当我们处理任何领域的单词和句子时(例如NLP)我们喜欢以向量的形式表示单词和句子,这样机器就可以很容易地识别单词并将其用于数学建模。比如说,我们的词汇中有10个单词。我们希望每一个单词都有唯一性。最简单的方法是为每个单词指定一个数字,创建一个包含10个元素的向量,然后仅激活包含该数字的元素,并停用所有其他元素。例如,在我们的vocab中,我们将dog作为一个词,并指定了数字3。向量是这样的

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

    同样地,对于其他的话,它将激活其他的元素。 上面的例子非常简单,但效率很低。假设我们有10万个单词。为了表示100000个单词,我们将有100000个[1*100000]向量。因此,为了有效地完成这项任务,我们可以使用嵌入。它们以密集的形式(比如说只有32个元素的向量)表示单词。狗可以表示为

    {0.24,0.97}


    在数学建模方面,它更有效、更好

    一个非常详细的解释。谢谢
    objects = ['cat', 'dog', 'snake', 'dog', 'mouse', 'cat', 'dog', 'snake', 'dog']
    
    unique = ['cat', 'dog', 'snake', 'mouse'] # list(set(objects))
    objects_index = [0, 1, 2, 1, 3, 0, 1, 2, 1] #map(unique.index, objects)
    
    
    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
    
    #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)