Continuous Action Spaces and Gaussian Policies
Imagine a robot arm that must apply a torque somewhere between −10 and +10 newton-meters. Or imagine a self-driving car that must pick a steering angle from a continuum of possibilities. Neither problem has a "list of actions" to rank. This differs from an Atari game with its handful of discrete joystick moves. Reinforcement learning agents acting in the physical world face this constantly. Actions are real-valued vectors, not tokens from a finite set. Any policy-based method built on Policy Parameterization and Objectives must therefore commit to something specific. It needs a way of representing a probability distribution over an infinite action set. It also needs a way of drawing samples from it efficiently and differentiably. The Gaussian policy is the workhorse solution. Outputting a probability for every action is impossible when there are uncountably many. Instead, the policy network outputs the parameters of a Normal distribution. Typically this means a mean vector and a variance (or log-variance) vector. The actual action is then sampled from that distribution. This single design choice makes continuous control tractable. It gives a closed-form, differentiable log-probability for the policy-gradient theorem. It gives a natural knob for exploration (the variance). It also composes cleanly with any neural network architecture producing real-valued outputs. This article develops the mechanics of Gaussian policies precisely. We cover how the mean and standard deviation are parameterized. We show how actions are sampled via the reparameterization trick. We explain how the log-density feeds the policy gradient. We also cover how squashing functions like handle bounded action ranges without breaking differentiability. We work through the complexity and correctness of the resulting gradient estimator. We trace a full numerical example from raw network outputs to a gradient update. We catalogue the pitfalls that make continuous-control RL notoriously fragile in practice — exploding variances, saturated squashing functions, and silently wrong log-density corrections. By the end, you will see Gaussian policies differently. They form the natural bridge between the discrete softmax world and the deterministic-policy world covered next. It is the same policy-gradient machinery, just with a different — and continuous — noise model. That bridge sets up Deterministic Policy Gradients. There, the exploration noise is stripped out of the policy itself. Instead, it is pushed entirely into a separate behavior distribution.
- Continuous action spaces have uncountably many actions, so policies output distribution parameters (mean, std) rather than per-action probabilities.
- The Gaussian policy is the default choice for real-valued action vectors.
- Sampling uses the reparameterization trick , , keeping the sample differentiable in .
- The log-density has a simple closed form, giving an exact score function for REINFORCE-style and actor-critic updates.
- Bounded actions require a squashing function (commonly ) with an explicit Jacobian correction term in the log-probability — a very common source of bugs.
- Gaussian policies generalize the softmax policy from discrete to continuous domains and lead naturally toward deterministic policies with separate exploration noise.
A Gaussian policy turns "which action to take" into "what mean and spread to predict," letting a neural network parameterize an infinite action space with just two differentiable numbers per action dimension.
The idea
A stochastic policy over a continuous action space cannot be represented as a table or a softmax over discrete outcomes, because there is no way to normalize a sum over infinitely many actions. Instead, the policy is represented as a probability density function , and the most common choice is the multivariate Normal (Gaussian) density:
where is the mean action predicted by a neural network, and is a covariance matrix controlling exploration spread. In the overwhelming majority of practical implementations, is restricted to be diagonal, , so each action dimension gets its own independent standard deviation. This turns the joint density into a product of univariate Gaussians, one per action dimension, which is far cheaper to evaluate, sample, and differentiate than a full covariance matrix. Two design decisions recur across implementations. First, whether is state-dependent (output by the network alongside ) or a single global learned parameter shared across all states — the latter is simpler and often used in early training stages of algorithms like PPO and TRPO. Second, how to keep positive: rather than letting the network output directly (which could go negative), the network typically outputs (unconstrained) and exponentiates it, or outputs a raw value passed through a softplus function. This is the same "parameterize in log-space" trick used throughout probabilistic deep learning to keep scale parameters positive without clipping. The other core idea is the reparameterization trick: instead of treating sampling as a black-box stochastic operation that blocks gradient flow, we write the sampled action as a deterministic, differentiable function of the network outputs plus independent noise,
This makes well-defined, which is essential both for the score-function estimator used in REINFORCE / actor-critic methods, and for the pathwise gradient estimator used in algorithms like Soft Actor-Critic that differentiate a critic's output directly through the sampled action.
How it works
Step 1 — network forward pass. A shared or separate neural network maps the state to raw outputs: a mean vector , and either a log-std vector or a single global log-std parameter vector .
Step 2 — construct the diagonal Gaussian. Exponentiate to get , clipped to a sane range (e.g. ) to avoid numerical blow-up.
Step 3 — sample via reparameterization. Draw and set .
Step 4 — squash if the action space is bounded. If the true action range is (or any bounded box), pass through : , then rescale to the environment's actual bounds. This is necessary because a Gaussian has unbounded support, but almost every physical actuator has hard limits.
Step 5 — compute the log-probability, with the change-of-variables correction if squashed. For the unsquashed Gaussian,
If a squashing function (e.g. ) is applied, the change-of-variables formula for densities requires subtracting the log-determinant of the Jacobian of :
Step 6 — plug into the policy gradient. For an actor-critic update, the log-probability's gradient with respect to is combined with an advantage estimate (from Policy Parameterization and Objectives):
Because everything above is differentiable in closed form, this expectation can be estimated with ordinary automatic differentiation over sampled trajectories. ```text function GAUSSIAN_POLICY_STEP(state s, θ): // Step 1: forward pass through policy network μ, log_σ ← PolicyNetwork(s; θ) // both vectors in ℝ^d log_σ ← clip(log_σ, LOG_SIGMA_MIN, LOG_SIGMA_MAX) σ ← exp(log_σ) // Step 2 & 3: reparameterized sample ε ← sample_standard_normal(d) a_raw ← μ + σ ⊙ ε // Step 4: squash into bounded action range (optional, if actions bounded) a_squash ← tanh(a_raw) a_env ← rescale(a_squash, action_low, action_high) // Step 5: log-probability with Jacobian correction logp_gauss ← -sum( (a_raw - μ)^2 / (2 σ^2) + log_σ + 0.5 log(2π) ) jac_corr ← sum( log(1 - a_squash^2 + ε_stable) ) // ε_stable avoids log(0) logp ← logp_gauss - jac_corr return a_env, logp, μ, σ
function ACTOR_CRITIC_UPDATE(trajectory batch, θ, critic φ): for each (s, a, r, s') in batch: a_env, logp, μ, σ ← GAUSSIAN_POLICY_STEP(s, θ) // during rollout: sample and store logp // ... environment executes a_env, returns r, s' ... for each stored (s, a, logp, r, s') in batch: V_s ← critic(s; φ) V_s_next ← critic(s'; φ) δ ← r + γ V_s_next - V_s // TD error / advantage estimate actor_loss ← actor_loss - logp stop_gradient(δ) // policy-gradient term critic_loss← critic_loss + δ^2 // value regression θ ← θ - η_actor ∇θ(actor_loss / batch_size) φ ← φ - η_critic ∇φ(critic_loss / batch_size) return θ, φ ``` The pseudocode separates the two concerns cleanly: `GAUSSIAN_POLICY_STEP` is a pure, reusable subroutine for turning a state into a differentiable sample and its log-density, and `ACTOR_CRITIC_UPDATE` shows how that log-density is consumed exactly as in the discrete-action case — the only thing that changed relative to a softmax policy is how is computed.
Complexity & correctness
Time complexity. For a diagonal Gaussian over action dimensions, sampling requires drawing standard normal variates and elementwise arithmetic, so sampling is . Evaluating the log-density is likewise : a sum over independent terms, each a constant number of arithmetic operations. This is asymptotically identical to evaluating a softmax over discrete actions when , but critically it does not scale with the size of the action space — for a full covariance matrix instead of a diagonal one, sampling and density evaluation cost due to the Cholesky factorization needed to sample correlated Gaussians and to compute the determinant in the density; this is the core reason diagonal covariance is preferred in practice for in the tens or hundreds. Backpropagating gradients through the reparameterized sample and log-density adds only a constant-factor overhead to the forward cost, since automatic differentiation is linear in the size of the computational graph.
Space complexity. The policy network needs an extra output head (or extra parameters for a global log-std vector) beyond whatever discrete-action network it is compared against, and storing the sampled action, noise, and log-density per trajectory step costs per timestep — no additional memory beyond ordinary trajectory storage.
Correctness argument. The correctness of using a Gaussian policy rests on two facts, both of which must be verified rather than assumed. Fact 1 — the policy gradient theorem does not care about the family of . The policy gradient theorem states
and this identity holds for any differentiable density , discrete or continuous, as long as is differentiable in and has support covering the actions actually taken. The Gaussian is simply one valid choice of ; the proof of the theorem (via the log-derivative trick ) never assumes discreteness. So plugging in a Gaussian's closed-form log-density is a legitimate instantiation, not an approximation. Fact 2 — the reparameterization trick preserves the expectation exactly. We need for any function , so that differentiating the right-hand side with respect to (which is legal because the randomness no longer depends on ) correctly estimates the gradient of the left-hand side. This equality is precisely the definition of an affine transformation of a standard Normal: if then , a standard fact from the closure of Gaussians under affine maps. So the reparameterized sample has exactly the target distribution, not merely approximately — no bias is introduced by this substitution. Fact 3 — the squashing correction is forced by the change-of-variables formula, not a heuristic. If for an invertible, differentiable (e.g. ), and has density , then the density of is , equivalently . For elementwise , , giving exactly the correction subtracted in Step 5 above. Omitting this term produces a log-probability that does not correspond to any valid density over the squashed action — the policy gradient computed from it is then simply wrong, not merely noisier, which is why this is flagged as the central pitfall below.
Tradeoffs. Diagonal-covariance Gaussians sacrifice the ability to represent correlated action dimensions (e.g. two joints that should move together), trading expressiveness for the versus speedup. State-independent (global) is simpler and more stable early in training but cannot adapt exploration to how confident the agent is in a given state, a limitation that state-dependent or later methods with entropy-regularized objectives address at the cost of extra network capacity and additional variance in the gradient estimator.
Worked example
Consider a 1-D torque-control task where the true action range is N·m. Suppose at state the policy network (after a forward pass) outputs raw mean and log-std:
We draw a single standard normal sample (fixed here for a reproducible trace).
| Step | Computation | Value |
|---|---|---|
| Raw (unsquashed) sample | ||
| Squashed action | ||
| Environment action | (scale to ) | N·m |
| Gaussian log-density of | ||
| Jacobian correction | ||
| Final |
(Sanity check: since we scaled 's output by 2, a fully rigorous treatment would add one more constant Jacobian term per action dimension for the final rescale — a fixed constant that does not depend on and so does not affect the policy gradient, which only needs ; it is nonetheless required if you want an exact log-likelihood, e.g. for comparing likelihoods across models.) Now suppose the critic estimates a TD error (the action turned out better than expected). The actor loss contribution for this single transition is . Backpropagating this scalar through the computational graph built in Steps 1–5 pushes in the direction that increases — i.e., increases the density the policy assigns to actions like N·m in states like — exactly the intended effect of a positive advantage. Notice what would happen without the Jacobian correction: the reported log-probability would be instead of , a difference of nearly nats for this single sample — large enough to substantially distort the gradient direction and magnitude, especially when is large and is deep in its saturated region (illustrated next).
Common pitfalls & traps
| Pitfall | Why it happens | Consequence |
|---|---|---|
| Forgetting the Jacobian correction after squashing | Treating as if it were | Systematically biased policy gradient; agent seems to learn but converges to a wrong or unstable policy |
| Letting | No lower bound on log-std, or entropy bonus too weak | Policy collapses to a near-deterministic point mass; exploration vanishes, gradients spike (division by tiny ) |
| Letting | No upper bound on log-std during early random initialization | Wildly noisy actions, unstable environment interaction, NaNs in log-density |
| Using raw (unclipped) network output as directly | Skipping the exp/softplus positivity transform | Negative variance is mathematically meaningless; density computation silently produces garbage |
| Confusing global vs. state-dependent std at inference time | Copy-pasted training code samples noise at evaluation | Evaluation returns noisy, non-reproducible actions instead of the near-greedy mean action |
| Ignoring saturation of near | Large raw means/stds push samples into flat regions of | Gradients vanish exactly where the correction term is largest, causing training instability |
Pioneers & history
The Gaussian policy grew out of the broader tradition of stochastic approximation and policy-gradient methods that treat action selection as sampling from a parameterized distribution, tracing back to Ronald Williams's REINFORCE algorithm, which established the score-function estimator that any differentiable stochastic policy — Gaussian included — relies on.
Origins · 1 minRonald J. Williams and how this was discovered
Williams's 1992 REINFORCE paper introduced the log-derivative trick that lets policy gradients be estimated from sampled trajectories without knowing the environment's dynamics. His formulation was general enough to apply directly to Gaussian action distributions, and his paper explicitly worked out the Gaussian unit case as one of the concrete examples of the general REINFORCE family — making it the direct ancestor of every continuous-control policy-gradient method since.
Where this matters
Gaussian policies are the default action representation in almost every modern continuous-control deep-RL algorithm: Proximal Policy Optimization (PPO), Trust Region Policy Optimization (TRPO), and Soft Actor-Critic (SAC) all parameterize their actor as a diagonal Gaussian (SAC additionally applying the tanh squash and Jacobian correction described here). These algorithms power robotic manipulation and locomotion research, simulated physics benchmarks (MuJoCo, PyBullet, Isaac Gym), and increasingly real hardware — quadruped and humanoid locomotion controllers, dexterous manipulation policies, and autonomous vehicle low-level control loops that must output continuous steering, throttle, and braking commands. In finance and operations research, Gaussian policies appear in continuous portfolio-allocation and inventory-control RL formulations where actions are fractional quantities. Understanding this representation is also the conceptual stepping stone to Deterministic Policy Gradients, where the stochastic Gaussian sampling is replaced by a deterministic mean output plus externally injected exploration noise, trading the closed-form score function for a lower-variance but off-policy-only gradient estimator — a tradeoff that only makes sense once the mechanics and costs of the Gaussian policy are fully understood.
Ask the tutor: How does the choice between state-dependent and global standard deviation change the bias-variance tradeoff of the policy gradient estimator in practice?
Why use a Gaussian rather than some other continuous distribution for the policy?
The Gaussian is attractive for three practical reasons: its log-density has a simple closed form, its sampling is trivial via the reparameterization trick, and it is closed under affine transformations, which makes the mathematics of the policy gradient theorem clean. Other choices exist — Beta distributions are sometimes preferred for actions naturally bounded in because they avoid the need for a squashing correction, and mixture-of-Gaussians or normalizing-flow policies can capture multimodal action distributions a single Gaussian cannot. But the Gaussian remains the default because it is simple, well-understood, numerically stable when properly bounded, and sufficient for most single-mode continuous-control tasks.
Does using a Gaussian policy assume the optimal action distribution is actually Gaussian?
No. The Gaussian is a parametric family chosen for tractability, not a claim about the true optimal policy's shape. If the truly optimal behavior at some state is multimodal — for instance, "swerve left or swerve right, but not straight" — a unimodal Gaussian simply cannot represent that; gradient descent will typically settle on one mode or an averaged, possibly poor, compromise action. This is a genuine expressiveness limitation, and it motivates richer policy families (mixtures, normalizing flows, diffusion-based policies) in settings where multimodality is important, at the cost of more expensive sampling and density evaluation.
How does the variance term affect exploration during training?
The standard deviation directly controls how far sampled actions spread around the mean, so it is the continuous analogue of the temperature in a softmax or the in -greedy. Early in training a larger encourages the agent to try a wide range of actions and discover good regions of action space; as training progresses, a well-trained policy typically learns to shrink in states where it is confident, narrowing around near-optimal actions. This adaptive behavior is why state-dependent is often preferred over a single global value, though it must be bounded away from zero to avoid premature convergence.
Why is the tanh squashing function used instead of simply clipping actions to their bounds?
Clipping is non-differentiable at the boundary and discards gradient information whenever a sampled action falls outside the valid range, which can happen often early in training when is large. The function is smooth and strictly monotonic, mapping the entire real line into without ever losing gradient signal to a hard cutoff, and its derivative has a simple closed form needed for the exact Jacobian correction. The tradeoff is that saturates for large inputs, producing near-zero gradients and a large negative Jacobian correction exactly when the raw pre-squash action is far from zero.
Can the same Gaussian-policy machinery be used for multi-dimensional, correlated actions?
Yes, by using a full covariance matrix instead of a diagonal one, typically parameterized via its Cholesky factor so that is guaranteed positive semi-definite. Sampling becomes and the log-density requires the log-determinant of , both costing in the dimension of the action space due to the Cholesky decomposition. This is used when action dimensions are known to be correlated — for instance, coordinated joint torques in a robot arm — but is rarely used at large because of the cubic cost.
How does the Gaussian policy relate to what comes next, deterministic policy gradients?
A Gaussian policy bundles exploration and action selection into a single stochastic object: sampling noise around a learned mean is both how the agent explores and how it acts. Deterministic policy gradients decouple these two roles — the policy itself outputs a single deterministic action , and any exploration noise is added externally as a separate, non-learned behavior policy used only during data collection. This trade removes the stochastic sampling step from the gradient computation entirely, replacing the score-function estimator with a lower-variance pathwise gradient through a learned critic, at the cost of needing off-policy correction machinery since the behavior and target policies now genuinely differ.
What happens numerically if log σ is not clipped or bounded?
During early training, a poorly initialized network can output extremely large or extremely negative log-std values. Extremely large log-std makes enormous, producing wild, physically nonsensical actions that can crash simulators or produce NaN rewards. Extremely negative log-std makes approach zero, causing the term in the log-density to blow up toward infinity for any sample that deviates even slightly from the mean, which destabilizes the loss and gradient magnitude. Clipping to a fixed range (commonly around ) before exponentiating is a standard, cheap safeguard against both failure modes.