web-dev-qa-db-fra.com

Implémentation de réseau neuronal multicouche simple

il y a quelque temps, j'ai commencé mon aventure avec le machine learning (au cours des 2 dernières années de mes études). J'ai lu beaucoup de livres et écrit beaucoup de code avec des algorithmes d'apprentissage automatique SAUF les réseaux de neurones, qui étaient hors de ma portée. Je suis très intéressé par ce sujet, mais j'ai un énorme problème: tous les livres que j'ai lus ont deux problèmes principaux:

  1. Contient des tons d'équations mathématiques. Après la conférence, je les connais assez bien et à la main, sur le papier, je peux faire les calculs.
  2. Contenir de grands exemples intégrés dans un contexte compliqué (par exemple, enquêter sur les taux de vente des boutiques Internet) et pour entrer dans la mise en œuvre des réseaux de neurones, je dois écrire beaucoup de code pour reproduire le contexte. Ce qui manque - une mise en œuvre simple et simple sans beaucoup de contexte et d'équations.

Pourriez-vous s'il vous plaît me conseiller, où puis-je trouver une mise en œuvre SIMPLE de la perception multicouche (réseau de neurones)? Je n'ai pas besoin de connaissances théoriques et je ne veux pas non plus d'exemples contextuels. Je préfère certains langages de script pour gagner du temps et des efforts - 99% de mes travaux précédents ont été réalisés en Python.

Voici la liste des livres que j'ai lus auparavant (et que je n'ai pas trouvé ce que je voulais):

  1. L'apprentissage automatique en action
  2. Programmation de l'intelligence collective
  3. Apprentissage automatique: une perspective algorithmique
  4. Introduction aux réseaux de neurones en Java
  5. Introduction aux réseaux de neurones en C #
27
Animattronic

Une implémentation simple

Voici une implémentation lisible utilisant des classes dans Python. Cette implémentation échange efficacité et compréhension:

    import math
    import random

    BIAS = -1

    """
    To view the structure of the Neural Network, type
    print network_name
    """

    class Neuron:
        def __init__(self, n_inputs ):
            self.n_inputs = n_inputs
            self.set_weights( [random.uniform(0,1) for x in range(0,n_inputs+1)] ) # +1 for bias weight

        def sum(self, inputs ):
            # Does not include the bias
            return sum(val*self.weights[i] for i,val in enumerate(inputs))

        def set_weights(self, weights ):
            self.weights = weights

        def __str__(self):
            return 'Weights: %s, Bias: %s' % ( str(self.weights[:-1]),str(self.weights[-1]) )

    class NeuronLayer:
        def __init__(self, n_neurons, n_inputs):
            self.n_neurons = n_neurons
            self.neurons = [Neuron( n_inputs ) for _ in range(0,self.n_neurons)]

        def __str__(self):
            return 'Layer:\n\t'+'\n\t'.join([str(neuron) for neuron in self.neurons])+''

    class NeuralNetwork:
        def __init__(self, n_inputs, n_outputs, n_neurons_to_hl, n_hidden_layers):
            self.n_inputs = n_inputs
            self.n_outputs = n_outputs
            self.n_hidden_layers = n_hidden_layers
            self.n_neurons_to_hl = n_neurons_to_hl

            # Do not touch
            self._create_network()
            self._n_weights = None
            # end

        def _create_network(self):
            if self.n_hidden_layers>0:
                # create the first layer
                self.layers = [NeuronLayer( self.n_neurons_to_hl,self.n_inputs )]

                # create hidden layers
                self.layers += [NeuronLayer( self.n_neurons_to_hl,self.n_neurons_to_hl ) for _ in range(0,self.n_hidden_layers)]

                # hidden-to-output layer
                self.layers += [NeuronLayer( self.n_outputs,self.n_neurons_to_hl )]
            else:
                # If we don't require hidden layers
                self.layers = [NeuronLayer( self.n_outputs,self.n_inputs )]

        def get_weights(self):
            weights = []

            for layer in self.layers:
                for neuron in layer.neurons:
                    weights += neuron.weights

            return weights

        @property
        def n_weights(self):
            if not self._n_weights:
                self._n_weights = 0
                for layer in self.layers:
                    for neuron in layer.neurons:
                        self._n_weights += neuron.n_inputs+1 # +1 for bias weight
            return self._n_weights

        def set_weights(self, weights ):
            assert len(weights)==self.n_weights, "Incorrect amount of weights."

            stop = 0
            for layer in self.layers:
                for neuron in layer.neurons:
                    start, stop = stop, stop+(neuron.n_inputs+1)
                    neuron.set_weights( weights[start:stop] )
            return self

        def update(self, inputs ):
            assert len(inputs)==self.n_inputs, "Incorrect amount of inputs."

            for layer in self.layers:
                outputs = []
                for neuron in layer.neurons:
                    tot = neuron.sum(inputs) + neuron.weights[-1]*BIAS
                    outputs.append( self.sigmoid(tot) )
                inputs = outputs   
            return outputs

        def sigmoid(self, activation,response=1 ):
            # the activation function
            try:
                return 1/(1+math.e**(-activation/response))
            except OverflowError:
                return float("inf")

        def __str__(self):
            return '\n'.join([str(i+1)+' '+str(layer) for i,layer in enumerate(self.layers)])

Une mise en œuvre plus efficace (avec apprentissage)

Si vous cherchez un exemple plus efficace de réseau neuronal avec apprentissage (rétropropagation), jetez un œil à mon référentiel Github de réseau neuronal ici .

32
jorgenkg

Hmm c'est délicat. J'ai eu le même problème avant et je n'ai rien trouvé entre une bonne explication mais fortement chargée en mathématiques et des implémentations prêtes à l'emploi.

Le problème avec les implémentations prêtes à l'emploi comme PyBrain est qu'elles cachent les détails, donc les personnes intéressées à apprendre à implémenter les ANN ont besoin d'autre chose. La lecture du code de ces solutions peut également être difficile car elles utilisent souvent des heuristiques pour améliorer les performances et cela rend le code plus difficile à suivre pour un débutant.

Cependant, vous pouvez utiliser quelques ressources:

http://msdn.Microsoft.com/en-us/magazine/jj658979.aspx

http://itee.uq.edu.au/~cogs2010/cmc/chapters/BackProp/

http://www.codeproject.com/Articles/19323/Image-Recognition-with-Neural-Networks

http://freedelta.free.fr/r/php-code-samples/artificial-intelligence-neural-network-backpropagation/

7
Pedrom

Voici un exemple de la façon dont vous pouvez implémenter un réseau neuronal à action directe à l'aide de numpy. Importez d'abord numpy et spécifiez les dimensions de vos entrées et de vos cibles.

import numpy as np

input_dim = 1000
target_dim = 10

Nous allons construire la structure du réseau maintenant. Comme suggéré dans le grand "Reconnaissance de Motifs et Apprentissage Automatique" de Bishop, vous pouvez simplement considérer la dernière ligne de vos matrices numpy comme des poids de biais et la dernière colonne de vos activations comme des neurones de biais. Les dimensions d'entrée/sortie de la première/dernière matrice de poids doivent alors être supérieures de 1.

dimensions = [input_dim+1, 500, 500, target_dim+1]

weight_matrices = []
for i in range(len(dimensions)-1):
  weight_matrix = np.ones((dimensions[i], dimensions[i]))
  weight_matrices.append(weight_matrix)

Si vos entrées sont stockées dans une matrice numd 2d, où chaque ligne correspond à un échantillon et les colonnes correspondent aux attributs de vos échantillons, vous pouvez propager à travers le réseau comme ceci: (en supposant la fonction sigmoïde logistique comme fonction d'activation)

def activate_network(inputs):
  activations = [] # we store the activations for each layer here
  a = np.ones((inputs.shape[0], inputs.shape[1]+1)) #add the bias to the inputs
  a[:,:-1] = inputs

  for w in weight_matrices:
    x = a.dot(w) # sum of weighted inputs
    a = 1. / (1. - np.exp(-x)) # apply logistic sigmoid activation
    a[:,-1] = 1. # bias for the next layer.
    activations.append(a)

  return activations

Le dernier élément de activations sera la sortie de votre réseau, mais attention, vous devez omettre la colonne supplémentaire pour les biais, donc votre sortie sera activations[-1][:,:-1].

Pour former un réseau, vous devez implémenter la rétropropagation qui prend quelques lignes de code supplémentaires. Vous devez boucler du dernier élément de activations au premier, en gros. Assurez-vous de mettre la colonne de polarisation du signal d'erreur à zéro pour chaque couche avant chaque étape de rétropropagation.

6
schreon

Ici est un algorithme backprop en python natif.

5
david_adler

Avez-vous essayé PyBrain ? Cela semble très bien documenté .

0
Salem