DeepLearning4j — конфигурация нейронной сети

В последние несколько дней я начал работать с библиотекой deeplearning4j и столкнулся с проблемой.

Мои тестовые и входные данные состоят из 25 двоичных значений. Учебный набор содержит 40 строк. Сеть имеет 4 выходных значения. Моя цель — научить сеть иметь как можно меньше ошибок.

Я пробовал разные конфигурации (в том числе те, которые были представлены в примерах deeplearning4j), но все равно не могу настроить свою сеть на удовлетворительный уровень точности. Более того, классификация действительно странная - например, выходные значения сети имеют вид [0,31, 0,12, 0,24, 0,33].

На мой взгляд, правильные значения должны быть такими, как [0, 0, 0, 1] и т. д.

Моя конфигурация нейронной сети:

private static final int SEED = 123;
private static final int ITERATIONS = 1;
private static final int NUMBER_OF_INPUT_NODES = 25; 
private static final int NUMBER_OF_OUTPUT_NODES = 4; 
private static final int EPOCHS = 10;

public static MultiLayerNetwork getNeuralNetwork() {
    StatsStorage storage = configureUI();
    MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(SEED).iterations(ITERATIONS).learningRate(1e-1)
            .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
            .weightInit(WeightInit.RELU).updater(Updater.ADADELTA).list()
            .layer(0, new DenseLayer.Builder().nIn(NUMBER_OF_INPUT_NODES).nOut(60)
                    .activation(Activation.RELU).build())
            .layer(1, new DenseLayer.Builder().nIn(60).nOut(50)
                    .activation(Activation.RELU).build())
            .layer(2, new DenseLayer.Builder().nIn(50).nOut(50)
                    .activation(Activation.RELU).build())
            .layer(3, new OutputLayer.Builder(LossFunctions.LossFunction.MCXENT).nIn(50).nOut(NUMBER_OF_OUTPUT_NODES)
                    .activation(Activation.SOFTMAX).build()).backprop(true).build();

    MultiLayerNetwork network = new MultiLayerNetwork(conf);
    network.init();
    network.setListeners(new StatsListener(storage), new ScoreIterationListener(1));
    DataSetIterator iterator = new ListDataSetIterator(createTrainingSet());
    for (int i = 0; i < EPOCHS; i++) {
        network.fit(iterator);
    }
    return network;
}

Буду очень признателен за любую помощь. С уважением,


person Thomas Clancy    schedule 20.03.2018    source источник
comment
не стесняйтесь присоединиться к сообществу поддержки разработчиков для DL4J на Gitter: gitter.im/deeplearning4j/deeplearning4j   -  person racknuf    schedule 23.03.2018


Ответы (1)


Способ 1:

Кажется, это ожидаемое поведение для активации SOFTMAX. Это из ссылки PredictGenderTest:

INDArray predicted = model.output(features);
//System.out.println("output : " + predicted);
if (predicted.getDouble(0) > predicted.getDouble(1))
   gender.setText("Female");
else if (predicted.getDouble(0) < predicted.getDouble(1))
   gender.setText("Male");

Если вы хотите оценить модель, может быть проще использовать этот шаблон:

Evaluation eval = new Evaluation(numOutputs);
while(testIter.hasNext()){
   DataSet t = testIter.next();
   INDArray features = t.getFeatureMatrix();
   INDArray labels = t.getLabels();
   INDArray predicted = network.output(features, false);
   eval.eval(labels, predicted);
}
System.out.println(eval.stats());

Тогда вы получите удобочитаемый результат

Метод 2:

Я нашел другой способ добиться этого, который в некоторых случаях может быть более желательным.

  1. Установите имена меток для ваших данных:

    DataSet verifyData = iterator.next(); List<String> labelNames = new ArrayList<>(); labelNames.add("Label 1"); labelNames.add("Label 2"); verifyData.setLabelNames(labelNames);

  2. Вместо model.output используйте прогнозирование:

ArrayList<String> labels = (ArrayList<String>) model.predict(verifyData);

person reden    schedule 21.03.2018