2. Getting started on device (ESP32/RP2/STM32/etc)

emlearn-micropython runs on most hardware platforms that MicroPython does.

2.1. Prerequisites

Ensure that you have Python and emlearn setup as per the Getting started on PC (Linux/MacOS/Windows).

Ensure that you have MicroPython flashed onto your device. Check the Download section for MicroPython.

2.2. Install mpremote

mpremote is used to run scripts and copy files to/from a hardware device running MicroPython.

pip install mpremote

2.3. Install emlearn-micropython modules

emlearn-micropython is distributed as a set of MicroPython native modules. These are .mpy file with native code, that can be installed at runtime using mip. This example uses the emlearn_trees module, so that is what we will install.

For ESP32 use the xtensawin architecture.

mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/latest/xtensawin_6.3/emlearn_trees.mpy

For ARM Cortex M4F/M33/M7 etc use the armv7emsp architecture.

mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/latest/armv7emsp_6.3/emlearn_trees.mpy

For more details about architectures for native modules, see MicroPython mpyfiles documentation

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

 1# python/host code
 2
 3import emlearn
 4from emlearn.preprocessing import Quantizer
 5import numpy
 6from sklearn.ensemble import RandomForestClassifier
 7from sklearn.metrics import get_scorer
 8
 9# Generate simple dataset
10def make_xor(lower=0.0, upper=1.0, threshold=0.5, samples=100, seed=42):
11    rng = numpy.random.RandomState(seed)
12    X = rng.uniform(lower, upper, size=(samples, 2))
13    y = numpy.logical_xor(X[:, 0] > threshold, X[:, 1] > threshold)
14    X = Quantizer(max_value=1.0).fit_transform(X) # convert to int16
15    return X, y
16
17X, y = make_xor()
18
19# Train a model
20estimator = RandomForestClassifier(n_estimators=3, max_depth=3, max_features=2, random_state=1)
21estimator.fit(X, y)
22score = get_scorer('f1')(estimator, X, y)
23assert score > 0.90, score # verify that we learned the function
24
25# Convert model using emlearn
26cmodel = emlearn.convert(estimator, method='inline')
27
28# Save as loadable .csv file
29path = 'xor_model.csv'
30cmodel.save(file=path, name='xor', format='csv')
31print('Wrote model to', path)

Run the script

python xor_train.py

It will generate a file xor_model.csv containing the C code for our model.

2.5. Use in MicroPython code

To run our model we use a simple MicroPython program.

Copy and save this as file xor_run.py.

 1# device/micropython code
 2
 3import emlearn_trees
 4import array
 5
 6model = emlearn_trees.new(5, 30, 2)
 7
 8# Load a CSV file with the model
 9with open('xor_model.csv', 'r') as f:
10    emlearn_trees.load_model(model, f)
11
12# run it
13max_val = (2**15-1) # 1.0 as int16
14examples = [
15    array.array('h', [0, 0]),
16    array.array('h', [max_val, max_val]),
17    array.array('h', [0, max_val]),
18    array.array('h', [max_val, 0]),
19]
20
21out = array.array('f', range(model.outputs()))
22for ex in examples:
23    model.predict(ex, out)
24    result = out[1] > 0.5
25    print(list(ex), '->', list(out), ':', result)
26

2.6. Try it out

In our training data input values above 2**14 is considered “true”. So for the XOR function, if one and only one of the values is above this limit, should get class 1 as output - else class 0.

Run the program on device using mpremote run:

mpremote run xor_host.py

The output should be something like:

[0, 0] -> [1.0, 0.0] : False
[32767, 32767] -> [0.666, 0.333] : False
[0, 32767] -> [0.0, 1.0] : True
[32767, 0] -> [0.0, 1.0] : True

2.7. Next

Now you have the emlearn-micropython on running hardware. For information on practical usecases, see Examples. Otherwise check out API reference.