TF中的负采样损失函数(word2vec中的负采样)

在训练word2vec的时候,为了预测目标词是哪个词,我们要使用softmax函数进行预测,也就是一个softmax多分类的问题(每个单词就是一类)。类似下面的式子
p ( o j ∣ w i ) = e f ( o j , w i ) ∑ j = 1 ∣ V ∣ e f ( o j , w i ) (1) \tag{1} p(o_{j}|w_{i}) = {e^{f(o_{j}, w_{i})} \over \sum_{j = 1}^{|V|} e^{f(o_{j}, w_{i})}} p(ojwi)=j=1Vef(oj,wi)ef(oj,wi)(1)
其中 f ( o j , w i ) f(o_{j}, w_{i}) f(oj,wi)衡量了预测单词 o j 与 输 入 单 词 w i o_{j}与输入单词w_{i} ojwi之间的某种联系。分母计算了整个词汇表的大小,所以在训练的时候很慢。解决的办法就是负采样,每次只评估所有类别的一个很小的子集,也就是分母不再是计算整个词汇表的大小,而是从词汇表中挑选出一些样本,然后在这些样本上进行计算。
p ( o j ∣ w i ) = e f ( o j , w i ) ∑ j = 1 ∣ V N E ∣ e f ( o j , w i ) (2) \tag{2} p(o_{j}|w_{i}) = {e^{f(o_{j}, w_{i})} \over \sum_{j = 1}^{|V_{NE}|} e^{f(o_{j}, w_{i})}} p(ojwi)=j=1VNEef(oj,wi)ef(oj,wi)(2)
其中 V N E V_{NE} VNE是负采样的样本集大小。

TF中采用上述思想实现了一些负采样损失的函数。

def sampled_softmax_loss(weights,
                         biases,
                         labels,
                         inputs,
                         num_sampled,
                         num_classes,
                         num_true=1,
                         sampled_values=None,
                         remove_accidental_hits=True,
                         partition_strategy="mod",
                         name="sampled_softmax_loss",
                         seed=None)

这个函数通过 模型的交叉熵损失。负采样类别子集由采样类别真实类别组成,即 。模型最后一层输出是 , 经过 softmax 激活函数转成模型输出的概率得出 。这个函数只能处理单个标签的情况,如果要处理多标签的情况使用下面的函数。

def nce_loss(weights, 
			 biases, 
			 inputs, 
			 labels, 
			 num_sampled, 
			 num_classes,
             num_true=1,
             sampled_values=None,
             remove_accidental_hits=False,
             partition_strategy="mod",
             name="nce_loss")

还有博客上说word2vec的负采样思想是:
比如根据这句话训练word2vec,The quick brown fox jumps over the lazy dog.,那么根据skip-gram的形式,我们设置中心词fox的上下文范围。我们使用skip_window来表示我们从中心词的左右两侧选取的词的数量,num_skips 表示我们在中心词的上下文中选取作为输出词的数量。例如:当skip_window=2,num_skips = 2,中心词为fox时 ,我们获得fox的上下文窗口为 [‘quick’,‘brown’,‘jumps’,‘over’]。我们随机从窗口中选取两个词作为输出,那么我们的样本元组应该如同:('fox','brown'),('fox','over')

由于训练神经网络模型为了达到更高的精度,需要通过每个训练样本细微地调整每个神经元的权重参数,因此每个训练样本都会微调神经网络中的所有参数。假设词汇表大小为10000,输出层神经元个数也为10000,那么输入一个训练样本('fox','brown')的时候,我们要更新这10000个神经元的权值。这样会导致训练过程很慢。
Negative Sampling通过让每个训练样本只修改一小部分权重(而不是网络中的全部权重)来解决计算量特别大的问题。如果使用了 negative sampling 仅仅去更新positive word 和选择的其他几个negative words 的结点对应的权重,这样计算量会大大降低。

个人觉得上述思想和我一开始所说的达到的效果一致,但是理解起来可能有困难。有理解的同学可以指点一下。

关于word2vec更详细的信息可以看博客word2vec详解(CBOW,skip-gram,负采样,分层Softmax)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值