optuna的python并行化
在超参数优化的Python库中,常用的有两个,一个是Hyperopt,另一个是Optuna。
有一篇文章很好的总结了两者的优劣之处,【机器学习】Optuna vs Hyperopt 超参数优化哪家强?_风度78的博客-CSDN博客,我这里选择了具有更好可视化和使用更加简单的Optuna作为超参数优化的工具。
在使用Optuna的过程中,想要提高超参数优化的速度,就要进行并行化操作。在Optuna的参数中有着对于并行化的简单设置,其中仅仅在自己的电脑上使用并行化,只需要更改study.optimize()
方法中的n_jobs
参数,其中n_jobs
的数值根据CPU的最大进程数设定,或者直接设定n_jobs=-1
study.optimize(objective, n_trials=100, n_jobs=12)
但是实际上在使用时,CPU并没有跑满,这是因为Python 的 GIL(全局解释器锁)阻止这些线程并行运行。因此,直接修改n_jobs是不起作用的,需要使用pythonjoblib
中的Parallel
进行并行化处理。同时可以使用SQLite
作为储存。
一个使用joblib
中的Parallel方法的例子如下:
Optuna example that optimizes a quadratic function in parallel using joblib. (github.com)
from joblib import Parallel, delayed
import optuna
# Define a simple 2-dimensional objective function whose minimum value is -1 when (x, y) = (0, -1).
def objective(trial):
x = trial.suggest_uniform('x', -100, 100)
y = trial.suggest_categorical('y', [-1, 0, 1])
return x**2 + y
def optimize(n_trials):
study = optuna.load_study(study_name='joblib-quadratic', storage='sqlite:///example.db')
study.optimize(objective, n_trials=n_trials)
if __name__ == '__main__':
# Let us minimize the objective function above.
print('Running 10 trials...')
study = optuna.create_study(study_name='joblib-quadratic', storage='sqlite:///example.db')
r = Parallel(n_jobs=-1)([delayed(optimize)(10) for _ in range(10)])
print('Number of finished trials: ', len(study.trials))
print('Best trial:')
trial = study.best_trial
print(' Value: ', trial.value)
print(' Params: ')
for key, value in trial.params.items():
print(' {}: {}'.format(key, value))