• 推荐模型复现(四):多任务模型ESMM、MMOE


    多任务模型:ESMM、MMOE

    本章为推荐模型复现第四章,使用torch_rechub框架进行模型搭建,主要介绍推荐系统召多任务模型ESMM、MMOE,包括结构讲解与代码实战,参考其他文章。

    推荐方向资料推荐:

    1.RecHub Wiki

     2. FunRec

    1 ESMM

    1.1 ESMM产生背景

    • 样本选择偏差:构建的训练样本集的分布采样不准确
    • 稀疏数据:点击样本占曝光样本的比例很小

    1.2 ESMM原理

    • 解决思路:基于多任务学习,引入CTR、CTCVR消除样本选择偏差和稀疏数据
    • 三个预测任务:
    1. pCTR:点击率预估模型
    2. pCVR:转化率预估模型
    3. pCTCVR: 点击和转化率预估模型

    \underbrace{p(y=1, z=1 | x)}_{pCTCVR}=\underbrace{p(y=1 | x)}_{pCTR} \times \underbrace{p(z=1 | y=1, x)}_{pCVR}pCTCVRp(y=1,z=1∣x)​​=pCTRp(y=1∣x)​​×pCVRp(z=1∣y=1,x)​​

    其中xx表示曝光,yy表示点击,zz表示转化

    • 主任务和辅助任务共享特征,并利用CTCVR和CTR的label构造损失函数:

      L(θcvr,θctr)=i=1Nl(yi,f(xi;θctr))+i=1Nl(yi&zi,f(xi;θctr)×f(xi;θcvr))
      L(θcvr​,θctr​)​=i=1∑N​l(yi​,f(xi​;θctr​))+i=1∑N​l(yi​&zi​,f(xi​;θctr​)×f(xi​;θcvr​))​
    • 解决样本选择偏差:在训练过程中,模型只需要预测pCTCVR和pCTR,即可更新参数,由于pCTCVR和pCTR的数据是基于完整样本空间提取的,故根据公式,可以解决pCVR的样本选择偏差

    • 解决数据稀疏:使用共享的embedding层,使得CVR子任务也能够从只展示没点击的样本中学习,可以缓解训练数据稀疏的问题

    1.3 ESSM模型的优化1.3 ESSM模型的优化1.3 ESSM模型的优化

    • 论文中,子任务独立的Tower网络是纯MLP模型,可以根据自身特点设置不一样的模型,例如使用DeepFM、DIN等
    • 引入动态加权的学习机制,优化loss
    • 可构建更长的序列依赖模型,例如美团AITM信用卡业务,用户转换过程是曝光->点击->申请->核卡->激活

    1.4 ESSM模型代码实现1.4 ESSM模型代码实现1.4 ESSM模型代码实现
     

    1. import torch
    2. import torch.nn.functional as F
    3. from torch_rechub.basic.layers import MLP, EmbeddingLayer
    4. from tqdm import tqdm
    5. class ESMM(torch.nn.Module):
    6. def __init__(self, user_features, item_features, cvr_params, ctr_params):
    7. super().__init__()
    8. self.user_features = user_features
    9. self.item_features = item_features
    10. self.embedding = EmbeddingLayer(user_features + item_features)
    11. self.tower_dims = user_features[0].embed_dim + item_features[0].embed_dim
    12. # 构建CVR和CTR的双塔
    13. self.tower_cvr = MLP(self.tower_dims, **cvr_params)
    14. self.tower_ctr = MLP(self.tower_dims, **ctr_params)
    15. def forward(self, x):
    16. embed_user_features = self.embedding(x, self.user_features,
    17. squeeze_dim=False).sum(dim=1)
    18. embed_item_features = self.embedding(x, self.item_features,
    19. squeeze_dim=False).sum(dim=1)
    20. input_tower = torch.cat((embed_user_features, embed_item_features), dim=1)
    21. cvr_logit = self.tower_cvr(input_tower)
    22. ctr_logit = self.tower_ctr(input_tower)
    23. cvr_pred = torch.sigmoid(cvr_logit)
    24. ctr_pred = torch.sigmoid(ctr_logit)
    25. # 计算pCTCVR = pCTR * pCVR
    26. ctcvr_pred = torch.mul(cvr_pred, cvr_pred)
    27. ys = [cvr_pred, ctr_pred, ctcvr_pred]
    28. return torch.cat(ys, dim=1)

    2 MMOE

    2.1 MMOE产生背景

    • 多任务模型:在不同任务之间学习共性以及差异性,能够提高建模的质量以及效率。
    • 多任务模型设计模式:
      1. Hard Parameter Sharing方法:底层是共享的隐藏层,学习各个任务的共同模式,上层用一些特定的全连接层学习特定任务模式
      2. Soft Parameter Sharing方法:底层不使用共享的shared bottom,而是有多个tower,给不同的tower分配不同的权重
      3. 任务序列依赖关系建模:这种适合于不同任务之间有一定的序列依赖关系

    2.2 MOE模型和MMOE模型原理

    2.2.1 MOE模型(混合专家模型)

    • 模型原理:基于多个Expert汇总输出,通过门控网络机制(注意力网络)得到每个Expert的权重
    • 特性:模型集成、注意力机制、multi-head机制

    2.2.2 MMOE模型

    • 基于OMOE模型,每个Expert任务都有一个门控网络
    • 特性:
      1. 避免任务冲突,根据不同的门控进行调整,选择出对当前任务有帮助的Expert组合
      2. 建立任务之间的关系
      3. 参数共享灵活
      4. 训练时模型能够快速收敛
    1. import torch
    2. import torch.nn as nn
    3. from torch_rechub.basic.layers import MLP, EmbeddingLayer, PredictionLayer
    4. class MMOE(torch.nn.Module):
    5. def __init__(self, features, task_types, n_expert, expert_params, tower_params_list):
    6. super().__init__()
    7. self.features = features
    8. self.task_types = task_types
    9. # 任务数量
    10. self.n_task = len(task_types)
    11. self.n_expert = n_expert
    12. self.embedding = EmbeddingLayer(features)
    13. self.input_dims = sum([fea.embed_dim for fea in features])
    14. # 每个Expert对应一个门控
    15. self.experts = nn.ModuleList(
    16. MLP(self.input_dims, output_layer=False, **expert_params) for i in range(self.n_expert))
    17. self.gates = nn.ModuleList(
    18. MLP(self.input_dims, output_layer=False, **{
    19. "dims": [self.n_expert],
    20. "activation": "softmax"
    21. }) for i in range(self.n_task))
    22. # 双塔
    23. self.towers = nn.ModuleList(MLP(expert_params["dims"][-1], **tower_params_list[i]) for i in range(self.n_task))
    24. self.predict_layers = nn.ModuleList(PredictionLayer(task_type) for task_type in task_types)
    25. def forward(self, x):
    26. embed_x = self.embedding(x, self.features, squeeze_dim=True)
    27. expert_outs = [expert(embed_x).unsqueeze(1) for expert in self.experts]
    28. expert_outs = torch.cat(expert_outs, dim=1)
    29. gate_outs = [gate(embed_x).unsqueeze(-1) for gate in self.gates]
    30. ys = []
    31. for gate_out, tower, predict_layer in zip(gate_outs, self.towers, self.predict_layers):
    32. expert_weight = torch.mul(gate_out, expert_outs)
    33. expert_pooling = torch.sum(expert_weight, dim=1)
    34. # 计算双塔
    35. tower_out = tower(expert_pooling)
    36. # logit -> proba
    37. y = predict_layer(tower_out)
    38. ys.append(y)
    39. return torch.cat(ys, dim=1)

    3 总结

     本次任务,主要介绍了ESSM和MMOE的多任务学习模型原理和代码实践:

    1. ESSM模型:主要引入CTR和CTCVR的辅助任务,解决样本选择偏差和稀疏数据问题,基于双塔模型,并可根据自身特点设置两个塔的不同模型,子网络支持任意替换
    2. MMOE模型:主要基于OMOE模型,其中每个Expert任务都有一个门控网络,下层是MOE基本模型,上层是双塔模型,满足各个任务在Expert组合选择上的解耦性,具备灵活的参数共享、训练快速收敛等特点。

    本文参考:

    我的组队学习

     

  • 相关阅读:
    JavaWeb---HTML
    python自动化测试(十一):写入、读取、修改Excel表格的数据
    uni-app 小程序跳转其他小程序方法
    西电系统分析与设计期末复习笔记
    mybatis-plus集成分页插件,针对多数据源分页失效的问题
    从零开始探索C语言(八)----指针
    周赛补题(AcWing、力扣)
    什么是代码签名?代码签名的好处
    【ACWing】2714. 左偏树
    微信的9个隐藏功能,我不允许还有人不知道!
  • 原文地址:https://blog.csdn.net/qq_36816848/article/details/125481278