Краткое руководство по созданию нейронных сетей PyTorch с Pycaret

Практически в каждом проекте машинного обучения мы обучаем и оцениваем несколько моделей машинного обучения. Это часто включает в себя написание нескольких строк импорта, множества вызовов функций, операторов печати для обучения отдельных моделей и сравнения результатов по моделям. Код превращается в беспорядок при сравнении разных моделей с циклами перекрестной проверки или при объединении моделей. Со временем все становится еще сложнее, когда мы переходим от моделей классификации к моделям регрессии или наоборот. В итоге мы копируем фрагменты кода из одного места в другое, создавая хаос! Избежать этого хаоса легко, просто импортировав PyCaret!

PyCaret - это машинная библиотека с низким кодом, которая позволяет создавать, обучать и тестировать модели машинного обучения через унифицированный API с учетом проблемы регрессии или классификации. PyCaret также предлагает различные этапы проекта машинного обучения, от подготовки данных до развертывания модели с минимальным объемом кода. Он может работать с любой моделью / библиотекой, которая соответствует API Scikit-Learn, например, Scikit-Learn Models, Xgboost, LightGBM, CatBoost и т. Д. В целом, библиотека представляет собой простой в использовании инструмент повышения производительности, который позволяет проводить быстрые эксперименты и поможет вам сосредоточиться на текущей бизнес-проблеме.

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

Что, если вы можете использовать тот же PyCaret с нейронными сетями с минимальными изменениями?

Да, вы не ослышались! SKORCH делает это возможным! SKORCH - это оболочка Scikit-Learn для PyTorch, которая позволяет обучать нейронные сети с помощью API, подобного sklearn, чего и ожидает PyCaret!

Многие ресурсы объясняют, как использовать Pycaret для построения моделей машинного обучения с помощью одной строчки кода! А также обучающие программы и примеры использования SKORCH для построения нейронных сетей. Рекомендуется ознакомиться с этими руководствами, прежде чем переходить к следующим частям этого блога. К этой записной книжке, содержащей код, можно относиться параллельно.

В этом блоге мы увидим

  • как построить нейронную сеть в SKORCH
  • как обучить нейронную сеть с PyCaret
  • как настроить нейронные сети с PyCaret

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

Для этого урока мы собираемся использовать набор данных «электрическая_сетка». Это задача двоичной классификации, содержащая 12 входных функций и одну целевую переменную. Этот набор данных доступен во встроенных наборах данных, которые поставляются с PyCaret, и к нему можно получить доступ, импортировав и вызвав функцию get_data, как показано

from pycaret.datasets import get_data
data = get_data('electrical_grid')

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

Как создавать нейронные сети с помощью SKORCH

PyTorchModel

SKORCH работает с моделями PyTorch; мы можем создать простую модель для начала так же, как мы это делаем при использовании чистого PyTorch. Мы построим трехуровневый MLP, как показано, который имеет 12 входов для первого уровня, поскольку у нас есть 12 функций в данных и два выхода для обоих классов.

import torch.nn as nn
class Net(nn.Module):
    def __init__(self, num_inputs=12, num_units_d1=200, num_units_d2=100):
        super(Net, self).__init__()
        self.dense0 = nn.Linear(num_inputs, num_units_d1)
        self.nonlin = nn.ReLU()
        self.dropout = nn.Dropout(0.5)
        self.dense1 = nn.Linear(num_units_d1, num_units_d2)
        self.output = nn.Linear(num_units_d2, 2)
        self.softmax = nn.Softmax(dim=-1)
    def forward(self, X, **kwargs):
        X = self.nonlin(self.dense0(X))
        X = self.dropout(X)
        X = self.nonlin(self.dense1(X))
        X = self.softmax(self.output(X))
        return X

Классификатор Скорча

Теперь, когда мы определили сетевую архитектуру, мы должны создать экземпляр нейронной сети, совместимой со sklearn, с помощью SKORCH, что выполняется путем импорта NeuralNetClassifier из skorch. Мы работаем над задачей классификации.

from skorch import NeuralNetClassifier
net = NeuralNetClassifier(
    module=Net,
    max_epochs=30,
    lr=0.1,
    batch_size=32,
    train_split=None
)

Самый важный аргумент, который необходимо передать, - это модуль, который принимает имя определенного nn.Module, в этом случае мы передаем ему Net. Точно так же мы можем передать другие аргументы max_epochs, указывающие, сколько эпох для обучения модели, и lr скорость обучения для оптимизатора, batch_size. Установить размер мини-партии. Мы будем придерживаться оптимизатора SGD по умолчанию, используемого в Skorch, и его можно изменить на любой настраиваемый оптимизатор, как описано здесь.

Skorch по умолчанию использует пятикратную перекрестную проверку. Таким образом, в каждом сплите 80% образцов находятся в очереди и 20% образцов являются проверочными. Это можно отключить, передав train_split = None, что мы и собираемся сделать, поскольку мы будем использовать PyCaret для обучения моделей, который уже использует перекрестную проверку для обучения моделей.

Как обучить нейронные сети с PyCaret

DataFrameTransformer

Теперь, когда мы инициализировали модель SKORCH NN, мы можем обучить модель с помощью PyCaret. Здесь мы должны помнить, что PyCaret по своей сути работает с pandas.DataFrames во время различных операций, но в модели Skorch он не может передавать данные непосредственно в модель. (подробнее об этом здесь) Следовательно, нам нужно построить sklearn Pipeline nn_pipe с помощью skorch.helper.DataFrameTransformer, чтобы преобразовать ввод, переданный PyCaret, в требуемый формат в дополнение к модели. Спасибо IncubatorShokuhou за определение этого.

from skorch.helper import DataFrameTransformer
nn_pipe = Pipeline(
    [
        ("transform", DataFrameTransformer()),
        ("net", net),
    ]
)

Настройка PyCaret

Теперь мы, наконец, готовы с нашей моделью и можем обучать ее, поскольку мы решили использовать PyCaret для обучения модели вместо Skorch API. Давайте быстро расскажем о PyCaret. Перед обучением какой-либо модели с помощью PyCaret нам необходимо инициировать эксперимент, вызвав функцию настройки, которая выполняет все шаги предварительной обработки, которыми, конечно же, можно управлять с помощью аргументов, передаваемых в функцию.

from pycaret.classification import *
target = "stabf"
clf1 = setup(data = data, 
            target = target,
            train_size = 0.8,
            fold = 5,
            session_id = 123,
            log_experiment = True, 
            experiment_name = 'electrical_grid_1', 
            silent = True)

Мы передаем данные, имя целевого столбца, train_size, количество складок, используемых при перекрестной проверке, в качестве основных аргументов настройки. Мы установим для log_experiment значение True, чтобы отслеживать эксперименты с MLFlow, и зададим экспериментальное_имя, чтобы мы могли вернуться и обратиться к результатам на более позднем этапе. Кроме того, мы установим аргумент silent в значение True, чтобы избежать шага «нажмите Enter, чтобы продолжить» на этапе настройки.

Модель PyCaret Train ML

Чтобы обучить модель ml, мы можем вызвать функцию create_model с аббревиатурой модели, которую мы хотим обучить. В этом случае мы можем выполнить create_model («rf») для обучения классификатора случайного леса.

model = create_model("rf")

Теперь PyCaret создает экземпляр RandomForestClassifier с параметрами по умолчанию, обучает модель пятикратной модели и распечатывает результаты, как показано.

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

Модель PyCaret Train Skorch

Теперь, когда мы знаем, как работает PyCaret, давайте обучим созданную нами модель Скорча. Хорошая вещь с Pycaret заключается в том, что create_model принимает любой объект, совместимый с Sklearn API. Поэтому мы можем передать nn_pipe, который мы создали выше, в функцию create_model, как показано ниже.

Опять же, create_model берет модель Скорча, тренирует модель по пяти сгибам и распечатывает результаты. А обученная модель скорча теперь сохраняется в переменной skorch_model.

Сравнение моделей

Теперь мы можем сравнить обе эти модели, передав их в виде списка функции compare_models в PyCaret. Функция сравнения моделей теперь будет обучать обе модели на свертках перекрестной проверки и записывать средние значения cv для сравнения моделей по желаемой метрике. Мы можем установить желаемую метрику, передав строку параметру сортировки; давайте использовать в нашем примере «AUC».

best_model = compare_models(include=[skorch_model, rf_model], sort="AUC"

Как настроить нейронные сети с помощью SKORCH

Настройка сетки гиперпараметров

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

custom_grid = {
	'net__max_epochs':[20, 30],
	'net__lr': [0.01, 0.05, 0.1],
	'net__module__num_units_d1': [50, 100, 150],
	'net__module__num_units_d2': [50, 100, 150],
	'net__optimizer': [optim.Adam, optim.SGD, optim.RMSprop]
	}

Обратите внимание, что имя модуля и параметры разделены двойным «__», потому что именно так NeuralNetClassifier ожидает, что аргументы будут переданы, чтобы он мог создать экземпляры требуемых модулей. Кроме того, здесь «net» представляет сетевую переменную, которую мы создали из NeuralNetClassifier, а «module» представляет сетевой модуль, который мы создали для модели Pytorch.

Если вы хотите узнать список параметров модели, вы можете просмотреть их, выполнив Estimator.get_params (). Keys (). Если в данном случае оценщиком является переменная skorch_model, skorch_model.get_params (). Keys () выводит следующий результат:

Обратите внимание, что аргументы net__module__num_units_d1 / 2 отсутствуют в выводе на печать, поскольку они не являются аргументами для skorch_model, а являются аргументами для сети; следовательно, они должны быть установлены с помощью net__module __ **.

Тюнинг

После настройки сетки гиперпараметров мы должны вызвать функцию tune_model из pycaret и передать модель и custom_grid в качестве аргументов для настройки. Здесь также мы можем выбирать из различных алгоритмов / библиотек настройки, поддерживаемых PyCaret, которые перечислены в документации.

tuned_skorch_model = tune_model(skorch_model, custom_grid=custom_grid)

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

Функция tune_model () возвращает настроенную модель, которая теперь доступна в переменной tuned_skorch_model.

Сравнение моделей

Опять же, мы можем сравнить эти модели, передав их в виде списка функции compare_models в PyCaret.

best_model = compare_models(include=[tuned_skorch_model, skorch_model, rf_model], sort="AUC")

К сожалению, нет возможности передать в качестве аргумента названия моделей. Поэтому и tuned_skorch_model, и skorch_model называются NeuralNetClassifier (который автоматически идентифицируется PyCaret). Я предполагаю, что второй ряд - это настроенная модель, а третий - ненастроенная.

Кроме того, этот блог посвящен тому, чтобы показать, как мы можем использовать Skorch с Pycaret для создания моделей PyTorch с минимальным кодом. В частности, он не ориентирован на улучшение характеристик модели.

Примечание.

  1. Здесь функция compare_models используется после create_model или tuned_model, но pycaret предлагает использовать compare_models в качестве первого шага для сравнения всех доступных моделей. Но цель здесь - объяснить, как использовать Skorch + Pytorch. Поэтому в данном случае это делается иначе. В общем, чтобы сравнивать разные модели после обучения, мы можем написать собственную функцию-оболочку. Мы можем передать список моделей и данных для оценки для получения результатов сравнения.

Панель управления MLFlow

Поскольку мы установили для log_experiment значение True в настройке PyCaret, все эксперименты регистрируются с помощью MLFlow, и мы ничего не делаем! Вуаля! Чтобы просмотреть все эксперименты, откройте терминал в рабочем каталоге и введите mlflow ui. Вы должны увидеть это в своем браузере, щелкнув URL-адрес, отображаемый в вашем терминале.

На картинке выше показаны все эксперименты, которые мы проводили в ноутбуке.

Заключение

Мы увидели, как Skorch и PyCaret могут обучать нейронные сети с минимальным кодом с преимуществом использования одного и того же API для обучения традиционных моделей машинного обучения и нейронных сетей. Кроме того, мы можем сравнить производительность всех моделей с помощью одной строчки кода и сохранить все показатели, сохраненные в MLFlow, с помощью одного аргумента! Я настоятельно рекомендую изучить официальную документацию PyCaret и Skorch, чтобы узнать больше о том, как использовать эти замечательные библиотеки и упростить эксперименты с ML!

использованная литература

  1. Https://pycaret.org/
  2. Https://www.analyticsvidhya.com/blog/2020/05/pycaret-machine-learning-model-seconds/
  3. Https://github.com/skorch-dev/skorch
  4. Https://towardsdatascience.com/skorch-pytorch-models-trained-with-a-scikit-learn-wrapper-62b9a154623e