]
emlearn
Machine learning for microcontroller and embedded systems. Train in Python, then do inference on any device with a C99 compiler.
Status
Actively maintained since 2018.
License
emlearn is MIT licensed.
Key features
Convert machine learning models to C
- Supports models made with scikit-learn and Keras
- Supports classification, regression and anomaly/outlier detection
- Supports tree-based ensembles, such as Random Forest, decision trees
- Supports simple neural networks, such as Multi-Layer Perceptron (MLP)
Embedded-friendly Inference
- Portable C99 code
- No dynamic allocations
- Small code size (from 2kB FLASH)
- Small RAM size (from 50 bytes RAM)
- Support integer/fixed-point math (some models)
- No libc required (some models)
Easy to integrate in project
- Single header file to include
- Easy to embed/integrate in other languages, via C API
- Packaged as Arduino library
- Packaged as Zephyr module
- MicroPython bindings via emlearn-micropython
Feature extraction and data processing utilities
- Infinite Impulse Response (IIR) filters
- Fast Fourier Transform (FFT)
- Read/write CSV files, with streaming support
Model validation tools
- Access generated C classifier via Python, to verify prediction correctness
- Estimate model computational cost and size (using scikit-learn compatible metrics). Example.
- Measure tools for model program/FLASH size. Example.
Platform support
Should work anywhere that has working C99 compiler. Tested running on a large range of bare-metal, RTOS and desktop operating systems. Such as ESP8266, ESP32, AVR Atmega (8 bit), ARM Cortex M (STM32), Linux, Mac OS and Windows.
Projects using emlearn
emlearn has been used in many projects by many different developers, across a range of usecases and applications. See the Made with emlearn section in documentation.
Model support
Classification:
eml_trees: sklearn.RandomForestClassifier, sklearn.ExtraTreesClassifier, sklearn.DecisionTreeClassifiereml_net: sklearn.MultiLayerPerceptron, Keras.Sequential with fully-connected layerseml_bayes: sklearn.GaussianNaiveBayes
Regression:
eml_trees: sklearn.RandomForestRegressor, sklearn.ExtraTreesRegressor, sklearn.DecisionTreeRegressoreml_net: Keras.Sequential with fully-connected layers
Unsupervised / Outlier Detection / Anomaly Detection
eml_distance: sklearn.EllipticEnvelope (Mahalanobis distance)eml_mixture: sklearn.GaussianMixture, sklearn.BayesianGaussianMixture
Documentation
For full documentation see examples, the user guide.
Other learning resources
emlearn and emlearn-micropython has been covered in the following presentations.
- Microcontrollers + Machine Learning in 1-2-3 (PyData Global 2024). Slides etc
- Sensor data processing on microcontrollers with MicroPython and emlearn (PyConZA 2024). Slides etc
- 6 years of open source TinyML with emlearn - a scikit-learn for microcontrollers (TinyML EMEA 2024) YouTube video | Slides etc
- emlearn - Machine Learning for Tiny Embedded Systems (Embedded Online Conference 2024). Youtube video | Slides etc
- Machine Learning on microcontrollers using MicroPython and emlearn (PyCon DE & PyData Berlin 2024). Slides etc | YouTube video.
Installing
Install from PyPI
pip install --user emlearn
Usage
The basic usage consist of 3 steps:
- Train your model in Python
from sklearn.ensemble import RandomForestClassifier
estimator = RandomForestClassifier(n_estimators=10, max_depth=10)
estimator.fit(X_train, Y_train)
...
- Convert it to C code
import emlearn
cmodel = emlearn.convert(estimator, method='inline')
cmodel.save(file='sonar.h', name='sonar')
- 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.
Contributing
See docs/CONTRIBUTING.md for contribution guidelines, and docs/developing.md for how to develop.
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}
}
Metadata
Release files for emlearn 0.23.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| emlearn-0.23.2.tar.gz | 82.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| emlearn-0.23.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 160.7 kB
Release files / emlearn-0.23.2.tar.gz
| Download URL | emlearn-0.23.2.tar.gz |
|---|---|
| Size | 82.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bc18c156e571cb77344adeaa911a073e16dcb1f4f37239ede947ca665e0e08bc
|
|
BLAKE2b-256 checksum How to use checksums |
130c44519039bc9153df5bae4cee7ca81f53e8b9a05f1c7d465668430d10ced4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / emlearn-0.23.2-py3-none-any.whl
| Download URL | emlearn-0.23.2-py3-none-any.whl |
|---|---|
| Size | 78.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d50982a7b3808823c943d0858e1ce7862ae88d2009d2d548e951434e3c4774cd
|
|
BLAKE2b-256 checksum How to use checksums |
b49362f8ed58397cf68eb3b91cd330f274e2b12cff38f838bbf399366daf0875
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|