**作者:**Tom O'Malley、Haifeng Jin
建立日期 2019/10/24
上次修改時間 2021/06/02
**說明:**使用多個 GPU 和多台機器調整模型的超參數。
**在 Colab 中檢視** •
**GitHub 來源**
!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):
"""Builds a convolutional model."""
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()
# Reshape the images to have the channel dimension.
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")],
)
Trial 2 Complete [00h 00m 18s]
val_accuracy: 0.07000000029802322
Best val_accuracy So Far: 0.07000000029802322
Total elapsed time: 00h 00m 26s