Edge Impulse: Data Collection, Training, Deployment to MCU
How Edge Impulse's data collection, DSP, training, and EON/TFLite Micro deployment stages actually affect MCU accuracy, RAM, and latency budgets.
Contents & prerequisites
Building a TinyML application from scratch — collecting labeled data, choosing a model, quantizing, writing a CMSIS-NN or TFLite Micro inference wrapper, and profiling RAM/flash/latency on target — is a multi-week task even for an engineer fluent in both ML and embedded C. Edge Impulse compresses that pipeline into a managed workflow (browser UI + CLI + SDK) that still exports a plain C++ library, so the result is auditable and portable rather than a black box. Understanding what it automates, and what it can't, is what separates a fast prototype from a production model that actually fits the target MCU.
Pipeline Overview
Edge Impulse organizes a project into four stages, each with concrete artifacts:
- Data acquisition — sensor samples (accelerometer, audio, image) streamed from a device SDK, mobile phone, or uploaded CSV/WAV/JPEG, all timestamped and labeled.
- Impulse design (DSP + learning blocks) — a graph: raw signal → digital signal processing (DSP) block (e.g., spectral features, MFCC, image resize/normalize) → learning block (neural network, anomaly detection, classical classifier).
- Training — runs in EI's cloud (or locally via the CLI/Docker), producing a quantized and float model plus a confusion matrix and per-class F1/precision/recall.
- Deployment — exports a C++ library (or full firmware binary for supported boards) with the DSP code, the inference call, and a memory/latency profile for a chosen target (Cortex-M0+ to M7, ESP32, Linux, or with EON/TFLite Micro backends).
The key architectural point: DSP feature extraction and the neural network are compiled together into one deterministic C++ library. There is no Python runtime dependency at inference time — the exported code is what you build in your STM32CubeIDE, Zephyr, or bare-metal Makefile project.
Data Collection: What Actually Matters
For time-series (IMU, audio) and image projects, the dominant failure mode isn't model architecture — it's data collection procedure.
- Sampling rate must match the physical bandwidth of the signal. A hand-gesture accelerometer signal has most energy below ~15 Hz; sampling at 62.5 Hz or 100 Hz (common EI defaults) satisfies Nyquist with margin. Undersampling aliases motion into false features; oversampling wastes RAM/flash on redundant window data.
- Window length vs. label granularity. EI slices continuous streams into fixed windows (e.g., 1000 ms with 500 ms stride) that become one inference each. Window length must be ≥ the shortest complete instance of the gesture/keyword you're classifying, or the model sees truncated patterns.
- Class balance and negative/"noise" class. Every real deployment needs a negative class covering "nothing interesting happening" — ambient noise for KWS, idle motion for gesture recognition — sampled from the actual deployment environment, not a quiet studio. Skipping this is the single most common cause of high validation accuracy but poor field performance (train/deployment distribution mismatch).
- Device parity between collection and deployment. Collecting audio on a phone mic and deploying on a MEMS mic with different frequency response and gain shifts the input distribution the DSP block was tuned against. EI's device SDKs (for supported dev boards) close this gap by collecting directly on the target sensor.
Rule of thumb for a first pass: 3–5 minutes per class for gesture/motion work, 1–2 minutes per class (chopped into 1 s windows) for KWS, and a few hundred images per class for vision — then use EI's data explorer (a UMAP-style 2D feature projection) to visually check for label overlap or outliers before spending compute on training sweeps.
The DSP Block: Where Most of the Compute Budget Goes
For non-vision projects, the DSP block frequently costs more MCU cycles than the neural network itself, and it runs on every inference regardless of model size.
| DSP block | Typical use | Approx. cost driver |
|---|---|---|
| Spectral Analysis (FFT + band energies) | Vibration, generic motion | FFT size (e.g., 256-pt ≈ few thousand cycles on Cortex-M4) |
| MFCC / MFE | Keyword spotting, audio classification | Mel filterbank + log + DCT per frame, repeated per hop |
| Image (resize/normalize) | Vision (MobileNet-style) | Dominated by resize/crop, not normalization |
| Raw/flatten | Very short, low-noise signals | Near zero — pushes all learning onto the network |
EI reports estimated flash, RAM, and latency for the DSP block and the learning block separately in the "Impulse design" and "Performance calibration" tabs, targeted at a selectable MCU (e.g., Cortex-M4F @ 80 MHz). This is the number to check before committing to a feature set — a 512-point FFT at 100 Hz sample rate with a 1 s window and 50% overlap can dominate a power budget on a Cortex-M0+ even with a trivial classifier behind it.
Training and Quantization
Training runs a standard Keras/TensorFlow backend under the hood (visible and editable via the "expert mode" Keras script), producing:
- Float32 model — reference accuracy.
- INT8 quantized model — via post-training quantization (calibrated on a subset of validation data), the version normally deployed to MCU targets.
Expect a small but non-zero accuracy delta between float32 and INT8 (typically 0–2 percentage points on well-conditioned data; larger if activations have long tails not well-covered by the calibration set). EI's "Model testing" tab runs the quantized model against a held-out test set — always check this number, not just validation accuracy from training, since validation in the training tab can still reference the float model depending on configuration.
EON (Edge Optimized Neural) compiler, EI's alternative to stock TFLite Micro, compiles the network graph directly to C rather than interpreting a .tflite flatbuffer at runtime. Practical effect: EON typically cuts RAM by 25–55% versus TFLite Micro interpreter overhead (arena buffers, op resolver tables) for the same architecture and accuracy, at the cost of losing runtime graph flexibility (you can't swap models without recompiling firmware). For RAM-starved parts (<64 KB SRAM), this difference decides feasibility.
Worked Example: Keyword Spotting Budget Check
Target: Cortex-M4F, 256 KB flash / 64 KB RAM, single wake word + "noise" + "unknown" (3 classes), 1 s window, 16 kHz audio.
- DSP: MFCC, 40 ms frame / 20 ms hop → 49 frames × 13 coefficients = 637 features. EI reports ≈ 6 KB RAM, ~5 ms compute at 80 MHz for this block.
- Learning block: small DS-CNN, EON-compiled INT8. EI reports ≈ 22 KB flash, ≈ 15 KB peak RAM, ~8 ms inference at 80 MHz.
- Total per inference: ~13 ms compute, ~21 KB RAM peak (≈6 KB DSP + ≈15 KB NN, worst case if the two buffers are not reused; some EON builds share scratch space between blocks and land a few KB lower), well inside a 64 KB budget with room for RTOS stack and buffers.
- Duty cycle check: running one inference per 500 ms stride at 13 ms compute = 2.6% CPU load — leaves ample margin for BLE stack or sensor polling on the same core.
Verification: 637 raw MFCC floats at 4 bytes would be 2.5 KB if kept as float32; the ≈6 KB reported RAM includes FFT scratch buffers and frame history, which is the expected overhead — a useful sanity check when the reported number looks larger than the naive feature-size calculation.
Deployment Paths
| Method | Output | Best for |
|---|---|---|
| C++ library export | Static lib + headers, drop into existing firmware project | Custom RTOS/bootloader integration |
| Arduino library | .zip for Arduino IDE | Rapid prototyping on supported boards |
| Full firmware binary | Prebuilt .bin for a named dev board | Fastest demo, least flexibility |
| WebAssembly | Runs in browser for testing | Pre-hardware validation |
The C++ library is the one that matters for production: it exposes a single run_classifier() (or similar) call taking a raw feature buffer and returning per-class scores, with all DSP and NN code statically linked — no dynamic memory allocation required if configured for the static arena option, which matters for MISRA/functional-safety-constrained codebases.
Practical Implications and Limits
- Not a substitute for understanding the model. EI abstracts training loops, not the underlying bias/variance tradeoffs — a bad dataset still produces a bad model, just faster.
- Vendor lock at the DSP+model bundle level, not at the code level. Exported C++ is yours to maintain; but re-tuning DSP parameters later generally means going back through the EI UI/CLI, not hand-editing generated code.
- Best fit for supervised classification/regression/anomaly-detection on well-understood sensor modalities (IMU, audio, small images). Highly custom architectures or multi-sensor fusion pipelines often need the CLI's "bring your own model" (BYOM) path or a hand-rolled TFLite Micro/CMSIS-NN pipeline instead.
- Always validate on-device, not just in the Performance Calibration estimate. EI's cycle/RAM numbers are per-MCU-family estimates; confirm with an actual flashed build and a logic analyzer or cycle counter (DWT_CYCCNT on Cortex-M) before committing to a power budget.
Key Takeaways
- Edge Impulse automates data collection, DSP feature extraction, training, INT8 quantization, and C++ export into one pipeline, but exports plain, auditable code with no runtime Python dependency.
- Data collection procedure (sample rate, window length, negative class, device parity between collection and deployment) determines field accuracy far more than model architecture choice.
- The DSP block's compute/RAM cost often rivals or exceeds the neural network's — check the per-block resource estimate before finalizing a feature set.
- Always evaluate the quantized INT8 model on a held-out test set, not the float32 validation accuracy from the training tab.
- The EON compiler trades runtime flexibility for a large (25–55%) RAM reduction versus a TFLite Micro interpreter — decisive for MCUs with <64 KB SRAM.
- Treat Performance Calibration numbers as estimates; confirm final RAM/flash/latency with an on-device build before locking a power or memory budget.
Learning
Sign in to track your progress.
Evidence
Public projects engineers linked to Edge Impulse: Data Collection, Training, Deployment to MCU.
No engineer has linked a project to this topic yet. Built something that proves it? Add the project and tag it with embedded-systems-edge-impulse-data-collection-training-deployment-t — it then shows here and on your public profile.
