Pairwise 损失函数的计算
CTR/CVR/LTV 预估中, 反馈通常是非常稀疏的行为, 我们期望引入 pairwise 的 ranking 损失去精细化建模, 针对激活后付费预估任务增加 ranking 损失: 具体做法对一个 batch 里面的 label, 构造正负样本 logit 对, 损失计算的是 log(sigmoid(s_i-s_j))/pair_nums
核心思想是
实际操作是
实现 & 测试代码
import tensorflow as tf
import numpy as np
tensor = [0, 1, 2, 3]
t_mask = np.array([True, False, True, False])
b = tf.boolean_mask(tensor, t_mask)
tf.print(b)
def pairwise_ranking_loss_with_logits(self, labels, logits, name=None):
labels = tf.reshape(tf.cast(labels, tf.float32), [-1, 1])
logits = tf.reshape(tf.cast(logits, tf.float32), [-1, 1])
pos_mask = tf.clip_by_value(labels, 0.0, 1.0)
neg_mask = 1.0 - pos_mask
pos_nums = tf.reduce_sum(pos_mask)
neg_nums = tf.reduce_sum(neg_mask)
pairs = pos_nums * neg_nums
pos_logits = tf.reshape(tf.boolean_mask(logits, pos_mask), [-1, 1])
neg_logits = tf.reshape(tf.boolean_mask(logits, neg_mask), [1, -1])
pos_logits_matrix = tf.tile(pos_logits, [1, neg_nums])
neg_logits_matrix = tf.tile(neg_logits, [pos_nums, 1])
delta_logits_matrix = pos_logits_matrix - neg_logits_matrix
rank_logits_mean = tf.where(tf.equal(pairs, 0.), 0.0, tf.reduce_sum(delta_logits_matrix) / pairs)
ranknet_loss = tf.reduce_sum(-tf.math.log_sigmoid(delta_logits_matrix))
ranknet_loss = tf.where(tf.equal(pairs, 0.), 0.0, ranknet_loss / pairs)
return ranknet_loss
labels = [ 1, 0, 0, 0, 0, 1]
logits = [0.8,0.3,0.2,0.15,0.01,0.7]
labels = tf.reshape(tf.cast(labels, tf.float32), [-1, 1])
logits = tf.reshape(tf.cast(logits, tf.float32), [-1, 1])
print(f"labels.shape()={labels.get_shape().as_list()}")
print(f"logits.shape()={logits.get_shape().as_list()}")
pos_mask = tf.clip_by_value(labels, 0.0, 1.0)
neg_mask = 1.0 - pos_mask
print("pos_mask:")
tf.print(pos_mask)
pos_nums = tf.reduce_sum(pos_mask)
neg_nums = tf.reduce_sum(neg_mask)
tf.print(pos_nums)
tf.print(neg_nums)
pairs = pos_nums * neg_nums
print("num_pairs:")
tf.print(pairs)
pos_logits = tf.reshape(tf.boolean_mask(logits, pos_mask), [-1, 1])
neg_logits = tf.reshape(tf.boolean_mask(logits, neg_mask), [1, -1])
tf.print(pos_logits)
tf.print(neg_logits)
pos_logits_matrix = tf.tile(pos_logits, [1, neg_nums])
neg_logits_matrix = tf.tile(neg_logits, [pos_nums, 1])
delta_logits_matrix = pos_logits_matrix - neg_logits_matrix
tf.print(pos_logits_matrix)
tf.print(neg_logits_matrix)
tf.print(delta_logits_matrix)
print(f"pos_logits_matrix.shape()={pos_logits_matrix.get_shape().as_list()}")
t = -tf.math.log_sigmoid(delta_logits_matrix)
tf.print(t)
ranknet_loss = tf.reduce_sum(-tf.math.log_sigmoid(delta_logits_matrix))
tf.print(ranknet_loss)
ranknet_loss_final = tf.where(tf.equal(pairs, 0.), 0.0, ranknet_loss / pairs)
tf.print(ranknet_loss_final)
Reference
[1]. On the Factory Floor: ML Engineering for Industrial-Scale Ads Recommendation Models.
[2]. Learning to Rank using Gradient Descent.
转载请注明来源, from goldandrabbit.github.io