В глубоком обучении сверточная нейронная сеть (CNN) представляет собой класс глубоких NN, которые обычно используются для распознавания шаблонов, присутствующих в изображениях, но они также используются для анализа пространственных данных, компьютерного зрения, обработки естественного языка, обработки сигналов и различных другие цели.
Цель этой статьи — продемонстрировать, как мы используем сверточные слои в качестве полносвязных слоев или как преобразовать полносвязные слои в слои Conv.
Я пытался найти соответствующий материал в Интернете, но смог найти только одну исследовательскую работу по этой теме, поэтому мы будем использовать ее для создания теоретической части, а затем углубимся в часть кодирования.
Основы
Прикоснуться к основам здесь быстро. Что такое слой Conv в глубоких сетях? Это не что иное, как операция свертки, которая выполняется на изображении/входе. Для такой операции требуется ядро (матрица) со значениями для перемещения по изображению (которое само преобразуется в матрицу) с заданным значением шага или шагов, выполняющих поэлементное умножение. Эта операция используется для обнаружения краев изображений или для размытия и повышения резкости изображений. Ядра в основном используются для обнаружения особенностей изображения.
Что такое полносвязный слой?
Полносвязный слой (FC) получает сглаженный вход, где каждый вход связан со всеми нейронами в нейронной сети.
Как преобразовать слой FC в слой Conv
Теоретическая часть
Теперь об основах, давайте рассмотрим теоретическую часть о том, как преобразовать полностью преобразованные слои в слои Conv. Стоит отметить, что единственная разница между слоями FC и CONV заключается в том, что нейроны в слое CONV связаны только с локальной областью на входе, и что многие нейроны в объеме CONV имеют общие параметры. Однако нейроны в обоих слоях по-прежнему вычисляют скалярные произведения, поэтому их функциональная форма идентична. Поэтому оказывается, что можно конвертировать между слоями FC и CONV.
Для любого уровня CONV существует уровень FC, который реализует ту же самую прямую функцию. Матрица весов будет большой матрицей, которая в основном равна нулю, за исключением определенных блоков (из-за локальной связи), где веса во многих блоках равны (из-за совместного использования параметров).
- И наоборот, любой слой FC можно преобразовать в слой CONV. Например, слой FC с K=4096, который просматривает некоторый входной объем размером 7×7×512, может быть эквивалентно выражен как слой CONV с F=7,P=0,S=1,K= 4096. Другими словами, мы устанавливаем размер фильтра точно равным размеру входного объема, и, следовательно, на выходе будет просто 1 × 1 × 4096, поскольку только один столбец глубины «умещается» в входной объем, что дает тот же результат, что и начальный слой FC.
FC-›CONV преобразование
Рассмотрим архитектуру ConvNet, которая берет изображение размером 224x224x3, а затем использует ряд слоев CONV и слоев POOL для уменьшения изображения до объема активаций размером 7x7x512 (это делается с использованием 5 слоев объединения, которые уменьшают дискретизацию входных данных в пространстве с помощью в два раза каждый раз, делая окончательный пространственный размер 224/2/2/2/2/2 = 7).
- Замените первый слой FC, который просматривает объем [7x7x512], на слой CONV, который использует размер фильтра F=7, что дает выходной объем [1x1x4096]. ].
- Замените второй слой FC на слой CONV, использующий размер фильтра F=1, что дает выходной объем [1x1x4096].
- Аналогичным образом замените последний слой FC на F=1, получив окончательный результат [1x1x1000].
Если изображение 224x224 дает объем размером [7x7x512] — т. е. уменьшение на 32, то пересылка изображения размером 384x384 через преобразованную архитектуру даст эквивалентный том размером [12x12x512], поскольку 384/32 = 12. следующие 3 слоя CONV, которые мы только что преобразовали из слоев FC, теперь дадут окончательный объем размера [6x6x1000], поскольку (12–7)/1 + 1 = 6. Обратите внимание, что вместо одного вектора оценок классов размером [ 1x1x1000], теперь мы получаем полный массив оценок классов 6x6 на изображении 384x384.
Вышеупомянутый метод преобразования был извлечен из Сверточных нейронных сетей (CNN / ConvNets).
Теперь мы знаем теоретическую часть, давайте посмотрим, как мы достигаем этого с помощью кода.
Часть кода
В моем проекте здесь я использую предварительно обученную сеть VGG-16 (без полносвязных слоев и инициализируя все веса с помощью обученных весов ImageNet) в качестве базовой модели, и я строю свою собственную модель поверх нее. Теперь в одной из моих моделей я хотел использовать слои Conv2D как полносвязные слои. Следуя приведенной выше теории, вот как я достиг:
cust_model = Sequential() cust_model.add(base_model) cust_model.add(Conv2D(filters=512, kernel_size=(8,8), strides=1, padding=’valid’, activation=’relu’, kernel_initializer=tf.keras.initializers.he_normal(seed=0))) cust_model.add(Conv2D(filters=256, kernel_size=(1,1), strides=(1,1), padding=’valid’, activation=’relu’, kernel_initializer=tf.keras.initializers.he_normal(seed=0))) cust_model.add(Flatten()) cust_model.add(Dense(units=16, activation=’softmax’, kernel_initializer=tf.keras.initializers.glorot_normal(seed=None)))
В приведенном выше блоке кода мой первый слой Conv2D работает как полносвязный слой. Хитрость заключается в том, чтобы сопоставить размер ядра входного слоя CONV с размером ядра выходного слоя предыдущего слоя, чтобы он действовал как полносвязный слой. В этом конкретном примере выход моей сети VGG16 был (8, 8), поэтому я использовал `kernel_size=(8,8). Выход сети VGG16 зависит от вашего входного размера изображения. Здесь мой входной размер был (256 256), поэтому после 5 операций преобразования в VGG16 размер изображения уменьшится в 32 раза. Для вас вывод может отличаться, но концепция остается той же: сопоставьте размер ядра входного слоя CONV в выходной слой предыдущего слоя
Спасибо, что прочитали!
Используемые ссылки: