返回介绍

数学基础

统计学习

深度学习

工具

Scala

十三、PinSage [2018]

发布于 2023-07-17 23:38:24 字数 100482 浏览 0 评论 0 收藏 0

  1. 深度学习方法在推荐系统应用中发挥着越来越重要的作用,并被用于学习图像、文本、甚至单个用户的有用的低维 embedding 。使用深度模型学到的 representation 可以用于补充甚至替代传统的推荐算法,如协同过滤。这些学到的 representation 具有很高的实用价值,因为它们可以在各种推荐任务中重复使用。例如,使用深度模型学到的 item embedding 可用于 item-item 推荐,也可用于被推荐主题的集合(如,playlists 或者 feed 内容)。

    近年来推荐领域取得了一些重大进展,尤其是随着图结构数据上的一些新的 深度方法的研发,这对于推荐 application 而言至关重要,如利用 user-item 交互的二部图、利用社交网络。

    在这些图的 deep learning 方法中,最突出的就是图卷积神经网络 GCN 相关的 deep learning 架构。GCN 背后的核心思想是:学习如何利用神经网络从图的 local graph neighborhood局部邻域 iteratively 迭代地聚合节点的特征信息。一次 “卷积” 运算就可以转换和聚合节点直接邻域(直接相连的邻居)中的特征信息。并且,通过堆叠这种卷积操作,信息可以向图的更远处进行传播。和单纯的 content-based 深度模型(如 RNN)不同,GCN 会同时利用内容信息以及图结构信息。

    虽然基于 GCN 的方法为无数推荐系统的 benchmark 设置了新的基准,但是 benchmark 上的这些任务的增益并未转换为实际生产任务的增益。主要挑战是 GCN 难以扩展到十亿节点、百亿边的大型图。

    GCNscale 非常困难,因为在大型图中违背了 GCN 设计过程中的诸多核心假设:

    • 首先,所有现有的基于 GCN 的推荐系统都需要在训练过程中对完整的图拉普拉斯矩阵进行操作,当底层的图具有数十亿节点时,计算和空间复杂度太高。
    • 其次,当图结构不断演变时,图的拉普拉斯矩阵发生变化,依赖于图拉普拉斯矩阵的 GCN 模型无法应用。

    为解决这些问题,论文 《Graph Convolutional Neural Networks for Web-Scale Recommender Systems》 提出了一个叫做 PinSagehighly-scalableGCN 框架,该框架是在 Pinterest 的生产环境中开发和部署的。PinSage 框架是基于随机游走的 GCN,应用在 30 亿节点、180 亿边的大规模图上。这种规模的图比 GCN 的典型任务大了 10000 倍。

    PinSage 利用几个关键洞察insight 来显著提高 GCN 的可扩展性:

    • 动态卷积On-the-fly convolution:传统的 GCN 算法通过将特征矩阵乘以完整的图拉普拉斯矩阵的幂来执行图卷积。相反,PinSage 算法通过对节点周围的邻域进行采样,并从该采样的邻域中动态构建计算图来执行高效的局部卷积 localized convolution

      类似于 GraphSAGE 的思想。

      这些动态构造的计算图指定了如何对特定节点执行局部卷积,从而缓解了训练期间对整个图进行操作的需求。

      注意:这里的计算图是原图的子图,而不是tensorflow 的计算图。

    • “生产者--消费者” mini-batch 构建:PinSage 设计了一种 “ 生产者--消费者” 体系结构来构建 mini-batch,从而确保模型训练期间最大限度地利用 GPU

      • 生产者:一个基于 CPU 的、超大内存的生产者高效地对节点的邻域进行采样来动态生成计算图,然后提取局部卷积需要的特征。
      • 消费者:一个基于 GPU 的消费者(tensorflow 模型)使用生产者动态生成的计算图以及节点特征,从而有效地执行随机梯度下降。
    • 高效的 MapReduce 推断:给定一个训练好的 GCN 模型,PinSage 设计了一种高效的 MapReduce pipeline ,它可以利用训练好的模型来为十亿级节点生成 embedding,并最大程度地减少重复计算。

      这意味着 item embedding 是离线计算的,而不是 online 学习的。

    除了可扩展性这方面的提升之外,作者还使用了新的训练技术以及创新算法从而提高了 PinSage 模型的效果,从而在下游推荐任务中显著提升了性能:

    • 基于随机游走的卷积:对节点的整个邻域进行卷积会产生巨大的计算图,因此PinSage求助于邻域采样。但是随机采样的结果是次优的suboptimal ,因此PinSage开发了一种基于 short random walk 采样来生成动态计算图。

      基于随机游走的卷积的另一个好处是:随机游走过程为每个邻域节点分配了一个 importance score,这个得分可以稍后应用于池化 pooling 层。

    • 重要性池化 importance pooling:图卷积的一个核心component 是对局部邻域特征信息的聚合,即池化 poolingPinSage通过随机游走来对邻域节点进行加权,从而引入基于重要性的池化。该策略使得离线效果评估指标提升 46%

      attention-based 聚合也是一种重要性池化方法。

    • curriculum trainingPinSage设计了一个 curriculum 训练方案,该方案在训练过程中向算法不断提供越来越难区分的样本。该策略使得模型性能提高 12%

    目前 PinSage 已经部署在 Pinterest 上用于各种推荐任务。Pinterest 是一个流行的内容发现和管理的 web 服务,它为用户提供大量的 pin (在线内容可视化的标签,如用户想要烹饪的食谱、用户想要购买的衣服)。用户可以和这些 pin 进行互动,如将这些 pin 保存到 board 中。每个 board 包含用户认为主题相关的一组pin,如都是食谱主题或者运动主题。总之 Pinterest 是世界上最大的用户精选 user-curated 的图,包含超过 20 亿去重的 pin、以及 10 亿个 board

    通过离线指标评估、用户调研评估、以及在线 A/B test,论文证明了 相比其它 scalablecontent-based 深度学习推荐算法,PinSageitem 推荐任务中和 homefeed 推荐任务中取得了 state-of-the-art 性能:

    • 在离线的 ranking 指标中,PinSage 比表现最好的 baseline 提高了 40% 以上。
    • head-to-head 的人工评估中,PinSage 的推荐在大约 60% 的时间里更受欢迎。
    • A/B test 中,在各种 setting 下,用户互动提高了 30%100%

    据作者所知,这时迄今为止 deep graph embedding 最大的应用,这为基于图卷积神经网络的新一代 web-scale 推荐系统指明了方向。

    这是一篇典型的工业界的论文,这类论文的一个重要问题是:效果没办法复现。一方面,其它研究者无法获完整的数据;另一方面,算法的训练和部署要求工业级的基础设施;第三,算法和业务强烈耦合。

  2. 相关工作:我们的工作建立在图结构数据深度学习方法的一些最新进展之上。

    • 《A new model for learning in graph domains》 首先概述了用于图数据的神经网络的概念,而 《The graph neural network model》 做了进一步的阐述。然而,这些在图上进行深度学习的初始方法需要运行昂贵的 message-passing 算法来收敛,并且在大型图上过于昂贵。

      《Gated graph sequenceneural networks》 提出的 Gated Graph Sequence Neural Network: GGSNN 解决了一些局限性,它采用了现代循环神经架构,但是计算成本仍然很高,并且主要用于小于 1 万个节点的图。

    • 最近,人们提出了很多的、依赖于 GCN 概念的方法。这些方法起源于 《Spectral networks and locally connected networks on graphs》,该论文提出了一个基于谱图理论spectral graph thery 的图卷积版本。遵从这项工作,许多作者提出了对谱卷积的改进、扩展、以及近似,从而在节点分类、链接预测、以及推荐系统任务等 benchmark 上产生了新的 state-of-the-art 结果。这些方法一直优于基于矩阵分解或基于随机游走的技术(如,node2vecDeepWalk)。并且,由于这些方法的成功,因此吸引了人们对将 GCN-based 方法应用到从推荐系统到药物设计的应用的兴趣。《Representation Learning on Graphs: Methods and Applications》《Geometric deep learning: Going beyond euclidean data》 对最近的进展进行了全面的综述。

    • 然而,尽管 GCN 算法取得了成功,但是以前没有任何工作能够将它们应用到具有数十亿节点和边的大型图数据。一个局限性是,传统的 GCN 方法需要在训练期间对整个图拉普拉斯算子进行操作。这里,我们填补了这一空白,并表明 GCN 可以扩展从而在涉及数十亿节点的 production-scale 的推荐系统 setting 中运行。我们的工作还展示了 GCN 在现实环境中对推荐性能的重大影响。

    • 在算法设计方面,我们的工作和 GraphSAGE 以及 FastGCN 密切相关。GraphSAGEGCNinductive 变体,从而避免在整个图拉普拉斯矩阵上进行操作。我们通过使用高效的随机游走来采样节点的邻域子图,从而消除了将整个图存储到 GPU 内存中的限制,从而从根本上改进了 GraphSAGE 。我们还引入了许多新的训练技术来提高性能,并引入 MapReduce pipelie 来扩展到数十亿节点的inference

    • 最后,经典的 graph embedding 方法(如 node2vec, DeepWalk)无法应用到此处。

      • 首先这些方法是无监督方法,而 Pinterest 包含大量的监督信息(用户保存了哪些 pin 是监督信息)
      • 其次,这些方法无法使用节点特征信息,如 pin 的视觉特征、文本特征。
      • 最后,这些方法直接学习节点的 embedding,因此模型参数规模和图的规模呈线性关系,这对于 Pinterest 是过于昂贵的。

      还有,这些方法是 transductive 的,因此无法应用到unseenitem

13.1 模型

  1. Pinterestgraph 包含 20 亿个去重的 pin10亿个 board,以及 180 亿条边。每条边包含一个 pin 节点、一个 board 节点。我们的任务是生成可用于推荐的高质量 embedding

    我们将 Pinterest 建模为一个二部图G=(V,E)$ G=(V,E) $ ,定义pin 集合为I$ \mathcal I $ ,定义 board 集合为C$ \mathcal C $ 。其中V=IC$ V=\mathcal I \cup \mathcal C $ ,e=(i,j)E,iI,jC$ e=(i,j) \in E, i\in \mathcal I, j\in \mathcal C $ 。

    每个piniI$ i\in \mathcal I $ 关联了实值特征向量xiRd$ \mathbf{\vec x}_i\in \mathbb R^d $ ,这些特征可以包括 pin 的元数据(如 degree )或者内容信息(如视觉特征或文本特征)。这里我们将 pin 与富文本和图像特征相关联。

    我们的目标是利用这些输入属性以及二部图的结构来生成高质量的 embedding。这些 embedding 然后通过最近邻查找用于推荐候选 item 的生成(召回阶段),或者作为机器学习系统中的特征来对候选 item 进行排名(排序阶段)。

13.1.1 模型架构

  1. 我们使用局部卷积模块为节点生成 embedding。我们从输入节点特征开始,然后学习神经网络,该神经网络在图上转换和聚合特征从而计算 node embedding

a. 前向传播算法

  1. 我们考虑为节点i$ i $ 生成 embeddinghi$ \mathbf{\vec h}_i $ ,这取决于节点i$ i $ 的输入特征以及节点的邻域结构。

  2. PinSage 的关键是局部图卷积 localized graph convolution

    为了生成 node embedding,我们应用了多个卷积模块(即,局部图卷积模块),这些模块从节点的局部图邻域来聚合特征信息(如,视觉特征、文本特征)。每个模块都学习如何从一个小的图邻域来聚合信息,并且通过堆叠多个这样的模块,我们的方法可以获得有关局部网络拓扑的信息。

    更重要的是,这些局部图卷积的参数在所有节点之间共享,使得我们方法的参数复杂度和输入图的规模无关。

  3. 局部图卷积操作 localized convolution operation 的基本思想是:

    • 通过全连接层对i$ i $ 的邻居节点的representationhv$ \mathbf{\vec h}_v $ 进行变换,vN(i)$ \forall v\in \mathcal N(i) $ ,N(i)$ \mathcal N(i) $ 为节点i$ i $ 的邻域。
    • 然后对变换的结果应用池化函数γ$ \gamma $ ,如均值池化,从而得到节点i$ i $ 的局部邻域N(i)$ \mathcal N(i) $ 的vector representationni$ \mathbf{\vec n}_i $ 。
    • 最后将节点i$ i $ 的局部邻域的representationni$ \mathbf{\vec n}_i $ 和节点的当前representationhi$ \mathbf{\vec h}_i $ 拼接,并利用另一个全连接层对它进行转换。根据经验,当使用拼接操作(而非均值操作)时,我们观察到 PinSage 效果的显著提升。

    此外,可以通过对结果进行归一化从而使得训练过程更为稳定,并且归一化的 embedding 执行近似的最近邻搜索 approximate nearest neighbor search 更为有效 。

  4. PinSage 局部图卷积算法convolve

    • 输入:

      • 节点i$ i $ 的当前 embeddinghi$ \mathbf{\vec h}_i $
      • 节点i$ i $ 的邻域节点的 embedding 集合{hvvN(i)}$ \left\{\mathbf{\vec h}_v\mid v\in \mathcal N(i)\right\} $
      • 节点i$ i $ 的邻域节点的加权系数组成的向量α$ \mathbf{\vec \alpha} $
      • 池化函数γ()$ \gamma(\cdot) $
    • 输出:节点i$ i $ 卷积后的、新的 embeddinghinew$ \mathbf{\vec h}_i^\text{new} $

    • 算法步骤:

      • 计算局部邻域N(i)$ \mathcal N(i) $ 的表示:

        ni=γ({relu(Qhv+q)vN(i)},α)
      • 计算节点i$ i $ 的新的 embedding

        hinew=relu(W@concat(hi,nu)+w)

        其中 @ 表示常规矩阵乘法。

      • 执行归一化:

        hinew=hinewhinew2
      • 返回节点i$ i $ 卷积后的、新的 embeddinghinew$ \mathbf{\vec h}_i^\text{new} $ 。

b. Importance-based 邻域

  1. 我们方法的一项重要创新是如何定义节点i$ i $ 的邻域N(i)$ \mathcal N(i) $ 。过往的 GCN 方法仅检查 k 阶邻域,而 PinSage 定义了基于重要性的邻域:节点i$ i $ 的邻域N(i)$ \mathcal N(i) $ 定义为对节点i$ i $ 产生最大影响的T$ T $ 个节点。

    具体而言,我们模拟从节点i$ i $ 开始的随机游走,并计算由随机游走访问的节点的L1$ L_1 $ 归一化的访问次数。归一化访问次数最高的T$ T $ 个节点就是节点i$ i $ 的邻域N(i)$ \mathcal N(i) $ 。

    这种基于重要性的邻域具有两个优点:

    • 首先,选择固定数量的邻域节点进行聚合,使得我们在训练过程中可以控制内存消耗。

    • 其次,它允许局部卷积算法在聚合邻域向量时考虑不同邻居节点的重要性。

      具体而言,我们将γ$ \gamma $ 实现为邻居向量的加权均值,其中权重系数α$ \vec\alpha $ 根据L1$ L_1 $ 归一化的访问次数来定义。我们将该方法称作重要性池化 importance pooling

c. 堆叠卷积

  1. 每次我们应用局部图卷积操作时,我们都会得到节点的一个新的 representation 。我们可以堆叠多层局部图卷积,从而得到节点i$ i $ 周围的图局部结构更多信息。其中第l$ l $ 层卷积的输入取决于第l1$ l-1 $ 层卷积的输出。初始representation 就是节点的输入特征向量。

    注意:前述局部卷积算法中的模型参数{Q,q,W,w}$ \left\{\mathbf Q,\mathbf{\vec q},\mathbf W, \mathbf{\vec w}\right\} $ 在不同节点之间共享,但是在不同层之间有所不同,因此记作{Q(l),q(l),W(l),w(l)}$ \left\{\mathbf Q^{(l)},\mathbf{\vec q}^{(l)},\mathbf W^{(l)}, \mathbf{\vec w}^{(l)}\right\} $ 。

  2. PinSage mini-batch 前向传播算法:

    • 输入:

      • mini-batch 节点集合BV$ \mathcal B\sub \mathcal V $
      • 卷积堆叠层数L$ L $
      • 邻域函数N()$ \mathcal N(\cdot) $
    • 输出:节点的 embeddingzi,iB$ \mathbf z_i, \forall i\in \mathcal B $

    • 算法步骤:

      采样 mini-batch 节点的邻域:

      • 初始化:S(L)B$ \mathcal S^{(L)} \leftarrow \mathcal B $

      • 迭代:l=L,,1$ l=L,\cdots,1 $ :

        • S(l1)S(l)$ \mathcal S^{(l-1)} \leftarrow \mathcal S^{(l)} $
        • 合并S(l)$ \mathcal S^{(l)} $ 中每个节点的采样邻域:S(l1)S(l1)N(i)$ \mathcal S^{(l-1)} \leftarrow \mathcal S^{(l-1)}\cup \mathcal N(i) $

      生成节点 embedding

      • 初始化第零层的 representationhi(0)xi,iS(0)$ \mathbf{\vec h}_i^{(0)} \leftarrow \mathbf{\vec x}_i, \forall i\in \mathcal S^{(0)} $

      • 迭代:l=1,2,,L$ l=1,2,\cdots,L $ :

        S(k)$ \mathcal S^{(k)} $ 中的每个节点i$ i $ 执行:

        • 获取节点i$ i $ 的邻域representation集合:H={hv(l1),vN(i)}$ \mathcal H=\left\{\mathbf{\vec h}_v^{(l-1)}, \forall v\in \mathcal N(i)\right\} $
        • 计算卷积输出:hi(l)convolve(l)(hi(l1),H)$ \mathbf{\vec h}_i^{(l)}\leftarrow \text{convolve}^{(l)}\left(\mathbf{\vec h}_i^{(l-1)},\mathcal H\right) $

      通过全连接层计算最终 embedding:对每个节点iB$ i\in \mathcal B $ ,计算:

      ziG2relu(G1hi(L)+b1)
  3. PinSage mini-batch 前向传播算法中,算法首先计算每个节点的各层邻域,然后应用L$ L $ 个卷积层来生成目标节点的L$ L $ 层 representation。最后将最终卷积层的输出馈入到全连接层,从而得到 final embeddingzi,iB$ \mathbf z_i, \forall i\in \mathcal B $ 。

    • 模型需要学习的参数是每层卷积层的权重和偏置{Q(l),q(l),W(l),w(l),l{1,,L}}$ \left\{\mathbf Q^{(l)}, \mathbf{\vec q}^{(l)}, \mathbf W^{(l)}, \mathbf{\vec w}^{(l)},\forall l\in \{1,\cdots,L\}\right\} $ ,以及最后全连接层的参数G1,G2,b1$ \mathbf G_1,\mathbf G_2,\mathbf{\vec b}_1 $ 。
    • 局部邻域N(i)$ \mathcal N(i) $ 的 embeddingniRm$ \mathbf{\vec n}_i\in \mathbb R^m $ ,而所有卷积层输出hi(l)$ \mathbf{\vec h}_i^{(l)} $ 的维度为d$ d $ (除了hi(0)$ \mathbf{\vec h}_i^{(0)} $ ,因为它是模型的输入特征向量)。最终模型输出zi$ \mathbf{\vec z}_i $ 的embedding 维度也是d$ d $ 。
  4. PinSage 整体结构如下图所示:

    • 左图:一个小尺寸输入图的示例。

    • 右图:一个两层卷积层的 PinSage 用于计算节点 Aembedding

    • 底图:一个两层卷积层的 PinSage 用于计算所有节点的 embedding

      尽管每个节点的计算图都不同,但是它们都共享相同的网络参数(即convolve(1),convolve(2)$ \text{convolve}^{(1)},\text{convolve}^{(2)} $ 函数参数)。

      其中,具有阴影图案的阴影框共享相同的参数;γ$ \gamma $ 表示重要性池化函数;细的矩形框(没有阴影图案)表示全连接层。

13.1.2 模型训练

  1. 我们首先详细描述我们的 margin-based 损失函数。然后我们概述了我们开发的几种技术,这些技术可以提高 PinSage 的计算效率和收敛速度,使得我们能够在十亿级节点的图以及数十亿个训练样本上进行训练。最后,我们描述了我们的课程学习方案curriculum-training scheme,该方案提高了整体的推荐质量。

  2. 损失函数:我们使用 max-margin ranking 损失函数来以监督学习的方式来训练 PinSage。我们根据用户历史行为数据来构造样本。每个样本都由一组 pin pairsq,i=(q,i)$ s_{q,i} = (q,i) $ 组成,其中q$ q $ 为 query pin

    • 如果q$ q $ 和i$ i $ 确实相关,则 label1,表示正样本。i$ i $ 称作 postive pin
    • 如果q$ q $ 和i$ i $ 不相关,则 label0,表示负样本。i$ i $ 称作 negative pin

    如果用户对 pinq$ q $ 互动之后立即和 pini$ i $ 互动,则我们认为sq,i=(q,i)$ s_{q,i} = (q,i) $ 是正样本,对于其它的所有jI$ j\in \mathcal I $ 我们认为sq.j=(q,j)$ s_{q.j} = (q,j) $ 为负样本。考虑到每个q$ q $ 的负样本数量太多,这里我们对负样本进行采样。

    max-margin ranking 损失函数的基本思想是:希望最大化正样本的 embedding 内积、并且确保负样本embedding 的内积比正样本 embedding 内积少一个预定义的 margin。因此,给定一个正样本的 pin pair(zq,zi)$ (\mathbf{\vec z}_q, \mathbf{\vec z}_i) $ ,其损失函数为:

    J(zq,zi)=EnkPn(q)max{0,zqznkzqzi+Δ}

    其中:

    • Δ$ \Delta $ 为预定义的 margin,它是一个正的超参数。
    • Pn(q)$ P_n(q) $ 为针对 query pinq$ q $ 的负样本分布,关于该分布后文详述。

    注意:在目标函数中我们仅考虑 pin 节点(因为 label 是定义在 pin 节点上的),不考虑 board 节点。但是在PinSage 的模型中,我们考虑所有类型的节点(包括 pinboard)。

  3. 大型 mini-batch 的多 GPU 训练:为了在单台机器上充分利用多 GPU 进行训练,我们以 multi-tower 的方式(multi-towertensorflow 利用多 GPU 训练的一种模式,默认情况下 tensorflow 使用单个 GPU 训练)进行前向传播和反向传播。

    对于多 GPU,我们首先将每个 mini-batch 划分为相等大小的部分,然后每个 GPU 使用 mini-batch 的一部分进行计算(即数据并行)。每个 GPU 使用相同的一组参数进行数据并行。在反向传播阶段,所有 GPU 上各个参数的梯度会汇聚在一起,并在每个迭代步执行同步 SGD 。由于需要训练数十亿样本,因此我们采用了较大的 batch size,从 5124096

    为处理较大的 batch size,我们使用类似于 《Accurate, Large Minibatch SGD: Training ImageNet in 1Hour》 等人提出的 gradual warmup procedure 技术,从而确保在保持准确性的条件下实现快速收敛:学习率从一个较小的值逐渐线性增加到峰值,然后指数下降。

    为什么要 warm up?因为刚开始训练时模型的权重是随机初始化的,此时如果选择一个较大的学习率可能带来模型的不稳定(震荡)。选择 warm up 预热学习率的方式,可以使得开始训练的前几个 epoch 或者 step 内的学习率较小,模型因此可以慢慢趋于稳定。等模型稳定之后再使用预先设置的学习率进行训练,使得模型收敛速度更快,模型效果更佳。

    上述这种 warm upconstant warm up,不足之处在于:从一个很小的学习率突然变为较大的学习率可能会导致训练误差突然增加。于是 18Facebook 提出了 gradual warmup 来解决这个问题,即学习率从一个较小的值逐渐增加到峰值,然后指数下降。

  4. “生产者 -- 消费者” mini-batch 构建:在训练期间,数十亿个节点的邻接表以及特征矩阵的规模太大,因此只能被放在 CPU 内存中。但是在 PinSage 卷积过程中,每个 GPU 进程都需要访问节点邻域,以及邻域中节点的特征信息。

    GPU 访问 CPU 内存中的数据的效率不高,为解决该问题我们使用 re-indexing 技术来重建一个子图G=(V,E)$ G^\prime = (V^\prime,E^\prime) $ ,该子图仅涉及当前的 mini-batch 节点(及其邻域节点)。另外我们还提取了当前 mini-batch 计算相关节点的特征,重建了一个较小的特征矩阵,矩阵的顺序和G$ G^\prime $ 中节点索引一致。

    G$ G^\prime $ 的邻接表和重建的小的特征矩阵在每次 mini-batch 迭代开始的时候都被馈送到 GPU 中,因此在卷积过程中不再需要 GPUCPU 之间进行通信,从而大幅提升了 GPU 的利用率。

    训练过程交替使用 CPUGPU:模型运算在 GPU 中进行;特征提取、reindexing、负采样可以在 CPU 中进行。另外我们通过 tensorflowmulti-tower 模式来并行化 GPU 计算,通过 OpenMP 来并行化 CPU 计算。

    最后我们还设计了一个 “生产者 -- 消费者” 模式:当 GPU 在计算当前迭代的运算时,CPU 同时在计算下一轮迭代需要的特征提取、reindexing、负采样等等。该策略使得PinSage 训练时间进一步降低近一半。

  5. 负样本采样:为提高较大 batch size 的训练效率,对于 mini-batch 中的每个正样本sq,i$ s_{q,i} $ 我们并未独立采样负样本,而是采样了一组 500 个负样本从而在所有正样本之间共享负样本。

    和每个节点独立地负采样相比,这种共享负样本的方式可以大大节省每个训练 step 需要计算的 embedding 数量。从经验上讲,我们并未观察到这两种方式之间的性能差异。

    最简单的负采样方式是均匀采样,但是这种方式采样的负样本过于简单,无法为模型提供足够区分度的负样本。考虑到我们有 20 亿个去重的 pin,我们的推荐算法需要在 20 亿个 pin 中推荐 1000 个和 query pinq$ q $ 最相关的 pin ,即在 200 万个 pin 中识别出 1pin,即模型分辨率为 1/200万。但是,如果是 500 个随机负样本(以及一个正样本),则模型的分辨率 resolution 仅为 1/501。因此,如果我们从 20 亿个 pin 中随机抽取 500 个负样本,则这些负样本与 mini-batch 中任何一个 query pin 相关的可能性都非常小。即:这些负样本都过于简单,没有足够的区分度。

    为解决上述问题,对于每个正样本sq,i$ s_{q,i} $ ,我们添加一些 hard 负样本,如和 query pinq$ q $ 相关、但是和 postive pini$ i $ 不相关的 pin 集合,我们称之为 hard negative pin 。这些 hard negative pin 是根据针对 query pinq$ q $ 的 Personalized PageRank 得分进行排序,然后挑选排序在 2000 - 5000pin 被随机采样为 hard negative pin 的。

    Personalized PageRank 用于计算所有节点相对于q$ q $ 的相关性。从节点q$ q $ 对应的节点开始随机游走,每到一个节点都以1ϵ$ 1-\epsilon $ 的概率停止游走并从q$ q $ 重新开始,或者以ϵ$ \epsilon $ 的概率继续游走。从当前节点游走到下一个节点按照 out degree 均匀分布。这样经过多轮游走之后,每个节点被访问的概率趋于稳定。

    Personalized PageRank 和常规 PageRank 区别在于:前者在重新游走(即,重启)时总是从节点q$ q $ 开始,后者是随机选择一个节点开始。另外在初始化节点权重时,前者将节点q$ q $ 权重初始为 1、其它节点初始化化为 0 ,后者均匀初始化。

    如下图所示,相比随机负样本,hard negative pinquery pin 更相似,因此对模型的 ranking 能力提出了挑战,从而迫使模型学会更精细化地区分不同的 pin

    hard 负样本没有选择最相关的(排序在 top 2000pin)。

  6. 课程学习方案:一旦使用 hard negative pin,则训练收敛需要的 epoch 会翻倍。为加快训练的收敛速度,我们制定了课程学习方案:

    • 在训练的第一个 epoch,我们不使用任何 hard negative pin,因此算法可以快速找到参数空间中损失函数相对较小的区域。

    • 在随后的训练 epoch 中,我们逐渐添加更多的 hard negative pin,迫使模型学习如何区分高度相关的 postive pin 和稍微相关的 negtive pin

      在训练的第n$ n $ 个 epoch ,我们对每个 query pinq$ q $ 添加n1$ n-1 $ 个 hard negative pin

    学习过程由易到难。

13.1.3 MapReduce Pipeline

  1. 利用训练好的模型为所有 pin (包括训练期间未见过的 pin )生成 embedding 仍然是一项挑战。直接应用 PinSage mini-batch 前向传播算法 会导致大量的重复计算,因为 mini batch 中的各个节点的邻域会相互重叠。当为不同目标节点生成 embedding 时,会在很多层重复计算很多节点,如下图所示。

    为了进行高效的 inference,我们开发了一种 MapReduce 方法,该方法无需重复计算即可执行 model inference

  2. node embeddinginference 非常适合 MapReduce 计算模型,下图给出了 pin-board 二部图上 embedding inference 的数据流。

    第零层为输入层,这一层的节点为 pin 节点;第一层节点为 board 节点。MapReduce pipeline 包含两个关键部分:

    • 一个 MapReduce 作业将所有 pin 投影到低维embedding 空间。
    • 另一个 MapReduce 作业通过将 board 内的 pinembedding 进行池化,得到 boardembedding

    我们的方法避免了冗余计算,并且每个节点的潜在 embedding 仅计算一次。

    在获得了 board embedding 之后,我们采用上述类似的方式,使用另外两个 MapReduce 作业来计算 pin 的第二层 embedding,并持续迭代最多L$ L $ 次(因为有L$ L $ 层卷积层)。

13.1.4 高效的最近邻检索

  1. PinSage 生成的 embedding 可用于下游推荐任务。在许多场景中我们可以通过在学到的 embedding 空间中执行最近邻检索来提供推荐。即:给定 query pinq$ q $ ,我们可以在 embedding 空间中检索q$ q $ 最近邻的K$ K $ 个 pin 作为推荐列表。
  2. 可以通过 locality sensitive hashing:lsh 来高效地获得近似的 kNNApproximate KNN) 。如果 PinSage 模型是离线训练好的,并且所有 node embedding 都是通过 MapReduce pipeline 计算并保存到数据库中,则 approximate KNN 可以使得系统在线提供推荐服务。

13.2 实验

  1. 为证明 PinSage 的效率和效果,我们对整个 Pinterest Graph 进行了全面的实验,包括离线实验、在线 A/B test 、用户调研user study

    我们评估了两个任务:

    • 相关 pin 的推荐 related-pin recommendation :选择query pin 最近邻的K$ K $ 个邻居。

      我们使用离线 ranking 指标,以及用户调研来评估推荐的效果。

    • 首页 feeds 流的推荐:选择用最近互动的 pin 的最近邻的K$ K $ 个邻居。

      我们使用在线 A/B test 来评估 PinSage 部署在生产系统上的效果。

  2. 数据集:我们通过Pinterest 用户历史行为数据来构建训练数据集。如果用户与 pinq$ q $ 互动后,又立即和 pini$ i $ 互动,则我们认为 pin pairsq,i=(q,i)$ s_{q,i} = (q,i) $ 为正样本;对于其它的所有jI$ j\in \mathcal I $ 我们认为sq.j=(q,j)$ s_{q.j} = (q,j) $ 为负样本。如前面 “模型训练” 部分所述,这里我们对负样本进行采样。

    总而言之,我们构建了 12 亿个正样本。此外,我们为每个 mini-batch 负采样了 500 个共享的负样本,以及每个 query pin 进行 hard 负采样了 6hard negative pin 。最终我们一共得到了 75 亿个训练样本。

    考虑到 PinSageinductive learning,因此我们仅在 Pinterest 的一个子图上进行训练,然后使用 MapReduce pipeline 为整个图生成 embedding

    我们从整个 PinSage 图中随机采样一个子图作为训练集,它包含 20%board 节点(以及这些 board 包含的所有 pin 节点),并且包含子图中 70% 的正样本。我们将子图中剩余的 10% 正样本作为验证集进行超参数调优;并将子图中剩余的 20% 正样本作为测试集,用于推荐效果的离线评估。

    注意:在测试期间我们对整个 PinSage 图进行 inference 从而计算所有 20 亿个 pinembedding 。而验证期间,我们只考虑训练集中出现的节点。

    使用整个图的子集来训练可以大大降低训练时间,而对最终的效果影响几乎可以忽略不计。总体而言,用于训练和验证的数据集大小约为 18TB,而完整的输出 embedding4TB

  3. 节点特征:Pinterest 的每个 pin 都和一副图片以及一组文本(标题、描述)相关联。对于每个 pinq$ q $ ,我们将视觉 embedding4096 维)、文本 embedding256 维)、pinlog degree 拼接起来作为q$ q $ 的特征。

    • 视觉 embedding :使用 VGG-16 架构的的图像分类网络的第 6 层全连接层的输出。
    • 文本 embedding:使用 word2vec-based 模型训练的文本 embedding,其中上下文为每个 pin 关联的其它文本(如标题、描述性文字)。

    视觉 embedding 和文本 embedding 由已在 Pinterest 上部署的 state-of-the-art deep learning content-based 系统生成。

  4. baseline 方法:包括 content-based 方法、graph-based 方法以及 deep learning based 方法。

    • content-based 方法:

      • Visual :基于视觉 embedding 最近邻检索的推荐。
      • Annotation:基于文本 embedding 最近邻检索的推荐。
      • Combined:拼接视觉 embedding 和文本 embedding,然后使用两层的全连接层来得到一个同时捕获了视觉特征和文本特征的 embedding。最后基于这个新的 embedding 最近邻检索的推荐。
    • graph based 方法:

      • Pixie:使用有偏的随机游走,通过模拟从 query pinq$ q $ 开始的随机游走来生成 ranking score。然后将排名最高的K$ K $ 个 pin 作为推荐列表。

        尽管这种方法不会产生 pin embedding,但是对某些推荐任务来讲它是 Pinterest 上的 state-of-the-art 技术,因此是一种很好的 baseline

    • deep learning based 方法:因为Pinterest 规模太大,因此我们并未与任何 deep learning based 方法进行比较。

    我们也未考虑其它生成 pin embedding 的非深度学习方法,因为其它工作已经证明了在推荐任务中生成 embedding 的深度学习方法是 state-of-the-art 的。

    最后我们评估了 PinSage 的几种变体从而进行消融研究:

    • max-pooling:使用最大池化γ=max$ \gamma = \max $ ,并且不使用 hard negative pin
    • mean-pooling:使用均值池化γ=mean$ \gamma = \text{mean} $ ,并且不使用 hard negative pin
    • mean-pooling-xent:使用均值池化γ=mean$ \gamma = \text{mean} $ ,并且不使用 hard negative pin ,且使用交叉熵损失函数。
    • mean-pooling-hard:使用均值池化γ=mean$ \gamma = \text{mean} $ ,并且使用 hard negative pin
    • PinSage:使用本文中介绍的所有优化,包括在卷积过程中使用重要性池化。

    最大池化和交叉熵的 settingGraphSAGEGCN 模型的最佳扩展。其它变体在测试中效果更差,因此这里不再讨论。

    所有的 Pinsage 及其变体使用K=2$ K=2 $ 两层卷积层,邻域 emebddingni$ \mathbf{\vec n}_i $ 的维度m=2048$ m=2048 $ ,输出 embedding 维度d=1024$ d=1024 $ 。

  5. 硬件配置:PinSage 采用 tensorflow 实现,并在单台机器上训练,机器配置为 32 core16Tesla K80 GPU

    为确保快速获取 pin 的视觉特征和文本特征,我们将视觉特征、文本特征和 Graph 一起放到内存中,并使用 Linux HugePages 将虚拟内存页的大小从 4KB 增加到 2MB。训练过程中使用的内存总量为 500GB

    inference 阶段的 MapReduce pipeline 运行在 Amazon AWS hadoop2 集群上,集群配置为 378d2.8 x large 节点。

13.2.1 离线评估

  1. 评估指标:

    • Hit Rate: HR:为评估 related-pin 推荐任务,我们定义了命中率hit-rate的概念。对于测试集中的每个正样本sq,i=(q,i)$ s_{q,i}=(q,i) $ ,我们将q$ q $ 作为 query pin,然后从采样的 500万 个测试 pin 中挑选出 top K 个最近邻的 pin 集合NNq$ \text{NN}_q $ 。如果iNNq$ i\in \text{NN}_q $ ,那么就认为 query pinq$ q $ 的推荐命中hit 了。

      总的命中的 query pin 占所有 query pin 的比例为命中率。该指标衡量了推荐列表中包含 query pin 相关的 pin 的可能性。在我们的实验中,我们选择K=500$ K=500 $ 。

    • Mean Reciprocal Rank: MRR :除了命中率之外,我们还评估了均值倒数排名MRR 指标,该指标考虑了 query pinq$ q $ 的推荐列表中,pinj$ j $ 的排名:

      MRR=1|D+|(q,i)D+1Rq,i/100

      其中:

      • D+$ \mathcal D_+ $ 为所有正样本集合,|D+|$ |\mathcal D_+| $ 为正样本数量。
      • Rq,i$ R_{q,i} $ 为 postive pini$ i $ 在 query pinq$ q $ 的推荐列表中的排名。

      由于有大量的候选 pin(约 20 亿),因此我们对排名进行缩小,缩小比例为 100 倍。这是为了确保排名在 10002000 之间的候选 pin 的差异仍然很明显。

  2. 不同模型在 related-pin 推荐任务中的效果如下表所示。可以看到:

    • PinSage 达到了最佳的 67% 命中率,以及 0.59MRR。在命中率的绝对值上超越了 baseline 40%(相对值 150%),在 MRR 的绝对值上超越了 baseline 22%(相对值 60%)。
    • 将视觉信息和文本信息组合起来,要比单独使用任何一种信息都要好得多。Combined 方法比单独的 Visual 或者 Annotation 改进了 60% (相对值)。

    这里对比的 baseline 太弱了,没有和经典推荐模型(如基于矩阵分解的模型)进行对比,也没有和深度推荐模型(如 Wide & Deep )进行对比,因此不知道 GCN-based 推荐模型和其它推荐模型之间的差异如何。

  3. embedding similarity 分布:学到的 embedding 的另一个有效性指标是 embedding 随机 pair 对的距离的分布是否广泛。如果所有 pin 的距离大致相同(即,距离上紧密聚集),则 embedding 空间没有足够的分辨率来区分不同相关性的 pin

    下图给出了使用视觉 embedding、文本 embeddingPinSage embedding 绘制的随机 pin pair 对之间距离的分布,距离采用embedding 的余弦相似度。

    可以看到:PinSage 具有最广泛的分布,这证明了 Pinsage embedding 的有效性。尤其是 PinSage embedding 随机 pin pair 距离分布的kurtosis峰度为 0.43,而文本 embedding 峰度为 2.49、视觉 embedding 峰度为 1.20

    随机变量X$ X $ 的峰度定义为:E[(Xμσ)4]$ \mathbb E\left[\left(\frac{X-\mu}{\sigma}\right)^4\right] $ ,其中μ$ \mu $ 为均值,σ$ \sigma $ 为标准差。它衡量了概率分布函数峰部的尖度。

    PinSage embedding 随机 pin pair 距离分布具有这种广泛分布的另一个优点是:它降低了后续 LSH 算法的冲突概率,从而提高了推荐期间检索最近邻 pin 的效率。

13.2.2 用户调研

  1. 我们还通过对不同方法学到的 embedding 进行 head-to-head 比较来研究 PinSage 的有效性。

    在用户研究中,我们向用户展示 query pin 的图片,以及通过两种不同推荐算法检索到的两个 pin。然后要求用户选择两个候选的 pin 中哪个和 query pin 更相关。用户可以考虑各种的相关性,如视觉外观、图像的类别(比如动物、植物等等)、各自的标识等等。如果两个候选的 pin 看起来都相关,则用户可以选择 equal 。在同一个 query pin 问题上,如果有 2/3 的用户没有达成共识,则我们认为结果是不确定的。

    最终 PinSagebaseline 方法之间的 head-to-head 对比结果如下。最终 PinSage 的推荐结果平均超越了 baseline 大约 60%(相对值)。

  2. 给定一些 query pin ,我们给出了不同推荐的一些典型 case ,如下图所示。左图代表 query pin,右图代表不同方法得到的 embedding 检索的最相似的 top 3 pin 。 可以看到:

    • 基于视觉 embedding 通常可以很好地预测 pin 的类别和 pin 的视觉相似性,但是它们有时在图像语义方面会犯错。

      如下图中,由于具有相似的图像样式和外观,因此基于视觉的 embedding 混淆了 “植物” 和 “食物“、”砍伐树木“ 和 ”战争“。

    • 基于图的 Pixie 方法利用了 pin-to-board 的图关系,正确地识别了 queryplant 的类别,并推荐了该类别中的 pin。但是,该方法找不到最相关的 pin

    • 结合了视觉信息、文本信息以及图结构,PinSage 能够找到在视觉、文本以及拓扑结构都和给定 query 更相似的 pin

  3. 我们从 PinSage embedding 中随机选择 10000pin ,基于 2D t-SNE 来可视化 embedding 空间。

    我们观察到:相似内容的 pin 之间的 embedding 距离很近,并且相同类别的 item 也被嵌入到相同的区间。

    注意:视觉上不同但是主题相同的 pinembedding 空间中也彼此靠近,如图的底部给出了时尚主题的、视觉上不同的一些 pin

13.2.3 A/B Test

  1. 最后我们还报告了在线 A/B test 实验的结果。我们将 PinSage 和其它的基于内容的 deep learning 推荐系统在 Pinterest 首页信息流上的推荐效果进行比较。我们通过观察用户互动的提升来评估推荐效果。

    评估指标是 repin rate,它衡量的是首页信息流中,被用户保存到 board 中的pin 的占比。每个保存行为代表一次用户的互动。这意味着当前时间给用户推荐的 pin 是用户感兴趣的,因此用户将这个 pin 保存到他们的 board 中,从而方便用户以后查阅。

    我们发现 PinSage 推荐始终比其它方法具有更高的 repin rate。在特定的配置下,我们发现 PinSage 相比文本 embedding 和视觉 embedding10% ~30%repin rate 的提升。

13.2.4 速度

  1. PinSage 的一个优势是它是 inductive 的,因此在 inference 阶段我们可以为训练过程中未见过的 pin 计算 embedding。这使得我们可以在子图上进行训练,然后为剩下的节点计算 embedding

    另外,随着时间推移不断有新节点加入到图中,为这些新节点生成 embedding 也很简单。

    通过验证集的实验表明,对包含 3 亿个 pin 的子图上进行训练,即可在命中率上取得最佳性能。进一步增加子图的大小似乎对测试结果影响不大。

    和训练整个 Pinterest 相比,训练这个 3 亿pin 的子图可以将训练时间减少 6 倍。

  2. 下面我们考察 batch size 对训练过程的影响。我们使用 mean-pooling-hard 变体,结果如下:

    • batch size 越大,则每个 mini-batch 的计算时间越高,模型收敛需要的迭代数量越少。
    • 不同 batch size 训练时间不同, batch size = 2048 时训练效率最高,训练时间最少。

  3. 在使用重要性池化时,邻域大小T$ T $ 也会影响 PinSage 的训练时间和训练效果。我们发现随着T$ T $ 的增加,训练时间大幅增加、训练效果小幅增长。最终我们发现T=50$ T=50 $ 可以很好的在效率和效果之间平衡。

  4. 训练完成后,由于高效的 MapReduce inference pipeline,为 30 亿个 pin 生成 embedding 可以在不到 24 个小时内完成。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文