Время прочтения: 4 мин.

CNN или сверточная нейронная сеть (convolutional neural network) — одна из широко используемых архитектур искусственных нейронных сетей, основной задачей которой является эффективное распознавание образов.

Главная идея архитектуры CNN заключается в чередовании сверточных слоев и слоев подвыборки. Данные нейронные сети зачастую проектируются многослойными (входят в состав технологий глубокого обучения) и однонаправленными (не имеют обратных связей). В основе данной архитектуры лежит операция двумерной свертки (2D convolution), которая, в целом, является довольно простой.

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

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

Существует две основные техники проведения свертки: Padding и Striding.

Padding – техника, используемая для устранения эффекта «потери пикселей».

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

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

Эти основы свертки помогут нам при проектировании архитектуры CNN.

Реализация сверточной нейронной сети

Для примера использования CNN, создадим классификатор областей изображения. В качестве исходных данных для обучения нейронной сети будем использовать аэрофотоснимки местности, содержащие в различных областях зелёные насаждения, которые необходимо выделить.

Для работы понадобится импортировать следующие библиотеки:

  • os
  • opencv
  • numpy
  • keras
  • matplotlib

Для начала обучения нейронной сети, необходимо сформировать набор данных из имеющегося набора изображений. Он представляет из себя набор изображений 50 на 50 пикселей двух классов: первый класс отвечает за зеленые насаждения на местности(лес), второй за местность без данных насаждений (дороги, асфальт и т.д.). В каждом классе находится 1130 изображений, 800 из которых используется в качестве изображений для обучения, остальные изображения — для тестирования нейронной сети.

python
def createDatasetFromCuts(img, cutSize, trainPath, testPath):
iter = 0
for i in range(0, img.shape[0]-cutSize, cutSize): # разбиение изображения на выборки
for j in range(0, img.shape[1]-cutSize, cutSize):
cut = img[i:i+cutSize, j:j+cutSize]
if(iter<= 800): # разбиение на обучающую выборку
plt.imsave(trainPath + str(iter) + ".jpg", cut)
else: # разбиение на проверочную выборку
plt.imsave(testPath + str(iter) + ".jpg", cut)
iter+=1

Параметры модели зададим следующим образом. Используем три каскада сверточных слоев и слоев подвыборки. Первый сверточный слой Conv2D имеет 16 карт признаков и размер ядра свертки 5х5, используется 3 канала изображения RGB, на слое подвыборки из размерности выбирается максимальное значение. Для предотвращения переобучения используется слой регуляризации Dropout, который выключает нейроны с вероятностью 50%. Во втором и третьем каскаде используется меньше карт признаков – 8.

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

python
def createModel(wsize):
model = Sequential()
model.add(Conv2D(16, kernel_size=5, activation='relu', input_shape=input_shape))
model.add(MaxPooling2D()) # слой подвыборки
model.add(Conv2D(8, kernel_size=5, activation='relu')) # слой свертки
model.add(MaxPooling2D()) # слой подвыборки
model.add(Dropout(0.5)) # слой регуляризации
model.add(Conv2D(8, kernel_size=5, activation='relu')) # слой свертки
model.add(MaxPooling2D()) # слой подвыборки
model.add(Flatten()) # операция сглаживания тензора
model.add(Dense(2, activation='softmax')) # полносвязный слой
# компилируем модель
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])
model.summary()
return model

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

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

Здесь жёлтой рамкой показаны блоки, которые были классифицированы как “объекты, содержащие зелёные насаждения”.

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