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

Развертывание моделей машинного обучения является сложной задачей. Навыки, используемые для создания модели, сильно отличаются от навыков, необходимых для развертывания модели для взаимодействия с конечными пользователями. С Anvil легко развернуть модели машинного обучения в Интернете, и мы можем сделать это полностью на Python — не нужно возиться с HTML, CSS, JavaScript или веб-хостингом.

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

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

Для этого урока вам необходимо знать основы Python.

Вот шаги, которые мы рассмотрим:

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

Шаг 1 — Создайте свое приложение Anvil

Войти в Anvil и нажать Новое пустое приложение. Выберите тему Материальный дизайн.

Сначала назовите приложение. Нажмите на имя в верхней части экрана и дайте ему имя.

Шаг 2 — Создайте свою страницу

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

Мы создаем пользовательский интерфейс, перетаскивая компоненты из Toolbox. Давайте начнем с того, что поместим карту в нашу форму — это будет аккуратный контейнер для других компонентов. Затем давайте добавим Label и TextBox в компонент карты:

Далее мы настроим компоненты label и TextBox для сбора длины чашелистика. Выберите Label, который мы только что добавили, и на панели свойств справа измените текст на «Длина чашелистика:». Затем выберите TextBox, который мы добавили, и измените имя на sepal_length, а текст-заполнитель на «(см)».

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

Далее добавим кнопку для запуска классификатора. Назовите его categorise_button и измените текст на «Categorize». Нажатие этой кнопки вызовет функцию Python для классификации измерений радужной оболочки с использованием нашей модели. (Мы настроим это через мгновение.)

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

Теперь наше приложение должно выглядеть так:

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

Шаг 3 — Запустите код Python, когда вы нажмете кнопку

Мы хотим, чтобы наш categorise_button что-то делал при нажатии, поэтому давайте добавим событие клика.

Выбрав кнопку, перейдите в нижнюю часть панели свойств. Затем нажмите синюю кнопку с двумя стрелками рядом с полем события щелчка. Это откроет представление нашего кода и создаст функцию с именем categorise_button_click(). С этого момента каждый раз, когда пользователь нажимает кнопку, эта функция будет вызываться.

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

Для этого добавим следующее:

def categorise_button_click(self, **event_args):
    """This method is called when the button is clicked"""
    # Call the server function and pass it the iris measurements
    iris_category = anvil.server.call('predict_iris', 
                                self.sepal_length.text,
                                self.sepal_width.text,
                                self.petal_length.text,
                                self.petal_width.text)
    # If a category is returned set our species 
    if iris_category:
      self.species_label.visible = True
      self.species_label.text = "The species is " + iris_category.capitalize()

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

Шаг 4 — Загрузите нашу модель

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

В нашем приложении Anvil нажмите кнопку + в боковом меню и выберите Файлы данных:

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

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

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

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

Шаг 5 — Настройте нашу серверную среду

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

Мы начнем с выбора значка шестеренки в меню боковой панели и открытия «Версии Python».

Затем в раскрывающемся списке версий Python выберите «Python 3.10». В разделе «Базовые пакеты» выберите «Редактировать файл requirements.txt напрямую».

Наконец, вставьте следующий список требований в текстовое поле:

joblib==1.1.0
numpy==1.21.6
scikit-learn==1.1.2
scipy==1.9.0
sklearn==0.0
threadpoolctl==3.1.0

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

Шаг 6 — Получите доступ к нашему сохраненному файлу модели

Мы можем получить доступ к нашему сохраненному файлу модели, используя data_files API в Серверном модуле. Затем мы можем загрузить его в scikit-learn.

Для начала давайте добавим серверный модуль в наше приложение, нажав + Добавить серверный модуль в Браузере приложений.

В верхней части нашего серверного модуля давайте импортируем библиотеку joblib, которая нам нужна для загрузки нашей модели, и импортируем load_iris из встроенного набора данных радужной оболочки глаза sklearn.

from sklearn.datasets import load_iris
import joblib

# Loading sklearn's built-in iris dataset
iris = load_iris()

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

@anvil.server.callable
def predict_iris(sepal_length, sepal_width, petal_length, petal_width):
  pass

Внутри функции predict_iris мы загрузим нашу модель из службы файлов данных. Для этого мы получим путь к файлу модели на диске с помощью data_files['knn.skmodel'], затем мы можем использовать joblib.load() для восстановления нашей модели из файла.

Как только мы воссоздали нашу модель, передаем данные о цветке ириса в model.predict() и возвращаем название цветка.

@anvil.server.callable
def predict_iris(sepal_length, sepal_width, petal_length, petal_width):
  model = joblib.load(data_files['knn.skmodel'])
  classification = model.predict([[sepal_length, sepal_width, petal_length, petal_width]])
  return iris.target_names[classification][0]

Еще в шаге 3 этого урока мы написали anvil.server.call('predict_iris', ...) в нашей функции categorise_button_click() на клиентской стороне. Добавление декоратора @anvil.server.callable к нашей серверной функции predict_iris() означает, что его можно вызывать из клиента.

Шаг 7 — Опубликуйте наше приложение

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

Давайте быстро протестируем приложение, чтобы убедиться, что оно работает. Мы можем нажать кнопку Выполнить в правом верхнем углу Редактора Anvil, чтобы запустить приложение в режиме разделенного просмотра и попробовать его.

Если есть проблема, появится App Console и покажет созданное исключение. Вы можете нажать на исключение, и редактор перенесет вас на строку кода, вызвавшую его.

Протестировав приложение, мы можем нажать кнопку «Опубликовать» в правом верхнем углу редактора. Затем выберите «Опубликовать это приложение» и используйте предоставленный общедоступный URL-адрес или введите свой собственный.

Вот и все, наше приложение готово и доступно для всех!

Заключение

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

Клонировать приложение

Для тех из вас, кто хочет увидеть исходный код этого приложения:

Посмотреть готовое приложение

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

Что дальше?

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

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

Дополнительно: Испытайте себя

Эта часть не является обязательной! Лучший способ изучить любую новую технологию — бросить вызов своему пониманию. Почему бы не бросить себе вызов, чтобы закрепить то, что вы узнали, и узнать больше?

Задача 1 — добавьте изображение в свое приложение

Добавьте компонент Image в интерфейс вашего приложения и установите его источник на основе возвращаемой классификации радужной оболочки. Вы можете установить источник изображения на один из следующих трех URL-адресов в функции categorise_button_click:

Задание 2. Сохраните результаты в таблице данных.

Попробуйте сохранить результаты классификации во встроенной базе данных Anvil.

Подсказка: добавьте в приложение Таблицу данных для хранения результатов классификации. Затем используйте Anvil add_row() в функции predict_iris вашего приложения. Это будет добавлять строку в вашу базу данных каждый раз, когда классификация завершена.

Задача 3. Превратите приложение в HTTP API

Вы можете создать HTTP API для своего приложения, украсив функцию predict_iris декоратором @anvil.server.http_endpoint. Почему бы не попробовать создать API для своего приложения, чтобы им могли пользоваться другие люди?

Новичок в Анвиле?

Если вы новичок в Anvil, добро пожаловать! Anvil — это платформа для создания полнофункциональных веб-приложений только на Python. Не нужно возиться с JS, HTML, CSS, Python, SQL и всеми их фреймворками — просто создайте все это на Python.

Да — Python, который работает в браузере. Python, который работает на сервере. Python, который строит ваш пользовательский интерфейс. Редактор пользовательского интерфейса с перетаскиванием. У нас даже есть встроенная база данных Python, если у вас нет своей.

Почему бы не поиграть с конструктором приложений? Это бесплатно! Нажмите здесь, чтобы начать:

Получить здание

Want to receive more good quality Python articles?
Follow me on Medium.