主要是按照以下3篇介绍+评论的脉络来整理(讲的真的超级好!),再加上我自己在实际运用过程中产生的问题。其实模型大概内容都能看懂。有困扰的地方主要在于user embedding和video embedding是如何生成的?以及本文将推荐问题转为多分类问题,那么这个多分类指的是什么? train和serve的不同之处?

  • 重读Youtube深度学习推荐系统论文,字字珠玑,惊为神文 - 王喆的文章 - 知乎
  • YouTube深度学习推荐系统的十大工程问题 - 王喆的文章 - 知乎
  • 揭开YouTube深度推荐系统模型Serving之谜 - 王喆的文章 - 知乎
  • 文中把推荐问题转换成多分类问题,在next watch的场景下,每一个备选video都会是一个分类,因此总共的分类有数百万之巨,这在使用softmax训练时无疑是低效的,这个问题Youtube是如何解决的?

这个问题原文的回答是这样的

We rely on a technique to sample negative classes from the background distribution ("candidate sampling") and then correct for this sampling via importance weighting.

简单说就是进行了负采样(negative sampling)并用 importance weighting 的方法对采样进行calibration(校准)。文中同样介绍了一种替代方法,hierarchical softmax,但并没有取得更好的效果。当然关于采样的具体技术细节以及优劣可能再开一篇文章都讲不完,感兴趣的同学可以参考tensorflow中的介绍(https://www.tensorflow.org/extras/candidate_sampling.pdf)以及NLP领域的经典论文https://link.zhihu.com/?target=http%3A//www.aclweb.org/anthology/P15-1001

  • 这个user vector和video vector是怎么生成的?

(另外的,这里embedded video watches是一个一开始就随机按照分布初始化的矩阵,不是从item2vec里取的。)

candidate generation model, video vector是如何生成的?(主要答案在参考的第二篇中的评论)

看这里的时候,建议和我一样的小白可以画一下word2vec的图,方便理解。具体细节可以看这里【深度学习】word2vec(上)

总结一下,如下word2vec示意图

user_embedding:对应上图的hidden layer;(user_emb到底是网络的最后一层呢?还是网络隐层呢?是隐层哦)

video_embedding:对应上图的 W_2 ;

@做最闲的咸鱼

这里说的softmax层是 dense + softmax 激活函数,假设最后一个hidden layer维度是100代表user embedding,输出节点维度200w表示videos,全连接权重维度就是[100,200w],而hidden layer与每一个输出节点的权重维度就是[100,1],这就是一个video对应embedding,计算一个video的概率时是u*v,即两个100维向量做内积,是可以在一个空间的。

u是[1*100],v是[100*1]

@老昶信

user vector和video vector的问题,这个DNN输入的特征是<user, context>类的特征,即根据用户每次刷新的状态去输入到网络中得到的最后一层的向量作为user vector,可以做到实时反馈,每次最新的浏览点击都能反馈到输入层进而得到不同的user vector。

而video vector则是 softmax 中 video 与最后一层的w作为这个video的vector,最终通过user_vec与item_vec的内积最大索引就能快速得到结果。在这个线上实时反馈工程上去之前,也可以直接拿video vector做i2i,效果也是很棒的。

@科学之友

其中 class probability里的class指的是所有的video,不考虑hash降规模的话每个video有一个id在 train的阶段把用户观看历史,用户人口统计学特征等编码表示出 user vector,(注意这里已经到了隐层->输出层部分了!!!)接着 user vector 乘以一个矩阵 W(这个矩阵其实就是各个 video 的embedding vector矩阵,它的大小必然是video_size*embedding_dim,然后矩阵里的每一行都对应一个video_id,也就是那个video vector),最后得到 class probability (softmax的结果)

注意以上的矩阵 W 是训练阶段得到的,在serving阶段直接取用即可,就和word2vec里预训练出来的词向量矩阵,到时候根据id去取矩阵的某一行就行啦。

不过在word2vec里词向量一般是取的输入层到隐层层的权重;在yotube这个模型中,video是取的最后一个隐层到softmax分类输出层的权重。

@杨旭东

负采样通过tf.nn.nce_loss函数来实现,这个函数有两个重要的参数:nce_weights和nce_biases,也就是你说的softmax的权重,也就是video的embedding。具体地,

nce_weights = tf.Variable(tf.truncated_normal([params['n_classes'],                     params['last_hidden_units']],stddev=1.0/math.sqrt(params['last_hidden_units'])),name='nce_weights')    nce_biases = tf.Variable(tf.zeros([params['n_classes']]), name='nce_biases')loss = tf.reduce_mean(tf.nn.nce_loss(weights=nce_weights,biases=nce_biases,labels=labels,inputs=net,num_sampled=params['num_sampled'],num_classes=params['n_classes'],num_true=1,remove_accidental_hits=True,partition_strategy='div',name='match_model_nce_loss'))

这里的最后一个 hidden 层和 softmax 层组成的结构与 word2vec 一模一样。
唯一的区别是 word2vec 用输入层与 hidden 层之间的权重作为 word embedding,没用 hidden 层与输出层的权重;而这里用了 hidden 层与输出层的权重作为 video embedding,用 hidden 层作为 user embedding。

@龙赛罗

线上使用时候,user embedding实时生成,video embedding离线训练好之后推到线上,使用类LSH方法进行匹配(比如使用现成工具faiss)

这里我想知道的是!word2vec结构导致在最后一个relu前还是softmax前?

def YoutubeDNN(user_feature_columns, item_feature_columns, num_sampled=5,user_dnn_hidden_units=(64, 32),dnn_activation='relu', dnn_use_bn=False,l2_reg_dnn=0, l2_reg_embedding=1e-6, dnn_dropout=0, output_activation='linear', seed=1024, ):"""Instantiates the YoutubeDNN Model architecture.:param user_feature_columns: An iterable containing user's features used by  the model.:param item_feature_columns: An iterable containing item's features used by  the model.:param num_sampled: int, the number of classes to randomly sample per batch.:param user_dnn_hidden_units: list,list of positive integer or empty list, the layer number and units in each layer of user tower:param dnn_activation: Activation function to use in deep net:param dnn_use_bn: bool. Whether use BatchNormalization before activation or not in deep net:param l2_reg_dnn: float. L2 regularizer strength applied to DNN:param l2_reg_embedding: float. L2 regularizer strength applied to embedding vector:param dnn_dropout: float in [0,1), the probability we will drop out a given DNN coordinate.:param seed: integer ,to use as random seed.:param output_activation: Activation function to use in output layer:return: A Keras model instance."""if len(item_feature_columns) > 1:raise ValueError("Now YoutubeNN only support 1 item feature like item_id")item_feature_name = item_feature_columns[0].nameitem_vocabulary_size = item_feature_columns[0].vocabulary_size# 为稀疏特征创建对应的Embedding字典embedding_matrix_dict = create_embedding_matrix(user_feature_columns + item_feature_columns, l2_reg_embedding,seed=seed)# 获得用户输入特征user_features = build_input_features(user_feature_columns)user_inputs_list = list(user_features.values())user_sparse_embedding_list, user_dense_value_list = input_from_feature_columns(user_features, user_feature_columns,l2_reg_embedding, seed=seed,embedding_matrix_dict=embedding_matrix_dict)user_dnn_input = combined_dnn_input(user_sparse_embedding_list, user_dense_value_list)item_features = build_input_features(item_feature_columns)item_inputs_list = list(item_features.values())user_dnn_out = DNN(user_dnn_hidden_units, dnn_activation, l2_reg_dnn, dnn_dropout,dnn_use_bn, output_activation=output_activation, seed=seed)(user_dnn_input)item_index = EmbeddingIndex(list(range(item_vocabulary_size)))(item_features[item_feature_name])item_embedding_matrix = embedding_matrix_dict[item_feature_name]#获得每一个item的Embedding向量item_embedding_weight = NoMask()(item_embedding_matrix(item_index))pooling_item_embedding_weight = PoolingLayer()([item_embedding_weight])output = SampledSoftmaxLayer(num_sampled=num_sampled)([pooling_item_embedding_weight, user_dnn_out, item_features[item_feature_name]])model = Model(inputs=user_inputs_list + item_inputs_list, outputs=output)# 设置属性接口,调用对应的数据model.__setattr__("user_input", user_inputs_list)model.__setattr__("user_embedding", user_dnn_out)model.__setattr__("item_input", item_inputs_list)model.__setattr__("item_embedding",get_item_embedding(pooling_item_embedding_weight, item_features[item_feature_name]))return model
  • 在确定优化目标的时候,Youtube为什么不采用经典的CTR,或者播放率(Play Rate),而是采用了每次曝光预期播放时间(expected watch time per impression)作为优化目标?

这个问题从模型角度出发,是因为 watch time更能反应用户的真实兴趣,从商业模型角度出发,因为watch time越长,YouTube获得的广告收益越多。而且增加用户的watch time也更符合一个视频网站的长期利益和用户粘性。

  • Youtube的用户对新视频有偏好,那么在模型构建的过程中如何引入这个feature?
  • 在对训练集的预处理过程中,Youtube没有采用原始的用户日志,而是对每个用户提取等数量的训练样本,这是为什么?
  • Youtube为什么不采取类似RNN的Sequence model,而是完全摒弃了用户观看历史的时序特征,把用户最近的浏览历史等同看待,这不会损失有效信息吗?
  • 在处理测试集的时候,Youtube为什么不采用经典的随机留一法(random holdout),而是一定要把用户最近的一次观看行为作为测试集?

只留最后一次观看行为做测试集主要是为了避免引入future information,产生与事实不符的数据穿越。

  • 在进行video embedding的时候,为什么要直接把大量长尾的video直接用0向量代替?
  • 针对某些特征,比如 previous impressions,为什么要进行开方和平方处理后,当作三个特征输入模型?

这是很简单有效的工程经验,引入了特征的非线性

  • 在candidate generation model的serving过程中,Youtube为什么不直接采用训练时的model进行预测,而是采用了一种最近邻搜索的方法?

这个问题的答案是一个经典的工程和学术做trade-off的结果,在model serving过程中对几百万个候选集逐一跑一遍模型的时间开销显然太大了,因此在通过candidate generation model得到user 和 video的embedding之后,通过最近邻搜索的方法的效率高很多。我们甚至不用把任何model inference的过程搬上服务器,只需要把user embedding和video embedding存到redis或者内存中就好了

评价指标

推荐系统Top-K问题(或者HR@K, HR为hit ratio),需要划分训练集和测试集吗? - Estero的回答 - 知乎
比如我曾经购买了30个商品,如果全部作为训练集,那么当推荐系统给我推荐新商品时,我就没法判断是否推荐准确了。
反之,将其中20个商品作为训练集来训练推荐模型,然后基于top-10来推荐。此时,如果推荐的10个商品,和我剩余的那10个商品(去掉训练集)相同,那hit ratio就是100%;如果只包括了10个商品中的3个,那就是30%,以此类推。

推荐系统遇上深度学习(十六)--详解推荐系统中的常用评测指标 - 梁勇的文章 - 知乎

在top-K推荐中,HR是一种常用的衡量召回率的指标,其计算公式如下:

分母是所有的测试集合,分子式每个用户top-K推荐列表中属于测试集合的个数的总和。举个简单的例子,三个用户在测试集中的商品个数分别是10,12,8,模型得到的top-10推荐列表中,分别有6个,5个,4个在测试集中,那么此时HR的值是 (6+5+4)/(10+12+8) = 0.5。

def hit(gt_items, pred_items):count = 0for item in pred_items:if item in gt_items:count += 1return count

暂时性小结

youtubednn召回是u2i的召回

之前学习din的时候,是将排序问题看做是ctr预估问题,即这个item点或者不点击。

这里youtubednn召回的问题,是将问题转为下一个视频,将会看哪一个视频,转为了多分类问题。

线上使用时候,user embedding实时生成,video embedding离线训练好之后推到线上,使用类LSH方法进行匹配(比如使用现成工具faiss)


推荐系统遇上深度学习(三十四)--YouTube深度学习推荐系统

https://github.com/onozeam/YoutubeDNN (github代码)

YouTube DNN论文精读 - 旷野孤灯的文章 - 知乎(中文翻译)

https://blog.csdn.net/weixin_35154281/article/details/112493756 (code)

关于Deep Neural Networks for YouTube Recommendations的一些思考和实现

【推荐系统】YoutubeDNN召回相关推荐

  1. 【datawhale202206】pyTorch推荐系统:召回模型 DSSMYoutubeDNN

    小结 本次所涉及的模型用于推荐系统中的召回环节,该环节主要是一个embedding和筛选,本次所涉及的模型主要用于embedding过程. DSSM双塔模型是指,user和item的embedding ...

  2. 推荐系统遇上深度学习(三十九)-推荐系统中召回策略演进!

    推荐系统中的核心是从海量的商品库挑选合适商品最终展示给用户.由于商品库数量巨大,因此常见的推荐系统一般分为两个阶段,即召回阶段和排序阶段.召回阶段主要是从全量的商品库中得到用户可能感兴趣的一小部分候选 ...

  3. 对比学习视角:重新审视推荐系统的召回粗排模型

    省时查报告-专业.及时.全面的行研报告库 省时查方案-专业.及时.全面的营销策划方案库 对比学习在快手推荐系统中的应用实践 机器学习在B站推荐系统中的应用实践 小红书推荐系统中台应用实践 微信视频号实 ...

  4. 【推荐系统】召回模型线下评价指标

    目录 Hit Rate(HR) Precision Recall NDCG 常用的评价标准: 第一类是线上评测,比如通过点击率.网站流量.A/B test等判断.这类评价标准在这里就不细说了,因为它们 ...

  5. 一文看懂推荐系统:召回07:双塔模型——正负样本的选择,召回的目的是区分感兴趣和不感兴趣的,精排是区分感兴趣和非常感兴趣的

    一文看懂推荐系统:召回07:双塔模型--正负样本的选择,召回的目的是区分感兴趣和不感兴趣的,精排是区分感兴趣和非常感兴趣的 提示:最近系统性地学习推荐系统的课程.我们以小红书的场景为例,讲工业界的推荐 ...

  6. 一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度

    一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度 提示:最近系统性地学习推荐系统的课程.我们以小红书的场景为例,讲工业界的推荐系统. 我只讲工业界实际有用的技术. ...

  7. 最全推荐系统Embedding召回算法总结

    最近特别忙,工作日几乎没什么时间学习.平时攒了一堆推荐相关的文章,趁周末整体学习了一下.主要是参考了网上的一篇技术文章(迄今为止我看到的比较好的推荐Embedding总结)以及我自己的一些理解. ​E ...

  8. 一文看懂推荐系统:召回02:Swing 模型,和itemCF很相似,区别在于计算相似度的方法不一样

    一文看懂推荐系统:召回02:Swing 模型,和itemCF很相似,区别在于计算相似度的方法不一样 提示:最近系统性地学习推荐系统的课程.我们以小红书的场景为例,讲工业界的推荐系统. 我只讲工业界实际 ...

  9. 【推荐系统】推荐系统主流召回方法综述

    " 本文主要梳理了近年来推荐系统中的主流召回方法,包括传统召回方法,基于表示学习的方法(Youtube DNN,DMF,DSSM,item2vec,graph embedding,MIND, ...

最新文章

  1. R语言ggplot2可视化在散点图中的每个点上绘制两个错误条:常见的是垂直错误条,它对应于Y值点上的错误(error bar),添加与X轴(水平)相关的错误条(error bar)
  2. 【PC工具】常用USB转串口芯片CH340G,驱动安装有可能遇到的问题及解决办法
  3. wxWidgets:wxAnimationCtrl类用法
  4. 2021高值人才职业发展洞察:连接、信任与赋能
  5. linux-2.6.
  6. oppoJava面试!java开发视频聊天
  7. 冲刺第五天 1.6 SUN
  8. 喜大普奔,微软Microsoft JDBC Driver For SQL Server已发布到maven中央仓库
  9. Thingsboard 3.1.0 - 源码编译
  10. Perl脚本使用小总结
  11. sql server 2000 打了sp4补丁包仍不能监听1433端口问题的解决
  12. png图片怎么转换成jpg?
  13. jzoj4245. 【五校联考6day2】er (B组——Day11)
  14. 近期优秀技术讲座资料和内容推荐
  15. 菲兹定律(Fitts's law)
  16. 荣耀平板5鸿蒙降级安卓并刷入原生Android12系统——麒麟659,4+64G,10英寸wifi版本
  17. js数组遍历的十种方法
  18. 微型计算机按照结构划分共分为几种,2016计算机一级《MS Office》基础习题与解析...
  19. wma音频怎么转换mp3格式
  20. 数据结构学习(C++)——队列应用(事件驱动模拟)

热门文章

  1. 相伴一生的IP和MAC
  2. 美白--中药配方(转)
  3. 2021-01-07.实训笔记
  4. poj 2446:Chessboard
  5. S2-MLP: Spatial-Shift MLP Architecture for Vision
  6. 万全T168服务器显示叹号黄灯,转速表上有个黄灯叹号
  7. Spring Boot 实践折腾记(四):配置即使用,常用配置
  8. JS--JavaScript节点插入、删除、替换、克隆(appendChild、cloneNode、insertBefore、normalize、removeChild、replaceChild)
  9. bluehost 盗版_Bluehost评论
  10. AI之循环神经网络进阶