aimclub / iOpt

Framework of intelligent optimization methods iOpt
https://iopt.readthedocs.io
BSD 3-Clause "New" or "Revised" License
51 stars 24 forks source link

Зацикливание при бесконечном значении функции #132

Closed YamLyubov closed 1 year ago

YamLyubov commented 1 year ago

Сейчас пробую добавить оптимизатор IOpt в FEDOT и столкнулась с такой проблемой.

Для задачи поиска гиперпараметров для композитных моделей машинного обучения бывает, что комбинация гиперпараметров может быть невалидной и для нее невозможно вычислить метрику (при обучении модели возвращается ошибка). В таком случае я попробовала возвращать оптимизатору худшее возможное значение метрики (для минимизации) - np.inf. Однако в таком случае алгоритм попадает в бесконечный цикл при попытке добавить dataItem в очередь, на первой итерации (это то, что мне удалось понять при дебаге, но возможно я не права).

Возможно, есть какой-то способ решить данную проблему? Подумала, что скорее всего поможет заменить np.inf на sys.maxsize, но решила все-таки рассказать о проблеме, вoзможно получится обработать такой экстремальный случай внутри IOpt.

Я использовала версию IOpt 0.1.6, но попробовала и текущую версию из main - алгоритм так же зависает.

Проблему сложно воспроизвести, если специально ничего не ломать, но вот код, который иногда ломается

import pandas as pd
from golem.core.tuning.iopt_tuner import IOptTuner

from fedot.core.data.data import InputData
from fedot.core.pipelines.pipeline_builder import PipelineBuilder
from fedot.core.pipelines.tuning.search_space import PipelineSearchSpace
from fedot.core.pipelines.tuning.tuner_builder import TunerBuilder
from fedot.core.repository.dataset_types import DataTypesEnum
from fedot.core.repository.tasks import TaskTypesEnum, Task, TsForecastingParams
from fedot.core.utils import fedot_project_root

search_space = PipelineSearchSpace().get_parameters_dict()

# Можно использовать
# pipeline = PipelineBuilder().add_node('cgru').build()
# чтобы сломать специально - тогда точно воспроизведется зацикливание
pipeline = PipelineBuilder().add_node('lagged').add_node('cgru').build()

task = Task(TaskTypesEnum.ts_forecasting, task_params=TsForecastingParams(forecast_length=10))
time_series = pd.read_csv(f'{fedot_project_root()}/examples/data/ts/beer.csv')
idx = time_series['idx'].values
time_series = time_series['value'].values
data = InputData(idx=idx,
                 features=time_series,
                 target=time_series,
                 task=task,
                 data_type=DataTypesEnum.ts)

tuner = TunerBuilder(task).with_tuner(IOptTuner).with_iterations(20).build(data)

tuner.tune(pipeline)

Датасет: https://github.com/aimclub/FEDOT/blob/master/examples/data/ts/beer.csv Я использую FEDOT и требования для него из своей ветки: https://github.com/aimclub/FEDOT/tree/add-iopt (pr https://github.com/aimclub/FEDOT/pull/1102) FEDOT использует реализацию тюнера на основе IOpt из этой ветки GOLEM: https://github.com/aimclub/GOLEM/tree/iopt-tuner Сам код IOptTuner: https://github.com/aimclub/GOLEM/blob/iopt-tuner/golem/core/tuning/iopt_tuner.py

YamLyubov commented 1 year ago

Пример вывода после которого алгоритм зависает image

MADZEROPIE commented 1 year ago

Для справки, заранее известно ли какие именно комбинации параметров невалидны? Или это можно определить только поймав исключение в рантайме? Если известны, то можно попробовать выразить их через функции-ограничения и попытаться использовать индексный метод. Но скорее всего это слишком сложный подход и так делать не надо...

kozinove commented 1 year ago

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

Я думаю что решение будет выражено в следующем виде. При невозможность вычислить критерий нужно будет кидать исключение. Метод будет исключение отлавливать и учитывать в вычислениях (способ учета основан на индексной схеме).

Конкретную имплементацию я думаю мы с командой обсудим в ближайшее время. С точки зрения пользователя не должно быть сложных схем. Пользователи не знают наши методы.

kozinove commented 1 year ago

Мы добавили прототип учета скрытых ограничений. Если вычислить значене критерия невозможно, то нужно выкидывать исключение. Модельный пример (строки 58-64) https://github.com/aimclub/iOpt/blob/main/problems/rastrigin_hidden_constraint.py

YamLyubov commented 1 year ago

Спасибо за ответ! Хотела бы узнать, когда у вас планируется следующий релиз? Чтобы можно было стабильную версию с этими обновлениями в GOLEM включить.

kozinove commented 1 year ago

Мы проводим финальные проверки версии кода с возможностью использования дискретных параметров. По использованию параметров в ближайшее время также подготовим пример и документацию. После будет выпущен релиз.