Uncertainty Loss不确定损失
背景:用于multi-task learning多任务学习
论文:Multi-task learning using uncertainty to weigh losses for scene geometry and semantics.
过去:两个子任务的Loss简单加权和。权重是超参数,需要人力调参。
本文思想:权重也作为可训练参数。
具体来说是建模任务间的同方差不确定性 。
(1)多任务学习
多任务学习可以认为是归纳知识迁移,通过共享互补任务的域信息提升泛化性能。
(2) 不确定性
在概率模型中,有两类 不确定性:
-
认知不确定性(缺少训练数据)
-
偶然不确定性(数据不能解释信息)。
偶然不确定性又可以分为两个子类:
- 数据依赖(异方差)不确定性:依赖于输入数据的不确定性,体现在模型的输出上;
- 任务依赖(同方差)不确定性:不取决于输入数据,而是取决于不同的任务。
在多任务联合学习中,任务依赖不确定性能够表示不同任务间的相对难度。
推导省略:一般假设预测误差满足高斯分布,考虑两个任务的方差分别为 σ 1 \sigma_1 σ1, σ 2 \sigma_2 σ2,最小化损失可得:
1 σ 1 2 L 1 ( w ) + 1 σ 2 2 L 2 ( w ) + 2 log σ 1 + 2 log σ 2 \frac{1}{\sigma _1^2}L_1(w) + \frac{1}{\sigma _2^2}L_2(w) + 2\log \sigma_1+ 2\log \sigma_2 σ121L1(w)+σ221L2(w)+2logσ1+2logσ2
当一个任务的损失增大时,其权重参数缩小,反之亦然。 从而, 使某些任务尽可能优化,但却不影响其他任务的优化 。 将这两个参数作为训练参数带到多任务学习中进行训练。
这里有一个需要注意的点是:学习率不要设置太大,否则会造成梯度爆炸
Pytorch实现:
class UncertaintyLoss(nn.Module):
def __init__(self, v_num):
super(UncertaintyLoss, self).__init__()
sigma = torch.randn(v_num)
self.sigma = nn.Parameter(sigma)
self.v_num = v_num
def forward(self, *input):
loss = 0
for i in range(self.v_num):
loss += input[i] / (2 * self.sigma[i] ** 2)
loss += torch.log(self.sigma.pow(2).prod())
return loss
if __name__ == '__main__':
weighted_loss_func = UncertaintyLoss(2)
weighted_loss_func.to(device)
optimizer = torch.optim.Adam(
filter(lambda x: x.requires_grad, list(model.parameters()) + list(weighted_loss_func.parameters())),
betas=(0.9, 0.98), eps=1e-09)
if epoch < 10:
loss = loss1
else:
loss = weighted_loss_func(loss1, loss2)
参考链接:csdn