In this post, we'll cover the basic tutorial for training simple regression model with tensorflow lite for for Microcontrollers(TFLM). This post is the summary of youtube video "TinyML Book Screencast - Training the Hello World model", presented by peter warden.

- toc: true
- badges: true
- comments: true
- author: Chanseok Kang
- categories: [Python, Deep_Learning, Tensorflow-Keras, Tensorflow-Lite]
- image:

In [1]:

```
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
plt.rcParams['figure.figsize'] = (16, 10)
plt.rcParams['text.usetex'] = True
plt.rc('font', size=15)
```

TensorFlow Lite for Microcontrollers (TFLM for short) is designed to run machine learning models on microcontrollers and other devices with only few kilobytes of memory. For the purpose of deploying machine learning model on embedded devices, it is also called TinyML. As you know already, Tensorflow is one of commonly-used deep learning frameworks, and from version 2.x they offer some machine learning features for embedded systems via tensorflow lite. Unlike high performance mobile processor(like cortex-A series), Microcontroller (Cortex-M series or ESP32) has low power consumptions and it can deploy in various ways of customer products, like refrigerator, wash-machine and so on.

Google introduced several supported boards for test,

- Arduino Nano 33 BLE Sense (using Arduino IDE)
- SparkFun Edge (building directly from source)
- STM32F746 Discovery kit (using Mbed)
- Adafruit EdgeBadge (using Arduino IDE)
- Adafruit TensorFlow Lite for Microcontrollers Kit (using Arduino IDE)
- Adafruit Circuit Playground Bluefruit (using Arduino IDE)
- Espressif ESP32-DevKitC (using ESP IDF)
- Espressif ESP-EYE (using ESP IDF)

Here, we'll implement the simple regression model in **Sparkfun Edge**. Most of contents are covered in Pete Warden's screencast. More informations are included in his book.

Before beginning, it requires some hardwares and basic knowledges,

- hardware
- Sparkfun edge
- CH340c USB-c to UART converter
- Desktop PC for training model (or you can use google colab)

- Knowledge
- Python
- C/C++
- Basic knowledge related on OS

Actually, "Hello world" may be the first program we faced, since it can show simple interaction between human and computer. TinyML also has simple example of "Hello world". Instead of Printing, we will build a model to generate the sine wave. So maybe our hypothesis will be like this,

$$ \tilde{H(x)} = \sin(x) $$At first, we load the required packages,

In [7]:

```
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import math
plt.rcParams['figure.figsize'] = (16, 10)
plt.rc('font', size=15)
# define random seed for reproducibility
np.random.seed(1) # numpy seed
tf.random.set_seed(1) # tensorflow global random seed
```

In [8]:

```
print('Numpy: {}'.format(np.__version__))
print('Tensorflow: {}'.format(tf.__version__))
```

Numpy: 1.18.1 Tensorflow: 2.2.0

In [14]:

```
# Generate a uniformly distributed set of random numbers in the range from
# 0 to 2π, which covers a complete sine wave oscillation
X = np.random.uniform(
low=0, high=2*math.pi, size=10000).astype(np.float32)
# Shuffle the values to guarantee they're not in order
np.random.shuffle(X)
# Calculate the corresponding sine values
y = np.sin(X).astype(np.float32)
# Plot our data. The 'b.' argument tells the library to print blue dots.
plt.plot(X, y, 'b.')
plt.grid()
plt.show()
```

In [15]:

```
# Add a small random number to each y value
y += 0.1 * np.random.randn(*y.shape)
# Plot our data
plt.plot(X, y, 'b.')
plt.grid()
plt.show()
```

Through this, we expect that the model is approximated with sinusoid curve if it is well trained.

To use it for training, we are going to preprocess the data. We'll split it with following proportions,

- Train data: 60%
- Validation data: 20%
- Test data: 20%

In [18]:

```
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=1)
# Plot the data in each partition in different colors:
plt.plot(X_train, y_train, 'b.', label="Train")
plt.plot(X_val, y_val, 'y.', label="Validate")
plt.plot(X_test, y_test, 'r.', label="Test")
plt.legend()
plt.grid()
plt.show()
```

In [20]:

```
model = tf.keras.Sequential(name='sine')
model.add(tf.keras.layers.Dense(16, activation='relu', input_shape=(1, )))
model.add(tf.keras.layers.Dense(1))
model.summary()
```

In [22]:

```
model.compile(optimizer='adam', loss='mse', metrics=['accuracy', 'mae'])
```

Now, it's time to train the model.

In [24]:

```
history = model.fit(X_train, y_train, epochs=1000, batch_size=15, validation_data=(X_val, y_val), verbose=False)
```

In [25]:

```
# Draw a graph of the loss, which is the distance between
# the predicted and actual values during training and validation.
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(loss) + 1)
plt.plot(epochs, loss, 'g.', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
```

In [26]:

```
# Exclude the first few epochs so the graph is easier to read
SKIP = 50
plt.plot(epochs[SKIP:], loss[SKIP:], 'g.', label='Training loss')
plt.plot(epochs[SKIP:], val_loss[SKIP:], 'b.', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
```