-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathneuralnet.py
148 lines (112 loc) · 5.26 KB
/
neuralnet.py
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from __future__ import division
import numpy
import scipy.special
class neuralNetwork:
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
# number of input nodes
self.input_nodes = inputnodes
# number of hidden nodes
self.hidden_nodes = hiddennodes
# number of output nodes
self.output_nodes = outputnodes
# learning rate
self.lr = learningrate
# random weight of links between input and hidden layer (in range of -0.5 to +0.5)
self.weight_input_hidden = (numpy.random.rand(self.hidden_nodes, self.input_nodes) - 0.5)
# random weight of links between hidden and output layer (in range of -0.5 to +0.5)
self.weight_hidden_output = (numpy.random.rand(self.output_nodes, self.hidden_nodes) - 0.5)
# sigmoid function
self.activation_function = lambda x: scipy.special.expit(x)
def train(self, inputs_list, targets_list):
# convert inputs and targets list to 2d array
inputs = numpy.array(inputs_list, ndmin=2).T
targets = numpy.array(targets_list, ndmin=2).T
# inputs to hidden layer
hidden_inputs = numpy.dot(self.weight_input_hidden, inputs)
# outputs from hidden layer
hidden_outputs = self.activation_function(hidden_inputs)
# inputs to output layer
final_inputs = numpy.dot(self.weight_hidden_output, hidden_outputs)
# outputs from output layer
final_outputs = self.activation_function(final_inputs)
# error between target value and observed value of the output layer
output_errors = targets - final_outputs
# error for the hidden layer via backpropagation
hidden_errors = numpy.dot(self.weight_hidden_output.T, output_errors)
# gradient descent to update the weights
# update the weights of the links between hidden and output layer
self.weight_hidden_output += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)),
numpy.transpose(hidden_outputs))
# update the weights of the links between the input and hidden layer
self.weight_input_hidden += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),
numpy.transpose(inputs))
def predict(self, inputs_list):
# convert input list to 2d array
inputs = numpy.array(inputs_list, ndmin=2).T
# inputs to hidden layer
hidden_inputs = numpy.dot(self.weight_input_hidden, inputs)
# outputs from the hidden layer
hidden_outputs = self.activation_function(hidden_inputs)
# inputs to output layer
final_inputs = numpy.dot(self.weight_hidden_output, hidden_outputs)
# outputs from the output layer
final_outputs = self.activation_function(final_inputs)
return final_outputs
def save_weights(self):
# print(self.weight_input_hidden)
numpy.savetxt( 'input_to_hidden.csv', self.weight_input_hidden, delimiter=',')
numpy.savetxt( 'hidden_to_output.csv', self.weight_hidden_output, delimiter=',')
input_nodes = 784
hidden_nodes = 300 # 2400
output_nodes = 36
learning_rate = 0.005 # 0.005
neural = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)
for i in range(1, 30):
# load the train data CSV file
training_data = open("train.csv", 'r')
training_list = training_data.readlines()
training_data.close()
for record in training_list:
all_values = record.split(',')
# prepreocess the pixels in order to scale them in between 0.01 to 1.00
inputs = (numpy.asfarray(all_values[1:]) / 255 * 0.99) + 0.01
# target labels. all values are 0.01 except the correct label which has a value of 0.99
targets = numpy.zeros(output_nodes) + 0.01
targets[int(all_values[0])] = 0.99
# print all_values[0], targets
# begin the training
neural.train(inputs, targets)
neural.save_weights();
# load the mnist test data CSV file
test_data = open("test.csv", 'r')
test_list = test_data.readlines()
test_data.close()
scores = []
for record in test_list:
all_values = record.split(',')
# the first value is the label
correct_label = int(all_values[0])
# all the others are the pixels (i.e inputs)
inputs = (numpy.asfarray(all_values[1:]) / 255 * 0.99) + 0.01
# use the trained network to predict the output based on the given input
outputs = neural.predict(inputs)
# the index of the highest value in output is the predicted label
label = numpy.argmax(outputs)
confidence = "Low"
if outputs[label] > 0.35:
confidence = "High"
print label, correct_label, confidence
# if the correct label, and the predicted label are same
if (label == correct_label):
# append 1 to scores.
scores.append(1)
else:
# otherwise, wrong prediction, append 0 to scores.
scores.append(0)
pass
pass
scores_array = numpy.asarray(scores)
print "Accuracy = ", (scores_array.sum() / scores_array.size) * 100, "%"
import dill # save the trained object as it is so that it can be used for prediction later on.
with open('nn.dill', 'wb') as f:
dill.dump(neural, f)