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).