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

How to correctly use mask_zero=True for Keras Embedding with pre-trained weights?

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

假设我有 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: Whether or not the input value 0 is a special "padding" value that should be masked out. This is useful when using recurrent layers which may take variable length input. If this is True then all subsequent layers in the model need to support masking or an exception will be raised. If mask_zero is set to True, as a consequence, index 0 cannot be used in the vocabulary (input_dim should equal size of vocabulary + 1).

所以我感到困惑的是如何为嵌入层构建权重数组,因为 "index 0 cannot be used in the vocabulary." 如果我将权重数组构建为

[[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]]

在我看来,第二个选项是将零放入词汇表中。换句话说,我很困惑。任何人都可以阐明这一点吗?

你第二种方法是正确的。您将希望通过以下方式构建嵌入层

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

因此整个内核仍然乘以输入,这意味着所有索引都向上移动了一个。