Bayesian decoding and the Kalman filter
A decoder as an estimator that blends what it expected with what it measured, weighted by how much it trusts each. The population vector, the Kalman filter, and why intracortical cursor control works.
You are skimming: the title, the first figure, and the short version. Switch to Read in the header for the full page, or Deep to open every deep dive.
A classifier picks one of a few labels. A cursor decoder has to produce a continuous position, sixty times a second, from neural activity that is noisy and only loosely related to movement. The trick that makes this work is to stop asking “what does the neural data say right now” and start asking “given what I believed a moment ago and what I just measured, what should I believe now.” That is Bayesian estimationBayesian estimationUpdating a belief about a hidden quantity by combining what you expected with what you measured, in proportion to their reliabilities. Glossary entry, the Kalman filterKalman filterAn estimator that blends a prediction from a motion model with a noisy measurement, weighting each by how much it trusts it; the decoder behind most intracortical cursor control. Glossary entry is its simplest form, and it has been the decoder behind most intracortical cursor control since the early 2000s.
- Raise the observation noise. The naive path wanders off; the Kalman path smooths but lags.
- Lower the process noise Q. The filter trusts its own prediction more: smoother, slower to turn.
- Raise Q. It trusts observations more: faster, noisier. There is a sweet spot, and it depends on the noise.
First, the population vector
Motor cortex neurons fire more for movements in a preferred direction, following roughly a cosine of the angle between the movement and that direction. Georgopoulos in the 1980s showed that if you take each neuron’s preferred direction, weight it by how fast the neuron is firing now, and add the vectors up, the sum points where the arm is about to move. That population vectorPopulation vectorA way to read out intended movement direction by adding up the preferred directions of many motor cortex neurons, weighted by how fast each is firing. Glossary entry was the first real neural decoder, and it is a snapshot method: each moment’s estimate uses only that moment’s firing.
Why snapshots are not enough
Spike counts in a 50 ms bin are noisy: a neuron firing at 20 per second gives one spike per bin on average, so the count is zero or one or two by chance. A snapshot decoder inherits all of that noise, and a cursor driven by it jitters. You could average over longer bins, but then the cursor lags. What you want is to use the past without being stuck in it.
The Kalman filter in two lines
Keep a belief about the state (position and velocity) and an uncertainty about it. Each time step:
Predict. Move the belief forward with a model of how cursors move: position advances by velocity, velocity mostly persists. The uncertainty grows, by an amount Q that says how unpredictable movement is.
Update. Take the new neural observation, which the model says should relate linearly to velocity with noise R. Compare it to what the prediction said the observation should be. Move the belief toward the observation by a fraction called the Kalman gain, which is large when the prediction is uncertain and the observation is reliable, and small when the reverse. The uncertainty shrinks.
That is the whole algorithm. The gain is computed from Q and R, so you never hand-tune a smoothing constant; you state how noisy the world and the sensors are and the optimal blend follows. In Figure 1 the sliders are Q and R.
A participant's neurons become noisier over the course of a session. If R is fixed, what happens to the cursor?
Jittery. The filter’s trust in observations is set by R. If the real noise rises but R does not, the filter keeps weighting noisy observations as if they were clean. Real systems re-estimate R periodically, or adapt it online, which is one form of the “closed-loop decoder adaptation” that made intracortical BCIs practical.
Fitting it
From a calibration block where the participant watches or attempts movements with known velocity: fit the observation model (a linear regression from velocity to each neuron’s firing rate) and estimate R from its residuals; estimate the movement model and Q from the kinematics. Twenty minutes of data suffices. Then run it. The BrainGate group’s refinement, ReFIT, refits the model using the participant’s intended direction (toward the target) rather than the cursor’s actual path, and roughly doubles performance; it is the single most important practical trick in the field.
Why it works for intracortical and less for EEG
Intracortical arrays give a hundred channels of spikes, each a reasonably direct report of a few neurons’ intent about movement direction. The linear model between velocity and firing holds well enough. EEG gives a few tens of channels of blurred oscillatory power whose relation to continuous movement is weak, so continuous EEG decoding gives correlations of 0.3 to 0.5 rather than 0.8 to 0.9. The Kalman machinery is the same; the signal is not.
Deep dive The equations 5 min
State x (position, velocity), transition A, process noise Q. Observation z (firing rates), observation matrix H, observation noise R.
Predict: x̂ ← A x̂; P ← A P Aᵀ + Q. Gain: K = P Hᵀ (H P Hᵀ + R)⁻¹. Update: x̂ ← x̂ + K (z − H x̂); P ← (I − K H) P.
P is the belief’s covariance. Everything in Figure 1 is these five lines in JavaScript. For a hundred neurons, H is 100 × 4 and R is 100 × 100, and the matrix inverse is the whole computational cost, which a laptop does thousands of times a second.
Deep dive Beyond linear: what the current decoders do 3 min
Firing rates are not Gaussian and not linear in velocity. Extensions: a Poisson observation model (the point-process filter), an unscented or particle filter for nonlinearities, and, since about 2020, recurrent neural networks trained end to end from neural data to kinematics, which win on offline benchmarks like the Neural Latents Benchmark by learning the neural population’s own low-dimensional dynamics. In closed loop, with a person adapting to the decoder, simple Kalman variants remain surprisingly competitive, and the interaction between a learning user and a learning decoder is a research field of its own.
Explain what this page was about to your roommate in three sentences. No jargon they would not know.