Data

First we need example inputs and outputs. So lets use a simple real world system ... an AND logic gate...


In [19]:
from itertools import product
from pprint import pprint
training_set = [
    [[1, i1, i2], [i1 or i2]]  # XOR
     for i1, i2 in product([0, 1], [0, 1])]
pprint(training_set)


[[[1, 0, 0], [0]], [[1, 0, 1], [1]], [[1, 1, 0], [1]], [[1, 1, 1], [1]]]

Training

Just push the weights halfway toward the right answer


In [20]:
def learn(training_set=(), weights=(0., 0., 0.), learning_rate=0.5, activate=lambda x:x):
    for inputs, outputs in training_set:
        error = 0
        for outp in outputs:
            prediction = sum([activate(w * i) for i, w in zip(inputs, weights)])
            error += outp - prediction
        print('      error = {} - {} = {}'.format(outputs, prediction, error))
        weights = [w + error * learning_rate for w in weights]
        print('new weights = {}'.format(weights))
    return weights
weights = learn(training_set)


      error = [0] - 0.0 = 0.0
new weights = [0.0, 0.0, 0.0]
      error = [1] - 0.0 = 1.0
new weights = [0.5, 0.5, 0.5]
      error = [1] - 1.0 = 0.0
new weights = [0.5, 0.5, 0.5]
      error = [1] - 1.5 = -0.5
new weights = [0.25, 0.25, 0.25]

In [23]:
weights = learn(training_set, weights)
weights = learn(training_set, weights)


      error = [0] - 0.25 = -0.25
new weights = [0.125, 0.125, 0.125]
      error = [1] - 0.25 = 0.75
new weights = [0.5, 0.5, 0.5]
      error = [1] - 1.0 = 0.0
new weights = [0.5, 0.5, 0.5]
      error = [1] - 1.5 = -0.5
new weights = [0.25, 0.25, 0.25]
      error = [0] - 0.25 = -0.25
new weights = [0.125, 0.125, 0.125]
      error = [1] - 0.25 = 0.75
new weights = [0.5, 0.5, 0.5]
      error = [1] - 1.0 = 0.0
new weights = [0.5, 0.5, 0.5]
      error = [1] - 1.5 = -0.5
new weights = [0.25, 0.25, 0.25]

Smarter Learning

How would you improve this learning approach? Are we pushing too hard (learning rate too high)?

Activation Function

A simple threshold/does fine for logic gate behavior


In [24]:
def activate(i):
    if i >= 0.5:
        return 1
    return 0

print(learn(training_set, activate=activate))


0 - 0 = 0
new weights = [0.0, 0.0]
0 - 0 = 0
new weights = [0.0, 0.0]
0 - 0 = 0
new weights = [0.0, 0.0]
1 - 0 = 1
new weights = [0.25, 0.25]
0 - 0 = 0
new weights = [0.25, 0.25]
0 - 0 = 0
new weights = [0.25, 0.25]
0 - 0 = 0
new weights = [0.25, 0.25]
1 - 0 = 1
new weights = [0.5, 0.5]
[0.5, 0.5]

Your Turn

See if you can train a neuron to behave like a XOR logic gate this time!


In [ ]:

Recursive Network

Let's train a NN to beat you at Rock, Paper, Scissors All we have to do is play against it And punish or reward it with each good/bad move


In [ ]:

Tic-Tac-Toe?

How long would it take to train a neural net To win at tic-tac-toe? With this simple training and back-propagation approach?