推荐系统之采样修正的双塔模型

本文介绍的论文题目是:《Sampling-Bias-Corrected Neural Modeling for Large Corpus Item Recommendations》
论文下载地址是:Google工业风最新论文, Youtube提出双塔结构流式模型进行大规模推荐

本文是谷歌工业风论文的新作,介绍了在大规模推荐系统中使用双塔模型来做召回的一些经验,值得细细品读。本文仅对文章内容做一个简单介绍,更多细节建议阅读原论文。

1、背景

大规模推荐系统一般分为两阶段,即召回和排序阶段,本文重点关注召回阶段。

给定{用户,上下文,物品}的三元组,一个通用的方法首先是分别计算{用户,上下文} 和 {物品} 的向量表示,然后通过一定的方式如点积来计算二者的匹配得分。这种基于表示学习的方法通常面临两个方面的挑战:

1)工业界中物品的数量十分巨大。
2)通过收集用户反馈得到的数据集十分稀疏,导致模型对于长尾物品的预测具有很大的方差,同时也面临着物品冷启动的问题。

工业界现有的推荐系统都需要从一个超大规模的候选集中拉取item进行打分排序。解决数据稀疏和指数级候选集分布的一种通常做法是从item的内容特征中学习出item的稠密表示。这里很自然地就想到了工业界大名鼎鼎且应用广泛的双塔神经网络结构,其中的一塔就是从丰富的item内容特征中学习到item的表示。

工业界目前训练双塔结构一般是通过随机mini-batch的方式来优化损失函数。这种训练方式存在的一个显著问题就是in-batch loss会因为随机采样偏差而导致模型效果不好,尤其是当样本分布出现明显倾斜的时候。我们提出了一种全新的算法,可以从流式数据中预估item的频率。通过理论分析和实验,新算法有能力在不知道候选集全部的词典情况下做出无偏差的估计并且可以自适应候选集分布的变化。在Youtube线上的实验也证明了该算法的有效性。
我们考虑一种通用的推荐问题设定:给定一系列query和候选集,目标就是在给定query的情况下返回最相关的一个候选子集。针对这里的query和候选集中的item,都可以用各自的特征向量来进行表示。在个性化推荐场景中,则是用户user和会话的上下文context构成这里的query侧。
都知道Youtube的推荐架构主要分为两个阶段:召回和排序。而本文则主要聚焦于新增一路如下图所示的双塔召回。query侧的塔是由大量的用户观看历史形成的user features以及共同的seed features构成,候选集侧的塔则是由视频特征构成。训练样本的Label则是由用户的点击和播放时长加权得到。

模型架构

近几年来,随着深度学习的发展,双塔模型常用来用做召回阶段的模型,双塔模型的一般结构如下:
在这里插入图片描述
可以看到,双塔模型两侧分别对{用户,上下文} 和 {物品} 进行建模,并在最后一层计算二者的内积。对于每一个正样本,需要随机采样一些负样本,当物品数量十分巨大的

### PyTorch实现推荐系统双塔模型中的Loss函数 在推荐系统双塔模型中,通常采用二分类交叉熵损失函数(Binary Cross Entropy Loss Function)来优化模型性能。这是因为双塔模型的目标是预测用户对某个项目的点击概率或偏好程度,这本质上是一个二分类问题[^1]。 以下是基于PyTorch框架实现双塔模型中常用的Loss函数的代码示例: ```python import torch import torch.nn as nn import torch.optim as optim # 定义双塔模型的基本结构 class TwoTowerModel(nn.Module): def __init__(self, user_embedding_dim, item_embedding_dim, hidden_dim): super(TwoTowerModel, self).__init__() self.user_tower = nn.Sequential( nn.Linear(user_embedding_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim) ) self.item_tower = nn.Sequential( nn.Linear(item_embedding_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim) ) def forward(self, user_embeddings, item_embeddings): user_out = self.user_tower(user_embeddings) item_out = self.item_tower(item_embeddings) return user_out, item_out # 初始化模型和其他组件 model = TwoTowerModel(user_embedding_dim=64, item_embedding_dim=64, hidden_dim=32) # 模拟输入数据 user_embeddings = torch.randn(10, 64) # 批次大小为10,嵌入维度为64 item_embeddings = torch.randn(10, 64) # 批次大小为10,嵌入维度为64 labels = torch.randint(0, 2, (10,)) # 随机生成标签,0表示未点击,1表示已点击 # 计算相似度得分 def compute_similarity(user_emb, item_emb): return torch.sum(user_emb * item_emb, dim=-1) # 使用点积计算相似度 # 获取模型输出 user_output, item_output = model(user_embeddings, item_embeddings) similarity_scores = compute_similarity(user_output, item_output) # 将相似度分数映射到[0, 1]范围内的概率值 sigmoid_layer = nn.Sigmoid() predicted_probabilities = sigmoid_layer(similarity_scores) # 定义损失函数 bce_loss_fn = nn.BCELoss() # 二分类交叉熵损失函数 loss_value = bce_loss_fn(predicted_probabilities, labels.float()) print(f"Loss Value: {loss_value.item()}") # 输出当前批次的损失值 ``` #### 关于Loss函数的选择与设计 - **为什么选择BCELoss?** BCELoss适用于二分类场景,在推荐系统中常用来衡量预测的概率分布与真实标签之间的差异。通过最小化这个损失函数,可以使模型更好地学习如何区分正样本和负样本[^1]。 - **温度系数的作用:** 在某些情况下,为了调整相似度计算的结果分布,可能会引入一个温度系数 \( T \),从而改变最终的相似度分值: \[ S_{\text{adjusted}} = \frac{\exp(S / T)}{\sum_i \exp(S_i / T)} \] 这种方法有助于缓解欧几里得空间中的距离偏差问题[^2]。 - **负样本采样的重要性:** 双塔模型的效果很大程度依赖于负样本的质量。如果负样本选取不当,则可能导致模型难以收敛或者泛化能力不足。因此,在实际应用中需要特别注意负样本采样策略的设计[^3]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值