Data

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


In [5]:
from itertools import product
from pprint import pprint
import pandas as pd

In [28]:
training_set = [
    [(1, i1, i2), 1. if (i1 and i2) else -1]
     for i1, i2 in product([0, 1], [0, 1])
    ] * 2
df = pd.DataFrame(training_set, columns=['Bias', 'Input1', 'Input2', 'Output'])
print(df)


---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-28-f8d2bc9eb20f> in <module>()
      3      for i1, i2 in product([0, 1], [0, 1])
      4     ] * 2
----> 5 df = pd.DataFrame(training_set, columns=['Bias', 'Input1', 'Input2', 'Output'])
      6 print(df)

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in __init__(self, data, index, columns, dtype, copy)
    249             if len(data) > 0:
    250                 if is_list_like(data[0]) and getattr(data[0], 'ndim', 1) == 1:
--> 251                     arrays, columns = _to_arrays(data, columns, dtype=dtype)
    252                     columns = _ensure_index(columns)
    253 

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in _to_arrays(data, columns, coerce_float, dtype)
   4917     if isinstance(data[0], (list, tuple)):
   4918         return _list_to_arrays(data, columns, coerce_float=coerce_float,
-> 4919                                dtype=dtype)
   4920     elif isinstance(data[0], collections.Mapping):
   4921         return _list_of_dict_to_arrays(data, columns,

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in _list_to_arrays(data, columns, coerce_float, dtype)
   5000         content = list(lib.to_object_array(data).T)
   5001     return _convert_object_array(content, columns, dtype=dtype,
-> 5002                                  coerce_float=coerce_float)
   5003 
   5004 

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in _convert_object_array(content, columns, coerce_float, dtype)
   5058             # caller's responsibility to check for this...
   5059             raise AssertionError('%d columns passed, passed data had %s '
-> 5060                                  'columns' % (len(columns), len(content)))
   5061 
   5062     # provide soft conversion of object dtypes

AssertionError: 4 columns passed, passed data had 2 columns

Training

Just push the weights halfway toward the right answer


In [26]:
def learn(training_set=(), weights=(0., 0., 0.), learning_rate=0.25, activate=lambda x:x):
    ans = []
    for i, example in enumerate(training_set):
        prediction = sum([activate(w * i) for i, w in zip(example[:2], weights)])
        error = example[-1] - prediction
        print('{} - {} = {}'.format(example[-1], prediction, error))
        
        weights = [error * learning_rate * ex for w, ex in zip(weights, example[:2])]
        ans += [list(example) + [error] + weights]
    return pd.DataFrame(ans, columns=['In1', 'In2', 'Out1', 'Err1', 'W1', 'W2'])

print(learn(df.values))


-1.0 - 0.0 = -1.0
-1.0 - -0.25 = -0.75
-1.0 - -0.1875 = -0.8125
1.0 - -0.40625 = 1.40625
-1.0 - 0.3515625 = -1.3515625
-1.0 - -0.337890625 = -0.662109375
-1.0 - -0.16552734375 = -0.83447265625
1.0 - -0.417236328125 = 1.41723632812
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-26-807cc294ac97> in <module>()
     10     return pd.DataFrame(ans, columns=['In1', 'In2', 'Out1', 'Err1', 'W1', 'W2'])
     11 
---> 12 print(learn(df.values))

<ipython-input-26-807cc294ac97> in learn(training_set, weights, learning_rate, activate)
      8         weights = [error * learning_rate * ex for w, ex in zip(weights, example[:2])]
      9         ans += [list(example) + [error] + weights]
---> 10     return pd.DataFrame(ans, columns=['In1', 'In2', 'Out1', 'Err1', 'W1', 'W2'])
     11 
     12 print(learn(df.values))

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in __init__(self, data, index, columns, dtype, copy)
    249             if len(data) > 0:
    250                 if is_list_like(data[0]) and getattr(data[0], 'ndim', 1) == 1:
--> 251                     arrays, columns = _to_arrays(data, columns, dtype=dtype)
    252                     columns = _ensure_index(columns)
    253 

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in _to_arrays(data, columns, coerce_float, dtype)
   4917     if isinstance(data[0], (list, tuple)):
   4918         return _list_to_arrays(data, columns, coerce_float=coerce_float,
-> 4919                                dtype=dtype)
   4920     elif isinstance(data[0], collections.Mapping):
   4921         return _list_of_dict_to_arrays(data, columns,

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in _list_to_arrays(data, columns, coerce_float, dtype)
   5000         content = list(lib.to_object_array(data).T)
   5001     return _convert_object_array(content, columns, dtype=dtype,
-> 5002                                  coerce_float=coerce_float)
   5003 
   5004 

/home/hobs/.virtualenvs/totalgood/lib/python2.7/site-packages/pandas/core/frame.pyc in _convert_object_array(content, columns, coerce_float, dtype)
   5058             # caller's responsibility to check for this...
   5059             raise AssertionError('%d columns passed, passed data had %s '
-> 5060                                  'columns' % (len(columns), len(content)))
   5061 
   5062     # provide soft conversion of object dtypes

AssertionError: 6 columns passed, passed data had 7 columns

In [29]:



------------------------------------------------------------
[0, 0, 0]
[0.1, 0.0, 0.0]
[0.2, 0.0, 0.1]
[0.30000000000000004, 0.1, 0.1]
------------------------------------------------------------
[0.30000000000000004, 0.1, 0.1]
[0.4, 0.1, 0.1]
[0.5, 0.1, 0.2]
[0.5, 0.1, 0.2]
------------------------------------------------------------
[0.4, 0.0, 0.1]
[0.5, 0.0, 0.1]
[0.5, 0.0, 0.1]
[0.6, 0.1, 0.1]
------------------------------------------------------------
[0.5, 0.0, 0.0]
[0.6, 0.0, 0.0]
[0.6, 0.0, 0.0]
[0.6, 0.0, 0.0]
------------------------------------------------------------
[0.5, -0.1, -0.1]
[0.6, -0.1, -0.1]
[0.7, -0.1, 0.0]
[0.7, -0.1, 0.0]
------------------------------------------------------------
[0.6, -0.2, -0.1]
[0.6, -0.2, -0.1]
[0.7, -0.2, 0.0]
[0.7999999999999999, -0.1, 0.0]
------------------------------------------------------------
[0.7, -0.2, -0.1]
[0.7, -0.2, -0.1]
[0.7, -0.2, -0.1]
[0.7999999999999999, -0.1, -0.1]
------------------------------------------------------------
[0.7, -0.2, -0.2]
[0.7, -0.2, -0.2]
[0.7999999999999999, -0.2, -0.1]
[0.7999999999999999, -0.2, -0.1]
------------------------------------------------------------
[0.7999999999999999, -0.2, -0.1]
[0.7999999999999999, -0.2, -0.1]
[0.7999999999999999, -0.2, -0.1]
[0.7999999999999999, -0.2, -0.1]

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 NOR logic gate


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?