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

Uld*_*tre 8 python machine-learning embedding neural-network keras

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

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

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

如何执行这些嵌入

我的理解是,如果离散特征f可以采用k值,则嵌入层会创建一个带有k列的矩阵.每次我收到该功能的值时,比如说i,在训练阶段,只会i更新矩阵的列.

我的理解是否正确?

Adr*_*ana 11

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

由于神经网络只能使用张量,您应该寻找某种方法将这些对象转换为张量。解决方案是在一个巨大的矩阵(嵌入矩阵)中,它将对象的每个索引与其转换为张量相关联。

object_index_1: vector_1
object_index_1: vector_2
...
object_index_n: vector_n
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

其中v是决定需要翻译哪个单词的 one-hot 向量。而中号是嵌入矩阵。

如果我们提出通常的管道,它将是以下内容:

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

Run Code Online (Sandbox Code Playgroud)
  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
Run Code Online (Sandbox Code Playgroud)
  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)
Run Code Online (Sandbox Code Playgroud)

通常嵌入矩阵是在同一个模型学习期间学习的,以适应每个对象的最佳向量。我们已经有了对象的数学表示!

如您所见,我们使用了一种热产品,后来使用了矩阵产品。你真正做的是取代表那个词的M列。

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


pro*_*sti 6

Keras 中的嵌入层(也是一般情况)是一种创建密集单词编码的方法。您应该将其视为矩阵乘以 One-hot-encoding (OHE) 矩阵,或者简单地视为 OHE 矩阵上的线性层。

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

稀疏密集字编码表示编码有效性。

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

假设我们知道一些输入激活是相关的,并且我们有 64 个潜在特征。我们会有这样的嵌入:

e = Embedding(1000, 64, input_length=50)
Run Code Online (Sandbox Code Playgroud)

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

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

这里创建Embedding层时还有其他参数

嵌入层的输出是什么?

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

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


Mar*_*jko 5

可能会很容易注意到- one-hot向量与Embedding矩阵的相乘可以在恒定时间内有效执行,这可以理解为矩阵切片。而这正是Embedding图层在计算过程中所做的。它仅使用gather后端功能选择适当的索引。这意味着您对Embedding图层的理解是正确的。