BERT4Rec
1.简介
在BERT4Rec出现之前,推荐系统试用的算法都是用序列神经网络从左到右地顺序编码用户的历史交互信息,采用这种编码方式,只利用了单项信息。但是,自然界中很多行为没有空间顺序的限制,为了解决这个问题,BERT4Rec采用了深层的双向注意力机制(双向self-attention)来对用户行为序列进行建模。为了充分利用数据信息,采用Cloze目标进行序列推荐,通过联合item左右的上下文来预测序列中随机masked item。采用这种方式,用户历史行为中每个item都会融合左右两侧信息。
注:cloze task 是bert模型预测训练的两个任务之一,等价于完形填空任务, 即给出句子中其他的上下午token, 推测出当前位置应当是什么token.
self-attention是用于同时建立两个输入序列之间的关联以及单个序列内部的关联。
2.BERT4Rec
问题定义
我们定义,U={u1,u2,...,u∣U∣}U = \{u_1,u_2,...,u_{|U|}\}U={u1,u2,...,u∣U∣}为用户集合,V={v1,v2,...,v∣V∣}V = \{v_1,v_2,...,v_{|V|}\}V={v1,v2,...,v∣V∣}为物品集合,Su=[v1(u),...,vt(u),...,vnu(u)]S_u = [v_1^{(u)},...,v_t^{(u)},...,v_{n_u}^{(u)}]Su=[v1(u),...,vt(u),...,vnu(u)]为用户历史行为序列。我们下一个目标是预测下一时刻用户与每个候选物品交互的概率。
p(vnu+1(u)=v∣Su)
p(v_{n_u+1}^{(u)} = v|S_u)
p(vnu+1(u)=v∣Su)
模型结构
如下图BERT4Rec,每一层的transformer都会利用前一层的信息。相比于RNN,self-attention可以获得任意位置的信息。相比于CNN,可以获得整个field的信息。并且,该模型为双向传播,可以解决单向传播模型信息缺失的问题。
Transformer层
Multi-Head Self-attention
对于第LLL层中的Transformer,输入HLH^LHL,首先使Multi-Head Self-Attention:
MH(HL)=[head1,head2,...,headh]headi=Attention(HLWiQ,HLWiK,HLWiV)Attention(Q,K,V)=softmax(QKTd/h)V
MH(H^L)=[head_1,head_2,...,head_h]\\
head_i = Attention(H^LW_i^Q,H^LW_i^K,H^LW_i^V)\\
Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d/h}})V
MH(HL)=[head1,head2,...,headh]headi=Attention(HLWiQ,HLWiK,HLWiV)Attention(Q,K,V)=softmax(d/hQKT)V
HLH^LHL表示从embedding layer传入过来的数据
HLWiQH^LW_i^QHLWiQ表示embedding后乘上三个权重矩阵,从而获得三个向量矩阵qkv
AttentionAttentionAttention激活函数使用softmax获得多头注意力
Dropout和Add & Norm
在多注意力层之后,加入Dropout层,在这里我们设定一个概率ppp随机关闭几个神经元,避免模型的退化(过拟合,梯度爆炸或者梯度消散)
Add&NormAdd \& NormAdd&Norm分成两部分Add和Norm
LayerNorm(X+MultiHeadAttention(X))
LayerNorm(X + MultiHeadAttention(X))
LayerNorm(X+MultiHeadAttention(X))
-
add
在注意力机制上加上一个残差项X,加入残差项的目的和Dropout一样,为了防止训练过程中模型发生退化的问题。
-
Normalize
归一化目的:
1、加快训练速度
2、提高训练的稳定性
使用到的归一化方法是Layer Normalization。Layer Normalization指的是在同一个样本中,不同神经元之间进行归一化,而Batch Normalization是在同一个batch中不同样本之间的同一位置的神经元之间进行归一化。
Positon-wise Feed-Forward Network位置向前传播全连接层
为了增加模型的非线性特性(softmax不是非线性特质么?),我们将每个位置的向量输入到向前神经网络,随后使用激活函数增加非线性特征
PFFN(Hl)=[FFN(h1l),...,FFN(htl)T]TFFN(x)=GELU(xW(1)+b(1))W(2)+b(2)GELU(X)=xΦ(x)
PFFN(H^l) = [FFN(h_1^l),...,FFN(h_t^l)^T]^T\\
FFN(x) = GELU(xW^{(1)}+b^{(1)})W^{(2)}+b^{(2)}\\
GELU(X) = x\Phi(x)
PFFN(Hl)=[FFN(h1l),...,FFN(htl)T]TFFN(x)=GELU(xW(1)+b(1))W(2)+b(2)GELU(X)=xΦ(x)
这里使用的激活函数是Gaussian Error Linear Unit(GELU),而非RELU。GELU在RELU的基础上加入了统计的特性,在论文中有较好的效果。
Embedding层
对于给定物品viv_ivi,加上位置信息pip_ipi,得到输入embedding
hi0=vi+pi
h_i^0 = v_i + p_i
hi0=vi+pi
Output层
经过L层的Transformer之后,我们得到所有的items最终输出HL={h1L,...,ht−1L,htL}H^L = \{h_1^L,...,h_{t-1}^L,h_{t}^L\}HL={h1L,...,ht−1L,htL}
我们再第t步的时候,将物品vtv_tvt加上mask集掩盖住,随后基于htLh_t^LhtL预测物品vtv_tvt。
最终使用GELU激活函数的前馈网络的最终输出为:(两层GELU?)
P(v)=softmax(GELU(htLWp+bP)ET+bO)
P(v) = softmax(GELU(h_t^LW^p+b^P)E^T + b^O)
P(v)=softmax(GELU(htLWp+bP)ET+bO)
这里的输出层公式是推荐场景特有的。WpW^pWp是前馈网络的权重矩阵;bPb^PbP和bOb^ObO是偏置项;EEE是item集合的embedding矩阵。BERT4Rec模型再输入层和输出层用的物品embedding矩阵是相同的,即物品embedding不参与拟合,目的是减轻过拟合以及减小模型体积。
模型训练和预测
为了提升模型的泛化性,我们借鉴BERT中的Masked Language Model的训练方式,随机把输入序列的一部分掩盖变为[mask],让模型来预测该位置对应的物品。
Input:[v1,v2,v3,v4,v5]−>[v1,[mask]1,v3,[mask]4,v5]Labels:[mask]1=v2,[mask]2=v4
Input:[v_1,v_2,v_3,v_4,v_5]->[v_1,[mask]_1,v_3,[mask]_4,v_5]\\
Labels:[mask]_1=v_2,[mask]_2=v_4
Input:[v1,v2,v3,v4,v5]−>[v1,[mask]1,v3,[mask]4,v5]Labels:[mask]1=v2,[mask]2=v4
损失函数:
L=1∣Sum∣∑vm∈Sum−logP(vm=vm∗∣Su′)
L =\frac{1}{|S_u^m|}\sum_{v_m\in S_u^m}{-logP(v_m = v_m^*|S'_u)}
L=∣Sum∣1vm∈Sum∑−logP(vm=vm∗∣Su′)
其中
Su′S'_uSu′是用户行为序列SuS_uSu的掩码版本
SumS_u^mSum是在Su′S'_uSu′序列中所有的随机掩码项
vmv_mvm是掩码项的真实值
vm∗v^*_mvm∗是掩码项的预测值
如上所述,我们在训练过程和最终的序列预测推荐任务之间是不匹配的。因为Cloze task的目的是预测当前被masked的物品,而序列预测推荐的目的是预测未来
为了解决这个问题,在预测阶段我们将masked附加到用户行为序列的末尾,然后根据该masked的最终隐藏表示来预测下一项。
为了更好地匹配序列推荐任务(即,预测最后一项),在训练过程中我们还生成了只mask输入序列中最后一项的样本。这个工作就像对序列推荐的微调一样,可以进一步提高推荐性能。
3.参考文档
https://blog.youkuaiyun.com/u013069552/article/details/131250923
https://zhuanlan.zhihu.com/p/263014307
https://arxiv.org/pdf/1904.06690.pdf
https://arxiv.org/pdf/1904.06690.pdf