SGP Official store ↗
Blog / Projects / Machine learning

Wi-Fi CSI datasets and tools for machine learning

Turning Channel State Information into a working classifier is a pipeline: capture, clean, extract features, train. This is the honest toolchain — the tools that capture CSI, the kinds of public datasets to look for, the features that matter, and which models to try first. We name categories, not links you should verify yourself.

Published 20 Oct 2026Read 12 minLevel IntermediateTopic CSI + ML
The CSI machine-learning pipeline Capture ESP32 / tool Clean filter, baseline Features amp, stats Model SVM to CNN labels ride along the whole pipeline · garbage in, garbage out most of the work is capture and cleaning, not the model
FIG 1 — The model is the last and often smallest step. Good capture, honest labels and clean features decide whether CSI machine learning works at all.

Machine learning on Wi-Fi CSI is less about clever models and more about disciplined data. The classifier at the end is usually the easy part. The work that decides success is capturing clean CSI, cleaning it honestly, and turning it into features that actually describe what is happening in the room.

01The CSI machine-learning pipeline

Every CSI project, whether it recognises gestures or counts people, follows the same four steps: capture raw Channel State Information, clean it, extract features, and train a model. The diagram above is not decoration; it is the order you should spend your time in. Beginners reach for the deep network first and wonder why it fails. Experienced builders spend most of their effort on the first two boxes.

If you have not captured CSI before, read how to capture Wi-Fi CSI on an ESP32 first, and keep cleaning CSI data open for the second box. This article is about the whole toolchain and the choices that connect those steps into a working model.

02Tools to capture CSI

You can either capture your own CSI or use someone else's. For a project you control, capturing your own is almost always better, because you know the hardware, the room and the labels. A few families of tools exist:

Formats differEvery capture path reports CSI in its own layout: subcarrier count, how amplitude and phase are packed, and what metadata rides along. Before you merge or compare data from two sources, confirm the exact format of each. Treating two formats as the same is a classic silent bug.

03Public dataset types

Public CSI datasets exist and can save weeks, but their names, hosts and licences change over time, so this section describes categories rather than specific files. Do not trust a dataset name or URL quoted in any article, including this one — search current academic repositories and dataset indexes, then verify the link, licence and format yourself before you build on it.

The common categories you will find are:

Two cautions. First, a dataset captured on an Intel 5300 card will not match your ESP32 capture, so mixing sources needs care. Second, published accuracy figures are tied to the exact dataset, split and hardware they were measured on; treat any single number as specific to its paper, not a promise for your room.

04Feature engineering

Raw CSI is complex-valued: a real and imaginary part per subcarrier, per packet. The first job is to turn that into stable, meaningful numbers. Amplitude (the magnitude of each subcarrier) is the workhorse and is far easier to use than raw phase, which is corrupted by timing and frequency offsets and usually needs sanitisation first — see cleaning CSI data for why.

A simple, effective starting point is to compute amplitude per subcarrier and then summarise a short time window with basic statistics:

csi_features.py · amplitude and simple stats
# Minimal CSI feature extraction.
# csi: int8 array per packet, interleaved [imag, real] per subcarrier,
# shaped (packets, 2 * subcarriers) to match a common ESP32 layout.
import numpy as np

def amplitude(csi):
    imag = csi[:, 0::2]            # even bytes = imaginary
    real = csi[:, 1::2]            # odd bytes  = real
    return np.sqrt(real.astype("float32")**2
                   + imag.astype("float32")**2)

def window_features(csi_window):
    amp = amplitude(csi_window)   # (packets, subcarriers)
    return np.concatenate([
        amp.mean(axis=0),        # mean per subcarrier
        amp.std(axis=0),         # variability = motion energy
        [amp.std()],             # one overall motion number
    ])

From there, useful additions include the variance over time (a strong motion cue), a spectrogram of amplitude over a window (which exposes the slow breathing band and the faster rhythm of walking), and selecting the most informative subcarriers while dropping dead ones. Keep features interpretable at first; you will debug far faster when you can see what each number means.

05Models to try, in order

Resist the urge to start deep. A sensible ladder:

  1. Baselines first. Train a support vector machine or a random forest on your hand-built features. These are fast, run on a CPU, and give an honest floor. If they cannot tell two classes apart, a deep net probably will not rescue bad data.
  2. Convolutional networks (CNN). Treat a window of CSI, or its spectrogram, as an image and let a CNN learn spatial-frequency patterns. A good step up once features plateau and you have enough varied data.
  3. Recurrent networks (LSTM/GRU). CSI is a time series, so recurrent layers, or a CNN feeding an LSTM, capture how a gesture or activity evolves over time. Powerful, but hungrier for data and compute.

Always split your data so the test set contains people, rooms or days the model never trained on. A random split that mixes the same session into train and test will flatter you badly, because the model learns the room, not the activity.

06Pitfalls that fool you

Get the data right and modest models work well. Get it wrong and no architecture saves you. That is the honest heart of CSI machine learning: the pipeline, not the network, is where projects are won or lost.

07FAQ

Do I need a GPU to train on Wi-Fi CSI?

Not for the baselines. Classical models such as SVM and random forest on hand-built features train fine on a normal CPU. You only really want a GPU once you move to deep models like CNNs or LSTMs on raw or spectrogram inputs, where it saves a lot of time.

How much CSI data do I need to train a model?

More varied than large. A few hundred to a few thousand labelled examples per class can get a baseline working, but the bigger factor is variety: different people, rooms and days. A model trained in one room often fails in another, so breadth of conditions matters more than raw count.

Where can I find public Wi-Fi CSI datasets?

Several research groups and code repositories publish CSI datasets for activity, gesture and occupancy tasks, but names and links change over time. Search current academic repositories and dataset indexes, and verify any link, licence and format yourself before you rely on it, rather than trusting a URL quoted in an article.

Which model should I start with for CSI?

Start simple. Build clean features, then train an SVM or a random forest as a baseline. Only move to a CNN or LSTM once that baseline is honest and you have enough varied data, because a deep model on a tiny single-room dataset usually just memorises the room.

SGP Lab — written by the team that designs and builds SGP hardware in Europe. We test every example on our own boards before publishing.

SGP devices are sold only at our official store.

sgpstore.net ↗