Multi-Interest Network with Dynamic Routing for Recommendation at Tmall
1.胶囊网络
将图像倒立,识别率会下降,将眼睛和嘴调换位置,仍能识别为人,所以CNN缺乏对相对空间位置的表达。
非洲还是澳大利亚?转换坐标系,其实是非洲。
low level capsule转化为high level capsule, 每个low level相当于表示实体的不同部分, high level表示整个实体。
三角形的第1个分量表示方向,整个 范数表示实体存在的置信度。
1.1胶囊网络和传统的神经网络的区别
传统的神经网络:(1)标量输入到标量输出的过程。(2)累积求和->激活函数输出
胶囊神经网络:(1)向量输入到向量输出的过程。(3)放射变换(向量乘以矩阵转化为另一个 向量)->通过c做线性加权求和->挤压(squash)->输出v。其中c是通过dynamic routing机制动态决定的。
∥
s
∥
2
1
+
∥
s
∥
2
\frac{\|s\|^{2}}{1+\|s\|^{2}}
1+∥s∥2∥s∥2?: squash类似sigmoid变换的函数,当s的 向量特别长,接近无穷时,将它压缩为1,当s为0时为0.
s
∥
s
∥
\frac{s}{\|s\|}
∥s∥s?为标准化的过程。
b
11
和
b
21
b_{11}和b_{21}
b11?和b21?初始化0,b可以理解为agreement(选举的意思,类似总统选举),其中
u
1
和
u
2
u_1和u_2
u1?和u2?类似总统候选人。b经过softmax生成和为1的权重。经过squash会生成
a
1
a_1
a1?,
a
1
a_1
a1?和
u
1
u_1
u1?的夹角比较接近,就b(agreement)就会靠近
u
1
u_1
u1?,update agreement。类似kmeans中心点的计算。v的范数表示confidence。范数很大,表示概率很大。
训练过程: 如果是minist数据集,假设训练的正样本为1,我门希望为的1范数会比较大,其他的范数比较小。
2. MIND
2.1问题的公式表示
匹配阶段的主要目标就是对每个用户
u
∈
U
u\in \mathcal{U}
u∈U在几十亿item池子中
I
\mathcal{I}
I,候选集的数量大约几千左右。
每个样本可以用
(
I
u
,
P
u
,
F
i
)
\left(\mathcal{I}_{u}, \mathcal{P}_{u}, \mathcal{F}_{i}\right)
(Iu?,Pu?,Fi?)表示,其中
I
u
\mathcal{I}_{u}
Iu?表示与用户交互的item(或者说用户的行为)。
P
u
\mathcal{P}_{u}
Pu?表示用户的基本信息(例如:用户的性别、年龄)。
F
i
\mathcal{F}_{i}
Fi?表示目标 item(例如:item id和category id)。
将原始特征映射为用户表示:
V
u
=
f
user?
(
I
u
,
P
u
)
(1)
\mathrm{V}_{u}=f_{\text {user }}\left(I_{u}, \mathcal{P}_{u}\right)\tag{1}
Vu?=fuser??(Iu?,Pu?)(1)
其中:
V
u
=
(
v
→
u
1
,
…
,
v
→
u
K
)
∈
R
d
×
K
\mathrm{V}_{u}=\left(\overrightarrow{\boldsymbol{v}}_{u}^{1}, \ldots, \overrightarrow{\boldsymbol{v}}_{u}^{K}\right) \in \mathbb{R}^{d \times K}
Vu?=(v
u1?,…,v
uK?)∈Rd×K用来表示用户
u
u
u的向量,
d
d
d表示向量维度,
K
K
K表示用户表示的数量,
K
=
1
K=1
K=1表示只有一个向量被使用 ,就像YouTube DNN。
target item
i
i
i的向量表示为:
e
→
i
=
f
item?
(
F
i
)
(2)
\overrightarrow{\boldsymbol{e}}_{i}=f_{\text {item }}\left(\mathcal{F}_{i}\right)\tag{2}
e
i?=fitem??(Fi?)(2) 其中:
e
?
i
∈
R
d
×
1
\vec{e}_{i} \in \mathbb{R}^{d \times 1}
e
i?∈Rd×1表示item
i
i
i 的一个向量。
Top N候选集计算:
f
score?
(
V
u
,
e
→
i
)
=
max
?
1
≤
k
≤
K
e
→
i
T
v
→
u
k
(3)
f_{\text {score }}\left(\mathrm{V}_{u}, \overrightarrow{\boldsymbol{e}}_{i}\right)=\max _{1 \leq k \leq K} \overrightarrow{\boldsymbol{e}}_{i}^{\mathrm{T}} \overrightarrow{\boldsymbol{v}}_{u}^{k}\tag{3}
fscore??(Vu?,e
i?)=1≤k≤Kmax?e
iT?v
uk?(3)
N
N
N表示候选集的数量。
2.2嵌入和池化层
MIND的 输入特征包括3部分:用户属性特征
P
u
\mathcal{P}_{u}
Pu?、用户的行为特征
I
u
\mathcal{I_u}
Iu?和标签item
F
i
\mathcal{F_i}
Fi?
P
u
\mathcal{P}_{u}
Pu?(性别、年龄)进行concatenate。
F
i
\mathcal{F_i}
Fi?(品牌id, shop id)传入average pooling 层,形成item embedding 为
e
?
i
\vec{e}_{i}
e
i?。
I
u
\mathcal{I_u}
Iu?用户的行为序列,
E
u
=
{
e
→
j
,
j
∈
I
u
}
\mathrm{E}_{u}=\left\{\overrightarrow{\boldsymbol{e}}_{j}, j \in I_{u}\right\}
Eu?={e
j?,j∈Iu?}。
2.3 多兴趣提取层
对用户的历史行为进行聚类
2.3.1 动态路由
假设有两个capsules, low-level capsules
c
?
i
l
∈
R
N
l
×
1
,
i
∈
{
1
,
…
,
m
}
\vec{c}_{i}^{l} \in \mathbb{R}^{N_{l} \times 1}, i \in\{1, \ldots, m\}
c
il?∈RNl?×1,i∈{1,…,m} 和high-level capsules
c
?
j
h
∈
R
N
h
×
1
,
j
∈
{
1
,
…
,
n
}
\vec{c}_{j}^{h} \in \mathbb{R}^{N_{h} \times 1}, j \in \{1, \ldots, n\}
c
jh?∈RNh?×1,j∈{1,…,n}
low-level capsule
i
i
i和 high-level capsule
j
j
j之间的logit
b
i
j
b_{ij}
bij?计算公式如下:
b
i
j
=
(
c
?
j
h
)
T
?
S
i
j
c
?
i
l
(4)
b_{i j}=\left(\vec{c}_{j}^{h}\right)^{T} \mathrm{~S}_{i j} \vec{c}_{i}^{l} \tag{4}
bij?=(c
jh?)T?Sij?c
il?(4) 其中,
S
i
j
∈
R
N
h
×
N
l
\mathrm{S}_{i j} \in \mathbb{R}^{N_{h} \times N_{l}}
Sij?∈RNh?×Nl?是需要学习的双线性映射矩阵。
candidate vector for high-level capsule j
z
?
j
h
=
∑
i
=
1
m
w
i
j
?
S
i
j
c
→
i
l
(5)
\vec{z}_{j}^{h}=\sum_{i=1}^{m} w_{i j} \mathrm{~S}_{i j} \overrightarrow{\boldsymbol{c}}_{i}^{l}\tag{5}
z
jh?=i=1∑m?wij??Sij?c
il?(5)
w
i
j
w_{ij}
wij?是连接low-level和high-level之间的权重,计算方式如下:
w
i
j
=
exp
?
b
i
j
∑
k
=
1
m
exp
?
b
i
k
(6)
w_{i j}=\frac{\exp b_{i j}}{\sum_{k=1}^{m} \exp b_{i k}}\tag{6}
wij?=∑k=1m?expbik?expbij??(6) quash 函数应用于high-level capsules, 计算方式如下:
c
?
j
h
=
squash
?
(
z
?
j
h
)
=
∥
z
?
j
h
∥
2
1
+
∥
∣
z
j
h
∥
2
z
?
j
h
∥
z
?
j
h
∥
(7)
\vec{c}_{j}^{h}=\operatorname{squash}\left(\vec{z}_{j}^{h}\right)=\frac{\left\|\vec{z}_{j}^{h}\right\|^{2}}{1+\left\|\mid{z}_{j}^{h}\right\|^{2}} \frac{\vec{z}_{j}^{h}}{\left\|\vec{z}_{j}^{h}\right\|}\tag{7}
c
jh?=squash(z
jh?)=1+∥∥?∣zjh?∥∥?2∥∥?z
jh?∥∥?2?∥∥?z
jh?∥∥?z
jh??(7)
b
i
j
b_{ij}
bij?初始化为0, 当路由结束,
c
?
j
h
\vec{c}_{j}^{h}
c
jh?可以固定下来,作为下一层的输入。
使用Shared bilinear mapping matrix 主要考虑两点:从低阶的用户行为胶囊中学习高阶的用户兴趣胶囊(1)用户行为是变长的,我们希望模型更加通用。(2)我们希望用户行为和用户兴趣能够在一个向量空间中。
b
i
j
=
u
?
j
T
?
S
e
→
i
,
i
∈
I
u
,
j
∈
{
1
,
…
,
K
}
(8)
b_{i j}=\vec{u}_{j}^{T} \mathrm{~S} \overrightarrow{\boldsymbol{e}}_{i}, \quad i \in I_{u}, j \in\{1, \ldots, K\}\tag{8}
bij?=u
jT??Se
i?,i∈Iu?,j∈{1,…,K}(8)
e
?
i
∈
R
d
\vec{e}_{i} \in \mathbb{R}^{d}
e
i?∈Rd表示item
i
i
i的用户行为,
u
?
j
∈
R
d
\vec{u}_{j} \in \mathbb{R}^{d}
u
j?∈Rd表示用户兴趣胶囊
j
j
j。
S
∈
R
d
×
d
S \in\mathbb{R}^{d \times d}
S∈Rd×d是用户行为胶囊和用户兴趣胶囊之间的共享矩阵。
**初始化routing logits:**如果矩阵初始化为0,会导致用户兴趣相同,因此采用高斯分布进行初始化。
动态用户兴趣的数量:
K
u
′
=
max
?
(
1
,
min
?
(
K
,
log
?
2
(
∣
I
u
∣
)
)
)
(9)
K_{u}^{\prime}=\max \left(1, \min \left(K, \log _{2}\left(\left|I_{u}\right|\right)\right)\right)\tag{9}
Ku′?=max(1,min(K,log2?(∣Iu?∣)))(9) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vklCkM8-1642259038786)(Selection_006.png)]
def build(self, input_shape):
self.routing_logits = self.add_weight(shape=[1, self.k_max, self.max_len],
initializer=RandomNormal(stddev=self.init_std),
trainable=False, name="B", dtype=tf.float32)
self.bilinear_mapping_matrix = self.add_weight(shape=[self.input_units, self.out_units],
initializer=RandomNormal(stddev=self.init_std),
name="S", dtype=tf.float32)
super(CapsuleLayer, self).build(input_shape)
def call(self, inputs, **kwargs):
behavior_embddings, seq_len = inputs
batch_size = tf.shape(behavior_embddings)[0]
seq_len_tile = tf.tile(seq_len, [1, self.k_max])
for i in range(self.iteration_times):
mask = tf.sequence_mask(seq_len_tile, self.max_len)
pad = tf.ones_like(mask, dtype=tf.float32) * (-2 ** 32 + 1)
routing_logits_with_padding = tf.where(mask, tf.tile(self.routing_logits, [batch_size, 1, 1]), pad)
weight = tf.nn.softmax(routing_logits_with_padding)
behavior_embdding_mapping = tf.tensordot(behavior_embddings, self.bilinear_mapping_matrix, axes=1)
Z = tf.matmul(weight, behavior_embdding_mapping)
interest_capsules = squash(Z)
delta_routing_logits = reduce_sum(
tf.matmul(interest_capsules, tf.transpose(behavior_embdding_mapping, perm=[0, 2, 1])),
axis=0, keep_dims=True
)
self.routing_logits.assign_add(delta_routing_logits)
interest_capsules = tf.reshape(interest_capsules, [-1, self.k_max, self.out_units])
return interest_capsules
2.3.2 Label-aware Attention
根据 用户的兴趣胶囊和item向量进行attention计算,对item进行加权。label是query, 兴趣胶囊是keys和values。user u的输出向量和item i计算方式如下:
v
?
u
=
?Attention?
(
e
?
i
,
?
V
u
,
?
V
u
)
=
V
u
softmax
?
(
pow
?
(
V
u
T
e
?
i
,
p
)
)
\begin{aligned} \vec{v}_{u} &=\text { Attention }\left(\vec{e}_{i}, \mathrm{~V}_{u}, \mathrm{~V}_{u}\right) \\ &=\mathrm{V}_{u} \operatorname{softmax}\left(\operatorname{pow}\left(\mathrm{V}_{u}^{\mathrm{T}} \vec{e}_{i}, p\right)\right) \end{aligned}
v
u??=?Attention?(e
i?,?Vu?,?Vu?)=Vu?softmax(pow(VuT?e
i?,p))? 其中,
p
p
p是调整attention分布的参数,当p为0时, attention是平均的。
p
p
p越大,趋近于无穷时,value更加关注权重最大的值,忽略其他的项。
def call(self, inputs, training=None, **kwargs):
keys = inputs[0]
query = inputs[1]
weight = reduce_sum(keys * query, axis=-1, keep_dims=True)
weight = tf.pow(weight, self.pow_p)
if len(inputs) == 3:
k_user = tf.cast(tf.maximum(
1.,
tf.minimum(
tf.cast(self.k_max, dtype="float32"),
tf.log1p(tf.cast(inputs[2], dtype="float32")) / tf.log(2.)
)
), dtype="int64")
seq_mask = tf.transpose(tf.sequence_mask(k_user, self.k_max), [0, 2, 1])
padding = tf.ones_like(seq_mask, dtype=tf.float32) * (-2 ** 32 + 1)
weight = tf.where(seq_mask, weight, padding)
weight = softmax(weight, dim=1, name="weight")
output = reduce_sum(keys * weight, axis=1)
return output
2.3.3 Training&Serving
得到用户的向量
v
?
u
\vec{v}_{u}
v
u?和标签的向量
e
?
i
\vec{e}_{i}
e
i?, 计算用户和标签的之间的交互的概率
Pr
?
(
i
∣
u
)
=
Pr
?
(
e
?
i
∣
v
?
u
)
=
exp
?
(
v
?
u
T
e
?
i
)
∑
j
∈
I
exp
?
(
v
?
u
T
e
?
j
)
(10)
\operatorname{Pr}(i \mid u)=\operatorname{Pr}\left(\vec{e}_{i} \mid \vec{v}_{u}\right)=\frac{\exp \left(\vec{v}_{u}^{\mathrm{T}} \vec{e}_{i}\right)}{\sum_{j \in I} \exp \left(\vec{v}_{u}^{\mathrm{T}} \vec{e}_{j}\right)}\tag{10}
Pr(i∣u)=Pr(e
i?∣v
u?)=∑j∈I?exp(v
uT?e
j?)exp(v
uT?e
i?)?(10) 训练的目标函数:
L
=
∑
(
u
,
i
)
∈
D
log
?
Pr
?
(
i
∣
u
)
(11)
L=\sum_{(u, i) \in \mathcal{D}} \log \operatorname{Pr}(i \mid u)\tag{11}
L=(u,i)∈D∑?logPr(i∣u)(11) 其中
D
\mathcal{D}
D是包括用户和item的训练数据
|