Skip to content

Commit 84be581

Browse files
committed
Merge pull request mnielsen#15 from drjerry/python-classes
python-izes classes
2 parents b89484d + ce419d0 commit 84be581

File tree

4 files changed

+43
-43
lines changed

4 files changed

+43
-43
lines changed

src/network.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# Third-party libraries
1717
import numpy as np
1818

19-
class Network():
19+
class Network(object):
2020

2121
def __init__(self, sizes):
2222
"""The list ``sizes`` contains the number of neurons in the
@@ -32,7 +32,7 @@ def __init__(self, sizes):
3232
self.num_layers = len(sizes)
3333
self.sizes = sizes
3434
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
35-
self.weights = [np.random.randn(y, x)
35+
self.weights = [np.random.randn(y, x)
3636
for x, y in zip(sizes[:-1], sizes[1:])]
3737

3838
def feedforward(self, a):
@@ -77,9 +77,9 @@ def update_mini_batch(self, mini_batch, eta):
7777
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
7878
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
7979
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
80-
self.weights = [w-(eta/len(mini_batch))*nw
80+
self.weights = [w-(eta/len(mini_batch))*nw
8181
for w, nw in zip(self.weights, nabla_w)]
82-
self.biases = [b-(eta/len(mini_batch))*nb
82+
self.biases = [b-(eta/len(mini_batch))*nb
8383
for b, nb in zip(self.biases, nabla_b)]
8484

8585
def backprop(self, x, y):
@@ -122,14 +122,14 @@ def evaluate(self, test_data):
122122
network outputs the correct result. Note that the neural
123123
network's output is assumed to be the index of whichever
124124
neuron in the final layer has the highest activation."""
125-
test_results = [(np.argmax(self.feedforward(x)), y)
125+
test_results = [(np.argmax(self.feedforward(x)), y)
126126
for (x, y) in test_data]
127127
return sum(int(x == y) for (x, y) in test_results)
128-
128+
129129
def cost_derivative(self, output_activations, y):
130130
"""Return the vector of partial derivatives \partial C_x /
131131
\partial a for the output activations."""
132-
return (output_activations-y)
132+
return (output_activations-y)
133133

134134
#### Miscellaneous functions
135135
def sigmoid(z):

src/network2.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
#### Define the quadratic and cross-entropy cost functions
2525

26-
class QuadraticCost:
26+
class QuadraticCost(object):
2727

2828
@staticmethod
2929
def fn(a, y):
@@ -39,7 +39,7 @@ def delta(z, a, y):
3939
return (a-y) * sigmoid_prime_vec(z)
4040

4141

42-
class CrossEntropyCost:
42+
class CrossEntropyCost(object):
4343

4444
@staticmethod
4545
def fn(a, y):
@@ -65,7 +65,7 @@ def delta(z, a, y):
6565

6666

6767
#### Main Network class
68-
class Network():
68+
class Network(object):
6969

7070
def __init__(self, sizes, cost=CrossEntropyCost):
7171
"""The list ``sizes`` contains the number of neurons in the respective
@@ -97,7 +97,7 @@ def default_weight_initializer(self):
9797
9898
"""
9999
self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]]
100-
self.weights = [np.random.randn(y, x)/np.sqrt(x)
100+
self.weights = [np.random.randn(y, x)/np.sqrt(x)
101101
for x, y in zip(self.sizes[:-1], self.sizes[1:])]
102102

103103
def large_weight_initializer(self):
@@ -117,7 +117,7 @@ def large_weight_initializer(self):
117117
118118
"""
119119
self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]]
120-
self.weights = [np.random.randn(y, x)
120+
self.weights = [np.random.randn(y, x)
121121
for x, y in zip(self.sizes[:-1], self.sizes[1:])]
122122

123123
def feedforward(self, a):
@@ -126,12 +126,12 @@ def feedforward(self, a):
126126
a = sigmoid_vec(np.dot(w, a)+b)
127127
return a
128128

129-
def SGD(self, training_data, epochs, mini_batch_size, eta,
130-
lmbda = 0.0,
131-
evaluation_data=None,
129+
def SGD(self, training_data, epochs, mini_batch_size, eta,
130+
lmbda = 0.0,
131+
evaluation_data=None,
132132
monitor_evaluation_cost=False,
133133
monitor_evaluation_accuracy=False,
134-
monitor_training_cost=False,
134+
monitor_training_cost=False,
135135
monitor_training_accuracy=False):
136136
"""Train the neural network using mini-batch stochastic gradient
137137
descent. The ``training_data`` is a list of tuples ``(x, y)``
@@ -201,9 +201,9 @@ def update_mini_batch(self, mini_batch, eta, lmbda, n):
201201
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
202202
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
203203
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
204-
self.weights = [(1-eta*(lmbda/n))*w-(eta/len(mini_batch))*nw
204+
self.weights = [(1-eta*(lmbda/n))*w-(eta/len(mini_batch))*nw
205205
for w, nw in zip(self.weights, nabla_w)]
206-
self.biases = [b-(eta/len(mini_batch))*nb
206+
self.biases = [b-(eta/len(mini_batch))*nb
207207
for b, nb in zip(self.biases, nabla_b)]
208208

209209
def backprop(self, x, y):
@@ -244,7 +244,7 @@ def accuracy(self, data, convert=False):
244244
"""Return the number of inputs in ``data`` for which the neural
245245
network outputs the correct result. The neural network's
246246
output is assumed to be the index of whichever neuron in the
247-
final layer has the highest activation.
247+
final layer has the highest activation.
248248
249249
The flag ``convert`` should be set to False if the data set is
250250
validation or test data (the usual case), and to True if the
@@ -264,7 +264,7 @@ def accuracy(self, data, convert=False):
264264
265265
"""
266266
if convert:
267-
results = [(np.argmax(self.feedforward(x)), np.argmax(y))
267+
results = [(np.argmax(self.feedforward(x)), np.argmax(y))
268268
for (x, y) in data]
269269
else:
270270
results = [(np.argmax(self.feedforward(x)), y)

src/network3.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ def shared(data):
7878
return [shared(training_data), shared(validation_data), shared(test_data)]
7979

8080
#### Main class used to construct and train networks
81-
class Network():
82-
81+
class Network(object):
82+
8383
def __init__(self, layers, mini_batch_size):
8484
"""Takes a list of `layers`, describing the network architecture, and
8585
a value for the `mini_batch_size` to be used during training
@@ -89,7 +89,7 @@ def __init__(self, layers, mini_batch_size):
8989
self.layers = layers
9090
self.mini_batch_size = mini_batch_size
9191
self.params = [param for layer in self.layers for param in layer.params]
92-
self.x = T.matrix("x")
92+
self.x = T.matrix("x")
9393
self.y = T.ivector("y")
9494
init_layer = self.layers[0]
9595
init_layer.set_inpt(self.x, self.x, self.mini_batch_size)
@@ -100,7 +100,7 @@ def __init__(self, layers, mini_batch_size):
100100
self.output = self.layers[-1].output
101101
self.output_dropout = self.layers[-1].output_dropout
102102

103-
def SGD(self, training_data, epochs, mini_batch_size, eta,
103+
def SGD(self, training_data, epochs, mini_batch_size, eta,
104104
validation_data, test_data, lmbda=0.0):
105105
"""Train the network using mini-batch stochastic gradient descent."""
106106
training_x, training_y = training_data
@@ -117,7 +117,7 @@ def SGD(self, training_data, epochs, mini_batch_size, eta,
117117
cost = self.layers[-1].cost(self)+\
118118
0.5*lmbda*l2_norm_squared/num_training_batches
119119
grads = T.grad(cost, self.params)
120-
updates = [(param, param-eta*grad)
120+
updates = [(param, param-eta*grad)
121121
for param, grad in zip(self.params, grads)]
122122

123123
# define functions to train a mini-batch, and to compute the
@@ -128,37 +128,37 @@ def SGD(self, training_data, epochs, mini_batch_size, eta,
128128
givens={
129129
self.x:
130130
training_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size],
131-
self.y:
131+
self.y:
132132
training_y[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
133133
})
134134
validate_mb_accuracy = theano.function(
135135
[i], self.layers[-1].accuracy(self.y),
136136
givens={
137-
self.x:
137+
self.x:
138138
validation_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size],
139-
self.y:
139+
self.y:
140140
validation_y[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
141141
})
142142
test_mb_accuracy = theano.function(
143143
[i], self.layers[-1].accuracy(self.y),
144144
givens={
145-
self.x:
145+
self.x:
146146
test_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size],
147-
self.y:
147+
self.y:
148148
test_y[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
149149
})
150150
self.test_mb_predictions = theano.function(
151151
[i], self.layers[-1].y_out,
152152
givens={
153-
self.x:
153+
self.x:
154154
test_x[i*self.mini_batch_size: (i+1)*self.mini_batch_size]
155155
})
156156
# Do the actual training
157157
best_validation_accuracy = 0.0
158158
for epoch in xrange(epochs):
159159
for minibatch_index in xrange(num_training_batches):
160160
iteration = num_training_batches*epoch+minibatch_index
161-
if iteration % 1000 == 0:
161+
if iteration % 1000 == 0:
162162
print("Training mini-batch number {0}".format(iteration))
163163
cost_ij = train_mb(minibatch_index)
164164
if (iteration+1) % num_training_batches == 0:
@@ -182,18 +182,18 @@ def SGD(self, training_data, epochs, mini_batch_size, eta,
182182

183183
#### Define layer types
184184

185-
class ConvPoolLayer():
185+
class ConvPoolLayer(object):
186186
"""Used to create a combination of a convolutional and a max-pooling
187187
layer. A more sophisticated implementation would separate the
188188
two, but for our purposes we'll always use them together, and it
189189
simplifies the code, so it makes sense to combine them.
190190
191191
"""
192192

193-
def __init__(self, filter_shape, image_shape, poolsize=(2, 2),
193+
def __init__(self, filter_shape, image_shape, poolsize=(2, 2),
194194
activation_fn=sigmoid):
195195
"""`filter_shape` is a tuple of length 4, whose entries are the number
196-
of filters, the number of input feature maps, the filter height, and the
196+
of filters, the number of input feature maps, the filter height, and the
197197
filter width.
198198
199199
`image_shape` is a tuple of length 4, whose entries are the
@@ -233,7 +233,7 @@ def set_inpt(self, inpt, inpt_dropout, mini_batch_size):
233233
pooled_out + self.b.dimshuffle('x', 0, 'x', 'x'))
234234
self.output_dropout = self.output # no dropout in the convolutional layers
235235

236-
class FullyConnectedLayer():
236+
class FullyConnectedLayer(object):
237237

238238
def __init__(self, n_in, n_out, activation_fn=sigmoid, p_dropout=0.0):
239239
self.n_in = n_in
@@ -267,7 +267,7 @@ def accuracy(self, y):
267267
"Return the accuracy for the mini-batch."
268268
return T.mean(T.eq(y, self.y_out))
269269

270-
class SoftmaxLayer():
270+
class SoftmaxLayer(object):
271271

272272
def __init__(self, n_in, n_out, p_dropout=0.0):
273273
self.n_in = n_in

src/old/perceptron_learning.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# Third-party library
1010
import numpy as np
1111

12-
class Perceptron():
12+
class Perceptron(object):
1313
""" A Perceptron instance can take a function and attempt to
1414
``learn`` a bias and set of weights that compute that function,
1515
using the perceptron learning algorithm."""
@@ -26,7 +26,7 @@ def __init__(self, num_inputs=2):
2626
# inputs it is: [np.array([0, 0, 0]), np.array([0, 0, 1]), ...]
2727
self.inputs = [np.array([int(y)
2828
for y in bin(x).lstrip("0b").zfill(num_inputs)])
29-
for x in xrange(2**num_inputs)]
29+
for x in xrange(2**num_inputs)]
3030

3131
def output(self, x):
3232
""" Return the output (0 or 1) from the perceptron, with input
@@ -37,12 +37,12 @@ def learn(self, f, eta=0.1):
3737
""" Find a bias and a set of weights for a perceptron that
3838
computes the function ``f``. ``eta`` is the learning rate, and
3939
should be a small positive number. Does not terminate when
40-
the function cannot be computed using a perceptron."""
40+
the function cannot be computed using a perceptron."""
4141
# initialize the bias and weights with random values
4242
self.bias = np.random.normal()
4343
self.weights = np.random.randn(self.num_inputs)
4444
number_of_errors = -1
45-
while number_of_errors != 0:
45+
while number_of_errors != 0:
4646
number_of_errors = 0
4747
print "Beginning iteration"
4848
print "Bias: {:.3f}".format(self.bias)
@@ -56,11 +56,11 @@ def learn(self, f, eta=0.1):
5656
self.weights = self.weights+eta*error*x
5757
print "Number of errors:", number_of_errors, "\n"
5858

59-
def f(x):
59+
def f(x):
6060
""" Target function for the perceptron learning algorithm. I've
6161
chosen the NAND gate, but any function is okay, with the caveat
6262
that the algorithm won't terminate if ``f`` cannot be computed by
63-
a perceptron."""
63+
a perceptron."""
6464
return int(not (x[0] and x[1]))
6565

6666
if __name__ == "__main__":

0 commit comments

Comments
 (0)