1. 多任务学习的“甜蜜烦恼”:当多个任务一起学习时,我们到底在烦什么?
如果你尝试过训练一个能同时干好几件事的模型,比如让一个神经网络既能识别图片里有什么物体(分类任务),又能预测这个物体在画面中的精确位置(回归任务),那你大概率经历过一种“左右为难”的困境。模型训练日志里,几个任务的损失值(Loss)就像在赛跑,但它们的“起跑线”和“速度”完全不一样。可能分类任务的损失值稳稳地停留在0.5左右,而回归任务的损失值却动不动就飙到好几百。这时候,如果你简单地把两个损失加起来,让模型去优化这个总和,会发生什么?
那个损失值大的任务(比如回归任务)会立刻成为“班里的尖子生”,吸引了优化器(比如Adam)绝大部分的注意力。模型会拼命地去降低回归任务的损失,因为它对总损失的“贡献”太大了。结果就是,分类任务可能被彻底“忽视”,学得一塌糊涂。反过来,如果你强行给分类任务加一个很大的权重,回归任务又可能学不好。这就是多任务学习最经典的痛点:如何给不同任务分配合适的权重,让它们能和谐共进,而不是互相拖后腿。
传统的做法是什么?手动调参,或者叫“网格搜索”。你可能会定义一个超参数 λ,把总损失写成 总损失 = λ * 分类损失 + (1-λ) * 回归损失。然后,你就开始了漫长的“炼丹”过程:λ=0.1试试,λ=0.5试试,λ=0.9试试……每次都要重新训练模型,观察两个任务的性能,像个老中医一样凭感觉调整。这个过程不仅耗时费力,而且极度不优雅。更糟糕的是,这个最优的 λ 可能随着训练过程动态变化,初期回归任务难,权重应该大点?后期分类任务进入瓶颈,需要更多关注?手动调参根本无法捕捉这种动态性。
我当年在一个自动驾驶感知项目里就踩过这个坑。我们需要模型同时输出车辆检测框(回归)和车辆类型(分类)。一开始手动设的权重,在白天场景下还行,一到夜晚光照不足的场景,回归损失剧烈波动,直接把分类任务带崩了。那段时间,团队里最常听到的对话就是:“你觉得分类权重再加0.1怎么样?”“昨晚跑了一夜,好像又过拟合了……” 这种依赖经验和运气的调参,严重拖慢了迭代效率。
所以,我们迫切需要一种更聪明的方法。它应该能自动地、动态地在训练过程中评估:“嘿,现在哪个任务更难、更不确定?我们应该多信任哪个任务的结果?” 然后据此分配学习精力。这就是“不确定性加权损失”闪亮登场的背景。它不是给每个任务一个固定的、人定的权重,而是让模型自己学会报告:“对于当前这个输入,我对自己在任务A上的预测有多不确定?” 然后,用这个“不确定度”来指导权重的分配。不确定度高的任务,说明模型自己都没啥信心,它的损失信号可能噪音比较大,那我们在更新参数时就应该少听它的一点;反之,模型很确信的任务,它的损失信号就更可靠,权重应该大一些。这听起来是不是合理多了?
2. 不确定性加权损失:让模型自己“报告”难度,动态分配学习精力
那么,这个让模型自己报告不确定性的魔法,具体是怎么实现的呢?核心思想其实来源于一个概率视角:我们把模型的预测看作一个概率分布,而不仅仅是输出一个值。对于回归任务,我们不再只预测一个值 y,而是预测一个高斯分布,即均值 μ 和方差 σ²。均值 μ 是我们预测的值,而方差 σ² 就代表了模型对这个预测的不确定性。σ² 越大,表示模型越不确定,可能因为数据模糊、样本少见等原因。
对于分类任务,虽然输出通常是类别概率,但我们可以类似地引入一个“温度”参数或直接对概率分布进行建模,来衡量预测的置信度。不过,在那篇经典的论文《Multi-Task Learning Using Uncertainty to Weigh Losses》中,作者提出了一种更统一和简洁的建模方式:为每个任务的损失函数引入一个可学习的不确定性参数 σ。
这个 σ 不是一个固定的超参数,而是模型参数的一部分,在训练过程中和其他权重一起被优化。它的作用就像一个“自动音量调节器”。我们来看一下改造后的总损失函数形式(以两个任务为例):
总损失 = (1/(2*σ₁²)) * L₁(θ) + (1/(2*σ₂²)) * L₂(θ) + log(σ₁) + log(σ₂)
别被这个公式吓到,我们来拆解一下它的“小心机”:
-
(1/(2*σ²)) * L(θ):这是核心的加权项。σ 是可学习的不确定性。注意,损失 L(θ) 被除以了 σ²。这意味着什么?- 如果某个任务的 σ 很大(模型认为这个任务不确定性高),那么
1/σ²就会很小。这会降低该任务损失 L(θ) 在总损失中的贡献。优化器在更新参数时,就不会太“在意”这个任务的信号
- 如果某个任务的 σ 很大(模型认为这个任务不确定性高),那么

5万+

被折叠的 条评论
为什么被折叠?



