Создайте и разверните собственную модель обнаружения объектов с помощью нескольких строк кода.
Введение
В этой статье я расскажу, как с помощью нескольких строк кода любой может создать свою собственную модель машинного обучения (ML) и развернуть ее в рабочей среде.
Мы сосредоточимся на построении модели компьютерного зрения, которая позволит нам обнаруживать объекты на изображениях. Существует множество применений этой технологии:
- Управление трафиком
- Раннее выявление рака
- Наблюдение
- Автоматизация процессов
- Список продолжается…
Итак, приступим!
Требования
Для этого упражнения вам не понадобится много.
- Учетная запись Google — мы будем использовать Colab для обучения нашей модели и подключим наш Google Диск для хранения учебных материалов.
- Python 3.X установлен на вашем компьютере
- pip или anaconda установлены на вашем компьютере
- Виртуальная среда Python — необязательно (рекомендуется)
- Докер установлен на вашем компьютере — опционально (только для деплоя в продакшене)
И это все!
*Colab — я знаю, что некоторые из вас сейчас могут подумать: «Зачем нам использовать Colab или любую другую платформу для обучения нашей модели, когда мы можем сделать это на наших компьютерах?». Ну правда в том, что вам не нужно его использовать. Просто обучать вашу модель быстрее, потому что Colab предоставляет вам возможность использовать GPU вместо CPU для обучения, что в x раз быстрее.
1) Подготовьте папку проекта
Итак, первое, с чего мы собираемся начать, — это создать папку проекта и установить необходимые пакеты.
*Отказ от ответственности — я занимаюсь разработкой для Mac OS. Если вы пользователь Linux, вы обнаружите, что все команды, которые я буду выполнять, работают и в Linux.
Мои друзья Windows, я рекомендую вам использовать любое программное обеспечение командной строки, которое воспроизводит Linux-подобные команды (GIT Bash, Linux Bash и т. д.)
Теперь давайте откроем терминал и создадим папку проекта:
mkdir object-detection cd object-detection
Теперь я буду использовать виртуальную среду Python, чтобы отделить зависимости моего проекта от остальных пакетов, которые я установил на свой компьютер. Это полезный способ содержать вещи в чистоте и порядке.
virtualenv venv
Теперь мы хотим активировать нашу новую среду и начать ее использовать:
source venv/bin/activate
И вуаля, мы отсортировали папку нашего проекта.
Теперь все, что нам нужно, это установить несколько пакетов, используя pip или anaconda. В этом случае я буду использовать pip, но команда для anaconda почти идентична (вам просто нужно заменить pip на conda).
pip install detecto pip install matplotlib pip install flask pip install flask-cors
Позвольте мне объяснить, что мы устанавливаем здесь:
- Детекто — это, по сути, пакет, построенный поверх PyTorch и позволяющий нам с легкостью обучать модели компьютерного зрения.
- maptolib — это пакет для построения графиков или, в нашем случае, вывода изображений с ограничивающими прямоугольниками.
- flask — это, по сути, пакет, который позволит нам обернуть нашу модель API и предоставить ее нашим клиентам.
- flask-cors — название говорит само за себя, этот пакет предназначен исключительно для включения запросов CORS к нашим API.
И мы закончили с установкой пакетов!
2) Подготовка набора обучающих данных
Многие из вас, возможно, слышали, что ИИ невозможен без данных. Это абсолютно верно, это все равно, что пытаться научить ребенка говорить, даже не пытаясь с ним заговорить. Машина не сможет учиться без исходных данных.
В нашем случае мы будем готовить наборы изображений и добавлять к ним коробки с метками, чтобы научить машину отличать интересующие объекты от остального мира.
Есть несколько различных инструментов, которые мы можем использовать для маркировки изображений, например:
- метка
- этикетка
- Инструмент аннотирования изображений VGG
- супервизор
- Этикетка
- и т.д..
Все вышеперечисленные инструменты дают аналогичный результат в виде xml-файла с координатами прямоугольников вокруг объектов и соответствующими метками.
Я буду использовать labelimg, вы можете найти его здесь.
Сначала нам нужно получить изображения для нашего набора данных. Для этой цели я загрузил изображения груш и клубники с сайта unsplash.com. Вы можете скачать мой набор данных ниже или перейти на unsplash.com и получить свои собственные изображения.
После того, как вы запустите labelimg, вы должны увидеть такой экран.
Теперь нам нужно указать labelimg на папку, в которой хранятся изображения. Для этого нажмите «Открыть каталог» и выберите папку, в которой вы сохранили свои изображения (или изображения из моего набора данных).
Теперь пришло время пометить эти изображения!
Вы увидите список всех доступных изображений в правой нижней части экрана.
Все, что вам нужно сделать, это использовать опцию прямоугольного меню в левой части экрана и нарисовать рамку вокруг объектов, которые вы хотите распознать. Labelimg предложит вам выбрать существующие ярлыки, но в нашем случае мы создадим новый, просто введя его в поле ввода.
Это должно выглядеть примерно так:
Не забудьте сохранить каждый результат в той же папке, где хранится изображение.
Вот и все. Мы подготовили учебный материал.
3) Обучение нашей модели
Как я упоминал ранее, мы можем либо пойти дальше и обучить наш мод локально на наших компьютерах, либо мы можем использовать сервис Google Colab, который позволяет нам использовать графические процессоры бесплатно.
В моем примере я буду проводить обучение в Colab, но вы можете выполнить те же действия на своем компьютере.
Загрузка файлов на Google Диск, чтобы мы могли получить к ним доступ из Colab — пропустите этот шаг, если вы запускаете код на своем компьютере.
Я создал папку на своем Google Диске для проекта и назвал ее обнаружение объектов. Я также загрузил свой набор данных (изображения вместе с файлами меток ml) в новую папку в разделе «Обнаружение объектов/изображения».
*Обратите внимание, что если вы использовали мой набор данных, вам нужно будет скопировать все файлы из обеих папок и собрать их в одну папку (изображения).
Это должно выглядеть примерно так:
Теперь вернемся в папку обнаружения объектов и правой кнопкой мыши выберем опцию
Подробнее-› Google Colaboratory
Сначала мы хотим включить графические процессоры для нашего ноутбука Colab:
Правка -> Настройки ноутбука -> Аппаратный ускоритель и выберите GPU
Затем нам нужно подключить нашу среду Colab к нашему Google Диску.
Для этого мы подключим диск к нашему ноутбуку Colab.
from google.colab import drive drive.mount('/content/drive')
Давайте посмотрим, что мы сделали с этими двумя строками:
- импортированный пакетный диск из стандартной библиотеки colab
- и подключили наш диск Google к нашей среде
После выполнения этих строк вам будет предложено ввести защитный код для монтирования диска. Откройте предоставленную ссылку и следуйте инструкциям, чтобы получить код. Получив его, скопируйте его и вставьте в поле ввода внутри нашего блокнота colab.
Вы успешно смонтировали диск!
5 строк кода для обучения нашей модели
Итак, теперь и в Colab, и в локальной среде мы можем начать писать 5 строк кода, которые позволят нам обучить нашу модель.
Во-первых, нам нужно установить библиотеку детектирования.
Внутри блокнота Colab мы можем сделать это так
!pip install detecto
добавьте его как код и запустите.
Для тех, кто просто запускает его локально, вы можете просто сделать:
pip install detecto
Внутри вашего терминала.
Далее мы добавим строки, которые фактически будут выполнять обучение.
from detecto import core, utils, visualize dataset = core.Dataset('/content/drive/My Drive/Projects/objects-detection/images/') model = core.Model(['pear', 'strawberry']) model.fit(dataset, verbose=1, epochs=10)
Давайте посмотрим на каждую строку кода:
- Импортные модули детектора
- Создал набор данных из папки «images» (содержащей наши файлы JPEG и XML)
- Инициализирована модель для обнаружения наших пользовательских объектов (клубника и груша).
- Обучил нашу модель на наборе данных (подробный — это флаг, который позволяет нам отображать или скрывать ход обучения. Эпохи — это флаг, который позволяет нам указать, сколько раундов обучения мы хотим запустить на нашем наборе данных; по умолчанию — 10)
И это все. После запуска этого кода и ожидания некоторое время ваша модель будет обучена.
4) Тестирование нашей пользовательской модели
Теперь, когда обучение завершено, пришло время протестировать нашу модель.
image = utils.read_image('/content/drive/My Drive/Projects/objects-detection/validation/tiard-schulz-Zt3JBpD6afg-unsplash.jpg') predictions = model.predict(image) labels, boxes, scores = predictions print(labels) print(boxes) print(scores)
Давайте посмотрим на код построчно:
- Чтение изображения (замените путь к изображению на свой)
- Запуск нашей модели для поиска объектов на нашем изображении
- Извлечение меток объектов (найденных на изображении), ограничивающих рамок (расположение объектов) и оценок (вероятность предсказания)
- Печать этикеток, коробок и счетов для проверки
Вывод приведенного выше кода будет примерно таким (зависит от выбранного вами изображения):
['strawberry', 'strawberry', 'strawberry', 'strawberry', 'pear', 'pear', 'strawberry', 'pear', 'strawberry', 'pear', 'pear'] tensor([[2452.0452, 4442.3599, 3442.1204, 5482.8232], [2674.3801, 1145.6279, 3394.1516, 1775.2996], [1041.0961, 2159.0103, 1681.6707, 2878.9133], [1347.9767, 5104.0605, 2330.7642, 6038.6021], [2509.6628, 4483.7910, 3419.3689, 5410.0591], [1399.2555, 5132.0474, 2254.4937, 6039.6279], [3381.9873, 1852.3215, 4010.2600, 2570.3640], [ 468.3965, 2090.4729, 2573.8916, 3904.5371], [3676.3425, 610.6763, 4145.3604, 1329.3901], [3695.3311, 642.4642, 4156.2090, 1339.7739], [3406.6868, 1866.6627, 4016.7891, 2654.2966]]) tensor([0.5450, 0.4850, 0.4824, 0.3997, 0.1882, 0.1450, 0.1412, 0.1241, 0.1221, 0.0999, 0.0965])
Итак, как вы видите выше, у нас есть 3 выхода:
- Показывает нам все метки объектов, которые были найдены на изображении.
- Распечатывает координаты для каждого обнаруженного объекта.
- Распечатывает баллы (вероятность) того, что эти объекты будут идентифицированы правильно.
Мы также можем взглянуть на само изображение с ограничивающими рамками, выполнив эту команду:
visualize.show_labeled_image(image, boxes, labels)
Как вы можете заметить, у нас много прямоугольников на этих изображениях, потому что мы выводим все прогнозы, найденные моделью. Чтобы сделать его более удобным, нам нужно применить к нему порог. Threshold по существу будет отфильтровывать результат с низкой вероятностью.
Добавьте этот код, чтобы применить порог:
import torch import matplotlib.pyplot as plt import matplotlib.patches as patches lab = [] box = [] for i in range(len(scores)): if scores[i] > 0.3: lab.append(labels[i]) box.append(boxes[i]) box = torch.stack(box) fig,ax = plt.subplots(1) ax.imshow(image) for i in range(len(box)): ax.add_patch(patches.Rectangle((box[i][0],box[i][1]),box[i][2] - box[i][0],box[i][3] - box[i][1],linewidth=1,edgecolor='r',facecolor='none')) plt.show()
Позвольте мне объяснить в нескольких словах, что происходит в коде выше. Сначала мы импортировали пакеты для работы с графиками и изображениями. Затем мы перебираем каждую оценку (вероятность), и только те, которые выше 0,3 (30%), мы добавляем в новый список, который мы будем использовать для построения наших полей. Отфильтрованный результат будет выглядеть примерно так:
И вот оно. Ваша собственная модель компьютерного зрения, способная находить клубнику и груши на ваших изображениях.
Последнее, что нужно сделать, это сохранить модель, чтобы вы могли вернуться к ней без необходимости повторного обучения. Мы сделаем это, выполнив эту команду:
model.save('/content/drive/My Drive/Projects/objects-detection/model_weights.pth')
5) Производство нашей модели
Итак, теперь у вас есть модель, которую вы можете запустить из файла Python, заставить ее считывать изображения из локальной папки и показывать результаты. Но полезно ли это?
Большинство моделей, которые я создаю, предназначены не для чисто исследовательских целей, а для производственного использования нашими клиентами. Что это значит?
Это означает, что модель должна быть легко развертываемой и масштабируемой. Он должен иметь возможность связываться с нашими службами внутри и снаружи. Как мы этого достигаем?
В этом разделе статьи я покажу вам, как нашу модель можно легко преобразовать в микросервис API и развернуть ее в производственной среде с помощью Docker.
Для этой части я скопировал сохраненную модель (model_weights.pth) обратно на свой компьютер, так как нам не требуется никакого дополнительного тяжелого обучения.
Первое, что мы хотим сделать, это убедиться, что мы можем загрузить модель и обнаружить объекты локально.
Я написал этот код, чтобы сделать это:
import torch import matplotlib.pyplot as plt import matplotlib.patches as patches from detecto import core, utils, visualize model = core.Model.load('model_weights.pth', ['pear', 'strawberry']) image = utils.read_image('assets/validation/plush-design-studio-WMvOeO-D8xo-unsplash.jpg') predictions = model.predict(image) labels, boxes, scores = predictions lab = [] box = [] for i in range(len(scores)): if scores[i] > 0.3: lab.append(labels[i]) box.append(boxes[i]) box = torch.stack(box) fig,ax = plt.subplots(1) ax.imshow(image) for i in range(len(box)): ax.add_patch(patches.Rectangle((box[i][0],box[i][1]),box[i][2] - box[i][0],box[i][3] - box[i][1],linewidth=1,edgecolor='r',facecolor='none')) plt.show()
Этот код очень похож на тот, который мы написали для обучения модели, с той лишь разницей, что мы загружаем модель, а не обучаем ее.
Теперь нам нужно преобразовать нашу модель, чтобы она была доступна через вызов API.
Если вы не знакомы с флягой, здесь можно прочитать о том, как это работает.
Вот код после добавления оболочки фляги вокруг нашей модели:
# Importing packages from detecto import core, utils, visualize from flask import Flask, escape, request, jsonify, Response import skimage from flask_cors import CORS import numpy as np import torch import matplotlib import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas import io # Initilaising app and wrapping it in CORS to allow request from different services app = Flask(__name__) CORS(app) # Telling matplotlib to not create GUI Windows as our application is backend and doesn't require direct visulaization matplotlib.use('agg') # Loading our custom model model = core.Model.load('model_weights.pth', ['pear', 'strawberry']) # Adding new POST endpoint that will accept image and output image with bounding boxes of detected objects @app.route("/detect", methods=['POST']) def detect(): # Accessing file from request file = request.files['image'] image = skimage.io.imread(file) # Using model to detect objects predictions = model.predict(image) labels, boxes, scores = predictions # Applying threshold lab = [] box = [] for i in range(len(scores)): if scores[i] > 0.4: lab.append(labels[i]) box.append(boxes[i]) box = torch.stack(box) # Creating figure and displaying original image fig,ax = plt.subplots(1) ax.imshow(image) # Adding bounding boxes for i in range(len(box)): ax.add_patch(patches.Rectangle((box[i][0],box[i][1]),box[i][2] - box[i][0],box[i][3] - box[i][1],linewidth=1,edgecolor='r',facecolor='none')) # Preparing output output = io.BytesIO() FigureCanvas(fig).print_png(output) # Sending response as png image return Response(output.getvalue(), mimetype='image/png') if __name__ == '__main__': app.debug = True app.run(host = '0.0.0.0',port=5000, threaded=True)
Теперь, если вы попытаетесь сделать POST-запрос на свой локальный хост с портом 5000 и прикрепленным изображением в качестве данных формы, вы получите обратно изображение с обнаруженными объектами.
Теперь, когда у нас есть микросервис API с нашей моделью, мы можем подготовить его к развертыванию.
Сначала нам нужно сохранить список всех зависимостей для этого проекта в один файл.
Мы можем сделать это, выполнив эту команду внутри папки проекта:
pip freeze > requirements.txt
Лучший способ выполнить развертывание — встроить свой код в образ докера. Это позволит вам легко развернуть вашу модель как в локальной среде, так и в облаке.
Здесь вы можете найти больше информации о Docker.
В той же папке, что и наша кодовая база, давайте создадим новый файл и назовем его «Dockerfile».
внутри этого файла напишите следующий код:
FROM jjanzic/docker-python3-opencv ADD . /app WORKDIR /app RUN pip install -r requirements.txt EXPOSE 5000 CMD [ "python", "./detect.py" ]
Давайте посмотрим, что происходит внутри этого кода:
- Мы используем образ Ubuntu с предустановленным python и opencv в качестве базового образа.
- Мы скопировали наш код в Docker Image
- Мы установили все зависимости проекта
- Мы открыли порт для прослушивания (5000)
- И, наконец, мы запускаем наш Python API в фоновом режиме.
Теперь давайте создадим наш образ Docker:
docker build -t object-detection .
Где -t — имя нашего изображения, а «.» означает, что мы собираем его из Dockerfile в этом каталоге.
После того, как наш образ был создан, мы можем развернуть его, запустив либо локально, выполнив следующую команду:
docker run -p 5000:5000 object-detection
«-p» — это то, как мы монтируем порт хоста к порту, указанному в образе докера.
Или разверните его на таких платформах, как Open-Shift, Kubernetes и т. д.…
В своей следующей статье я больше сосредоточусь на типах платформ для производственного развертывания, где мы рассмотрим различные подходы и плюсы и минусы каждого из них.
И теперь он у вас есть. Полностью функциональная модель в производстве.
Поздравляем!
Дайте мне знать, как вы нашли эту статью, и если у вас есть какие-либо вопросы :)
Ссылки
Окончательная кодовая база доступна здесь