作者:来自斯坦福的Rex Ying , Ruining He, Kaifeng Chen , Pong Eksombatchai等人
时间:2018
来源:KDD
论文链接:https://arxiv.org/pdf/1806.01973.pdf
Github链接:这篇文章既没有公开数据,也没有公开代码。猜想可能是由于和Pinterest公司合作,涉及商业数据以及数据量高达十几T的原因。
Pinterest图片社交网站:https://www.pinterest.com/
近年来在图数据上的深度神经网络在推荐系统上表现的很好。然而,把这些算法应用到数十亿的物品和数百亿的用户上仍然是个挑战。
文中提出了一种在 Pinterest 上的大规模深度推荐引擎,开发了一种高效的图卷积算法PinSage。该算法联合有效的random walk以及图卷积来生成涵盖图结构和结点特征的节点embedding。
相对于之前的GCN方法,作者提出了高效的random walk方法同时设计了一个新颖的训练策略以提高模型的收敛性和鲁棒性。
文中使用PinSage算法在 Pinterest 上面的75亿个样本上进行训练,图上有30亿个顶点表示 pins 和 boards,180亿条边(文章说的是pin and board,可以理解成图片和展示面板)。
根据离线评测、用户调研和 A/B 测试(在线评测)的评测结果显示,PinSage 生成了相比其他深度学习和基于图的方法更高质量的推荐结果。
这是深度图表示目前规模最大的应用,并且为新一代基于图卷积结构的大规模推荐系统奠定了基础。
Pinterest是国外的一款社交软件,成立于2010年,采用的是瀑布流的形式展现图片内容,无需用户翻页,新的图片不断自动加载在页面底端,让用户不断的发现新的图片。可以说是图片版的Twitter,用户可以浏览、收藏、关注自己喜欢的图片,2013年9月该网站进入全球最热门社交网络前十名,但是目前在大陆和facebook相同,普通用户暂时无法直接访问。
该平台最主要的价值就是通过分析大量用户留下的兴趣痕迹,帮助用户发现和匹配他们感兴趣的想法和商品。随着用户量的增加和网站对象的增加,该团队不得不考虑如何使自己的搜索引擎变得更加智能。
此论文由Pinterest公司和Stanford联合发表。在Pinterest网站上,有大量的图片,被称为pins;而用户可以将喜欢的图片分类,即将pins放在展示面板boards上。网站会根据用户的历史浏览轨迹为用户推荐可能感兴趣的图片。
GCN在AI领域是最近比较热门的研究方向,前段时间阿里妈妈开源了内部基于tesorflow搭建的GNN(Graph Neural Network)计算框架Euler,内置了其自研算法;而2019年的顶会论文中也不乏关于GNN的论文。
传统的深度学习网络主要针对图片,语音等欧氏空间内规则型数据;而对社交、电商和医疗等非规则结构数据则仍受到一定程度的限制。以电商场景为例,可以将用户、商品和广告等都看作节点(nodes),而将用户对于商品的购买,广告的点击等操作视为边(edges,节点间连接)。节点和边就构成了一张大图(Graph),GNN将这张整图作为输入,进行邻居信息汇聚等操作,学习图中节点,边或子图的向量表达(embedding),从而实现分类、推荐和预测等任务。可以看出在设计思路上GNN对于非结构化数据是具有一定优势的,但实践是检验真理的唯一标准,PinSage正是在工业界利用大规模数据验证了GNN的强大,这也是PinSage这篇论文意义重大的原因。
推荐系统中的评测大致分为三类:离线评测、在线评测、用户调研。
此文的框架是一个基于随机游走的GCN,名为PinSage,它运行在一个包含30亿个节点和180亿个edgs的大型图上——这个图比GCNs的典型应用程序大10,000倍。PinSage利用了以下几个关键点,大大提高了GCNs的可扩展性:
on-the-fly convolutions 动态GCN
PinSage使用DeepWalk的方式,通过对节点周围的邻域进行采样并动态构建计算图来执行局部卷积。这些动态构建的计算图指定了如何在特定节点周围执行局部卷积,由此减轻在训练期间对整个图进行操作的需要。
在PinSage中,通过模拟随机游走并选择具有最高访问次数的邻居来定义基于重要性的邻域。这样做有两方面好处:
Producer-consumer minibatch construction
利用生产者消费者架构来最大化GPU利用率
Efficient MapReduce inference
设计有效的MapReduce流水线
给定一个完全训练好的GCN模型,用训练好的模型为所有节点生成嵌入仍然是一个挑战,包括那些在训练中隐藏的节点。简单地计算具有局部共解的节点的嵌入会导致由节点K-hop邻域之间的重叠引起的重复计算。
节点嵌入自上而下的聚合很适合Google的大规模数据集运算框架,Map reduce,在Mapreduce中将所有节点上的每个聚合步骤分解为三个操作:map、join和reduce。简而言之,对于每个聚合步骤,使用map将所有节点投影到潜在空间,而不需要任何重复的计算,然后join将它们发送到层次结构上相应的上层节点,最后reduce以执行聚合以获得上层节点的嵌入。
除了这些在可扩展性方面的基本改进之外,文中还引入了新的训练技术和算法创新。这些创新提高了PinSage学习的表示的质量,使得下游推荐系统任务的性能有了显著提高:
Pinterest 是一个内容挖掘应用,在这里用户与 pins 进行交互,这些 pins 是在线内容的可见标签(比如用户做饭时的食谱,或者他们想买的衣服)。用户用 boards 将 pins 组织起来,boards 里面包含了 pins 组成的集合,这些 pins 在用户看来是主题相关的。论文中涉及到的数据为20亿图片(pins),10亿画板(boards),180亿边(pins与boards连接关系)。
文中的任务是生成可以用于推荐的高质量的 embedding 或 pins 的表示(比如,使用最近邻来查找 pin 的推荐,或是使用下游的评分系统进行推荐)。为了学习这些 embedding,如前所述GCN是将数据以一张图的形式进行输入,在论文中pins和boards构成了二分图,即pins仅与boards相连接,pins或boards内部无连接, I I I 表示 pins, C C C 表示 boards。当然,我们的方法是可以泛化到其他方面的,比如 I I I看作是物品 C C C看作是用户定义的环境或收藏品集合等。
为了符号的简洁,我们使用 V = I ∪ C V=I∪C V=I∪C 来表示图中的顶点集,没有特殊需要不区分 pin 和 board 顶点,一律使用 node 来表示顶点。
传统的GCN是整张图都参与训练,但是在Pinterest推荐场景中有几十亿的节点和上百亿的边,这种情况下整张图都参与运算是存在困难的,也是基于此PinSage借鉴了GraphSage的方法对GCN进行的改进。改进主要涉及以下三个方面:
使用局部卷积模块对顶点生成 embeddings。首先输入顶点的特征,然后学习神经网络,神经网络会变换并聚合整个图上的特征来计算顶点的 embeddings(图1)。
PinSage建模的思路还是很简单的,针对某一个节点,划分为三步:
考虑对顶点 u u u生成 embedding z u z_u zu的任务,需要依赖顶点的输入特征和这个顶点周围的图结构:
算法1和图1的对应关系如下
作者为了统一每个节点的领域个数,已经进一步引入每个领域节点对当前节点的重要性,采用了随机游走的策略来生成节点的领域。并且通过计算随机游走对顶点的访问次数的 ?1 归一化值。来定义领域节点的重要性,按对定点的访问次数排序后取top-T个节点作为当前节点的领域。
目标函数max-margin ranking loss,其实就是hinge loss(svm的loss)。
为了训练模型的参数,使用了一个基于最大边界的损失函数。基本的思想是希望最大化正样本之间的内积,也就是说,查询物品的 embedding 和对应的相关物品的 embedding 之间的内积。与此同时还想确保负例之间的内积,也就是查询物品的 embedding 和那些不相关物品 embedding 之间的内积要小于通过提前定义好的边界划分出的正例的内积。对于单个顶点对 embeddings ( z q , z i ) : ( q , i ) ∈ L (z_q, z_i):(q, i) \in \mathcal{L} (zq,zi):(q,i)∈L的损失函数是:
J G ( z q z i ) = E n k ∼ p n ( q ) max { 0 , z q ⋅ z n k − z q ⋅ z i + Δ } J_{\mathcal{G}}(z_qz_i) = \mathbb{E}_{n_k \thicksim p_n(q)}\max\lbrace 0, z_q \cdot z_{n_k}-z_q \cdot z_i + \Delta\rbrace JG(zqzi)=Enk∼pn(q)max{0,zq⋅znk−zq⋅zi+Δ}
其中
为了在训练中充分利用单台机器的多个 GPU,文中以一种 multi-tower 的方法运行前向和反向传播。首先将每个 minibatch(图1底部)分成相等大小的部分。每个 GPU 获得 minibatch 的一部分,并使用同一组参数来运算。在反向传播之后,所有 GPU 上的针对每个参数的梯度进行汇集,然后使用一个同步的 SGD。由于训练需要极大数量的样本,文中在运行时使用了很大的 batch size,范围从 512 到 4096。
在训练的过程中,由于邻接矩阵和特征矩阵有数十亿的顶点,所以放在了 CPU 内存中。然而,在训练 PinSage 的 CONVOLVE 步骤时,每个 GPU 需要处理邻居和顶点邻居的特征信息。从 GPU 访问 CPU 内存中的数据时会有很大的开销。
为了解决上述问题,文中采用了re-indexing技术,创建包含了当前minnibatch计算涉及的的所有节点的embedding和邻接矩阵的子图G′=(V′,E′),并在训练开始之前输入到GPU中,以减少GPU与CPU之间的通信,极大的提高了 GPU 的利用率。训练过程中,除模型计算在GPU内完成,其余操作,如采样,特征提取,re-indexing等操作均在CPU上完成。训练的过程中各GPU之间权重共享,反向传播完成之后,所有GPU上的梯度汇聚到一起,再执行同步SGD进行梯度更新。
文中设计了一个生产者消费者模式在当前迭代中使用 GPU 计算,在下一轮使用 CPU 计算,两者并行进行,差不多减少了一半的时间。
损失函数中存在的负样本,需要进行一定程度的说明,如果用户在浏览了一个pin(query)之后马上浏览了下一个pin(item),也就是推荐正确,那么这一对pins就是正样本,除此之外所有的pins对于query来说都是负样本,由此可见如果随机的选取负样本其实是降低了训练的难度,因此论文增加了“hard”负样本这一操作,“hard”负样本的要求是与query有一定关联性,但与正样本item区别较大,那么如何确定“hard”负样本呢,论文中根据PageRank排名来确定,对于query来说排名在2000-5000之间的items为“hard”负样本候选集,可进行随机采样,这种方式其实是在增加训练难度,强行提高模型区分items的能力。
在模型训练结束后,对于所有的物品(包括那些在训练中未见过的物品)直接用训练好的模型生成 embeddings 还是有挑战的。使用算法2对顶点直接计算 embedding 的方法会导致重复计算,这是由顶点的K-hop 邻居导致的。如图1所示,很多顶点在针对不同的目标顶点生成 embedding 的时候被很多层重复计算多次。为了确保推算的有效性,文中使用了一种 MapReduce 架构来避免在使用模型进行推算的时候的重复计算问题。
图3详细地表述了 pin-to-board Pinterest 二部图上的数据流,假设输入(”layer-0”)顶点是 pins/items(layer-1 顶点是 boards/contexts)。MR pipeline 有两个关键的组成部分(这两部分工作与通常意义下的MapReduce并不相同):
此方法避免了冗余的计算,对于每个顶点的隐含向量只计算一次。在获得 boards 的 embedding 之后,使用两个以上的 MR 任务,用同样的方法计算第二层 pins 的 embedding,这个步骤也是可以迭代的(直到 K 个卷积层)。
由 PinSage 生成的 embeddings 可以用在很多下游推荐任务上,在很多场景中我们可以直接使用这些 embeddings 来做推荐,通过在学习到的embedding空间中使用最近邻句查找。也就是,给定一个查询物品 q,使用 KNN的方式来查找查询物品 embedding 的最近的 K 个邻居的embedding。
PinSage在训练的过程中采用了Multi-GPU形式,minibatch取值为512-4096不等,大的batchsize可能会导致收敛困难,论文采取了warmup策略,即根据线性规则在第一个epoch中逐步将学习率(learning rate)从一个小值增加到峰值,之后在指数级减小learning rate。
分布式训练,采用了re-indexing技术,创建包含了当前minnibatch计算涉及的的所有节点的embedding和邻接矩阵的子图G′=(V′,E′),并在训练开始之前输入到GPU中,以减少GPU与CPU之间的通信。训练过程中,除模型计算在GPU内完成,其余操作,如采样,特征提取,re-indexing等操作均在CPU上完成。训练的过程中各GPU之间权重共享,反向传播完成之后,所有GPU上的梯度汇聚到一起,再执行同步SGD进行梯度更新。
“hard”负样本的加入可能会导致训练中收敛困难,所以在训练过程中,第一个epoch没有“hard”负样本,参数空间可以被迅速的缩小,之后逐渐加入“hard”负样本,对于第n个epoch,每个item加入n-1个“hard”负样本。
推理过程中,论文采用了“MapReduce”方案减少重复计算,这里对MapReduce加引号是因为根据论文介绍,“MapReduce”中进行的两部分主要工作分别为:
论文中涉及的实验有两个任务,第一个任务是推荐有关联的pins,利用embedding空间内K临近的方法推荐;第二个任务是home/news的场景下推荐pins,在embedding空间推荐距离用户最经常浏览的item最近的pins。
训练过程中数据集内包含12亿正样本,每个batch包含500个负样本,每个pin包含6个“hard”负样本,共计75亿样本。训练过程中并没有采用所有的数据,而是利用部分数据进行训练,再利用训练好的模型推理出所有节点的embedding。训练数据是随机选取的,其中包含了20%boards,70%有label的样本。在超参的精调中会再加入10%有label的样本,剩余的20%有label的样本作为测试集。训练和验证集大小接近18T,最终输出的embedding为4T。
pin的原始feature(特征)由三部分组成,视觉信息,文字说明和每个节点在图中度的log值。其中视觉信息由VGG-16提取,共4096维;文字说明由Word2Vec-based模型提取,共256维。
在实验过程中,信息汇聚函数 γ ( ⋅ ) \gamma(\cdot) γ(⋅)的选取方式也有很多,包括max-pooling、mean-pooling、mean-pooling-xent、mean-polling-hard和PinSage提到的考虑邻居重要性的importance pooling,论文对上述汇聚方式也都做了比较。训练过程中采样深度K=2,隐层维度为2048,最终embedding维度为1024。
其中
实际情况中Pinterest公司在采用PinSage之前是利用Pixie算法进行推荐的,PinSage训练过程中的正负样本label也来自于Pixie,针对这种情况,论文对两种算法进行了A/B test。即利用两种算法对相同的query进行推荐,让用户进行选择,哪种算法推荐的更好。
可以看出60%的情况下PinSage的推荐结果是优于Pixie的。
下图给出了不同推荐算法推荐的示例,左边的图是要查询的图,也就是query pin,右边是使用不通的算法推荐的图,也就是recommended items。
最后,文中还做了A/B测试实验,该实验比较了PinSage与Pinterest上其他基于深度学习内容的推荐系统在homefeed推荐任务上的性能。可以通过观察用户参与度的提升来评估性能。用repin rate度量兴趣程度,它度量用户保存的homefeed推荐的百分比。用户将pin保存到board上是一种高价值的行为,表示用户的深度参与。
PinSage,一个能够学习节点嵌入的随机游走GCN,输入的图是包含数十亿对象的web-scale graph,图中的节点是图像。通过这种方法能够根据邻居节点的信息来实现更加强大和准确的节点嵌入。比如,如果让机器识别图像,床栏和花园栅栏会比较相似,让机器分辨起来很困难,但是在构建的Graph中,大门和花园栅栏通常会成为邻居节点,但是床和大门却很少相邻。通过graph的构建,可以建立其图像背后的语义关系,而不仅仅是图像的内容。
Pinterest工程师表示他们的PinSage是目前最大的深度图嵌入应用,并且也是图卷积在推荐系统中应用的一大突破。(该团队使用英伟达Tesla GPU的和cuDNN -accelerated TensorFlow深度学习框架,用大约18TB字节的数据,75亿例子图训练卷积网络,30亿board和Pin节点。)
目前业界将GCN应用于推荐系统的主要困难就是图的规模太大,可能有数十亿个节点和上百亿的边。而在大数据的工作环境中想要扩展GCN并不容易,比如现在的推荐系统在训练GCN的时候,对于有数十亿上百亿节点的大规模图来说,这不太可行。
综上,PinSage结合了random-walk和GraphSage,并引入了weight importance对GCN进行了优化,减小了计算成本,并在工业级数据上有良好的表现。