一般在NLP中经常用到这个函数。在NLP中,词汇表中存储了所有单词的word embedding
,这个词汇表中的word embedding
可以是通过word2vec
算法训练好的,但是我们的语料库中的文本都是按照一篇篇文档存储的,而且语料库中存储的也只是一篇篇文档的对应单词的id,而不是embedding。故需要把文档中每个词都通过id映射成embedding向量,这个函数就是做这件事的。
函数原型
tf.nn.embedding_lookup(
params,
ids,
partition_strategy='mod',
name=None,
validate_indices=True,
max_norm=None
)
参数:
-
params
: 表示完整的嵌入张量,或者除了第一维度之外具有相同形状的P个张量的列表,表示经分割的嵌入张量 -
ids
: 一个类型为int32或int64的Tensor,即要在params中查找的id -
partition_strategy
: 指定分区策略的字符串,如果len(params)> 1,则相关。当前支持“div”和“mod”。 默认为“mod” -
name
: 操作名称(可选) -
validate_indices
: 是否验证收集索引 -
max_norm
: 如果不是None,嵌入值将被l2归一化为max_norm的值
返回值
返回的就是params中查找到的ids所组成的tensor。
举个例子:
import numpy as np
import tensorflow as tf
data = np.array([[[2],[1]],[[3],[4]],[[6],[7]]])
data = tf.convert_to_tensor(data)
lk = [[0,1],[1,0],[0,0]]
lookup_data = tf.nn.embedding_lookup(data,lk)
init = tf.global_variables_initializer()
先让我们看下不同数据对应的维度:
In [76]: data.shape
Out[76]: (3, 2, 1)
In [77]: np.array(lk).shape
Out[77]: (3, 2)
In [78]: lookup_data
Out[78]: <tf.Tensor 'embedding_lookup_8:0' shape=(3, 2, 2, 1) dtype=int64>
这个是怎么做到的呢?关键的部分来了,看下图:
这个函数根据lk中的值在data中找对应的index下的vector进行拼接。返回的tensor的维度是lk的维度+data的除了第一维后的维度拼接。
结果:
In [79]: data
Out[79]:
array([[[2],
[1]],
[[3],
[4]],
[[6],
[7]]])
In [80]: lk
Out[80]: [[0, 1], [1, 0], [0, 0]]
# lk[0]也就是[0,1]就是查找data[0]和data[1],也就是[[2],[1]]和[[3],[4]],
# 并将二者拼为一个元素[[[2],[1]],[[3],[4]]],这个元素就是look_data中的第一个元素
In [81]: sess.run(lookup_data)
Out[81]:
array([[[[2],
[1]],
[[3],
[4]]],
[[[3],
[4]],
[[2],
[1]]],
[[[2],
[1]],
[[2],
[1]]]])
参考:https://www.jianshu.com/p/abea0d9d2436
https://blog.csdn.net/yangfengling1023/article/details/82910951