сохранить построенную модель после обучения
Техблог Александра Куракина
Машинное обучение, нейронные сети
Страницы
понедельник, 10 сентября 2018 г.
TensorFlow: сохранение и восстановление моделей
Прогресс модели может быть сохранен в течение или после тренировки. Это означает, что обучение модели может быть возобновлено с того места, где оно было остановлено, избежав долгого времени повторной тренировки. Сохранение также означает, что вы можете поделиться своей моделью и другие могут воссоздать вашу работу. Во время публикации исследовательских моделей и техник большинство практиков машинного обучения делятся:
Предоставление этих данных позволяет другим понять как модель работает и испробовать модель самим с новыми данными.
Опции
Настройка
Получение примерного набора данных
Мы будем использовать MNIST набор данных для тренировки нашей модели и демонстрации сохраненных весов. Чтобы ускорить демонстрацию, используем только первые 1000 примеров:
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()
train_labels = train_labels[:1000]
test_labels = test_labels[:1000]
train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0
Определение модели
Построим простую модель, которую мы будем использовать для демонстрации сохранения и загрузки весов.
Сохранение контрольных точек в ходе тренировки
Использование колбека контрольных точек
Тренируем модель и передаем ей ModelCheckpoint колбек:
Epoch 00003: saving model to training_1/cp.ckpt
Epoch 00010: saving model to training_1/cp.ckpt
Это создает единственную коллекцию файлов контрольных точек TensorFlow, которые обновляются в конце каждой эпохи:
Создадим новую нетренированную модель. При восстановлении модели только из весов необходимо иметь модель точно с такой же архитектурой, как и модель, которой принадлежали веса. Ввиду того, что это та же самая архитектура, мы можем поделиться весами, несмотря на то, что это другой экземпляр модели.
Теперь перестроим свежую, нетренированную модель, и оценим ее на тестовом наборе. Нетренированная модель будет выполняться на случайных уровнях (
Затем загрузим веса из контрольной точки и переоценим:
Свойства колбека контрольной точки
Колбек предоставляет несколько свойств для задания уникальных имен для результирующих контрольных точек и нормализации частоты контрольных точек.
Натренируем новую модель и сохраним уникально названные контрольные точки каждые 5 эпох:
Теперь посмотрим на результирующие контрольные точки (сортируя по дате изменения):
Следует отметить, что по умолчанию TensorFlow сохраняет только 5 наиболее недавних контрольных точек.
Для тестирования сбросим модель и загрузим последнюю контрольную точку:
В какие файлы сохраняются контрольные точки
Код выше сохраняет веса в коллекцию отформатированных по контрольным точкам файлов, которые содержат только тренированные веса в бинарном формате. Контрольные точки содержат:
Ручное сохранение весов
Выше было показано как загружать веса в модель.
Ручное сохранение весов настолько же просто, используйте Model.save_weights метод.
Сохранение модели целиком
Модель целиком может быть сохранена в файл, который содержит значения весов, конфигурацию модели, и конфигурацию оптимизатора. Это позволяет создавать контрольную точку модели и восстанавливать тренировку позже, с того же самомо места, без доступа к исходному коду.
Keras предоставляет базовый формат сохранения, используя HDF5 стандарт. Для наших целей сохраненная модель может трактоваться как единый бинарный блоб (blob).
Теперь пересоздаем модель из этого файла:
Проверяем ее аккуратность:
Эта техника сохраняет все:
Сохранение и загрузка обученных моделей
Узнайте, как сохранять и загружать в приложение обученные модели.
В процессе создания модель находится в памяти и доступна на протяжении всего жизненного цикла приложения. Однако, если приложение прекращает работу, а модель не сохранена ни на локальном компьютере, ни на удаленном ресурсе, она станет недоступна. Обычно модели используются после обучения в других приложениях для вывода либо для переобучения. В связи с этим модель необходимо сохранять. Сохраняйте и загружайте модели, выполняя действия, описанные в последующих разделах этого документа, при использовании конвейеров подготовки данных и обучения модели, подобных описанному ниже. Несмотря на то что в этом примере используется модель линейной регрессии, такая же процедура подходит и для других алгоритмов ML.NET.
Сохранение модели на локальном компьютере
При сохранении модели нужны две вещи:
Загрузка модели, сохраненной на локальном компьютере
В отдельном приложении или процессе вызовите метод Load с указанием пути к файлу, чтобы загрузить в приложение обученную модель.
Загрузка модели, сохраненной на удаленном ресурсе
Работа с отдельными конвейерами подготовки данных и модели
Работать с отдельными конвейерами подготовки данных и обучения модели необязательно. Отделение конвейеров упрощает проверку параметров обученной модели. Для создания прогнозов проще сохранять и загружать единый конвейер, который включает операции подготовки данных и обучения модели.
При работе с отдельными конвейерами подготовки данных и моделей применяется тот же порядок действий, что и при работе с единым конвейером за тем исключением, что оба конвейера должны сохраняться и загружаться одновременно.
Допустим, у нас есть отдельные конвейеры подготовки данных и обучения модели:
Сохранение конвейера подготовки данных и обученной модели
Чтобы сохранить и конвейер подготовки данных, и обученную модель, используйте следующие команды:
Загрузка конвейера подготовки данных и обученной модели
Для одновременной загрузки конвейера подготовки данных и обученной модели в отдельный процесс или приложение используйте следующие команды:
scikit-learn: Сохранение и восстановление моделей
Инструменты для сохранения и восстановления моделей
Инициализация модели
Теперь давайте создадим модель с некоторыми нестандартными параметрами и поместим ее в обучающие данные. Мы предполагаем, что вы заранее нашли оптимальные параметры модели, то есть те, которые дают наибольшую оценочную точность.
И наша результирующая модель:
Модуль Рассола
Запуск этого кода должен дать ваш счет и сохранить модель с помощью Pickle:
Самое замечательное в использовании Pickle для сохранения и восстановления наших моделей обучения заключается в том, что это быстро – вы можете сделать это в двух строках кода. Это полезно, если вы оптимизировали параметры модели на обучающих данных, поэтому вам не нужно повторять этот шаг снова. Во всяком случае, он не сохраняет результаты тестов или какие-либо данные. Тем не менее, вы можете сделать это, сохранив кортеж или список из нескольких объектов (и запомнив, какой объект куда идет), следующим образом:
Модуль Joblib
Библиотека Joblib предназначена для замены Pickle для объектов, содержащих большие данные. Мы повторим процедуру сохранения и восстановления, как и в случае с Pickle.
Как видно из примера, библиотека Joblib предлагает немного более простой рабочий процесс по сравнению с Pickle. В то время как Pickle требует передачи объекта file в качестве аргумента, Joblib работает как с объектами file, так и со строковыми именами файлов. Если ваша модель содержит большие массивы данных, каждый массив будет храниться в отдельном файле, но процедура сохранения и восстановления останется прежней. Joblib также допускает различные методы сжатия, такие как “zlib”, “gzip”, ” bz2 ” и различные уровни сжатия.
Ручное сохранение и восстановление в JSON
В зависимости от вашего проекта, много раз вы находили бы Pickle и Joblib как неподходящие решения. Некоторые из этих причин обсуждаются далее в разделе Проблемы совместимости. В любом случае, когда вы хотите иметь полный контроль над процессом сохранения и восстановления, лучше всего создавать свои собственные функции вручную.
Ниже приведен пример сохранения и восстановления объектов вручную с помощью JSON. Этот подход позволяет нам выбрать данные, которые необходимо сохранить, такие как параметры модели, коэффициенты, обучающие данные и все остальное, что нам нужно.
Для простоты мы сохраним только три параметра модели и обучающие данные. Некоторые дополнительные данные, которые мы могли бы хранить при таком подходе,-это, например, оценка перекрестной проверки обучающего набора, тестовые данные, оценка точности тестовых данных и т. Д.
Распечатав новый объект, мы можем видеть наши параметры и обучающие данные по мере необходимости.
Поскольку сериализация данных с помощью JSON фактически сохраняет объект в строковом формате, а не в байтовом потоке, файл ‘mylogreg.json’ можно открыть и изменить с помощью текстового редактора. Хотя такой подход был бы удобен для разработчика, он менее безопасен, поскольку злоумышленник может просматривать и изменять содержимое файла JSON. Более того, этот подход больше подходит для объектов с небольшим количеством переменных экземпляра, таких как модели scikit-learn, поскольку любое добавление новых переменных требует изменений в методах сохранения и восстановления.
Проблемы совместимости
Хотя некоторые плюсы и минусы каждого инструмента были рассмотрены в тексте до сих пор, вероятно, самым большим недостатком инструментов Pickle и Joblib является их совместимость с различными моделями и версиями Python.
Совместимость версий Python – В документации обоих инструментов говорится, что не рекомендуется (де)сериализовывать объекты в разных версиях Python, хотя это может работать при незначительных изменениях версий.
Совместимость моделей – Одной из наиболее частых ошибок является сохранение модели с помощью Pickle или Joblib, а затем изменение модели перед попыткой восстановления из файла. Внутренняя структура модели должна оставаться неизменной между сохранением и перезагрузкой.
Последняя проблема как с Pickle, так и с Joblib связана с безопасностью. Оба инструмента могут содержать вредоносный код, поэтому не рекомендуется восстанавливать данные из ненадежных или неаутентифицированных источников.
Выводы
В этом посте мы описали три инструмента для сохранения и восстановления моделей scikit-learn. Библиотеки Pickle и Joblib быстры и просты в использовании, но имеют проблемы совместимости в разных версиях Python и изменения в модели обучения. С другой стороны, ручной подход более сложен в реализации и нуждается в модификации с любым изменением структуры модели, но с положительной стороны он может быть легко адаптирован к различным потребностям и не имеет никаких проблем совместимости.
Обучение и оценка модели с Keras
Это руководство охватывает обучение, оценку и прогнозирование (выводы) моделей в TensorFlow 2.0 в двух общих ситуациях:
Установка
Часть I: Использование встроенных циклов обучения и оценки
При передаче данных во встроенные циклы обучения модели вы должны использовать массивы Numpy (если ваши данные малы и умещаются в памяти), либо объекты Dataset tf.data. В следующих нескольких параграфах мы будем использовать набор данных MNIST в качестве массива Numpy, чтобы показать, как использовать оптимизаторы, функции потерь и метрики.
Обзор API: первый полный пример
Давайте рассмотрим следующую модель (будем строим ее с помощью Functional API, но она может быть и Sequential или субклассированной моделью):
Вот как выглядит типичный полный процесс работы, состоящий из обучения, проверки на отложенных данных, сгенерированных из исходных данных обучения, и, наконец, оценки на тестовых данных:
Определение потерь, метрик и оптимизатора
Вам нужно передать их в модель в качестве аргументов метода compile() :
Аргумент metrics задается в виде списка — ваша модель может иметь любое количество метрик.
Если у вашей модели несколько выходов, вы можете задать различные метрики и функции потерь для каждого выхода и регулировать вклад каждого выхода в общее значение потерь модели.
Обратите внимание, что часто функции потерь и метрики задаются с помощью строковых идентификаторов:
Для последующего переиспользования поместим определение нашей модели и шаг компиляции в функции; мы будем вызывать их несколько раз в разных примерах этого руководства.
Вам доступно множество встроенных оптимизаторов, функций потерь и метрик
Как правило, вам не нужно создавать с нуля собственные функции потерь, метрики, или оптимизаторы, поскольку то, что вам нужно, скорее всего, уже является частью Keras API:
Кастомные функции потерь
Кастомные метрики
Обработка функций потерь и метрик, не соответствующих стандартной сигнатуре
В таких случаях вы можете вызвать self.add_loss(loss_value) из метода call кастомного слоя. Вот простой пример, который добавляет регуляризацию активности (отметим что регуляризация активности встроена во все слои Keras — этот слой используется только для приведения конкретного примера):
Вы можете сделать то же самое для логирования значений метрик:
Вот простой пример:
Автоматическое выделение валидационного отложенного множества
В первом полном примере, как вы видели, мы использовали аргумент validation_data для передачи кортежа массивов Numpy (x_val, y_val) в модель для оценки валидационных потерь и метрик в конце каждой эпохи.
Вот другая опция: аргумент validation_split позволяет вам автоматически зарезервировать часть ваших тренировочных данных для валидации. Значением аргумента является доля данных, которые должны быть зарезервированы для валидации, поэтому значение должно быть больше 0 и меньше 1. Например, validation_split=0.2 значит «используйте 20% данных для валидации», а validation_split=0.6 значит «используйте 60% данных для валидации».
Вы можете использовать validation_split только когда обучаете модель данными Numpy.
Обучение и оценка с tf.data Dataset
Давайте теперь рассмотрим случай, когда ваши данные поступают в форме Dataset tf.data.
tf.data API это набор утилит в TensorFlow 2.0 для загрузки и предобработки данных быстрым и масштабируемым способом.
Заметьте, что Dataset сбрасывается в конце каждой эпохи, поэтому он может быть переиспользован в следующей эпохе.
Если вы хотите учиться только на определенном количестве пакетов из этого Dataset, вы можете передать аргумент `steps_per_epoch`, который указывает, сколько шагов обучения должна выполнить модель, используя этот Dataset, прежде чем перейти к следующей эпохе.
В этом случае датасет не будет сброшен в конце каждой эпохи, вместо этого мы просто продолжим обрабатывать следующие пакеты. В датасете в конечном счете могут закончиться данные (если только это не зацикленный бесконечно датасет).
Использование валидационного датасета
Вы можете передать экземпляр Dataset как аргумент validation_data в fit :
В конце каждой эпохи модель будет проходить по валидационному Dataset и вычислять потери и метрики на валидации.
Обратите внимание, что валидационный Dataset будет сбрасываться после каждого использования (так что вы всегда будете получать оценку на одних и тех же примерах от эпохи к эпохе).
Аргумент validation_split (генерирующий отложенную выборку из тренировочных данных) не поддерживается при обучении на объектах Dataset, поскольку для этого требуется возможность индексирования элементов, что в общем невозможно в Dataset API.
Другие поддерживаемые форматы входных данных
Кроме массивов Numpy и TensorFlow Dataset-ов, можно обучить модель Keras с использованием датафрейма Pandas, или с генераторами Python которые выдают значения пакетами.
В общем, мы рекомендуем вам использовать входные данные Numpy если их количество невелико и помещается в памяти, и Dataset-ы в других случаях.
Использование весов для примеров и классов
Кроме входных данных и меток модели можно передавать веса примеров и веса классов при использовании fit :
Словарь «class weights» является более специфичным экземпляром той же концепции: он сопоставляет индексам классов веса которые должны быть использованы для элементов принадлежащих этому классу. Например, если класс «0» представлен втрое меньше чем класс «1» в ваших данных, вы можете использовать class_weight= <0: 1., 1: 0.5>.
Вот примеры Numpy весов классов и весов элементов позволяющих придать большее значение корректной классификации класса #5 (соответствующий цифре «5» в датасете MNIST).
Вот соответствующий Dataset пример:
Передача данных в модели с несколькими входами и выходами
В предыдущих примерах, мы рассматривали модель с единственным входом (тензор размера (764,) ) и одним выходом (тензор прогнозов размера (10,) ). Но как насчет моделей, у которых есть несколько входов или выходов?
Рассмотрим следующую модель, в которой на входными данными являются изображения размера (32, 32, 3) (это (height, width, channels) ) и временные ряды размера (None, 10) (это (timesteps, features) ). У нашей модели будет два выхода вычисленных из комбинации этих входов: «score» (размерности (1,) ) и вероятностное распределение по пяти классам (размерности (5,) ).
Давайте начертим эту модель, чтобы вы ясно увидели что мы здесь делаем (заметьте что размерности, которые вы видите на схеме это размерности пакетов, а не поэлементные размерности).
Во время компиляции мы можем указать разные функции потерь для разных выходов, передав функции потерь в виде списка:
Если мы передаем только одну функцию потерь модели, она будет применена к каждому выходу, что здесь не подходит.
Аналогично для метрик:
Так как мы дали имена нашим выходным слоям, мы могли бы также указать функции потерь и метрики для каждого выхода в dict:
Мы рекомендуем использовать имена и словари если у вас более 2 выходов.
Имеется возможность присвоить разные веса разным функциям потерь (например, в нашем примере мы можем захотеть отдать предпочтение потере «score», увеличив в 2 раза важность потери класса), используя аргумент loss_weights :
Вы можете также не вычислять потери для некоторых выходов, если эти выходы предполагаются только для прогнозирования, но не для обучения:
Передача данных в модель с несколькими входами и выходами в fit происходит аналогично определению функции потерь в compile : вы можете передать списки массивов Numpy (совпадающие 1:1 с выходами на которых есть функции потерь) или словари сопоставляющие имена выходов массивам Numpy тренировочных данных.
Ниже пример для Dataset: аналогично массивам Numpy, Dataset должен возвращать кортеж словарей.
Использование колбеков
Колбеки в Keras это объекты которые вызываются в разных местах во время обучения (в начале эпохи, в конце пакета, в конце эпохи, и т.д.) и которые могут быть использованы для реализации такого поведения, как:
Выполнение валидации в различных точках во время обучения (кроме встроенной валидации в конце каждой эпохи)
Пользователям доступно большое количество встроенных колбеков
Написание собственного колбека
Вот простой пример сохранения списка значений попакетных потерь во время обучения:
Сохранение контрольных точек моделей
Когда вы обучаете модель на относительно больших датасетах, крайне важно сохранять чекпоинты вашей модели через определенные промежутки времени.
Проще всего сделать это с помощью колбека ModelCheckpoint :
Вы также можете написать собственный колбек для сохранения и восстановления моделей.
Использование графиков скорости обучения
Обычным паттерном при тренировке моделей глубокого обучения является постепенное сокращение скорости обучения по мере тренировки модели. Это общеизвестно как «снижение скорости обучения».
График снижения скорости может быть как статичным (зафиксированным заранее, как функция от индекса текущей эпохи или текущего пакета) так и динамическим (зависящим от текущего поведения модели в частности от потерь на валидации).
Передача расписания оптимизатору
Вы можете легко использовать график статического снижения скорости обучения передав объект расписания в качестве аргумента learning_rate вашему оптимизатору:
Использование колбеков для реализации графика динамического изменения скорости обучения
Расписание динамического изменения скорости обучения (например, уменьшение скорости обучения, когда потери при валидации более не улучшаются) не может быть достигнуто с этими объектами расписания, поскольку оптимизатор не имеет доступа к показателям валидации.
Визуализация потерь и метрик во время обучения
Лучший способ следить за вашей моделью во время обучения — это использовать TensorBoard — приложение на основе браузера, которое вы можете запустить локально и которое предоставляет вам:
Использование колбека TensorBoard
В простейшем случае просто укажите, куда вы хотите, чтобы колбек писал логи, и все готово:
Колбек TensorBoard имеет много полезных опций, в том числе, писать ли лог вложений, гистограмм и как часто писать логи:
Часть II: Написание собственных циклов обучения и оценки с нуля
Использование GradientTape: первый полный пример
Вызов модели внутри области видимости GradientTape позволяет получить градиенты обучаемых весов слоя относительно значения потерь. Используя экземпляр оптимизатора, вы можете использовать эти градиенты для обновления переменных (которые можно получить с помощью model.trainable_weights ).
Давайте переиспользуем нашу первоначальную модель MNIST из первой части и обучим ее, используя мини-пакетный градиентный спуск с кастомным циклом обучения.
Низкоуровневая обработка метрик
Давайте рассмотрим метрики. Вы можете легко использовать встроенные метрики (или собственные, которые вы написали) в таких, написанных с нуля, циклах обучения. Вот последовательность действий:
Низкоуровневая обработка дополнительных потерь
В общем вы можете захотеть учесть эти потери в своих пользовательских циклах обучения (если только вы сами не написали модель и уже знаете, что она не создает таких потерь).
Вспомните пример из предыдущего раздела, где есть слой, который создает потери регуляризации:
Когда вы вызываете модель так:
потери которые она создает во время прямого прохода добавляются в атрибут model.losses :
Чтобы учесть эти потери во время обучения, все, что вам нужно сделать, это модифицировать цикл обучения, добавив к полному значению потерь sum(model.losses) :
Это была последняя часть паззла! Вы достигли конца руководства.
Сейчас вы знаете все, что нужно об использовании встроенных циклов обучения и написании своих собственных с нуля.
Сохранение и загрузка моделей машинного обучения в Python с помощью scikit-learn
Дата публикации 2016-06-08
В этом посте вы узнаете, как сохранить и загрузить модель машинного обучения в Python с помощью scikit-learn.
Это позволяет сохранить вашу модель в файл и загрузить ее позже, чтобы делать прогнозы.
Завершите свою модель с рассолом
Вы можете использоватьсоленый огурецоперация, чтобы сериализовать ваши алгоритмы машинного обучения и сохранить сериализованный формат в файл.
Позже вы можете загрузить этот файл, чтобы десериализовать вашу модель и использовать ее для новых прогнозов.
Пример ниже демонстрирует, как вы можете обучить модель логистической регрессии наПима индейцы начало набора данных диабета, сохраните модель в файл и загрузите ее, чтобы делать прогнозы для невидимого набора тестов (обновление:скачать отсюда).
Выполнение примера сохраняет модель вfinalized_model.savв вашем локальном рабочем каталоге. Загрузка сохраненной модели и ее оценка дает оценку точности модели на невидимых данных.
Завершите свою модель с JobLib
Joblibявляется частью экосистемы SciPy и предоставляет утилиты для конвейерной работы Python.
Это обеспечиваетутилиты для сохранения и загрузки объектов Pythonкоторые эффективно используют структуры данных NumPy.
Это может быть полезно для некоторых алгоритмов машинного обучения, которые требуют много параметров или хранят весь набор данных (например, K-Nearest Neighbours).
Приведенный ниже пример демонстрирует, как вы можете обучить модель логистической регрессии на наборе данных диабета у индейцев пима, сохранить модель в файл с помощью joblib и загрузить ее, чтобы сделать прогнозы на невидимом наборе тестов.
Выполнение примера сохраняет модель в файл какfinalized_model.savа также создает один файл для каждого массива NumPy в модели (четыре дополнительных файла). После загрузки модели оценивается точность модели по невидимым данным.
Советы по доработке вашей модели
В этом разделе перечислены некоторые важные соображения при доработке ваших моделей машинного обучения.
Запомните версию, чтобы вы могли заново создать среду, если по какой-то причине вы не можете перезагрузить модель на другом компьютере или другой платформе позже.
Резюме
В этом посте вы узнали, как сохранить свои алгоритмы машинного обучения в Python с помощью scikit-learn.
Вы изучили две техники, которые вы можете использовать:
У вас есть вопросы о сохранении и загрузке алгоритмов машинного обучения или об этом посте? Задайте свои вопросы в комментариях, и я сделаю все возможное, чтобы ответить на них.