Optuna Pytorch: возвращаемое значение целевой функции не может быть преобразовано в float

def autotune(trial):

      cfg= { 'device' : "cuda" if torch.cuda.is_available() else "cpu",
         #   'train_batch_size' : 64,
         #   'test_batch_size' : 1000,
         #   'n_epochs' : 1,
         #   'seed' : 0,
         #   'log_interval' : 100,
         #   'save_model' : False,
         #   'dropout_rate' : trial.suggest_uniform('dropout_rate',0,1.0),
            'lr' : trial.suggest_loguniform('lr', 1e-3, 1e-2),
            'momentum' : trial.suggest_uniform('momentum', 0.4, 0.99),
            'optimizer': trial.suggest_categorical('optimizer',[torch.optim.Adam,torch.optim.SGD, torch.optim.RMSprop, torch.optim.$
            'activation': F.tanh}
      optimizer = cfg['optimizer'](model.parameters(), lr=cfg['lr'])
      #optimizer = torch.optim.Adam(model.parameters(),lr=0.001

Как вы можете видеть выше, я пытаюсь запустить испытания Optuna для поиска наиболее оптимальных гиперпараметров для моей модели CNN.

# Train the model
# use small epoch for large dataset
# An epoch is 1 run through all the training data
# losses = [] # use this array for plotting losses
      for _ in range(epochs):
    # using data_loader 
         for i, (data, labels) in enumerate(trainloader):
        # Forward and get a prediction
        # x is the training data which is X_train
            if name.lower() == "rnn":
                model.hidden = (torch.zeros(1,1,model.hidden_sz),
                    torch.zeros(1,1,model.hidden_sz))

            y_pred = model.forward(data)

        # compute loss/error by comparing predicted out vs acutal labels
            loss = criterion(y_pred, labels)
        #losses.append(loss)

            if i%10==0:  # print out loss at every 10 epoch
                 print(f'epoch {i} and loss is: {loss}')

        #Backpropagation
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

study = optuna.create_study(sampler=optuna.samplers.TPESampler(), direction='minimize',pruner=optuna.pruners.SuccessiveHalvingPrune$
study.optimize(autotune, n_trials=1)

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

[W 2020-11-11 13:59:48,000] Trial 0 failed, because the returned value from the objective function cannot be cast to float. Returned value is: None
Traceback (most recent call last):
  File "autotune2", line 481, in <module>
    n_instances, n_features, scores = run_analysis()
  File "autotune2", line 350, in run_analysis
    print(study.best_params)
  File "/home/shar/anaconda3/lib/python3.7/site-packages/optuna/study.py", line 67, in best_params
    return self.best_trial.params
  File "/home/shar/anaconda3/lib/python3.7/site-packages/optuna/study.py", line 92, in best_trial
    return copy.deepcopy(self._storage.get_best_trial(self._study_id))
  File "/home/shar/anaconda3/lib/python3.7/site-packages/optuna/storages/_in_memory.py", line 287, in get_best_trial
    raise ValueError("No trials are completed yet.")
ValueError: No trials are completed yet.

person Tonz    schedule 11.11.2020    source источник


Ответы (1)


Это исключение возникает из-за того, что целевая функция из вашего исследования должна возвращать число с плавающей запятой.

В вашем случае проблема в этой строке:

study.optimize(autotune, n_trials=1)

Функция автонастройки, которую вы определили ранее, не возвращает значения и не может использоваться для оптимизации.

Как исправить?

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

Быстрое исправление вашего кода может быть примерно таким:

def autotune():
  cfg= { 'device' : "cuda" if torch.cuda.is_available() else "cpu"
        ...etc...
       }

  best_loss = 1e100;  # or larger

  # Train the model
  for _ in range(epochs):
     for i, (data, labels) in enumerate(trainloader):
        ... (train the model) ...
        # compute loss/error by comparing predicted out vs actual labels
        loss = criterion(y_pred, labels)
        best_loss = min(loss,best_loss)

  return best_loss

В репозитории Optuna есть хороший пример с Pythorch, который использует обратный вызов pythoch для получения точности (но при необходимости его можно легко изменить для использования RMSE). Также используется более одного эксперимента и берется медиана гиперпараметров.

person Iñigo    schedule 24.11.2020