Simple Logistic Regression in C/C++ (ESP32 Arduino) for Predicting Rain

Introduction

In the previous tutorial, we have built a simple logistic regression model for predicting rain. Now, in this tutorial, we will go through the basic steps of deploying the model in ESP32 Arduino. We are going to build the model from scratch in C. Then, we are going to use humidity value from DHT11 sensor as input for the model.

System Overview

The following figure shows the block diagram of this tutorial. We have got the ESP32 DevKit v1 board and the DHT11 temperature and humidity sensor. Then, we are going to use the serial communication to interact with the ESP32 from our development host.

Here, in the ESP32, we build our simple logistic regression model from scratch in C. Then, we are also going to build the gradient descent algorithm. So, we can train the model directly in ESP32. After that, we do the inference process with real-time data from sensor, i.e. we read the relative humidity value from DHT11 sensor, and we fed the value to the model.

Schematic Diagram

The following figure shows the schematic diagram of the ESP32 (in this case, I use the ESP32 DevKit v1).

  • First, connect the VCC and GND from ESP32 to DHT11.
  • Second, connect a GPIO (in this case, I use D4, you can use other pins) from ESP32 to the data pin of DHT11.
  • Third, connect a 10k resistor from the VCC to the GPIO.

Recommended reading: ESP32 DHT11/DHT22 Web Server – Temperature and Humidity using Arduino IDE

Arduino Sketch

In this section, we are going to build the simple logistic regression model from scratch in C Arduino. We use the model that has been developed in Python in the previous tutorial. The model mainly consists of three parts: sigmoid function, hypothesis function, and gradient descent.

Sigmoid Function

Firstly, let us build the sigmoid function in C which is given by

\(g(z)=\frac{1}{1+e^{-z}}\)

where \(z\) is the input, and \(g(z)\) is the output. The following code is the sigmoid function implementation in C. It takes input x as the argument and return the sigmoid calculation. We use the exp function, which is part of C standard library.

Hypothesis Function

Secondly, let us build the hypothesis function in C which is given by

\(h_{\theta}(x)=\frac{1}{1+e^{-(\theta_{0}+\theta_{1}x)}}\)

where \(x\) is the input, \(h_{\theta}(x)\) is the output, and it is parameterized by \(\theta_{0}\) and \(\theta_{1}\). The following code is the hypothesis function implementation in C. It takes input x as the argument and return the hypothesis calculation. We use the sigmoid function that was defined before.

Gradient Descent

Thirdly, let us build the gradient descent function for training the model. The gradient descent is given by

\(
repeat \; until \; convergence \; \{ \\
\qquad temp0:=\theta_{0}-\alpha\frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)}) \\
\qquad temp1:=\theta_{1}-\alpha\frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})x^{(i)} \\
\qquad \theta_{0}:=temp0 \\
\qquad \theta_{1}:=temp1 \\
\}
\)

where \(m\) is number of training samples, and \(\alpha\) is learning rate. The following code is the implementation of gradient descent in C. It takes five input arguments: array of input x, array of expected output y, number of samples m, number of iterations iter, and learning rate alpha. The gradient descent algorithm updates the parameters theta_0 and theta_1 for every iteration. The parameters itself are defined as global variables.

Putting It All Together

Now, we are ready to put the code all together. The following code shows the complete code. First of all, we should initialize the DHT11 sensor. In line 6-7, we define the DHT11 input pin and the DHT type. Then, in line 10, we instantiate the dht class. After that, we initialize the dht by calling begin function in line 31.

Now, let us define the training set and the parameters in line 12-24. We use the training set to train the model in line 37. After the model is trained, we can make predictions by feeding the humidity value fetched by DHT11 (line 43) to the model. We pass the humidity value as an input argument to the hypothesis function in line 44.

Demonstration

After the code is compiled and uploaded, we can open the serial monitor. Then, wait till the training process is completed. You should obtain the trained parameters theta_0 and theta_1. After that, check that the humidity value and rain prediction are being read correctly from DHT11.

Source Code

You can get the source code from this repository.

Summary

In this tutorial, we have learned how to build a simple logistic regression model from scratch in C. We have implemented the model in ESP32 Arduino. Then, we have also trained the model using gradient descent. Finally, we make predictions by feeding real-time humidity value from DHT11 sensor.