How does RMSProp adapt the learning rate per parameter?
Answer
RMSProp keeps a per-parameter exponential moving average of squared gradients and divides each gradient component by the square root of that average before stepping, so the effective learning rate shrinks for parameters with historically large gradients and grows for those with small or sparse ones. The running estimate acts as a per-coordinate normalizer: two parameters share one global learning rate yet move by very different amounts. On ill-conditioned surfaces, where curvature differs wildly across directions, this damps oscillation along steep directions while sustaining progress along shallow ones, something a single global learning rate cannot do. Tieleman and Hinton introduced the method in their 2012 Coursera lecture series to cope with non-stationary objectives such as mini-batch and recurrent training; Adam is essentially RMSProp plus a first-moment momentum term and bias correction.
(1) Per-Coordinate Normalization: each parameter steps by ; a parameter whose gradients run 10x larger builds a 10x larger
, so its effective learning rate shrinks 10x and the two coordinates end up moving by comparable amounts instead of one dwarfing the other.
(2) Memory With a Window: the decay (0.9 in the original lecture; PyTorch’s RMSprop defaults to 0.99) makes
an average over recent history, so the normalization adapts as the landscape changes instead of stalling like AdaGrad’s monotonically growing accumulator.
(3) No Bias Correction: starts at zero and is never corrected, so early steps are oversized; Adam fixes this with
, one of the two additions (the other is momentum) that turn RMSProp into Adam.

Figure 1: On the ravine , SGD spends its budget oscillating across the steep
direction and after 42 steps is still at
; RMSProp normalizes both coordinates, never overshoots, and reaches
in the same 42 steps.
The same normalization explains RMSProp’s strength on sparse features. For an embedding row that receives a gradient only occasionally, decays toward zero between updates, so when a gradient finally arrives its effective learning rate
is several times larger than a densely-updated parameter’s, and the rare signal is not drowned out by a global rate tuned for frequent gradients. The flip side appears at the start of every run: with
the first estimate is
, so the first step has magnitude
whatever the gradient scale, a warmup-like quirk that Adam’s bias correction removes. In practice RMSProp remains a solid choice for RNNs and other non-stationary objectives, while vision recipes still often prefer well-tuned SGD with momentum for final generalization.

Figure 2: Two parameters over 60 steps with : the one with a large steady gradient sees its effective learning rate
fall 6.7x by step 60 (heading for
as
), while the sparse-gradient parameter still enjoys a roughly 4x larger rate.
Mathematical Formulation:
Where:
is the minibatch gradient at step
; the squaring in the accumulator is element-wise.
is the per-parameter running average of squared gradients, with the same shape as
, initialized to zero.
is the decay (0.9 in Hinton’s lecture, 0.99 by default in PyTorch),
the global learning rate, and
a numerical floor guarding the division.
- All operations are element-wise, so each parameter gets its own effective rate
under one shared
.
| Aspect | SGD + Momentum | RMSProp | Adam |
|---|---|---|---|
| State per Parameter | Velocity m (first moment) | Squared-gradient average v (second moment) | Both m and v |
| Normalization | None; one global rate for all coordinates | Gradient divided by sqrt(v) per coordinate | Bias-corrected m divided by sqrt(v-hat) |
| Early Steps | Stable from step one | Oversized; v underestimated with no correction | Bias correction keeps steps near alpha scale |
| Typical Strength | Final test accuracy on tuned vision recipes | RNNs and non-stationary objectives | Default for transformers and general use |
Leave a Reply