Создание архитектуры MobileNet с нуля в TensorFlow

Ранее я обсуждал архитектуру MobileNet и ее наиболее важный уровень Глубоко разделяемые свертки в рассказе Понимание глубинно разделяемых сверток и эффективности мобильных сетей.

Далее мы увидим, как реализовать эту архитектуру с нуля с помощью TensorFlow.

Выполнение:

На рисунке 2 показана архитектура MobileNet, которую мы реализуем в коде. Сеть начинается с блока Vonv, BatchNorm, ReLU и следует за несколькими блоками MobileNet оттуда. Наконец, он заканчивается средним пулом и полностью связанным слоем с активацией Softmax.

Мы видим, что в архитектуре есть шаблон - Conv dw / s1, затем Conv / s1 и так далее. Здесь dw - глубинный слой с количеством шагов, за которым следует слой Conv с количеством шагов. Эти две строки представляют собой блок MobileNet.

В столбце «Форма фильтра» приводится подробная информация о размере ядра и количестве используемых фильтров. Последний номер столбца указывает количество фильтров. Мы видим, что номер фильтра постепенно увеличивается с 32 до 64, с 64 до 128, от 128 до 256 и так далее.

Последний столбец показывает, как изменяется размер изображения по мере того, как мы углубляемся в сеть. Размер ввода выбран как 224 * 224 пикселя, с 3 каналами, а выходной слой классифицирует 1000 классов.

Несколько вещей, которые следует учитывать при построении сети:

  1. Все слои сопровождаются пакетной нормализацией и нелинейностью ReLU.
  2. В отличие от обычных моделей CNN, которые имеют слой Conv2D, в MobileNet есть слои Depthwise Conv, как показано на рисунке 3. Чтобы лучше понять этот уровень, обратитесь к разделу Глубинные сверточные блоки.

Рабочий процесс:

  1. Импортируйте все необходимые слои из библиотеки TensorFlow.
  2. Написание вспомогательной функции для блока MobileNet
  3. Построение основы модели
  4. Используйте вспомогательную функцию, чтобы построить основную часть модели.

Импорт слоев

import tensorflow as tf
#import all necessary layers
from tensorflow.keras.layers import Input, DepthwiseConv2D
from tensorflow.keras.layers import Conv2D, BatchNormalization
from tensorflow.keras.layers import ReLU, AvgPool2D, Flatten, Dense
from tensorflow.keras import Model

В Keras уже есть встроенный слой DepthwiseConv, поэтому нам не нужно создавать его с нуля.

Блокировка MobileNet

Для создания функции для блока MobileNet нам потребуются следующие шаги:

  1. Вход в функцию:

а. Тензор (x)

б. количество фильтров для сверточного слоя (фильтров)

c. шаги для сверточного слоя по глубине (шаги)

2. Выполните (Рисунок 3 - изображение справа):

а. применение сверточного слоя 3x3 Dethwise с шагами, за которым следует слой пакетной нормализации и активация ReLU

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

3. Вернуть тензор (вывод)

Эти 3 шага реализованы в приведенных ниже блоках кода.

# MobileNet block
def mobilnet_block (x, filters, strides):
    
    x = DepthwiseConv2D(kernel_size = 3, strides = strides, padding = 'same')(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    
    x = Conv2D(filters = filters, kernel_size = 1, strides = 1)(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    
    return x

Построение основы модели

Как видно на рисунке 2, первый слой - это Conv / s2 с формой фильтра 3x3x3x32.

#stem of the model
input = Input(shape = (224,224,3))
x = Conv2D(filters = 32, kernel_size = 3, strides = 2, padding = 'same')(input)
x = BatchNormalization()(x)
x = ReLU()(x)

Основная часть модели

# main part of the model
x = mobilnet_block(x, filters = 64, strides = 1)
x = mobilnet_block(x, filters = 128, strides = 2)
x = mobilnet_block(x, filters = 128, strides = 1)
x = mobilnet_block(x, filters = 256, strides = 2)
x = mobilnet_block(x, filters = 256, strides = 1)
x = mobilnet_block(x, filters = 512, strides = 2)
for _ in range (5):
     x = mobilnet_block(x, filters = 512, strides = 1)
x = mobilnet_block(x, filters = 1024, strides = 2)
x = mobilnet_block(x, filters = 1024, strides = 1)
x = AvgPool2D (pool_size = 7, strides = 1, data_format='channels_first')(x)
output = Dense (units = 1000, activation = 'softmax')(x)
model = Model(inputs=input, outputs=output)
model.summary()

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

#plot the model
tf.keras.utils.plot_model(model, to_file='model.png', show_shapes=True, show_dtype=False,show_layer_names=True, rankdir='TB', expand_nested=False, dpi=96)

Полная реализация модели MobileNet с использованием TensorFlow:

import tensorflow as tf
#import all necessary layers
from tensorflow.keras.layers import Input, DepthwiseConv2D
from tensorflow.keras.layers import Conv2D, BatchNormalization
from tensorflow.keras.layers import ReLU, AvgPool2D, Flatten, Dense
from tensorflow.keras import Model
# MobileNet block
def mobilnet_block (x, filters, strides):
    
    x = DepthwiseConv2D(kernel_size = 3, strides = strides, padding = 'same')(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    
    x = Conv2D(filters = filters, kernel_size = 1, strides = 1)(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    
    return x
#stem of the model
input = Input(shape = (224,224,3))
x = Conv2D(filters = 32, kernel_size = 3, strides = 2, padding = 'same')(input)
x = BatchNormalization()(x)
x = ReLU()(x)
# main part of the model
x = mobilnet_block(x, filters = 64, strides = 1)
x = mobilnet_block(x, filters = 128, strides = 2)
x = mobilnet_block(x, filters = 128, strides = 1)
x = mobilnet_block(x, filters = 256, strides = 2)
x = mobilnet_block(x, filters = 256, strides = 1)
x = mobilnet_block(x, filters = 512, strides = 2)
for _ in range (5):
     x = mobilnet_block(x, filters = 512, strides = 1)
x = mobilnet_block(x, filters = 1024, strides = 2)
x = mobilnet_block(x, filters = 1024, strides = 1)
x = AvgPool2D (pool_size = 7, strides = 1, data_format='channels_first')(x)
output = Dense (units = 1000, activation = 'softmax')(x)
model = Model(inputs=input, outputs=output)
model.summary()
#plot the model
tf.keras.utils.plot_model(model, to_file='model.png', show_shapes=True, show_dtype=False,show_layer_names=True, rankdir='TB', expand_nested=False, dpi=96)

Вывод

MobileNet - одна из самых маленьких глубинных нейронных сетей, которые являются быстрыми и эффективными и могут работать на устройствах без высокопроизводительных графических процессоров. Реализовать эти сети очень просто при использовании такой инфраструктуры, как Keras (на TensorFlow).

Статьи по Теме

Чтобы узнать о том, как реализовать другие известные архитектуры CNN с помощью TensorFlow, перейдите по ссылкам ниже -

  1. Xception
  2. РесНет
  3. ВГГ
  4. DenseNet

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

Ховард, А.Г., Чжу, М., Чен, Б., Калениченко, Д., Ван, В., Вейанд, Т., Андреетто, М., и Адам, Х. (2017). MobileNets: эффективные сверточные нейронные сети для приложений мобильного зрения. ArXiv, abs / 1704.04861.