keras利用sklearn进行超参数自动搜索

2023-07-12 20:07:39 浏览数 (4)

深度学习模型通常具有许多可以调整的超参数,例如学习率、批次大小、隐藏层数、神经元数量及优化器等。为了在给定的任务和数据集上获得模型的最佳性能,我们需要找到在模型中使用的最佳超参数值。搜索最佳超参数组合的过程称为超参数优化。

在本文中,我们将介绍如何使用 Python 库 scikit-learn 和 TensorFlow- Keras 框架执行深度学习模型的超参数优化。

1. 核心步骤

利用sklearn中的RandomizedSearchCV:

  1. 转化为sklearn的model(其中,把tf的model转换成sklearn的model需要调用的api在tf.keras.wrappers下面)
  2. 定义参数集合
  3. 搜索参数

2. 转换为sklearn的model

虽然 Keras 是用于构建和训练深度学习模型的受欢迎框架,但它并没有内置的工具来执行超参数搜索。相反,scikit-learn 库提供了强大的工具,可用于执行高效的超参数搜索。为了在 Keras 模型中使用 scikit-learn 工具,我们需要将 Keras 模型包装成 scikit-learn 所支持的形式。

在这个步骤中,我们将使用 Keras 的 tensorflow.keras.wrappers.scikit_learn 模块将 Keras 模型转换为 scikit-learn 模型。该模块提供了一个名为 KerasRegressor 的类,它为回归问题提供了一个 scikit-learn 回归器接口。我们需要定义一个构建函数 build_model,该函数将接受模型的超参数作为输入并返回编译好的 Keras 模型,然后将这个函数作为输入传递给 KerasRegressor。接着用KerasRegressor的fit方法,训练模型,并传入callbacks参数。(到此只是完成了tf_keras到sklearn模型的转换)

代码语言:python代码运行次数:0复制
# RandomizedSearchCV
# 1. 转化为sklearn的model
# 2. 定义参数集合
# 3. 搜索参数



def build_model(hidden_layers = 1,
                layer_size = 30,
                learning_rate = 3e-3):
    model = keras.models.Sequential()
    model.add(keras.layers.Dense(layer_size, activation='relu',
                                 input_shape=x_train.shape[1:]))
    for _ in range(hidden_layers - 1):
        model.add(keras.layers.Dense(layer_size,
                                     activation = 'relu'))
    model.add(keras.layers.Dense(1))
    optimizer = keras.optimizers.SGD(learning_rate)
    model.compile(loss = 'mse', optimizer = optimizer)
    return model



sklearn_model = KerasRegressor(
    build_fn = build_model)
callbacks = [keras.callbacks.EarlyStopping(patience=5, min_delta=1e-2)]
history = sklearn_model.fit(x_train_scaled, y_train,
                            epochs = 10,
                            validation_data = (x_valid_scaled, y_valid),
                            callbacks = callbacks)

3.定义参数集合

现在我们已经有了可以用于超参数搜索的 scikit-learn 模型,下一步是定义我们要搜索的超参数及其值范围。在此示例中,我们将尝试对学习率、隐藏层数和每层神经元的数量进行优化。

将为学习率定义一个连续分布,而隐藏层和神经元数量将选择离散值范围。

代码语言:python代码运行次数:0复制
from scipy.stats import reciprocal
# f(x) = 1/(x*log(b/a)) a <= x <= b


param_distribution = {
    "hidden_layers":[1, 2, 3, 4],
    "layer_size": np.arange(1, 100),
    "learning_rate": reciprocal(1e-4, 1e-2),
}

参数定义在param_distribution这么一个dict里面,需要注意的是,learning_rate取的是连续值,所以需要给一个分布,这里调用的是scipy的reciprocal分布,最小值和最大值是1e-4和1e-2。

4.搜索参数

在本例中,我们将使用 RandomizedSearchCV进行超参数搜索需要传入sklearn的模型,以及参数的dict,n_iter是采样数,cv是交叉验证参数,n_jobs是并行数。与 GridSearchCV不同RandomizedSearchCV 不会尝试所有可能的参数组合,而是从参数分布中随机抽样。这通常会产生更快的结果,并在许多情况下(尤其是在参数空间非常大时)能够获得合适的参数组合。定义完之后,使用fit开始训练。训练的过程中它会自己交叉验证,并用全量数据做训练。

代码语言:python代码运行次数:0复制
from sklearn.model_selection import RandomizedSearchCV



random_search_cv = RandomizedSearchCV(sklearn_model,
                                      param_distribution,
                                      n_iter = 10,
                                      cv = 3,
                                      n_jobs = 1)
random_search_cv.fit(x_train_scaled, y_train, epochs = 100,
                     validation_data = (x_valid_scaled, y_valid),
                     callbacks = callbacks)


# cross_validation: 训练集分成n份,n-1训练,最后一份验证.    

执行此代码后,将获得一个最佳超参数组合的输出。进一步,可以将搜索到的最佳超参数值用于训练 Keras 模型。可以使用random_search_cv.best_estimator_获取最佳模型。

代码语言:javascript复制
print(random_search_cv.best_params_)
print(random_search_cv.best_score_)
print(random_search_cv.best_estimator_)
代码语言:javascript复制
{'hidden_layers': 3, 'layer_size': 94, 'learning_rate': 0.009963250731270197}
-0.3331597646077474
<tensorflow.python.keras.wrappers.scikit_learn.KerasRegressor object at 0x7fc0c0212310>
In [13]:
model **=** random_search_cv.best_estimator_.model
model.evaluate(x_test_scaled, y_test)
162/162 [==============================] - 0s 807us/step - loss: 0.3224
Out[13]:
0.32240527868270874

本文介绍了使用 scikit-learn 和 Keras 进行深度学习超参数优化的方法。我们学会了如何将 Keras 模型转换为 scikit-learn 模型,定义超参数分布和范围,以及利用RandomizedSearchCV执行参数搜索。这使得在Keras 模型中优化超参数更加简便和高效。最后,对于具体任务和数据,通过实验证据和调整搜索方法和参数来找到最佳超参数组合。

1 人点赞