Несколько значений для одного параметра в команде mlflow run

Вопрос или проблема

Как передать несколько значений каждому параметру в команде mlflow run?

Цель состоит в том, чтобы передать словарь в GridSearchCV в качестве param_grid для выполнения перекрестной проверки.

В моем основном коде я получаю параметры командной строки с помощью argparse. Добавляя nargs=”+” в add_argument(), я могу записывать значения с пробелами для каждого гиперпараметра, а затем применить vars() для создания словаря. См. код ниже:

import argparse

# Создайте параметры для командной строки
param_names = list(RandomForestClassifier().get_params().keys())

# Типы параметров в том же порядке, в котором они появлются в param_names, используя get_params()
param_types = [bool, float, dict, str, int, float, int, float, float, float,
               float, float, float, int, int, bool, int, int, bool]

# Разрешить только необязательные аргументы командной строки
parser = argparse.ArgumentParser()
grid_group = parser.add_argument_group('param_grid_group')
for i, p in enumerate(param_names):
    grid_group.add_argument(f'--{p}', type=param_types[i], nargs="+")
# Создайте param_grid для передачи в GridSearchCV
param_grid_unprocessed = vars(parser.parse_args())

Это хорошо работает с классической командой python :

python my_code.py --max_depth 2 3 4 --n_estimators 400 600 1000

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

{'max_depth':[2, 3, 4], 'n_estimators':[400, 600, 1000]}

Однако с командой mlflow run я пока не могу это сделать, так как она принимает только одно значение для каждого параметра. Вот мой файл MLproject :

name: mlflow_project

conda_env: conda.yml

entry_points:

  main:
    parameters:
      max_depth: int
      n_estimators: int
    command: "python my_code.py --max_depth {max_depth} --n_estimators {n_estimators}"

Так что это работает :

mlflow run . -P max_depth=2 -P n_estimators=400

Но не это :

 mlflow run . -P max_depth=[2, 3, 4] -P n_estimators=[400, 600, 1000]

В документации кажется, что это невозможно сделать. Есть ли какой-либо способ обойти эту проблему?

Один из вариантов – перейти с argparse на fire. Fire – это сторонний пакет Python для создания интерфейсов командной строки (CLI). Fire имеет лучшую поддержку для группировки команд.

Ответ или решение

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

Проблема

Команда mlflow run не поддерживает передачу массивов через параметры, так как принимает только одно значение для каждого параметра. Ваш код с использованием argparse работает хорошо для классического запуска, но не может адаптироваться под ограничения mlflow.

Решение

  1. Использование JSON для передачи списков
    Один из способов обойти это ограничение – передать параметры в формате JSON. В вашем MLproject файле вам нужно будет изменить способ передачи параметров, чтобы он принимал строку и разбирал её в коде:

    name: mlflow_project
    
    conda_env: conda.yml
    
    entry_points:
    
     main:
       parameters:
         max_depth: str
         n_estimators: str
       command: "python my_code.py --max_depth {max_depth} --n_estimators {n_estimators}"

    Затем в вашем коде, используя argparse, вы можете разбирать эти строки в списки:

    import argparse
    import json
    
    parser = argparse.ArgumentParser()
    grid_group = parser.add_argument_group('param_grid_group')
    grid_group.add_argument('--max_depth', type=str)
    grid_group.add_argument('--n_estimators', type=str)
    
    params = vars(parser.parse_args())
    max_depth = json.loads(params['max_depth'])
    n_estimators = json.loads(params['n_estimators'])
    
    param_grid = {
       'max_depth': max_depth,
       'n_estimators': n_estimators
    }

    Теперь вы можете вызывать команду mlflow run, передавая значения в формате JSON:

    mlflow run . -P max_depth='[2, 3, 4]' -P n_estimators='[400, 600, 1000]'
  2. Использование несколько запусков mlflow
    В зависимости от ваших требований, возможно, имеет смысл запускать команду mlflow run несколько раз (например, используя скрипт), чтобы перебрать комбинации параметров. Например:

    from itertools import product
    
    depths = [2, 3, 4]
    estimators = [400, 600, 1000]
    
    for depth, estimator in product(depths, estimators):
       command = f"mlflow run . -P max_depth={depth} -P n_estimators={estimator}"
       os.system(command)
  3. Использование сторонних библиотек
    Как вы уже упомянули, вы можете рассмотреть возможность использования библиотеки, такой как Fire, для упрощения работы с CLI. Fire позволяет автоматически создавать командные интерфейсы из объектов Python и лучше обрабатывает такие структуры данных, как списки.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...