4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
4 关于word2vec的skip-gram模型使用负例采样nce_loss损失函数的...
来自 : 开源中国 发布时间:2021-03-25
sampled_losses = sigmoid_cross_entropy_with_logits( labels=labels, logits=logits, name=\"sampled_losses\") # sampled_losses is batch_size x {true_loss, sampled_losses...} # We sum out true and sampled losses. return _sum_rows(sampled_losses)

可以看出核心就在于传入sigmoid_cross_entropy_with_logits的参数。对于任何一个输出节点只有一个的二分类神经网络,用sigmoid_cross_entropy_with_logits是最好理解的。logits的维度是batch_size,1。labels的维度就是batch_size,元素取值为0或者1,

来看一下sigmoid_cross_entropy_with_logits函数

\"\"

sigmoid_cross_entropy_with_logits的返回值是:

Returns: A `Tensor` of the same shape as `logits` with the componentwise logistic losses.

也就是说:logits的维度是batch_size,1,其返回的维度也是batch_size,1。这个位置的元素就是用这个公式计算的loss:

\"\"

但是在负例采样中,传入的logits的维度不是batch_size,1,而是[batch_size, num_true + num_sampled]`。主要观察一下_compute_sampled_logits函数的输出。其输出如下:

Returns: out_logits: `Tensor` object with shape `[batch_size, num_true + num_sampled]`, for passing to either `nn.sigmoid_cross_entropy_with_logits` (NCE) or `nn.softmax_cross_entropy_with_logits` (sampled softmax). out_labels: A Tensor object with the same shape as `out_logits`. \"\"\"

其传入参数的解释是:

labels: A `Tensor` of type `int64` and shape `[batch_size, num_true]`. The target classes. Note that this format differs from the `labels` argument of `nn.softmax_cross_entropy_with_logits`. inputs: A `Tensor` of shape `[batch_size, dim]`. The forward activations of the input network. weights: A `Tensor` of shape `[num_classes, dim]`, or a list of `Tensor` objects whose concatenation along dimension 0 has shape `[num_classes, dim]`. The (possibly-partitioned) class embeddings.

可以看出_compute_sampled_logits完成的是一个什么过程呢。就是对于每一个样本,计算出一个维度为[batch_size, num_true + num_sampled]的向量,向量的每个元素都同之前logits的每个元素的意义一样,是输出值。同时,返回一个维度为[batch_size, num_true + num_sampled]的向量labels。这个labels中只有一个元素为1。于是再看一下如下公式:

\"\"

其实,此时的out_logits中对应(label位置为0)的元素就是\"\",对应label位置为1)的元素就是\"\"

然后再传给sigmoid_cross_entropy_with_logits,同样是对于每个元素位置的计算使用下面的公式:

\"\"

所以,nce_loss中调用sigmoid_cross_entropy_with_logits后返回的是:[batch_size, num_true + num_sampled]的向量,其中每个元素都是一个用上述公式计算出loss。

nce_loss的最后一步是_sum_rows:

def _sum_rows(x): \"\"\"Returns a vector summing up each row of the matrix x.\"\"\" # _sum_rows(x) is equivalent to math_ops.reduce_sum(x, 1) when x is # a matrix. The gradient of _sum_rows(x) is more efficient than # reduce_sum(x, 1)\'s gradient in today\'s implementation. Therefore, # we use _sum_rows(x) in the nce_loss() computation since the loss # is mostly used for training. cols = array_ops.shape(x)[1] ones_shape = array_ops.stack([cols, 1]) ones = array_ops.ones(ones_shape, x.dtype) return array_ops.reshape(math_ops.matmul(x, ones), [-1])

最后,再对nce_loss的返回结果用reduce_mean即可计算一个batch的平均损失。

关于_compute_sampled_logits中如何采样,如何计算的,这里就不再阐述,同文字理论是一样的。

我们将_compute_sampled_logits函数中的

# Construct output logits and labels. The true labels/logits start at col 0. out_logits = array_ops.concat([true_logits, sampled_logits], 1) # true_logits is a float tensor, ones_like(true_logits) is a float # tensor of ones. We then divide by num_true to ensure the per-example # labels sum to 1.0, i.e. form a proper probability distribution. out_labels = array_ops.concat([ array_ops.ones_like(true_logits) / num_true, array_ops.zeros_like(sampled_logits) ], 1)

改为

out_logits = array_ops.concat([true_logits, sampled_logits], 1,name=\"xiaojie_logits\") # true_logits is a float tensor, ones_like(true_logits) is a float # tensor of ones. We then divide by num_true to ensure the per-example # labels sum to 1.0, i.e. form a proper probability distribution. out_labels = array_ops.concat([ array_ops.ones_like(true_logits) / num_true, array_ops.zeros_like(sampled_logits)], 1,name=\"xiaojie_labels\")然后由于这些代码位于: with ops.name_scope(name, \"compute_sampled_logits\", weights + [biases, inputs, labels]):ops指定的name下,name为“nce_loss”

本文链接: http://nceed.immuno-online.com/view-747317.html

发布于 : 2021-03-25 阅读(0)