From fa4e2ac86eceaae018cb18c720420665b485f3b7 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Mon, 14 Dec 2020 22:27:56 +0530 Subject: [PATCH 01/16] added neural network with 2 hidden layers --- .../2_hidden_layers_neural_network.py | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 neural_network/2_hidden_layers_neural_network.py diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py new file mode 100644 index 000000000000..b924a85930cf --- /dev/null +++ b/neural_network/2_hidden_layers_neural_network.py @@ -0,0 +1,112 @@ +import numpy + +class NeuralNetwork: + + def __init__(self, input_array, output_array): + ''' + input_array : input values for training the neural network. + output_array : expected output values of the given inputs. + ''' + self.input = input_array + #Initial weights are assigned randomly where first argument is the number of nodes in previous layer + #and second argument is the number of nodes in the next layer. + + #random initial weights for the input layer + #self.input.shape[1] is used to reprsent number of nodes in input layer + #first hidden layer consists of 4 nodes + self.weights1 = numpy.random.rand(self.input.shape[1],4) + + #random initial weights for the first hidden layer + #first hidden layer has 4 nodes + #second hidden layer has 3 nodes + self.weights2 = numpy.random.rand(4,3) + + #random inital weights for the second hidden layer + #second hidden layer has 3 nodes + #output layer has 1 node + self.weights3 = numpy.random.rand(3,1) + + self.y = output_array + self.output = numpy.zeros(output_array.shape) + + def feedforward(self): + ''' + feedforward propagation using sigmoid activation function between layers + return the last layer of the neural network + ''' + #layer1 is the layer connecting the input nodes with the first hidden layer nodes + self.layer1 = sigmoid(numpy.dot(self.input, self.weights1)) + + #layer2 is the layer connecting the first hidden set of nodes with the second hidden set of nodes + self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) + + #layer3 is the layer connecting second hidden layer with the output node + self.layer3 = sigmoid(numpy.dot(self.layer2,self.weights3)) + + return self.layer3 + + def back_propagation(self): + ''' + backpropagating between the layers using sigmoid derivative and loss between layers + updates the weights between the layers + ''' + + updated_weights3 = numpy.dot(self.layer2.T,2*(self.y-self.output)*sigmoid_derivative(self.output)) + updated_weights2 = numpy.dot(self.layer1.T, numpy.dot(2*(self.y -self.output)*sigmoid_derivative(self.output), self.weights3.T)*sigmoid_derivative(self.layer2)) + updated_weights1 = numpy.dot(self.input.T, numpy.dot(numpy.dot(2*(self.y -self.output)*sigmoid_derivative(self.output), self.weights3.T)*sigmoid_derivative(self.layer2),self.weights2.T)*sigmoid_derivative(self.layer1)) + + self.weights1 += updated_weights1 + self.weights2 += updated_weights2 + self.weights3 += updated_weights3 + + def train(self, output, iterations): + ''' + output : required for calculating loss + performs the feeding and back propagation process for the given number of iterations + every iteration will update the weights of neural network + ''' + for iteration in range(1,iterations+1): + self.output = self.feedforward() + self.back_propagation() + print("Iteration %s "%iteration,"Loss: " + str(numpy.mean(numpy.square(output - self.feedforward())))) + + def predict(self, input): + ''' + predict output for the given input values + ''' + self.array = input + self.layer1 = sigmoid(numpy.dot(self.array, self.weights1)) + self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) + self.layer3 = sigmoid(numpy.dot(self.layer2,self.weights3)) + return self.layer3 + +def sigmoid(value): + ''' + applies sigmoid activation function + return normalized values + ''' + return 1/(1+numpy.exp(-value)) + +def sigmoid_derivative(value): + ''' + returns derivative of the sigmoid value + ''' + return sigmoid(value)*(1-sigmoid(value)) + + +if __name__ == "__main__": + + #input values + input = numpy.array(([0,0,0],[0,0,1],[0,1,0],[0,1,1], + [1,0,0],[1,0,1],[1,1,0],[1,1,1]),dtype=float) + + #true output for the given input values + output = numpy.array(([0],[1],[1],[0], + [1],[0],[0],[1]),dtype=float) + + #calling neural network class + Neural_Network = NeuralNetwork(input_array= input, output_array= output) + + #calling training function + Neural_Network.train(output= output, iterations= 1000) + print(Neural_Network.predict([0,1,1])) \ No newline at end of file From 1219f8c74c8d9de194801132fdac4c81355ce236 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Mon, 14 Dec 2020 22:30:07 +0530 Subject: [PATCH 02/16] Revert "added neural network with 2 hidden layers" This reverts commit fa4e2ac86eceaae018cb18c720420665b485f3b7. --- .../2_hidden_layers_neural_network.py | 112 ------------------ 1 file changed, 112 deletions(-) delete mode 100644 neural_network/2_hidden_layers_neural_network.py diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py deleted file mode 100644 index b924a85930cf..000000000000 --- a/neural_network/2_hidden_layers_neural_network.py +++ /dev/null @@ -1,112 +0,0 @@ -import numpy - -class NeuralNetwork: - - def __init__(self, input_array, output_array): - ''' - input_array : input values for training the neural network. - output_array : expected output values of the given inputs. - ''' - self.input = input_array - #Initial weights are assigned randomly where first argument is the number of nodes in previous layer - #and second argument is the number of nodes in the next layer. - - #random initial weights for the input layer - #self.input.shape[1] is used to reprsent number of nodes in input layer - #first hidden layer consists of 4 nodes - self.weights1 = numpy.random.rand(self.input.shape[1],4) - - #random initial weights for the first hidden layer - #first hidden layer has 4 nodes - #second hidden layer has 3 nodes - self.weights2 = numpy.random.rand(4,3) - - #random inital weights for the second hidden layer - #second hidden layer has 3 nodes - #output layer has 1 node - self.weights3 = numpy.random.rand(3,1) - - self.y = output_array - self.output = numpy.zeros(output_array.shape) - - def feedforward(self): - ''' - feedforward propagation using sigmoid activation function between layers - return the last layer of the neural network - ''' - #layer1 is the layer connecting the input nodes with the first hidden layer nodes - self.layer1 = sigmoid(numpy.dot(self.input, self.weights1)) - - #layer2 is the layer connecting the first hidden set of nodes with the second hidden set of nodes - self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) - - #layer3 is the layer connecting second hidden layer with the output node - self.layer3 = sigmoid(numpy.dot(self.layer2,self.weights3)) - - return self.layer3 - - def back_propagation(self): - ''' - backpropagating between the layers using sigmoid derivative and loss between layers - updates the weights between the layers - ''' - - updated_weights3 = numpy.dot(self.layer2.T,2*(self.y-self.output)*sigmoid_derivative(self.output)) - updated_weights2 = numpy.dot(self.layer1.T, numpy.dot(2*(self.y -self.output)*sigmoid_derivative(self.output), self.weights3.T)*sigmoid_derivative(self.layer2)) - updated_weights1 = numpy.dot(self.input.T, numpy.dot(numpy.dot(2*(self.y -self.output)*sigmoid_derivative(self.output), self.weights3.T)*sigmoid_derivative(self.layer2),self.weights2.T)*sigmoid_derivative(self.layer1)) - - self.weights1 += updated_weights1 - self.weights2 += updated_weights2 - self.weights3 += updated_weights3 - - def train(self, output, iterations): - ''' - output : required for calculating loss - performs the feeding and back propagation process for the given number of iterations - every iteration will update the weights of neural network - ''' - for iteration in range(1,iterations+1): - self.output = self.feedforward() - self.back_propagation() - print("Iteration %s "%iteration,"Loss: " + str(numpy.mean(numpy.square(output - self.feedforward())))) - - def predict(self, input): - ''' - predict output for the given input values - ''' - self.array = input - self.layer1 = sigmoid(numpy.dot(self.array, self.weights1)) - self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) - self.layer3 = sigmoid(numpy.dot(self.layer2,self.weights3)) - return self.layer3 - -def sigmoid(value): - ''' - applies sigmoid activation function - return normalized values - ''' - return 1/(1+numpy.exp(-value)) - -def sigmoid_derivative(value): - ''' - returns derivative of the sigmoid value - ''' - return sigmoid(value)*(1-sigmoid(value)) - - -if __name__ == "__main__": - - #input values - input = numpy.array(([0,0,0],[0,0,1],[0,1,0],[0,1,1], - [1,0,0],[1,0,1],[1,1,0],[1,1,1]),dtype=float) - - #true output for the given input values - output = numpy.array(([0],[1],[1],[0], - [1],[0],[0],[1]),dtype=float) - - #calling neural network class - Neural_Network = NeuralNetwork(input_array= input, output_array= output) - - #calling training function - Neural_Network.train(output= output, iterations= 1000) - print(Neural_Network.predict([0,1,1])) \ No newline at end of file From 97556abf36f5c82cf9db804e0a003955f7719f9b Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Mon, 14 Dec 2020 23:43:26 +0530 Subject: [PATCH 03/16] added neural network with 2 hidden layers --- .../2_hidden_layers_neural_network.py | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 neural_network/2_hidden_layers_neural_network.py diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py new file mode 100644 index 000000000000..d0c72bfaa2e1 --- /dev/null +++ b/neural_network/2_hidden_layers_neural_network.py @@ -0,0 +1,158 @@ +import numpy + + +class NeuralNetwork: + def __init__(self, input_array, output_array): + """ + input_array : input values for training the neural network. + output_array : expected output values of the given inputs. + """ + self.input = input_array + # Initial weights are assigned randomly where first argument is the number + # of nodes in previous layer and second argument is the + # number of nodes in the next layer. + + # random initial weights for the input layer + # self.input.shape[1] is used to represent number of nodes in input layer + # first hidden layer consists of 4 nodes + self.weights1 = numpy.random.rand(self.input.shape[1], 4) + + # random initial weights for the first hidden layer + # first hidden layer has 4 nodes + # second hidden layer has 3 nodes + self.weights2 = numpy.random.rand(4, 3) + + # random initial weights for the second hidden layer + # second hidden layer has 3 nodes + # output layer has 1 node + self.weights3 = numpy.random.rand(3, 1) + + self.y = output_array + self.output = numpy.zeros(output_array.shape) + + def feedforward(self): + """ + feedforward propagation using sigmoid activation function between layers + return the last layer of the neural network + """ + # layer1 is the layer connecting the input nodes with + # the first hidden layer nodes + self.layer1 = sigmoid(numpy.dot(self.input, self.weights1)) + + # layer2 is the layer connecting the first hidden set of nodes + # with the second hidden set of nodes + self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) + + # layer3 is the layer connecting second hidden layer with the output node + self.layer3 = sigmoid(numpy.dot(self.layer2, self.weights3)) + + return self.layer3 + + def back_propagation(self): + """ + backpropagating between the layers using sigmoid derivative and + loss between layers + updates the weights between the layers + """ + + updated_weights3 = numpy.dot( + self.layer2.T, 2 * (self.y - self.output) * sigmoid_derivative(self.output) + ) + updated_weights2 = numpy.dot( + self.layer1.T, + numpy.dot( + 2 * (self.y - self.output) * sigmoid_derivative(self.output), + self.weights3.T, + ) + * sigmoid_derivative(self.layer2), + ) + updated_weights1 = numpy.dot( + self.input.T, + numpy.dot( + numpy.dot( + 2 * (self.y - self.output) * sigmoid_derivative(self.output), + self.weights3.T, + ) + * sigmoid_derivative(self.layer2), + self.weights2.T, + ) + * sigmoid_derivative(self.layer1), + ) + + self.weights1 += updated_weights1 + self.weights2 += updated_weights2 + self.weights3 += updated_weights3 + + def train(self, output, iterations): + """ + output : required for calculating loss + performs the feeding and back propagation process for the + given number of iterations + every iteration will update the weights of neural network + """ + for iteration in range(1, iterations + 1): + self.output = self.feedforward() + self.back_propagation() + print( + "Iteration %s " % iteration, + "Loss: " + str(numpy.mean(numpy.square(output - self.feedforward()))), + ) + + def predict(self, input): + """ + predict output for the given input values + """ + self.array = input + self.layer1 = sigmoid(numpy.dot(self.array, self.weights1)) + self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) + self.layer3 = sigmoid(numpy.dot(self.layer2, self.weights3)) + if self.layer3 >= 0.5: + return 1 + else: + return 0 + + +def sigmoid(value): + """ + applies sigmoid activation function + return normalized values + """ + return 1 / (1 + numpy.exp(-value)) + + +def sigmoid_derivative(value): + """ + returns derivative of the sigmoid value + """ + return sigmoid(value) * (1 - sigmoid(value)) + + +def example(): + # input values + input = numpy.array( + ( + [0, 0, 0], + [0, 0, 1], + [0, 1, 0], + [0, 1, 1], + [1, 0, 0], + [1, 0, 1], + [1, 1, 0], + [1, 1, 1], + ), + dtype=float, + ) + + # true output for the given input values + output = numpy.array(([0], [1], [1], [0], [1], [0], [0], [1]), dtype=float) + + # calling neural network class + Neural_Network = NeuralNetwork(input_array=input, output_array=output) + + # calling training function + Neural_Network.train(output=output, iterations=250) + print(Neural_Network.predict([0, 1, 0])) + + +if __name__ == "__main__": + example() From a783a4ddb12e230c1a7a1ff72ba085e2860463f2 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Mon, 14 Dec 2020 23:51:53 +0530 Subject: [PATCH 04/16] passing pre-commit requirements --- neural_network/2_hidden_layers_neural_network.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index d0c72bfaa2e1..b2e7d849c75b 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -2,7 +2,7 @@ class NeuralNetwork: - def __init__(self, input_array, output_array): + def __init__(self, input_array: numpy.array, output_array: numpy.array): """ input_array : input values for training the neural network. output_array : expected output values of the given inputs. @@ -83,7 +83,7 @@ def back_propagation(self): self.weights2 += updated_weights2 self.weights3 += updated_weights3 - def train(self, output, iterations): + def train(self, output: numpy.array, iterations: int): """ output : required for calculating loss performs the feeding and back propagation process for the @@ -98,7 +98,7 @@ def train(self, output, iterations): "Loss: " + str(numpy.mean(numpy.square(output - self.feedforward()))), ) - def predict(self, input): + def predict(self, input: numpy.array) -> int: """ predict output for the given input values """ @@ -112,7 +112,7 @@ def predict(self, input): return 0 -def sigmoid(value): +def sigmoid(value: float) -> float: """ applies sigmoid activation function return normalized values @@ -120,7 +120,7 @@ def sigmoid(value): return 1 / (1 + numpy.exp(-value)) -def sigmoid_derivative(value): +def sigmoid_derivative(value: float) -> float: """ returns derivative of the sigmoid value """ From 07fd20ed711c826f02cc247a1b70b163c50a78db Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 15 Dec 2020 00:07:50 +0530 Subject: [PATCH 05/16] doctest completed --- .../2_hidden_layers_neural_network.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index b2e7d849c75b..32d17200f53e 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -98,11 +98,11 @@ def train(self, output: numpy.array, iterations: int): "Loss: " + str(numpy.mean(numpy.square(output - self.feedforward()))), ) - def predict(self, input: numpy.array) -> int: + def predict(self, input: list) -> int: """ - predict output for the given input values + predict's output for the given input values """ - self.array = input + self.array = numpy.array((input), dtype=float) self.layer1 = sigmoid(numpy.dot(self.array, self.weights1)) self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) self.layer3 = sigmoid(numpy.dot(self.layer2, self.weights3)) @@ -116,6 +116,12 @@ def sigmoid(value: float) -> float: """ applies sigmoid activation function return normalized values + + >>> sigmoid(2) + 0.8807970779778823 + + >>> sigmoid(0) + 0.5 """ return 1 / (1 + numpy.exp(-value)) @@ -123,6 +129,9 @@ def sigmoid(value: float) -> float: def sigmoid_derivative(value: float) -> float: """ returns derivative of the sigmoid value + + >>> sigmoid_derivative(0.7) + 0.22171287329310904 """ return sigmoid(value) * (1 - sigmoid(value)) @@ -150,8 +159,8 @@ def example(): Neural_Network = NeuralNetwork(input_array=input, output_array=output) # calling training function - Neural_Network.train(output=output, iterations=250) - print(Neural_Network.predict([0, 1, 0])) + Neural_Network.train(output=output, iterations=1000) + print(Neural_Network.predict([0, 1, 1])) if __name__ == "__main__": From 3f17bfc65ba179fbb65be6c0f4381f40baabf332 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 15 Dec 2020 00:12:48 +0530 Subject: [PATCH 06/16] added return hints --- neural_network/2_hidden_layers_neural_network.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 32d17200f53e..dd5086288f34 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -2,7 +2,7 @@ class NeuralNetwork: - def __init__(self, input_array: numpy.array, output_array: numpy.array): + def __init__(self, input_array: numpy.array, output_array: numpy.array) -> None: """ input_array : input values for training the neural network. output_array : expected output values of the given inputs. @@ -30,7 +30,7 @@ def __init__(self, input_array: numpy.array, output_array: numpy.array): self.y = output_array self.output = numpy.zeros(output_array.shape) - def feedforward(self): + def feedforward(self) -> None: """ feedforward propagation using sigmoid activation function between layers return the last layer of the neural network @@ -48,7 +48,7 @@ def feedforward(self): return self.layer3 - def back_propagation(self): + def back_propagation(self) -> None: """ backpropagating between the layers using sigmoid derivative and loss between layers @@ -83,7 +83,7 @@ def back_propagation(self): self.weights2 += updated_weights2 self.weights3 += updated_weights3 - def train(self, output: numpy.array, iterations: int): + def train(self, output: numpy.array, iterations: int) -> None: """ output : required for calculating loss performs the feeding and back propagation process for the From ff553632cde6d1254d23f0407e37ae3690b1073d Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 15 Dec 2020 00:23:57 +0530 Subject: [PATCH 07/16] added example --- neural_network/2_hidden_layers_neural_network.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index dd5086288f34..f407344d04a9 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -136,7 +136,13 @@ def sigmoid_derivative(value: float) -> float: return sigmoid(value) * (1 - sigmoid(value)) -def example(): +def example() -> int: + """ + used for example + + >>> example() + 0 + """ # input values input = numpy.array( ( @@ -160,7 +166,7 @@ def example(): # calling training function Neural_Network.train(output=output, iterations=1000) - print(Neural_Network.predict([0, 1, 1])) + return Neural_Network.predict([0, 1, 1]) if __name__ == "__main__": From 0454f72065c34501281a093da43b1e2611a56606 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 15 Dec 2020 00:35:22 +0530 Subject: [PATCH 08/16] example added --- neural_network/2_hidden_layers_neural_network.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index f407344d04a9..5a0b1a26567b 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -139,9 +139,6 @@ def sigmoid_derivative(value: float) -> float: def example() -> int: """ used for example - - >>> example() - 0 """ # input values input = numpy.array( @@ -165,8 +162,8 @@ def example() -> int: Neural_Network = NeuralNetwork(input_array=input, output_array=output) # calling training function - Neural_Network.train(output=output, iterations=1000) - return Neural_Network.predict([0, 1, 1]) + Neural_Network.train(output=output, iterations=1500) + return Neural_Network.predict([1, 1, 1]) if __name__ == "__main__": From 003445890c1bfff46a8e37214bb869eed4cec268 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 15 Dec 2020 01:49:06 +0530 Subject: [PATCH 09/16] completed doctest's --- .../2_hidden_layers_neural_network.py | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 5a0b1a26567b..0df5f5b309fb 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -34,6 +34,15 @@ def feedforward(self) -> None: """ feedforward propagation using sigmoid activation function between layers return the last layer of the neural network + + >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) + >>> output_val=numpy.array(([0],[0],[0]),dtype=float) + >>> nn = NeuralNetwork(input_val,output_val) + >>> res = nn.feedforward() + >>> array_sum = numpy.sum(res) + >>> array_has_nan = numpy.isnan(array_sum) + >>> print(array_has_nan) + False """ # layer1 is the layer connecting the input nodes with # the first hidden layer nodes @@ -53,6 +62,12 @@ def back_propagation(self) -> None: backpropagating between the layers using sigmoid derivative and loss between layers updates the weights between the layers + + >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) + >>> output_val = numpy.array(([0],[0],[0]),dtype=float) + >>> nn = NeuralNetwork(input_val,output_val) + >>> res = nn.feedforward() + >>> weights = nn.back_propagation() """ updated_weights3 = numpy.dot( @@ -83,30 +98,44 @@ def back_propagation(self) -> None: self.weights2 += updated_weights2 self.weights3 += updated_weights3 - def train(self, output: numpy.array, iterations: int) -> None: + def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: """ output : required for calculating loss performs the feeding and back propagation process for the given number of iterations every iteration will update the weights of neural network + + >>> input_val = numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) + >>> output_val = numpy.array(([0],[1],[1]),dtype=float) + >>> nn = NeuralNetwork(input_val,output_val) + >>> nn.train(output_val,10,False) """ for iteration in range(1, iterations + 1): self.output = self.feedforward() self.back_propagation() - print( - "Iteration %s " % iteration, - "Loss: " + str(numpy.mean(numpy.square(output - self.feedforward()))), - ) + if give_loss: + print( + "Iteration %s " % iteration, + "Loss: " + + str(numpy.mean(numpy.square(output - self.feedforward()))), + ) def predict(self, input: list) -> int: """ predict's output for the given input values + + >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) + >>> output_val =numpy.array(([0],[0],[0]),dtype=float) + >>> nn = NeuralNetwork(input_val,output_val) + >>> nn.train(output_val,100,False) + >>> nn.predict([0,0,0]) + 0 """ - self.array = numpy.array((input), dtype=float) + self.array = input self.layer1 = sigmoid(numpy.dot(self.array, self.weights1)) self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) self.layer3 = sigmoid(numpy.dot(self.layer2, self.weights3)) - if self.layer3 >= 0.5: + if self.layer3 > 0.45: return 1 else: return 0 @@ -139,6 +168,9 @@ def sigmoid_derivative(value: float) -> float: def example() -> int: """ used for example + + >>> example() + 1 """ # input values input = numpy.array( @@ -162,7 +194,8 @@ def example() -> int: Neural_Network = NeuralNetwork(input_array=input, output_array=output) # calling training function - Neural_Network.train(output=output, iterations=1500) + # set give_loss to True if you want to see loss in every iteration + Neural_Network.train(output=output, iterations=5000, give_loss=False) return Neural_Network.predict([1, 1, 1]) From 4536f59a9a4375b0fbfee6f223114f23fdcd97de Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 22 Dec 2020 20:05:40 +0530 Subject: [PATCH 10/16] changes made as per the review --- .../2_hidden_layers_neural_network.py | 221 ++++++++++++------ 1 file changed, 149 insertions(+), 72 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 0df5f5b309fb..648b2e98ae0c 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -1,113 +1,167 @@ +from typing import List + import numpy -class NeuralNetwork: +class TwoHiddenLayerNeuralNetwork: def __init__(self, input_array: numpy.array, output_array: numpy.array) -> None: """ - input_array : input values for training the neural network. + This function initializes the TwoHiddenLayerNeuralNetwork class with random + weights for every layer and initializes predicted output with zeroes. + + input_array : input values for training the neural network (i.e training data) . output_array : expected output values of the given inputs. """ - self.input = input_array + + # Input values provided for training the model. + self.input_array = input_array + # Initial weights are assigned randomly where first argument is the number # of nodes in previous layer and second argument is the # number of nodes in the next layer. - # random initial weights for the input layer - # self.input.shape[1] is used to represent number of nodes in input layer - # first hidden layer consists of 4 nodes - self.weights1 = numpy.random.rand(self.input.shape[1], 4) + # Random initial weights for the input layer. + # self.input_array.shape[1] is used to represent number of nodes in input layer. + # First hidden layer consists of 4 nodes. + self.input_layer_and_first_hidden_layer_weights = numpy.random.rand( + self.input_array.shape[1], 4 + ) + + # Random initial weights for the first hidden layer. + # First hidden layer has 4 nodes. + # Second hidden layer has 3 nodes. + self.first_hidden_layer_and_second_hidden_layer_weights = numpy.random.rand( + 4, 3 + ) - # random initial weights for the first hidden layer - # first hidden layer has 4 nodes - # second hidden layer has 3 nodes - self.weights2 = numpy.random.rand(4, 3) + # Random initial weights for the second hidden layer. + # Second hidden layer has 3 nodes. + # Output layer has 1 node. + self.second_hidden_layer_and_output_layer_weights = numpy.random.rand(3, 1) - # random initial weights for the second hidden layer - # second hidden layer has 3 nodes - # output layer has 1 node - self.weights3 = numpy.random.rand(3, 1) + # Real output values provided. + self.output_array = output_array - self.y = output_array - self.output = numpy.zeros(output_array.shape) + # Predicted output values by the neural network. + # Predicted_output array initially consists of zeroes. + self.predicted_output = numpy.zeros(output_array.shape) def feedforward(self) -> None: """ - feedforward propagation using sigmoid activation function between layers - return the last layer of the neural network + The information moves in only one direction i.e. forward from the input nodes, + through the two hidden nodes and to the output nodes. + There are no cycles or loops in the network. + + Return layer_between_second_hidden_layer_and_output + (i.e the last layer of the neural network). >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) >>> output_val=numpy.array(([0],[0],[0]),dtype=float) - >>> nn = NeuralNetwork(input_val,output_val) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> res = nn.feedforward() >>> array_sum = numpy.sum(res) >>> array_has_nan = numpy.isnan(array_sum) >>> print(array_has_nan) False """ - # layer1 is the layer connecting the input nodes with - # the first hidden layer nodes - self.layer1 = sigmoid(numpy.dot(self.input, self.weights1)) + # Layer_between_input_and_first_hidden_layer is the layer connecting the + # input nodes with the first hidden layer nodes. + self.layer_between_input_and_first_hidden_layer = sigmoid( + numpy.dot(self.input_array, self.input_layer_and_first_hidden_layer_weights) + ) - # layer2 is the layer connecting the first hidden set of nodes - # with the second hidden set of nodes - self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) + # layer_between_first_hidden_layer_and_second_hidden_layer is the layer + # connecting the first hidden set of nodes with the second hidden set of nodes. + self.layer_between_first_hidden_layer_and_second_hidden_layer = sigmoid( + numpy.dot( + self.layer_between_input_and_first_hidden_layer, + self.first_hidden_layer_and_second_hidden_layer_weights, + ) + ) - # layer3 is the layer connecting second hidden layer with the output node - self.layer3 = sigmoid(numpy.dot(self.layer2, self.weights3)) + # layer_between_second_hidden_layer_and_output is the layer connecting + # second hidden layer with the output node. + self.layer_between_second_hidden_layer_and_output = sigmoid( + numpy.dot( + self.layer_between_first_hidden_layer_and_second_hidden_layer, + self.second_hidden_layer_and_output_layer_weights, + ) + ) - return self.layer3 + return self.layer_between_second_hidden_layer_and_output def back_propagation(self) -> None: """ - backpropagating between the layers using sigmoid derivative and - loss between layers - updates the weights between the layers + Function for fine-tuning the weights of the neural net based on the + error rate obtained in the previous epoch (i.e., iteration). + Updation is done using derivative of sogmoid activation function. >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) >>> output_val = numpy.array(([0],[0],[0]),dtype=float) - >>> nn = NeuralNetwork(input_val,output_val) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> res = nn.feedforward() >>> weights = nn.back_propagation() """ - updated_weights3 = numpy.dot( - self.layer2.T, 2 * (self.y - self.output) * sigmoid_derivative(self.output) + updated_second_hidden_layer_and_output_layer_weights = numpy.dot( + self.layer_between_first_hidden_layer_and_second_hidden_layer.T, + 2 + * (self.output_array - self.predicted_output) + * sigmoid_derivative(self.predicted_output), ) - updated_weights2 = numpy.dot( - self.layer1.T, + updated_first_hidden_layer_and_second_hidden_layer_weights = numpy.dot( + self.layer_between_input_and_first_hidden_layer.T, numpy.dot( - 2 * (self.y - self.output) * sigmoid_derivative(self.output), - self.weights3.T, + 2 + * (self.output_array - self.predicted_output) + * sigmoid_derivative(self.predicted_output), + self.second_hidden_layer_and_output_layer_weights.T, ) - * sigmoid_derivative(self.layer2), + * sigmoid_derivative( + self.layer_between_first_hidden_layer_and_second_hidden_layer + ), ) - updated_weights1 = numpy.dot( - self.input.T, + updated_input_layer_and_first_hidden_layer_weights = numpy.dot( + self.input_array.T, numpy.dot( numpy.dot( - 2 * (self.y - self.output) * sigmoid_derivative(self.output), - self.weights3.T, + 2 + * (self.output_array - self.predicted_output) + * sigmoid_derivative(self.predicted_output), + self.second_hidden_layer_and_output_layer_weights.T, ) - * sigmoid_derivative(self.layer2), - self.weights2.T, + * sigmoid_derivative( + self.layer_between_first_hidden_layer_and_second_hidden_layer + ), + self.first_hidden_layer_and_second_hidden_layer_weights.T, ) - * sigmoid_derivative(self.layer1), + * sigmoid_derivative(self.layer_between_input_and_first_hidden_layer), ) - self.weights1 += updated_weights1 - self.weights2 += updated_weights2 - self.weights3 += updated_weights3 + self.input_layer_and_first_hidden_layer_weights += ( + updated_input_layer_and_first_hidden_layer_weights + ) + self.first_hidden_layer_and_second_hidden_layer_weights += ( + updated_first_hidden_layer_and_second_hidden_layer_weights + ) + self.second_hidden_layer_and_output_layer_weights += ( + updated_second_hidden_layer_and_output_layer_weights + ) def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: """ - output : required for calculating loss - performs the feeding and back propagation process for the - given number of iterations - every iteration will update the weights of neural network + Performs the feedforwarding and back propagation process for the + given number of iterations. + Every iteration will update the weights of neural network. + + output : real output values,required for calculating loss. + iterations : number of times the weights are to be updated. + give_loss : boolean value, If True then prints loss for each iteration, + If False then nothing is printed >>> input_val = numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) >>> output_val = numpy.array(([0],[1],[1]),dtype=float) - >>> nn = NeuralNetwork(input_val,output_val) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> nn.train(output_val,10,False) """ for iteration in range(1, iterations + 1): @@ -120,22 +174,38 @@ def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: + str(numpy.mean(numpy.square(output - self.feedforward()))), ) - def predict(self, input: list) -> int: + def predict(self, input: List[int]) -> int: """ - predict's output for the given input values + Predict's the output for the given input values using + the trained neural network. >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) >>> output_val =numpy.array(([0],[0],[0]),dtype=float) - >>> nn = NeuralNetwork(input_val,output_val) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> nn.train(output_val,100,False) >>> nn.predict([0,0,0]) 0 """ + + # Input values for which the predictions are to be made. self.array = input - self.layer1 = sigmoid(numpy.dot(self.array, self.weights1)) - self.layer2 = sigmoid(numpy.dot(self.layer1, self.weights2)) - self.layer3 = sigmoid(numpy.dot(self.layer2, self.weights3)) - if self.layer3 > 0.45: + + self.layer_between_input_and_first_hidden_layer = sigmoid( + numpy.dot(self.array, self.input_layer_and_first_hidden_layer_weights) + ) + self.layer_between_first_hidden_layer_and_second_hidden_layer = sigmoid( + numpy.dot( + self.layer_between_input_and_first_hidden_layer, + self.first_hidden_layer_and_second_hidden_layer_weights, + ) + ) + self.layer_between_second_hidden_layer_and_output = sigmoid( + numpy.dot( + self.layer_between_first_hidden_layer_and_second_hidden_layer, + self.second_hidden_layer_and_output_layer_weights, + ) + ) + if self.layer_between_second_hidden_layer_and_output > 0.45: return 1 else: return 0 @@ -143,7 +213,8 @@ def predict(self, input: list) -> int: def sigmoid(value: float) -> float: """ - applies sigmoid activation function + Applies sigmoid activation function. + return normalized values >>> sigmoid(2) @@ -157,6 +228,8 @@ def sigmoid(value: float) -> float: def sigmoid_derivative(value: float) -> float: """ + Provides the derivative value of the sigmoid function. + returns derivative of the sigmoid value >>> sigmoid_derivative(0.7) @@ -167,12 +240,16 @@ def sigmoid_derivative(value: float) -> float: def example() -> int: """ - used for example + Example for "how to use the neural network class and use the + respected methods for the desired output". + Calls the TwoHiddenLayerNeuralNetwork class and + provides the fixed input output values to the model. + Model is trained for a fixed amount of iterations then the predict method is called. >>> example() 1 """ - # input values + # Input values. input = numpy.array( ( [0, 0, 0], @@ -187,16 +264,16 @@ def example() -> int: dtype=float, ) - # true output for the given input values + # True output values for the given input values. output = numpy.array(([0], [1], [1], [0], [1], [0], [0], [1]), dtype=float) - # calling neural network class - Neural_Network = NeuralNetwork(input_array=input, output_array=output) + # Calling neural network class. + neural_network = TwoHiddenLayerNeuralNetwork(input_array=input, output_array=output) - # calling training function - # set give_loss to True if you want to see loss in every iteration - Neural_Network.train(output=output, iterations=5000, give_loss=False) - return Neural_Network.predict([1, 1, 1]) + # Calling training function. + # Set give_loss to True if you want to see loss in every iteration. + neural_network.train(output=output, iterations=5000, give_loss=False) + return neural_network.predict([1, 1, 1]) if __name__ == "__main__": From c5f71ebf777897d602da936ffab2a383c71c6c6e Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Tue, 22 Dec 2020 20:22:45 +0530 Subject: [PATCH 11/16] changes made --- .../2_hidden_layers_neural_network.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 648b2e98ae0c..bfd110e35ba5 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -168,23 +168,24 @@ def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: self.output = self.feedforward() self.back_propagation() if give_loss: - print( - "Iteration %s " % iteration, - "Loss: " - + str(numpy.mean(numpy.square(output - self.feedforward()))), - ) + loss = numpy.mean(numpy.square(output - self.feedforward())) + print(f"Iteration {iteration} Loss: {loss}") def predict(self, input: List[int]) -> int: """ Predict's the output for the given input values using the trained neural network. - >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) - >>> output_val =numpy.array(([0],[0],[0]),dtype=float) + The output value given by the model ranges in-between 0 and 1. + The predict function returns 1 if the model value is greater + than 0.45 else return 0, as the real output values are in binary. + + >>> input_val =numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) + >>> output_val =numpy.array(([0],[1],[1]),dtype=float) >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) - >>> nn.train(output_val,100,False) - >>> nn.predict([0,0,0]) - 0 + >>> nn.train(output_val,1000,False) + >>> nn.predict([0,1,0]) + 1 """ # Input values for which the predictions are to be made. From 527109d1c8ec9def91bb1875dfa1959279f6152b Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Thu, 24 Dec 2020 19:13:54 +0530 Subject: [PATCH 12/16] changes after review --- .../2_hidden_layers_neural_network.py | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index bfd110e35ba5..fa80786d609d 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -1,4 +1,9 @@ -from typing import List +""" +References: + - http://neuralnetworksanddeeplearning.com/chap2.html (Backpropagation) + - https://en.wikipedia.org/wiki/Sigmoid_function (Sigmoid activation function) + - https://en.wikipedia.org/wiki/Feedforward_neural_network (Feedforward) +""" import numpy @@ -16,25 +21,25 @@ def __init__(self, input_array: numpy.array, output_array: numpy.array) -> None: # Input values provided for training the model. self.input_array = input_array - # Initial weights are assigned randomly where first argument is the number - # of nodes in previous layer and second argument is the + # Random initial weights are assigned where first argument is the + # number of nodes in previous layer and second argument is the # number of nodes in the next layer. - # Random initial weights for the input layer. + # Random initial weights are assigned. # self.input_array.shape[1] is used to represent number of nodes in input layer. # First hidden layer consists of 4 nodes. self.input_layer_and_first_hidden_layer_weights = numpy.random.rand( self.input_array.shape[1], 4 ) - # Random initial weights for the first hidden layer. + # Random initial values for the first hidden layer. # First hidden layer has 4 nodes. # Second hidden layer has 3 nodes. self.first_hidden_layer_and_second_hidden_layer_weights = numpy.random.rand( 4, 3 ) - # Random initial weights for the second hidden layer. + # Random initial values for the second hidden layer. # Second hidden layer has 3 nodes. # Output layer has 1 node. self.second_hidden_layer_and_output_layer_weights = numpy.random.rand(3, 1) @@ -55,13 +60,12 @@ def feedforward(self) -> None: Return layer_between_second_hidden_layer_and_output (i.e the last layer of the neural network). - >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) - >>> output_val=numpy.array(([0],[0],[0]),dtype=float) + >>> input_val = numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) + >>> output_val = numpy.array(([0],[0],[0]),dtype=float) >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> res = nn.feedforward() >>> array_sum = numpy.sum(res) - >>> array_has_nan = numpy.isnan(array_sum) - >>> print(array_has_nan) + >>> numpy.isnan(array_sum) False """ # Layer_between_input_and_first_hidden_layer is the layer connecting the @@ -96,11 +100,14 @@ def back_propagation(self) -> None: error rate obtained in the previous epoch (i.e., iteration). Updation is done using derivative of sogmoid activation function. - >>> input_val =numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) + >>> input_val = numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) >>> output_val = numpy.array(([0],[0],[0]),dtype=float) >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> res = nn.feedforward() - >>> weights = nn.back_propagation() + >>> nn.back_propagation() + >>> updated_weights = nn.second_hidden_layer_and_output_layer_weights + >>> (res == updated_weights).all() + False """ updated_second_hidden_layer_and_output_layer_weights = numpy.dot( @@ -162,7 +169,11 @@ def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: >>> input_val = numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) >>> output_val = numpy.array(([0],[1],[1]),dtype=float) >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) - >>> nn.train(output_val,10,False) + >>> first_iteration_weights = nn.feedforward() + >>> nn.back_propagation() + >>> updated_weights = nn.second_hidden_layer_and_output_layer_weights + >>> (first_iteration_weights == updated_weights).all() + False """ for iteration in range(1, iterations + 1): self.output = self.feedforward() @@ -171,17 +182,18 @@ def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: loss = numpy.mean(numpy.square(output - self.feedforward())) print(f"Iteration {iteration} Loss: {loss}") - def predict(self, input: List[int]) -> int: + def predict(self, input: numpy.array) -> int: """ Predict's the output for the given input values using the trained neural network. The output value given by the model ranges in-between 0 and 1. The predict function returns 1 if the model value is greater - than 0.45 else return 0, as the real output values are in binary. + than the threshold value else returns 0, + as the real output values are in binary. - >>> input_val =numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) - >>> output_val =numpy.array(([0],[1],[1]),dtype=float) + >>> input_val = numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) + >>> output_val = numpy.array(([0],[1],[1]),dtype=float) >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) >>> nn.train(output_val,1000,False) >>> nn.predict([0,1,0]) @@ -194,19 +206,22 @@ def predict(self, input: List[int]) -> int: self.layer_between_input_and_first_hidden_layer = sigmoid( numpy.dot(self.array, self.input_layer_and_first_hidden_layer_weights) ) + self.layer_between_first_hidden_layer_and_second_hidden_layer = sigmoid( numpy.dot( self.layer_between_input_and_first_hidden_layer, self.first_hidden_layer_and_second_hidden_layer_weights, ) ) + self.layer_between_second_hidden_layer_and_output = sigmoid( numpy.dot( self.layer_between_first_hidden_layer_and_second_hidden_layer, self.second_hidden_layer_and_output_layer_weights, ) ) - if self.layer_between_second_hidden_layer_and_output > 0.45: + + if self.layer_between_second_hidden_layer_and_output > 0.6: return 1 else: return 0 @@ -234,9 +249,9 @@ def sigmoid_derivative(value: float) -> float: returns derivative of the sigmoid value >>> sigmoid_derivative(0.7) - 0.22171287329310904 + 0.21000000000000002 """ - return sigmoid(value) * (1 - sigmoid(value)) + return (value) * (1 - (value)) def example() -> int: @@ -246,6 +261,8 @@ def example() -> int: Calls the TwoHiddenLayerNeuralNetwork class and provides the fixed input output values to the model. Model is trained for a fixed amount of iterations then the predict method is called. + In this example the output is divided into 2 classes i.e. binary classification, + the two classes are represented by '0' and '1'. >>> example() 1 @@ -273,8 +290,9 @@ def example() -> int: # Calling training function. # Set give_loss to True if you want to see loss in every iteration. - neural_network.train(output=output, iterations=5000, give_loss=False) - return neural_network.predict([1, 1, 1]) + neural_network.train(output=output, iterations=10, give_loss=False) + + return neural_network.predict(numpy.array(([1, 1, 1]), dtype=float)) if __name__ == "__main__": From 1033bd1fbdcf4a6c3cd8a4d70f906fd8e076a953 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Fri, 25 Dec 2020 15:13:32 +0530 Subject: [PATCH 13/16] changes --- neural_network/2_hidden_layers_neural_network.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index fa80786d609d..0e66be7bfc1b 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -221,10 +221,7 @@ def predict(self, input: numpy.array) -> int: ) ) - if self.layer_between_second_hidden_layer_and_output > 0.6: - return 1 - else: - return 0 + return int(self.layer_between_second_hidden_layer_and_output > 0.6) def sigmoid(value: float) -> float: From 481d7b7330f9e68f4622cd5a9a220e504d2d1b5e Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Fri, 25 Dec 2020 15:16:42 +0530 Subject: [PATCH 14/16] spacing --- .../2_hidden_layers_neural_network.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 0e66be7bfc1b..6ba5ab9d9045 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -60,9 +60,9 @@ def feedforward(self) -> None: Return layer_between_second_hidden_layer_and_output (i.e the last layer of the neural network). - >>> input_val = numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) - >>> output_val = numpy.array(([0],[0],[0]),dtype=float) - >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) + >>> input_val = numpy.array(([0, 0, 0], [0, 0, 0], [0, 0, 0]), dtype=float) + >>> output_val = numpy.array(([0], [0], [0]), dtype=float) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val, output_val) >>> res = nn.feedforward() >>> array_sum = numpy.sum(res) >>> numpy.isnan(array_sum) @@ -100,9 +100,9 @@ def back_propagation(self) -> None: error rate obtained in the previous epoch (i.e., iteration). Updation is done using derivative of sogmoid activation function. - >>> input_val = numpy.array(([0,0,0],[0,0,0],[0,0,0]),dtype=float) - >>> output_val = numpy.array(([0],[0],[0]),dtype=float) - >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) + >>> input_val = numpy.array(([0, 0, 0], [0, 0, 0], [0, 0, 0]), dtype=float) + >>> output_val = numpy.array(([0], [0], [0]), dtype=float) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val, output_val) >>> res = nn.feedforward() >>> nn.back_propagation() >>> updated_weights = nn.second_hidden_layer_and_output_layer_weights @@ -166,9 +166,9 @@ def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: give_loss : boolean value, If True then prints loss for each iteration, If False then nothing is printed - >>> input_val = numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) - >>> output_val = numpy.array(([0],[1],[1]),dtype=float) - >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) + >>> input_val = numpy.array(([0, 0, 0], [0, 1, 0], [0, 0, 1]), dtype=float) + >>> output_val = numpy.array(([0], [1], [1]), dtype=float) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val, output_val) >>> first_iteration_weights = nn.feedforward() >>> nn.back_propagation() >>> updated_weights = nn.second_hidden_layer_and_output_layer_weights @@ -192,10 +192,10 @@ def predict(self, input: numpy.array) -> int: than the threshold value else returns 0, as the real output values are in binary. - >>> input_val = numpy.array(([0,0,0],[0,1,0],[0,0,1]),dtype=float) - >>> output_val = numpy.array(([0],[1],[1]),dtype=float) - >>> nn = TwoHiddenLayerNeuralNetwork(input_val,output_val) - >>> nn.train(output_val,1000,False) + >>> input_val = numpy.array(([0, 0, 0], [0, 1, 0], [0, 0, 1]), dtype=float) + >>> output_val = numpy.array(([0], [1], [1]), dtype=float) + >>> nn = TwoHiddenLayerNeuralNetwork(input_val, output_val) + >>> nn.train(output_val, 1000, False) >>> nn.predict([0,1,0]) 1 """ From 1285ca36e8bd0355b12e3d42afd163f5fc763224 Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Fri, 25 Dec 2020 22:40:49 +0530 Subject: [PATCH 15/16] changed return type --- neural_network/2_hidden_layers_neural_network.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 6ba5ab9d9045..1edd5909faa9 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -9,7 +9,7 @@ class TwoHiddenLayerNeuralNetwork: - def __init__(self, input_array: numpy.array, output_array: numpy.array) -> None: + def __init__(self, input_array: numpy.ndarray, output_array: numpy.ndarray) -> None: """ This function initializes the TwoHiddenLayerNeuralNetwork class with random weights for every layer and initializes predicted output with zeroes. @@ -51,7 +51,7 @@ def __init__(self, input_array: numpy.array, output_array: numpy.array) -> None: # Predicted_output array initially consists of zeroes. self.predicted_output = numpy.zeros(output_array.shape) - def feedforward(self) -> None: + def feedforward(self) -> numpy.ndarray: """ The information moves in only one direction i.e. forward from the input nodes, through the two hidden nodes and to the output nodes. @@ -155,7 +155,7 @@ def back_propagation(self) -> None: updated_second_hidden_layer_and_output_layer_weights ) - def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: + def train(self, output: numpy.ndarray, iterations: int, give_loss: bool) -> None: """ Performs the feedforwarding and back propagation process for the given number of iterations. @@ -182,7 +182,7 @@ def train(self, output: numpy.array, iterations: int, give_loss: bool) -> None: loss = numpy.mean(numpy.square(output - self.feedforward())) print(f"Iteration {iteration} Loss: {loss}") - def predict(self, input: numpy.array) -> int: + def predict(self, input: numpy.ndarray) -> int: """ Predict's the output for the given input values using the trained neural network. From 3e2e723e1180739730ff7bc11bd950f1d44bcedf Mon Sep 17 00:00:00 2001 From: raman77768 <53868914+raman77768@users.noreply.github.com> Date: Sat, 26 Dec 2020 20:10:19 +0530 Subject: [PATCH 16/16] changed dtype --- .../2_hidden_layers_neural_network.py | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/neural_network/2_hidden_layers_neural_network.py b/neural_network/2_hidden_layers_neural_network.py index 1edd5909faa9..baa4316200d9 100644 --- a/neural_network/2_hidden_layers_neural_network.py +++ b/neural_network/2_hidden_layers_neural_network.py @@ -224,29 +224,28 @@ def predict(self, input: numpy.ndarray) -> int: return int(self.layer_between_second_hidden_layer_and_output > 0.6) -def sigmoid(value: float) -> float: +def sigmoid(value: numpy.ndarray) -> numpy.ndarray: """ Applies sigmoid activation function. return normalized values - >>> sigmoid(2) - 0.8807970779778823 - - >>> sigmoid(0) - 0.5 + >>> sigmoid(numpy.array(([1, 0, 2], [1, 0, 0]), dtype=numpy.float64)) + array([[0.73105858, 0.5 , 0.88079708], + [0.73105858, 0.5 , 0.5 ]]) """ return 1 / (1 + numpy.exp(-value)) -def sigmoid_derivative(value: float) -> float: +def sigmoid_derivative(value: numpy.ndarray) -> numpy.ndarray: """ Provides the derivative value of the sigmoid function. returns derivative of the sigmoid value - >>> sigmoid_derivative(0.7) - 0.21000000000000002 + >>> sigmoid_derivative(numpy.array(([1, 0, 2], [1, 0, 0]), dtype=numpy.float64)) + array([[ 0., 0., -2.], + [ 0., 0., 0.]]) """ return (value) * (1 - (value)) @@ -276,11 +275,11 @@ def example() -> int: [1, 1, 0], [1, 1, 1], ), - dtype=float, + dtype=numpy.float64, ) # True output values for the given input values. - output = numpy.array(([0], [1], [1], [0], [1], [0], [0], [1]), dtype=float) + output = numpy.array(([0], [1], [1], [0], [1], [0], [0], [1]), dtype=numpy.float64) # Calling neural network class. neural_network = TwoHiddenLayerNeuralNetwork(input_array=input, output_array=output) @@ -289,7 +288,7 @@ def example() -> int: # Set give_loss to True if you want to see loss in every iteration. neural_network.train(output=output, iterations=10, give_loss=False) - return neural_network.predict(numpy.array(([1, 1, 1]), dtype=float)) + return neural_network.predict(numpy.array(([1, 1, 1]), dtype=numpy.float64)) if __name__ == "__main__":