我想用 optuna 优化我的卷积自动编码器的超参数,但我一直收到这个错误,没有完成任何试验。有什么想法吗?
[W 2023-04-22 17:57:07,202] 试验 0 失败,参数为:{'learning_rate': 0.0001, 'weight': 1e-06, 'drop': 0.8, 'conv1': 128, 'conv2' : 8, 'conv3': 128, 'fc': 130, 'latent_dim': 100} 因为以下错误:值 None 无法转换为 float..
[W 2023-04-22 17:57:07,228] 试验 0 失败,值为 None。
ValueError:尚未完成试验。
这是代码: `
class Encoder_cae1_hp(nn.Module):
def __init__(self, hyperparameters=dict):
super().__init__()
self.encoder = nn.Sequential(
nn.Conv1d(1,hyperparameters['conv1'],5, stride=3),
nn.Dropout(hyperparameters['drop']),
nn.Conv1d(hyperparameters['conv1'], hyperparameters['conv2'], 3, stride=3),
nn.LeakyReLU(),
nn.Conv1d(hyperparameters['conv2'], hyperparameters['conv3'], 4, stride=2),
nn.Dropout(hyperparameters['drop']),
nn.LeakyReLU(),
nn.Flatten(start_dim=1),
nn.Linear(2924*hyperparameters['conv3'], hyperparameters['fc']),
nn.Linear(hyperparameters['fc'], hyperparameters['latent_dim']))
def forward(self, x):
z = self.encoder(x)
return z
class Decoder_cae1_hp(nn.Module):
def __init__(self, hyperparameters=dict):
super().__init__()
self.decoder = nn.Sequential(
nn.Linear(hyperparameters['latent_dim'], hyperparameters['fc']),
nn.Linear(hyperparameters['fc'], 2924*hyperparameters['conv3']),
nn.Unflatten(dim=1, unflattened_size=(hyperparameters['conv3'], 2924)),
nn.ConvTranspose1d(hyperparameters['conv3'], hyperparameters['conv2'], 4, stride=2,output_padding=1),
nn.LeakyReLU(),
nn.Dropout(hyperparameters['drop']),
nn.ConvTranspose1d(hyperparameters['conv2'], hyperparameters['conv1'], 3, stride=3, padding =0, output_padding=2),
nn.LeakyReLU(),
nn.Dropout(hyperparameters['drop']),
nn.ConvTranspose1d(hyperparameters['conv1'], 1, 5, stride=3, padding =0, output_padding=1)
)
def forward(self, x):
reconstruction = self.decoder(x)
return reconstruction
#%% Hyperparameters
def objective(trial: optuna.trial.Trial) -> float:
learning_rate = trial.suggest_categorical("learning_rate", [1e-5, 1e-4, 1e-3])
weight = trial.suggest_categorical("weight", [1e-5, 1e-4, 1e-3, 1e-2, 1e-6])
drop = trial.suggest_float("drop", 0.0, 1, step = 0.2)
conv1 = trial.suggest_categorical("conv1", [8, 16, 32, 64, 128])
conv2 = trial.suggest_categorical("conv2", [8, 16, 32, 64, 128])
conv3 = trial.suggest_categorical("conv3", [8, 16, 32, 64, 128])
fc = trial.suggest_categorical("fc", [30, 50, 70, 100, 130, 270, 320])
latent_dim = trial.suggest_categorical("latent_dim", [20,40,60,80,100])
train_batch = trial.suggest_categorical("train_batch", [10,20,40,60,80,100])
loss_fn = nn.MSELoss()
hyperparameters = {
'learning_rate': learning_rate,
'drop':drop,
'conv1':conv1,
'conv2':conv2,
'conv3':conv3,
'fc':fc,
'weight':weight,
'latent_dim':latent_dim
}
#%%
data = dataset.linearized_matrices()
encoder = Encoder_cae1_hp(hyperparameters = hyperparameters)
decoder = Decoder_cae1_hp(hyperparameters = hyperparameters)
#%% Train the optimizer
train_points, val_points = train_test_split(data, test_size= 0.1, shuffle=True, random_state = 0)
train_points = dataset.Dataset(train_points, transform = dataset.ToTensor())
validation_points = dataset.Dataset(val_points, transform = dataset.ToTensor())
train_points_dl= DataLoader(train_points, batch_size = train_batch, shuffle= True)
validation_points_dl= DataLoader(validation_points, batch_size = len(validation_points), shuffle=False)
optimizer = torch.optim.Adam([{'params': encoder.parameters()},{'params': decoder.parameters()}], lr = hyperparameters['learning_rate'], weight_decay = hyperparameters['weight'])
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
print(f'Selected device: {device}')
encoder.to(device)
decoder.to(device)
try:
num_epochs = 30
for epoch in range(num_epochs):
print(f'################# \n | EPOCH {epoch+1} | \n')
train_loss = train.train(encoder, decoder, device, train_points_dl, loss_fn, optimizer)
print(f'\t Average train loss for epoch: {train_loss.data}')
val_loss, _ = test.test(encoder, decoder, device, validation_points_dl, loss_fn)
print('\n\t VALIDATION - EPOCH %d/%d - loss: %f\n' % (epoch + 1, num_epochs, val_loss))
if trial.should_prune():
raise optuna.exceptions.TrialPruned()
trial.report(val_loss)
return val_loss
except RuntimeError:
trial.set_user_attr("constraint", (1,))
def print_best_callback(study, trial):
print(f"Best value: {study.best_value}, Best params: {study.best_trial.params}")
#%%
study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials = 800, gc_after_trial = True, callbacks=[print_best_callback])
And the test function that returns the val_loss:
def test(encoder, decoder, device, dataloader, loss_fn):
encoder.eval()
decoder.eval()
latent_codes = dict(z = [], subj_id = [])
with torch.no_grad():
for subj, image_batch in dataloader:
image_batch = image_batch.to(device)
z = encoder(image_batch)
reconstruction = decoder(z)
latent_codes['z'].append(z.detach().cpu())
latent_codes['subj_id'].append(subj)
val_loss = loss_fn(reconstruction, image_batch)
return val_loss.data, latent_codes
`