精华内容
下载资源
问答
  • mmoe
    2020-04-20 16:27:11

    Time:2018

    Author:Jiaqi Ma, Zhe Zhao, Xinyang Yi, Jilin Chen, Lichan Hong, Ed H. Chi

     

    Abstract

    MMoE从数据中学习目标之间的关系。MMoE是MoE模型的延伸,expert submodels对所有的目标是共享的,再使用gating network来优化单个目标。

    在目标之间的相关性较低的情况下,MMoE的效果也更好,并且,在多次训练中,MMoE都收敛到更好的loss,这说明了,在训练non-convex DNN时,模块化(modulation)和gating机制都能提升训练。

     

    Model Architecture

    MoE

    MMoE

    task k的输出:

    gating network:输入的线性变换+softmax,W_{gk} \in R^{n*d},n是expert个数,d是feature dimension

     

    Reference

    更多相关内容
  • AI上推荐 之 MMOE(多任务yyds)

    千次阅读 热门讨论 2021-10-25 14:26:06
    PS: 本来这篇文章的构想是整理MMOE家族,想借助MMOE总结三篇paper的,第一篇是MMOE本身,第二篇是2019年的MMOE在YoutubeDNN中的应用, 这篇文章的核心点是基于W&D框架设计了一个多任务学习框架, Deep端是MMOE, ...

    1. 写在前面

    这篇文章开始多任务模型的学习,算是把多任务模型这块的坑填一下哈哈。

    随着推荐技术的蓬勃发展,目前越来越多的推荐场景,往往并不是单纯的优化一个指标,比如:

    • 视频推荐领域: 推荐排序任务不仅需要考虑到用户点击率,完播率,也需要考虑到一些满意度指标,例如,对视频是否喜欢,用户观看后对视频的评分;
    • 文章推荐领域: 不仅希望用户点击阅读文章,还希望用户有更多的停留时长,互动、关注。
    • 电商推荐领域: 不仅希望用户更多对商品点击浏览,还希望用户看完商品后进行付费,点击率和转化率

    所以,推荐系统做到后期,往往会朝着多目标学习进行演化,承担更多的业务目标,提高用户粘性。 而多目标排序呢, 大致上有4种解决方案:

    1. 改变样本权重进行多目标优化: 这是一种比较初级的方式。 比如主目标是点击率,分享功能是我们希望提高的功能。 那么点击和分享都是正样本,分享的样本可以设置更高的样本权重。 模型训练在计算梯度更新参数时,梯度要乘以权重,对样本权重大的样本给予更大权重。 通过这种方法,使得原始目标A会受到一定的损失以换取新增加目标B的增长,实现初级的多目标优化。
      • 优点: 模型简单,不需要额外架构支持,没有增加算法复杂度
      • 缺点: 没有对多目标建模,而是将多个目标折算成一个,折算权重不好确定
    2. 多模型分数融合: 这个比较好理解, 之前的整理的模型大多都是只针对于单目标的优化模型,多模型融合的思路,就是用多个模型分别预测每个目标,最后的预测分数加权融合, 比如
      s c o r e = C T R ∗ ( a l p h a + C V R ) ∗ ( b e t a + p r i c e ) ∗ s t a y a ∗ c a r t b ∗ c o l l e c t c ∗ r u l e ∗ w e i g h t . . . score = CTR * (alpha+CVR) * (beta+price) * stay^a * cart^b*collect^c*rule*weight... score=CTR(alpha+CVR)(beta+price)stayacartbcollectcruleweight...
      • 优点: 模型简单
      • 缺点: 线上服务时间开销大,部署困难,需要多个模型预测结果组合,并且不同目标难以量化评估重要性,如果样本部分特征稀疏, 有的模型不好单独学习,模型融合的这几个超参数也不好确定
    3. 排序学习: 通过预测两两物品之间相对顺序或物品序列之间顺序解决多目标学习的问题。比如,视频推荐为例,用户观看很长的 i i i视频,点击了 j j j视频,那么觉得观看比点击重要,假设 u u u代表用户的偏好,则 u i > u j u_i >u_j ui>uj。 有了相对顺序,就可以使用排序学习的方式,融合多个目标,不需要序列多个模型
      1. 优点: 优化目标顺序,不需要设计复杂超参,本身是单个模型的多个目标,线上服务压力小
      2. 缺点: 相对顺序不好构造,样本数量增大,训练速度慢,样本不平衡会被放大,比如有的用户有10次点击,有的只有1次点击,10次的会有更多机会训练
    4. 多任务学习: 上面整理铺垫那么多,就是为了引出这个话题,这个才是目前最常用的技术,多任务学习,可以简单的理解是用一个网络同时完成多个任务的优化, 有很多优势,比如多个任务共享一个模型,占用内存少,计算速度快,并且关联任务还可以通过共享信息,互相补充,提升彼此的表现。 但是呢, 同样也面临很多挑战,比如不同任务究竟如何融合呢? 万一多个目标不怎么相关怎么办? 目标的重要性不同,这个在训练模型的时候如何体现等等。

    多任务学习是我后面学习的重点,也是目前推荐领域火热研究的技术, 近几年也出现了很多非常经典,可学习的paper,接下来的一段时间,就围绕着多任务学习这个话题,学习一些经典paper, 在这里,基于我目前对多任务学习的了解,大致上整理了一个框架图:
    在这里插入图片描述
    这里面的每个点几乎都对应着一篇paper,正好符合"热追"推荐算法模型的整理思路,目前的打算是先把这里面最经典的一些整理了,然后零碎知识点进行补充。

    这篇文章先从MMOE开始整理, 这个模型是2018年谷歌提出的, 虽然有3年多的历史了,现在依然是非常常用的模型范式,所以非常非常重要。MMOE全称是Multi-gate Mixture-of-Experts, 对于多个优化任务,引入了多个专家进行不同的决策和组合,最终完成多目标的预测。解决的是硬共享里面如果多个任务相似性不是很强,底层的embedding学习反而相互影响,最终都学不好的痛点。

    本篇文章稍微简单一点了, 首先是先了解下Hard-parameter sharing以及存在的问题,然后引出MMOE,对理论部分进行整理,最后是参考deepctr简单复现下MMOE,然后在之前的新闻推荐数据集上完成训练和测试。

    PS: 本来这篇文章的构想是整理MMOE家族,想借助MMOE总结三篇paper的,第一篇是MMOE本身,第二篇是2019年的MMOE在YoutubeDNN中的应用, 这篇文章的核心点是基于W&D框架设计了一个多任务学习框架, Deep端是MMOE, Wide端引入一个浅层网络来进行消偏,比如position bias, 这种结构也很常见了,比较偏应用, 第三篇是2020年的一篇是MOSE,多任务混合序列专家模型,就是把MMOE中的专家从DNN换成了LSTM来学习有关序列的相关信息,算是一种结构替换。 但后面由于时间原因, 还是想先整理MMOE吧,因为后两篇算是简单的修改或者直接迁移,掌握了MMOE,后面两个就简单了,然后把后两篇总结的比较好的文章以及原论文放到最后面,如果以后用到了再看。 因为目前要兼顾好几条线,还是先把时间放到最重点的事情上。

    主要内容

    • MMOE? 先简单的了解下多任务里面的Hard-parameter sharing
    • MMOE模型的理论及论文细节
    • MMOE模型的简单复现与多任务预测
    • 小总

    Ok, let’s go!

    2. MMOE? 先简单了解下多任务里面的hard-parameter sharing

    推荐系统中,即使同一个场景,常常也不只有一个业务目标。 在Youtube的视频推荐中,推荐排序任务不仅需要考虑到用户点击率,完播率,也需要考虑到一些满意度指标,例如,对视频是否喜欢,用户观看后对视频的评分;在淘宝的信息流商品推荐中,需要考虑到点击率,也需要考虑转化率;而在一些内容场景中,需要考虑到点击和互动、关注、停留时长等指标。

    模型中,如果采用一个网络同时完成多个任务,就可以把这样的网络模型称为多任务模型, 这种模型能在不同任务之间学习共性以及差异性,能够提高建模的质量以及效率。 常见的多任务模型的设计范式大致可以分为三大类:

    • hard parameter sharing 方法: 这是非常经典的一种方式,底层是共享的隐藏层,学习各个任务的共同模式,上层用一些特定的全连接层学习特定任务模式。

      在这里插入图片描述
      这种方法目前用的也有,比如美团的猜你喜欢,知乎推荐的Ranking等, 这种方法最大的优势是Task越多, 单任务更加不可能过拟合,即可以减少任务之间过拟合的风险。 但是劣势也非常明显,就是底层强制的shared layers难以学习到适用于所有任务的有效表达。 尤其是任务之间存在冲突的时候。MMOE中给出了实验结论,当两个任务相关性没那么好(比如排序中的点击率与互动,点击与停留时长),此时这种结果会遭受训练困境,毕竟所有任务底层用的是同一组参数。

    • soft parameter sharing: 硬的不行,那就来软的,这个范式对应的结果从MOE->MMOE->PLE等。 即底层不是使用共享的一个shared bottom,而是有多个tower, 称为多个专家,然后往往再有一个gating networks在多任务学习时,给不同的tower分配不同的权重,那么这样对于不同的任务,可以允许使用底层不同的专家组合去进行预测,相较于上面所有任务共享底层,这个方式显得更加灵活

    • 任务序列依赖关系建模:这种适合于不同任务之间有一定的序列依赖关系。比如电商场景里面的ctr和cvr,其中cvr这个行为只有在点击之后才会发生。所以这种依赖关系如果能加以利用,可以解决任务预估中的样本选择偏差(SSB)和数据稀疏性(DS)问题

      • 样本选择偏差: 后一阶段的模型基于上一阶段采样后的样本子集训练,但最终在全样本空间进行推理,带来严重泛化性问题
      • 样本稀疏: 后一阶段的模型训练样本远小于前一阶段任务


      ESSM是一种较为通用的任务序列依赖关系建模的方法,除此之外,阿里的DBMTL,ESSM2等工作都属于这一个范式。 这个范式可能后面会进行整理,本篇文章不过多赘述。

    通过上面的描述,能大体上对多任务模型方面的几种常用建模范式有了解,然后也知道了hard parameter sharing存在的一些问题,即不能很好的权衡特定任务的目标与任务之间的冲突关系。
    在这里插入图片描述
    而这也就是MMOE模型提出的一个动机所在了, 那么下面的关键就是MMOE模型是怎么建模任务之间的关系的,又是怎么能使得特定任务与任务关系保持平衡的?

    带着这两个问题,下面看下MMOE的细节。

    3. MMOE模型的理论及论文细节

    MMOE这篇文章并不是很复杂,介绍结构的篇幅并不是很多,前面的篇幅主要是作者采用了一个自己合成的数据集模拟了一个多任务,而这个多任务的好处是能人为控制任务之间的关系,从而去证明了传统的共享模型,会受到任务关系的瓶颈,得出传统的多任务模型对任务之间相关性非常敏感的结论。这里也可以直观感受下结果:


    在这里面可以至少可以看出三点:

    1. 每一种情况下, MMOE模型表现都是最好, OMOE模型次之, 共享bottom的模型最差。这能证明MOE结构的有效性(后面具体介绍)
    2. 随着任务相关性越来越高,OMOE和MMOE的效果越来越接近,这说明OMOE在任务相关性低的时候,会遭受到一些困境, 这证明了多门控网络的有效性
    3. 对所有模型,任务相关性越高,表现越好,因为任务相关性越高,共性模式越大

    上面三种模型结构图如下。

    在这里插入图片描述
    这其实是一个演进的过程,首先hard parameter sharing这个就不用过多描述了, 下面主要是看MOE模型以及MMOE模型。

    3.1 混合专家模型

    我们知道共享的这种模型结构,会遭受任务之间冲突而导致可能无法很好的收敛,从而无法学习到任务之间的共同模式。这个结构也可以看成是多个任务共用了一个专家。

    先抛开任务关系, 我们发现一个专家在多任务学习上的表达能力很有限,于是乎,尝试引入多个专家,这就慢慢的演化出了混合专家模型。 公式表达如下:
    y = ∑ i = 1 n g ( x ) i f i ( x ) y=\sum_{i=1}^{n} g(x)_{i} f_{i}(x) y=i=1ng(x)ifi(x)
    这里的 y y y表示的是多个专家的汇总输出,接下来这个东西要过特定的任务塔去得到特定任务的输出。 这里还加了一个门控网络机制,就是一个注意力网络, 来学习各个专家的重要性权重 ∑ i = 1 n g ( x ) i = 1 \sum_{i=1}^{n} g(x)_{i}=1 i=1ng(x)i=1 f i ( x ) f_i(x) fi(x)就是每个专家的输出, 而 g ( x ) i g(x)_i g(x)i就是每个专家对应的权重。 虽然感觉这个东西,无非就是在单个专家的基础上多引入了几个全连接网络,然后又给这几个全连接网络加权,但是在我看来,这里面至少蕴含了好几个厉害的思路:

    1. 模型集成思想: 这个东西很像bagging的思路,即训练多个模型进行决策,这个决策的有效性显然要比单独一个模型来的靠谱一点,不管是从泛化能力,表达能力,学习能力上,应该都强于一个模型
    2. 注意力思想: 为了增加灵活性, 为不同的模型还学习了重要性权重,这可能考虑到了在学习任务的共性模式上, 不同的模型学习的模式不同,那么聚合的时候,显然不能按照相同的重要度聚合,所以为各个专家学习权重,默认了不同专家的决策地位不一样。这个思想目前不过也非常普遍了。
    3. multi-head机制: 从另一个角度看, 多个专家其实代表了多个不同head, 而不同的head代表了不同的非线性空间,之所以说表达能力增强了,是因为把输入特征映射到了不同的空间中去学习任务之间的共性模式。可以理解成从多个角度去捕捉任务之间的共性特征模式。

    但是,这种机制有没有问题呢? 作者说:

    在这里插入图片描述
    也就是,MOE使用了多个混合专家增加了各种表达能力,但是呢, 一个门控并不是很灵活,因为这所有的任务,最终只能选定一组专家组合,即这个专家组合是在多个任务上综合衡量的结果,并没有针对性了。 如果这些任务都比较相似,那就相当于用这一组专家组合确实可以应对这多个任务,学习到多个相似任务的共性。 但如果任务之间差的很大,这种单门控控制的方式就不行了,因为此时底层的多个专家学习到的特征模式相差可能会很大,毕竟任务不同,而单门控机制选择专家组合的时候,肯定是选择出那些有利于大多数任务的专家, 而对于某些特殊任务,可能学习的一塌糊涂。

    如果不好理解, 可以举个最简单的例子,比如我有A、B、C、D四个Task, A、B任务非常相似, C、D任务非常相似,但这两类任务之间相差很远。 此时用OMOE模型学习的时候, 选择出的专家要么只能很好的处理AB,要么只能很好的处理CD,无法同时兼得。虽然此时底层的专家们,可能有3个已经能很好的学习到AB的共性特征, 有另外2个也能很好的学习到CD的共性特征,但是单门控,可能只能择其中一种组合。毕竟只有一组权重。

    所以,这种方式的缺口很明显,这样,也更能理解为啥提出多门控控制的专家混合模型了。

    3.2 MMOE结构

    Multi-gate Mixture-of-Experts(MMOE)的魅力就在于在OMOE的基础上,对于每个任务都会涉及一个门控网络,这样,对于每个特定的任务,都能有一组对应的专家组合去进行预测。更关键的时候,参数量还不会增加太多。公式如下:

    y k = h k ( f k ( x ) ) , y_{k}=h^{k}\left(f^{k}(x)\right), yk=hk(fk(x)),
    where f k ( x ) = ∑ i = 1 n g k ( x ) i f i ( x ) f^{k}(x)=\sum_{i=1}^{n} g^{k}(x)_{i} f_{i}(x) fk(x)=i=1ngk(x)ifi(x). 这里的 k k k表示任务的个数。 每个门控网络是一个注意力网络:
    g k ( x ) = softmax ⁡ ( W g k x ) g^{k}(x)=\operatorname{softmax}\left(W_{g k} x\right) gk(x)=softmax(Wgkx)
    W g k ∈ R n × d W_{g k} \in \mathbb{R}^{n \times d} WgkRn×d表示权重矩阵, n n n是专家的个数, d d d是特征的维度。

    上面的公式这里不用过多解释。

    这个改造看似很简单,只是在OMOE上额外多加了几个门控网络,但是却起到了杠杆般的效果,我这里分享下我的理解。

    • 首先,就刚才分析的OMOE的问题,在专家组合选取上单门控会产生限制,此时如果多个任务产生了冲突,这种结构就无法进行很好的权衡。 而MMOE就不一样了。MMOE是针对每个任务都单独有个门控选择专家组合,那么即使任务冲突了,也能根据不同的门控进行调整,选择出对当前任务有帮助的专家组合。所以,我觉得单门控做到了针对所有任务在专家选择上的解耦,而多门控做到了针对各个任务在专家组合选择上的解耦
    • 多门控机制能够建模任务之间的关系了。如果各个任务都冲突, 那么此时有多门控的帮助, 此时让每个任务独享一个专家,如果任务之间能聚成几个相似的类,那么这几类之间应该对应的不同的专家组合,那么门控机制也可以选择出来。如果所有任务都相似,那这几个门控网络学习到的权重也会相似,所以这种机制把任务的无关,部分相关和全相关进行了一种统一。
    • 灵活的参数共享, 这个我们可以和hard模式或者是针对每个任务单独建模的模型对比,对于hard模式,所有任务共享底层参数,而每个任务单独建模,是所有任务单独有一套参数,算是共享和不共享的两个极端,对于都共享的极端,害怕任务冲突,而对于一点都不共享的极端,无法利用迁移学习的优势,模型之间没法互享信息,互为补充,容易遭受过拟合的困境,另外还会增加计算量和参数量。 而MMOE处于两者的中间,既兼顾了如果有相似任务,那就参数共享,模式共享,互为补充,如果没有相似任务,那就独立学习,互不影响。 又把这两种极端给进行了统一。
    • 训练时能快速收敛,这是因为相似的任务对于特定的专家组合训练都会产生贡献,这样进行一轮epoch,相当于单独任务训练时的多轮epoch。

    所以,在不产生太大的参数开销的同时,能通过这样一个小小的改动,既建模了任务关系,又灵活参数共享,又减少训练时间,是不是很powerful呢?

    这个idea,竟然是在谷歌的一个实习生想到的,如果让我们考虑,是否也能想到呢? 我至少有了下面三点启发:

    1. 所谓大道至简,往往越简单的东西,才会越实用。 所以考虑事情,一定要从简单开始考虑,“如无必要,勿增实体”。
    2. 一定要多带看前人的工作,且不能被某一个特定方向限制住, 跨领域,多思维,再有巨人的肩膀加成,才会看得更远。
    3. 带着怀疑的眼光去看待别人的工作,不能人家说对就是对,一定要思考背后的原因,往背后多看几层,因为每个人就某事得到结论是基于自己的已有认知,也就是每个人的思维都会带有局限性。如果我们看别人工作的时候,能看到后面的这种局限,才能够去想办法去打破局限,获得新的idea

    OK, 到这里就把MMOE的故事整理完了,模型结构本身并不是很复杂呀,非常符合"大道至简"原理,简单且实用, 最青睐这样的文章了。

    那么, 为什么多任务学习为什么是有效的呢? 这里整理一个看到比较不错的答案:

    多任务学习有效的原因是引入了归纳偏置,两个效果:

    • 互相促进: 可以把多任务模型之间的关系看作是互相先验知识,也称为归纳迁移,有了对模型的先验假设,可以更好提升模型的效果。解决数据稀疏性其实本身也是迁移学习的一个特性,多任务学习中也同样会体现
    • 泛化作用:不同模型学到的表征不同,可能A模型学到的是B模型所没有学好的,B模型也有其自身的特点,而这一点很可能A学不好,这样一来模型健壮性更强

    4. MMOE模型的简单复现之多任务预测

    4.1 模型概貌

    这里是MMOE模型的简单复现,参考的deepctr。

    由于MMOE模型不是很复杂,所以这里就可以直接上代码,然后简单解释:

    def MMOE(dnn_feature_columns, num_experts=3, expert_dnn_hidden_units=(256, 128), tower_dnn_hidden_units=(64,),
            gate_dnn_hidden_units=(), l2_reg_embedding=0.00001, l2_reg_dnn=0, dnn_dropout=0, dnn_activation='relu',
            dnn_use_bn=False, task_types=('binary', 'binary'), task_names=('ctr', 'ctcvr')):
        
        num_tasks = len(task_names)
        
        # 构建Input层并将Input层转成列表作为模型的输入
        input_layer_dict = build_input_layers(dnn_feature_columns)
        input_layers = list(input_layer_dict.values())
        
        # 筛选出特征中的sparse和Dense特征, 后面要单独处理
        sparse_feature_columns = list(filter(lambda x: isinstance(x, SparseFeat), dnn_feature_columns))
        dense_feature_columns = list(filter(lambda x: isinstance(x, DenseFeat), dnn_feature_columns))
        
        # 获取Dense Input
        dnn_dense_input = []
        for fc in dense_feature_columns:
            dnn_dense_input.append(input_layer_dict[fc.name])
        
        # 构建embedding字典
        embedding_layer_dict = build_embedding_layers(dnn_feature_columns)
        # 离散的这些特特征embedding之后,然后拼接,然后直接作为全连接层Dense的输入,所以需要进行Flatten
        dnn_sparse_embed_input = concat_embedding_list(sparse_feature_columns, input_layer_dict, embedding_layer_dict, flatten=False)
        
        # 把连续特征和离散特征合并起来
        dnn_input = combined_dnn_input(dnn_sparse_embed_input, dnn_dense_input)
        
        # 建立专家层
        expert_outputs = []
        for i in range(num_experts):
            expert_network = DNN(expert_dnn_hidden_units, dnn_activation, l2_reg_dnn, dnn_dropout, dnn_use_bn, seed=2022, name='expert_'+str(i))(dnn_input)
            expert_outputs.append(expert_network)
        
        expert_concat = Lambda(lambda x: tf.stack(x, axis=1))(expert_outputs)
        
        # 建立多门控机制层
        mmoe_outputs = []
        for i in range(num_tasks):  # num_tasks=num_gates
            # 建立门控层
            gate_input = DNN(gate_dnn_hidden_units, dnn_activation, l2_reg_dnn, dnn_dropout, dnn_use_bn, seed=2022, name='gate_'+task_names[i])(dnn_input)
            gate_out = Dense(num_experts, use_bias=False, activation='softmax', name='gate_softmax_'+task_names[i])(gate_input)
            gate_out = Lambda(lambda x: tf.expand_dims(x, axis=-1))(gate_out)
            
            # gate multiply the expert
            gate_mul_expert = Lambda(lambda x: reduce_sum(x[0] * x[1], axis=1, keep_dims=False), name='gate_mul_expert_'+task_names[i])([expert_concat, gate_out])
            
            mmoe_outputs.append(gate_mul_expert)
        
        # 每个任务独立的tower
        task_outputs = []
        for task_type, task_name, mmoe_out in zip(task_types, task_names, mmoe_outputs):
            # 建立tower
            tower_output = DNN(tower_dnn_hidden_units, dnn_activation, l2_reg_dnn, dnn_dropout, dnn_use_bn, seed=2022, name='tower_'+task_name)(mmoe_out)
            logit = Dense(1, use_bias=False, activation=None)(tower_output)
            output = PredictionLayer(task_type, name=task_name)(logit)
            task_outputs.append(output)
        
        model = Model(inputs=input_layers, outputs=task_outputs)
        return model
    

    这个其实比较简单, 首先是传入封装好的dnn_features_columns, 这个是

    dnn_features_columns = [SparseFeat(feat, feature_max_idx[feat], embedding_dim=4) for feat in sparse_features] \
                             + [DenseFeat(feat, 1) for feat in dense_features]
    

    就是数据集先根据特征类别分成离散型特征和连续型特征,然后通过sparseFeat或者DenseFeat进行封装起来,组成的一个列表。

    传入之后, 首先为这所有的特征列建立Input层,然后选择出离散特征和连续特征来,连续特征直接拼接即可, 而离散特征需要过embedding层得到连续型输入。把这个输入与连续特征拼接起来,就得到了送入专家的输入。

    接下来,建立MMOE的多个专家, 这里的专家直接就是DNN,当然这个可以替换,比如MOSE里面就用了LSTM,这样的搭建模型方式非常灵活,替换起来非常简单。 把输入过多个专家得到的专家的输出,这里放到了列表里面。

    接下来,建立多个门控网络,由于MMOE里面是每个任务会有一个单独的门控进行控制,所以这里的门控网络个数和任务数相同,门控网络也是DNN,接收输入,得到专家个输出作为每个专家的权重,把每个专家的输出加权组合得到门控网络最终的输出,放到列表中,这里的列表长度和task_num对应。

    接下来, 为每个任务建立tower,学习特定的feature信息。同样也是DNN,接收的输入是上面列表的输出,每个任务的门控输出输入到各自的tower里面,得到最终的输出即可。 最终的输出也是个列表,对应的每个任务最终的网络输出值。

    这就是整个MMOE网络的搭建逻辑。

    4.2 数据集与预处理

    这里使用的数据还是我之前准备好的新闻推荐数据集,之前说争取所有的网络统一用这一个数据集, 当然对于多任务这里,采用的时候,由于是有多个目标,我这里除了预测click之外,还预测用户的停留时长duration。 所以拿这两个作为目标,其余作为特征:

    在这里插入图片描述
    接下来,做了简单的数据预处理,离散特征labelEncoder以及连续特征归一化等,但这里的img_num特征有异常值,需要事先处理。

    # 简单数据预处理
    sparse_features = [
        'user_id', 'article_id', 'net_status', 'exop_position', 'device', 'city', 'age', 'gender', 'cat_1'
    ]
    dense_features = [
        'img_num'
    ]
    
    # 填充缺失值
    data_new[sparse_features] = data_new[sparse_features].fillna('-1')
    data_new[dense_features] = data_new[dense_features].fillna(0)
    
    # 归一化
    mms = MinMaxScaler(feature_range=(0, 1))
    data_new[dense_features] = mms.fit_transform(data_new[dense_features])
    
    feature_max_idx = {}
    for feat in sparse_features:
        lbe = LabelEncoder()
        data_new[feat] = lbe.fit_transform(data_new[feat])
        feature_max_idx[feat] = data_new[feat].max() + 1
    

    接下来就是按照曝光时间划分成训练集和测试集,这里和召回模型的划分方式不一样了,那里按照用户分组,保留最后一次点击作为测试,而这里是直接用曝光时间划分。 召回和排序里面数据集划分还是不同的。

    # 划分数据集  这里按照曝光时间划分
    train_data = data_new[data_new['expo_time'] < '2021-07-06']
    test_data = data_new[data_new['expo_time'] >= '2021-07-06']
    

    接下来封装特征

    dnn_features_columns = [SparseFeat(feat, feature_max_idx[feat], embedding_dim=4) for feat in sparse_features] \
                             + [DenseFeat(feat, 1) for feat in dense_features]
    
    feature_names = get_feature_names(dnn_features_columns)
    
    # AttributeError: 'numpy.dtype[int64]' object has no attribute 'base_dtype' 
    # Keras需要把输入声明为Keras张量,其他的比如numpy张量作为输入不好使
    train_model_input = {name: tf.keras.backend.constant(train_data[name]) for name in feature_names}
    test_model_input = {name: tf.keras.backend.constant(test_data[name]) for name in feature_names}
    

    这里构建模型输入字典的时候,这个字典的值要用tf.keras.backend.constant转换下numpy数组。因为如果不转换,在后面模型训练的时候会报错AttributeError: 'numpy.dtype[int64]' object has no attribute 'base_dtype', 之前的召回模型都没有报,在这里竟然遇到了这个错误,卡了我一会,通过搜索说keras需要把输入声明为Keras张量,numpy张量不好使。 后面的label值也需要用这个转一下就解决了。 Keras张量格式长这样子:

    在这里插入图片描述
    我也不知道是不是版本带来的原因,反正如果遇到这个报错,就把numpy数组转成keras张量即可。

    这样数据就处理完了。

    4.3 模型训练和预测

    模型训练这里,要整理点今天学习到的新东西了,首先,整体代码如下:

    model = MMOE(dnn_features_columns, tower_dnn_hidden_units=[], task_types=['regression', 'binary'], 
                 task_names=['duration', 'click'])
    model.compile("adam", loss={"duration": "mean_squared_error", "click": "binary_crossentropy"}, 
                  loss_weights={"duration": 0.02, "click": 0.98},
                  metrics={"duration": "mae", "click": "binary_crossentropy"})
    
    label_duration = tf.keras.backend.constant(train_data['duration'].values)
    label_click = tf.keras.backend.constant(train_data['click'].values)
    
    history = model.fit(train_model_input, [label_duration, label_click],
                            batch_size=128, epochs=10, verbose=1, validation_split=0.2)
    

    这里的第一个点,就是在模型编译的时候,可以通过上面这种字典的方式传入多个loss进行优化,并且不同的loss还可以指定不同的权重, 模型评估也可以传入字典。 而这里的loss名字要和task_names的名字进行对应。

    我这里一开始是没有指定loss的权重的,但是这样评估的时候,效果会很差,因为这里优化的任务是一个回归,一个分类,这两者的loss范围相差很大,几乎感觉都是回归的loss占尽了主导。所以,我这里手动加了一个权重之后, 效果就好了很多,点击的auc从0.55->0.65, 停留时长的mae从95->48, 全程只改了loss的权重,所以多任务学习中不同loss的幅值对于模型训练有很大的影响的,这种情况可以通过给loss施加权重进行改善。关于权重怎么加,这一块也是有很多工作的,也就是多loss优化的相关内容,我下篇文章会给出几种让网络自己学习loss权重的思路。我这里只是无脑加的。

    另外,怀着好奇,我这里顺便探索了下如果想自定义损失的时候,应该怎么玩? 其实也比较简单:

    def myloss(y_true,y_pred):
        return tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
    
    model.compile(optimizer='adam',loss=myloss,metrics=['acc'])    
    

    自己定义一个loss, 传入y_true和y_pred, 里面就可以自己实现损失的计算流程。 然后把这个放到loss的那个地方即可。 所谓一通百通, 通过这次的小demo, 就学会了keras模型自定义loss以及多个loss联合训练的方法。 这对于我也是收获。

    下面是模型最终的预测结果:

    在这里插入图片描述
    当然,这个除了我上面为每个loss添加权重的那个重要结论之外,并没有啥实质性的参考意义。 第一个原因是我这次实验,由于机子的限制,样本非常少,从采样的里面又采样了1000个用户,数据量很小。 第二个是迭代次数很少。 第三个是由于我没有多任务这块的实战经验, 对于数据的特征只简单预处理, 两种label也没有处理(但click显然类别不平衡,而duration里面分布也不一), 划分训练集和测试集也不知道有啥规则等,所以这次模型训练,训练的loss确实整体下降,但验证的loss时而降时而升,不是很稳定,我感觉这个和loss的权重设置也有关系。 如果有大佬有同时训练过回归和分类任务的经验的,麻烦带一下弟弟呀。

    关于模型复现,就先整理这么多了, 具体细节,可以参考我GitHub上的代码啦。

    5. 小总

    今天抽出了一天时间,填了下多任务的坑,因为纵观我之前梳理的推荐算法导图,多任务这块目前是一点都没有涉及,但目前反而工业上最常用,所以产生了一种不舒服。


    所以今天拿出一天,把MMOE搞定, 这样其实多任务学习网络结构方面这些没有啥太大的值得整理的亮点了,ESMM这个可能也是一个,但有了MMOE,这个就不慌了, 因为MMOE及变体后面用的奇多, 上面也分析过,MMOE这个模型算是符合"大道至简"的设计准则,小而美最容易受到青睐,有了它,想之前提到的YouTubeDNN的W&D多任务学习框架,MOSE以及PLE等就比较容易看了。

    这周末再整理一篇文章,把多任务学习loss优化的这几篇paper的精华搞定,这几个主要就是围绕着我这次训练时出现的那种问题,比如多个loss放一块,可能由于幅度不一样,导致某些任务占据了主导,而其他任务可能贡献不大,这样学习出的网络在贡献不大的任务上反而还不如单独训练的效果好。加权虽然是一种有效的方式(我验证了),但手动加权太无脑且无法自适应,于是乎,就有了很多在loss优化方面的研究,这里面会挑比较经典也用的较多的几篇,看看如何根据网络训练时的具体情境让网络自己学习权重。这一篇不仅可以用于推荐,像cv,NLP里面的多任务学习都可以得到借鉴。这也就是为啥这篇文章只整理MMOE,不整理另外几篇的原因,性价比上,不如后面一篇大,于是乎,我想突击另一篇哈哈。

    OK, 到了这里,关于推荐的"热追"模型方面基本上就先结束,根据上面梳理的导图, 我发现已经用了大约20多篇的文章,梳理完了上面大部分的模型(当然主要是经典且常用的),比如排序那块的大部分目前常用网络FM,DeepFM,xDeepFM,FibiNet等, 召回里面的协同过滤,YouTubeDNN,多兴趣MIND以及序列模型SDM,以及多任务的MMOE。 这些都是目前工业界非常常用的模型。 这次整理也是按照时间线的顺序,并进行相关知识的串联,这样可以把所有的模型由点呈线,而不是孤立起来,不仅容易理解和记忆,而且还有利于自主创新哈哈。

    当然,上面还有一个坑就是关于图的相关召回,这个目前先不补了,第一个原因是图这块我目前只了解点皮毛,如果要补,还需要先重温这块的原理,第二个是目前这块暂时用不上,如果这个感兴趣的,可以看我们的fun-rec项目,这里面已经有大佬把图这块的内容做好了,所以就不重复造一遍了,如果发现有像MMOE这种"大道至简"的,我再出来填一下坑。

    参考:

    整理这篇文章的同时, 也建立了一个GitHub项目, 把各种主流的推荐模型复现一遍,并用通俗易懂的语言进行注释和逻辑整理, 模型大部分都介绍完了,接下来这个项目主要是代码方面的相关优化工作,比如数据集统一,实验统一, 模型复现代码完善以及增加pytorch版等。

    今天的MMOE模型代码已经上传, 该GitHub项目只是单纯供学习使用, 不作任何商业用途,感兴趣的可以看一下 ,star下我会更开心哈哈😉

    筋斗云: https://github.com/zhongqiangwu960812/AI-RecommenderSystem

    展开全文
  • 作者|知乎博主@青枫拂岸整理|NewBeeNLP今天继续代码MMoE在推荐系统中的应用篇,来自Google Youtube团队发表在Recsys 2019的文章 Recommending what video to watch next: a multitask ranking system论文:...

    281c16552e1c7cf09f19bf08602b0166.png

    作者 | 知乎博主@青枫拂岸  

    整理 | NewBeeNLP

    今天继续代码MMoE在推荐系统中的应用篇,来自Google Youtube团队发表在Recsys 2019的文章 Recommending what video to watch next: a multitask ranking system

    • 论文:Recommending What Video to Watch Next: A Multitask Ranking System

    • 链接:https://dl.acm.org/doi/10.1145/3298689.3346997

    不了解MMoE的小伙伴可以参考我之前的文章:多任务学习经典品读:MMoE模型篇

    文章聚焦于推荐系统的排序层,对于工业界多任务目标相互竞争以及用户反馈中的隐性选择偏差问题进行深入研究和解决。

    1.背景介绍

    给定用户当前播放视频,如何预测用户下一个可能播放的视频,这是Youtube工程师关注的问题。但是摆在面前的两个问题需要解决:

    • 优化的多个目标往往不同,有时相互冲突。例如,除了点击观看视频(ctr)外,我们可能还想推荐给用户评价较高或者更可能个朋友分享的视频。

    • 系统中经常存在隐性偏见。例如,用户单击并观看视频可能仅仅是因为该视频被排在物理位置的前面,而不是因为该视频是用户最喜欢的视频。因此,使用当前系统生成的数据训练的模型将有偏差,可能会出现反馈循环,导致模型越学偏差越大。如何有效地学习减少此类偏差是也是一个需要解决的问题。

    2.模型结构

    整体结构图

    919123af7cd384e7d06665cb938cef23.png

    文章针对两个问题,使用Wide&Deep架构:

    针对问题1,采用MMoE 代替 Deep层通用结构,将任务分为两大类:(更为详细可参考MMoE结构的上篇专栏)

    1> 参与度目标 如点击、对推荐视频的参与度 等。

    2> 满足度目标 如 喜欢 不喜欢 评分等。

    目标是分类和回归问题的组合。从而避免多任务优化冲突问题。

    针对问题2,在主模型中添加shallow tower。

    针对于偏差单独建模。只接收选择偏差相关的输入,例如:当前系统决定的排名顺序,输出则为一个倾向分数 propensity score

    采用的预测方法是point-wise,虽然pair-wise和list-wise可以对两个或多个candidate的顺序进行预测,可以潜在的提升推荐结果的多样性,但是point-wise更加适应serving。更加快速和有效。对比而言,pair-wise和list-wise 更加耗时。

    (point-wise、pair-wise和list-wise的差别可参考 Point wise、pairwise及list wise的比较[1]

    两个任务分别为:

    • engagement objective(参与目标 ) 是否点击或观看(分类问题) 、用户观看视频时长(回归问题)

    • satisfaction objective(满足目标) 是否点击”喜欢“(分类问题)、视频打分(回归问题)。

    多任务就是两类目标的互相组合。分类问题设置loss为交叉熵,回归问题设置loss为平方损失。

    输出:对于每个候选item,计算得到的engagement objective和satisfaction objective进行组合函数得到最终的组合分数。

    MMoE模型代替shared Bottom

    1850a36280f135d781b586848b3df67f.png

    常见的多目标的排序系统用的是shared-bottom结构,但是这种hard-parameter强行共享底层的方案对于目标之间相关性小的任务,效果不够好。

    利用gating网络和expert网络组成的MMoE模型针对不同任务对expert网络的输出结果进行不同比例的融合,更好的建模多模态特征空间,效果更好,但是也带来了更大的参数量和时间消耗。

    具体MMoE模型可参考我的上篇文章:

    消除位置、选择偏差

    很过youtube用户看完当前视频,下一个视频并不是他们感兴趣的,而可能是处于位置最上方的视频,这就是我们所说的选择偏差的一种表现形式:位置偏差。这部分的目的就是消除排序模型的选择偏差,从而打破模型越学越偏的反馈循环。

    解决的办法则是类似wide&deep架构,在main tower 即前面的MMoE模型旁边,构建一个shallow tower。单独建模select bias,将输出的logit添加到main model的输出上如图3所示。

    3b83dd75074019a0d419d2d63d2f880a.png

    训练时,浏览时的位置信息作为输入,drop-out rate为10%,从而防止过度依赖。线上服务时,位置特征被设置为"missing"。上图中文章将 位置特征 设备特征 交叉,是因为作者发现在不同类型的设备上观察到不同的位置偏差。

    3.实验结果

    实验当然是利用youtube平台,毕竟是世界上最大的视频分享网站,月活19亿,每天千亿级别的用户日志。

    cd4e762651cf26f8d7dd9868eb5ca341.png

    对于offline实验,评价指标:分类任务用AUC 和 回归任务用squared error。并进行生产环境A/B测试,使用离线和实时指标调整超参数,如learning rate。测试了多种参与度指标( 如:使用时间) 和 满意度指标(如:用户调查响应)。另外,也关心在线服务的计算成本,由于Youtube每秒有大量查询响应。

    针对多任务问题实验

    Baseline Model 采用shared-bottom model。改变模型内部参数来改变模型复杂度。

    86502db3487081b6afb5711640130e34.png

    结果表明:模型复杂性相同时,MMoE显著提高了参与度(engagement metric)和满意度(satisfaction metric)指标。

    Gating 网络是对Expert网络输出分配权重动态分配权重的,我们将权重的分配图进一步展示。(注:所有Expert网络分配权重之和为1)

    48ca782717189a63fdb3169856768a39.png

    可以出,engagement task 概率分布更加均匀;而satisfaction task概率分配更加极端,可能只依赖于一个或几个Expert输出。

    Gating网络稳定性问题

    当使用多台机器训练神经网络模型时,分布式训练策略会导致模型频繁发散。比如Relu death。在MMoE中,softmax选通网络已被指出对于不平衡的Expert分布问题,即对接受分布式培训的Expert的利用率为零的情况,我们在我们的模型中观察到20%的概率存在这种gating网络极化问题。gating网络极化会损害使用极化gating网络的任务上的模型性能。

    本文针对解决此问题的方法是:使用drop-out。设置为10%,将专家利用率设置为0并重新规范化softmax输出,可以消除了所有gating网络的权重分布极化问题。

    针对position bias问题实验

    下图6展示了位置1-9的CTR,结果包含了item相关性,但也有position bias的因素。

    3152cdf50f52eeb445c81a08387f1f96.png

    Baseline Model 两个:

    • Input Feature:将Postition feature 作为一个特征输入模型,现阶段最广泛使用的方法。

    • Adversarial Learning:引入副主任吴预测训练数据中的展现位置,反向传播时,使反向传播梯度消失,以确保主模型的预测不依赖于位置特征。(具体参考论文:Eric Tzeng, Judy Hofman, Kate Saenko, and Trevor Darrell. 2017. Adversarial discriminative domain adaptation)

    83b8b522e3ff951b23359b9f6efded13.png

    对比之后,Shallow Tower模型效果最优。其中的各位置的ctr情况为下图7:

    b063f3b2c0b96715be3616a54b5186fb.png

    模型学习到了每个位置的偏差,越靠下位置,position bias消除的越好。说明shallow tower在position bias消除方面有效果。

    4.未来改进方向

    • 探索更多多目标模型架构 平衡 稳定性、可训练性和表达性。MMoE通过灵活的选择共享Expert 网络。下一步要在不影响预测性能的情况下,提高稳定性。

    • 继续探索未知的潜在bias 模型去自动识别潜在的偏差目标并消除这些bias。

    • 模型压缩 让模型参数更少,更简单。

    5.总结

    1. 这篇文章是MMoE模型的工程落地,可以看出多任务场景下,MMoE对比常用的shared-bottom在工业界的大规模数据部署使用上,效果提升。

    2. 把多任务进行分类,分别是:engagement task 和 satisfaction task。

    • engagement task:是否点击 、 观看时长

    • satisfication task:是否点击喜欢或讨厌 、 用户对视频的评分

    个人认为:engagement 代表着客观反馈 只要你在app内,一定会留下这种目标值,而并非主观做出的;satisfaction 相反,则是代表着主观的反馈 如 知乎文章,喜欢则点击赞同, 不喜欢则点击不感兴趣,或者 B站的一键三连 等等,这些根据主观来进行的行为

    3. 提出了implicit selection bias 是可以影响模型结果的,文中举例如 position bias,有可能用户点击只是因为没想好下一个看什么,但是这个query就是顺序上的第一个,这样播放的视频并不是用户喜欢的,但是模型训练会产生循环,导致模型越学越偏。单独构建shallow tower来解决这个问题,也是有效的。

    一起交流

    想和你一起学习进步!『NewBeeNLP』目前已经建立了多个不同方向交流群(机器学习 / 深度学习 / 自然语言处理 / 搜索推荐 / 图网络 / 面试交流 / 等),名额有限,赶紧添加下方微信加入一起讨论交流吧!(注意一定o要备注信息才能通过)

    0e87631b901f74c6648ebf4518ec7a87.png

    本文参考资料

    [1]

    Point wise、pairwise及list wise的比较: https://zhuanlan.zhihu.com/p/337478373

    a291048500b274d115f71cbdf52b2e32.gif

    展开全文
  • ESMM、MMOE-推荐系统小结

    ESMM、MMOE-推荐系统小结

    1.多任务学习

    多任务学习的优势在于通过部分参数共享,联合训练,能在保证“还不错”的前提下,实现多目标共同提升。原因有以下几种:

    • 任务互助:对于某个任务难学到的特征,可通过其他任务学习
    • 隐式数据增强:不同任务有不同的噪声,一起学习可抵消部分噪声
    • 学到通用表达,提高泛化能力:模型学到的是对所有任务都偏好的权重,有助于推广到未来的新任务
    • 正则化:对于一个任务而言,其他任务的学习对该任务有正则化效果

    最早的多任务学习模型是底层共享结构(Shared-Bottom):

    优点:

    • 浅层参数共享,互相补充学习,任务相关性越高,模型loss优化效果越明显,也可以加速训练。

    缺点:

    • 任务不相关甚至优化目标相反时(例如新闻的点击与阅读时长),可能会带来负收益,多个任务性能一起下降。

    一般把Shared-Bottom的结构称作“参数硬共享”,多任务学习网络结构设计的发展方向便是如何设计更灵活的共享机制,从而实现“参数软共享”。

    2.阿里ESMM

    传统的CVR预估问题存在着两个主要的问题:样本选择偏差稀疏数据。下图的白色背景是曝光数据,灰色背景是点击行为数据,黑色背景是购买行为数据。传统CVR预估使用的训练样本仅为灰色和黑色的数据。

    img

    这会导致两个问题:

    • 样本选择偏差(sample selection bias,SSB):如图所示,CVR模型的正负样本集合={点击后未转化的负样本+点击后转化的正样本},但是线上预测的时候是样本一旦曝光,就需要预测出CVR和CTR以排序,样本集合={曝光的样本}。构建的训练样本集相当于是从一个与真实分布不一致的分布中采样得到的,这一定程度上违背了机器学习中训练数据和测试数据独立同分布的假设。
    • 训练数据稀疏(data sparsity,DS):点击样本只占整个曝光样本的很小一部分,而转化样本又只占点击样本的很小一部分。如果只用点击后的数据训练CVR模型,可用的样本将极其稀疏。

    解决方案

    其中x表示曝光,y表示点击,z表示转化:

    img

    pCTCVR是指,当用户已经点击的前提下,用户会购买的概率;pCVR是指如果用户点击了,会购买的概率。

    三个任务之间的关系为:

    img

    如图,主任务和辅助任务共享特征,不同任务输出层使用不同的网络,将cvr的预测值*ctr的预测值作为ctcvr任务的预测值,利用ctcvr和ctr的label构造损失函数:

    img

    该架构具有两大特点,分别给出上述两个问题的解决方案:

    • 帮助CVR模型在完整样本空间建模(即曝光空间X)。

      img

    ​ 从公式中可以看出,pCVR 可以由pCTR 和pCTCVR推导出。从原理上来说,相当于分别单独训练两个模型拟合出pCTR 和pCTCVR,再通过pCTCVR 除以pCTR 得到最终的拟合目标pCVR 。在训练过程中,模型只需要预测pCTCVR和pCTR,利用两种相加组成的联合loss更新参数。pCVR 只是一个中间变量。而pCTCVR和pCTR的数据是在完整样本空间中提取的,从而相当于pCVR也是在整个曝光样本空间中建模。

    • 提供特征表达的迁移学习(embedding层共享)。CVR和CTR任务的两个子网络共享embedding层,网络的embedding层把大规模稀疏的输入数据映射到低维的表示向量,该层的参数占了整个网络参数的绝大部分,需要大量的训练样本才能充分学习得到。由于CTR任务的训练样本量要大大超过CVR任务的训练样本量,ESMM模型中特征表示共享的机制能够使得CVR子任务也能够从只有展现没有点击的样本中学习,从而能够极大地有利于缓解训练数据稀疏性问题。

    模型训练完成后,可以同时预测cvr、ctr、ctcvr三个指标,线上根据实际需求进行融合或者只采用此模型得到的cvr预估值。

    总结:

    ESMM首创了利用用户行为序列数据在完整样本空间建模,并提出利用学习CTR和CTCVR的辅助任务,迂回学习CVR,避免了传统CVR模型经常遭遇的样本选择偏差和训练数据稀疏的问题,取得了显著的效果。

    ESSM代码(torch-rechub)

    import torch
    import torch.nn.functional as F
    from torch_rechub.basic.layers import MLP, EmbeddingLayer
    from tqdm import tqdmCopy to clipboardErrorCopied
    
    class ESMM(torch.nn.Module):
        def __init__(self, user_features, item_features, cvr_params, ctr_params):
            super().__init__()
            self.user_features = user_features
            self.item_features = item_features
            self.embedding = EmbeddingLayer(user_features + item_features)
            self.tower_dims = user_features[0].embed_dim + item_features[0].embed_dim
            # 构建CVR和CTR的双塔
            self.tower_cvr = MLP(self.tower_dims, **cvr_params)
            self.tower_ctr = MLP(self.tower_dims, **ctr_params)
    
        def forward(self, x):
            embed_user_features = self.embedding(x, self.user_features, 
                                                 squeeze_dim=False).sum(dim=1) 
            embed_item_features = self.embedding(x, self.item_features, 
                                                 squeeze_dim=False).sum(dim=1)
            input_tower = torch.cat((embed_user_features, embed_item_features), dim=1)
            cvr_logit = self.tower_cvr(input_tower)
            ctr_logit = self.tower_ctr(input_tower)
            cvr_pred = torch.sigmoid(cvr_logit)
            ctr_pred = torch.sigmoid(ctr_logit)
            
            # 计算pCTCVR = pCTR * pCVR
            ctcvr_pred = torch.mul(cvr_pred, cvr_pred)
    
            ys = [cvr_pred, ctr_pred, ctcvr_pred]
            return torch.cat(ys, dim=1)
    

    3.MMOE

    MMOE是2018年谷歌提出的,全称是Multi-gate Mixture-of-Experts, 对于多个优化任务,引入了多个专家进行不同的决策和组合,最终完成多目标的预测。解决的是硬共享里面如果多个任务相似性不是很强,底层的embedding学习反而相互影响,最终都学不好的痛点。

    背景与动机

    推荐系统中,即使同一个场景,常常也不只有一个业务目标。 在Youtube的视频推荐中,推荐排序任务不仅需要考虑到用户点击率,完播率,也需要考虑到一些满意度指标,例如,对视频是否喜欢,用户观看后对视频的评分;在淘宝的信息流商品推荐中,需要考虑到点击率,也需要考虑转化率;而在一些内容场景中,需要考虑到点击和互动、关注、停留时长等指标。

    模型中,如果采用一个网络同时完成多个任务,就可以把这样的网络模型称为多任务模型, 这种模型能在不同任务之间学习共性以及差异性,能够提高建模的质量以及效率。 常见的多任务模型的设计范式大致可以分为三大类:

    • hard parameter sharing 方法: 这是非常经典的一种方式,底层是共享的隐藏层,学习各个任务的共同模式,上层用一些特定的全连接层学习特定任务模式。

      在这里插入图片描述

      这种方法目前用的也有,比如美团的猜你喜欢,知乎推荐的Ranking等, 这种方法最大的优势是Task越多, 单任务更加不可能过拟合,即可以减少任务之间过拟合的风险。 但是劣势也非常明显,就是底层强制的shared layers难以学习到适用于所有任务的有效表达。 尤其是任务之间存在冲突的时候。MMOE中给出了实验结论,当两个任务相关性没那么好(比如排序中的点击率与互动,点击与停留时长),此时这种结果会遭受训练困境,毕竟所有任务底层用的是同一组参数。

    • soft parameter sharing: 硬的不行,那就来软的,这个范式对应的结果从MOE->MMOE->PLE等。 即底层不是使用共享的一个shared bottom,而是有多个tower, 称为多个专家,然后往往再有一个gating networks在多任务学习时,给不同的tower分配不同的权重,那么这样对于不同的任务,可以允许使用底层不同的专家组合去进行预测,相较于上面所有任务共享底层,这个方式显得更加灵活

    • 任务序列依赖关系建模:这种适合于不同任务之间有一定的序列依赖关系。比如电商场景里面的ctr和cvr,其中cvr这个行为只有在点击之后才会发生。所以这种依赖关系如果能加以利用,可以解决任务预估中的样本选择偏差(SSB)和数据稀疏性(DS)问题

      • 样本选择偏差: 后一阶段的模型基于上一阶段采样后的样本子集训练,但最终在全样本空间进行推理,带来严重泛化性问题
        
      • 样本稀疏: 后一阶段的模型训练样本远小于前一阶段任务
        


      ESSM是一种较为通用的任务序列依赖关系建模的方法,除此之外,阿里的DBMTL,ESSM2等工作都属于这一个范式。

    通过上面的描述,能大体上对多任务模型方面的几种常用建模范式有了解,然后也知道了hard parameter sharing存在的一些问题,即不能很好的权衡特定任务的目标与任务之间的冲突关系。而这也就是MMOE模型提出的一个动机所在了, 那么下面的关键就是MMOE模型是怎么建模任务之间的关系的,又是怎么能使得特定任务与任务关系保持平衡的?

    带着这两个问题,下面看下MMOE的细节。

    MMOE模型的理论及论文细节

    MMOE模型结构图如下。

    在这里插入图片描述

    这其实是一个演进的过程,首先hard parameter sharing这个就不用过多描述了, 下面主要是看MOE模型以及MMOE模型。

    混合专家模型

    我们知道共享的这种模型结构,会遭受任务之间冲突而导致可能无法很好的收敛,从而无法学习到任务之间的共同模式。这个结构也可以看成是多个任务共用了一个专家。

    先抛开任务关系, 我们发现一个专家在多任务学习上的表达能力很有限,于是乎,尝试引入多个专家,这就慢慢的演化出了混合专家模型。 公式表达如下:
    y = ∑ i = 1 n g ( x ) i f i ( x ) y=\sum_{i=1}^{n} g(x)_{i} f_{i}(x) y=i=1ng(x)ifi(x)
    ∑ i = 1 n g ( x ) i = 1 \sum_{i=1}^{n} g(x)_{i}=1 i=1ng(x)i=1 f i ( x ) f_i(x) fi(x)就是每个专家的输出, 而 g ( x ) i g(x)_i g(x)i就是每个专家对应的权重。改进:

    1. 模型集成思想: 这个东西很像bagging的思路,即训练多个模型进行决策,这个决策的有效性显然要比单独一个模型来的靠谱一点,不管是从泛化能力,表达能力,学习能力上,应该都强于一个模型
    2. 注意力思想: 为了增加灵活性, 为不同的模型还学习了重要性权重,这可能考虑到了在学习任务的共性模式上, 不同的模型学习的模式不同,那么聚合的时候,显然不能按照相同的重要度聚合,所以为各个专家学习权重,默认了不同专家的决策地位不一样。这个思想目前不过也非常普遍了。
    3. multi-head机制: 从另一个角度看, 多个专家其实代表了多个不同head, 而不同的head代表了不同的非线性空间,之所以说表达能力增强了,是因为把输入特征映射到了不同的空间中去学习任务之间的共性模式。可以理解成从多个角度去捕捉任务之间的共性特征模式。

    MOE使用了多个混合专家增加了各种表达能力,但是, 一个门控并不是很灵活,因为这所有的任务,最终只能选定一组专家组合,即这个专家组合是在多个任务上综合衡量的结果,并没有针对性了。 如果这些任务都比较相似,那就相当于用这一组专家组合确实可以应对这多个任务,学习到多个相似任务的共性。 但如果任务之间差的很大,这种单门控控制的方式就不行了,因为此时底层的多个专家学习到的特征模式相差可能会很大,毕竟任务不同,而单门控机制选择专家组合的时候,肯定是选择出那些有利于大多数任务的专家, 而对于某些特殊任务,可能学习的一塌糊涂。

    所以,这种方式的缺口很明显,这样,也更能理解为啥提出多门控控制的专家混合模型了。

    MMOE结构

    Multi-gate Mixture-of-Experts(MMOE)的魅力就在于在OMOE的基础上,对于每个任务都会涉及一个门控网络,这样,对于每个特定的任务,都能有一组对应的专家组合去进行预测。更关键的时候,参数量还不会增加太多。公式如下:

    y k = h k ( f k ( x ) ) , y_{k}=h^{k}\left(f^{k}(x)\right), yk=hk(fk(x)),

    • 首先,就刚才分析的OMOE的问题,在专家组合选取上单门控会产生限制,此时如果多个任务产生了冲突,这种结构就无法进行很好的权衡。 而MMOE就不一样了。MMOE是针对每个任务都单独有个门控选择专家组合,那么即使任务冲突了,也能根据不同的门控进行调整,选择出对当前任务有帮助的专家组合。
    • 多门控机制能够建模任务之间的关系了。如果各个任务都冲突, 那么此时有多门控的帮助, 此时让每个任务独享一个专家,如果任务之间能聚成几个相似的类,那么这几类之间应该对应的不同的专家组合,那么门控机制也可以选择出来。如果所有任务都相似,那这几个门控网络学习到的权重也会相似,所以这种机制把任务的无关,部分相关和全相关进行了一种统一。
    • 灵活的参数共享, 这个我们可以和hard模式或者是针对每个任务单独建模的模型对比,对于hard模式,所有任务共享底层参数,而每个任务单独建模,是所有任务单独有一套参数,算是共享和不共享的两个极端,对于都共享的极端,害怕任务冲突,而对于一点都不共享的极端,无法利用迁移学习的优势,模型之间没法互享信息,互为补充,容易遭受过拟合的困境,另外还会增加计算量和参数量。 而MMOE处于两者的中间,既兼顾了如果有相似任务,那就参数共享,模式共享,互为补充,如果没有相似任务,那就独立学习,互不影响。 又把这两种极端给进行了统一。
    • 训练时能快速收敛,这是因为相似的任务对于特定的专家组合训练都会产生贡献,这样进行一轮epoch,相当于单独任务训练时的多轮epoch。
    • 虽然模型的复杂度提升了,但是计算量不会大幅增加。MoE是条件计算(conditional computation)的一种实现,而条件计算可以提升模型容量而不会大幅增加计算力需求。

    那么, 为什么多任务学习为什么是有效的呢? 这里整理一个看到比较不错的答案:

    多任务学习有效的原因是引入了归纳偏置,两个效果:

    • 互相促进: 可以把多任务模型之间的关系看作是互相先验知识,也称为归纳迁移,有了对模型的先验假设,可以更好提升模型的效果。解决数据稀疏性其实本身也是迁移学习的一个特性,多任务学习中也同样会体现
    • 泛化作用:不同模型学到的表征不同,可能A模型学到的是B模型所没有学好的,B模型也有其自身的特点,而这一点很可能A学不好,这样一来模型健壮性更强

    代码

    import torch
    import torch.nn as nn
    
    from torch_rechub.basic.layers import MLP, EmbeddingLayer, PredictionLayerCopy to clipboardErrorCopied
    
    class MMOE(torch.nn.Module):
        def __init__(self, features, task_types, n_expert, expert_params, tower_params_list):
            super().__init__()
            self.features = features
            self.task_types = task_types
            # 任务数量
            self.n_task = len(task_types)
            self.n_expert = n_expert
            self.embedding = EmbeddingLayer(features)
            self.input_dims = sum([fea.embed_dim for fea in features])
            # 每个Expert对应一个门控
            self.experts = nn.ModuleList(
                MLP(self.input_dims, output_layer=False, **expert_params) for i in range(self.n_expert))
            self.gates = nn.ModuleList(
                MLP(self.input_dims, output_layer=False, **{
                    "dims": [self.n_expert],
                    "activation": "softmax"
                }) for i in range(self.n_task))
            # 双塔
            self.towers = nn.ModuleList(MLP(expert_params["dims"][-1], **tower_params_list[i]) for i in range(self.n_task))
            self.predict_layers = nn.ModuleList(PredictionLayer(task_type) for task_type in task_types)
    
        def forward(self, x):
            embed_x = self.embedding(x, self.features, squeeze_dim=True)
            expert_outs = [expert(embed_x).unsqueeze(1) for expert in self.experts]  
            expert_outs = torch.cat(expert_outs, dim=1) 
            gate_outs = [gate(embed_x).unsqueeze(-1) for gate in self.gates]
    
            ys = []
            for gate_out, tower, predict_layer in zip(gate_outs, self.towers, self.predict_layers):
                expert_weight = torch.mul(gate_out, expert_outs)  
                expert_pooling = torch.sum(expert_weight, dim=1) 
                # 计算双塔
                tower_out = tower(expert_pooling)
                # logit -> proba
                y = predict_layer(tower_out)
                ys.append(y)
            return torch.cat(ys, dim=1)
    

    论文阅读

    • ESMM https://arxiv.org/abs/1804.07931

    • MMOE https://dl.acm.org/doi/pdf/10.1145/3219819.3220007

    展开全文
  • KDD 2018 MMOE (内含论文官方讲解视频) PDF Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts 一、前言 阿里团队提出 ESMM 模型利用 MTL 的方法极大地提升了 CVR 预估的...
  • MMOE原理介绍

    2021-09-27 21:41:20
    推荐算法的分类 MMOE原理介绍 文章目录: 现有的解决方案 Multi-gate Mixture-of-Experts(MMoE) MoE Layer ​ 实验结果: 结论: 背景 神经网络的多任务学习已成功用于工业界的大规模应用程序中,例如在视频推荐中...
  • mmoe论文解读

    千次阅读 2020-08-30 13:34:20
    所有的模型,任务相关性越高,表现越好 随着任务相关性的差别造成的MMoE模型表现的差异要小于OMoE 模型以及Shared-Bottom模型,这种趋势在比较MMoE 模型和OMoE 模型的时候尤为明显: 在极端的情况下,当两个任务...
  • MMOE多任务多目标案例

    2021-03-29 16:22:54
    参考:https://github.com/drawbridge/keras-mmoe https://blog.csdn.net/weixin_42357472/article/details/106852113 数据字段说明下载: ...
  • 多任务学习是排序模型的一种发展方式,诞生于多任务的背景。实践表明,多任务联合建模可以有效提升模型效果,因其可以:任务互助;...任务序列依赖关系建模(ESMM属于这种)本次学习涉及了两个模型:ESMM和MMOE...
  • MMOE核心代码块

    2022-03-28 15:11:18
    class MMoE_Layer(tf.keras.layers.Layer): def __init__(self,expert_dim,n_expert,n_task): super(MMoE_Layer, self).__init__() self.n_task = n_task self.expert_layer = [Dense(expert_dim,activation = '...
  • MMOE模型

    千次阅读 2021-06-11 23:42:33
    MMOE模型 本质是与Shared-Bottom底层网络共享加深了专业领域程度,同时融入了注意力机制(信息融合)
  • Multi-gate Mixture-of-Experts(MMoE)模型 从MMoE的名称来看,可以看到主要包括两个部分,分别为:Multi-gate(多门控网络)和Mixture-of-Experts(混合专家)。 2.2.1. Mixture-of-Experts(MoE)模型 MoE模型...
  • 2.2 MMOE模型框架 mmoe的思想就是,在底部的embedding层上设立多个expert网络,不同的task可以根据需求选择expert,通过expert输出的概率加权平均获得每个task的输入。 2.2.1 MOE模型 模型原理:基于多个Expert汇总...
  • 本文主要介绍tensorflow中mmoe的实现方式。 一.mmoe概念 先简单回忆下mmoe的概念: https://blog.csdn.net/u013250416/article/details/118642297 二.已有keras版本实现思路分析 github中已经有keras版本mmoe的...
  • 本章为推荐模型复现第四章,使用torch_rechub框架进行模型搭建,主要介绍推荐系统召多任务模型ESMM、MMOE,包括结构讲解与代码实战,参考其他文章。
  • 其中涉及到多任务学习,本篇将会大概整理一些常用的模型如MMoE, ESMM, SNR方便理解与学习。 MMoE 背景与动机 在工业界基于神经网络的多任务学习在推荐等场景业务应用广泛,比如在推荐系统中对用户推荐物品时,不仅要...
  • 多目标排序MMoE、PLE
  • 论文地址:KDD 2018 | Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts github上大神的开源地址:GitHub - drawbridge/keras-mmoe: A TensorFlow Keras implementation of ...
  • 多任务学习模型MTL: MMoE、PLE

    千次阅读 2021-10-24 20:12:17
    CGC 从上面的结构图,容易看出跟MMoE的差别就在于:除了共享的Expert之外,还加入了每个task自己的Specific Expert 所有task共享的expert(如上图Experts Shared)、每个task自己的expert(如上图task A的Experts A...
  • 比如,CTR、点赞、时长、完播、分享等,并且有的目标的数据量并不是很足够,甚至无法单独训练一个DNN(当然,你如果说我单独建模用xgb,那我无话可说),在这种情况下,我们可能就要考虑MTL了,这时候MMoE就可以派上...
  • MMOE多目标学习

    2021-01-03 13:06:39
    本文通过讲解MMOE的原理,并根据笔者在工作中应用MMOE的经验,来给大家引出这篇博文。 多目标模型的意义: 现实世界中,我们的业务目标往往不是单一的。 比如购物APP中,我们不仅仅希望你浏览商品,也希望你购买...
  • Task04 多任务模型:ESMM、MMOE 一、ESMM ESMM的全称是Entire Space Multi-task Model (ESMM),是阿里巴巴算法团队提出的多任务训练方法。其在信息检索、推荐系统、在线广告投放系统的CTR、CVR预估中广泛使用。 ESMM...
  • 推荐系统(十八)推荐系统中的MMOE

    千次阅读 2021-12-07 17:07:10
    mmoe
  • 作者|知乎博主@青枫拂岸整理|NewBeeNLP今天带来是Google发表于KDD2018,针对于多任务推荐的经典模型MMOE。论文:Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts地址: ...
  • MMOE 多任务学习模型介绍与源码浅析

    千次阅读 2021-01-29 08:44:59
    MMOE 多任务学习模型介绍与源码浅析 前言 (与正文无关, 请忽略~) 后续打算写 DMT, 先介绍一些基础模块. 文章信息 论文标题: Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-...
  • MMoE在躺平多目标优化实践 基于MMoE的灵活性及高可扩展性,我们选择MMoE作为躺平多目标优化模型,并对其进行了4个维度的优化和实验。 ▐ 底层特征处理,引入局部激活单元 在传统的Embedding + MLP模型中,首先将大...
  • ​在实际生活中,我们关注的任务往往是一对...​这次和大家分享其中常见的几种多任务模型MMOE,ESMM,CGC,AITM,文末给出了参考文献,有兴趣的小伙伴可以​从论文中获取详细内容。 Hard-parameter sharing 图...
  • 多目标MMOE

    千次阅读 2020-07-24 18:17:43
    介绍MMOE deep部分:存在多个Expert网络,每个Expert网络的输出最终会经过门网络进行加权平均(比较简单的线性加权,Attention的思想) 门网络通过softmax输出每个专家网络的可能性,线性加权相乘。然后进行分类或者...
  • MMOE多任务模型总结

    2021-07-25 11:46:33
    MMOE多任务模型 18年KDD google 原文链接:Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts 论文中提出了一个Multi-gate Mixture-of-Experts(MMoE)的多任务学习结构,学习...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 610
精华内容 244
关键字:

mmoe

友情链接: shipin.rar