В этой серии статей мы рассмотрим, как на основе готовых моделей разрабатывать приложения, использующие машинное обучение, и развертывать их на различных платформах. Начнем с создания Web-приложения на основе Streamlit и развертывания его на облачной платформе Heroku, используя бесплатный аккаунт. Этот подход подойдет для прототипов и персональных или учебных проектов. В качестве примера сделаем приложение для классификации изображений. Для классификации изображений мы будем использовать библиотеку TensorFlow и модель EfficientNetB0, обученную на наборе данных ImageNet. Эта модель умеет распознавать 1000 классов изображений.  EfficientNetB0 – не самая качественная предварительно обученная модель, у нее доля правильных ответов (Top-1 Accuracy) составляет 77.1%. Но зато размер у модели очень маленький – всего 29 МБ. Небольшой размер модели важен для нас, т.к. в бесплатном аккаунте Heroku есть ограничения по объему памяти для запуска приложений: не более 512 МБ. Поэтому большие модели можно развертывать только на платном аккаунте. Кроме того, EfficientNetB0 работает достаточно быстро: время распознавания 46 мс. Классифицировать изображение с использованием модели EfficientNetB0 можно с помощью слегка модифицированного кода с сайта Keras: Давайте попробуем запустить этот код для распознавания вот такого изображения с самолетом (картинку нужно предварительно сохранить в файл 'plane.jpg'). После запуска получим следующий результат: airliner 0.4786306wing 0.0591435warplane 0.03492508 Самая большая вероятность, что на картинке воздушный лайнер (airliner) – 47%. Это правильный ответ. На втором месте крыло (wing) – почти 6%. Крыло на изображении, действительно, есть, и даже не одно, а два. Однако основной объект – это самолет, а не отдельные крылья. Так что второй ответ будем считать неправильным, хотя и достаточно обоснованным. Третий вариант – военный самолет (warplane), вероятность всего 3,4%, что не очень много. Опять же, ответ частично правильный: на картинке самолет, но другого типа – гражданский, а не военный. Итак, код для определения объектов на изображении работает. Но его нужно запускать из командной строки и каждый раз прописывать путь к изображению прямо в коде. Это делать очень неудобно. Давайте создадим Web-приложение, в которое пользователь может загрузить любую картинку, которую он хочет распознать. Быстро преобразовать наш скрипт на Python в Web-приложение можно с помощью бесплатной библиотеки Streamlit, созданной как раз для этих целей. Streamlit позволяет добавлять в скрипт элементы управления, например, загрузчик изображений, и запускать этот скрипт во встроенном Web-сервере. Для начала нам нужно установить Streamlit с помощью pip: Описание элементов управления в Streamlit выполняется в скрипте на Python. Давайте создадим простое Web-приложение, которое позволяет загрузить изображение.  Запуск Web-приложения выполняется командой: При запуске нужно указать имя скрипта на Python с описанием Web-страницы, в нашем случае app.py. Streamlit запустит встроенный Web-сервер, а в нем – страницу на основе скрипта app.py. Сервер Streamlit запущен по адресу http://localhost:8501. Наше приложение будет выглядеть следующим образом. В область выбора файла можно перетащить картинку, тогда она загрузится на сервер и будет показана на странице. Мы создали заготовку приложения, которое позволяет загрузить на сервер картинку. Теперь нам нужно аккуратно перенести в это приложение код, который занимается распознаванием изображения. Для удобства исходный скрипт распознавания мы разделим на несколько функций. Первая функция загружает нейронную сеть. Декоратор @st.cache говорит Streamlit, что модель нужно загрузить только один раз, чтобы избежать утечек памяти. Вторая функция выполняет предварительную обработку изображения для подготовки к распознаванию. Третья функция печатает названия и вероятность для ТОП 3 классов, выданных моделью. Теперь мы готовы написать код, создающий Web-страницу с помощью Streamlit. Полный код приложения можно посмотреть в репозитории с исходным кодом для статьи. Запущенное приложение будет выглядеть так. Если нажать кнопку "Распознать изображение", то запустится нейронная сеть и результаты ее работы будут показаны под изображением. На первом месте по-прежнему воздушный лайнер (airliner), так что распознавание происходит правильно. Более подробно о создании Web-приложения распознавания изображений с использованием Streamlit и TensorFlow можно посмотреть в видео. Итак, у нас получилось создать Web-приложение, в которое можно загрузить произвольную картинку для распознавания. Однако это приложение запускается только на локальном компьютере, его адрес – http://localhost:8501. Это означает, что другие пользователи не смогут подключиться к этому приложению по сети. Чтобы это стало возможным, нужно разместить приложение на каком-либо сервере в Интернет. Для этого хорошо подходят облачные платформы. Далее мы рассмотрим, как разместить наше приложение на облачной платформе Heroku. Heroku – это облачная платформа PaaS (Platform as a Service), которая предоставляет удобные инструменты для развертывания приложения. Пользователю не нужно самому создавать виртуальную машину, устанавливать ОС, запускать и настраивать Web-сервер. Все это платформа Heroku делает автоматически.  Чтобы развернуть приложение на Heroku нужно просто сделать push в репозиторий Git Heroku. Это очень удобно. На Heroku есть бесплатные аккаунты, в которых можно использовать 550 часов работы контейнеров (на Heroku контейнеры называются Dyno). У бесплатного аккаунта есть ограничения по ресурсам контейнера: Максимальный объем оперативной памяти: 512 МБ. Максимальный объем образа для контейнера (на Heroku он называется slug): 500 МБ.  Бесплатный контейнер останавливается после 30 минут бездействия. Но если к остановленному таким образом контейнеру поступает запрос, то он автоматически запускается. Возможностей бесплатного аккаунта вполне достаточно для создания небольших прототипов, домашних и образовательных проектов. В том числе для запуска нашего Web-приложения классификации изображений. Если у вас еще нет аккаунта на Heroku, то нужно зарегистрироваться. После регистрации и входа вы попадаете в панель управления Heroku (dashboard). Чтобы создать новое приложение, нужно в правой верхней части панели управления Heroku нажать на кнопку "New", а затем в появившемся меню выбрать пункт "Create new app". Откроется страница создания приложения, в котором нужны выполнить три действия: Ввести имя приложения. Имя должно быть уникально для всех приложений Heroku. Пользователи смогут обращаться к вашему приложению по ссылке виде https://app-name.herokuapp.com. Например, если имя приложения image-classification-demo, то ссылка на приложение будет https://image-classification-demo.herokuapp.com. Heroku подсвечивает введенное имя зеленым, если оно свободно, и красным в противном случае. Выбрать регион размещения приложения. Регионов доступно всего два, США и Европа. Лучше выбирать тот, который географически ближе к вам. Поэтому я выбрал Европу. Нажать на кнопку "Create app". Приложение на платформе Heroku создано, но пока в нем нет нашего кода. Чтобы этот код можно было развернуть в приложении, его нужно разместить в репозитории Git и добавить конфигурационные файлы с инструкциями по запуску приложения на облачной платформе. Давайте создадим репозиторий Git в том каталоге, где находится наш Python скрипт с Web-приложением. Для этого выполняем команду: Теперь нужно добавит скрипт с Web-приложением в репозиторий. Пусть скрипт называется image_classification.py, тогда команды будут следующие: Репозиторий Git создан и скрипт с Web-приложением зафиксирован в нем. Однако пока репозиторий не готов для развертывания на Heroku. Облачной платформе для успешного запуска нашего приложения требуются дополнительные сведения: Какие библиотеки Python нужны для работы приложения? Heroku установит эти библиотеки в образ для запуска приложения. В Python список библиотек указывается в файле requirements.txt. Как запускать наше приложение? Вручную мы запускали приложение из командной строки с помощью streamlit run. Heroku использует файл с названием Procfile чтобы узнать, как нужно запускать приложение. Именно в него мы и пропишем команду запуска. Также нужно будет добавить дополнительный скрипт на shell, который создает конфигурационные файлы Streamlit для работы в режиме сервера.  Мы начнем с файла requirements.txt. В него нужно записать всего две библиотеки: Обратите внимание, что мы будем использовать версию TensorFlow с поддержкой только CPU. Во-первых, в контейнерах Heroku нет GPU, поэтому пытаться его применять бессмысленно. Во-вторых, версия TensorFlow с поддержкой GPU занимает значительное место, превышающее размер образа для бесплатного аккаунта на Heroku в 500МБ. Теперь можно создать bash скрипт, создающий конфигурационные файлы Streamlit. Файл будет называться setup.sh и содержать следующее: Первая команда в этом скрипте создает каталог .streamlit в домашнем каталоге пользователя, где и будут храниться настройки Streamlit.  Вторая команда записывает в файл credentials.toml адрес вашей почты. Не забудьте прописать этот адрес в скрипт. Третья команда создает конфигурационный файл для сервера Streamlit config.toml, в котором две опции: headless = true – при запуске Streamlit не будет открывать новое окно браузера (это поведение Streamlit по умолчанию подходит для персонального компьютера, но не для сервера) port = $PORT – Streamlit будет работать не на порту 8501, как он обычно делает, а на порту, который ему укажет облачная платформа Heroku в переменной окружения $PORT.  Последний файл, Procfile, содержит команду, которую платформа Heroku должна выполнить для запуска нашего приложения: web в начале строки говорит Heroku о типе контейнера, в котором должно быть запущено приложение – контейнер для Web приложений. Затем идет команда запуска приложения, которая в нашем случае состоит из двух частей: sh setup.sh – запуск скрипта для создания конфигурационных файлов streamlit run image_classification.py - запуск нашего Web-приложения в Streamlit. Эта команда выполняется только в случае успешного выполнения первой команды (символы &&). Все три файла есть в репозитории с исходным кодом статьи. Теперь нам нужно зафиксировать добавление новых файлов в репозитории Git: Сейчас наш репозиторий готов к развертыванию на Heroku! Инструкция по развертыванию есть на закладке "Deploy" приложения Heroku. Устанавливаем Heroku CLI. Подробная инструкция есть на сайте Heroku. Установка в Linux: Установка на macOS:  Для Windows нужно скачать и запустить установочный файл.  Выполняем логин в Heroku CLI. В консоли запускаем команду: После этого откроется окно браузера, в котором нужно будет войти на платформу Heroku. В случае успешного логина появится сообщение о том, что окно браузера можно закрыть и вернуться в командную строку. В консоли также будет написано об успешном выполнении логина. Подключаем удаленный Git репозиторий Heroku. Не забудьте заменить image-classification-demo на название вашего приложения на Heroku. После подключения удаленного репозитория Git на платформе Heroku, развертывание можно выполнять с помощью push в этот репозиторий: В результате Heroku запустит сборку образа контейнера для вашего приложения и развернет его по ссылке вида https://application-name.herokuapp.com. В облачной платформе наше приложение выглядит следующим образом: Пользователям можно давать ссылку на наше приложение – https://image-classification-demo.herokuapp.com. При необходимости Heroku позволяет подключить собственный домен для приложения. Подробнее о развертывании приложения Streamlit на Heroku можно посмотреть в видео. Итак, мы рассмотрели, как преобразовать Python скрипт классификации изображений в Web-приложение и развернуть его на облачной платформе Heroku. Основные действия, которые необходимо выполнить: Написать скрипт классификации изображений. Мы использовали библиотеку TensorFlow, но подойдет PyTorch или любая аналогичная библиотека. Преобразовать скрипт в Web-приложение с помощью библиотеки Streamlit. Создать приложение на облачной платформе Heroku в бесплатном аккаунте. Создать репозиторий Git для развертывания приложения, добавить в него конфигурационные файлы, необходимые Heroku. Подключить репозиторий Git к приложению на Heroku и выполнить развертывание командой git push. Передать ссылку на развернутое приложение пользователям. В следующей части мы рассмотрим, как развертывать созданное нами Web-приложение классификации изображений через Docker. Если вам интересно создавать приложения, использующие модели машинного обучения, и развертывать их для продуктивного применения пользователями, приглашаем в новую магистратуру Уральского федерального университета "Инженерия искусственного интеллекта".  В этой магистратуре мы учим создавать крупные программные системы, использующие машинное обучение. Основные курсы магистратуры в двух областях: Машинное обучение: математические основы, классические алгоритмы, глубокие нейронные сети, компьютерное зрение, обработка естественного языка, анализ временных рядов. Промышленная разработка программного обеспечения: Python, Linux, программная инженерия, DevOps, MLOps. В магистратуре вы будете работать над проектами от компаний-партнеров. В случае успешного выполнения проекта есть шанс устроиться на работу прямо во время обучения в магистратуре. Социальные сети магистратуры цифровых профессий УрФУ: Телеграм канал. Сообщество VK. Пишем о программах магистратуры в области ИТ, кибербезопасности и радиоэлектроники: как поступить, как подготовиться к экзаменам, как перейти в ИТ с помощью магистратуры. Предварительно обученная нейронная сеть EfficientNetB0. Использование предварительно обученных нейронных сетей в TensorFLow и Keras.  Библиотека Streamlit. Репозиторий с исходными кодами статьи. Облачная платформа Heroku. Приложение классификации изображений, развернутое на платформе Heroku. Магистратура УрФУ "Инженерия искусственного интеллекта". Телеграм канал "Магистратура ИРИТ-РТФ УрФУ". Сообщество "Магистратура ИРИТ-РТФ УрФУ" в VK.  Преподаватель университета