贝叶斯优化中高斯过程代理模型与采集函数EI/UCB
当需要寻找一个“黑箱”函数(即内部机理未知,只知道输入和输出)的最大值或最小值时,贝叶斯优化是一种极其高效的策略。它特别适用于评估一次实验或一次计算成本非常高的场景(例如训练一个大型机器学习模型、进行一次物理实验)。
贝叶斯优化的核心思想是:建立一个关于目标函数的“代理模型”,并用这个模型来指导下一步去哪里采样(进行实验),从而以尽可能少的尝试次数找到最优解。
本指南将重点讲解该方法的两个核心组件:高斯过程代理模型与两种主流的采集函数:期望改进和置信上界。
1. 高斯过程代理模型
高斯过程是贝叶斯优化中最常用的代理模型。你可以将它理解为 “对所有可能的函数形状的一个概率分布”。在观察到一些数据点(输入-输出对)后,高斯过程会更新这个分布,给出一个“最可能”的函数预测,并量化预测的不确定性。
关键思想:在任何一个你尚未测试过的点,高斯过程不仅会预测一个可能的输出值(均值),还会给出一个不确定性范围(方差)。通常,离已知数据点越远的地方,不确定性就越大。
建立高斯过程模型的步骤如下:
-
选择核函数:定义输入点之间的相似性。核函数决定了模型认为函数应该具备的“平滑性”。最常用的是平方指数核。选择不同的核函数,相当于赋予了模型关于目标函数的不同先验假设。
-
拟合初始模型:使用你手上已有的(通常很少量的)初始数据点,计算高斯过程的后验分布。这一步会得到一个模型,它可以为任意新点
x预测输出y的分布P(y|x)。 -
获得预测:对于一个新输入点
x*,高斯过程会输出一个预测均值μ(x*)和预测方差σ²(x*)。均值是我们对该点函数值的最佳估计,方差则代表了我们的“不确定程度”。
2. 采集函数:决定下一步去哪里探索
有了高斯过程代理模型,我们需要一个“采集函数”来决定下一个要评估的点 x_next 在哪里。采集函数的目标是在“探索”(去不确定性高的区域)和“利用”(去预测均值高的区域)之间取得平衡。
2.1 期望改进
期望改进衡量的是:在某个点 x 进行实验,相比当前已知的最优值 f_best,期望能获得多大的改进量。
它的核心逻辑是:
- 如果该点的预测均值很高,那么改进的潜力就大(利用)。
- 如果该点的不确定性很高,那么虽然预测均值不高,但也存在“赌一把”获得高回报的可能(探索)。
计算期望改进的步骤:
-
确定当前最优值:
f_best是当前所有已观测点中的最大(或最小)函数值。 -
计算改进量:对于新点
x,其改进量I(x) = max(0, f(x) - f_best)。只有当预测值比当前最优值更好时,改进才为正。 -
计算期望值:由于我们不知道真实的
f(x),我们用高斯过程给出的预测分布N(μ(x), σ²(x))来计算改进量的期望。最终得到采集函数:$$EI(x) = \mathbb{E}[I(x)] = \int_{-\infty}^{\infty} \max(0, t - f_{best}) \cdot p(t) \, dt$$
其中
p(t)是在点x处预测值t的概率密度。 -
选择下一个点:选择使
EI(x)最大的点x_next进行实验。
简单来说,EI函数倾向于选择那些“可能比当前最好结果好很多”的点,综合考虑了希望和风险。
2.2 置信上界
置信上界是一种更直观的采集函数。它直接为函数构造一个乐观的估计,并在这个乐观估计的“峰值”处进行探索。
计算置信上界的公式很简单:
$$LCB(x) = \mu(x) - \kappa \cdot \sigma(x)$$
μ(x)是高斯过程在点x的预测均值。σ(x)是预测的标准差(不确定性)。κ是一个可调的超参数,控制了探索的程度。
选择下一个点的逻辑是:选择使 LCB(x) 最小的点(因为我们在寻找最小值)。这个公式鼓励算法去访问那些“预测值可能很低”(μ(x) 小)或者“我们非常不确定但有可能很低”(σ(x) 大)的区域。
- 当
κ较大时,算法会更探索不确定性高的区域。 - 当
κ较小时,算法会更利用当前预测均值低的区域。
简单来说,UCB函数相当于在乐观预测(均值减去一个与不确定性成正比的惩罚项)的峰值处采样。
3. Python实操步骤
以下是在Python中使用 scikit-optimize 库进行贝叶斯优化的基本流程。
-
安装必要的库。
pip install scikit-optimize numpy -
定义目标函数。这里我们模拟一个黑箱函数,例如一个带有噪声的函数。
import numpy as np # 这是一个示例函数,我们要寻找它在[0, 10]区间内的最大值 def black_box_function(x): return -np.sin(x) - x**0.5 + np.random.normal(0, 0.1) -
设置优化过程。使用
gp_minimize函数,它默认使用高斯过程代理模型和LCB(置信下界,寻找最小值)作为采集函数。要最大化函数,我们可以优化其负值。from skopt import gp_minimize from skopt.space import Real # 定义搜索空间 space = [Real(0.0, 10.0, name='x')] # 运行贝叶斯优化,n_calls是总调用次数(包括初始点) result = gp_minimize(lambda x: -black_box_function(x), # 最小化负函数即为最大化原函数 dimensions=space, n_calls=20, random_state=42) # 结果 best_value = -result.fun best_point = result.x[0] print(f"找到的最大值:{best_value:.3f},对应的输入:{best_point:.3f}") -
(可选)切换采集函数。
gp_minimize允许通过acq_func参数指定采集函数。- 使用期望改进:
acq_func='EI' - 使用置信下界(LCB,即UCB的最小化版本):
acq_func='LCB',并可通过kappa参数调整探索程度。 - 使用改进概率:
acq_func='PI'
示例:明确使用期望改进。
result_ei = gp_minimize(lambda x: -black_box_function(x), dimensions=space, n_calls=20, acq_func='EI', random_state=42) - 使用期望改进:
整个优化过程会自动维护一个高斯过程模型,并根据你选择的采集函数智能地推荐下一个实验点。你只需不断评估目标函数(在真实场景中这可能是昂贵的操作),并将结果反馈给优化器即可。

暂无评论,快来抢沙发吧!