首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >推荐系统常见Loss及随笔

推荐系统常见Loss及随笔

原创
作者头像
Mirza Zhao
修改2024-12-25 14:38:29
修改2024-12-25 14:38:29
1.9K0
举报
文章被收录于专栏:推荐算法学习推荐算法学习

简单梳理一下推荐场景常见的一些loss和,以及一些随笔

1. BCE Loss

Binary Cross-Entropy Loss(BCE Loss):用于度量二元分类任务(即每个样本都只有两个类别)中的预测概率与实际标签之间的差异。BCE Loss 的计算公式如下:

BCE Loss = -[(y * log(p)) + ((1 - y) * log(1 - p))]

其中,y 是实际的标签(0 或 1),p 是预测概率。当 y=1 时,损失计算为 -log(p);当 y=0 时,损失计算为 -log(1-p)。模型的目标是最小化损失,这将使预测的概率接近实际标签。

代码语言:python
复制
import tensorflow as tf

# 假设我们有一个二分类问题
labels = [1, 0, 1]  # 实际标签
logits = [0.8, 0.3, 0.6]  # 模型预测的概率

labels = tf.constant(labels, dtype=tf.float32)
logits = tf.constant(logits, dtype=tf.float32)

# 计算二元交叉熵损失
loss = tf.keras.losses.binary_crossentropy(labels, logits, from_logits=False)
print("Loss: ", loss.numpy())

其中,from_logits=False表示我们的输出已经是概率分布(经过了softmax或sigmoid函数),如果from_logits=True,则表示输出是原始的logits,还没有经过softmax或sigmoid函数。

如果扩展成CE Loss,那么需要注意,输入的label需要是one-hot形式:

代码语言:python
复制
import tensorflow as tf

# 假设我们有一个二分类问题,且标签是one-hot编码的
labels = [[1, 0], [0, 1], [1, 0]]  # 实际标签
logits = [[0.6, 0.4], [0.4, 0.6], [0.7, 0.3]]  # 模型预测的概率

labels = tf.constant(labels, dtype=tf.float32)
logits = tf.constant(logits, dtype=tf.float32)

# 计算交叉熵损失
loss = tf.keras.losses.categorical_crossentropy(labels, logits, from_logits=False)
print("Loss: ", loss.numpy())

注意,如果标签不是one-hot编码的,而是类别的整数编码,那么应该使用tf.keras.losses.sparse_categorical_crossentropy函数来计算交叉熵损失。

关于BCE 梯度消失:

《Understanding the Ranking Loss for Recommendation with Sparse User Feedback SIGKDD‘2024》

提到:在正样本稀疏的场景下BCE loss存在负样本导致梯度消失问题

实证方法:BCE方法产生的负样本的梯度norms相比于Combined-Pair方法小的许多

解决方法:负样本会产生较大的梯度,因此引入排序loss(LTR)能够减轻仅使用BCE loss的优化困难,从而产生更好的效果。

梯度范数(Gradient Norms)是指梯度向量的范数(通常是L2范数),它衡量的是梯度向量的大小。具体来说,给定一个梯度向量 \mathbf{g} = [g_1, g_2, \ldots, g_n] ,其L2范数定义为:

\|\mathbf{g}\|_2 = \sqrt{g_1^2 + g_2^2 + \cdots + g_n^2}

梯度范数在深度学习中有重要的意义,因为它反映了梯度的整体大小。梯度范数的大小直接影响到参数更新的幅度,从而影响模型的训练过程。

为什么梯度范数可以衡量梯度消失

梯度消失问题是指在深度神经网络中,随着网络层数的增加,梯度在反向传播过程中逐渐变小,最终可能接近于零。这会导致参数更新非常缓慢,甚至停止更新,从而使得模型难以训练。通过观察梯度范数的变化,可以衡量梯度消失问题的严重程度:

2. Focal Loss

Focal Loss是一种针对分类问题中类别不平衡的损失函数,在2017年的论文《Focal Loss for Dense Object Detection》中提出。Focal Loss如下:

FL(p_t) = -\alpha_t (1 - p_t)^{\gamma} \log(p_t)

其中:

  • p_t:表示模型预测的概率。对于正样本(y=1)p_t等于预测概率p;对于负样本(y=0)p_t等于1-p
  • \alpha_t:是一个平衡因子,用于调整正负样本的权重。通常情况下,正样本的权重\alpha较小,负样本的权重较大(1-\alpha)
  • \gamma:是一个聚焦参数,用于调整调制因子的大小。当\gamma增大时,模型对于难以分类样本的关注度会增加。

简单说就是在CE的基础上加了-\alpha_t (1 - p_t)^{\gamma} 用来控制loss的权重,预测离label越近的样本(简单label),权重越低;反之则权重越重。从而实现让模型更加关注难样本。

注意:这里需要注意的是\alpha_t ,通常情况下,正样本是负样本少的,所以默认值是给0.25,但是有些时候如果正样本比负样本多了,这里要做相应的调整。

代码语言:python
复制
import tensorflow as tf

def focal_loss(labels, logits, alpha=0.25, gamma=2.0):
    labels = tf.cast(labels, dtype=tf.float32)
    logits = tf.cast(logits, dtype=tf.float32)
    
    # 计算二元交叉熵损失
    ce_loss = tf.keras.losses.binary_crossentropy(labels, logits, from_logits=True)
    
    # 计算预测概率
    pred_prob = tf.sigmoid(logits)
    
    # 计算Focal Loss中的调制因子
    modulating_factor = tf.pow(tf.abs(labels - pred_prob), gamma)
    
    # 计算Focal Loss
    loss = tf.reduce_mean(alpha * modulating_factor * ce_loss)
    return loss

# 假设我们有一个二分类问题
labels = [1, 0, 1]  # 实际标签
logits = [2.0, -1.0, 1.0]  # 模型预测的logits

labels = tf.constant(labels, dtype=tf.float32)
logits = tf.constant(logits, dtype=tf.float32)

# 计算Focal Loss
loss = focal_loss(labels, logits)
print("Loss: ", loss.numpy())

3. InfoNCE Loss

它用于对比学习(contrastive learning)任务,特别是在自监督学习(self-supervised learning)中。InfoNCE Loss 显示了两个随机变量之间的互信息估计。其计算公式如下:

InfoNCE Loss = -Σlog\frac{( exp(f(x_i, y_i) / τ)} {Σ_{i=0}^{k} exp(f(x_i, y_j) / τ))}

其中,x_i 是输入样本,y_iy_j分别是正样本(相似样本)和负样本(不相似样本)。函数 f(x, y) 表示 x 和 y 之间的相似度分数。τ 是温度系数,用于调节 softmax 函数的稀疏程度。上式分母中的sum是在1个正样本和k个负样本上做的,从0到k,所以共k+1个样本

恺明大佬在MoCo里提到,InfoNCE loss其实就是一个cross entropy loss,做的是一个k+1类的分类任务,目的就是想把这个q图片分到K+这个类

和CE区别:1. 加了一个温度系数τ。2. 分母不一样,CE是所有分类(K个),InfoNCE是所有负样本还加一个正样本(K+1)

和NCE区别:NCE是BCE形式,只区分噪声和非噪声数据。但是噪声不一定都是一个类,所以改成多分类就有了InfoNCE。类似于BCE和CE的区别,也就是二分类还是多分类。

4. BPR Loss

Bayesian Personalized Ranking Loss(BPR Loss):它用于处理隐式反馈(例如用户与某个物品的交互记录)的推荐系统。BPR 旨在学习用户和物品之间的相对排序,通常用于pair-wise推荐。BPR Loss具有以下形式:

\text{BPR Loss} = - \sum_{(u, i, j) \in D} \ln(\sigma(x_{ui} - x_{uj}))

其中:

  • x_{ui} 是用户 u 和物品 i 之间的预测分数(正反馈)。
  • x_{uj}是用户 u 和物品 j 之间的预测分数(负反馈)。
  • σ是 sigmoid 函数,定义为 \sigma(x) = \frac{1}{1 + \exp(-x)}
  • D 是训练数据集,包含用户 u 的正样本 i 和负样本 j 的三元组。

目标就是希望每一对正负样本中的正样本预估值要大于负样本的预估值。从公式看就是x_{ui} (正反馈)越大越好, x_{uj}(负反馈)越小越好。

5. Hinge Loss

Hinge Loss和BPR Loss差不多,一般都是用于pair-wise的任务中。其目标是最大化正确分类与错误分类之间的间隔。在多类别分类问题中,在二分类问题中,Hinge Loss 的定义如下:

Hinge Loss =\sum_{i=1}^{N} \max(0, 1 - y_i f(x_i))

在多类别分类问题中,Multiclass Hinge Loss 的计算公式如下:

\text{Multiclass Hinge Loss} = \sum_{i=1}^{N} \sum_{y \neq y_i} \max(0, \Delta(y_i, y) + f(x_i, y) - f(x_i, y_i))

其中:

  • x_i是第 i 个输入样本。
  • y_i是第 i 个样本的真实标签。
  • y 是其他类别。
  • f(x_i, y) 表示类别 y 的预测分数。
  • \Delta(y_i, y) 用于计算两个类别之间的损失差异。通常情况下,当y_i \neq y 时,\Delta(y_i, y) = 1=1;当y_i = y 时,\Delta(y_i, y) = 0

Loss期望是正样本的分数高于负样本的分数至少一个固定的margin,这个margin大小是超参数,不太好拍,一般还是用BPR Loss叭~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. BCE Loss
  • 2. Focal Loss
  • 3. InfoNCE Loss
  • 4. BPR Loss
  • 5. Hinge Loss
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档