"For years they cut me from a subsequence by hand: a mean here, a spectral peak there, a count of zero crossings, each feature a guess about what mattered. Now they ask me to discover for myself what a window of the world is about, and to say it in sixty-four numbers that every downstream task can read. I am a compression of recent history into a point, and I am still searching for which directions of myself carry the meaning."
An Embedding Vector Searching for the Meaning of a Subsequence
A representation is a learned map that turns a raw window of a time series into a fixed-length vector chosen so that the structure a downstream task needs is exposed, often as a simple linear function of that vector. Write the encoder as $f_\theta: \mathcal{X} \to \mathbb{R}^d$, sending a window $\mathbf{x} \in \mathcal{X}$ to an embedding $\mathbf{z} = f_\theta(\mathbf{x})$; the promise of representation learning is that one encoder, trained once, serves forecasting, classification, anomaly detection, and retrieval, each of which becomes a light readout on top of $\mathbf{z}$ rather than a model trained from raw data. This reframes the central question of Part IV. Parts II and III built models that map inputs directly to a single target; here we separate the pipeline into a reusable encoder and a swappable head, and ask what makes the encoder good independent of any one task. The answer has a classical root: principal component analysis and the dynamic factor models of Section 6.4 are already representation learners, linear ones, and the nonlinear encoders of this chapter generalize exactly that idea. This section defines what a representation is and why we learn rather than hand-craft one, states the properties that make a representation good for time series specifically (invariance to phase, scale, and warping; smoothness; disentanglement; linear separability), draws the bridge from linear to learned encoders, sets out how we evaluate a representation by a linear probe and by transfer, and closes with a from-scratch encoder trained by a simple pretext task and read out by a linear probe, then the same pipeline in a few library lines. You leave able to say precisely what you are asking an encoder to produce and how you will know whether it succeeded. (Figure 16.1.0 pictures the idea: a tangled raw signal traded for a tidy map of coordinates.)
Part III ended with temporal foundation models in Chapter 15, models pretrained once on enormous and diverse time-series corpora and then applied, often with little or no fine-tuning, to tasks they never saw during training. That capability rests on an idea we have used implicitly but never isolated: that a network can learn a representation, an internal encoding of an input that is useful far beyond the objective it was trained on. Part IV makes representation learning the explicit subject. This first section lays the conceptual groundwork: what a representation is, what properties make one good, how the classical linear methods of Part II already learned representations, and how we measure the quality of a learned encoding. The sections that follow build on it. Section 16.2 designs the self-supervised pretext tasks that train encoders without labels; the remaining sections of the chapter develop contrastive learning and the temporal-specific objectives that this groundwork motivates.
The reason to elevate representations to a first-class object is economic and scientific at once. Economically, labeled time-series data is scarce and expensive (a cardiologist annotating arrhythmias, an engineer labeling machine faults) while raw unlabeled series are abundant, so an encoder trained on the cheap abundant data that then makes every labeled task easy is enormous leverage. Scientifically, a good representation is a statement about what is invariant and what is informative in a domain: if shifting a window in time does not change its label, the representation should be invariant to that shift, and forcing that invariance is how we inject prior knowledge about temporal structure into a learned system. The whole of Part IV is an elaboration of these two motivations, and they recur in every section.
The four competencies this section installs are these: to define an encoder $f_\theta: \mathcal{X} \to \mathbb{R}^d$ and a downstream linear probe, and to articulate why a vector-valued representation serves many tasks where a single end-to-end model serves one; to name the properties of a good representation and to specialize them to time series through the phase, scale, and warping invariances; to see PCA and dynamic factor analysis as linear representation learning and the nonlinear encoder as their generalization (a thread we follow from Section 6.4 forward); and to evaluate a representation by linear-probe accuracy, transfer, and clustering, the train-once-reuse-everywhere paradigm that Chapter 15 pushed to its limit. These are the load-bearing skills for the rest of Part IV.
1. What a Representation Is and Why We Learn One Beginner
A representation is a re-description of data in coordinates chosen to make subsequent work easy. For time series the data is a window: a contiguous slice $\mathbf{x} = (x_{t-L+1}, \dots, x_t)$ of $L$ steps (possibly multivariate, so each $x$ is itself a vector of channels). The encoder is a function $f_\theta$ with learnable parameters $\theta$ that maps that window to a vector,
$$f_\theta: \mathcal{X} \to \mathbb{R}^d, \qquad \mathbf{z} = f_\theta(\mathbf{x}),$$where $\mathcal{X}$ is the space of input windows and $d$ is the embedding dimension, typically far smaller than the raw window length times its channel count. The vector $\mathbf{z}$ is the representation, also called the embedding, the latent, or the feature vector. The defining claim of representation learning is that a single such $\mathbf{z}$ exposes the structure needed for many different downstream tasks at once: a forecaster reads $\mathbf{z}$ to predict the next value, a classifier reads the same $\mathbf{z}$ to assign a label, an anomaly detector flags windows whose $\mathbf{z}$ is far from the bulk, and a retrieval system finds similar windows by nearest neighbors in $\mathbb{R}^d$. One encoding, many readouts.
The sharpest way to see what learning buys is to contrast it with the hand-crafted features of Section 2.4, where we built a window descriptor by computing a fixed catalogue of statistics: mean, variance, skew, dominant spectral frequency, autocorrelation at a few lags, count of zero crossings, and so on. That catalogue is a representation too, a map from window to vector, but it is fixed in advance by a human guess about what matters. Hand-crafted features have real virtues: they are interpretable, cheap, and need no training data. Their limitation is that any structure the designer did not anticipate is simply absent from the vector, and no downstream model can recover information the representation threw away. A learned encoder instead discovers, from data, which directions of the window carry task-relevant signal, and can represent structure no one thought to hand-code. The trade is the usual one: hand-crafted features cost human insight and risk omission, learned features cost data and compute and risk learning the wrong invariances.
This separation into a shared encoder and per-task heads is the structural commitment of Part IV, and it changes how we think about a model's value. An end-to-end forecaster trained on raw windows is worth exactly one task; its internal activations may encode reusable structure, but we discard them. An encoder, by contrast, is an asset: trained once, it amortizes across every task that reads its output, and the cost of adding a new task drops to fitting a small head. That amortization is precisely what makes the foundation-model paradigm of Chapter 15 economically sensible, and it is why "what makes an encoder good, independent of the head?" is the question this chapter exists to answer.
The single idea to carry from this subsection is the factorization $\text{task}(\mathbf{x}) = \text{head}\big(f_\theta(\mathbf{x})\big)$, where $f_\theta$ is shared across all tasks and only the head is task-specific. End-to-end learning fuses encoder and head into one model worth one task. Representation learning insists on keeping them separable, so the expensive part, $f_\theta$, is paid for once and reused everywhere, while each new task costs only a cheap head. Everything in this chapter, the pretext tasks of Section 16.2, the contrastive objectives that follow, the foundation-model transfer of Chapter 15, is a method for making that shared $f_\theta$ as good as possible without committing to any one head.
2. Properties of a Good Representation Intermediate
If an encoder can be anything, "good" needs a definition. Four properties recur across the representation-learning literature, and each has a precise temporal specialization. We state them generally, then ground each in what it means for a window of a time series.
Invariance versus equivariance. A representation is invariant to a transformation $g$ if $f_\theta(g \cdot \mathbf{x}) = f_\theta(\mathbf{x})$: applying $g$ to the input leaves the embedding unchanged. It is equivariant if the transformation passes through to a structured change in the embedding, $f_\theta(g \cdot \mathbf{x}) = \rho(g)\, f_\theta(\mathbf{x})$ for some known action $\rho$. Which you want depends on the task. A classifier of heartbeat type wants invariance to where in the window the beat falls (phase) and to recording gain (scale); a forecaster wants equivariance to a time shift, because the prediction must move when the window moves. The art of representation design is choosing, per nuisance factor, whether the encoder should ignore it (invariance) or track it (equivariance).
Smoothness. A representation is smooth if windows that are close in a task-relevant sense map to embeddings that are close in $\mathbb{R}^d$: small, meaningless perturbations of the input should not jump the embedding across the space. Smoothness is what makes nearest-neighbor retrieval and clustering in embedding space sensible, and what lets a linear head generalize from a finite training set to nearby unseen windows.
Disentanglement. A representation is disentangled if distinct generative factors of the data occupy distinct, ideally independent, coordinates of $\mathbf{z}$: one set of dimensions captures trend, another seasonality, another noise level, so that varying one factor in the world moves one part of the embedding. Disentanglement aids interpretability and makes downstream heads simpler, though perfect disentanglement is rarely achievable and not always necessary.
Linear separability. A representation is linearly separable for a task if a linear function of $\mathbf{z}$ suffices to solve it: classes are separated by a hyperplane, or the target is an affine readout. This is the property we most directly test, because it is the cleanest operational definition of "the structure is exposed". If a linear probe on $\mathbf{z}$ solves the task, the encoder has done the hard nonlinear work and left only a trivial readout. Formally, with a linear probe $\mathbf{W}_p \in \mathbb{R}^{c \times d}$ and bias $\mathbf{b}_p$, the prediction is
$$\hat{\mathbf{y}} = \mathbf{W}_p\, f_\theta(\mathbf{x}) + \mathbf{b}_p,$$and the encoder is judged by how well this affine map performs with $f_\theta$ frozen. The probe is deliberately weak so that any success is credited to the representation, not to the head.
For time series these four properties acquire a specific list of invariances that a general-purpose image or text encoder would not name. Three matter most. Phase invariance: shifting a window by a few steps usually should not change its class (an ECG beat is the same beat whether it sits at the start or middle of the window), so $f_\theta$ should be approximately invariant to small time translations for classification, even while a forecaster wants the opposite. Scale invariance: multiplying a window by a constant (a sensor with a different gain, an asset quoted in a different unit) often should not change its meaning, so the representation should be invariant to amplitude scaling, which is why instance normalization of each window is a near-universal preprocessing step. Warping invariance: stretching or compressing a window along the time axis (a gait performed slowly versus quickly, a heartbeat at a different rate) frequently preserves identity, so robustness to mild temporal warping is the time-series analogue of the deformation invariances that vision encoders cultivate. These three, phase, scale, and warping, are the invariances the self-supervised objectives of Section 16.2 are specifically engineered to instill, by constructing training signals that hold identity fixed while varying exactly these nuisances.
The generic properties (invariance/equivariance, smoothness, disentanglement, linear separability) become concrete for temporal data through three nuisance transformations the encoder should usually ignore for classification: a shift in time (phase), a change in amplitude (scale), and a stretch along the time axis (warping). The operational test of all of it is linear separability: freeze the encoder, fit only a linear probe, and measure the task. A representation that is invariant to the nuisances and linearly separable for the signal has, by construction, moved every hard nonlinearity into $f_\theta$ and left the head trivial. Choosing which transformations are nuisances (invariance) and which are signal (equivariance) is how you encode domain knowledge into the encoder, and getting that choice wrong, making a forecaster phase-invariant, say, silently destroys the very information the task needs.
3. The Classical-to-Learned Bridge: PCA and Dynamic Factor Models as Linear Encoders Intermediate
Representation learning can feel like a wholly new idea introduced by deep learning, but its linear case is decades old and we have already used it. Principal component analysis takes a data matrix and finds the orthogonal directions of maximal variance; projecting a window onto the top $d$ of those directions is precisely an encoder $f_\theta(\mathbf{x}) = \mathbf{P}^\top(\mathbf{x} - \boldsymbol{\mu})$, where $\mathbf{P} \in \mathbb{R}^{L \times d}$ holds the leading eigenvectors of the window covariance and $\boldsymbol{\mu}$ is the mean window. This is a learned representation by every criterion of subsection one: parameters $\mathbf{P}, \boldsymbol{\mu}$ fit from data, a fixed-length output $\mathbf{z} \in \mathbb{R}^d$, reused across tasks. It is simply constrained to be linear and to maximize reconstruction variance rather than any downstream objective.
The dynamic factor models of Section 6.4 are the temporal generalization of this same move. There we modeled a high-dimensional multivariate series as driven by a small number of latent factors evolving over time, $\mathbf{x}_t = \boldsymbol{\Lambda}\mathbf{f}_t + \boldsymbol{\epsilon}_t$ with $\mathbf{f}_t$ following its own low-dimensional dynamics. The factor vector $\mathbf{f}_t$ is exactly a learned representation of the observation $\mathbf{x}_t$: a low-dimensional code, fit from data, that captures the comovement structure many downstream analyses (forecasting the panel, detecting regime shifts) can read. The loading matrix $\boldsymbol{\Lambda}$ plays the role of $\mathbf{P}$, and inferring $\mathbf{f}_t$ from $\mathbf{x}_t$ is the encoder. Classical factor analysis is linear representation learning with a temporal prior on how the code evolves.
This section places another bead on the temporal thread that runs through the whole book: each classical construction returns as a learned, nonlinear generalization. The Kalman filter of Section 7.6 returned as the recurrent cell of Chapter 9; here the linear factor model of Section 6.4 returns as the nonlinear encoder. PCA and dynamic factor analysis answer the representation question under a linearity constraint: find a low-dimensional code that explains the data's variance or comovement. The encoders of Part IV lift that constraint. A neural $f_\theta$ is a nonlinear factor model, free to fold, warp, and curve the input space in ways a single projection matrix cannot, and trained against pretext objectives (Section 16.2) rather than pure reconstruction. The continuity is the point: representation learning did not arrive from nowhere, it is the classical latent-variable program with the linearity assumption removed and the objective generalized.
Why does removing the linearity constraint matter? Because the structure that distinguishes time-series classes is often not a linear subspace of the raw window. Two heartbeats of the same type, one slightly warped in time, live on a curved manifold that no single projection matrix can flatten; phase and warping invariance are intrinsically nonlinear requirements. A linear encoder can be invariant to amplitude scaling (project onto normalized directions) but cannot be invariant to time warping, because warping acts nonlinearly on the window. The nonlinear encoder is exactly the tool that can learn to collapse a curved manifold of equivalent windows to a single region of embedding space, which is why deep encoders outperform PCA on tasks dominated by these nonlinear nuisances, and underperform their own potential when trained with an objective (like pure reconstruction) that does not ask for the right invariances. That last caveat is the entire motivation for the pretext-task design of Section 16.2: the objective, not just the architecture, decides which invariances the encoder learns.
4. Evaluating a Representation: Linear Probe, Transfer, and Clustering Intermediate
A representation is a means, not an end, so it is evaluated by what it enables, not by its training loss. Three protocols dominate, and together they form the standard evaluation suite for any temporal encoder.
Linear-probe accuracy. Freeze the encoder, fit only a linear head (logistic regression for classification, ridge regression for forecasting) on the embeddings, and measure downstream performance. The probe is deliberately weak so that its success measures the encoder, not the head: if a single hyperplane separates the classes in embedding space, the encoder has exposed the structure linearly, which is the property of subsection two. Linear-probe accuracy is the single most reported number for a self-supervised encoder, precisely because it isolates representation quality from head capacity.
Transfer. Train the encoder on one corpus or task and evaluate it on a different one, with the encoder either frozen (feature transfer) or lightly fine-tuned. Strong transfer is the operational meaning of "general-purpose representation" and is the defining capability of the foundation models of Chapter 15: an encoder pretrained on broad data should make a held-out downstream task easy with few or no labels. Transfer measures whether the encoder learned domain structure or merely memorized its training distribution.
Clustering and retrieval. Without any labels, measure whether the embedding space organizes the data sensibly: do windows of the same (held-out) class form tight clusters, do nearest neighbors in $\mathbb{R}^d$ share semantics? Metrics like cluster purity, normalized mutual information, and nearest-neighbor accuracy (purity: the fraction of each cluster sharing one true label; NMI: label-cluster agreement normalized to $[0,1]$; nearest-neighbor accuracy: how often a window's closest neighbor shares its label) quantify the smoothness and separability of the space directly. This protocol matters most when labels are entirely absent at evaluation time, the common case for anomaly detection and exploratory analysis.
Across all three protocols the governing paradigm is the same: train the encoder once, reuse it everywhere. The encoder is fit by an expensive, often label-free procedure on abundant data; then a sequence of cheap downstream evaluations reads its frozen output. This is the paradigm Chapter 15 pushed to its extreme, pretraining one encoder on a corpus spanning domains and applying it zero-shot, and the evaluation protocols here are exactly how that chapter measures whether the pretraining paid off. A subtle but critical discipline accompanies the suite: the data split must respect time. Because windows overlap and nearby windows are correlated, a naive random split leaks future information into the training probe and inflates every metric, the temporal leakage hazard of Section 2.4. Probes must be fit and evaluated on time-disjoint segments, or the numbers are fiction.
The evaluation question this subsection poses, "is this representation good in general?", is exactly where the temporal foundation-model wave of 2024 to 2026 has concentrated. Encoder-style pretrained models such as MOMENT (Goswami et al., 2024) and the masked-reconstruction encoder of the Moirai family (Woo et al., 2024) are trained on broad multi-domain corpora and evaluated precisely by the linear-probe and transfer protocols above, reporting frozen-encoder performance across classification, forecasting, anomaly detection, and imputation from a single representation. The community has consolidated these tests into benchmark suites (for example the GIFT-Eval suite of 2024 and the long-standing UCR/UEA archives used for probing classification), turning "representation quality" into a standardized, multi-task leaderboard rather than a single accuracy. A parallel methodological frontier asks whether linear probing is even the right yardstick: 2024-2025 work on probing critiques argues that frozen linear probes can both understate an encoder (when the useful structure is nonlinearly but cleanly decodable) and overstate it (when the probe overfits a leaky split), motivating richer evaluation including few-shot fine-tuning curves and warping-stress tests. The practitioner's takeaway for 2026: report a multi-task probe suite on a time-respecting split, not a single number, and treat transfer to an unseen domain as the real test of a representation's generality.
It is a small paradox of the field that we evaluate our most powerful encoders with our most feeble classifiers. After training a deep network on millions of windows, we strap on a single linear layer, the humblest model in the toolbox, and declare the encoder good only if that feeble head can do the job. The weakness is the whole point: a strong head can paper over a mediocre representation by doing the hard work itself, so any nonlinear capacity in the probe contaminates the measurement. The linear probe is kept deliberately incompetent so that all credit, and all blame, lands squarely on the encoder. It is the one place in machine learning where you hire the least capable candidate on purpose.
5. Worked Example: Train an Encoder by a Pretext Task, Read It With a Linear Probe Advanced
We now make the whole pipeline concrete and runnable. The plan demonstrates every idea above on a small synthetic dataset where we control the ground truth. We generate windows belonging to two classes, sine waves at two different base frequencies, each instance randomized in phase and amplitude (the phase and scale nuisances of subsection two) so that the class is defined by frequency alone. We train an encoder with a label-free forecasting pretext: predict the next few steps of the window from its prefix, an objective that forces the encoder to capture the window's frequency content because frequency is what determines continuation. Then we freeze the encoder, fit a linear probe to classify frequency from the embedding, and measure accuracy, the linear-separability test of subsection two. Code 16.1.1 builds the data and the from-scratch encoder plus forecasting pretext.
import torch, torch.nn as nn
torch.manual_seed(0)
L, H, d, N = 48, 12, 16, 1200 # prefix length, horizon, embed dim, dataset size
def make_dataset(n):
"""Two classes by base frequency; each instance random in PHASE and AMPLITUDE."""
t = torch.linspace(0, 1, L + H)
freqs = torch.where(torch.rand(n) < 0.5,
torch.tensor(3.0), torch.tensor(6.0)) # class 0: 3 Hz, class 1: 6 Hz
phase = torch.rand(n) * 6.283 # nuisance: random phase
amp = 0.5 + torch.rand(n) * 1.5 # nuisance: random amplitude
series = amp[:, None] * torch.sin(2 * 3.14159 * freqs[:, None] * t + phase[:, None])
series = series + 0.05 * torch.randn(n, L + H) # observation noise
x_prefix = series[:, :L] # encoder input (the window)
y_future = series[:, L:] # pretext target (continuation)
label = (freqs > 4.5).long() # downstream class, UNUSED in pretext
return x_prefix, y_future, label
xp, yf, lab = make_dataset(N)
xp = (xp - xp.mean(1, keepdim=True)) / (xp.std(1, keepdim=True) + 1e-6) # per-window scale invariance
class Encoder(nn.Module):
"""f_theta: window in R^L -> embedding in R^d, a small MLP."""
def __init__(self):
super().__init__()
self.net = nn.Sequential(nn.Linear(L, 64), nn.ReLU(), nn.Linear(64, d))
def forward(self, x):
return self.net(x) # z = f_theta(x)
enc = Encoder()
head = nn.Linear(d, H) # pretext head: z -> next H steps
opt = torch.optim.Adam(list(enc.parameters()) + list(head.parameters()), lr=1e-2)
for epoch in range(300): # SELF-SUPERVISED: labels never used
opt.zero_grad()
z = enc(xp) # embed the window
pred = head(z) # forecast the continuation
loss = ((pred - yf) ** 2).mean() # forecasting pretext loss
loss.backward(); opt.step()
print("final pretext (forecasting) loss = %.4f" % loss.item())
lab is never touched during this training: the encoder learns frequency structure only because forecasting the continuation of a sinusoid requires knowing its frequency.final pretext (forecasting) loss = 0.0417
The encoder is now trained without a single label. The test of subsection two is whether the frequency class is linearly readable from the frozen embedding. Code 16.1.2 freezes the encoder, fits a linear probe on the embeddings of a training split, and reports accuracy on a held-out split, alongside the accuracy of the same linear probe applied to the raw windows, the baseline that says how much the encoder actually added.
from sklearn.linear_model import LogisticRegression
import numpy as np
xp_te, yf_te, lab_te = make_dataset(400) # held-out evaluation windows
xp_te = (xp_te - xp_te.mean(1, keepdim=True)) / (xp_te.std(1, keepdim=True) + 1e-6)
with torch.no_grad(): # FREEZE the encoder
z_tr = enc(xp).numpy(); z_te = enc(xp_te).numpy() # embeddings, train and test
# Linear probe ON THE EMBEDDING (the representation-quality test).
probe = LogisticRegression(max_iter=1000).fit(z_tr, lab.numpy())
acc_emb = probe.score(z_te, lab_te.numpy())
# Same linear probe ON RAW WINDOWS (baseline: what a probe gets without the encoder).
raw = LogisticRegression(max_iter=1000).fit(xp.numpy(), lab.numpy())
acc_raw = raw.score(xp_te.numpy(), lab_te.numpy())
print("linear probe on embedding : %.3f" % acc_emb)
print("linear probe on raw window: %.3f" % acc_raw)
linear probe on embedding : 0.987
linear probe on raw window: 0.793
The two numbers in Output 16.1.2 quantify the value of the representation precisely. A linear probe on the raw normalized windows reaches $0.793$ accuracy: a hyperplane in raw-window space partially separates the two frequencies, but the random phase smears each class across the space so the linear boundary cannot cleanly cut it. After the encoder, the same kind of linear probe reaches $0.987$. The encoder has folded the phase-randomized manifold of each frequency into a compact, linearly separable region of $\mathbb{R}^{16}$, exactly the nonlinear collapse of subsection three that a linear method (PCA) could not perform. The lift is $0.987 - 0.793 = 0.194$, roughly a $19$ percentage-point gain, and it measures the structure the encoder exposed that the raw representation hid. Note the error rate fell from $20.7\%$ to $1.3\%$, a $16\times$ reduction in mistakes: the encoder did almost all of the remaining separable work, leaving the linear head an easy task, which is the operational definition of a good representation.
Read the two code blocks together and the whole section is enacted. Code 16.1.1 trained an encoder with no labels by a forecasting pretext, the train-once half of the paradigm; Code 16.1.2 reused that frozen encoder under a linear probe, the reuse half, and measured a large gain in linear separability over raw data. The encoder learned the right invariance (it discarded phase and amplitude, which were nuisances, while keeping frequency, which was signal) purely from the structure of the pretext task, not from labels, which is exactly the mechanism the next section systematizes.
Who: The machine-learning team at a wearables company building activity and health features on accelerometer windows from a wrist device, the kind of multivariate sensor series threaded through Part IV.
Situation: They had hundreds of millions of unlabeled three-axis windows streaming from shipped devices, but only a few thousand windows labeled by a costly in-lab study (walking, running, cycling, sleeping), and every new feature request (fall detection, a new activity) demanded its own scarce labels.
Problem: Training a separate end-to-end classifier per feature from a few thousand labels overfit badly and generalized poorly across device firmware revisions that subtly changed sampling and gain, the scale and warping nuisances of subsection two.
Dilemma: Either keep paying for large labeled studies per feature (slow and expensive, and still brittle to firmware drift), or invest once in a self-supervised encoder on the abundant unlabeled stream and hope its embedding would make each downstream feature a cheap linear probe, with no guarantee the pretext would learn the right invariances.
Decision: They trained one encoder on the unlabeled windows with a forecasting-and-masking pretext (the family of Section 16.2), with per-window normalization for gain invariance and augmentations for time-warp robustness, then evaluated it by linear-probe accuracy on each labeled task and by transfer across firmware revisions, exactly the protocols of subsection four.
How: The pipeline mirrored the worked example at scale: freeze the encoder, fit a small linear (or shallow) head per feature on the few labeled windows, and measure on a strictly time-disjoint and firmware-disjoint split to avoid the leakage hazard of Section 2.4.
Result: Each new feature dropped from a multi-month labeling study to a probe fit on existing labels, linear-probe accuracy on the frozen encoder matched the old per-task end-to-end models with a fraction of the labels, and the encoder transferred across firmware revisions because per-window normalization had made it gain-invariant by construction.
Lesson: The reusable-encoder bet pays off when unlabeled data is abundant and the right invariances (here gain and mild warping) can be built into the pretext and preprocessing. The whole value is in choosing the encoder's invariances to match the domain's nuisances, then verifying with a frozen linear probe on a leak-free split.
The from-scratch encoder, training loop, and probe of Code 16.1.1 and Code 16.1.2 ran roughly 45 lines of explicit PyTorch and scikit-learn. A representation-learning library collapses the encoder definition, the self-supervised training, and the probe into a few lines: a prebuilt encoder is fit with one fit call on unlabeled windows, encode returns embeddings, and a probe is a one-line scikit-learn estimator. The library handles the architecture, the augmentation pipeline that instills the invariances, the masking or contrastive objective, batching, and normalization internally.
# tsai: TSStandardize, the SSL callbacks, and encoder wrappers
from sklearn.linear_model import LogisticRegression
# A library encoder: define, self-supervise on unlabeled windows, and embed, in three calls.
encoder = build_ssl_encoder(d=16) # schematic: see tsai SSL tutorials for the concrete class
encoder.fit(unlabeled_windows) # self-supervised training (forecast/mask/contrast)
z_tr, z_te = encoder.encode(train_x), encoder.encode(test_x) # frozen embeddings
# Probe is still one line, exactly as in Code 16.1.2.
acc = LogisticRegression(max_iter=1000).fit(z_tr, train_y).score(z_te, test_y)
build, fit, encode), dropping the pipeline from roughly 45 lines to about 5; the library supplies the architecture, augmentations, and objective that instill the phase, scale, and warping invariances by hand here.The line count drops from roughly 45 to about 5, with the encoder architecture, the augmentation pipeline that encodes the invariances, the self-supervised objective, and the batching all handled internally. The linear probe stays a single line in both versions, because it is already as simple as it can be, which is the point of keeping it linear.
The encoder we just trained is the dynamic factor model of Section 6.4 with two constraints removed. Section 6.4 found a low-dimensional code $\mathbf{f}_t$ by a linear projection fit to explain comovement; our $f_\theta$ finds a low-dimensional code $\mathbf{z}$ by a nonlinear network fit to forecast continuations. The linearity is gone, so the encoder can collapse the phase-warped manifolds that defeated PCA in subsection three; the reconstruction objective is gone, replaced by a pretext that asks for the right invariances. What survives is the core idea both share, the idea this whole book traces from classical to learned: compress recent history into a small code that many downstream tasks can read. Part II built that code by hand from a linear model; Part IV learns it from data with a nonlinear one, and Section 16.2 turns the design of the pretext that trains it into a discipline of its own.
Four mistakes recur when readers first build and evaluate temporal encoders, and naming them now saves a misleading result later:
- Leaking time across the probe split. Because adjacent windows overlap and correlate, a random train/test split lets the probe see near-copies of test windows in training and inflates every accuracy. Probes must be fit and scored on time-disjoint segments, the leakage hazard of Section 2.4, or the numbers are fiction.
- Building the wrong invariance. An invariance that is signal for one task is a nuisance for another. Making a forecaster phase-invariant destroys the very shift information it needs; making a classifier phase-sensitive lets random phase leak into the label. Choose invariance versus equivariance per task and per factor.
- Crediting the head, not the encoder. Evaluating with a high-capacity nonlinear head lets the head do the work a weak representation could not, hiding a bad encoder. Keep the probe linear so the measurement isolates the representation.
- Skipping per-window normalization. Without per-instance scaling, an encoder learns amplitude, a nuisance, as if it were signal, and fails to transfer across sensors with different gains. Normalize each window unless amplitude genuinely carries the label.
For each of the following tasks on a univariate window, state whether the encoder should be invariant or equivariant to (a) a time shift (phase), (b) an amplitude scaling, and (c) a constant additive offset: (i) classifying the window's activity type, (ii) one-step-ahead forecasting, (iii) detecting whether an anomaly occurred anywhere in the window, (iv) estimating the window's dominant frequency. Justify each choice in one sentence using the definitions of subsection two, and identify one task above where building the wrong invariance would silently destroy the information the task needs.
Using the dataset of Code 16.1.1, build a linear PCA encoder (project each normalized window onto its top $d=16$ principal components) and fit the same logistic-regression linear probe on the PCA embeddings, scoring on the held-out split. Compare the PCA linear-probe accuracy to the neural-encoder accuracy of Output 16.1.2 and to the raw-window baseline. Then increase the phase randomization range in make_dataset and re-run all three; explain, in terms of the nonlinear-manifold argument of subsection three, why the gap between the neural encoder and PCA widens as phase variation grows.
The forecasting pretext of Code 16.1.1 made the encoder discard phase and amplitude while keeping frequency. Replace the pretext with a pure autoencoding objective (reconstruct the input window from its embedding) keeping everything else fixed, retrain, and re-measure the linear-probe accuracy on the frequency class. Report whether autoencoding produces a representation as linearly separable for frequency as forecasting did, and argue from the nature of each objective why the pretext task, not just the architecture, decides which structure the embedding exposes. There is no single right answer; ground your argument in what each objective forces the encoder to preserve, and connect your finding to the pretext-design motivation that opens Section 16.2.
We have defined what a temporal representation is, named the properties that make one good, traced the line from the linear factor models of Part II to the nonlinear encoders of Part IV, set out how to evaluate an encoder by a frozen linear probe and by transfer, and demonstrated the full train-once-reuse-everywhere pipeline on a controlled dataset where a label-free forecasting pretext made the target class linearly separable. One question was deferred at every turn and now takes center stage: where does the training signal come from when there are no labels? The worked example used forecasting as a pretext, and the wearables case study hinted at masking and contrast, but we never asked which pretext to choose or why. Section 16.2 answers exactly that, turning the design of self-supervised pretext tasks for time series, masked reconstruction, forecasting, contrastive pair construction, and the augmentations that instill phase, scale, and warping invariance, into a deliberate engineering discipline. The encoder of this section was the asset; the next section is the factory that builds it without labels.