/*
www.aifes.ai
https://github.com/Fraunhofer-IMS/AIfES_for_Arduino
Copyright (C) 2020-2022 Fraunhofer Institute for Microelectronic Circuits and Systems.
All rights reserved.
AIfES is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
AIfES-Express ESP32 dual core demo
ONLY FOR ESP32!!!!!!!
--------------------
Versions:
1.0.0 Initial version
--------------------
Wokwi hardware simulation:
The hardware simulation is very complex.
It can take quite a long time until a command is processed.
USE IT IN THE ARDUINO IDE
- Install AIfES via the library manager (search for "aifes")
- Download the project from Wokwi (Download project ZIP)
- Open it in the Arduino IDE
AIfES-Express is a simplified API for AIfES, which is directly integrated. So you can simply decide which variant you want to use.
The sketch shows an example of how a neural network is trained from scratch in AIfES-Express using training data.
An XOR gate is mapped here using a neural network.
The 4 different states of an XOR gate are fed in as training data here.
The network structure is 2-3(Sigmoid)-1(Sigmoid) and Sigmoid is used as activation function.
The calculation is done in float 32.
XOR truth table / training data
Input Output
0 0 0
0 1 1
1 0 1
1 1 0
Tested on:
ESP32 DevKit (Wokwi simulation)
Heltec ESP 32 WiFi
You can find more AIfES tutorials here:
https://create.arduino.cc/projecthub/aifes_team
*/
#define DATASETS 4
#define INPUTS 2
#define OUTPUTS 1
TaskHandle_t Core0TaskHnd ;
const int led = LED_BUILTIN;
bool NET_TRAINED = false;
float input_data[DATASETS][INPUTS] = {
{0.0f, 0.0f}, // Input data
{0.0f, 1.0f},
{1.0f, 0.0f},
{1.0f, 1.0f}
};
float target_data[] = {0.0f, 1.0f, 1.0f, 0.0f}; // Target Data
float output_data[DATASETS];
uint32_t i;
String str;
void setup()
{
Serial.begin(115200);
pinMode(led, OUTPUT);
Serial.println ("AIfES - ESP32 dual core demo");
Serial.print ("Core ");
Serial.print (xPortGetCoreID());
Serial.println (": I am responsible for the AI and read the UART commands");
build_AIfES_model();
xTaskCreatePinnedToCore(CoreTask0,"CPU_0",1000,NULL,1,&Core0TaskHnd,0);
//IMPORTANT
//AIfES requires random weights for training
//Here the random seed is generated by the noise of an analog pin
srand(analogRead(A5));
}
void loop()
{
str = Serial.readString();
if(str.indexOf("training") > -1)
{
Serial.println("Training");
train_AIfES_model((float*)input_data,(float*)target_data,(float*)output_data);
NET_TRAINED = true;
Serial.println(F(""));
Serial.println(F("Results:"));
Serial.println(F("input 1:\tinput 2:\treal output:\tcalculated output:"));
for (i = 0; i < DATASETS; i++)
{
Serial.print (input_data[i][0]);
Serial.print (F("\t\t"));
Serial.print (input_data[i][1]);
Serial.print (F("\t\t"));
Serial.print (target_data[i]);
Serial.print (F("\t\t"));
Serial.println(output_data[i], 5);
}
Serial.println(F("A learning success is not guaranteed"));
Serial.println(F("The weights were initialized randomly"));
Serial.println(F("You can repeat the training with >training<\n"));
Serial.println(F("Type >inference< to perform the inference"));
}
if(str.indexOf("inference") > -1)
{
if(NET_TRAINED == true)
{
Serial.println("inference");
output_data[0] = 0.0f;
output_data[1] = 0.0f;
output_data[2] = 0.0f;
output_data[3] = 0.0f;
inference((float*)input_data,(float*)output_data);
Serial.println(F(""));
Serial.println(F("Inference results:"));
Serial.println(F("input 1:\tinput 2:\tcalculated output:"));
for (i = 0; i < DATASETS; i++)
{
Serial.print (input_data[i][0]);
Serial.print (F("\t\t"));
Serial.print (input_data[i][1]);
Serial.print (F("\t\t"));
Serial.println(output_data[i], 5);
}
}
else
{
Serial.println("Net not trained");
}
}
}
void CoreTask0( void * parameter )
{
Serial.print ("Core ");
Serial.print (xPortGetCoreID());
Serial.println(" (Task0): I switch the internal LED on and off");
Serial.println("");
Serial.println("Type >training< to start training");
Serial.println("Type >inference< to peform the inference");
for (;;)
{
digitalWrite(led, HIGH);
delay (1000);
digitalWrite(led, LOW);
delay (1000);
yield();
}
}