AcquisitionFunction#
SurrogatePredictStageはSurrogateの予測をAcquisitionStageへ渡し、スカラー化をAcquisitionFunctionへ委譲します。
AcquisitionFunctionは候補、予測、アーカイブ、コンテキスト、準備済みデータを受け取りますが、Surrogateの内部実装や予測を生成したアルゴリズムは知りません。
AcquisitionFunctionの役割#
AcquisitionFunctionが実装するメソッドはevaluate(candidates_x, prediction, archive, ctx=None, *, prepared=...) -> AcquisitionResultです。
点ごとの基準には、便利な基底クラスPointwiseAcquisitionがこの処理を2つのメソッドに分けます。
compute_reference(archive, rng=None) -> Any:PointwiseAcquisitionで、スコアリングに使う参照値(現在の最良値など)をアーカイブから計算します。
参照値を使わない獲得関数はNoneを返してよいです。
score(prediction, reference, rng=None) -> np.ndarray:PointwiseAcquisitionで、SurrogatePredictionと参照値からスコアを計算します。
saealib全体の規約どおり、スコアは高いほど良いです。
compute_reference()はctxを受け取らないため、実行時状態が必要なサブクラス(ctx.decision_countを読むLowerConfidenceBoundの beta_scheduleなど)は代わりにprepare(archive, ctx=None)を直接オーバーライドします。その戻り値はreferenceとしてscore()にそのまま渡されます。
クラス属性requires_uncertainty: boolは、この獲得関数がSurrogatePrediction.std(不確実性)を必要とするかを示します。
direction_sensitive: bool(既定True)は、Optimizerが実行開始時にproblem.directionをこの獲得関数へ自動注入する対象かどうかを示します。
実行可能性確率のように目的の方向という概念を持たない獲得関数は、direction_sensitive = Falseにしてこの自動注入を無効化します。
組み込みAcquisitionFunction#
クラス |
特徴 |
|
|---|---|---|
|
予測平均のみを使う、最も単純な獲得関数 |
|
|
期待改善量(EI)[24] |
|
|
バッチの多様性を考慮したqEI風選択用の同時EI |
|
|
信頼下限(LCB)[25] |
|
|
予測の不確実性が大きいほど良い(探索寄り) |
|
|
|
|
|
SMS-EMOA風のハイパーボリューム指標(Ponweiser et al., 2008が提案するSMS-EGO)。多目的向け |
|
|
|
|
|
|
|
|
複数制約の実行可能性確率の積[32] |
|
|
アーカイブの最近傍点までの平均距離 |
|
|
アーカイブ近傍密度の逆数 |
|
|
候補とアーカイブの多様性基準 |
|
表の不確実性ベースの獲得関数はrequires_uncertainty=Trueです。
アーカイブベースの獲得関数(NoveltyAcquisition、InverseDensityAcquisition、MaximinDistanceAcquisition)は予測の不確実性を必要としません。
不確実性ベースの獲得関数を使うには、組み合わせるSurrogateがstdを返す(provides_uncertainty=True)必要があります。
バッチ獲得関数には、候補の共分散など明示的な同時事後分布の表現も必要です。
この契約の決定論的な実装例はサンプルを参照してください。組み込みSurrogateではSklearnGPRSurrogateだけがこれを満たします。詳細はSurrogateの不確実性対応表を参照してください。
MaxUncertainty/ProbabilityOfFeasibility/ProductOfFeasibilityはdirection_sensitive = Falseです。
不確実性の大きさや実行可能性確率は、目的の最大化と最小化という方向の概念を持たないためです。
ProbabilityOfFeasibility/ProductOfFeasibilityは、制約値gを予測する分類サロゲートや回帰サロゲートと組み合わせて使います。
TrainingSetのConstraintObjectiveSetで学習データを抽出し、目的側の獲得関数(EIなど)とCompositeAcquisitionのproduct_combineで組み合わせるのが典型的な使い方です。
ei_manager = GlobalSurrogateManager(gp_surrogate, ArchiveObjectiveSet())
pof_manager = GlobalSurrogateManager(
PerObjectiveSurrogate([gp_g1, gp_g2]),
ConstraintObjectiveSet(),
)
optimizer.set_surrogate_manager(
CompositeSurrogateManager({"objective": ei_manager, "feasibility": pof_manager})
)
optimizer.set_acquisition(
CompositeAcquisition(
{"objective": ExpectedImprovement(), "feasibility": ProductOfFeasibility()},
product_combine,
)
)
weights/direction引数の意味#
MeanPredictionなど一部の獲得関数は、weights引数で多目的予測をスカラー化できます。
weights=np.array([-1.0])のように、最小化したい目的には負の重みを使います。
direction引数を指定すると、大きさを持たない符号だけのスカラー化になり、weightsよりも優先されます。
directionを明示しない場合、実行開始時にproblem.directionが自動的に注入されます(direction_sensitiveがTrueの獲得関数のみ)。
独自AcquisitionFunctionの実装方法#
独自の点ごとのスコアリング方式が必要な場合は、PointwiseAcquisitionを継承してcompute_reference()/score()を実装します。
次の例は、予測平均が閾値を下回る候補ほど高いスコアを与える単純な獲得関数です。
from saealib import PointwiseAcquisition
class ThresholdAcquisition(PointwiseAcquisition):
"""Gives a higher score to candidates whose predictive mean falls further below a threshold (assumes minimization)."""
def __init__(self, threshold: float = 0.0):
self.threshold = threshold
def compute_reference(self, archive, rng=None):
return None
def score(self, prediction, reference=None, rng=None):
m = prediction.value[:, 0]
return self.threshold - m
Optimizer.set_acquisition()へ渡して組み込みます。
注釈
Optimizer.validate() detects and warns about a mismatch between the acquisition function's requires_uncertainty and the surrogate's provides_uncertainty.
This warning will catch you if you pair an acquisition function with requires_uncertainty=True with a surrogate that doesn't return std.
関連コンポーネント#
Surrogate:
SurrogatePredictionの提供元。不確実性対応表もこちらを参照するSurrogateManager:
AcquisitionFunctionへ予測を提供するTrainingSet:
ProbabilityOfFeasibility/ProductOfFeasibilityと組み合わせる制約用データ抽出