我最近审核了convolutional text classification的一个有趣的实现。但是,我所评论的所有TensorFlow代码都使用了一个随机(未预先训练)的嵌入向量,如下所示:
with tf.device('/cpu:0'), tf.name_scope("embedding"):
W = tf.Variable(
tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
name="W")
self.embedded_chars = tf.nn.embedding_lookup(W, self.input_x)
self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1)
有人知道如何使用Word2vec或GloVe预训练的单词嵌入的结果而不是随机的吗?
答案 0 :(得分:124)
有几种方法可以在TensorFlow中使用预先训练的嵌入。我们假设你在一个名为embedding
的NumPy数组中嵌入了vocab_size
行和embedding_dim
列,并且你想要创建一个张量W
用于致电tf.nn.embedding_lookup()
。
只需将W
创建为tf.constant()
作为其值embedding
:
W = tf.constant(embedding, name="W")
这是最简单的方法,但它不具有内存效率,因为tf.constant()
的值在内存中多次存储。由于embedding
可能非常大,因此您只应将此方法用于玩具示例。
将W
创建为tf.Variable
,并通过tf.placeholder()
从NumPy数组初始化它:
W = tf.Variable(tf.constant(0.0, shape=[vocab_size, embedding_dim]),
trainable=False, name="W")
embedding_placeholder = tf.placeholder(tf.float32, [vocab_size, embedding_dim])
embedding_init = W.assign(embedding_placeholder)
# ...
sess = tf.Session()
sess.run(embedding_init, feed_dict={embedding_placeholder: embedding})
这样可以避免在图中存储embedding
的副本,但它确实需要足够的内存来将矩阵的两个副本同时保存在内存中(一个用于NumPy数组,一个用于{{1} })。请注意,我假设您希望在培训期间保持嵌入矩阵不变,因此使用tf.Variable
创建W
。
如果嵌入是作为另一个TensorFlow模型的一部分进行训练的,则可以使用tf.train.Saver
从其他模型的检查点文件加载值。这意味着嵌入矩阵可以完全绕过Python。按照选项2创建trainable=False
,然后执行以下操作:
W
答案 1 :(得分:29)
我使用此方法加载和共享嵌入。
W = tf.get_variable(name="W", shape=embedding.shape, initializer=tf.constant_initializer(embedding), trainable=False)
答案 2 :(得分:6)
@mrry的答案是不正确的,因为它证明了每次运行网络时都会覆盖嵌入权重,所以如果您按照小批量方法训练网络,则会覆盖嵌入的权重。因此,根据我的观点,预训练嵌入的正确方法是:
embeddings = tf.get_variable("embeddings", shape=[dim1, dim2], initializer=tf.constant_initializer(np.array(embeddings_matrix))
答案 3 :(得分:5)
2.0兼容答案:有很多预训练的嵌入,这些嵌入是由Google开发的,并且是开源的。
其中有些是Universal Sentence Encoder (USE), ELMO, BERT
等。在代码中重用它们非常容易。
重新使用Pre-Trained Embedding
, Universal Sentence Encoder
的代码如下所示:
!pip install "tensorflow_hub>=0.6.0"
!pip install "tensorflow>=2.0.0"
import tensorflow as tf
import tensorflow_hub as hub
module_url = "https://tfhub.dev/google/universal-sentence-encoder/4"
embed = hub.KerasLayer(module_url)
embeddings = embed(["A long sentence.", "single-word",
"http://example.com"])
print(embeddings.shape) #(3,128)
有关Google开发和开源的预训练嵌入的更多信息,请参见TF Hub Link。
答案 4 :(得分:5)
使用tensorflow第2版,如果您使用嵌入层,则非常简单
X=tf.keras.layers.Embedding(input_dim=vocab_size,
output_dim=300,
input_length=Length_of_input_sequences,
embeddings_initializer=matrix_of_pretrained_weights
)(ur_inp)
答案 5 :(得分:2)
我也面临嵌入问题,所以我用数据集写了详细的教程。 在这里,我想添加我尝试的内容您也可以尝试这种方法,
import tensorflow as tf
tf.reset_default_graph()
input_x=tf.placeholder(tf.int32,shape=[None,None])
#you have to edit shape according to your embedding size
Word_embedding = tf.get_variable(name="W", shape=[400000,100], initializer=tf.constant_initializer(np.array(word_embedding)), trainable=False)
embedding_loopup= tf.nn.embedding_lookup(Word_embedding,input_x)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for ii in final_:
print(sess.run(embedding_loopup,feed_dict={input_x:[ii]}))
如果您想从头开始理解,请参阅详细的教程Ipython example。