多个参数变更update_使用Keras Tuner进行超参数自动调优

多个参数变更update_使用Keras Tuner进行超参数自动调优_第1张图片

前言

本文主要介绍了使用Keras Tuner进行超参数自动调优的示例,还介绍了一些高级用法,包括分布式调优,自定义调优模型等等。如果想了解Keras Tuner的安装和基本用法请参考第一篇博客。

周大侠:Keras-Tuner:适用于TensorFlow 2.0和keras的超参数调优器​zhuanlan.zhihu.com
多个参数变更update_使用Keras Tuner进行超参数自动调优_第2张图片

此文主要翻译于TensorFlow的官方Blog,同时也补充了些个人注释。

Hyperparameter tuning with Keras Tuner​blog.tensorflow.org

真正的前言

一个机器学习项目的成功通常都严重依赖于好的超参数的选择。随着机器学习已经发展成一个领域的不断成熟,仅仅依靠反复尝试和试错(trial and error)来为这些超参数找到较优的值是不合适的。事实上,如今许多效果最好的算法如EfficientNet,是通过复杂的超参数优化算法发现的。

Keras Tuner 是一个易于使用、可分布式的超参数优化框架,用于解决执行超参数搜索的痛点。Keras Tuner可以很容易地定义搜索空间,并利用所包含的算法来查找最佳超参数值。 Keras Tuner内置了贝叶斯优化(Bayesian Optimization)、Hyperband和随机搜索(Random Search)算法,同时也便于研究人员扩展,进行新搜索算法的试验。

超参数自动调优实例

下面将介绍一个简单的端到端的示例。首先,定义一个model-building函数,通过该函数中的参数hp进行超参数的定义,例如:

 hp.Int('units', min_value=32, max_value=512, step=32)  #该句定义了一个范围内的整数

请注意查看如何在model-building函数中定义超参数,下面的示例将创建一个简单的可调(tunable)模型,其训练使用的数据是CIFAR-10 :

 import tensorflow as tf
 ​
 def build_model(hp):
   inputs = tf.keras.Input(shape=(32, 32, 3)) #模型输入 RGB图片
   x = inputs
     
   for i in range(hp.Int('conv_blocks', 3, 5, default=3)): # 调优卷积层数
     filters = hp.Int('filters_' + str(i), 32, 256, step=32) # 调优filters数量
     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': #调优pooling函数
       x = tf.keras.layers.MaxPool2D()(x)
     else:
       x = tf.keras.layers.AvgPool2D()(x)
   x = tf.keras.layers.GlobalAvgPool2D()(x)
   x = tf.keras.layers.Dense(
       hp.Int('hidden_size', 30, 100, step=10, default=50), 
       activation='relu')(x)    #调优隐含层大小
   x = tf.keras.layers.Dropout(
       hp.Float('dropout', 0, 0.5, step=0.1, default=0.5))(x)  #调优dropout大小
   outputs = tf.keras.layers.Dense(10, activation='softmax')(x)
 ​
   model = tf.keras.Model(inputs, outputs)
   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  
#返回一个构建好的模型(compiled model,指整体模型结构已经搭好,包括损失函数的定义等等,但模型还未经过训练)

下一步,实例化(instantiate)一个tuner。首先应该指定model-building函数需要要优化的目标的名称(其中优化目标是最小化还是最大化是根据内置metrics自动推断出来的,或者可以通过kerastuner.Objective class 使用自定义的metric )。在本示例中,Keras tuner使用Hyperband算法用于超参搜索:

 import kerastuner as kt
 ​
 tuner = kt.Hyperband(
     build_model,
     objective='val_accuracy',
     max_epochs=30,
     hyperband_iterations=2)

接下来通过TensorFlow Datasets 下载CIFAR-10数据集,然后调用search方法进行超参搜索。search方法与keras.model.fit具有相同的参数(signature):

 import tensorflow_datasets as tfds
 ​
 data = tfds.load('cifar10')
 train_ds, test_ds = data['train'], data['test']
 ​
 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个epochs,以及Hyperband会迭代2次(在你的算力允许下,越多越好)。随后通过使用get_best_models 函数得到搜索期间的最佳模型:

 best_model = tuner.get_best_models(1)[0]

还可以查看通过搜索找到的最佳超参数值:

 best_hyperparameters = tuner.get_best_hyperparameters(1)[0]

至此就是执行复杂的超参数搜索所需的全部代码! 完整代码在此

内置的可调模型

除了上述允许定义自己的可调模型之外,Keras Tuner 提供2个内置的可调模型:HyperResnet 和 HyperXception。这两个模型分别会搜索HyperResnet 和 HyperXception的各种参数组合,通过配合Tuner一起使用:

 tuner = kt.tuners.BayesianOptimization(
   kt.applications.HyperResNet(input_shape=(256, 256, 3), classes=10),
   objective='val_accuracy',
   max_trials=50)

分布式优化

当使用Keras Tuner,可以同时进行数据并行试验并行的分布式(both data-parallel and trial-parallel distribution)。即可以使用tf.distribute.Strategy在多个GPUs上运行模型;还可以在不同的worker上并行地搜索多个不同的超参数组合。

执行并行试验不需要修改原来的搜索代码,仅仅需要设置the 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

所有的tuner通过一个中央Oracle 服务器来协调它们的参数搜索,该服务器分发每个tuner接下来尝试哪个超参数值。更多的细节请参考 Distributed Tuning guide

自定义训练循环

你可以自定义 kerastuner.Tuner 类的子类(subclass)来支持更高级的用法:

  • 自定义训练循环(例如GAN,强化学习等等)
  • 在model-building函数外增加超参数(例如数据预处理,数据增强,测试时增强test time augmentation等等)

下面是一个简单的例子,更多细节请参考Tuner Subclassing guide.

 class MyTuner(kt.Tuner):
 ​
     def run_trial(self, trial, ...):
         model = self.hypermodel.build(trial.hyperparameters)
         score = …  # Run the training loop and return the result.
         self.oracle.update_trial(trial.trial_id, {
      'score': score})
         self.oracle.save_model(trial.trial_id, model)

调优 Scikit-learn 模型

尽管其名字叫Keras Tuner,但它可以用来调优各种机器学习模型。除了内置用于Keras模型的tuner外,Keras Tuner还提供了一个能用于Scikit-learn模型的内置Tuner。下面是如何使用的一个简单示例:

 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
 ​
 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)

所以只要你封装得好,Keras Tuner还能调优Pytorch(手动滑稽)!具体可以参考官方如何实现对Scikit-learn模型调优的源码。

最后,又发现了一个TensorFlow最新发布的Keras Tuner Tutorial,包含了另一个简单却完整的示例,链接如下:

Keras Tuner简介 | TensorFlow Core​tensorflow.google.cn
多个参数变更update_使用Keras Tuner进行超参数自动调优_第3张图片

你可能感兴趣的:(多个参数变更update)