Limbo follows a `policy-based design <https://en.wikipedia.org/wiki/Policy-based_design>`_, which allows users to combine high flexibility (almost every part of Limbo can be substituted by a user-defined part) with high performance (the abstraction do not add any overhead, contrary to classic OOP design). These two features are critical for researchers who want to experiment new ideas in Bayesian optimization. This means that changing a part of limbo (e.g. changing the kernel functions) usually corresponds to changing a template parameter of the optimizer.
...
...
@@ -46,7 +46,7 @@ However, there is no need to inherit from a particular 'abstract' class.
Every class is parametrized by a :ref:`Params <params-guide>` class that contains all the parameters.
Sequence diagram
---------------
-----------------
.. figure:: pics/limbo_sequence_diagram.png
:alt: Sequence diagram
:target: _images/limbo_sequence_diagram.png
...
...
@@ -56,7 +56,7 @@ Sequence diagram
File Structure
--------------
---------------
(see below for a short explanation of the concepts)
.. highlight:: none
...
...
@@ -149,7 +149,7 @@ Template
}
Available initializers
^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^
.. doxygengroup:: init
:undoc-members:
...
...
@@ -272,7 +272,7 @@ Not all the algorithms support bounded optimization and/or initial point:
Available optimizers
^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^
.. doxygengroup:: opt
:undoc-members:
...
...
@@ -283,7 +283,7 @@ Default parameters
Models / Gaussian processes (model)
---------------
------------------------------------
Currently, Limbo only includes Gaussian processes as models. More may come in the future.
.. doxygenclass:: limbo::model::GP
...
...
@@ -304,7 +304,7 @@ Kernel functions (kernel)
.. _kernel-api:
Template
^^^^^^^^
^^^^^^^^^
.. code-block:: cpp
template <typename Params>
...
...
@@ -329,14 +329,14 @@ Default parameters
Mean functions (mean)
--------------------------
----------------------
.. _mean-api:
Mean functions capture the prior about the function to be optimized.
Template
^^^^^^^^
^^^^^^^^^
.. code-block:: cpp
...
...
@@ -353,7 +353,7 @@ Template
};
Available mean functions
^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^
.. doxygengroup:: mean
:members:
...
...
@@ -370,12 +370,12 @@ Internals
Stopping criteria (stop)
---------------------------------
-------------------------
Stopping criteria are used to stop the Bayesian optimizer algorithm.
Template
^^^^^^^^
^^^^^^^^^
.. code-block:: cpp
template <typename Params>
...
...
@@ -388,7 +388,7 @@ Template
};
Available stopping criteria
^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. doxygengroup:: stop
:members:
...
...
@@ -406,12 +406,12 @@ Internals
.. _statistics-stats:
Statistics (stats)
--------------------------
-------------------
Statistics are used to report informations about the current state of the algorithm (e.g., the best observation for each iteration). They are typically chained in a `boost::fusion::vector<>`.
file={Cully et al. - 2015 - Robots that can adapt like animals.pdf:/Users/jbm/Documents/zotero_bib/storage/WQ9SQZX3/Cully et al. - 2015 - Robots that can adapt like animals.pdf:application/pdf;Cully et al_2015_Robots that can adapt like animals.pdf:/Users/jbm/Documents/zotero_bib/storage/ADZPNDPM/Cully et al_2015_Robots that can adapt like animals.pdf:application/pdf}
}
@inproceedings{chatzilygeroudis2017,
TITLE={{Black-Box Data-efficient Policy Search for Robotics}},
AUTHOR={Chatzilygeroudis, Konstantinos and Rama, Roberto and Kaushik, Rituraj and Goepp, Dorian and Vassiliades, Vassilis and Mouret, Jean-Baptiste},
URL={https://hal.inria.fr/hal-01576683},
BOOKTITLE={{IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)}},
Limbo is a lightweight framework for Bayesian Optimization, a powerful approach for global optimization of expensive, non-convex functions. Github page (to report issues and/or help us to improve the library): `[Github repository] <http://github.com/resibots/limbo>`_
Limbo (LIbrary for Model-Based Optimization) is an open-source C++11 library for Gaussian Processes and data-efficient optimization (e.g., Bayesian optimization, see :cite:`b-brochu2010tutorial,b-Mockus2013`) that is designed to be both highly flexible and very fast. It can be used as a state-of-the-art optimization library or to experiment with novel algorithms with "plugin" components. Limbo is currently mostly used for data-efficient policy search in robot learning :cite:`b-lizotte2007automatic` and online adaptation because computation time matters when using the low-power embedded computers of robots. For example, Limbo was the key library to develop a new algorithm that allows a legged robot to learn a new gait after a mechanical damage in about 10-15 trials (2 minutes) :cite:`b-cully_robots_2015`, and a 4-DOF manipulator to learn neural networks policies for goal reaching in about 5 trials :cite:`b-chatzilygeroudis2017`.
The development of Limbo is funded by the `ERC project ResiBots <http://www.resibots.eu>`_.
The implementation of Limbo follows a policy-based design :cite:`b-alexandrescu2001modern` that leverages C++ templates: this allows it to be highly flexible without the cost induced by classic object-oriented designs (cost of virtual functions). `The regression benchmarks <http://www.resibots.eu/limbo/reg_benchmarks.html>`_ show that the query time of Limbo's Gaussian processes is several orders of magnitude better than the one of GPy (a state-of-the-art `Python library for Gaussian processes <https://sheffieldml.github.io/GPy/>`_) for a similar accuracy (the learning time highly depends on the optimization algorithm chosen to optimize the hyper-parameters). The `black-box optimization benchmarks <http://www.resibots.eu/limbo/bo_benchmarks.html>`_ demonstrate that Limbo is about 2 times faster than BayesOpt (a C++ library for data-efficient optimization, :cite:`b-martinezcantin14a`) for a similar accuracy and data-efficiency. In practice, changing one of the components of the algorithms in Limbo (e.g., changing the acquisition function) usually requires changing only a template definition in the source code. This design allows users to rapidly experiment and test new ideas while keeping the software as fast as specialized code.
Limbo shares many ideas with `Sferes2 <http://github.com/sferes2>`_, a similar framework for evolutionary computation.
Limbo takes advantage of multi-core architectures to parallelize the internal optimization processes (optimization of the acquisition function, optimization of the hyper-parameters of a Gaussian process) and it vectorizes many of the linear algebra operations (via the `Eigen 3 library <http://eigen.tuxfamily.org/>`_ and optional bindings to Intel's MKL).
The library is distributed under the `CeCILL-C license <http://www.cecill.info/index.en.html>`_ via a `Github repository <http://github.com/resibots/limbo>`_. The code is standard-compliant but it is currently mostly developed for GNU/Linux and Mac OS X with both the GCC and Clang compilers. New contributors can rely on a full API reference, while their developments are checked via a continuous integration platform (automatic unit-testing routines).
Main features
--------------
Limbo is currently used in the `ERC project ResiBots <http://www.resibots.eu>`_, which is focused on data-efficient trial-and-error learning for robot damage recovery, and in the `H2020 projet PAL <http://www.pal4u.eu/>`_, which uses social robots to help coping with diabetes. It has been instrumental in many scientific publications since 2015 :cite:`b-cully_robots_2015,b-chatzilygeroudis2018resetfree,b-tarapore2016,b-chatzilygeroudis2017,b-pautrat2018bayesian,b-chatzilygeroudis2018using`.
- Implementation of the classic algorithms (Bayesian optimization, many kernels, likelihood maximization, etc.)
- Modern C++-11
- Generic framework (template-based / policy-based design), which allows for easy customization, to test novel ideas
- Experimental framework that allows user to easily test variants of experiments, compare treatments, submit jobs to clusters (OAR scheduler), etc.
- High performance (in particular, Limbo can exploit multicore computers via Intel TBB and vectorize some operations via Eigen3)
- Purposely small to be easily maintained and quickly understood
Limbo shares many ideas with `Sferes2 <http://github.com/sferes2>`_, a similar framework for evolutionary computation.
If you are not familiar with the main concepts of Bayesian Optimization, a quick introduction is available :ref:`here <bayesian_optimization>`.
In this tutorial, we will explain how to create a new experiment in which a simple function ( :math:`-{(5 * x - 2.5)}^2 + 5`) is maximized.
Let's say we want to create an experiment called "myExp". The first thing to do is to create the folder ``exp/myExp`` under the limbo root. Then add two files:
...
...
@@ -22,6 +24,8 @@ Next, copy the following content to the ``wscript`` file:
.. code:: python
from waflib.Configure import conf
def options(opt):
pass
...
...
@@ -36,13 +40,19 @@ Next, copy the following content to the ``wscript`` file:
For this example, we will optimize a simple function: :math:`-{(5 * x - 2.5)}^2 + 5`, using all default values and settings. If you did not compile with libcmaes and/or nlopt, remove LIBCMAES and/or NLOPT from 'uselib'.
To begin, the ``main`` file has to include the necessary files, and declare the ``Parameter struct``:
To begin, the ``main`` file has to include the necessary files:
Here we are stating that the samples are observed without noise (which makes sense, because we are going to evaluate the function), that we want to output the stats (by setting stats_enabled to `true`), that the model has to be initialized with 10 samples (that will be selected randomly), and that the optimizer should run for 40 iterations. The rest of the values are taken from the defaults. **By default limbo optimizes in** :math:`[0,1]`, but you can optimize without bounds by setting ``BO_PARAM(bool, bounded, false)`` in ``bayes_opt_bobase`` parameters. If you do so, limbo outputs random numbers, wherever needed, sampled from a gaussian centered in zero with a standard deviation of :math:`10`, instead of uniform random numbers in :math:`[0,1]` (in the bounded case). Finally **limbo always maximizes**; this means that you have to update your objective function if you want to minimize.
...
...
@@ -64,16 +74,32 @@ With this, we can declare the main function:
:linenos:
:lines: 114-123
The full ``main.cpp`` can be found `here <../../src/tutorials/basic_example.cpp>`_
Finally, from the root of limbo, run a build command, with the additional switch ``--exp myExp``: ::
./waf build --exp myExp
Then, an executable named ``myExp`` should be produced under the folder ``build/exp/myExp``.
When running this executable, you should see something similar to this:
These lines show the result of each sample evaluation of the :math:`40` iterations (after the random initialization). In particular, we can see that algorithm progressively converges toward the maximum of the function (:math:`5`) and that the maximum found is located at :math:`x = 0.500014`.
Running the executable also created a folder with a name composed of YOUCOMPUTERHOSTNAME-DATE-HOUR-PID. This folder should contain two files: ::
limbo
|-- YOUCOMPUTERHOSTNAME-DATE-HOUR-PID
+-- samples.dat
+-- aggregated_observations.dat
The file ``samples.dat`` contains the coordinates of the samples that have been evaluated during each iteration, while the file ``aggregated_observations.dat`` contains the corresponding observed values.
If you want to display the different observations in a graph, you can use the python script ``print_aggregated_observations.py`` (located in ``limbo_root/src/tutorials``).
For instance, from the root of limbo you can run ::
The Debian/Unbuntu NLOpt package does NOT come with C++ bindings. Therefore you need to compile NLOpt yourself. The brew package (OSX) comes with C++ bindings (`brew install homebrew/science/nlopt`).
The Debian/Unbuntu NLOpt package does NOT come with C++ bindings. Therefore you need to compile NLOpt yourself. The brew package (OSX) comes with C++ bindings (`brew install nlopt`).
* `libcmaes <https://github.com/beniz/libcmaes>`_. We advise you to use our own `fork of libcmaes <https://github.com/resibots/libcmaes>`_ (branch **fix_flags_native**). Make sure that you install with **sudo** or configure the **LD_LIBRARY_PATH** accordingly. Be careful that gtest (which is a dependency of libcmaes) needs to be manually compiled **even if you install it with your package manager** (e.g. apt-get): ::