optora.dro.kl_dro¶
KL-divergence-constrained ambiguity set (KL-DRO).
KLAmbiguitySet
¶
Bases: DualAmbiguitySet
KL-divergence-constrained ambiguity set for KL-DRO.
Bounds every candidate distribution q by
\(D_{\mathrm{KL}}(q \,\|\, \mathrm{nominal}) \le \mathrm{radius}\). The
worst-case expected loss over this set admits a convex dual (Hu and Hong
2013; Ben-Tal et al. 2013):
reducing the worst-case expectation to a one-dimensional convex
minimization over the dual variable \(\eta\). dual_solver solves this
minimization over \(\log(\eta)\) rather than \(\eta\) directly, so the
unconstrained GradientDescent solver keeps \(\eta\) strictly positive
throughout the iteration. This formulation needs no optimal-transport
machinery, making it the simplest DRO formulation to build (see
progress/architecture.md).
Attributes:
| Name | Type | Description |
|---|---|---|
nominal |
Tensor
|
Reference distribution the ambiguity set is centered on. |
divergence |
|
|
radius |
float | Tensor
|
Nonnegative bound on the KL divergence of any distribution
inside the ambiguity set from |
eps |
Small positive constant used to clamp |
|
dual_solver |
Solver minimizing the dual objective over |
|
initial_dual_point |
Tensor
|
Value of |
log_nominal |
Tensor
|
Elementwise logarithm of the clamped |
__init__(nominal, radius, eps=1e-12, dual_solver=None, initial_log_eta=0.0, validate=False)
¶
Initialize the KL-DRO ambiguity set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nominal
|
Tensor
|
Reference distribution the ambiguity set is centered on, a nonnegative tensor that sums to one along its last dimension. |
required |
radius
|
float | Tensor
|
Nonnegative bound on the KL divergence of any
distribution inside the ambiguity set from |
required |
eps
|
float
|
Small positive constant used to clamp |
1e-12
|
dual_solver
|
Solver[MinimizationProblem, MinimizationResult] | None
|
Solver minimizing the dual objective over
|
None
|
initial_log_eta
|
float
|
Value of |
0.0
|
validate
|
bool
|
Whether to check that |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
worst_case_expectation(loss)
¶
Compute the worst-case expected loss over the KL ambiguity set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loss
|
Tensor
|
Per-scenario loss values of shape |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
A tensor of shape |
Tensor
|
the exact |
Tensor
|
ambiguity set then contains only |
Tensor
|
convex dual objective evaluated at the |
Tensor
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
RuntimeError
|
If |
contains(candidate)
¶
Check whether a candidate distribution lies inside the ambiguity set.
The answer is returned as a boolean tensor on candidate's device
rather than as a Python bool, so membership can be used as a mask
or composed with further tensor work without forcing a
device-to-host synchronization. Call bool(...) on the result only
where a host-side branch is genuinely needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
candidate
|
Tensor
|
Candidate distribution with the same shape as
|
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
A boolean tensor that is |
Tensor
|
|
reset_warm_start()
¶
Discard the cached dual optimum so the next solve starts cold.
After this call the next worst_case_expectation starts from
initial_dual_point again, as the first one did.