来自知乎专栏-张俊林老师-对比学习视角:重新审视推荐系统的召回粗排模型
什么是对比学习
对比学习的渊源与谱系
对比学习它最大的技术源泉来自于度量学习(Metric Learning)。
- 一方面
度量学习的优化目标就是说:比如我有正例和负例,它要将实体映射到一个空间里面去。它的目标是让正例在空间中近一些,负例在空间中远一些。对比学习从框架上来讲,基本就是度量学习上述思想 - 另一方面
对比学习的提出,包括这两年的兴起,很大的刺激因素是来自于BERT,因为我们知道BERT在NLP里面效果特别好,它是通过自监督的方式,在BERT预训练模型的时候,是把输入的句子随机扣掉一定比例的单词,然后让模型去准确地预测这些词。这是典型的自监督的模式,就是说不用人工来构造训练数据,可以根据一些规则自动构造训练数据。因为BERT效果特别好,我的理解是很多做图像领域的学者受到这件事的启发,所以就拿度量学习的框架再加上自监督学习的思路,来构造对比学习 - 另外一个方向
另外一个方向,叫做instance discrimination training ,核心思想是将每张图片里的实体自身当作一个类别,在这个基础上构建自监督的分类任务,对比学习与这个方向也有比较密切的关系。
什么对比学习系统
对于一个对比学习系统来说,最关键的是三个问题:
- 第一个问题是:正例怎么构造?
对于对比学习来说,原则上正例应该是自动构造出的,也就是自监督的方式构造的。负例怎么构造?一般来说负例好选,通常就是随机选的。 - 第二个关键问题是Encoder映射函数
- 第三个问题是Loss function
对比学习的典型例子
首先我们看正例是怎么构造的。比如说我们要训练一个模型,会先随机形成一个图像构成的batch,正例是怎么构造的?SimCLR会拿任意一张图片,对这个图片做一些变形,比如说翻转,抠出一部分,颜色变换一下,等等各种可能的变换。这样,每张图片会构造出它对应的两个正例。而负例,Batch内任意其它图片都可作为这张图片的负例。这是第一个问题的解决方案。
再看第二个问题:Encoder的网络结构。SimCLR从结构上来说,是由两个分支构成的。今天我们做搜索、广告、推荐的同学比较多,你看这个结构应该感到很亲切,这不就是典型的双塔结构么?上下两个塔结构就是映射函数,也就是投影函数f。这个投影函数可进一步分为两部分,第一部分是ResNet,ResNet先抽取图片中的特征,把图片打成embedding,这个Embedding来表征图片的内容。第二部分是个投影结构projector,一般由两到三层MLP连接构成,projector把Embeddding映射到某个投影空间里面,这也是一个embedding。同时,SimCLR上下分支也完全一样,包括参数也是共享的。这样做,它就把对应batch的正负例全部映射成对应的embedding了。这是第二个问题的解决方案。
最后来看第三个问题:损失函数问题。经过双塔结构,SimCLR已经将输入数据,映射到投影空间里了。我们可以对正负例做相似度计算,一般会用cosine,这个相似度其实就是正负例在投影空间里的距离远近的度量标准。做完相似度计算后,用对比损失函数InfoNCE来驱动,来达成对比学习的目标,也就是刚才讲的,要求在投影空间里面,用InfoNCE推动正例距离拉近一些,负例距离推远一些。
什么是不好的对比学习系统
对于对比学习系统,我们希望在投影空间中,它的正例距离越近越好,这是我们希望达成的。
但这很容易产生问题:如果你的系统设计得不太合理的话,很容易诱发模型坍塌问题。什么是模型坍塌?就是说不论你输入的是什么图片,经过映射函数之后,在投影空间里面,所有图像的编码都会坍塌到同一个点。坍塌到同一个点又是什么含义呢?就是说不论我的输入是什么,最终经过函数映射,被映射成同一个embedding,所有图像对应的Embedding都是一样的,这意味着你的映射函数没有编码任何有用的信息
什么是好的对比学习
好的对比学习系统应该满足什么条件呢?(可以参考上图所示论文)它应兼顾两个要素: Alignment和Uniformity。
- Alignment
Alignment代表我们希望对比学习把相似的正例在投影空间里面有相近的编码,一般我们做一个embedding映射系统,都是希望达成此目标。 - Uniformity
Uniformity直观上来说就是:当所有实例映射到投影空间之后,我们希望它在投影空间内的分布是尽可能均匀的。
其实,追求分布均匀性不是Uniformity的目的,而是手段。追求分布的Uniformity实际想达成的是希望实例映射到投影空间后,在对应的Embedding包含的信息里,可以更多保留自己个性化的与众不同的信息。
SimCLR怎么防止坍塌
SimCLR本质上是通过引入负例来防止模型坍塌的。
InfoNCE的分子部分体现了Alignment这个要素,因为它期望正例在投影空间里面越近越好,也就是相似性越大越好。
它防止坍塌是靠分母里的负例:也就是说,如果图片和负例越不相似,则相似性得分越低,代表投影空间里距离越远,则损失函数就越小。
图像领域对比学习中的两个明确结论
- 在Batch内随机选取负例,选取的负例数量越多,对比学习模型的效果越好
- 在InfoNCE的公式里有个温度系数,温度系数对于对比学习模型效果的影响非常之大,你设置成不同的参数,可能效果会差百分之几十,一般来说,这个τ经验上应该取比较小的值。
典型对比学习模型
Batch内负例-SimCLR
SimCLR比较重要的几个要点:
- 模型结构上采用了我们做“搜广推”很常见的双塔结构
- 对正负例的Embedding做相似性计算前,应该先做一个L2 Norm
- 模型自动构造正例
- 负例是In-Batch内随机负例
Batch外负例-Moco
前面说过一个已有结论:负例用的越多,模型效果越好。因为batch size增大对计算资源要求比较高,所以总有个限度。MocoV2是典型的解决这种矛盾的例子,也就是说,我们如何能够解除batch size的约束,来大幅增加负例的数量。
Moco V2的模型结构图和SimCLR的基本是类似的,也是上下两个双塔结构,网络结构也由两个映射子结构组成,下分支结构本身是和上分支的网络结构是完全一样的。
上下两个分支的区别有两点:
- 下分支的网络参数更新机制和上分支的更新机制不一样,采用动量更新机制
- Moco维护了一个负例队列
下分支的正例通过下分支打成embedding,然后会把它放入队列里面(入队),在队列待了太久的会让它出队。Moco的负例采集方法和SimCLR一样,是随机抽取负例。但它不是在batch里面取,而是从负例队列里取。
基于负例方法谱系
用负例避免模型坍塌的对比学习系统比较多,要归纳的话,主要分为两大谱系:一个是Moco系,一个是SimCLR系列。
采纳负例的方法主要有三个共识
- 网络结构现在大家基本用的都是双塔结构
- 映射函数一般由两部分组成,首先是Resnet,用来对图像编码,还有一个是projector
- 在Moco v3和SimCLRv2 版本升级时都有体现,就是encoder越来越复杂
对比聚类-SwAV
SwAV是个典型的对比聚类的方法,是图像对比学习众多模型中效果最好的方法之一。关于正负例构造方法,SwAV和刚才提到的方法一样。关于模型结构,SwAV的双塔结构和两个映射函数,和SimCLR等模型一样,是上下对称的。
SwAV的主要特点:
对比学习视角来看召回/粗拍模型
重新审视召回/粗排模型
双塔模型概述
双塔模型的思路:它把user特征(包括context特征)和Item特征拆分,分别传给两个塔,通过DNN打成Embedding。左塔打出user embedding,表征用户兴趣。右塔通过DNN打成Item embedding,表征物品。然后对两者做相似度计算,一般会用内积或者Cosine。
在实践的时候,你会发现有几个决策点需要去考虑。有三个实践经验我在这里提一下
- 双塔模型-负例问题
- 第一种选择就是in-batch负例
我们在做排序(Rank环节)的时候,负例怎么构建呢?比如对于点击模型,一般把展示给用户曝光未点击样本做负例,就是曝光给用户了,不过他没点击,说明他不感兴趣,那这就是负例。但是,在做召回时,应该说不能完全应用这种做法。原因很简单,一般这个问题在学术上叫做selection bias:也就是说,因为召回用的双塔模型是排序的前置环节,它面临的候选集是整个物料集合,它不像rank阶段, rank阶段面临的候选集是召回或粗排筛完之后剩下的子集合,只是物料全集的一个子集。所以召回和排序的候选物料集合分布是有差异的。如果你用rank阶段做负例的方式,来给召回环节做负例的话,你会发现有很多未曝光的或低曝光的样本,召回模型从来没有见到过,所以容易误分。这实际是会有些问题。 - 第二种典型做法是全局随机抽样
- 混合一下,就是说负例一部分来自于in-batch负例,一部分来自于全局随机采样负例
- 考虑各种不同类型负例进行混合,召回模型负例有非常多种可能的做法,比如把in-batch随机负例+曝光未点击负例,两者按照一定比例混合。
在这里,我假设在这个决策点,我们的负例策略用in-batch负例。
-
双塔模型-Embedding Norm
第二个决策点是:user特征打成user embedding,item特征打成item embedding,在相似度计算时有两个选择:一种是用内积,一种是用cosine。
如果你把cosine公式写出来仔细看下的话,会发现cosine可以理解为对user embedding和item embedding各自先做了一个L2 Norm,然后两者再做内积。问题来了:我们是不是应该对user embedding和item embedding做Norm?
这是第二个决策点,就是说对user embedding和item embedding,在做相似性计算前,实验结论是应该先做Norm。 -
双塔模型-温度超参
第三个也是召回模型的一个决策点:温度超参。温度超参对于图像领域里的对比学习模型效果来说,不同参数设置,其影响是巨大的。那么我的问题是:我们做召回模型,比如说做双塔模型的时候,应不应该在Loss里或者相似性计算的时候引入温度超参?你可以加也可以不加,就我的了解:大多数是不会加的。现在的经验结果是你最好加一个,至少可以作为一个改进模型尝试的选项。
目前的双塔就是一种对比学习
今天的主题是重新审视召回/粗排模型。我们再看一下经典的DNN双塔召回和粗排模型。我们如果把刚才的三个决策点敲定的话,那么结构是这样的:左塔的user打成embedding,右塔的item打成embedding,然后对两个embedding做Norm,上完Norm之后做相似度计算,负例应该是in-batch负例,还应该带一个温度超参。
然后再对比刚才讲的SimCLR,我们再回顾一下SimCLR。其实仔细考虑一下的话,会发现把这几个因素考虑进来的话,我们现在在做的双塔模型就是一个典型的对比学习系统。我们把SimCLR逐步改造一下,就很容易改造出我们现在在用的双塔模型。可以这样改造SimCLR:首先,负例还是采用in-batch负例,把正例的方式换一下:图像是通过自动图像增强,对于推荐来说,我把用户行为过的Item作为正例,然后把正例方式换一下。第二点,我把上图中SimCLR的encoder拿掉,因为encoder用的是Resnet,是专门提取图像特征的,我们做推荐不需要这部分,但是我们保留projector, projector的实际做法也是MLP,跟我们推荐做双塔的DNN模型结构基本是一样的。然后,对两个embedding我再做Norm,两个embedding的正负例做Norm,然后引入InfoNCE loss,InfoNCE Loss可以看成推荐里常见的Pairwise Loss 比如BPR的一个拓展,我们这里仍然带着温度超参。经过这几个改造,就是我把正例的方式换一下,仍然采用in-batch随机负例,把encoder拿掉,BPR Loss拓展成InfoNCE,你会发现这就是现在典型的双塔模型的做法。所以说,从这个角度,我们可以把目前双塔方法理解为一个典型的对比学习方法。
用对比学习解释经验做法
-
双塔模型随机负例的作用是什么
什么是一个好的对比学习系统。它要满足两个要素:一个是alignment,另一个是uniformity。Alignment就是InfoNCE里面的分子,就是相似性越高拉的越近。Uniformity的话,我们讲了SimCLR是通过引入负例达成的,也就是我引入负例后,可以让投影空间中的所有实例分布比较均匀,也就是说让实例映射到投影空间之后,尽量多保留自己个性化的信息,这就是uniformity。我们可以从这个角度来解释为什么双塔召回模型要引入in-batch随机负例。它的作用是什么?它的作用是防止双塔模型的模型坍塌,这是目的。效果体现在user特征,item特征,映射到投影空间后,它让投影空间中的embedding,不论是user还是item,在投影空间分布得更均匀。分布的更均匀代表的是每一个user embedding和item embedding保留了更多个性化信息。这应该是引入in-batch随机负例的作用。
进一步做个推论:因为基于负例的对比学习系统有这么一个结论:负例越多模型效果越好,那么我们可以得出推论:做in-batch随机负例的双塔模型召回,随着batch size逐渐放大,效果应该越来越好。
-
温度超参的作用是什么
上图的分析数据,是从上面列出的论文中拿来的,它讲的是图像领域对比学习里,InfoNCE中温度超参的作用是什么。我在这里说一下它的作用。在InfoNCE里面引入温度超参对于对比学习图像系统来说影响非常大,你设不同的参数,效果可能会差百分之几十。那么怎么理解它的作用?其实对InfoNCE做一个梯度分析的话,会发现结论是这样的:小的温度超参可以让loss聚焦在hard负例上,也就是说,在大量随机选的负例中,会自动给hard负例分配更多的loss,因为这些hard负例带有更多信息,能够对我们的模型带来更多正面作用。
上面这张图说的是:假设设置不同温度超参,对训练好的对比学习系统带来的不同影响。纵坐标代表某个锚点实例和其它不同实例的相似性得分,横坐标列出10个实例,红色的是锚点对应的正例,蓝色的代表较难区分的负例,不同的子图代表设置不同温度超参它们对应的得分变化情况。从这里可以发现:前面子图引入小的温度系数和后面比较大的温度系数,最大的区别是:如果引入的是比较小的温度系数,锚点实例和正例及hard负例的相似性距离就会被拉开,意思就是在投影空间里面,小的温度超参会把难的负例推的更远,所以这个相似性得分就拉开了,也就是说正例和hard负例区分度更明显。这就是温度超参的作用。这是个比较直观的例子。这说明了引入温度超参而且设的温度超参越小,那么hard负例在投影空间和锚点的距离就会越远。这是图像领域里面对温度超参作用的一个解释。
那么做推荐里的召回模型,前面说过经验结论是应该引入温度超参,引入温度超参后,效果应该会有提升。怎么理解引入温度超参会对模型效果有作用呢?我的理解,应该也是上面类似的原因:对于召回模型来说,小的温度超参会将优化过程自动聚焦到hard负例上,因为hard负例带给我们的loss作用更大一些。这说明引入温度超参,能起到类似Focal Loss的作用。
如果这种解释是成立的,那么可以进一步做些推论:召回模型用的是随机负例/in-batch负例,因为引入了大量的随机负例,大量简单负例信息含量不大,但是因为数量多,所以聚集起来的loss会淹没掉hard负例的作用,那么这种情况下,引入温度超参应该更重要,因为他可以让loss更聚焦在hard负例上去。
进一步,我们可以再做更深层的推论:如果引入温度超参,其实不用花大的精力去挖掘hard负例,现在很多工作是专门挖掘hard负例的,既然温度超参的作用就是把loss聚焦在hard负例上,意味着它自动会做hard负例的选择,那么你费劲力气去挖掘hard负例就没有太大必要性。你可能需要做的是放大负例数量,然后加入温度超参,让模型自己去找hard负例。
-
Embedding为什么要做Norm
第三个问题是为什么在做召回模型的user embedding和item embedding时,我们应该引入Norm。或者换个说法:为什么说相似性函数要用cosine而不是内积。这里也用图像领域对比学习的内容来做一个分析,具体可以参考上面列出的论文。我们直接把结论迁移到推荐领域里来,它的解释是说:对user embedding或者item embedding做一个L2 Norm,相当于在投影空间里面把长度因素统一转换成了1,L-2 Norm的作用是把embedding的长度都归一化为1,也就是说把它们都映射到一个长度为1的单位超球面上去。为什么要这么做?现在的结论是这样的:如果把它投影到单位超平面上,会增加训练稳定性和投影空间的线性可分性,增加线性可分性,意思也就是说你用简单算法也能得到比较好的效果。这是目前图像领域里面得出的结论。那么自然的,我们可以把它推广到召回模型里面,也就是为什么召回模型要带上L-2 Norm,原因应该也是这个原因。
搞点新意思
在介绍杜比学习角度可能的改进之前,这里做一些我们做的其它工作的简介。前面说过,召回模型其实有一个很典型的问题:user/item embedding之间特征交互太晚,导致它的效果不是那么好。我们的一个实践结论是如果在user embedding和item embedding做MLP之前引入SENet,这么改造一下,应该是对召回模型的效果有提升的,我的想法是引入SENet抑制噪音特征,强化有效特征,能更有效表达user/item之间的特征交叉。大家感兴趣的话可以参考上面图片列出的FiBiNET文献。
我之前做Rank模型,其实是把重心放在feature embedding上的,我们的一系列改进,其实都是在feature embedding上做的文章,包括最初我们提出的FiBiNet里的SENet也好,以及后面针对FiBiNet进一步拓展出的MaskNET也好,ContextNET也好(具体做法可以参照上图列出的论文)。其实可以用一句话归纳一下:都是在特征embedding上面做的一些工作,因为我个人判断是feature embedding这一块可挖掘的空间比较大。
怎么用对比学习做召回模型。这里给一个我们正在做的一个例子。刚才讲了经典的双塔模型,我们可以从对比学习角度来理解它。刚才我介绍过SwAV模型,原则上可以拿它来做推荐的召回模型。上图列出的是我们正在做的叫做ConCAT的召回模型,其实就是推荐领域里面的SwAV模型。这里说一下它的具体做法,是参考SwAV对双塔模型的一个改进:就是用用户行为过的item作为正例,这些正例形成batch,经过user和item塔,形成user embedding和item embedding,类似SwAV,我们在形成embedding后加了一个聚类过程,就是对user embedding做了一个聚类,对item embedding也做了一个聚类。优化目标是什呢?对于某个user embedding,优化目标是我希望user embedding和对应的正例item所属聚类的类中心的embedding的距离越近越好,和其它的聚类类中心越远越好。这是左塔对应的loss。因为它是结构对称的,那么反过来,也可以希望item embedding和对应正例user所属的聚类类中心距离越近越好。这是右塔的loss。把这两个loss加起来就是模型优化的目标。这是一个用对比学习改造召回模型的具体例子,我个人认为这种方式可能做出一些比较新型的召回模型。
-
思考题:推荐系统有足够多训练数据,好像不需要对比学习?
,对于推荐系统来说,其实有足够多的可用训练数据,比如我们一般会用用户的点击item作为正例。既然我们有足够多的训练数据,好像我们不太需要对比学习,那么为什么还要在推荐系统里面引入对比学习?
那么引入对比学习有什么好处呢?它可以解决数据长尾分布的问题。对于长尾侧的数据,用现有的有监督方法,你会发现不论是对应的item也好,user也好,还是id特征也好,它打出的embedding不可靠,因为它的频次太低,很难通过很多用户行为数据推导出靠谱的embedding。这时候,对比学习就可以发挥它的作用了,这是推荐领域为什么要引入对比学习的初衷。
更纯正的对比学习
-
双塔模型-Item侧引入对比辅助Loss
接下来再介绍Google做的一个工作,上图是示意图,左侧是标准的双塔召回模型,这个工作的初衷是在item侧,把长尾的item embedding打的更靠谱一点。怎么做呢?就是在优化的过程中,除了主Loss,也就是常规user和item侧的交叉熵Loss,在item侧,额外引入一个对比学习辅助Loss。这个辅助Loss体现在图右侧这一部分,它是针对item的一个新的双塔。我们讲过,对比学习里最重要的是正例怎么做,那么假设在item侧引入了一个对比辅助Loss,正例怎么做?我们知道,item有很多side information类特征,这个工作把做正例放在这里。它有两种做法:一种叫DropOut,就是把item的特征随机抛掉一部分,因为item两个塔各自随机抛掉的特征不一样,就会构造出同一个item两个不同的视图view,这两个不同的view,就可以当作item的正例,经过item双塔,打出两个embedding,losss函数采取InfoNCE,也就是刚才经过dropout后的两个正例,经过DNN映射后,要求它在投影空间里面距离越近越好,in-batch随机抽样作为负例,让它和正例在投影空间里面越远越好。这就是在item侧引入对比Loss的做法。
这个论文中还引入了另一种正例的做法,叫feature mask。刚才的做法是说做正例时,在item特征引入dropout,随机抛一部分,item两个塔抛法不一样,通过这个方式制造一对正例。还有一种可能做法:因为item的特征很多,所以人工把它们分成两个子集合:子集合A和子集合B。通过这种方式,制作item两个不同的view,并要求这两个view在投影空间里面距离要近一些,In-batch随机负例与正例的距离越远越好。这是另外一种引入辅助的对比Loss的做法。
那么在item侧引入对比辅助Loss,有没有用呢?上图是它的实验结果。从结果中,我们能发现FD(dropout)、FM(mask)这两种做法相对baseline这种标准双塔模型来说,效果上还是有比较明显提升的。在什么场景下效果尤其好呢?就是对于数据稀疏场景,也就是低频的item或者user embedding较多的场景,它的效果尤其好。它这里做了个对比实验:就是在选择训练数据的时候,我只取原始数据10%比例作为训练数据,甚至1%的训练数据,意思是人为制造稀疏场景,即使里面有些中高频的,因为抽样只取1%,很多高频和中频也成了稀疏的了。结论是对于这种稀疏的数据集下,采用这种引入对比学习Loss,方法,效果提升更明显。
-
双塔模型-user侧和item侧同时引入对比辅助Loss
刚才介绍了Google的一种典型的对比学习召回模型做法,实际就是在item侧引入辅助的对比学习Loss,目的是对于中低频或者长尾的item embedding,让它打的更靠谱一点。其实稍微拓展一下,就可以得到改进的模型:可以仿照item侧的做法,把user侧也引入对比辅助Loss。做法和刚才讲的item引入的对比loss做法一样。可以把user侧的特征做dropout,或者mask,都可以。当然,我们可以引入新的不同的做正例的方式,对比学习怎么做正例是比较关键的,不同的正例构建方法对效果影响很大。其实有很多做法,举个例子,可以在user侧引入用户行为序列,如果在用户侧引入用户行为序列,可以引入不同的做正例的方式,比如可以引入GNN对比Loss。原因很简单,因为大家目前对于GNN这个图模型计算有很多对比学习的做法,有些做法效果提升比较明显。那么你可以把这些在GNN领域已有的做法直接迁到召回模型里来,就能够实现一个新的引入对比学习的召回模型。这也是目前我们正在尝试的一个方案。
图模型召回
最后介绍一下怎么把对比学习引入到图召回模型里面。上图讲的是典型的如何用图模型做召回的思路:一般做召回模型时,我们把user和item特征分离,把user特征、item特征通过离线模型训练打出user embedding和item embedding。在线服务的时候,拿到用户user embedding然后从item库里去做ANN匹配,找出出得分最相似的item,作为召回结果。这就是典型的用模型做模型召回的框架。
那么怎么用图模型做召回?很简单,把打user和item embedding的模型换成一个典型的GNN模型就可以了。
上图展示了典型的图模型方法:把用户行为图,也就是把user对item的行为构建为一个二分图,也可以把user的属性和item的属性放进来,拓展成更复杂的图,然后在这上面做些图的迭代算法。这是典型的GNN模型的方式
那么,有了经典的GNN模型,首先一个问题是:我们怎么在GNN上采用对比学习呢?这里给一个在图计算里面引入对比学习的例子。想想我们刚才讲过的SimCLR和双塔召回模型,其实在GNN里引入对比学习,其过程是一样的:对于整个图中的一个子图,我们可以对子图做些操作,得到这个子图不同的视角view,以此来构造图的正例,常见的操作方法包括Node dropping和Edge Perturbation等。做完正例,然后把它通过一个模型映射到embedding空间里面去,要求两个正例在投影空间里面距离越近越好。负例可以采取In-batch随机选择负例,要求这些负例和正例在投影空间里面的距离越远越好。这是典型的SimCLR的做法,唯一的区别是这里的输入侧不再是个图像,或者不再是推荐里的user或者item,而是一个子图,就这么个区别。所以可理解为在套用SimCLR的做法
在对比学习里面最关键的是怎么构造正例,那么在图模型里面是怎么构造正例的呢?这里列出几种常见方法。一种叫Node Dropping,因为图由图节点和连接图节点的边构成,那随机drop掉一些节点,就可以够造出一个不同的子图view出来。这是一种基于图节点的做法。另外可以对边做一些工作,同样的,这么多边,可以随机删掉一些边,也可以随机增加一些,这样也可以构造不同的正例,这是基于边的做法。还可以有其他做法,我们讲过图节点可能是带属性的,那么我们可以随机mask掉图节点的一些属性,这也是一种构造图模型正例的方式。还可以在图上随机游走,利用不同游走结果来构造对比学习子图的view。所以这四种是典型的图模型里面构造正例的方式。现有的工作基本超不出这四种模式。
最后一个问题是:我们现在知道了GNN模型如何引入对比模型,在推荐里,对于图模型召回,怎么引入对比学习呢?只要把上面介绍的知识结合起来就行。可以利用用户行为构造用户行为图,然后像刚才讲的借用经典GNN的方法来构建一个图计算系统,之后可以参照上面GNN引入对比学习的思路,把对比学习系统引入GNN召回模型,这样对于稀疏的user和item数据,会打出更靠谱的user embedding和item embedding。在线服务的时候用user embedding拉对应的item embedding就可以了。这样,我们就构造出一个典型的基于对比学习的图召回模型。它对于借鉴冷启动应该是有帮助的。
-
在rank模型里面引入对比学习?