DL0070 Multi-Task Loss Balancing

How would you design a loss for multi-task learning when the tasks have very different scales?

Answer

Start from the failure mode: with a naive sum L = \sum_i L_i, each task contributes gradient in proportion to its loss scale, so a depth-regression MSE sitting near 200 drowns out a segmentation cross-entropy sitting near 1, and the shared trunk optimizes the loud task while the quiet ones stall. The fix comes in three tiers. First, put the losses on a common scale by dividing each by a fixed or running estimate of its magnitude, such as its initial value. Second, learn the weights: Kendall et al.’s uncertainty weighting attaches a trainable \sigma_i per task and minimizes \sum_i L_i / (2\sigma_i^2) + \log \sigma_i, derived from Gaussian and categorical likelihoods, so noisy tasks are down-weighted automatically while the \log \sigma_i term stops \sigma_i from blowing up. Third, when scales are balanced but gradient directions still conflict, move to gradient-level methods: GradNorm tunes the task weights so each task’s gradient norm on the shared trunk approaches a common scale adjusted by its relative inverse training rate, so tasks that are learning slowly get pushed harder, and PCGrad projects away mutually conflicting components.

(1) Scale Equals Loudness: task i‘s gradient share scales with the units of L_i, so the unweighted sum is an implicit weighting set by arbitrary unit choices; expressing depth in millimeters instead of meters multiplies its MSE by 10^6 and hands it the entire gradient budget.
(2) Uncertainty Weighting: treat \sigma_i as task i‘s observation noise; the weight 1/(2\sigma_i^2) falls as noise grows while the \log \sigma_i penalty (the likelihood’s normalizing constant) rises, so the optimum is a genuine trade-off learned by gradient descent alongside the network weights.
(3) Magnitude Is Not Direction: scale balancing fixes how loudly tasks speak, not whether they agree; when task gradients point in opposing directions (negative transfer), gradient-space methods such as GradNorm or PCGrad are the right lever.

Grouped bar chart on a log scale of illustrative gradient norms on the shared trunk for segmentation, depth, and normals tasks: unweighted bars are 1.1, 160, and 0.8, while uncertainty-weighted bars are 0.9, 1.0, and 0.7

Figure 1: Illustrative three-task trunk, gradient norms on a log scale: unweighted, the depth MSE contributes over 100x the others; once each loss carries a learned 1/(2\sigma_i^2) weight, the three contribute comparably.

The uncertainty objective is not ad hoc. Modeling regression noise as p(y \mid f(x)) = \mathcal{N}(f(x), \sigma^2) gives the negative log-likelihood \|y - f(x)\|^2 / (2\sigma^2) + \log \sigma per task, up to constants; classification slots in through a scaled softmax likelihood whose approximation yields the analogous weight 1/\sigma^2 (without the factor 2) alongside the same \log \sigma penalty. Two properties matter in practice: \sigma_i is learned by the same optimizer as the network, so balancing needs no manual grid search; and the \log \sigma_i term keeps the objective honest, because without it every \sigma_i would grow without bound, all task weights would collapse to zero, and nothing would be learned. Most implementations optimize s_i = \log \sigma_i^2 and compute e^{-s_i} L_i + s_i for numerical stability.

Two panels against task uncertainty sigma: top shows the task weight 1/(2 sigma^2) collapsing on a log scale as sigma grows from 0.25 to 4; bottom shows the penalty log sigma rising over the same range

Figure 2: The learned trade-off: as a task’s noise \sigma grows, its weight 1/(2\sigma^2) collapses while the penalty \log \sigma rises, so the optimizer cannot silence a noisy task for free.

Mathematical Formulation:
L_{\mathrm{naive}} = \sum_{i=1}^{T} L_i
L_{\mathrm{total}} = \sum_{i=1}^{T} \left( \frac{1}{2\sigma_i^2}\, L_i + \log \sigma_i \right)

Where:

  • L_i is the loss of task i (cross-entropy for segmentation, MSE for depth) and T the number of tasks sharing the trunk.
  • \sigma_i is a learned per-task scalar modeling homoscedastic (task-level, input-independent) observation noise, initialized at 1 and trained by the same optimizer as the weights.
  • 1/(2\sigma_i^2) is the derived task weight and \log \sigma_i the likelihood’s normalizing term that penalizes inflating \sigma_i; in code, parameterize s_i = \log \sigma_i^2 and optimize e^{-s_i} L_i + s_i instead.
MethodWhat It BalancesExtra CostWhen to Reach for It
Fixed Weights (Grid Search)Loss scales, set by handSearch cost grows fast with task countTwo tasks and plenty of compute
Loss NormalizationLoss magnitudes via running scale estimatesNegligibleQuick baseline before anything fancier
Uncertainty Weighting (Kendall)Loss weights via learned sigma per taskOne extra scalar per taskDefault starting point for shared-trunk training
GradNormGradient norms toward a common scale by training rateExtra backward bookkeeping each stepTasks learning at very different speeds
PCGradConflicting gradient directionsPer-task gradients every stepNegative transfer between tasks

Login to view more content


Log in to track your progress

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *