在TensorFlow Word2Vec示例中,权重和偏见的目的是什么?



我试图了解Word2Vec示例的工作原理,并且并不真正了解将权重和偏见传递到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中您想要的是单词的向量表示。为了做到这一点,您可以使用神经网络。因此,您有输入神经元,输出和隐藏层。您要学习矢量表示的方法是拥有一个隐藏的层,哪个神经元的数量与矢量中所需的维度相同。每个单词有一个输入,每个单词有一个输出。然后,您将网络训练以从输出中学习输入,但是在中间,您有一个较小的层,您可以将其视为向量中输入的编码。因此,这是权重和偏见。但是您以后不需要它们,您用于测试的内容是一个字典,其中包含代表该单词的单词和向量。这比运行神经网络以获取表示更快。这就是为什么您以后再也看不到它。

您写的有关余弦距离的最后一个代码是要知道哪些向量对您计算的向量已关闭。您有一些单词(向量)您进行了一些操作(例如:King -Man Woman),然后您有一个要在结果中转换的向量。这是所有向量之间运行的余弦函数(Queen与操作的结果向量具有最小距离)。

总结一下,您不会在验证阶段看到重量和偏差,因为您不需要它们。您使用您在培训中创建的字典。

update s0urcer更好地解释了如何创建向量表示。

网络的输入层和输出层表示单词。这意味着如果单词不存在,则值为0,如果单词在那里,则为1。第一个位置是一个单词,彼此第二个等。您的输入/输出神经元与单词一样

中间层是上下文,或者您的向量表示单词的表示。

现在,您可以用句子或一组连续单词训练网络。从这个组中,您可以键入一个单词并将其设置在输入中,而其他单词是网络的输出。因此,基本上,网络了解一个单词与其上下文中的其他单词之间的关系。

要获取每个单词的向量表示,您将单词的输入神经元设置为1,并查看上下文层的值(中间层)。这些值是向量的值。由于所有输入均为0,但单词为1,这些值是输入神经元与上下文的连接的权重。

您以后不会使用网络,因为您不需要计算上下文层的所有值,这会慢。您只需要在字典中检查单词的这些值是什么。

skip-gramm的想法正在通过其上下文进行比较。因此,如果单词出现在平等的上下文中,我们认为它们相等。NN的第一层表示单词向量编码(基本上是所谓的嵌入)。第二层代表上下文。每次我们仅采用第一层的一行(RI)(因为输入向量总是看起来像0,...,0、1、0,...,0),并将其乘以第二层的所有列(CJ,CJ,j = 1 ..单词),该产品将是NN的输出。如果单词i和j经常出现在附近(在同一上下文中),我们将训练神经网络具有最大的输出组件RI * CJ。在训练的每个周期中,我们仅调整一个RI(再次是由于选择输入向量的方式)和所有CJ,j = 1..w。当训练结束时,我们将第二层的矩阵抛弃,因为它代表上下文。我们仅使用代表单词的向量编码的第一层的矩阵。

权重和偏见在此处进行更新:

_, loss_val = session.run([optimizer, loss], feed_dict=feed_dict)

优化器执行以下操作 - 计算梯度,然后执行更新步骤。

相似性是一个单独的计算,在不同的位置被调用,用于验证结果。这发生在代码的以下部分中:

if step % 10000 == 0: sim = similarity.eval()

嵌入的验证依赖于相似性嵌入。

最新更新