batch内负采样

2022-09-12 08:10:10 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

一般在计算softmax交叉熵时,需要用tf.nn.log_uniform_candidate_sampler对itemid做随机负采样。但是在类似dssm这种双塔模型中,item侧特征除了itemid外,还有其他meta特征,此时负样本对itemid做负采样后,还需要取相应负样本的meta特征。可是在tf训练数据中并不方便建立itemid与各类meta特征的映射表。 为了解决dssm类模型的负采样问题,可以取一个batch内其他用户的正样本做为本用户的负样本,以解决负采样meta特征问题。好了,废话少说,直接上代码

代码语言:javascript复制
     for i in range(NEG):
        rand = int((random.random()   i) * batchSize / NEG)
        item_y = tf.concat([item_y,
                            tf.slice(item_y_temp, [rand, 0], [batchSize - rand, -1]),
                            tf.slice(item_y_temp, [0, 0], [rand, -1])], 0)
      prod_raw = tf.reduce_sum(tf.multiply(tf.tile(user_y, [NEG   1, 1]), item_y), 1, True)
      prod = tf.transpose(tf.reshape(tf.transpose(prod_raw), [NEG   1, batchSize])) 
      # 转化为softmax概率矩阵。
      prob = tf.nn.softmax(prod)
      # 只取第一列,即正样本列概率。
      hit_prob = tf.slice(prob, [0, 0], [-1, 1])
      loss = -tf.reduce_mean(tf.log(hit_prob))

代码注解: 其中item_y和item_y_temp 初始化为item侧最后一层embedding值,shape为[batchSize, emb_size]。 user_y为user侧最后一层embedding值,shape为[batchSize, emb_size]。 NEG为负采样个数,batchSize为batch大小。

  1. 在每次循环中,通过rand值打乱item_y_temp的行顺序,相当于取其他用户的正样本做为本用户的负样本
  2. 经历NEG次循环后,item_y的shape变为[(NEG 1)*batchSize, emb_size];注:item_y初始值有batchSize行,每次循环累加batchSize行
  3. 与user_emb点乘后,prod_raw的shape为[(NEG 1)*batch_size,1],
  4. 经过reshape和转置后,prod的shape为[batch_size,(NEG 1)];注:prod的第一列为正样本,其他列为负样本。

后面即可计算出采样后的softmax交叉熵了。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/149671.html原文链接:https://javaforall.cn

0 人点赞