In [1]:
import copy
import numpy as np

Define functions

  • Sigmoid Function $$ \sigma(x) = {1 \over 1 + e^{-x}} $$
  • Sigmoid Derivative $$ \sigma'(x) = \sigma(x) \cdot (1-\sigma(x)) $$

In [2]:
# Define sigmoid function
def sigmoid(x):
    output = 1/(1 + np.exp(-x))
    return output

# Define sigmoid derivative
def sigmoid_derivative(sigmoid_x):
    return sigmoid_x * (1 - sigmoid_x)

In [3]:
# Generate training dataset
int2binary = {}
binary_dim = 8

largest_number = pow(2,binary_dim)
binary = np.unpackbits(
    np.array([range(largest_number)],dtype=np.uint8).T, axis=1)

for i in range(largest_number):
    int2binary[i] = binary[i]

In [4]:
int2binary


Out[4]:
{0: array([0, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 1: array([0, 0, 0, 0, 0, 0, 0, 1], dtype=uint8),
 2: array([0, 0, 0, 0, 0, 0, 1, 0], dtype=uint8),
 3: array([0, 0, 0, 0, 0, 0, 1, 1], dtype=uint8),
 4: array([0, 0, 0, 0, 0, 1, 0, 0], dtype=uint8),
 5: array([0, 0, 0, 0, 0, 1, 0, 1], dtype=uint8),
 6: array([0, 0, 0, 0, 0, 1, 1, 0], dtype=uint8),
 7: array([0, 0, 0, 0, 0, 1, 1, 1], dtype=uint8),
 8: array([0, 0, 0, 0, 1, 0, 0, 0], dtype=uint8),
 9: array([0, 0, 0, 0, 1, 0, 0, 1], dtype=uint8),
 10: array([0, 0, 0, 0, 1, 0, 1, 0], dtype=uint8),
 11: array([0, 0, 0, 0, 1, 0, 1, 1], dtype=uint8),
 12: array([0, 0, 0, 0, 1, 1, 0, 0], dtype=uint8),
 13: array([0, 0, 0, 0, 1, 1, 0, 1], dtype=uint8),
 14: array([0, 0, 0, 0, 1, 1, 1, 0], dtype=uint8),
 15: array([0, 0, 0, 0, 1, 1, 1, 1], dtype=uint8),
 16: array([0, 0, 0, 1, 0, 0, 0, 0], dtype=uint8),
 17: array([0, 0, 0, 1, 0, 0, 0, 1], dtype=uint8),
 18: array([0, 0, 0, 1, 0, 0, 1, 0], dtype=uint8),
 19: array([0, 0, 0, 1, 0, 0, 1, 1], dtype=uint8),
 20: array([0, 0, 0, 1, 0, 1, 0, 0], dtype=uint8),
 21: array([0, 0, 0, 1, 0, 1, 0, 1], dtype=uint8),
 22: array([0, 0, 0, 1, 0, 1, 1, 0], dtype=uint8),
 23: array([0, 0, 0, 1, 0, 1, 1, 1], dtype=uint8),
 24: array([0, 0, 0, 1, 1, 0, 0, 0], dtype=uint8),
 25: array([0, 0, 0, 1, 1, 0, 0, 1], dtype=uint8),
 26: array([0, 0, 0, 1, 1, 0, 1, 0], dtype=uint8),
 27: array([0, 0, 0, 1, 1, 0, 1, 1], dtype=uint8),
 28: array([0, 0, 0, 1, 1, 1, 0, 0], dtype=uint8),
 29: array([0, 0, 0, 1, 1, 1, 0, 1], dtype=uint8),
 30: array([0, 0, 0, 1, 1, 1, 1, 0], dtype=uint8),
 31: array([0, 0, 0, 1, 1, 1, 1, 1], dtype=uint8),
 32: array([0, 0, 1, 0, 0, 0, 0, 0], dtype=uint8),
 33: array([0, 0, 1, 0, 0, 0, 0, 1], dtype=uint8),
 34: array([0, 0, 1, 0, 0, 0, 1, 0], dtype=uint8),
 35: array([0, 0, 1, 0, 0, 0, 1, 1], dtype=uint8),
 36: array([0, 0, 1, 0, 0, 1, 0, 0], dtype=uint8),
 37: array([0, 0, 1, 0, 0, 1, 0, 1], dtype=uint8),
 38: array([0, 0, 1, 0, 0, 1, 1, 0], dtype=uint8),
 39: array([0, 0, 1, 0, 0, 1, 1, 1], dtype=uint8),
 40: array([0, 0, 1, 0, 1, 0, 0, 0], dtype=uint8),
 41: array([0, 0, 1, 0, 1, 0, 0, 1], dtype=uint8),
 42: array([0, 0, 1, 0, 1, 0, 1, 0], dtype=uint8),
 43: array([0, 0, 1, 0, 1, 0, 1, 1], dtype=uint8),
 44: array([0, 0, 1, 0, 1, 1, 0, 0], dtype=uint8),
 45: array([0, 0, 1, 0, 1, 1, 0, 1], dtype=uint8),
 46: array([0, 0, 1, 0, 1, 1, 1, 0], dtype=uint8),
 47: array([0, 0, 1, 0, 1, 1, 1, 1], dtype=uint8),
 48: array([0, 0, 1, 1, 0, 0, 0, 0], dtype=uint8),
 49: array([0, 0, 1, 1, 0, 0, 0, 1], dtype=uint8),
 50: array([0, 0, 1, 1, 0, 0, 1, 0], dtype=uint8),
 51: array([0, 0, 1, 1, 0, 0, 1, 1], dtype=uint8),
 52: array([0, 0, 1, 1, 0, 1, 0, 0], dtype=uint8),
 53: array([0, 0, 1, 1, 0, 1, 0, 1], dtype=uint8),
 54: array([0, 0, 1, 1, 0, 1, 1, 0], dtype=uint8),
 55: array([0, 0, 1, 1, 0, 1, 1, 1], dtype=uint8),
 56: array([0, 0, 1, 1, 1, 0, 0, 0], dtype=uint8),
 57: array([0, 0, 1, 1, 1, 0, 0, 1], dtype=uint8),
 58: array([0, 0, 1, 1, 1, 0, 1, 0], dtype=uint8),
 59: array([0, 0, 1, 1, 1, 0, 1, 1], dtype=uint8),
 60: array([0, 0, 1, 1, 1, 1, 0, 0], dtype=uint8),
 61: array([0, 0, 1, 1, 1, 1, 0, 1], dtype=uint8),
 62: array([0, 0, 1, 1, 1, 1, 1, 0], dtype=uint8),
 63: array([0, 0, 1, 1, 1, 1, 1, 1], dtype=uint8),
 64: array([0, 1, 0, 0, 0, 0, 0, 0], dtype=uint8),
 65: array([0, 1, 0, 0, 0, 0, 0, 1], dtype=uint8),
 66: array([0, 1, 0, 0, 0, 0, 1, 0], dtype=uint8),
 67: array([0, 1, 0, 0, 0, 0, 1, 1], dtype=uint8),
 68: array([0, 1, 0, 0, 0, 1, 0, 0], dtype=uint8),
 69: array([0, 1, 0, 0, 0, 1, 0, 1], dtype=uint8),
 70: array([0, 1, 0, 0, 0, 1, 1, 0], dtype=uint8),
 71: array([0, 1, 0, 0, 0, 1, 1, 1], dtype=uint8),
 72: array([0, 1, 0, 0, 1, 0, 0, 0], dtype=uint8),
 73: array([0, 1, 0, 0, 1, 0, 0, 1], dtype=uint8),
 74: array([0, 1, 0, 0, 1, 0, 1, 0], dtype=uint8),
 75: array([0, 1, 0, 0, 1, 0, 1, 1], dtype=uint8),
 76: array([0, 1, 0, 0, 1, 1, 0, 0], dtype=uint8),
 77: array([0, 1, 0, 0, 1, 1, 0, 1], dtype=uint8),
 78: array([0, 1, 0, 0, 1, 1, 1, 0], dtype=uint8),
 79: array([0, 1, 0, 0, 1, 1, 1, 1], dtype=uint8),
 80: array([0, 1, 0, 1, 0, 0, 0, 0], dtype=uint8),
 81: array([0, 1, 0, 1, 0, 0, 0, 1], dtype=uint8),
 82: array([0, 1, 0, 1, 0, 0, 1, 0], dtype=uint8),
 83: array([0, 1, 0, 1, 0, 0, 1, 1], dtype=uint8),
 84: array([0, 1, 0, 1, 0, 1, 0, 0], dtype=uint8),
 85: array([0, 1, 0, 1, 0, 1, 0, 1], dtype=uint8),
 86: array([0, 1, 0, 1, 0, 1, 1, 0], dtype=uint8),
 87: array([0, 1, 0, 1, 0, 1, 1, 1], dtype=uint8),
 88: array([0, 1, 0, 1, 1, 0, 0, 0], dtype=uint8),
 89: array([0, 1, 0, 1, 1, 0, 0, 1], dtype=uint8),
 90: array([0, 1, 0, 1, 1, 0, 1, 0], dtype=uint8),
 91: array([0, 1, 0, 1, 1, 0, 1, 1], dtype=uint8),
 92: array([0, 1, 0, 1, 1, 1, 0, 0], dtype=uint8),
 93: array([0, 1, 0, 1, 1, 1, 0, 1], dtype=uint8),
 94: array([0, 1, 0, 1, 1, 1, 1, 0], dtype=uint8),
 95: array([0, 1, 0, 1, 1, 1, 1, 1], dtype=uint8),
 96: array([0, 1, 1, 0, 0, 0, 0, 0], dtype=uint8),
 97: array([0, 1, 1, 0, 0, 0, 0, 1], dtype=uint8),
 98: array([0, 1, 1, 0, 0, 0, 1, 0], dtype=uint8),
 99: array([0, 1, 1, 0, 0, 0, 1, 1], dtype=uint8),
 100: array([0, 1, 1, 0, 0, 1, 0, 0], dtype=uint8),
 101: array([0, 1, 1, 0, 0, 1, 0, 1], dtype=uint8),
 102: array([0, 1, 1, 0, 0, 1, 1, 0], dtype=uint8),
 103: array([0, 1, 1, 0, 0, 1, 1, 1], dtype=uint8),
 104: array([0, 1, 1, 0, 1, 0, 0, 0], dtype=uint8),
 105: array([0, 1, 1, 0, 1, 0, 0, 1], dtype=uint8),
 106: array([0, 1, 1, 0, 1, 0, 1, 0], dtype=uint8),
 107: array([0, 1, 1, 0, 1, 0, 1, 1], dtype=uint8),
 108: array([0, 1, 1, 0, 1, 1, 0, 0], dtype=uint8),
 109: array([0, 1, 1, 0, 1, 1, 0, 1], dtype=uint8),
 110: array([0, 1, 1, 0, 1, 1, 1, 0], dtype=uint8),
 111: array([0, 1, 1, 0, 1, 1, 1, 1], dtype=uint8),
 112: array([0, 1, 1, 1, 0, 0, 0, 0], dtype=uint8),
 113: array([0, 1, 1, 1, 0, 0, 0, 1], dtype=uint8),
 114: array([0, 1, 1, 1, 0, 0, 1, 0], dtype=uint8),
 115: array([0, 1, 1, 1, 0, 0, 1, 1], dtype=uint8),
 116: array([0, 1, 1, 1, 0, 1, 0, 0], dtype=uint8),
 117: array([0, 1, 1, 1, 0, 1, 0, 1], dtype=uint8),
 118: array([0, 1, 1, 1, 0, 1, 1, 0], dtype=uint8),
 119: array([0, 1, 1, 1, 0, 1, 1, 1], dtype=uint8),
 120: array([0, 1, 1, 1, 1, 0, 0, 0], dtype=uint8),
 121: array([0, 1, 1, 1, 1, 0, 0, 1], dtype=uint8),
 122: array([0, 1, 1, 1, 1, 0, 1, 0], dtype=uint8),
 123: array([0, 1, 1, 1, 1, 0, 1, 1], dtype=uint8),
 124: array([0, 1, 1, 1, 1, 1, 0, 0], dtype=uint8),
 125: array([0, 1, 1, 1, 1, 1, 0, 1], dtype=uint8),
 126: array([0, 1, 1, 1, 1, 1, 1, 0], dtype=uint8),
 127: array([0, 1, 1, 1, 1, 1, 1, 1], dtype=uint8),
 128: array([1, 0, 0, 0, 0, 0, 0, 0], dtype=uint8),
 129: array([1, 0, 0, 0, 0, 0, 0, 1], dtype=uint8),
 130: array([1, 0, 0, 0, 0, 0, 1, 0], dtype=uint8),
 131: array([1, 0, 0, 0, 0, 0, 1, 1], dtype=uint8),
 132: array([1, 0, 0, 0, 0, 1, 0, 0], dtype=uint8),
 133: array([1, 0, 0, 0, 0, 1, 0, 1], dtype=uint8),
 134: array([1, 0, 0, 0, 0, 1, 1, 0], dtype=uint8),
 135: array([1, 0, 0, 0, 0, 1, 1, 1], dtype=uint8),
 136: array([1, 0, 0, 0, 1, 0, 0, 0], dtype=uint8),
 137: array([1, 0, 0, 0, 1, 0, 0, 1], dtype=uint8),
 138: array([1, 0, 0, 0, 1, 0, 1, 0], dtype=uint8),
 139: array([1, 0, 0, 0, 1, 0, 1, 1], dtype=uint8),
 140: array([1, 0, 0, 0, 1, 1, 0, 0], dtype=uint8),
 141: array([1, 0, 0, 0, 1, 1, 0, 1], dtype=uint8),
 142: array([1, 0, 0, 0, 1, 1, 1, 0], dtype=uint8),
 143: array([1, 0, 0, 0, 1, 1, 1, 1], dtype=uint8),
 144: array([1, 0, 0, 1, 0, 0, 0, 0], dtype=uint8),
 145: array([1, 0, 0, 1, 0, 0, 0, 1], dtype=uint8),
 146: array([1, 0, 0, 1, 0, 0, 1, 0], dtype=uint8),
 147: array([1, 0, 0, 1, 0, 0, 1, 1], dtype=uint8),
 148: array([1, 0, 0, 1, 0, 1, 0, 0], dtype=uint8),
 149: array([1, 0, 0, 1, 0, 1, 0, 1], dtype=uint8),
 150: array([1, 0, 0, 1, 0, 1, 1, 0], dtype=uint8),
 151: array([1, 0, 0, 1, 0, 1, 1, 1], dtype=uint8),
 152: array([1, 0, 0, 1, 1, 0, 0, 0], dtype=uint8),
 153: array([1, 0, 0, 1, 1, 0, 0, 1], dtype=uint8),
 154: array([1, 0, 0, 1, 1, 0, 1, 0], dtype=uint8),
 155: array([1, 0, 0, 1, 1, 0, 1, 1], dtype=uint8),
 156: array([1, 0, 0, 1, 1, 1, 0, 0], dtype=uint8),
 157: array([1, 0, 0, 1, 1, 1, 0, 1], dtype=uint8),
 158: array([1, 0, 0, 1, 1, 1, 1, 0], dtype=uint8),
 159: array([1, 0, 0, 1, 1, 1, 1, 1], dtype=uint8),
 160: array([1, 0, 1, 0, 0, 0, 0, 0], dtype=uint8),
 161: array([1, 0, 1, 0, 0, 0, 0, 1], dtype=uint8),
 162: array([1, 0, 1, 0, 0, 0, 1, 0], dtype=uint8),
 163: array([1, 0, 1, 0, 0, 0, 1, 1], dtype=uint8),
 164: array([1, 0, 1, 0, 0, 1, 0, 0], dtype=uint8),
 165: array([1, 0, 1, 0, 0, 1, 0, 1], dtype=uint8),
 166: array([1, 0, 1, 0, 0, 1, 1, 0], dtype=uint8),
 167: array([1, 0, 1, 0, 0, 1, 1, 1], dtype=uint8),
 168: array([1, 0, 1, 0, 1, 0, 0, 0], dtype=uint8),
 169: array([1, 0, 1, 0, 1, 0, 0, 1], dtype=uint8),
 170: array([1, 0, 1, 0, 1, 0, 1, 0], dtype=uint8),
 171: array([1, 0, 1, 0, 1, 0, 1, 1], dtype=uint8),
 172: array([1, 0, 1, 0, 1, 1, 0, 0], dtype=uint8),
 173: array([1, 0, 1, 0, 1, 1, 0, 1], dtype=uint8),
 174: array([1, 0, 1, 0, 1, 1, 1, 0], dtype=uint8),
 175: array([1, 0, 1, 0, 1, 1, 1, 1], dtype=uint8),
 176: array([1, 0, 1, 1, 0, 0, 0, 0], dtype=uint8),
 177: array([1, 0, 1, 1, 0, 0, 0, 1], dtype=uint8),
 178: array([1, 0, 1, 1, 0, 0, 1, 0], dtype=uint8),
 179: array([1, 0, 1, 1, 0, 0, 1, 1], dtype=uint8),
 180: array([1, 0, 1, 1, 0, 1, 0, 0], dtype=uint8),
 181: array([1, 0, 1, 1, 0, 1, 0, 1], dtype=uint8),
 182: array([1, 0, 1, 1, 0, 1, 1, 0], dtype=uint8),
 183: array([1, 0, 1, 1, 0, 1, 1, 1], dtype=uint8),
 184: array([1, 0, 1, 1, 1, 0, 0, 0], dtype=uint8),
 185: array([1, 0, 1, 1, 1, 0, 0, 1], dtype=uint8),
 186: array([1, 0, 1, 1, 1, 0, 1, 0], dtype=uint8),
 187: array([1, 0, 1, 1, 1, 0, 1, 1], dtype=uint8),
 188: array([1, 0, 1, 1, 1, 1, 0, 0], dtype=uint8),
 189: array([1, 0, 1, 1, 1, 1, 0, 1], dtype=uint8),
 190: array([1, 0, 1, 1, 1, 1, 1, 0], dtype=uint8),
 191: array([1, 0, 1, 1, 1, 1, 1, 1], dtype=uint8),
 192: array([1, 1, 0, 0, 0, 0, 0, 0], dtype=uint8),
 193: array([1, 1, 0, 0, 0, 0, 0, 1], dtype=uint8),
 194: array([1, 1, 0, 0, 0, 0, 1, 0], dtype=uint8),
 195: array([1, 1, 0, 0, 0, 0, 1, 1], dtype=uint8),
 196: array([1, 1, 0, 0, 0, 1, 0, 0], dtype=uint8),
 197: array([1, 1, 0, 0, 0, 1, 0, 1], dtype=uint8),
 198: array([1, 1, 0, 0, 0, 1, 1, 0], dtype=uint8),
 199: array([1, 1, 0, 0, 0, 1, 1, 1], dtype=uint8),
 200: array([1, 1, 0, 0, 1, 0, 0, 0], dtype=uint8),
 201: array([1, 1, 0, 0, 1, 0, 0, 1], dtype=uint8),
 202: array([1, 1, 0, 0, 1, 0, 1, 0], dtype=uint8),
 203: array([1, 1, 0, 0, 1, 0, 1, 1], dtype=uint8),
 204: array([1, 1, 0, 0, 1, 1, 0, 0], dtype=uint8),
 205: array([1, 1, 0, 0, 1, 1, 0, 1], dtype=uint8),
 206: array([1, 1, 0, 0, 1, 1, 1, 0], dtype=uint8),
 207: array([1, 1, 0, 0, 1, 1, 1, 1], dtype=uint8),
 208: array([1, 1, 0, 1, 0, 0, 0, 0], dtype=uint8),
 209: array([1, 1, 0, 1, 0, 0, 0, 1], dtype=uint8),
 210: array([1, 1, 0, 1, 0, 0, 1, 0], dtype=uint8),
 211: array([1, 1, 0, 1, 0, 0, 1, 1], dtype=uint8),
 212: array([1, 1, 0, 1, 0, 1, 0, 0], dtype=uint8),
 213: array([1, 1, 0, 1, 0, 1, 0, 1], dtype=uint8),
 214: array([1, 1, 0, 1, 0, 1, 1, 0], dtype=uint8),
 215: array([1, 1, 0, 1, 0, 1, 1, 1], dtype=uint8),
 216: array([1, 1, 0, 1, 1, 0, 0, 0], dtype=uint8),
 217: array([1, 1, 0, 1, 1, 0, 0, 1], dtype=uint8),
 218: array([1, 1, 0, 1, 1, 0, 1, 0], dtype=uint8),
 219: array([1, 1, 0, 1, 1, 0, 1, 1], dtype=uint8),
 220: array([1, 1, 0, 1, 1, 1, 0, 0], dtype=uint8),
 221: array([1, 1, 0, 1, 1, 1, 0, 1], dtype=uint8),
 222: array([1, 1, 0, 1, 1, 1, 1, 0], dtype=uint8),
 223: array([1, 1, 0, 1, 1, 1, 1, 1], dtype=uint8),
 224: array([1, 1, 1, 0, 0, 0, 0, 0], dtype=uint8),
 225: array([1, 1, 1, 0, 0, 0, 0, 1], dtype=uint8),
 226: array([1, 1, 1, 0, 0, 0, 1, 0], dtype=uint8),
 227: array([1, 1, 1, 0, 0, 0, 1, 1], dtype=uint8),
 228: array([1, 1, 1, 0, 0, 1, 0, 0], dtype=uint8),
 229: array([1, 1, 1, 0, 0, 1, 0, 1], dtype=uint8),
 230: array([1, 1, 1, 0, 0, 1, 1, 0], dtype=uint8),
 231: array([1, 1, 1, 0, 0, 1, 1, 1], dtype=uint8),
 232: array([1, 1, 1, 0, 1, 0, 0, 0], dtype=uint8),
 233: array([1, 1, 1, 0, 1, 0, 0, 1], dtype=uint8),
 234: array([1, 1, 1, 0, 1, 0, 1, 0], dtype=uint8),
 235: array([1, 1, 1, 0, 1, 0, 1, 1], dtype=uint8),
 236: array([1, 1, 1, 0, 1, 1, 0, 0], dtype=uint8),
 237: array([1, 1, 1, 0, 1, 1, 0, 1], dtype=uint8),
 238: array([1, 1, 1, 0, 1, 1, 1, 0], dtype=uint8),
 239: array([1, 1, 1, 0, 1, 1, 1, 1], dtype=uint8),
 240: array([1, 1, 1, 1, 0, 0, 0, 0], dtype=uint8),
 241: array([1, 1, 1, 1, 0, 0, 0, 1], dtype=uint8),
 242: array([1, 1, 1, 1, 0, 0, 1, 0], dtype=uint8),
 243: array([1, 1, 1, 1, 0, 0, 1, 1], dtype=uint8),
 244: array([1, 1, 1, 1, 0, 1, 0, 0], dtype=uint8),
 245: array([1, 1, 1, 1, 0, 1, 0, 1], dtype=uint8),
 246: array([1, 1, 1, 1, 0, 1, 1, 0], dtype=uint8),
 247: array([1, 1, 1, 1, 0, 1, 1, 1], dtype=uint8),
 248: array([1, 1, 1, 1, 1, 0, 0, 0], dtype=uint8),
 249: array([1, 1, 1, 1, 1, 0, 0, 1], dtype=uint8),
 250: array([1, 1, 1, 1, 1, 0, 1, 0], dtype=uint8),
 251: array([1, 1, 1, 1, 1, 0, 1, 1], dtype=uint8),
 252: array([1, 1, 1, 1, 1, 1, 0, 0], dtype=uint8),
 253: array([1, 1, 1, 1, 1, 1, 0, 1], dtype=uint8),
 254: array([1, 1, 1, 1, 1, 1, 1, 0], dtype=uint8),
 255: array([1, 1, 1, 1, 1, 1, 1, 1], dtype=uint8)}

In [5]:
# Input variables
learning_rate = 0.3
input_dim = 2
hidden_dim = 16
output_dim = 1

In [6]:
# Initialize weights
wih = 2 * np.random.random((input_dim, hidden_dim)) - 1
who = 2 * np.random.random((hidden_dim, output_dim)) - 1
whh = 2 * np.random.random((hidden_dim, hidden_dim)) - 1

update_wih = np.zeros_like(wih)
update_who = np.zeros_like(who)
update_whh = np.zeros_like(whh)

In [11]:
# Training
iteration = 10000

for iterate in range(iteration):
    # generate a simple addition problem (a + b = c)
    a_int = np.random.randint(largest_number/2) # int version
    a = int2binary[a_int] # binary encoding

    b_int = np.random.randint(largest_number/2) # int version
    b = int2binary[b_int] # binary encoding
    
    # True answer
    c_int = a_int + b_int
    c = int2binary[c_int]

    # where we'll store our best guess (binary encoded)
    d = np.zeros_like(c)
    overallError = 0

    output_deltas = list()
    hidden_values = list()
    hidden_values.append(np.zeros(hidden_dim))
    
    # Moving along the positions in the binary encoding
    for position in range(binary_dim):
        # Generate input and output
        X = np.array([
            [a[binary_dim - position - 1],
             b[binary_dim - position - 1]]])

        y = np.array([[c[binary_dim - position - 1]]]).T

        # Hidden layer (input ~+ prev_hidden)
        hidden_layer = sigmoid(np.dot(X, wih) + np.dot(hidden_values[-1], whh))
#        print(hidden_layer)
        # output layer (new binary representation)
        output_layer = sigmoid(np.dot(hidden_layer,who))

        # did we miss?... if so, by how much?
        output_error = y - output_layer
        output_deltas.append((output_error) * sigmoid_derivative(output_layer))
        overallError += np.abs(output_error[0])
    
        # decode estimate so we can print it out
        d[binary_dim - position - 1] = np.round(output_layer[0][0])
#        print(output_layer)
        # store hidden layer so we can use it in the next timestep
        hidden_values.append(copy.deepcopy(hidden_layer))
        
    future_hidden_delta = np.zeros(hidden_dim)
    
    for position in range(binary_dim):
        X = np.array([[a[position], b[position]]])
        hidden_layer = hidden_values[-position -1]
        prev_hidden = hidden_values[-position -2]
#        print(len(hidden_values), hidden_values)
        # error at output layer
        output_delta = output_deltas[-position -1]
        # error at hidden layer
        hidden_delta = (future_hidden_delta.dot(whh.T)
                        + output_delta.dot(who.T)) * sigmoid_derivative(hidden_layer)

        # let's update all our weights so we can try again
        update_who += np.atleast_2d(hidden_layer).T.dot(output_delta)
        update_whh += np.atleast_2d(prev_hidden).T.dot(hidden_delta)
        update_wih += X.T.dot(hidden_delta)
        
        future_hidden_delta = hidden_delta

    wih += update_wih * learning_rate
    who += update_who * learning_rate
    whh += update_whh * learning_rate

    update_wih = 0
    update_who = 0
    update_whh = 0
    # print out progress
    if iterate % (iteration/10) == 0:
        print("Iteration:", iterate)
        print("Error:" + str(overallError))
        print("Pred:" + str(d))
        print("True:" + str(c))
        out = 0
        for index,x in enumerate(reversed(d)):
            out += x*pow(2,index)
        print(str(a_int) + " + " + str(b_int) + " = " + str(out))
        print("------------")


[[0]] [[ 0.715086]] [[-0.715086]]
[array([[-0.1456902]])]
[[1]] [[ 0.588029]] [[ 0.411971]]
[array([[-0.1456902]]), array([[ 0.09980034]])]
[[0]] [[ 0.46491614]] [[-0.46491614]]
[array([[-0.1456902]]), array([[ 0.09980034]]), array([[-0.11565678]])]
[[1]] [[ 0.69802908]] [[ 0.30197092]]
[array([[-0.1456902]]), array([[ 0.09980034]]), array([[-0.11565678]]), array([[ 0.06365079]])]
[[1]] [[ 0.52683458]] [[ 0.47316542]]
[array([[-0.1456902]]), array([[ 0.09980034]]), array([[-0.11565678]]), array([[ 0.06365079]]), array([[ 0.11795063]])]
[[0]] [[ 0.50468882]] [[-0.50468882]]
[array([[-0.1456902]]), array([[ 0.09980034]]), array([[-0.11565678]]), array([[ 0.06365079]]), array([[ 0.11795063]]), array([[-0.12616111]])]
[[0]] [[ 0.61721187]] [[-0.61721187]]
[array([[-0.1456902]]), array([[ 0.09980034]]), array([[-0.11565678]]), array([[ 0.06365079]]), array([[ 0.11795063]]), array([[-0.12616111]]), array([[-0.14582333]])]
[[1]] [[ 0.67018643]] [[ 0.32981357]]
[array([[-0.1456902]]), array([[ 0.09980034]]), array([[-0.11565678]]), array([[ 0.06365079]]), array([[ 0.11795063]]), array([[-0.12616111]]), array([[-0.14582333]]), array([[ 0.07290086]])]
Iteration: 0
Error:[ 3.81882374]
Pred:[1 1 1 1 1 0 1 1]
True:[1 0 0 1 1 0 1 0]
54 + 100 = 251
------------

In [ ]: