多任务学习,找到“忽略”某些样本的损失函数

数据挖掘 神经网络
2021-09-30 05:24:52

我正在训练一个具有 1 个输入和 3 个输出的卷积神经网络:一个分类和 2 个回归输出。

我最初使用了 3 个单独的模型,但我发现将第一个和第二个损失函数组合到一个模型中可以提高两者的准确度/rmse。我正在应用多任务学习。

现在我正在尝试将第 3 个损失函数与前 2 个损失函数合并到同一个模型中。

我的挑战是,第三个损失函数仅在第一个分类器识别出正样本时才有效(它是测量识别样本的回归输出)。这些标签在训练时是已知的。

我尝试过:

  1. 标准化标签并为所有负样本的第三次回归估算一个 0 值。在某些情况下,这种方法偏向于 0,所以我把它扔掉了。
  2. 在第 1 次和第 2 次损失的所有样本之间交替训练,并且仅使用所有 3 个损失函数的总和的正样本。这里的结果好坏参半,但第 3 个损失函数的表现似乎比它在其自己的单独模型中的表现更差。

问题:

我正在考虑如何重新构建损失函数(目前是 L2 损失),以便将 0 值视为不相关(例如,当标签为 0 时不传播梯度)。

有什么想法吗?

2个回答

我似乎有一个可行的解决方案,使用这个对平方损失的小调整:

大号=(是的-是的^)2(是的是的+ε)

在哪里是的是标签和是的^是预测,并且ε=1e-6 是为了避免除以零错误(它是〜32位精度内的最小数字)

在张量流中:

epsilon = 1e-6
loss = tf.reduce_sum(
          tf.mul(tf.square(prediction - label),
                 tf.div(label, label + epsilon))
)

当标签为 0 时,第二项为 0(例如,损失为 0,并且没有为该样本添加梯度),当标签不为零时,它会四舍五入到 1 或足够接近。只要标签的范围不超过 0,这应该可以工作,如果默认情况下不是这样,那就是缩放标签的简单问题。

比我在 2017 年发布的更简单的答案是将损失函数乘以 {1,0} 掩码。当你乘以 0 因为时,这将使梯度归零0dx = 0,而当乘以 1 因为时,它不会改变任何东西1dx = dx{1,0} 掩码是一个常数,与输入到模型的标签相同。