Всем привет! Я продолжаю участвовать в проектах с открытым исходным кодом, связанных с наукой о данных и машинным обучением. Я собираюсь поделиться своим опытом участия в проекте с открытым исходным кодом — Оптуна. Я сделал несколько вещей:
- Объединение Visual Studio Code и Docker с помощью расширений Docker для Visual Studio Code.
- Общение с разработчиком Оптуны для устранения возникших проблем
- Написал модульные тесты
- Отправленный запрос на слияние
- Изменен код, отражающий обратную связь с запросом на слияние.
Первый вклад в библиотеку Pandas был объединен!
Мой первый вклад в библиотеку Pandas получил одобрение и был объединен с основной веткой.
Прочтите мою статью об этом вкладе.
См. Pull Request — https://github.com/pandas-dev/pandas/pull/44007
Оптуна
Optuna — это программная среда для автоматической оптимизации гиперпараметров, разработанная для машинного обучения. Раньше я не использовал эту структуру, но хотел бы применить ее в своих будущих проектах по машинному обучению.
Проблема
https://github.com/optuna/optuna/issues/3037 — проблема
Проблема, над которой я работаю, связана с модульными тестами.
В Optuna есть тюнеры гиперпараметров для LightGBM, LightGBM с перекрестной проверкой:
- https://optuna.readthedocs.io/en/stable/reference/generated/optuna.integration.lightgbm.LightGBMTuner.html#optuna-integration-lightgbm-lightgbmtuner
- https://optuna.readthedocs.io/en/stable/reference/generated/optuna.integration.lightgbm.LightGBMTunerCV.html#optuna.integration.lightgbm.LightGBMTunerCV
Говоря о проблеме, мне нужно написать модульные тесты, чтобы убедиться, что значения аргументов по умолчанию для тюнеров optuna совпадают с соответствующими методами оригинального LightGBM:
- https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.train.html
- https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.cv.html
Первый подход
Мой первый подход заключался в доступе к значениям аргументов по умолчанию через атрибуты объекта. В приведенном ниже коде показано, как я получил доступ к значениям аргументов по умолчанию для LightGBMTuner от Optuna.
import optuna
import numpy as np
from optuna.integration._lightgbm_tuner.optimize import _BaseTuner
from optuna.integration._lightgbm_tuner.optimize import _OptunaObjective
from optuna.integration._lightgbm_tuner.optimize import _OptunaObjectiveCV
from optuna.integration._lightgbm_tuner.optimize import LightGBMTuner
from optuna.integration._lightgbm_tuner.optimize import LightGBMTunerCV
import optuna.integration.lightgbm as lgb
from typing import Dict
train_dataset = lgb.Dataset(np.zeros((10, 10)))
valid_dataset = lgb.Dataset(np.zeros((10, 10)))
params: Dict = {}
runner = lgb.LightGBMTuner(
params,
train_dataset,
valid_sets=[valid_dataset]
)
runner.lgbm_kwargs
Выход
{'callbacks': None,
'categorical_feature': 'auto',
'early_stopping_rounds': None,
'evals_result': None,
'feature_name': 'auto',
'feval': None,
'fobj': None,
'keep_training_booster': False,
'learning_rates': None,
'num_boost_round': 1000,
'valid_names': None,
'valid_sets': [<lightgbm.basic.Dataset at 0x7f9fdcb41590>],
'verbose_eval': True}
Однако мне не удалось найти способ получить параметры значений по умолчанию из оригинального LightGBM. Я попытался получить к нему доступ через их метод attr()
, но вместо этого я получил только пустой объект. Кроме того, я попытался получить к нему доступ через атрибут класса Booster
, но получил только два значения аргумента.
import lightgbm as lgb1
model = lgb1.train(params, train_dataset)
model._Booster__attr
Выход
{'early_stopping_round': None, 'num_iterations': 100}
Итак, после нескольких часов гугления, я решил обратиться за помощью к члену Optuna Kento Nozawa.
Кенто Нозава предложил отличное решение проблемы. Я протестировал код в Google Colab и перешел в Visual Studio Code.
Страница вклада
Первым делом я зашел на страницу вклада. Там я узнал, как внести свой вклад в проект Оптуна:
- Настройка Оптуны
- Проверка формата, стиля кода
- Модульные тесты
Встреча с первыми проблемами
У меня были проблемы с установкой зависимостей. Возможно, некоторые модули (библиотеки) установлены некорректно.
После нескольких часов гугления я решил сменить интерпретатор в Visual Studio Code.
Это действительно помогло, однако это была небольшая проблема.
Сначала я думал, что решил проблему. После этого я попытался протестировать некоторые скрипты Optuna для модульного тестирования.
pytest tests/integration_tests/lightgbm_tuner_tests/test_optimize.py
Затем я столкнулся со следующей проблемой.
Я подумал, что, возможно, что-то не так с моей средой разработки. Итак, я решил перейти на контейнеры Docker, чтобы иметь изолированную среду.
Докер
В прошлый раз я использовал Docker через терминал. Я решил интегрировать Docker в Visual Studio Code, установив расширения Docker:
- https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker
- https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
В папке проекта находится образ Dockerfile.
Для создания образа я могу легко использовать расширение Docker.
С расширением вы можете запускать контейнер Docker.
Это создаст новое окно разработки кода Visual Studio с запущенным контейнером Docker.
После этого я успешно установил все зависимости.
Теперь я могу работать в Visual Studio Code, и все мои изменения кода будут отражаться в контейнере Docker.
Написание модульных тестов
Модульное тестирование проверяет, что отдельные блоки кода работают должным образом.
Забавное видео про модульные тесты и код-ревью :)
Документация Visual Studio Code по модульным тестам — https://code.visualstudio.com/docs/python/testing
Я написал 2 модульных теста:
- Модульный тест, который обеспечивает согласованность аргументов по умолчанию между поездом LightGBM и тюнером LightGBM от Optuna.
2. Модульный тест, обеспечивающий согласованность аргументов по умолчанию между LightGBM CV и LightGBM Tuner CV от Optuna.
Когда часть написания кода была завершена, я начал проверять форматирование кода с помощью существующих утилит, которые предоставляет Optuna.
Создание запроса на включение
Я сделал пулреквест — https://github.com/optuna/optuna/pull/3070
Там я описал то, что я сделал. Кроме того, я связался с рецензентом по поводу обновления кода на основе отзывов.
Заключение
Я узнал о модульных тестах и о том, как писать модульные тесты на Python. Кроме того, я улучшил свои навыки работы с Docker, интегрировав его с Visual Studio Code через расширения.