9. Сохранение модели#
Метод сохранения |
Плюсы |
Риски / Минусы |
|---|---|---|
ONNX |
|
|
skops_persistence |
|
|
|
|
|
|
|
|
|
|
|
После обучения модели scikit-learn желательно иметь способ сохранить модель для использования в будущем без необходимости повторного обучения. В следующих разделах мы дадим вам несколько советов о том, как сохранить модель scikit-learn.
9.1. Сериализация для Python#
Сохранить модель в scikit-learn можно с помощью встроенной в Python модели сохранения, а именно pickle:
>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC()
>>> X, y= datasets.load_iris(return_X_y=True)
>>> clf.fit(X, y)
SVC()
>>> import pickle
>>> s = pickle.dumps(clf)
>>> clf2 = pickle.loads(s)
>>> clf2.predict(X[0:1])
array([0])
>>> y[0]
0
В конкретном случае scikit-learn, возможно, лучше использовать
pickle от joblib (dump и load), которая более
эффективна для объектов, несущих внутри себя большие массивы
numpy, как это часто бывает для обученых моделей
scikit-learn, но может сохранять только на диск, а не в строку:
>>> from joblib import dump, load
>>> dump(clf, 'filename.joblib')
Позже вы можете загрузить обратно pickle модель (возможно, в другой процесс Python) с помощью:
>>> clf = load('filename.joblib')
Note
Функции dump и load также
принимают файлоподобные объекты вместо имен
файлов. Больше информации о сохранении данных с помощью Joblib можно найти
здесь <https://joblib.readthedocs.io/en/latest/persistence.html>`_.
InconsistentVersionWarning#
Когда модель распаковывается с версией scikit-learn, которая
несовместима с версией, с которой модель был
распакован, выдается предупреждение InconsistentVersionWarning. Это предупреждение можно
перехватить, чтобы получить исходную версию, с которой была сохранена модель:
from sklearn.exceptions import InconsistentVersionWarning
warnings.simplefilter("error", InconsistentVersionWarning)
try:
est = pickle.loads("model_from_prevision_version.pickle")
except InconsistentVersionWarning as w:
print(w.original_sklearn_version)
9.1.1. Ограничения безопасности и удобства сопровождения#
У pickle (и joblib в придачу) есть некоторые проблемы, связанные с сопровождаемостью и безопасностью. В связи с этим,
Никогда не распаковывайте недоверенные данные, так как это может привести к выполнению вредоносного кода при загрузке.
Хотя модели, сохраненные с помощью одной версии scikit-learn, могут загружаться в другие версии, это совершенно не поддерживается и не рекомендуется. Также следует помнить, что операции, выполняемые с такими данными, могут дать разные и неожиданные результаты.
Для того чтобы восстановить аналогичную модель в будущих версиях scikit-learn, необходимо, чтобы дополнительные метаданные были сохранены вместе с моделью:
Обучающие данные, например, ссылка на неизменяемый снимок.
Исходный код python, использованный для создания модели
Версии scikit-learn и его зависимостей
Оценка перекрестной валидации, полученная на обучающих данных.
Это должно позволить проверить, что результат кросс-валидации находится в том же диапазоне, что и раньше.
За некоторыми исключениями, сохраненные модели должны быть переносимы между архитектурами при условии, что используются те же версии зависимостей и Python. Если вы столкнулись с моделью, которая не переносится, пожалуйста, откройте проблему на GitHub. Pickled-модели часто разворачиваются в производстве с помощью контейнеров, таких как Docker, чтобы заморозить окружение и зависимости.
Если вы хотите узнать больше об этих проблемах и изучить другие возможные методы сериализации, пожалуйста, обратитесь к этой статье talk by Alex Gaynor.
9.1.2. Более безопасный формат: skops#
skops предоставляет более безопасный формат через модуль
skops.io. Он позволяет избежать использования pickle и загружает
только те файлы, которые имеют типы и ссылки
на функции, которым доверяют либо по умолчанию, либо по желанию пользователя.
Использование skops#
API очень похож на pickle, и вы можете сохранять свои
модели, как объясняется в документации, используя
skops.io.dump и skops.io.dumps:
import skops.io as sio
obj = sio.dumps(clf)
А загрузить их обратно можно с помощью
skops.io.load и skops.io.loads. Однако вам необходимо указать
типы, которым вы доверяете. Вы можете получить
существующие неизвестные типы в дампе объекта/файла с
помощью skops.io.get_untrusted_types, и, проверив его содержимое, передать его функции load:
unknown_types = sio.get_untrusted_types(data=obj)
clf = sio.loads(obj, trusted=unknown_types)
Если вы доверяете источнику файла / объекта, вы можете передать trusted=True:
clf = sio.loads(obj, trusted=True)
Пожалуйста, сообщайте о проблемах и пожеланиях, связанных с этим форматом, на трекере проблем skops.
9.2. Совместимые форматы#
Для воспроизводимости и контроля качества, когда
необходимо учитывать различные архитектуры и среды,
экспорт модели в формат Open Neural Network
Exchange или Predictive Model
Markup Language (PMML) может быть
лучшим подходом, чем использование только pickle.
Они полезны, если вы хотите использовать
модель для прогнозирования в среде, отличной от той, в которой модель обучалась.
ONNX - это бинарная сериализация модели. Она была разработана для улучшения удобства взаимодействия моделей данных. Она призвана облегчить преобразование моделей данных между различными фреймворками машинного обучения, а также улучшить их переносимость на различные вычислительные архитектуры. Более подробную информацию можно найти в учебнике по ONNX. Для преобразования модели scikit-learn в ONNX был разработан специальный инструмент sklearn-onnx.
PMML - это реализация стандарта документов XML, предназначенного для представления моделей данных вместе с данными, используемыми для их создания. Будучи человеко и машиночитаемым, PMML является хорошим вариантом для проверки моделей на различных платформах и долгосрочного архивирования. С другой стороны, как и XML в целом, его многословность не помогает в производстве, когда производительность критична. Для преобразования модели scikit-learn в PMML можно использовать, например, sklearn2pmml, распространяемый под лицензией Affero GPLv3.