Python 理解hyperopt';s-TPE算法

Python 理解hyperopt';s-TPE算法,python,optimization,bayesian,hyperopt,Python,Optimization,Bayesian,Hyperopt,我正在为我的主项目演示hyperopt的TPE算法,但似乎无法使算法收敛。据我从原始和youtube上了解,TPE算法按以下步骤工作: (在下文中,x=超参数,y=损耗) 首先创建[x,y]的搜索历史记录,比如说10个点 根据超参数的损失对其进行排序,并使用一些分位数γ将其分为两组(γ=0.5表示这些集的大小相等) 对差超参数群(g(x))和好超参数群(l(x))进行核密度估计 好的估计在g(x)中具有低概率,在l(x)中具有高概率,因此我们建议在argmin(g(x)/l(x))处对函数进行评

我正在为我的主项目演示hyperopt的TPE算法,但似乎无法使算法收敛。据我从原始和youtube上了解,TPE算法按以下步骤工作:

(在下文中,x=超参数,y=损耗)

  • 首先创建[x,y]的搜索历史记录,比如说10个点
  • 根据超参数的损失对其进行排序,并使用一些分位数γ将其分为两组(γ=0.5表示这些集的大小相等)
  • 对差超参数群(g(x))和好超参数群(l(x))进行核密度估计
  • 好的估计在g(x)中具有低概率,在l(x)中具有高概率,因此我们建议在argmin(g(x)/l(x))处对函数进行评估
  • 在建议的点评估(x,y)对,并重复步骤2-5
  • 我已经用python在目标函数f(x)=x^2上实现了这一点,但该算法无法收敛到最小值

    将numpy导入为np
    将scipy作为sp导入
    从matplotlib导入pyplot作为plt
    从scipy.stats导入高斯_kde
    定义目标函数(x):
    返回x**2
    def测量(x):
    噪声=np.random.randn(len(x))*0
    返回x**2+噪声
    def分割测量(x_obs,y_obs,伽马=1/2):
    #将x和y观测值分成两组,并返回一个分离阈值(y_星)
    大小=整数(len(x_obs)/(1/伽马))
    l={'x':x_obs[:size],'y':y_obs[:size]}
    g={'x':x_obs[size:],'y':y_obs[size:}
    y_星=(l['y'][-1]+g['y'][0])/2
    返回l,g,y_星
    #用于说明的目标函数值示例
    x_obj=np.linspace(-5,510000)
    y_obj=目标函数(x_obj)
    #首先对参数搜索历史进行采样
    x_obs=np.linspace(-5,5,10)
    y_obs=测量值(x_obs)
    nr_迭代次数=100次
    对于范围内的i(nr_迭代):
    #根据损失对观察结果进行排序
    sort_idx=y_obs.argsort()
    x_obs,y_obs=x_obs[sort_idx],y_obs[sort_idx]
    #将已排序的观察结果分成两组(l和g)
    l、 g,y_星=分割测量(x_obs,y_obs)
    #使用核密度估计两组的近似分布
    kde_l=高斯(l['x'])。评估(x_obj)
    kde_g=高斯(g['x'])。评估(x_obj)
    #定义采样新点的评估度量
    eval_measure=kde_g/kde_l
    如果i%10==0:
    plt.图()
    plt.子地块(2,2,1)
    plt.绘图(x_obj,y_obj,label='Objective')
    plt.绘图(x_obs,y_obs,“*”,标签为观察值)
    plt.绘图([-5,5],[y_星,y_星],'k')
    plt.子地块(2,2,2)
    plt.plot(x_obj,kde_l)
    plt.子地块(2,2,3)
    plt.plot(x_obj,kde_g)
    plt.子地块(2,2,4)
    plt.符号学(x_obj,eval_度量)
    plt.draw()
    #找到要评估的点并添加新的观察结果
    最佳搜索=x_obj[np.argmin(评估度量)]
    x_obs=np.append(x_obs,[最佳搜索])
    y_obs=np.append(y_obs,[measure(np.asarray([best_search])))
    plt.show()
    

    我怀疑这是因为我们一直在最确定的地方取样,从而使l(x)在这一点附近越来越窄,这根本不会改变我们取样的位置。那么,我的理解还有哪些不足呢?

    因此,我仍然在学习TPE。但这段代码中有两个问题:

  • 此代码将只计算几个唯一点。因为最佳位置是根据内核密度函数推荐的最佳位置计算出来的,但是代码无法探索搜索空间。例如,采集功能的作用

  • 因为这段代码只是在x和y的列表中添加新的观察值。它添加了大量的重复项。重复导致了一组扭曲的观察结果,这导致了一个非常奇怪的分裂,你可以很容易地在后面的图中看到这一点。
    eval_度量开始时与目标函数类似,但随后会出现分歧


  • 如果在
    x_obs
    y_obs
    中删除重复项,则可以删除问题2。然而,第一个问题只能通过添加一些探索搜索空间的方法来解决

    谢谢你的评论。我发现了问题所在,这确实是你指出的;新的搜索点不是搜索最确定的点(导致重复),而是从近似分布中提取。这一页确实帮助我最终理解了TPE算法(如果你还在学习的话)。