总述:facebook 在技术行业上一直和谷歌这些公司一样,处于一个领头羊的地位,在 facebook 的业务当中,搜索推荐算法一直是一个比较重要的板块,在今年他们提出来一个新的算法,就是在“深度方法”的基础上,再加上这个行业刚兴起时候的“协同过滤”!本文先从论文翻译入手,后续还会给出源码理解、以及博主的实践理解
原文地址链接:https://arxiv.org/pdf/1906.00091.pdf
下面这篇论文的翻译,也可以在这个链接进行下载,我已经上传了上去:https://download.csdn.net/download/a1066196847/11294026 默认需要积分才能下载,没积分的可以给我留言,我发给你
英文题目:Deep Learning Recommendation Models for Personalization and Recommendation Systems
中文题目:个性化和推荐系统中的深度学习推荐模型
摘要
随着深度学习的发展,基于神经网络的推荐模型已经成为解决个性化和推荐的重要工具。这些网络与其他深度学习网络有很大不同,他们需要处理分类特征,这个方向还没有得到很好的研究和理解。在本文中,我们开发了一种最先进的深度学习推荐模型(DLRM),并且提供了他们基于pytorch和caffe2的实现,此外,我们还设计了一种专用的并行化方案,利用嵌入表上的模型并行性来减少内存约束,同时利用他们的数据并行性来从“全连接层”向外扩展计算。我们把DLRM模型和现有的推荐模型进行比较,并且在Big Basin人工智能平台上来描述其性能,展现他在未来的算法试验和系统协同过滤上作为基准的有用性。
1:介绍
目前,个性化和推荐系统已经在各大互联网公司用于各种业务上,包括CTR预估和排序模型。虽然这些方法历史悠久,这些方法最近才采用了神经网络。两个主要观点为深度学习模型的设计做出了贡献。
第一个是来自于推荐系统的观点,这些系统最初利用协同过滤的思想,用户可以根据自己相近的人来进行推荐喜欢的东西【22】。推荐的内容是基于用户过去的行为,利用以前用户对产品的评价等。邻域方法【21】通过对用户分组、产品聚类、潜在因素办法来给用户进行推荐,通过这些隐含的特征,来构建矩阵分解技术来表征用户和产品【9,17】在后来已经成功在线上得到证实可用。
第二个是来自于预测分析,他依赖于统计模型来进行分类或者根据给定的数据来预测事件发生的概率【5】。预测模型从使用简单的模型开始,比如线性回归、逻辑回归模型,一直到包含深度网络的模型。为了处理类别特征,这些模型采用了用嵌入式转换的办法,将one-hot和multi-hot的向量在一个“抽象空间”中变成dense向量。这个抽象的空间可以被看做推荐系统发现潜在因素的空间。
在本文中,我们介绍了由两者思想结合的个性化模型,这个模型用嵌入式embedding的方式来表征“类别特征”,还有一个多层感知器(MLP)来处理“数值特征”,最后,用在【24】中提出来的统计技术的方法来明确的进行相互作用这些特征,最后,他通过和另一个MLP模型后处理这些相互作用,找到了事件概率。我们将这种模型成为深度学习推荐模型(DLRM)。这个流程可以参见Figure 1。这个模型已经用Pytorch和caffe2来实现,并且随着这个手稿的发出已经用于测试和试验。
2:模型设计和架构
在本节中,我们将描述DLRM的设计。我们将从这个网络的高级组件开始,解释他们怎么、为什么能够组装在一起,对未来模型设计产生影响;然后介绍低级操作和基本元件构成这个模型,对未来的硬件系统设计产生影响。
2.1:DLRM的组成部分
DLRM的高级组件可以很容易的通过回顾更早之前的model来进行理解。我们将避免全盘科学回顾,我们将专注早期用过的4种技术,这些可以解释为DLRM的高级组件。
2.1.1 向量
为了处理类别特征,我们需要把每个category表征成一个dense的向量。特别是,一个向量可能用一个one-hot向量ei(第i个位置是1,其他位置是0,第i个位置和第i个取值保持一致)来获取相应的行向量。向量表W属于R(m*d),可以写成下面这样
在更复杂的场景中,一个embedding也可以代表多个item加权后的结果,一个multi-hot向量的权重,其中每个元素,ai不等于0,
,其他的地方填补0。
这些index可以代表相应的item。要注意到假设一个mini-batch的size为t的话,向量的查询可以被写成,
,稀疏矩阵A是
DLRMS将会利用embedding tables将每一个类别特征都转换成N维的向量,然而即使可以做到这种映射是有意义的,他们又将如何被应用?为了回答这个问题,我们回到“潜在因子方法”。
2.1.2 矩阵分解
回想一下,在推荐问题的典型描述中,我们给出来一组用户S,这些用户已经评定了一些产品。我们想要用向量来表征第i个产品,i的取值是1,…,n,第j个user也用向量表征,
,j的取值也是1,…,m,n m分别表示产品和用户的总数。更严格的说当第j个用户对第i个产品进行交互时,可以用一个索引元祖(i,j)来进行表达。矩阵分解方法可以通过最小化下面这个公式来表达
我们用来表示第i个item和第j个user向量的乘积,i和j的取值范围和上面一样,我们让
,我们可以用
来表示近似于整个矩阵的乘积
,这里的W V是两个向量表,每一行都代表一个item或者一个user,这些嵌入向量的点乘产生了对后续评级有意义的预测,这是设计DLRM的关键点。
2.1.3 分解机
在分类问题中,我们想要定义一个预测函数,,从输入的数据
到一个目标target
。举个栗子,我们可以通过定义T={+1,-1}来预测点击率(+1表示存在点击,-1表示不存在)。分解机FM通过定义一个模型将二阶交互转化到一个线性模型中,这个模型长下面这个样子
这个公式中,,upper这个参数选择矩阵的上三角部分。
FM与具有多项式、核的支持向量机明显不同【4】,因为FM将二阶相互作用矩阵分解成潜在因子(或者说是嵌入向量),这种方式更加有效的处理了稀疏数据。这显著减少了通过仅捕获不同对这件的交互产生的embedding向量的复杂度,产生线性计算复杂度。
2.1.4 多层感知机
最近很多在机器学习上的成功归功于深度学习的兴起。其中最基础的模型是多层感知器(MLP),一种由全连接层组成的交错序列,激活函数是,
这些方法已经用于捕获更复杂的交互。这表明了,如果给定足够多的参数,MLP也具有足够深度、宽度,就能使数据适应任意精度【1】,这些方法的变换已经广泛的被用在计算机在内的各种计算版本、神经语言处理上。一个特例,NFC[15,25]使用MLPerf基准【19】中的一部分,使用MLP而非点乘来计算矩阵分解中的embedding的相互作用
2.2 DLRM的架构
截止到目前为止,我们已经描述了推荐系统和预测分析中使用的不同模型。让我们直觉性的来比较一下他们,以创建一个截止到目前为止最先进的模型。
首先让user和item被许多连续、离散的特征来描述,为了处理这些类别特征,每一个类别特征都会被表达成同一个维度的向量,概括了矩阵分解中使用到的潜在因素的概念(3)。为了处理连续特征,连续特征将由一个MLP(我们称之为底部或稠密的MLP),将产生一个与嵌入相同长度的embedding向量。
我们将根据直觉,明确的计算不同特征间的二阶交叉,处理FMs(4)中提供的稀疏数据,选择性的把它们通过我们的MLP模型,这个操作已经被在所有的向量对中通过点乘和处理dense特征解决。这些点乘的item被原始处理的dense特征和一个后处理的MLP(output MLP)所连接,然后将预测结果输入到一个sigmoid函数来给出预测概率。
我们将得到的模型称为DLRM,在Fig1中展示。我们展示了一些在pytorch中、Caffe2中常用的操作。
2.3 与先前模型的比较
许多基于深度学习的推荐模型【3,13,27,18,28,29】使用类似的主意去生成高阶项以便来处理这些稀疏特征。比如这些Widw and Deep、Deep and Cross、deepfm、xDeepFM网络,设计专门的网络去构建高阶表达。这些网络然后把他们输出的模型和一个MLP模型的结果加起来,然后通过linear模型和一个sigmoid激活函数把最终的概率输出。DLRM用一个可以模型向量机的结构化方法来专门嵌入这些embedding,通过在最后一层MLP只考虑有交叉的item之间的点乘,来显著降低模型的维数。我们再下面这个理论上有个争论,我们在其他模型里面发现高阶交叉要比二阶交叉效果好,但这在计算内存成本上来说是不划来的。
DLRM和其他网络比较看,一个最主要的不同点是:模型如何来对待已经被变成向量的特征、已经他们之间的交叉。特别支持,DLRM(and xDeepFM[18])把每一个特征向量解释成一个,用单神经元表达单特征,与此同时,像Deep和Cross这样的网络把特征向量中的每一个元素看成一个新的神经元,并且进行互相交叉。因此,Deep and Cross网络不仅把不同特征向量和item进行点乘,像在DLRM中医药,并且在不同特征之间也进行了交叉,最终就导致了一个很高的参数维度。
3:并行化
现代个性化模型和推荐系统需要大批量参数、复杂的模型才能hold得住大规模数据。DLRMs更是包含很多的参数,最多可以比一些常见的深度模型,比如CNN,RNN,GAN多出几个数量级。这导致模型的训练时间会长达几个周。因此,为了在实际规模上有效的解决这些问题,有效的建模,将这些任务并行化是非常重要滴。
正如上一节所述,DLRM可以同时处理类别特征(需要用embedding表达)、和连续特征(最后一层使用MLP)。Embedding有助于实现主要的参数,每个表需要好多G的内存,使得DLRM内存占用过大并且带宽也比较密集。Embedding的size使得他可能禁止进行并行化,因为他需要在每个worker上都复制一份lookup table。在很多种情况下,这种内存约束使得训练模型的时候,需要将一份参数跨多个设备复制到每个机器上。
另一方面,MLP这种模型在内存中的参数了是非常小的,但需要转换成相当大的数量来进行计算。因此,数据并行性对于MLP来说是首选的,因为这能模型当在更新模型参数的时候,能够进行并发处理不同设备上的样本。我们得并行化DLRM将使用模型并行化的组合,来实现embedding的分享和数据并行,MLP的并行化可以缓解查找embedding向量带来的内存,并且在整个MLP阶段,也就是前向和后向传播阶段都可以这样做。由于MLRM的结构、大规模模型,组合模型、数据并行在DLRM上是一个特别的要求。这样的组合、并行不管在caffe2和pytorch上都是不支持的(其他的深度学习框架上也是不支持),所以我们设计了一个自定义的实现,我们会在下面的论文中详细说说他。
在我们的设计中,top MLP和相互操作,需要从bottom MLP和总体的embedding查找表中,访问小批量的数据。由于模型并行性已经用在在各个设备上去分布这些数据,这需要个性化的全面通信【12】。在embedding lookup的最后,每一个设备都有整个embedding table里的一部分数据,需要验证小批量维度进行分割并传送到适当的设备。就像在Fig2中记录的一样
我们注意到数据并行NLP模型中,向后传递中的参数更新是使用 allreduce来进行累计的,并且把参数应用于每一个设备上【12】,确保在每一次迭代之前,每个设备上的参数都是最新的。IN pytorch,数据并行可以用 nn.DistributedDataParallel和nn.DataParallel模块来做,并且用于在每个设备上复制模型,并且插入 allreduce 必须的依赖。在 caffe2 中,我们在每次 梯度更新时 手动插入 allreduce。
4:Data
为了测量模型的准确性,测试其整体性能,并对每个独立的操作进行表征,我们需要为我们得试验创造或者获取到一个数据集,我们现在的方式是:随机造一个、合成一个、公开的数据。
前两个数据集可用于从系统角度试验模型,特别是,他允许我们测试不同的硬件属性,并且在移除数据存储系统的依赖关系中动态获取数据,并且测试准确率。
4.1
回想一下,DLRM模型接受类别特征、连续特征作为输入。前者可以通过使用均匀或者正态(高斯)分布,生成随机数矢量,这两个函数使用默认的参数 numpy.random/rand/randn。输入数据的一个小批量可以通过随机生成一个矩阵完成,每一行都是小批量中的一个元素。
为了生成类别特征,我们需要首先确定,在一个multi-hot中我们需要多少个非0元素。在基准测试的时候,可以允许这个数字固定或者是随机,在[1,k]直接生成。然后,我们生成相对数量的整数索引,取值范围是[1,m],m就是行数。最后,为了创造一个mini-batch的lookups,我们连接上面的索引,并且描述每个单独的查找,用SparseLengthsSum或者nn.EmbeddingBag
4.2
有很多理由支持自定义生成与分类特征相对应的索引。例如,如果我们得应用使用了一个特殊的数据集,但我们因为隐私不想公开它,然后我们就会通过分布来表达分类特征。这可以作为应用程序中,使用的隐私保护技术的替代方案,比如在 federated learning[2,10]。另外,如果我们想要锻炼系统的组件的健壮性,比如学习记忆行为,我们或许想要捕获原始痕迹访问的基本位置。
现在让我们说一下如何使用合成数据集。假定我们有一系列指数,对应于单个分类特征的lookup table(并且为所有特征重复这个过程)。我们可以记录重复访问之间的唯一访问、距离频率(Alg.1),然后生成一个合成的轨迹(Alg.2),就像在【14】中提出的方法一样。
请注意,我们只能生成一个堆栈距离,最多可以是s个唯一的访问,因此,s用于控制在分布p中的一个支持,就像在Alg.2中一样。给定一定数量的唯一访问,较长的输入轨迹将导致在Alg.1中分配给他们的概率更低,这将导致在Alg.2中为了全分布式的操作造成更多的时间。为了解决这个问题,我们将唯一访问的概率挺高到最小阈值,并且一旦有了全部内容,我们就删掉唯一访问的那些记录。基于原始和合成轨迹的概率分布p如图3所示。在我们的原始实验,和调整合成轨迹中,生产了一些低缓存命中或者未命中率。
Alg.1和Alg.2是为了更准确的缓存模拟才被设计的,但他们说明了一个一般概念,怎么样概率分布可以用来生成具有所需属性的合成轨迹。
4.3 公开
很少有公开数据集可用于推荐和个性化系统。有两个比赛的数据可以用,一个是 The Criteo AI Labs Ad kaggle,一个是 Terabyte,这两个数据集是开放的并且包含了点击日志和CTR预估的label。每一个数据集都包含13个连续的特征、26个类别特征。一般来说,对连续的特征都会使用log(x+1)来进行处理,类别特征都拿到相应的index,一些NULL数据就给个0或者NULL吧。
The Criteo AI Labs Ad kaggle这个比赛的数据报告超过7天的数据量,总数据了大约4500万。这7天的数据,前6天会被当做训练集,最后1天当做验证集。Terabyte超过24天,前23当做训练集,最后1天当做测试集。每天都有大约相等数量的样本。
5 试验
让我们现在说明下DLRM的准确性。这个模型是基于caff2和pytorch框架的,可以再github中得到。在模型参数、索引上,他的精度是使用的fp32,int32(Caffe2)/int64(Pytorch)。这个试验是在 Big Basin 平台上进行,基于 Dual Socket Intel Xeon 6138CPU,2.0Ghz,还有8块 16gb的V100卡
5.1 模型在公共数据集上的准确率
我们再Criteo Ad kaggle数据集上进行评估模型,并且使用了DLRM模型,我们和一个Deep Cross网络(DCN)来进行对比性能,而且没有进行大量的参数调整。我们还对比了DCN网络,因为这个网络是少量的几个在同一数据上具有全面结果的模型之一。在这种情况下,模型的大小取决于数据量的多少。特别是,DLRM由可以处理Dense数据的底部MLP组成,三个隐藏层包含有512 256 64个节点,top MLP包含有两个隐藏层,512 256个节点。另一方面,DCN包含有6个交叉层,和一个深度网络包含有512 256个节点。Embedding的尺寸是16,这些造成的结果是,DLRM和DCN都有大约540M的参数。
我们在一个epoch上,绘制了完整的训练集、验证集的准确率曲线,使用的优化器是 SGD、Adagrad optimizers【6】。没有使用正则化。在这个试验中,DLRM表现出了稍高的训练和验证准确率。就想在Fig 5中表现的那样。需要强调下,这是没有对模型参数进行调整过的一个泛化结果。
5.2 在单个通道/设备上的模型表现
为了在单台设备上看看我们模型的性能,我们准备了一个小数据集,8个类别特征,512个连续特征。所有的类别特征都通过一个1M大小的lookup table进行查询,64维度,连续特征就 assembled 成512维度的特征。让最后一层的MLP有两个层,第一层的MKP有4个层。我们随机选择了2048个样本,batch_size大小是1000
Caffe2中这个模型在cpu上运行大约256秒,在GPU上运行62秒。和我们期待的一样,大多数时间都花费在了从lookup table中查找、和全连接层。在cpu上,全连接层占据的时间分量很大,在gpu上就忽略不计了。
6 结论
在这个论文中,我们提出并开源了一个新颖的,可以利用类别特征的,基于深度学习的推荐模型。虽然现在推荐系统上,深度学习的引入已经取得了成功,我们提出的网络在今后的学术界、生活中还是能得到很大的实际使用。通过提供最先进的推荐模型的系统描述,我们希望可以引起人们的主意,这个网络展现出他的独特魅力,以便进一步的实现算法试验、建模、系统协同设计和基准测试。