从Flax模型

您可以使用Fortuna通过可扩展的贝叶斯推理方法拟合后验分布, 校准模型输出, 进行不确定性估计, 计算指标, 并获得保形预测集。 所有这些方法的结合为您提供了获得可靠校准不确定性估计的最大机会。

为了做到这一点,你需要在Flax(由JAX驱动)中构建一个深度学习模型,或者从Fortuna中已经实现的模型中选择一个预构建的模型。同样,你需要提供一些数据,可以是数组格式,也可以是数据加载器。你可以使用DataLoader轻松地将这些转换为Fortuna可以消化的内容。

就是这样。这些是让Fortuna训练模型并获得校准预测的最低要求。

当然,如果您熟悉机器学习和不确定性估计,欢迎您构建一个概率模型,并以最适合您需求的方式配置训练和校准方法。您的选择越好,结果就越好。

分类

让我们展示如何在分类中训练模型、获取预测、计算指标和符合集。

提供数据加载器

首先,您需要提供一些训练数据 train_data。这必须转换为与Fortuna兼容的数据加载器。在这个例子中,我们假设您的数据是一个数组元组,分别包含输入和目标变量。还支持其他几种数据格式,例如PyTorch数据加载器、TensorFlow数据加载器等。请查看 DataLoader 以探索支持的转换选项。

from fortuna import DataLoader
train_data_loader = DataLoader.from_array_data(
    train_data,
    batch_size=128,
    shuffle=True,
    prefetch=True
)

选择或构建一个模型

其次,您必须提供一个从输入变量到softmax函数的logits的深度学习模型。输出维度,即logits的数量,必须与数据中不同标签的数量相对应。为此,您可以选择Fortuna的预建模型之一,或者在Flax中构建自己的模型。在此代码示例中,我们采用了一个预建的多层感知器(MLP),并通过output_dim表示输出维度。

References: MLP
from fortuna.model import MLP
model = MLP(
    output_dim=output_dim
)

构建一个概率模型

Fortuna 现在将模型封装成一个概率分类器,即您的接口对象。您可以通过选择先验分布、后验近似方法、输出校准方法和随机种子来配置它;请参考概率分类器的参考文档。然而,如果您对这些概念不太熟悉,只需使用默认选项即可,就像我们在这个示例中所做的那样。

References: ProbClassifier
from fortuna import ProbClassifier
prob_model = ProbClassifier(
    model=model
)

训练概率模型

现在让我们训练概率模型。训练包括两个部分:拟合后验分布和后处理校准。然而,只有在提供了校准数据加载器时才会执行校准。至于训练数据,对于这个例子,我们假设你有校准数据calib_data,格式为数组的元组,并让Fortuna将其转换为数据加载器。训练返回一个状态对象,描述训练过程的进度。

我们鼓励您根据需要配置拟合和校准。您可以指定优化过程、保存和恢复检查点、监控训练并启用早期停止,以及选择您的计算设备;请参阅fit configurationcalibration configuration参考。在本例中,我们将坚持使用默认配置选项。

calib_data_loader = DataLoader.from_array_data(
    calib_data,
    batch_size=128,
    prefetch=True
)
status = prob_model.train(
    train_data_loader=train_data_loader,
    calib_data_loader=calib_data_loader
)

估计统计

给定一些测试数据 test_data, 我们将像上面那样将其转换为数据加载器, 我们准备估计预测统计量。 这些包括预测模式、均值、对数概率密度函数、方差、熵等; 请查阅 predictive 参考。 除了对数概率密度函数, 计算这些统计量只需要测试输入数据, 而不需要测试目标数据。 使用 Fortuna, 你可以通过输入 test_data_loader.to_inputs_loader(), 轻松地从测试数据加载器 test_data_loader 构建测试输入数据的加载器, 正如你将在下面的代码中看到的那样。

注意

在分类中,预测模式给出标签预测,即对某个输入预测的标签,而预测均值给出概率预测,即每个标签的概率。

test_data_loader = DataLoader.from_array_data(
    test_data,
    batch_size=128
)
test_inputs_loader = test_data_loader.to_inputs_loader()
test_logprob = prob_model.predictive.log_prob(
    data_loader=test_data_loader
)
test_modes = prob_model.predictive.mode(
    inputs_loader=test_inputs_loader
)
test_means = prob_model.predictive.mean(
    inputs_loader=test_inputs_loader
)

计算指标

Fortuna 支持一些分类指标, 例如准确率、预期校准误差和 Brier 分数。 我们鼓励您从其他框架引入指标并将其应用于 Fortuna 的预测, 因为后者与操作在 numpy.narray 上的指标兼容。

指标通常需要测试目标数据的数组。你可以通过输入test_data_loader.to_array_targets()轻松获取这些数据。

from fortuna.metric.classification import accuracy, expected_calibration_error
test_targets = test_data_loader.to_array_targets()
acc = accuracy(
    preds=test_modes,
    targets=test_targets
)
ece = expected_calibration_error(
    preds=test_modes,
    probs=test_means,
    targets=test_targets
)

计算共形集

最后, 就像在从不确定性估计中一样, 从预测统计量开始,你可以计算符合集。 同样,我们需要一个数据加载器来实现这一目的。 为了简单起见,我们将使用与上面相同的校准数据加载器, 但也可以使用一个新的。

References: conformal_set()
from fortuna.conformal import AdaptivePredictionConformalClassifier
calib_inputs_loader = calib_data_loader.to_inputs_loader()
calib_targets = calib_data_loader.to_array_targets()
calib_means = prob_model.predictive.mean(
    inputs_loader=calib_inputs_loader
)
conformal_sets = AdaptivePredictionConformalClassifier().conformal_set(
    val_probs=calib_means,
    test_probs=test_means,
    val_targets=calib_targets,
    error=0.05
)

回归

分类示例类似,让我们展示如何在回归中训练模型、获得预测、计算指标和符合区间。

提供数据加载器

首先,您需要提供一些训练数据 train_data。这必须转换为与Fortuna兼容的数据加载器。在这个例子中,我们假设您的数据是一个数组元组,分别包含输入和目标变量。还支持其他几种数据格式,例如PyTorch数据加载器、TensorFlow数据加载器等。请查看 DataLoader 以探索支持的转换选项。

from fortuna import DataLoader
train_data_loader = DataLoader.from_array_data(
    train_data,
    batch_size=128,
    shuffle=True,
    prefetch=True
)

选择或构建一个模型

其次,您必须提供一个深度学习模型,将输入变量映射到目标变量的空间。 您可以选择Fortuna的预建模型之一,或者在Flax中构建自己的模型。在此代码示例中,我们采用了一个预建的多层感知器(MLP),并通过output_dim表示输出维度。

此外,您必须为似然函数的对数方差构建或选择一个模型。 在这个例子中,我们构建一个线性模型。

References: MLP
from fortuna.model import MLP
model = MLP(
    output_dim=output_dim
)
likelihood_log_variance_model = MLP(
    output_dim=output_dim,
    widths=(),
    activations=()
)

构建一个概率模型

Fortuna 现在将模型和似然对数方差模型封装成一个概率回归器,即您的接口对象。您可以通过选择先验分布、后验近似方法、输出校准方法和随机种子来配置它;请参阅概率回归器参考。然而,如果您对这些概念不太熟悉,只需使用默认选项,就像我们在这个示例中所做的那样。

References: ProbRegressor
from fortuna import ProbRegressor
prob_model = ProbRegressor(
    model=model,
    likelihood_log_variance_model=likelihood_log_variance_model
)

训练概率模型

现在让我们训练概率模型。训练包括两个部分:拟合后验分布和后处理校准。然而,只有在提供了校准数据加载器时才会执行校准。至于训练数据,我们假设你有校准数据calib_data,格式为数组的元组,并让Fortuna将其转换为数据加载器。训练返回一个状态对象,描述训练过程的进度。

您可以根据需要配置拟合和校准。您可以指定优化过程、保存和恢复检查点、监控训练并启用早期停止,以及选择您的计算设备;请参阅fit configurationcalibration configuration参考。在此示例中,我们将坚持使用默认配置选项。

calib_data_loader = DataLoader.from_array_data(calib_data, batch_size=128, prefetch=True)
status = prob_model.train(
    train_data_loader=train_data_loader,
    calib_data_loader=calib_data_loader
)

估计统计

给定一些测试数据 test_data, 我们将像上面那样将其转换为数据加载器, 我们准备好估计预测统计量。 这些包括预测模式、均值、对数概率密度函数、方差、熵、分位数、可信区间等; 请查阅 predictive 参考。 除了对数概率密度函数, 计算这些统计量只需要测试输入数据, 而不需要测试目标数据。 使用 Fortuna, 你可以通过输入 test_data_loader.to_inputs_loader(), 轻松地从测试数据加载器 test_data_loader 构建输入数据加载器, 正如你将在下面的代码中看到的那样。

注意

与分类相比,在回归中,预测的均值和预测的众数都为目标变量提供预测,并不代表不确定性的度量。

test_data_loader = DataLoader.from_array_data(
    test_data,
    batch_size=128
)
test_inputs_loader = test_data_loader.to_inputs_loader()
test_logprob = prob_model.predictive.log_prob(
    data_loader=test_data_loader
)
test_means = prob_model.predictive.mean(
    inputs_loader=test_inputs_loader
)
test_cred_intervals = prob_model.predictive.credible_interval(
    inputs_loader=test_inputs_loader
)

计算指标

Fortuna 支持一些回归指标, 例如均方根误差 (RMSE) 和预测区间覆盖概率 (PICP)。 鼓励您从其他框架引入指标并将其应用于 Fortuna 的预测, 因为后者与操作在 numpy.ndarray 上的指标兼容。

指标通常需要测试目标数据的数组。你可以通过输入test_data_loader.to_array_targets()轻松获取这些数据。

from fortuna.metric.regression import root_mean_squared_error, prediction_interval_coverage_probability
test_targets = test_data_loader.to_array_targets()
rmse = root_mean_squared_error(
    preds=test_modes,
    targets=test_targets
)
picp = prediction_interval_coverage_probability(
    lower_bounds=test_cred_intervals[:, 0],
    upper_bounds=test_cred_intervals[:, 1],
    targets=test_targets
)

计算保形区间

最后, 就像在从置信或可信区间得到的保形区间中一样, 从预测统计量出发,你可以计算保形区间。 同样,我们需要一个数据加载器来实现这一目的。 为了简单起见,我们将使用与上面相同的校准数据加载器, 但也可以使用一个新的。

from fortuna.conformal import QuantileConformalRegressor
calib_inputs_loader = calib_data_loader.to_inputs_loader()
calib_targets = calib_data_loader.to_array_targets()
calib_cred_intervals = prob_model.predictive.credible_interval(
    inputs_loader=calib_inputs_loader
)
conformal_intervals = QuantileConformalRegressor().conformal_intervals(
    val_lower_bounds=calib_cred_intervals[:, 0],
    val_upper_bounds=calib_cred_intervals[:, 1],
    test_lower_bounds=test_cred_intervals[:, 0],
    test_upper_bounds=test_cred_intervals[:, 1],
    val_targets=calib_targets
)