import torch
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[
= torch.linspace(-1, 1, 100)
x = lambda x: 3*x + 1
f
= torch.distributions.Normal(0, 0.1).sample((100,))
noise = f(x) + noise y
='x', c='k', s=20, label="Noisy data")
plt.scatter(x, y, marker='k', label="True function")
plt.plot(x, f(x), c plt.legend()
<matplotlib.legend.Legend at 0x7fc90a452970>
def forward(x, theta):
return x*theta[1] + theta[0]
def nll(theta):
= forward(x, theta)
mu = torch.tensor(1.0)
sigma = torch.distributions.normal.Normal(mu, sigma)
dist return -dist.log_prob(y).sum()
2)), nll(torch.tensor([1., 3.])) nll(torch.zeros(
(tensor(297.3265), tensor(92.3937))
# Create a grid of theta[0] and theta[1] values
= torch.linspace(-4, 4, 100)
theta0_values = torch.linspace(-4, 4, 100)
theta1_values = torch.meshgrid(theta0_values, theta1_values)
theta0_mesh, theta1_mesh = torch.zeros_like(theta0_mesh)
nll_values
# Calculate negative log-likelihood values for each combination of theta[0] and theta[1]
for i in range(len(theta0_values)):
for j in range(len(theta1_values)):
= nll([theta0_values[i], theta1_values[j]])
nll_values[i, j]
# Create a contour plot
=(8, 6))
plt.figure(figsize= plt.contourf(theta0_mesh, theta1_mesh, nll_values, levels=20, cmap='viridis')
contour
plt.colorbar(contour)r'$\theta_0$')
plt.xlabel(r'$\theta_1$')
plt.ylabel(#plt.title('Contour Plot of Negative Log-Likelihood')
# Adding contour level labels
= plt.contour(theta0_mesh, theta1_mesh, nll_values, levels=20, colors='black', linewidths=0.5)
contour_labels =True, fontsize=8, fmt='%1.1f')
plt.clabel(contour_labels, inline
# Find and mark the minimum
= torch.argmin(nll_values)
min_indices = theta0_mesh.flatten()[min_indices]
min_theta0 = theta1_mesh.flatten()[min_indices]
min_theta1 ='red', marker='x', label='Minima')
plt.scatter(min_theta0, min_theta1, color
# Draw lines from the minimum point to the axes
='gray', linestyle='--')
plt.axhline(min_theta1, color='gray', linestyle='--')
plt.axvline(min_theta0, color
# Add labels to the lines
4.2, f'{min_theta0:.2f}', color='gray', fontsize=10)
plt.text(min_theta0, -4.5, min_theta1, f'{min_theta1:.2f}', color='gray', fontsize=10)
plt.text( plt.legend()
<matplotlib.legend.Legend at 0x7fc90a276d60>
def plot_theta(theta):
=(8, 4))
plt.figure(figsize
# Left-hand side plot (contour plot)
1, 2, 1)
plt.subplot(= plt.contourf(theta0_mesh, theta1_mesh, nll_values, levels=20, cmap='viridis')
contour # Colorbar
plt.colorbar(contour)0], theta[1], color='red', marker='x')
plt.scatter(theta[1], color='gray', linestyle='--')
plt.axhline(theta[0], color='gray', linestyle='--')
plt.axvline(theta[r'$\theta_0$')
plt.xlabel(r'$\theta_1$')
plt.ylabel('Contour Plot of Negative Log-Likelihood')
plt.title(
# Right-hand side plot (data fit)
1, 2, 2)
plt.subplot(='Data')
plt.scatter(x, y, label0] + theta[1] * x, color='red', label='Fit')
plt.plot(x, theta['x')
plt.xlabel('y')
plt.ylabel('Data Fit')
plt.title(
plt.legend()
#plt.tight_layout()
plt.show()
# Generate a random theta vector
= torch.randn(2)
random_theta print(random_theta)
import ipywidgets as widgets
from ipywidgets import interact
@interact(theta0=(-5, 5, 0.1), theta1=(-5, 5, 0.1))
def plot_interactive(theta0=random_theta[0], theta1=random_theta[1]):
= [theta0, theta1]
theta plot_theta(theta)
tensor([-0.9771, 0.4177])
## Logistic regression
= torch.linspace(-5, 5, 100)
x
= torch.tensor([-10.0, 4.0])
true_theta = torch.sigmoid(true_theta[0] + true_theta[1] * x)
p
='p(x)') plt.plot(x, p, label
= torch.distributions.Bernoulli(probs=p).sample()
y y
tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
0., 0., 0., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
'o') plt.plot(x, y,
def nll_lr(theta):
= torch.sigmoid(theta[0]+ theta[1]*x)
p = torch.distributions.Bernoulli(probs=p)
dist return -dist.log_prob(y).sum()
def nll_lr_logits(theta):
= theta[0]+ theta[1]*x
logits = torch.distributions.Bernoulli(logits=logits)
dist return -dist.log_prob(y).sum()
1.0, 1.0])), nll_lr(true_theta), nll_lr_logits(torch.tensor([1.0, 1.0])), nll_lr_logits(true_theta), nll_lr(torch.tensor([
(tensor(78.3085), tensor(6.8952), tensor(78.3085), tensor(6.8952))
# Create a grid of theta[0] and theta[1] values
= torch.linspace(-15, 5, 100)
theta0_values = torch.linspace(-2, 8, 100)
theta1_values = torch.meshgrid(theta0_values, theta1_values)
theta0_mesh, theta1_mesh = torch.zeros_like(theta0_mesh)
nll_values
# Calculate negative log-likelihood values for each combination of theta[0] and theta[1]
for i in range(len(theta0_values)):
for j in range(len(theta1_values)):
= nll_lr([theta0_values[i], theta1_values[j]])
nll_values[i, j]
# Create a contour plot
=(8, 6))
plt.figure(figsize= plt.contourf(theta0_mesh, theta1_mesh, nll_values, levels=20, cmap='viridis')
contour
plt.colorbar(contour)0], true_theta[1], color='red', marker='x', label='True Theta')
plt.scatter(true_theta[r'$\theta_0$')
plt.xlabel(r'$\theta_1$')
plt.ylabel('Contour Plot of Negative Log-Likelihood (Logistic Regression)')
plt.title( plt.legend()
<matplotlib.legend.Legend at 0x7fc90358c6a0>
def decision_boundary(theta):
return - (theta[0] + theta[1] * x) / theta[1]
# Create a given theta vector
= torch.tensor([-10.0, 4.0])
given_theta
# Plot data and decision boundary for the given theta
=(8, 4))
plt.figure(figsize
# Left-hand side plot (data and decision boundary)
1, 2, 1)
plt.subplot(='Data')
plt.scatter(x, y, label='red', label='Decision Boundary')
plt.plot(x, decision_boundary(given_theta), color'x')
plt.xlabel('y')
plt.ylabel('Logistic Regression: Data and Decision Boundary')
plt.title( plt.legend()
<matplotlib.legend.Legend at 0x7fc90c4838e0>