栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

排序算法常用损失函数

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

排序算法常用损失函数

ListMLE

$S=left{s_{1}, s_{2}, s_{3}, ldots, s_{n}right}$ 表示模型对n个doc的得分,将预测得分按目标顺序排列,

$hat{S}=left{s_{pi_{1}}, s_{pi_{2}}, s_{pi_{3}}, ldots, s_{pi_{n}}right}$

$P(hat{S})=prod_{i=1}^{n} frac{exp left(s_{pi_{i}}right)}{sum_{j=i}^{n} exp left(s_{pi_{j}}right)}$

$L=-log P(hat{S})$

def list_mle(logits, labels, topn):
    """
    将预测得分按真实顺序排列,根据PL模型构造排序的概率
    """
    _, indices = tf.math.top_k(labels, k=topn, sorted=True)
    indices = tf.cast(indices, tf.float32)
    batch_ids = tf.ones_like(indices, dtype=tf.float32) * tf.expand_dims(
          tf.cast(tf.range(tf.shape(input=indices)[0]),dtype=tf.float32), 1)
    
    # batchsize x topk x 2
    nd_indices = tf.cast(tf.stack([batch_ids, indices], axis=-1),tf.int32)
    
    sorted_labels, sorted_logits = [tf.gather_nd(f, nd_indices) for f in [logits, labels]]
    
    raw_max = tf.reduce_max(sorted_logits, axis=1, keepdims=True)
    sorted_logits = sorted_logits - raw_max
    sums = tf.cumsum(tf.exp(sorted_logits), axis=1, reverse=True)
    sums = tf.math.log(sums) - sorted_logits
    
    negative_log_likelihood = tf.reduce_sum(
        input_tensor=sums, axis=1, keepdims=True)
    return negative_log_likelihood
    

ApproxNDCG

y_pred = tf.convert_to_tensor([[0.5, 0.2, 0.1, 0.4, 1.0, -1.0]], dtype=tf.float32)
y_true = tf.convert_to_tensor([[1.0, 2.0, 2.0, 4.0, 1.0, 4.0]], dtype=tf.float32)
loss = approx_ndcg_loss(y_true, y_pred)
def approx_rank(logits, temperature=0.1):
    """计算列表的近似排名
    rank(j) = 1 + sum_{j neq i} I_{s_j > s_i}, I is indicator function
    
    I_{s_j > s_i} = approx 1 / (1 + exp(-(s_j - s_i) / temperature))
    """
    list_size = tf.shape(input=logits)[1]
    x = tf.tile(tf.expand_dims(logits, 2), [1, 1, list_size])
    y = tf.tile(tf.expand_dims(logits, 1), [1, list_size, 1])
    
    pairs = tf.sigmoid((y - x) / temperature)
    rank = tf.reduce_sum(input_tensor=pairs, axis=-1) + 0.5
    
    return rank

def ndcg(labels, ranks):
    """
    labels: [Batch_size, list_size]
    ranks:  [Batch_size, list_size]
    """
    discounts = 1. / tf.math.log1p(tf.cast(ranks, dtype=tf.float32))
    gains = tf.math.pow(2.0, tf.cast(labels, dtype=tf.float32))
    
    dcg = tf.reduce_sum(input_tensor=gains * discounts, axis=-1, keepdims=True)
    
    def inverse_max_dcg(labels):
        """calc inverse of ideal dcg
        """
        ideal_sorted_labels = tf.sort(labels, axis=-1, direction='DESCENDING')
        rank = tf.range(tf.shape(ideal_sorted_labels)[1]) + 1
        
        discounted_gain = tf.math.pow(2.0, ideal_sorted_labels) / tf.math.log1p(tf.cast(rank, dtype=tf.float32))
        discounted_gain = tf.reduce_sum(discounted_gain, axis=-1)
        
        return 1.0 / discounted_gain
    
    normalized_dcg = dcg * inverse_max_dcg(labels)
    return normalized_dcg

def approx_ndcg_loss(labels, logits):
    ranks = approx_rank(logits)
    
    return -ndcg(labels, ranks)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1017869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号