-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmain.py
More file actions
112 lines (94 loc) · 3.51 KB
/
main.py
File metadata and controls
112 lines (94 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# TODO:
# Implement backpropogation, and updating weights
# Allow network to forward prop on multiple images, one after another
# Allow network to parse + test on user-made images (both from file, and from camera)
#
import math
from PIL import Image
import random
import Tests
import csv
from layers import HiddenLayer, OutputLayer
# Freddie ;)
"""
Converts a CSV of image pixels into an array of pixel values
INPUTS: CSV File name
RETURNS: 2d array of all the pixel values for each image [[pixels in img 1], [pixels in img 2], ..]
"""
def CsvToArray(filename="mnist_train.csv"):
data = []
with open(filename, "r") as file: # Might be good to make the file name a param, and default it to the "train.csv" (I belive there's a programming principle which involves this idea, but I can't remember it!)
training_data = csv.reader(file)
counter = 0
for row in training_data:
if counter == 0:
sigmalabels = row
else:
int_row = [int(i) for i in row]
data.append(int_row)
counter += 1
return data
class Network:
# Data
layers : list = []
output : int = None
# Functionality
def __init__(self):
self.layers : list = [HiddenLayer(inputSize=784, layerSize=10),
OutputLayer(inputSize=10, layerSize=10)]
"""
TODO : Add comment to method
"""
def ForwardPropogate(self, expectedInput : list):
previousLayerInput = expectedInput
for layer in self.layers:
previousLayerInput = layer.ForwardPropogate(previousLayerInput)
# Find index of largest probability in output (that's the guessed number)
self.output = previousLayerInput.index(max(previousLayerInput))
"""
Backpropogates through layers
Each layer calculates the partial derivative of the Error between the generated output and the expected output WRT each weight,
then updates the weight using the defined rule
INPUTS: list backpropogrand = value to backpropogate to previous layer
"""
def BackPropogate(self, backPropogrand : list):
self.layers.reverse()
for layer in self.layers: # So, now output layer is at front
layer.BackPropogate(backPropogrand)
layer.UpdateWeights()
backPropogrand = layer
self.layers.reverse() # Flip them back before F-Prop (!!BODGE!!)
def __main__():
# ==============================================
# Get network running on 100 different images
# - Output its guess
# - Output the actual value
# - Backpropogate error through network
# - At end, show the difference in accuracy between the first 20 entries, and the last 20 entries
# ==============================================
totalSuccessRate = 0
first20SuccessRate = 0
last20SuccessRate = 0
# Initialise Network
N = Network()
# Get images
Images = CsvToArray()
# Iterate over images
for i in range(100):
# Propogate over image
N.ForwardPropogate(Images[i][1:])
# Output guess + actual
print(f"Generated Ouput : {N.output}")
print(f"Expected Output : {Images[i][0]}")
if N.output == Images[i][0]:
print("Successful guess!")
# Update success rate
totalSuccessRate += 1
if i < 20: first20SuccessRate += 1
elif i >= 79: last20SuccessRate += 1 # As loop goes 0 - 99
# Backpropogate
N.BackPropogate(Images[i][0])
# Output total success rate, 1st 20 success rate, last 20 success rate
print(f"Final Stats : \nTotal Success Rate : {totalSuccessRate}\nFirst 20 Success Rate : {first20SuccessRate}\nLast 20 Success Rate : {last20SuccessRate}")
if __name__ == "__main__":
__main__()