The whole matrix
Each row is one window of past SOH values. The three batteries’ blocks are stacked one after another, and the labels y sit in a separate column beside X.
Selected entry x[300,30] = 0.84387; the label of this row is y[300] = 0.85065.
How the capacity records of four batteries become a forecasting experiment: a model learns from three batteries, then forecasts the fourth in two ways, one cycle ahead from the real history, and many cycles ahead from its own predictions.
Data source. CALCE CS2 lithium-ion cycling data with a derived per-cycle state-of-health series. Detailed dataset provenance and usage conditions are on the Dataset page.
Each value stated in the source record is set beside a count made directly from the files: the four per-battery CSV files of SOH values and the raw CALCE workbooks.
| Property | Stated value | Measured in the files | Check |
|---|
CALCE CS2 batteries · PC5251 final project (2024) · 2010-08-16 to 2011-02-03 · four batteries · supplied per-cycle rows: CS2_35 882 · CS2_36 936 · CS2_37 972 · CS2_38 996 · SOH ratio from fixed 4,100 A·s denominator.
State of health (SOH) is the charge a battery delivers in one discharge divided by a fixed reference of 4,100 ampere-seconds (about 1.14 Ah). It starts just below 1 and falls as the battery ages. One cycle is one full charge followed by one full discharge.
CS2_35 (882 cycles), CS2_36 (936 cycles), CS2_37 (972 cycles). The model learns only from windows cut from these three complete records.
CS2_38 (996 cycles). The model never sees this battery during training; every test score on this page is measured on it.
Some cycles show a sudden one-off dip in SOH, a measurement glitch rather than ageing. For each cycle, the filter fits a straight line to the preceding cycles, extends it to the current cycle, and replaces the value if it lies too far from that line, measured in median absolute deviations (MAD; a Hampel test). Because it uses only earlier cycles, it can run as each new cycle arrives. A plain running median would instead mistake a steady decline for a run of outliers. Methods that clean the whole curve at once, such as CEEMDAN, use later values, so they cannot be applied cycle by cycle.
On CS2_38, a length-7 trailing window at 3× MAD replaces 11 of 996 cycles; the largest correction is at cycle 86 (0.135 SOH). Every replacement uses only earlier cycles.
Retraining the model and scoring it on the filtered series (30-cycle window, seed 123) lowers the one-step error (MSE) from 1.30e-4 to 8.40e-5 and the mean recursive-forecast error from 2.40e-3 to 2.10e-3. Both errors are explained under Forecasting and evaluation.
A design matrix is the table a model learns from: one row per example, one column per input value. Here each row is a run of consecutive SOH values from one battery, and the model learns to predict the value that comes next.
Training rows with the notebook’s 30-cycle window
Rows from the 3 training batteries with a window of w = 30 cycles. 2,430 rows train the model; the last 270, all late windows of CS2_37, are held back to monitor training (validation).
The three views below are linked. “The whole matrix” shows the three training batteries stacked into one table; “Across one row” shows one window and the label that follows it; “Down one column” shows one position in the window across all rows, which traces the same SOH series shifted by one cycle per column. Press Slide rows, or move either slider, to change the selection in all three views.
Each row is one window of past SOH values. The three batteries’ blocks are stacked one after another, and the labels y sit in a separate column beside X.
Selected entry x[300,30] = 0.84387; the label of this row is y[300] = 0.85065.
These 30 values, in order, are what the model receives; the point after them is the next measured SOH, the label the model learns to predict.
CS2_35 cycles 301–330 become row 300 in that battery block; cycle 331 supplies y = 0.85065.
A column is one position inside the window. The neighbouring column (dashed line) traces the same SOH series shifted by one cycle, so the columns are positions in time, not different measurements.
Column 30 holds position 30 of every window. Moving to the next column advances the same SOH series by one cycle; neighbouring rows likewise share 29 of 30 values.
The window length w is the number of past SOH values in each row. Choosing a different w switches every result below to the run trained with that window: the number of rows, the saved training states, the one-step predictions and the recursive forecasts. The Design matrix section always shows w = 30, the notebook’s setting.
With w = 30, the three training batteries yield 2,700 training rows and CS2_38 yields 966 test rows.
A recurrent neural network that reads the window one value at a time while carrying a memory (50 hidden units, 1 layer); a final linear layer outputs the next SOH. Training uses the Adam optimiser with learning rate 0.01, mean squared error as the loss, 300 full-batch epochs and seed 123, as in the notebook’s code.
Predicts that the next value equals the last value in the window. It has no fitted parameters, and on a slowly changing series it is hard to beat.
Fits a least-squares line to the current window and extrapolates it. It carries a local slope but cannot bend or change regimes.
Press Replay, or drag the slider, to step through the saved stages of training, from the untrained model to the final one. “Prediction for unseen CS2_38” shows the model’s one-step predictions at that stage; “Training and validation loss” marks the stage on the error curves. Both charts keep fixed axes, so every change you see is a change in the model.
After 300 updates: training MSE 1.31e-4; the CS2_38 points shown score 1.54e-4. Most of the visible fit is already present; the numerical tail keeps improving more than the picture changes.
Final training MSE 1.31e-4 and validation MSE 1.45e-4. Each epoch is one update computed from all training rows at once, so 300 epochs are 300 updates. Testing uses the whole CS2_38 curve.
A nudge test changes one past value in the window slightly and measures how much the prediction moves. The chart shows the average size of that change for each position, counted back from the most recent cycle (1).
The most recent cycle accounts for about 22% of summed sensitivity and the last five for about 76%. One-step MSE spreads only 3% across w = 5, 10, 20, 30. Earlier positions still matter: flattening or shuffling them gives worse scores in the ablation table below.
For every cycle of CS2_38, the model receives the measured values of the preceding window and predicts only the next cycle. Each prediction starts again from real measurements, so errors cannot build up.
| model | one-step test MSE | RMSE (SOH points) | vs persistence |
|---|---|---|---|
| LSTM · trained on three batteries | 1.31e-4 | 1.14 | 0.94× |
| Persistence · no training | 1.39e-4 | 1.18 | 1.00× |
| Linear trend · no training | 1.68e-4 | 1.30 | 1.20× |
Each forecast starts at an anchor cycle, the last measured value it is given. After that, each model’s own prediction is added to its input and used for the next step, so no further measurement corrects it (a recursive forecast). Persistence stays flat, the linear trend stays straight, and any bend in the LSTM forecast must come from what it learned. Move the anchor slider or pick an example below; choose a failure threshold to see when each forecast says the battery will reach it.
| model | RMSE @ +10 cycles | RMSE @ +25 cycles | RMSE @ +50 cycles | RMSE @ +100 cycles | RMSE @ +200 cycles | predicted crossing | RUL error |
|---|---|---|---|---|---|---|---|
| LSTM rollout | 0.44 | 0.59 | 0.96 | 1.53 | 1.65 | 727 | -26 |
| Persistence | 0.48 | 0.49 | 0.57 | 0.57 | 2.16 | never reaches | no crossing |
| Linear trend | 0.39 | 0.62 | 1.21 | 2.20 | 2.75 | 744 | -9 |
Measured crossing: cycle 753, so the true remaining useful life (RUL) from anchor 400 is 353 cycles. A crossing counts only when SOH stays at or below the threshold for 5 consecutive cycles; a positive RUL error means the forecast promises more life than the battery had.
one rollout MSE = mean[(forecast − measured)²] over its future cycles; mean rollout MSE = the average over 38 stored anchors.
At anchor 400, the widest absolute gap is 0.135 SOH. Squaring and averaging all 596 forecast-cycle gaps gives this rollout MSE 8.51e-4; averaging the same calculation over 38 stored anchors gives w = 30 mean rollout MSE 2.40e-3.
Each window length is scored with both tests. The two tests have different error scales, so compare how much each line changes, not which line is higher.
Across these windows, the one-step MSE changes by 3%, while the mean recursive MSE changes by a factor of 14.0.
Recursive forecasts were also scored for longer windows, up to w = 150. Longer windows leave fewer training rows and add mostly repeated history.
The lowest mean recursive MSE among the windows tested is at w = 30 (2.40e-3); at w = 150 it is 6.46e-3, 2.7 times higher.
The model was trained three times with the same data and settings but different random starting weights (seeds 123, 124 and 125). The table compares their one-step test scores; recursive forecasts were saved for seed 123.
| training seed | one-step test MSE | RMSE (SOH points) |
|---|---|---|
| seed 123 · used throughout | 1.31e-4 | 1.14 |
| seed 124 | 1.29e-4 | 1.14 |
| seed 125 | 1.32e-4 | 1.15 |
The notebook also tried other settings, one at a time. Each table lists the one-step test MSE for each setting; at learning rate 0.2, training fails (MSE 0.032).
| 5e-4 | 2.20e-4 |
|---|---|
| 5e-3 | 1.40e-4 |
| 1e-2 | 1.30e-4 |
| 5e-2 | 1.30e-4 |
| 2e-1 | 3.20e-2 |
| 25 | 1.40e-4 |
|---|---|
| 50 | 1.30e-4 |
| 100 | 1.20e-4 |
| 200 | 1.30e-4 |
| 1 | 1.30e-4 |
|---|---|
| 2 | 1.60e-4 |
| 3 | 1.70e-4 |
| 20 | 1.30e-4 |
|---|---|
| 30 | 1.30e-4 |
| 40 | 1.30e-4 |
The numbers below follow the window, anchor and threshold you selected above.
Persistence, which just repeats the last measured value, scores almost the same on the same task.
w = 30 · LSTM MSE 1.31e-4 · persistence 1.39e-4 · ratio 0.94×
In the nudge test, most of the sensitivity sits in the last few values of each window. This is why the one-step score barely changes with window length.
most recent cycle ≈ 22% · last five ≈ 76% of summed sensitivity
After the anchor, no measurement corrects the forecast, so errors build up; when the forecast crosses the threshold, and the shape of the long forecast, show how much.
anchor 400 · threshold 0.7 · measured crossing 753 · LSTM crossing 727
Over the full range of windows tested, the mean recursive error falls and then rises: long windows leave fewer training rows and add repeated history.
lowest mean recursive MSE at w = 30 · 2.40e-3 · longest w = 150 gives 6.46e-3
Each term is defined as it is used on this page.
One of the four test batteries, CS2_35 to CS2_38: a 1.1 Ah lithium-cobalt-oxide (LCO) prismatic cell tested by the CALCE group at the University of Maryland, charged at constant current, then held at constant voltage, and discharged at room temperature. Each battery is a single cell, so “battery” and “cell” mean the same thing here.
The charge a battery delivers in one discharge, C_t, divided by a fixed reference C₀ = 4,100 A·s (about 1.14 Ah). The rated capacity, 1.1 Ah, is about 3,960 A·s, so SOH starts slightly below 1. (The Battery curve shape demo divides by the rated 1.1 Ah instead.)
The discharge current added up over the time of one discharge, which gives the charge delivered. Dividing it by the fixed reference gives that cycle’s SOH.
The capacity loss built up through cycling, including changes in the electrodes and growth of the solid-electrolyte interphase. This page tracks its result, the fall in SOH.
The number of cycles from the forecast anchor until SOH crosses the chosen failure threshold (see Sustained crossing). If the battery never crosses it, or crossed it before the anchor, there is no RUL to score.
The table the model learns from: the stacked sliding windows. With w = 30 it has 2,700 rows and 30 columns, one per position in the window.
A consecutive run of past SOH measurements used as one model input. Sliding it forward by one cycle creates the next, heavily overlapping row.
One window of past SOH values: everything the model receives for one prediction. Its label is stored separately.
One relative position inside every window. Adjacent columns are the same underlying sequence shifted by one cycle, not different physical sensors.
The measured SOH immediately after a row's window. Supervised regression trains the output to match this value.
Information from the test battery, or from later cycles, reaching the model during training or preprocessing. Holding out a whole battery and using a backward-looking filter prevent it here.
A recurrent neural network with a memory state. Here one layer with 50 hidden units reads the ordered window and a linear head predicts one SOH value.
A forecast without training that copies the last measured value. It is the simplest baseline to compare a one-step forecast with.
A least-squares line fitted within the current window and extrapolated forward. Recursive use continues that line without curvature.
One optimizer update computed from all training rows. The submitted loop therefore performs 300 parameter updates, not 300 mini-batch passes.
A number that fixes the model’s random starting weights. One-step results are stored for 3 seeds, recursive forecasts for seed 123.
The average absolute change in the prediction when the value at one position in the window is nudged.
A controlled corruption of input history—flattening or shuffling here—to test whether ordered earlier values contain information beyond the last point.
Every prediction receives the real preceding window and forecasts only the next cycle, so measurement continuously resets accumulated error.
After an anchor, each prediction is fed back as the next input. This exposes compounding error and is the protocol needed to draw a future trajectory.
The anchor is the final measured cycle allowed to a rollout; the horizon is how many forecast cycles beyond it are scored.
Mean squared error averages squared prediction gaps. RMSE is its square root; this page multiplies RMSE by 100 to report SOH percentage points.
A threshold event counts only after SOH remains at or below it for 5 consecutive cycles. This prevents isolated noise dips from becoming false end-of-life alarms.
A Hampel-style filter that uses only earlier cycles: it fits a local trend to the last 7 cycles and replaces a value more than 3 scaled median absolute deviations away from it, with a residual floor of 0.01 (the default settings).
A whole-series decomposition mentioned by the source work. Because later values affect earlier components, it is useful for retrospective cleaning but leaks future information if used as an online forecast input.