Итак, вы много слышали о сверточных нейронных сетях (CNN), но вы не знаете, что это такое, как оно работает и почему сейчас об этом так много говорят. Позвольте мне объяснить как можно лучше!

свертка

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

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

Итак, что мы здесь делаем? Мы берем изображение 3x3, которое представлено как крайняя левая матрица, затем у нас есть то, что мы называем фильтром, то есть матрица с именем «Ядро» (эти имена ядро ​​и фильтр используются для ссылки на одно и то же, я буду использовать имя фильтра для остальной части этого поста), результат получается путем умножения каждого значения изображения на перекрывающееся значение в фильтре, которое равно 0x0 + 1x1 + 2x3 + 4x3 = 1 + 6 + 12 = 19, что мы есть на выходе синим цветом. Итак, мы берем верхнее левое значение в фильтре и помещаем его в верхнее левое значение на входе, мы умножаем его, поэтому мы делаем 0x0. Мы берем верхнее правое значение фильтра и умножаем его на верхнее правое значение на входе, делаем 1x1. И так далее.

Какие фильтры

Итак, вы только что узнали, что мы делаем свертку изображения с фильтром, но что такое фильтры и что они могут делать?

Мы можем выполнять различные операции, такие как применение размытия, смещение изображения и многое другое, я приведу еще несколько примеров, но важно отметить, что мы используем один и тот же фильтр 3x3 для всего изображения, потому что эти функции могут повторяться для целое изображение, нам не нужны очень большие фильтры. Давайте посмотрим на этот пример, мы хотим классифицировать изображение как геометрическую фигуру, поэтому нам нужно определить его края. Например, мы могли бы сделать что-то вроде этого:

что бы получить вертикальные ребра (слева направо), вы можете видеть в выводе, что мы получаем ребро 30 посередине. Это связано с тем, что край возникает, когда в изображении происходит большое изменение, например, при переходе от 10 к 0, большое изменение означает большой градиент, поэтому это то, что мы аппроксимируем (не очень хорошо) с помощью этого фильтра, градиент. Затем мы получаем горизонтальные края, используя другой фильтр.

Или мы могли бы также использовать фильтр для обнаружения границ, который называется фильтром Собеля.

Из чего мы можем сделать свертку каждого из этих фильтров с изображением (называя выходы Ox и Oy), где фильтр Gy аппроксимирует вертикальную производную, а фильтр Gx аппроксимирует горизонтальную производную, затем берем выходы Ox и Oy и делаем

который будет аппроксимировать комбинированную амплитуду градиента и использовать ее для создания таких углов:

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

Который работает, сортируя значения в разрезе изображения 3x3 и беря среднее значение, например:

Или даже двусторонний фильтр, который действительно может уменьшить шум сигнала или изображения или сгладить его, например:

Там, где вы можете видеть, он хорошо сохраняет края, но сглаживает их.

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

Выбор фильтров

Если парадигма проблемы хорошо известна, возможно, мы можем разработать некоторые фильтры для обработки данных по мере необходимости. Иногда это сложно, что, если бы мы могли заставить компьютер выучить необходимые фильтры для желаемой задачи, например, посмотреть на рентгеновский снимок и определить какое-то заболевание или нет (при условии отсутствия предварительных знаний о заболевании). Введите CNN! Используя CNN, мы заставим компьютер изучить необходимые фильтры, необходимые для самостоятельного обнаружения.

Сверточный слой

Вот что делают сверточные слои: они разрабатывают фильтры, которые будут «накладываться» в сети для обнаружения сложной информации. Они фиксируют пространственные и временные зависимости в изображении, применяя фильтры.

Прокладка

А как насчет угла изображения? Они появляются только один раз в свертке, как мы можем заставить их появляться чаще и иметь больший вес для других точек? Мы можем дополнить изображение!

Это решает эту проблему!

Страйд

Мы можем применить свертку к каждому пикселю, двигаясь один за другим, или мы можем делать большие шаги, известные как шаг. Допустим, мы берем шаг равный 2, поэтому каждый раз мы прыгаем на 2 пикселя:

Поговорим о размерах

Так каков размер выходов?

«Квадратные скобки» вокруг выражения означают «пол» для округления в меньшую сторону.

Итак, давайте проверим предыдущий пример: изображение 7x7, шаг = 2, размер ядра = 3 и отступ = 0.

Это дает нам: пол((7–3)/2) + 1 = 2 + 1 = 3.

Таким образом, мы получаем вывод 3x3, как и ожидалось. Таким образом, мы действительно можем использовать шаг, чтобы уменьшить размер вывода, если захотим/нужно.

Конвекция по объему

До сих пор мы видели случай изображений nxnx1, что, если наши изображения nxnx3 (изображения RGB), как тогда это работает?

Так что теперь наши фильтры вместо 3х3 должны быть 3х3х3 и будет вот так:

Итак, у нас есть фильтр 1, и мы применяем его к каждому из 3 каналов нашего входного изображения (фильтр 3x3x3, потому что это тот же фильтр, что и 3x3, но 3 раза, по одному для каждого канала ввода), затем мы суммируем его up, который сгенерирует имеющуюся у нас матрицу 4x4, помните, что выходной размер будет равен полу ((6–3)/1) + 1 = 4. Таким образом, это будет 4x4, но поскольку у нас есть 2 фильтра, наш выход будет 4x4x2, 4x4 для каждый фильтр, а затем количество фильтров.

Обычно это представлено в виде трехмерных фигур, например:

В этом примере у нас есть фильтр 5x5, и у нас их 10. В этом случае выходной размер совпадает с входным размером. Это фильтрация, называемая «такой же» фильтрацией, потому что она сохраняет те же размеры, что и входные данные, это достигается за счет использования заполнения. Фильтры, которые вы видели ранее, в которых изменяется размер, называются «действительными» фильтрами.

Объединение слоев

Conv-слои могут стать большими, содержать ненужную информацию и стать дорогостоящими в вычислительном отношении. Как мы можем получить доминирующие функции из слоя Conv и уменьшить его размер? Применяя объединение!

Существует два типа пулинга: максимальный и средний. Давайте сначала посмотрим на Max Pooling

Максимальное объединение

У нас есть изображение 4x4, и мы будем использовать слой объединения с размером 2, поэтому фильтр 2x2. Это возьмет области из 4 чисел и примет максимальное значение этих чисел, тем самым мы уменьшим размер ввода вдвое! Итак, наше изображение 4x4 становится изображением 2x2!

Средний пул

Для среднего пула у нас есть фильтр 2x2, мы берем области по 4 пикселя и усредняем их. В объединении шаг обычно является размером фильтра, но вы можете изменить его и получить другие выходные размеры, как и раньше.

Выбор слоя объединения

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

Свести слои

Это последний тип слоев в нашей CNN, и они в основном делают то, что следует из их названия, они сглаживают данные, например так:

Создание конвергентной сети

Теперь все, что нам нужно сделать, это взять эти слои и построить нашу собственную сеть!

Мы берем несколько слоев Conv и pool, сглаживаем их, а затем используем полносвязные слои, как в MLP.

Пример CNN:

Вы можете, и это обычно, использовать активации ReLu или другие, чтобы ввести нелинейность либо после слоя Conv, либо после слоя Pool.

Обычная структура конвергентной сети: Conv-›Pooling-›ReLu-›Conv-›Pooling-›Relu….-›Flatten-›Fullyconnected-›Fullyconnected.

Почему вы должны заботиться об этом?

Так почему же вы должны использовать CNN вместо MLP? Вы можете просто взять изображение, сгладить его и поместить в полностью связанные слои, так почему бы и нет?

Количество параметров в MLP может действительно быстро расти, скажем, у нас есть изображение 32x32x3, и мы используем 6 фильтров 5x5, генерируя вывод 28x28x6. 32x32x3=3072 и 28x28x6=4074. Итак, если бы мы собирались создать MLP с 3072 узлами на одном уровне и 4074 узлами на другом уровне и соединить их все, матрица весов была бы 3072x4704, что составляет около 14M. Это много параметров и всего два слоя, если бы изображения были больше, это было бы действительно невозможно. Если мы посмотрим на параметры в свёрточном слое, то каждый фильтр имеет размер 5x5, поэтому он имеет (5x5x3) параметров плюс смещение, то есть 76 параметров, так как у нас есть 6 фильтров, то есть 456 параметров. Таким образом, количество параметров действительно невелико, это это потому, что, как я упоминал ранее, фильтры учитывают то, что работает для части изображения, вероятно, также работает и для другой части, поэтому в MLP будет много избыточных параметров. Еще одна веская причина, по которой CNN сходятся быстрее и работают так хорошо, заключается в том, что в каждом слое выходные значения зависят от небольшого количества входных данных. MLP также игнорирует пространственную информацию, поскольку в качестве входных данных он принимает сглаженные векторы.

Как их использовать

CNN обычно очень требовательны к данным, поэтому нам нужны инструменты для увеличения имеющихся данных, если мы не можем получить больше данных.

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

Который состоит из изображений, подобных предыдущему. Поэтому, прежде чем мы загрузим эти изображения в нашу модель, вероятно, было бы неплохо увеличить некоторые области, сдвинуть изображение, возможно, немного повернуть его, чтобы сеть могла действительно понять очереди, необходимые для его обнаружения. Для этого мы можем использовать ImageDataGenerator из tensorflow, например:

Затем мы могли бы взять сеть, подобную следующей:

Я также сделал схему, чтобы вы могли визуализировать сеть, которую я реализовал (разбил ее на две строки для облегчения визуализации):

Эта сеть набрала 87 % при тестировании и 93 % при обучении. Небольшое переоснащение, большинство сетей также находились в этом районе 85%-88%.

Трансферное обучение

Метод, который очень распространен в области компьютерного зрения, — это трансферное обучение. Скажем, у вас есть небольшой объем данных для подготовки к задаче, хорошей идеей может быть просто использование чужой сети, удаление полностью связанных слоев и добавление своих собственных. Если у вас есть немного больше данных, вы также можете обучить некоторые слои в сети, которую вы импортировали, или всю ее. Я также использовал трансферное обучение для предыдущего набора данных и получил аналогичный результат.

Я использовал сеть VGG19. Вы можете импортировать его в тензорный поток следующим образом:

Вы можете взять сети из таких газет, как AlexNet, LeNet, Inception, ResNets или других. Я не буду вдаваться в подробности этой темы, чтобы пост не получился слишком длинным, но важно, чтобы вы знали об этом методе.

Следующие шаги

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

Первоначально опубликовано на https://joao-maria-janeiro.github.io 27 января 2021 г.