From 4f90aabfba7efabeed2130e4d90fe766b131c4c0 Mon Sep 17 00:00:00 2001 From: inzouzouwetrust Date: Thu, 12 Jul 2018 18:05:37 +0200 Subject: [PATCH 1/5] Python 3 compatibility in simple_mlp.py --- simple_mlp.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/simple_mlp.py b/simple_mlp.py index 398f32d..a9b6e77 100644 --- a/simple_mlp.py +++ b/simple_mlp.py @@ -7,15 +7,15 @@ def applySigmoid(x, giveMeTheDerivative = False): return 1 / (1 + np.exp(-x)) def print_data(iter, inputs, keys, weights, prediction): - print "This is iteration # ", iter - print "Your original input data was... \n", inputs - print "Your orignal keys were... \n", keys - print "Your weights at this specific iteration are... \n", weights - print "Our prediction at this iteration was... \n", prediction - print "--------------------------------------------------\n" + print ("This is iteration # ", iter) + print ("Your original input data was... \n", inputs) + print ("Your orignal keys were... \n", keys) + print ("Your weights at this specific iteration are... \n", weights) + print ("Our prediction at this iteration was... \n", prediction) + print ("--------------------------------------------------\n") def train(inputs, keys, weights): - for iter in xrange(20000): + for iter in range(20000): prediction = applySigmoid(np.dot(inputs, weights)) error = keys - prediction change_in_error = error * applySigmoid(prediction,True) @@ -23,16 +23,15 @@ def train(inputs, keys, weights): if(iter == 0 or iter == 5000 or iter == 9999): print_data(iter, inputs, keys, weights, prediction) - print "Output After Training:" - print prediction + print ("Output After Training:") + print (prediction) def main(): np.random.seed(1) - inputs = np.array( [[0,0,1], - [1,1,1], - [1,0,1], - [0,1,1]]) - + inputs = np.array([[0,0,1], + [1,1,1], + [1,0,1], + [0,1,1]]) keys = np.array([[0,1,1,0]]).T weights = 2*np.random.random((3,1)) - 1 train(inputs, keys, weights) From 4981b006b575863508aaef806eeb03a1abb20277 Mon Sep 17 00:00:00 2001 From: inzouzouwetrust Date: Fri, 13 Jul 2018 00:22:07 +0200 Subject: [PATCH 2/5] Fix printing statement compatibility to Python 2 and 3 in simple_mlp. Fix weights and keys initialization --- simple_mlp.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/simple_mlp.py b/simple_mlp.py index a9b6e77..a0be7e2 100644 --- a/simple_mlp.py +++ b/simple_mlp.py @@ -7,11 +7,11 @@ def applySigmoid(x, giveMeTheDerivative = False): return 1 / (1 + np.exp(-x)) def print_data(iter, inputs, keys, weights, prediction): - print ("This is iteration # ", iter) - print ("Your original input data was... \n", inputs) - print ("Your orignal keys were... \n", keys) - print ("Your weights at this specific iteration are... \n", weights) - print ("Our prediction at this iteration was... \n", prediction) + print ("This is iteration # %d" % iter) + print ("Your original input data was...\n%s" % inputs) + print ("Your orignal keys were...\n%s" % keys) + print ("Your weights at this specific iteration are...\n%s" % weights) + print ("Our prediction at this iteration was...\n%s" % prediction) print ("--------------------------------------------------\n") def train(inputs, keys, weights): @@ -23,16 +23,15 @@ def train(inputs, keys, weights): if(iter == 0 or iter == 5000 or iter == 9999): print_data(iter, inputs, keys, weights, prediction) - print ("Output After Training:") - print (prediction) + print ("Output After Training:\n%s" % prediction) def main(): np.random.seed(1) inputs = np.array([[0,0,1], - [1,1,1], [1,0,1], - [0,1,1]]) - keys = np.array([[0,1,1,0]]).T + [0,1,1], + [1,1,1]]) + keys = np.array([[0,1,0,1]]).T weights = 2*np.random.random((3,1)) - 1 train(inputs, keys, weights) From 25b70088c3c04403ca742911b93cd42881a25cae Mon Sep 17 00:00:00 2001 From: inzouzouwetrust Date: Fri, 13 Jul 2018 09:29:51 +0200 Subject: [PATCH 3/5] Code formatting consistency in simple_mlp.py --- simple_mlp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simple_mlp.py b/simple_mlp.py index a0be7e2..bbace63 100644 --- a/simple_mlp.py +++ b/simple_mlp.py @@ -19,7 +19,7 @@ def train(inputs, keys, weights): prediction = applySigmoid(np.dot(inputs, weights)) error = keys - prediction change_in_error = error * applySigmoid(prediction,True) - weights += np.dot(inputs.T ,change_in_error) + weights += np.dot(inputs.T, change_in_error) if(iter == 0 or iter == 5000 or iter == 9999): print_data(iter, inputs, keys, weights, prediction) @@ -32,7 +32,7 @@ def main(): [0,1,1], [1,1,1]]) keys = np.array([[0,1,0,1]]).T - weights = 2*np.random.random((3,1)) - 1 + weights = 2 * np.random.random((3,1)) - 1 train(inputs, keys, weights) if __name__ == "__main__": From 78507455cffe05deebe991fc3e33320136cc7387 Mon Sep 17 00:00:00 2001 From: inzouzouwetrust Date: Fri, 13 Jul 2018 10:16:46 +0200 Subject: [PATCH 4/5] Fix fancy_mlp.py implementation as it was throwing a ValueError: Traceback (most recent call last): File "fancy_mlp.py", line 74, in main() File "fancy_mlp.py", line 71, in main train(inputs, keys, layer_one_weights, layer_two_weights) File "fancy_mlp.py", line 53, in train layer_one_weights += np.dot(layer_one_prediction.T, layer_one_change_in_error) ValueError: operands could not be broadcast together with shapes (3,4) (4,4) (3,4) Increase training steps to 40000 --- fancy_mlp.py | 104 +++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/fancy_mlp.py b/fancy_mlp.py index e993688..f3b94d5 100644 --- a/fancy_mlp.py +++ b/fancy_mlp.py @@ -2,64 +2,78 @@ def applySigmoid(x, giveMeTheDerivative = False): - if(giveMeTheDerivative == True): - return applySigmoid(x) * (1 - applySigmoid(x)) - return 1 / (1 + np.exp(-x)) - -def print_data(iter, inputs, keys, weights, prediction): - print "This is iteration # ", iter - print "Your original input data was... \n", inputs - print "Your orignal keys were... \n", keys - print "Your weights at this specific iteration are... \n", weights - print "Our prediction at this iteration was... \n", prediction - print "--------------------------------------------------\n" + if(giveMeTheDerivative == True): + return applySigmoid(x) * (1 - applySigmoid(x)) + return 1 / (1 + np.exp(-x)) + +def print_data(iter, inputs, keys, layer_one_weights, layer_two_weights, prediction): + print ("This is iteration # %d" % iter) + print ("Your original input data was...\n%s" % inputs) + print ("Your orignal keys were...\n%s" % keys) + print ("Layer one weights at this specific iteration are... \n%s" % layer_one_weights) + print ("Layer two weights at this specific iteration are... \n%s" % layer_two_weights) + print ("Our prediction at this iteration was...\n%s" % prediction) + print ("--------------------------------------------------\n") def train(inputs, keys, layer_one_weights, layer_two_weights): - for iter in xrange(20000): + for iter in range(40000): - # Layer one will have its own inputs and they are the ones directly given to us from main. - layer_one_inputs = inputs; + # Layer one will have its own inputs and they are the ones directly given to us from main. + layer_one_inputs = inputs - # Predict just like in simple_mlp.py - layer_one_prediction = applySigmoid(np.dot(layer_one_inputs, layer_one_weights)) + # Predict just like in simple_mlp.py + layer_one_prediction = applySigmoid(np.dot(layer_one_inputs, layer_one_weights)) - # Take the prediction from layer one and forward proogate it to the second layer of weights for a final output. - layer_two_prediction = applySigmoid(np.dot(layer_one_prediction, layer_two_weights)) + # Take the prediction from layer one and forward proogate it to the second layer of weights for a final output. + layer_two_prediction = applySigmoid(np.dot(layer_one_prediction, layer_two_weights)) - # How much were we off by? - layer_two_error = keys - layer_two_prediction + # How much were we off by? + layer_two_error = keys - layer_two_prediction - # Change in error just like in simple_mlp.py - layer_two_change_in_error = layer_two_error * applySigmoid(layer_two_prediction, True) + # Change in error just like in simple_mlp.py + layer_two_change_in_error = layer_two_error * applySigmoid(layer_two_prediction, True) - # Figure out how wrong our output for layer_one was by seeing how wrong the layer_two_prediction was - layer_one_error = np.dot(layer_two_change_in_error, layer_two_weights.T) + # Figure out how wrong our output for layer_one was by seeing how wrong the layer_two_prediction was + layer_one_error = np.dot(layer_two_change_in_error, layer_two_weights.T) - # Just like in simple_mlp.py - layer_one_change_in_error = layer_one_error * applySigmoid(layer_one_error, True) + # Just like in simple_mlp.py + layer_one_change_in_error = layer_one_error * applySigmoid(layer_one_prediction, True) - # adjust your weights accoridngly. - layer_one_weights += np.dot(layer_one_prediction.T, layer_one_change_in_error) - layer_two_weights += np.dot(layer_two_prediction.T, layer_two_change_in_error) + if iter == 0: + assert layer_one_prediction.shape[0] == 4 + assert layer_one_prediction.shape[1] == 4 + assert layer_two_prediction.shape[0] == 4 + assert layer_two_prediction.shape[1] == 1 + assert layer_one_weights.shape[0] == 3 + assert layer_one_weights.shape[1] == 4 + assert layer_two_weights.shape[0] == 4 + assert layer_two_weights.shape[1] == 1 - if(iter == 0 or iter == 5000 or iter == 9999): - print_data(iter, inputs, keys, weights, prediction) + # adjust your weights accoridngly. + layer_one_weights += np.dot(inputs.T, layer_one_change_in_error) + layer_two_weights += np.dot(layer_one_prediction.T, + layer_two_change_in_error) - print "Output After Training:" - print prediction + if(iter == 0 or iter == 5000 or iter == 9999): + print_data(iter, + inputs, + keys, + layer_one_weights, + layer_two_weights, + layer_two_prediction) -def main(): - np.random.seed(1) - inputs = np.array( [[0,0,1], - [1,0,1], - [0,1,1], - [1,1,1]]) + print ("Output After Training:\n%s" % layer_two_prediction) - keys = np.array([[0,1,1,0]]).T - layer_one_weights = 2*np.random.random((3,4)) - 1 - layer_two_weights = 2*np.random.random((4,1)) - 1 - train(inputs, keys, layer_one_weights, layer_two_weights) +def main(): + np.random.seed(1) + inputs = np.array([[0,0,1], + [1,0,1], + [0,1,1], + [1,1,1]]) + keys = np.array([[0,1,1,0]]).T + layer_one_weights = 2 * np.random.random((3,4)) - 1 + layer_two_weights = 2 * np.random.random((4,1)) - 1 + train(inputs, keys, layer_one_weights, layer_two_weights) if __name__ == "__main__": - main() - + main() From 7347802bf7060b01f9468f6ef0eb4130d8dd2691 Mon Sep 17 00:00:00 2001 From: inzouzouwetrust Date: Fri, 13 Jul 2018 10:23:02 +0200 Subject: [PATCH 5/5] Update README to discard Python 3 compatibility issues --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 42cbfb5..5edcebc 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,7 @@ pip install numpy python simple_mlp.py ``` -Make sure you have Python 2 installed, since this does not run in Python 3. -As for prior knowledge, know how Python works and the basics of calculus/matrix algebra. +Basic Python and calculus/matrix algebra knowledge might be needed to fully understand this tutorial. I don't go over how numpy works in this tutorial but just imagine it as a super cool/easy library to work with matrixes and many other things. Every numpy method call will have an ```np``` come before it. If you don't get what it's doing, refer to this easy doc: http://cs231n.github.io/python-numpy-tutorial/