hyperparameter_tuning_with_hparams.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. __author__ = "Christian Heider Nielsen"
  4. __doc__ = r"""
  5. Created on 31-10-2020
  6. """
  7. # To add a new cell, type '# %%'
  8. # To add a new markdown cell, type '# %% [markdown]'
  9. # %%
  10. from IPython import get_ipython
  11. # %% [markdown]
  12. # ##### Copyright 2019 The TensorFlow Authors.
  13. # %%
  14. # @title Licensed under the Apache License, Version 2.0 (the "License");
  15. # you may not use this file except in compliance with the License.
  16. # You may obtain a copy of the License at
  17. #
  18. # https://www.apache.org/licenses/LICENSE-2.0
  19. #
  20. # Unless required by applicable law or agreed to in writing, software
  21. # distributed under the License is distributed on an "AS IS" BASIS,
  22. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. # See the License for the specific language governing permissions and
  24. # limitations under the License.
  25. # %% [markdown]
  26. # # Hyperparameter Tuning with the HParams Dashboard
  27. #
  28. # <table class="tfo-notebook-buttons" align="left">
  29. # <td>
  30. # <a target="_blank" href="https://www.tensorflow.org/tensorboard/hyperparameter_tuning_with_hparams"><img src="https://www.tensorflow.org/images/tf_logo_32px.png" />View on TensorFlow.org</a>
  31. # </td>
  32. # <td>
  33. # <a target="_blank" href="https://colab.research.google.com/github/tensorflow/tensorboard/blob/master/docs/hyperparameter_tuning_with_hparams.ipynb"><img src="https://www.tensorflow.org/images/colab_logo_32px.png" />Run in Google Colab</a>
  34. # </td>
  35. # <td>
  36. # <a target="_blank" href="https://github.com/tensorflow/tensorboard/blob/master/docs/hyperparameter_tuning_with_hparams.ipynb"><img src="https://www.tensorflow.org/images/GitHub-Mark-32px.png" />View source on GitHub</a>
  37. # </td>
  38. # </table>
  39. # %% [markdown]
  40. # When building machine learning models, you need to choose various [hyperparameters](https://en.wikipedia.org/wiki/Hyperparameter_(machine_learning)), such as the dropout rate in a layer or the learning rate. These decisions impact model metrics, such as accuracy. Therefore, an important step in the machine learning workflow is to identify the best hyperparameters for your problem, which often involves experimentation. This process is known as "Hyperparameter Optimization" or "Hyperparameter Tuning".
  41. #
  42. # The HParams dashboard in TensorBoard provides several tools to help with this process of identifying the best experiment or most promising sets of hyperparameters.
  43. #
  44. # This tutorial will focus on the following steps:
  45. #
  46. # 1. Experiment setup and HParams summary
  47. # 2. Adapt TensorFlow runs to log hyperparameters and metrics
  48. # 3. Start runs and log them all under one parent directory
  49. # 4. Visualize the results in TensorBoard's HParams dashboard
  50. #
  51. # Note: The HParams summary APIs and dashboard UI are in a preview stage and will change over time.
  52. #
  53. # Start by installing TF 2.0 and loading the TensorBoard notebook extension:
  54. # %%
  55. # Load the TensorBoard notebook extension
  56. get_ipython().run_line_magic("load_ext", "tensorboard")
  57. # %%
  58. # Clear any logs from previous runs
  59. get_ipython().system("rm -rf ./logs/ ")
  60. # %% [markdown]
  61. # Import TensorFlow and the TensorBoard HParams plugin:
  62. # %%
  63. import tensorflow as tf
  64. from tensorboard.plugins.hparams import api as hp
  65. # %% [markdown]
  66. # Download the [FashionMNIST](https://github.com/zalandoresearch/fashion-mnist) dataset and scale it:
  67. # %%
  68. fashion_mnist = tf.keras.datasets.fashion_mnist
  69. (x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
  70. x_train, x_test = x_train / 255.0, x_test / 255.0
  71. # %% [markdown]
  72. # ## 1. Experiment setup and the HParams experiment summary
  73. #
  74. # Experiment with three hyperparameters in the model:
  75. #
  76. # 1. Number of units in the first dense layer
  77. # 2. Dropout rate in the dropout layer
  78. # 3. Optimizer
  79. #
  80. # List the values to try, and log an experiment configuration to TensorBoard. This step is optional: you can provide domain information to enable more precise filtering of hyperparameters in the UI, and you can specify which metrics should be displayed.
  81. # %%
  82. HP_NUM_UNITS = hp.HParam("num_units", hp.Discrete([16, 32]))
  83. HP_DROPOUT = hp.HParam("dropout", hp.RealInterval(0.1, 0.2))
  84. HP_OPTIMIZER = hp.HParam("optimizer", hp.Discrete(["adam", "sgd"]))
  85. METRIC_ACCURACY = "accuracy"
  86. with tf.summary.create_file_writer("logs/hparam_tuning").as_default():
  87. hp.hparams_config(
  88. hparams=[HP_NUM_UNITS, HP_DROPOUT, HP_OPTIMIZER],
  89. metrics=[hp.Metric(METRIC_ACCURACY, display_name="Accuracy")],
  90. )
  91. # %% [markdown]
  92. # If you choose to skip this step, you can use a string literal wherever you would otherwise use an `HParam` value: e.g., `hparams['dropout']` instead of `hparams[HP_DROPOUT]`.
  93. # %% [markdown]
  94. # ## 2. Adapt TensorFlow runs to log hyperparameters and metrics
  95. #
  96. # The model will be quite simple: two dense layers with a dropout layer between them. The training code will look familiar, although the hyperparameters are no longer hardcoded. Instead, the hyperparameters are provided in an `hparams` dictionary and used throughout the training function:
  97. # %%
  98. def train_test_model(hparams):
  99. """description"""
  100. model = tf.keras.models.Sequential(
  101. [
  102. tf.keras.layers.Flatten(),
  103. tf.keras.layers.Dense(hparams[HP_NUM_UNITS], activation=tf.nn.relu),
  104. tf.keras.layers.Dropout(hparams[HP_DROPOUT]),
  105. tf.keras.layers.Dense(10, activation=tf.nn.softmax),
  106. ]
  107. )
  108. model.compile(
  109. optimizer=hparams[HP_OPTIMIZER],
  110. loss="sparse_categorical_crossentropy",
  111. metrics=["accuracy"],
  112. )
  113. model.fit(
  114. x_train, y_train, epochs=1
  115. ) # Run with 1 epoch to speed things up for demo purposes
  116. _, accuracy = model.evaluate(x_test, y_test)
  117. return accuracy
  118. # %% [markdown]
  119. # For each run, log an hparams summary with the hyperparameters and final accuracy:
  120. # %%
  121. def run(run_dir, hparams):
  122. """description"""
  123. with tf.summary.create_file_writer(run_dir).as_default():
  124. hp.hparams(hparams) # record the values used in this trial
  125. accuracy = train_test_model(hparams)
  126. tf.summary.scalar(METRIC_ACCURACY, accuracy, step=1)
  127. # %% [markdown]
  128. # When training Keras models, you can use callbacks instead of writing these directly:
  129. #
  130. # ```python
  131. # model.fit(
  132. # ...,
  133. # callbacks=[
  134. # tf.keras.callbacks.TensorBoard(logdir), # log metrics
  135. # hp.KerasCallback(logdir, hparams), # log hparams
  136. # ],
  137. # )
  138. # ```
  139. # %% [markdown]
  140. # ## 3. Start runs and log them all under one parent directory
  141. #
  142. # You can now try multiple experiments, training each one with a different set of hyperparameters.
  143. #
  144. # For simplicity, use a grid search: try all combinations of the discrete parameters and just the lower and upper bounds of the real-valued parameter. For more complex scenarios, it might be more effective to choose each hyperparameter value randomly (this is called a random search). There are more advanced methods that can be used.
  145. #
  146. # Run a few experiments, which will take a few minutes:
  147. # %%
  148. session_num = 0
  149. for num_units in HP_NUM_UNITS.domain.values:
  150. for dropout_rate in (HP_DROPOUT.domain.min_value, HP_DROPOUT.domain.max_value):
  151. for optimizer in HP_OPTIMIZER.domain.values:
  152. hparams = {
  153. HP_NUM_UNITS: num_units,
  154. HP_DROPOUT: dropout_rate,
  155. HP_OPTIMIZER: optimizer,
  156. }
  157. run_name = f"run-{session_num:d}"
  158. print(f"--- Starting trial: {run_name}")
  159. print({h.name: hparams[h] for h in hparams})
  160. run(f"logs/hparam_tuning/{run_name}", hparams)
  161. session_num += 1
  162. # %% [markdown]
  163. # ## 4. Visualize the results in TensorBoard's HParams plugin
  164. # %% [markdown]
  165. # The HParams dashboard can now be opened. Start TensorBoard and click on "HParams" at the top.
  166. # %%
  167. get_ipython().run_line_magic("tensorboard", "--logdir logs/hparam_tuning")
  168. # %% [markdown]
  169. # <img class="tfo-display-only-on-site" src="images/hparams_table.png?raw=1"/>
  170. # %% [markdown]
  171. # The left pane of the dashboard provides filtering capabilities that are active across all the views in the HParams dashboard:
  172. #
  173. # - Filter which hyperparameters/metrics are shown in the dashboard
  174. # - Filter which hyperparameter/metrics values are shown in the dashboard
  175. # - Filter on run status (running, success, ...)
  176. # - Sort by hyperparameter/metric in the table view
  177. # - Number of session groups to show (useful for performance when there are many experiments)
  178. #
  179. # %% [markdown]
  180. # The HParams dashboard has three different views, with various useful information:
  181. #
  182. # * The **Table View** lists the runs, their hyperparameters, and their metrics.
  183. # * The **Parallel Coordinates View** shows each run as a line going through an axis for each hyperparemeter and metric. Click and drag the mouse on any axis to mark a region which will highlight only the runs that pass through it. This can be useful for identifying which groups of hyperparameters are most important. The axes themselves can be re-ordered by dragging them.
  184. # * The **Scatter Plot View** shows plots comparing each hyperparameter/metric with each metric. This can help identify correlations. Click and drag to select a region in a specific plot and highlight those sessions across the other plots.
  185. #
  186. # A table row, a parallel coordinates line, and a scatter plot market can be clicked to see a plot of the metrics as a function of training steps for that session (although in this tutorial only one step is used for each run).
  187. # %% [markdown]
  188. # To further explore the capabilities of the HParams dashboard, download a set of pregenerated logs with more experiments:
  189. # %%
  190. get_ipython().run_cell_magic(
  191. "bash",
  192. "",
  193. "wget -q 'https://storage.googleapis.com/download.tensorflow.org/tensorboard/hparams_demo_logs.zip'\nunzip -q hparams_demo_logs.zip -d logs/hparam_demo",
  194. )
  195. # %% [markdown]
  196. # View these logs in TensorBoard:
  197. # %%
  198. get_ipython().run_line_magic("tensorboard", "--logdir logs/hparam_demo")
  199. # %% [markdown]
  200. # <img class="tfo-display-only-on-site" src="images/hparams_parallel_coordinates.png?raw=1"/>
  201. # %% [markdown]
  202. # You can try out the different views in the HParams dashboard.
  203. #
  204. # For example, by going to the parallel coordinates view and clicking and dragging on the accuracy axis, you can select the runs with the highest accuracy. As these runs pass through 'adam' in the optimizer axis, you can conclude that 'adam' performed better than 'sgd' on these experiments.