想象你是一名美食猎人,刚搬进一座陌生城市。你的目标是从数百家餐厅里找到最好吃的那家,但每顿饭都要花不少钱和时间,不可能把整条街逐家吃遍。与其挨家乱试,你更愿意每次吃完都在心里画一张“寻味地图”:哪些地方已经尝过、味道如何,哪些地方还是一团迷雾。每多试一家店,地图就更精确一点。下一次,你就知道去哪个新方向才最可能吃到惊喜。这种“边吃边学、用地图找下一站”的思路,正是机器学习里贝叶斯优化的缩影——它不说“把所有组合都试一遍”,而是聪明地决定下一步该试什么,用最少的昂贵试错,找到最好的答案。

岗位关联

对 AI 从业者来说,贝叶斯优化是超参数调优和 AutoML 的核心武器。学会它,你就能在动辄数小时的单次训练中省下大量 GPU 预算,更快找到更优模型。

目录
  1. 可视化演示
  2. 优化问题:从挨家试吃学会画地图
  3. 代理模型:不断更新的寻味地图
  4. 采集函数:下一站去哪吃
  5. 探索与利用:尝鲜还是回味
  6. 迭代流程:吃一口,改一版地图
  7. 应用优势:省下每一顿昂贵的饭
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

优化问题:从挨家试吃学会画地图

想象你是刚搬到陌生城市的美食猎人。目标是在整条街的餐厅里找到最好吃的那家,但每顿都要花不少时间和预算,不可能把每家餐厅都吃一遍。超参数就像“选几分熟、加什么酱、配什么酒”,目标函数就是给这顿饭打出的味道分。网格搜索是拿着菜单按顺序把每家餐厅都试一遍,随机搜索则是站在街口闭眼乱走。这两种方式都没有从“上一顿好不好吃”里学到任何东西。

在机器学习里,我们要调的是学习率、批大小、网络层数等超参数。把每一种超参数组合记为 $\theta$,把验证集上得到的分数记为 $\text{Score}(\theta)$。目标就是找到 $\theta^{*}$ 使分数最高。网格搜索需要的评估次数会随维度爆炸,随机搜索虽然不用暴力穷举,但依旧很盲目。贝叶斯优化的思路完全不同:先吃几口,把“哪片区域更好吃”的概率画成地图,再按地图决定下一口该去哪儿。

与其把预算烧在逐户试吃上,不如让每一次试吃都变成地图上的一笔情报。这正是贝叶斯优化的起点。

θ∗=arg⁡max⁡θ∈ΘScore(θ)\displaystyle \theta^{*} = \arg\max_{\theta \in \Theta} \text{Score}(\theta)
这个式子就是在说:在所有可能的超参数组合里,找到让验证分数最高的那一组。
  1. 目标变量$\theta$ 表示一组超参数,比如学习率、批大小、网络层数等。
    θ\theta
  2. 评分函数$\text{Score}(\theta)$ 表示这组超参数在验证集上的表现,分数越高越好。
    Score(θ)\text{Score}(\theta)
  3. 搜索空间$\Theta$ 是所有可行超参数组合的集合,也就是美食猎人眼中的整条美食街。
    Θ\Theta
  4. 最优解$\theta^{*} = \arg\max$ 表示在候选集合中挑出评分最高的那一组。
    θ∗=arg⁡max⁡θ∈ΘScore(θ)\theta^{*} = \arg\max_{\theta \in \Theta} \text{Score}(\theta)

代理模型:不断更新的寻味地图

吃过前几顿之后,美食猎人会记住这些口味,画出一张“寻味地图”。去过的地方,地图很清晰;没去过的地方,地图上是一团迷雾。高斯过程就是这种地图的数学版本:它不仅给出每个位置“预测的美味值”,还给出“这个预测到底可不可信”。预测均值 $\mu(x)$ 是估出的味道,不确定度 $\sigma^2(x)$ 是那团迷雾的浓度。

除高斯过程之外,TPE 模型是另一种画法。它不直接画整张地图,而是把已知点分成“表现好”和“表现差”两组,分别统计概率密度 $l(x)$ 和 $g(x)$,再用两个密度的比值判断哪里更可能出现好味道。TPE 在高维和混合类型的超参数空间中往往更灵活。两者都属于“代理模型”:用便宜的计算去近似那个昂贵的目标函数。

地图越画越准,每一次试吃都在修正迷雾。代理模型的价值,就是让下一顿饭不再靠运气。

P(f∣D)=N(f; μ(x), σ2(x))\displaystyle P(f \mid \mathcal{D}) = \mathcal{N}\left(f;\, \mu(x),\, \sigma^{2}(x)\right)
高斯过程把对目标函数的猜测写成一种带不确定性的分布:平均值是好味道的最佳估计,方差则说明猜测有多没底。
  1. 历史数据$\mathcal{D}$ 是已经试过的超参数及其对应分数,相当于美食猎人已经吃过的餐厅记录。
    D\mathcal{D}
  2. 后验分布$P(f \mid \mathcal{D})$ 是在看过历史数据之后,对目标函数 $f$ 的新信念。
    P(f∣D)P(f \mid \mathcal{D})
  3. 高斯分布$\mathcal{N}(f; \mu(x), \sigma^{2}(x))$ 把这种信念近似成一个均值加方差的高斯分布。
    N(f; μ(x), σ2(x))\mathcal{N}\left(f;\, \mu(x),\, \sigma^{2}(x)\right)
  4. 均值与方差$\mu(x)$ 预测味道,$\sigma^{2}(x)$ 表示没尝过区域的不确定度。
    μ(x),σ2(x)\mu(x), \quad \sigma^{2}(x)

采集函数:下一站去哪吃

地图画好了,但地图本身不会说话。下一步去哪家店,需要一条“美食猎人直觉”,这就是采集函数。常见的直觉有三种:期望提升 EI 会问“这家店比我当前最爱的店平均能好多少”;置信上界 UCB 会计算“预测美味值 + 冒险津贴”;概率提升 PI 只关心“超过当前最佳的可能性”,不在乎超过多少。

在贝叶斯优化里,采集函数把代理模型的均值和不确定性揉成一个分数。分数最高的位置,就是下一个最值得做真实评估的点。用 EI 来举例,它先看某个候选点是否可能超过当前最佳值,再看超出量有多大,最后按模型给出的概率分布求期望。这样既不是闷头找已知最好的店,也不是盲目探索。

采集函数就是美食猎人的第六感:它把地图上的预测和迷雾统一成一个方向,让你知道下一脚该往哪踩。

EI(x)=E[max⁡(f(x)−fbest, 0)]\displaystyle EI(x) = \mathbb{E}\left[\max\left(f(x) - f_{\text{best}},\, 0\right)\right]
EI 的直觉是:如果预测这家店不如当前最佳,期望提升就是 0;如果可能更好,就把高出的部分按概率平均。
  1. 当前最佳$f_{\text{best}}$ 是目前已尝到的最好口味,也就是历史样本中最高的目标函数值。
    fbestf_{\text{best}}
  2. 潜在提升$\max(f(x) - f_{\text{best}}, 0)$ 表示候选点若超过当前最佳,高出多少才算收益,没超过就记 0。
    max⁡(f(x)−fbest, 0)\max\left(f(x) - f_{\text{best}},\, 0\right)
  3. 期望运算$\mathbb{E}[\cdot]$ 在模型给出的不确定分布上取平均,得到“长远期待值”。
    E[⋅]\mathbb{E}[\cdot]
  4. EI 决策下一轮的评估点就选在让 $EI(x)$ 最大的位置。
    xt+1=arg⁡max⁡xEI(x)x_{t+1} = \arg\max_{x} EI(x)

探索与利用:尝鲜还是回味

有了地图和直觉之后,猎人还要做一道选择题:去已经确定好吃的店再来一顿,还是去从未踏足的街道碰碰运气。前者叫“利用”,利用已知信息锁定眼前的收益;后者叫“探索”,用一次可能有风险的尝试换取更长远的收获。如果只利用,你会困在一个局部好吃的区域;如果只探索,预算很快花完却不一定吃到什么好味道。

贝叶斯优化把这道选择题揉进了采集函数里。以 UCB 为例,它给每个候选点算两个数:预测均值代表利用价值,不确定度代表探索潜力。用一个系数 $\kappa$ 把两者相加,$\kappa$ 越大,算法越愿意选择认识不足的区域;$\kappa$ 越小,算法越保守,更偏爱预测最好的区域。面对多个看起来都不错的多峰区域,不确定性会自动给冷门方向加分,避免你在一个小山头上自嗨。

最佳策略不是一味尝鲜,也不是反复回味,而是找到两者之间的甜蜜点。$\kappa$ 就是那个可调的火候。

α(x)=μ(x)⏟exploit+κσ(x)⏟explore\displaystyle \alpha(x) = \underbrace{\mu(x)}_{\text{exploit}} + \kappa \underbrace{\sigma(x)}_{\text{explore}}
这个公式把“再吃一遍熟悉的店”和“去未知街道探险”统一成一个分数,参数 \kappa 就是冒险旋钮。
  1. 预测均值$\mu(x)$ 是地图上预估的美味度,代表利用已有信息带来的收益。
    μ(x)\mu(x)
  2. 不确定度$\sigma(x)$ 是没尝过区域的不确定性,代表探索新路径可能带来的信息量。
    σ(x)\sigma(x)
  3. 调节系数$\kappa$ 控制冒险程度,越大越愿意选择高不确定性的区域。
    κ\kappa
  4. 组合公式$\alpha(x)$ 越大,这个点越值得作为下一站。
    α(x)=μ(x)+κσ(x)\alpha(x) = \mu(x) + \kappa \sigma(x)

迭代流程:吃一口,改一版地图

贝叶斯优化不是一个一次性公式,而是一套反复更新的流程。美食猎人先在几条街区随便吃几顿,形成最初的吃后感;然后根据这些体验画一张粗糙地图;接着用采集函数选出下一个最值得去的餐厅;真实吃一顿之后,把新口味补充进地图,让下一版地图更准确。这个循环不断重复,每一轮都在逼近真正最好的餐厅。

算法流程依次为:初始化采样、拟合代理模型、最大化采集函数选择新点、评估真实目标函数、更新历史数据集。每一步都很轻量,只有“真实评估”这一步是昂贵的。代理模型和采集函数负责用便宜的计算替代昂贵的试错,把每次试错的信息价值最大化。

每吃一口,地图就改一版;每改一版,下一口就更有方向。这种正反馈循环就是贝叶斯优化高效的核心。

Dt+1=Dt∪{(xt+1, yt+1)},xt+1=arg⁡max⁡xα(x∣Dt)\displaystyle \mathcal{D}_{t+1} = \mathcal{D}_{t} \cup \left\{\left(x_{t+1},\, y_{t+1}\right)\right\},\quad x_{t+1} = \arg\max_{x} \alpha\left(x \mid \mathcal{D}_{t}\right)
这个式子描述了一轮循环:从已有数据出发,选出下一评估点,真实评估后把新记录加入数据集合。
  1. 历史数据$\mathcal{D}_t$ 是第 $t$ 轮已吃过的餐厅和评分记录,也就是当前数据集。
    Dt\mathcal{D}_t
  2. 下一步选点$x_{t+1}$ 由采集函数在所有候选点中挑出,表示下一顿去哪吃。
    xt+1=arg⁡max⁡xα(x∣Dt)x_{t+1} = \arg\max_{x} \alpha\left(x \mid \mathcal{D}_{t}\right)
  3. 真实评估$y_{t+1}$ 是实际训练一次得到的分数,对应猎人真正去餐厅吃一顿。
    yt+1=f(xt+1)y_{t+1} = f\left(x_{t+1}\right)
  4. 数据扩充把新样本加入历史记录,得到更完整的新数据集,地图也随之更新。
    Dt+1=Dt∪{(xt+1, yt+1)}\mathcal{D}_{t+1} = \mathcal{D}_t \cup \left\{\left(x_{t+1},\, y_{t+1}\right)\right\}

应用优势:省下每一顿昂贵的饭

美食猎人的地图不是万能的。如果一顿饭只花一块钱,认真画地图反而有点小题大做;但如果一次训练要跑几小时,地图省下的预算就非常可观。贝叶斯优化最擅长的是“单次评估非常昂贵”的超参数调优场景:训练一个深度学习模型可能要花数小时 GPU,网格搜索可能在数十种组合里试错,而贝叶斯优化能用更少的尝试逼近同样好的性能。

在 AutoML 和神经架构搜索中,贝叶斯优化也是常用引擎。候选网络结构训练一次同样昂贵,代理模型负责猜测什么结构可能更好,采集函数负责从结构空间里挑出下一个候选。相比网格搜索和随机搜索,贝叶斯优化的样本效率更高,也就是“每一份预算带来的性能提升更大”。不过它也有前提:如果每次评估足够便宜,那么地图建模本身的成本可能超过收益。

贵的饭,才配得上精细的地图。贝叶斯优化不为省钱而省,而是用同样的预算,换取更有价值的每一次尝试。

Esample=ΔfbestNeval\displaystyle E_{\text{sample}} = \frac{\Delta f_{\text{best}}}{N_{\text{eval}}}
样本效率定义为“最好成绩的提升量”除以“真实评估次数”。提升越多、评估次数越少,说明策略越高效。
  1. 性能提升$\Delta f_{\text{best}}$ 是搜索过程中最好成绩的提升量,相当于猎人从第一顿到现在提升的口味分。
    Δfbest\Delta f_{\text{best}}
  2. 评估次数$N_{\text{eval}}$ 是真实训练或真实试吃的次数,也就是花掉的预算。
    NevalN_{\text{eval}}
  3. 样本效率$E_{\text{sample}}$ 越高,说明每一顿昂贵的饭换来的地图进步越大。
    Esample=ΔfbestNevalE_{\text{sample}} = \frac{\Delta f_{\text{best}}}{N_{\text{eval}}}

AI 应用场景

深度学习模型超参数调优

阶段:模型开发与调优阶段

解决的问题:网格搜索需要把学习率、批大小、权重衰减等组合全部试一遍,每次训练可能耗时数小时,GPU 成本极高。贝叶斯优化用代理模型学习历史训练结果,用采集函数挑选最有价值的下一组超参数,大幅减少训练次数。

具体案例:某算法团队训练图像分类模型时,用 Optuna 的 TPE 采样器替代网格搜索。原本 200 次全量训练才能找到好配置,用贝叶斯优化约 40 次就达到了相近准确率,GPU 成本下降约八成。

神经架构搜索 NAS

阶段:架构搜索阶段

解决的问题:候选神经网络结构组合爆炸,每个候选都要完整训练一次,暴力枚举不现实。贝叶斯优化把网络层数、卷积核大小、正则策略等作为搜索变量,用代理模型预测结构性能,再逐步聚焦最可能成功的结构区域。

具体案例:在语音识别任务中搜索轻量级 CNN 结构,单个候选训练需要 2 小时。贝叶斯优化每轮只选 1 个高潜力的结构验证,节省了数千 GPU 小时,最终搜到的结构比人工设计基线准确率更高。

Python 演示

python55 行
import numpy as npfrom scipy.stats import norm  def objective(x):    # 真实且昂贵的评估函数    return -((x - 0.37) ** 2 + 0.2 * np.sin(8 * x))  class GaussianProcessRegressor:    def __init__(self, length_scale=0.2, noise=1e-4):        self.l = length_scale        self.noise = noise        self.X = np.empty((0, 1))        self.y = np.empty((0,))     def fit(self, X, y):        self.X = X        self.y = y.ravel()     def predict(self, X_test):        K = self._kernel(self.X, self.X) + self.noise * np.eye(len(self.X))        Ks = self._kernel(self.X, X_test)        Kss = self._kernel(X_test, X_test)        L = np.linalg.cholesky(K)        alpha = np.linalg.solve(L.T, np.linalg.solve(L, self.y))        mu = Ks.T @ alpha        v = np.linalg.solve(L, Ks)        var = np.diag(Kss) - np.sum(v * v, axis=0)        return mu, np.sqrt(var)     def _kernel(self, A, B):        sq = np.sum(A ** 2, axis=1)[:, None] + np.sum(B ** 2, axis=1)[None, :] - 2 * A @ B.T        return np.exp(-sq / (2 * self.l * self.l))  def expected_improvement(X, model, y_best):    mu, sigma = model.predict(X)    gamma = (mu - y_best) / sigma    return (mu - y_best) * norm.cdf(gamma) + sigma * norm.pdf(gamma)  if __name__ == "__main__":    x_grid = np.linspace(0, 1, 201).reshape(-1, 1)    X = np.array([[0.2], [0.6], [0.8]])    y = objective(X).ravel()    model = GaussianProcessRegressor()    for step in range(10):        model.fit(X, y)        ei = expected_improvement(x_grid, model, y.max())        x_next = x_grid[np.argmax(ei)]        y_next = objective(x_next)        X = np.vstack([X, x_next.reshape(1, -1)])        y = np.append(y, y_next)        print("step=%d x=%.4f y=%.4f" % (step, float(x_next), float(y_next)))
目的:实现一个最简贝叶斯优化循环,用高斯过程代理模型和 EI 采集函数,在 1 维昂贵函数上逐轮寻找最优参数。
  1. model.fit(X, y)用历史试吃记录更新寻味地图。
  2. ei = expected_improvement(x_grid, model, y.max())计算每个候选点相对当前最佳表现的期望提升。
  3. x_next = x_grid[np.argmax(ei)]找出 EI 最大的点作为下一顿的候选餐厅。
  4. X = np.vstack([X, x_next.reshape(1, -1)])把新评估点加入历史数据,让地图越来越清晰。

常见误区

误区贝叶斯优化应该就是随机搜索加一点运气,多跑几次就能找到好参数。

正解随机搜索不学习历史信息,每次取值彼此独立;贝叶斯优化则会建立代理模型,并在每次评估后更新对目标函数的认知。地图会越画越准,随机乱走不会。

为何常见:两者都只采样少量点,表面上看都是“碰运气”,但贝叶斯优化的每一次选择都在使用历史情报。

误区既然地图已经预测出哪里好吃,下一步当然要选预测分数最高的位置。

正解纯选均值最高是“利用”,会错过未知区域。采集函数会同时考虑不确定度,像 UCB 一样给未知区域加冒险分,EI 也会计算可能超过当前最佳的概率。

为何常见:均值最好理解,大家容易忽略“不确定度”这个同样重要的信息。

误区贝叶斯优化就是高斯过程,换个模型就不叫贝叶斯优化了。

正解代理模型可以是高斯过程、TPE、随机森林等多种模型。TPE 在高维和混合超参数空间里常常更实用,Optuna 默认使用的就是 TPE。

为何常见:很多入门教程用 GP 做例子,“高斯过程”这个术语出现频率最高,导致以偏概全。

误区只要迭代次数足够多,贝叶斯优化就会找到绝对最优的超参数。

正解模型假设、初始化样本、采集函数和噪声都可能影响最终结果。贝叶斯优化能够高效逼近优秀区域,但不能保证每次都在有限预算内命中全局最优。

为何常见:看到优化曲线不断上升,容易误以为它收敛到了全局极值。

误区贝叶斯优化样本效率高,所以任何调参场景都该用它。

正解如果单次评估特别便宜,代理模型的训练和采集函数计算反而成了额外开销。此时随机搜索甚至可能更划算。贝叶斯优化适合“评估昂贵”的场景。

为何常见:营销式教程总强调“比随机搜索好”,忽略了前提条件。

面试题

Q1. 贝叶斯优化相比网格搜索最核心的优势是什么?

单选题 · easy

  • A.代码实现更简单
  • B.样本效率更高← 正确答案
  • C.一定能找到全局最优
  • D.不需要定义搜索空间

答案:B。贝叶斯优化用代理模型和采集函数选择下一评估点,能用更少的昂贵评估接近最优解。网格搜索虽然实现简单,但样本效率低;C 和 D 都不符合贝叶斯优化的特性。

Q2. 采集函数中 EI 表示什么?

单选题 · easy

  • A.期望提升← 正确答案
  • B.最大似然
  • C.最小方差
  • D.平均梯度

答案:A。EI 是 Expected Improvement 的缩写,意思是“候选点相对当前最佳值的期望提升量”。它结合了超越概率和超越幅度,是贝叶斯优化中常用的选点标准。

Q3. 贝叶斯优化里“代理模型”的主要任务是什么?

单选题 · easy

  • A.直接训练最终模型
  • B.近似目标函数← 正确答案
  • C.生成训练数据
  • D.压缩存储日志

答案:B。代理模型用便宜的计算近似昂贵的目标函数,例如高斯过程、TPE 等。它不负责训练最终模型,而是给采集函数提供预测均值和不确定度。

Q4. 高斯过程预测结果除了均值还会提供什么?

单选题 · mid

  • A.特征重要度
  • B.梯度方向
  • C.不确定性方差← 正确答案
  • D.模型参数量

答案:C。高斯过程输出一个分布,既有预测均值 $\mu(x)$,也有不确定性方差 $\sigma^2(x)$。这个方差让贝叶斯优化能够在探索未知区域和利用已知最优区域之间做权衡。

Q5. 在 UCB 采集函数中增大 κ 会让算法如何变化?

单选题 · mid

  • A.更专注已知最优区域
  • B.更愿意尝试未知区域← 正确答案
  • C.完全忽略预测均值
  • D.收敛速度必然提升

答案:B。UCB 公式是 $\mu(x) + \kappa \sigma(x)$。增大 $\kappa$ 会放大不确定度的权重,让算法更偏爱未充分探索的区域;但不一定保证收敛更快。

Q6. 下面哪些属于贝叶斯优化中常用的采集函数?

多选题 · mid

  • A.期望提升(EI)← 正确答案
  • B.置信上界(UCB)← 正确答案
  • C.随机梯度下降(SGD)
  • D.丢弃法(Dropout)

答案:AB。常见的采集函数包括 EI、UCB、PI 等。SGD 是优化器,Dropout 是正则化方法,它们都不负责选择下一个超参数评估点。

Q7. 相比高斯过程,TPE 更突出的优势是什么?

单选题 · mid

  • A.更擅长高维混合参数← 正确答案
  • B.不需要目标函数
  • C.低维空间绝对更准
  • D.无需任何历史数据

答案:A。TPE 通过分别建模“好点”和“差点”的概率密度来指导搜索,在高维和混合类型超参数空间里更灵活。它仍然需要目标函数和历史数据,也不是绝对更准。

Q8. 贝叶斯优化流程中“更新数据集”具体指什么?

单选题 · hard

  • A.从历史样本中随机删除旧数据
  • B.把新评估点及结果加入历史样本← 正确答案
  • C.对原始训练数据做数据增强
  • D.将全部历史样本复制一份

答案:B。完成一轮真实评估后,需要把新选择的 $x$ 和观测到的 $y$ 加入数据集 $\mathcal{D}$,再用增强后的数据集重新拟合代理模型,形成闭环。

Q9. 哪些场景更适合选用贝叶斯优化?

多选题 · hard

  • A.单次训练评估耗时数小时← 正确答案
  • B.搜索空间大且评估代价高← 正确答案
  • C.每次训练只需毫秒级
  • D.只有两个离散取值

答案:AB。贝叶斯优化的优势是减少昂贵评估次数。如果评估很快,地图建模开销可能反而不划算;如果搜索空间只有两个离散值,枚举即可,也不需要复杂代理模型。

Q10. 若随机搜索表现不输贝叶斯优化,最可能的原因是什么?

单选题 · extreme

  • A.评估便宜导致建模成本不划算← 正确答案
  • B.随机搜索总能覆盖完整搜索空间
  • C.贝叶斯优化不能处理离散变量
  • D.高斯过程在任何场景都不准确

答案:A。贝叶斯优化的建模和采集函数计算也有成本。如果单次评估极便宜,省下的评估次数不足以抵消建模开销,随机搜索反而更有性价比。其他选项是绝对化或错误说法。