Termination#
Optimizerは、交換可能なトップレベルコンポーネントであるTerminationに、最適化をいつ停止するかの判断を委譲します。Optimizer.set_termination(termination)で渡します。Stage互換経路(同期パイプライン)では、各世代の終了時にis_terminated(ctx) -> boolが呼び出されます。
Terminationの役割#
Termination(*conditions)は1つ以上の条件を受け取り、そのいずれか1つでも真になった時点で終了します(OR結合)。 コンストラクタに複数条件を渡す書き方は、後述するany_ofと同じ意味になります。
from saealib import Termination, max_fe, max_gen
termination = Termination(max_fe(2000), max_gen(100))
クラスメソッドも用意されています。
クラスメソッド |
意味 |
|---|---|
|
いずれか1つで終了( |
|
全て満たすまで終了しない |
|
条件を満たさない間だけ終了しない |
組み込み終了条件#
Terminationに渡す各条件は、TerminationConditionという薄いラッパーです。 組み込みのファクトリ関数はいずれもTerminationConditionを返します。
関数 |
終了条件 |
|---|---|
|
評価回数が |
|
世代数が |
|
アーカイブの最良目的値が |
|
|
stalledが返すTerminationConditionは、内部に「これまでの最良スコア」をクロージャで保持する状態付きの条件です。 1回のrunにつき1つのインスタンスを使う想定であり、複数のrunで使い回すと前回の状態が残ってしまいます。
Terminationの拡張#
TerminationConditionは抽象基底クラスではなく、任意のcallableを受け取って|(OR)/&(AND)/~(NOT)という演算子オーバーロードを提供する合成用のラッパーです。 OptimizationState -> boolを返すプレーンな関数はどこでも自動的にTerminationConditionへ変換されるため、独自の終了条件を追加するのに基底クラスを継承する必要はありません。
from saealib import Termination, max_fe
def my_condition(ctx):
f = ctx.archive.get("f")
return f is not None and len(f) > 0 and f.min() < 1e-6
termination = Termination(max_fe(2000), my_condition)
名前や説明文を明示的に持たせたい場合だけ、TerminationCondition(func, name=..., doc=...)で明示的にラップします。
複数の条件は演算子で宣言的に組み合わせられます。
from saealib import max_fe, max_gen, stalled
both = max_fe(2000) & max_gen(100) # continues until both are met
either = max_gen(100) | max_fe(2000) # stops on whichever comes first
not_stalled = ~stalled(20) # while not stalled
注釈
TerminationCondition のコンストラクタの spec 引数は、Registry がプリセットへシリアライズするときに使う内部フィールドであり、通常のユーザーコードで意識する必要はありません。
関連コンポーネント#
OptimizationState:各終了条件が受け取る
ctx拡張ガイドライン:
Registryによる設定駆動の構築