optimal_transport
optimal_transport
¶
Loss functions using Sinkhorn Optimal Transport (geomloss + pykeops).
IMPORTANT: geomloss is imported lazily to avoid PyKeOps JIT compilation overhead.
OptimalTransportLoss
¶
OptimalTransportLoss(action_keys, weight=1.0, p=2, blur_fraction=0.1, reach_multiplier=None, expected_std=1.0, time_scale=1.0)
Bases: ScalarWeightedLoss
Debiased Sinkhorn divergence between predicted and target action chunks.
Note
Uses GeomLoss SamplesLoss(loss="sinkhorn", ...) with
debias=True, implementing the Sinkhorn divergence
S_eps(a, b) = OT_eps(a, b) - 0.5 * OT_eps(a, a) - 0.5 * OT_eps(b, b)
(Feydy et al., AISTATS 2019, arXiv:1810.08278). Debiasing is
essential: raw entropic OT does not vanish on identical
distributions and its minimizer is a shrunk version of the target.
Interpolation property (Feydy et al. 2019): small blur: S -> Wasserstein distance W_p large blur: S -> (1/2) MMD with negative-cost kernel k = -c
A linear time embedding in [0, 1] * time_scale is concatenated to each action vector before the Sinkhorn computation, giving OT a soft temporal-alignment preference: coupling actions at similar trajectory positions is cheaper than coupling across time. time_scale=0 gives permutation-invariant OT over the horizon.
Unbalanced variant: passing reach_multiplier enables JUMBOT-style unbalanced OT (Fatras et al., ICML 2021, arXiv:2103.03606), letting outlier mass be dropped at a KL cost rather than force-matched.
Reference: Genevay, Peyre, Cuturi (AISTATS 2018, arXiv:1706.00292) "Learning Generative Models with Sinkhorn Divergences".
Requires the optional dependencies geomloss and pykeops
(pip install geomloss pykeops). Imported lazily to avoid
PyKeOps JIT compilation unless this loss is instantiated.
Initializes the OptimalTransportLoss.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action_keys
|
list[str]
|
List of keys for action tensors in predictions and targets. |
required |
weight
|
float
|
Scaling factor for the total loss. |
1.0
|
p
|
int
|
Exponent for the ground cost. p=1 gives |
2
|
blur_fraction
|
float
|
Dimensionless Sinkhorn regularization, expressed as a fraction of the reference pairwise scale sqrt(2 * dim) * expected_std. GeomLoss recommends ~0.1. |
0.1
|
reach_multiplier
|
float | None
|
Unbalanced OT scale, as a multiple of the
reference pairwise scale. |
None
|
expected_std
|
float
|
Expected per-dimension standard deviation of the action samples. For actions normalized to [-1, 1], use ~1/sqrt(3) ~ 0.577. |
1.0
|
time_scale
|
float
|
Scaling factor for the linear time embedding concatenated to actions. time_scale=0 gives permutation-invariant OT over the horizon. |
1.0
|
Raises:
| Type | Description |
|---|---|
ImportError
|
If geomloss is not installed. |
Source code in src/versatil/metrics/losses/optimal_transport.py
get_required_keys
¶
forward
¶
Computes the forward pass for the OT loss.
Flattens and masks actions for composite cost ||a - a'||^p then applies debiased Sinkhorn OT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
predictions
|
dict[str, Tensor]
|
Dict of predicted action tensors. |
required |
targets
|
dict[str, Tensor]
|
Dict of target action tensors. |
required |
is_pad
|
Tensor | None
|
Optional padding mask (B, horizon); True where padded. |
None
|
Returns:
| Type | Description |
|---|---|
LossOutput
|
LossOutput with total weighted loss and the Sinkhorn component. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If required action keys are missing in predictions or targets. |
Source code in src/versatil/metrics/losses/optimal_transport.py
LatentOptimalTransportLoss
¶
LatentOptimalTransportLoss(weight=1.0, p=2, blur_fraction=0.1, reach_multiplier=None, prior_target_key=value)
Bases: ScalarWeightedLoss
Debiased Sinkhorn divergence between posterior and prior latent samples.
Regularizes the aggregate posterior q(z) = E_x[q(z|x)] toward the
prior p(z) via sample-based OT (WAE strategy with Sinkhorn instead
of MMD). Only the aggregate posterior is constrained to match the
prior, so per-sample posteriors remain free to separate.
Note
Assumes the latent samples have approximately unit per-dimension standard deviation, which holds for the Gaussian-reparameterized and LayerNorm-output transformer posteriors and priors.
Initialize latent OT loss.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
weight
|
float
|
Scaling factor for the total loss. |
1.0
|
p
|
int
|
Exponent for the ground cost. p=2 is standard for W_2-style regularization of latent distributions. |
2
|
blur_fraction
|
float
|
Dimensionless Sinkhorn regularization, as a fraction of the reference pairwise scale sqrt(2 * dim). |
0.1
|
reach_multiplier
|
float | None
|
Unbalanced OT scale, as a multiple of the
reference pairwise scale. |
None
|
prior_target_key
|
str
|
Posterior output key used as aggregate prior-matching samples.
Use |
value
|
Raises:
| Type | Description |
|---|---|
ImportError
|
If geomloss is not installed. |
Source code in src/versatil/metrics/losses/optimal_transport.py
get_required_keys
¶
forward
¶
Compute Sinkhorn divergence between posterior and prior latents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
predictions
|
dict[str, Tensor]
|
Must contain posterior and prior latent tensors of shape (B, latent_dim). |
required |
targets
|
dict[str, Tensor]
|
Unused. |
required |
is_pad
|
Tensor | None
|
Unused. |
None
|
Returns:
| Type | Description |
|---|---|
LossOutput
|
LossOutput with Sinkhorn divergence loss. |
Source code in src/versatil/metrics/losses/optimal_transport.py
RelaxedConditionalLatentOptimalTransportLoss
¶
RelaxedConditionalLatentOptimalTransportLoss(weight=1.0, p=2, blur_fraction=0.1, reach_multiplier=None, prior_target_key=value, condition_key=value, state_weight=1.0, normalize_condition=True)
Bases: LatentOptimalTransportLoss
Relaxed conditional Sinkhorn loss over joint state-latent samples.
This matches empirical (s, z_posterior) samples to (s, z_prior)
samples. A finite state_weight lets mass move across nearby state
vectors.
Initialize relaxed conditional latent OT loss.
Source code in src/versatil/metrics/losses/optimal_transport.py
get_required_keys
¶
forward
¶
Compute relaxed conditional Sinkhorn divergence.