単目的最適化#
評価コストの高い目的関数を持つ単目的最適化問題を、saealibで解きます。
まず問題を定義し、高レベルAPIの minimize で単目的最適化を実行します。
各コンポーネントの詳しい仕様やカスタマイズ方法は、この後の節からリンクするコンポーネント配下の各ページを参照してください。
このページでできるようになること
このページを終えると、高コストな単目的関数を minimize() で最適化できます。
目的関数を渡してすぐ実行したいだけなら高レベルAPI、コンポーネントを責務から選びたい場合はビルトインコンポーネントの差し替えを参照してください。このページではminimize()による単目的最適化を実行し、文字列引数でアルゴリズム、Surrogate、評価Strategyを選びます。
問題を設定する#
シミュレーションのように、1回の呼び出しに時間がかかる目的関数を想定します。
ここでは例として、評価コストの高さを模したSphere関数を最小化します。
import numpy as np
def expensive_func(x):
# assume a function that is expensive to call in practice
return np.sum(x**2)
DIM = 10
LB = [-5.0] * DIM
UB = [5.0] * DIM
DIMは設計変数の次元数、LBとUBはその下限と上限を与えるDIM次元のリストです。
目的関数は、DIM次元の設計変数を受け取り、目的関数値を返すCallableとして定義します。
高レベルAPI:minimize / maximize#
minimizeは、dim、lb、ubを指定するだけで最適化を実行できる高レベルAPIです。
from saealib import minimize
result = minimize(expensive_func, dim=DIM, lb=LB, ub=UB, seed=0)
print(result.x) # optimal design variables shape: (dim,)
print(result.f) # optimal objective value shape: (n_obj,)
print(result.fe) # true function evaluations
print(result.gen) # completed generations
最大評価回数max_feを省略すると、200 * dimが既定値として使われます。
評価回数を明示的に制限するには、次のように指定します。
result = minimize(expensive_func, dim=DIM, lb=LB, ub=UB, max_fe=500, seed=0)
コンポーネントの切り替え#
minimizeは、進化的アルゴリズム、サロゲートモデル、評価戦略という3つのコンポーネントを、それぞれalgorithm、surrogate、strategy引数の文字列で切り替えられます。
3つとも、文字列の代わりにインスタンスを直接渡すこともできます。
各コンポーネントの内部動作やカスタマイズ方法は、Algorithm、Surrogate、OptimizationStrategyのページで扱います。
アルゴリズム#
algorithm引数は、候補解を生成する進化的アルゴリズムを選びます。
文字列 |
クラス |
特徴 |
|---|---|---|
|
|
交叉と突然変異による探索(既定) |
|
|
粒子の速度更新による探索 |
result = minimize(expensive_func, dim=DIM, lb=LB, ub=UB, algorithm="PSO", seed=0)
Surrogate#
surrogate引数は、目的関数を近似するサロゲートモデルを選びます。
文字列 |
解決される構成 |
説明 |
|---|---|---|
|
|
ガウスRBFカーネルによる近傍点の局所フィット |
result = minimize(expensive_func, dim=DIM, lb=LB, ub=UB, surrogate="rbf", seed=0)
評価戦略#
strategy引数は、生成した候補解のうちどれに真の(高コストな)評価を行うかを決める評価戦略を選びます。
文字列 |
クラス |
動作 |
|---|---|---|
|
|
候補を個別にサロゲートで評価し、上位 |
|
|
|
|
|
大量の候補をサロゲートで絞り込み、上位 |
result = minimize(expensive_func, dim=DIM, lb=LB, ub=UB, strategy="ib", seed=0)
minimize() の既定構成では足りない場合は、各コンポーネントを個別に構成して Optimizer に登録できます。Optimizerを低レベルAPIで組み立てる では、Terminationの複数条件や iterate() による世代ごとの進捗取得も扱います。