Реализация всех популярных архитектур CNN.

В глубоком обучении сверточная нейронная сеть (CNN) - это класс глубоких нейронных сетей, которые чаще всего применяются для анализа визуальных образов. Сверточные нейронные сети - это современные модели для классификации изображений, сегментации, обнаружения объектов и многих других задач обработки изображений. Чтобы начать работу в области обработки изображений или повысить точность прогнозирования пользовательских моделей CNN, знание некоторых из известных архитектур CNN поможет нам достичь темпа в этом конкурентном и ненасытном мире. Итак, в этом посте я расскажу о нескольких известных архитектурах CNN. Я в основном подчеркиваю, как реализовать их в Keras в целом, то есть создавать собственные модели с идеологией и структурой этих архитектур.

В этом посте я расскажу о следующих архитектурах:

  • VGG Net
  • ResNet
  • Плотная сеть
  • Начальная сеть
  • Xception Net

VGG Net (группа визуальной геометрии)

VGG Net - это простая и понятная архитектура CNN среди всего прочего. Хотя это выглядит простым, он превосходит многие сложные архитектуры. Это 1-е место, занявшее второе место в конкурсе ImageNet Challenge в 2014 году. Как показано выше, всего существует 6 архитектур VGGNet. Среди них популярны ВГГ-16 и ВГГ-19.

Идея архитектур VGG довольно проста. мы должны складывать сверточные слои с увеличивающимся размером фильтра. то есть, если уровень 1 имеет 16 фильтров, то уровень 2 должен иметь 16 или более фильтров.

Еще один заслуживающий внимания момент заключается в том, что в каждой архитектуре VGG все фильтры имеют размер 3 * 3. Идея здесь в том, что два фильтра 3 * 3 почти покрывают площадь того, что покрывает фильтр 5 * 5, а также два фильтра 3 * 3 дешевле, чем один фильтр 5 * 5 (дешевле в смысле общего количества умножений. будет выполнено).

Давайте создадим пользовательскую сеть VGG с 6 сверточными слоями в Keras.

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

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

Однако VGG Nets удобны для передачи обучения и небольших задач классификации.

ResNet (остаточная сеть)

Остаточные сети являются первыми более глубокими сетями, которые будут выиграны на конкурсе ImageNet Challenge. ResNet, используемая в ImageNet в 2015 году, имеет 152 уровня. А до тех пор идея обучения таким более глубоким сетям - мечта. ResNet, однако, добился коэффициента ошибок 3,57% (топ-5 ошибок).

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

Есть много вариантов ResNets. Основная идея заключается в том, что давайте рассмотрим x как результат некоторого уровня Conv2D. Добавьте несколько слоев Conv2D к x, а затем добавьте результат к x и отправьте его как ввод на следующий слой.

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

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

Вышеупомянутая функция принимает следующие аргументы:

x : input to the res_layer.
filters : number of filters in each convolutional layer.
pooling : whether to add a pooling layer (default is False).
dropout : whether to add a dropout layer (default is No).

И процесс состоит в том, что он соединяет входной уровень со слоем Conv2D с фильтрами, указанными в нашем вызове функции, а затем присоединяет слой BatchNormalization, на который добавляется слой активации ReLU, а затем складывается другой слой Conv2D. Теперь этот сложенный вывод добавляется к начальному вводу, но начальный ввод преобразуется, пропуская его через слой Conv2D заданных фильтров. Этот шаг выполняется для соответствия выходным размерам обоих добавляемых слоев. Затем, если мы предпочитаем иметь слой MaxPooling2D, мы добавляем его, а также, если задано какое-либо значение Dropout, затем также добавляется слой Dropout, а затем, наконец, добавляются еще один слой BatchNormalization и слой активации, а затем этот последний слой возвращается нашим res_layer функция.

Теперь, когда мы создали наш res_layer, давайте создадим собственный реснет.

Приведенный выше код создает простую модель ResNet. Функция res_layer используется для упрощения процесса объединения нескольких слоев и их многократного добавления, что делает наш код удобочитаемым и управляемым.

Преимущество ResNet в том, что с этой архитектурой мы можем обучать более глубокие сети.

DenseNet

В ResNet мы добавили сложенный слой вместе с его входным слоем. В DenseNet для данного слоя все остальные предшествующие ему слои объединяются и передаются в качестве входных данных для текущего слоя. С такой компоновкой мы можем использовать меньшее количество фильтров, а также это минимизирует проблему исчезающего градиента, поскольку все слои напрямую подключены к выходу, градиенты могут быть рассчитаны непосредственно из выходных данных для каждого слоя.

Подобно функции res_layer, давайте разработаем функцию для density_layer.

Inputs
x : input layer.
layer_configs: a list of dictionaries, where each dictionary is of the below format.
Inside the layer_configs, the dictionaries have the following keys:
"layer_type" : which type of layer we are going to create. Currently only Conv2D layer is supported by the above dense_layer function.
"filters" : determining number of filters in that layer. An integer is given as value.
"kernel_size" : size of the kernel. A tuple of kernel size is given as value. like (3, 3).
"strides" : step size of stride. An integer is given as value.
"padding" : type of padding to be applied to the layer.
"activation" : type of activation to be applied to the layer.

Теперь, когда мы определили нашу функцию, давайте создадим несколько пользовательских конфигураций layer_configs.

Теперь давайте создадим собственный DenseNet.

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

Начальная сеть

Начало означает идти глубже. В ResNet мы создали более глубокие сети. Идея Inception Net - сделать сеть шире. Это можно сделать путем параллельного соединения нескольких слоев, имеющих разные фильтры, а затем, наконец, объединения всех этих параллельных путей для перехода к следующим уровням.

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

Inputs
x : input layer.
layer_configs : a list of lists, where each list have dictionaries.

Давайте посмотрим на демонстрационный список layer_configs, чтобы получить представление.

The keys in the dictionaries are:
"layer_type" : which type of layer we are going to create. Currently only Conv2D layer is supported by the above dense_layer function.
"filters" : determining number of filters in that layer. An integer is given as value.
"kernel_size" : size of the kernel. A tuple of kernel size is given as value. like (3, 3).
"strides" : step size of stride. An integer is given as value.
"padding" : type of padding to be applied to the layer.
"activation" : type of activation to be applied to the layer.

Теперь, когда мы создали функцию inception_layer, давайте создадим настраиваемую Inception Net. Layer_configs для разных слоев в этом примере можно найти в этой сути.

Наконец, давайте создадим собственную начальную сеть.

Есть много вариантов начальных сетей. Различия между ними заключаются в следующем:

  • Вместо использования фильтра 5 * 5 используйте два фильтра 3 * 3, поскольку они вычислительно эффективны (как обсуждается в VGGNet).
  • Использование слоя Conv2D 1 * 1 с меньшим количеством фильтров перед выполнением любого слоя Conv2D с большими размерами фильтров в качестве фильтра 1 * 1 с меньшим количеством фильтров уменьшит глубину ввода и, следовательно, будет эффективным с вычислительной точки зрения.
  • Вместо использования фильтра 3 * 3 выполните фильтр 1 * 3, а затем фильтр 3 * 1. Это резко повысит вычислительную эффективность.

Используя нашу функцию inception_layer, мы можем настроить все вышеперечисленные типы архитектур InceptionNet, написав соответствующие Layer_configs.

InceptionNets предпочтительнее, поскольку они не только глубже, но и шире, и мы можем складывать много таких слоев, и все же выходные параметры для обучения меньше по сравнению со всеми другими архитектурами.

Xception Net

Xception Net - это импровизация InceptionNet с точки зрения вычислительной эффективности. Xception означает экстремальное начало. Архитектура Xception, представленная на изображении выше, больше похожа на ResNet, чем на InceptionNet. Xception Net превосходит Inception Net v3.

Разница между Inception Net и Xception Net заключается в том, что в Inception Net выполняются обычные сверточные операции, тогда как в Xception Net выполняются сверточные операции с разделением по глубине. Свертки с разделением по глубине отличаются от обычных сверток тем, что в обычном слое Conv2D для ввода изображения (32, 32, 3) мы можем использовать любое количество фильтров в слое Conv. Каждый из этих фильтров будет работать по всем трем каналам, а на выходе будет сумма всех соответствующих значений. Но в свертках с разделением по глубине каждый канал имеет только одно ядро ​​для свертки. Следовательно, выполняя свертки с разделением по глубине, мы можем снизить вычислительную сложность, поскольку каждое ядро ​​имеет только двумерное измерение и свертывает только по одному каналу. В Keras мы можем реализовать это, используя слой DepthwiseConv2D.

Давайте создадим простую архитектуру Xception Net.

Выше представлена ​​более простая реализация архитектуры Xception Net. Мы можем использовать XceptionNet в устройствах с низким энергопотреблением, так как на уровне Conv меньше вычислений, а также точность очень похожа по сравнению с обычным слоем свертки.

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

Например, возьмем MobileNet. Он выполняет разделимые по глубине свертки, а не обычные свертки. Это делает его более подходящим для использования в устройствах с низким энергопотреблением и для моделей с более быстрым откликом.

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

В этом мне помогли следующие статьи и статьи:

Начальная сеть https://arxiv.org/pdf/1409.4842v1.pdf

Плотная сеть https://arxiv.org/pdf/1608.06993v3.pdf, https://towardsdatascience.com/densenet-2810936aeebb

Xception Net http://zpascal.net/cvpr2017/Chollet_Xception_Deep_Learning_CVPR_2017_paper.pdf