«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 имеет четыре основных атрибута:
- inputConnection: weighted connections between Neurons
- inputFunction: specifies weights and vector sums applied to incoming connection data
- transferFunction: specifies weights and vector sums applied to outgoing data
- 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).
Все нейронные сети состоят из слоев, которые обычно организованы в виде трихотомии:
- input layers
- hidden layers
- 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());
Помните, что сила и мощность нейронной сети во многом зависят от:
- the number of Layers in the NeuralNetwork
- the number of Neurons in each Layer (and the weighted functions between them), and
- 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.
«