Optimization on Manifolds
Manifold optimization adapts gradient steps to curved constraint sets using tangent projections and retractions, keeping iterates exactly feasible.
Why Does This Exist?
Orthogonal RNNs, low-rank adapters, and subspace models need constraints to hold at every step, not approximately at the end. Penalty terms drift and need tuning; Euclidean steps with hard projection zigzag. Riemannian optimization moves natively on the set: each iterate satisfies constraints by construction and each step follows the surface.
It powers orthogonal initialization, Grassmannian subspace tracking, and rotation averaging. Prerequisites: manifolds, geodesics.
The one idea you need first
A retraction maps a tangent step back to the manifold with and local rigidity (it matches the exponential to first order). QR-based retraction on Stiefel ( of ) is the workhorse example.
Think of It Like This
Walking while glued to a globe
You must stay on the globe's surface with every footstep. Each move has three beats: face a compass direction (tangent), stride onto a flat local map (linear step), then snap your boots back to the soil (retraction).
Short strides make the snap tiny; giant leaps teleport you somewhere unintended. Good manifold code keeps strides chart-sized.
Where the analogy stops: retractions are first-order approximations, cheaper than true exponentials, and the savings fund larger models.
How It Actually Works
Riemannian gradient descent: where is the tangent-projected gradient. On Stiefel (): with the Euclidean gradient. Convergence mirrors Euclidean rates with curvature-dependent constants; trust-region variants use Hessian actions in tangent space.
Worked example
Minimize on unit circle from with :
- Euclidean gradient: . Tangent at : , so projected gradient is already tangent.
- Linear step: . Norm .
- Retract (normalize): . Loss vs start . Improved and feasible.
- Repeat: gradient , tangent projection removes radial part , tangent . Steps march toward , the true minimizer with loss .
Code
import numpy as np
def rgrad_circle(x: np.ndarray, g: np.ndarray) -> np.ndarray: return g - (g @ x) * x # remove radial component
x = np.array([0.0, 1.0])for _ in range(20): g = np.array([-1.0, 0.0]) x = x - 0.5 * rgrad_circle(x, g) x = x / np.linalg.norm(x) # retraction by normalization
print(np.round(x, 3)) # -> about [1. 0.], the minimizerWatch Out For
Retracting after oversized steps
Large tangent steps leave the chart where retraction approximates the exponential. QR and polar retractions can jump to distant representatives and loss spikes.
Scale steps by the manifold's injectivity radius proxy (curvature-aware caps) and shrink on retraction failure.
Forgetting vector transport for momentum
Tangent spaces differ per point, so yesterday's momentum vector lives in the wrong space today. Adding it raw breaks feasibility and direction.
Transport momentum () before combining with the new gradient.
The Quick Version
- Riemannian steps project gradients, move in tangents, and retract to feasibility.
- Stiefel and sphere formulas make projection plus retraction cheap.
- Rates mirror Euclidean theory with curvature constants added.
- Momentum needs vector transport across differing tangent planes.
- Step sizes must respect chart validity, not just loss decrease.