BoTorch 测试函数与基准评估:验证优化算法性能
BoTorch 是一个基于 PyTorch 的贝叶斯优化库,提供了丰富的测试函数和基准评估工具,帮助开发者验证和比较优化算法的性能。本文将详细介绍 BoTorch 的测试函数体系、使用方法以及如何通过基准评估确保优化算法的有效性。
BoTorch 测试函数概述
BoTorch 的测试函数模块位于 botorch/test_functions/ 目录下,提供了从简单到复杂的多种测试问题,涵盖单目标、多目标、带约束条件等不同场景。这些测试函数是评估优化算法性能的黄金标准,能够模拟真实世界中的各种优化挑战。
核心测试函数类型
BoTorch 测试函数主要分为以下几类:
- 基础测试问题:位于
botorch/test_functions/base.py,定义了测试函数的基本接口和属性 - 合成测试函数:位于
botorch/test_functions/synthetic.py,包含经典的单目标优化问题 - 多目标测试函数:位于
botorch/test_functions/multi_objective.py,用于多目标优化场景 - 多保真度测试函数:位于
botorch/test_functions/multi_fidelity.py,支持多保真度优化问题
常用单目标测试函数
BoTorch 实现了多种经典的单目标测试函数,适用于不同特性的优化算法测试:
- Ackley 函数:具有多个局部最优解的连续优化问题,常用于测试算法的全局搜索能力
- Rosenbrock 函数:高度非线性的连续优化问题,对优化算法的精度要求较高
- Branin 函数:具有三个全局最优解的双变量函数,适合测试算法处理多峰问题的能力
- Hartmann 函数:6 维函数,具有多个局部最优解,常用于评估高维优化算法
这些函数都继承自 SyntheticTestFunction 类,提供统一的接口进行函数评估和性能指标计算。
使用测试函数的完整流程
1. 导入测试函数
from botorch.test_functions.synthetic import Ackley, Branin, Rosenbrock
from botorch.test_functions.multi_objective import DTLZ2
2. 初始化测试问题
# 单目标测试函数
ackley = Ackley(dim=5) # 5 维 Ackley 函数
branin = Branin() # 2 维 Branin 函数
# 多目标测试函数
dtlz2 = DTLZ2(dim=6, num_objectives=2) # 6 维输入,2 个目标的 DTLZ2 函数
3. 评估函数值
import torch
# 生成测试点
X = torch.rand(10, ackley.dim) # 生成 10 个随机测试点
# 评估函数值(带噪声)
Y = ackley(X)
# 评估真实函数值(不带噪声)
Y_true = ackley.evaluate_true(X)
4. 访问问题属性
# 获取问题边界
print("Ackley 函数边界:", ackley.bounds)
# 获取全局最优值
print("Branin 函数最优值:", branin.optimal_value)
# 获取最优解
print("Rosenbrock 函数最优解:", rosenbrock.optimal_x)
基准评估方法
单目标优化评估指标
BoTorch 提供了多种指标来评估单目标优化算法的性能:
- 累计悔恨值(Cumulative Regret):衡量算法收敛到最优解的速度
- 成功率(Success Rate):算法找到全局最优解的概率
- 收敛曲线:展示算法在迭代过程中的目标函数值变化
多目标优化评估指标
对于多目标优化问题,BoTorch 支持以下评估指标:
- 超体积(Hypervolume):衡量 Pareto 前沿覆盖的区域大小
- Pareto 前沿距离:与真实 Pareto 前沿的接近程度
- 世代距离(Generational Distance):评估收敛性和多样性
from botorch.utils.multi_objective.hypervolume import Hypervolume
# 计算超体积
hv = Hypervolume(ref_point=dtlz2.ref_point)
hypervolume = hv.compute(Y_pareto)
测试函数应用场景
1. 算法开发与调试
测试函数为优化算法开发提供了标准化的评估环境:
def test_my_optimizer(optimizer, test_function, num_trials=10):
regrets = []
for _ in range(num_trials):
# 运行优化算法
best_value = optimizer.optimize(test_function)
# 计算悔恨值
regret = best_value - test_function.optimal_value
regrets.append(regret)
return torch.mean(torch.tensor(regrets))
2. 算法比较研究
通过在多个测试函数上比较不同算法的性能,可以客观评估算法的优劣。
3. 参数调优
测试函数可用于优化算法自身参数的调优:
from botorch.optim import optimize_acqf
# 使用测试函数优化算法超参数
def tune_hyperparameters(hyperparameter_space):
def objective(params):
# 设置算法参数
algorithm = MyAlgorithm(params=params)
# 在多个测试函数上评估性能
performance = evaluate_algorithm(algorithm, [Ackley(), Branin(), Rosenbrock()])
return -performance # 转为最小化问题
# 优化超参数
optimal_params = optimize_acqf(
acq_function=objective,
bounds=hyperparameter_space,
q=1,
num_restarts=5,
raw_samples=20
)
return optimal_params
高级使用技巧
自定义测试函数
通过继承基础类,可以创建自定义测试函数:
from botorch.test_functions.base import SyntheticTestFunction
class MyTestFunction(SyntheticTestFunction):
dim = 3
_bounds = [(-5.0, 5.0) for _ in range(dim)]
_optimal_value = 0.0
_optimizers = [(0.0, 0.0, 0.0)]
def _evaluate_true(self, X: Tensor) -> Tensor:
# 定义自定义函数
return torch.sum(X ** 2, dim=-1)
带约束条件的测试问题
BoTorch 支持带约束条件的测试问题,位于 botorch/test_functions/base.py 中的 ConstrainedBaseTestProblem 类:
from botorch.test_functions.base import ConstrainedBaseTestProblem
class ConstrainedProblem(ConstrainedBaseTestProblem):
num_constraints = 1
def _evaluate_true(self, X: Tensor) -> Tensor:
# 目标函数
return X.pow(2).sum(dim=-1)
def _evaluate_slack_true(self, X: Tensor) -> Tensor:
# 约束条件:x1 + x2 <= 1
return 1 - X[..., :2].sum(dim=-1, keepdim=True)
多保真度测试问题
多保真度测试函数位于 botorch/test_functions/multi_fidelity.py,支持不同保真度下的函数评估:
from botorch.test_functions.multi_fidelity import AugmentedBranin
# 初始化多保真度测试函数
aug_branin = AugmentedBranin()
# 在不同保真度下评估
X = torch.rand(10, 3) # 最后一维为保真度参数
Y = aug_branin(X)
总结
BoTorch 的测试函数模块为优化算法开发和评估提供了全面的工具支持。通过本文介绍的测试函数和评估方法,开发者可以:
- 使用标准化的测试问题验证优化算法性能
- 客观比较不同算法的优缺点
- 调试和改进现有优化方法
- 为特定应用场景选择最合适的优化策略
无论是学术研究还是工业应用,合理利用这些测试函数都能显著提高优化算法的开发效率和可靠性。要深入了解更多测试函数的细节,可以参考 BoTorch 的官方文档和源代码实现。
通过 BoTorch 提供的丰富测试函数和评估工具,开发者可以构建更加稳健、高效的优化算法,应对各种复杂的现实优化问题。
