1. Getting started on PC (Linux/MacOS/Windows)
emlearn models work anywhere there is a C99 compiler available. This includes common desktop platforms such as Linux, Mac OS, Windows, etc. Since you need such a host platform to develop the Python machine-learning, it is convenient also to do the first tests of the model on the host.
1.1. Prerequisites
You need to have installed Python (version 3.6+), and a C99 compiler for your platform (GCC/Clang/MSVC).
On Windows, the Windows Subsystem for Linux (WSL) is recommended, but MSCV and cmd.exe/Powershell can also be used.
1.2. Install scikit-learn
In this example, scikit-learn is used to train the models.
pip install scikit-learn
1.3. Install emlearn
emlearn will be used to convert the scikit-learn models to C code.
pip install emlearn
1.4. Create model in Python
We will train a simple model to learn the XOR function.
The same steps will be used for model of any complexity.
Copy and save this as file xor_train.py
.
1import emlearn
2import numpy
3from sklearn.ensemble import RandomForestClassifier
4from sklearn.metrics import get_scorer
5
6# Generate simple dataset
7def make_xor(lower=0.0, upper=1.0, threshold=0.5, samples=100, seed=42):
8 rng = numpy.random.RandomState(seed)
9 X = rng.uniform(lower, upper, size=(samples, 2))
10 y = numpy.logical_xor(X[:, 0] > threshold, X[:, 1] > threshold)
11 return X, y
12
13X, y = make_xor()
14
15# Train a model
16estimator = RandomForestClassifier(n_estimators=3, max_depth=3, max_features=2, random_state=1)
17estimator.fit(X, y)
18score = get_scorer('f1')(estimator, X, y)
19assert score > 0.90, score # verify that we learned the function
20
21# Convert model using emlearn
22path = 'xor_model.h'
23cmodel = emlearn.convert(estimator, method='inline')
24cmodel.save(file=path, name='xor_model')
25print('Wrote model to', path)
Run the script
python xor_train.py
It will generate a file xor_model.h
containing the C code for our model.
1.5. Use in C code
To run our model we use a simple C program that takes data on the commandline, and prints out the detected class.
Copy and save this as file xor_host.c
.
1#include "xor_model.h" // emlearn generated model
2
3#include <stdio.h> // printf
4#include <stdlib.h> // stdod
5
6int
7main(int argc, const char *argv[])
8{
9 if (argc != 3) {
10 fprintf(stderr, "Wrong number of arguments. Usage: xor_model A-number B-number \n");
11 return -1;
12 }
13
14 const float a = strtod(argv[1], NULL);
15 const float b = strtod(argv[2], NULL);
16 const float features[] = { a, b };
17
18 int out = xor_model_predict(features, 2); // Alternative A: "inline"
19 out = eml_trees_predict(&xor_model, features, 2); // Alternative B: "loadable"
20 if (out < 0) {
21 return out; // error
22 } else {
23 printf("%d\n", out);
24 }
25 return 0;
26}
On Linux / MacOS / WSL with GCC
export EMLEARN_INCLUDE_DIR=`python -c 'import emlearn; print(emlearn.includedir)'`
gcc -o xor_host xor_host.c -I${EMLEARN_INCLUDE_DIR}
On Windows with cmd.exe
python -c "import emlearn; print(emlearn.includedir)"
set EMLEARN_INCLUDE_DIR= output from above command
cl xor_host.c /I %EMLEARN_INCLUDE_DIR% /link /out:xor_host.exe
1.6. Try it out
In our training data input values above 0.5
is considered “true”.
So for the XOR function, if one and only one of the values is above 0.5
, should get class 1 as output - else class 0.
The following should output 1
./xor_host 0.6 0.0
./xor_host 0.1 0.7
The following should output 0
./xor_host 0.8 0.7
./xor_host 0.0 0.0
1.7. Next
Now you have the emlearn tool running on your system, and it can be used to convert the models that you are interested in.
You may be interested in trying it out on a hardware device. See for example Getting started on hardware (Arduino).