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

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

После создания CNN ее можно использовать для классификации содержимого различных изображений. Все, что нам нужно сделать, это загрузить эти изображения в модель. Как и ИНС, CNN вдохновлены работой человеческого мозга. CNN могут классифицировать изображения, обнаруживая особенности, аналогично тому, как человеческий мозг обнаруживает особенности для идентификации объектов.

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

Как работают CNN?

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

1. Свертка

Свертка - это комбинированная интеграция двух функций, которая показывает, как одна функция изменяет другую.

[Функция свертки. Источник: Википедия]

В этом процессе следует упомянуть три важных элемента: входное изображение, детектор признаков и карта признаков. Входное изображение - это обнаруживаемое изображение. Детектор признаков представляет собой матрицу, обычно 3x3 (также может быть 7x7). Детектор функций также называется ядром или фильтром.

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

Однако основные характеристики изображения, которые важны для обнаружения изображения, сохраняются. Эти особенности являются уникальными для идентификации этого конкретного объекта. Например, у каждого животного есть уникальные особенности, которые позволяют нам идентифицировать его. Чтобы предотвратить потерю информации об изображении, используйте множество карт функций. Каждая карта функций определяет расположение определенных функций на изображении.

2. Нанесите ReLu (выпрямленный линейный блок).

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

3. Объединение

Пространственная инвариантность - это концепция, при которой расположение объекта на изображении не влияет на способность нейронной сети обнаруживать его специфические особенности. Объединение позволяет CNN обнаруживать особенности в различных изображениях независимо от разницы в освещении на изображениях и различных углов изображений.

Существуют разные типы пулов, например, максимальный пул и минимальный пул. Max pooling работает, помещая матрицу 2x2 на карту функций и выбирая наибольшее значение в этом поле. Матрица 2x2 перемещается слева направо по всей карте признаков, выбирая наибольшее значение на каждом проходе.

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

4. Сглаживание

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

5. Полное подключение

После выравнивания развернутая карта признаков проходит через нейронную сеть. Этот шаг состоит из входного слоя, полностью связанного слоя и выходного слоя. Полностью связанный слой похож на скрытый слой в ИНС, но в данном случае он полностью связан. Выходной слой - это то место, где мы получаем предсказанные классы. Информация передается по сети и вычисляется ошибка предсказания. Затем ошибка распространяется через систему, чтобы улучшить прогноз.

Окончательные цифры, полученные нейронной сетью, обычно не равняются единице. Однако важно, чтобы эти цифры были сокращены до чисел от нуля до единицы, которые представляют вероятность каждого класса. Это роль функции Softmax.

[Функция Softmax. Источник: Википедия]

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

Реализация с Keras с использованием бэкэнда TensorFlow

Теперь давайте напишем код, который может классифицировать изображения. Для этого упражнения рекомендуется расположить папки, содержащие изображения, как показано ниже. Мы разделяем изображения по папкам и даем им соответствующие имена, то есть обучающий набор и тестовый набор. Это упрощает импорт изображений в Керас. Убедитесь, что у рабочего каталога есть разрешения на доступ к изображениям.

1) Настройка

На этом этапе нам нужно импортировать Keras и другие пакеты, которые мы собираемся использовать при построении CNN. Импортируйте следующие пакеты:

  • Последовательный используется для инициализации нейронной сети.
  • Convolution2D используется для создания сверточной сети, которая работает с изображениями.
  • Слой MaxPooling2D используется для добавления слоев объединения.
  • Flatten - это функция, которая преобразует объединенную карту объектов в один столбец, который передается на полностью связанный слой.
  • Dense добавляет к нейронной сети полностью связанный слой.
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense

2) Инициализация нейронной сети

Для инициализации нейронной сети создаем объект класса Sequential.

classifier = Sequential()

3) Свертка

Чтобы добавить слой свертки, мы вызываем функцию add с объектом классификатора и передаем Convolution2D с параметрами. Первый аргумент nb_filter. nbfilter - это количество детекторов функций, которые мы хотим создать. Второй и третий параметры - это размеры матрицы детектора признаков.

Принято начинать с 32 детекторов функций для CNN. Следующим параметром является input_shape, который представляет собой форму входного изображения. Изображения будут преобразованы в эту форму во время предварительной обработки. Если изображение черно-белое, оно будет преобразовано в 2D-массив, а если изображение будет цветным, оно будет преобразовано в 3D-массив.

В этом случае предположим, что мы работаем с цветными изображениями. Input_shape передается в виде кортежа с количеством каналов, равным 3 для цветного изображения, и размерами 2D-массива в каждом канале. Если вы не используете графический процессор, рекомендуется использовать меньшие размеры, чтобы сократить время вычислений. При использовании процессора размер 64 на 64 работает хорошо. Последний параметр - функция активации. Классификация изображений - это нелинейная проблема. Поэтому мы используем функцию выпрямителя, чтобы гарантировать отсутствие отрицательных значений пикселей во время вычислений. Так мы добиваемся нелинейности.

classifier.add(Convolution2D(32, 3, 3, input_shape = (256, 256, 3), activation=’relu’))

4) Объединение

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

classifier.add(MaxPooling2D(pool_size=(2,2)))

5) сплющивание

На этом этапе все объединенные карты функций берутся и помещаются в один вектор. Функция Flatten объединяет все карты функций в один столбец.

classifier.add(Flatten())

6) Полное подключение

Следующим шагом будет использование вектора, который мы получили выше, в качестве входных данных для нейронной сети с помощью функции Dense в Keras. Первый параметр - output_dim - количество узлов в скрытом слое. Вы можете определить наиболее подходящее число экспериментальным путем. Чем выше количество измерений, тем больше вычислительных ресурсов вам потребуется для соответствия модели. Обычной практикой является выбор количества узлов в степени двойки. Второй параметр - функция активации. Обычно мы используем функцию активации ReLu в скрытом слое.

classifier.add(Dense(output_dim = 128, activation=’relu’))

Следующий слой, который нам нужно добавить, - это выходной слой. В этом случае мы будем использовать функцию активации sigmoid, поскольку мы ожидаем двоичного результата. Если бы мы ожидали более двух результатов, мы бы использовали функцию softmax.

output_dim здесь равен 1, поскольку мы просто ожидаем предсказанных вероятностей классов.

classifier.add(Dense(output_dim=1, activation=’sigmoid’))

7) Составление CNN

Затем мы компилируем CNN с помощью функции compile. Эта функция ожидает трех параметров: оптимизатора, функции потерь и показателей производительности. Оптимизатор - это алгоритм градиентного спуска, который мы собираемся использовать. Мы используем функцию потерь binary_crossentropy, поскольку делаем двоичную классификацию.

classifier.compile(optimizer=’adam’, loss=’binary_crossentropy’,metrics=[‘accuracy’])

8) Установка CNN

Мы собираемся предварительно обработать изображения с помощью Keras, чтобы избежать переобучения. Эта обработка называется увеличением изображения. Для этой цели мы используем утилиту Keras ImageDataGenerator.

from keras.preprocessing.image import ImageDataGenerator

Эта функция работает путем переворачивания, масштабирования, масштабирования и обрезки изображений. Первый аргумент rescale обеспечивает масштабирование изображений для получения значений пикселей от нуля до единицы. horizontal_flip=True означает, что изображения будут перевернуты по горизонтали. Все эти действия являются частью увеличения изображения.

train_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True)

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

test_datagen = ImageDataGenerator(rescale=1./255)

Следующее, что нам нужно сделать, это создать обучающий набор. Мы делаем это, используя train_datagen, который мы только что создали выше, и функцию flow_from_directory . Функция flow_from_directory позволяет нам получать изображения нашего обучающего набора из текущего рабочего каталога. Первый параметр - это путь к обучающей выборке.

Второй параметр - это target_size, который представляет собой размер изображения, которое должна ожидать CNN. Мы уже указали это выше как 256x256, поэтому мы будем использовать то же самое для этого параметра. batch_size - это количество изображений, которые пройдут по сети до обновления весов. Параметр class_mode указывает, является ли классификация двоичной или нет.

training_set = train_datagen.flow_from_directory(‘training_set’, target_size=(256, 256), batch_size=32, class_mode=’binary’)

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

test_set = test_datagen.flow_from_directory(‘test_set’, target_size=(64, 64), batch_size=32, class_mode=’binary’)

Наконец, нам нужно подогнать модель к набору обучающих данных и протестировать ее производительность с помощью набора тестов. Мы достигаем этого, вызывая функцию fit_generator для объекта классификатора. Первый аргумент, который он принимает, - это обучающий набор. Второй аргумент - это количество аргументов в нашем обучающем наборе. Epochs - количество эпох, которое мы хотим использовать для обучения CNN. Validation_data - набор тестовых данных. nb_val_samples - количество изображений в тестовом наборе.

classifier.fit_generator(training_set, steps_per_epoch=5000, epochs=25, validation_data=test_set, nb_val_samples=1000)

9) Делаем единичный прогноз

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

import numpy as np
from keras.preprocessing import image

Следующим шагом является загрузка изображения, которое мы хотели бы спрогнозировать. Для этого мы используем функцию load_img из модуля image. Первый аргумент, который принимает эта функция, - это путь к местоположению изображения, а второй аргумент - размер изображения. Размер изображения должен совпадать с размером, используемым во время тренировочного процесса.

test_image = image.load_img(‘brain_image1.jpg’, target_size=(256, 256))

Как отмечалось ранее, мы используем 3 канала, потому что наши изображения цветные и поэтому необходимо преобразовать это изображение в трехмерный массив. Для этого мы используем функцию img_to_array из модуля imagemodule.

test_image = image.img_to_array(test_image)

Теперь у нас есть изображение с тремя измерениями. Однако мы еще не готовы делать прогнозы, потому что метод predict предполагает четыре измерения. Четвертое измерение соответствует размеру партии. Это связано с тем, что в нейронных сетях данные, которые необходимо прогнозировать, обычно передаются в виде пакета. В этом случае у нас есть одна партия одного входного изображения. Мы используем метод expand_dims из numpy, чтобы добавить это новое измерение. Он принимает первый параметр в качестве тестового изображения, которое мы расширяем, а второй параметр - это положение добавляемого измерения. Метод predict ожидает, что это новое измерение будет в первой позиции, которая соответствует оси 0.

test_image = np.expand_dims(test_image, axis=0)

Теперь мы используем метод predict, чтобы предсказать, к какому классу принадлежит изображение.

prediction = classifier.predict(test_image)

После запуска этой функции мы получим результат: число от нуля до 1, указывающее вероятность того, что изображение относится к классу изображения 1. Однако мы не знаем, какое значение представляет какой класс. Чтобы выяснить это, мы используем атрибут class_indices обучающего набора.

training_set.class_indices

Предполагая, что вы выполнили эту классификацию для кошек и собак, вы получите следующий результат

Заключение

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

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



Обсудите этот пост в Hacker News.

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

Являясь независимой редакцией, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по данным и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее создавать лучшие модели машинного обучения.