当前位置:网站首页>【datawhale202206】pyTorch推荐系统:召回模型 DSSM&YoutubeDNN
【datawhale202206】pyTorch推荐系统:召回模型 DSSM&YoutubeDNN
2022-07-01 12:03:00 【SheltonXiao】
小结
本次所涉及的模型用于推荐系统中的召回环节,该环节主要是一个embedding和筛选,本次所涉及的模型主要用于embedding过程。
DSSM双塔模型是指,user和item的embedding向量分别出自两个网络。模型并不复杂,由两个dnn流再加相似度计算构成。需要主要负样本采样及归一化/温度系数以保证欧氏空间的问题。
而YoutubeDNN则是单塔模型,user和item的embedding向量出自一个网络。模型由一个DNN构成,但对于特征的处理比较讲究。
前情回顾
目录
0 背景回顾
本次所涉及的模型为召回模型,其在推荐系统中的位置常在排序之前。
召回模型的功能在于快速地筛选及形成值得注意的数据的过程,具体为实现从推荐池中选取几千上万的item,送给后续的排序模块。
召回+排序这样分阶段漏斗体系诞生的原因,主要是算力局限所致。
如果在排序阶段选择所有的item作为候选集,则训练的耗时及内存开销巨大,服务响应时间都是灾难性的。
召回模块非常重要,该模块决定了整个系统最终表现的天花板,需要保证能召回高质量(高点击率或高转化率)的候选item。
因此如何创新和发展找回技术是对业务有重大意义的问题,也是业界和学术界关注的重点问题。
近几年的召回算法可以分为两类:
- 单塔类召回模型:user和item的embedding向量都出自同一个网络,如:YoutubeDNN
- 双塔类召回模型:user和item的embedding向量分别出自两个网络,如:DSSM
1 双塔召回模型
双塔模型在推荐领域中是一个十分经典的模型,无论是在召回还是粗排阶段,都会是首选。
双塔模型的主要优势在于其结构,劣势也在于其结构
- 灵活的结构在线预估时可以满足低延时;
- 无法考虑user和item间的特征交叉。
1.1 常见的双塔模型
1.1.1 经典双塔模型
DSSM(Deep Structured Semantic Model)是由微软研究院于CIKM在2013年提出的一篇工作。该模型并不是针对推荐系统提出的,因而下面部分会先介绍模型的背景,再介绍其在推荐系统中的具体形式。
问题的背景是NLP领域语义相似度,doc和query的匹配。
该模型主要用来解决NLP领域语义相似度任务 ,利用深度神经网络将文本表示为低维度的向量,用来提升搜索场景下文档和query匹配的问题。
DSSM 模型的原理主要是:通过用户搜索行为中query 和 doc 的日志数据,通过深度学习网络将query和doc映射到到共同维度的语义空间中,通过最大化query和doc语义向量之间的余弦相似度,从而训练得到隐含语义模型,即 query 侧特征的 embedding 和 doc 侧特征的 embedding,进而可以获取语句的低维语义向量表达 sentence embedding,可以预测两句话的语义相似度。
感觉上面这段话没有讲人话。理解了一下大概就是,DSSM是用来训练一个隐含语义模型的,目标是匹配语义相似的doc和query。
- 这个模型的作用对象是:用户搜索行为中query 和 doc 的日志数据。
- 具体实现手段是:最大化对象语义向量间的余弦相似度(量化相似度);而为了实现这一点,需要先将二者映射到同维度的语义空间。
- 对应作用对象的具体模型训练对象:是query 侧特征的 embedding 和 doc 侧特征的 embedding。
双塔模型的结构如下:
该网络结构比较简单,是一个由几层DNN组成网络。
- 将要搜索文本(Query)和要匹配的文本(Document)的 embedding 输入到多层DNN网络,网络输出为 128 维的向量;
- 通过向量之间计算余弦相似度来计算向量之间距离,可以看作每一个 query 和 document 之间相似分数;
- 再做 softmax。
而在推荐系统中,user和item间的匹配是关键。
而在推荐系统中,最为关键的问题是如何做好用户与item的匹配问题,因此对于推荐系统中DSSM模型的则是为 user 和 item 分别构建独立的子网络塔式结构,利用user和item的曝光或点击日期进行训练,最终得到user侧的embedding和item侧的embedding。
因而在推荐系统中,模型变为下面形式
从模型结构上来看,主要包括两个部分:user侧塔和item侧塔,对于每个塔分别是一个DNN结构。
- 特征输入通过DNN模块得到user和item的embedding,维度需要保持一致(即最后一层全连接层隐藏单元个数相同)
- 计算之间user和item的embedding的相似度(常用內积或者余弦值,下面会说这两种方式的联系和区别)
如何匹配相似度,定义最终的输出?
在召回模型中,这个问题类似于多分类问题(如YouTubeDNN模型)。此处将物料库中的一个item视为一个类别,因此损失函数需要计算每个类的概率值:
其中 s ( x , y ) s(x,y) s(x,y)表示两个向量的相似度, P ( y ∣ x ; θ ) P(y|x;\theta) P(y∣x;θ)表示预测类别的概率, M M M表示物料库所有的item。
但是在实际场景中,由于物料库中的item数量巨大,在计算上式时会十分的耗时,因此会采样一定的数量的负样本来近似计算,后面针对负样本的采样做一些简单介绍。
以上就是推荐系统中经典的双塔模型,之所以在实际应用中非常常见,是因为在海量的候选数据进行召回的场景下,速度很快,效果说不上极端好,但一般而言效果也够用了。
在实际的工业应用场景中,分为离线训练和在线服务两个环节。
- 在离线训练阶段,同过训练数据,训练好模型参数。然后将候选库中所有的item集合离线计算得到对应的embedding,并存储进ANN检索系统,比如faiss。为什么将离线计算item集合,主要是因为item的会相对稳定,不会频繁的变动,而对于用户而言,如果将用户行为作为user侧的输入,那么user的embedding会随着用户行为的发生而不断变化,因此对于user侧的embedding需要实时的计算。
- 在线服务阶段,正是因为用户的行为变化需要被即使的反应在用户的embedding中,以更快的反应用户当前的兴趣,即可以实时地体现用户即时兴趣的变化。因此在线服务阶段需要实时的通过拼接用户特征,输入到user侧的DNN当中,进而得到user embedding,在通过user embedding去 faiss中进行ANN检索,召回最相似的K个item embedding。
可以看到双塔模型结构十分的适合实际的应用场景,在快速服务的同时,还可以更快的反应用户即时兴趣的变化。
之所以双塔模型在服务时速度很快,是因为模型结构简单(两侧没有特征交叉),但这也带来了问题,双塔的结构无法考虑两侧特征之间的交互信息,在一定程度上牺牲掉模型的部分精准性。
例如在精排模型中,来自user侧和item侧的特征会在第一层NLP层就可以做细粒度的特征交互;
而对于双塔模型,user侧和item侧的特征只会在最后的內积计算时发生,这就导致很多有用的信息在经过DNN结构时就已经被其他特征所模糊了,因此双塔结构由于其结构问题先天就会存在这样的问题。
接下来提到的模型,都尝试弥补user侧和item侧特征交互的问题。
1.1.2 SENet双塔模型
SENet由Momenta在2017年提出,当时是一种应用于图像处理的新型网络结构。后来张俊林将SENet引入了精排模型FiBiNET中,其作用是为了将大量长尾的低频特征抛弃,弱化不靠谱低频特征embedding的负面影响,强化高频特征的重要作用。
我们先看看SENet的结构,如下
从上图可以看出SENET主要分为三个步骤Squeeze, Excitation, Re-weight:
- Squeeze阶段:对每个特征的embedding向量进行数据压缩与信息汇总(在embedding维度计算均值,将每个特征的Squeeze转换成单一的数值)
- Excitation阶段:根据上一阶段得到的向量进行缩放,即将上阶段的得到的 1 × f 1 \times f 1×f的向量 Z Z Z先压缩成 1 × f r 1 \times \frac{f}{r} 1×rf长度,然后在放回到 1 × f 1 \times f 1×f的维度,其中 r r r表示压缩的程度。这个过程的具体操作就是经过两层DNN。
该过程可以理解为:对于当前所有输入的特征,通过相互发生关联,来动态地判断哪些特征重要,哪些特征不重要,而这体现在Excitation阶段的输出结果 A A A,其反应每个特征对应的重要性权重。 - Re-weight阶段:是将Excitation阶段得到的每个特征对应的权重 A A A 再乘回到特征对应的Embedding里,就完成了对特征重要性的加权操作。
以上简单的介绍了一下SENet结构,可以发现这种结构可以通过对特征embedding先压缩,再交互,再选择,进而实现特征选择的效果。
张俊林将SENet应用于双塔模型中,模型结构如下所示:
就是在特征输入部分各自加上SENet模块。
具体地是将双塔中的user塔和Item侧塔的特征输入部分加上一个SENet模块,通过SENet网络,动态地学习这些特征的重要性,通过小权重抑制噪音或者无效低频特征,通过大权重放大重要特征影响的目的。
为什么加入SENet是有效的呢?
张俊林老师的解释是:双塔模型的问题在于User侧特征和Item侧特征交互太晚,在高层交互,会造成细节信息,也就是具体特征信息的损失,影响两侧特征交叉的效果。
而SENet模块在最底层就进行了特征的过滤,使得很多无效低频特征即使被过滤掉,这样更多有用的信息被保留到了双塔的最高层,使得两侧的交叉效果很好;
同时由于SENet模块选择出更加重要的信息,使得User侧和Item侧特征之间的交互表达方面增强了DNN双塔的能力。
也就是说SENet双塔模型主要是从特征选择的角度,提高了两侧特征交叉的有效性,减少了噪音对有效信息的干扰,进而提高了双塔模型的效果。(也不失为一个不错的思路)
此外,还可以增加通道,如用多个DNN,这样变成多兴趣的概念(腾讯正在尝试中)
1.1.3 多目标的双塔模型
主要是因为实际场景中业务复杂(如点击,评论,收藏,关注,转发等),所以针对不同的任务各独有一个tower。
可以采用多通道DNN,然后多优化目标的形式。
这种模型结构,可以针对多目标进行联合建模,通过多任务学习的结构,一方面可以利用不同任务之间的信息共享,为一些稀疏特征提供其他任务中的迁移信息,另一方面可以在召回时,直接使用一个模型得到多个目标预测,解决了多个模型维护困难的问题。也就是说,在线上通过这一个模型就可以同时得到多个指标,例如视频场景,一个模型就可以直接得到点赞,品论,转发等目标的预测值,进而通过这些值计算分数获得最终的Top-K召回结果。
1.2 一些值得关注的双塔模型细节
关于双塔模型,其模型结构相比排序模型来说很简单,没有过于复杂的结构。但除了结构,有一些细节部分容易被忽视,而这些细节部分往往比模型结构更加重要
归一化与温度系数
在Google的双塔召回模型中,重点介绍了两个trick,将user和item侧输出的embedding进行归一化以及对于內积值除以温度系数,实验证明这两种方式可以取得十分好的效果。
归一化的操作主要原因是因为向量点积距离是非度量空间,不满足三角不等式,而归一化的操作使得点击行为转化成了欧式距离。
那为啥非要转为欧式距离呢?这是因为ANN一般是通过计算欧式距离进行检索,这样转化成欧式空间,保证训练和检索一致。
负样本采样
对于召回模型而言,其负样本并不能和排序模型一样只使用展现未点击样本,因为召回模型在线上面临的数据分布是全部的item,而不仅仅是展现未点击样本。因此在离线训练时,需要让其保证和线上分布尽可能一致,所以在负样本的选择样要尽可能的增加很多未被曝光的item。
常见的采样方法有
- 全局随机采样:从全局候选item中随机抽取一定数量的item作为找回模型的负样本。但候选的item属于长尾数据(少数热门物料占据了绝大多数的曝光与点击),对尾部item并不友好
- 全局随机采样+热门打压:在上一个基础上,对一些热度item进行打压(欠采样),让模型关注一些非热门的item
- Hard Negative增强样本:选取一部分匹配度适中的item,能够增加模型在训练时的难度,提升模型能学习到item之间细粒度上的差异(选取方式在业界有多种)
- Batch内随机选择负采样:将batch内选择除了正样本之外的其它Item,做为负样本,其本质就是利用其他样本的正样本随机采样作为自己的负样本(基于batch的负采样方法受batch的影响很大,当batch的分布与整体的分布差异很大时就会出现问题,同时batch内负采样也会受到热门item的影响,需要考虑打压热门item的问题。)
1.3 代码实现
教程给出了使用一点资讯提供数据的DSSM召回模型实践
1.3.1 训练数据
训练数据基于一点资讯获取,详见教程
分为以下几步:
- 数据预处理:
用户侧主要包含一些用户画像属性(用户性别,年龄,所在省市,使用设备及系统);
新闻侧主要包括新闻的创建时间,题目,所属 一级、二级类别,题片个数以及关键词。 - 构造训练样本:该部分主要是根据用户的交互日志中前6天的数据作为训练集,第7天的数据作为测试集,来构造模型的训练测试样本。
- 负样本采样:该部分主要采用基于item的展现次数对全局item进行负采样。
1.3.2 DSSM模型实现
代码详见教程。
模型的结构其实并不复杂,主要实现分为:
- 将输入的user 特征以及 item 特征处理完之后分别送入两侧的DNN结构
- CosinSimilarity相似度计算,需要注意归一化及温度系数的技巧。
1.3.3 模型训练
代码详见教程。
需要针对输入数据有一些处理,分为以下几步:
- 稀疏特征编码:主要是针对于用户侧和新闻侧的稀疏特征进行编码,并将训练样本join上两侧的特征。
- 配置特征以及模型训练:构建模型所需的输入特征,同时构建DSSM模型及训练。
- 生成embedding用于召回:利用训练过的模型获取所有item的embeddings,同时获取所有测试集的user embedding,保存之后用于之后的召回工作。
1.3.4 召回
双塔模型生成了embedding之后,具体到推荐系统中,应用是召回。
代码详见教程。
这里采用的召回模型是ANN。
分为以下两步:
- 为测试集用户召回:通过annoy tree为所有的item构建索引,并通过测试集中所有的user embedding为每个用户召回一定数量的item。
- 测试召回结果:为测试集用户的召回结果进行测试。
2 YoutubeDNN
YouTubeDNN模型是2016年的一篇文章,虽然离着现在有些久远, 但这篇文章无疑是工业界论文的典范, 完全是从工业界的角度去思考如何去做好一个推荐系统,并且处处是YouTube工程师留给我们的宝贵经验, 由于这两天用到了这个模型,今天也正好重温了下这篇文章,所以借着这个机会也整理出来吧, 王喆老师都称这篇文章是"神文", 可见其不一般处。
首先是从工程的角度去剖析了整个推荐系统,讲到了推荐系统中最重要的两大模块: 召回和排序, 这篇论文对初学者非常友好,之前的论文模型是看不到这么全面的系统的,总有一种管中规豹的感觉,看不到全局,容易着相。 其次就是这篇文章给出了很多优化推荐系统中的工程性经验, 不管是召回还是排序上,都有很多的套路或者trick,比如召回方面的"example age", “负采样”,“非对称消费,防止泄露”,排序方面的特征工程,加权逻辑回归等, 这些东西至今也都非常的实用,所以这也是这篇文章厉害的地方。
2.0 YouTubeDNN推荐系统架构
更具体地讲述了一下召回和精排的联系和区别。
对于召回,大致上有两大类召回方式,
- 监督模型+embedding,其中策略规则,往往和真实场景有关,比如热度,历史重定向等等,不同的场景会有不同的召回方式,这种属于"特异性"知识。
- 模型+embedding思路是一种"普适"方法,我 这些方法大致成几个系列,比如FM系列(FM,FFM等), 用户行为序列,基于图和知识图谱系列,经典双塔系列等,这些方法看似很多很复杂,其实本质上还是给用户或者是物品打embedding而已,只不过考虑的角度方式不同。 (YouTubeDNN召回模型属于这种)
召回那边对于每个用户, 给出了几百个比较相关的候选视频, 把几百万的规模降到了几百, 当然,召回那边利用的特征信息有限,并不能很好的刻画用户和视频特点,所以, 在精排侧,主要是想利用更多的用户,视频特征,刻画特点更加准确些,从这几百个里面选出几个或者十几个推荐给用户。 而涉及到准, 主要的发力点一般有三个:特征工程, 模型设计以及训练方法。 这三个发力点文章几乎都有所涉及, 除了模式设计有点审时度势之外,特征工程以及训练方法的处理上非常漂亮,具体的后面再整理。
精排侧,这一块的大致发展趋势,从ctr预估到多目标, 而模型演化上,从人工特征工程到特征工程自动化。主要是三大块, CTR预估主要分为了传统的LR,FM大家族,以及后面自动特征交叉的DNN家族.
而多目标优化,目前是很多大公司的研究现状,更是未来的一大发展趋势,如何能让模型在各个目标上面的学习都能"游刃有余"是一件非常具有挑战的事情,毕竟不同的目标可能会互相冲突,互相影响,所以这里的研究热点又可以拆分成网络结构演化以及loss设计优化等, 而网络结构演化中,又可以再一次细分。 当然这每个模型或者技术几乎都有对应paper,我们依然可以通过读paper的方式,把这些关键技术学习到。
对模型的评估,
- 线下评估的时候,主要是采用一些常用的评估指标(精确率,召回率, 排序损失或者auc这种),
- 但是最终看算法和模型的有效性, 是通过A/B实验, 在A/B实验中会观察用户真实行为,比如点击率, 观看时长, 留存率这种, 这些才是终极目标(而有时候, A/B实验的结果和线下我们用的这些指标并不总是相关, 这也是推荐系统这个场景的复杂性)
我们往往也会用一些策略,比如修改模型的优化目标,损失函数这种, 让线下的这个目标尽量的和A/B衡量的这种指标相关性大一些。
2.1 YoutubeDNN模型
模型的问题背景是:在大量YouTube视频中检索出数百个和用户相关的视频来。
这个问题,可以看成一个多分类的问题,即用户在某一个时刻点击了某个视频, 可以建模成输入一个用户向量, 从海量视频中预测出被点击的那个视频的概率。
问题的数学描述借鉴了word2vec。
模型结构如下
是一个简单的DNN。
DNN的输入是下列用户侧的特征整理而成的长向量:
- 用户历史序列,历史搜索tokens这种序列性的特征: 一般长这样
[item_id5, item_id2, item_id3, ...]
, 是高维稀疏特征
处理方式是首先会通过一个embedding层,转成低维稠密的embedding特征,即历史序列里面的每个id都会对应一个embedding向量, 这样历史序列就变成了多个embedding向量的形式, 这些向量一般会进行融合,常见的是average pooling,即每一维求平均得到一个最终向量来表示用户的历史兴趣或搜索兴趣。 - 用户人文特征,
其中离散型此类特征的依然是labelEncoder,然后embedding转成低维稠密;
而连续型的特征,一般是先归一化操作,然后直接输入,当然有的也通过分桶,转成离散特征,还可以加入一些非线性的操作增加模型表达能力。
这些特征对新用户的推荐会比较有帮助,常见的用户的地理位置, 设备, 性别,年龄等。 - 还有一个比较特色的特征example age,与场景相关。
3 基于rechub的代码实现
本部分代码的原文件见github
colab版本在这里
3.1 MovieLens数据集
MovieLens数据集是电影网站提供的一份数据集,原数据分为三个文件,users.dat
, movies.dat
, ratings.dat
,包含了用户信息、电影信息和用户对电影的评分信息。
教程对数据进行了一个处理,和采样(在全量数据中取出前100个样本),数据的开头如下:
数据的基本信息如下:
3.2 DSSM模型训练
在教程的DSSM模型中,使用了两种类别的特征,分别是稀疏特征(SparseFeature)和序列特征(SequenceFeature)。
对应的处理方式包括:
对于稀疏特征,是一个离散的、有限的值(例如用户ID,一般会先进行LabelEncoding操作转化为连续整数值),模型将其输入到Embedding层,输出一个Embedding向量。
对于序列特征,每一个样本是一个List[SparseFeature](一般是观看历史、搜索历史等),对于这种特征,默认对于每一个元素取Embedding后平均,输出一个Embedding向量。此外,除了平均,还有拼接,最值等方式,可以在pooling参数中指定。
具体到本例,Sparse Feature是把genres特征第一个作为cate_id特征,其他的sparse feature还包括’user_id’, ‘movie_id’, ‘gender’, ‘age’, ‘occupation’, ‘zip’。
对Sparse Feature进行label encoder处理,对比处理前后结果如下
除了常规的输入数据定义,还需要定义塔的特征
在DSSM中,分为用户塔和物品塔,每一个塔的输出是用户/物品的特征拼接后经过MLP(多层感知机)得到的。 下面我们来定义物品塔和用户塔都有哪些特征
# 定义两个塔对应哪些特征
user_cols = ["user_id", "gender", "age", "occupation", "zip"]
item_cols = ['movie_id', "cate_id"]
# 从data中取出相应的数据
user_profile = data[user_cols].drop_duplicates('user_id')
item_profile = data[item_cols].drop_duplicates('movie_id')
对序列特征,本数据集中的序列特征为观看历史,根据timestamp形成。generate_seq_feature_match
函数
边栏推荐
- 【单片机】【数码管】数码管显示
- Le semester manquant
- Golang根据参数引入相应配置文件的实现方式
- usb peripheral 驱动 - cable connect/disconnect
- Learning summary on June 28, 2022
- Redis startup and library entry
- LeetCode力扣(剑指offer 31-35)31. 栈的压入弹出序列32I.II.III.从上到下打印二叉树33. 二叉搜索树的后序遍历序列34. 二叉树中和为某一值的路径35. 复杂链表的复制
- Custom grpc plug-in
- redis中value/hush
- Seckill system 03 - redis cache and distributed lock
猜你喜欢
91. (chapitre Cesium) simulation de lancement de fusées cesium
Dlhsoft Kanban, Kanban component of WPF
Botu V15 add GSD file
Summary of JFrame knowledge points 1
研发效能度量框架解读
NOV Schedule for . Net to display and organize appointments and recurring events
Message queue monitoring refund task batch process
Joint Time-Frequency and Time Domain Learning for Speech Enhancement
Powerful, easy-to-use, professional editor / notebook software suitable for programmers / software developers, comprehensive evaluation and comprehensive recommendation
C summary of knowledge points 1
随机推荐
Huawei HMS core joins hands with hypergraph to inject new momentum into 3D GIS
uniapp 使用 uni-upgrade-center
Value/string in redis
陈珙:微服务,它还那么纯粹吗?
leetcode 406. Queue Reconstruction by Height(按身高重建队列)
C#依赖注入(直白明了)讲解 一看就会系列
Neo4j 中文开发者月刊 - 202206期
The Missing Semester
LeetCode力扣(剑指offer 31-35)31. 栈的压入弹出序列32I.II.III.从上到下打印二叉树33. 二叉搜索树的后序遍历序列34. 二叉树中和为某一值的路径35. 复杂链表的复制
Extended tree (I) - concept and C implementation
对于mvvm和mvc的理解
91. (chapitre Cesium) simulation de lancement de fusées cesium
Personnaliser le plug - in GRPC
easyexcel的使用
GID:旷视提出全方位的检测模型知识蒸馏 | CVPR 2021
Exposure: a white box photo post processing framework reading notes
CPI tutorial - asynchronous interface creation and use
The specified service is marked for deletion
Talk about biological live broadcast - genovis Zhang Hongyan antibody specific enzyme digestion technology helps to characterize the structure of antibody drugs
The Missing Semester