【问题标题】:What is the purpose of weights and biases in tensorflow word2vec example?tensorflow word2vec 示例中权重和偏差的目的是什么?
【发布时间】:2016-06-23 04:40:19
【问题描述】:

我试图了解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)

那么模型的第二个组件呢?为什么权重和偏见被忽略了?

谢谢。

【问题讨论】:

    标签: machine-learning tensorflow deep-learning


    【解决方案1】:

    在 word2vec 中,您想要的是单词的向量表示。为此,您可以使用神经网络等。所以你有输入神经元、输出和隐藏层。你学习向量表示的方法是有一个隐藏层,它的神经元数量与你想要的向量维度相同。每个单词有一个输入,每个单词有一个输出。然后你训练网络从输出中学习输入,但在中间你有一个较小的层,你可以将其视为向量中输入的编码。所以这里是权重和偏差。但是您以后不需要它们,您用于测试的是一个包含单词和表示该单词的向量的字典。这比运行神经网络来获得表示要快。这就是为什么你以后看不到它的原因。

    您编写的关于余弦距离的最后一个代码是了解哪些向量与您的计算向量接近。你有一些词(向量)你做了一些操作(比如:国王 - 男人+女人),然后你有一个你想在结果中转换的向量。这是在所有向量之间运行的余弦函数(queen 与运算结果向量的距离最小)。

    总而言之,您在验证阶段看不到权重和偏差,因为您不需要它们。你使用你在训练中创建的字典。

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

    网络的输入层和输出层代表单词。这意味着如果该词不存在则值为 0,如果该词存在则值为 1。第一个位置是一个单词,第二个是另一个单词,依此类推。输入/输出神经元就是单词。

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

    现在您使用句子或一组连续单词来训练网络。从这个组中,你取一个词并将其设置在输入中,其他词是网络的输出。所以基本上网络会学习一个词如何与上下文中的其他词相关。

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

    以后不用网络,因为不需要计算上下文层的所有值,会比较慢。你只需要在你的字典里查一下这个词的那些值是什么。

    【讨论】:

    • 我明白你的意思,但在这种情况下,每个单词的输入和每个单词的输出是来自嵌入的随机值。通常,在学习过程中,只会更新层的权重和偏差。但在这种情况下(这让我感到困惑)学习过程会更新输入、输出(它们都来自嵌入的不同部分)以及权重。此外,学习似乎是随机的,因为每个单词的权重都是随机的。我错过了什么吗?
    • 它们不是随机值,它们是随机选择的值。当你有一个数据集并且你要在几个时期运行算法时,你所做的就是在每个时期随机化数据集的顺序,这就是随机选择值的原因。权重在开始时是随机的,然后由优化器在每批中修改。它们在开始时是随机化的,以避免陷入局部最小值。
    • 这让我非常兴奋。你的意思是我们不需要权重,因为我们只需要单词之间的关系信息,而不是“绝对”值?在这样的数学运算中,所有的权重都会抵消吗?
    • 不,我不是那个意思。 Word2Vec 尝试创建单词的向量表示。神经网络是一种方式,但还有更多。所以基本上神经网络是学习每个单词的向量。然后你使用一个字典来存储单词和向量之间的关系。就这些。所以你以后不需要神经网络的权重来获得向量,因为你使用了字典。您可以使用神经网络,但它可能会更慢。
    • 好的,我明白那部分。但是权重和输入会在每个时期同时更新。对我来说,它们看起来同样重要。并且权重没有用于关系计算。我只能看到两个原因:要么权重抵消,要么我们没有通过剥离模型的一部分来丢失太多信息。这是正确的直觉吗?
    【解决方案2】:

    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。当训练结束时,我们扔掉第二层的矩阵,因为它代表了上下文。我们只使用第一层的矩阵来表示单词的向量编码。

    【讨论】:

      【解决方案3】:

      权重和偏差在此处更新:

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2017-07-15
        • 2017-12-01
        • 2017-02-26
        • 2019-12-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多