From bee7d68c4ac516083fe182e50826c2b49ea265c4 Mon Sep 17 00:00:00 2001 From: Bryon Tjanaka Date: Fri, 22 Nov 2024 01:55:16 -0800 Subject: [PATCH 01/12] Add visualization tool --- package/visualization/plot_pyribs/LICENSE | 21 +++++ package/visualization/plot_pyribs/README.md | 77 ++++++++++++++++++ package/visualization/plot_pyribs/__init__.py | 39 +++++++++ .../plot_pyribs/images/archive.png | Bin 0 -> 23589 bytes 4 files changed, 137 insertions(+) create mode 100644 package/visualization/plot_pyribs/LICENSE create mode 100644 package/visualization/plot_pyribs/README.md create mode 100644 package/visualization/plot_pyribs/__init__.py create mode 100644 package/visualization/plot_pyribs/images/archive.png diff --git a/package/visualization/plot_pyribs/LICENSE b/package/visualization/plot_pyribs/LICENSE new file mode 100644 index 00000000..51c2bdfd --- /dev/null +++ b/package/visualization/plot_pyribs/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Bryon Tjanaka + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md new file mode 100644 index 00000000..c00bdded --- /dev/null +++ b/package/visualization/plot_pyribs/README.md @@ -0,0 +1,77 @@ +--- +author: Bryon Tjanaka +title: Pyribs Visualization Wrappers +description: This visualizaton module provides wrappers around the visualization functions from pyribs, which is useful for plotting results from CmaMaeSampler. +tags: [visualization, quality diversity, pyribs] +optuna_versions: [4.0.0] +license: MIT License +--- + +## Class or Function Names + +- plot_grid_archive_heatmap + +## Installation + +```shell +$ pip install ribs[visualize] +``` + +## Example + +A minimal example would be the following: + +```python +import matplotlib.pyplot as plt +import optuna +import optunahub +from optuna.study import StudyDirection + +module = optunahub.load_module("samplers/cmamae") +CmaMaeSampler = module.CmaMaeSampler + +plot_pyribs = optunahub.load_module(package="visualization/plot_pyribs",) +plot_grid_archive_heatmap = plot_pyribs.plot_grid_archive_heatmap + + +def objective(trial: optuna.trial.Trial) -> tuple[float, float, float]: + """Returns an objective followed by two measures.""" + x = trial.suggest_float("x", -10, 10) + y = trial.suggest_float("y", -10, 10) + return x**2 + y**2, x, y + + +if __name__ == "__main__": + sampler = CmaMaeSampler( + param_names=["x", "y"], + archive_dims=[20, 20], + archive_ranges=[(-1, 1), (-1, 1)], + archive_learning_rate=0.1, + archive_threshold_min=-10, + n_emitters=1, + emitter_x0={ + "x": 0, + "y": 0, + }, + emitter_sigma0=0.1, + emitter_batch_size=20, + ) + study = optuna.create_study( + sampler=sampler, + directions=[ + StudyDirection.MINIMIZE, + # The remaining directions are for the measures, which do not have + # an optimization direction. However, we set MINIMIZE as a + # placeholder direction. + StudyDirection.MINIMIZE, + StudyDirection.MINIMIZE, + ], + ) + study.optimize(objective, n_trials=10000) + + fig, ax = plt.subplots(figsize=(8, 6)) + plot_grid_archive_heatmap(study, ax=ax) + plt.show() +``` + +![Example of this Plot](images/archive.png) diff --git a/package/visualization/plot_pyribs/__init__.py b/package/visualization/plot_pyribs/__init__.py new file mode 100644 index 00000000..8b049785 --- /dev/null +++ b/package/visualization/plot_pyribs/__init__.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import matplotlib.pyplot as plt +import optuna +from ribs.visualize import grid_archive_heatmap + + +if TYPE_CHECKING: + from matplotlib.axes._axes import Axes + + +def plot_grid_archive_heatmap( # type: ignore + study: optuna.Study, + ax: Axes | None = None, + **kwargs, +) -> Axes: + """Wrapper around pyribs grid_archive_heatmap. + + Args: + study: Optuna study with a sampler that uses pyribs. This function will + plot the result archive from the sampler's scheduler. + ax: Axes on which to plot the heatmap. If None, we create a new axes. + kwargs: All remaining kwargs will be passed to `grid_archive_heatmap + `_. + Returns: + The axes on which the plot was created. + """ + if ax is None: + ax = plt.gca() + + archive = study.sampler.scheduler.result_archive + grid_archive_heatmap(archive, ax=ax, **kwargs) + + return ax + + +__all__ = ["plot_grid_archive_heatmap"] diff --git a/package/visualization/plot_pyribs/images/archive.png b/package/visualization/plot_pyribs/images/archive.png new file mode 100644 index 0000000000000000000000000000000000000000..c23a5ff59d62d3778c038f2e46b940f626988069 GIT binary patch literal 23589 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 Zh16Oo>HaFqxqxO={F= Date: Sun, 1 Dec 2024 18:57:24 -0800 Subject: [PATCH 02/12] Update example --- package/visualization/plot_pyribs/README.md | 22 ++++------ package/visualization/plot_pyribs/example.py | 44 ++++++++++++++++++++ 2 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 package/visualization/plot_pyribs/example.py diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index c00bdded..c101c03e 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -30,20 +30,23 @@ from optuna.study import StudyDirection module = optunahub.load_module("samplers/cmamae") CmaMaeSampler = module.CmaMaeSampler -plot_pyribs = optunahub.load_module(package="visualization/plot_pyribs",) +plot_pyribs = optunahub.load_module(package="visualization/plot_pyribs") plot_grid_archive_heatmap = plot_pyribs.plot_grid_archive_heatmap -def objective(trial: optuna.trial.Trial) -> tuple[float, float, float]: +def objective(trial: optuna.trial.Trial) -> float: """Returns an objective followed by two measures.""" x = trial.suggest_float("x", -10, 10) y = trial.suggest_float("y", -10, 10) - return x**2 + y**2, x, y + trial.set_user_attr("m0", 2 * x) + trial.set_user_attr("m1", x + y) + return x**2 + y**2 if __name__ == "__main__": sampler = CmaMaeSampler( param_names=["x", "y"], + measure_names=["m0", "m1"], archive_dims=[20, 20], archive_ranges=[(-1, 1), (-1, 1)], archive_learning_rate=0.1, @@ -56,21 +59,12 @@ if __name__ == "__main__": emitter_sigma0=0.1, emitter_batch_size=20, ) - study = optuna.create_study( - sampler=sampler, - directions=[ - StudyDirection.MINIMIZE, - # The remaining directions are for the measures, which do not have - # an optimization direction. However, we set MINIMIZE as a - # placeholder direction. - StudyDirection.MINIMIZE, - StudyDirection.MINIMIZE, - ], - ) + study = optuna.create_study(sampler=sampler) study.optimize(objective, n_trials=10000) fig, ax = plt.subplots(figsize=(8, 6)) plot_grid_archive_heatmap(study, ax=ax) + plt.savefig("archive.png") plt.show() ``` diff --git a/package/visualization/plot_pyribs/example.py b/package/visualization/plot_pyribs/example.py new file mode 100644 index 00000000..97b88743 --- /dev/null +++ b/package/visualization/plot_pyribs/example.py @@ -0,0 +1,44 @@ +import matplotlib.pyplot as plt +import optuna +import optunahub + + +module = optunahub.load_module("samplers/cmamae") +CmaMaeSampler = module.CmaMaeSampler + +plot_pyribs = optunahub.load_module(package="visualization/plot_pyribs") +plot_grid_archive_heatmap = plot_pyribs.plot_grid_archive_heatmap + + +def objective(trial: optuna.trial.Trial) -> float: + """Returns an objective followed by two measures.""" + x = trial.suggest_float("x", -10, 10) + y = trial.suggest_float("y", -10, 10) + trial.set_user_attr("m0", 2 * x) + trial.set_user_attr("m1", x + y) + return x**2 + y**2 + + +if __name__ == "__main__": + sampler = CmaMaeSampler( + param_names=["x", "y"], + measure_names=["m0", "m1"], + archive_dims=[20, 20], + archive_ranges=[(-1, 1), (-1, 1)], + archive_learning_rate=0.1, + archive_threshold_min=-10, + n_emitters=1, + emitter_x0={ + "x": 0, + "y": 0, + }, + emitter_sigma0=0.1, + emitter_batch_size=20, + ) + study = optuna.create_study(sampler=sampler) + study.optimize(objective, n_trials=10000) + + fig, ax = plt.subplots(figsize=(8, 6)) + plot_grid_archive_heatmap(study, ax=ax) + plt.savefig("archive.png") + plt.show() From 0fb885d3644bc145201147c6a7d9377beec049ef Mon Sep 17 00:00:00 2001 From: Bryon Tjanaka Date: Sun, 1 Dec 2024 19:01:30 -0800 Subject: [PATCH 03/12] Docs fixes --- package/visualization/plot_pyribs/README.md | 1 - package/visualization/plot_pyribs/__init__.py | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index c101c03e..6825fff1 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -25,7 +25,6 @@ A minimal example would be the following: import matplotlib.pyplot as plt import optuna import optunahub -from optuna.study import StudyDirection module = optunahub.load_module("samplers/cmamae") CmaMaeSampler = module.CmaMaeSampler diff --git a/package/visualization/plot_pyribs/__init__.py b/package/visualization/plot_pyribs/__init__.py index 8b049785..94e76b72 100644 --- a/package/visualization/plot_pyribs/__init__.py +++ b/package/visualization/plot_pyribs/__init__.py @@ -18,6 +18,10 @@ def plot_grid_archive_heatmap( # type: ignore ) -> Axes: """Wrapper around pyribs grid_archive_heatmap. + Refer to the `grid_archive_heatmap + `_ + function from pyribs for information. + Args: study: Optuna study with a sampler that uses pyribs. This function will plot the result archive from the sampler's scheduler. From dd3cdca31cc0a1cf4469cf0e886190136201ae1e Mon Sep 17 00:00:00 2001 From: Bryon Tjanaka Date: Sun, 1 Dec 2024 19:15:50 -0800 Subject: [PATCH 04/12] Update example image --- .../plot_pyribs/images/archive.png | Bin 23589 -> 24334 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/package/visualization/plot_pyribs/images/archive.png b/package/visualization/plot_pyribs/images/archive.png index c23a5ff59d62d3778c038f2e46b940f626988069..96a615e00a546750a8b8ce3c0ad538d70d168e7f 100644 GIT binary patch literal 24334 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 Zh16Oo>HaFqxqxO={F= Date: Sun, 1 Dec 2024 19:17:48 -0800 Subject: [PATCH 05/12] Fix docstring --- package/visualization/plot_pyribs/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/visualization/plot_pyribs/__init__.py b/package/visualization/plot_pyribs/__init__.py index 94e76b72..6d6630eb 100644 --- a/package/visualization/plot_pyribs/__init__.py +++ b/package/visualization/plot_pyribs/__init__.py @@ -25,7 +25,8 @@ def plot_grid_archive_heatmap( # type: ignore Args: study: Optuna study with a sampler that uses pyribs. This function will plot the result archive from the sampler's scheduler. - ax: Axes on which to plot the heatmap. If None, we create a new axes. + ax: Axes on which to plot the heatmap. If None, we retrieve the current + axes. kwargs: All remaining kwargs will be passed to `grid_archive_heatmap `_. Returns: From 85000537694fa4ff5c20dccab5a508dcb42e92cb Mon Sep 17 00:00:00 2001 From: Bryon Tjanaka Date: Mon, 2 Dec 2024 15:50:50 -0800 Subject: [PATCH 06/12] Add visualization to CmaMaeSampler --- package/samplers/cmamae/README.md | 10 ++++++++++ package/samplers/cmamae/example.py | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/package/samplers/cmamae/README.md b/package/samplers/cmamae/README.md index 7801df9f..52869cca 100644 --- a/package/samplers/cmamae/README.md +++ b/package/samplers/cmamae/README.md @@ -46,12 +46,17 @@ $ pip install ribs ## Example ```python +import matplotlib.pyplot as plt import optuna import optunahub + module = optunahub.load_module("samplers/cmamae") CmaMaeSampler = module.CmaMaeSampler +plot_pyribs = optunahub.load_module(package="visualization/plot_pyribs") +plot_grid_archive_heatmap = plot_pyribs.plot_grid_archive_heatmap + def objective(trial: optuna.trial.Trial) -> float: """Returns an objective followed by two measures.""" @@ -80,6 +85,11 @@ if __name__ == "__main__": ) study = optuna.create_study(sampler=sampler) study.optimize(objective, n_trials=10000) + + fig, ax = plt.subplots(figsize=(8, 6)) + plot_grid_archive_heatmap(study, ax=ax) + plt.savefig("archive.png") + plt.show() ``` ## Others diff --git a/package/samplers/cmamae/example.py b/package/samplers/cmamae/example.py index 2903a81a..97b88743 100644 --- a/package/samplers/cmamae/example.py +++ b/package/samplers/cmamae/example.py @@ -1,3 +1,4 @@ +import matplotlib.pyplot as plt import optuna import optunahub @@ -5,6 +6,9 @@ module = optunahub.load_module("samplers/cmamae") CmaMaeSampler = module.CmaMaeSampler +plot_pyribs = optunahub.load_module(package="visualization/plot_pyribs") +plot_grid_archive_heatmap = plot_pyribs.plot_grid_archive_heatmap + def objective(trial: optuna.trial.Trial) -> float: """Returns an objective followed by two measures.""" @@ -33,3 +37,8 @@ def objective(trial: optuna.trial.Trial) -> float: ) study = optuna.create_study(sampler=sampler) study.optimize(objective, n_trials=10000) + + fig, ax = plt.subplots(figsize=(8, 6)) + plot_grid_archive_heatmap(study, ax=ax) + plt.savefig("archive.png") + plt.show() From 08fd2fb63f0de33273f7a53baf255d5b962e3884 Mon Sep 17 00:00:00 2001 From: Bryon Tjanaka Date: Mon, 2 Dec 2024 15:53:38 -0800 Subject: [PATCH 07/12] Note viz module --- package/samplers/cmamae/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/samplers/cmamae/README.md b/package/samplers/cmamae/README.md index 52869cca..ac015ef5 100644 --- a/package/samplers/cmamae/README.md +++ b/package/samplers/cmamae/README.md @@ -27,6 +27,9 @@ with improvement ranking, all wrapped up in a However, it is possible to implement many variations of CMA-MAE and other quality diversity algorithms using pyribs. +For visualizing the results of the `CmaMaeSampler`, note that we use the +`plot_grid_archive_heatmap` function from the `plot_pyribs` plugin. + ## Class or Function Names - CmaMaeSampler From 17878b4030154b4c79deec7c48811ea80f4b7aaf Mon Sep 17 00:00:00 2001 From: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com> Date: Thu, 12 Dec 2024 03:25:00 +0100 Subject: [PATCH 08/12] Update package/visualization/plot_pyribs/README.md --- package/visualization/plot_pyribs/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index 6825fff1..36beb444 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -9,7 +9,13 @@ license: MIT License ## Class or Function Names -- plot_grid_archive_heatmap +- `plot_grid_archive_heatmap()` + +- `HEBOSampler(study: optuna.Study, ax: plt.Axes, **kwargs)` + - `study`: Optuna study with a sampler that uses pyribs. This function will plot the result archive from the sampler's scheduler. + - ax: Axes on which to plot the heatmap. If None, we retrieve the current axes. + - kwargs: All remaining kwargs will be passed to [`grid_archive_heatmap`](https://docs.pyribs.org/en/stable/api/ribs.visualize.grid_archive_heatmap.html). + ## Installation From e289417fef194e3ccdeea369f1c7e8add3548e8a Mon Sep 17 00:00:00 2001 From: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com> Date: Thu, 12 Dec 2024 03:29:13 +0100 Subject: [PATCH 09/12] Update package/visualization/plot_pyribs/README.md --- package/visualization/plot_pyribs/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index 36beb444..308cb702 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -11,10 +11,10 @@ license: MIT License - `plot_grid_archive_heatmap()` -- `HEBOSampler(study: optuna.Study, ax: plt.Axes, **kwargs)` +- `plot_grid_archive_heatmap(study: optuna.Study, ax: plt.Axes, **kwargs)` - `study`: Optuna study with a sampler that uses pyribs. This function will plot the result archive from the sampler's scheduler. - - ax: Axes on which to plot the heatmap. If None, we retrieve the current axes. - - kwargs: All remaining kwargs will be passed to [`grid_archive_heatmap`](https://docs.pyribs.org/en/stable/api/ribs.visualize.grid_archive_heatmap.html). + - `ax`: Axes on which to plot the heatmap. If None, we retrieve the current axes. + - `**kwargs`: All remaining kwargs will be passed to [`grid_archive_heatmap`](https://docs.pyribs.org/en/stable/api/ribs.visualize.grid_archive_heatmap.html). ## Installation From e519d362ac6cf29413c516646d36c6766267fc03 Mon Sep 17 00:00:00 2001 From: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com> Date: Thu, 12 Dec 2024 03:29:59 +0100 Subject: [PATCH 10/12] Update package/visualization/plot_pyribs/README.md --- package/visualization/plot_pyribs/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index 308cb702..1f2e1309 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -9,8 +9,6 @@ license: MIT License ## Class or Function Names -- `plot_grid_archive_heatmap()` - - `plot_grid_archive_heatmap(study: optuna.Study, ax: plt.Axes, **kwargs)` - `study`: Optuna study with a sampler that uses pyribs. This function will plot the result archive from the sampler's scheduler. - `ax`: Axes on which to plot the heatmap. If None, we retrieve the current axes. From 43e2e0abfc9e0d367a3a6e18f0b71e88b003ec54 Mon Sep 17 00:00:00 2001 From: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com> Date: Thu, 12 Dec 2024 03:30:53 +0100 Subject: [PATCH 11/12] Fix pre-commit --- package/visualization/plot_pyribs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index 1f2e1309..7ffd9aae 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -10,6 +10,7 @@ license: MIT License ## Class or Function Names - `plot_grid_archive_heatmap(study: optuna.Study, ax: plt.Axes, **kwargs)` + - `study`: Optuna study with a sampler that uses pyribs. This function will plot the result archive from the sampler's scheduler. - `ax`: Axes on which to plot the heatmap. If None, we retrieve the current axes. - `**kwargs`: All remaining kwargs will be passed to [`grid_archive_heatmap`](https://docs.pyribs.org/en/stable/api/ribs.visualize.grid_archive_heatmap.html). From 48e1bf4082a8e4cab6a42ffa9ceac135bac3c185 Mon Sep 17 00:00:00 2001 From: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com> Date: Thu, 12 Dec 2024 03:32:16 +0100 Subject: [PATCH 12/12] Fix pre-commit --- package/visualization/plot_pyribs/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/package/visualization/plot_pyribs/README.md b/package/visualization/plot_pyribs/README.md index 7ffd9aae..f7eb29ca 100644 --- a/package/visualization/plot_pyribs/README.md +++ b/package/visualization/plot_pyribs/README.md @@ -15,7 +15,6 @@ license: MIT License - `ax`: Axes on which to plot the heatmap. If None, we retrieve the current axes. - `**kwargs`: All remaining kwargs will be passed to [`grid_archive_heatmap`](https://docs.pyribs.org/en/stable/api/ribs.visualize.grid_archive_heatmap.html). - ## Installation ```shell