Part IV: Deep Learning for Sensor Time Series
Chapter 15: Transformers for Sensor Data

Attention over time and channels

"You asked me to summarize the last ten minutes of vibration. I looked at all of it at once and decided which forty milliseconds actually mattered."

An Attentive AI Agent

Prerequisites

This section assumes you are comfortable with a multichannel sensor stream as a matrix of time by channel, the framing from Chapter 3, and with the neural-network mechanics (linear projections, softmax, minibatch training) refreshed in Appendix B and first applied to sensor windows in Chapter 13. It helps to have met the recurrent and convolutional models of Chapter 14, since attention is a third answer to the same question those models addressed: how does one sample's meaning depend on the others? No prior exposure to transformers is required; positional encoding, patchification, and efficient long-context variants are deferred to later sections of this chapter.

The Big Picture

A recurrent network passes information through time one step at a time; a convolution mixes only what falls inside its fixed window. Attention discards both constraints: it lets every point in a sensor window look directly at every other point and decide, from the signal's own content, which ones matter. The mechanism is a weighted average whose weights are computed on the fly, so a spike at one moment can pull in evidence from far away in a single step, with no decay and no fixed receptive field. For sensor data there are two axes to attend over, and one memorable way to hold them apart: attention over time asks which moments explain each other, attention over channels asks which sensors do. This section builds the core attention operation once, then shows how pointing it along each axis buys long-range temporal reasoning and learned cross-sensor coupling from the same few lines of algebra.

Scaled dot-product attention: a content-addressed average

Attention takes a set of tokens, here a set of vectors extracted from the sensor stream, and rebuilds each one as a weighted blend of all the others. Every token is projected three ways by learned matrices into a query \(q\), a key \(k\), and a value \(v\). The query says what this token is looking for; the key says what each token offers; the value is the content it contributes if selected. Stacking the tokens of one window into matrices \(Q\), \(K\), and \(V\), the whole operation is:

$$\mathrm{Attention}(Q,K,V) = \mathrm{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V$$

Read it inside out. The product \(QK^{\top}\) scores every query against every key by dot product, an \(n \times n\) grid of compatibilities for a window of \(n\) tokens. Dividing by \(\sqrt{d_k}\), the square root of the key dimension, keeps those scores from growing with dimension and saturating the softmax into a near one-hot spike; this is the scaled in the name, and it is what keeps gradients stable. The softmax turns each row into a probability distribution, the attention weights, and multiplying by \(V\) forms, for each token, a convex combination of all values weighted by relevance. The result is content addressing: attention is a lookup table the model writes at inference time, retrieving each token not by position but by resemblance.

A single attention map forces every relationship in the window through one weighting scheme, which is too coarse: a wrist IMU window may need one pattern to track a slow postural drift and a different one to catch a sharp tap transient, and one softmax cannot represent both at once. Multi-head attention fixes this by splitting the model dimension \(d\) into \(h\) smaller subspaces of size \(d/h\), running an independent scaled dot-product attention in each with its own \(Q\), \(K\), \(V\) projections, then concatenating the \(h\) outputs and mixing them with one further learned projection \(W_O\). Each head sees the same tokens through a different learned lens, so one head can specialize on the slow trend while another locks onto transients, at little extra compute since every subspace is narrower than \(d\). The payoff shrinks once the sensor set and window are themselves small, since a handful of channels over a short window may hold only two or three genuinely distinct relationships worth separating.

Key Insight

Every token reaches every other token in exactly one operation, so the path length between two samples stays constant regardless of how far apart they sit. Contrast this with the recurrent cell of Chapter 14, where the path grows linearly with the gap and the gradient decays along it, and with the convolution, whose reach is capped by its receptive field. Attention pays for that reach with an \(n \times n\) score matrix: cost and memory grow with the square of the window length. That quadratic bill is the defining tradeoff of the architecture, and the reason Section 15.4 is devoted entirely to taming it for long sensor sequences.

Attention over time: which moments explain each other

Point the mechanism along the time axis and each token is one time step (or, after Section 15.2, one short patch of time). The attention weights then form a map from each moment to every other, showing which instants the model consults to represent the present one, a strict generalization of what the temporal models of the previous chapter did. Where a causal convolution averages a fixed neighborhood with fixed weights, temporal attention averages the whole window with weights that depend on the signal itself, so a heartbeat can attend to the previous beat to measure an interval, and a gait classifier can line up the current stride against the one before it even if the cadence drifted. Because the raw operation is permutation invariant, it has no built-in sense of order; the model only learns that step \(t{-}1\) precedes step \(t\) once you add the position information of Section 15.3. For streaming and forecasting you also apply a causal mask that sets the scores for future positions to \(-\infty\) before the softmax, so a token attends only to the past, preserving the real-time constraint that disqualified bidirectional recurrence in Chapter 14.

The listing below runs one head of self-attention over a short multichannel window and reads off the temporal attention map, the row of weights that says where the model looks.

import torch, torch.nn.functional as F

torch.manual_seed(0)
T, C, d = 50, 6, 32                       # 50 time steps, 6 sensor channels, model width d
x = torch.randn(T, C)                     # one window: time by channel

Wq, Wk, Wv = (torch.randn(C, d) for _ in range(3))
Q, K, V = x @ Wq, x @ Wk, x @ Wv          # project each time step to query/key/value

scores = (Q @ K.transpose(0, 1)) / d**0.5 # T x T compatibility between every pair of steps
weights = F.softmax(scores, dim=-1)       # each row is a distribution over source steps
context = weights @ V                      # T x d : each step rebuilt from relevant steps

print("attention-map shape:", tuple(weights.shape))          # (50, 50): time attends to time
print("step 25 looks most at step:", int(weights[25].argmax()))
Listing 15.1.1. One head of temporal self-attention on a 50-step window. The weights matrix is the time-by-time attention map; row t shows which moments the model blends to represent step t. Swapping the transpose to operate on the channel axis instead is the one-line change discussed next.

As Listing 15.1.1 shows, the attention map is a first-class, inspectable object: it tells you, per output moment, which input moments drove the representation.

Common Misconception: attention weights are not explanations

A high attention weight is not proof the model used that moment for the right reason, and it is not a causal explanation of the output. Softmax must place its probability mass somewhere, so an irrelevant or redundant step can pick up a large weight simply because nothing else in the window competed for it, and a head can fixate on a spurious correlate, such as a sensor artifact co-occurring with the true cause, as easily as on the true cause itself. Treat an attention map as a hypothesis worth checking with an intervention, for example masking the high-weight step and confirming the output actually changes, before it drives a decision in workflows like the root-cause methods of Chapter 67.

Attention over channels: which sensors explain each other

Now transpose the question. Treat each sensor channel as a token, its value across the window (or a learned embedding of it) as the vector to project, and let attention run over the channel axis. The weights now form a sensor-by-sensor map: for a nine-axis inertial unit plus a barometer and a magnetometer, the model learns which channels inform which, so the three accelerometer axes can pool into a motion estimate while the magnetometer is down-weighted during an electrical disturbance. This is a learned, input-dependent alternative to the hand-built cross-channel features of Chapter 8, and its practical virtue is that it does not care about channel order or, within limits, channel count: a model attending over channels can absorb a sensor dropping out by masking its key rather than crashing on a missing input. Whether an architecture should mix channels at all, or keep them strictly separate, is a genuine design fork with real accuracy and robustness consequences; that decision is the subject of Section 15.5, so here we only establish that channel attention is the tool that makes mixing learnable.

In Practice: cross-axis attention on an automotive suspension rig

A vehicle-dynamics team logged four wheel-speed sensors, a six-axis IMU, and steering angle at 200 Hz to detect a subtle damper fault that appeared only under cornering. A per-channel model missed it because the signature was not in any single sensor but in the relationship between them: a healthy damper keeps vertical IMU acceleration in a particular phase against wheel speed through a turn, and the fault shifted that phase. A transformer with attention over both axes solved it: the temporal heads aligned the signal across the several seconds of a corner, and a channel head learned to co-weight vertical acceleration with the two wheel-speed sensors on the loaded side, exactly the coupling a human engineer would have hand-coded. The attention map became a debugging aid, since technicians could see the model consulting the correct sensor pair, building trust before the system reached the condition-monitoring pipeline of Chapter 37. The team split train and test by vehicle so no single car's quirks could leak across the boundary and flatter the reported detection rate.

The Right Tool

Writing this from scratch means the three projections, the scaled scores, an optional mask, the softmax, the value blend, then the head-splitting, concatenation, and output projection \(W_O\) of the multi-head wrapper, plus a numerically safe masked softmax that is easy to get wrong: roughly fifty lines in total. A framework gives you the whole multi-head block, fused and hardware-accelerated, in one:

import torch, torch.nn as nn

mha = nn.MultiheadAttention(embed_dim=64, num_heads=8, batch_first=True)
x = torch.randn(16, 50, 64)                       # batch, time steps, model width
out, attn = mha(x, x, x, need_weights=True)       # self-attention over the time axis
# feed x.transpose(1, 2) instead to attend over the channel axis
Listing 15.1.2. One constructor replaces about fifty lines of attention plumbing, including the masked softmax and multi-head bookkeeping, and returns the attention weights for inspection. Choosing which axis to attend over is the single transpose noted in the comment.

Putting the two axes together

Real sensor transformers rarely attend over one axis alone; the dominant patterns are three. Flatten time and channel into one long sequence of tokens and let full attention couple everything, the most expressive and most expensive option, since the score matrix grows with the product of the two axis lengths. Factorize the two axes into alternating blocks, a temporal-attention layer followed by a channel-attention layer, so cost stays linear in each axis while information still crosses both over depth; this axis-factorized design is the workhorse for multichannel sensing and reappears in the spatial-temporal graph models of Chapter 54. Restrict to one axis on purpose, the channel-independent choice, when the channels are better kept separate. The right pattern depends on how strongly your sensors are physically coupled and on your compute budget, a tradeoff of accuracy, latency, and memory the rest of this chapter equips you to navigate.

Research Frontier

The axis-factorized idea sits at the heart of current time-series transformers. Crossformer (Zhang and Yan, 2023) makes cross-channel attention explicit with a two-stage attention over time segments and across variables, iTransformer (Liu et al., 2024) inverts the usual layout by treating each whole channel as a token so attention runs primarily over variables rather than time, and TimeXer (Wang et al., 2024) folds exogenous channels into a patch-based backbone through a dedicated cross-variable attention stage instead of treating every channel as symmetric. The open question these lines share is when explicit channel attention beats a strictly channel-independent model such as PatchTST; the current answer is that it depends on how coupled the sensors are, and settling it on your own data is precisely the comparison Section 15.5 and Lab 15 ask you to run.

Exercise

Take a multichannel window (real or synthetic, at least six channels and 200 steps). (1) Implement single-head self-attention and produce both the time-by-time map and, by transposing the input, the channel-by-channel map; visualize each as a heatmap. (2) Inject a known cross-channel dependency, for example set channel 4 to a delayed copy of channel 1, and confirm the channel attention map discovers the pair. (3) Add a causal mask to the temporal version and verify every row's weight on future positions is exactly zero. (4) Time the flattened variant against the axis-factorized variant as you double the window length, and plot how each scales.

Self-Check

1. In the attention formula, state precisely what the query, key, and value of a token represent, and explain why the scores are divided by \(\sqrt{d_k}\) rather than used raw.

2. Attention is permutation invariant. What does that imply the model cannot know about a time series on its own, and which later section supplies the missing ingredient?

3. Give one sensing task where attention over channels is clearly the more useful axis than attention over time, and justify it in terms of where the discriminative information lives.

What's Next

In Section 15.2, we confront the quadratic cost head-on by changing what a token is: instead of one token per sample, we chop the stream into short patches and embed each as a single token, cutting the sequence length by the patch size and giving each token a richer local view before attention ever runs.