#java #deep-learning #neural-network #neuroph
Вопрос:
Я пытаюсь создать пользовательскую нейронную сеть Neuroph API. В конструкторе я добавил все свои слои и подключил их, но даже до того, как я его обучу, он постоянно выводит 0, независимо от того, какие входные данные.
Класс приведен ниже. Я пропустил какие-либо шаги по подготовке сети? Правильно ли я вычисляю выходные данные? Если это помогает, процесс обучения тоже ничего не делает (не изменяет вывод или ошибку), поэтому я думаю, что я просто неправильно настроил сеть.
К вашему сведению, я хотел бы избежать готовых опций, если смогу, потому что это часть исследовательского проекта, и я хотел бы иметь полную автономию в отношении характеристик сети.
Кроме того, Neuroph кажется довольно легким решением, и я не против, чтобы оно было медленным, но если у кого-нибудь есть какие-либо другие простые решения java NN, я бы с радостью принял предложения.
imports ...
public class ScoringNetwork extends NeuralNetwork<LMS> implements Serializable {
private static final long serialVersionUID = 2L;
private static final transient int seed = 123456;
private final transient Lock lock = new ReentrantLock(); // For concurrency
private final transient Random random = new Random(seed);
public ScoringNetwork() {
// create input layer
NeuronProperties inputNeuronProperties = new NeuronProperties(InputNeuron.class, Linear.class);
Layer inputLayer = LayerFactory.createLayer(8, inputNeuronProperties);
inputLayer.addNeuron(new BiasNeuron());
this.addLayer(inputLayer);
NeuronProperties hiddenNeuronProperties = new NeuronProperties(TransferFunctionType.RECTIFIED, true);
Layer hiddenLayer = LayerFactory.createLayer(50, hiddenNeuronProperties);
hiddenLayer.addNeuron(new BiasNeuron());
this.addLayer(hiddenLayer);
ConnectionFactory.fullConnect(inputLayer, hiddenLayer);
// Create output layer
NeuronProperties outputNeuronProperties = new NeuronProperties(TransferFunctionType.RECTIFIED, false);
Layer outputLayer = LayerFactory.createLayer(1, outputNeuronProperties);
this.addLayer(outputLayer);
ConnectionFactory.fullConnect(hiddenLayer, outputLayer);
NeuralNetworkFactory.setDefaultIO(this);
this.setLearningRule(new LMS());
this.getLearningRule().setLearningRate(0.1);
this.getLearningRule().setMaxError(0.1);
this.getLearningRule().setErrorFunction(new MeanSquaredError());
}
// My method to set the inputs, calculate the (single) output, then return the output
public double calculateOutputs(/* Custom Input Parameters */) {
lock.lock();
this.setInput(/* Custom Input Parameters into 8 network input parameters of type double */);
this.calculate();
double output = this.getOutput()[0];
System.out.println("output: " output);
lock.unlock();
return output;
}
}
Ответ №1:
Исправлено с помощью негерметичной функции ReLU для решения проблемы умирающего ReLU.
Подробная информация
Я обнаружил свою проблему: я везде использовал функцию ReLU, но давал отрицательные веса для половины случайных значений, что приводило к деактивации узлов повсюду. Я считаю, что если бы узлы еще не были деактивированы, они попали бы туда в течение одной итерации.
Я попытался исправить свою проблему, приведя все свои веса к положительным значениям, но обнаружил, что значение моей ошибки по-прежнему остается неизменным (после первой итерации, которая показала изменение ошибки).). Так что это был провал!
Наконец, я исправил фактическую проблему, переключившись на негерметичную функцию ReLU и вернувшись к распределению случайных весов, включая отрицательные значения. Похоже, что моя сеть стала жертвой умирающей проблемы ReLU. Теперь моя сеть работает как шарм!