1. Введение
В этой статье рассматривается Neuroph — библиотека с открытым исходным кодом для создания нейронных сетей и использования машинного обучения.
В статье мы рассмотрим основные концепции и несколько примеров того, как все это собрать вместе.
2. Нейрофил
Мы можем взаимодействовать с 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
имеет четыре основных атрибута:
inputConnection:
взвешенные соединения междунейронами
inputFunction:
определяетвеса
ивекторные суммы
, применяемые к входящим данным соединения .TransferFunction:
определяетвеса
ивекторные суммы
, применяемые к исходящим данным . ``output:
выходное значение, полученное в результате примененияtransferFunctions
иinputFunctions
кinputConnection
Вместе эти четыре основных атрибута определяют поведение:
output = transferFunction(inputFunction(inputConnections));
3.2. Слой
Слои
представляют собой группы нейронов
, так что каждый нейрон
в слое
(обычно) связан только с нейронами в
предыдущем
и последующем слоях
.
Таким образом, слои
передают информацию между собой через взвешенные функции, существующие на их нейронах
.
Нейроны
можно добавлять в слои: ``
Layer layer = new Layer();
layer.addNeuron(n);
3.3. Нейронная сеть
Надкласс верхнего уровня NeuralNetwork подразделяется
на несколько знакомых видов искусственных нейронных сетей, включая сверточные нейронные сети (подкласс ConvolutionalNetwork
), нейронные сети Хопфилда (подкласс Hopfield
) и многослойные нейронные сети персептрона (подкласс MultilayerPerceptron
).
Все нейронные сети
состоят из слоев
, которые обычно организованы в виде трихотомии:
- входные слои
- скрытые слои
- выходные слои
Если мы используем конструктор подкласса NeuralNetwork
(например, Perceptron
), мы можем передать Layer
s, количество Neuron
для каждого Layer
и их индекс, используя этот простой метод:
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());
Помните, что сила и мощность нейронной сети
во многом зависят от:
- количество
слоев
внейронной сети
- количество
нейронов
в каждомслое
(ивзвешенные функции
между ними), и - эффективность алгоритмов обучения/точность
набора данных
3.4. Обучение нашей нейронной сети
Нейронные сети
обучаются с использованием классов DataSet
и LearningRule .
DataSet
используется для представления и предоставления информации, которую нужно изучить или использовать для обучения NeuralNetwork
. Наборы
данных характеризуются своим входным размером, выходным размером
и строками (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
определяет способ, которым DataSet
обучается или обучается NeuralNetwork
. Подклассы 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 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 LearningRule
:
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();
Важно помнить, что NeuralNetworks
выводит значение только на инклюзивном интервале 0 и 1 . Чтобы вывести какое-то другое значение, мы должны нормализовать
и денормализовать
наши данные.
В этом случае для логических операций идеально подходят 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 .