ST Edge AI Core for MLC
for MLC target, based on ST Edge AI Core Technology 2.2.0
Overview
The Machine Learning Core (MLC) is an AI engine integrated into a variety of STMicroelectronics MEMS sensors that can run multiple decision trees for classification tasks using motion data (accelerometer, gyroscope) or, depending on the device, even data coming from external sources (magnetometer, vertical analog front-end, etc.).
Once a new prediction is obtained from any of the configured decision trees, the MLC can trigger an interrupt to communicate the event to a MCU/MPU that can handle it accordingly.
For more information about MLC, please explore the dedicated page available on STMicroelectronics website: MEMS Sensors Ecosystem for Machine Learning.
Development flow
The flow for developing and validating AI solutions for MLC-compatible devices is composed of the following steps:
- Feature extraction: MLC feature computation from raw data logs.
- Model training: Decision tree training using extracted features.
- Sensor configuration: Generation of MLC sensor configuration.
- Performance analysis: Simulation of decision tree performance.
- Validation on target: Validation on target using ProfiMEMS evaluation board.
Feature extraction
To ensure a correct model training, the features comprising the training set must be aligned 1:1 to the MLC hardware. For this reason, ST Edge AI Core enables an extra generation step for automatically extracting the features from data logs acquired using ST MEMS software tools (for example, MEMS Studio, Unico GUI, Unicleo GUI).
This is done by providing a MLC device settings file containing the desired device settings needed for extracting the features (ODR, full-scale, etc.). An example can be found below:
{
"datalogs": [
{ "filename": "data/stationary.csv", "label": "stationary" },
{ "filename": "data/walking.csv", "label": "walking" },
{ "filename": "data/cycling.csv", "label": "cycling" },
{ "filename": "data/running.csv", "label": "running" },
"..."
],
"name": "LSM6DSV16X",
"mlc_odr": "30 Hz",
"input_type": "accelerometer_only",
"accelerometer_fs": "8 g",
"accelerometer_odr": "30 Hz",
"decision_tree_count": 1,
"window_length": 60,
"filters": [
{ "filter_id": "filter_1", "filter_type": "BP", "input": "Acc_V2", "a2": "-1.66", "a3": "0.81", "gain": "0.09" },
"..."
],
"features": [
{ "feature_name": "MEAN", "input": "Acc_V2", },
{ "feature_name": "MEAN", "input": "Acc_V2_filter_1" },
"..."
],
"features_output_filename": "features.arff"
}
For more information please follow the link to the dedicated article: MLC device settings.
By providing the settings to the generate
command,
ST Edge AI Core will extract all the features in the
.arff file format:
--target mlc --device lsm6dsv16x --settings mlc_settings.json --gen-type features $ stedgeai generate
Model training
After extracting the features, the data can now be loaded inside the ML framework of choice (Python, MATLAB, Weka, etc.) for model training. The following snippet of code shows how this can be achieved using Python:
# Import dependencies
import numpy as np
import pandas as pd
from scipy.io import arff
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_text
# Load labels and features from ARFF
= arff.loadarff("features.arff")
arff_data = pd.DataFrame(arff_data[0])
df = df.drop("class", axis=1).values.astype(np.float32)
X = np.array([LABELS.index(label.decode()) for label in df["class"]])
y = list(df.drop("class", axis=1).columns)
feature_names
# Split dataset into train set and test set
= train_test_split(X, y, stratify=y, test_size=0.3)
X_train, X_test, y_train, y_test
# Train decision tree classifer
= DecisionTreeClassifier(
clf =128,
max_depth="entropy",
criterion=1e-3,
min_impurity_decrease=1e-2,
ccp_alpha="balanced",
class_weight
)
clf.fit(X_train, y_train)
# Define utility function for weka format conversion
def convert_sklearn_to_weka(clf, feature_names):
= re.sub(r"\|--- ", r"", export_text(clf, feature_names=feature_names)).splitlines()
dt = []
new_dt = 1
line_idx while line_idx < len(dt):
= re.search(r"class: (\d+)$", dt[line_idx])
match if match is not None:
= LABELS[int(match.group(1))]
label f"{dt[line_idx - 1]}: {label}")
new_dt.append(+= 2
line_idx else:
- 1])
new_dt.append(dt[line_idx += 1
line_idx return "\n".join(new_dt)
# Export model to weka textual format
= convert_sklearn_to_weka(clf, feature_names)
dectree with open("dectree.txt", "w") as f:
f.write(dectree)
After training and saving the model(s), the user should have one or more decision tree files in the Weka format. An example can be found below:
F6_ENERGY_ACC_V2_FILTER_1 <= 7.86
| F5_ENERGY_ACC_V2 <= 62.14: stationary
| F5_ENERGY_ACC_V2 > 62.14
| | F11_PEAK_DETECTOR_ACC_V2 <= 31.00
| | | F5_ENERGY_ACC_V2 <= 83.12: stationary
| | | F5_ENERGY_ACC_V2 > 83.12: walking
| | F11_PEAK_DETECTOR_ACC_V2 > 31.00
| | | F11_PEAK_DETECTOR_ACC_V2 <= 37.50
| | | | F12_PEAK_DETECTOR_ACC_V2_FILTER_1 <= 17.50: stationary
| | | | F12_PEAK_DETECTOR_ACC_V2_FILTER_1 > 17.50: cycling
| | | F11_PEAK_DETECTOR_ACC_V2 > 37.50: cycling
F6_ENERGY_ACC_V2_FILTER_1 > 7.86
| F1_MEAN_ACC_V2 <= 2.92
| | F9_ZERO_CROSSING_ACC_V2 <= 43.00: walking
| | F9_ZERO_CROSSING_ACC_V2 > 43.00: cycling
| F1_MEAN_ACC_V2 > 2.92: running
Sensor configuration
A second, and final, generation step will now use the same MLC device settings file as before with additional fields to integrate one or more decision trees in the final sensor configuration. An example can be found below:
{
"dectree_features": [
"F1_MEAN_ACC_V2",
"F2_MEAN_ACC_V2_FILTER_1",
"..."
],
"dectrees": [
{
"filename": "dectree.txt",
"results": [
{ "label": "stationary", "value": 1 },
{ "label": "walking", "value": 4 },
{ "label": "cycling", "value": 8 },
{ "label": "running", "value": 12 },
],
"metaclassifier": [ 2, 2, 2, 2 ]
},
"..."
],
"config_output_filename": "mlc_conf.json"
}
For more information please follow the link to the dedicated article: MLC device settings.
By running the generate
command again, now with the
updated settings, we can generate the sensor configuration in the
.json file format:
--target mlc --device lsm6dsv16x --settings mlc_settings.json --gen-type config $ stedgeai generate
A C header file and a minimal header file (.h) containing the same configuration are also generated in the output folder to allow for the integration inside the firmware of the MCU/MPU used for setting up the sensor at runtime.
Performance analysis
By using the analyze
command, ST Edge AI
Core can execute the MLC logic offline by inputting features
(extracted previously using the generate command) inside a
given decision tree with an optional metaclassifier stage
to obtain the final predictions:
--target mlc --device lsm6dsv16x --tree dectree.txt --arff features.arff --meta meta.txt $ stedgeai analyze
where meta.txt configures the metaclassifier stage by specifying rows with: class name, metaclassifier end counter, and metaclassifier subgroup. For example:
stationary 2 0
walking 2 1
running 2 2
cycling 2 3
For more information on the metaclassifier please refer to the MLC application note of the specific device, for example, the MLC application note for LSM6DSV16X sensor.
In addition to computing raw MLC prediction logs, a report summarizing decision tree information and the overall model performance is also generated:
ST Edge AI Core v2.1.0 (MLC 1.2.0)
Created date : YYYY-MM-DD hh:mm:ss
Parameters : analyze --target mlc --device lsm6dsv16x --tree dectree.txt --arff features.arff --meta meta.txt
Exec/report summary (analyze)
--------------------------------------------------------------------------------
target/series : mlc
device name : LSM6DSV16X
decision tree : /path/to/workspace/dectree.txt
arff features : /path/to/workspace/features.arff
metaclassifier : /path/to/workspace/meta.txt
output dir : /path/to/workspace/mlc_ai_output
--------------------------------------------------------------------------------
Running the simulation...
Features used:
F1_MEAN_ACC_V2
F5_ENERGY_ACC_V2
F6_ENERGY_ACC_V2_FILTER_1
F9_ZERO_CROSSING_ACC_V2
F11_PEAK_DETECTOR_ACC_V2
F12_PEAK_DETECTOR_ACC_V2_FILTER_1
Decision tree info:
Nodes : 17
Leaves : 9
Depth : 6
Results before meta-classifier:
Class "stationary" accuracy : 98.848053 %
recall : 98.504272 %
precision : 97.052635 %
Class "walking" accuracy : 99.012619 %
recall : 98.933899 %
precision : 97.274628 %
Class "cycling" accuracy : 99.122330 %
recall : 96.868011 %
precision : 99.540230 %
Class "running" accuracy : 99.725731 %
recall : 99.088837 %
precision : 99.770645 %
Global accuracy : 98.354362 %
stationary (T) walking (T) cycling (T) running (T)
stationary 461 4 10 0
walking 5 464 4 4
cycling 2 0 433 0
running 0 1 0 435
Results after meta-classifier:
Class "stationary" accuracy : 99.780342 %
recall : 100.000000 %
precision : 99.148933 %
Class "walking" accuracy : 99.615601 %
recall : 99.360344 %
precision : 99.148933 %
Class "cycling" accuracy : 99.615601 %
recall : 98.434006 %
precision : 100.000000 %
Class "running" accuracy : 99.450851 %
recall : 99.088837 %
precision : 98.639458 %
Global accuracy : 99.231186 %
stationary (T) walking (T) cycling (T) running (T)
stationary 466 3 1 0
walking 0 466 0 4
cycling 0 0 440 0
running 0 0 6 435
Validation on target
ST Edge AI Core also supports validation on target using the ProfiMEMS Evaluation Board (STEVAL-MKI109D or STEVAL-MKI109V3) and DIL24 adapters with the MLC-compatible sensor of choice, for example, the DIL24 adapter for LSM6DSV16X sensor.
Before using the ProfiMEMS board for MLC validation, the user must flash the firmware provided with MEMS Studio and insert the sensor adapter into the DIL24 slot. For flashing the board please follow the steps descibed in the user manual of MEMS Studio and/or of the ProfiMEMS board.
By connecting the board via USB to a PC, the
validate
command can be used for loading the sensor
configuration and inject any data log inside the sensor to obtain
MLC predictions:
--target mlc --device lsm6dsv16x --mlc-conf mlc_conf.json --logs testset.csv --ignore-zero $ stedgeai validate
Again, in addition to generating raw MLC prediction logs, a report summarizing the overall performance is also generated:
ST Edge AI Core v2.1.0 (MLC 1.2.0)
Created date : YYYY-MM-DD hh:mm:ss
Parameters : validate --target mlc --device lsm6dsv16x --mlc-conf mlc_conf.json --logs testset.csv --ignore-zero
Exec/report summary (validate)
--------------------------------------------------------------------------------
target/series : mlc
device name : LSM6DSV16X
config file : /path/to/workspace/mlc_conf.json
output dir : /path/to/workspace/mlc_ai_output
logs dir/file : /path/to/workspace/testset.csv
--------------------------------------------------------------------------------
Computing the metrics...
Accuracy report for decision tree 0
--------------------------------------------------------------------------------
notes: - computed against the provided ground truth values
- 5880 samples (4 items per sample)
- C0 may also indicates the initial state of DT0
acc: 100.00%, rmse: 0.0, mae: 0.0, l2r: 0.0, mean: 0.0, std: 0.0, nse: 1.0, cos: 1.0
4 classes (5880 samples)
----------------------------
C1 1620 . . .
C4 . 1440 . .
C8 . . 1560 .
C12 . . . 1260
acc : Classification accuracy (all classes)
rmse : Root Mean Squared Error
mae : Mean Absolute Error
l2r : L2 relative error
nse : Nash-Sutcliffe efficiency criteria
cos : Cosine similarity
Command line interface
$ stedgeai --target mlc --help
usage: st_ai.py [--target STR] [--output DIR] [--device DEVICE] [--gen-type {features,config}] [--settings FILE]
[--port COM] [--mlc-conf FILE] [--logs FILE | DIR] [--ignore-zero] [--tree FILE] [--arff FILE]
[--meta FILE] [--help] [--version] [--tools-version] [--verbosity [{0,1}]] [--no-report]
generate|validate|analyze
ST Edge AI Core v2.1.0 (MLC 1.2.0)
...
Command
Type of command to execute, must be specified first. Available commands for MLC target:
analyze
analyze MLC model performance by inputting extracted features into a given decision tree with metaclassifier stage to compute the predictions
validate
validate MLC sensor configuration on real-hardware by using data injection (requires ProfiMEMS board with sensor adapter)
generate
extract MLC features from data logs or generate MLC sensor configuration
Common options
--target
STR
target selector
-o
, --output
DIR
folder where the generated files are saved (default: mlc_ai_output)
-d
, --device
DEVICE
MLC-compatible device name, choose one from:
- ASM330LHB
- ASM330LHBG1
- ASM330LHHX
- ASM330LHHXG1
- IIS2DULPX
- IIS2ICLX
- ISM6HG256X
- ISM330BX
- ISM330DHCX
- LIS2DUX12
- LIS2DUXS12
- LSM6DSO32X
- LSM6DSOX
- LSM6DSRX
- LSM6DSV16BX
- LSM6DSV16X
- LSM6DSV32X
- LSM6DSV80X
- LSM6DSV320X
- ST1VAFE3BX
- ST1VAFE6AX
Specific generate options
-s
, --settings
FILE
generation settings JSON file
-g
, --gen-type
{‘config’,
‘features’}
generation output type
Specific validate options
-p
, --port
COM
serial port where ProfiMEMS board is connected (default: automatic discovery)
-mc
, --mlc-conf
FILE
sensor configuration file
-l
, --logs
FILE | DIR
single log file or directory containing log files
-z
, --ignore-zero
ignore label value ‘0’ in metrics computations
Specific analyze options
-t
, --tree
FILE
decision tree file in Weka format
-a
, --arff
FILE
ARFF file containing extracted features
-m
, --meta
FILE
loads a metaclassifier file where each row must specify:
- class name
- metaclassifier end counter
- metaclassifier subgroup
Additional options
-h
, --help
show this help message and exit
-V
, --version
print the version of the tool
--tools-version
print the versions of the third party packages used by the tool
-v
, --verbose
,
--verbosity
{0, 1}
set verbosity level
--no-report
do not generate the report file
Examples
.py analyze --target mlc --device lsm6dsv16x --tree dectree.txt --arff features.arff $ st_ai
.py validate --target mlc --device lsm6dsv16x --mlc-conf mlc_config.json --logs test_data.csv $ st_ai
.py generate --target mlc --device lsm6dsv16x --settings mlc_settings.json --gen-type features $ st_ai
.py generate --target mlc --device lsm6dsv16x --settings mlc_settings.json --gen-type config -o output_dir $ st_ai
Application examples
A curated list of configurations and examples ready to be used in all MLC-compatible sensors can be found at the following GitHub repository.