以下是自己的一些想法和提问,不一定正确,还望大家指正,感恩!
word2vec为什么使用NCE?
使用NCE来替代softmax, 是因为softmax在类别很多很多的时候计算量大(计算每个类的得分的时候都需要对所有类求和来做分母),word2vec最后需要输出词表大小的类别,数量很大。NCE相当于将多类别分类变成多个二类分类,正类是输入词的上下文中的某个词,负类是不属于上下文的某些词。
什么是NCE?
可以参考博客 https://blog.youkuaiyun.com/littlely_ll/article/details/79252064
简单理解是使用logistic regression区分正类和负类。
word2vec中使用nce 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.
# tf.nce_loss automatically draws a new sample of the negative labels each
# time we evaluate the loss.
loss = tf.reduce_mean(
tf.nn.nce_loss(weights=nce_weights,
biases=nce_biases,
labels=train_labels,
inputs=embed,
num_sampled=num_sampled,
num_classes=vocabulary_size))
nce_weights, nce_biases是否就相当于之前提到的logistic regression所需要的参数,这些参数在训练过程中会更新
而embedding相当与从输入层到隐藏层中间的参数,backpropagation后也会更新这些参数,也就是相当于词向量表得到更新。