import torch
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
# Retina display
%config InlineBackend.figure_format = 'retina'
from tueplots import bundles
plt.rcParams.update(bundles.beamer_moml())
# Also add despine to the bundle using rcParams
'axes.spines.right'] = False
plt.rcParams['axes.spines.top'] = False
plt.rcParams[
# Increase font size to match Beamer template
'font.size'] = 16
plt.rcParams[# Make background transparent
'figure.facecolor'] = 'none'
plt.rcParams[
import logging
'matplotlib.font_manager').disabled = True
logging.getLogger(
from ipywidgets import interact, FloatSlider, IntSlider
Setting Up & Imports
Coin Toss Problem
def plot_beta(alpha, beta):
= torch.distributions.Beta(concentration1=alpha, concentration0=beta)
dist = torch.linspace(0, 1, 500)
xs = dist.log_prob(xs).exp()
ys ="C0")
plt.plot(xs, ys, color
plt.grid()r"$\theta$")
plt.xlabel(r"$p(\theta)$")
plt.ylabel("Beta Distribution")
plt.title(
plt.show()
interact(
plot_beta,=FloatSlider(min=1, max=11, step=0.5, value=1),
alpha=FloatSlider(min=1, max=11, step=0.5, value=1),
beta )
<function __main__.plot_beta(alpha, beta)>
= [[1, 1], [5, 1], [1, 3], [2, 2], [2, 5]]
combinations = plt.subplots(1, 1)
fig, ax for alpha, beta in combinations:
= torch.distributions.Beta(concentration1=alpha, concentration0=beta)
dist = torch.linspace(0, 1, 500)
xs = dist.log_prob(xs).exp()
ys =rf"($\alpha$={alpha}, $\beta$={beta})")
ax.plot(xs, ys, label
ax.legend()
ax.grid()r"$\theta$")
ax.set_xlabel(r"$p(\theta)$")
ax.set_ylabel("Beta Distribution")
ax.set_title(0, 3)
ax.set_ylim("../figures/map/beta_distribution.pdf", bbox_inches="tight")
plt.savefig( plt.show()
= 11
alpha = 11
beta = 0.5
bernoulli_theta = 9
n_1 = 1
n_0
= torch.distributions.Beta(concentration1=alpha, concentration0=beta)
dist = torch.linspace(0, 1, 500)
xs = dist.log_prob(xs).exp()
ys ="Beta Prior")
plt.plot(xs, ys, label
= n_1 + n_0
sample_size f"H: {n_1}, T: {n_0}")
plt.title(
= n_1 / (sample_size) # samples.mean()
mle_estimate ="k", linestyle="--", label="MLE")
plt.axvline(mle_estimate, color
= (n_1 + alpha - 1) / (sample_size + alpha + beta - 2)
map_estimate ="r", linestyle="-.", label="MAP")
plt.axvline(map_estimate, color
/ (alpha + beta), color="g", linestyle=":", label="Prior Mean")
plt.axvline(alpha
plt.grid()r"$\theta$")
plt.xlabel(r"$p(\theta)$")
plt.ylabel(=(1.25, 1), borderaxespad=0)
plt.legend(bbox_to_anchor"../figures/map/coin_toss_prior_mle_map.pdf", bbox_inches="tight")
plt.savefig( plt.show()
def plot_beta_all(alpha, beta, bernoulli_theta=0.5, sample_size=10):
42)
torch.manual_seed(
= torch.distributions.Beta(concentration1=alpha, concentration0=beta)
dist = torch.linspace(0, 1, 500)
xs = dist.log_prob(xs).exp()
ys ="Beta Prior")
plt.plot(xs, ys, label
= torch.empty(sample_size)
samples for s_num in range(sample_size):
= torch.distributions.Bernoulli(probs=bernoulli_theta)
dist = dist.sample()
samples[s_num] = int(samples.sum())
n_1 = int(sample_size - n_1)
n_0 f"H: {n_1}, T: {n_0}")
plt.title(
= n_1 / (sample_size) # samples.mean()
mle_estimate ="k", linestyle="--", label="MLE")
plt.axvline(mle_estimate, color
= (n_1 + alpha - 1) / (sample_size + alpha + beta - 2)
map_estimate ="r", linestyle="-.", label="MAP")
plt.axvline(map_estimate, color
/ (alpha + beta), color="g", linestyle=":", label="Prior Mean")
plt.axvline(alpha
plt.grid()r"$\theta$")
plt.xlabel(r"$p(\theta)$")
plt.ylabel(=(1.25, 1), borderaxespad=0)
plt.legend(bbox_to_anchor
plt.show()
interact(
plot_beta_all,=FloatSlider(min=1, max=51, step=1, value=11),
alpha=FloatSlider(min=1, max=51, step=1, value=11),
beta=FloatSlider(min=0, max=1, step=0.1, value=0.5),
bernoulli_theta=IntSlider(min=10, max=1000, step=10, value=10),
sample_size )
<function __main__.plot_beta_all(alpha, beta, bernoulli_theta=0.5, sample_size=10)>
Linear Regression
= 20
n_data = torch.linspace(-1, 1, n_data)
x = 2
slope = 1
intercept = lambda x: slope * x + intercept
f
= torch.distributions.Normal(0, 1).sample((n_data,))
noise = f(x) + noise
y
plt.figure()="x", c="k", s=20, label="Noisy data")
plt.scatter(x, y, marker="k", label="True function")
plt.plot(x, f(x), c"x")
plt.xlabel("y")
plt.ylabel(= f"{slope} x + {intercept}"
line_str r"$y_{true} = $" + line_str)
plt.title(f"../figures/map/linreg_data-{n_data}.pdf", bbox_inches="tight")
plt.savefig( plt.legend()
<matplotlib.legend.Legend at 0x7f2b9d6409d0>
def nll(theta):
= theta[0] + theta[1] * x
mu = torch.tensor(1.0)
sigma = torch.distributions.normal.Normal(mu, sigma)
dist return -dist.log_prob(y).sum()
def neg_log_prior(theta):
= torch.tensor([0.0, 0.0]) # Prior mean for slope and intercept
prior_mean = torch.tensor(
prior_std 0.1, 0.1]
[# Prior standard deviation for slope and intercept
) = torch.distributions.normal.Normal(prior_mean, prior_std)
dist return -dist.log_prob(theta).sum()
def neg_log_joint(theta):
return nll(theta) + neg_log_prior(theta)
# Create a grid of theta[0] and theta[1] values
= torch.linspace(-4, 4, 101)
theta0_values = torch.linspace(-4, 4, 101)
theta1_values = torch.meshgrid(theta0_values, theta1_values)
theta0_mesh, theta1_mesh = torch.zeros_like(theta0_mesh)
nll_values = torch.zeros_like(theta0_mesh)
nlp_values = torch.zeros_like(theta0_mesh)
nlj_values
for i in range(len(theta0_values)):
for j in range(len(theta1_values)):
= torch.tensor([theta0_values[i], theta1_values[j]])
theta_current = nll(theta_current)
nll_values[i, j] = neg_log_prior(theta_current)
nlp_values[i, j] = neg_log_joint(theta_current) nlj_values[i, j]
def plot_contour_with_minima(values, theta0_values, theta1_values, title, ax, cbar_ax):
# plt.figure(figsize=(6, 6))
= ax.contourf(theta0_mesh, theta1_mesh, values, levels=20, cmap="viridis")
contour r"$\theta_0$")
ax.set_xlabel(r"$\theta_1$")
ax.set_ylabel(
ax.set_title(title)
"equal", adjustable="box") # Set aspect ratio to be equal
ax.set_aspect(
# mark the minimum
= np.unravel_index(np.argmin(values), values.shape)
min_idx = theta0_values[min_idx[0]]
t0_min = theta1_values[min_idx[1]]
t1_min
ax.scatter(
t0_min,
t1_min,="x",
marker="red",
color=100,
s
)
ax.annotate(f"({t0_min:.2f}, {t1_min:.2f})",
(t0_min, t1_min),=(t0_min - 0.5, t1_min - 0.8),
xytext="red",
color# set size of text
=12,
size
)
=ax, cax=cbar_ax)
fig.colorbar(contour, ax# plt.tight_layout()
# plt.show()
# return contour
# Usage example
= plt.subplots(
fig, ax 1, 7, figsize=(15, 3), gridspec_kw={"width_ratios": [10, 10, 1, 10, 1, 10, 1]}
)= 0
i
def get_next_ax():
global i
+= 1
i return ax[i - 1]
= get_next_ax()
data_ax ="x", c="k", s=20, label="Noisy data")
data_ax.scatter(x, y, marker="k", label="True function")
data_ax.plot(x, f(x), c"x")
data_ax.set_xlabel("y")
data_ax.set_ylabel(= f"{slope} x + {intercept}"
line_str r"$y_{true} = $" + line_str)
data_ax.set_title(
data_ax.legend()
= plot_contour_with_minima(
contour
nll_values,
theta0_values,
theta1_values,"Negative Log-Likelihood",
get_next_ax(),
get_next_ax(),
)= plot_contour_with_minima(
contour
nlp_values,
theta0_values,
theta1_values,"Negative Log-Prior",
get_next_ax(),
get_next_ax(),
)= plot_contour_with_minima(
contour
nlj_values,
theta0_values,
theta1_values,"Negative Log-Joint",
get_next_ax(),
get_next_ax(), )