«1. Введение

В этой статье рассматривается Neuroph — библиотека с открытым исходным кодом для создания нейронных сетей и использования машинного обучения.

В этой статье мы рассмотрим основные концепции и несколько примеров того, как все это собрать.

2. Neuroph

Мы можем взаимодействовать с Neuroph, используя:

    инструмент на основе графического интерфейса пользователя библиотеку Java

Оба подхода основаны на базовой иерархии классов, которая строит искусственные нейронные сети из слоев нейронов.

Мы сосредоточимся на программной стороне, но обратимся к нескольким общим классам из подхода Neuroph на основе графического интерфейса, чтобы прояснить, что мы делаем.

Чтобы узнать больше о подходе на основе графического интерфейса, ознакомьтесь с документацией Neuroph.

2.1. Зависимости

Если вы хотите использовать Neuroph, нам нужно добавить следующую запись Maven:

<dependency>
    <groupId>org.beykery</groupId>
    <artifactId>neuroph</artifactId>
    <version>2.92</version>
</dependency>

Самую последнюю версию можно найти на Maven Central.

3. Ключевые классы и концепции

Все используемые основные концептуальные строительные блоки имеют соответствующие классы Java.

Нейроны связаны со слоями, которые затем группируются в нейронные сети. Нейронные сети впоследствии обучаются с использованием LearningRules и DataSets.

3.1. Neuron

Класс Neuron имеет четыре основных атрибута:

  1. inputConnection: weighted connections between Neurons
  2. inputFunction: specifies weights and vector sums applied to incoming connection data
  3. transferFunction: specifies weights and vector sums applied to outgoing data
  4. output: the output value resulting from the application of transferFunctions and inputFunctions to an inputConnection

Вместе эти четыре основных атрибута определяют поведение:

output = transferFunction(inputFunction(inputConnections));

3.2. Слой

Слои — это, по сути, группы нейронов, так что каждый нейрон в слое (обычно) связан только с нейронами в предыдущем и последующем слоях.

Слои, таким образом, передают информацию между собой через взвешенные функции, существующие на их Нейронах.

Нейроны можно добавлять в слои:

Layer layer = new Layer(); 
layer.addNeuron(n);

3.3. NeuralNetwork

Суперкласс верхнего уровня NeuralNetwork подразделяется на несколько знакомых видов искусственных нейронных сетей, включая сверточные нейронные сети (подкласс ConvolutionalNetwork), нейронные сети Хопфилда (подкласс Hopfield) и нейронные сети многослойного персептрона (подкласс MultilayerPerceptron).

Все нейронные сети состоят из слоев, которые обычно организованы в виде трихотомии:

  1. input layers
  2. hidden layers
  3. output layers

Если мы используем конструктор подкласса нейронной сети (например, персептрон), мы можем передать слои, количество нейронов для каждого слоя , и их индекс с помощью этого простого метода:

NeuralNetwork ann = new Perceptron(2, 4, 1);

Иногда нам нужно сделать это вручную (и хорошо видеть, что происходит под капотом). Основная операция по добавлению слоя в нейронную сеть выполняется следующим образом:

NeuralNetwork ann = new NeuralNetwork();   
Layer layer = new Layer();
ann.addLayer(0, layer);
ann.setInputNeurons(layer.getNeurons());

Первый аргумент указывает индекс слоя в нейронной сети; второй аргумент определяет сам слой. Добавленные вручную слои должны быть связаны с помощью класса ConnectionFactory:

ann.addLayer(0, inputLayer);    
ann.addLayer(1, hiddenLayerOne); 
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));

Первый и последний слои также должны быть связаны:

ConnectionFactory.fullConnect(ann.getLayerAt(0), 
  ann.getLayerAt(ann.getLayersCount() - 1), false);
ann.setOutputNeurons(ann.getLayerAt(
  ann.getLayersCount() - 1).getNeurons());

Помните, что сила и мощность нейронной сети во многом зависят от:

  1. the number of Layers in the NeuralNetwork
  2. the number of Neurons in each Layer (and the weighted functions between them), and
  3. the effectiveness of the training algorithms/accuracy of the DataSet

3.4. Обучение нашей нейронной сети

Нейронные сети обучаются с использованием классов DataSet и LearningRule.

DataSet используется для представления и предоставления информации, которую необходимо изучить или использовать для обучения нейронной сети. Наборы данных характеризуются своим входным размером, выходным размером и строками (DataSetRow).

int inputSize = 2; 
int outputSize = 1; 
DataSet ds = new DataSet(inputSize, outputSize);

DataSetRow rOne 
  = new DataSetRow(new double[] {0, 0}, new double[] {0});
ds.addRow(rOne);
DataSetRow rTwo 
  = new DataSetRow(new double[] {1, 1}, new double[] {0});
ds.addRow(rTwo);

LearningRule определяет, как нейронная сеть обучает набор данных. Подклассы LearningRule включают BackPropagation и SupervisedLearning.

NeuralNetwork ann = new NeuralNetwork();
//...
BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);

4. Соединяем все вместе

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

4.1. Слои

Мы соберем нашу нейронную сеть, объединив четыре слоя. Наша цель — построить (2, 4, 4, 1) нейронную сеть.

Давайте сначала определим наш входной слой:

Layer inputLayer = new Layer();
inputLayer.addNeuron(new Neuron());
inputLayer.addNeuron(new Neuron());

Затем мы реализуем скрытый слой один:

Layer hiddenLayerOne = new Layer();
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());

И скрытый слой два:

Layer hiddenLayerTwo = new Layer(); 
hiddenLayerTwo.addNeuron(new Neuron()); 
hiddenLayerTwo.addNeuron(new Neuron()); 
hiddenLayerTwo.addNeuron(new Neuron()); 
hiddenLayerTwo.addNeuron(new Neuron());

Наконец, мы определим наш выходной слой: ~ ~~

Layer outputLayer = new Layer();
outputLayer.addNeuron(new Neuron()); 

4.2. NeuralNetwork

Далее мы можем объединить их в NeuralNetwork:

NeuralNetwork ann = new NeuralNetwork();
ann.addLayer(0, inputLayer);
ann.addLayer(1, hiddenLayerOne);
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));
ann.addLayer(2, hiddenLayerTwo);
ConnectionFactory.fullConnect(ann.getLayerAt(1), ann.getLayerAt(2));
ann.addLayer(3, outputLayer);
ConnectionFactory.fullConnect(ann.getLayerAt(2), ann.getLayerAt(3));
ConnectionFactory.fullConnect(ann.getLayerAt(0), 
  ann.getLayerAt(ann.getLayersCount()-1), false);
ann.setInputNeurons(inputLayer.getNeurons());
ann.setOutputNeurons(outputLayer.getNeurons());

4.3. Обучение

«В целях обучения давайте соберем DataSet, указав размер как входного, так и результирующего выходного вектора:

int inputSize = 2;
int outputSize = 1;
DataSet ds = new DataSet(inputSize, outputSize);

Мы добавляем элементарную строку в наш DataSet, придерживаясь входных и выходных ограничений, определенных выше — наша цель в этом примере — научить нашу сеть выполнять базовые операции XOR (исключающее или):

DataSetRow rOne
  = new DataSetRow(new double[] {0, 1}, new double[] {1});
ds.addRow(rOne);
DataSetRow rTwo
  = new DataSetRow(new double[] {1, 1}, new double[] {0});
ds.addRow(rTwo);
DataSetRow rThree 
  = new DataSetRow(new double[] {0, 0}, new double[] {0});
ds.addRow(rThree);
DataSetRow rFour
  = new DataSetRow(new double[] {1, 0}, new double[] {1});
ds.addRow(rFour);

Далее давайте обучим нашу нейронную сеть с помощью встроенного правила обучения BackPropogation:

BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);

4.4. Тестирование

Теперь, когда наша нейронная сеть обучена, давайте проверим ее. Для каждой пары логических значений, переданных в наш DataSet как DataSetRow, мы запускаем тест следующего типа: вывести какое-то другое значение, мы должны нормализовать и денормализовать наши данные.

ann.setInput(0, 1);
ann.calculate();
double[] networkOutputOne = ann.getOutput();

В этом случае для логических операций идеально подходят 0 и 1. Результат будет таким:

Мы видим, что наша нейронная сеть успешно предсказывает правильный ответ!

Testing: 1, 0 Expected: 1.0 Result: 1.0
Testing: 0, 1 Expected: 1.0 Result: 1.0
Testing: 1, 1 Expected: 0.0 Result: 0.0
Testing: 0, 0 Expected: 0.0 Result: 0.0

5. Заключение

Мы только что рассмотрели основные концепции и классы, используемые Neuroph.

Дополнительная информация об этой библиотеке доступна здесь, а примеры кода, используемые в этой статье, можно найти на GitHub.

«