推荐系统相关
pairwise hinge loss
其衡量的是pairwise场景下正负样本的差异,公式如下所示,其中 m a r g i n margin margin代表的是预设的阈值, u u u代表输入query, d + d+ d+代表的是正样本, d − d- d−代表的是负样本, < > <> <>代表的是两个向量之间的相似度,该公式代表的含义是只有当输入query与正样本足够相似时,loss才会降为0,否则与正样本越不相似或者与负样本越相似,则loss都会变得很大。
l o s s = m a x ( 0 , m a r g i n − < u , d + > + < u , d − > ) loss = max(0, margin - <u, d+> + <u, d->) loss=max(0,margin−<u,d+>+<u,d−>)
bpr loss
其同样衡量的是pairwise场景下正负样本的差异,公式如下,可以看出其整体的含义和pairwise hinge lossl类似,但少了 m a r g i n margin margin参数,这使得模型变得更加鲁棒。
l o s s = l o g ( 1 + e x p ( < u , d − > − < u , d + > ) ) loss = log(1 + exp(<u, d-> - <u, d+>)) loss=log(1+exp(<u,d−>−<u,d+>))
常规
contrastive loss
对比损失,让相似样本尽量相似,非相似样本尽量不相似,公式如下所示:
l o s s = 1 N ∑ n = 1 N y d 2 + ( 1 − y ) m a x ( m a r g i n − d , 0 ) 2 loss = \frac{1}{N}\sum_{n=1}^N yd^2+(1-y)max(margin-d,0)^2 loss=N1n=1∑Nyd2+(1−y)max(margin−d,0)2
triplet loss
从名称上可以看出,该损失函数的输入由三部分构成,这三部分分别是anchor(锚点)、positive(正例)以及negative(负例)。triplet loss的核心思想由有如下三部分构成:
- anchor与negative差异越大越好
- anchor与positive差异越小越好
- positive与negative差异越大越好
基于上面三个子思想,写出triplet loss的公式,其中anc、pos以及neg是anchor、positive以及negative在模型中的表示,可以理解为
a
n
c
=
f
(
a
n
c
h
o
r
)
anc=f(anchor)
anc=f(anchor),
p
o
s
=
f
(
p
o
s
i
t
i
v
e
)
pos=f(positive)
pos=f(positive),
n
e
g
=
f
(
n
e
g
a
t
i
v
e
)
neg=f(negative)
neg=f(negative)。
l
o
s
s
=
{
2
∗
∥
p
o
s
−
a
n
c
∥
2
−
∥
p
o
s
−
n
e
g
∥
2
−
∥
a
n
c
−
n
e
g
∥
2
+
m
a
r
g
i
n
i
f
l
a
b
e
l
=
1
2
∗
∥
n
e
g
−
a
n
c
∥
2
−
∥
n
e
g
−
p
o
s
∥
2
−
∥
a
n
c
−
p
o
s
∥
2
+
m
a
r
g
i
n
i
f
l
a
b
e
l
=
0
loss = \left\{\begin{matrix} 2 * \left \| pos - anc \right \|^2 - \left \| pos - neg \right \|^2 - \left \| anc - neg \right \|^2 + margin \ \ \ \ if \ label = 1 \\ 2 * \left \| neg - anc \right \|^2 - \left \| neg -pos \right \|^2 - \left \| anc - pos \right \|^2 + margin \ \ \ \ if \ label = 0 \end{matrix}\right.
loss={2∗∥pos−anc∥2−∥pos−neg∥2−∥anc−neg∥2+margin if label=12∗∥neg−anc∥2−∥neg−pos∥2−∥anc−pos∥2+margin if label=0
上述公式的含义为:
- 如果label为1,则pos与anc差异越小越好 + pos与neg差异越大越好 + anc与neg差异越大越好
- 如果label为0,则neg与anc差异越小越好 + pos与neg差异越大越好 + anc与pos差异越大越好
- margin存在的意义为提升模型学习的难度,因为如果不加margin,则模型很容易把anc、pos以及neg弄成0,这样loss也会很小。
这里给出triplet loss的tf代码实现:
def triplet_loss(self, pos, neg, anc, label):
part1 = tf.reduce_sum(tf.square(pos - anc), axis=-1)
part2 = tf.reduce_sum(tf.square(pos - neg), axis=-1)
part3 = tf.reduce_sum(tf.square(anc - neg), axis=-1)
part1_1 = tf.reduce_sum(tf.square(neg - anc), axis=-1)
part2_1 = tf.reduce_sum(tf.square(neg - pos), axis=-1)
part3_1 = tf.reduce_sum(tf.square(anc - pos), axis=-1)
loss1 = tf.expand_dims(2 * part1 - part2 - part3 + self.triplet_loss_margin, axis=-1)
loss2 = tf.expand_dims(2 * part1_1 - part2_1 - part3_1 + self.triplet_loss_margin, axis=-1)
loss = tf.where(tf.equal(label, 1.0), loss1, loss2)
return loss