使用 Keras Tuner 进行超参数调优
摘要:KerasTuner是一款专为深度学习设计的超参数优化工具,支持贝叶斯优化、Hyperband和随机搜索算法。开发者可轻松定义搜索空间,在模型构建代码中直接嵌入超参数采样逻辑。框架提供端到端解决方案,从模型定义(如卷积层数、滤波器数量、学习率等)到分布式训练,并支持自定义训练循环和Scikit-learn模型调优。通过内置算法自动寻找最优参数组合,显著提升模型性能,同时保持代码简洁性。其分布式架构支持多节点并行搜索,大幅提高调优效率。
目录
使用 Keras Tuner 进行超参数调优
Keras Tuner 是一款易用、支持分布式部署的超参数优化框架,能够解决超参数搜索过程中的各类痛点问题。借助它,开发者可以轻松定义超参数搜索空间,并利用框架内置的算法找到最优的超参数取值。Keras Tuner 内置了贝叶斯优化、超波段算法(Hyperband)和随机搜索三种核心算法,同时其架构设计也为研究人员提供了便捷的扩展能力,方便他们尝试研发新的搜索算法。
Keras Tuner 实战演示
下方为你提供完整的代码示例。这里展示一个简单的端到端实战案例,首先我们需要定义一个模型构建函数,该函数接收一个hp参数,通过这个参数可以对超参数进行采样,例如hp.Int('units', min_value=32, max_value=512, step=32)(用于从指定范围内选取整数超参数)。可以看到,超参数能够直接内嵌在模型构建代码中定义。以下示例将构建一个简单的可调优模型,并在 CIFAR-10 数据集上完成训练:
import tensorflow as tf
def build_model(hp):
inputs = tf.keras.Input(shape=(32, 32, 3))
x = inputs
# 定义卷积块数量的超参数,取值3-5,默认值3
for i in range(hp.Int('conv_blocks', 3, 5, default=3)):
# 为每个卷积块定义滤波器数量超参数,取值32-256,步长32
filters = hp.Int('filters_' + str(i), 32, 256, step=32)
for _ in range(2):
x = tf.keras.layers.Convolution2D(
filters, kernel_size=(3, 3), padding='same')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU()(x)
# 选择池化方式,可选平均池化或最大池化
if hp.Choice('pooling_' + str(i), ['avg', 'max']) == 'max':
x = tf.keras.layers.MaxPool2D()(x)
else:
x = tf.keras.layers.AvgPool2D()(x)
x = tf.keras.layers.GlobalAvgPool2D()(x)
# 定义全连接层神经元数量超参数,取值30-100,步长10,默认值50
x = tf.keras.layers.Dense(
hp.Int('hidden_size', 30, 100, step=10, default=50),
activation='relu')(x)
# 定义dropout概率超参数,取值0-0.5,步长0.1,默认值0.5
x = tf.keras.layers.Dropout(
hp.Float('dropout', 0, 0.5, step=0.1, default=0.5))(x)
# 输出层,适配CIFAR-10的10分类任务
outputs = tf.keras.layers.Dense(10, activation='softmax')(x)
model = tf.keras.Model(inputs, outputs)
# 编译模型,优化器学习率为超参数,对数采样1e-4至1e-2
model.compile(
optimizer=tf.keras.optimizers.Adam(
hp.Float('learning_rate', 1e-4, 1e-2, sampling='log')),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
接下来,实例化一个调优器。需要指定模型构建函数,以及待优化的目标指标名称(对于框架内置的指标,会自动推断是求最大值还是最小值;自定义指标则可通过kerastuner.Objective类手动指定)。本示例中,我们将使用超波段算法(Hyperband)进行超参数搜索:
import kerastuner as kt
tuner = kt.Hyperband(
build_model,
objective='val_accuracy', # 优化目标:验证集准确率
max_epochs=30, # 单模型最大训练轮数
hyperband_iterations=2) # 超波段算法迭代次数
然后,我们通过 TensorFlow Datasets 下载 CIFAR-10 数据集,随后启动超参数搜索。调用search方法即可开始搜索,该方法的参数签名与keras.Model.fit完全一致:
import tensorflow_datasets as tfds
# 加载CIFAR-10数据集
data = tfds.load('cifar10')
train_ds, test_ds = data['train'], data['test']
# 数据标准化处理:将像素值缩放到0-1区间
def standardize_record(record):
return tf.cast(record['image'], tf.float32) / 255., record['label']
# 数据集预处理:标准化、缓存、批处理、打乱
train_ds = train_ds.map(standardize_record).cache().batch(64).shuffle(10000)
test_ds = test_ds.map(standardize_record).cache().batch(64)
# 启动超参数搜索,加入早停策略防止过拟合
tuner.search(train_ds,
validation_data=test_ds,
epochs=30,
callbacks=[tf.keras.callbacks.EarlyStopping(patience=1)])
每个模型最多训练 30 轮,同时超波段算法会运行 2 次迭代。搜索完成后,可通过get_best_models函数获取搜索过程中得到的最优模型:
best_model = tuner.get_best_models(1)[0] # 获取排名第一的最优模型
也可以查看搜索得到的最优超参数取值:
best_hyperparameters = tuner.get_best_hyperparameters(1)[0] # 获取最优超参数配置
以上就是实现一次专业的超参数搜索所需的全部代码!你可以在 [此链接] 获取上述示例的完整代码。
内置可调优模型
除了支持自定义可调优模型外,Keras Tuner 还提供了两个内置的可调优模型:HyperResnet 和 HyperXception。这两个模型会分别在 ResNet 和 Xception 网络架构的各类变体中进行搜索。可通过以下方式将其与调优器配合使用:
tuner = kt.tuners.BayesianOptimization(
# 实例化HyperResnet,输入尺寸256×256×3,10分类任务
kt.applications.HyperResNet(input_shape=(256, 256, 3), classes=10),
objective='val_accuracy', # 优化目标:验证集准确率
max_trials=50) # 最大搜索试验次数
分布式调优
Keras Tuner 同时支持数据并行和试验并行两种分布式调优方式。也就是说,既可以通过tf.distribute.Strategy在多块 GPU 上运行单个模型,也可以在不同的工作节点上并行搜索不同的超参数组合。
实现试验并行搜索无需修改任何代码,只需设置三个环境变量:KERASTUNER_TUNER_ID、KERASTUNER_ORACLE_IP和KERASTUNER_ORACLE_PORT,示例如下(bash 脚本):
export KERASTUNER_TUNER_ID="chief"
export KERASTUNER_ORACLE_IP="127.0.0.1"
export KERASTUNER_ORACLE_PORT="8000"
python run_my_search.py
所有调优器会通过一个中央的 “预言机”(Oracle)服务协同完成搜索,该服务会为每个调优器分配下一个待尝试的超参数取值。更多相关信息可查阅官方文档。
自定义训练循环
通过继承kerastuner.Tuner基类,可实现各类高级用法,例如:
- 自定义训练循环(生成对抗网络 GAN、强化学习等场景)
- 在模型构建函数外添加超参数(数据预处理、数据增强、测试时增强等环节)
以下是一个简单的示例:
class MyTuner(kt.Tuner):
def run_trial(self, trial, ...):
# 根据超参数配置构建模型
model = self.hypermodel.build(trial.hyperparameters)
score = … # 运行自定义训练循环并返回评估分数
# 更新试验结果
self.oracle.update_trial(trial.trial_id, {'score': score})
# 保存当前模型
self.oracle.save_model(trial.trial_id, model)
调优 Scikit-learn 模型
尽管命名中带有 “Keras”,但 Keras Tuner 可用于调优各类机器学习模型。除了为 Keras 模型设计的内置调优器外,它还提供了适配 Scikit-learn 模型的专属调优器,使用示例如下:
from sklearn import ensemble
from sklearn import linear_model
def build_model(hp):
# 选择模型类型:随机森林或岭回归分类器
model_type = hp.Choice('model_type', ['random_forest', 'ridge'])
if model_type == 'random_forest':
# 随机森林专属超参数作用域
with hp.conditional_scope('model_type', 'random_forest'):
model = ensemble.RandomForestClassifier(
n_estimators=hp.Int('n_estimators', 10, 50, step=10),
max_depth=hp.Int('max_depth', 3, 10))
elif model_type == 'ridge':
# 岭回归专属超参数作用域
with hp.conditional_scope('model_type', 'ridge'):
model = linear_model.RidgeClassifier(
alpha=hp.Float('alpha', 1e-3, 1, sampling='log'))
else:
raise ValueError('Unrecognized model_type')
return model
# 实例化Scikit-learn调优器,使用贝叶斯优化算法
tuner = kt.tuners.Sklearn(
oracle=kt.oracles.BayesianOptimization(
objective=kt.Objective('score', 'max'), # 优化目标:最大化评估分数
max_trials=10), # 最大试验次数
hypermodel=build_model,
directory=tmp_dir) # 模型保存目录
X, y = ... # 加载特征数据和标签数据
tuner.search(X, y) # 启动超参数搜索
更多推荐


所有评论(0)