# 多任务模型
## 什么是多任务模型?
多任务学习(Multi-Task Learning)是机器学习的一个子领域,其中同时解决多个学习任务。与单独训练模型相比,MTL利用各任务之间的共性和差异,来提高特定任务模型的**学习效率**和**预测准确性**。
## 为什么采用多任务模型?
- 减少多个不同任务模型的维护成本。每个任务的模型都有自己的一套pipeline,数据收集、数据处理、离线训练、近线训练、线上服务。如果将多个子任务模型合并成一个多任务模型,可以大大减少维护成本。
- 参数共享。通过共享embedding参数,可以减少参数规模,节省机器资源,同时可以帮助冷启动模型快速收敛。
- 解决样本选择偏差问题。用数据更多的任务(ctr)指导学习数据较少的任务(cvr)。
- 加快线上推理。只请求一次模型就可以获得各个任务结果,降低线上延时。
- 增加模型泛化能力。对某任务而言,其他任务的学习都会对该任务有正则化效果。
## 什么是参数共享?
<img alt="参数共享" src="../../md/model/mtl/参数共享.jpeg" width="1798"/>
工业界离散特征(ID类等)往往会转换成embedding,而推荐模型中embedding部分就占据着相当大的参数规模和计算量。做多任务时,如果各任务都需要embedding映射,那么每个任务都有一个独立的sparse映射表会非常的占用资源,所以底层参数(embedding、nn)共享在多任务学习中很是常见。
- 硬参数共享(Hard Parameter Sharing)。模型的主体部分共享参数,输出结构任务独立(一般是最后一层区分sigmoid/softmax输出),能降低模型在单个任务上过拟合的风险。适合处理有较强相关性的多任务,遇到弱相关任务时常常表现很差。
- 软参数共享(Soft Parameter Sharing)。不同任务采用独立模型,但是模型参数彼此约束,每个任务的网络都可以访问其他任务对应网络中的信息,例如表示、梯度等。软共享机制非常灵活,不需要对任务相关性做任何假设,但是由于为每个任务分配一个网络,常常需要增加很多参数。
## 怎么调权重?
### 1、根据初始状态设置权重
在没有任何任务先验的情况下,总损失可以设置为所有任务损失的算术平均值,即$w_k=\frac{1}{k}$。然而每个任务的损失函数的数量级和物理量纲都不同,因此可以使用损失函数初始值的倒数进行**无量纲化**:
$$w_k=\frac{1}{\mathcal{L}_k^{(0)}}$$
这样得到的权重具有**缩放不变性(Scale Invariance)**,可以使得每个任务的损失在无量纲化后具有相同的重要性,从而平衡多个任务的训练。损失函数初始值既可以取前几个epoch的loss(对于二分类任务是交叉熵损失)平均估计:
```python
loss_weights={"k1": 1.0 / np.mean([loss_k1_epoch_1, loss_k1_epoch_2]), "k2": 1.0 / np.mean([loss_k2_epoch_1, loss_k2_epoch_2])}
```
### 2、根据先验状态设置权重
若能够预先获取数据集的标签信息,则可以根据其统计值构造损失函数的先验状态 $L^{prior}_k$ ,并用作权重:
$$w_k = \frac{1}{\mathcal{L}^{\text{prior}}_k}$$
先验状态可以代表当前任务的初始难度。
- 分类任务中统计每个类别的出现频率为 $[p_1,\cdots,p_k ]$ ,则先验状态 $\mathcal{L}^{\text{prior}}_k = − \sum^K_kp_klogp_k$
```python
def calculate_prior_loss(y_true):
prior_loss = 0
counter = Counter(y_true)
pprobs = [freq / y_true.shape[0] for freq in counter.values()]
for p in pprobs:
if p > 0:
prior_loss -= p * math.log(p)
return prior_loss
```
- 回归任务的中统计所有样本标签的期望$\mu = \Bbb{E}_y[y]$,则先验状态 $\mathcal{L}_k^{\text{prior}}=\Bbb{E}_y[\|y-\mu\|^2]$
```python
def calculate_prior_loss(labels):
mu = np.mean(labels)
prior_loss = np.mean(np.square(labels - mu))
return prior_loss
```
### 3、根据实时梯度设置权重
根据初始状态和先验状态设定的权重都是固定值,更合理的方案是根据训练过程中的实时状态动态地调整权重:
$$w_k^{(t)}=\frac{1}{sg(\mathcal{L}_k^{(t)})}$$
- $sg(\cdot)$: stop gradient,即在反向传播时不计算其梯度
- ∇(nabla): 梯度
- θ(theta): 模型的参数,即```model.trainable_variables```
在该权重设置下,虽然每个任务的损失函数恒为 1 ,但梯度不恒为 0。
此时总损失函数等价于每个任务的损失函数的**几何平均值**
```python
def custom_dynamic_weight_loss(y_true, y_pred):
# 根据模型输出和真实标签计算基本损失(这里假设使用交叉熵损失)
base_loss = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true, y_pred))
# 计算权重
loss_gradient = tf.gradients(base_loss, y_pred)[0]
dynamic_weight = 1.0 / tf.stop_gradient(loss_gradient)
return dynamic_weight * base_loss
with tf.GradientTape() as tape:
outputs = model(inputs)
total_loss = 0.0
for i, out in enumerate(outputs):
this_loss = custom_dynamic_weight_loss(y_true=y_true[i], y_pred=out)
total_loss += this_loss
grad = tape.gradient(total_loss, model.trainable_variables)
optimizer.apply_gradients(grads_and_vars=zip(grad, model.trainable_variables))
```
### 4、根据实时梯度的模长设置权重
同样是根据实时梯度设置权重,但是考虑采用损失函数梯度的模长来替代损失本身,以构造权重:
$$w_k^{(t)} = \frac{1}{sg(||\nabla_{\theta} \mathcal{L}_k^{(t)}||)}$$
因此该权重设置同时具有缩放与**平移不变性(Translation Invariance)**,等价于将每个任务损失的梯度进行**归一化**后,再把梯度累加起来参与梯度更新。
```python
def custom_dynamic_weight_loss(y_true, y_pred):
# 根据模型输出和真实标签计算基本损失(这里假设使用交叉熵损失)
base_loss = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true, y_pred))
# 计算权重
loss_gradient = tf.gradients(base_loss, y_pred)[0]
dynamic_weight = 1.0 / tf.stop_gradient(tf.sign(tf.norm(loss_gradient)))
return dynamic_weight * base_loss
```
### 5、[Uncertainty](https://arxiv.org/abs/1705.07115v3)
查看代码:[uncertainty_weight_loss_layer](../layer/uncertainty_weight_loss_layer.py)
作者从不确定性(uncertainty)的角度出发,设计了一种自动设置任务权重的方法。在深度学习建模中,通常会引入两种形式的不确定性:
- 认知不确定性(epistemic uncertainty):模型本身的不确定性,表示由于缺乏训练数据导致模型认知不足,可以通过增加训练数据来降低
- 偶然不确定性(aleatoric uncertainty):表示由数据无法解释的信息导致的不确定性,可以通过增强观察所有解释变量的能力来降低
其中偶然不确定性又可以分成两个子类:
- 异方差不确定性(heteroscedastic uncertainty):又叫数据依赖(data-dependent)的不确定性,依赖于输入数据的不确定性,表现在模型的输出上
- 同方差不确定性(homoscedastic uncertainty):又叫任务依赖(task-dependent)的不确定性,不依赖于输入数据,而是依赖于任务的不确定性,该不确定性对所有输入数据保持不变,但在不同任务之间变化
对于多任务学习,通常是对于同样的输入数据集,产生不同任务的输出结果。如本文中作者研究的是给定一张单目图像,同时进行语义分割、实例分割和深度估计任务。因此可以用同方差不确定性作为多任务学习中不同人物的权重指标。
## share bottom
查看代码
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
ryc-note-note-pth (264个子文件)
.gitignore 33B
.gitignore 7B
.gitignore 7B
column_config_deepfm_fe.json 589KB
column_config_mmoe_sequence.json 202KB
column_config_mmoe_base.json 202KB
column_config_pppnet_20240620.json 194KB
column_config_deepfm_oaid.json 126KB
column_config_deepfm_base.json 126KB
column_config_deepfm_base_pth1.json 126KB
fe_config_new.json 120KB
column_config_deepfm_base_ctr.json 117KB
column_config_pppnet_20240626.json 115KB
column_config_deepfm_base.json 115KB
fixed_feature_config.json 73KB
feature_cluster.json 2KB
tables.json 459B
README.md 9KB
README.md 9KB
README.md 4KB
README.md 4KB
README.md 2KB
README.md 2KB
README.md 2KB
README.md 2KB
README.md 1KB
README.md 1KB
README.md 30B
README.md 30B
README.md 8B
README.md 8B
README.md 0B
README.md 0B
input.py 47KB
new_input.py 46KB
train.py 46KB
train.py 45KB
data.py 42KB
data.py 42KB
fibinet_layer.py 33KB
io_config.py 33KB
io_config.py 32KB
inputs.py 30KB
tools.py 30KB
tools.py 30KB
inputs.py 29KB
zhuque.py 24KB
zhuque.py 24KB
tools.py 23KB
data.py 21KB
hinet.py 20KB
mind【undone】.py 18KB
mind【undone】.py 18KB
train_config_mmoe_base.py 17KB
metrics.py 16KB
star.py 15KB
star.py 15KB
metrics.py 14KB
evaluate.py 13KB
feature.py 13KB
fit.py 13KB
dcnv2_dien.py 12KB
hierarchical_information_extraction.py 12KB
hierarchical_information_extraction.py 12KB
dfn.py 12KB
dfn.py 12KB
ple.py 12KB
ple.py 12KB
finalmlp_dien.py 11KB
fibinet.py 11KB
fibinet.py 11KB
train_config_deepfm_base.py 11KB
dien.py 10KB
dien【undone】.py 10KB
dien【undone】.py 10KB
embedding.py 10KB
finalmlp_din.py 10KB
model.py 10KB
din.py 10KB
autoint.py 10KB
autoint.py 10KB
dcnv2.py 10KB
pnn.py 10KB
pnn.py 10KB
gdcn_dien.py 9KB
autoint.py 9KB
dcnv2.py 9KB
dcnv2.py 9KB
escm2.py 9KB
escm2.py 9KB
finalmlp.py 9KB
auto_upload.py 8KB
metaheac.py 8KB
metaheac.py 8KB
dcn.py 8KB
dcn.py 8KB
dcn.py 8KB
upload_model.py 8KB
fibinet_din.py 8KB
din.py 8KB
共 264 条
- 1
- 2
- 3
资源评论
tomlvyihua1
- 粉丝: 6
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功