Практические руководства

Как я построил классификатор изображений без машинного обучения

Для достижения точности 93,75% не всегда нужны продвинутые алгоритмы ML / DL.

«Это решение выглядит многообещающим, но позвольте нам вернуться к вам. Вложения на развертывание этого решения могут быть слишком высокими ».

Я был разочарован. Все мы знали, что это в конечном итоге означает.

Как мы могли не думать об этом? Мы уделяли слишком много внимания точности и производительности решения, игнорируя затраты на инфраструктуру.

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

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

Портфельный проект: классификатор изображений "день-ночь"

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

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

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

Данные этого проекта представляют собой отрывок из 400 изображений из набора данных AMOS (Архив многих уличных сцен). Они окрашены в цвета RGB и содержат по 200 дневных и ночных классов - заслуга Udacity за то, что они собрали этот проект в своей программе Computer Vision Nanodegree, которую я закончил.

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

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

Давайте начнем?

Шаг 1: Загрузите и визуализируйте данные.

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

В Python модуль glob используется для получения файлов / путей, соответствующих указанному шаблону. Используя модуль изображений matplotlib, мы можем считывать загруженные изображения в память.

Нам нужно визуализировать, чтобы лучше понимать данные. Передача соответствующего каталога в функцию выше загрузит данные, а с помощью функции imshow() matplotlib мы сможем визуализировать изображения. Хорошее понимание данных только поможет вам в дальнейшем.

# Load training data
IMAGE_LIST = load_dataset(image_dir_training)
# Select an image and its label by list index
image_index = 49
selected_image = IMAGE_LIST[image_index][0]
plt.imshow(selected_image);

  • Заметили какие-либо измеримые различия между этими изображениями? Это может помочь позже разделить классы изображений.
  • Заметили, как разные изображения имеют разный размер? Это не идеально, если вы хотите применить какую-либо обработку изображений (или глубокое обучение).

Шаг 2: Предварительная обработка данных.

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

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

Код не требует пояснений. Мы уменьшаем все изображения до стандартного размера (1100 600). Выбирать эту форму не обязательно, но какая бы форма вы ни выбрали, она должна быть неизменной на протяжении всего проекта.

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

Мы оборачиваем функции encode() и standardize_input() в функцию preprocess() и используем ее для стандартизации наших изображений. Теперь, когда мы загрузили и предварительно обработали наши изображения, мы буквально в хорошей форме для извлечения функций из изображений (интересная часть конвейера!).

Шаг 3: Извлеките функции.

Чтобы извлекать элементы из изображений, нам необходимо понимать некоторые основные свойства изображений.

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

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

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

Средняя яркость как характеристика

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

Рассмотрение изображений как числовой сетки является основой многих методов обработки изображений. Каждый пиксель изображения - это просто числовое значение, и мы также можем изменить эти значения пикселей. Эти пиксели имеют один цвет, который представлен цветовым пространством.

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

Например, другое цветовое пространство - HSV - положение для оттенка, насыщенности и значения. Эти 3 компонента различаются в зависимости от различных элементов изображения:

  • Оттенок остается неизменным в тени или даже при высокой яркости.
  • Значение больше всего меняется в зависимости от условий освещения.
  • Насыщенность описывает количество серого в определенном цвете.

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

  1. Преобразуйте изображение в цветовое пространство HSV (как мы объяснили выше, канал значений является приблизительным значением яркости)
  2. Просуммируйте все значения пикселей в канале значений.
  3. Разделите эту сумму яркости на площадь изображения, которая равна ширине, умноженной на высоту.

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

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

Шаг 4: Создайте классификатор.

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

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

Давайте реализуем эту функцию, а?

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

Наша следующая задача - настроить порог, в идеале где-то в середине 0–255. Я пробовал разные значения и проверял с помощью различных обучающих изображений, правильно ли я классифицировал изображения. В итоге я остановился на 99.

Теперь, когда мы создали классификатор, давайте посмотрим, как мы можем оценить модель?

Шаг 5: Оцените классификатор.

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

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

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

Знаете ли вы, какое окончательное значение точности я получил? Ошеломляющие 93,75%! В зависимости от ранее выбранного порогового значения это значение может колебаться, поэтому не стесняйтесь настраивать параметр и экспериментировать с ним.

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

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

Последние мысли

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

  • Загрузка и визуализация данных
  • Предварительная обработка данных
  • Извлечение функций
  • Построение классификатора
  • Оценка классификатора

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

Спасибо, что дошли до конца статьи; Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь сказать привет в LinkedIn.

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

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

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

С тех пор я ни разу не слышал от клиента «нет».

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