DSSM双塔模型系列之三

双塔模型中的细节

Posted by BY on August 7, 2023

第一篇简单聊了双塔模型的一些基础,这一篇聊一些实操中的关键点。

最后一层

上一篇看到双塔两边各自一个DNN,上去之后做点积或者cosine。

但是在实际工业中会发现很多在双塔的最后一层要做一个l2标准化,这是为什么呢?

实际上这是工业上又一个工程和算法配合的典型案例,之前说到在线上需要把item侧的最后一层保存起来扔到向量检索工具里面,之后用user测计算最新的embeding做检索,向量检索工具加速检索最成熟的算法是点积,即按位乘积求和,而从算法的角度相似度一般用cosine衡量效果比较好,即角度越小越相似。而我们知道点积和cosine差了一个分母的正则化,所以为了工程上的检索效率,需要在算法涉及的最后一层做l2正则化。

在推荐系统初期,对实效性要求不高,系统检索非实时,相似性离线计算的情况下,往往发现最后一层不做l2的效果要好于正则化后,这是为什么呢?这就涉及到下面的温度系数。

温度系数

我们知道正则化之后,则内积之后的值域为[-1, 1]之间,计算sigmoid = \(\frac{1}{1+exp^{-x}}\)得到结果在[0.2689414213699951, 0.7310585786300049], 之后计算交叉墒 \(loss = -\sum p_i * log(q_i)\)得到交叉墒为0.3132616875182228,即预测完全正确,每个样本算出来得交叉墒loss依然有0.31。

所以怎么办呢,既然为了工程上向量检索的方便归一化了,那我们能不能在后面计算的时候给一个系数找补回来呢?

很显然是可以的,只要对值域进行等比例放大就可以,原始值域是[-1, 1],假设我们使用经典系数0.07,则放大为[-1/0.07, 1/0.07]结果为[-14.2857, 14.2857],带入之后计算sigmoid为0.9999993751254396, 这就和1很接近了,计算交叉墒loss为-6.248747556628904e-07。

当然这个系数可以调整,论文一般的范围是[0.05, 0.2]之间,即sigmoid在[0.9933071490757153, 0.9999999979388463]。那么如何调节这个Temperature呢?

单纯的调节首先可以统计看一下原始双塔最后内积之后的值域,然后按照14除以值域大体计算出来参数的范围,之后在范围内训练看实际结果。

按照《Understanding the Behaviour of Contrastive Loss》的说法,参数越小,向量在空间中越均匀(uniformity),越能自动地关注hard负例,但过分的关注hard负例,并不是什么好事,它会破坏掉底层语义结构,潜在的语义相似负例都被打了很低的分数。所以,这个参数需要权衡。

损失函数

2016年youtube的论文,首次引入在召回测和之前word2vec一样的使用softmax多分类器,之后召回测模型开始大规模使用softmax的先例。

我们在前面双塔之一说到样本的划分,加入做点击率,正样本是点击,负样本是其他。既然是其他那么就涉及到构造负样本,大规模构造负样本首先是一些动态特征很难控制生成容易穿越,其他样本存储也是一个问题。所以工业上通用的方法就是不构造,直接使用现在正样本的其他样本当作负样本,这个是不是和softmax很像,就是除了正样本其他都是负样本。而且为了训练速度,通常的做法是batch内采样。这也为后续埋下了坑,或者换个说法引入了新的可优化点,一个是banch内的大多数都是很热的,直接采样会有很大的热度bias,引入之后会拉偏模型,使得模型区分度大大降低,youtube2019在recsys发文就是优化这个问题。第二个是直接banch内采样会导致很多库里的样本模型根本没有见过,导致出去的多样性很差,这个解决方法就是构造小比例的其他样本,给模型见见世面。当然还有就是直接batch内采样太简单了,没办法学习到真正喜欢和不喜欢直接的界限。扯的有点远了,说回来。

使用softmax除了前面说的天然契合样本的构造,另外一个是召回测不追求绝对的精确性,不像是精排测,我要求点击率非常的准就是0.789,否则会影响后面的计费或者其他的融合计算,召回测更追求相对的序,把用户可能喜欢的召回出来就ok,所以候选的loss就会比较多,像二分类交叉墒loss,多分类softmax loss,甚至pair wise的BPR或者henge loss等。

不同loss的差异

实际上召回测双塔很少用交叉墒loss,常用的是sample softmax loss 和pair-wise的henge和BPR loss。

原因一方面前面说了召回测不关心准确的值,更关心相对的序;甚至于可以在负样本中作区分,某一些完全不相关,某一些部分相关。另一方面,召回测的负样本大多数都是没曝光过的,我们直接当作负样本,中间存在一定噪声,所以更倾向于建模相对的准确性。

hard负样本加入后,BPR和henge类的loss一般效果较好。原因是BPR类的对负样本排序到前面了惩罚更大,核心是关注它在几个正样本前面,而softmax只关注当前交叉墒,BPR会计算很多次,和softmax只会计算一次。所以在错的hard负样本上学的更好。