【人工智能】多目标融合算法(二):底部共享多任务模型(Shared-Bottom Multi-task Model)

【人工智能】多目标融合算法(二):底部共享多任务模型(Shared-Bottom Multi-task Model)

 

目录

一、引言

1.1 往期回顾

1.2 本期概要

二、Shared-Bottom Multi-task Model(SBMM)

2.1 技术原理

2.2 技术优缺点

2.3 业务代码实践

三、总结


一、引言

在朴素的深度学习ctr预估模型中(如DNN),通常以一个行为为预估目标,比如通过ctr预估点击率。但实际推荐系统业务场景中,更多是多种目标融合的结果,比如视频推荐,会存在视频点击率、视频完整播放率、视频播放时长等多个目标,而多种目标如何更好的融合,在工业界与学术界均有较多内容产出,由于该环节对实际业务影响最为直接,特开此专栏对推荐系统深度学习多目标问题进行讲述。

1.1 往期回顾

上一篇文章主要介绍了推荐系统多目标算法中的“样本Loss加权”,该方法在训练时Loss乘以样本权重实现对多种目标的加权,通过引导Loss梯度的学习方向,让模型参数朝着你设定的权重方向去学习。

1.2 本期概要

今天进一步深化,主要介绍Shared-Bottom Multi-task Model算法,该算法中文可译为“底部共享多任务模型”,该算法设定多个任务,每个任务设定多个目标,通过“Loss计算时调整每个任务的权重”,亦或是“每个塔单元内,多目标Loss计算时调整每个目标的权重”进行多任务多目标的调整。

二、Shared-Bottom Multi-task Model(SBMM)

2.1 技术原理

Shared-Bottom Multi-task Model(SBMM)全称为底层共享多任务模型,主要由底层共享网络、多任务塔、多目标输出构成。核心原理:通过构造多任务多目标样本数据,在Loss计算环节,将各任务Loss求和(或加权求和),对Loss求导(求梯度)后,逐步后向传播迭代。

底部网络:Shared-Bottom 网络通常位于底部,可以为一个DNN网络,或者emb+pooling+mlp的方式对input输入的稀疏(sparse)特征进行稠密(dense)化。多个任务塔:底部网络上层接N个任务塔(Tower),每个塔根据需要可以定义为简单或复杂的多层感知器(mlp)网络。每个塔可以对应特定的场景,比如一二级页面场景。多个目标:每个任务塔(Tower)可以输出多个学习目标,每个学习目标还可以像上一篇文章一样进行样本Loss加权。每个目标可以对应一种特定的指标行为,比如点击、时长、下单等。

2.2 技术优缺点

相比于上一篇文章提到的样本Loss加权融合法,以及后续文章将会介绍的MoE、MMoE方法,有如下优缺点:

优点:可以对多级场景任务进行建模,使得ctcvr等点击后转化问题可以被深度学习浅层参数共享,互相补充学习,任务相关性越高,模型的loss可以降低到更低

缺点: 跷跷板问题:任务没有好的相关性时,这种Hard parameter sharing会损害效果

2.3 业务代码实践

我们以小红书推荐场景为例,用户在一级发现页场景中停留并点击了“误杀3”中的一个视频笔记,在二级场景视频播放页中观看并点赞了视频。

跨场景多目标建模:我们定义一个SBMM算法结构,底层是一个3层的MLP(64,32,16),MLP出来后接一级场景Tower和二级场景Tower,一级场景任务中分别定义视频一级页“是否停留”、“停留时长”、“是否点击”,二级场景任务中分别定义“点击后播放时长”,“播放后是否点赞”

伪代码:

导入 pytorch 库 定义 SharedBottomMultiTaskModel 类 继承自 nn.Module: 定义 __init__ 方法 参数 (self, 输入维度, 隐藏层1大小, 隐藏层2大小, 隐藏层3大小, 输出任务1维度, 输出任务2维度): 初始化共享底部的三层全连接层 初始化任务1的三层全连接层 初始化任务2的三层全连接层 定义 forward 方法 参数 (self, 输入数据): 计算输入数据通过共享底部后的输出 从共享底部输出分别计算任务1和任务2的结果 返回任务1和任务2的结果 生成虚拟样本数据: 创建训练集和测试集 实例化模型对象 定义损失函数和优化器 训练循环: 前向传播: 获取预测值 计算每个任务的损失 反向传播和优化

PyTorch版本:

算法逻辑导入必要的库。定义一个类来表示共享底部和特定任务头部的模型结构。在初始化方法中定义共享底部和两个独立的任务头部网络层。实现前向传播函数,处理输入数据通过共享底部后分发到不同的任务头部。生成虚拟样本数据。定义损失函数和优化器。编写训练循环。进行模型预测。
import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset class SharedBottomMultiTaskModel(nn.Module): def __init__(self, input_dim, hidden1_dim, hidden2_dim, hidden3_dim, output_task1_dim, output_task2_dim): super(SharedBottomMultiTaskModel, self).__init__() # 定义共享底部的三层全连接层 self.shared_bottom = nn.Sequential( nn.Linear(input_dim, hidden1_dim), nn.ReLU(), nn.Linear(hidden1_dim, hidden2_dim), nn.ReLU(), nn.Linear(hidden2_dim, hidden3_dim), nn.ReLU() ) # 定义任务1的三层全连接层 self.task1_head = nn.Sequential( nn.Linear(hidden3_dim, hidden2_dim), nn.ReLU(), nn.Linear(hidden2_dim, output_task1_dim) ) # 定义任务2的三层全连接层 self.task2_head = nn.Sequential( nn.Linear(hidden3_dim, hidden2_dim), nn.ReLU(), nn.Linear(hidden2_dim, output_task2_dim) ) def forward(self, x): # 计算输入数据通过共享底部后的输出 shared_output = self.shared_bottom(x) # 从共享底部输出分别计算任务1和任务2的结果 task1_output = self.task1_head(shared_output) task2_output = self.task2_head(shared_output) return task1_output, task2_output # 构造虚拟样本数据 torch.manual_seed(42) # 设置随机种子以保证结果可重复 input_dim = 10 task1_dim = 3 task2_dim = 2 num_samples = 1000 X_train = torch.randn(num_samples, input_dim) y_train_task1 = torch.randn(num_samples, task1_dim) # 假设任务1的输出维度为task1_dim y_train_task2 = torch.randn(num_samples, task2_dim) # 假设任务2的输出维度为task2_dim # 创建数据加载器 train_dataset = TensorDataset(X_train, y_train_task1, y_train_task2) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) # 实例化模型对象 model = SharedBottomMultiTaskModel(input_dim, 64, 32, 16, task1_dim, task2_dim) # 定义损失函数和优化器 criterion_task1 = nn.MSELoss() criterion_task2 = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 训练循环 num_epochs = 10 for epoch in range(num_epochs): model.train() running_loss = 0.0 for batch_idx, (X_batch, y_task1_batch, y_task2_batch) in enumerate(train_loader): # 前向传播: 获取预测值 outputs_task1, outputs_task2 = model(X_batch) # 计算每个任务的损失 loss_task1 = criterion_task1(outputs_task1, y_task1_batch) loss_task2 = criterion_task2(outputs_task2, y_task2_batch) #print(f'loss_task1:{loss_task1},loss_task2:{loss_task2}') total_loss = loss_task1 + loss_task2 # 反向传播和优化 optimizer.zero_grad() total_loss.backward() optimizer.step() running_loss += total_loss.item() print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}') # 模型预测 model.eval() with torch.no_grad(): test_input = torch.randn(1, input_dim) # 构造一个测试样本 pred_task1, pred_task2 = model(test_input) print(f'任务1预测结果: {pred_task1}') print(f'任务2预测结果: {pred_task2}')

三、总结

本文从技术原理、技术优缺点方面对推荐系统深度学习多任务多目标“Shared-Bottom Multi-task Model”算法进行讲解,该模型使用深度学习模型对多个任务场景多个目标的业务问题进行建模,使得用户在多个场景连续性行为可以被学习,在现实推荐系统业务中是比较基础的方法,后面本专栏还会陆续介绍MoE、MMoE等多任务多目标算法,期待您的关注和支持。

如果您还有时间,欢迎阅读本专栏的其他文章:

【深度学习】多目标融合算法(一):样本Loss加权(Sample Loss Reweight)

【深度学习】多目标融合算法(二):底部共享多任务模型(Shared-Bottom Multi-task Model) 

Read more

Ollama下载模型太慢?试试国内HuggingFace镜像+LLama-Factory组合

Ollama下载模型太慢?试试国内HuggingFace镜像+LLama-Factory组合 在本地跑一个大模型,第一步不是写代码、调参数,而是——等它下载完。 这听起来有点荒诞,却是许多中国开发者的真实日常。当你兴致勃勃地打开终端,输入 ollama run llama3:8b,满心期待地准备开启微调之旅时,现实却给你泼了一盆冷水:进度条纹丝不动,网络连接频繁中断,几个小时过去连基础权重都没拉下来。 问题出在哪?根源就在于——Ollama 默认从 HuggingFace 官方仓库拉取模型,而这个服务器远在海外。对于国内用户来说,这无异于“越洋取经”,不仅速度慢如龟爬,还常因网络波动导致失败重试,白白浪费时间和算力资源。 但其实,我们完全不必硬扛这条路。真正聪明的做法是:绕开公网瓶颈,借助国内镜像高速获取模型 + 使用 LLama-Factory 实现低门槛、高效率的本地微调。这套组合拳不仅能让你把“等待下载”的时间省下来喝杯咖啡,还能让7B甚至13B级别的模型在一张消费级显卡上顺利训练起来。 镜像加速:别再用裸连 HuggingFace

【AIGC行业前沿】2026年2月AIGC行业模型发布以及主要前沿资讯

目录 1. 阿里Qoder发布Qwen-Coder-Qoder 2. Kimi与南大发布SimpleSeg赋能模型像素感知 3. 字节研究团队发布ConceptMoE提升AI推理 4. 阶跃星辰发布并开源模型Step 3.5 Flash 5. 智谱发布并开源OCR模型GLM-OCR 6. xAI正式发布Grok Imagine 1.0视频模型 7. 优必选开源具身智能大模型Thinker 8. 通义千问发布开源编程模型Qwen3-Coder-Next 9. OpenAI宣布GPT-5.2系列模型提速40% 10. OpenBMB发布多模态模型MiniCPM-o 4.5 11. ACE Studio与StepFun联合发布开源音乐模型ACE-Step 1.5 12. Ai2发布轻量级开源编码模型SERA-14B 13. 上海AI实验室推出万亿参数多模态科学推理模型Intern-S1-Pro 14. Mistral AI开源40亿参数实时语音模型Voxtral Mini 4B Realtime 2602 15. 快手可灵发布可灵3.0 1

【Model】【llm38】Llama API - 示例

【Model】【llm38】Llama API - 示例

案例目标 Llama API是一个托管的Llama 2 API服务,支持函数调用功能。本案例展示了如何通过LlamaIndex集成Llama API,实现基本的文本补全、对话交互、函数调用和结构化数据提取功能。Llama API为开发者提供了一个便捷的方式来使用Llama 2模型,无需本地部署,可以直接通过API调用模型服务,大大简化了使用流程。同时,该API支持函数调用功能,使得模型能够与外部工具和服务进行交互,扩展了应用场景。 环境配置 1. 安装依赖 安装必要的依赖包: %pip install llama-index-program-openai %pip install llama-index-llms-llama-api !pip install llama-index 2. 获取API密钥 要运行此示例,您需要从Llama API官网获取API密钥。 3. 导入库并设置API密钥 导入必要的库并设置API密钥: from llama_index.llms.llama_api import LlamaAPI

AIGC实战——CycleGAN详解与实现

AIGC实战——CycleGAN详解与实现

AIGC实战——CycleGAN详解与实现 * 0. 前言 * 1. CycleGAN 基本原理 * 2. CycleGAN 模型分析 * 3. 实现 CycleGAN * 小结 * 系列链接 0. 前言 CycleGAN 是一种用于图像转换的生成对抗网络(Generative Adversarial Network, GAN),可以在不需要配对数据的情况下将一种风格的图像转换成另一种风格,而无需为每一对输入-输出图像配对训练数据。CycleGAN 的核心思想是利用两个生成器和两个判别器,它们共同学习两个域之间的映射关系。例如,将马的图像转换成斑马的图像,或者将苹果图像转换为橙子图像。在本节中,我们将学习 CycleGAN 的基本原理,并实现该模型用于将夏天的风景图像转换成冬天的风景图像,或反之将冬天的风景图像转换为夏天的风景图像。 1. CycleGAN 基本原理 CycleGAN 是一种无需配对的图像转换技术,它可以将一个图像域中的图像转换为另一个图像域中的图像,而不需要匹配这两个域中的图像。它使用两个生成器和两个判别器,其中一个生成器将一个域中的图像