不确定性基线
不确定性基线的目标是为研究人员提供一个模板以供构建。这些基线可以作为任何新想法、应用的起点,和/或用于与其他不确定性和鲁棒性研究人员交流。这通过三种方式实现:
- 在标准任务上提供高质量的标准和最先进方法的实现。
- 对代码库中的其他文件依赖最小化。基线应该易于分叉,不依赖于其他基线和通用模块。
- 规定不确定性和鲁棒性基准测试的最佳实践。
动机。 GitHub上有许多不确定性和鲁棒性实现。然而,它们通常是针对特定论文的一次性实验(许多论文甚至没有代码)。没有明确的示例供不确定性研究人员快速原型化他们的工作。每个人都必须实现自己的基线。事实上,即使在标准任务上,每个项目在实验设置上也略有不同,无论是架构、超参数还是数据预处理。这使得正确地与基线进行比较变得困难。
安装
要安装最新的开发版本,请运行
pip install "git+https://github.com/google/uncertainty-baselines.git#egg=uncertainty_baselines"
目前还没有稳定版本(也没有该库的官方发布)。所有API都可能发生变化。安装uncertainty_baselines
不会自动安装任何后端。对于TensorFlow,你需要安装TensorFlow(tensorflow
或tf-nightly
)、TensorFlow Addons(tensorflow-addons
或tfa-nightly
)和TensorBoard(tensorboard
或tb-nightly
)。查看setup.py
中可以安装的额外依赖项。
使用
基线
baselines/
目录包含所有基线,按训练数据集组织。例如,baselines/cifar/determinstic.py
是一个Wide ResNet 28-10,在CIFAR-10上获得96.0%的测试准确率。
使用TPU启动。 你通常需要TPU来复现基线。有三个选项:
-
Colab。Colab提供免费的TPU。这是最方便和经济的选择。你可以通过复制基线脚本并从头运行来进行实验。这对于简单的实验很有效。但是,要小心长期依赖Colab:TPU访问不能保证,而且Colab对于管理多个长时间实验的能力有限。
-
__Google Cloud。__这是最灵活的选项。首先,你需要创建一个虚拟机实例(详情在这里)。
这里有一个在CIFAR-10上启动BatchEnsemble基线的例子。我们假设设置了一些与云TPU相关的环境变量(详情在这里)。
export BUCKET=gs://bucket-name export TPU_NAME=ub-cifar-batchensemble export DATA_DIR=$BUCKET/tensorflow_datasets export OUTPUT_DIR=$BUCKET/model python baselines/cifar/batchensemble.py \ --tpu=$TPU_NAME \ --data_dir=$DATA_DIR \ --output_dir=$OUTPUT_DIR
注意TPU的加速器类型必须与基线的核心数量(
num_cores
标志)一致。在这个例子中,BatchEnsemble默认使用num_cores=8
。所以TPU必须设置为accelerator_type=v3-8
。 -
更改标志。 例如,从8个TPU核心改为8个GPU,或减少核心数量来训练基线。
python baselines/cifar/batchensemble.py \ --data_dir=/tmp/tensorflow_datasets \ --output_dir=/tmp/model \ --use_gpu=True \ --num_cores=8
结果可能相似,但最终所有结果都是不确定的。GPU与TPU在实践中可能没有太大区别,特别是如果你使用相同的数值精度。然而,更改核心数量非常重要。每个训练步骤的总批量大小通常由
num_cores
决定,所以要小心!
数据集
ub.datasets
模块包含遵循TensorFlow Datasets API的数据集。它们添加了最小的逻辑,如默认数据预处理。
注意:在ipython/colab笔记本中,可能需要激活tf急切执行模式tf.compat.v1.enable_eager_execution()
。
import uncertainty_baselines as ub
# 加载CIFAR-10,保留10%用于验证。
dataset_builder = ub.datasets.Cifar10Dataset(split='train',
validation_percent=0.1)
train_dataset = dataset_builder.load(batch_size=FLAGS.batch_size)
for batch in train_dataset:
# 对数据批次应用代码。
你也可以使用get
从字符串(例如,命令行标志)实例化数据集。
dataset_builder = ub.datasets.get(dataset_name, split=split, **dataset_kwargs)
要在Jax和PyTorch中使用数据集:
for batch in tfds.as_numpy(ds):
train_step(batch)
注意tfds.as_numpy
调用tensor.numpy()
。与tensor._numpy()
相比,这会导致不必要的复制。
for batch in iter(ds):
train_step(jax.tree.map(lambda y: y._numpy(), batch))
模型
ub.models
模块包含遵循tf.keras.Model
API的模型。
import uncertainty_baselines as ub
model = ub.models.wide_resnet(input_shape=(32, 32, 3),
depth=28,
width_multiplier=10,
num_classes=10,
l2=1e-4)
指标
我们在下面定义了跨数据集使用的指标。所有结果都报告约3个有效数字,并在10次运行中取平均。
-
参数数量。 训练后模型进行预测所需的参数数量。
-
测试准确率。 在测试集上的准确率。对于一个包含
N
个输入-输出对(xn, yn)
的数据集,其中标签yn
取K
个值中的一个,准确率为1/N \sum_{n=1}^N 1[ \argmax{ p(yn | xn) } = yn ],
其中
1
是指示函数,当模型预测的类别等于标签时为1,否则为0。 -
测试校准误差。 在测试集上的期望校准误差(ECE)(Naeini等人,2015)。ECE将概率区间
[0, 1]
离散化为等间距的bins,并将每个预测概率分配到包含它的bin中。校准误差是bin中正确预测的比例(准确率)与bin中概率的平均值(置信度)之间的差异。期望校准误差在各个bins之间取平均。对于一个包含
N
个输入-输出对(xn, yn)
的数据集,其中标签yn
取K
个值中的一个,ECE计算加权平均\sum_{b=1}^B n_b / N | acc(b) - conf(b) |,
其中
B
是bins的数量,n_b
是binb
中预测的数量,acc(b)
和conf(b)
分别是binb
的准确率和置信度。 -
测试NLL。 在测试集上的负对数似然(以nats为单位)。对于一个包含
N
个输入-输出对(xn, yn)
的数据集,负对数似然为-1/N \sum_{n=1}^N \log p(yn | xn).
它在常数范围内等价于从真实数据分布到模型的KL散度,因此捕捉了与真实分布整体拟合的优度(Murphy, 2012)。它也可以被解释为解释数据所需的比特数(nats)(Grunwald, 2004)。
- 训练/测试运行时间。 训练运行时间是训练模型的总挂钟时间,包括任何中间测试集评估。测试运行时间指在GPU/TPU上运行前向传播所需的时间,即设备非空闲的持续时间。注意测试运行时间不包括协调器上的时间:这在比较基线时更精确,因为包括协调器会增加GPU/TPU调度和数据获取的开销---产生高方差结果。
查看指标。
Uncertainty Baselines将TensorFlow摘要写入model_dir
,可以被TensorBoard使用。这包括TensorBoard超参数插件,可用于分析超参数调优扫描。
如果你希望上传到公开可读的tensorboard.dev,使用:
tensorboard dev upload --logdir MODEL_DIR --plugins "scalars,graphs,hparams" --name "My experiment" --description "My experiment details"
参考文献
如果你想引用Uncertainty Baselines,请使用以下BibTeX条目。
Z. Nado, N. Band, M. Collier, J. Djolonga, M. Dusenberry, S. Farquhar, A. Filos, M. Havasi, R. Jenatton, G. Jerfel, J. Liu, Z. Mariet, J. Nixon, S. Padhy, J. Ren, T. Rudner, Y. Wen, F. Wenzel, K. Murphy, D. Sculley, B. Lakshminarayanan, J. Snoek, Y. Gal, and D. Tran. Uncertainty Baselines: Benchmarks for uncertainty & robustness in deep learning, arXiv preprint arXiv:2106.04015, 2021.
@article{nado2021uncertainty,
author = {Zachary Nado and Neil Band and Mark Collier and Josip Djolonga and Michael Dusenberry and Sebastian Farquhar and Angelos Filos and Marton Havasi and Rodolphe Jenatton and Ghassen Jerfel and Jeremiah Liu and Zelda Mariet and Jeremy Nixon and Shreyas Padhy and Jie Ren and Tim Rudner and Yeming Wen and Florian Wenzel and Kevin Murphy and D. Sculley and Balaji Lakshminarayanan and Jasper Snoek and Yarin Gal and Dustin Tran},
title = {{Uncertainty Baselines}: Benchmarks for Uncertainty \& Robustness in Deep Learning},
journal = {arXiv preprint arXiv:2106.04015},
year = {2021},
}
使用Uncertainty Baselines的论文
以下论文使用了Uncertainty Baselines的代码:
- A Simple Fix to Mahalanobis Distance for Improving Near-OOD Detection
- BatchEnsemble: An Alternative Approach to Efficient Ensembles and Lifelong Learning
- DEUP: Direct Epistemic Uncertainty Prediction
- Distilling Ensembles Improves Uncertainty Estimates
- Efficient and Scalable Bayesian Neural Nets with Rank-1 Factors
- Exploring the Uncertainty Properties of Neural Networks' Implicit Priors in the Infinite-Width Limit
- Hyperparameter Ensembles for Robustness and Uncertainty Quantification
- Measuring Calibration in Deep Learning
- Measuring and Improving Model-Moderator Collaboration using Uncertainty Estimation
- Neural networks with late-phase weights
- On the Practicality of Deterministic Epistemic Uncertainty
- Prediction-Time Batch Normalization for Robustness under Covariate Shift
- Refining the variational posterior through iterative optimization
- Revisiting One-vs-All Classifiers for Predictive Uncertainty and Out-of-Distribution Detection in Neural Networks
- Simple and Principled Uncertainty Estimation with Deterministic Deep Learning via Distance Awareness
- Training independent subnetworks for robust prediction
- Plex: Towards Reliability Using Pretrained Large Model Extensions, 可在此处获取
贡献
格式化代码
在提交代码之前,请确保文件按照yapf的yapf样式进行了格式化:
yapf -i --style yapf [源文件]
添加基线
- 编写一个加载固定训练数据集和模型的脚本。通常,这是从其他基线分叉而来。
- 调优后,将默认标志值设置为最佳超参数。
- 将基线的性能添加到相应
README.md
中的结果表格。
添加数据集
- 将bibtex参考添加到
references.md
。 - 将数据集定义添加到datasets/目录。每个文件应该有一个
datasets.base.BaseDataset
的子类,至少需要实现一个构造函数、一个tfds.core.DatasetBuilder
和_create_process_example_fn
。 - 添加一个测试,至少构造数据集并检查元素的形状。
- 将数据集添加到
datasets/datasets.py
以便于访问。 - 将数据集类添加到
datasets/__init__.py
。
有关添加数据集的示例,请参见此拉取请求。
添加模型
-
将bibtex参考添加到
references.md
。 -
将模型定义添加到models/目录。每个文件应该有一个具有以下签名的
create_model
函数:def create_model( batch_size: int, ... **unused_kwargs: Dict[str, Any]) -> tf.keras.models.Model:
-
添加一个测试,至少构造模型并进行前向传播。
-
将模型添加到
models/models.py
以便于访问。 -
将
create_model
函数添加到models/__init__.py
。