CS-866 Deep Reinforcement Learning
Notebook: Gaussian Density
Instructor: Nazar Khan | Semester: Fall 2025
This notebook provides an interactive introduction to the Gaussian Density function.
1. What is a Gaussian Density?¶
A Gaussian (also called Normal Distribution or Bell Curve) is a smooth hill-shaped curve.
- Most values are near the center
- Fewer values appear far away
- The shape looks like a bell
It is important in:
- Machine learning
- Reinforcement learning (policies!)
- Statistics
- Physics
- Nature (heights, errors, noise, etc.) -- hence the name Normal
2. Why is Gaussian Density important in RL?¶
In REINFORCE with continuous actions:
- The policy outputs mean (
μ) and standard deviation (σ) - Actions are sampled from a Gaussian, which provides an inherent way of exploration.
- The log-probability of the action is needed for gradients
So Gaussian density is at the heart of continuous-action RL.
3. The Formula¶
The probability of a value x under a Gaussian with mean $\mu$ and standard deviation $\sigma$ is:
$\mathcal{N}(x \mid \mu, \sigma) = \frac{1}{\sqrt{2\pi}\sigma} \exp\left( -\frac{1}{2} \left( \frac{x - \mu}{\sigma} \right)^2 \right)$
Think of it like this:
- $\mu$ = where the bell curve is centered
- $\sigma$ = how wide or skinny it is
- The exponential makes the curve drop smoothly as you move away from the center.
4. Let's interactively change $\mu$ and $\sigma$¶
We will create interactive sliders to change the bell curve shape.
Requires: ipywidgets. Install if needed:
#!pip install ipywidgets
Interactive Gaussian Visualization¶
# ============================================================
# INTERACTIVE GAUSSIAN DEMO
# Extremely child-friendly explanation + visualization
# ============================================================
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider
from IPython.display import display
# Nice plot style
plt.style.use("seaborn-v0_8")
# ------------------------------------------------------------
# Function to draw a Gaussian curve
# ------------------------------------------------------------
def plot_gaussian(mu, sigma):
# Make 400 points from -10 to 10
x = np.linspace(-10, 10, 400)
# Gaussian formula
coef = 1.0 / (np.sqrt(2 * np.pi) * sigma)
exponent = np.exp(-0.5 * ((x - mu) / sigma) ** 2)
y = coef * exponent
plt.figure(figsize=(8, 4))
plt.plot(x, y, linewidth=3)
plt.title(f"Gaussian Density (μ = {mu}, σ = {sigma})", fontsize=16)
plt.xlabel("x")
plt.ylabel("Probability Density")
plt.ylim(0, max(0.5, np.max(y)*1.1))
# Vertical line at mean
plt.axvline(mu, color="red", linestyle="--", label="Mean (center)")
plt.legend()
plt.grid(True)
plt.show()
# ------------------------------------------------------------
# Interactive sliders
# ------------------------------------------------------------
interact(
plot_gaussian,
mu=FloatSlider(value=0, min=-5, max=5, step=0.1, description="μ (center)"),
sigma=FloatSlider(value=1.0, min=0.2, max=5, step=0.1, description="σ (spread)")
);
interactive(children=(FloatSlider(value=0.0, description='μ (center)', max=5.0, min=-5.0), FloatSlider(value=1…
5. Explanation of parameter effects¶
$\mu$ (mean): Moves the whole bell curve left or right. (Like moving the center of a flashlight beam.)
$\sigma$ (standard deviation): Controls width
- Small $\sigma\implies$ skinny + tall
- Large $\sigma\implies$ wide + flat (Like zooming in and out on a hill.)
The interactive sliders show this clearly.
Interactive Sampling Demo¶
# ============================================================
# GAUSSIAN SAMPLING DEMO
# ============================================================
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider, IntSlider
plt.style.use("seaborn-v0_8")
def sample_gaussian(mu, sigma, n):
samples = np.random.normal(mu, sigma, n)
plt.figure(figsize=(8, 4))
plt.hist(samples, bins=20, density=True, alpha=0.6, color="orange")
plt.title(f"Samples from Gaussian (μ = {mu}, σ = {sigma})", fontsize=16)
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.grid(True)
plt.show()
interact(
sample_gaussian,
mu=FloatSlider(value=0, min=-5, max=5, step=0.1),
sigma=FloatSlider(value=1, min=0.2, max=5, step=0.1),
n=IntSlider(value=200, min=50, max=2000, step=50, description="Samples")
);
interactive(children=(FloatSlider(value=0.0, description='mu', max=5.0, min=-5.0), FloatSlider(value=1.0, desc…
7. Sampling animation¶
# ============================================================
# GAUSSIAN SAMPLING ANIMATION (GIF)
# Samples "falling" onto a histogram frame-by-frame
# ============================================================
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter
# Parameters
mu = 0 # center
sigma = 1 # spread
num_samples = 4000 # total points to animate
frames = 100 # how many animation frames
gif_name = "gaussian_falling_samples.gif"
# Generate all samples in advance
samples = np.random.normal(mu, sigma, num_samples)
# Prepare figure
fig, ax = plt.subplots(figsize=(8, 4))
ax.set_xlim(-5, 5)
ax.set_ylim(0, 0.5)
ax.set_title(f"Gaussian Sampling Animation (μ={mu}, σ={sigma})")
ax.set_xlabel("Value")
ax.set_ylabel("Density")
# Draw the true Gaussian density curve
x = np.linspace(-5, 5, 400)
true_pdf = (1/(np.sqrt(2*np.pi)*sigma)) * np.exp(-0.5 * ((x - mu)/sigma)**2)
ax.plot(x, true_pdf, linewidth=2, color="blue", label="True Density")
ax.legend()
# Prepare histogram data
hist_data = []
# Histogram bars (initial empty)
bars = ax.bar([], [], width=0.3)
# Animation function
def update(frame_index):
global bars
# Add some samples each frame
chunk = samples[: int((frame_index+1) * num_samples/frames)]
# Compute histogram
counts, bin_edges = np.histogram(chunk, bins=30, range=(-5, 5), density=True)
# Clear previous bars
for col in ax.collections:
col.clear()
#ax.collections.clear()
# Draw updated histogram
ax.hist(chunk, bins=30, range=(-5, 5), density=True, alpha=0.6, color="orange")
ax.set_title(f"Gaussian Sampling (Frame {frame_index+1}/{frames})")
# Create animation
anim = FuncAnimation(fig, update, frames=frames, interval=80)
# Save as GIF
anim.save(gif_name, writer=PillowWriter(fps=20))
plt.close()
print("GIF saved as:", gif_name)
/tmp/ipykernel_30545/3930654035.py:64: UserWarning: Creating legend with loc="best" can be slow with large amounts of data. anim.save(gif_name, writer=PillowWriter(fps=20))
