Помощь с нейронной нейронной сетью
Для моего исследования выпускников я создаю нейронную сеть, которая тренируется, чтобы распознавать изображения. Я собираюсь сделать намного сложнее, чем просто взять сетку значений 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;
}
}