Рубрики
Без рубрики

Как реализовать CNN с Deeplearning4j

Узнайте, как построить и обучить сверточную модель нейронной сети с помощью библиотеки Deeplearning4j на Java.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы построим и обучим сверточную нейронную сеть модель с использованием библиотеки Deeplearning4j на Java.

Для получения дополнительной информации о том, как настроить библиотеку, пожалуйста, обратитесь к нашему руководству по Deeplearning4j .

2. Классификация изображений

2.1. Постановка задачи

Предположим, у нас есть набор изображений. Каждое изображение представляет объект определенного класса. Более того, объект на изображении принадлежит к единственному известному классу. Итак, постановка задачи состоит в том, чтобы построить модель, которая сможет распознать класс объекта на данном изображении .

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

2.2. Представление изображений

В памяти компьютера изображение может быть представлено в виде матрицы чисел. Каждое число представляет собой значение пикселя в диапазоне от 0 до 255.

Изображение в оттенках серого-это 2D-матрица. Аналогично, изображение RGB представляет собой 3D-матрицу с размерами ширины, высоты и глубины.

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

3. Сверточные Нейронные сети

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

3.1. Сверточный слой

Каждый сверточный слой представляет собой набор квадратных матриц, называемых ядрами . Прежде всего, они нужны нам для выполнения свертки на входном изображении. Их количество и размер могут варьироваться в зависимости от данного набора данных. В основном мы используем ядра размером 3×3 или 5×5 и редко 7×7. Точный размер и количество выбираются методом проб и ошибок.

Кроме того, мы случайным образом выбираем переменные матриц ядра в начале поезда. Они являются весами сети.

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

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

3.2. Слой подвыборки

Слой подвыборки (или объединения) – это слой сети, обычно используемый после сверточного. После свертки мы получаем множество вычисляемых переменных . Однако наша задача-выбрать из них наиболее ценные .

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

3.3. Плотный слой

Плотный (или полностью связанный) слой-это слой, состоящий из нескольких нейронов. Нам нужен этот слой для выполнения классификации. Более того, таких последовательных слоев может быть два или более. Важно отметить, что последний слой должен иметь размер, равный количеству классов для классификации.

Выход сети-это вероятность принадлежности изображения к каждому из классов . Чтобы предсказать вероятности, мы будем использовать функцию активации Softmax .

3.4. Методы оптимизации

Чтобы выполнить тренировку, нам нужно оптимизировать веса. Помните, что мы изначально случайным образом выбираем эти переменные. Нейронная сеть-это большая функция . И у него много неизвестных параметров, наших весов.

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

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

Мы можем увеличить или уменьшить значение веса, чтобы найти локальный минимум нашей функции потерь, потому что мы знаем наклон. Более того, этот процесс является итеративным и называется Градиентным спуском . Обратное распространение использует градиентный спуск для распространения обновления веса от конца до начала сети.

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

3.5. Показатели оценки

Наконец, после обучения сети нам нужно получить информацию о том, насколько хорошо работает наша модель.

Наиболее часто используемая метрика-точность . Это отношение правильно классифицированных изображений ко всем изображениям. Между тем, отзыв, точность и оценка F1 также очень важны метрики для классификации изображений .

4. Подготовка набора данных

В этом разделе мы подготовим изображения. Давайте использовать встроенный набор данных CIFAR10 в этом уроке. Мы создадим итераторы для доступа к изображениям:

public class CifarDatasetService implements IDataSetService {

    private CifarDataSetIterator trainIterator;
    private CifarDataSetIterator testIterator;

    public CifarDatasetService() {
         trainIterator = new CifarDataSetIterator(trainBatch, trainImagesNum, true);
         testIterator = new CifarDataSetIterator(testBatch, testImagesNum, false);
    }

    // other methods and fields declaration

}

Некоторые параметры мы можем выбрать самостоятельно. Партия поездов и тестовая партия – это количество изображений на поезд и этап оценки соответственно. Train Images Num и test Images Num – это количество изображений для обучения и тестирования. Длится одна эпоха количество изображений поезда /|/серия поездов шаги . Таким образом, наличие 2048 изображений поезда с пакетом приведет к 2048/шагам за одну эпоху.

5. Сверточная нейронная сеть в Deeplearning4j

5.1. Построение модели

Далее, давайте построим нашу модель CNN с нуля. Для этого мы будем использовать сверточные, подвыборки (объединение) и полностью связанные (плотные) слои .

MultiLayerConfiguration configuration = new NeuralNetConfiguration.Builder()
  .seed(1611)
  .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
  .learningRate(properties.getLearningRate())
  .regularization(true)
  .updater(properties.getOptimizer())
  .list()
  .layer(0, conv5x5())
  .layer(1, pooling2x2Stride2())
  .layer(2, conv3x3Stride1Padding2())
  .layer(3, pooling2x2Stride1())
  .layer(4, conv3x3Stride1Padding1())
  .layer(5, pooling2x2Stride1())
  .layer(6, dense())
  .pretrain(false)
  .backprop(true)
  .setInputType(dataSetService.inputType())
  .build();

network = new MultiLayerNetwork(configuration);

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

5.2. Обучение модели

Затем мы обучим построенную модель. Это можно сделать в нескольких строках кода:

public void train() {
    network.init();    
    IntStream.range(1, epochsNum + 1).forEach(epoch -> {
        network.fit(dataSetService.trainIterator());
    });
}

Количество эпох-это параметр, который мы можем указать сами . У нас есть небольшой набор данных. В результате будет достаточно нескольких сотен эпох.

5.3. Оценка модели

Наконец, мы можем оценить теперь обученную модель. Библиотека Deeplearning4j предоставляет возможность сделать это легко:

public Evaluation evaluate() {
   return network.evaluate(dataSetService.testIterator());
}

Оценка – это объект, который содержит вычисленные метрики после обучения модели. Это точность, точность, отзыв и оценка F1 . Кроме того, он имеет удобный интерфейс для печати:

==========================Scores=====================
# of classes: 11
Accuracy: 0,8406
Precision: 0,7303
Recall: 0,6820
F1 Score: 0,6466
=====================================================

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

В этом уроке мы узнали об архитектуре моделей CNN, методах оптимизации и метриках оценки. Кроме того, мы реализовали модель с использованием библиотеки Deeplearning4j в Java.

Как обычно, код для этого примера доступен на GitHub .