Сверточная нейронная сеть быстрой сегментации (Fast-SCNN) - это описанная выше модель семантической сегментации в реальном времени на данных изображения с высоким разрешением, подходящая для эффективных вычислений на встроенных устройствах с малым объемом памяти. Авторы оригинальной статьи: Рудра П.К. Пудель, Стефан Ливицки и Роберто Чиполла. Код, использованный в этой статье, не является официальной реализацией авторов, а моей попыткой воссоздать модель, как описано в статье.

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

Некоторые ключевые аспекты Fast-SCNN:

  1. Выше сегментации в реальном времени на изображениях с высоким разрешением (1024 x 2048 пикселей)
  2. Точность выхода 68% среднего пересечения по объединению
  3. Обработка ввода со скоростью 123,5 кадра в секунду на Набор данных Cityscapes
  4. Не требуется большой предварительной подготовки
  5. Сочетает пространственные детали в высоком разрешении с глубокими деталями, извлеченными при более низком разрешении.

Более того, Fast-SCNN использует популярные методы, имеющиеся в современных моделях, для обеспечения перечисленных выше характеристик, такие как Pyramid Pooling Module или PPM, используемые в PSPNet, уровни инвертированных остаточных узких мест, используемые в MobileNet V2. »И Feature Fusion Module, используемый в такой модели, как ContextNet , который использует как глубокие особенности, извлеченные из данных с более низким разрешением, так и пространственные детали из данных с более высоким разрешением, чтобы обеспечить лучшую и быструю сегментацию.

Давайте теперь начнем с исследования и реализации Fast-SCNN. Fast-SCNN построен с использованием 4 основных строительных блоков. Они есть:

  1. Учимся снижать выборку
  2. Экстрактор глобальных функций
  3. Функция Fusion
  4. Классификатор

1. Учимся снижать выборку

Пока мы знаем, что первые несколько уровней нейронной сети Deep Convolutional извлекают из изображения низкоуровневые функции, такие как края и углы. Таким образом, чтобы использовать эту функцию и сделать ее повторно используемой для дальнейших слоев, используется Learning to Down Sample. Это грубый глобальный экстрактор функций, который может использоваться повторно и совместно использоваться другими модулями в сети.

Модуль Learning to Down-sample использует 3 слоя для извлечения этих глобальных функций. Это: слой Conv2D, за которым следуют 2 сверточных слоя с разделением по глубине. Во время реализации, после каждого слоя Conv2D и Depthwise Separable Conv, используется слой Batchnorm с последующей активацией Relu, поскольку обычно это стандартная практика для введения BatchNorm и Activations после таких слоев. Здесь все 3 уровня используют шаг 2 и размер ядра 3x3.

Теперь давайте начнем с реализации этого модуля. Для начала давайте сначала установим Tensorflow 2.0. Сейчас это сделать проще, чем когда-либо. Мы можем просто использовать Google Colab и приступить к реализации. На данный момент доступна только альфа-версия Tensorflow 2.0, которую вы можете просто установить с помощью следующей команды:

!pip install tensorflow-gpu==2.0.0-alpha0

Здесь '-gpu' означает, что мой ноутбук Google Colab использует графический процессор, и в случае вашего, если вы предпочитаете не использовать его, вы можете просто удалить '-gpu', и тогда установка Tensorflow будет использовать процессор системы. .

После этого импортируем Tensorflow:

import tensorflow as tf

Теперь давайте сначала создадим входной слой для нашей модели. В Tensorflow 2.0 с использованием высокоуровневого API TF.Keras мы можем сделать это следующим образом:

Этот входной слой является нашей точкой входа в модель, которую мы собираемся построить. Здесь мы используем функциональный API Tf.Keras. Причина использования функционального API вместо последовательного заключается в том, что он обеспечивает гибкость, необходимую для построения этой конкретной модели.

Двигаясь дальше, давайте теперь определим слои для модуля Learning to Down-sample. Для этого, чтобы сделать процесс простым и повторно используемым, я создал специальную функцию, которая будет проверять, является ли слой, который я хочу добавить, слоем Conv2D или слоем с разделением по глубине, а затем проверяет, хочу ли я добавить relu в конце слой или нет. Использование этого блока кода сделало реализацию простой для понимания и повторного использования на протяжении всей реализации.

В TF.Keras сверточный слой определяется как tf.keras.layers.Conv2D, а слой с разделением по глубине - как tf.keras.layers.SeparableConv2D

Теперь давайте добавим слои для модуля, просто вызвав нашу пользовательскую функцию с соответствующими параметрами:

2. Экстрактор глобальных функций

Этот модуль был направлен на захват глобального контекста для сегментации. Он напрямую принимает выходные данные модуля Learning to Down-sample. В этом разделе вводятся различные остаточные блоки узких мест, а также вводится специальный модуль под названием Pyramid Pooling Module или PPM для агрегирования различной контекстной информации на основе региона.

Начнем с остаточного блока "Узкое место".

Выше приведено описание остаточного блока узкого места из бумаги. Как и в предыдущем случае, давайте теперь реализуем его с помощью высокоуровневого api tf.keras.

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

Этот остаточный блок узкого места добавляется в архитектуре несколько раз, количество раз, которое они добавляются, обозначено параметром ’n’ в таблице 1 выше. Итак, в соответствии с архитектурой, описанной в документе, чтобы добавить ее n раз, мы вводим другую настраиваемую функцию, которая просто сделает это.

Теперь давайте добавим эти узкие места в нашу модель.

Здесь вы заметите, что первый вход в этот блок узких мест поступает из выходных данных модуля Learning to Down-Sample.

Последний блок в этом разделе Global Feature Extractor - это Pyramid Pooling Module или, вкратце, PPM.

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

Чтобы реализовать это с помощью TF.Keras, я использовал другую настраиваемую функцию

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

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

3. Функция Fusion

В этом модуле два входа складываются вместе, чтобы лучше представить сегментацию. Первый - это функция более высокого уровня, извлеченная из модуля Learning to Down-sample, выходные данные этого Learning to Down-sample сначала точечно свертываются, а затем добавляются ко второму входу. Здесь активация не добавляется в конце точечной свертки.

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

Вот операции с более низким разрешением, реализованные с помощью TF.Keras

Теперь давайте добавим эти два входа вместе для модуля слияния функций.

4. Классификатор

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

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

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

Составление модели

Теперь, когда мы добавили все слои, давайте создадим нашу окончательную модель и скомпилируем ее. Для создания модели, как уже было сказано выше, мы используем Functional api от TF.Keras. Здесь входом в модель является начальный входной уровень, описанный в модуле Learning to Down-sample, а выходом - окончательный выходной классификатор.

Теперь давайте скомпилируем его с оптимизаторами и функциями потерь. В исходной статье авторы использовали оптимизатор SGD со значением импульса 0,9 с размером пакета 12 в процессе обучения. Они также использовали скорость поли-обучения для планирования скорости обучения с базовым значением 0,045 и мощностью 0,9. Для простоты я не использовал здесь какое-либо планирование скорости обучения, но при необходимости вы можете добавить его самостоятельно для своего конкретного тренировочного процесса. Кроме того, всегда рекомендуется начинать с оптимизатора ADAM при компиляции модели, но в этом конкретном случае с набором данных CityScapes авторы использовали только SGD. Но в общем случае всегда полезно начать с оптимизатора ADAM, а затем при необходимости перейти к другим вариантам. Для функции потерь авторы использовали потерю кросс-энтропии и поэтому использовали здесь во время реализации.

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

Вот некоторые результаты проверки Fast-SCNN в сравнении с исходным изображением и достоверностью данных.

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

Таким образом, мы можем легко реализовать Fast-SCNN, используя Tensorflow 2.0 и его высокоуровневый api TF.Keras. Ниже приведены ссылки, которые я использовал при реализации модели.

Полный код можно найти в моем репозитории GitHub:



использованная литература

  1. Ссылка на исходную статью: https://arxiv.org/abs/1902.04502
  2. Ссылка на исходный документ PSPNet: https://arxiv.org/pdf/1612.01105.pdf
  3. Ссылка на исходный документ ContextNet: https://arxiv.org/abs/1805.04554
  4. Официальный сайт CityScapes Dataset: https://www.cityscapes-dataset.com/
  5. Официальное руководство по Tensorflow 2.0: https://www.tensorflow.org/alpha
  6. Полный код для реализации: https://github.com/kshitizrimal/Fast-SCNN/blob/master/tf_2_0_fast_scnn.py
  7. Официальная реализация ContextNet.
  8. Код модуля Pyramid Pooling, вдохновленный реализацией PSPNet: https://github.com/dhkim0225/keras-image-segmentation/blob/master/model/pspnet.py
  9. Узкое место Остаточный блочный код, вдохновленный реализацией MobileNet V2: https://github.com/xiaochus/MobileNetV2/blob/master/mobilenet_v2.py