Помощь с нейронной нейронной сетью

Для моего исследования выпускников я создаю нейронную сеть, которая тренируется, чтобы распознавать изображения. Я собираюсь сделать намного сложнее, чем просто взять сетку значений RGB, понизить дискретизацию и отправить их на вход в сеть, как это делают многие примеры. Я на самом деле использую более 100 независимо обученных нейронных сетей, которые обнаруживают такие функции, как линии, шаблоны затенения и т.д. Гораздо больше, чем человеческий глаз, и он работает очень хорошо до сих пор! Проблема в том, что у меня довольно много учебных данных. Я показываю более 100 примеров того, как выглядит автомобиль. Затем 100 примеров того, как выглядит человек. Тогда более 100 из того, что выглядит собака, и т.д. Это довольно немного учебных данных! В настоящее время я работаю около недели для обучения сети. Это своего рода убийство моего прогресса, поскольку мне нужно настроить и переквалифицироваться.

Я использую Neuroph, как низкоуровневый API нейронной сети. Я запускаю двухъядерный процессор (16 ядер с гиперпотоком), поэтому это должно быть быстро. Мой процент процессора составляет всего 5%. Есть ли какие-то трюки в исполнении Нейрофа? Или производительность Java в целом? Предложения? Я докторант когнитивного психолога, и я порядочный, как программист, но не очень разбираюсь в программировании производительности.

Ответ 1

Да, я пошел по этой дороге несколько месяцев назад. Также для университетского проекта. Первая проблема - нейроф. Его смертельно медленно. Neuroph хорошо знает основные архитектурные проблемы и проблемы с производительностью, на прошлой неделе была опубликована статья о проекте кода.

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

Я пошел по тому же пути, что и автор этой статьи. Переключение с Neuroph на Encog - настоящий легкий порт. У автора вышеуказанной статьи есть еще один, который сравнивает синтаксис Encog, JOONE и Neuroph, поэтому вы можете сравнить это. Для получения дополнительной информации об Encog,

http://www.heatonresearch.com/encog

Encog будет использовать больше преимуществ ваших ядер. Посмотрите на диаграмму в приведенной выше статье.

Удачи! Ваше исследование звучит потрясающе, я бы хотел увидеть результаты.

Ответ 2

Также посмотрите на свой метод обучения. Multicores помогают вам работать FASTER. Умная работа тоже хороша. Если вы просто используете backpropagation, вы собираетесь долгое время сходиться. Как минимум, используйте что-то вроде упругого распространения, я думаю, что это может быть в нейрофе. Или посмотрите на Scaled Conjugate Gradient или Levenberg Marquardt. Encog делает оба из них. Encog также может использовать ваш GPU для еще большей скорости работы с помощью OpenCL.

Ускорение итераций - это хорошо. Но делать БОЛЬШЕ с учебной итерацией часто даже лучше. И делать БОЛЬШЕ лучше всего.

Насколько независимы ваши нейронные сети? Честно говоря, я главный программист Encog, и мне бы хотелось, чтобы вы переключились. НО, если вы находитесь под временным хрустом и должны остаться Neuroph, и эти сети действительно независимы, тогда вы сможете создавать несколько потоков и иметь несколько тренировочных циклов Neuroph сразу. По всем вашим ядрам. Предполагая, что в нейрофе нет ничего, что может случиться, когда сразу появляется несколько примеров их тренера. Я не знаю Neuroph достаточно хорошо, чтобы сказать, как это происходит.

Также я согласен, ваше исследование звучит очень интересно.

Ответ 3

Вы тренируетесь из графического интерфейса или Java-кода и какую версию Neuroph используете? Если вы используете графический интерфейс, используйте последнюю обновленную версию 2.4u1 (просто загрузив ее), она имеет некоторые улучшения в производительности. Также какой алгоритм обучения вы используете и какие настройки? Вы можете попробовать DynamicBackpropagation. Ваш проект звучит очень интересно, и мне очень жаль, что у вас проблемы с нейрофом. Мы не знали, что производительность Neuroph настолько низка по сравнению с другими, до этих тестов, и в будущем мы это улучшим.

Как и Джефф (спасибо Джеффу), если ваши сети независимы, вы можете сделать что-то вроде этого:

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

Кроме того, поскольку у вас так много параметров сетевого обучения, это может быть критическим, поэтому вы можете использовать тренер Neuroph, чтобы определить правильные настройки. Он еще не закончен, но в основном он генерирует все возможные комбинации настроек обучения и пытается поодиночке. Надеюсь, это поможет вам, также если у вас есть дополнительные вопросы или вам нужна помощь, чтобы что-то не стесняйтесь спрашивать.

Ответ 4

Если вы ищете небольшую (< 50kb) реализацию нейронной сети на Java, вы можете также взглянуть на Nen Beta - Я не знаю, как это сравнивается с Neuroph или Encog, но сравнение производительности и скорости против LibSVM выглядит довольно многообещающе.

Ответ 5

Возможно, слишком поздно, но я тоже использую Neuroph. Я создаю до 100 тысяч сетей за ночь с моим SSD и 4-ядерным процессором. Когда вы используете Java 8, вы можете выполнять многопоточность без больших навыков кодера. Просто взгляните на новых "Исполнителей" Java 8. Я использую его в своем классе. Посмотрите на объект "MONKEY". И, пожалуйста, не против плохого стиля кодирования. Мне нужно было быстро здесь...

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

}