Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Use new Portfolio class #10

Open
wants to merge 31 commits into
base: portfolio_refactor
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3639e2f
[WIP] Use new Portfolio class
jrapin Apr 14, 2021
9cb9708
fix
jrapin Apr 14, 2021
4817b96
Merge branch 'portfolio_refactor' into portfolio_use
jrapin Apr 14, 2021
e595917
Merge branch 'portfolio_refactor' into portfolio_use
jrapin Apr 14, 2021
ecca034
fix
jrapin Apr 14, 2021
fe5c36a
fix
jrapin Apr 14, 2021
116b9b3
Check attribute outside init in CI (#1098)
jrapin Apr 15, 2021
5df0f3a
Update index page to use NGOpt (#1099)
jrapin Apr 16, 2021
7e86ab2
Change 1+1 to NGOpt throughout the documentation (#1100)
jrapin Apr 16, 2021
a534b35
Remove pointless print (#1096)
teytaud Apr 19, 2021
c090d77
Refactor CMA wrapper (#1102)
jrapin Apr 19, 2021
d80b482
Refactor recombination/mutation to use layers (experimental) (#1086)
jrapin Apr 20, 2021
7e447e4
Better random state initialization (#1106)
jrapin Apr 20, 2021
5a914cd
Remove progress bar in circleci install (#1108)
jrapin Apr 22, 2021
fe2beb5
Update mlda (#1109)
jrapin Apr 22, 2021
c4daab5
Lazily import mixsimylator + Use native numpy typing (#1110)
jrapin Apr 26, 2021
ccb0745
Record number of objectives (#1111)
jrapin Apr 26, 2021
351e8d6
Quickfix for logger of ConfiguredOptimizer (#1116)
jrapin May 7, 2021
2fb7d17
Update mixsimulator experiment (benchmark) (#1107)
TokyAxel May 12, 2021
3f21757
Ignore mypy for numpy sum axis (#1117)
jrapin May 12, 2021
ae1b9a3
Improving our one-shot optimization methods (#1103)
teytaud May 21, 2021
6fd743e
max num vars in collaborative coevolution (#1120)
teytaud May 21, 2021
97c9e36
New NgOpt (#1123)
teytaud May 21, 2021
bf0a927
Adding non-progressive NoisySplit (#1089)
teytaud May 21, 2021
308092c
Make Portfolio more generic (#1094)
jrapin May 21, 2021
f2ce076
merge
jrapin May 21, 2021
a1817e6
fixes
jrapin May 21, 2021
7360f3a
Simple new benchs (#1129)
teytaud May 25, 2021
dcc9df8
Merge branch 'master' into portfolio_use
jrapin Jun 2, 2021
c5c46ce
fix
jrapin Jun 2, 2021
782049d
fix
jrapin Jun 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,18 @@ commands:
- restore_cache:
name: "[all] Restore cache"
keys:
- v6-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}
- v7-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}
# fallback to installing main requirements
- v6-dependencies-main-{{ checksum "requirements/main.txt"}}
- v7-dependencies-main-{{ checksum "requirements/main.txt"}}

- run:
name: "[all] Install dependencies"
command: |
python3 -m venv venv
. venv/bin/activate
pip install -U pip
pip install -e .[all]
# master numpy-stubs adds a lot of messy warnings :s
pip install git+https://github.com/numpy/numpy-stubs@2c8d8f26adb1eef54571ccc85ef8ad4f2fb90c4c

pip install --progress-bar off pip==21.0.1 # TODO update after 21.1 which bugs
pip install --progress-bar off -e .[all]
pip install --progress-bar off -U numpy>=1.20.0

jobs:
install:
Expand All @@ -53,16 +51,16 @@ jobs:
- restore_cache:
name: "[no-extra] Restore cache"
keys:
- v6-dependencies-main-{{ checksum "requirements/main.txt"}}
- v7-dependencies-main-{{ checksum "requirements/main.txt"}}
# fallback to using the latest cache if no exact match is found

- run:
name: "[no-extra] Install dependencies"
command: |
python3 -m venv venv
. venv/bin/activate
pip install --upgrade pip
pip install -e .
pip install --progress-bar off pip==21.0.1
pip install --progress-bar off -e .

- run:
name: "[no-extra] Print installation"
Expand All @@ -80,7 +78,7 @@ jobs:
name: "[no-extra] Save cache"
paths:
- ./venv
key: v6-dependencies-main-{{ checksum "requirements/main.txt"}}
key: v7-dependencies-main-{{ checksum "requirements/main.txt"}}

- run:
name: "[no-extra] Run basic tests (checking dependencies)"
Expand All @@ -95,7 +93,7 @@ jobs:
name: "[all] Save cache"
paths:
- ./venv
key: v6-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}
key: v7-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}

- run:
name: "[all] Print installation"
Expand All @@ -118,7 +116,7 @@ jobs:
python3 -m venv test_wheel
. test_wheel/bin/activate
cd .. # don't use nevergrad locally
pip install repo/nevergrad-build/dist/nevergrad-*any.whl
pip install --progress-bar off repo/nevergrad-build/dist/nevergrad-*any.whl
python -c "from nevergrad import functions;f = functions.ArtificialFunction(name='sphere', block_dimension=2);f([2, 3])"

- persist_to_workspace:
Expand Down Expand Up @@ -172,7 +170,7 @@ jobs:
command: |
. venv/bin/activate
pylint --version
pylint nevergrad --disable=all --enable=unused-import,unused-argument,unused-variable,undefined-loop-variable,redefined-builtin,used-before-assignment,super-init-not-called,useless-super-delegation,dangerous-default-value,unnecessary-pass
pylint nevergrad --disable=all --enable=unused-import,unused-argument,unused-variable,undefined-loop-variable,redefined-builtin,used-before-assignment,super-init-not-called,useless-super-delegation,dangerous-default-value,unnecessary-pass,attribute-defined-outside-init

- run:
name: "Run black"
Expand Down Expand Up @@ -240,22 +238,22 @@ jobs:
- restore_cache:
name: "[all] Restore cache"
keys:
- v6-win-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}
- v7-win-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}

- run:
name: Setup nevergrad in virtualenv
command: |
py -3 -m venv venv
. ./venv/Scripts/activate
pip install -U pip
pip install torch==1.4.0+cpu torchvision==0.5.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
pip install .[all]
pip install --progress-bar off pip==21.0.1
pip install --progress-bar off torch==1.4.0+cpu torchvision==0.5.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
pip install --progress-bar off .[all]

- save_cache:
name: "[all] Save cache"
paths:
- ./venv
key: v6-win-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}
key: v7-win-dependencies-{{ checksum "requirements/dev.txt" }}-{{ checksum "requirements/main.txt"}}-{{ checksum "requirements/bench.txt"}}

- run:
name: pytest
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
- Half the budget alloted to solve cheap constrained is now used by a sub-optimizer
[#1047](https://github.com/facebookresearch/nevergrad/pull/1047). More changes of constraint management will land
in the near future.
- Experimental methods `Array.set_recombination` and `Array.set_mutation(custom=.)` are removed in favor of
layers changing `Array` behaviors [#1086](https://github.com/facebookresearch/nevergrad/pull/1086).
Caution: this is still very experimental (and undocumented).

### Important changes

Expand Down Expand Up @@ -56,6 +59,8 @@
- `EvolutionStrategy` now defaults to NSGA2 selection in the multiobjective case
- A new experimental callback adds an early stopping mechanism
[#1054](https://github.com/facebookresearch/nevergrad/pull/1054).
- `Choice`-like parameters now accept integers are inputs instead of a list, as a shortcut for `range(num)`
[#1106](https://github.com/facebookresearch/nevergrad/pull/1106).

## 0.4.3 (2021-01-28)

Expand Down
2 changes: 1 addition & 1 deletion docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Basic optimization example

**By default all optimizers assume a centered and reduced prior at the beginning of the optimization (i.e. 0 mean and unitary standard deviation).**

Optimizing (minimizing!) a function using an optimizer (here :code:`OnePlusOne`) can be easily run with:
Optimizing (minimizing!) a function using an optimizer (here :code:`NGOpt`, our adaptative optimization algorithm) can be easily run with:

.. literalinclude:: ../nevergrad/optimization/test_doc.py
:language: python
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ You can find other installation options (including for Windows users) in the :re

Feel free to join `Nevergrad users Facebook group <https://www.facebook.com/groups/nevergradusers/>`_.

Minimizing a function using an optimizer (here :code:`OnePlusOne`) can be easily run with:
Minimizing a function using an optimizer (here :code:`NGOpt`, our adaptative optimization algorithm) can be easily run with:

.. literalinclude:: ../nevergrad/optimization/test_doc.py
:language: python
Expand Down
4 changes: 2 additions & 2 deletions docs/optimization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ How to perform optimization
Basic example
-------------

Minimizing a function using an optimizer (here :code:`OnePlusOne`) can be easily run with:
Minimizing a function using an optimizer (here :code:`NGOpt`, our adaptative optimization algorithm) can be easily run with:

.. literalinclude:: ../nevergrad/optimization/test_doc.py
:language: python
Expand Down Expand Up @@ -80,7 +80,7 @@ Please make sure that your function returns a float, and that you indeed want to
Choosing an optimizer
---------------------

:code:`ng.optimizers.registry` is a :code:`dict` of all optimizers, so you :code:`ng.optimizers.OnePlusOne` is equivalent to :code:`ng.optimizers.registry["OnePlusOne"]`.
:code:`ng.optimizers.registry` is a :code:`dict` of all optimizers, so you :code:`ng.optimizers.NGOpt` is equivalent to :code:`ng.optimizers.registry["NGOpt"]`.
Also, **you can print the full list of optimizers** with:


Expand Down
5 changes: 3 additions & 2 deletions nevergrad/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
from .optimization import families as families
from .optimization import callbacks as callbacks
from .common import errors as errors
from . import ops as ops


__all__ = ["optimizers", "families", "callbacks", "p", "typing", "errors"]
__all__ = ["optimizers", "families", "callbacks", "p", "typing", "errors", "ops"]


__version__ = "0.4.3.post2"
__version__ = "0.4.3.post3"
83 changes: 69 additions & 14 deletions nevergrad/benchmark/experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,16 @@ def keras_tuning(


def mltuning(
seed: tp.Optional[int] = None, overfitter: bool = False, seq: bool = False
seed: tp.Optional[int] = None,
overfitter: bool = False,
seq: bool = False,
nano: bool = False,
) -> tp.Iterator[Experiment]:
"""Machine learning hyperparameter tuning experiment. Based on scikit models."""
seedg = create_seed_generator(seed)
optims: tp.List[str] = get_optimizers("basics", seed=next(seedg)) # type: ignore

if not seq:
optims = get_optimizers("oneshot", seed=next(seedg)) # type: ignore
for dimension in [None, 1, 2, 3]:
if dimension is None:
datasets = ["boston", "diabetes", "auto-mpg", "red-wine", "white-wine"]
Expand All @@ -119,7 +123,7 @@ def mltuning(
function = MLTuning(
regressor=regressor, data_dimension=dimension, dataset=dataset, overfitter=overfitter
)
for budget in [50, 150, 500]:
for budget in [50, 150, 500] if not nano else [20, 40, 80, 160]:
# Seq for sequential optimization experiments.
parallelization = [1, budget // 4] if seq else [budget]
for num_workers in parallelization:
Expand Down Expand Up @@ -152,13 +156,31 @@ def naive_seq_keras_tuning(seed: tp.Optional[int] = None) -> tp.Iterator[Experim
return keras_tuning(seed, overfitter=True, seq=True)


# We register only the sequential counterparts for the moment.
@registry.register
def oneshot_mltuning(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""One-shot counterpart of Scikit tuning."""
return mltuning(seed, overfitter=False, seq=False)


# We register only the (almost) sequential counterparts for the moment.
@registry.register
def seq_mltuning(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Sequential counterpart of mltuning."""
return mltuning(seed, overfitter=False, seq=True)


@registry.register
def nano_seq_mltuning(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Sequential counterpart of mltuning."""
return mltuning(seed, overfitter=False, seq=True, nano=True)


@registry.register
def nano_naive_seq_mltuning(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Sequential counterpart of mltuning with overfitting of valid loss, i.e. train/valid/valid instead of train/valid/test."""
return mltuning(seed, overfitter=True, seq=True, nano=True)


@registry.register
def naive_seq_mltuning(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Sequential counterpart of mltuning with overfitting of valid loss, i.e. train/valid/valid instead of train/valid/test."""
Expand Down Expand Up @@ -446,13 +468,16 @@ def oneshot(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
functions = [
ArtificialFunction(name, block_dimension=bd, useless_variables=bd * uv_factor)
for name in names
for bd in [3, 25]
for uv_factor in [0, 5]
for bd in [3, 10, 30, 100, 300, 1000, 3000]
for uv_factor in [0] # , 5]
]
for func in functions:
for optim in optims:
for budget in [30, 100, 3000]:
yield Experiment(func, optim, budget=budget, num_workers=budget, seed=next(seedg))
# if not any(x in str(optim) for x in ["Tune", "Large", "Cauchy"]):
# if "Meta" in str(optim):
for budget in [100000, 30, 100, 300, 1000, 3000, 10000]:
if func.dimension < 3000 or budget < 100000:
yield Experiment(func, optim, budget=budget, num_workers=budget, seed=next(seedg))


@registry.register
Expand Down Expand Up @@ -586,6 +611,8 @@ def yabbob(
hd: bool = False,
constraint_case: int = 0,
split: bool = False,
tiny: bool = False,
tuning: bool = False,
) -> tp.Iterator[Experiment]:
"""Yet Another Black-Box Optimization Benchmark.
Related to, but without special effort for exactly sticking to, the BBOB/COCO dataset.
Expand Down Expand Up @@ -628,14 +655,18 @@ def yabbob(
optims += ["OnePlusOne"]
optims += get_optimizers("splitters", seed=next(seedg)) # type: ignore

if hd and small:
optims = ["BO", "BOSplit", "CMA", "PSO", "DE"]
# List of objective functions.
functions = [
ArtificialFunction(name, block_dimension=d, rotation=rotation, noise_level=noise_level, split=split)
for name in names
for rotation in [True, False]
for num_blocks in ([1] if not split else [7, 12])
for d in ([100, 1000, 3000] if hd else [2, 10, 50])
for d in ([100, 1000, 3000] if hd else ([2, 5, 10, 15] if tuning else [2, 10, 50]))
]
if tiny:
functions = functions[::13]

# We possibly add constraints.
max_num_constraints = 4
Expand Down Expand Up @@ -668,6 +699,12 @@ def yabbob(
yield xp


@registry.register
def yahdlbbbob(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Counterpart of yabbob with HD and low budget."""
return yabbob(seed, hd=True, small=True)


@registry.register
def yanoisysplitbbob(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Counterpart of yabbob with more budget."""
Expand Down Expand Up @@ -712,6 +749,18 @@ def yahdsplitbbob(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
return yabbob(seed, hd=True, split=True)


@registry.register
def yatuningbbob(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Counterpart of yabbob with less budget."""
return yabbob(seed, parallel=False, big=False, small=True, tiny=True, tuning=True)


@registry.register
def yatinybbob(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Counterpart of yabbob with less budget."""
return yabbob(seed, parallel=False, big=False, small=True, tiny=True)


@registry.register
def yasmallbbob(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Counterpart of yabbob with less budget."""
Expand Down Expand Up @@ -1021,7 +1070,7 @@ def realworld(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
funcs += [
_mlda.SammonMapping.from_mlda("Virus", rescale=False),
_mlda.SammonMapping.from_mlda("Virus", rescale=True),
_mlda.SammonMapping.from_mlda("Employees"),
# _mlda.SammonMapping.from_mlda("Employees"),
]
funcs += [_mlda.Landscape(transform) for transform in [None, "square", "gaussian"]]

Expand Down Expand Up @@ -1061,15 +1110,15 @@ def realworld(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:


@registry.register
def rocket(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
def rocket(seed: tp.Optional[int] = None, seq: bool = False) -> tp.Iterator[Experiment]:
"""Rocket simulator. Maximize max altitude by choosing the thrust schedule, given a total thrust.
Budget 25, 50, ..., 1600.
Sequential or 30 workers."""
funcs = [Rocket(i) for i in range(17)]
seedg = create_seed_generator(seed)
optims = get_optimizers("basics", seed=next(seedg))
for budget in [25, 50, 100, 200, 400, 800, 1600]:
for num_workers in [1, 30]:
for num_workers in [1] if seq else [1, 30]:
if num_workers < budget:
for algo in optims:
for fu in funcs:
Expand All @@ -1079,6 +1128,12 @@ def rocket(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
yield xp


@registry.register
def mono_rocket(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""Sequential counterpart of the rocket problem."""
return rocket(seed, seq=True)


@registry.register
def mixsimulator(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
"""MixSimulator of power plants
Expand All @@ -1088,7 +1143,7 @@ def mixsimulator(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
seedg = create_seed_generator(seed)
optims: tp.List[str] = get_optimizers("basics", seed=next(seedg)) # type: ignore

seq = np.arange(0, 1601, 20)
seq = np.arange(0, 1601, 50)
for budget in seq:
for num_workers in [1, 30]:
if num_workers < budget:
Expand Down Expand Up @@ -1236,7 +1291,7 @@ def mlda(seed: tp.Optional[int] = None) -> tp.Iterator[Experiment]:
funcs += [
_mlda.SammonMapping.from_mlda("Virus", rescale=False),
_mlda.SammonMapping.from_mlda("Virus", rescale=True),
_mlda.SammonMapping.from_mlda("Employees"),
# _mlda.SammonMapping.from_mlda("Employees"),
]
funcs += [_mlda.Perceptron.from_mlda(name) for name in ["quadratic", "sine", "abs", "heaviside"]]
funcs += [_mlda.Landscape(transform) for transform in [None, "square", "gaussian"]]
Expand Down
4 changes: 4 additions & 0 deletions nevergrad/benchmark/test_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def test_experiments_registry(name: str, maker: tp.Callable[[], tp.Iterator[expe
if "_pgan" in name and os.environ.get("CIRCLECI", False):
raise SkipTest("Too slow in CircleCI")

# mixsimulator is not accepted by circleci pytest.
if "mixsimulator" in name and os.environ.get("CIRCLECI", False):
raise SkipTest("Sigkill in CircleCI")

# Our IQAs and our ScikitLearn are not well guaranteed on Windows.
if all(x in name for x in ["image", "quality"]) and platform.system() == "Windows":
raise SkipTest("Image quality not guaranteed on Windows.")
Expand Down
Loading