Отправьте статью сегодня! Журнал выйдет ..., печатный экземпляр отправим ...
Опубликовать статью

Молодой учёный

Анализ средств для реализации нейронных сетей на языке программирования Java

Технические науки
03.05.2017
3026
Поделиться
Аннотация
В данной статье рассматриваются основные требования к реализации нейронных сетей, описываются возможности языка Java по созданию компонентов нейронных сетей. Так же приводится анализ и сравнение уже существующих решений для данного языка и производится выбор технологий, для конкретных категорий задач.
Библиографическое описание
Крылов, А. С. Анализ средств для реализации нейронных сетей на языке программирования Java / А. С. Крылов. — Текст : непосредственный // Молодой ученый. — 2017. — № 18 (152). — С. 36-39. — URL: https://moluch.ru/archive/152/43043.


В данной статье рассматриваются основные требования к реализации нейронных сетей, описываются возможности языка Java по созданию компонентов нейронных сетей. Также приводится анализ и сравнение уже существующих решений для данного языка и производится выбор технологий для конкретных категорий задач.

Ключевые слова: нейронные сети, Java, Neuroph, Deeplearning4j

В данный момент большую популярность в задачах обработки данных получают нейронные сети. Нейронная сеть представляет собой высокопараллельную динамическую систему с топологией направленного графа, которая может получать выходную информацию путем реакции ее состояния на выходные воздействия [1]. Нейронные сети решают широкий спектр задач: классификация объектов, выявление закономерностей, распознавание образов, прогнозирование, аппроксимация, сжатие данных.

Универсальность и востребованность нейронных сетей порождает задачу их реализации на различных языках программирования с использованием различных стеков технологий, что должно позволить использовать продвинутые технологии в любой сфере от мобильных приложений до серверных. Одним из универсальных языков программирования является Java. На данном языке возможно создавать как ПО для использования в крупных промышленных системах (Java EE), так и приложения для платформы Android.

Для реализации нейронной сети на любом языке программирования требуются несколько составляющих:

‒ непосредственное описание объектов нейронной сети, таких как нейрон, связь, слой, входы и выходы сети;

‒ представление в конструкциях языка архитектуры сети: связи между слоями, их количество и тип;

‒ программные функции, реализующие алгоритмы обучения сети, которые могут позволить задать количество эпох обучения, установить целевую погрешность;

‒ сохранение и загрузка параметров обученной сети.

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

Java является объектно-ориентированным языком. В данном случае каждый элемент нейронной сети может быть отображен в свой класс [2]. В случае кодирования всех узлов без использования библиотек необходимо создать класс для каждого из них. Далее описываются основные узлы, которые необходимо реализовать.

Нейрон — вычислительная единица, которая получает информацию, передает ее дальше и производит над ней простые вычисления. Нейроны можно поделить на три группы: входные, скрытые и выходные [3]. В рамках языка Java возможно организовать абстрактный класс, который описывает нейрон, его входы и выходы, а затем создать наследников, которые будут выполнять роли входных, скрытых и выходных нейронов.

Синапс — связь между нейронами. Синапс описывается всего одним параметром — весом. Данные веса используются при передаче сигнала между нейронами. Логику синапса можно внести в класс нейрона. Таким образом один объект будет одновременно отвечать и за передачу сигнала, и за использование весовых коэффициентов.

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

‒ линейная функция ;

‒ гиперболический тангенс ;

‒ сигмоидная функция .

Начиная с Java версии 1.8 стало возможно объявлять лямбда-функции. Функции такого вида можно передавать как аргументы другой функции, но, самое главное, они могут являться полем класса. В примере далее показывается объявление простейшей линейной функции.

Function<double, double=""> function = (x) -> x; </double,>

Подобный подход позволяет менять поведение нейрона изменяя одно поле класса. Так как количество функций активации ограничено, задачей становится создать объект-перечисление enum, который будет реализовывать каждую из функций и предоставлять к ней доступ.

Нейронные сети зачастую состоят из большого количества слоев. В данном случае достаточной абстракцией является массив или список из нейронов. После создания необходимых нейронов они группируются в такие структуры и формируют архитектуру нейронной сети.

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

Для вычисления ошибки используются различные способы:

Mean Squared Error (MSE) ;

‒ Root MSE;

‒ Arctan .

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

Обучение на различных наборах по эпохам реализуется с помощью цикла for. При этом важно учитывать порядок вложенности: нейронная сеть тренируется на полном наборе данных, и только после этого возможен переход к следующей эпохе [4].

// Верный подход

for (int i = 0; i < maxEpoch; i++) {

for (int j = 0; j < trainSetLength; j++) {

// Обучение сети

}

}

// Неверный подход

for (int i = 0; i < trainSetLength; i++) {

for (int j = 0; j < maxEpoch; j++) {

// Обучение сети

}

}

Программирование всех элементов сети самостоятельно имеет смысл, когда требуется особенное поведение, дополнительная оптимизация, в нейронной сети используется небольшое количество элементов. Подобный подход позволяет уменьшить размер итогового исполняемого файла, так как в него входят только действительно требующиеся структуры и функции, но увеличивает сроки разработки ПО. В случае ограниченности ресурсов времени целесообразно использовать библиотеки. Далее приводится описание основных возможностей Neuroph и Deeplearning4j (DL4J) — библиотек, позволяющих упростить программирование нейронных сетей.

Neuroph — легковесный фреймворк для языка Java. Он позволяет создавать сети с традиционными архитектурами:

‒ однослойная нейронная сеть (Adaline);

‒ перцептрон;

‒ многослойный перцептрон с обратным распространением;

‒ сеть Хопфилда;

‒ сеть Кохонена;

‒ cеть радиально-базисных функций.

Neuroph состоит из двух компонентов: логики нейронных сетей и графического приложения Neuroph Studio, которое позволяет конфигурировать сеть без написания кода [5]. В графическом режиме требуется выбрать тип сети, ее параметры, задать обучающую выборку. После этого становится доступным просмотр структуры получившейся сети, появляется возможность проверки качества обучения сети.

http://neuroph.sourceforge.net/images/screenshot3.png

Рис. 1. Представление графа сети в Neuroph Studio

Помимо графического интерфейса программисту предоставляется доступ к классам библиотеки. Конфигурирование сети происходит в объектно-ориентированном стиле. В следующем примере формируется тренировочный набор данных для сети, на котором тренируется сеть, представляющая собой простейший перцептрон с двумя входами и одним выходом.

// создание набора для реализации функции логического И

DataSet trainingSet = new DataSet(2, 1);

trainingSet.addRow(new DataSetRow(new double[]{0, 0}, new double[]{0}));

trainingSet.addRow(new DataSetRow(new double[]{0, 1}, new double[]{0}));

trainingSet.addRow(new DataSetRow(new double[]{1, 0}, new double[]{0}));

trainingSet.addRow(new DataSetRow(new double[]{1, 1}, new double[]{1}));

// создание НС типа перцептрон

NeuralNetwork myPerceptron = new Perceptron(2, 1);

// обучение на наборе

myPerceptron.learn(trainingSet);

// сохранение обученной сети в файл

myPerceptron.save("mySamplePerceptron.nnet");

Использование Neuroph Studio может упростить обучение теории нейронных сетей, а библиотека Neuroph позволяет легко конфигурировать требуемую архитектуру сети. Данную библиотеку можно расширять за счет добавления новых типов сетей и способов обучения.

Deeplearning4j — библиотека, реализующая глубокое обучение. Глубокое обучение — отдельный класс задач, в который входит, например, распознавание образов на изображениях. Для глубокого обучения требуется больше вычислительных ресурсов, чем для классических нейронных сетей. В отличие от Neuroph сложные вычисления в DL4J осуществляются отдельным модулем, который работает вне зависимости от JVM, что позволяет ускорить работу библиотеки. Вычисления могут также производиться на распределенных ресурсах и на графических ускорителях [6].

DL4J позволяет создавать сверточные нейронные сети, что важно при обработке изображений. Все конфигурирование производится с помощью программного кода. В следующем примере показано определение сети LeNet. LeNet — это классическая сверточная сеть, которая состоит из 5 слоев.

MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()

.layer(1, maxPool("maxpool1", new int[]{2,2}))

.layer(2, conv5x5("cnn2", 100, new int[]{5, 5}, new int[]{1, 1}, 0))

.layer(3, maxPool("maxool2", new int[]{2,2}))

.layer(4, new DenseLayer.Builder().nOut(500).build())

.layer(5, new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)

.nOut(numLabels)

.activation(Activation.SOFTMAX)

.build())

.backprop(true).pretrain(false)

.setInputType(InputType.convolutional(height, width, channels))

.build();

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

В данной статье были проанализированы три подхода к реализации нейронных сетей. Каждый из подходов имеет свои преимущества и сферы применения. Программирование с нуля хорошо ложится на объектную модель и позволяет учесть особенности конкретной сети, чтобы использовать только те элементы, которые необходимы. Neuroph представляет графический интерфейс и упрощает создание архитектуры сети, давая возможность реализовать большинство известных типов нейронных сетей. Deeplearning4j позволяет решать задачи глубокого обучения, а также оптимизирует вычисления за счет использования распределенных ресурсов. Основой для выбора подхода является задача, которую необходимо решить.

Литература:

  1. Галушкин А. И. Нейронные сети: Основы теории. — М.: Горячая Линия — Телеком, 2012. — 496 с.
  2. Васильев А. Н. Java. Объектно-ориентированное программирование. — СПб.: Питер, 2011. — 400 с.
  3. Тархов Д. А. Нейросетевые модели и алгоритмы. Справочник. — М.: Радиотехника, 2014. — 352 с.
  4. Рашитов Э. Э., Стоякова К. Л., Ибраев Р. Р. Модель математической нейронной сети // Молодой ученый. — 2017. — № 15 (149). — С. 77–80.
  5. Documentation // Java Neural Network Framework Neuroph. URL: http://neuroph.sourceforge.net/documentation.html (дата обращения: 25.04.2017).
  6. Deeplearning4j: Open-source, Distributed Deep Learning for the JVM // Deep Learning for Java. URL: https://deeplearning4j.org/ (дата обращения: 22.04.2017).
Можно быстро и просто опубликовать свою научную статью в журнале «Молодой Ученый». Сразу предоставляем препринт и справку о публикации.
Опубликовать статью
Молодой учёный №18 (152) май 2017 г.
Скачать часть журнала с этой статьей(стр. 36-39):
Часть 1 (стр. 1-107)
Расположение в файле:
стр. 1стр. 36-39стр. 107

Молодой учёный