Keras使用预训练的嵌入初始化大型嵌入层

时间:2018-11-21 17:23:26

标签: tensorflow keras

我正在尝试通过使用预训练的嵌入和自定义语料库在带有Tensorflow后端的Keras 2中重新训练word2vec模型。

这是我如何使用预训练的嵌入初始化嵌入层的方法:

embedding = Embedding(vocab_size, embedding_dim,
                      input_length=1, name='embedding',
                      embeddings_initializer=lambda x: pretrained_embeddings)

其中pretrained_embeddings是大小为vocab_size x embedding_dim

的大矩阵

只要pretrained_embeddings不太大就可以使用。

不幸的是,不是我的情况-vocab_size=2270872embedding_dim=300

初始化Embeddings层时,出现错误:

Cannot create a tensor proto whose content is larger than 2GB.

错误来自于函数add_weight()  /opt/r/anaconda3/lib/python3.6/site-packages/keras/engine/base_layer.py,更具体地说是以下行:

weight = K.variable(initializer(shape),
                    dtype=dtype,
                    name=name,
                    constraint=constraint)

initializer是上面的lambda函数,它返回大矩阵。如上所述,shape(2270872, 300)

是否可以解决这个问题而不必进行低级Tensorflow编程?如果我将Theano用作后端,则代码运行良好,但是我想使用Tensorflow以获得更好的长期前景。

我发现的唯一类似的Stackoverflow问题是this,它提出了占位符变量,但是我不确定如何将它们应用于Keras级别。

非常感谢

编辑: 我非常愿意在Tensorflow后端的级别上解决此问题。只是我不知道在这种情况下如何在同一应用程序中组合Tensorflow和Keras代码。大多数示例是一个或另一个,而不是两者。

例如,当Keras中的Embeddings层的初始化不可避免地调用add_weight()函数时,Tensorflow占位符变量有什么用,这会导致问题?

解决方案:

正如@ blue-phoenox的评论所暗示的,我重新编写了如下代码:

embedding = Embedding(vocab_size, embedding_dim,
                      input_length=1, 
                      name='embedding')
embedding.build(input_shape=(1,)) # the input_shape here has no effect in the build function
embedding.set_weights([pretrained_embeddings])

做到了。再次感谢@ blue-phoenox。

1 个答案:

答案 0 :(得分:3)

您可以使用embeddings_initializer参数为嵌入层加载预先训练的权重,而不必使用Embedding层的weights参数,这样您就可以移交预先训练的嵌入大于2GB。

这是一个简短的示例:

from keras.layers import Embedding

embedding_layer = Embedding(vocab_size,
                            EMBEDDING_DIM,
                            weights=[embedding_matrix],
                            input_length=MAX_SEQUENCE_LENGTH,
                            trainable=False)

embedding_matrix只是包含权重的常规numpy矩阵。

例如,您也可以在这里查看:
https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html


编辑:

正如 @PavlinMavrodiev (请参阅问题结尾)指出,weights参数已被弃用。他改为使用 layer方法 set_weights设置权重:

  •   

    layer.set_weights(weights):从列表中设置图层的权重   的Numpy数组(形状与get_weights的输出相同)。

要获得训练后的权重,可以使用get_weights

  •   

    layer.get_weights():返回图层的权重作为列表   numpy数组。

这都是Keras Layer-Baseclass中的方法,可用于所有keras层,包括嵌入层。

相关问题