机器学习超参数调优指南(附代码)

548 阅读40分钟

公众号:尤而小屋
作者:Peter
编辑:Peter

大家好,我是Peter~

本文的主题:机器学习建模的超参数调优。开局一张图:

文章很长,建议直接收藏~

一、什么是机器学习超参数?

机器学习超参数是在开始学习过程之前设置值的参数,而不是通过训练得到的参数数据。

超参数是在模型训练之外设置的选项,不会在训练过程中被优化或更改。相反,需要在训练之前手动设置它们,并且对模型的性能有很大的影响。

二、为什么要进行机器学习超参数的调优?

在机器学习中,通常需要针对特定任务选择和调整超参数。例如,在支持向量机(SVM)中,有一个重要的超参数是正则化参数C,它可以控制模型复杂度并影响模型的泛化能力。在训练神经网络时,学习率和批次大小也是常见的超参数,它们可以影响模型的收敛速度和最终的预测效果。

机器学习超参数的调优是为了找到一组最佳的超参数组合,使模型在特定任务上表现最佳。超参数的调优对于提高模型性能、防止过拟合、加速收敛等方面都非常重要。

不同的超参数组合可以显著影响模型的性能,因此通过调优来找到最佳的超参数组合是非常必要的。

下文从网格搜索等直接调优方法、基于Optuna等调优工具、基于AutoML的调优、基于算法的调优等4个方面进行阐述。

三、超参数调优方法

常用的超参数调优方法有以下几种:

  • 网格搜索(Grid Search):网格搜索是一种简单的超参数调优方法,它通过穷举指定的参数组合,计算每一组参数在验证集上的表现,最终选择表现最好的参数组合。
  • 贝叶斯优化:贝叶斯优化是一种利用贝叶斯定理和最优化方法寻找全局最优解的优化算法,它适用于高维、高成本、有限样本的优化问题。
  • 随机搜索(Random Search):随机搜索是一种基于随机采样的超参数调优方法,它通过在参数空间中随机选择参数组合,寻找最优解。

3.1 网格搜索Grid Search

1、什么是网格搜索

网格搜索(Grid Search)是一种超参数调优方法,它通过穷举指定的参数组合,计算每一组参数在验证集上的表现,最终选择表现最好的参数组合。

https://pyimagesearch.com/2021/05/24/grid-search-hyperparameter-tuning-with-scikit-learn-gridsearchcv/

网格搜索是一种简单而有效的调优方法,常用于确定最佳的超参数组合。

2、网格搜索的python实战

from sklearn.model_selection import GridSearchCV  
from sklearn.svm import SVC  
from sklearn.datasets import load_iris  
  
# 加载数据集  
iris = load_iris()  
X = iris.data  
y = iris.target  
  
# 定义模型  
svm = SVC(kernel='linear', C=100, gamma='auto')  
  
# 定义网格搜索参数范围  
param_grid = {  
    'C': [0.1, 1, 10, 100],  
    'gamma': [1e-3, 1e-2, 1e-1, 1],  
}  
  
# 创建网格搜索对象  
grid_search = GridSearchCV(svm, param_grid, cv=5)  
  
# 对数据进行网格搜索  
grid_search.fit(X, y)  
  
# 输出最佳参数组合和对应的得分  
print('Best parameters:', grid_search.best_params_)  
print('Best score:', grid_search.best_score_)
  • 使用了Scikit-learn库中的GridSearchCV类来实现网格搜索
  • 定义了一个参数网格(param_grid),其中包含了C和gamma两个超参数的不同取值组合
  • 创建了一个GridSearchCV对象,并将参数网格、SVM模型和交叉验证(cv)参数传入
  • 使用best_params_和best_score_属性输出最佳参数组合和对应的得分

3.2随机搜索Random Search

1、什么是随机搜索

随机搜索是一种优化方法,它通过在允许的范围内随机生成点来搜索可能的解决方案,并计算每个点的目标函数值。然后,它根据目标函数值选择下一个点进行搜索,以逐步接近最优解。

这种方法适用于处理高维、非线性、非凸或非连续的优化问题,特别是当精确解的计算成本非常高时。

2、基于随机搜索的python实战

import numpy as np  
from sklearn.datasets import load_iris  
from sklearn.ensemble import RandomForestClassifier  
  
# 加载数据集  
iris = load_iris()  
X = iris.data  
y = iris.target  
  
# 定义随机搜索函数  
def random_search(X, y, model, param_space, iteration_num):  
    best_score = -1  
    best_params = None  
    for i in range(iteration_num):  
        # 从参数空间中随机采样一组超参数  
        params = {k: v[np.random.randint(len(v))] for k, v in param_space.items()}  
        # 训练模型并计算验证集上的准确率  
        model.set_params(**params)  
        score = model.score(X[:100], y[:100])  
        # 更新最优解  
        if score > best_score:  
            best_score = score  
            best_params = params  
    return best_score, best_params  
  
# 定义随机森林分类器模型  
model = RandomForestClassifier()  
  
# 定义超参数空间  
param_space = {  
    'n_estimators': [100, 200, 300, 400, 500],  
    'max_depth': [2, 3, 4, 5, 6],  
    'max_features': ['auto', 'sqrt', 'log2'],  
    'bootstrap': [True, False]  
}  
  
# 执行随机搜索  
best_score, best_params = random_search(X, y, model, param_space, 100)  
print('最佳准确率:', best_score)  
print('最佳超参数:', best_params)
  • 使用随机森林分类器模型,并定义了四个需要优化的超参数:n_estimators、max_depth、max_features和bootstrap
  • 从参数空间中随机采样100组超参数,然后使用验证集上的准确率来评估这些超参数的优劣,最终输出最佳准确率和对应的最佳超参数

网格搜索优化和随机搜索优化的对比:

3.3贝叶斯优化

1、什么是贝叶斯优化

贝叶斯优化是一种黑盒优化算法,用于求解表达式未知的函数的极值问题。它基于贝叶斯定理,通过构建概率模型来描述目标函数的后验分布,并利用这个模型来选择下一个采样点,以最大化采样价值。

其核心思想是利用高斯过程回归(Gaussian Process Regression, GPR)来建模目标函数的分布。GPR认为目标函数是由一系列训练数据点(输入和输出)所构成的随机过程,通过高斯概率模型来描述这个随机过程的概率分布。贝叶斯优化通过不断地添加样本点来更新目标函数的后验分布,直到后验分布基本贴合真实分布。

贝叶斯优化有两个核心过程:

  • 先验函数(Prior Function, PF):PF主要利用高斯过程回归来建模目标函数的先验分布
  • 采集函数(Acquisition Function, AC):AC主要包括 Expected Improvement(EI)、Probability of Improvement(PI)和 Upper Confidence Bound(UCB)等方法,用于衡量每一个点对目标函数优化的贡献,并选择下一个采样点。

贝叶斯优化在机器学习种被用于AutoML算法,自动确定机器学习算法的超参数。它也是一种全局极值搜索方法,特别适用于高维非线性非凸函数,具有较好的效果和效率。

贝叶斯优化以函数被视为一个满足某种分布的随机过程,通过在定义域内求函数值,使用贝叶斯公式更新对分布的估计,然后根据新的分布找到最可能的极值点位置,从而提高对函数及其极值的估计的精确性。

2、贝叶斯优化的python实战

import numpy as np  
from scipy.optimize import minimize  
from sklearn.gaussian_process import GaussianProcessRegressor  
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C  
  
# 定义目标函数  
def f(x):  
    return np.sin(5 * x) + np.cos(x)  
  
# 定义高斯过程回归模型  
kernel = C(1.0, (1e-3, 1e3)) * RBF(10, (1e-2, 1e2))  
gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10)  
  
# 定义贝叶斯优化函数  
def bayesian_optimization(X_train, y_train, X_test):  
    # 训练高斯过程回归模型  
    gpr.fit(X_train, y_train)  
    # 计算测试集的预测值和方差  
    y_pred, sigma = gpr.predict(X_test, return_std=True)  
    # 计算期望改进(Expected Improvement)  
    gap = y_pred - f(X_test)  
    improvement = (gap + np.sqrt(sigma ** 2 + 1e-6) * np.abs(gap).mean()) * 0.5  
    # 计算高斯过程回归模型的超参数  
    result = minimize(gpr.kernel_, np.zeros(gpr.kernel_.shape[0]), method='L-BFGS-B')  
    hyperparameters = result.x  
    # 输出最优超参数和对应的期望改进值  
    return hyperparameters, improvement.max()  
  
# 定义贝叶斯优化的迭代次数和采样点数量  
n_iter = 20  
n_samples = 5  
  
# 进行贝叶斯优化  
results = []  
for i in range(n_iter):  
    # 在定义域内随机采样n_samples个点  
    X_train = np.random.uniform(-2 * np.pi, 2 * np.pi, (n_samples, 1))  
    y_train = f(X_train)  
    # 进行贝叶斯优化并记录最优超参数和对应的期望改进值  
    result = bayesian_optimization(X_train, y_train, X_test=np.random.uniform(-2 * np.pi, 2 * np.pi, (100, 1)))  
    results.append(result)  
    print('Iter: {}, Hyperparameters: {:.2f}, Expected Improvement: {:.4f}'.format(i, result[0][0], result[1]))
  • 定义目标函数f
  • 使用高斯过程回归模型(GPR)来建模目标函数的分布
  • 定义贝叶斯优化函数bayesian_optimization;其中训练集、测试集和采样点数作为输入,输出最优的超参数和对应的期望改进值
  • Expected Improvement作为采集函数,通过不断地添加样本点来更新目标函数的后验分布,并使用L-BFGS-B方法来最小化高斯过程回归模型的超参数

四、基于超参数调优工具

4.1 什么是超参数优化库?

超参数优化库(Hyperparameter Optimization Library)是一种用于自动化超参数优化的软件库或工具。这些库使用不同的算法和技术,以实现自动化超参数搜索和优化过程。

超参数优化库通常提供易于使用的接口,允许用户定义要优化的超参数和目标函数。它们使用不同的算法和技术,如网格搜索、随机搜索、遗传算法、贝叶斯优化等,以搜索和优化超参数空间。这些库的目标是减少人工调整超参数的工作量,提高模型性能,并加速机器学习模型的训练过程。

4.2 常见的超参数优化工具

以下是几个常用的超参数优化库:

  • scikit-Opitimize
  • Hyperopt
  • Optuna
  • Spearmint
  • Gaussian Process-based Hyperparameter Optimization (GPGO)
  • Ray Tune
  • GPyOpt
  • SigOpt
  • Keras Tuner

这些库都提供了不同的算法和工具,以实现超参数优化,并具有不同的特点和优点。您可以根据您的需求选择最适合您的库。

4.3Scikit-Optimize库

1、Scikit-Optimize库简介

Scikit-optimize 是一个 Python 库,用于执行基于scipy的优化算法。它旨在提供一种简单而有效的工具,用于机器学习和科学计算的优化问题。Scikit-optimize 提供了许多不同的优化算法,包括梯度下降、随机搜索、贝叶斯优化等。

Scikit-optimize 提供了许多预定义的搜索空间和目标函数,以便轻松地设置超参数优化任务。用户可以定义自己的搜索空间和目标函数,以适应特定的机器学习模型和任务。Scikit-optimize 还提供了可视化工具,可以帮助用户更好地理解优化过程和结果。

2、基于python的Scikit-Optimize库优化实战

import numpy as np  
from sklearn.datasets import load_iris  
from sklearn.ensemble import RandomForestClassifier  
from sklearn.model_selection import train_test_split  
from sklearn.metrics import accuracy_score  
from skopt import gp_minimize  
  
# 加载数据集  
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, random_state=42)  
  
# 定义机器学习模型  
clf = RandomForestClassifier()  
  
# 定义搜索空间和目标函数  
search_space = {  
    'n_estimators': [100, 200, 500],  
    'max_depth': [3, 5, None],  
    'max_features': ['auto', 'sqrt', 'log2']  
}  
  
def objective(x):  
    clf.set_params(**{search_space[name]: x[name] for name in x})  
    clf.fit(X_train, y_train)  
    y_pred = clf.predict(X_test)  
    return -accuracy_score(y_test, y_pred)  
  
# 执行优化算法  
res = gp_minimize(objective, search_space, n_calls=20, random_state=42)  
  
# 输出最优超参数组合和对应的验证准确率  
print("Best hyperparameters:", res.x)  
print("Max validation accuracy:", res.fun)

4.4 Hyperopt库

1、Hyperopt库简介

Hyperopt是一个Python库,用于对机器学习模型的算法进行智能搜索。它主要使用三种算法:随机搜索算法、模拟退火算法和TPE(Tree-structured Parzen Estimator)算法。

安装Hyperopt库:可以使用pip命令来安装Hyperopt库:

pip install hyperopt

使用步骤:

  • 准备目标函数:目标函数应该是一个可优化的函数,它接受一个超参数列表作为输入,并返回一个标量值。在Hyperopt中,使用fn来指定目标函数。
  • 定义超参数搜索空间:使用Hyperopt的hp模块定义超参数的搜索空间。可以使用hp.choice、hp.uniform等函数来定义不同类型的超参数。
  • 使用fmin函数进行优化:使用Hyperopt的fmin函数进行优化,该函数接受目标函数、超参数搜索空间和优化算法作为输入,并返回最佳的超参数组合。

官方学习地址:github.com/hyperopt/hy…

2、基于python优化的实战案例

from hyperopt import hp, fmin, tpe  
from sklearn.datasets import load_iris  
from sklearn.model_selection import train_test_split  
from sklearn.svm import SVC  
  
# 加载数据集  
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, random_state=42)  
  
# 定义目标函数  
def objective(params):  
    clf = SVC(kernel=params['kernel'], C=params['C'], gamma=params['gamma'])  
    clf.fit(X_train, y_train)  
    score = clf.score(X_test, y_test)  
    return -score  # 因为Hyperopt需要最小化目标函数,所以我们需要将准确率取反  
  
# 定义超参数搜索空间  
space = {  
    'kernel': hp.choice('kernel', ['linear', 'poly', 'rbf', 'sigmoid']),  
    'C': hp.uniform('C', 0.001, 10),  
    'gamma': hp.uniform('gamma', 0.001, 10)  
}  
  
# 使用贝叶斯优化进行超参数搜索  
best = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=100)  
print('Best parameters: ', best)

4.5 Optuna库

1、Optuna库简介

Optuna是一个用于超参数优化的库,它支持定义目标函数,搜索超参数空间并自动进行优化。

可以使用pip命令来安装Optuna库:

pip install Optuna

使用步骤:

  • 定义搜索空间:使用Optuna提供的分布函数来定义超参数的搜索空间。例如,对于一个取值范围为[0, 1]的浮点数,可以使用uniform函数来定义该超参数的搜索空间。
  • 定义目标函数:目标函数是需要优化的模型,可以是任何可调用对象,如Python函数、类方法等。目标函数的输入是超参数的值,输出是模型的性能指标。
  • 创建Optuna试验:创建Optuna试验对象,并指定目标函数和搜索算法。
  • 运行Optuna试验:运行Optuna试验,进行超参数搜索。在每次试验结束后,Optuna会更新超参数的取值,并记录当前试验的性能指标。可以设置尝试的次数或时间,来控制搜索空间的大小和搜索时间的限制。
  • 分析试验结果:在试验结束后,可以使用Optuna提供的可视化工具来分析试验结果,并选择最优的超参数组合。

2、基于python的使用案例

import numpy as np  
from sklearn.datasets import make_regression  
from sklearn.model_selection import train_test_split  
from sklearn.linear_model import SGDRegressor  
  
# 生成数据集  
X, y = make_regression(n_samples=100, n_features=1, noise=0.1)  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  
  
# 定义目标函数  
def objective(trial):  
    # 定义超参数  
    learning_rate = trial.suggest_float('learning_rate', 1e-10, 1e-5)  
    batch_size = trial.suggest_int('batch_size', 32, 256)  
    optimizer = trial.suggest_categorical('optimizer', ['sgd', 'adam'])  
  
    # 创建模型  
    model = SGDRegressor(learning_rate=learning_rate, batch_size=batch_size, optimizer=optimizer)  
  
    # 训练模型  
    model.fit(X_train, y_train)  
  
    # 计算性能指标  
    loss = np.mean((model.predict(X_test) - y_test) ** 2)  
    return loss

# 创建Optuna的study对象,并指定需要优化的目标函数和搜索空间
import optuna  
study = optuna.create_study()  
study.optimize(objective, n_trials=100)

# 最佳的超参数组合
print(study.best_params)  # 输出最佳的超参数组合  
print(study.best_value)   # 输出最佳的性能指标值

4.6Spearmint库

1、Spearmint库简介

Spearmint是一个用于优化贝叶斯推断的库。它基于论文《实用贝叶斯优化》中概述的算法。该库可用于执行贝叶斯优化,这是一种用于全局优化的算法,主要用于寻找最小化目标函数的配置。(建议少使用)

github.com/JasperSnoek…

Spearmint库提供了一种表达和优化贝叶斯推断问题的方式。它允许用户定义目标函数以及用于描述优化问题的约束和边界。库中的核心算法则负责根据这些定义来优化目标函数。Spearmint库的优点包括:

  • 灵活的目标函数表达:Spearmint支持多种类型的数据和复杂的模型结构,使得用户可以灵活地表达各种目标函数。
  • 高性能:Spearmint通过高效的实现和优化算法来提高运行速度,从而能够处理大规模的数据集和复杂的模型。
  • 易于使用:Spearmint提供了简单易用的接口,使得用户可以轻松地配置和运行优化任务。
  • 社区支持:Spearmint是由一个活跃的社区支持的开源项目,这意味着用户可以获得来自其他开发者的反馈和支持。

2、基于Spearmint的实战案例

import numpy as np  
import spearmint as sp  
from scipy.stats import norm  
  
# 定义目标函数  
def objective(x):  
    # 假设目标函数是一个简单的二次函数,其中x是一个向量  
    return x[0]**2 + x[1]**2  
  
# 定义Spearmint的优化器  
spearmint = sp.Spearmint()  
  
# 设置要优化的参数范围  
var_names = ['var1', 'var2']  
bounds = [[-5, 5], [-5, 5]]  
priors = [sp.priors.NormalPrior(0, 1), sp.priors.NormalPrior(0, 1)]  
  
# 运行贝叶斯优化,设置最大迭代次数为10次  
results = spearmint.optimize(objective, var_names, bounds, priors, n_iter=10)  
  
# 输出最优的参数组合和对应的函数值  
print('最优参数组合:', results.x)  
print('最优函数值:', results.func)

4.7GPGO库

1、GPGO简介

GPGO全称是Gaussian Process Optimization for Hyperparameters Optimization,是Google的超参数优化库,它使用Gaussian Processes(高斯过程)进行超参数优化,专为TensorFlow和Keras而设计。

高斯过程是一种强大的非参数贝叶斯模型,它为超参数优化提供了一种概率框架,可以自动管理探索与利用的权衡。

使用之前先安装:

pip install gpgo

使用步骤:

  • 首先,需要定义要优化的目标函数(例如,神经网络的训练损失)。
  • 其次,需要定义搜索空间,即超参数的可能取值范围。
  • 然后,使用GPGO运行优化过程。在每次迭代中,优化器会选择一组超参数,并使用目标函数评估该组超参数的性能。
  • 最后,优化器会根据评估结果更新其关于最佳超参数的信念,并继续搜索,直到达到预设的终止条件(例如,达到最大迭代次数或找到满意的超参数组合)。

2、python实战案例

import numpy as np  
import tensorflow as tf  
from tensorflow.keras.datasets import mnist  
from tensorflow.keras.models import Sequential  
from tensorflow.keras.layers import Dense, Flatten  
from gpgo import GPGO  
  
# 加载MNIST数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()  
# 数据缩放
x_train = x_train / 255.0  
x_test = x_test / 255.0  
  
# 1-定义神经网络模型  
model = Sequential([  
    Flatten(input_shape=(28, 28)),  
    Dense(128, activation='relu'),  
    Dense(64, activation='relu'),  
    Dense(10)  
])  
  
#2- 定义优化目标函数(即神经网络的训练损失)  
def loss_fn(y_true, y_pred):  
    return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_pred))  
  
# 3-定义优化器并设置超参数的搜索空间  
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4)  
hyperparams = {  
    'kernel__lgcp': [5, 10, 20],  
    'kernel__scale': [1e-4, 1e-3, 1e-2],  
    'kernel__lengthscale': [1., 5., 10.]  
}  
  
# 4-创建GPGO优化器并运行优化过程  
gpgo = GPGO(optimizer=optimizer, loss_fn=loss_fn, hyperparams=hyperparams, datasets=(x_train, y_train), epochs=10)  
best_params, best_loss = gpgo.run()
  • 加载MNIST数据集并定义了一个简单的神经网络模型
  • 定义了优化目标函数,即神经网络的训练损失
  • 创建了一个GPGO优化器,并将超参数的搜索空间传递给它
  • 使用run方法运行优化过程,并输出最佳超参数和最低的训练损失

4.8Ray Tune库

1、简介

Ray Tune是Ray的一个超参数优化库,可以用于优化深度学习模型的性能。它基于Scikit-learn和Google Vizier的接口,并提供了简单易用的API来定义和运行超参数搜索实验。

Ray Tune的特性包括:

  • 支持多种超参数优化算法,如网格搜索、随机搜索和贝叶斯优化等。
  • 可以自动管理实验的进度和结果,提供清晰的可视化界面。
  • 可以轻松扩展到分布式环境,支持多节点并行超参数搜索。
  • 与Ray框架无缝集成,可以轻松扩展到其他Ray任务中。

官方学习地址:docs.ray.io/en/latest/t…

2、官网提供的优化实战案例:

from ray import tune

def objective(config):  # 1-定义目标优化函数
    score = config["a"] ** 2 + config["b"]
    return {"score": score}

search_space = {  # 2-定义超参数搜索空间
    "a": tune.grid_search([0.001, 0.01, 0.1, 1.0]),
    "b": tune.choice([1, 2, 3]),
}

tuner = tune.Tuner(objective, param_space=search_space)  # 3-执行搜索过程
results = tuner.fit()
print(results.get_best_result(metric="score", mode="min").config)  # 最佳超参数组合

4.9 Bayesian Optimization库

1、简介

Bayesian optimization,也称为Bayesian experimental design或sequential design,是一种使用贝叶斯推理和高斯过程(Gaussian process)的全局优化技术。它是一种在尽可能少的迭代次数内找到一个未知函数的最大值或最小值的方法,特别适合优化高成本函数或在勘探和开发之间需要平衡的情况。

官方学习地址:github.com/bayesian-op…

先安装:

pip install bayesian-optimization

2、python实战案例

import numpy as np  
from sklearn.gaussian_process import GaussianProcessRegressor  
from scipy.optimize import minimize  
  
# 定义目标函数  
def target_function(x):  
    return np.sin(5 * x) + np.cos(2 * x) + np.random.normal(0, 0.1, size=x.shape)  
  
# 定义高斯过程模型  
def gpr_model(X, y):  
    kernel = 1.0 * np.eye(X.shape[0]) + 0.5 * np.ones((X.shape[0], X.shape[0]))  
    gpr = GaussianProcessRegressor(kernel=kernel)  
    gpr.fit(X, y)  
    return gpr  
  
# 定义Bayesian Optimization函数  
def bayesian_optimization(n_iterations, n_initial_points):  
    # 初始化数据点  
    x_initial = np.random.uniform(-5, 5, n_initial_points)  
    y_initial = target_function(x_initial)  
  
    # 初始化高斯过程模型  
    X_train = np.vstack((x_initial, x_initial))  
    y_train = np.vstack((y_initial, y_initial))  
    gpr = gpr_model(X_train, y_train)  
  
    # 进行n_iterations次迭代  
    for i in range(n_iterations):  
        # 使用EI策略选择新的数据点  
        acquisition_func = gpr.predictive_mean + np.sqrt(gpr.predictive_covariance(x_initial)[:, None, None]) * np.random.randn(*x_initial.shape)  
        EI = -gpr.negative_log_predictive_density(y_initial, acquisition_func)  
        x_new = x_initial[np.argmax(EI)]  
        y_new = target_function(x_new)  
        
        X_train = np.vstack((X_train, x_new))  
        y_train = np.vstack((y_train, y_new)) 
        
        gpr = gpr_model(X_train, y_train)  
        
        x_initial = np.vstack((x_initial, x_new))  
        y_initial = np.vstack((y_initial, y_new)) 
        
        print("Iteration {}: Best value = {} at x = {}".format(i+1, np.min(y_initial), np.argmin(y_initial)))  
    return x_initial[np.argmin(y_initial)], np.min(y_initial)  
  
# 运行Bayesian Optimization函数并输出结果  
best_x, best_y = bayesian_optimization(n_iterations=10, n_initial_points=3)  
print("Best x = {}, best y = {}".format(best_x, best_y))
  • 定义了一个目标函数target_function,该函数是一个带有随机噪声的正弦和余弦函数的组合;
  • 定义了一个高斯过程模型gpr_model,该模型使用一个常数核来构建高斯过程;
  • 定义了一个bayesian_optimization函数,该函数使用贝叶斯优化算法来找到目标函数的最大值;
  • 最后调用bayesian_optimization函数并输出结果

4.9GPyOpt库

1、简介

GPyOpt是一个基于GPy的Python库,用于实现贝叶斯优化。它提供了灵活的框架,可以处理具有各种类型代理模型(如高斯过程和随机森林)的优化问题。

GPyOpt库旨在解决实际问题,包括但不限于函数优化、超参数优化、深度学习中的模型调参等。使用者可以根据需要自定义代理模型,并且能够方便地与第三方库集成。此外,GPyOpt支持多种优化算法,如贝叶斯优化、粒子群优化等,以满足不同应用场景的需求。

官方学习地址:sheffieldml.github.io/GPyOpt/

直接使用pip进行安装:

pip install gpyopt

基于源码的安装:

# git clone https://github.com/SheffieldML/GPyOpt.git
# cd GPyOpt
# git checkout devel
# nosetests GPyOpt/testing

3个主要依赖包的版本要求:

  • GPy (>=1.0.8)
  • numpy (>=1.7)
  • scipy (>=0.16)

2、基于python的使用案例

使用GPyOpt库来解决一个简单的函数优化问题:尝试找到函数f(x)=x2f(x) = -x^2的最大值

import numpy as np  
from gpyopt import Optimizer  
  
# 定义目标函数  
def f(x):  
    return -x**2  
  
# 定义初始点  
x0 = np.array([0.0])  
# 定义优化器  
optimizer = Optimizer(f=f, x0=x0)  
# 设置优化选项  
optimizer.set_verbose(True)  # 设置是否输出优化信息  
optimizer.set_stop_condition(stop='max_iter', value=100)  # 设置最大迭代次数和停止条件  
  
# 运行优化  
optimizer.optimize()  
  
# 输出结果  
print('最优解:', optimizer.x_opt)  
print('最优值:', optimizer.f_opt)

4.10SigOpt库

1、简介

SigOpt超参数优化库是一个用于优化机器学习模型的软件库。SigOpt的优化算法使用贝叶斯优化,这是一种用于寻找全局最优的优化算法,通常用于寻找深度学习模型中的最佳超参数组合。

SigOpt的API使得调整模型超参数变得容易,并且可以与许多不同的机器学习库(包括TensorFlow、PyTorch、Scikit-learn等)集成。SigOpt还提供了一个可视化界面,可以帮助用户监控和调整优化过程。通过使用SigOpt,开发人员可以更快地找到最佳超参数组合,提高模型的性能和准确性。

官方学习地址:docs.sigopt.com/intro/main-…

基于pip的安装:

pip install sigopt  

2、基于python的实战案例

import torch  
import torch.nn as nn  
from torch.utils.data import DataLoader  
from torchvision import datasets, transforms
# 优化相关
import sigopt  
from sigopt.api import create_run  
from sigopt.config import get_version_id  
from sigopt.local import local_experiment  
from sigopt.run import run_fn, get_default_args, get_default_config, get_default_options, get_default_suggestion_callback, run_in_notebook, run_in_script, run_in_jupyter_notebook   # 用于定义运行函数和运行环境  
from sigopt.suggestion import get_suggestion, get_suggestion_from_web  # 用于获取建议的超参数值


# 定义学习率和批量大小
space = {  
  "learning_rate": (1e-5, 1e-2, "log-uniform"),  
  "batch_size": (32, 256, "uniform")  
}

# 定义基于pytorch的深度学习模型
class SimpleModel(nn.Module):  
  def __init__(self):  
    super(SimpleModel, self).__init__()  
    self.fc = nn.Linear(784, 10)  
      
  def forward(self, x):  
    x = x.view(-1, 784)  
    x = self.fc(x)  
    return x

# 加载mnist数据集
transform = transforms.Compose([  
  transforms.ToTensor(),    # 转成张量
  transforms.Normalize((0.1307,), (0.3081,))  # 数据标准化  
])  
train_dataset = datasets.MNIST(root="data", train=True, transform=transform, download=True)  
train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True)

# 优化过程
def objective(config):  # 定义优化目标函数,即模型的准确率  
  model = SimpleModel()  # 创建模型实例  
  optimizer = torch.optim.Adam(model.parameters(), lr=config["learning_rate"])  # 创建优化器并设置学习率  
  criterion = nn.CrossEntropyLoss()  # 创建损失函数  
  train_loss = 0.0  
  correct = 0.0  
  total = 0.0  
  for i, data in enumerate(train_loader, 0):  # 对训练集进行迭代,计算损失和准确率  
    inputs, labels = data  # 获取输入和标签数据  
    optimizer.zero_grad()  # 清零梯度缓存  
    outputs = model(inputs)  # 前向传播,计算输出张量  
    loss = criterion(outputs, labels)  # 计算损失张量  
    loss.backward()  # 反向传播,计算梯度张量并更新权重参数  
    train_loss += loss.item()  # 累加损失值并计算平均损失值和准确率 
    
    _, predicted = torch.max(outputs.data, 1)  # 找到最大概率的标签作为预测结果并计算准确率  
    total += labels.size(0)  # 累加样本数以计算总体准确率  
    correct += predicted.eq(labels.data).cpu().sum()  # 累加正确预测的样本数并计算准确率  
  accuracy = correct / total  # 计算总体准确率并返回给优化器作为目标函数值  
  return accuracy, {"learning_rate": config["learning_rate"], "batch_size": config["batch_size"]}  # 将目标函数值和超参数值返回给优化器

4.11Keras Tuner

KerasTuner是一个易于使用的分布式超参数优化框架,能够解决执行超参数搜索时的一些痛点。它利用高级搜索和优化方法,如HyperBand搜索和贝叶斯优化,来帮助找到最佳的神经网络超参数。

安装命令:

pip install keras-tuner --upgrade

官方学习地址:keras.io/keras_tuner…

2、实战案例

import keras_tuner
from tensorflow import keras

# 定义网络模型
def build_model(hp):
    model = keras.Sequential()
    model.add(keras.layers.Dense(
        hp.Choice("units", [8,16,32]),
        activation="relu"
    ))
    model.add(keras.layers.Dense(1,activation="relu"))
    model.compile(loss="mse")
    return model

tuner = keras_tuner.RandomSearch(
    build_model,
    objective="val_loss",
    max_trials=5
)

tuner.search(x_train, y_train, epochs=5, validation_data=(x_val, y_val))

完整案例:www.analyticsvidhya.com/blog/2021/0…

五、基于AutoML库的超参数调优

5.1什么是AutoML库

自动化机器学习库(AutoML)是一种软件工具或库,旨在自动化机器学习工作流程。这些库使用不同的算法和技术,以实现自动化机器学习任务的过程,包括数据预处理、特征选择、模型选择、参数优化、模型评估等。

AutoML的目的是简化机器学习的过程,使非专业人士也可以应用机器学习,或者帮助专业人士更高效地处理机器学习任务。这些库通常提供易于使用的接口,并且能够处理大规模的数据集。

5.2常见的自动化机器学习库

自动化机器学习库有以下几种:

  • Auto-Sklearn。Auto-Sklearn是基于scikit-learn软件包构建的开源AutoML库。它为给定的数据集找到最佳性能的模型以及最佳的超参数集。它包括一些特征工程技术,例如单点编码,特征归一化,降维等。该库适用于中小型数据集,不适用大型数据集。

  • H2O AutoML。H2O AutoML是一个完整的端到端的机器学习自动化工具,可以处理各种类型的数据集,包括小数据和大数据,标准数据和非标准数据。它实现了整个机器学习流程的自动化,包括数据准备,模型选择,特征选择,模型优化等。

  • Auto-Keras。Auto-Keras是一个基于Keras深度学习框架的自动机器学习库。它旨在为深度学习模型提供高度自动化的设计和训练流程,以解决用户在面对不同任务时可能需要重复编写大量代码的问题。

  • AutoGluon。AutoGluon是一个开源的深度学习自动机器学习库,由AWS团队开发和维护。它旨在帮助开发者自动完成机器学习的所有过程,包括数据预处理、特征工程、模型选择和超参数调整等。AutoGluon使用了一种称为“神经架构搜索”的技术来自动化地选择最佳的模型架构。

  • Pycaret。PyCaret 是一个开源的、低代码的机器学习库,旨在简化机器学习工作流并提高工作效率。它是一个 Python 库,封装了多个流行的机器学习库和框架,如 scikit-learn、XGBoost、LightGBM、CatBoost、spaCy、Optuna、Hyperopt、Ray 等。PyCaret 还提供了一套简单易用的 API,可以帮助你完成各种机器学习任务,包括数据预处理、模型训练、评估和部署等。

  • MLBox。MLBox是一个功能强大的自动化机器学习库,旨在为机器学习工程师和研究者提供一站式的机器学习解决方案。它是由国内的一家公司开发的,封装了多种流行的机器学习算法和框架,如scikit-learn、XGBoost、LightGBM、CatBoost、spaCy、Optuna、Hyperopt、Ray等,并将它们整合到一个统一的框架中,提供了简单易用的API,使得机器学习的流程变得更加高效和便捷。

  • Auto-PyTorch。Auto-PyTorch是一个基于PyTorch的自动机器学习库。它旨在为超参数搜索和模型选择提供自动化的解决方案,以帮助用户在训练深度学习模型时提高效率和准确性。

5.3Auto-Sklearn

1、简介

Auto-Sklearn是一个开源的AutoML库,它利用流行的Scikit-Learn机器学习库进行数据转换和机器学习算法。Auto-Sklearn是由Matthias Feurer等人开发的。在他们的2015年题为“efficient and robust automated machine learning”的论文中进行了描述。

Auto-Sklearn通过元学习(meta-learning)或梯度增强来自动选择最佳的学习算法及其超参数。它还可以自动调整模型的复杂性和集成度,以及执行数据预处理和后处理。

安装命令:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple auto-sklearn

官方学习地址:automl.github.io/auto-sklear…

2、案例学习

import autosklearn.classification  # 基于自动化机器学习库的分类模型
import sklearn.model_selection
import sklearn.datasets
import sklearn.metrics

if __name__ == "__main__":
    X, y = sklearn.datasets.load_digits(return_X_y=True)
    # 数据切分
    X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y, random_state=1)
    # 基于自动化机器学习库的分类模型
    automl = autosklearn.classification.AutoSklearnClassifier()
    # 模型训练和预测
    automl.fit(X_train, y_train)
    y_hat = automl.predict(X_test)
    print("Accuracy score", sklearn.metrics.accuracy_score(y_test, y_hat))

5.4H2O AutoML

1、简介

H2O AutoML是一款由H2O.ai开发的自动化机器学习工具。它通过自动化机器学习领域中的流程和技术,使得数据分析师和科学家们能够更快、更容易地构建高质量的预测模型。

H2O AutoML支持多种算法和模型选择,包括基于树的方法、线性模型和深度学习模型等。该工具还提供了自动特征工程、模型交叉验证和超参数优化等功能,可以帮助用户自动地进行数据清洗、特征工程、模型选择和调优等过程,从而提高模型的准确性和效率。

官网学习地址:docs.h2o.ai/h2o/latest-…

2、使用案例

import h2o
from h2o.automl import H2OAutoML

# 启动H2O
h2o.init()

# 导入一个二分类数据集
train = h2o.import_file("https://s3.amazonaws.com/erin-data/higgs/higgs_train_10k.csv")
test = h2o.import_file("https://s3.amazonaws.com/erin-data/higgs/higgs_test_5k.csv")

x = train.columns
y = "response"
x.remove(y)

# 转成向量
train[y] = train[y].asfactor()
test[y] = test[y].asfactor()

# 训练模型:最多20个基线模型
aml = H2OAutoML(max_models=20, seed=1)
aml.train(x=x, y=y, training_frame=train)

# 查看模型效果 
lb = aml.leaderboard
lb.head(rows=lb.nrows) 

# 预测
preds = aml.predict(test)
# preds = aml.leader.predict(test)

# 模型排行输出
lb = h2o.automl.get_leaderboard(aml, extra_columns = "ALL")

获取单个模型的效果:

m = aml.leader
# 等效
m = aml.get_best_model()

# 使用非默认指标获取最佳模型
m = aml.get_best_model(criterion="logloss")
# 基于默认的排序指标获取XGBoost模型
xgb = aml.get_best_model(algorithm="xgboost")
# 基于logloss指标获取 XGBoost 
xgb = aml.get_best_model(algorithm="xgboost", criterion="logloss")
# 指定获取某个特殊的模型
m = h2o.get_model("StackedEnsemble_BestOfFamily_AutoML_20191213_174603")

# 获取模型的参数信息
xgb.params.keys()
# 特定参数
xgb.params['ntrees']

获取H2O的训练日志及时间信息:

log = aml.event_log  # 日志
info = aml.training_info  # 时间

5.5Auto-Keras

1、简介

Auto-Keras是一种自动机器学习(AutoML)工具,旨在简化深度学习模型的构建和优化。它利用神经架构搜索(NAS)技术自动选择合适的模型结构和超参数,从而大大减少了人工调整的繁琐工作。

Auto-Keras通过智能搜索算法,自动搜索适合数据集的最佳模型结构和超参数,从而提供最佳的模型性能。它提供了简洁易用的接口,使得即使没有深入了解深度学习的用户也能够快速构建强大的深度学习模型。

Auto-Keras支持多种数据类型,包括传统的结构化数据、图像、文本和时间序列等不同类型的数据。它还提供了许多高级功能,如自动化模型选择、简洁的用户界面、支持多种数据类型等,使得即使没有专业知识的用户也能够快速构建强大的机器学习模型

安装Auto-Keras:

pip install autokeras

对应python和TensorFlow的版本要求:Python >= 3.7 and TensorFlow >= 2.8.0.

官方学习地址:autokeras.com/

2、实战案例

import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import mnist

import autokeras as ak

# 导入数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(x_train.shape)  # (60000, 28, 28)
print(y_train.shape)  # (60000,)
print(y_train[:3])  # array([7, 2, 1], dtype=uint8)

# 创建模型并训练
clf = ak.ImageClassifier(overwrite=True, max_trials=1)
clf.fit(x_train, y_train, epochs=10)
# 预测模型
predicted_y = clf.predict(x_test)
# 评估模型
clf.evaluate(x_test, y_test)

使用验证数据集:

clf.fit(
    x_train,
    y_train,
    validation_split=0.15,   # 验证集比例
    epochs=10,
)

# 手动切分验证集
split = 50000
x_val = x_train[split:]
y_val = y_train[split:]
x_train = x_train[:split]
y_train = y_train[:split]
clf.fit(
    x_train,
    y_train,
    validation_data=(x_val, y_val),
    epochs=10,
)

自定义搜索空间:

input_node = ak.ImageInput()
output_node = ak.ImageBlock(
    block_type = "resnet",
    normalize=True,  # 标准化
    augment=False  # 没有数据增强
)(input_node)

output_node = ak.Classification()(output_node)

clf = ak.AutoModel(inputs=input_node, 
                  outputs=output_node,
                  overwrite=True,
                  max_trials=1)

clf.fit(x_train,y_train, epochs=10)

5.6AutoGluon

1、简介

AutoGluon是一个自动化机器学习框架,由AWS团队开发和维护。它可以自动调整超参数并选择最佳的深度学习模型来解决回归和分类问题。AutoGluon提供了一种简单易用的界面来控制自动机器学习流程,并且可以与其他常用的深度学习框架集成。

AutoGluon的原理是基于自动化机器学习的思想,它使用了一系列的算法和技术来实现自动化机器学习的过程。其中,AutoGluon使用了一种称为“神经架构搜索”的技术来自动化地选择最佳的模型架构。此外,AutoGluon还提供了一些实用的功能,例如自动数据增强、自动模型选择、自动调整学习率等。

Windows10系统下的安装:

auto.gluon.ai/stable/inst…

conda create -n myenv python=3.9 -y   # 创建虚拟环境  指定python版本
conda activate myenv  # 进入虚拟环境

pip install -U pip
pip install -U setuptools wheel
# 安装torch相关
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
# 安装
pip install autogluon

官网学习地址:auto.gluon.ai/stable/inde…

AutoGluon requires Python version 3.8, 3.9, or 3.10 and is available on Linux, MacOS, and Windows.

2、实战案例

import pandas as pd
import numpy as np
np.random.seed=42

import warnings
warnings.filterwarnings("ignore")

from autogluon.tabular import TabularDataset, TabularPredictor
# 读取在线数据
data_url = 'https://raw.githubusercontent.com/mli/ag-docs/main/knot_theory/'
train = TabularDataset(f'{data_url}train.csv')
# 数据基本信息
train.shape  # (10000, 19)
train.columns 
# 结果
Index(['Unnamed: 0', 'chern_simons', 'cusp_volume',
       'hyperbolic_adjoint_torsion_degree', 'hyperbolic_torsion_degree',
       'injectivity_radius', 'longitudinal_translation',
       'meridinal_translation_imag', 'meridinal_translation_real',
       'short_geodesic_imag_part', 'short_geodesic_real_part', 'Symmetry_0',
       'Symmetry_D3', 'Symmetry_D4', 'Symmetry_D6', 'Symmetry_D8',
       'Symmetry_Z/2 + Z/2', 'volume', 'signature'],
      dtype='object')

# 目标变量
label  = "signature"
train[label].describe()
# 模型训练
predictor = TabularPredictor(label=label).fit(train)
# 模型预测
test = TabularDataset(f"{data_url}test.csv")
pred = predictor.predict(test.drop(columns=label))

# 模型评估
predictor.evaluate(test, silent=True)
# 结果
{'accuracy': 0.9448,
 'balanced_accuracy': 0.7445352845015228,
 'mcc': 0.9323703476874563}

# 对比不同模型
predictor.leaderboard(test, silent=True)

5.7PyCaret

1、简介

PyCaret 是一个开源的、低代码的机器学习库,旨在简化机器学习工作流并提高工作效率。它是一个 Python 库,封装了多个流行的机器学习库和框架,如 scikit-learn、XGBoost、LightGBM、CatBoost、spaCy、Optuna、Hyperopt、Ray 等。

官方学习地址:pycaret.org/

基于清华源安装pycaret:

pip install pycaret  -i  https://pypi.tuna.tsinghua.edu.cn/simple

# 相关依赖安装
pip install pycaret[analysis]
pip install pycaret[models]
pip install pycaret[tuner]
pip install pycaret[mlops]
pip install pycaret[parallel]
pip install pycaret[test]
pip install pycaret[analysis,models]

版本要求:

  • Python 3.7, 3.8, 3.9, and 3.10
  • Ubuntu 16.04 or later
  • Windows 7 or later

2、实战案例

一个关于二分类问题的实战案例,使用内置的数据集

from pycaret.datasets import get_data
from pycaret.classification import *

data = get_data("diabetes")
# 查看数据基本信息

# 1-函数式API
s = setup(data, target="Class variable",session_id=123)

# 2-OOP API
from pycaret.classification import ClassificationExperiment
s = ClassificationExperiment()
s.setup(data, target="Class variable", session_id=123)

# 比较不同模型

# 函数式API
# best = compare_models()
# OOP-API
best = s.compare_models()

# 模型分析

# 函数式API
# evaluate_model(best)
# OOP-API
s.evaluate_model(best)

# 模型预测

# 函数式API
# predict_model(best)
# OOP-API
s.predict_model(best)

模型的保存和加载使用:

# functional API
# save_model(best, 'my_first_pipeline')
# OOP API
s.save_model(best, 'my_first_pipeline')

# functional API
# loaded_model = load_model('my_first_pipeline')
# OOP API
loaded_model = s.load_model('my_first_pipeline')
print(loaded_model)

5.8MLBox

1、简介

MLBox是一个功能强大的自动化机器学习库,旨在为机器学习工程师和研究者提供一站式的机器学习解决方案。

MLBox提供了多种数据预处理、特征工程、模型选择和超参数优化等功能,可以帮助用户快速构建和评估各种机器学习模型。它还支持多种类型的任务,包括分类、回归、聚类和异常检测等。此外,MLBox还提供了一些额外的功能,如模型解释和模型部署等,可以帮助用户更好地理解和应用机器学习模型。它提供以下功能:

  • 快速进行数据读取和分布式数据预处理/清洗/格式化。
  • 高可靠性的特征选择和信息泄漏检测。
  • 高维空间中精确超参数优化。
  • 用于分类和回归的最先进的预测模型(深度学习,堆叠,LightGBM等)。
  • 具有模型解释的预测。

官网学习地址:mlbox.readthedocs.io/en/latest/

python版本要求:Python versions: 3.5 - 3.7. & 64-bit version only(32位的Windows系统不再支持)。

pip install mlbox

基于源码的安装:

# linux 或者Macos
git clone git://github.com/AxeldeRomblay/mlbox
cd MLBox
python setup.py install

2、实战案例

from mlbox.preprocessing import *
from mlbox.optimisation import *
from mlbox.prediction import *

paths = ["<file_1>.csv", "<file_2>.csv", ..., "<file_n>.csv"] 
target_name = "<my_target>" 

data = Reader(sep=",").train_test_split(paths, target_name)  
data = Drift_thresholder().fit_transform(data)

# 评估模型
Optimiser().evaluate(None, data)

# 自定义搜索参数
space = {
        'ne__numerical_strategy' : {"space" : [0, 'mean']},
        'ce__strategy' : {"space" : ["label_encoding", "random_projection", "entity_embedding"]},
        'fs__strategy' : {"space" : ["variance", "rf_feature_importance"]},
        'fs__threshold': {"search" : "choice", "space" : [0.1, 0.2, 0.3]},
        'est__strategy' : {"space" : ["LightGBM"]},
        'est__max_depth' : {"search" : "choice", "space" : [5,6]},
        'est__subsample' : {"search" : "uniform", "space" : [0.6,0.9]}
        }
best = opt.optimise(space, data, max_evals = 5)

# 预测
Predictor().fit_predict(best, data)

5.9Auto-Pytorch

1、简介

Auto-PyTorch是一个自动机器学习的框架,它通过使用PyTorch实现神经网络体系架构的自动搜索。Auto-PyTorch可以根据数据集的特点自动选择最佳的神经网络架构,从而使得模型的性能达到最优。

Auto-PyTorch的算法会自动搜索神经网络的架构、超参数等,以寻找在特定数据集上表现最佳的模型。这种自动搜索可以通过GPU计算来加速,大大减少了人工调整模型参数和架构的繁琐工作。

要使用Auto-PyTorch,需要先安装PyTorch和Auto-PyTorch库。然后,可以通过编写简单的Python代码来定义训练和测试数据集,并调用Auto-PyTorch的API进行自动模型训练和测试。

GitHub官网地址:github.com/automl/Auto…

安装:

pip install autoPyTorch
# 时序预测相关
pip install autoPyTorch[forecasting]

手动安装:

# 创建虚拟环境
conda create -n auto-pytorch python=3.8
conda activate auto-pytorch
conda install swig
python setup.py install

2、实战案例

from autoPyTorch.api.tabular_classification import TabularClassificationTask

# 导入数据
import sklearn.model_selection
import sklearn.datasets
import sklearn.metrics
X, y = sklearn.datasets.load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y, random_state=1)

# 实例化分类模型
api = TabularClassificationTask()

# 自动化搜索
api.search(
    X_train=X_train,
    y_train=y_train,
    X_test=X_test,
    y_test=y_test,
    optimize_metric='accuracy',
    total_walltime_limit=300,
    func_eval_time_limit_secs=50
)

# 计算准确率
y_pred = api.predict(X_test)
score = api.score(y_pred, y_test)
print("Accuracy score", score)

六、基于算法的超参数调优

6.1基于算法的超参数调优

基于算法的超参数优化是指通过运行不同的算法,例如遗传算法、粒子群优化算法等,来自动调整超参数,以寻找最优的超参数组合。这种方法通过利用算法来搜索超参数空间,以找到最优的超参数组合。

基于算法的超参数优化通常需要设置一些参数,例如种群大小、迭代次数等,这些参数会影响优化的效果。在运行算法时,会根据一定的评估标准来评估不同超参数组合的效果,并逐渐搜索出最优的超参数组合。

6.2常见用于超参数优化的算法

  • Bayesian Optimization and HyperBand:一种超参数优化算法,结合了贝叶斯优化和HyperBand算法。BOHB的目标是在给定的预算内找到最优的超参数组合,使得机器学习模型在特定任务上的性能达到最佳。

  • 遗传优化算法:遗传优化算法是一种通过模拟自然进化过程来搜索最优解的方法。它是一种全局优化方法,可以在一个较大的解空间内搜索最优解。

  • 梯度优化算法:梯度优化算法是一种基于梯度下降的优化算法,用于求解复杂的优化问题。它通过迭代地调整参数,最小化损失函数,从而搜索最优解。在梯度下降算法中,每次迭代时,算法会根据当前梯度方向调整参数,更新参数的值。如动量梯度下降、Adam算法和L-BFGS算法等。

  • 种群优化算法:种群优化算法是一种基于自然界生物进化原理的优化算法,它模拟了生物进化的过程,通过不断地迭代和优胜劣汰的过程,逐步寻找最优解。种群优化算法的核心思想是将待优化问题转化为一个适应度函数,然后通过不断地迭代和优胜劣汰的过程,逐步寻找最优解

6.3Bayesian Optimization and HyperBand(BOHB)

1、简介

Bayesian Optimization and HyperBand混合了Hyperband算法和Bayesian优化。BOHB算法使用贝叶斯优化算法进行采样,并通过对超参数的组合进行评估来寻找最佳的超参数组合。它结合了全局和局部搜索的优势,能够快速找到最优的超参数组合,同时具有健壮性和可扩展性。

BOHB算法适用于深度学习任务,通过选择合适的超参数,可以显著提高模型的性能和准确性。它适用于不同的模型和数据集,可以轻松添加新的超参数和约束条件。

BOHB算法的步骤如下:

  1. 初始化:选择超参数的初始范围和分布,定义评估指标和评估次数。
  2. 运行贝叶斯优化算法:根据初始范围和分布,生成超参数组合,使用贝叶斯优化算法进行评估和选择。
  3. 根据HyperBand算法进行资源分配和模型选择:根据贝叶斯优化算法的评估结果,将模型分为若干等级,并根据等级分配不同的资源。
  4. 重复步骤2和3,直到达到预设的评估次数或预算。
  5. 输出最优的超参数组合:从所有评估结果中选择最优的超参数组合作为最终结果。

参考文献:

www.automl.org/blog_bohb/

neptune.ai/blog/hyperb…

2、python实战案例

import numpy as np  
from keras.models import Sequential  
from keras.layers import Dense  
from keras.optimizers import Adam  
from keras.losses import BinaryCrossentropy  
from keras.metrics import Accuracy  
from keras.utils import to_categorical  
from sklearn.model_selection import train_test_split  
from bandit import Bandit  
  
# 加载数据集  
data = np.loadtxt('data.csv', delimiter=',')   # data数据集最后一个为预测目标变量,前面所有字段为特征变量
X = data[:, :-1]  
y = to_categorical(data[:, -1])  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  
  
# 定义模型  
model = Sequential()  
model.add(Dense(64, activation='relu', input_shape=(X_train.shape[1],)))  
model.add(Dense(64, activation='relu'))  
model.add(Dense(y_train.shape[1], activation='softmax'))  
model.compile(optimizer=Adam(), loss=BinaryCrossentropy(), metrics=[Accuracy()])  
  
# 定义BOHB优化器  
def bohb(x):  
    model.set_weights(x)  
    history = model.fit(X_train, y_train, epochs=10, batch_size=32, validation_split=0.2)  
    loss, accuracy = history.history['val_loss'], history.history['val_accuracy']  
    return loss, accuracy  
  
# 定义Bandit类  
bandit = Bandit(bohb, n_iter=1000, n_restarts=10, noise=0.1)  
  
# 进行优化  
bandit.run()

6.4遗传优化算法(Genetic Algorithm)

1、什么是遗传算法?

遗传优化算法是一种通过模拟自然进化过程来搜索最优解的优化算法。

这种算法主要受到生物进化中自然选择、交叉(遗传信息重组)和突变过程的启发。遗传优化算法通常用于解决一些复杂的优化问题,如函数优化、组合优化、机器学习中的参数优化等。

cloud.tencent.com/developer/a…

2、遗传算法的基本步骤:

  • 初始化:首先,算法会随机生成一个种群,这个种群包含了可能的解决方案。
  • 适应度评估:每个个体(即种群中的每一个解决方案)都有一个与其相对应的适应度值。这个适应度值表示该个体的优良程度,通常是目标函数值的一种度量。
  • 选择:根据适应度值,选择种群中的一部分个体进行繁殖。高适应度的个体有更大的机会被选择。
  • 交叉:被选中的个体通过交叉操作生成新的个体。这个过程模拟了生物进化中的基因重组。
  • 突变:为了保持种群的多样性,会随机对某些个体进行突变操作,模拟了生物进化中的基因突变。
  • 替换:用新生成的一批个体替换原来种群中的一部分个体,形成新的种群。
  • 终止条件:如果满足终止条件(如达到最大迭代次数或最优适应度已经达到一定精度),则停止搜索,否则回到步骤2。

3、遗传算法的python实战

import numpy as np  
  
# 目标函数  
def f(x):  
    return x ** 2  
  
# 遗传算法优化函数  
def genetic_algorithm(n_pop, n_gen, lower_bound, upper_bound):  
    # 初始化种群  
    pop = np.random.uniform(lower_bound, upper_bound, n_pop)  
    # 计算适应度  
    fit = np.array([f(x) for x in pop])  
    # 进行遗传优化  
    for gen in range(n_gen):  
        # 选择  
        idx = np.random.choice(np.arange(n_pop), size=n_pop, replace=True, p=fit/fit.sum())  
        pop = pop[idx]  
        fit = fit[idx]  
        # 交叉  
        for i in range(0, n_pop, 2):  
            if np.random.rand() < 0.5:  
                pop[i], pop[i+1] = pop[i+1], pop[i]  
            pop[i] = (pop[i] + pop[i+1]) / 2.0  
        # 突变  
        for i in range(n_pop):  
            if np.random.rand() < 0.1:  
                pop[i] += np.random.normal(0, 0.5)  
    # 返回最优解  
    return pop[np.argmin(fit)]  
  
# 参数设置  
n_pop = 100  # 种群大小  
n_gen = 100  # 迭代次数  
lower_bound = -10  # 下界  
upper_bound = 10  # 上界  
  
# 进行遗传优化  
best_x = genetic_algorithm(n_pop, n_gen, lower_bound, upper_bound)  
print('最优解:x = %.3f, f(x) = %.3f' % (best_x, f(best_x)))
  • 定义了目标函数f(x) = x**2,然后实现了一个遗传算法优化函数

  • 基于numpy库生成一个均匀分布的随机种群,并计算每个个体的适应度

  • 在迭代过程中,使用轮盘赌选择、算术交叉和随机突变操作来生成新的种群。最后,返回适应度最小的个体,即最优解

6.5基于梯度的优化Gradient Optimization Algorithm

1、什么是梯度优化?

基于梯度的优化是一种利用梯度信息进行优化的方法。其基本原理是利用目标函数的梯度信息来逐步迭代更新参数,以找到目标函数的最小值(或最大值)。

具体来说,梯度优化算法Gradient Optimization Algorithm通过计算目标函数的梯度,即函数在某一点的切线斜率,来决定参数更新的方向和步长。在每一次迭代中,算法根据梯度信息来更新参数,使得目标函数的值朝着梯度的反方向进行更新。通过这样的迭代过程,梯度优化算法可以逐步逼近目标函数的最小值点。

梯度优化算法还经常结合其他的优化技巧,如动量法、学习率退火等。

2、梯度优化算法的python实战

import numpy as np  
  
# 加载数据集  
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])  
y = np.array([0, 1, 1, 0])  
  
# 参数初始化  
theta = np.random.randn(2, 1)  
alpha = 0.1  # 学习率  
iters = 1000  
  
# 梯度下降算法  
for i in range(iters):  
    # 计算预测值和误差  
    y_pred = np.dot(X, theta) >= 0.5  
    error = y - y_pred  
    # 计算梯度  
    gradient = np.dot(X.T, error) / len(X) + alpha * theta  
    # 更新参数  
    theta -= gradient  
  
# 输出结果  
print('最优解:theta =', theta)

6.6 基于种群的优化Population-based Optimization Algorithm

1、种群优化算法的原理

种群优化算法Population-Based Optimization Algorithms(POAs)的原理基于群体智慧和群体进化规则,它通过模拟生物进化过程的算法来求解复杂优化问题。在种群优化算法中,每个个体都代表了一个可能的解,而整个种群则代表了所有可能的解。每个个体都有一个适应度值,表示其在优化问题中的优良程度。

算法的核心思想是将待优化问题转化为一个适应度函数,然后通过不断地迭代和优胜劣汰的过程,逐步寻找最优解。在每一次迭代中,种群中的每个个体都会根据其适应度值进行排序,然后根据一定的概率进行选择、交叉和变异,从而产生新的个体。这个过程会不断地重复,直到找到最优解或达到预设的迭代次数。

种群优化算法具有全局搜索能力强、对问题依赖少、鲁棒性强等优点,适用于解决复杂的非线性优化问题。常见的种群优化算法包括遗传算法、粒子群优化算法、蚁群算法等。

2、种群优化算法的python实战

import numpy as np  
  
# 适应度函数  
def fitness(x):  
    return x ** 2  
  
# 初始化种群  
population_size = 100  
gene_length = 10  
population = np.random.randint(2, size=(population_size, 基因长度))  
  
# 迭代进化  
iters = 100    # 迭代次数
cross_entropy = 0.8   # 交叉概率
mutation_probability = 0.01    # 变异概率
  
for i in range(iters):  
    # 选择  
    selection_probability = fitness(population) / sum(fitness(population))  
    selected = np.random.choice(np.arange(population_size), size=population_size, p=selection_probability)  
    population = population[selected]  
  
    # 交叉  
    for j in range(population_size):  
        if np.random.rand() < cross_entropy:  
            pos = np.random.randint(gene_length)  
            population[j], population[j+1] = np.roll(population[j], pos), np.roll(population[j+1], pos)  
  
    # 变异  
    for j in range(population_size):  
        if np.random.rand() < mutation_probability:  
            pos = np.random.randint(gene_length)  
            population[j][pos] = 1 - population[j][pos]  
  
    # 计算适应度值并排序  
    fitness_value = np.array([fitness(x) for x in population])  
    fitness_value_index = np.argsort(fitness_value)[::-1]  
    population = population[fitness_value_index]  
  
# 输出最优解  
best_solution_index = np.argmax(fitness_value)  
best_solution = population[best_solution_index]  
print('最优解:',best_solution)