Fitting a Straight Line using the Normal Equations
Fitting a Straight Line using the Normal Equations
Reference: OpenCV University
Fitting a Straight Line using the Normal Equations
We will begin by showing that the normal equations can be used to find the parameters of a straight line (Slope and intercept) given a set of data points in two dimensions.
import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.optim as optim
plt.style.use("ggplot")
plt.rcParams["figure.figsize"] = (10, 5)
plt.rcParams["axes.titlesize"] = 18
plt.rcParams["axes.labelsize"] = 16
block_plot = False
Create Convenience Functions
import random
# Random manual seed for consistency.
seed = 42
random.seed(seed)
np.random.seed(seed)
torch.random.manual_seed(seed)
torch.manual_seed(seed)
torch.backends.deterministic = True
torch.backends.benchmark = True
def create_linear_data(num_data=100, y_offset=0, slope=1, stddev=0.3):
# Create some linear data with a small amount of noise.
X = 10 * torch.rand(size=[num_data])
y = y_offset + slope * X + torch.normal(std=stddev, mean=0, size=[num_data])
# Standard deviation(표준 편차) : stddev, add 0 mean Gaussina noise
X = X.view((len(X), 1))
y = y.view((len(y), 1))
return X, y
def plot_data(x, y, xlim=(0, 10), ylim=(0, 10)):
plt.figure
plt.plot(x, y, "b.")
plt.xlabel("x")
plt.ylabel("y"),
plt.xlim(xlim)
plt.ylim(ylim)
plt.show(block=block_plot)
Generate Linear Data
y_int = 3
slope = .4
X, y = create_linear_data(y_offset = y_int, slope = slope, stddev = 0.3)
plot_data(X, y)
Implement Normal Equations
# Function of Normal Equations
def compute_theta(X, y):
m = X.shape[0] # Number of samples.
# Concatenate a 1 to the beginning of each feature vector.
X = torch.cat((torch.ones((m, 1)), X), axis=1)
y = y.view((m, 1))
# Solve for theta using the Normal Equations.
X_T = X.T
XT_X = torch.matmul(X_T, X)
XT_X_inv = torch.inverse(XT_X)
XT_y = torch.matmul(X_T, y)
theta = torch.matmul(XT_X_inv, XT_y)
return theta
print("Actual Coefficients:\n")
print("Slope: ", slope)
print("Y-Int: ", y_int)
print("\n")
# Compute the parameters (theta) based on the closed-form solution using the Normal Equations.
theta = compute_theta(X, y)
y_int = theta[0].numpy()
slope = theta[1].numpy()
print("Predicted Coefficients:\n")
print("Slope: ", slope[0])
print("Y-int: ", y_int[0])
Display the results
def predict_y(X, theta):
X = torch.cat((torch.ones((X.shape[0], 1)), X), axis=1)
pred_y = torch.matmul(X, theta)
return pred_y
pred_y = predict_y(X, theta)
plt.plot(X, y, "b.")
plt.plot(X, pred_y, "c-")
plt.xlim((0, 10))
plt.ylim((0, 10))
plt.text(1, 7.0, "theta[0]: Slope = " + str(slope[0]), fontsize=14)
plt.text(1, 6.5, "theta[1]: Y-Int = " + str(y_int[0]), fontsize=14)
plt.xlabel("X")
plt.ylabel("y")