emlearn / emlearn

Machine Learning inference engine for Microcontrollers and Embedded devices
MIT License
478 stars 54 forks source link
c classifier embedded-systems inference keras machine-learning microcontroller neural-networks python random-forest scikit-learn sklearn tensorflow tinyml

Tests DOI

emlearn

Machine learning for microcontroller and embedded systems. Train in Python, then do inference on any device with a C99 compiler.

emlearn logo

Status

Minimally useful. Used in dozens of projects by dozens of developers.

Key features

Embedded-friendly Inference

Convenient Training

MIT licensed

Supporting libraries

Can be used as an open source alternative to MATLAB Classification Trees, Decision Trees using MATLAB Coder for C/C++ code generation. fitctree, fitcensemble, TreeBagger, ClassificationEnsemble, CompactTreeBagger

Model support

Classification:

Regression:

Unsupervised / Outlier Detection / Anomaly Detection

Feature extraction:

Platform support

Tested running on AVR Atmega, ESP8266, ESP32, ARM Cortex M (STM32), Linux, Mac OS and Windows.

Should work anywhere that has working C99 compiler.

Installing

Install from PyPI

pip install --user emlearn

Usage

The basic usage consist of 3 steps:

  1. Train your model in Python
from sklearn.ensemble import RandomForestClassifier
estimator = RandomForestClassifier(n_estimators=10, max_depth=10)
estimator.fit(X_train, Y_train)
...
  1. Convert it to C code

    import emlearn
    cmodel = emlearn.convert(estimator, method='inline')
    cmodel.save(file='sonar.h', name='sonar')
  2. Use the C code

Simple classifiers

#include "sonar.h"

const int32_t length = 60;
int16_t values[length] = { ... };

// using generated "inline" code for the decision forest
const int32_t predicted_class = sonar_predict(values, length):

// ALT: using the generated decision forest datastructure
const int32_t predicted_class = eml_trees_predict(&sonar, length):

Neural net regressor

Copy the generated .h file, the eml_net.h and eml_common.h into your project, then

#include "nnmodel.h" // the generated code basedon on keras.Sequential

float values[6] = { ... };

const float_t predicted_value = nnmodel_regress1(values, 6);
if (predicted_value == NAN) {
    exit(-1);
}
// Process the value as needed

// Or, passing in a result array directly if more than 1 output is generated
float out[2];
EmlError err = nnmodel_regress(values, 6, out, 2);
if (err != EmlOk)
{
    // something went wrong
}
else {
    // predictions are in the out array
}

For a complete runnable code see Getting Started.

For full documentation see examples, the user guide.

Contributing

Check out the source code, make sure you install the Unity submodule as well with git submodule update --init

Before committing any code, run the tests by ./test.sh and install the module locally with pip install ./ -v

Contributors

Jon Nordby
Mark Cooke

Citations

If you use emlearn in an academic work, please reference it using:

@misc{emlearn,
  author       = {Nordby, Jon AND Cooke, Mark AND Horvath, Adam},
  title        = {{emlearn: Machine Learning inference engine for 
                   Microcontrollers and Embedded Devices}},
  month        = mar,
  year         = 2019,
  doi          = {10.5281/zenodo.2589394},
  url          = {https://doi.org/10.5281/zenodo.2589394}
}

Made with emlearn

emlearn has been used in the following works (among others).

If you are using emlearn, let us know! You can for example submit a pull request for inclusion in this README, or create an issue on Github.