Starting with Machine Learning on devices like MCU - Part 23 (Predicting the next temperature value based on previous values)

Starting with Machine Learning on devices like MCU - Part 23 (Predicting the next temperature value based on previous values)

In the previous video, we have seen how to connect DHT11 sensor to Arduino Nano 33 BLE board and collected set of temperature values to use to train our model.



The below steps show the sequence for predicting a next temperature value from past values. 
  • Take a fixed number of past readings and creating sliding windowsCreating sliding windows means taking consecutive chunks of past data (inputs) and pairing each chunk with the next future value (output), so the model can learn to predict the next reading from previous readings.
  • Define simple linear regression model
  • Train using past data. During this stage, weights are learnt. For example,

            next_temp = w1*t1 + w2*t2 + ... + w22*t22 + b
  • Normalize the data. Normalization makes learning more stable and faster by keeping values small.
  • Forecast the next value
  • Create a .TFLite file
  • Convert the .TFLite file to .h file to be used in the Microcontroller code
The experiment we did is give a single value of temperature and then tried to predict on the board which should also result in output of same temperature value. So, the input value and predicted value were the same and this shows the model has trained properly.

Below is the model used for this experiment.

data = np.array(temp_data)
print(data)

window_size = 22 # Changed from 11 to 10 to allow sequence creation
X, y = [], []

# Create sequences
for i in range(len(data)-window_size):
    X.append(data[i:i+window_size])
    y.append(data[i+window_size])
X, y = np.array(X), np.array(y)

# Simple model: single dense layer (linear regression)
   tf.keras.layers.Dense(1, input_shape=(window_size,))
])

#model from chatGPT. This adds nonlinear capacity to capture subtle patterns but still remains lightweight enough to run on your Arduino.
'''model = tf.keras.Sequential([
    tf.keras.layers.Dense(32, activation='relu', input_shape=(window_size,)),
    tf.keras.layers.Dense(16, activation='relu'),
    tf.keras.layers.Dense(1)
])'''

model.compile(optimizer='adam', loss='mse')
model.fit(X, y, epochs=50, verbose=0)

#Even though values are the same, normalizing helps gradients:
data = np.array(temp_data, dtype=float)
mean = np.mean(data)
std = np.std(data) if np.std(data) != 0 else 1
data = (data - mean) / std

# Test prediction
pred = model.predict(X[-1].reshape(1, -1))
pred = pred * std + mean
print("Next predicted temp:", pred)

# Save model
model.save("temp_predictor.keras")

# Convert to TFLite
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
open("temp_predictor.tflite", "wb").write(tflite_model)

Post a Comment

0 Comments