外观
构建多任务学习(MTL)模型
Building Multi-task Learning (MTL) Models
大多数机器学习模型只在单个任务上训练。因此,许多人难以直观地理解一个模型如何能同时在多个任务上接受训练。

那么让我们在本章讨论它。再次强调,在 MTL 中,网络拥有若干共享层和任务特定部分。在反向传播过程中,梯度(gradient)会从所有分支累加而来,如下方动画所示:

我们通过一个简单的例子来理解其实现。假设我们希望模型以一个实数值(x)作为输入,并产生两个输出:
- sin(x)
- cos(x)
这可以表述为一个 MTL 问题。
首先,我们用 PyTorch 定义模型类。

- 我们在 self.model 中有一些全连接层 → 这些就是共享层。
- 此外,我们还有用于预测 sin(x) 和 cos(x) 的输出特定层。
- 接下来,我们在上面的类中定义前向传播:
- 首先,将输入通过共享层(self.model)。
- 共享层的输出再经过 sin 和 cos 两个分支。
- 我们返回两个分支的输出。

我们基本完成了。本实现的最后一步是训练模型。我们以均方误差(mean squared error)作为损失函数(loss function)。训练循环的实现如下:

- 我们将输入数据通过模型。
- 它返回两个输出,分别来自网络的两个部分。
- 我们用真实预测值计算各分支特定的损失值(loss1 和 loss2)。
- 我们将两个损失值相加,得到网络的总损失。
- 最后,我们执行反向传播过程。
至此,我们已经训练好了 MTL 模型。同时,我们得到的损失在持续下降,这表明模型正在被训练。这就是我们训练 MTL 模型的方式。你可以将同样的思路推广,构建任何你想要的 MTL 模型。
请记住,在彼此无关的任务上构建 MTL 模型不会产生好的效果。因此,“任务相关性”是所有 MTL 模型的关键组成部分,因为存在共享层。另外,每个任务也未必都要对整个网络的损失做出同等贡献。我们还可以为每个任务分配权重,如下所示:

权重可以基于任务的重要性。或者……有时候我也会使用动态任务权重,使其与该任务所达到的验证准确率(validation accuracy)成反比。

我采用这一技巧的理由是:在 MTL 场景下,有些任务可能较容易,而另一些则较困难。如果模型在训练中对某个任务已经达到很高的准确率,我们就可以稳妥地降低它的损失贡献,让模型把更多注意力放在第二个任务上。你可以在这里下载本章的 notebook:https://bit.ly/3ztY5hy。