Overview
Utility classes for the MQF2 (Multivariate Quantile Function Forecaster) metric, providing neural convex flow networks and a distribution class for quantile-based probabilistic forecasting.
Description
This module provides three core classes for the MQF2 metric. DeepConvexNet extends DeepConvexFlow from the CP-Flow library and wraps a partially input convex neural network (PICNN) with logdet computation for normalizing flows, supporting both energy score and maximum likelihood objectives. SequentialNet extends SequentialFlow to chain multiple DeepConvexNet and ActNorm layers, providing forward passes, energy score sampling, and energy score computation. MQF2Distribution extends torch.distributions.Distribution to provide a full distribution interface including loss computation (energy score or negative log-likelihood), log_prob, rsample for generating sample paths, and quantile function evaluation. An additional TransformedMQF2Distribution class handles affine transformations for scaled predictions.
Usage
Use these classes when implementing or extending the MQF2 probabilistic forecasting metric. DeepConvexNet and SequentialNet are building blocks for the neural quantile function, while MQF2Distribution provides the distribution interface for training (loss) and inference (rsample, quantile).
Code Reference
Source Location
Signature: DeepConvexNet
class DeepConvexNet(DeepConvexFlow):
def __init__(
self,
picnn: torch.nn.Module,
dim: int,
is_energy_score: bool = False,
estimate_logdet: bool = False,
m1: int = 10,
m2: int | None = None,
rtol: float = 0.0,
atol: float = 1e-3,
) -> None:
Signature: SequentialNet
class SequentialNet(SequentialFlow):
def __init__(self, networks: list[torch.nn.Module]) -> None:
Signature: MQF2Distribution
class MQF2Distribution(Distribution):
def __init__(
self,
picnn: torch.nn.Module,
hidden_state: torch.Tensor,
prediction_length: int,
is_energy_score: bool = True,
es_num_samples: int = 50,
beta: float = 1.0,
threshold_input: float = 100.0,
validate_args: bool = False,
) -> None:
Signature: TransformedMQF2Distribution
class TransformedMQF2Distribution(TransformedDistribution):
def __init__(
self,
base_distribution: MQF2Distribution,
transforms: list[AffineTransform],
validate_args: bool = False,
) -> None:
Import
from pytorch_forecasting.metrics._mqf2_utils import (
DeepConvexNet,
SequentialNet,
MQF2Distribution,
TransformedMQF2Distribution,
)
I/O Contract
DeepConvexNet Inputs
| Name |
Type |
Required |
Description
|
| picnn |
torch.nn.Module |
Yes |
A partially input convex neural network
|
| dim |
int |
Yes |
Dimension of the input
|
| is_energy_score |
bool |
No |
If True, use energy score objective; otherwise add quadratic term for strict convexity (default False)
|
| estimate_logdet |
bool |
No |
If True, use stochastic logdet estimation; otherwise use brute force (default False)
|
| m1 |
int |
No |
Dimension of Krylov subspace for Lanczos tridiagonalization (default 10)
|
| m2 |
int or None |
No |
Iteration count for conjugate gradient algorithm
|
| rtol |
float |
No |
Relative tolerance for conjugate gradient (default 0.0)
|
| atol |
float |
No |
Absolute tolerance for conjugate gradient (default 1e-3)
|
SequentialNet Inputs
| Name |
Type |
Required |
Description
|
| networks |
list[torch.nn.Module] |
Yes |
List of DeepConvexNet and/or ActNorm layer instances
|
MQF2Distribution Inputs
| Name |
Type |
Required |
Description
|
| picnn |
torch.nn.Module |
Yes |
A SequentialNet instance of PICNN
|
| hidden_state |
torch.Tensor |
Yes |
Hidden state from RNN encoder; shape (batch_size, context_length, hidden_size) for training or (batch_size, hidden_size) for inference
|
| prediction_length |
int |
Yes |
Length of the prediction horizon
|
| is_energy_score |
bool |
No |
If True, use energy score; else use MLE/normalizing flows (default True)
|
| es_num_samples |
int |
No |
Number of samples for energy score approximation (default 50)
|
| beta |
float |
No |
Hyperparameter for energy score power (default 1.0)
|
| threshold_input |
float |
No |
Clamping threshold for scaled input in MLE mode (default 100.0)
|
| validate_args |
bool |
No |
Whether to enable distribution argument validation (default False)
|
MQF2Distribution Outputs
| Name |
Type |
Description
|
| loss |
torch.Tensor |
Energy score or negative log-likelihood of shape (batch_size * context_length,)
|
| samples |
torch.Tensor |
Sample paths of shape (batch_size, *sample_shape, prediction_length) from rsample
|
| quantiles |
torch.Tensor |
Predicted paths of shape (batch_shape, prediction_length) from quantile method
|
Usage Examples
import torch
from pytorch_forecasting.metrics._mqf2_utils import (
MQF2Distribution,
SequentialNet,
DeepConvexNet,
)
# Assuming picnn_model is a partially input convex neural network
# and hidden_state is obtained from an RNN encoder
# Create distribution for training
dist = MQF2Distribution(
picnn=sequential_net,
hidden_state=hidden_state, # (batch, context_len, hidden_size)
prediction_length=24,
is_energy_score=True,
es_num_samples=50,
)
# Compute loss
observations = torch.randn(32, 24 + 96 - 1) # (batch, context+pred-1)
loss = dist.loss(observations)
# Generate samples for inference
samples = dist.rsample(torch.Size([100])) # (batch, 100, prediction_length)
# Get quantile predictions
alpha = torch.rand(32, 24) # (batch, prediction_length)
quantile_preds = dist.quantile(alpha)
Related Pages