【问题标题】:Keras initialize large embeddings layer with pretrained embeddingsKeras 使用预训练嵌入初始化大型嵌入层
【发布时间】:2018-11-21 17:23:26
【问题描述】:

我正在尝试使用预训练的嵌入和自定义语料库在 Keras 2 中使用 Tensorflow 后端重新训练 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

初始化嵌入层时出现错误:

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

错误来自函数add_weight() in /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。

【问题讨论】:

  • 其实这是链接,我在问题的最后也提到了这个链接。不幸的是,我不知道如何在我的情况下使用它。
  • 好的,抱歉我错过了链接
  • 只设置权重而不是初始化怎么样?stackoverflow.com/questions/51819213/…
  • @blue-phoenox 谢谢。做到了。您能否将您的回复作为单独的评论发布,以便我将其选为最佳答案?

标签: tensorflow keras


【解决方案1】:

您可以使用 weights 参数为嵌入层加载预训练权重,而不是使用嵌入层的 embeddings_initializer 参数,这样您应该能够移交大于 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 层,包括嵌入层。

【讨论】:

  • 我接受这个作为问题的解决方案,尽管我的实现略有不同。我已将后者作为原始问题的编辑。原因是Embedding 层的weights 参数似乎已经过时,尽管它目前有效。最新的 Keras 2 文档中没有提到它。我相信我已经实现了一个更面向未来的版本。
  • 当您在自定义class MyLayer(tf.keras.layers.Layer)__init__ 中使用tf.keras.layers.Embedding 层时,您将如何使用set_weights 方法?你需要把它放在哪里?我想不通。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
  • 2020-09-03
  • 2019-11-14
  • 2018-01-06
  • 2019-06-11
  • 1970-01-01
相关资源
最近更新 更多