-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Gaussian, IsoLine Operators and Refactor GaussianEmitter/IsoLineE…
…mitter (#418) ## Description <!-- Provide a brief description of the PR's purpose here. --> Add Gaussian, IsoLine Operators and Refactor GaussianEmitter/IsoLineEmitter <!-- Notable points that this PR has either accomplished or will accomplish. --> ## Questions <!-- Any concerns or points of confusion? --> ## Status - [x] I have read the guidelines in [CONTRIBUTING.md](https://github.com/icaros-usc/pyribs/blob/master/CONTRIBUTING.md) - [x] I have formatted my code using `yapf` - [x] I have tested my code by running `pytest` - [x] I have linted my code with `pylint` - [x] I have added a one-line description of my change to the changelog in `HISTORY.md` - [x] This PR is ready to go --------- Co-authored-by: Bryon Tjanaka <[email protected]>
- Loading branch information
Showing
6 changed files
with
148 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
"""Gaussian Operator""" | ||
import numpy as np | ||
|
||
from ribs.emitters.operators._operator_base import OperatorBase | ||
|
||
|
||
class GaussianOperator(OperatorBase): | ||
"""Adds Gaussian noise to solutions. | ||
Args: | ||
sigma (float or array-like): Standard deviation of the Gaussian | ||
distribution. Note we assume the Gaussian is diagonal, so if this | ||
argument is an array, it must be 1D. | ||
lower_bounds (array-like): Upper bounds of the solution space. Passed in | ||
by emitter | ||
upper_bounds (array-like): Upper bounds of the solution space. Passed in | ||
by emitter | ||
seed (int): Value to seed the random number generator. Set to None to | ||
avoid a fixed seed. | ||
""" | ||
|
||
def __init__(self, sigma, seed, lower_bounds, upper_bounds): | ||
|
||
self._sigma = sigma | ||
self._lower_bounds = lower_bounds | ||
self._upper_bounds = upper_bounds | ||
|
||
self._rng = np.random.default_rng(seed) | ||
|
||
def ask(self, parents): | ||
"""Adds Gaussian noise to parents. | ||
Args: | ||
parents (array-like): (batch_size, solution_dim) array of | ||
solutions to be mutated. | ||
Returns: | ||
numpy.ndarray: ``(batch_size, solution_dim)`` array that contains | ||
``batch_size`` mutated solutions. | ||
""" | ||
parents = np.asarray(parents) | ||
|
||
noise = self._rng.normal( | ||
scale=self._sigma, | ||
size=(parents.shape[0], parents.shape[1]), | ||
).astype(parents.dtype) | ||
|
||
return np.clip(parents + noise, self._lower_bounds, self._upper_bounds) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
"""Iso Line Operator""" | ||
import numpy as np | ||
|
||
from ribs.emitters.operators._operator_base import OperatorBase | ||
|
||
|
||
class IsoLineOperator(OperatorBase): | ||
"""Adds Isotropic Gaussian noise and directional noise to parents. | ||
This operator was introduced in `Vassiliades 2018 | ||
<https://arxiv.org/abs/1804.03906>`_. | ||
Args: | ||
sigma (float or array-like): Standard deviation of the Gaussian | ||
distribution. Note we assume the Gaussian is diagonal, so if this | ||
argument is an array, it must be 1D. | ||
lower_bounds (array-like): Upper bounds of the solution space. Passed in | ||
by emitter | ||
upper_bounds (array-like): Upper bounds of the solution space. Passed in | ||
by emitter | ||
seed (int): Value to seed the random number generator. Set to None to | ||
avoid a fixed seed. | ||
""" | ||
|
||
def __init__(self, iso_sigma, line_sigma, lower_bounds, upper_bounds, seed): | ||
|
||
self._iso_sigma = iso_sigma | ||
self._line_sigma = line_sigma | ||
self._lower_bounds = lower_bounds | ||
self._upper_bounds = upper_bounds | ||
|
||
self._rng = np.random.default_rng(seed) | ||
|
||
def ask(self, parents): | ||
""" Adds Isotropic Guassian noise and directional noise to parents. | ||
Args: | ||
parents (array-like): (2, batch_size, solution_dim) | ||
parents[0] array of solutions selected by emitter | ||
parents[1] array of second batch of solutions passed by | ||
emitter. Used for calculating directional correlation. | ||
Returns: | ||
numpy.ndarray: ``(batch_size, solution_dim)`` array that contains | ||
``batch_size`` mutated solutions. | ||
""" | ||
parents = np.asarray(parents) | ||
|
||
elites = parents[0] | ||
directions = parents[1] - parents[0] | ||
|
||
iso_gaussian = self._rng.normal( | ||
scale=self._iso_sigma, | ||
size=(elites.shape[0], elites.shape[1]), | ||
).astype(elites.dtype) | ||
|
||
line_gaussian = self._rng.normal( | ||
scale=self._line_sigma, | ||
size=(elites.shape[0], 1), | ||
).astype(elites.dtype) | ||
solution_batch = elites + iso_gaussian + line_gaussian * directions | ||
|
||
return np.clip(solution_batch, self._lower_bounds, self._upper_bounds) |