From eda7283d40e75ae68de0f3ac5162f52f267de9f9 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:48:02 +0900 Subject: [PATCH 01/10] Update docs --- recipes/001_first.py | 97 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index d3844e86..3207fa68 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -4,12 +4,15 @@ How to Implement and Register Your Algorithm with OptunaHub =========================================================== -OptunaHub is an Optuna package registry, which is a user platform to share their optimization algorithms. -This recipe shows how to implement and register your own sampling algorithm with OptunaHub. +OptunaHub is an Optuna package registry, which is a user platform to share their optimization and visualization algorithms. +This recipe shows how to implement and register your own algorithm with OptunaHub. -How to Implement Your Own Algorithm +How to Implement Your Own Sampler ----------------------------------- +In this section, we show how to implement your own sampler, i.e., optimizaiton algorithm. +If you want to implement a visualization function rather than a sampler, you can skip this section and move to the next section. + Usually, Optuna provides `BaseSampler` class to implement your own sampler. However, it is a bit complicated to implement a sampler from scratch. Instead, in OptunaHub, you can use `samplers/simple/SimpleSampler` class, which is a sampler template that can be easily extended. @@ -107,6 +110,80 @@ def objective(trial: optuna.trial.Trial) -> float: ################################################################################################### # We can see that ``x`` value found by Optuna is close to the optimal value ``2``. + +################################################################################################### +# How to Implement Your Own Visualization Function +# --------------------------------------------------------- +# +# In this section, we show how to implement your own visualization function. +# If you want to implement a sampler rather than a visualization function, you can skip this section and move to the next section. +# +# You need to install `optuna` to implement your own sampler, and `optunahub` to use the template `SimpleSampler`. +# +# .. code-block:: bash +# +# $ pip install optuna optunahub +# +# Next, define your own visualization function. +# +# If you use `plotly` (https://plotly.com/python/) for visualization, the function should return a `plotly.graph_objects.Figure` object. +# In this example, we implement a visualization function that plots the optimization history. + +from __future__ import annotations +import optuna +import plotly.graph_objects as go + + +def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: + trials = study.trials + best_values = [trial.value for trial in trials] + best_values = [min(best_values[:i + 1]) for i in range(len(best_values))] + iteration = [i for i in range(len(trials))] + + fig = go.Figure() + fig.add_trace(go.Scatter( + x=iteration, + y=best_values, + mode="lines+markers", + )) + fig.update_layout(title="Optimization history") + return fig + + +# If you use `matplotlib` (https://matplotlib.org/) for visualization, the function should return a `matplotlib.figure.Figure` object. + +from __future__ import annotations +import matplotlib.pyplot as plt +import optuna + + +def plot_optimizaiton_history_matplotlib(study: optuna.study.Study) -> plt.Figure: + trials = study.trials + best_values = [trial.value for trial in trials] + best_values = [min(best_values[:i + 1]) for i in range(len(best_values))] + + fig, ax = plt.subplots() + ax.set_title("Optimization history") + ax.plot(best_values, marker="o") + return fig + + +################################################################################################### +# In this example, the objective function is a simple quadratic function. + + +def objective(trial: optuna.trial.Trial) -> float: + x = trial.suggest_float("x", -10, 10) + return x**2 + + +study = optuna.create_study() +study.optimize(objective, n_trials=100) + +fig = plot_optimizaiton_history(study) +fig.show() # plt.show() for matplotlib + + ################################################################################################### # How to Register Your Implemented Algorithm with OptunaHub # --------------------------------------------------------- @@ -117,8 +194,8 @@ def objective(trial: optuna.trial.Trial) -> float: # The following is an example of the directory structure of the pull request. # # | package -# | └── samplers -# | └── YOUR_ALGORITHM_NAME +# | └── samplers (or visualization) +# | └── YOUR_PACKAGE_NAME # | ├── README.md # | ├── __init__.py # | ├── LICENSE @@ -128,16 +205,18 @@ def objective(trial: optuna.trial.Trial) -> float: # | ├── requirements.txt # | └── YOUR_ALGORITHM_NAME.py # -# An implemented sampler should be put in the `samplers` directory. -# In the `samplers` directory, you should create a directory named after your algorithm. +# An implemented sampler (resp. visualization) should be put in the `samplers` (resp. `visualization`) directory. +# In the `samplers` (resp. `visualization`) directory, you should create a directory with a unique identifier. +# This unique identifier is the name of your algorithm package, is used to load the package, and is unable to change once it is registered. +# # The created directory should include the following files: # # - `README.md`: A description of your algorithm. This file is used to create an `web page of OptunaHub `_. Let me explain the format of the `README.md` file later. -# - `__init__.py`: An initialization file. This file must import your implemented sampler from `YOUR_ALGORITHM_NAME.py`. +# - `__init__.py`: An initialization file. This file must implement your algorithm or import its implementation from another file, e.g., `YOUR_ALGORITHM_NAME.py`. # - `LICENSE`: A license file. This file must contain the license of your algorithm. It should be the MIT license in the alpha version. # - `images`: This is optional. A directory that contains images. The images in this directory will be used the `web page of OptunaHub `_. `thumbnail.png` will be used as a thumbnail in the web page. Note that `README.md` can also refer to image files, e.g. `images/screenshot.png`, in this directory. # - `requirements.txt`: This is optional. A file that contains the additional dependencies of your algorithm. If there are no additional dependencies, you do not need to create this file. -# - `YOUR_ALGORITHM_NAME.py`: Your implemented sampler. +# - `YOUR_ALGORITHM_NAME.py`: The implementation of your algorithm. # # `README.md` must contain the following sections: # From dbbffee9a348383ddfd313e7946650a18dd92976 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:50:39 +0900 Subject: [PATCH 02/10] Fix code --- recipes/001_first.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index 3207fa68..3dd7293a 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -137,15 +137,17 @@ def objective(trial: optuna.trial.Trial) -> float: def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: trials = study.trials best_values = [trial.value for trial in trials] - best_values = [min(best_values[:i + 1]) for i in range(len(best_values))] + best_values = [min(best_values[: i + 1]) for i in range(len(best_values))] iteration = [i for i in range(len(trials))] fig = go.Figure() - fig.add_trace(go.Scatter( - x=iteration, - y=best_values, - mode="lines+markers", - )) + fig.add_trace( + go.Scatter( + x=iteration, + y=best_values, + mode="lines+markers", + ) + ) fig.update_layout(title="Optimization history") return fig @@ -160,7 +162,7 @@ def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: def plot_optimizaiton_history_matplotlib(study: optuna.study.Study) -> plt.Figure: trials = study.trials best_values = [trial.value for trial in trials] - best_values = [min(best_values[:i + 1]) for i in range(len(best_values))] + best_values = [min(best_values[: i + 1]) for i in range(len(best_values))] fig, ax = plt.subplots() ax.set_title("Optimization history") From bb1ea5de88afd07e9ddd607a1c0d43dadcc2e3e7 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:53:35 +0900 Subject: [PATCH 03/10] Update docs --- recipes/001_first.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index 3dd7293a..a069b218 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -216,7 +216,7 @@ def objective(trial: optuna.trial.Trial) -> float: # - `README.md`: A description of your algorithm. This file is used to create an `web page of OptunaHub `_. Let me explain the format of the `README.md` file later. # - `__init__.py`: An initialization file. This file must implement your algorithm or import its implementation from another file, e.g., `YOUR_ALGORITHM_NAME.py`. # - `LICENSE`: A license file. This file must contain the license of your algorithm. It should be the MIT license in the alpha version. -# - `images`: This is optional. A directory that contains images. The images in this directory will be used the `web page of OptunaHub `_. `thumbnail.png` will be used as a thumbnail in the web page. Note that `README.md` can also refer to image files, e.g. `images/screenshot.png`, in this directory. +# - `images`: This is optional. A directory that contains images. The images in this directory will be used the `web page of OptunaHub `_. `thumbnail.png` will be used as a thumbnail in the web page for visualization packages. Note that `README.md` can also refer to image files, e.g. `images/screenshot.png`, in this directory. # - `requirements.txt`: This is optional. A file that contains the additional dependencies of your algorithm. If there are no additional dependencies, you do not need to create this file. # - `YOUR_ALGORITHM_NAME.py`: The implementation of your algorithm. # From 6e59f1d6a318878a13d16e7b08b70d638949f866 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:53:38 +0900 Subject: [PATCH 04/10] Update docs --- recipes/001_first.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index a069b218..ff514c8f 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -129,7 +129,6 @@ def objective(trial: optuna.trial.Trial) -> float: # If you use `plotly` (https://plotly.com/python/) for visualization, the function should return a `plotly.graph_objects.Figure` object. # In this example, we implement a visualization function that plots the optimization history. -from __future__ import annotations import optuna import plotly.graph_objects as go @@ -154,7 +153,6 @@ def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: # If you use `matplotlib` (https://matplotlib.org/) for visualization, the function should return a `matplotlib.figure.Figure` object. -from __future__ import annotations import matplotlib.pyplot as plt import optuna From c3079cb02ec69f656dc5e7accd2d52134236abc1 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:55:48 +0900 Subject: [PATCH 05/10] Update code example --- recipes/001_first.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index ff514c8f..cf36c74c 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -33,9 +33,11 @@ from typing import Any from github import Auth +import matplotlib.pyplot as plt import numpy as np import optuna import optunahub +import plotly.graph_objects as go ################################################################################################### @@ -129,9 +131,6 @@ def objective(trial: optuna.trial.Trial) -> float: # If you use `plotly` (https://plotly.com/python/) for visualization, the function should return a `plotly.graph_objects.Figure` object. # In this example, we implement a visualization function that plots the optimization history. -import optuna -import plotly.graph_objects as go - def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: trials = study.trials @@ -153,10 +152,6 @@ def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: # If you use `matplotlib` (https://matplotlib.org/) for visualization, the function should return a `matplotlib.figure.Figure` object. -import matplotlib.pyplot as plt -import optuna - - def plot_optimizaiton_history_matplotlib(study: optuna.study.Study) -> plt.Figure: trials = study.trials best_values = [trial.value for trial in trials] From 0a678d3c1bb837e5c0f82af8ef24d877f1b3e608 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:57:29 +0900 Subject: [PATCH 06/10] Apply ruff format --- recipes/001_first.py | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/001_first.py b/recipes/001_first.py index cf36c74c..311a2e74 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -152,6 +152,7 @@ def plot_optimizaiton_history(study: optuna.study.Study) -> go.Figure: # If you use `matplotlib` (https://matplotlib.org/) for visualization, the function should return a `matplotlib.figure.Figure` object. + def plot_optimizaiton_history_matplotlib(study: optuna.study.Study) -> plt.Figure: trials = study.trials best_values = [trial.value for trial in trials] From f558ca7fbfdd205ea0144228142f07af231876ae Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 17:58:43 +0900 Subject: [PATCH 07/10] Update --- recipes/001_first.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index 311a2e74..915ea10c 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -168,11 +168,6 @@ def plot_optimizaiton_history_matplotlib(study: optuna.study.Study) -> plt.Figur # In this example, the objective function is a simple quadratic function. -def objective(trial: optuna.trial.Trial) -> float: - x = trial.suggest_float("x", -10, 10) - return x**2 - - study = optuna.create_study() study.optimize(objective, n_trials=100) From a17e58f30c156e8f32545a6612e013efeffcc08d Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 18:00:28 +0900 Subject: [PATCH 08/10] Update --- recipes/001_first.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index 915ea10c..dc4384ee 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -7,6 +7,21 @@ OptunaHub is an Optuna package registry, which is a user platform to share their optimization and visualization algorithms. This recipe shows how to implement and register your own algorithm with OptunaHub. + +# First of all, import `optuna`, `optunahub`, and other required modules. +from __future__ import annotations + +import os +from typing import Any + +from github import Auth +import matplotlib.pyplot as plt +import numpy as np +import optuna +import optunahub +import plotly.graph_objects as go + + How to Implement Your Own Sampler ----------------------------------- @@ -25,21 +40,6 @@ """ -################################################################################################### -# First of all, import `optuna`, `optunahub`, and other required modules. -from __future__ import annotations - -import os -from typing import Any - -from github import Auth -import matplotlib.pyplot as plt -import numpy as np -import optuna -import optunahub -import plotly.graph_objects as go - - ################################################################################################### # Next, define your own sampler class by inheriting `SimpleSampler` class. # In this example, we implement a sampler that returns a random value. From ee3a2bb65f862448aeb0ca2cdc2e240727e238b1 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 18:02:56 +0900 Subject: [PATCH 09/10] Update --- recipes/001_first.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/recipes/001_first.py b/recipes/001_first.py index dc4384ee..915ea10c 100644 --- a/recipes/001_first.py +++ b/recipes/001_first.py @@ -7,21 +7,6 @@ OptunaHub is an Optuna package registry, which is a user platform to share their optimization and visualization algorithms. This recipe shows how to implement and register your own algorithm with OptunaHub. - -# First of all, import `optuna`, `optunahub`, and other required modules. -from __future__ import annotations - -import os -from typing import Any - -from github import Auth -import matplotlib.pyplot as plt -import numpy as np -import optuna -import optunahub -import plotly.graph_objects as go - - How to Implement Your Own Sampler ----------------------------------- @@ -40,6 +25,21 @@ """ +################################################################################################### +# First of all, import `optuna`, `optunahub`, and other required modules. +from __future__ import annotations + +import os +from typing import Any + +from github import Auth +import matplotlib.pyplot as plt +import numpy as np +import optuna +import optunahub +import plotly.graph_objects as go + + ################################################################################################### # Next, define your own sampler class by inheriting `SimpleSampler` class. # In this example, we implement a sampler that returns a random value. From 56f25df0f8410cde82642dcd3f31133b9c74ca98 Mon Sep 17 00:00:00 2001 From: y0z Date: Mon, 20 May 2024 18:04:39 +0900 Subject: [PATCH 10/10] Add plotly --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 304256a5..2dde8014 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ checking = [ ] docs = [ + "plotly", "sphinx", "sphinx_rtd_theme", "sphinx-gallery",