USER
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[19], line 39
36 return float('-inf') # Возвращаем отрицательное бесконечное значение в случае ошибки
38 study = optuna.create_study(direction='maximize')
---> 39 study.optimize(objective, n_trials=100)
41 print("Best hyperparameters: ", study.best_params)
File ~/anaconda3/lib/python3.12/site-packages/optuna/study/study.py:475, in Study.optimize(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)
373 def optimize(
374 self,
375 func: ObjectiveFuncType,
(...)
382 show_progress_bar: bool = False,
383 ) -> None:
384 """Optimize an objective function.
385
386 Optimization is done by choosing a suitable set of hyperparameter values from a given
(...)
473 If nested invocation of this method occurs.
474 """
--> 475 _optimize(
476 study=self,
477 func=func,
478 n_trials=n_trials,
479 timeout=timeout,
480 n_jobs=n_jobs,
481 catch=tuple(catch) if isinstance(catch, Iterable) else (catch,),
482 callbacks=callbacks,
483 gc_after_trial=gc_after_trial,
484 show_progress_bar=show_progress_bar,
485 )
File ~/anaconda3/lib/python3.12/site-packages/optuna/study/_optimize.py:63, in _optimize(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)
61 try:
62 if n_jobs == 1:
---> 63 _optimize_sequential(
64 study,
65 func,
66 n_trials,
67 timeout,
68 catch,
69 callbacks,
70 gc_after_trial,
71 reseed_sampler_rng=False,
72 time_start=None,
73 progress_bar=progress_bar,
74 )
75 else:
76 if n_jobs == -1:
File ~/anaconda3/lib/python3.12/site-packages/optuna/study/_optimize.py:160, in _optimize_sequential(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)
157 break
159 try:
--> 160 frozen_trial = _run_trial(study, func, catch)
161 finally:
162 # The following line mitigates memory problems that can be occurred in some
163 # environments (e.g., services that use computing containers such as GitHub Actions).
164 # Please refer to the following PR for further details:
165 # https://github.com/optuna/optuna/pull/325.
166 if gc_after_trial:
File ~/anaconda3/lib/python3.12/site-packages/optuna/study/_optimize.py:248, in _run_trial(study, func, catch)
241 assert False, "Should not reach."
243 if (
244 frozen_trial.state == TrialState.FAIL
245 and func_err is not None
246 and not isinstance(func_err, catch)
247 ):
--> 248 raise func_err
249 return frozen_trial
File ~/anaconda3/lib/python3.12/site-packages/optuna/study/_optimize.py:197, in _run_trial(study, func, catch)
195 with get_heartbeat_thread(trial._trial_id, study._storage):
196 try:
--> 197 value_or_values = func(trial)
198 except exceptions.TrialPruned as e:
199 # TODO(mamu): Handle multi-objective cases.
200 state = TrialState.PRUNED
Cell In[19], line 12, in objective(trial)
9 divisors = get_divisors(n_steps)
11 # Используем suggest_categorical для выбора batch_size только из делителей n_steps
---> 12 batch_size = trial.suggest_categorical('batch_size', divisors)
14 learning_rate = trial.suggest_float('learning_rate', 1e-6, 1e-1, log=True)
15 gamma = trial.suggest_float('gamma', 0.9, 1.0)
File ~/anaconda3/lib/python3.12/site-packages/optuna/trial/_trial.py:402, in Trial.suggest_categorical(self, name, choices)
351 """Suggest a value for the categorical parameter.
352
353 The value is sampled from ``choices``.
(...)
397 :ref:`configurations` tutorial describes more details and flexible usages.
398 """
399 # There is no need to call self._check_distribution because
400 # CategoricalDistribution does not support dynamic value space.
--> 402 return self._suggest(name, CategoricalDistribution(choices=choices))
File ~/anaconda3/lib/python3.12/site-packages/optuna/trial/_trial.py:637, in Trial._suggest(self, name, distribution)
635 # `param_value` is validated here (invalid value like `np.nan` raises ValueError).
636 param_value_in_internal_repr = distribution.to_internal_repr(param_value)
--> 637 storage.set_trial_param(trial_id, name, param_value_in_internal_repr, distribution)
639 self._cached_frozen_trial.distributions[name] = distribution
640 self._cached_frozen_trial.params[name] = param_value
File ~/anaconda3/lib/python3.12/site-packages/optuna/storages/_in_memory.py:202, in InMemoryStorage.set_trial_param(self, trial_id, param_name, param_value_internal, distribution)
200 # Check param distribution compatibility with previous trial(s).
201 if param_name in self._studies[study_id].param_distribution:
--> 202 distributions.check_distribution_compatibility(
203 self._studies[study_id].param_distribution[param_name], distribution
204 )
206 # Set param distribution.
207 self._studies[study_id].param_distribution[param_name] = distribution
File ~/anaconda3/lib/python3.12/site-packages/optuna/distributions.py:678, in check_distribution_compatibility(dist_old, dist_new)
676 return
677 if dist_old != dist_new:
--> 678 raise ValueError(
679 CategoricalDistribution.__name__ + " does not support dynamic value space."
680 )
ValueError: CategoricalDistribution does not support dynamic value space.ASSISTANT
Ошибка `ValueError: CategoricalDistribution does not support dynamic value space` возникает, когда вы пытаетесь передать динамически созданный список значений в `Optuna` для параметра с помощью `suggest_categorical`. Это происходит потому, что `Optuna` пытается сохранить распределение (категории) для гиперпараметра между испытаниями, и динамический список не может быть использован для этого.
Для решения этой проблемы можно использовать один из следующих подходов:
1. **Заранее определенные значения**: вместо динамически вычисляемых делителей `n_steps` использовать фиксированный набор категорий для `batch_size`.
2. **Фиксированный диапазон для n_steps**: заранее определить диапазон для `n_steps`, так чтобы это значение всегда имело предсказуемые делители при создании `study`.
Вот как можно применить первое решение:
### Пример кода с фиксированным набором значений для `batch_size`
```python
import optuna
from stable_baselines3 import PPO # Убедитесь, что вы импортировали необходимые библиотеки
def get_possible_batch_sizes():
"""Функция для возвращения фиксированного набора допустимых значений для batch_size."""
return [2, 4, 8, 16, 32] # Задайте допустимые значения batch_size
def objective(trial):
# Оптимизация n_steps
n_steps = trial.suggest_int('n_steps', 16, 4096, log=True)
# Получаем фиксированные значения для batch_size
batch_sizes = get_possible_batch_sizes()
# Выбираем batch_size из фиксированных значений
batch_size = trial.suggest_categorical('batch_size', batch_sizes)
# Настройка других гиперпараметров
learning_rate = trial.suggest_float('learning_rate', 1e-6, 1e-1, log=True)
gamma = trial.suggest_float('gamma', 0.9, 1.0)
model = PPO('MlpPolicy', env, n_steps=n_steps, learning_rate=learning_rate,
batch_size=batch_size, verbose=0)
try:
model.learn(total_timesteps=30000)
# Тестирование модели для получения вознаграждения
obs = env.reset()
total_reward = 0.0
done = False
while not done:
action, _states = model.predict(obs)
obs, reward, done, info = env.step(action)
total_reward += reward
return float(total_reward) # Возвращаем скалярное значение
except Exception as e:
print(f"An error occurred during training: {e}")
return float('-inf') # Возвращаем отрицательное бесконечное значение в случае ошибки
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
print("Best hyperparameters: ", study.best_params)
```
### Объяснения:
1. **get_possible_batch_sizes**: Эта функция возвращает фиксированный набор значений для `batch_size`, которые вы хотите использовать. Подберите значения так, чтобы в них были наиболее распространенные делители.
2. **suggest_categorical**: Теперь мы используем заранее заданный список значений, чтобы `Optuna` мог корректно обрабатывать распределение.
В этом подходе избегается динамическая генерация значений в процессе выполнения и устраняются ошибки, связанные с невозможностью использования динамических категорий. Вы также можете адаптировать значения внутри `get_possible_batch_sizes` в зависимости от специфики вашей задачи и допустимых значений.