A collection of simple incremental forward and inverse model learning algorithms

learning, algorithm
pip install learners==1.0.4



A small library for incremental learning of forward and inverse models, compatible with the environments module.

This code was designed and written to conduct scientific experiments. It is probably not fit for any other purpose, and certainly not for production environments. In particular, its maintenance and development depend on the direction of future research. That being said, do not hesitate to submit issues or contact me by mail for questions and comments.

Install & fastlearners

Install through pip:

pip install learners

This library is pure-python, but C++ implementations of some expensive algorithms is available in the 'fastlearners' package. If installed, the learner package will automatically make use of it. Should that not be desired, learners should be imported as:

import learners

Conversely, in case of an error during the import of fastlearners, learners will silently revert to python implementations. This can be made explicit with the following call:

import learners

OpenScience License

This software is placed under the OpenScience license, which is the LGPL, with the additional condition that if you publish scientific results using this code, you have to publish the corresponding modifications of the code.

If you publicly release any scientific claims or data that were supported or generated by the Program or a modification thereof, in whole or in part, you will release any modifications you made to the Program. This License will be in effect for the modified program.


The learners module is organized around the notion of channels. A Channel has a name, describes a single scalar and can incorporate bounds. Here we describe three channels, x, y and a, with bounds [0, 10] for x and y and [0, 100] for a.

    import scicfg
    from learners import Channel, RandomLearner

    ch_x = Channel('x', [0, 10])
    ch_y = Channel('y', [0, 10])
    ch_a = Channel('a', [0, 100])

Then we create a learner that accept x and y as motor input, and learns their mapping to sensory channel a. We create the configuration and instantiate a RandomLearner instance, that returns a random prediction.

    cfg = {'m_channels': [ch_x, ch_y],
           's_channels': [ch_a]}

    learner = RandomLearner(cfg)

We can then update the learner with an observation, a pair of motor and sensory signal.

    learner.update({'x': 5, 'y': 4}, {'a': 9})

We can then ask the learner to predict the result of a motor signal.

    learner.predict({'x': 3, 'y': 4})


    {'a': 14.046620079802707}

Or infer the motor command that should produce a certain sensory output.

    learner.infer({'a': 3})


    {'x': 3.9660529699286418, 'y': 3.132155464083369}

Here the learner is returning random signal, and thus is particularly useless. Many different---and smarter---algorithms are available in the module.