Непрерывное глубокое обучение: другая точка зрения

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

Непрерывное глубокое обучение: другая точка зрения

От идеи до нативного приложения с YOLOv5, TorchServe и React Native

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

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

Примечание. В остальной части этой статьи проекты и проекты глубокого обучения используются как взаимозаменяемые.

Когда кто-то начинает изучать концепции глубокого обучения, создаются проекты для изучения конкретной технологии или подобласти, такой как НЛП или CV. Сегодня, если вы зайдете на такие ресурсы, как https://paperswithcode.com/, вы найдете исследования по различным проблемам, которые стали междоменными или которые чрезвычайно трудно решить с помощью традиционных подходов к контролируемому обучению и, следовательно, Для решения этих проблем были опробованы такие подходы, как обучение с самоконтролем, обучение с полу-контролем, причинно-следственный вывод и т. д. Это приводит к важному вопросу: как лучше всего подходить к проекту и работать над ним? Следует ли выбрать домен и решить проблемы, основанные на нем, или следует выбрать проблему и изучить, что будет включать ее решение? Давайте попробуем ответить на некоторые из этих вопросов в этой статье.

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

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

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

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

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

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

«Выберите то, что вам нравится. Выберите то, что побуждает вас усердно работать ».

Абхишек Тхакур

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

Тогда поговорим немного о мотивации этого проекта. Я большой поклонник Masterchef (большинство из них), и для тех, кто живет под камнем и никогда его не смотрел, просто знайте, что он о кулинарии. В шоу есть один сегмент под названием Mystery Box Challenge, в котором участникам нужно приготовить блюдо из некоторых загадочных ингредиентов. Это заставило меня задуматься о том, как я буду решать эту проблему, оставаясь в своей комфортной зоне глубокого обучения и разработки программного обеспечения. Лампочка погасла, и так родилась идея приложения MBC.

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

См. также:  Можно использовать стрелочную функцию в качестве инициализатора свойств класса, если у вас не слишком много экземпляров…

Теперь, когда у нас есть мотивация, и мы решили не идти по какому-либо конкретному пути к решению проблемы, разве мы не думаем о решении вообще? Что ж, это слишком смело даже для нас, поклонников глубокого обучения. Между процессом и методологией должно быть четкое различие. «Процесс» — это широкий термин, который описывает, что необходимо сделать для решения проблемы, тогда как методология выполнения этого может сильно отличаться, тогда как методология говорит о шагах, которые необходимо предпринять, чтобы выполнить что-то конкретное. Например, знание того, следует ли подходить к проблеме как регрессия или классификация, может быть частью процесса, тогда как конкретная магистраль для выбора из ResNet, EfficientNet или VGG может состоять из конкретной методологии.

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

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

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

Учебный конвейер YOLOv5

Мы решили использовать модель обнаружения объектов для обнаружения различных ингредиентов в рамках процесса, но тогда мы не решили, как это будет выполняться и какие спецификации выбрать для этого из различных доступных вариантов. Существуют различные популярные модели обнаружения объектов, такие как Faster-RCNN, Mask-RCNN, SSD, YOLO и т. Д. Вы можете найти статьи со всесторонним сравнением этих моделей, но мы предпочли бы сделать его кратким и простым и обосновать наш выбор, чем сосредоточение внимания на тех, которые мы не выбрали.

YOLO v5 — одно из последних пополнений в списке этих моделей обнаружения объектов. Он превосходит все последние модели как по скорости предсказания на GPU, так и по метрике COCO (от 0 до 1). Он имеет хорошо написанную кодовую базу и предоставляет различные альтернативы на выбор в зависимости от масштаба и требований проекта. Вместе с тем, он обеспечивает хорошую мобильность. Хотя он написан на Pytorch, его можно преобразовать в такие форматы, как Onnx, CoreML, TFLite и Torchscript (которые мы будем использовать). Кроме того, его способность конвертировать в Onnx открывает множество возможностей. Следовательно, благодаря хорошо написанной кодовой базе и хорошей переносимости, мы выбираем YOLOv5 в качестве нашей модели обнаружения объектов и, в частности, YOLOv5m, как хороший компромисс между скоростью и средней точностью (AP).

Здорово! Теперь все, что нам нужно сделать, это обучить модель обнаружения объектов, и все готово, верно? Чтобы лопнуть пузырь, нет. Мы много говорили о процессе, но не говорили о самих данных, которые являются одним из основных элементов любого конвейера Data Science. Итак, давайте обозначим модель и процесс и поговорим о данных.

Давайте сначала поговорим об еще одном важном отличии. Мы всегда слышим такие термины и фразы, как «большие данные», «данные — новое золото», «данных в изобилии», но Дело в том, что неструктурированных и необработанных данных очень много. И снова, когда мы начинаем изучать глубокое обучение и науку о данных в целом, мы сталкиваемся с наборами данных, такими как Iris или MNIST и т. Д. Это хорошо обработанные данные, и для этого требуются усилия. Эти усилия большую часть времени остаются нереализованными, но рассмотрите возможность создания набора данных с 70 000 изображений разных цифр, с разным почерком или чего-то еще большего и более актуального для проекта, например набора данных COCO. Сбор и обработка таких крупномасштабных наборов данных — дело непростое и непростое. В большинстве случаев в профессиональных сценариях данные, относящиеся к задаче, недоступны, и их необходимо собирать, обрабатывать и обрабатывать задолго до того, как даже подумать о запуске всего цикла обучения-тестирования-экспериментирования.

См. также:  Удивительные DevTools

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

На этом этапе жизненного цикла проекта мы собираем данные, аннотируем их с помощью информации ограничивающего прямоугольника, структурируем их до того, как они могут быть переданы модели для обучения. Для простоты мы предпочитаем работать с 10–20 ингредиентами, чем с целым набором ингредиентов, бессонными ночами и кувшином, полным кофе. В наборе данных Indian Food 101 ингредиенты выбираются в соответствии с их частотой в разных блюдах. На данный момент выбрано всего 10 ингредиентов. Этот набор данных также будет важен в более поздней части, когда нам придется прогнозировать блюда из признанных ингредиентов, но об этом позже.

Листья карри, гарам масала, топленое масло, имбирь, джаггери, молоко, рисовая мука, сахар, помидоры, урад дал

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

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

food-ingredients/
      |--curry-leaves/
      |--garam-masala/
      .
      .
      .
      |--urad-dal/

Остается одна задача, прежде чем вернуться к самой модели, и с меньшим количеством альтернатив, чем предыдущая. Задача аннотирования и создания ограничивающих рамок на каждом из изображений. Либо мы можем сделать это вручную, используя такие инструменты, как LabelImg, либо мы можем выбрать какой-то совершенно другой подход, например, локализацию объекта с полу-контролем, но давайте воздержимся от разговора о последнем, поскольку он выходит за рамки данного обсуждения. Давайте останемся на этом пути и вручную аннотируем данные. Проект YOLO v5 ожидает очень специфической структуры каталогов для данных:

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

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

Здорово! Теперь, когда маркировка выполнена и данные правильно структурированы, мы можем продолжить обучение модели YOLO v5 на нашем пользовательском наборе данных. Мы будем использовать yolov5m и напишем нашу конфигурацию для данных, которая будет выглядеть примерно так:

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

 

himanshu-dutta / mbc-object-detection-yolov5
Экземпляр YOLOv5, обученный на пользовательском наборе данных пищевых ингредиентов, собранных и аннотированных вручную. Ниже приведены… github.com

 

Конечная точка вывода

Когда дело доходит до обслуживания модели машинного обучения или глубокого обучения, доступно множество вариантов. От более знакомых, таких как Streamlit и Flask, до чуть менее обсуждаемых, «развертывание на периферии» и новых возможностей, которые продолжают появляться. , как FastAPI (с которым мне еще предстоит поиграться).

Нам нужно выбрать вариант, который наилучшим образом соответствует нашей цели. Поскольку мы решили создать собственное приложение для проекта, мы можем выбрать развертывание модели изначально с такими параметрами, как Onnxjs или TensorFlow.js. Проблема с этой опцией заключается в том, что Onnx не работает должным образом с React Native (поскольку приложение будет построено с использованием этого), и хотя TF.js имеет совместимую структуру для React Native, в нем есть некоторые ошибки, которые необходимо исправить. вне. Это ограничивает наши возможности по созданию конечной точки API. Для этого мы выбрали TorchServe, который по своей сути использует привязки C ++ для развертывания модели Torchscript. Причина выбора TorchServe — это питонический стиль, в котором могут быть написаны конечные точки, а также его развертывание Torchscript, которое учитывает скорость.

Обработчик конечной точки состоит из методов, которые в любом случае будут частью вашей кодовой базы (в нашем случае кодовой базы YOLOv5). Он состоит из следующих методов:

__init__: Used to initialize the endpoint, can be image transforms, or encoders for text, etc.
preprocess: Method used to process the input batch before feeding it to the model and making inference, such as given an input image, transforming it in the desired way.
inferencce: This method is where the actual inference happens. The preprocessed input is passed to the model, and output is obtained from it. Other smaller changes to the output can also be performed here.
postprocess: After the inference is made the output is passed to this method, where the output can be packaged in the desired way, before the response is made for the given input, such as converting class index to label names, etc.
Note: Although the method names are predefined, what is actually done inside these methods is completely upto us. Above are the suggeested best practices.

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

См. также:  Получить входные каналы для conv2d с предыдущего слоя?

Конечную точку можно развернуть с помощью команды, подобной этой:

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

Родное приложение

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

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

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

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

Так как последний вариант более осуществим, приступим к нему. После принятия решения о предпочтительном способе вывода, нам теперь нужно определиться с пользовательским интерфейсом и компонентами, необходимыми для приложения. Нам определенно потребуются компоненты Camera и Image (для отображения неподвижных изображений), а также для этого потребуются некоторые кнопки, с помощью которых пользователь будет щелкать изображения, переворачивать камера и т. д., а также раздел, в котором можно перечислить ингредиенты и рецепты. Также было бы неплохо нарисовать ограничивающие рамки вокруг обнаруженных ингредиентов. Большинство этих элементов уже встроены в React Native, но нам придется создать компонент «ограничивающий прямоугольник» самостоятельно.

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

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

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

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

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

Ссылки на проекты

[1] https://github.com/himanshu-dutta/mbc-object-detection-yolov5

[2] https://github.com/himanshu-dutta/mystery-box-challenge-app

использованная литература

[1] Йоло v5

[2] TorchServe и Pytorch

[3] React Native

Понравилась статья? Поделиться с друзьями:
IT Шеф
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: