Python 理解tensorflow中的'tf.nn.nce_loss()
我试图理解张量流中的NCE损失函数。NCE丢失用于word2vec任务,例如:Python 理解tensorflow中的'tf.nn.nce_loss(),python,tensorflow,Python,Tensorflow,我试图理解张量流中的NCE损失函数。NCE丢失用于word2vec任务,例如: # 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 variable
# 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))
更多详细信息,请参考Tensorflow
嵌入
,输出矩阵是nce\u权重
。是这样吗
根据同样与
nce
相关的一位学者的说法,最终的嵌入矩阵就是输入矩阵。而最终嵌入=输入矩阵+输出矩阵
。哪个是正确的/更常见的?嵌入张量是最终的输出矩阵。它将单词映射到向量。在单词预测图中使用此选项
输入矩阵是从培训文本生成的一批中心词:上下文词对(train\u input
和train\u label
)
虽然我还不知道nce\u loss
op的确切工作原理,但其基本思想是,它使用单层网络(参数nce\u权重
和nce\u偏差
)将输入向量(使用嵌入
op从嵌入中选择)映射到输出字,然后将输出与训练标签(训练文本中的相邻单词)以及vocab中所有其他单词的随机子样本(num_sampled
)进行比较,然后修改输入向量(存储在embeddings
)和网络参数,以将错误降至最低
NCE函数中的输入和输出矩阵是什么
以skip gram模型为例,对于这句话:
敏捷的棕色狐狸跳过了懒狗
输入和输出对为:
(快,那个),(快,棕色),(棕色,快),(棕色,狐狸),…
有关更多信息,请参阅
什么是最终嵌入
您应该提取的最终嵌入通常是输入层和隐藏层之间的{w}
# 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]))
loss = tf.reduce_mean(
tf.nn.nce_loss(weights=nce_weights, # [vocab_size, embed_size]
biases=nce_biases, # [vocab_size]
labels=train_labels, # [bs, 1]
inputs=embed, # [bs, embed_size]
num_sampled=num_sampled,
num_classes=vocabulary_size))
为了更直观地说明,请看下图:
一个热向量[0,0,0,1,0]是上图中的输入层,输出是单词嵌入[10,12,19],W(上图中)是介于两者之间的矩阵
有关详细说明,请阅读。1)简而言之,它在总体上是正确的,但对于所讨论的函数来说只是部分正确。见:
噪声对比估计损失定义为
logistic回归模型。为此,我们需要定义权重和
词汇表中每个单词的偏差(也称为输出权重
与输入嵌入相反
因此,函数nce\u loss
的输入是输出权重
和一小部分输入嵌入
2) “最终”嵌入(又名单词向量,又名单词向量表示)就是您所说的输入矩阵。嵌入是该矩阵的字符串(向量),对应于每个单词
警告事实上,由于在NN环境中使用输入和输出概念,这个术语令人困惑。嵌入矩阵不是NN的输入,因为NN的输入在技术上是一个输入层。您可以在培训过程中获得此矩阵的最终状态。尽管如此,该矩阵应在编程时初始化,因为算法必须从该矩阵的某个随机状态开始,以便在训练期间逐步更新
重量也是如此——它们也需要初始化。它发生在以下行中:
nce_weights = tf.Variable(
tf.truncated_normal([50000, 128], stddev=1.0 / math.sqrt(128)))
每个嵌入向量可以与权重矩阵中的向量相乘(以字符串到列的方式)。因此,我们将在NN输出层
中获得标量。该标量的范数被解释为目标词(来自输入层)将伴随与输出层中标量位置对应的标签[或上下文]词的概率
因此,如果我们说的是函数的输入(参数),那么这两个矩阵都是这样的:权重和从嵌入中批量提取:
tf.nn.nce_loss(weights=nce_weights, # Tensor of shape(50000, 128)
biases=nce_biases, # vector of zeros; len(128)
labels=train_labels, # labels == context words enums
inputs=embed, # Tensor of shape(128, 128)
num_sampled=num_sampled, # 64: randomly chosen negative (rare) words
num_classes=vocabulary_size)) # 50000: by construction
此nce\u loss
函数输出批量大小的向量-在TensorFlow示例中是一个shape(128,)
tensor。
然后reduce_mean()
将此结果减少到一个标量,取这128个值的平均值,这实际上是进一步最小化的目标
希望这有帮助。让我们看看word2vec示例()中的相关代码
这两条线创建嵌入表示<代码>嵌入
是一个矩阵,其中每行表示一个单词向量<代码>嵌入查找
是一种快速获取与训练输入
对应的向量的方法。在word2vec示例中,train_输入由一些int32
数字组成,表示目标单词的id
。基本上,它可以通过隐藏层功能放置
# 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]))
loss = tf.reduce_mean(
tf.nn.nce_loss(weights=nce_weights, # [vocab_size, embed_size]
biases=nce_biases, # [vocab_size]
labels=train_labels, # [bs, 1]
inputs=embed, # [bs, embed_size]
num_sampled=num_sampled,
num_classes=vocabulary_size))
这两行创建参数。它们将在培训期间由optimizer更新。我们可以使用tf.matmul(嵌入,tf.transpose(nce_权重))+nce_偏差
来获得最终的输出分数。换句话说,分类中的最后一个内积层可以被它所取代
# 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]))
loss = tf.reduce_mean(
tf.nn.nce_loss(weights=nce_weights, # [vocab_size, embed_size]
biases=nce_biases, # [vocab_size]
labels=train_labels, # [bs, 1]
inputs=embed, # [bs, embed_size]
num_sampled=num_sampled,
num_classes=vocabulary_size))
这些行创建了nce损耗,@garej
给出了很好的解释num_sampled
是指nce中的负采样数<