实用超参数优化

241 阅读10分钟

关于如何使用以下技术微调机器和深度学习模型的简介:随机搜索,自动超参数调整和人工神经网络调整。

![](https://static001.geekbang.org/infoq/19/19e2018f56d864eeef2f9ba1e54ad2ec.png)

介绍

机器学习模型由两种不同类型的参数组成:

  • 超参数=是用户在开始训练之前可以任意设置的所有参数(例如,Random Forest中的估计量)。

  • 取而代之的是在模型训练过程中学习模型参数(例如,神经网络中的权重,线性回归)。

模型参数定义了如何使用输入数据来获得所需的输出,并在训练时进行学习。相反,超参数首先确定我们的模型的结构。

机器学习模型调整是一种优化问题。我们有一组超参数,我们的目标是找到它们的值的正确组合,这可以帮助我们找到函数的最小值(例如,损耗)或最大值(例如,精度)。

当比较不同的机器学习模型如何对数据集执行时,这尤其重要。实际上,例如将具有最佳超参数的SVM模型与尚未优化的随机森林模型进行比较将是不公平的。

在这篇文章中,将说明以下超参数优化方法:

  1. 手动搜寻

  2. 随机搜寻

  3. 网格搜索

  4. 自动超参数调整(贝叶斯优化,遗传算法)

  5. 人工神经网络(ANN)调整

![](https://static001.geekbang.org/infoq/e6/e664ad2d39c8c6c00da4e1d2c0014986.png)

为了演示如何在Python中执行超参数优化,我决定对信用卡欺诈检测Kaggle数据集执行完整的数据分析 。本文的目的是正确分类哪些信用卡交易应标记为欺诈或真实(二进制分类)。该数据集在分发前已被匿名化,因此,大多数功能的含义尚未公开。

在这种情况下,我决定仅使用数据集的一个子集,以加快训练时间并确保在两个不同的类之间实现完美的平衡。此外,仅使用了少量功能就使优化任务更具挑战性。最终数据集如下图所示(图2)。

![](https://static001.geekbang.org/infoq/11/11bc1537ddb8fab190ce17f205cd35fd.png)

机器学习

首先,我们需要将数据集分为训练集和测试集。

在本文中,我们将使用随机森林分类器作为模型进行优化。

随机森林模型由大量不相关的决策树形成,这些决策树共同构成一个整体。在随机森林中,每个决策树都进行自己的预测,并且将整体模型输出选择为最常出现的预测。

现在,我们可以从计算基本模型的准确性开始。

![](https://static001.geekbang.org/infoq/28/28eaeef2e08e831ff968663b7e6c5e23.png)

将随机森林分类器与默认的scikit-learn参数一起使用可获得95%的整体准确性。现在让我们看看是否应用一些优化技术可以提高精度。

手动搜寻

使用“手动搜索”时,我们会根据我们的判断/经验选择一些模型超参数。然后,我们训练模型,评估模型的准确性并重新开始该过程。重复该循环,直到获得满意的准确性为止。

随机森林分类器使用的主要参数是:

  • 标准 =用于评估分割质量的函数。

  • max_depth =每棵树中允许的最大级别数。

  • max_features =拆分节点时考虑的最大特征数。

  • min_samples_leaf =可以存储在树叶中的最小样本数。

  • min_samples_split =节点中导致节点分裂所需的最小样本数。

  • n_estimators =集成树的数量。

可以在scikit-learn 文档中找到有关随机森林参数的更多信息。

作为手动搜索的示例,我尝试指定模型中的估计量。不幸的是,这并没有导致准确性的提高。

![](https://static001.geekbang.org/infoq/7e/7e62586fe1f6863dde336728df71febf.png)

随机搜寻

在随机搜索中,我们创建超参数网格,并仅基于这些超参数的某些随机组合来训练/测试模型。在此示例中,我另外决定对训练集执行交叉验证。

在执行机器学习任务时,我们通常将数据集分为训练集和测试集。这样做是为了在训练模型后测试我们的模型(通过这种方式,我们可以在处理看不见的数据时检查其性能)。使用交叉验证时,我们将训练集划分为其他N个分区,以确保我们的模型不会过度拟合我们的数据。

最常用的交叉验证方法之一是K折验证。在K-Fold中,我们将训练集划分为N个分区,然后使用N-1个分区迭代地训练模型,并使用剩余的分区进行测试(在每次迭代中,我们都会更改剩余的分区)。一旦对模型进行了N次训练,我们就可以平均每次迭代获得的训练结果,从而获得整体训练效果结果。

![](https://static001.geekbang.org/infoq/40/40fc16587016ab9f560e30d08625e977.png)

在实现超参数优化时使用交叉验证非常重要。这样,我们可能会避免使用一些对训练数据非常有效但对测试数据却不太好的超参数。

现在,我们可以通过首先定义一个超参数网格来开始实现随机搜索,在调用_RandomizedSearchCV()时将随机采样该超参数网格 。对于此示例,我决定将训练集划分为4折(cv = 4),并选择80作为要采样的组合数(n_iter = 80)。然后,使用scikit-learn **best_estimator** 属性,可以检索在训练过程中表现最佳的超参数集,以测试我们的模型。

训练完模型后,我们可以可视化更改其某些超参数如何影响整体模型的准确性(图4)。在这种情况下,我决定观察改变估计量和准则的数量如何影响我们的随机森林准确性。

![](https://static001.geekbang.org/infoq/a0/a04dea592cc0be26df5ca06eeac12b7d.png)

然后,我们可以使可视化更具交互性,从而使这一步骤更进一步。在下面的图表中,我们可以检查(使用滑块)在模型中考虑估计的min_split和min_leaf参数时,改变估算器数量如何影响模型的整体准确性。

现在,我们可以使用随机搜索评估模型的性能。在这种情况下,与我们的基本模型相比,使用随机搜索会导致准确性不断提高。

![](https://static001.geekbang.org/infoq/bc/bc3112ddf3a835fcdb3c6dfb5724d7e2.png)

网格搜索

在网格搜索中,我们建立了一个超参数网格,并在每种可能的组合上训练/测试我们的模型。

为了选择在Grid Search中使用的参数,我们现在可以查看哪些参数与Random Search一起使用效果最好,并根据这些参数形成网格,以查看是否可以找到更好的组合。

可以使用scikit-learn GridSearchCV() 函数在Python中实现网格搜索 。同样在这种情况下,我决定将训练集划分为4折(cv = 4)。

使用网格搜索时,将尝试网格中所有可能的参数组合。在这种情况下,训练期间将使用128000个组合(2×10×4×4×4×10)。相反,在前面的“网格搜索”示例中,仅使用了80种组合。

![](https://static001.geekbang.org/infoq/42/42a5a0389ee0e7f6eee467a2f983c32a.png)

与随机搜索相比,网格搜索速度较慢,但由于它可以遍历整个搜索空间,因此总体上更有效。取而代之的是,随机搜索可以更快更快,但是可能会错过搜索空间中的一些重要点。

自动超参数调整

使用自动超参数调整时,将使用以下技术来标识要使用的模型超参数:贝叶斯优化,梯度下降和进化算法。

贝叶斯优化

贝叶斯优化可以使用Hyperopt库在Python中执行。贝叶斯优化使用概率来找到函数的最小值。最终目的是找到函数的输入值,该函数可以为我们提供尽可能低的输出值。

贝叶斯优化已被证明比随机,网格或手动搜索更有效。因此,贝叶斯优化可以在测试阶段带来更好的性能,并减少优化时间。

在Hyperopt中,可以实现贝叶斯优化,为函数**fmin()**提供3个三个主要参数 。

  • 目标函数 =定义要最小化的损失函数。

  • 域空间 =定义要测试的输入值的范围(在贝叶斯优化中,该空间为每个使用的超参数创建概率分布)。

  • 优化算法 =定义用于选择最佳输入值以在每次新迭代中使用的搜索算法。

此外,还可以在_fmin()中_定义 要执行的最大评估数。

贝叶斯优化可以通过考虑过去的结果来选择输入值,从而减少搜索迭代的次数。这样,我们可以从一开始就将搜索集中在更接近所需输出的值上。

现在,我们可以使用fmin() 函数运行贝叶斯优化器 。 首先创建一个 Trials()对象,以便稍后可视化fmin() 函数运行时正在发生的事情 (例如,loss函数的变化方式以及Hyperparameters的使用方式变化)。

![](https://static001.geekbang.org/infoq/85/855bbdd4789e7bf00b9b02c8fb2ffec4.png)

现在,我们可以检索识别出的最佳参数集,并使用 在训练过程中创建的_最佳字典来测试模型 。一些参数已 使用索引_数字方式存储在 _最佳_字典中,因此,我们需要先将它们转换回字符串,然后再将其输入到随机森林中。

使用贝叶斯优化的分类报告如下所示。

![](https://static001.geekbang.org/infoq/8d/8d3afeb79b54788b22c08037ae1659d9.png)

遗传算法

遗传算法试图将自然选择机制应用于机器学习环境。它们受到达尔文自然选择过程的启发,因此通常也称为进化算法。

假设我们创建了具有一些预定义超参数的N个机器学习模型。然后,我们可以计算每个模型的准确性,并决定只保留一半模型(性能最好的模型)。现在,我们可以生成具有与最佳模型相似的超参数的后代,以便再次获得N个模型的种群。在这一点上,我们可以再次计算每个模型的准确性,并在定义的世代中重复该循环。这样,只有最佳模型才能在流程结束时生存下来。

为了在Python中实现遗传算法,我们可以使用 TPOT自动机器学习库。TPOT建立在scikit-learn库上,可用于回归或分类任务。

以下代码片段显示了使用遗传算法确定的培训报告和最佳参数。

![](https://static001.geekbang.org/infoq/40/40e5e5ac77e8c2b8b4e91b077bf61915.png)

我们的随机森林遗传算法优化模型的整体准确性如下所示。

![](https://static001.geekbang.org/infoq/fc/fce18a539446b10804710edeb3e45752.png)

人工神经网络(ANN)调整

使用KerasClassifier包装器,可以像使用scikit-learn机器学习模型时一样,对深度学习模型应用网格搜索和随机搜索。在以下示例中,我们将尝试优化一些ANN参数,例如:在每个层中使用多少个神经元,以及使用哪个激活函数和优化器。此处提供更多深度学习超参数优化的示例 。

![](https://static001.geekbang.org/infoq/9d/9d77bc9298c941cc0442544cd2c7fddc.png)

使用我们的人工神经网络(ANN)评分的总体准确性可以在下面看到。

![](https://static001.geekbang.org/infoq/81/81599bb154917329af52015d65264aed.png)

评价

现在,我们可以比较在此给定练习中所有不同优化技术的执行情况。总体而言,随机搜索和进化算法的效果最佳。

![](https://static001.geekbang.org/infoq/c7/c7cc5bac885e8b01d48a156e0334dd1b.png)

获得的结果高度依赖于所选的网格空间和所使用的数据集。因此,在不同情况下,不同的优化技术将比其他技术表现更好。

如果你喜欢本文的话,欢迎点赞转发!谢谢。

看完别走还有惊喜!

我精心整理了计算机/Python/机器学习/深度学习相关的2TB视频课与书籍,价值1W元。关注微信公众号“计算机与AI”,点击下方菜单即可获取网盘链接。

![](https://static001.geekbang.org/infoq/90/903237ffd0a3b3ae06272386f26ecb9e.png)