注意力机制
“注意力机制”来源于人类天生的“选择性注意”的习惯。最典型的例子是用户在浏览网页时,会有选择性地注意页面的特定区域,而忽视其他区域。近年来,注意力机制已经成功应用在各种场景下的推荐系统中了。其中最知名的,要数阿里巴巴的深度推荐模型,DIN(Deep Interest Network,深度兴趣网络)。
Deep Interest Network
DIN模型结构图如图所示:
DIN模型依然是采用了基模型的结构,只不过是在这个的基础上加了一个注意力机制来学习用户兴趣与当前候选广告间的关联程度, 用论文里面的话是,引入了一个新的local activation unit, 这个东西用在了用户历史行为特征上面, 能够根据用户历史行为特征和当前广告的相关性给用户历史行为特征embedding进行加权。我们先看一下它的结构,然后看一下这个加权公式。相比于base model, 这里加了一个local activation unit, 这里面是一个前馈神经网络,输入是用户历史行为商品和当前的候选商品, 输出是它俩之间的相关性, 这个相关性相当于每个历史商品的权重,把这个权重与原来的历史行为embedding相乘求和就得到了用户的兴趣表示
v
U
(
A
)
\boldsymbol{v}_{U}(A)
vU(A), 这个东西的计算公式如下:
v
U
(
A
)
=
f
(
v
A
,
e
1
,
e
2
,
…
,
e
H
)
=
∑
j
=
1
H
a
(
e
j
,
v
A
)
e
j
=
∑
j
=
1
H
w
j
e
j
\boldsymbol{v}_{U}(A)=f\left(\boldsymbol{v}_{A}, \boldsymbol{e}_{1}, \boldsymbol{e}_{2}, \ldots, \boldsymbol{e}_{H}\right)=\sum_{j=1}^{H} a\left(\boldsymbol{e}_{j}, \boldsymbol{v}_{A}\right) \boldsymbol{e}_{j}=\sum_{j=1}^{H} \boldsymbol{w}_{j} \boldsymbol{e}_{j}
vU(A)=f(vA,e1,e2,…,eH)=j=1∑Ha(ej,vA)ej=j=1∑Hwjej
代码
class AttentionPoolingLayer(Layer):
def __init__(self, att_hidden_units=(256, 128, 64)):
super(AttentionPoolingLayer, self).__init__()
self.att_hidden_units = att_hidden_units
self.local_att = LocalActivationUnit(self.att_hidden_units)
def call(self, inputs):
queries, keys = inputs
key_masks = tf.not_equal(keys[:,:,0], 0) # B x len
attention_score = self.local_att([queries, keys]) # B x len
paddings = tf.zeros_like(attention_score) # B x len
outputs = tf.where(key_masks, attention_score, paddings) # B x len
outputs = tf.expand_dims(outputs, axis=1) # B x 1 x len
outputs = tf.matmul(outputs, keys) # B x 1 x dim
outputs = tf.squeeze(outputs, axis=1)
return outputs
训练优化
Mini-batch Aware Regularization
Mini-Batch Aware regularization主要解决的就是在大规模稀疏场景下,采用SGD对引入L2正则的Loss进行更新时计算开销过大的问题。该方法只对每一个Mini-Batch中不为0的参数进行梯度更新,经过一系列推导之后得到近似的梯度计算公式如公式所示:
w
j
←
w
j
−
η
[
1
∣
B
m
∣
∑
(
x
,
y
)
∈
B
m
∂
L
(
p
(
x
)
,
y
)
∂
w
j
+
λ
α
m
j
n
j
w
j
]
w_{j} \leftarrow w_{j}-\eta\left[\frac{1}{\left|\mathcal{B}_{m}\right|} \sum_{(x, y) \in \mathcal{B}_{m}} \frac{\partial L(p(x), y)}{\partial w_{j}}+\lambda \frac{\alpha_{m j}}{n_{j}} w_{j}\right]
wj←wj−η⎣⎡∣Bm∣1(x,y)∈Bm∑∂wj∂L(p(x),y)+λnjαmjwj⎦⎤
Data Adaptive Activation Function
文章认为采用PRelu激活函数的校正点固定不变,在输入分布发生变化时是不适用的。文章对该激活函数进行了改进,Dice激活函数会根据每层输入数据的分布来自适应调整校正点的位置,具体形式如下:
f
(
s
)
=
p
(
s
)
⋅
s
+
(
1
−
p
(
s
)
)
⋅
α
s
,
p
(
s
)
=
1
1
+
e
−
s
−
E
[
s
]
Var
[
s
]
+
ϵ
f(s)=p(s) \cdot s+(1-p(s)) \cdot \alpha s, p(s)=\frac{1}{1+e^{-\frac{s-E[s]}{\sqrt{\operatorname{Var}[s]+\epsilon}}}}
f(s)=p(s)⋅s+(1−p(s))⋅αs,p(s)=1+e−Var[s]+ϵs−E[s]1