:mod:`torchfilter.base` ======================= .. py:module:: torchfilter.base .. autoapi-nested-parse:: Base classes for filtering. Package Contents ---------------- Classes ~~~~~~~ .. autoapisummary:: torchfilter.base.DynamicsModel torchfilter.base.Filter torchfilter.base.KalmanFilterBase torchfilter.base.KalmanFilterMeasurementModel torchfilter.base.ParticleFilterMeasurementModel torchfilter.base.ParticleFilterMeasurementModelWrapper torchfilter.base.VirtualSensorModel .. py:class:: DynamicsModel(*, state_dim: int) Bases: :class:`torch.nn.Module`, :class:`abc.ABC` .. autoapi-inheritance-diagram:: torchfilter.base.DynamicsModel :parts: 1 Base class for a generic differentiable dynamics model, with additive white Gaussian noise. Subclasses should override either ``forward`` or ``forward_loop`` for computing dynamics estimates. .. attribute:: state_dim Dimensionality of our state. :type: int .. method:: forward(self, *, initial_states: types.StatesTorch, controls: types.ControlsTorch) -> Tuple[types.StatesTorch, types.ScaleTrilTorch] Dynamics model forward pass, single timestep. Computes both predicted states and uncertainties. Note that uncertainties correspond to the (Cholesky decompositions of the) "Q" matrices in a standard linear dynamical system w/ additive white Gaussian noise. In other words, they should be lower triangular and not accumulate -- the uncertainty at at time ``t`` should be computed as if the estimate at time ``t - 1`` is a ground-truth input. By default, this is implemented by bootstrapping the ``forward_loop()`` method. :param initial_states: Initial states of our system. Shape should be ``(N, state_dim)``. :type initial_states: torch.Tensor :param controls: Control inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type controls: dict or torch.Tensor :returns: *Tuple[torch.Tensor, torch.Tensor]* -- Predicted states & uncertainties. States should have shape ``(N, state_dim)``\ , and uncertainties should be lower triangular with shape ``(N, state_dim, state_dim).`` .. method:: forward_loop(self, *, initial_states: types.StatesTorch, controls: types.ControlsTorch) -> Tuple[types.StatesTorch, torch.Tensor] Dynamics model forward pass, over sequence length ``T`` and batch size ``N``. By default, this is implemented by iteratively calling ``forward()``. Computes both predicted states and uncertainties. Note that uncertainties correspond to the (Cholesky decompositions of the) "Q" matrices in a standard linear dynamical system w/ additive white Gaussian noise. In other words, they should be lower triangular and not accumulate -- the uncertainty at at time ``t`` should be computed as if the estimate at time ``t - 1`` is a ground-truth input. To inject code between timesteps (for example, to inspect hidden state), use ``register_forward_hook()``. :param initial_states: Initial states to pass to our dynamics model. Shape should be ``(N, state_dim)``. :type initial_states: torch.Tensor :param controls: Control inputs. Should be either a dict of tensors or tensor of size ``(T, N, ...)``. :type controls: dict or torch.Tensor :returns: *Tuple[torch.Tensor, torch.Tensor]* -- Predicted states & uncertainties. States should have shape ``(T, N, state_dim)``\ , and uncertainties should be lower triangular with shape ``(T, N, state_dim, state_dim).`` .. method:: jacobian(self, initial_states: types.StatesTorch, controls: types.ControlsTorch) -> torch.Tensor Returns Jacobian of the dynamics model. :param states: Current state, size ``(N, state_dim)``. :type states: torch.Tensor :param controls: Control inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type controls: dict or torch.Tensor :returns: *torch.Tensor* -- Jacobian, size ``(N, state_dim, state_dim)`` .. py:class:: Filter(*, state_dim: int) Bases: :class:`torch.nn.Module`, :class:`abc.ABC` .. autoapi-inheritance-diagram:: torchfilter.base.Filter :parts: 1 Base class for a generic differentiable state estimator. As a minimum, subclasses should override: * ``initialize_beliefs`` for populating the initial belief of our estimator * ``forward`` or ``forward_loop`` for computing state predictions .. attribute:: state_dim Dimensionality of our state. :type: int .. method:: initialize_beliefs(self, *, mean: types.StatesTorch, covariance: types.CovarianceTorch) -> None :abstractmethod: Initialize our filter with a Gaussian prior. :param mean: Mean of belief. Shape should be ``(N, state_dim)``. :type mean: torch.Tensor :param covariance: Covariance of belief. Shape should be ``(N, state_dim, state_dim)``. :type covariance: torch.Tensor .. method:: forward(self, *, observations: types.ObservationsTorch, controls: types.ControlsTorch) -> types.StatesTorch Filtering forward pass, over a single timestep. By default, this is implemented by bootstrapping the ``forward_loop()`` method. :param observations: Observation inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type observations: dict or torch.Tensor :param controls: Control inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type controls: dict or torch.Tensor :returns: *torch.Tensor* -- Predicted state for each batch element. Shape should be ``(N, state_dim).`` .. method:: forward_loop(self, *, observations: types.ObservationsTorch, controls: types.ControlsTorch) -> types.StatesTorch Filtering forward pass, over sequence length ``T`` and batch size ``N``. By default, this is implemented by iteratively calling ``forward()``. To inject code between timesteps (for example, to inspect hidden state), use ``register_forward_hook()``. :param observations: observation inputs. Should be either a dict of tensors or tensor of size ``(T, N, ...)``. :type observations: dict or torch.Tensor :param controls: control inputs. Should be either a dict of tensors or tensor of size ``(T, N, ...)``. :type controls: dict or torch.Tensor :returns: *torch.Tensor* -- Predicted states at each timestep. Shape should be ``(T, N, state_dim).`` .. py:class:: KalmanFilterBase(*, dynamics_model: DynamicsModel, measurement_model: KalmanFilterMeasurementModel, **unused_kwargs) Bases: :class:`torchfilter.base.Filter`, :class:`abc.ABC` .. autoapi-inheritance-diagram:: torchfilter.base.KalmanFilterBase :parts: 1 Base class for a generic Kalman-style filter. Parameterizes beliefs with a mean and covariance. Subclasses should override ``_predict_step()`` and ``_update_step()``. .. attribute:: dynamics_model Forward model. :type: torchfilter.base.DynamicsModel .. attribute:: measurement_model Measurement model. :type: torchfilter.base.KalmanFilterMeasurementModel .. method:: forward(self, *, observations: types.ObservationsTorch, controls: types.ControlsTorch) -> types.StatesTorch Kalman filter forward pass, single timestep. :param observations: Observation inputs. Should be either a dict of tensors or tensor of shape ``(N, ...)``. :type observations: dict or torch.Tensor :param controls: Control inputs. Should be either a dict of tensors or tensor of shape ``(N, ...)``. :type controls: dict or torch.Tensor :returns: *torch.Tensor* -- Predicted state for each batch element. Shape should be ``(N, state_dim).`` .. method:: initialize_beliefs(self, *, mean: types.StatesTorch, covariance: types.CovarianceTorch) -> None Set filter belief to a given mean and covariance. :param mean: Mean of belief. Shape should be ``(N, state_dim)``. :type mean: torch.Tensor :param covariance: Covariance of belief. Shape should be ``(N, state_dim, state_dim)``. :type covariance: torch.Tensor .. method:: belief_mean(self) -> types.StatesTorch :property: Posterior mean. Shape should be ``(N, state_dim)``. .. method:: belief_covariance(self) -> types.CovarianceTorch :property: Posterior covariance. Shape should be ``(N, state_dim, state_dim)``. .. py:class:: KalmanFilterMeasurementModel(*, state_dim, observation_dim) Bases: :class:`abc.ABC`, :class:`torch.nn.Module` .. autoapi-inheritance-diagram:: torchfilter.base.KalmanFilterMeasurementModel :parts: 1 Helper class that provides a standard way to create an ABC using inheritance. .. attribute:: state_dim State dimensionality. :type: int .. attribute:: observation_dim Observation dimensionality. :type: int .. method:: forward(self, *, states: types.StatesTorch) -> Tuple[types.ObservationsNoDictTorch, types.ScaleTrilTorch] :abstractmethod: Observation model forward pass, over batch size ``N``. :param states: States to pass to our observation model. Shape should be ``(N, state_dim)``. :type states: torch.Tensor :returns: *Tuple[torch.Tensor, torch.Tensor]* -- tuple containing expected observations and cholesky decomposition of covariance. Shape should be ``(N, M)``. .. method:: jacobian(self, *, states: types.StatesTorch) -> torch.Tensor Returns Jacobian of the measurement model. :param states: Current state, size ``(N, state_dim)``. :type states: torch.Tensor :returns: *torch.Tensor* -- Jacobian, size ``(N, observation_dim, state_dim)`` .. py:class:: ParticleFilterMeasurementModel(state_dim: int) Bases: :class:`abc.ABC`, :class:`torch.nn.Module` .. autoapi-inheritance-diagram:: torchfilter.base.ParticleFilterMeasurementModel :parts: 1 Observation model base class for a generic differentiable particle filter; maps (state, observation) pairs to the log-likelihood of the observation given the state ( $\log p(z | x)$ ). .. attribute:: state_dim Dimensionality of our state. :type: int .. method:: forward(self, *, states: types.StatesTorch, observations: types.ObservationsTorch) -> torch.Tensor :abstractmethod: Observation model forward pass, over batch size ``N``. For each member of a batch, we expect ``M`` separate states (particles) and one unique observation. :param states: States to pass to our observation model. Shape should be ``(N, M, state_dim)``. :type states: torch.Tensor :param observations: Measurement inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type observations: dict or torch.Tensor :returns: *torch.Tensor* -- Log-likelihoods of each state, conditioned on a corresponding observation. Shape should be ``(N, M)``. .. py:class:: ParticleFilterMeasurementModelWrapper(kalman_filter_measurement_model: KalmanFilterMeasurementModel) Bases: :class:`torchfilter.base.ParticleFilterMeasurementModel` .. autoapi-inheritance-diagram:: torchfilter.base.ParticleFilterMeasurementModelWrapper :parts: 1 Helper class for creating a particle filter measurement model (states, observations -> log-likelihoods) from a Kalman filter one (states -> observations). :param kalman_filter_measurement_model: Kalman filter measurement model instance to wrap. :type kalman_filter_measurement_model: torchfilter.base.KalmanFilterMeasurementModel .. method:: forward(self, *, states: types.StatesTorch, observations: types.ObservationsTorch) -> torch.Tensor Observation model forward pass, over batch size ``N``. For each member of a batch, we expect ``M`` separate states (particles) and one unique observation. :param states: States to pass to our observation model. Shape should be ``(N, M, state_dim)``. :type states: torch.Tensor :param observations: Measurement inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type observations: torch.Tensor :returns: *torch.Tensor* -- Log-likelihoods of each state, conditioned on a corresponding observation. Shape should be ``(N, M)``. .. py:class:: VirtualSensorModel(state_dim: int) Bases: :class:`abc.ABC`, :class:`torch.nn.Module` .. autoapi-inheritance-diagram:: torchfilter.base.VirtualSensorModel :parts: 1 Virtual sensor base class for our differentiable Kalman filters. Maps each observation input to a predicted state and uncertainty, in the style of BackpropKF. This is often necessary for complex observation spaces like images or point clouds, where it's not possible to learn a standard state->observation measurement model. .. attribute:: state_dim Dimensionality of our state. :type: int .. method:: forward(self, *, observations: types.ObservationsTorch) -> Tuple[types.StatesTorch, types.ScaleTrilTorch] :abstractmethod: Predicts states and uncertainties from observation inputs. Uncertainties should be lower-triangular Cholesky decompositions of covariance matrices. :param observations: Measurement inputs. Should be either a dict of tensors or tensor of size ``(N, ...)``. :type observations: dict or torch.Tensor :returns: *Tuple[torch.Tensor, torch.Tensor]* -- Predicted states & uncertainties. States should have shape ``(N, state_dim)``\ , and uncertainties should be lower triangular with shape ``(N, state_dim, state_dim).``