pythonperceptron

Is there a way to use a range loop and record data for said loop for a scatter plot in python?


I'm making a basic Perceptron in Python 3.11.1 and I need a way to visualize change between epochs.

Here's my code:

import numpy as np
from matplotlib import pyplot as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_d(x):
    return x * (1 - x)

training_inputs = np.array([[0, 0, 1],
                           [1, 1, 1],
                           [1, 0, 1],
                           [0, 1, 1]])

training_outputs = np.array([[1, 0, 1, 0]]).T

np.random.seed(1)

synaptic_weights = 2 * np.random.random((3, 1)) - 1

print("Random Starting Synaptic Weights: ")
print(synaptic_weights)

for i in range(100000):
    input_layer = training_inputs

    outputs = sigmoid(np.dot(input_layer, synaptic_weights))

    error = training_outputs - outputs

    adjustments = error * sigmoid_d(outputs)
    
    synaptic_weights += np.dot(input_layer.T, adjustments)
    
plt.scatter(i, outputs[0], c="blue")
plt.scatter(i, outputs[1], c="orange")
plt.scatter(i, outputs[2], c="green")
plt.scatter(i, outputs[3], c="red")

print("Synaptic Weights after training: ")
print(synaptic_weights)

print("Post-Training Outputs: ")
print(outputs)

plt.show()


When I tried it, it gave me the data from the last epoch. I was expecting for it to show the Perceptron training off of my basic dataset over time.


Solution

  • Change the indentation of the plt commands so that they are inside the loop and add a pause at each step to create an animation:

    import numpy as np
    from matplotlib import pyplot as plt
    
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
    
    def sigmoid_d(x):
        return x * (1 - x)
    
    training_inputs = np.array([[0, 0, 1],
                               [1, 1, 1],
                               [1, 0, 1],
                               [0, 1, 1]])
    
    training_outputs = np.array([[1, 0, 1, 0]]).T
    
    np.random.seed(1)
    
    synaptic_weights = 2 * np.random.random((3, 1)) - 1
    
    print("Random Starting Synaptic Weights: ")
    print(synaptic_weights)
    
    for i in range(100):
        input_layer = training_inputs
    
        outputs = sigmoid(np.dot(input_layer, synaptic_weights))
    
        error = training_outputs - outputs
    
        adjustments = error * sigmoid_d(outputs)
        
        synaptic_weights += np.dot(input_layer.T, adjustments)
        
        plt.scatter(i, outputs[0], c="blue")
        plt.scatter(i, outputs[1], c="orange")
        plt.scatter(i, outputs[2], c="green")
        plt.scatter(i, outputs[3], c="red")
        plt.pause(0.05)
    
    print("Synaptic Weights after training: ")
    print(synaptic_weights)
    
    print("Post-Training Outputs: ")
    print(outputs)
    
    plt.show()
    

    The plot will not be updated "live" but at the end of the loop.

    For real-time animation you could look at the Matplotlib animation API.

    See also: