TL;DR 👉 Я построил сверточную нейронную сеть, используя Keras и Tensorflow.js, чтобы иметь возможность классифицировать качество пинты Гиннеса по изображению.
Может быть, это просто ирландская черта, но мы все знаем этих пьющих Гиннесс, тех, кто думает, что они лучше всех остальных. Те, кто гордо держит свою пинту высоко над головой, прежде чем сделать первый глоток. Те, кто проверяют каждый аспект своей пинты, когда она ставится на стойку перед ними. Я бы знал, потому что я один из этих людей.
Пинта простого пива — ваш единственный мужчина — Фланн О’Брайен
Так что я здесь делаю, говоря о пинтах? Ну, вне моей социальной жизни я работаю инженером-программистом, и я всегда был немного фанатом, когда дело доходит до машинного обучения. Однажды днем я просматривал Твиттер, когда наткнулся на твит от аккаунта под названием @beautifulpints, в котором было опубликовано это произведение искусства:
И я подумал про себя, что это красивая пинта, но что делает ее такой? Как мы можем отличить хорошую пинту пива от плохой, просто взглянув на нее? Размер головы? Купол над стеклом? Темно-черный стаут без пузырей? И могу ли я научить машину интуитивно делать то же самое? 🤨
Так что же такое машинное обучение?
Машинное обучение – это приложение искусственного интеллекта (ИИ), которое позволяет системам автоматически обучаться и совершенствоваться на основе полученного опыта без явного программирования. Другими словами, машинное обучение фокусируется на разработке компьютерных программ, которые могут получать доступ к данным и использовать их для самостоятельного обучения. Звучит круто, верно?
Чтобы разработать решение нашей проблемы с помощью машинного обучения, мы должны понять, в чем заключается наша проблема. Вот некоторые вопросы, которые мы можем себе задать:
- Какие данные у нас есть? (эта часть имеет решающее значение: Нет данных = нет машинного обучения 😢)
- Это структурированные данные? (например, база данных, csv, excel)
- Это неструктурированные данные? (т.е. пиксели изображения, аудио, видео пиксели)
- Данные помечены?
Существует множество возможных решений для каждого из вышеперечисленных вопросов, и для целей этого сообщения в блоге я не собираюсь погружаться во все их, но вот полезная диаграмма, если вы заинтересованы в рассмотрении потенциальных решений для различные наборы данных:
В этом сценарии мы попытаемся обучить нашу машину (мой MacBook) различать «хорошую пинту» и «плохую пинту». Таким образом, с точки зрения машинного обучения мы будем стремиться классифицировать наши данные по группам, и в этом конкретном сценарии мы будем обучать бинарный классификатор. Двоичный означает два возможных результата: Да/Нет – 1/ 0 – хорошо/плохо.
Кроме того, поскольку наши данные представляют собой пиксели изображения, мы будем работать с неструктурированными данными. Тысячи пикселей, которые вместе составляют изображение хорошей или плохой пинты. Чтобы решить эту проблему, мы воспользуемся сверточной нейронной сетью (CNN).
В машинном обучении CNN представляют собой сложные нейронные сети с прямой связью. Они используются для классификации и распознавания изображений из-за их исторически высокой точности. Сверточная нейронная сеть была предложена ученым-компьютерщиком Яном Лекуном в конце 90-х, когда он был вдохновлен человеческим визуальным восприятием распознавания вещей. CNN следует иерархической модели, которая работает над построением сети, как воронка, и, наконец, выдает полностью связанный слой, где все нейроны связаны друг с другом, а выходные данные обрабатываются (я знаю, там много запутанных слов). , но, к счастью, для целей этого поста нам не нужно вдаваться в подробности).
Хорошо, вернемся к забавным вещам - фотографии пинт
Чтобы работать с любым проектом машинного обучения, нам необходимо выполнить ряд шагов:
- Соберите наши данные 🤠
- Очистите и обработайте наши данные 🥸
- Обучение нашей модели 🤯
- Протестируйте нашу модель 🧐
- Разверните нашу модель 😎
Но подождите, у нас еще нет данных? Где я могу найти сотни изображений как хороших, так и плохих пинтов Гиннеса, чтобы построить модель машинного обучения для прогнозирования? И тут появляется Ян! Гордый мужчина из Корка, живущий в Лондоне, который основал сайты социальных сетей @beautifulpints и @shitlondonguiness, без которых этот проект был бы невозможен (ура, Ян!). Смотрите, как Джейми Дорнан кричит Йену здесь 👉 Ссылка
Таким образом, просмотрев эти две учетные записи Instagram, я смог получить достаточно данных, чтобы приступить к созданию моей модели машинного обучения. Я собрал около 150 изображений "хороших пинтов" и 150 изображений "дерьмовых пинтов" (в идеале вам нужны тысячи изображений, но я просто имею дело с тем, что могу получить здесь).
Получив данные (скриншоты каждой пинты), я приступил к очистке и обработке данных. Для этого я пометил каждое изображение как хорошее или плохое и разделил их на 2 папки.
В проекте машинного обучения вы хотите разделить свои данные на 3 раздела:
- Тренировочные данные (50%)
- Данные проверки (30%)
- Тестовые данные (20%)
Для этого я дополнительно разделил свои данные на папки для обучения и тестирования. Я выбрал разделение 70/20/10, так как объем данных, которые у меня были, был ограничен, и я не думал, что 50% моих данных будет достаточно для обучения.
Крайне важно, чтобы вы не проверяли и не тестировали те же данные, на которых вы обучали моделировать, поскольку вы можете получить переобученную модель, которая не будет работать в реальном мире!
Самое интересное: код 🤠
Поэтому для обучения этой модели мы будем использовать Keras, API глубокого обучения, написанный на Python, работающий поверх платформы машинного обучения TensorFlow. Он был разработан с акцентом на возможность быстрого экспериментирования.
Для начала я запустил Jupyter Notebooks и создал пустой блокнот Python 3.
Затем мы импортируем соответствующие модули, которые нам понадобятся для написания кода:
Затем мы можем работать над получением наших размеченных данных и создавать следующие объекты:
Keras ImageDataGenerator упрощает маркировку и загрузку больших наборов данных изображений. Здесь мы создаем два объекта для ImageDataGenerator, а также масштабируем изображение таким образом, чтобы значения их пикселей были нормализованы между 0 и 1, не влияя на качество изображения. Это облегчит обучение CNN 👌.
Мы также указываем целевой размер, который важен, поскольку реальные изображения могут быть разных форм и размеров, поэтому каким бы ни был размер входного изображения — мы изменим его размер до 150X150 для согласованности.
Нормализация данных – это важный шаг, который гарантирует, что каждый входной параметр (в данном случае пиксель) имеет одинаковое распределение данных. Это ускоряет сходимость при обучении сети.
Затем мы указываем размер пакета, что просто означает количество выборок, которые будут распространяться по сети в заданное время (32 — значение по умолчанию для этого поля). Мы также указываем, что наш class_mode должен быть бинарным, поскольку мы хотим, чтобы наш результат попадал в один из двух классов, т. е. 1 или 0 / Хорошая пинта или Плохая пинта.
Вы также можете проверить закодированные метки классов, выполнив следующий код:
Следующий шаг: Создание слоев CCN
У Keras есть полезный API, который упрощает определение слоев нашей нейронной сети. Здесь input_shape равен 150 150, что является размером нашего изображения, а 3 представляет собой цветовой канал RGB (если бы мы использовали изображение в оттенках серого, мы должны указать это как 1).
- Conv2D(). Нейронные сети применяют фильтр к входному изображению, чтобы создать карту объектов, которая обобщает наличие обнаруженных объектов во входных данных. В нашем случае имеется 32, 64, 128 и 128 фильтров или ядер в соответствующих слоях, а размер фильтров составляет 3X3 с использованием функции активации Relu.
- MaxPool2D(): максимальное объединение — это операция объединения, которая выбирает максимальный элемент из области карты объектов, покрываемой фильтром. Таким образом, выходными данными после слоя максимального объединения будет карта объектов, содержащая наиболее заметные объекты предыдущей карты объектов.
- Flatten(): этот метод преобразует массив данных многомерного изображения в одномерный массив.
Затем мы указываем оптимизатор и функцию потерь для нашей модели, а также метрики, которые мы хотим визуализировать во время обучения. Роль оптимизатора состоит в том, чтобы измерить, насколько хорошо наша модель предсказала результат по сравнению с истинным результатом. Если потери велики, то оптимизаторы используются для изменения атрибутов вашей нейронной сети, таких как веса и скорость обучения, чтобы уменьшить общая потеря. В TF доступно несколько оптимизаторов и функций потерь. Здесь мы используем adam и binary_crossentropy (если бы это была задача классификации нескольких классов, т. е. выявление различий между пинтами разных марок, тогда мы могли бы использовать sparse_categorical_crossentropy как функция потерь).
Обучение нашей модели 🕺:
Мы можем обучить наш режим, вызвав функцию fit_generator(), которая использует наши обучающие изображения и наши проверочные изображения в качестве входных данных для обучения и проверки соответственно. Мы также указываем эпохи и шаги в эпоху. Наиболее распространенный способ выбора шагов в эпоху:
шагов в эпоху = нет. train_images/batch_size
В нашем случае это примерно 7.
Обучение вашей модели займет некоторое время в зависимости от количества слоев и размера вашего набора данных, так что расслабьтесь и расслабьтесь! Обычно предпочтительнее использоватьграфический процессор в качестве аппаратного ускорителя для ускорения процесса обучения.
Как только ваша модель закончит обучение, вы получите такой вывод:
Мы обучили нашу модель — как мы на самом деле ее используем? 🤷♂️
Здесь мы создаем простую функцию, которая принимает имя файла изображения (вместе с его путем) в качестве входных данных, загружает его с помощью метода keras load_image (изменяя его размер, чтобы он соответствовал размеру нашего изображения с обучающими данными). Затем мы передаем это в качестве входных данных для метода i. Этот метод вернет значение либо 1, либо 0, что будет предсказанием нашей модели на входном изображении.
Посмотрим, как летает этот малыш 🚀
Посмотрите, мы успешно построили нейронную сеть 🥳
Прежде чем продолжить, убедитесь, что вы сохранили свою модель!
Итак, мы успешно построили модель Tensorflow с использованием CNN, которая может классифицировать качество пинты пива, отлично! Но на данный момент он просто сидит в блокноте Jupyter (что не так уж и интересно). Куда мы можем пойти отсюда? Я думаю, что следующим шагом будет сделать эту модель интерактивной. Как я могу создать пользовательский интерфейс, в котором я могу перетаскивать изображения пинты, и модель выдает то, что она предсказывает? Для этого мы перейдем к пользователю Tensorflow.js, а точнее, возьмем только что обученную модель Keras и преобразуем ее в модель Tensorflow.js (это так просто!)
Что такое Tensorflow.js?
TFJS — это библиотека с открытым исходным кодом, которую вы можете использовать для определения, обучения и запуска моделей машинного обучения полностью в браузере с использованием Javascript и API слоев высокого уровня. Если вы разработчик Javascript, который плохо знаком с ML, TFJS — отличный способ начать обучение!
Чтобы использовать TFJS, мы собираемся создать веб-приложение, которое позволит нам запускать нашу обученную модель машинного обучения прямо в браузере!
Когда мы преобразуем модель Keras в TFJS, у нас останется папка с «весами». Эти веса представляют собой вес каждого из слоев в нашей сверточной нейронной сети, которые составляют нашу модель.
Итак, как мы можем использовать эту модель теперь, когда она может использоваться TFJS? Что ж, я не собираюсь утомлять вас тем, как я настроил свою веб-страницу HTML/CSS, чтобы продемонстрировать это, но я покажу вам важные части!
Внизу вашей HTML-страницы вы импортируете сценарий, описанный в приведенном ниже фрагменте. Этот скрипт импортирует и инициализирует нашу модель. Это также позволяет нам запускать нашу модель с помощью функции predict() (я связал эту функцию с кнопкой HTML, чтобы сделать ее интерактивной).
Используя python для запуска локального сервера, я смог продемонстрировать следующее:
Очевидно, что над пользовательским интерфейсом нужно много работать 😂, но интерфейсы на самом деле не в моем вкусе 👀
Каковы следующие шаги?
В настоящее время все это просто находится в репозитории Github и нигде не развернуто, и в его текущем состоянии это не так уж и полезно.
Мой следующий шаг — встроить эту модель в фильтр Instagram и/или Snapchat, чтобы, когда посетители наслаждаются пинтой Гиннесса в тишине, они могли сделать снимок своей пинты на свой телефон, а фильтр предоставил вам оценку. из 10, чтобы поделиться ими в своих социальных сетях (хотя для этого мне пришлось бы изменить свой двоичный классификатор).
Заключение
В любом случае, я надеюсь, что этот пост в блоге был вполовину так же приятен для чтения, как и этот проект. Я думаю, что одно из самых больших заблуждений об ML/AI заключается в том, что вам нужна степень доктора философии по математике и статистике, чтобы работать в космосе, хотя это совсем не так! Библиотеки с открытым исходным кодом, такие как Keras и Tensorflow.js, позволяют разработчикам легко запачкать руки и построить модели машинного обучения для любого варианта использования (но помните, что для этого вам понадобятся данные!)
Еще раз спасибо за чтение, если вы зашли так далеко!
Slán! 👋