-
Notifications
You must be signed in to change notification settings - Fork 1
/
multilayer_network.py
151 lines (108 loc) · 4.16 KB
/
multilayer_network.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
149
150
151
"""multilayer_network.py: Multilayer network class."""
__author__ = "Jordon Dornbos"
import layer
import math
class MultilayerNetwork(object):
def __init__(self, num_input_nodes, num_hidden_layers, num_nodes_per_hidden_layer, num_output_nodes):
self.num_input_nodes = num_input_nodes
self.num_hidden_layers = num_hidden_layers
self.num_nodes_per_hidden_layer = num_nodes_per_hidden_layer
self.num_output_nodes = num_output_nodes
# create input layer
self.input_layer = layer.Layer(num_input_nodes, num_input_nodes)
# create hidden layers
self.hidden_layers = []
for i in range(num_hidden_layers):
self.hidden_layers.append(layer.Layer(num_nodes_per_hidden_layer, self.get_layer(i).num_nodes))
# create output layer
self.output_layer = layer.Layer(num_output_nodes, num_nodes_per_hidden_layer)
def num_nodes(self):
"""Function to return the number of nodes in the network.
Returns:
The number of nodes in the network.
"""
return self.num_input_nodes + self.num_hidden_layers * self.num_nodes_per_hidden_layer + self.num_output_nodes
def num_layers(self):
"""Function to return the number of layers in the network.
Returns:
The number of layers in the network.
"""
return 2 + self.num_hidden_layers
def get_layer(self, l):
"""Method to return a certain layer in the network.
Args:
l: The layer number.
Returns:
The layer requested.
"""
if l == 0:
return self.input_layer
elif 0 < l < self.num_layers() - 1:
return self.hidden_layers[l - 1]
elif l == self.num_layers() - 1:
return self.output_layer
else:
return None
def get_node_with_layer(self, l, j):
"""Method to return a particular node in a certain layer.
Args:
l: The layer to get the node from.
j: The offset of the node in that layer.
Returns:
The node in the specified layer.
"""
return self.get_layer(l).nodes[j]
def position_in_network(self, l, n):
"""Method to return a node's position in the entire network.
Args:
l: The layer containing the node.
n: The offset of the node in that layer.
Returns:
The position of the node in the network.
"""
pos = n
for i in range(l):
pos += self.get_layer(i).num_nodes
return pos
def load_weights(self, weights):
"""Method to load a given set of weights into the network.
Args:
weights: An array of weights to put in the network.
"""
i = 0
for l in range(1, self.num_layers()):
for n in range(self.get_layer(l).num_nodes):
for w in range(len(self.get_node_with_layer(l, n).weights)):
self.get_node_with_layer(l, n).weights[w] = weights[i]
i += 1
def print_weights(self, round=False):
"""Method to print the weights in the network.
Args:
round: Whether or not to round the values to the third decimal place.
"""
print "[",
for l in range(1, self.num_layers()):
for n in range(self.get_layer(l).num_nodes):
weights = self.get_node_with_layer(l, n).weights
for w in range(len(weights)):
if round:
print '{0:.3f}'.format(weights[w]),
else:
print weights[w],
print ']'
def sigmoid(x):
"""Sigmoid function to be used by the network.
Args:
x: The value to use in the sigmoid computation.
Returns:
The sigmoid value for x.
"""
return 1 / (1 + math.exp(-x))
def sigmoid_derivative(x):
"""The derivative of the sigmoid function to be used by the network.
Args:
x: The value to use in the calculation.
Returns:
The value of the sigmoid derivative function for a given x.
"""
return sigmoid(x) * (1 - sigmoid(x))