2010-06-06 23 views
10

Pour mes recherches supérieures, je crée un réseau de neurones qui s'entraîne à reconnaître les images. Je vais beaucoup plus complexe que de simplement prendre une grille de valeurs RVB, de sous-échantillonner et de les envoyer à l'entrée du réseau, comme le font de nombreux exemples. J'utilise en fait plus de 100 réseaux de neurones formés indépendamment qui détectent des caractéristiques, telles que des lignes, des motifs d'ombrage, etc. Beaucoup plus comme l'œil humain, et cela fonctionne très bien jusqu'ici! Le problème est que j'ai un peu de données d'entraînement. Je montre plus de 100 exemples de ce à quoi ressemble une voiture. Puis 100 exemples de ce à quoi ressemble une personne. Ensuite, plus de 100 de ce à quoi ressemble un chien, etc. C'est un peu de données d'entraînement! Actuellement, je cours environ une semaine pour former le réseau. C'est en quelque sorte de tuer mes progrès, car j'ai besoin d'ajuster et de se recycler. J'utilise Neuroph, en tant qu'API de réseau neuronal de bas niveau. J'utilise une machine dual-quadcore (16 cœurs avec hyperthreading), donc ça devrait être rapide. Mon pourcentage de processeur est à seulement 5%. Y a-t-il des astuces sur les performances de Neuroph? Ou la performance Java en général? Suggestions? Je suis un doctorant en psychologie cognitive, et je suis décent en tant que programmeur, mais je ne connais pas grand-chose à la programmation de performance.Aide pour le réseau de neurones Neuroph

Répondre

12

Oui, je suis allé sur cette route il y a quelques mois. Aussi pour un projet universitaire. Le premier problème est Neuroph. C'est lent mortel. Neuroph a bien connu les grands problèmes d'architecture et de performance, il y avait juste un article à ce sujet la semaine dernière sur le projet de code.

http://www.codeproject.com/KB/recipes/benchmark-neuroph-encog.aspx

J'ai suivi un chemin similaire à l'auteur de cet article. Passer de Neuroph à Encog est un véritable port facile. L'auteur de l'article ci-dessus a même un autre qui compare la syntaxe d'Encog, JOONE et Neuroph, de sorte que vous pouvez comparer cela. Pour plus d'informations sur Encog,

http://www.heatonresearch.com/encog

Encog prendra plus d'avantage de vos cœurs aussi. Il suffit de regarder le tableau dans l'article ci-dessus.

Bonne chance! Votre recherche semble vraiment géniale, j'aimerais voir les résultats.

+0

Merci pour la réponse rapide. Cela ressemble à un bon article. Et un excellent conseil sur Neuroph. – user359708

4

Regardez également votre méthode d'entraînement. Les Multicores vous aident à travailler PLUS RAPIDEMENT. Travailler plus intelligemment, c'est bien aussi. Si vous utilisez juste la rétropropagation, vous allez prendre beaucoup de temps à converger. Au minimum, utiliser quelque chose comme la propagation résiliente, je pense que cela pourrait être dans Neuroph. Ou regardez Scalable Conjugate Gradient ou Levenberg Marquardt. Encog fait les deux. Encog peut également utiliser votre GPU pour accélérer encore les choses en utilisant OpenCL.

L'accélération des itérations est bonne. Mais faire PLUS avec une itération de formation est souvent encore mieux. Et faire les deux est le meilleur de tous.

Quelle est l'indépendance de vos réseaux de neurones? Honnêtement, je suis le programmeur principal d'Encog et j'adorerais vous voir changer. MAIS, si vous êtes dans une période de temps critique et que vous avez besoin de garder Neuroph et que ces filets sont vraiment indépendants, alors vous pourriez être en mesure de générer plusieurs threads et d'avoir plusieurs boucles d'entraînement Neuroph en même temps. Sur tous vos coeurs. En supposant qu'il n'y a rien dans Neuroph qui va flipper quand il y a plusieurs exemples de leur entraîneur à la fois. Je ne connais pas suffisamment Neuroph pour dire à quel point c'est ré-entrant.

Aussi je suis d'accord, votre recherche semble vraiment intéressante.

3

Est-ce que vous vous entraînez à partir de l'interface graphique ou du code Java et quelle version de Neuroph utilisez-vous? Si vous utilisez l'interface graphique, prenez la dernière version mise à jour 2.4u1 (il suffit de la télécharger). De même, quel algorithme d'entraînement utilisez-vous et quels sont les paramètres? Vous pouvez essayer la DynamicBackpropagation. Votre projet semble très intéressant et je suis vraiment désolé que vous ayez des problèmes avec Neuroph. Nous n'étions pas au courant que les performances de Neuroph sont si faibles comparées à d'autres, avant ces benchmarks, et nous allons certainement l'améliorer à l'avenir.

Comme Jeff suggéré (merci Jeff) si vos réseaux sont indépendants que vous pourriez faire quelque chose comme ceci:

for(int index = 0; index < numberThreads ; index++) {  
    MultiLayerPerceptron mlp = new MultiLayerPerceptron(inputSize, hiddenLayerSize,outputSize);  
    SupervisedLearning learningRule = (SupervisedLearning)mlp.getLearningRule(); 
    learningRule.setMaxError(maxError); 
    learningRule.setMaxIterations(maxIterations); // make sure we can end. 
    learningRule.addObserver(this); // user observer to tell when individual networks are done and launch new networks. 
    this.mlpVector.add(mlp); 
    mlp.learnInNewThread(trainingSet); 
} 

En outre, depuis que vous avez tant de paramètres d'apprentissage du réseau peuvent être critiques pour que vous puissiez utiliser le Neuroph trainer à déterminer les bons paramètres. Ce n'est pas encore fini, mais fondamentalement, il génère toutes les combinaisons possibles de paramètres d'entraînement et essaie un par un. J'espère que cela vous aidera, même si vous avez d'autres questions ou si vous avez besoin d'aide pour quelque chose, n'hésitez pas à demander.

-1

Peut-être trop tard, mais j'utilise aussi Neuroph. Je crée jusqu'à 100-milliers de réseaux pendant la nuit avec mon processeur SSD et mon processeur 4 Core. Lorsque vous utilisez Java 8, vous pouvez faire du multithreading sans grandes compétences de codeur. Jetez un oeil aux nouveaux "Executors" de Java 8. Je l'utilise dans ma classe. Jetez un oeil à l'objet "MONKEY". Et s'il vous plaît ne me dérange pas le mauvais style de codage. Je devais être rapide ici ...

package de.sauer.dispe; 

import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.time.Instant; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

import org.neuroph.core.NeuralNetwork; 
import org.neuroph.core.data.DataSet; 
import org.neuroph.nnet.MultiLayerPerceptron; 
import org.neuroph.nnet.learning.BackPropagation; 
import org.neuroph.util.TransferFunctionType; 

import de.sauer.dispe.model.Director; 
import de.sauer.dispe.model.Specialist; 

@SuppressWarnings("rawtypes") 
public class DirBreeder_old { 

    private static final int MAX_ITER = 40; 
    public static final double GG_EPS = 0.49; 
    private static final double[] ERROR_RANGE = {0.02, 0.05, 0.47}; 
    private static final double[] LEARNING_RANGE = {0.1, 0.1, 0.3}; 
    private static final int[] LAYER_RANGE = {25, 5, 50}; 

    private static final TransferFunctionType[] TF_TYPES = { 
      TransferFunctionType.GAUSSIAN, 
      TransferFunctionType.LOG 
     }; 

    private static final String DIRECTOR_FOLDER = SpecAnalyser.SPEC_PATH+"\\director\\"; 
    private static final String OUTPUT_SUMMARY_FILE = DIRECTOR_FOLDER+"\\summary.csv"; 
    private static final String DATASET_FILE = TeamBuilder.TEAM_PATH+"\\1918_train.csv"; 
    private static ExecutorService MONKEY; 

    public static void main(String[] args) throws IOException { 
     doStuff(); 
    } 

    public static void doStuff() throws IOException { 
     System.out.println("Starting at: "+Instant.now()); 
     int counter = 0; 

     MONKEY = Executors.newFixedThreadPool(4); 
     FileWriter output = new FileWriter(new File(OUTPUT_SUMMARY_FILE), true); 

     DataSet ds = DataSet.createFromFile(DATASET_FILE, 11, 1, ";"); 

     for(int firstLayer=LAYER_RANGE[0];firstLayer<=LAYER_RANGE[2];firstLayer+=LAYER_RANGE[1]) { 
      for(int secondLayer=LAYER_RANGE[0];secondLayer<=LAYER_RANGE[2];secondLayer+=LAYER_RANGE[1]) { 
       for(int thirdLayer=LAYER_RANGE[0];thirdLayer<=LAYER_RANGE[2];thirdLayer+=LAYER_RANGE[1]) { 
        for(int forthLayer=LAYER_RANGE[0];forthLayer<=LAYER_RANGE[2];forthLayer+=LAYER_RANGE[1]) { 
         for(double maxError=ERROR_RANGE[0];maxError<=ERROR_RANGE[2];maxError+=ERROR_RANGE[1]) { 
          for(double learnRate=LEARNING_RANGE[0];learnRate<=LEARNING_RANGE[2];learnRate+=LEARNING_RANGE[1]) { 
           for(TransferFunctionType tft: TF_TYPES) { 

            Specialist trainee = new Director(
              buildAnn(tft, firstLayer, secondLayer, thirdLayer, forthLayer), 
              tft, 
              maxError, 
              ds, 
              MAX_ITER, 
              GG_EPS, 
              learnRate); 

            MONKEY.execute(new Trainer(trainee, output, counter++)); 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
     System.out.println("Building "+counter); 
     MONKEY.shutdown(); 
     try { 
      MONKEY.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     output.flush(); 
     output.close(); 
    } 

    @SuppressWarnings("unchecked") 
    private static NeuralNetwork<BackPropagation> buildAnn(TransferFunctionType tft, int layer1, int layer2, int layer3, int layer4) { 
     NeuralNetwork nn = new MultiLayerPerceptron(tft, 11, layer1, layer2, layer3, layer4, 1); 
     nn.randomizeWeights(); 
     return nn; 
    } 

} 
+0

Que signifiait "les nouveaux exécutants de java8"? Executors sont avec nous depuis java 1.5 – rkosegi

+0

@rkosegi: Bien sûr. Vous auriez pu le construire avec java 1 (puisqu'il supportait le threading). Mais Java 8 a fait un bon pas en avant. Découvrez les nouveautés dans java.util.concurrent et le traitement de flux parallèle. C'est beaucoup plus pratique que dans le passé :) – Sauer

+0

Dans votre réponse, il n'y a pas de code spécifique à Java-8, mais en même temps vous avez affirmé que 'Executors of Java 8'. Encore une fois, ce n'est pas vrai, Executors vient en Java 1.5.And btw, je suis assez familier avec l'API de flux. – rkosegi