TensorFlow中tf.nn.embedding_lookup函数的作用
tf.nn.embedding_lookup()
是一个TensorFlow中的函数,用于获取一个嵌入矩阵embedding中对应某些id的向量。嵌入矩阵是在训练期间由模型学习得到的,它用于将高维稀疏输入向量映射到低维密集向量,并且是自动调整模型参数的一部分。tf.nn.embedding_lookup()
函数可根据已经学习过的输入向量中的id,查询嵌入矩阵获取相应的向量,进而应用到神经网络中的计算当中。
TensorFlow中tf.nn.embedding_lookup函数的使用方法
tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None, validate_indices=True, max_norm=None)
- params:一个Tensor,即嵌入矩阵;
- ids:一个Tensor,即需要查询的id的向量,如[1,4,3,0],表示查询id为1、4、3、0的向量;
- partition_strategy:可选参数,默认为’mod’,表示对查询负责的参数切片方法,还可选’div’;
- name:可选参数,即操作的名称;
- validate_indices:可选参数,默认为True,如果ids包含超出params范围的id,则出现错误。为了防止出现错误,可以设定validate_indices=False,这时超出范围的id会被省略;
- max_norm:可选参数,用于防止查询矩阵过大。如果norm(params[i])>max_norm则params[i]会将其归一化。
TensorFlow中tf.nn.embedding_lookup函数的使用实例
实例1
假设有一个嵌入矩阵embeddings,维度为[vocab_size, embedding_size],现在需要获取id为[1,4]对应的嵌入向量。
import tensorflow as tf
# 定义嵌入矩阵
embedding_matrix = tf.Variable(tf.random.uniform([100, 20]))
# 定义id需要查询的向量
ids = tf.constant([1, 4])
# 获取id对应的嵌入向量
embed = tf.nn.embedding_lookup(embedding_matrix, ids)
# 输出结果
print(embed)
# 输出结果:
# tf.Tensor(
# [[0.4917979 0.87882507 0.57262003 0.8421457 0.5403719 0.8186798
# 0.35642695 0.38667548 0.93609357 0.05233753 0.52740574 0.23522377
# 0.74791014 0.24250424 0.32109773 0.2219608 0.34579444 0.7588749
# 0.8003664 0.3135711 ]
# [0.6517054 0.18227732 0.5801036 0.02903068 0.78686786 0.6700156
# 0.3066647 0.46917617 0.9126215 0.58738196 0.51217496 0.8223007
# 0.96326256 0.42194593 0.63572156 0.58043814 0.8691418 0.37210774
# 0.8524401 0.11304176]], shape=(2, 20), dtype=float32)
实例2
在自然语言处理中,分词是一个常见且重要的任务。假设我们现在有100个语料中的词语,需要对其进行分词,并生成一个有序的标识序列,模型利用该序列对语句中的单词做出适当的反应。运用tf.nn.embedding_lookup()
函数,需要一个嵌入矩阵 embedding_matrix,将分词序列映射到嵌入式向量,并进行下一步分析。
import tensorflow as tf
# 分词,得到100个语料的词语,其中每个词语是一个字符串
vocab = ['hello', 'world', 'happy', 'sad', 'good', 'bad', 'beautiful', 'ugly', 'rich', 'poor']
# 将各个词语映射到一个数字id
word2id = {word: i for i, word in enumerate(vocab)}
# 定义语句序列,其中第一句话中的单词为'happy', 'world', 'beautiful'
# 第二句话中的单词为'hello', 'good', 'bad', 'beautiful'
word_sequences = [['happy', 'world', 'beautiful'], ['hello', 'good', 'bad', 'beautiful']]
# 将语句序列转换成id序列
sequences = [[word2id[word] for word in seq] for seq in word_sequences]
# 定义嵌入矩阵
embedding_matrix = tf.Variable(tf.random.uniform([len(vocab), 50]))
# 定义TensorFlow嵌入层
embedding_layer = tf.keras.layers.Embedding(input_dim=len(vocab), output_dim=50)
# 应用嵌入函数
embedded_sequences_tf = embedding_layer(sequences)
# 应用tf.nn.embedding_lookup()函数
embedded_sequences_tfnn = tf.nn.embedding_lookup(embedding_matrix, sequences)
print('嵌入函数:\n', embedded_sequences_tf)
print('nn.embedding_lookup函数:\n', embedded_sequences_tfnn)
输出结果:
嵌入函数:
<tf.Tensor: id=2, shape=(2, 4, 50), dtype=float32, numpy=
array([[[-0.02657657, 0.04367925, 0.04348334, ..., -0.04511099,
-0.04847957, -0.04996951],
[ 0.03080476, 0.03671204, 0.04224157, ..., 0.04016547,
-0.01546608, -0.04328248],
[-0.04092123, 0.0071875 , 0.037015 , ..., 0.00482953,
0.03387523, 0.03677404],
[ 0.02344636, 0.01370478, -0.01861667, ..., 0.04942558,
0.00154033, -0.02365799]],
[[ 0.04021914, -0.03556326, 0.03572621, ..., 0.0094734 ,
0.00997394, 0.03245097],
[ 0.03080476, 0.03671204, 0.04224157, ..., 0.04016547,
-0.01546608, -0.04328248],
[ 0.04762372, 0.03456892, -0.00585009, ..., 0.01125333,
-0.02227677, -0.03114393],
[-0.04092123, 0.0071875 , 0.037015 , ..., 0.00482953,
0.03387523, 0.03677404]]], dtype=float32)>
nn.embedding_lookup函数:
<tf.Tensor: id=5, shape=(2, 4, 50), dtype=float32, numpy=
array([[[-0.00078437, -0.04668594, 0.04331756, ..., -0.0184459 ,
-0.00778775, -0.04864551],
[ 0.0425796 , -0.01526481, 0.03475915, ..., 0.01825951,
0.01100857, -0.02030005],
[-0.02850162, 0.01985961, -0.01198661, ..., 0.0053514 ,
0.04655654, -0.00240004],
[ 0.0425796 , -0.01526481, 0.03475915, ..., 0.01825951,
0.01100857, -0.02030005]],
[[-0.00036677, -0.03249858, -0.04684117, ..., 0.02597435,
-0.00753907, -0.01449659],
[ 0.02048823, -0.00779581, -0.04282027, ..., -0.02629659,
0.00711864, -0.03432438],
[-0.01288979, 0.0392493 , -0.03521512, ..., -0.03696192,
-0.00722067, 0.00369492],
[-0.02850162, 0.01985961, -0.01198661, ..., 0.0053514 ,
0.04655654, -0.00240004]]], dtype=float32)>
可以看到,我们利用嵌入函数和tf.nn.embedding_lookup()
函数都成功完成了相同的计算,将分词序列转换为相应的嵌入向量。