class OurNeuralNetwork: ''' A neural network with: - 2 inputs - a hidden layer with 2 neurons (h1, h2) - an output layer with 1 neuron (o1) Each neuron has the same weights and bias: - w = [0, 1] - b = 0 ''' def __init__(self): weights = np.array([0, 1]) bias = 0 # The Neuron class here is from the previous section self.h1 = Neuron(weights, bias) self.h2 = Neuron(weights, bias) self.o1 = Neuron(weights, bias) def feedforward(self, x): out_h1 = self.h1.feedforward(x) out_h2 = self.h2.feedforward(x) # The inputs for o1 are the outputs from h1 and h2 out_o1 = self.o1.feedforward(np.array([out_h1, out_h2])) return out_o1
class BasicNeuralNetwork: """ A neural network with: - two inputs: x1, and x2 - a hidden layer with two neurons: h1 and h2 - an output layer with a neuron: o1 The three neurons use the same weights and bias """ def __init__(self, weights, bias, activation): self.h1 = Neuron(weights, bias, activation) self.h2 = Neuron(weights, bias, activation) self.o1 = Neuron(weights, bias, activation) def feedforward(self, x): """First we compute the output of the first layer""" output_h1 = self.h1.feedforward(x) output_h2 = self.h2.feedforward(x) """The outputs of the hiden layer h1 and h2 are the input of the output layer""" output_o1 = self.o1.feedforward(np.array([output_h1, output_h2])) return output_o1 def show_configuration(self): # return 'Network configuration: ' \ # 'Weights: {}, Bias: {}, and Activation: {}'.format(self.weights, self.bias, # self.activation(0)['name']) return '* Hidden layer (2 neurons):\n - {}\n - {} \n* Output layer (1 neuron):\n - {} \n'.format( self.h1.show_configuration(), self.h2.show_configuration(), self.o1.show_configuration())
class NeuralNetwork: def __init__(self, weights): self.weights = weights self.a = Neuron(weights[0:2], weights[2]) self.b = Neuron(weights[3:5], weights[5]) self.c = Neuron(np.array(weights[6:8]), weights[8]) def update_weights(self): self.weights = self.new_weidhts def feedforward(self, x): feed_a = self.a.feedforward(x) feed_b = self.b.feedforward(x) out_o1 = self.c.feedforward(np.array([feed_a, feed_b])) return out_o1
def test_neuron(): print('Testing a neuron...') activations = ActivationFunctions() weights = np.array([3, 1]) # w1 = 3, w2 = 1 bias = -1 # b = -1 n = Neuron(weights, bias, activations.sigmoid) x = np.array([4, 1]) # x1 = 4, x2 = 1 print(n.show_configuration()) print('Input: {} --> Result: {}'.format(x, n.feedforward(x))) # 0.9999938558253978
class TwoLayerNeuralNetwork: """It encapsulates a two layer neural neuron with: - input_layer_size inputs - a hidden layer with hidden_layer_size neurons - an output layer with 1 neuron (o1) - the weights are randomly computed """ def __init__(self, input_layer_size, hidden_layer_size, bias, activation): weights = np.array([0, 1]) self.bias = bias self.input_layer_size = input_layer_size self.hidden_layer_size = hidden_layer_size self.activation = activation # The Neuron class here is from the previous section self.hidden_layer = list() for i in range(self.hidden_layer_size): self.hidden_layer.append( Neuron(self.create_weights(self.input_layer_size), self.bias, self.activation)) self.o1 = Neuron(self.create_weights(self.hidden_layer_size), self.bias, self.activation) def feedforward(self, x): if len(x) != self.input_layer_size: print( 'The input {} has not the size of the input of the network, which is {}' .format(x, self.input_layer_size)) hidden_layer_output = list() for neuron in self.hidden_layer: hidden_layer_output.append(neuron.feedforward(x)) # The inputs for o1 are the outputs from h1 and h2 output_o1 = self.o1.feedforward(np.array(hidden_layer_output)) return output_o1 def show_configuration(self): config_string = 'Two layer neural networ configuration: \n' config_string += '* Input layer size: {}\n'.format( self.input_layer_size) config_string += '* Hidden layer size: {}\n'.format( self.hidden_layer_size) for neuron in self.hidden_layer: config_string += ' - {}\n'.format(neuron.show_configuration()) config_string += ' * Output layer size: {}\n'.format(1) config_string += ' - {}\n'.format(self.o1.show_configuration()) return config_string def create_weights(self, size): return np.random.normal(size=size)
iterations = len(images) l1_size = len(b1) l2_size = len(b2) for imgNo in range(iterations): print(imgNo + 1, '/', iterations) res1.append([]) res2.append([]) # layer 1 for l1No in range(l1_size): # weights = column(W1, l1No) weights = W1[l1No] bias = b1[l1No] inputs = images[imgNo] neuron = Neuron(weights, bias) result = neuron.feedforward(inputs) res1[imgNo].append(result) # layer 2 for l2No in range(l2_size): weights = W2[l2No] bias = b2[l2No] inputs = res1[imgNo] neuron = Neuron(weights, bias) result = neuron.feedforward(inputs) res2[imgNo].append(result) # check result if labels[imgNo] == array(res2[imgNo]).argmax(): total = total + 1 # accuracy print('accuracy:', total / iterations * 100, '%')