如何正确使用mask_zero = True进行预先训练的权重进行Keras嵌入?

时间:2018-07-17 13:29:04

标签: python tensorflow keras word-embedding

如果我还要设置Embedding,我对于如何格式化自己的Keras mask_zero=True层的预训练权重感到困惑。这是一个具体的玩具示例。

假设我的词汇量为4个单词[1,2,3,4],并且使用的矢量权重是:

weight[1]=[0.1,0.2]
weight[2]=[0.3,0.4]
weight[3]=[0.5,0.6]
weight[4]=[0.7,0.8]

我想嵌入长度不超过5个单词的句子,因此在将它们输入到嵌入层之前,必须将它们填充零。我想屏蔽零,以便其他图层不再使用它们。

在阅读Keras文档进行嵌入时,它说0值不能包含在我的词汇表中。

  

mask_zero:输入值0是否为特殊的“填充”   应该屏蔽掉的值。这在使用循环时非常有用   可能需要可变长度输入的层。如果这是真的,那么所有   模型中的后续层需要支持屏蔽或异常   将被提出。如果mask_zero设置为True,则索引0   不能在词汇表中使用(input_dim的大小应等于   词汇量+ 1)。

所以我很困惑的是如何为Embedding层构造权重数组,因为“词汇表中不能使用索引0”。如果我将权重数组构建为

[[0.1,0.2],
 [0.3,0.4],
 [0.5,0.6],
 [0.7,0.8]]

然后通常情况下,单词1指向索引1,在这种情况下,该索引保留单词2的权重。还是当您指定mask_zero=True时,Keras会内部使之成为单词1指向索引0?或者,您是否将索引为零的零向量预先添加,如下所示?

[[0.0,0.0],
 [0.1,0.2],
 [0.3,0.4],
 [0.5,0.6],
 [0.7,0.8]]

在我看来,第二个选择是将零添加到词汇表中。换句话说,我很困惑。有人可以阐明这一点吗?

1 个答案:

答案 0 :(得分:2)

您第二种方法是正确的。您将需要通过以下方式构造嵌入层

embedding = Embedding(
   output_dim=embedding_size,
   input_dim=vocabulary_size + 1,
   input_length=input_length,
   mask_zero=True,
   weights=[np.vstack((np.zeros((1, embedding_size)),
                       embedding_matrix))],
   name='embedding'
)(input_layer)

其中embedding_matrix是您提供的第二个矩阵。

您可以通过查看implementation of keras' embedding层来看到这一点。值得注意的是,mask_zero如何仅用于从字面上掩盖输入

def compute_mask(self, inputs, mask=None):
    if not self.mask_zero:
        return None
    output_mask = K.not_equal(inputs, 0)
    return output_mask

因此整个内核仍将与输入相乘,这意味着所有索引都上移一个。