Пользовательская сеть Neuroph API настроена неправильно (выходы 0)

#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. Теперь моя сеть работает как шарм!