From 1276934c547445eb2c87ab4594def372473de536 Mon Sep 17 00:00:00 2001 From: Absobel Date: Sun, 6 Jun 2021 17:59:19 +0200 Subject: [PATCH] Ajout de deux trois trucs --- RUN.py | 8 +- network mais annotations changées.py | 106 +++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 network mais annotations changées.py diff --git a/RUN.py b/RUN.py index d3eeaa5..215673a 100644 --- a/RUN.py +++ b/RUN.py @@ -3,13 +3,13 @@ import mnist_loader training_data, validation_data, test_data = mnist_loader.load_data_wrapper() -print(list(training_data)[0][1]) +#print(list(training_data)[0][1]) import network -#net = network.Network([784, 30, 10]) #Testé : 94,56% -#net.SGD(training_data, 10, 10, 3.0, test_data=None) -#print("Results : {} / 10000".format(net.evaluate(test_data))) +net = network.Network([784, 30, 10]) #Testé : 94,56% / 94,87% +net.SGD(training_data, 30, 10, 3.0, test_data=test_data) +print("Results : {} / 10000".format(net.evaluate(test_data))) # net = network.Network([784, 100, 10]) #Marche mieux apparemment # net.SGD(training_data, 30, 10, 3.0, test_data=test_data) diff --git a/network mais annotations changées.py b/network mais annotations changées.py new file mode 100644 index 0000000..d785693 --- /dev/null +++ b/network mais annotations changées.py @@ -0,0 +1,106 @@ +import random +import numpy as np + +class Network(object): + + def __init__(self, sizes): + """sizes : [nb neurones input, nb de neurones couche 1, ..., nb de neurones couche n, nb de neurones output] + biases : seuils générés aléatoirement + weights : poids générés aléatoirement""" + self.num_layers = len(sizes) + self.sizes = sizes + self.biases = [np.random.randn(y, 1) for y in sizes[1:]] + self.weights = [np.random.randn(y, x) + for x, y in zip(sizes[:-1], sizes[1:])] + + def feedforward(self, a): + for b, w in zip(self.biases, self.weights): + a = sigmoid(np.dot(w, a)+b) + return a + + def SGD(self, training_data, epochs, mini_batch_size, eta, + test_data=None): + """epochs : iterations + eta : taux d'apprentissage + test_data : s'il y en a pas le programme ne s'arrêtera pas à chaque iterations pour se tester""" + + training_data = list(training_data) + n = len(training_data) + + if test_data: + test_data = list(test_data) + n_test = len(test_data) + + for j in range(epochs): + random.shuffle(training_data) + mini_batches = [ + training_data[k:k+mini_batch_size] + for k in range(0, n, mini_batch_size)] + for mini_batch in mini_batches: + self.update_mini_batch(mini_batch, eta) + if test_data: + print("Epoch {} : {} / {}".format(j,self.evaluate(test_data),n_test)) + else: + print("Epoch {} complete".format(j)) + + def update_mini_batch(self, mini_batch, eta): + """Met à jour les poids et seuils grâce aux gradient descendant""" + nabla_b = [np.zeros(b.shape) for b in self.biases] + nabla_w = [np.zeros(w.shape) for w in self.weights] + for x, y in mini_batch: + delta_nabla_b, delta_nabla_w = self.backprop(x, y) + nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] + nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] + self.weights = [w-(eta/len(mini_batch))*nw + for w, nw in zip(self.weights, nabla_w)] + self.biases = [b-(eta/len(mini_batch))*nb + for b, nb in zip(self.biases, nabla_b)] + + def backprop(self, x, y): + """Calcul du gradient descendant""" + nabla_b = [np.zeros(b.shape) for b in self.biases] + nabla_w = [np.zeros(w.shape) for w in self.weights] + # feedforward + activation = x + activations = [x] # list to store all the activations, layer by layer + zs = [] # list to store all the z vectors, layer by layer + for b, w in zip(self.biases, self.weights): + z = np.dot(w, activation)+b + zs.append(z) + activation = sigmoid(z) + activations.append(activation) + # backward pass + delta = self.cost_derivative(activations[-1], y) * \ + sigmoid_prime(zs[-1]) + nabla_b[-1] = delta + nabla_w[-1] = np.dot(delta, activations[-2].transpose()) + # Note that the variable l in the loop below is used a little + # differently to the notation in Chapter 2 of the book. Here, + # l = 1 means the last layer of neurons, l = 2 is the + # second-last layer, and so on. It's a renumbering of the + # scheme in the book, used here to take advantage of the fact + # that Python can use negative indices in lists. + for l in range(2, self.num_layers): + z = zs[-l] + sp = sigmoid_prime(z) + delta = np.dot(self.weights[-l+1].transpose(), delta) * sp + nabla_b[-l] = delta + nabla_w[-l] = np.dot(delta, activations[-l-1].transpose()) + return (nabla_b, nabla_w) + + def evaluate(self, test_data): + """Teste le programme avec le dataset fourni""" + test_results = [(np.argmax(self.feedforward(x)), y) + for (x, y) in test_data] + return sum(int(x == y) for (x, y) in test_results) + + def cost_derivative(self, output_activations, y): + """Return the vector of partial derivatives \partial C_x / + \partial a for the output activations.""" + return (output_activations-y) + +def sigmoid(z): + return 1.0/(1.0+np.exp(-z)) + +def sigmoid_prime(z): + return sigmoid(z)*(1-sigmoid(z))