Skip to content

Instantly share code, notes, and snippets.

@rjlutz
Last active March 19, 2024 00:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjlutz/5fb448c6f6b9d2663a745c833bbf162f to your computer and use it in GitHub Desktop.
Save rjlutz/5fb448c6f6b9d2663a745c833bbf162f to your computer and use it in GitHub Desktop.
Starter code and data files for neural net / python practice assignment
## modified from:
## https://github.com/miloharper/simple-neural-network and
## https://medium.com/technology-invention-and-more/how-to-build-a-simple-neural-network-in-9-lines-of-python-code-cc8f23647ca1
## thanks!
import csv
from numpy import exp, array, random, dot
class NeuralNetwork():
def __init__(self):
# Seed the random number generator, so it generates the same numbers
# every time the program runs.
random.seed(1)
# The Sigmoid function, which describes an S shaped curve.
# We pass the weighted sum of the inputs through this function to
# normalise them between 0 and 1.
def __sigmoid(self, x):
return 1 / (1 + exp(-x))
# The derivative of the Sigmoid function.
# This is the gradient of the Sigmoid curve.
# It indicates how confident we are about the existing weight.
def __sigmoid_derivative(self, x):
return x * (1 - x)
def randomize_weights(self, num_inputs, num_outputs):
# We model a single neuron, with inputs*outputs input connections and 1 output connection.
# We assign random weights to an i*o x 1 matrix, with values in the range -1 to 1
# and mean 0.
self.synaptic_weights = 2 * random.random((num_inputs*num_outputs, 1)) - 1
# We train the neural network through a process of trial and error.
# Adjusting the synaptic weights each time. if __name__ == "__main__":
def train(self, training_set_inputs, training_set_outputs, number_of_training_iterations):
for iteration in range(number_of_training_iterations):
# Pass the training set through our neural network (a single neuron).
output = self.think(training_set_inputs)
# Calculate the error (The difference between the desired output
# and the predicted output).
error = training_set_outputs - output
# Multiply the error by the input and again by the gradient of the Sigmoid curve.
# This means less confident weights are adjusted more.
# This means inputs, which are zero, do not cause changes to the weights.
adjustment = dot(training_set_inputs.T, error * self.__sigmoid_derivative(output))
# Adjust the weights.
self.synaptic_weights += adjustment
# The neural network thinks.
def think(self, inputs):
# Pass inputs through our neural network (our single neuron).
return self.__sigmoid(dot(inputs, self.synaptic_weights))
def read_data(self, input_file):
'''
:param self:
:param input_file: read inputs from data file
here is an example data file
1, 3
0, 1, 1, 0
0, 0, 1
1, 1, 1
1, 0, 1
0, 1, 1
where the first line contains every image's 2d dimensions,
the second line contains the dataset's labels,
and the remaining lines contain a 2d map of images
:return: a 2d array of unrolled image values and a column vector of labels, such as:
images = array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
labels = array([[0, 1, 1, 0]]).T
'''
with open(input_file, 'r') as csvfile:
reader = csv.reader(csvfile, delimiter=',', quotechar='|')
image_height, image_width = (0,0)
## TODO
## Read in the first line of the file from the reader object
## you will need to convert each comma separated value to an int and
## place these in a two-item list. assign these list items as:
##
## image_height, image_width =
##
labels = ()
## TODO
## Read in the second line of the file from the reader object
## you will need to convert each csv element to an int and place
## them into a variable length list named 'labels.'
## labels =
##
images = []
for i in range(len(labels)):
input = []
pixels = 0;
while pixels < image_height * image_width:
## TODO
## Read in the next line in the file
## Assign the results to 'line'. No further processing is necessary
## line =
##
if len(line) == 0 or line[0].startswith("#"): continue
for px in map(int, line):
input.append(px)
pixels += 1;
images.append(input)
# reset synaptic weights, based on new dims, input equals # of pixels, output = 1
self.randomize_weights(image_width * image_height, 1)
return array(images), array([labels]).T
if __name__ == "__main__":
# Intialise a single neuron neural network.
neural_network = NeuralNetwork()
training_set_inputs, training_set_outputs = neural_network.read_data('images4x1x3.csv')
# Train the neural network using a training set.
# Do it 10,000 times and make small adjustments each time.
neural_network.train(training_set_inputs, training_set_outputs, 10000)
# Test the neural network with a new situation.
print("Considering new situation [1, 0, 0] -> ?: (expecting ~0.99993704)")
challenge = array([1, 0, 0])
print(neural_network.think(challenge), "expecting value close to 1")
print()
neural_network = NeuralNetwork()
training_set_inputs, training_set_outputs = neural_network.read_data('images4x2x2.csv')
neural_network.train(training_set_inputs, training_set_outputs, 10000)
print("Considering new situation [1, 0, 0, 0] -> ?: (expecting ~0.99993703)")
challenge = array([1, 0, 0, 0])
print(neural_network.think(challenge), "expecting value close to 1")
print()
## TODO use the following code to test your 5x5 image detection data file
'''
neural_network = NeuralNetwork()
training_set_inputs, training_set_outputs = neural_network.read_data('images25x5x5.csv')
neural_network.train(training_set_inputs, training_set_outputs, 10000)
print("Considering new situation [] -> ?: ")
challenge = array(
[[1, 0, 0, 0, 1],
[0, 1, 0, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 0, 1, 0],
[1, 0, 0, 0, 1]]).ravel() ##
print(neural_network.think(challenge), "expecting probability close to 1")
print()
challenge = array(
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]).ravel()
print(neural_network.think(challenge), "expecting probability close to 0")
print()
challenge = array(
[[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]]).ravel()
print(neural_network.think(challenge), "expecting probability close to 0")
print()
'''
We can make this file beautiful and searchable if this error is corrected: It looks like row 2 should actually have 2 columns, instead of 4. in line 1.
1, 3
0, 1, 1, 0
0, 0, 1
1, 1, 1
1, 0, 1
0, 1, 1
We can make this file beautiful and searchable if this error is corrected: It looks like row 2 should actually have 2 columns, instead of 4. in line 1.
2, 2
0, 1, 1, 0
0, 0, 1, 0
1, 1, 1, 0
1, 0, 1, 0
0, 1, 1, 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment