Multi-task learning is the attempt to learn tasks jointly — walking, running, jumping — instead of independently, by exploiting the shared dynamics underneath them.
The naive version just unions the datasets and sums the losses. That assumes independence and leaves the shared substructure on the table. The interesting versions decide where task information enters the network: late (multi-head, multiplicative gating) or early (shared conditioning), or everywhere (cross-stitching).
Two failure modes worth remembering. Negative transfer: one task hurts another, usually a data-distribution or capacity problem, not proof that no shared structure exists. Optimization interference: gradients from one task fight another; a single learning rate rarely suits all tasks at once.
The frame I keep: shared parameters learn the common factors, task-specific parameters learn the rest. Choosing where that split happens is the architecture decision. Full writeup with diagrams lives in the old blog archive; this note is the version I actually want to remember.