器→工具, 开源项目, 数据, 术→技巧
[LATEXPAGE]
目录
学习器模型中一般有两类参数,一类是可以从数据中学习估计得到,我们称为参数(Parameter)。还有一类参数时无法从数据中估计,只能靠人的经验进行设计指定,我们称为超参数(Hyper parameter)。超参数是在开始学习过程之前设置值的参数。 相反,其他参数的值通过训练得出。
超参数:
参数空间的搜索一般由以下几个部分构成:
在机器学习模型中,比如随机森林中决策树的个数,人工神经网络模型中的隐藏层层数和每层的节点个数,正则项中常数大小等等,它们都需要事先指定。超参数选择不恰当,就会出现欠拟合或者过拟合的问题。在Scikit-Learn中,超参数是在学习过程开始之前设置其值的参数。典型的例子包括支持向量机里的C、kernel、gamma等。
class sklearn.svm.SVC(*, C=1.0, kernel='rbf', degree=3, gamma='scale', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', break_ties=False, random_state=None)
使用过程中可以使用estimator.get_params() 获得学习器模型的超参数列表和当前取值。
Sklearn提供了两种通用的超参数优化方法:网格搜索与随机搜索。
在机器学习里,通常来说我们不能将全部用于数据训练模型,否则我们将没有数据集对该模型进行验证,从而评估我们的模型的预测效果。为了解决这一问题,有如下常用的方法:
这种是方法最简单的,也是很容易就想到的。我们可以把整个数据集分成两部分,一部分用于训练,一部分用于验证,这也就是我们经常提到的训练集(training set)和测试集(test set)。
不过,这个简单的方法存在两个弊端:
基于这样的背景,有人就提出了Cross-Validation方法,也就是交叉验证。
LOOCV(留一法)
LOOCV即(Leave-one-out cross-validation)。像Test set approach一样,LOOCV方法也包含将数据集分为训练集和测试集这一步骤。但是不同的是,我们只用一个数据作为测试集,其他的数据都作为训练集,并将此步骤重复N次(N为数据集的数据数量)。
假设我们现在有n个数据组成的数据集,那么LOOCV的方法就是每次取出一个数据作为测试集的唯一元素,而其他n-1个数据都作为训练集用于训练模型和调参。结果就是我们最终训练了n个模型,每次都能得到一个MSE。而计算最终test MSE则就是将这n个MSE取平均。
$$CV(n) = \frac{1}{n}\sum_{i=1}^{n}MSE_i$$
比起test set approach,LOOCV有很多优点。首先它不受测试集合训练集划分方法的影响,因为每一个数据都单独的做过测试集。同时,其用了n-1个数据训练模型,也几乎用到了所有的数据,保证了模型的bias更小。不过LOOCV的缺点也很明显,那就是计算量过于大,是test set approach耗时的n-1倍。
K-fold Cross Validation(k 折交叉验证)
K折交叉验证,和LOOCV的不同在于,我们每次的测试集将不再只包含一个数据,而是多个,具体数目将根据K的选取决定。比如,如果K=5,那么我们利用五折交叉验证的步骤就是:
$$CV(k) = \frac{1}{k}\sum_{i=1}^{k}MSE_i$$
不难理解,其实LOOCV是一种特殊的K-fold Cross Validation(K=N)。最后K的选取是一个Bias和Variance的trade-off。K越大,每次投入的训练集的数据越多,模型的Bias越小。但是K越大,又意味着每一次选取的训练集之前的相关性越大(考虑最极端的例子,当k=N,也就是在LOOCV里,每次都训练数据几乎是一样的)。而这种大相关性会导致最终的test error具有更大的Variance。一般K值选择5或10。
我们在选择超参数有两个途径:1)凭经验;2)选择不同大小的参数,带入到模型中,挑选表现最好的参数。通过途径2选择超参数时,人力手动调节注意力成本太高,非常不值得。For循环或类似于for循环的方法受限于太过分明的层次,不够简洁与灵活,注意力成本高,易出错。GridSearchCV 称为网格搜索交叉验证调参,它通过遍历传入的参数的所有排列组合,通过交叉验证的方式,返回所有参数组合下的评价指标得分。
GridSearchCV听起来很高大上,其实就是暴力搜索。注意的是,该方法在小数据集上很有用,数据集大了就不太适用了。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法:拿当前对模型影响最大的参数调优,直到最优化;再拿下一个影响最大的参数调优,如此下去,直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优,但是省时间省力。
class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, refit=True, cv='warn', verbose=0, pre_dispatch='2*n_jobs', error_score='raise-deprecating', return_train_score='warn')
参数详解:
GridSearchCV对象
GridSearchCV方法
使用示例:
from sklearn.model_selection import GridSearchCV from sklearn.svm import SVR from sklearn import datasets dataset = datasets.load_iris() X = dataset.data y = dataset.target grid = GridSearchCV( estimator=SVR(kernel='rbf'), param_grid={ 'C': [0.1, 1, 10, 100], 'epsilon': [0.0001, 0.001, 0.01, 0.1, 1, 10], 'gamma': [0.001, 0.01, 0.1, 1] }, cv=5, scoring='neg_mean_squared_error', verbose=0, n_jobs=-1) grid.fit(X, y) print(grid.best_score_) print(grid.best_params_)
我们在搜索超参数的时候,如果超参数个数较少(三四个或者更少),那么我们可以采用网格搜索,一种穷尽式的搜索方法。但是当超参数个数比较多的时候,我们仍然采用网格搜索,那么搜索所需时间将会指数级上升。所以有人就提出了随机搜索的方法,随机在超参数空间中搜索几十几百个点,其中就有可能有比较小的值。这种做法比上面稀疏化网格的做法快,而且实验证明,随机搜索法结果比稀疏网格法稍好。
RandomizedSearchCV使用方法和类GridSearchCV 很相似,但他不是尝试所有可能的组合,而是通过选择每一个超参数的一个随机值的特定数量的随机组合,这个方法有两个优点:
RandomizedSearchCV的使用方法其实是和GridSearchCV一致的,但它以随机在参数空间中采样的方式代替了GridSearchCV对于参数的网格搜索,在对于有连续变量的参数时,RandomizedSearchCV会将其当做一个分布进行采样进行这是网格搜索做不到的,它的搜索能力取决于设定的n_iter参数。
class sklearn.model_selection.RandomizedSearchCV(estimator, param_distributions, *, n_iter=10, scoring=None, n_jobs=None , refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', random_state=None, error_score=nan, return_train_score=False)
与GridSearchCV不同的主要有以下两参数:
使用示例:
from scipy.stats import randint as sp_randint from sklearn.model_selection import RandomizedSearchCV from sklearn.datasets import load_digits from sklearn.ensemble import RandomForestClassifier # 载入数据 digits = load_digits() X, y = digits.data, digits.target # 建立一个分类器或者回归器 clf = RandomForestClassifier(n_estimators=20) # 给定参数搜索范围:list or distribution param_dist = {"max_depth": [3, None], # 给定list "max_features": sp_randint(1, 11), # 给定distribution "min_samples_split": sp_randint(2, 11), # 给定distribution "bootstrap": [True, False], # 给定list "criterion": ["gini", "entropy"]} # 给定list # 用RandomSearch+CV选取超参数 n_iter_search = 20 random_search = RandomizedSearchCV(clf, param_distributions=param_dist, n_iter=n_iter_search, cv=5, iid=False) random_search.fit(X, y) print(random_search.best_score_) print(random_search.best_params_)
贝叶斯优化用于机器学习调参由J. Snoek(2012)提出,主要思想是,给定优化的目标函数(广义的函数,只需指定输入和输出即可,无需知道内部结构以及数学性质),通过不断地添加样本点来更新目标函数的后验分布(高斯过程,直到后验分布基本贴合于真实分布。简单的说,就是考虑了上一次参数的信息,从而更好的调整当前的参数。
贝叶斯优化与常规的网格搜索或者随机搜索的区别是:
贝叶斯优化提供了一个优雅的框架来尽可能少的步骤中找到全局最小值。
让我们构造一个函数c(x)或者一个接收输入x的模型,如下图所示为c(x)的形状。当然,优化器并不知道该函数,称之为“目标函数”。
贝叶斯优化通过代理优化的方式来完成任务。代理函数通过采样点模拟构造(见下图)。
根据代理函数,我们大致可以确定哪些点是可能的最小值。然后再这些点附近做更多的采样,并随之更新代理函数。
每一次迭代,我们都会继续观察当前的代用函数,通过采样了解更多感兴趣的区域,并更新函数。需要注意的是,代用函数在数学上的表达方式将大大降低评估成本。经过一定的迭代次数后,我们注定要到达一个全局最小值,除非函数的形状非常诡异。
让我们仔细看看代用函数,通常用高斯过程来表示,它可以被认为是掷骰子,返回与给定数据点(如sin、log)拟合的函数,而不是1到6的数字。这个过程会返回几个函数,这些函数都附有概率。为什么用高斯过程,而不是其他的曲线拟合方法来模拟代用函数,有一个很好的理由:它是贝叶斯性质的。代用函数–表示为概率分布,即先验–被更新为 “获取函数”。这个函数负责在勘探和开发的权衡中提出新的测试点。
一个鼓励过多的开发和过少探索的获取函数将导致模型只停留在它首先发现的最小值(通常是局部的–“只去有光的地方”)。一个鼓励相反的获取函数将不会首先停留在一个最小值,本地或全球。在微妙的平衡中产生良好的结果。acquisition 函数,我们将其表示为a(x),必须同时考虑开发和探索。常见的获取函数包括预期改进和最大改进概率,所有这些函数都是在给定先验信息(高斯过程)的情况下,衡量特定投入在未来可能得到回报的概率。
让我们把这些东西整合起来。贝叶斯优化可以这样进行。
贝叶斯优化就是把概率论的思想放在代入优化的思想后面。综上所述:
Hyperopt是一个强大的Python库,用于超参数优化,由jamesbergstra开发。Hyperopt使用贝叶斯优化的形式进行参数调整,允许你为给定模型获得最佳参数。它可以在大范围内优化具有数百个参数的模型。
Hyperopt包含4个重要的特性
1、搜索空间
hyperopt有不同的函数来指定输入参数的范围,这些是随机搜索空间。选择最常用的搜索选项:
你可以使用的其他选项包括:
2、目标函数
这是一个最小化函数,它从搜索空间接收超参数值作为输入并返回损失。这意味着在优化过程中,我们使用选定的超参数值训练模型并预测目标特征,然后评估预测误差并将其返回给优化器。优化器将决定要检查哪些值并再次迭代。你将在一个实际例子中学习如何创建一个目标函数。
3、fmin
4、试验对象
Trials对象用于保存所有超参数、损失和其他信息,这意味着你可以在运行优化后访问它们。此外,trials 可以帮助你保存和加载重要信息,然后继续优化过程。
Hyperopt的使用
在理解了Hyperopt的重要特性之后,下面将介绍Hyperopt的使用方法。
from sklearn import datasets from hyperopt import fmin, tpe, hp, STATUS_OK, Trials from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import cross_val_score iris = datasets.load_iris() X = iris.data y = iris.target def hyperopt_train_test(params): clf = KNeighborsClassifier(**params) return cross_val_score(clf, X, y).mean() # 定义参数空间 space_knn = { 'n_neighbors': hp.choice('n_neighbors', range(1, 100)) } # 定义最小化函数(目标函数) def fn_knn(params): acc = hyperopt_train_test(params) return {'loss': -acc, 'status': STATUS_OK} # hyperopt最小化函数,所以在acc中添加了负号 # 实例化Trial 对象,对模型进行微调,然后用其超参数值打印出最佳损失 trials = Trials() best = fmin(fn_knn, space_knn, algo=tpe.suggest, max_evals=100, trials=trials) print("Best: {}".format(best)) print(trials.results) # 搜索期间“objective”返回的词典列表。
algo指定搜索算法,目前支持以下算法:
除了Hyperopt外,贝叶斯优化方法的Python包还有:
遗传算法试图将自然选择机制应用于机器学习环境。它受到达尔文自然选择过程的启发,因此通常也称为进化算法。假设我们创建了具有一些预定义超参数的N个机器学习模型。然后,我们可以计算每个模型的准确性,并决定只保留一半模型(性能最好的模型)。现在,我们可以生成具有与最佳模型相似的超参数的后代,以便再次获得N个模型的种群。在这一点上,我们可以再次计算每个模型的准确性,并在定义的世代中重复该循环。这样,只有最佳模型才能在流程结束时生存下来。
TPOT是一种基于遗传算法优化机器学习管道(pipeline)的Python自动机器学习工具。简单来说,就是TPOT可以智能地探索数千个可能的pipeline,为数据集找到最好的pipeline,从而实现机器学习中最乏味的部分。
更重要地是,一旦TPOT完成搜索,TPOT同时也提供了Python代码。通过这个代码,我们可以具体地知道TPOT获得最优性能时的具体pipeline的内容,这对于后续修改是十分方便的!
TPOT是在sklearn的基础之上做的封装库。其主要封装了sklearn的模型相关模块、processesing模块和feature_selection模块,所以TPOT的主要功能是集中在使用pipeline的方式完成模型的数据预处理、特征选择和模型选择方面。此外,我们还发现了TPOT已经对xgboost进行了支持。
虽然TPOT使用遗传算法代替了传统的网格搜索进行超参数选择,但由于默认初始值的随机性,在少量的进化(迭代)次数下,TPOT最终选择的模型往往并不相同。
计算效率问题。作者在代码中写道:进化(迭代)次数和每一代保留的个体数量值越多,最终得模型得分会越高。但这同样也会导致耗时很长。如果使用相当复杂的数据集或运行TPOT短时间,不同的TPOT运行可能会导致不同的流水线推荐。TPOT的优化算法本质上是随机的,这意味着它使用随机性(部分地)来搜索可能的流水线空间。当两个TPOT运行推荐不同的管道时,这意味着TPOT运行由于时间不够而不收敛,或者多个管道在数据集上执行的次数大致相同。这实际上是一个优于固定网格搜索技术的优点:TPOT是一个助手,它通过探索您可能从未考虑过的流水线配置来提供解决如何解决特定机器学习问题的想法,然后将微调留给更受约束的参数调整技术,例如网格搜索。
使用TPOT(版本0.9.5)开发模型需要把握以下几点:
示例代码:
from tpot import TPOTClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split iris = load_iris() X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) tpot = TPOTClassifier(generations=5, population_size=50, verbosity=2, n_jobs=-1) tpot.fit(X_train, y_train) print(tpot.score(X_test, y_test))
TPOT的主要参数:
使用这个迭代过程,我们选出最佳配置。 准备遗传算法的结果一般取决于初始状态。 因此,它随机产生的初始种群影响输出,重新运行相同的设置可能会输出不同的结果。
Scikit-Optimize(Skopt)
是一个超参数优化库,包括随机搜索、贝叶斯搜索、决策森林和梯度提升树。这个库包含一些理论成熟且可靠的优化方法,但是这些模型在小型搜索空间和良好的初始估计下效果最好。
auto-sklearn
Auto-sklearn 提供了开箱即用的监督型自动机器学习。从名字可以看出,auto-sklearn 是基于机器学习库 scikit-learn 构建的,可为新的数据集自动搜索学习算法,并优化其超参数。因此,它将机器学习使用者从繁琐的任务中解放出来,使其有更多时间专注于实际问题。
Simple(x)
一个优化库,可作为贝叶斯优化的替代方法。Simple(x)和贝叶斯搜索一样,试图以尽可能少的样本进行优化,但也将计算复杂度从n³降低到log(n),这对大型搜索空间非常有用。这个库使用单形(n维三角形),而不是超立方体(n维立方体),来模拟搜索空间,这样做可以避开贝叶斯优化中具有高计算成本的高斯过程。
Ray.tune
是一个超参数优化库,主要适用于深度学习和强化学习模型。它结合了许多先进算法,如Hyperband算法(最低限度地训练模型来确定超参数的影响)、基于群体的训练算法(Population Based Training,在共享超参数下同时训练和优化一系列网络)、Hyperopt方法和中值停止规则(如果模型性能低于中等性能则停止训练)。这些都运行在Ray分布式计算平台上,这让它具有很强的扩展性。
Chocolate
是一个分布式超参数优化库(支持计算机集群的并行运算且无需中央主机),它使用通用数据库来联合执行各个任务。它还支持网格搜索、随机搜索、准随机搜索、贝叶斯搜索和自适应协方差矩阵进化策略。它的优势体现在它支持受约束的搜索空间和多损失函数优化(多目标优化)。
GpFlowOpt
一个基于GpFlow库的高斯过程优化器,可使用TensorFlow在GPU上运行高斯过程任务。你如果要用到贝叶斯优化且有可用的GPU计算资源,那GpFlowOpt库应该是理想之选。
FAR-HO
运行在TensorFlow上,包含一系列基于梯度的优化器,包括Reverse-HG和Forward-HG。这个库旨在构建TensorFlow中基于梯度的超参数优化器的访问,允许在GPU或其他张量优化计算环境中进行深度学习模型的训练和超参数优化。
Xcessiv
支持大规模模型开发、执行和集成。它的优势在于能够在单个GUI界面中管理多个机器学习模型的训练、执行和评估。它具有多个集成工具来组合这些模型,以实现最佳性能。它包括一个贝叶斯搜索参数优化器,这个优化器支持高级别并行计算,还支持与TPOT库的集成。
HORD
一个用于超参数优化的独立算法,它能为需要优化的黑盒模型生成一个代理函数,并用它来生成最接近理想状态的超参数组合,以减少对整个模型的评估。与Tree Parzen Estimators、SMAC和高斯过程方法相比,它始终具有更高的一致性和更低的错误率,而且这个方法特别适用于极高维数据分析。
ENAS-pytorch
可在pytorch中实现高效的深度学习结构搜索。它使用参数共享来构建更高效的网络,使其适用于深度学习结构搜索。
Keras Tuner
Keras官方出品,是一个易于使用、可分布式的超参数优化框架,用于解决执行超参数搜索的痛点。Keras Tuner可以很容易地定义搜索空间,并利用所包含的算法来查找最佳超参数值。 Keras Tuner内置了贝叶斯优化(Bayesian Optimization)、Hyperband和随机搜索(Random Search)算法,同时也便于研究人员扩展,进行新搜索算法的试验。
Hyperas
是将hyperopt与keras相结合的库。
talos
Talos的优势在于原样暴露了Keras,没有引进任何新语法。Talos把超参数优化的过程从若干天缩短到若干分钟,也使得优化过程更有意思,而不是充满了痛苦的重复。
Auto-PyTorch
一个自动机器学习的框架,通过PyTorch实现神经网络体系架构的自动搜索。它源自Mendoza等人的工作Towards Automatically-Tuned Deep Neural Networks。
Katib
是对 Google Vizier 的开源实现,因此也遵循其中对问题的抽象模型:Study,Trial 和 Suggestion。
HyperparameterHunter
RL Baselines Zoo
是一系列用Stable Baselines预训练的强化学习agents。它也提供用于训练、评估agents、微调超参数、记录视频的基础脚本。
参考链接:
深圳SEO优化公司本溪seo优化推荐延边百度竞价昆明网站搭建哪家好宝安网站推广工具多少钱安阳网站搭建多少钱铜陵品牌网站设计淮北百度seo价格辽阳百度标王多少钱苏州网站seo优化价格铜仁网络营销价格威海seo网站优化多少钱邯郸网页制作公司郴州网站改版哪家好平湖外贸网站建设公司毕节网站改版价格长春外贸网站设计晋中SEO按天计费价格临汾百搜标王多少钱吴忠seo网站推广哪家好泉州品牌网站设计报价自贡建站江门模板制作报价周口网站优化推荐辽源SEO按天扣费报价诸城网络推广价格威海网站改版价格大浪网站设计模板公司怒江关键词按天收费报价黑河如何制作网站公司阜阳网站推广多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运