使用Keras Tuner进行自动化超参数调整的实例演示

2022-04-21 704阅读

温馨提示:这篇文章已超过740天没有更新,请注意相关的内容是否还可用!

一、什么是超参数调整

在机器学习工作流程中,您已经根据对数据集的先验分析为模型选择或提取了特征和目标 - 可能使用了PCA等降维技术。

训练机器学习模型时会进行如下迭代:

在训练开始之前,以随机或几乎随机的方式初始化神经网络的权重;

在前向传递中,会将所有样本(通常以小批量)提供给机器学习模型,该模型会生成预测。

使用损失函数,将预测与真实目标进行比较,并出现损失值。

通过反向计算特定神经元在反向传递中的误差贡献,可以清楚每个神经元对误差的贡献有多大。

使用诸如Gradient Descent或Adaptive Optimization之类的优化器,权重会发生微小的变化。

新的迭代开始,我们期望模型表现更好一点。一直迭代持续到模型改进到足以在实践中使用为止。

1、神经网络架构和配置

构建模型通常会依照下面三个步骤:

1、创建模型骨架(在 Keras 中,这通过Sequential API或Functional API发生)。

2、实例化模型:使用骨架和配置选项创建可训练模型。

3、将数据拟合到模型:开始训练过程。

(1)调整神经网络中的参数

在步骤 (1) 中,您将神经网络的各个层添加到骨架中,例如此处使用 Keras 创建的卷积神经网络:

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(no_classes, activation='softmax'))

在这里,您所做的架构选择,例如Conv2D层的过滤器数量、内核大小或层的输出节点数量Dense)决定了所谓的神经网络参数 - 权重(以及由此产生的偏差)。

神经网络的参数通常是连接的权重。在这种情况下,这些参数是在训练阶段学习的。因此,算法本身(和输入数据)会调整这些参数。

(2)调整神经网络中的超参数

在步骤 (2) 中,将在实例化期间通过设置各种配置选项来配置模型。

这些选项包括但不限于:

训练期间使用的优化器:例如,无论您是使用梯度下降还是像Adam这样的自适应优化器。

优化期间使用的学习率:即发现的误差贡献的哪一部分将用于优化特定神经元。

batchsize:在前向传递期间将使用的批量大小。

epochs:将用于训练神经网络的迭代次数。

这就是它们被称为 hyper_parameters 的原因:

超参数通常是学习率、批量大小或时期数。之所以称为“超参”,是因为它们会影响您的参数的学习方式。您可以根据需要优化这些超参数:网格搜索、随机搜索、手动搜索、使用可视化...

可以通过多种方式选择(和优化)超参数。最简单的方法是手动:选择一组超参数,随后测试,然后再调整超参......不断迭代这个过程。

二、了解Keras Tuner

Keras Tuner可用于自动调整 Keras 模型的参数和超参数。通过搜索空间自动调整Keras模型的超参数。

实际上,在2D空间的情况下 - 其中轴表示例如超参数学习率和参数(或更严格地说,是参数数量的影响因素)层数,您可以将空间可视化如下:

在这里,两个轴(维度)之间的所有交点都是可以为模型选择的超参数的可能组合。依此类推。在这里,我们有两个维度(这有利于可视化),但是您添加到模型中的可调选项越多,添加到搜索空间的维度就越多。

搜索超参数空间不能无限期地进行。Keras Tuner允许您限制搜索:通过设置最大试验次数,可以在一段时间后停止搜索。

以下是 Keras Tuner 支持的搜索策略的简要概述:

随机搜索:对于搜索空间中的每个维度,该算法将选择一个随机值,训练模型并报告结果。

贝叶斯优化:将超参数调整视为黑盒函数的优化,并使用贝叶斯规则进行优化。

Hyperband:这个尝试通过非常短的时间运行实验来减少总调整时间,然后以竞赛式的方式只将最好的实验用于更长时间的训练。

Sklearn:允许您使用交叉验证的超参数搜索来调整 Scikit-learn 模型的超参数。

三、使用Keras Tuner的基本示例

我们构建一个简单的 ConvNet 。然后使用 Keras Tuner 在有限数量的 epoch 中调整其超参数,并最终完全训练出最佳模型。

为了简单起见,只根据Adam优化器的学习率构建一维搜索空间。

首先在您的机器学习环境中执行来安装Keras Tuner。

pip install -U keras-tuner

1、导入、模型配置和加载数据

创建tuning.py,导入如下的包,并使用MINST数据集,并将其重塑为与 Conv2D 兼容的格式。。

from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Conv2D
from tensorflow.keras.losses import sparse_categorical_crossentropy
from tensorflow.keras.optimizers import Adam
from kerastuner.tuners import RandomSearch

# Model configuration
batch_size = 50
img_width, img_height, img_num_channels = 28, 28, 1
loss_function = sparse_categorical_crossentropy
no_classes = 10
no_epochs = 25
validation_split = 0.2
verbosity = 1

# Load MNIST data
(input_train, target_train), (input_test, target_test) = mnist.load_data()

# Reshape data
input_train = input_train.reshape(input_train.shape[0], img_width, img_height, 1)
input_test = input_test.reshape(input_test.shape[0], img_width, img_height, 1)

# Determine shape of the data
input_shape = (img_width, img_height, img_num_channels)

# 将数据转换为float32使得GPU更快地训练。
input_train = input_train.astype('float32')
input_test = input_test.astype('float32')

# 数据缩放
input_train = input_train / 255
input_test = input_test / 255

2、定义模型构建函数

Keras Tuner允许您以两种方式执行实验。第一种,更具可扩展性的方法是一个HyperModel类;另外是Keras Tuner可以通过模型构建功能自动超参数调整。

如下这是模型构建功能的代码。通过如下指定学习率超参数来调整它hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])。

def build_model(hp):
# Create the model
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(no_classes, activation='softmax'))

# Display a model summary
model.summary()

# Compile the model
model.compile(loss=loss_function,
optimizer=Adam(
hp.Choice('learning_rate',
values=[1e-2, 1e-3, 1e-4])),
metrics=['accuracy'])

# Return the model
return model

3、执行调优

首先定义我们的搜索策略——RandomSearch。

tuner = RandomSearch(
build_model,
objective='val_accuracy',
max_trials=5,
executions_per_trial=3,
directory='tuning_dir',
project_name='machinecurve_example')

上面代码的含义是,我们最终目标是最小化验证准确度(Keras Tuner 会根据目标自动推断应该最大化还是最小化),告诉它应该执行 5 次试验,并且每次试验应该执行 3 次。后者确保导致超参数“最佳”的不仅仅是方差,因为更多性能更好的实例往往表明性能实际上更好。directory设置和project_name属性以便保存调整操作的检查点。

# Display search space summary
tuner.search_space_summary()

# Perform random search
tuner.search(input_train, target_train,
 epochs=5,
 validation_split=validation_split)

指示Keras Tuner使用我们的训练集执行超参数调整,每次试验5个epoch,并确保进行验证拆分(在我们的例子中,根据我们的模型配置方式,为 20%)。

4、充分训练最佳模型

搜索完成后,您可以获得最佳模型,并根据您的配置对其进行全面训练。

# Get best model
models = tuner.get_best_models(num_models=1)
best_model = models[0]

# Fit data to model
history = best_model.fit(input_train, target_train,
batch_size=batch_size,
epochs=no_epochs,
verbose=verbosity,
validation_split=validation_split)

# Generate generalization metrics
score = model.evaluate(input_test, target_test, verbose=0)
print(f'Test loss: {score[0]} / Test accuracy: {score[1]}')

四、总结 

通过上面了解了神经网络参数和超参数的自动调优,然后我们完整的使用了一个基于 Keras Tuner 的超参数搜索器。