作者: Tom O'Malley, Haifeng Jin
创建日期: 2019/10/24
最后修改: 2021/06/02
描述: 使用多个GPU和多个机器调优模型的超参数。
!pip install keras-tuner -q
KerasTuner使得执行分布式超参数搜索变得简单。无需对您的代码进行任何更改,即可从本地单线程运行扩展到在数十或数百个工作程序上并行运行。分布式KerasTuner使用首席-工作者模型。首席运行一个服务,工作者将结果报告给该服务并查询下一个要尝试的超参数。首席应该在单线程的CPU实例上运行(或者在一个工作者上作为一个单独的进程运行)。
配置KerasTuner的分布式模式只需要设置三个环境变量:
KERASTUNER_TUNER_ID: 对于首席进程,应设置为"chief"。其他工作者应传递一个唯一的ID(按照约定,"tuner0"、"tuner1"等)。
KERASTUNER_ORACLE_IP: 首席服务应运行的IP地址或主机名。所有工作者都应该能够解析和访问此地址。
KERASTUNER_ORACLE_PORT: 首席服务应运行的端口。可以自由选择,但必须是其他工作者可以访问的端口。实例通过gRPC协议进行通信。
所有工作者可以运行相同的代码。分布式模式的其他考虑因素包括:
Tuner.__init__
中应保持overwrite
为False
(False
是默认值)。首席服务的示例bash脚本(页面底部的run_tuning.py
示例代码):
export KERASTUNER_TUNER_ID="chief"
export KERASTUNER_ORACLE_IP="127.0.0.1"
export KERASTUNER_ORACLE_PORT="8000"
python run_tuning.py
工作者的示例bash脚本:
export KERASTUNER_TUNER_ID="tuner0"
export KERASTUNER_ORACLE_IP="127.0.0.1"
export KERASTUNER_ORACLE_PORT="8000"
python run_tuning.py
tf.distribute
的数据并行性KerasTuner还支持通过tf.distribute进行数据并行性。数据并行性和分布式调优可以结合使用。例如,如果您有10个工作者,每个工作者有4个GPU,您可以通过使用tf.distribute.MirroredStrategy运行10个并行试验,每个试验在4个GPU上训练。您还可以通过tf.distribute.TPUStrategy在TPU上运行每个试验。目前tf.distribute.MultiWorkerMirroredStrategy不支持,但该功能在开发计划中。
当上述环境变量设置后,下面的示例将运行分布式调优,并在每个试验中通过tf.distribute
使用数据并行性。该示例从tensorflow_datasets
加载MNIST,并使用Hyperband进行超参数搜索。
import keras
import keras_tuner
import tensorflow as tf
import numpy as np
def build_model(hp):
"""构建卷积模型。"""
inputs = keras.Input(shape=(28, 28, 1))
x = inputs
for i in range(hp.Int("conv_layers", 1, 3, default=3)):
x = keras.layers.Conv2D(
filters=hp.Int("filters_" + str(i), 4, 32, step=4, default=8),
kernel_size=hp.Int("kernel_size_" + str(i), 3, 5),
activation="relu",
padding="same",
)(x)
if hp.Choice("pooling" + str(i), ["max", "avg"]) == "max":
x = keras.layers.MaxPooling2D()(x)
else:
x = keras.layers.AveragePooling2D()(x)
x = keras.layers.BatchNormalization()(x)
x = keras.layers.ReLU()(x)
if hp.Choice("global_pooling", ["max", "avg"]) == "max":
x = keras.layers.GlobalMaxPooling2D()(x)
else:
x = keras.layers.GlobalAveragePooling2D()(x)
outputs = keras.layers.Dense(10, activation="softmax")(x)
model = keras.Model(inputs, outputs)
optimizer = hp.Choice("optimizer", ["adam", "sgd"])
model.compile(
optimizer, loss="sparse_categorical_crossentropy", metrics=["accuracy"]
)
return model
tuner = keras_tuner.Hyperband(
hypermodel=build_model,
objective="val_accuracy",
max_epochs=2,
factor=3,
hyperband_iterations=1,
distribution_strategy=tf.distribute.MirroredStrategy(),
directory="results_dir",
project_name="mnist",
overwrite=True,
)
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# 重塑图像以具有通道维度。
x_train = (x_train.reshape(x_train.shape + (1,)) / 255.0)[:1000]
y_train = y_train.astype(np.int64)[:1000]
x_test = (x_test.reshape(x_test.shape + (1,)) / 255.0)[:100]
y_test = y_test.astype(np.int64)[:100]
tuner.search(
x_train,
y_train,
steps_per_epoch=600,
validation_data=(x_test, y_test),
validation_steps=100,
callbacks=[keras.callbacks.EarlyStopping("val_accuracy")],
)
实验 2 完成 [00小时 00分钟 18秒]
val_accuracy: 0.07000000029802322
目前最佳 val_accuracy: 0.07000000029802322
总耗时: 00小时 00分钟 26秒