函数 tf.nn.embedding_lookup():
- 简要说明
- tf.nn.embedding_lookup函数的用法主要是选取一个张量里面索引对应的元素。tf.nn.embedding_lookup(params, ids):params可以是张量也可以是数组等,id就是对应的索引。
- 实际上tf.nn.embedding_lookup的作用就是找到要寻找的embedding data中的对应的行下的vector。
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是我们给出的,可以通过:
1.tf.get_variable("item_emb_w", [self.item_count, self.embedding_size])
等方式生产服从[0,1]的均匀分布或者标准分布
2.tf.convert_to_tensor
转化我们现有的array
- 然后,ids是我们要找的params中对应位置的索引。
函数用法说明:
- tf.nn.embedding_lookup() 函数的用法主要是选取一个张量里面索引对应的元素
- tf.nn.embedding_lookup(params=tensor,ids=id): 即tensor就是输入的张量,id 就是张量对应的索引
- tf.nn.embedding_lookup() 就是根据input_ids中的id,寻找embeddings中的第id行。比如input_ids=[1,3,5],则找出embeddings中第1,3,5行(第0行开始),组成一个tensor返回
- embedding_lookup不是简单的查表,id对应的向量是可以训练的,训练参数个数应该是 category num*embedding size,也就是说lookup是一种全连接层
应用
- 一般做自然语言相关的。需要把每个词都映射成向量,这个向量可以是word2vec预训练好的,也可以是在网络里训练的,在网络里需要先把词的id转换成对应的向量,这个函数就是做这件事的
- 在基于深度学习的实体识别中,字向量会提前训练好,这个就可以理解成上面的tensor,而在实际的句子中每一个字所对应的字向量是通过id进行关联上的。
如,embedding层写法:
embedding =[]
with tf.variable_scope("word_embedding" if not name else name), tf.device('/gpu:0'):
self.word_lookup = tf.get_variable(
name="word_embedding",
shape=[self.num_words, self.word_dim],
initializer=self.initializer
)
embedding.append(tf.nn.embedding_lookup(params=self.word_lookup, ids=word_inputs))
例子
1. ids只有一行:
import tensorflow as tf
import numpy as np
a = np.random.random([5,1])
print('a:',a)
b = tf.nn.embedding_lookup(a, [1, 3])
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print('b:',sess.run(b))
print(b)
输出:
a: [[0.61166073]
[0.08096354]
[0.37446513]
[0.8719863 ]
[0.74964065]]
b: [[0.08096354]
[0.8719863 ]]
Tensor("embedding_lookup/Identity:0", shape=(2, 1), dtype=float64)
【分析】输出为张量的第一和第三个元素。
2. ids有多行:
import tensorflow as tf
import numpy as np
a = [[0.1, 0.2, 0.3], [1.1, 1.2, 1.3], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3], [4.1, 4.2, 4.3]]
a = np.asarray(a)
print('a:\n',a)
print('*'*15)
idx1 = tf.Variable([0, 2, 3, 1], tf.int32)
idx2 = tf.Variable([[0, 2, 3, 1], [4, 0, 2, 2]], tf.int32)
out1 = tf.nn.embedding_lookup(a, idx1)
out2 = tf.nn.embedding_lookup(a, idx2)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print('out1:',sess.run(out1))
print(out1)
print('*'*15)
print('out2:',sess.run(out2))
print(out2)
输出:
a:
[[0.1 0.2 0.3]
[1.1 1.2 1.3]
[2.1 2.2 2.3]
[3.1 3.2 3.3]
[4.1 4.2 4.3]]
***************
out1: [[0.1 0.2 0.3]
[2.1 2.2 2.3]
[3.1 3.2 3.3]
[1.1 1.2 1.3]]
Tensor("embedding_lookup_1/Identity:0", shape=(4, 3), dtype=float64)
***************
out2: [[[0.1 0.2 0.3]
[2.1 2.2 2.3]
[3.1 3.2 3.3]
[1.1 1.2 1.3]]
[[4.1 4.2 4.3]
[0.1 0.2 0.3]
[2.1 2.2 2.3]
[2.1 2.2 2.3]]]
Tensor("embedding_lookup_2/Identity:0", shape=(2, 4, 3), dtype=float64)
【分析】相当于把两个4*3矩阵拼接在一起,合成一个张量2*4*3。