2010-06-06 16 views
10

Para mi investigación de postgrado estoy creando una red neuronal que entrena para reconocer imágenes. Voy a ir mucho más complejo que simplemente tomar una grilla de valores RGB, reducir la resolución de muestreo y enviarlos a la entrada de la red, como lo hacen muchos ejemplos. De hecho, uso más de 100 redes neuronales formadas de forma independiente que detectan características, como líneas, patrones de sombreado, etc. ¡Mucho más como el ojo humano, y hasta ahora funciona muy bien! El problema es que tengo bastante información de entrenamiento. Le muestro más de 100 ejemplos de cómo es un auto. Luego, 100 ejemplos de cómo se ve una persona. Luego más de 100 de lo que parece un perro, etc. ¡Esto es un poco de información de entrenamiento! Actualmente estoy corriendo aproximadamente una semana para entrenar la red. Esto está matando mi progreso, ya que necesito ajustarme y volver a entrenarme.Ayuda con la red neuronal Neuroph

Estoy usando Neuroph, como la API de redes neuronales de bajo nivel. Estoy ejecutando una máquina dual-quadcore (16 núcleos con hyperthreading), así que esto debería ser rápido. El porcentaje de mi procesador es solo del 5%. ¿Hay algún truco en el rendimiento de Neuroph? O el rendimiento de Java en general? Sugerencias? Soy un estudiante de doctorado en psicología cognitiva, y soy un programador decente, pero no conozco mucho acerca de la programación de rendimiento.

Respuesta

12

Sí, fui por ese camino hace unos meses. También para un proyecto universitario. El primer problema es Neuroph. Es mortalmente lento. Neuroph conoce bien los principales problemas arquitectónicos y de rendimiento, solo hubo un artículo sobre la semana pasada en el proyecto de código.

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

que siguió un camino similar como el autor de este artículo. Cambiar de Neuroph a Encog es un puerto realmente fácil. El autor del artículo anterior incluso tiene otro que compara la sintaxis de Encog, JOONE y Neuroph, por lo que puede comparar eso. Para obtener más información sobre Encog,

http://www.heatonresearch.com/encog

Encog tendrá más ventaja de sus núcleos también. Solo mira la tabla en el artículo anterior.

Buena suerte! Tu investigación suena realmente increíble, me encantaría ver los resultados.

+0

Gracias, por la respuesta rápida. Eso parece un gran artículo. Y un gran consejo sobre Neuroph. – user359708

4

También revise su método de entrenamiento. Las multihojas te ayudan a trabajar MÁS RÁPIDO. Trabajar más inteligentemente también es bueno. Si solo está utilizando la retropropagación, tardará mucho tiempo en converger. Como mínimo, utilice algo así como la propagación flexible, creo que podría ser en Neuroph. O mira Scaled Conjugate Gradient o Levenberg Marquardt. Encog hace ambas cosas. Encog también puede usar su GPU para acelerar aún más las cosas usando OpenCL.

Las iteraciones aceleradas son buenas. Pero hacer MÁS con una iteración de entrenamiento a menudo es incluso mejor. Y hacer AMBOS es lo mejor de todo.

¿Qué tan independientes son sus redes neuronales? Honestamente, soy el programador principal de Encog y me encantaría verte cambiar. PERO, si tienes un problema de tiempo y necesitas permanecer Neuroph y esas redes SON realmente independientes, entonces podrás generar múltiples hilos y tener varios ciclos de entrenamiento Neuroph al mismo tiempo. Sobre todos tus núcleos. Asumiendo que no hay nada en Neuroph que se vaya a complicar cuando hay varias instancias de su entrenador a la vez. No conozco a Neuroph lo suficiente como para decir qué tan reentrante es.

También estoy de acuerdo, su investigación suena realmente interesante.

3

¿Estás entrenando desde código GUI o Java y qué versión de Neuroph estás usando? Si está utilizando la GUI, tome la última versión actualizada 2.4u1 (recién cargada), tiene algunas mejoras de rendimiento. ¿Qué algoritmo de entrenamiento estás usando y qué ajustes? Puedes probar la DynamicBackpropagation. Su proyecto parece muy interesante y lamento mucho que tenga problemas con Neuroph. No sabíamos que el rendimiento de Neuroph es tan bajo en comparación con otros, antes de estos puntos de referencia, y lo mejoraremos con seguridad en el futuro.

Al igual que el Jeff sugirió (gracias Jeff) si sus redes son independientes se podría hacer algo como esto:

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); 
} 

Asimismo, puesto que tiene tantos parámetros de aprendizaje de la red pueden ser críticos para que pueda utilizar el Neuroph trainer a determinar la configuración correcta. Aún no está terminado, pero básicamente genera todas las combinaciones posibles de configuraciones de entrenamiento y lo prueba una a una. Espero que esto te ayude, también si tienes más preguntas o necesitas ayuda con algo siéntete libre pregunta.

-1

Quizás sea demasiado tarde, pero también uso Neuroph. Creé hasta 100-miles de redes durante la noche con mi SSD y 4 Core CPU. Cuando está utilizando Java 8, puede hacer subprocesos múltiples sin grandes habilidades de codificador. Solo eche un vistazo a los nuevos "Ejecutores" de Java 8. Lo uso en mi clase. Eche un vistazo al objeto "MONO". Y no te moleste el mal estilo de codificación. Necesitaba ser rápido aquí ...

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

¿A qué se refieren los "nuevos ejecutores de java8"? Los ejecutores están con nosotros desde java 1.5 – rkosegi

+0

@rkosegi: Claro. Podrías construirlo con java 1 (ya que admite el enhebrado). Pero Java 8 dio un buen paso adelante. Verifique cosas nuevas en java.util.concurrent y en el procesamiento en paralelo. Es mucho más conveniente que en los viejos tiempos :) – Sauer

+0

En su respuesta, no hay un código que sea específico para Java-8, pero al mismo tiempo afirmó que 'Ejecutores de Java 8'. De nuevo, esto no es cierto, los ejecutores vienen en Java 1.5. Y, por cierto, estoy bastante familiarizado con la transmisión API. – rkosegi

Cuestiones relacionadas