在 Pytorch 中优化具有多任务目标的神经网络

Bra*_*roy 3 python deep-learning pytorch

在深度学习中,您通常有一个希望优化的目标(例如图像识别)。然而,在我的领域(自然语言处理),我们看到了多任务训练的兴起。例如,在单个系统中的下一个句子预测和句子分类。

我了解如何构建前向传递,例如分类任务(obj1)和回归任务(obj2)

class Net(nn.Module):
    def __init__():
        super().__init__()
        self.linear = Linear(300, 200)
        self.obj1 = Linear(200, 5)
        self.obj2 = Linear(200, 1)

    def forward(inputs):
        out = self.linear(inputs)
        out_obj1 = self.obj1(out)
        out_obj2 = self.obj2(out)
        return out_obj1, out_obj2
Run Code Online (Sandbox Code Playgroud)

但问题就变成了,如何优化这一点。您是否分别对这两个损失进行向后传递?或者将它们减少为单一损失(例如总和、平均值)?是否有一种通常用于多任务学习的方法?

为了跟进这一点,也许有人甚至会认为不同层的参数需要不同的优化器。在这种情况下,我认为损失必须单独处理。

Jos*_*tar 7

它更简单,您可以同时优化所有变量而不会出现问题。只需使用各自的标准计算两个损失,然后将它们添加到单个变量中:

total_loss = loss_1 + loss_2
Run Code Online (Sandbox Code Playgroud)

并调用.backward()这个总损失(仍然是张量),对于两者来说都非常有效。您还可以对损失进行加权,以更加重视其中一个而不是另一个。

查看PyTorch 论坛以获取更多信息。

  • 可能是这样,这就是为什么我建议加权求和。然而,如果这两项任务是相关的,并且可以通过一起训练来改进,那么两者都可能会减少损失。另外,请确保两个损失的大小相同,否则可能会发生您所要求的情况,即较大的损失会“抵消”较小的任何可能的变化。 (2认同)
  • @Bram Vanroy 对于总和案例,假设您有损失 L = L1 + L2。考虑权重 W 的梯度。通过微分的线性,您显然可以得到 gradW = dL/dW = dL1/dW + dL2/dW。相反,如果您首先计算 L1 的梯度,则有 gradW = dL1/dW,然后对 L2 进行额外的向后传递,将 L2 的梯度累积在现有梯度之上,从而得到 gradW = gradW + dL2/dW = dL1/ dW + dL2/dW = dL/dW。这与求和情况相同,但代价是额外的向后传递。 (2认同)
  • 无耻插件:我写了一个小辅助库,可以更轻松地组合多任务层和损失并将它们组合起来。请随意查看:[torchMTL](https://github.com/chrisby/torchMTL)。 (2认同)