Хабрахабр

Введение в свёрточные нейронные сети (Convolutional Neural Networks)

Полный курс на русском языке можно найти по этой ссылке.

Оригинальный курс на английском доступен по этой ссылке.


Выход новых лекций запланирован каждые 2-3 дня.

Интервью с Себастьяном

— Итак, мы снова с Себастьяном в третьей части этого курса. Себастьян, я знаю, что вы проводили много разработок с использованием свёрточных нейронных сетей. Можете нам рассказать чуточку больше об этих сетях и что они собой представляют? Я уверена, что студенты нашего курса будут слушать с не меньшим интересом, потому что в этой части им предстоит разрабатывать свёрточную нейронную сеть самим.
— Отлично! Итак, свёрточные нейронные сети это великолепный способ структурирования в сети, построения так называемой инвариантности (выделения неизменяемых признаков). Например, возьмём идею распознавания образов на сцене или фотографии, вы хотите понять изображён ли Себастьян на ней или нет. Не важно в какой части фотографии я располагаюсь, где располагается моя голова — по центру фотографии или в углу. Распознавание моей головы, моего лица должно происходить вне зависимости от того, где они расположены на изображении. Это и есть инвариантность, вариативность местоположения, которая реализуется свёрточными нейронными сетями.
— Очень интересно! Можете назвать нам основные задачи в которых применяются свёрточные нейронные сети?
— Свёрточные нейронные сети достаточно плотно используются при работе с аудио и видео, включая медицинские изображения. Так же они используются в языковых технологиях, где специалисты используют глубокое обучение для понимания и воспроизведения языковых конструкций. На самом деле применений у этой технологии очень много, я бы даже сказал, что они безграничны! Её, технологию, можно использовать в финансах и любых других областях.
— Я использовала свёрточные нейронные сети для анализа снимков со спутников.
— Здорово! Стандартная задача!
— Как вы думаете, можем ли мы считать свёрточные нейронные сети чем-то последним и самым продвинутым инструментом в развитии глубокого обучения?
— Ха! Я уже научился никогда не говорить «никогда». Всегда будет находиться нечто новое и потрясающее!
— Значит нам ещё предстоит поработать? 🙂
— Работы будет достаточно!
— Превосходно! В этом курсе мы как раз обучаем будущих пионеров машинного обучения. Есть ли у вас пожелания нашим студентам, перед тем как они начнут строить свою первую свёрточную нейронную сеть?
— Вот вам интересный факт. Свёрточные нейронные сети были изобретены в 1989 году, а это очень давно! Большинство из вас даже не родились ещё в то время, а это означает, что не гениальность алгоритма имеет огромное значение, а данные, которыми оперирует этот алгоритм. Мы живём в мире, где предостаточно данных для анализа и поиска закономерностей. У нас есть возможность эмулировать функции человеческого разума используя это огромное количество данных. Когда вы будете работать над свёрточными нейронными сетями, попробуйте сфокусироваться на поиске правильных данных и их применении — посмотрите, что из этого получится и, порой, это может оказаться настоящей магией, как было в нашем случае, когда мы решали задачу определения рака кожи.
— Великолепно! Ну, что, давайте наконец-то займёмся магией!

Введение

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

И это в несколько строк кода (не учитывая код построения графиков и изображений)! Результаты, которых мы добились в процессе работы над нейронной сетью, были впечатляющими — 88% точность классификации.

model = tf.keras.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28, 1)), tf.keras.layers.Dense(128, activation=tf.nn.relu), tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

NUM_EXAMPLES = 60000
train_dataset = train_dataset.repeat().shuffle(NUM_EXAMPLES).batch(32)
test_dataset = test_dataset.batch(32)

model.fit(train_dataset, epochs=5, steps_per_epoch=math.ceil(num_train_examples/32))

test_loss, test_accuracy = model.evaluate(test_dataset, steps=math.ceil(num_test_examples/32))
print('Точность: ', test_accuracy)

Точность: 0.8782

Мы так же экспериментировали с влиянием количества нейронов в скрытых слоях и количества обучающих итераций на точность модели. Но как нам сделать эту модель ещё лучше и точнее? Один из способов этого добиться — использовать свёрточные нейронные сети, сокращённо СНС. СНС показывают большую точность при решении задач классификации изображений, нежели стандартные полносвязные нейронные сети с которыми мы сталкивались на предыдущих занятиях. Именно по этой причине СНС стали такими популярными и именно благодаря им стал возможен технологический прорыв в области машинного зрения.

Мы будем использовать тот же набор данных Fashion MNIST, который использовали на предыдущем занятии. На этом занятии мы узнаем, насколько легко разработать СНС-классификатор с нуля используя TensorFlow и Keras. В конце этого занятия мы сравним точность классификации элементов одежды предыдущей нейронной сети со свёрточной нейронной сетью из этого занятия.

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

Две основные концепции в свёрточных нейронных сетях:

  • свёртка
  • операция подвыборки (pooling, max pooling)

Давайте рассмотрим их подробнее.

Свёртка

В этой части нашего занятия мы изучим технику, которая называется свёрткой. Давайте посмотрим, как же она работает.

Возьмём изображение в оттенках серого и, для примера, представим, что его размеры 6 px в высоту и 6 px в ширину.

Так как наше изображение в оттенках серого, то значение каждого пикселя будет находиться в интервале от 0 до 255. Наш компьютер интерпретирует изображение как двумерный массив пикселей. 0 — черный, 255 — белый.

На изображении ниже мы видим представление изображения 6px x 6px и соответствующие значения пикселей:

Однако в данном примере, для удобства пояснений, сохраним значения пикселей изображения и не будет их нормализовать. Как вы уже знаете, перед работой с изображениями значения пикселей необходимо нормализовать — привести значения к интервалу от 0 до 1.

Пример можно увидеть на изображении ниже — матрица размером 3 х 3: Суть свёртки заключается в создании другого набора значений, который называется ядром или фильтром.

Размеры нашего изображения 6х6px, а ядра — 3x3px. Затем мы можем просканировать наше изображение с использованием ядра. Свёрточный слой применяется к ядру и каждому участку входного изображения.

Давайте представим себе, что мы хотим выполнить свёртку над пикселем со значением 25 (3 строка, 3 столбец) и первым делом, что необходимо сделать — центрировать ядро над этим пикселем:

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

Теперь берём значения пикселей изображения и ядра, умножаем каждый пиксель изображения с соответствующим пикселем ядра и складываем все значения произведений, а результатирующее значение пикселя присваиваем новому изображению.

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

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

Теперь, когда произведено выравнивание нулевыми значениями пикселей, мы можем вычислить значение итогового пикселя в свёрнутом изображении как и прежде.

Свёртка — это процесс применения ядра (фильтра) к каждому участку входного изображения, по аналогии с полносвязным слоем (dense-слоем) мы увидим, что и свёртка представляет собой такой же слой в Keras.

Теперь давайте рассмотрим вторую концепцию свёрточных нейронных сетей — операцию подвыборки (pooling, max-pooling).

Операция подвыборки (pooling, max-pooling)

Сейчас мы рассмотрим вторую фундаментальную концепцию лежащую в основе свёрточных нейронных сетей — операцию подвыборки (pooling, max-pooling). Простыми словами, операция подвыборки это процесс сжатия (уменьшения размеров) изображения путём сложения значений блоков пикселей. Давайте рассмотрим как это работает на конкретном примере.

В этом примере мы будем использовать прямоугольную сетку размером 3х3 и шагом 3. Чтобы выполнить операцию подвыборку нам необходимо определиться с двумя составляющими этого процесса — размером выборки (размером прямоугольной сетки) и величиной шага. Шаг определяет количество пикселей на которые необходимо сдвигать прямоугольную сетку при выполнении операции подвыборки.

В пример выше в сетку попадают значения 1, 0, 4, 8, 2, 5, 20, 13, 25. После того как мы определились с размером сетки и размером шага нам необходимо найти максимальное значение пикселя попадающее в выделенную сетку. Это значение «переносится» в новое изображение. Максимальное значение — 25. Сетка сдвигается на 3 пикселя вправо и процесс выборки максимального значения и его переноса на новое изображение повторяется.

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

Давайте посмотрим как это будет работать в Python!

Резюме

Мы познакомились с такими понятиями как свёртка и операция подвыборки (max-pooling).

Операция подвыборки по максимальному значению — процесс уменьшения размеров изображения через объединение группы пикселей в единое максимальное значение из этой группы. Свёртка — процесс применения фильтра («ядра») к изображению.

Этот слой подобен Dense-слою, и содержит веса и смещения, которые подвергаются оптимизации (подбору). Как мы увидим в практической части, свёрточный слой может быть добавлен к нейронной сети с использованием Conv2D-слоя в Keras. Итак, в Conv2D-слое значения внутри матрицы фильтра и есть переменные, которые подвергаются оптимизации. Conv2D-слой так же содержит фильтры («ядра»), значения которых тоже оптимизируются.

Некоторые термины с которыми мы успели столкнуться:

  • СНС — свёрточные нейронные сети. Нейронная сеть, которая содержит хотя бы один свёрточный слой. Типичная СНС содержит и другие слои, такие как слои выборки и полносвязные слои.
  • Свёртка — процесс применения фильтра («ядра») к изображению.
  • Фильтр (ядро) — матрица, по размерам меньше, чем входные данные, предназначенная для преобразования входных данных блоками.
  • Выравнивание — процесс добавления, чаще всего нулевых значений, по краям изображения.
  • Операция подвыборки — процесс уменьшения размера изображения через сэмплирование. Существует несколько типов слоёв подвыборки, например, слой усредненной подвыборки (выборка среднего значения), однако подвыборка по максимальному значению используется чаще всего.
  • Подвыборка по максимальному значению — процесс подвыборки, в ходе которого множество значений преобразовываются в единое значение — максимальное среди выборки.
  • Шаг — количество пикселей смещения фильтром (ядром) на изображении.
  • Сэмплирование (downsampling) — процесс уменьшения размера изображения.

CoLab: классификация элементов одежды Fashion MNIST с использованием свёрточной нейронной сети

Нас обвели вокруг пальца! Данную практическую часть есть смысл выполнять только после выполнения предыдущей части — весь код, кроме одного блока, остаётся прежним. Меняется структура нашей нейронной сети, а это — четыре дополнительные строки для свёрточных нейронных слоёв и слоёв подвыборки по максимальному значению (max-pooling).

model = tf.keras.Sequential([ tf.keras.layers.Conv2D(32, (3,3), padding='same', activation=tf.nn.relu, input_shape=(28, 28, 1)), tf.keras.layers.MaxPooling2D((2, 2), strides=2), tf.keras.layers.Conv2D(64, (3,3), padding='same', activation=tf.nn.relu), tf.keras.layers.MaxPooling2D((2, 2), strides=2), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation=tf.nn.relu), tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

Все детальные пояснения, как это работать, нам обещают дать в следующей части — 4 части.

Точность модели на этапе обучения стала равна 97% (модель «переобучилась» при epochs=10), а при прогонке по набору данных для тестов показала точно 91%. Ах, да. Заметный прирост точности относительно предыдущей архитектуры, где у нас были использованы только полносвязаные слои — 88%.

Итоги

В этой части занятия мы изучили новый тип нейронных сетей — свёрточные нейронные сети. Познакомились с такими терминами как «свёртка» и «операция подвыборки по максимальному значению» (max-pooling), разработали и обучили свёрточную нейронную сеть с нуля. В результе мы увидели, что наша свёрточная нейронная сеть выдаёт точность больше, чем нейронная сеть, которую мы разрабатывали на прошлом занятии.

S. P. Примечание от автора перевод.

Курс называется «Введение в глубокое обучение с использованием TensorFlow», поэтому сетовать на то, что нет детализированных пояснений по принципу работы свёрточных нейронных сетей (слоёв) мы не будем — следующие две статьи будут как раз о принципе работы свёрточной нейронной сети и их внутренней структуре (статьи не касаются курса, а были рекомендованы участниками StackOverflow для лучшего понимания происходящего).

… и стандартные call-to-action — подписывайся, ставь плюс и делай share 🙂
YouTube
Telegram
ВКонтакте

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть