tensorflow word2vec 示例中权重和偏差的目的是什么?
What is the purpose of weights and biases in tensorflow word2vec example?
我试图了解 word2vec example 的工作原理,但并不真正了解传递到 nse_loss 函数的权重和偏差的目的是什么。该函数有两个变量输入:权重(加上偏差)和嵌入。
# Look up embeddings for inputs.
embeddings = tf.Variable(
tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_inputs)
# Construct the variables for the NCE loss
nce_weights = tf.Variable(
tf.truncated_normal([vocabulary_size, embedding_size],
stddev=1.0 / math.sqrt(embedding_size)))
nce_biases = tf.Variable(tf.zeros([vocabulary_size]))
两者都是随机初始化的,并且(据我所知)两者都在学习过程中进行更新。
# Compute the average NCE loss for the batch.
loss = tf.reduce_mean(
tf.nn.nce_loss(nce_weights, nce_biases, embed, train_labels,
num_sampled, vocabulary_size))
我想它们都应该代表训练有素的模型。然而,权重和偏差不会在以后用于相似性计算。相反,只使用一个组件:
# Compute the cosine similarity between minibatch examples and all embeddings.
norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True))
normalized_embeddings = embeddings / norm
valid_embeddings = tf.nn.embedding_lookup(
normalized_embeddings, valid_dataset)
similarity = tf.matmul(
valid_embeddings, normalized_embeddings, transpose_b=True)
那么模型的第二个组成部分呢?为什么权重和偏差被忽略了?
谢谢。
在 word2vec 中,您需要的是单词的矢量表示。为此,您可以使用神经网络等。所以你有输入神经元、输出和隐藏层。学习向量表示的方法是拥有一个隐藏层,其神经元数量与向量中所需的维度相同。每个词有一个输入,每个词有一个输出。然后你训练网络从输出中学习输入,但在中间你有一个较小的层,你可以将其视为向量中输入的编码。所以这是权重和偏差。但是您以后不需要它们,您用于测试的是一个字典,其中包含单词和代表该单词的向量。这比 运行 神经网络获得表示更快。这就是为什么你以后看不到它的原因。
你最后写的关于余弦距离的代码是为了知道哪些向量与你计算的向量接近。你有一些词(向量)你做了一些操作(比如:国王 - 男人 + 女人)然后你有一个你想要在结果中转换的向量。这是所有向量中的余弦函数运行(queen与运算结果向量的距离最小)
总而言之,您在验证阶段看不到权重和偏差,因为您不需要它们。您使用您在培训中创建的词典。
更新 s0urcer 更好地解释了如何创建矢量表示。
网络的输入层和输出层表示单词。这意味着如果单词不存在则值为 0,如果单词存在则值为 1。第一个位置是一个单词,第二个是另一个单词,依此类推。您有 input/output 个神经元作为单词。
中间层是上下文,或者是单词的向量表示。
现在你用句子或一组连续的词来训练网络。从这一组中,你取一个词并将其设置在输入中,其他词是网络的输出。所以基本上网络学习了一个词如何与其上下文中的其他词相关。
要获得每个词的向量表示,您将该词的输入神经元设置为 1 并查看上下文层(中间层)的值。这些值是向量的值。由于除了单词为 1 之外所有输入均为 0,因此这些值是输入神经元与上下文的连接权重。
后面不要用网络,因为不需要计算context层的所有值,那样会比较慢。你只需要在你的字典中检查这个词的那些值是什么。
权重和偏差在此处更新:
_, loss_val = session.run([optimizer, loss], feed_dict=feed_dict)
优化器执行以下操作 - 计算梯度,然后执行更新步骤。
相似之处在于在不同位置调用单独的计算并用于验证结果。这发生在以下代码部分:
if step % 10000 == 0:
sim = similarity.eval()
嵌入的验证依赖于相似性嵌入。
skip-gramm 的思想是根据上下文比较单词。因此,如果单词出现在相同的上下文中,我们就认为它们是相等的。 NN 的第一层表示词向量编码(基本上就是所谓的嵌入)。第二层表示上下文。每次我们只取第一层的一行 (Ri)(因为输入向量总是看起来像 0, ..., 0, 1, 0, ..., 0)并将它乘以第二层的所有列(Cj , j = 1..num of words) 并且该产品将是 NN 的输出。如果单词 i 和 j 经常出现在附近(在相同的上下文中),我们训练神经网络具有最大输出分量 Ri * Cj。在每个训练周期中,我们只调整一个 Ri(同样是因为选择输入向量的方式)和所有 Cj,j = 1..w。当训练结束时,我们将第二层的矩阵扔掉,因为它代表上下文。我们只使用第一层的矩阵,表示单词的向量编码。
我试图了解 word2vec example 的工作原理,但并不真正了解传递到 nse_loss 函数的权重和偏差的目的是什么。该函数有两个变量输入:权重(加上偏差)和嵌入。
# Look up embeddings for inputs.
embeddings = tf.Variable(
tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_inputs)
# Construct the variables for the NCE loss
nce_weights = tf.Variable(
tf.truncated_normal([vocabulary_size, embedding_size],
stddev=1.0 / math.sqrt(embedding_size)))
nce_biases = tf.Variable(tf.zeros([vocabulary_size]))
两者都是随机初始化的,并且(据我所知)两者都在学习过程中进行更新。
# Compute the average NCE loss for the batch.
loss = tf.reduce_mean(
tf.nn.nce_loss(nce_weights, nce_biases, embed, train_labels,
num_sampled, vocabulary_size))
我想它们都应该代表训练有素的模型。然而,权重和偏差不会在以后用于相似性计算。相反,只使用一个组件:
# Compute the cosine similarity between minibatch examples and all embeddings.
norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True))
normalized_embeddings = embeddings / norm
valid_embeddings = tf.nn.embedding_lookup(
normalized_embeddings, valid_dataset)
similarity = tf.matmul(
valid_embeddings, normalized_embeddings, transpose_b=True)
那么模型的第二个组成部分呢?为什么权重和偏差被忽略了?
谢谢。
在 word2vec 中,您需要的是单词的矢量表示。为此,您可以使用神经网络等。所以你有输入神经元、输出和隐藏层。学习向量表示的方法是拥有一个隐藏层,其神经元数量与向量中所需的维度相同。每个词有一个输入,每个词有一个输出。然后你训练网络从输出中学习输入,但在中间你有一个较小的层,你可以将其视为向量中输入的编码。所以这是权重和偏差。但是您以后不需要它们,您用于测试的是一个字典,其中包含单词和代表该单词的向量。这比 运行 神经网络获得表示更快。这就是为什么你以后看不到它的原因。
你最后写的关于余弦距离的代码是为了知道哪些向量与你计算的向量接近。你有一些词(向量)你做了一些操作(比如:国王 - 男人 + 女人)然后你有一个你想要在结果中转换的向量。这是所有向量中的余弦函数运行(queen与运算结果向量的距离最小)
总而言之,您在验证阶段看不到权重和偏差,因为您不需要它们。您使用您在培训中创建的词典。
更新 s0urcer 更好地解释了如何创建矢量表示。
网络的输入层和输出层表示单词。这意味着如果单词不存在则值为 0,如果单词存在则值为 1。第一个位置是一个单词,第二个是另一个单词,依此类推。您有 input/output 个神经元作为单词。
中间层是上下文,或者是单词的向量表示。
现在你用句子或一组连续的词来训练网络。从这一组中,你取一个词并将其设置在输入中,其他词是网络的输出。所以基本上网络学习了一个词如何与其上下文中的其他词相关。
要获得每个词的向量表示,您将该词的输入神经元设置为 1 并查看上下文层(中间层)的值。这些值是向量的值。由于除了单词为 1 之外所有输入均为 0,因此这些值是输入神经元与上下文的连接权重。
后面不要用网络,因为不需要计算context层的所有值,那样会比较慢。你只需要在你的字典中检查这个词的那些值是什么。
权重和偏差在此处更新:
_, loss_val = session.run([optimizer, loss], feed_dict=feed_dict)
优化器执行以下操作 - 计算梯度,然后执行更新步骤。
相似之处在于在不同位置调用单独的计算并用于验证结果。这发生在以下代码部分:
if step % 10000 == 0:
sim = similarity.eval()
嵌入的验证依赖于相似性嵌入。
skip-gramm 的思想是根据上下文比较单词。因此,如果单词出现在相同的上下文中,我们就认为它们是相等的。 NN 的第一层表示词向量编码(基本上就是所谓的嵌入)。第二层表示上下文。每次我们只取第一层的一行 (Ri)(因为输入向量总是看起来像 0, ..., 0, 1, 0, ..., 0)并将它乘以第二层的所有列(Cj , j = 1..num of words) 并且该产品将是 NN 的输出。如果单词 i 和 j 经常出现在附近(在相同的上下文中),我们训练神经网络具有最大输出分量 Ri * Cj。在每个训练周期中,我们只调整一个 Ri(同样是因为选择输入向量的方式)和所有 Cj,j = 1..w。当训练结束时,我们将第二层的矩阵扔掉,因为它代表上下文。我们只使用第一层的矩阵,表示单词的向量编码。