• Stars
    star
    102
  • Rank 334,386 (Top 7 %)
  • Language
    Jupyter Notebook
  • Created over 4 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

TinyML example showing how to do anomaly detection with Python and Arduino

TinyML Example: Anomaly Detection

This project is an example demonstrating how to use Python to train two different machine learning models to detect anomalies in an electric motor. The first model relies on the classic machine learning technique of Mahalanobis distance. The second model is an autoencoder neural network created with TensorFlow and Keras.

Data was captured using an ESP32 and MSA301 3-axis accelerometer taped to a ceiling fan. Each sample is about 200 samples of all 3 axes captured over the course of 1 second. Fan was run at multiple speeds (off, low, medium, high) with and without a weight. 1 "weight" is one US quarter taped to one of the fan's blades to create an offset motion. All raw data is stored in the ceiling-fan-dataset directory.

Note that if you create a "robust" model by moving the fan around during data collection, the Autoencoder works much better than the Mahalanobis Distance method.

The full articles that explain how these programs work and how to use them can be found here:

Here are the accompanying YouTube videos that explain how to use these programs and some of the theory behind them:

ESP32 on ceiling fan for anomaly detection

Prerequisites

You will need to install TensorFlow, Keras, and Jupyter Notebook on your desktop or laptop. This guide will walk you through that process.

Alternatively, you can use Google Colab to run a Jupyter Notebook instance in the cloud, however, loading files (e.g. training samples) will require you to upload them to Google Drive and write different code to import them into your program. This guide offers some tips on how to do that.

If you plan to collect data yourself, you will need an Adafruit Feather Huzzah32, Adafruit MSA301 accelerometer breakout board, battery, breadboard, and jumper wires.

For deployment, you will want to install TensorFlow Lite on your Raspberry Pi by following these instructions. For Arduino, you will want to install the TensorFlow Lite for Microcontrollers Arduino library.

Hardware

For this project, you will need the following:

You can use whatever breadboard, jumper wires, and battery you want to connect everything together.

Getting Started

Please read the tutorials above for full documentation on how to use the scripts found in this project.

In general, you will want to perform the following steps:

  1. Collect data samples
  2. Analyze data for good features
  3. Train one or more machine learning models
  4. Convert models for deployment
  5. Deploy machine learning model to end system

Collect Data

Download this repository. Connect an MSA301 accelerometer breakout board to the ESP32 Feather. Open the data_collection/esp32_accel_post/esp32_accel_post.ino Arduino sketch and change the WiFi SSID, password, and server IP address. Upload to your ESP32. Place your ESP32 and accelerometer on the system you wish to monitor (e.g. ceiling fan).

Run data_collection/http_accel_server.py on your server computer to collect data. Repeat this process for however many normal and anomaly states you wish to collect data from. I recommend at least 200 sample files per state.

See the Collecting Your Own Data section below for more information on how to use the server script.

Analyze Data

Open data_collection/anomaly-detection-feature-analysis in Jupyter Notebook and run it. Change the dataset_path to point to wherever you collected your sample files. Change the op_lists to be the names of the directories in that dataset path. Note that by default, the dataset path is set to datasets/ in this repository. You are welcome to use my collected data (although it might not be indicative of your particular system).

Carefully look at the various plots to determine which features can be used to best discriminate between normal and anomalous operation.

Train Machine Learning Models

You have two options for detecting anomalies: Mahalanobis Distance, which is a more classical machine learning method, and Autoencoder, which is a neural network.

Open mahalanobis_distance/anomaly-detection-training-mahalanobis-distance.ipynb with Jupyter Notebook to train the Mahalanobis Distance model. Change the datasets variables to point to your normal and anomaly samples. The model is the mean and covariance matrix of the normal dataset's median absolute deviation (MAD). It should be saved as a .npz file (you can find mine stored in mahalanobis_distance/models).

For the Autoencoder, open autoencoder/anomaly-detection-training-autoencoder.ipynb. Change the datasets variables to point to your normal and anomaly samples. The model is a trained neural network. Note that you might need to create and train the model several times (initialized parameters are random) to get a good separation between normal and anomaly mean squared errors (MSEs). The model is saved as a .h5 Keras file (you can find my models in autonecoder/models).

Convert Models

If you are deploying the model(s) to a Raspberry Pi (or other single board computer), you can use the generated .npz file for the Mahalanobis Distance. For the Autoencoder, you will want to convert the .h5 file to a TensorFlow Lite (.tflite) file. The functions for converting the .h5 file to a .tflite file can be found in autoencoder/anomaly-detection-tflite-conversion.ipynb.

For use on a microcontroller, you will want to develop a set of C functions to calculate the MAD and Mahalanobis Distance or use TensorFlow Lite for Microcontrollers.

To generate constant arrays in C and header files, use the functions in utils/c_writer.py.

Converting the Mahalanobis Distance model to C can be done with mahalanobis_distance/anomaly-detection-md-conversion.ipynb. Note that this Notebook also saves a normal and anomaly sample as a C header file for use in testing.

Converting the Autoencoder model to C can be done with autoencoder/anomaly-detection-tflite-conversion.ipynb. This will generate a .tflite model file and then convert that file to a constant C array (inside of a .h header file).

You will need to copy the generated .h files (model, test samples, etc.) to your microcontroller project (i.e. in your Arduino sketch directory).

Deploy Models

If you wish to use your ESP32 remotely (i.e. it sends raw accelerometer data back to a server that performs inference), run the original data collection sketch on it. For your server, run mahalanobis_distance/http_server_anomaly_detection_md.py or autoencoder/http_server_anomaly_detection_tflite.py, depending on which model you want to use. Note that for the Autoencoder, you will want to install TensorFlow Lite on your server.

To use the model locally on your microcontroller (ESP32), you will want to use mahalanobis_distance/esp32_deploy_md for the Mahalanobis Distance or autoencoder/esp32_deploy_tflite for the Autoencoder. You will need to copy the respective model .h file generated in the previous step to the Arduino sketch's folder. Note that utils.h and utils.c (found in the utils directory) are also required, as they contain necessary C functions for computing MAD, matrix multiplication, etc.

By default, a piezo buzzer is to be connected to pin A1 of the ESP32 Feather board, which buzzes any time an anomaly is detected. Feel free to change this to whatever action you want to take to alert the user.

If you are curious, mahalanobis_distance/esp_test_md and autoencoder/esp32_test_tflite are used to test inference using the normal and anomaly samples generated earlier. You would want to use these files to check your C implementation against known good outputs in Python.

Collecting Your Own Data

If you wish to collect your own data, you will need to connect an MSA301 accelerometer to an ESP32 (I used the Adafruit Feather Huzzah32) via I2C. Open the data_collection/esp32_accel_post/esp32_accel_post.ino sketch and change the WiFi credentials and server IP address to match your computer's IP address. Upload the sketch to the ESP32.

Attach a battery to the ESP32 and secure it (using something like tape) to your electric motor (I used a ceiling fan).

Start data_collection/http_accel_server.py with the following arguments:

python http-accel-server.py -d <output directory where samples are stored> -p <port, such as 1337> -t <time to run server; something like 2400 seconds seems to work well>

You'll want to run the collection process for each operating mode of your motor. For a ceiling fan, that's off, low, medium, and high. It can also help to collect some "anomaly" data in a separate folder. For example, tape a coin to a ceiling fan blade and run the collection process again with all operating modes (except for "off").

To create a more "robust" model, I recommend slightly moving the fan's base around every minute or so during "normal" sample collection. See the 4th YouTube episode for more details.

License

All code in this repository, unless otherwise specified, is for demonstration purposes and licensed under Beerware.

Distributed as-is; no warranty is given.

More Repositories

1

introduction-to-rtos

C++
435
star
2

rpi-cm4-carrier-template

145
star
3

ei-keyword-spotting

C
144
star
4

introduction-to-fpga

Verilog
131
star
5

computer-vision-with-embedded-machine-learning

Jupyter Notebook
106
star
6

rpi-cm4-base-carrier

HTML
92
star
7

tflite-speech-recognition

Demo for training a convolutional neural network to classify words and deploy the model to a Raspberry Pi using TensorFlow Lite.
Jupyter Notebook
87
star
8

rpi-pico-debugger-shoe

HTML
61
star
9

phaser-plugin-virtual-gamepad

Phaser plugin that provides joystick and button overlay for mobile games written in JavaScript. Playable demo at:
JavaScript
49
star
10

fail-badges

A community collection of image (svg) files to celebrate failure!
JavaScript
45
star
11

ai-nose

Jupyter Notebook
11
star
12

openmv-lego-brick-finder

Python
11
star
13

lora-weather

C++
10
star
14

MICS-4514_CO_and_NOx_Sensor_Breakout

Breakout board for the MiCS-4514 CO and NOx gas sensor.
C++
9
star
15

tflite-keyword-spotting

C
8
star
16

HoverPong

Classic Pong using a 32x32 LED matrix and two ZX Sensors from XYZ Interactive.
C++
7
star
17

Electronics_Workbench

Designs for an electronics workbench made of wood.
Ruby
7
star
18

555_badge

6
star
19

EdiBot

Demos for the Edison-based rover platform.
Eagle
6
star
20

CarHUD

Simple DIY heads-up display for a car.
Eagle
6
star
21

wifi_maximizer

Arduino
5
star
22

tensorflow-object-detection

Project that uses TensorFlow to train an object detection neural network that can be used with the Raspberry Pi.
Python
5
star
23

c-unit-test

Makefile
5
star
24

DIY_Breathalyzer

Read BAC with MQ-3 and display on 7-Segment Shield
Arduino
5
star
25

wenk-sao

C
5
star
26

perfect-toast-machine

Jupyter Notebook
4
star
27

github-action-docker-test

Dockerfile
4
star
28

Vortex

A continuous, infinite shooter Tempest clone. The goal is to get the high score, and that's it. There is no end.
JavaScript
4
star
29

pendulum-pid

Jupyter Notebook
4
star
30

kicon19-blinky

C++
4
star
31

ei-workshop-image-data-augmentation

Jupyter Notebook
4
star
32

mk-hallway-leds

C
3
star
33

Hardware_Mouse_Jiggler

A tech prank that jiggles your mouse pointer every 10-20 seconds.
C++
3
star
34

pico-deployment-demo

CMake
2
star
35

shawnhymel.github.io

CSS
2
star
36

MICS-2614_O3_Sensor_Breakout

Breakout board for the MiCS-2614 O3 sensor.
Arduino
2
star
37

face-tracking-camera-openmv

Python
2
star
38

course-embedded-ml-capstone

C
2
star
39

myoken

Arduino project that buzzes whenever it's facing north.
C++
1
star
40

openmv-face-tracking

Python
1
star
41

neopixel-workshop

C++
1
star
42

Breadboard_Supply_5V

PCB design files for workshop.
Eagle
1
star
43

introduction-to-freecad

introduction-to-freecad
1
star
44

custom-speech-commands-dataset

1
star
45

SAMD11C_Mini_Breakout

1
star
46

reinforcement-learning-demos

Jupyter Notebook
1
star
47

M2X_CC3000

Example Arduino projects for communicating with AT&T's M2X service using a CC3000.
Arduino
1
star
48

xrp-object-detection

Python
1
star
49

google-coral-micro-object-detection

HTML
1
star
50

pendulum-rl

Jupyter Notebook
1
star
51

hopper-chat

Python
1
star
52

LearnScraper

JavaScript
1
star
53

serial-image-capture

C++
1
star
54

hex2c

Convert binary files and Python byte lists to C arrays
1
star
55

esp8266-temp-proto

C++
1
star
56

Getting_Started_With_RPi

Python code used in my "Getting Started With Raspberry Pi" video series.
Python
1
star
57

roshamglo_flashing_tool

Arduino
1
star
58

qwop-ai

Jupyter Notebook
1
star
59

Intar

Eagle
1
star
60

simple-recorderjs-projects

JavaScript
1
star
61

gaming-lap-desk

1
star