Optuna是特別為機器學(xué)習(xí)而設(shè)計的一個自動超參數(shù)優(yōu)化軟件框架幽七。它具有命令式的谬运、隨運行而定義的用戶API爽冕。用Optuna編寫的代碼具有高度的模塊化仇祭,Optuna的用戶可以動態(tài)地構(gòu)造超參數(shù)的搜索空間披蕉。
參考
Akiba T, Sano S, Yanase T, et al. Optuna: A next-generation hyperparameter optimization framework[C]//Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. 2019: 2623-2631.
Optuna的使用
使用Optuna至少需要了解3個東西:Trail 對象颈畸,Study 對象和objective函數(shù)。
1. Trail 對象
一個trail實例是一個評估目標(biāo)函數(shù)的過程没讲。該實例被傳遞給一個目標(biāo)函數(shù)眯娱,并提供了獲取參數(shù)建議、管理狀態(tài)爬凑、設(shè)置/獲取用戶自定義的trail屬性的接口徙缴,以便Optuna用戶可以通過這些接口定義自定義的目標(biāo)函數(shù)。
對象方法如下:
方法 | 描述 |
---|---|
report(value, step) | Report an objective function value for a given step. |
set_system_attr(key, value) | 設(shè)置系統(tǒng)屬性 |
set_user_attr(key, value) | 設(shè)置用戶屬性 |
should_prune() | 是否應(yīng)被剪枝 |
suggest_categorical(name, choices) | 為分類型參數(shù)建議一個值 |
suggest_discrete_uniform(name, low, high, q) | 為離散型參數(shù)建議一個值 |
suggest_float(name, low, high, *, [step, log]) | 為浮點型參數(shù)建議一個值 |
suggest_int(name, low, high, [step, log]) | 為整型參數(shù)建議一個值 |
suggest_loguniform(name, low, high) | 為對數(shù)域連續(xù)型參數(shù)建議一個值 |
suggest_uniform(name, low, high) | 為連續(xù)型參數(shù)建議一個值 |
官方文檔中有較詳細的論述和用例,例如report和should_prune可以結(jié)合起來使用剪枝表現(xiàn)不好的trail于样,set_user_attr可用于保存模型的固定參數(shù)疏叨。
2. objective函數(shù)
objective函數(shù)需要用戶自己編寫,主要有下面三個要求:
以trail作為函數(shù)參數(shù)
定義超參數(shù)和尋參范圍
返回模型目標(biāo)函數(shù)值
一個簡單的objective函數(shù)例子如下:
def objective(trial: optuna.trial.Trial): # 以trail作為參數(shù)
x = trial.suggest_uniform("x", 0, 10) # 定義參數(shù)和尋參范圍
return x ** 2 # 返回模型目標(biāo)函數(shù)值
3. Study對象
一個study相當(dāng)于一個優(yōu)化任務(wù)穿剖,即一組試驗蚤蔓。這個對象提供接口來運行一個新的trail,訪問其歷史糊余,設(shè)置/獲取用戶自定義的study本身的屬性秀又。
4. 如何使用
下面的代碼展示了一個簡單的使用Optuna優(yōu)化超參數(shù)的例子,具體應(yīng)用的核心在于根據(jù)自己的模型改寫objective函數(shù)贬芥。
# 定義模型訓(xùn)練函數(shù)
def train(data, params):
pass
# 返回指標(biāo)吐辙,如損失,精度等
return loss
# 定義objective函數(shù)
def objective(trial: optuna.trial.Trial):
# 定義模型超參數(shù)及其范圍
params = {
'n_layers_rnn': trial.suggest_int('n_layers_rnn', 1, 4),
'n_units_rnn': trial.set_user_attr('n_units_rnn', 256),
'activation': trial.suggest_categorical('activation', ['relu', 'tanh']),
'dropout': trial.suggest_uniform('dropout', 0.1, 0.7),
'lr': trial.suggest_loguniform('lr', 1e-6, 1e-2)
}
# 計算模型損失
loss = train(data, params)
# 返回損失
return loss
# 創(chuàng)建優(yōu)化任務(wù)
study = optuna.create_study(direction='minimize')
# 執(zhí)行優(yōu)化任務(wù)蘸劈,設(shè)置運行100次trial
study.optimize(objective, n_trials=100)
# 最優(yōu)結(jié)果
trial_ = study.best_trial
print(f'min loss: {trial_.value}') # 輸出最優(yōu)結(jié)果的損失值
print(f'best params: {trial_.params}') # 輸出最優(yōu)結(jié)果的模型超參數(shù)