Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45bcc83

Browse files
implements backprop and neural net learner
1 parent eb61b32 commit 45bcc83

File tree

1 file changed

+136
-8
lines changed

1 file changed

+136
-8
lines changed

learning.py

Lines changed: 136 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -416,24 +416,152 @@ def predict(example):
416416
# ______________________________________________________________________________
417417

418418

419-
def NeuralNetLearner(dataset, sizes):
420-
"""Layered feed-forward network."""
419+
def NeuralNetLearner(dataset, hidden_layer_sizes=[3],
420+
learning_rate=0.01, epoches=100):
421+
"""
422+
Layered feed-forward network.
423+
hidden_layer_sizes: List of number of hidden units per hidden layer
424+
learning_rate: Learning rate of gradient decent
425+
epoches: Number of passes over the dataset
426+
"""
421427

422-
activations = [[0.0 for i in range(n)] for n in sizes] # noqa
423-
weights = [] # noqa
428+
examples = dataset.examples
429+
i_units = len(dataset.inputs)
430+
o_units = 1 # As of now, dataset.target gives only one index.
431+
432+
# construct a network
433+
raw_net = network(i_units, hidden_layer_sizes, o_units)
434+
learned_net = BackPropagationLearner(dataset, raw_net,
435+
learning_rate, epoches)
424436

425437
def predict(example):
426-
unimplemented()
438+
439+
# Input nodes
440+
i_nodes = learned_net[0]
441+
442+
# Activate input layer
443+
for v, n in zip(example, i_nodes):
444+
n.value = v
445+
446+
# Forward pass
447+
for layer in learned_net[1:]:
448+
for node in layer:
449+
inc = [n.value for n in node.inputs]
450+
in_val = dotproduct(inc, node.weights)
451+
node.value = node.activation(in_val)
452+
453+
# Hypothesis
454+
o_nodes = learned_net[-1]
455+
pred = [o_nodes[i].value for i in range(o_units)]
456+
return pred[0]
427457

428458
return predict
429459

430460

431461
class NNUnit:
462+
"""
463+
Single Unit of Multiple Layer Neural Network
464+
inputs: Incoming connections
465+
weights: weights to incoming connections
466+
"""
432467

433-
"""Unit of a neural net."""
468+
def __init__(self, weights=None, inputs=None):
469+
self.weights = []
470+
self.inputs = []
471+
self.value = None
472+
self.activation = sigmoid
434473

435-
def __init__(self):
436-
unimplemented()
474+
475+
def network(input_units, hidden_layer_sizes, output_units):
476+
"""
477+
Create of Directed Acyclic Network of given number layers
478+
hidden_layers_sizes : list number of neuron units in each hidden layer
479+
excluding input and output layers.
480+
"""
481+
layers_sizes = [input_units] + hidden_layer_sizes + [output_units]
482+
net = [[NNUnit() for n in range(size)]
483+
for size in layers_sizes]
484+
n_layers = len(net)
485+
486+
# Make Connection
487+
for i in range(1, n_layers):
488+
for n in net[i]:
489+
for k in net[i-1]:
490+
n.inputs.append(k)
491+
n.weights.append(0)
492+
return net
493+
494+
495+
def BackPropagationLearner(dataset, network, learning_rate, epoches):
496+
"[Fig. 18.23] The back-propagation algorithm for multilayer network"
497+
# Initialise weights
498+
for layer in network:
499+
for node in layer:
500+
node.weights = [random.uniform(-0.5, 0.5)
501+
for i in range(len(node.weights))]
502+
503+
examples = dataset.examples
504+
'''
505+
As of now dataset.target gives an int instead of list,
506+
Changing dataset class will have effect on all the learners.
507+
Will be taken care of later
508+
'''
509+
idx_t = [dataset.target]
510+
idx_i = dataset.inputs
511+
n_layers = len(network)
512+
o_nodes = network[-1]
513+
i_nodes = network[0]
514+
515+
for epoch in range(epoches):
516+
# Iterate over each example
517+
for e in examples:
518+
i_val = [e[i] for i in idx_i]
519+
t_val = [e[i] for i in idx_t]
520+
# Activate input layer
521+
for v, n in zip(i_val, i_nodes):
522+
n.value = v
523+
524+
# Forward pass
525+
for layer in network[1:]:
526+
for node in layer:
527+
inc = [n.value for n in node.inputs]
528+
in_val = dotproduct(inc, node.weights)
529+
node.value = node.activation(in_val)
530+
531+
# Initialize delta
532+
delta = [[] for i in range(n_layers)]
533+
534+
# Compute outer layer delta
535+
o_units = len(o_nodes)
536+
err = [t_val[i] - o_nodes[i].value
537+
for i in range(o_units)]
538+
delta[-1] = [(o_nodes[i].value)*(1 - o_nodes[i].value) *
539+
(err[i]) for i in range(o_units)]
540+
541+
# Backward pass
542+
h_layers = n_layers - 2
543+
for i in range(h_layers, 0, -1):
544+
layer = network[i]
545+
h_units = len(layer)
546+
nx_layer = network[i+1]
547+
# weights from each ith layer node to each i + 1th layer node
548+
w = [[node.weights[k] for node in nx_layer]
549+
for k in range(h_units)]
550+
551+
delta[i] = [(layer[j].value) * (1 - layer[j].value) *
552+
dotproduct(w[j], delta[i+1])
553+
for j in range(h_units)]
554+
555+
# Update weights
556+
for i in range(1, n_layers):
557+
layer = network[i]
558+
inc = [node.value for node in network[i-1]]
559+
units = len(layer)
560+
for j in range(units):
561+
layer[j].weights = vector_add(layer[j].weights,
562+
scalar_vector_product(learning_rate * delta[i][j], inc))
563+
564+
return network
437565

438566

439567
def PerceptronLearner(dataset, sizes):

0 commit comments

Comments
 (0)