LoginSignup
1
1

XIAO ESP32S3にTinyMLをインストールしてみた。

Last updated at Posted at 2023-08-07

はじめに

XIAO ESP32S3でTensorflowを使ってみたかったのでEloquentTinyMLをインストールして、まずは、簡単な正弦関数を予測するサンプルプログラムを動かしてみた。

xiao_esp32_s3.jpg

環境

XIAO ESP32S3
EloquentTinyML 2.4.4
Arduino IDE 1.8.9
Python 3.11
Windows 11 Pro

参考にした記事

やったこと

まずは、seeed studioのWikiページに行ってXIAO -> XIAO ESP32S3 (Sense) -> Getting Startedを開いて、Getting StartedのSoftware PreparationをStep 1からStep 4まで実行したあと、Blink(File->Examples->01.Basics->Blink)を動かして開発環境を確認しました。
次に、参考にした記事に従ってPythonでモデルを作って、BlinkのプログラムにTensorflowの初期設定のコードとSineの予測の部分をコピーして動かそうとしたところ、以下のコンパイルエラーが出てきました。調べたところ、Arduino IDE 2.1.1では動かないようで、1.8.9にすると動いたということが書いてあったので、同じように1.8.9にすると動きました。

sineNN.png
コンパイルエラー
c:\Users\User1\Documents\Arduino\libraries\EloquentTinyML\src\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_HWC_q15_fast_nonsquare.c:1: fatal error: opening dependency file C:\Users\User1\AppData\Local\Temp\arduino\sketches\25A51BD3B31BC7D774EE9260A84C8A6B\libraries\EloquentTinyML\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_HWC_q15_fast_nonsquare.c.d: No such file or directory
 #if !defined(ESP32)
 
compilation terminated.
c:\Users\User1\Documents\Arduino\libraries\EloquentTinyML\src\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_1x1_HWC_q7_fast_nonsquare.c:1: fatal error: opening dependency file C:\Users\User1\AppData\Local\Temp\arduino\sketches\25A51BD3B31BC7D774EE9260A84C8A6B\libraries\EloquentTinyML\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_1x1_HWC_q7_fast_nonsquare.c.d: No such file or directory
 #if !defined(ESP32)
 
compilation terminated.
c:\Users\User1\Documents\Arduino\libraries\EloquentTinyML\src\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_HWC_q7_basic_nonsquare.c:1: fatal error: opening dependency file C:\Users\User1\AppData\Local\Temp\arduino\sketches\25A51BD3B31BC7D774EE9260A84C8A6B\libraries\EloquentTinyML\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_HWC_q7_basic_nonsquare.c.d: No such file or directory
 #if !defined(ESP32)
 
compilation terminated.
c:\Users\User1\Documents\Arduino\libraries\EloquentTinyML\src\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_HWC_q7_fast_nonsquare.c:1: fatal error: opening dependency file C:\Users\User1\AppData\Local\Temp\arduino\sketches\25A51BD3B31BC7D774EE9260A84C8A6B\libraries\EloquentTinyML\eloquent_tinyml\tensorflow\arm\tensorflow\lite\micro\tools\make\downloads\cmsis\CMSIS\NN\Source\ConvolutionFunctions\arm_convolve_HWC_q7_fast_nonsquare.c.d: No such file or directory
 #if !defined(ESP32)
 
compilation terminated.

exit status 1

Compilation error: exit status 1
ESP32のコード
#include <EloquentTinyML.h>
 

/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

#include "SineNN.h"

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);

  while (!sineNN.begin()) {
    Serial.print("Error in NN initialization: ");
    Serial.println(sineNN.getErrorMessage());
  }
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second

  for (int i = 0; i < 20; i++) {
        digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
        // pick x from 0 to PI
        float x = 3.14f * i / 20.0f;
        // even if the input vector is made of a single value
        // you ALWAYS need to create an array
        float input[1] = { x };

        float y_true = sin(x);
        // to run the network, call `predict()`
        float y_pred = sineNN.predict(input);

        Serial.print("sin(");
        Serial.print(x);
        Serial.print(") = ");
        Serial.print(y_true);
        Serial.print("\t predicted: ");
        Serial.println(y_pred);
        delay(1000);
       digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
    }
}

モデルを作るためのPytonコード(https://eloquentarduino.com/tensorflow-lite-esp32/より)

import math
import numpy as np
import tensorflow as tf
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split
from everywhereml.code_generators.tensorflow import tf_porter

def get_model():
    x_values = np.random.uniform(low=0, high=2 * math.pi, size=1000)
    y_values = np.sin(x_values)
    x_train, x_test, y_train, y_test = train_test_split(x_values, y_values, test_size=0.3)
    x_train, x_validate, y_train, y_validate = train_test_split(x_train, y_train, test_size=0.3)

    # create a NN with 2 layers of 16 neurons
    model = tf.keras.Sequential()
    model.add(layers.Dense(16, activation='relu', input_shape=(1,)))
    model.add(layers.Dense(16, activation='relu'))
    model.add(layers.Dense(1))
    model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
    model.fit(x_train, y_train, epochs=100, batch_size=16, validation_data=(x_validate, y_validate))

    return model, x_train, y_train


tf_model, x_train, y_train = get_model()
# tf_porter() requires:
#   1. the neural network model
#   2. the input data (to detect the input dimensions)
#   3. the output labels (to detect the number of classes - if classification)
#
# Passing `instance_name` will create an instance of the model, so you don't have to
# `area_size` is to control how much memory to allocate for the network
# It is a trial-and-error process
porter = tf_porter(tf_model, x_train, y_train)
cpp_code = porter.to_cpp(instance_name='sineNN', arena_size=4096)

print(cpp_code)

参考文献

https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/
https://eloquentarduino.com/tensorflow-lite-esp32/
https://github.com/eloquentarduino/EloquentTinyML
https://www.tensorflow.org/lite/examples/image_classification/overview
https://docs.arduino.cc/software/ide-v1/tutorials/installing-libraries

以上

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1