Use AI to Detect Training Plateaus and Diminishing Returns

How to use AI models to detect plateau points in training

Plateaus are not just a feeling; they show up in your data. With a small, sensible AI toolkit, you can spot diminishing returns early and adjust before motivation and fitness slip. The idea is simple: relate training load to performance and recovery, then flag when extra work stops moving the needle on your key metrics like FTP, power-duration curve, or submax endurance.

What a plateau looks like in your data

Think of a plateau as a period where performance is flat while load stays high, or where the cost of holding the same watts keeps rising. Typical signs include:

  • FTP or 20-minute power stalls despite increasing weekly TSS or hours.
  • Endurance decoupling (power vs. heart rate) worsens at the same steady pace.
  • RPE drifts up for the same watts and duration.
  • HRV trends down and morning heart rate creeps up.
  • Training becomes monotonous (too similar day-to-day) and recovery lags.
Signal What it means Typical threshold
FTP/20-min power trend Output not rising <1–2% gain over 4–6 weeks while weekly TSS is +10–15%
Endurance decoupling (Pa:Hr) Inefficient aerobic base >5–7% on a 60–90 min zone 2 ride
RPE at fixed watts More cost for same work +2 points vs. baseline at same watts and duration
HRV (rMSSD) Strain outpacing recovery 7-day avg >1 SD below 60-day mean
Training monotony Lack of variation >2.0 for 2 consecutive weeks (mean load / SD)
TSB (CTL–ATL) Responsiveness check TSB near 0 but performance flat for 2+ weeks

None of these alone proves a plateau. AI helps combine them, quantify the trend, and give you a clear, timely nudge.

Model approaches that work for riders

1) Baseline and change-point detection

  • Rolling slope: Fit a short rolling regression to your key metric (e.g., 20-min power or 95% of 20-min as FTP proxy). Flag when the slope is near zero while training load slope is positive.
  • Change-point: Use cumulative sum (CUSUM) or Bayesian change-point methods to find when improvement flattens after a period of growth.
  • Power-duration curve drift: If gains across your curve (e.g., 1, 5, 20, 60 min) are <1% over 21 days while CTL rises >3 points per week, you likely have diminishing returns.

2) Dose–response with training load

  • Impulse–response (Banister) models: Use ATL (7-day EMA of TSS) and CTL (42-day EMA of TSS) to predict performance. When predicted performance gains per unit added load (marginal benefit) fall below a small threshold for several weeks, you are at a plateau.
  • TSB responsiveness: If TSB returns to neutral or slightly positive and your 20-min or 5-min power does not rebound, your recent load is not translating into performance.

3) Machine learning predictors for small datasets

  • Lightweight models: Gradient boosting or random forest can predict next-week performance using features such as CTL, ATL, TSB, monotony, zone distribution (time in zone 1/2/3+), HRV, sleep, and RPE.
  • Uncertainty-aware: Gaussian process regression provides a prediction and confidence interval. Plateau risk rises when the model predicts little improvement with high confidence despite higher planned load.
  • Feature importance: Use model explanations (e.g., SHAP) to see whether lack of easy volume, too much intensity in high zones, or poor sleep is driving the stall.

Keep it practical: start with rolling slopes and a dose–response fit. Add ML when you have consistent data over 12+ weeks.

A simple workflow you can implement this week

  1. Collect and align

    Daily: power (watts), TSS or similar load, heart rate, HRV (morning rMSSD), RPE (0–10), sleep hours, and a short note on fueling and stress. Mark key tests (e.g., 20-min bests, 5-min VO2max efforts).

  2. Engineer features
    • CTL (42-day EMA of TSS), ATL (7-day EMA), TSB = CTL − ATL.
    • Training monotony = mean 7-day load / SD.
    • Zone distribution: time in zone 1, 2, and 3+ (or 7-zone if you prefer).
    • Endurance decoupling: compare first vs second half of a steady zone 2 ride.
  3. Fit a simple model
    • Rolling slope of 20-min power and of PD-curve area (e.g., sum of best powers at 1–60 min).
    • Optional: impulse–response model using CTL/ATL to predict 20-min power.
  4. Define plateau rules
    • Performance slope >= 0% and < 0.25% per week for 21 days while CTL increases > 3 per week.
    • Endurance decoupling > 5% in two consecutive submax tests.
    • RPE at fixed watts +2 for two or more similar sessions.
    • HRV 7-day avg >1 SD below 60-day mean for 5+ days.
  5. Validate the signal
    • Require persistence for at least 7 days.
    • Check confidence: if your model’s prediction interval overlaps zero change, be cautious.
    • Cross-check context: heat, altitude, illness, travel, and menstrual cycle phase can shift baselines temporarily.
  6. Decide and adjust

    When the plateau flag is on, act for 7–14 days, then retest:

    • Deload: reduce volume by 30–50% for 3–5 days; keep 1 short high-intensity session to stay sharp.
    • Change stimulus: swap threshold-heavy for VO2max micro-intervals (e.g., 30/15s), or move from polarized to pyramidal distribution for a block.
    • Add strength: 2 sessions/week of lower-body lifts (e.g., squats, RDLs) in the general prep or base phases.
    • Fuel recovery: 8–10 g/kg/day carbs in heavy weeks; 0.7–1.0 g/kg carbs plus 20–30 g protein within 60 minutes post-ride.
    • Sleep target: 7–9 hours; add a 20–30 min nap on hard days if possible.
    • Retest: after deload, do a 60–90 min zone 2 decoupling ride and a 5-min or 20-min benchmark within a week.
  7. Iterate monthly

    Re-tune thresholds to your response. As FTP rises, the same absolute watts feel easier; your model should follow that evolution.

# Pseudocode: simple plateau flag
for each day:
  CTL = ema(TSS, span=42)
  ATL = ema(TSS, span=7)
  TSB = CTL - ATL
  monotony_7d = mean(TSS_last_7) / std(TSS_last_7)

# Weekly update
perf = rolling_best(power_20min, window=7)
perf_slope_21d = slope(last_21_days(perf))
ctl_slope_21d  = slope(last_21_days(CTL))

plateau = (
  perf_slope_21d >= 0 and perf_slope_21d < 0.0025 and
  ctl_slope_21d  > 0.1 and
  decoupling_recent > 0.05 or
  rpe_drift_recent >= 2 or
  hrv_7d < (hrv_60d_mean - 1*hrv_60d_sd)
)

if plateau persists >= 7 days:
  suggest(["deload", "change_stimulus", "fuel_sleep_focus"])

The goal is not perfect prediction. It is timely, defensible decisions: notice when more load is no longer buying you better watts, then change the input so adaptation resumes.