作者:一元,四品炼丹师
Sequential Recommendation with Bidirectional Encoder Representations from Transformer(CIKM19)
背景
之前和海归博士朋友聊天,他说,这篇文章是他所有的复现算法中,处理序列最好的算法之一。原本以为Bert只常见于NLP中,本文我们一起详细地阅读学习一下如何使用Bert来做推荐系统并取得最好的效果的。
本文的所有代码可以在后台回复“BertRec”即可得到。
之前我们的序列化模型从左到右的无向模型是次优的,
本文是最早使用Bert方法来处理该问题的文章。为了防止信息泄露并且高效地训练双向模型,我们在序列化建模时采用了Cloze目标,通过联合调节左右上下文来预测序列中的随机屏蔽项。通过这种方式,我们学习了一个双向表示模型,通过允许用户历史行为中的每一项融合来自左侧和右侧的信息来融合信息。
Bert4Rec
问题描述
在序列化推荐问题中,我们令表示用户的集合, 表示商品的集合, 表示用户的单调顺序的交互序列,其中, 是用户在时间和商品交互的信息, 是用户的交互序列长度。给定交互历史, 序列化推荐希望能预测处用户在时间步时间段与商品的交互概率。
模型框架
如上图所示,Bert4Rec是由L个有向Transformer层堆叠起来的,在每一层,它通过与Transformer层并行地交换前一层所有位置的信息,迭代地修改每个位置的表示,与图1d中基于RNN的方法不同, self-attentio赋予BERT4Rec直接捕捉任何距离的依赖关系的能力,而不是像图1d中基于RNN的方法那样一步一步地传递相关信息。这种机制导致了一个全局的接受野,而基于CNN的方法,如Caser通常有一个有限的接受野。此外,与基于RNN的方法相比,self-attention非常易于直接并行化。
对比图1b、1c和1d,最显著的区别是基于SASRec和RNN的方法都是从左到右的单向结构,而我们的BERT4Rec使用双向的自我注意来建模用户的行为序列。这样,我们提出的模型可以获得更强大的用户行为序列表示,从而提高推荐性能。
和上面所展示的类似,给定一个长度的输入序列,我们对每个位置在每一层迭代的计算隐藏表示,因为我们在所有位置同时计算attention的分数,因此,我们将进行stack到矩阵中。
注意机制已经成为各种任务中序列建模的一个重要组成部分,它允许捕获表示对之间的依赖关系,而不考虑它们在序列中的距离。
以往的工作表明,在不同的位置联合处理来自不同表示子空间的信息是有益的。因此,我们在这里采用多头自我注意,而不是执行单一的注意功能。具体地说,多头注意首先用不同的、可学习的线性投影将线性投影到子空间,然后应用注意函数产出输出的表示。
于是我们有:
其中,每个head的投影矩阵为:, , ,这些参数都是可以学习的参数。
此处,我们省略掉网络层的下标, 于是我们得到Scaled Dot-Product Attention:
其中, 是从相同的矩阵使用不同的投影矩阵进行投影得到的。此处被引入来产出softer的attention分布,从而避免极小的梯度。
self-attention sub-layer主要是基于线性投影,为了赋予模型非线性和不同维度的交互,此处我们对self-attention sub-layer的输出加入Position-wise的FNN。它主要由两块组成,
其中,是标准高斯分布的累积分布函数, , , , .为了方便,我们将层的下标省去。
如上所述,我们可以使用自我注意机制轻松地捕捉整个用户行为序列中的商品-商品交互。然而,通过堆叠自我注意层来学习更复杂的商品转换模式通常是有益的。
然而,随着网络的深入,训练变得更加困难。因此,如图1a所示,我们在两个子层的每一层周围使用残差连接,然后进行层标准化。此外,我们还将dropout应用于每个子层的输出,然后将其规范化。即每个子层的输出为LN(x+Dropout(sublayer(x)),其中sublayer是子层本身实现的功能,LN是中定义的层规范化函数。我们使用LN对同一层所有隐藏单元的输入进行规范化,以稳定和加速网络训练。
Trim是没有意识到输入序列的顺序的,为了使用输入的序列信息,我们将位置Embedding注入到Transformer层stacks的底部,对于给定的商品, 它对应的输入表示通过对商品和位置编码进行求和得到:
其中是关于商品的维的embedding,是关于位置index 的维度的位置编码。位置embedding矩阵允许我们的模型识别它正在处理的输入的哪一部分。此处我们设定了模型可以处理的句子最大长度, 所以我们会将输入序列的长度进行截断, 截断到最后的个商品, 。
在层之后对于输入序列的所有商品我们得到最终的输出, 假设我们在时间步处mask了商品,我们基于预测masked商品, 特殊地,我们使用一个两层的FFN以及GELU激活函数来产出目标商品的输出分布:
其中是可以学习的投影矩阵,, 是偏差项, 是商品集的embedding矩阵,我们使用共享的商品embedding矩阵来缓解过拟合问题同时降低模型的大小。
模型学习
1. 训练
为了防止过拟合等问题,我们创建了个样本(子序列的形式为:, ,...) 我们将用双向模型对每个历史子序列进行编码以预测目标,为了方便我们模型的快速训练,我们使用了一个新的目标:Cloze task(Masked Language Model). 在每个训练步,我们随机mask掉输入序列中占比的商品。
与“[mask]”相对应的最终隐藏向量被输入到商品集上的输出softmax中,就像在传统的顺序推荐中一样。最终,我们定义每个masked掉的输入作为masked的目标的negative log-likelihood:
其中,是用户行为历史的masked版本, 是随机masked的商品, 是masked商品的真实商品,是之前定义的概率。
Cloze task的另外一个优势在于它可以产出更多的样本用于模型的训练。
如上所述,我们在训练和最终的顺序推荐任务之间造成了不匹配,因为Cloze task的目标是预测当前被屏蔽的商品,而顺序推荐的目标是预测未来。为了解决这个问题,我们在用户行为序列的末尾附加一个特殊的标记“[mask]”,然后根据这个token的最终隐藏表示来预测下一个项目。为了更好地匹配顺序推荐任务(即预测最后一个项目),我们还生成了在训练期间只屏蔽输入序列中最后一个商品的样本。它的工作原理类似于顺序推荐的微调,可以进一步提高推荐性能。
实验
不同的head对应的attention不同。
结论
深度bidirectional自我注意结构在语言理解方面取得了巨大的成功。本文介绍了一种用于序列推荐的深度双向序列模型BERT4Rec。在模型训练中,我们引入Cloze task任务,该任务利用左右两个上下文预测被掩蔽的商品。在四个真实世界数据集的大量实验结果表明,我们的模型优于目前最好的方案。
参考文献