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

Что такое модельная гниль?

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

Меняются не только зомби

Конечно, вымышленные существа могут меняться, но также могут меняться финансовые рынки, жилые помещения, схемы движения транспорта, погодные условия, то, как люди пишут твиты, и то, как выглядят кошки! Хорошо, может быть, кошки всегда будут выглядеть как кошки (хотя дайте ему несколько миллионов лет, а может и нет). Дело в том, что в зависимости от того, что предсказывают ваши модели, будет зависеть, насколько быстро они будут гнить.

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

Давайте бороться с гниением модели (с помощью ML Engine + DataStore)

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

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

Сейчас мы планируем развернуть нашу модель в ML Engine, который будет размещать нашу модель для нас в облаке. (посмотрим, как мы это делаем с помощью команд gcloud в записной книжке)

Сначала перенесем нашу модель в облачное хранилище:

gsutil cp model.joblib gs://your-storage-bucket/v1/model.joblib

Затем создайте новую модель ML Engine, которую вы можете сделать с помощью пользовательского интерфейса Google Cloud Console или с помощью команд gcloud (которые вы можете увидеть здесь, используются в записной книжке):

Затем мы развертываем нашу модель дерева решений как версию 1:

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

Хорошо, наша модель развернута, и приложения могут легко получать из нее прогнозы! Теперь отслеживайте гниение моделей с помощью DataStore!

Хранилище данных?

Представьте себе место в облаке, где вы можете быстро хранить миллионы словарей Python, а затем запрашивать их (также быстро). Это DataStore, полностью управляемая база данных NoSQL на платформе Google Cloud. Если у вас есть предыдущий опыт работы с базами данных, вы могли бы тщательно спланировать, какую именно структуру данных хранить в таблицах, а затем испытаете боль создания сценариев миграции для обновления структуры вашей базы данных. Ничего подобного с DataStore, вы хотите хранить следующие данные:

{
  "name": "Alex"
  "occupation": "Zombr trainer"
}

затем сделайте это (используя клиентскую библиотеку python):

# create new entity/row
new_person = datastore.Entity(key=client.key('person'))
new_person['name'] = 'Alex'
new_person['occupation'] = 'Zombr trainer'
# save to datastore
client.put(new_person)

Ой, подождите, вы хотите начать хранить гитхабы и твиттеры людей? Действуй:

# create new entity/row
new_person = datastore.Entity(key=client.key('person'))
new_person['name'] = 'Zack'
new_person['occupation'] = 'Zombr CEO'
new_person['github'] = 'https://github.com/zackakil'
new_person['twitter'] = '@zackakil'
# save to datastore
client.put(new_person)

и DataStore скажет «спасибо»:

Использование DataStore для сбора отзывов о модели

Данные обратной связи, которые мы собираемся собрать, будут выглядеть следующим образом:

{
"model": "v1",
"prediction input": [2.1, 1.4, 5.3, 8.0],
"prediction output": 1,
"was correct": False,
"time": "23-10-2018,14:45:23"
}

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

Мы снова будем использовать Cloud Functions, чтобы создать еще одну конечную точку веб-API, на этот раз для получения данных обратной связи и сохранения их в DataStore:

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

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

Проявите творческий подход к сбору отзывов

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

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

Обратная связь собирается, что теперь?

Теперь мы можем проанализировать данные обратной связи. Для любой работы по анализу данных я по умолчанию использую Jupyter Notebooks.

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

Важными частями выборки данных из DataStore являются сначала установка клиентской библиотеки Python DataStore:

pip install google-cloud-datastore

затем вы можете импортировать его и подключиться к DataStore:

from google.cloud import datastore
# connect to DataStore
client = datastore.Client('your project id')
# query for all prediction-feedback items 
query = client.query(kind='prediction-feedback') 
 
# order by the time field 
query.order = ['time'] 
 
# fetch the items 
# (returns an iterator so we will empty it into a list) 
data = list(query.fetch())

Библиотека с автоматическим преобразованием всех данных в словари Python:

print(data[0]['was correct'])
print(data[0]['model'])
print(data[0]['time'])
print(data[0]['input data'])
>>> True
>>> v1
>>> 2018-10-22 14:21:02.199917+00:00
>>> [-0.8300105114555543, 0.3990742221560673, 1.9084475908892906, 0.3804372006233603]

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

number_of_items = len(data)
number_of_was_correct = len([d for d in data if d['was correct']])
print(number_of_was_correct / number_of_items)
>>> 0.84

0,84 - это не так уж много, так как мы сначала обучили нашу модель, которая набрала точность ~ 0,9, но это рассчитано с использованием всех данных обратной связи вместе. Что, если мы сделаем тот же расчет точности для скользящего окна по нашим данным и построим его на графике? (вы можете увидеть код для этого в блокноте анализа)

По последним отзывам, производительность сильно упала.

Мы должны продолжить расследование. Давайте сравним входные данные (то есть данные о характеристиках зомби) от времен высокой точности до времен низкой точности. Хорошо, что мы также собрали это в наших отзывах:

Ах, данные выглядят совершенно иначе. Я предполагаю, что популяция зомби мутировала! Нам нужно как можно скорее переобучить нашу модель с новыми данными. Хорошо, что мы собрали входные данные в обратной связи, мы можем использовать их в качестве новых обучающих данных (избавляет нас от необходимости вручную собирать новые данные). Мы можем использовать информацию о прогнозе, сделанном моделью (поле «прогноз») и отзывы пользователей (поле «было правильно»), чтобы вывести правильную метку прогноза для новых данных обучения:

Посмотрите, как используется этот код, внизу блокнота анализа обратной связи.

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

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

Если вы установите модель по умолчанию на v2, тогда все запросы прогнозов для «зомби» перейдут в версию v2:

PREDICTION REQUEST BODY:
{
"instances":[[2.0, 3.4, 5.1, 1.0]],
"model":"zombies"
}

или ваши клиенты могут быть более конкретными:

PREDICTION REQUEST BODY:
{
"instances":[[2.0, 3.4, 5.1, 1.0]],
"model":"zombies/versions/v2"
}

После всего этого вы можете расслабиться и просто запустить тот же анализ после того, как будет собрана еще несколько отзывов:

Надеюсь, это дало вам несколько идей о том, как вы можете отслеживать развернутые модели на предмет гниения моделей. Весь используемый код можно найти в репозитории github:



Обращайтесь ко мне @ZackAkil с любыми мыслями / вопросами о мониторинге гнили модели.