默认参数的最优化

场景:速读时,有些学生速读 1 次就能复述,有些需要 2 次,有些需要 N 次,而建议速读次数 X 是个默认值,这个默认值到底取多少合适
技术:使用线性回归技术

TODO1:非常全的总结:https://www.cnblogs.com/chuqianyu/p/17684614.html

网格搜索是暴力搜索,在给定超参搜索空间内,尝试所有超参组合,最后搜索出最优的超参组合。sklearn已实现该方法,使用样例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn import svm, datasets
from sklearn.model_selection import GridSearchCV
import pandas as pd

# 导入数据
iris = datasets.load_iris()
# 定义超参搜索空间
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
# 初始化模型
svc = svm.SVC()
# 网格搜索
clf = GridSearchCV(estimator = svc,
param_grid = parameters,
scoring = 'accuracy',
n_jobs = -1,
cv = 5)
clf.fit(iris.data, iris.target)

# 打印结果
print('详细结果:\n', pd.DataFrame.from_dict(clf.cv_results_))
print('最佳分类器:\n', clf.best_estimator_)
print('最佳分数:\n', clf.best_score_)
print('最佳参数:\n', clf.best_params_).

sklearn.model_selection.GridSearchCV的重要参数说明:

  • estimator: scikit-learn模型。
  • param_grid: 超参搜索空间,即超参数字典。
  • scoring: 在交叉验证中使用的评估策略。
  • n_jobs: 并行任务数,-1为使用所有CPU。
  • cv: 决定采用几折交叉验证。

随机搜索是在搜索空间中采样出超参组合,然后选出采样组合中最优的超参组合。随机搜索的好处如下图所示:

解释图1,如果目前我们要搜索两个参数,但参数A重要而另一个参数B并没有想象中重要,网格搜索9个参数组合(A, B),而由于模型更依赖于重要参数A,所以只有3个参数值是真正参与到最优参数的搜索工作中。反观随机搜索,随机采样9种超参组合,在重要参数A上会有9个参数值参与到搜索工作中,所以,在某些参数对模型影响较小时,使用随机搜索能让我们有更多的探索空间

同样地,sklearn实现了随机搜索,样例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

from sklearn import svm, datasets
from sklearn.model_selection import RandomizedSearchCV
import pandas as pd
from scipy.stats import uniform


# 导入数据
iris = datasets.load_iris()
# 定义超参搜索空间
distributions = {'kernel':['linear', 'rbf'], 'C':uniform(loc=1, scale=9)}
# 初始化模型
svc = svm.SVC()
# 网格搜索
clf = RandomizedSearchCV(estimator = svc,
param_distributions = distributions,
n_iter = 4,
scoring = 'accuracy',
cv = 5,
n_jobs = -1,
random_state = 2021)
clf.fit(iris.data, iris.target)


# 打印结果
print('详细结果:\n', pd.DataFrame.from_dict(clf.cv_results_))
print('最佳分类器:\n', clf.best_estimator_)
print('最佳分数:\n', clf.best_score_)
print('最佳参数:\n', clf.best_params_)

相比于网格搜索,sklearn随机搜索中主要改变的参数是param_distributions,负责提供超参值分布范围。

贝叶斯优化(Bayesian Optimization)

调优的目的是要找到一组最优的超参组合,能使目标函数 ff 达到全局最小值。

x=argminf(x),xX\begin{matrix}x^*=argminf(x),x\in X\end{matrix}

在机器学习中,目标函数 ff 常是被称作expensive blackbox function,计算开销大且不一定为凸函数。为此,贝叶斯优化出现了,它特别适合针对expensive blackbox function找到全局最优

假设我们的真实的目标函数 f(x)f(x) 长下图这样:

注意: 目标函数 f(x)f(x)xx 是指超参数,我们希望找到最优的超参 xx 去得到最小的 f(x)f(x) 。为什么用虚线表示 f(x)f(x) 呢?因为它是黑箱函数 (blackbox function)。也就是说我们根本不知道 f(x)f(x) 具体是什么样的,就好比我们不知道用某一个学习率的值训练出的模型效果会是什么样子。

这里有一个问题,每次尝试一种超参值 xx ,计算 f(x)f(x) 的代价是昂贵的,为了减轻开销,贝叶斯优化采用了代理模型 (surrogate model),代理模型可以被看作是一个简单模型去拟合原本复杂且不好理解的模型。

贝叶斯优化使用了高斯过程 (gasussian processes, GP) 去构建代理模型,高斯过程的细节这里暂时不讲,有兴趣的小伙伴可以自行查阅资料了解。基于给定的输入和输出,GP 会推断出一个模型 (这里为代理模型)。假设我们从昂贵的 f(x)f(x) 采样了 4 个点,然后我们把这 4 个点交给 GP,它会返回一个代理模型,如下图所示:

绿色实线就是 GP 猜的代理模型,绿色条带是输出分布的标准差 (即为 Uncertainty)。我们有了代理模型,后续我们去找下一个合适的超参值,就能带入到计算开销相对较小的代理模型中,评估给定超参值的情况。

现在,我们来思考回之前提到的问题:" 如何找到下一个合适的点?",这个问题本质是在问:“哪里有全局最小的点?”,为了解决这个问题,我们要关注两个地方:

  • 已开发区域: 在绿色实线上最低的超参点。因为很可能它附近存在全局最优点。

  • 未探索区域: 绿色实线上还未被探索的区域。比如上图,相比于 0.15-0.25 区间,0.65-0.75 区间更具有探索价值 (即该区间 Uncertainty 更大)。探索该区域有利于减少我们猜测的方差。

为了实现以上探索和开发的平衡 (exploration-exploitation trade-off),贝叶斯优化使用了采集函数 (acquisition function),它能平衡好全局最小值的探索和开发。

TODO 2: 迭代策略与采集函数

https://banxian-w.com/article/2023/3/27/2539.html

https://leovan.me/cn/2020/06/bayesian-optimization/

https://mp.weixin.qq.com/s/waPWzo6iIEXYaH_MQdLfYg

Hyperband

TODO 3

https://www.cnblogs.com/marsggbo/p/10161605.html

https://blog.csdn.net/jose_M/article/details/106313669

高斯过程回归

疑似最切题的一种方法

TODO4

https://banxian-w.com/article/2023/3/17/2522.html

https://cloud.tencent.com/developer/article/1965403

一些执行超参数搜索的tips和tricks

1. Implementation

大型神经网络通常需要很长时间来训练,因此执行超参数搜索可能需要很多天/周的时间。记住这一点很重要,因为它会影响代码库的设计。一种特殊的设计是让一个worker不断地对随机超参数进行采样并执行优化。在训练期间,worker将跟踪每个epoch之后的validation performance,并将模型检查点(以及其他训练统计信息,如随时间的损失 the loss over time)写入文件,最好是在共享文件系统上。将validation performance直接包含在文件名中是很有用的,这样可以方便地检查和排序进度。然后还有第二个程序,我们称之为master,它在计算集群中启动或终止worker,还可以检查worker编写的检查点,绘制他们的训练统计数据等。

2. Prefer one validation fold to cross-validation

在大多数情况下,一个大小合适的单一验证集大大简化了代码库,而不需要多次交叉验证。你会听到人们说他们“交叉验证”了一个参数,但很多时候都假设他们仍然只使用了一个验证集。

3. Hyperparameter ranges

在对数尺度上搜索超参数。例如,学习率的典型抽样如下learning_rate = 10 ** uniform(-6, 1)。也就是说,我们从 一个均匀分布中生成一个随机数,然后把它乘以10的幂。正则化强度也应采用相同的策略。直观地说,这是因为学习率和正则化强度对training dynamics有乘法效应(multiplicative effects)。例如,当学习率为0.001时,学习率加0.01的固定变化对dynamics有很大影响,而当学习率为10时,几乎没有影响。这是因为在更新中学习率和计算的梯度相乘了。因此,将一个范围内的学习率乘以或除以某个值,比将这个范围内的学习率乘以或减去某个值要合适得多。一些参数(如dropout)通常在原始比例(original scale)中搜索(如dropout = uniform(0,1))。

正如Bergstra and Bengio在Random Search for Hyper-Parameter Optimization上所说的:“randomly chosen trials比trials on a grid更有效”。事实证明,这通常也更容易实现。


通常情况下,某些超参数比其他超参数更重要(例如图中顶部的超参数与左侧的超参数相比)。相比于网格搜索,执行随机搜索可以更精确地发现重要值。

5. Careful with best values on border

有时可能发生的情况是,你正在一个坏的范围(bad range)内搜索一个超参数(如学习率)。例如,假设我们使用learning_rate = 10 ** uniform(-6, 1)。一旦我们获取到结果,重要的是要再次检查最终的学习率不在此间隔的边缘,否则你可能会错过超出此间隔的更优化的超参数设置。

6. Stage your search from coarse to fine

在实践中,一个好的方法是首先在粗略范围(例如10**[-6,1])中搜索,然后根据最佳结果出现的位置缩小范围。此外,在只训练1个epoch或更少epoch的情况下进行初始粗搜索也是有帮助的,因为许多超参数设置会导致模型根本不进行学习,或者因为无穷大的代价(infinite cost)而直接崩溃,代价是无限的。然后,第二阶段可以对5个epochs执行更窄的搜索,最后一阶段可以在最终范围内对更多epochs执行详细搜索。

7. Bayesian Hyperparameter Optimization

贝叶斯超参数优化是一个致力于提出更有效地寻找超参数空间的算法研究领域。其核心思想是在查询不同超参数下的性能时,适当地平衡exploration - exploitation之间的权衡。在这些模型的基础上还开发了多个库,其中一些比较著名的是Spearmint、SMAC和Hyperopt。然而,在使用ConvNets的实际环境中,carefully-chosen intervals击败random search仍然是相对困难的。

Reference

https://cs231n.github.io/neural-networks-3/

https://blog.csdn.net/weixin_44120025/article/details/114677393

https://mp.weixin.qq.com/s/waPWzo6iIEXYaH_MQdLfYg