推荐系统(二十)谷歌YouTubeDNN(Deep Neural Networks for YouTube Recommendations)

推荐系统(二十)谷歌YouTubeDNN(Deep Neural Networks for YouTube Recommendations)

推荐系统系列博客:

  1. 推荐系统(一)推荐系统整体概览
  2. 推荐系统(二)GBDT+LR模型
  3. 推荐系统(三)Factorization Machines(FM)
  4. 推荐系统(四)Field-aware Factorization Machines(FFM)
  5. 推荐系统(五)wide&deep
  6. 推荐系统(六)Deep & Cross Network(DCN)
  7. 推荐系统(七)xDeepFM模型
  8. 推荐系统(八)FNN模型(FM+MLP=FNN)
  9. 推荐系统(九)PNN模型(Product-based Neural Networks)
  10. 推荐系统(十)DeepFM模型
  11. 推荐系统(十一)阿里深度兴趣网络(一):DIN模型(Deep Interest Network)
  12. 推荐系统(十二)阿里深度兴趣网络(二):DIEN模型(Deep Interest Evolution Network)
  13. 推荐系统(十三)阿里深度兴趣网络(三):DSIN模型(Deep Session Interest Network)
  14. 推荐系统(十四)多任务学习:阿里ESMM(完整空间多任务模型)
  15. 推荐系统(十五)多任务学习:谷歌MMoE(Multi-gate Mixture-of-Experts )
  16. 推荐系统(十六)多任务学习:腾讯PLE模型(Progressive Layered Extraction model)
  17. 推荐系统(十七)双塔模型:微软DSSM模型(Deep Structured Semantic Models)
  18. 推荐系统(十八)Gate网络(一):新浪微博GateNet
  19. 推荐系统(十九)Gate网络(二):百度GemNN(Gating-Enhanced Multi-Task Neural Networks)

写在前面: 这篇发表在RecSys’16上的文章,距今已经有些年头了,初读这篇论文是在18年的时候,如今从实习到工作已3年多时间,再次重温,心中还是不禁感叹『经典』二字,还是那句话:『谷歌出品,必属精品』,虽然这句话不是完全的对,但适用大部分谷歌发表的paper。谷歌的paper中总是带着强烈浓厚的工业实践风,这也是我个人比较喜欢的,有些论文你看一眼模型结构图基本就领会了这篇论文的80%-90%,但YouTubeDNN这篇论文,如果你只看模型结构图,也许只能领会20%-30%。当然任何商业公司的论文都会基于保密性的出发点,在论文中隐去核心的东西,所以有时候有一些细节的隐去会导致论文晦涩难懂,YouTube这篇论文也不例外。

YouTubeDNN包含召回和排序两个模块,目前这个时间点再去按照实用价值评价YouTubeDNN的话,其召回价值大于精排价值,因为目前精排迭代的模型已经很多了,基本上不会有公司使用YouTubeDNN的精排了,其召回应该还应用的很广,目前在我们自己的业务中就有一路YouTubeDNN的召回。

本篇博客将会从三个大的方面介绍YouTubeDNN:

  1. YouTubeDNN召回
    1.1 优化目标
    1.2 样本构造
    1.3 高效的训练多分类模型
    1.4 YouTubeDNN召回的模型架构
    1.5 YouTubeDNN召回在线
  2. YouTubeDNN排序

一、YouTubeDNN召回

这是本篇博客的重点,也是目前实用价值更大的一块,下面来具体谈一谈:

1.1 优化目标

YouTubeDNN召回模块没有把CTR作为优化目标,而是预测用户下一个观看的视频(next watch),也就说给定一个用户及上下文后,在候选集(所有视频)中挑选用户在下一次最可能观看的视频(next watch,这里一般是topK个),因此即转化成了一个多分类问题(数百万),这里使用一个softmax输出在所有候选视频上的概率分布。

用公式形式化的定义就是:
P ( w t = i ∣ U , C ) = e v i u ∑ j ∈ V e v j u (1) P(w_t=i|U,C) = \frac{e^{v_iu}}{\sum_{j \in V}e^{v_ju}} \tag{1} P(wt=iU,C)=jVevjueviu(1)
其中, U U U表示用户, C C C表示上下文, w t w_t wt表示用户在时刻 t t t 观看的视频, V V V表示整个视频语料库, v j v_j vj表示视频 j j j的embedding, u u u表示用户 u u u的embedding。因此,公式(1)的含义为:基于用户 U U U和上下文 C C C在时间 t t t,预估 w t w_t wt类别为 i i i(这个类别为整个视频语料库 V V V,数量在百万级别)的概率。

1.2 样本构造

再来看YouTube这里样本的构造,这里把用户看完的视频作为正样本(注意是看完的,也就是完成播放的,而不是看了的)。YouTube这里也解释了为什么没有使用YouTube上面『点赞』和『踩』这种显式反馈作为正负样本,因为使用完播这种隐式反馈所能构造出来的正样本比显式反馈的『点赞』多了一个数量级。正常情况下,用户看完一个视频去点一下『赞』这种行为是比较少的。

这里有必要说下训练样本是怎么构造的,感觉也是个非常大的细节。就拿我们自己的日志举例子吧,我们的原始日志都是item级别的(有曝光的item),一条原始日志由<item信息,用户信息,上下文信息,是否点击>组成,我们在抽取训练样本时,只抽取有点击的item,显然该点击的item就为生成的训练样本的label,然后我们需要去用户过去X天点击的item序列,用户过去X天query历史,以及一些该item相关的特征等。

YouTube这里介绍了一个trick,就是每个用户抽取的训练样本数量是相等的,这样做主要是为了防止活跃用户主导整个模型。 这是一个非常好的trick,大家可以借鉴。

此外还有个非常非常重要的点,大家可以思考下:当我们在做精排模型时,如果训练样本全都是这个模型曝光出去的item会不会有问题?

答案是显而易见的,这会导致精排模型『自嗨』也就是自我学习,它在排序的时候会非常倾向于把自己之前排出去过的再次排出去,没见过的新内容露出的可能性非常小。由此又涉及到另一个主题EE,即Explore&Expliot。YouTube这篇论文也提到了这个问题,原话如下:

Training examples are generated from all YouTube watches (even those embedded on other sites) rather than just watches on the recommendations we produce. Otherwise, it would be very difficult for new content to surface and the recom- mender would be overly biased towards exploitation.


1.3 高效的训练多分类模型

YouTube这里的类别数量达到百万的级别,采用softmax来训练显然效率很低。至于效率为什么低,似乎这个话题又回到了谷歌另一篇旷世之作word2vec论文里了,这里简单说一下,因为softmax的分母,每一次都要对语料库中所有的item计算一次。因此,word2vec里提出了两种解决办法:负采样(negative sample)和分层的softmax(hierarchical softmax)。YouTube这里并没有创新什么方法,也是在自己的场景下通过实验比较了下两种方法,最终选了一个效果比较好的方法:负采样。 提到负采样就不得不提NCE(Noise-Contrastive Estimation,噪声对比估计),负采样为NCE的一个变种,NCE通过较大化正样本的概率,同时最小化负样本的概率来优化目标函数,也就是在训练每个样本时, 负采样只挑选DNN的部分权重做小范围更新,举个例子:假设我们的视频语料库大小为1000个,一条训练样本为{x=A, y=B},即输入特征A,期望的label为B,即期望B对应的那个神经元为1(最后softmax层),其余的999个神经元都应该输出0,也就是视频语料库中除了B之外的999个视频都称之为negative word,negative sample的做法是随机选择一小部分比如10个negative word来更新对应的权重参数。

1.4 YouTubeDNN召回的模型架构

YouTubeDNN_recall

图1. YouTubeDNN召回模型架构

这里自底向上的看一下整体模型结构:

1.4.1 特征

这里特征大的方面就两类:类别特征和连续值特征。具体主要包含用户历史观看的视频序列,用户搜索的query切词,以及用户DMP特征。对于序列特征,比如用户历史观看的视频,分别对每个视频做完embedding后直接做了个average pooling,当然现在回过头的话你还可以做各种attention。

YouTube这里有两个trick:

  1. 简单的类别特征(比如年龄等二值的)以及连续值特征,直接输入,并且做了normalization压缩到[0,1]范围内,也就意味着压缩到同一量纲。
  2. 从模型结构图能够看出连续值特征还做了 x 2 x^2 x2等非线性转换,实验结果表明对连续值特征做非线性转换有0.2%的性能提升。

特殊特征Example Age: 这是一个非常巧妙的特征,也完全是YouTube工程师基于对自己场景深刻理解所设计的一个特征,设计这个特征的出发点是:YouTube工程师观察到YouTube平台上的用户比较喜欢新内容。关于这个example age到底怎么计算这个细节论文并没有交代的很清楚,我个人的理解加上参考了一些资料后, 认为是用当前训练时间减去label(视频item,也就是点击的那个item)的点击时间。 更详细的说,我们一般原始日志都是item级别的,即曝光的item,一条原始日志由<item信息,用户信息,上下文信息,是否点击>组成,我们在根据原始样本抽取特征生成训练样本时,这时候如果直接产出Example Age,其实就是用抽取时间减去label item的点击时间,当然也可以在训练时再产出这个特征,具体哪个方法还要看具体的效果。有个点就是在线上预估时,直接把这个特征置为0,用于确保预测时处在训练的最后一刻。

1.4.3 网络结构

虽然是一个普通的DNN,但有一个细节非常值得探讨,先来上图。
YouTubeDNN_recall_softmax

图2. YouTubeDNN召回模型用户向量和视频向量

这里面涉及两个细节:

  1. 用户向量即 user vector u u u 是怎么生成的?
  2. 视频向量即 video vector v j v_j vj是怎么生成的?

目前很多很多博客文章都没有讲清楚视频向量(video vector v j v_j vj)是怎么生成的,这是一个非常重要的细节点。基于讲清楚的需要,我会重新画个图,如下图所示。
youtubeDNN_recall_detail

图3. YouTubeDNN召回模型用户向量和视频向量详细版

先回答一个问题:用户向量即 user vector u u u 是怎么生成的?
这个问题相对简单些,根据论文中的描述就是为最后一层隐藏层的输出,用图3作为例子,则用户向量为 a [ l ] = [ a 1 [ l ] , a 2 [ l ] , a 3 [ l ] ] a^{[l]} = [a^{[l]}_1, a^{[l]}_2, a^{[l]}_3] a[l]=[a1[l],a2[l],a3[l]],因此这里的用户向量为3维向量。

⭐再来回答第二个问题:视频向量即 video vector v j v_j vj是怎么生成的?
非常多的博客对这个问题一带而过,不知道是他们不屑讲解,还是他们也没有搞懂。最后一层隐藏层 a [ l ] a^{[l]} a[l]与softmax层 a [ l + 1 ] a^{[l+1]} a[l+1]之间通过参数 w [ l + 1 ] w^{[l+1]} w[l+1]来转换,如下公式所示( σ \sigma σ为softmax函数):
a [ l + 1 ] = σ ( w [ l + 1 ] a [ l ] + b [ l + 1 ] ) = σ ( [ w 10 [ l + 1 ] w 11 [ l + 1 ] w 12 [ l + 1 ] w 20 [ l + 1 ] w 21 [ l + 1 ] w 22 [ l + 1 ] w 30 [ l + 1 ] w 31 [ l + 1 ] w 32 [ l + 1 ] w 40 [ l + 1 ] w 41 [ l + 1 ] w 42 [ l + 1 ] w 50 [ l + 1 ] w 51 [ l + 1 ] w 52 [ l + 1 ] ] ⋅ [ a 1 [ l ] a 2 [ l ] a 3 [ l ] ] + [ b 1 [ l ] b 2 [ l ] b 3 [ l ] ] ) (1) \begin{aligned} a^{[l+1]} &= \sigma(w^{[l+1]}a^{[l]} + b^{[l+1]})\\ &= \sigma(\begin{bmatrix} w^{[l+1]}_{10}& w^{[l+1]}_{11}& w^{[l+1]}_{12} \\ w^{[l+1]}_{20}& w^{[l+1]}_{21}& w^{[l+1]}_{22} \\ w^{[l+1]}_{30}& w^{[l+1]}_{31}& w^{[l+1]}_{32} \\ w^{[l+1]}_{40}& w^{[l+1]}_{41}& w^{[l+1]}_{42} \\ w^{[l+1]}_{50}& w^{[l+1]}_{51}& w^{[l+1]}_{52} \\ \end{bmatrix} \cdot \begin{bmatrix} a^{[l]}_1\\ a^{[l]}_2 \\ a^{[l]}_3 \\ \end{bmatrix} + \begin{bmatrix} b^{[l]}_1\\ b^{[l]}_2 \\ b^{[l]}_3 \\ \end{bmatrix} ) \end{aligned} \tag{1} a[l+1]=σ(w[l+1]a[l]+b[l+1])=σ(w10[l+1]w20[l+1]w30[l+1]w40[l+1]w50[l+1]w11[l+1]w21[l+1]w31[l+1]w41[l+1]w51[l+1]w12[l+1]w22[l+1]w32[l+1]w42[l+1]w52[l+1]a1[l]a2[l]a3[l]+b1[l]b2[l]b3[l])(1)

根据图3的示意图,假设我们的视频库有5个视频,最后一层softmax会输出类别是个每个视频的概率。公式1中的 W W W矩阵参数即为视频向量,每行为一个视频向量,维度为3。比如第一行的向量 [ w 10 [ l + 1 ] , w 11 [ l + 1 ] , w 12 [ l + 1 ] ] [w^{[l+1]}_{10}, w^{[l+1]}_{11}, w^{[l+1]}_{12}] [w10[l+1],w11[l+1],w12[l+1]]即为视频id为1的向量。

这也是为什么视频向量可以离线产出,建好ANN索引库,用户向量根据模型实时生成,再去ANN库里根据内积检索topK个视频召回。因为视频向量和用户向量在同一个向量空间且维度相同。

1.5 YouTubeDNN召回在线

YouTubeDNN在线召回的架构与DSSM非常类似,先离线产出item向量,存到ANN索引库里,在线的时候,用户向量通过模型实时生成,再去ANN库里根据内积召回topK个item。这样做的好处非常明显:

  1. item向量离线生成,节省了在线servering的耗时
  2. 因为用户行为时刻变化,用户向量实时生成可以捕捉到最新的用户表达。

关于YouTubeDNN的召回就介绍到这里,下面开始介绍YouTubeDNN的排序模型。

二、YouTubeDNN排序

推荐领域,排序模型目前已经迭代了非常多,因此目前应该没有公司还在用YouTubeDNN的rank模型,因此这一块的重要性不如召回。

2.1 特征工程

这一块也算是YouTubeDNN的良心了,分享了一些对模型性能影响比较大的特征,虽然每个场景都不一样,但可借鉴下。总的来说,YouTubeDNN精排模型特征包含两大类:类别特征和连续值特征。比较重要的一些特征包括:

  1. 用户历史与item交互的一些特征,比如点击统计量
  2. 召回通道号及召回时得分这两个特征

另外就是多值特征embedding直接做了average pooling,这里参考DIN实际上可以做个attention。另外就是不同特征中涉及的同一个item的embedding是共享的,比如曝光的video列表,观看的video列表,这两个特征交集的video的embedding是共享的。

另外还有一些trick:

  1. 连续值normalization,YouTube发现对连续值特征做normalization非常有利于DNN的收敛,原话为:We found that proper normalization of continuous features was critical for convergence.
  2. 连续值特征的非线性变换,比如 x 2 x^2 x2 l o g x logx logx x \sqrt{x} x 等,这种变换对于提高模型准性非常有用。
  3. 做视频的embedding时,对于长尾视频,直接把其embedding用0来代替。实际上,目前在工业界这种做法不多了,通常的做法是把长尾的特征直接干掉。也有一种做法,就是把长尾特征分个类,相当于做了个聚合,直接用聚合后的id代替。
2.2 优化目标

召回模块建模为一个多分类问题,优化目标是next video。而排序时,优化目标则是expected watch time,即视频期望观看时长。看到这里大家可能第一反应是:既然要优化期望观看时长,那为什么不搞个回归模型,而还要搞个分类呢?这个问题我也不知道,如果有懂得大佬可以评论区留言。

既然是二分类,首先正负样本依然是曝光已点击的视频,负样本为曝光未点击的样本,那么如何和expected watch time这个连续值结合在一起。这里YouTubeDNN的做法是把正样本的观看时间作为权重,相当于给正样本做了加权。这个权重会直接作用到损失函数中,也就是weighted cross entropy。例如,正常的二分类交叉熵函数如下所示:
L ( y , y ^ ) = − 1 m ∑ i [ y i log ⁡ y i ^ + ( 1 − y i ) log ⁡ ( 1 − y i ^ ) ] (2) L(y,\hat{y}) = -\frac{1}{m}\sum_{i}[y_i\log\hat{y_i} + (1-y_i)\log{(1-\hat{y_i})}] \tag{2} L(y,y^)=m1i[yilogyi^+(1yi)log(1yi^)](2)
假设对正样本给个权重 w w w,则公式(2)变为:
L ( y , y ^ ) = − 1 m ∑ i [ w ∗ y i log ⁡ y i ^ + ( 1 − y i ) log ⁡ ( 1 − y i ^ ) ] (3) L(y,\hat{y}) = -\frac{1}{m}\sum_{i}[w*y_i\log\hat{y_i} + (1-y_i)\log{(1-\hat{y_i})}] \tag{3} L(y,y^)=m1i[wyilogyi^+(1yi)log(1yi^)](3)
上面的 w w w即为正样本的权重,也就是点击视频的观看时长。

最后推荐两篇关于YouTubeDNN比较好的博客,尤其是下面的评论,聚合了各路大神的真知灼见:

  1. 重读Youtube深度学习推荐系统论文,字字珠玑,惊为神文
  2. YouTube深度学习推荐系统的十大工程问题



参考文献

[1]: Deep Neural Networks for YouTube Recommendations
[2]: 重读Youtube深度学习推荐系统论文,字字珠玑,惊为神文
[3]: YouTube深度学习推荐系统的十大工程问题

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值