NanoEdge AI Library for n-class classification (nCC)

1. What is NanoEdge AI Library for n-class classification?

NanoEdge™ AI Library is an Artificial Intelligence (AI) static library for embedded C software running on Arm® Cortex® microcontrollers.

When embedded on microcontrollers, it gives them the ability to easily classify sensor patterns by themselves, without the need for the user to have additional skills in Mathematics, Machine Learning, or data science.

The NanoEdge AI static library for n-class classification is the code that contains an AI model designed to assign a signal to one of several predefined classes.

2. Install / Getting started

The main functions available via the library are:

neai_classification_init() run first before the classification process
neai_classification() run a classification iteration to identify the class of a signal

2.1. Static library

In NanoEdge AI Studio, after obtaining a library, click Compile on the "Deployment" screen.

The .zip file obtained contains:

  • libneai.a: the static precompiled NanoEdge AI library
  • NanoEdgeAI.h: the NanoEdge AI header file, with the function declarations and the library constants
  • emulators/: the NanoEdge AI Emulator (Python script nanoedgeai_studio_emulator.py and compiled libraries libneai.dll for Windows® and libneai.so for Linux®), see the NanoEdge AI Emulator page
  • metadata.json: library metadata (target, algorithm type, estimated RAM and flash usage, performance)
  • artifacts/: JSON files describing the model parameters and the preprocessing configuration and parameters
  • docs/: the documentation of the library in PDF format
  • for_llms.txt: an example prompt to give to an LLM, together with metadata.json and the JSON files of artifacts/, to get a complete Markdown description of the library (preprocessing, ML configuration and parameters)

To use the library, add libneai.a and NanoEdgeAI.h to your project, then link the static library to your project code. For example in STM32CubeIDE, go to Project -> Properties -> C/C++ Build -> Settings -> MCU GCC Linker -> Libraries. Add neai in the Libraries section and the libneai.a path in the Library search path section. Click Apply and Close.

2.2. NanoEdge AI Library functions

2.2.1. Initialization

enum neai_state neai_classification_init(void);

Initialization must be called at the beginning.

2.2.2. Classification

enum neai_state neai_classification(float *in, float *probabilities, int *id_class);

This function returns the probability vector and the detected class.

  • Input:
float *in, pointer to the input buffer, the length of the buffer is NEAI_INPUT_SIGNAL_LENGTH * NEAI_INPUT_AXIS_NUMBER
float *probabilities: pointer to the output probability vector, size NEAI_NUMBER_OF_CLASSES
int *id_class: pointer to the identifier of the detected class, in range [0, NEAI_NUMBER_OF_CLASSES - 1]
  • Output:
probability vector, with one probability per class
identifier of the detected class
the neai_state enum

Most NanoEdge AI functions return the status of the library in the following enum, neai_state:

enum neai_state {
    NEAI_OK = 0,
    NEAI_ERROR = 1,
    NEAI_NOT_INITIALIZED = 2,
    NEAI_INVALID_PARAM = 3,
    NEAI_NOT_SUPPORTED = 4,
    NEAI_LEARNING_DONE = 5,
    NEAI_LEARNING_IN_PROGRESS = 6
};

Here are the possible statuses:

NEAI_OK: library working as expected
NEAI_ERROR: internal error with the library
NEAI_NOT_INITIALIZED: classification function was called without running the init function first
NEAI_INVALID_PARAM: neai function was called with one or more incorrect or missing parameters
NEAI_NOT_SUPPORTED: board not supported
NEAI_LEARNING_DONE: minimum number of learning iterations reached
NEAI_LEARNING_IN_PROGRESS: fail-safe to prevent insufficient number of learning iterations
Information

Although they are present in all NanoEdge AI header files, the NEAI_LEARNING_DONE and NEAI_LEARNING_IN_PROGRESS statuses are only relevant for anomaly detection libraries.

2.3. Example "Hello World!"

Header file: NanoEdgeAI.h

NanoEdgeAI.h is provided in the .zip file that you download by clicking Compile in NanoEdge AI Studio. It declares the following elements:

This snippet is provided AS IS, and by taking it, you agree to be bound to the license terms that can be found here for the component: Application.


#ifndef NANOEDGEAI_H
#define NANOEDGEAI_H

#include <stdint.h>
#include <stdbool.h>

/* NEAI ID */
#define NEAI_ID "None"

/* Input signal configuration */
#define NEAI_INPUT_SIGNAL_LENGTH 256
#define NEAI_INPUT_AXIS_NUMBER 3
#define NEAI_NUMBER_OF_CLASSES 3

/* NEAI State Enum */
enum neai_state {
    NEAI_OK = 0,
    NEAI_ERROR = 1,
    NEAI_NOT_INITIALIZED = 2,
    NEAI_INVALID_PARAM = 3,
    NEAI_NOT_SUPPORTED = 4,
    NEAI_LEARNING_DONE = 5,
    NEAI_LEARNING_IN_PROGRESS = 6
};

#ifdef __cplusplus
extern "C" {
#endif

/* ===== Classification API ===== */
enum neai_state neai_classification_init(void);
enum neai_state neai_classification(float *in, float *probabilities, int *id_class);

/* ===== Common getter functions ===== */
char* neai_get_id(void);
int neai_get_input_signal_size(void);
int neai_get_axis_number(void);

/* =====  Specific classification getter functions ===== */
int neai_get_number_of_classes(void);
const char* neai_get_class_name(int id_class);


#ifdef __cplusplus
}
#endif

#endif /* NANOEDGEAI_H */

Main program: main.c

This program must be completed by the user (depending for instance on the application or the desired features).

This snippet is provided AS IS, and by taking it, you agree to be bound to the license terms that can be found here for the component: Application.


/* Includes ------------------------------------------------------------------*/
#include "NanoEdgeAI.h"

float input_signal[NEAI_INPUT_SIGNAL_LENGTH * NEAI_INPUT_AXIS_NUMBER];
float output_class_buffer[NEAI_NUMBER_OF_CLASSES];

/*
 * @brief Collect data process
 *
 * This function is defined by user, depends on applications and sensors
 *
 * @param input_signal: [in, out] buffer of sample values
 * @note   If NEAI_INPUT_AXIS_NUMBER = 3 (cf NanoEdgeAI.h), the buffer must be
 *         ordered as follows:
 *         [x0 y0 z0 x1 y1 z1 ... xn yn zn], where xi, yi and zi
 *         are the values for x, y and z axes, n is equal to
 *         NEAI_INPUT_SIGNAL_LENGTH (cf NanoEdgeAI.h)
 */
void fill_buffer(float *input_signal)
{
    /* USER BEGIN */
    /* USER END */
}

int main(void)
{
    /* Initialization ------------------------------------------------------------*/
    enum neai_state error_code = neai_classification_init();

    if (error_code != NEAI_OK) {
        /* Check the returned error code (cf NanoEdgeAI.h). */
    }

    /* Classification ------------------------------------------------------------*/
    int class_id = 0;
    while (1) {
        fill_buffer(input_signal);
        neai_classification(input_signal, output_class_buffer, &class_id);
        /* USER BEGIN */
        /*
         * e.g.: Trigger functions depending on class_id
         * (print output class probabilities using output_class_buffer[class_id],
         * print the name of the associated class, blink LED, ring alarm, etc.).
         */
        /* USER END */
    }
}

The class name can be retrieved with the getter function neai_get_class_name.