Source code for qumphy.uq

"""
File: qumphy/uq.py
Project: 22HLT01 QUMPHY
Contact: oskar.pfeffer@ptb.de
Gitlab: https://gitlab.com/qumphy
Description: Uncertainty quantification utilities.
"""

import numpy as np
import typing


[docs] def deep_ensemble( models: typing.List, data: np.ndarray, weights: np.ndarray | None = None, ) -> np.ndarray: """Compute deep ensemble of the data using the given models. Parameters ---------- models : list List of callable models. Expected to return type ``np.ndarray``. data : np.ndarray Input data. weights : np.ndarray, optional Weights for each model. Returns ------- np.ndarray Weighted model output predictions. Examples -------- Compute unweighted deep ensemble prediction of two models on given data. >>> model0 = lambda x : np.dot(np.zeros((1, 2)), x.T).reshape(-1, 1) >>> model1 = lambda x : np.dot(np.ones((1, 2)), x.T).reshape(-1, 1) >>> data = np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) >>> deep_ensemble([model0, model1], data) [[0. ] [0.5] [0.5] [1. ]] Compute weighted deep ensemble prediction of two models on given data. >>> model0 = lambda x : np.dot(np.zeros((1, 2)), x.T).reshape(-1, 1) >>> model1 = lambda x : np.dot(np.ones((1, 2)), x.T).reshape(-1, 1) >>> data = np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]) >>> weights=np.array([0.0, 1.0]) >>> deep_ensemble([model0, model1], data) [[0.] [1.] [1.] [2.]] """ models_output = [model(data) for model in models] assert np.all([isinstance(m, np.ndarray) for m in models_output]) assert np.all(models_output[0].shape == v.shape for v in models_output) return np.average(np.array(models_output), axis=0, weights=weights)
[docs] def deep_ensemble_gaussian( prediction_mean: np.ndarray, prediction_var: np.ndarray, weights: np.ndarray | None = None, ) -> typing.Tuple[np.ndarray, np.ndarray]: """Compute deep ensemble using the given predictions. Parameters ---------- prediction_mean: np.ndarray Mean of the predicted gaussian distribution. prediction_std: np.ndarray Variance of the predicted gaussian distribution. weights : np.ndarray, optional Weights for each model. Returns ------- Tuple[np.ndarray, np.ndarray] Weighted ensemble prediction mean and variance. Examples -------- Compute deep ensemble using the given predictions. Shape of `prediction_mean` and `prediction_var` should be: `[#models, #samples, #outputs]` >>> prediction_mean_1 = np.array([[[0.0], [0.5]], [[0.5], [1.0]]]) >>> prediction_mean_2 = np.array([[[1.0], [0.5]], [[0.5], [1.0]]]) >>> prediction_var_1 = np.array([[[0.0], [1.0]], [[0.5], [1.0]]]) >>> prediction_var_2 = np.array([[[0.0], [0.0]], [[0.5], [1.0]]]) >>> prediction_mean = np.array([prediction_mean_1, prediction_mean_2]) >>> prediction_var = np.array([prediction_var_1, prediction_var_2]) >>> weights = np.array([0.25, 0.75]) >>> deep_ensemble_gaussian(prediction_mean, prediction_var, weights) """ if weights is None: weights = np.ones(len(prediction_mean)) / len(prediction_mean) ensemble_mean = np.average(prediction_mean, axis=0, weights=weights) ensemble_var = ( np.average(prediction_var + prediction_mean**2, axis=0, weights=weights) - ensemble_mean**2 ) ensemble_var_aleatoric = np.average(prediction_var, axis=0, weights=weights) ensemble_var_epistemic = np.std(prediction_mean, axis=0) return ensemble_mean, ensemble_var, ensemble_var_aleatoric, ensemble_var_epistemic