<jupyter_start><jupyter_text>Notice of OwnershipBased on <NAME>'s Example designed in CS 8001 Nonlinear Systems<jupyter_code>import numpy as np
import torch
import matplotlib.pyplot as plt
from typing import Union<jupyter_output><empty_output><jupyter_text>General IdeaLinear Regression is attempting to fit a linear equation to data as a line of best fit. This means we need both a training dataset as well as a testing dataset. For our use purposes, we have defined a simple ground truth function to prove our accuracy and derive the data from.<jupyter_code>def ground_truth_function(x: Union[np.ndarray, float]) -> Union[np.ndarray, float]:
    return 2*x+3 # A test function, you can change this to whatever you want.
    
def generate_data(start, stop, resolution, std=0.5):
    x_values = np.linspace(start, stop, resolution)
    signal = ground_truth_function(x_values)   
    return x_values, signal, signal + np.random.normal(0, std, signal.shape)<jupyter_output><empty_output><jupyter_text>Now lets plot the training data.<jupyter_code>def plot_data(x_values,regression,training_data):
    plt.plot(x_values, regression, label='function')
    plt.scatter(x_values, training_data, label='training data')
    plt.legend()
    plt.show()

#Generate some data to use for the rest of the notebook.
data = generate_data(0,1,100)

#Plot it.
plot_data(data[0],data[1],data[2])<jupyter_output><empty_output><jupyter_text>PerceptronThe key to understand here is that a single perceptron is able to represent a linear regression problem. Therefore we can take advantage of Pytorch's Linear layer model to make a linear regression example. Another way to do this is simply through the sklearn toolkit.<jupyter_code>#Now implement a Perceptron
import torch.nn as nn 
class Perceptron(nn.Module):
    def __init__(self):
        super().__init__()
        self.node = nn.Linear(1,1)
    
    def forward(self, x):
        return self.node(x)

#Define the criteria function.
def criterion(out,label):
    return (label - out)**2
#Now lets train the network.
import torch.optim as optim
from tqdm import tqdm
perceptron = Perceptron()

optimizer = optim.Adam(perceptron.parameters(), lr=1e-1)

inputs, ground_truth, training = data

#Now run the training loop.
for epoch in tqdm(range(1000), desc='Training network'):
    #Do one update for each sample.
    for x,y in zip(inputs, training):

        x = torch.tensor([x]).float() 
        y = torch.tensor([y]).float()

        optimizer.zero_grad()
        network_output = perceptron(x)
        loss = criterion(network_output, y)
        
        
        loss.backward()
        optimizer.step()


#Now lets plot the found function.
found_values = np.array([perceptron(torch.Tensor([inp]).float()).detach().numpy() for inp in inputs])
plot_data(inputs, found_values, training)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09667250437828372, 'fraction_numerical': 0.009106830122591943, 'mean_word_length': 4.398865784499055, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '480131', 'license': 'MIT', 'n_tokens_mistral': 911, 'n_tokens_neox': 871, 'n_words': 287, 'path': 'tutorials/python/LinearRegression.ipynb', 'repo_name': 'MJC598/SystemID', 'size': '2862'}