在多目标多任务训练的网络中,如果最终的loss为有时为多个loss的加权和,例如 loss = a*loss_x+b*loss_y+c*loss_y+... ,这个问题在微信视频号推荐比赛里也存在。任务需要对视频号的某个视频的收藏、点击头像、转发、点赞、评论、查看评论等进行多任务建模,也就产生了多个loss。
这里介绍在这次实践过程中测试过的几个方法。
1.GradNorm
GradNorm:ω(t+1)=ω(t)+λβ(t),该方法主要在对各损失函数权重的梯度进行处理,利用梯度更新公式动态更新权重ω。
2.Multi-Task Learning as Multi-Objective Optimization
在处理多个loss时,引入Pareto用一次训练的方式将问题转化为求取Pareto最优解。有兴趣的可以看看原文:https://arxiv.org/pdf/1810.04650.pdf
3.Multi-task likelihoods
最简单的多任务Loss的线性加权:
对于分类任务,经常通过softmax函数产生概率向量中抽取样本来构造多任务的最大似然函数。
class MultiLossLayer(nn.Module):
"""
计算自适应损失权重
implementation of "Multi-Task Learning Using Uncertainty to Weigh Losses for Scene Geometry and Semantics"
"""
def __init__(self, num_loss):
super(MultiLossLayer, self).__init__()
self.sigmas_dota = nn.Parameter(nn.init.uniform_(torch.empty(num_loss), a=0.2, b=1.0), requires_grad=True)
def get_loss(self, loss_set):
factor = torch.div(1.0, torch.mul(2.0, self.sigmas_dota))
loss_part = torch.sum(torch.mul(factor, loss_set))
regular_part = torch.sum(torch.log(self.sigmas_dota))
loss = loss_part + regular_part
return loss
4.玄学调参
上面说了太多方法调参,来点手动的经验吧。最简单的方法如下:
参考资料