推荐系统实战(七)-多任务多场景(上)多任务

news2024/11/13 15:19:31

多任务Multi-Task,有时也被称为多目标Multi-Objective建模。比如说电商场景下,希望曝光的物料被多多点击,还希望商品被下单购买,因此同时建模三个目标:曝光到点击CTR,点击到购买转换率CVR,曝光到购买的概率CTCVR。

一、多任务建模的误区

(一)为什么不为每个目标单独建模

1、浪费资源

为每个目标单独建模,对内存和算力要求大。

2、用户转化是个链条

用户转化是个链条,链条中越靠后的部分对最终目标贡献越大,但是相应的样本数目也比较少,单独训练会因为样本稀疏导致训练效果不好。因此采用联合训练的方式,可以使前面数据量充足的环节对后面数据量较少的环节进行知识迁移

(二)为什么不直接给终极目标建模

拿电商场景中,CTR、CVR、CTCVR举例。用户点击但未购买,并不意味着用户对推荐的商品不感兴趣,可能是超出了用户的购买能力。因此如果直接只将CTCVR这个终极目标建模,可能短期内给用户推荐的商品都是定价在中低档的。可能造成以下两个后果:

  • 审美疲劳,短期内推荐给用户的商品价格相似,内容相似。
  • 不利于用户种草价格稍高的商品。

因此只按照CTCVR这个终极目标建模,对短期、当下的销售额提升是有效的,但是应当也考虑长期的用户留存和销售额提升。

在广告定价时,对CTR、CVR、CTCVR分别设计不同的计费模式,联合训练三个目标,可以使前面数据充足的部分对后面数据稀疏的环节起到知识迁移的作用。

二、并发建模

(一)share bottom共享底层

1、描述

并发模式最直接的实现方式是share bottom共享底层。底层结构,比如说embedding层和底层DNN。每个任务都有一个塔,共享底层的输出就是每个塔的输入。

2、优点

可以实现多任务之间的知识迁移,比如说任务A的正样本数据充足,任务B的正样本数据较少,任务A充足的数据会将共享底层训练得很好,这样对任务B的训练会有帮助。

3、缺点

共享底层的缺点在于不同任务对共享底层参数的梯度方向可能不同,就会造成以下两种现象:

  • 负迁移negative transfer:任务A和任务B联合训练的效果都没有单独训练好。
  • 跷跷板seesaw:任务A和任务B联合训练,任务A的效果比单独训练好,而任务B的效果没有单独训练好。

因此,可以采用不同任务更新不同参数的方式,一部分参数共享,一部分独立。

“共享底层”多任务模型

(二) Multi-gate Mixture-of-Experts

1、MoE

将共享底层拆解成若干个DNN,每个DNN被称作一个expert。再由一个gate来管控每个experts对所有不同的任务的参与程度。如下图所示。

MoE结构示意

任务k的预测值公式如下所示:

其中h_k表示第k个任务的塔,y_k是任务k的预测值,一共有n个expert,g(x)_i是gate对第i个expert设置的权重,expert_i表示第i个expert网络模型。其实gate就是一个简单的MLP,最后一层使用softmax激活函数,让所有的expert权重之和为1。

2、MMoE

MMoE和MoE的不同之处在于,MoE只有一个gate来控制不同experts对所有任务的参与程度,而MMoE有多个gate,控制不同experts对不同任务的参与程度。如下图所示。

MMoE结构示意

公式如下所示: 

MMoE中各专家分配到的权重累加

3、MoE和MMoE的特点

  • 不再使用一套参数为所有任务所共享。
  • 没有重走给每个目标单独建模的老路。
  • 所有专家被所有任务共享,但是共享程度由gate控制。
  • 虽然共享,但是某个专家是专注于某个任务的,从而每个任务都更新不同的参数,减少干扰。

4、MMoE代码

MMoE层的实现:

class MMOE:
    def __init__(self, expert_dnn_config, num_task, num_expert=None, ):
        # expert_dnn_config是一个list
        # expert_dnn_config[i]是第i个expert的配置
        self._expert_dnn_configs = expert_dnn_config
        self._num_expert = len(expert_dnn_config)
        self._num_task = num_task

    def gate(self, unit, deep_fea, name):
        # deep_fea还是底层的输入向量,和喂给expert的是同一个向量
        # unit:应该是experts的数量
        fea = tf.layers.dense(inputs=deep_fea, units=unit,)

        # fea: [B,N],N是experts的个数
        # 代表对于某个task,每个expert的贡献程度
        fea = tf.nn.softmax(fea, axis=1)
        return fea

    def __call__(self, deep_fea):
        """ 
        输入deep_fea: 底层的输入向量
        输出:一个长度为T的数组,T是task的个数,其中第i个元素是Expert层给第i个task的输入
        """
        expert_fea_list = []
        for expert_id in range(self._num_expert):
            # expert_dnn_config是expert_id对应的expert的配置
            # 比如有几层、每一层采用什么样的激活函数、......
            expert_dnn_config = self._expert_dnn_configs[expert_id]
            expert_dnn = DNN(expert_dnn_config, ......)

            expert_fea = expert_dnn(deep_fea)  # 单个expert的输出
            expert_fea_list.append(expert_fea)

        # 假设有N个expert,每个expert的输出是expert_fea,其形状是[B,D]
        # B=batch_size, D=每个expert输出的维度
        # experts_fea是N个expert_fea拼接成的向量,形状是[B,N,D]
        experts_fea = tf.stack(expert_fea_list, axis=1)

        task_input_list = []  # 给每个task tower的输入
        for task_id in range(self._num_task):
            # gate: [B,N],N是experts的个数, 代表对于某个task,每个expert的贡献程度
            gate = self.gate(self._num_expert, deep_fea, ......)
            # gate: 变形成[B,N,1]
            gate = tf.expand_dims(gate, -1)

            # experts_fea: [B,N,D]
            # gate: [B,N,1]
            # task_input: [B,N,D],根据gate给每个expert的输出加权后的结果
            task_input = tf.multiply(experts_fea, gate)
            # task_input: [B,D],每个expert的输出加权相加
            task_input = tf.reduce_sum(task_input, axis=1)

            task_input_list.append(task_input)
        return task_input_list

基于MMoE的多任务学习:

mmoe_layer = MMOE(......)

# feature_dict是每个field的输入
# 通过input_layer的映射,映射成一个向量features
features = input_layer(feature_dict, 'all')
# task_input_list是一个长度为T的数组,T是task的个数
# task_input_list[i]是Expert层给第i个task的输入
# 形状是[B,D],B=batch_size, D是每个expert的输出维度
task_input_list = mmoe_layer(features)

tower_outputs = {}
for i, task_tower_cfg in enumerate(model_config.task_towers):
    # task_tower_cfg是第i个task tower的配置
    # 比如:当前task的名字、task tower有几层、每层的激活函数等
    tower_name = task_tower_cfg.tower_name

    # 构建针对第i个task的Tower网络结构
    tower_dnn = DNN(task_tower_cfg, ......)

    # task_input_list[i]是Expert层给第i个task的输入
    # tower_output是第i个task的输出
    tower_output = tower_dnn(task_input_list[i])
    tower_outputs[tower_name] = tower_output

(三)渐进式分层抽取PLE

渐进式分层抽取PLE(Progressive Layer Extraction)建模多目标,在MMoE上做出了两点改进:

1、MMoE中所有任务共享所有专家,而PLE将专家分为两类:任务独占和任务共享。任务独占专家只参与指定任务,而任务共享专家参与所有任务。

2、MMoE的expert只有一层,专家之间的交互较弱,而PLE中的专家有多层。

PLE结构示意

PLE的第k层需要输出n+1个向量:n个任务的建模结果向量+1个共享信息建模向量。 

任务向量获取流程:分别获取任务独占专家在第k-1层的输出向量集合和任务共享专家在第k-1层的输出向量集合。求出这些专家向量的权重,与第k-1层的输出向量做加权求和得到任务t在第k层的输出。

共享信息向量获取流程:需要获得所有任务的任务独占专家和共享专家在第k-1层的输出向量集合,求出权重后,加权求和得到在第k层的共享信息向量。

最后PLE对各目标的预测公式如下所示:

p_t=h_t(x_t^K)

第K层是最后一层,h_t是针对任务t的塔结构,p_t是PLE对任务t的预测值,x_t^K是最后一层专家对任务t的建模结果。

三、串行建模

串行建模主要用于电商场景。在电商场景中,我们需要对CTR、CVR、CTCVR建模,而对于CVR而言,是基于曝光的物料中点击物料进行训练的。然而,在预测的过程中,CVR要对一些经过曝光但是没有被点击的物料进行预测,由于未点击的物料与已点击物料可能有显著差异,这就导致了样本选择偏差。

CVR的样本选择偏差问题

(一)ESMM

ESMM(Entire Space Multi-task Model)解决思路是CTR、CVR还有CTCVR全部建模在已曝光物料的基础之上,由于曝光但未点击的物料不符合CVR(点击到购买的转化率)的定义,因此CVR作为隐藏目标,在其他目标被优化的同时间接被优化。

ESMM结构示意

模型主要由两个部分组成:CTR模型和CVR模型。其中两者共享底层embedding,有利于正样本充足的CTR向正样本稀疏的CVR进行知识迁移。在预测得到CTR和CVR概率后,两者相乘得到CTCVR的概率。因此直接优化CTR和CTCVR的同时,可以间接优化CVR。

基于MMoE实现的ESMM

由上图基于MMoE实现的ESMM可知, 并发建模和串行建模并非泾渭分明,而是可以有机结合。

(二)ESM2 

在点击和购买之间还有许多其他信号可以使用,比如说加入购物车、加入愿望清单等直接行为。

阿里巴巴根据条件概率拆解的思路,提出了Elaborated Entire Space Supervised Multi-Tak Model(ESM2)。

1、ESM2需要预测的四种概率

  • 曝光-点击的概率CTR
  • 点击-直接行为的概率,直接行为Direct Action包括加入购物车、加入愿望清单等。其他行为是在点击行为之后除了直接行为之外的行为或者无行为。
  • 直接行为-购买的概率。
  • 其他行为-购买的概率。

 2、ESM2需要优化的三个目标

将三个loss加权求和就是最后需要优化的目标:

①曝光-点击

②曝光-直接行为

③曝光-购买

(三)更通用的知识迁移

在ESM中,pCTR参与pCTCVR建模,只传递了CTR信息,过于浓缩,并且只拘泥与概率相乘的方式过于简单。

因此可以采用更通用的知识迁移:提取出CTR模型中倒数第二层的输出向量,和MMoE或者PLE输出向量一起喂给后端环节的塔中,辅助后端环节的训练。

需要注意的是,前端CTR的隐式向量喂给后端环节之前需要先调用tf.stopgradient以防后端环节将训练好的前端隐层带偏。

前端环节的隐层输出喂给后端环节

(四)ESCM2

ESMM是把CVR建模当成隐藏目标,随着CTR和CTCVR被间接优化。

ESCM2的修正公式如下所示:

其中样本集合D中的每条样本是由(样本特征,是否点击,是否购买)的三元组组成的。修正项是除以点击率的预测值,当对点击率的预测够准时,CVR就等价于在全体曝光样本上训练的。

修正公式的简单理解:点击样本的CTR肯定高,而CVR是基于点击样本训练的,因此未点击样本也就是pCTR小的样本更加珍贵,所以要按照CTR的倒数进行加权。

ESCM2的训练过程:先在全体曝光数据的基础上训练好CTR和CTCVR,然后再在曝光已点击的数据上训练好CVR,并根据CTR修正。模型最终要优化的loss是三个损失之和,下面两个λ是需要调整的超参数:

需要注意的是,训练好CTR以后参与修正前,需要禁止回代。

ESCM2结构示意

四、多个损失的融合

(一)融合方式

将不同损失加权求和融合成最终优化目标,设置各个损失的权重的时候需要考虑以下两点:

  • 不同目标有轻重缓急之分,因此权重设置不同。
  • 不同损失的数值范围不同,有两种方式解决:1、通过开方、取对数等方式将较大数值范围的损失压缩到合理范围。2、设置合理的损失权重。

(二)权重设置

权重设置有两种方式。一种是依靠人工设置,一边调整权重,一边观察离线、在线指标。另外一种是半自动算法调整,比如说阿里巴巴提出的基于帕累托有效的算法PEC(Pareto-Efficient)。Pareto-Efficient代表了多目标优化时的理想状态,多目标中任何一个目标想要优化,只能以损失其他目标为代价。

Pareto-Efficient的算法步骤如下:

  • 接收新一批训练数据,上一轮得到的模型参数θ和各损失权重w_i。
  • 计算每个目标的损失函数对参数θ的导数。
  • 计算整体损失的梯度。
  • 更新模型参数。
  • 利用各目标损失的梯度,计算出新的各损失权重。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2079719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记一次对某佛教系统的漏洞挖掘

前言 简单记录一次漏洞挖掘,一个系统居然爆了这么多类型的洞,于是想记录哈。(比较基础,我是菜狗,大佬轻喷) 业务介绍 是一个某佛教的系统 有一些佛教的学习资源、一些佛教相关的实物商品可购买,有个人中心&#xff…

PyCharm中python语法要求——消去提示波浪线

PyCharm中python语法要求——消去提示波浪线 关闭代码规范检查 在Setting里边搜索pep,取消勾选pep8 coding style violation 问题产生 解决问题 按照下图操作,也可直接CtrlAlts弹出设置页面 在 Settings 中 : Editor > Color Sheame >…

设计模式26-解析器模式

设计模式26-解析器模式 动机定义与结构定义结构 C代码推导代码说明 优缺点应用总结 动机 在软件构建过程中,如果某一特定领域的问题比较复杂,类似结构会不断重复的出现。如果使用普通的编程方式来实现,将面临非常频繁的变化。 在这种情况下&…

二叉树算法算法【二叉树的创建、插入、删除、查找】

一、原理 1.1、二叉排序树的插入 1.2、二叉树的删除 (1)删除度为0的节点,就是最后的叶子节点,直接删除就可以了. (2)删除度为1的节点,就是爷爷节点接收孙子节点。 (3)删…

什么软件可以约束员工摸鱼行为?「5款软件助力企业管控员工上班摸鱼!」

你的企业是否也在面临这些问题: 1.工作效率下降:频繁的分心会打断工作连贯性,降低任务完成的质量和速度。 2.团队协作受损:个别员工的低效可能导致整个团队进度滞后,影响项目按时交付。 3.资源浪费:非工…

Git —— 1、Windows下安装配置git

Git简介 Git 是一个免费的开源分布式版本控制系统,旨在处理从小型到 快速高效的超大型项目。 Git 易于学习,占用空间小,性能快如闪电。 它超越了 Subversion、CVS、Perforce 和 ClearCase 等 SCM 工具 具有 cheap local branching、 方便的暂…

【分布式架构幂等性总结】

文章目录 幂等性什么场景需要幂等设计?产生幂等性的原因解决重复操作,实现幂等性 幂等性 接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。比如:公交车刷卡&#xff0…

.NET8 Web 利用BAT命令 一键部署 IIS - CI-CD基础

1. Windows Server 前置准备 1.1 IIS安装好 1.2 .NET8 Sdk 运行时 安装 官方下载地址:https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0 1.3 创建一个.NET8 WebMvc项目 生成发布包 微软MVC这个项目模板直接创建,发布 2. 利用 BAT 来一键部署…

特效与样式(5)——Timetables的使用

第一次使用timetables做学校课表的开发,里面的门道东西挺多的,比我想的要复杂很多。包括我现在也只是实现了课表的初级效果。 主要是标题部分,数据部分,还有颜色控制部分。每个表格都需要一个控制颜色,每次写数据的时候…

hyperf注解,自定义注解

注解是 Hyperf 非常强大的一项功能,可以通过注解的形式减少很多的配置,以及实现很多非常方便的功能。 结构 建立注解 在app下建立Annotation注解文件夹 在Annotation下建立Jim.php注解 下面的的Annotation 和 Target是全局注解,所以不需…

Go学习笔记(一)语法

标准库文档:Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国 B站课程:8小时转职Golang工程师(如果你想低成本学习Go语言) 课程作者语雀(首页有更多内容):8小时转职Golang工程师 语雀 代码仓…

C语言基础(二十)

链表是一种常见的数据结构,通常用来存储一系列元素,每个元素由一个节点来表示。在链表中,每个节点包含两部分:数据元素本身和指向下一个节点的指针。这种结构使得链表中的元素在内存中不是连续存储的,而是通过指针连接…

可拖拽表单设计器都有哪些突出特点?

为了提高效率、降低开发成本,利用低代码技术平台的优势特点可以实现这一目标。究竟什么是低代码技术平台?都有哪些值得夸耀的特点和优势?今天,我们就带着这些问题,一起来了解低代码技术平台、可拖拽表单设计器的多个优…

香港站群服务器优势

香港站群服务器因其独特的地理位置和网络连接优势,在SEO优化、网站群管理和网络营销等方面受到广泛关注。其优势主要体现在以下几个方面,rak小编为您整理发布。 地理位置优越 连接亚洲国际市场:香港作为亚太地区的重要经济中心,具…

华为2024年秋招-结构与材料工程师-结构方向-机试题(四套)(每套四十题)

华为2024年招聘-结构与材料工程师-结构方向-机试题(四套)(每套四十题) 岗位——结构与材料工程师 岗位意向——结构 真题题目分享,完整版带答案(有答案和解析,答案非官方,未仔细校正&#xff…

详细了解如何设计和实现一个SSO系统?

一、SSO系统有什么好处? 1、用户角度:一次登录多次使用,无需记录多套用户名和密码,省事省心。 2、系统管理员角度:管理员只需要维护好一个统一的账号中心就可以了,方便 3、新系统开发角度:新系统…

(二十六)STL vector容器(动态数组)

动态数组vector是标准模版库(STL, Stardard Template Library)中的模版,它有着节省空间和使用方便的优势,我们用一个形象的例子来说明: 开学了,有40个学生来报名,想要存储每个同学的姓名&#…

数字验证:一文弄懂UVM的factory机制

如果我们用SystemVerilog构建验证平台,构建好了之后,想改变平台中的某个组件,例如将driver改成driver_new,我们需要重新定义一下driver_new,当然也可以直接从driver继承。但是我们还需要在driver对象例化的地方将drive…

PHP同城派送多区域运营配送小程序源码

🚚💨「同城派送多区域运营小程序」——让每一份需求快速触达!🌈🚀 🔥 开篇燃爆:同城生活新风尚,一键速达不是梦! Hey小伙伴们,你还在为找不到合适的同城服务…

WEB渗透Win提权篇-PowerUp

提权工具合集包(免费分享): 夸克网盘分享 往期文章 WEB渗透Win提权篇-提权工具合集-CSDN博客 WEB渗透Win提权篇-RDP&Firewall-CSDN博客 WEB渗透Win提权篇-MSSQL-CSDN博客 WEB渗透Win提权篇-MYSQL-udf-CSDN博客 WEB渗透Win提权篇-Acc…