Reconnaissance de nombre

L’objectif est de réaliser un algorithme de reconnaissance du nombre affiché par un afficheur 7 segments.

 

Proposer un programme Arduino utilisant la bibliothèque NeuralNetwork permettant l’apprentissage puis le test d’un réseau de neurones qui traduira la table de vérité suivante :

La table de vérité ci-dessous donne l’ensemble des combinaisons possibles des états des segments :

a b c d e f g N (décimal)
1 1 1 1 1 1 0 0
0 1 1 0 0 0 0 1
1 1 0 1 1 0 1 2
1 1 1 1 0 0 1 3
0 1 1 0 0 1 1 4
1 0 1 1 0 1 1 5
0 0 1 1 1 1 1 6
1 1 1 0 0 0 0 7
1 1 1 1 1 1 1 8
1 1 1 0 0 1 1 9

La bibliothèque NeuralNetwork donne des valeurs de sortie de type float < 1. Il faudra donc ajuster les sorties souhaitées par des valeurs < 1, soient 0.1 pour 1 0.2 pour 2 etc.

Correction

Attention, l’apprentissage dure environ 7.5 minutes sur Arduino Uno !

#define NumberOf(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0]))) //calculates the amount of layers (in this case 4)

#include <NeuralNetwork.h>

// 4 couches neurales. La 1ere couche avec 7 neurones d'entrée. Les 2e et 3e couches contenant chacune 9 neurones cachées et la 4e couche avec 1 neurone de sortie
unsigned int layers[] = {7, 9, 9, 1};

// Sorties pour la 4e couche (ici 1 sortie)
float *outputs; 

//Valeurs d'entrée
const float inputs[10][7] = {
  { 1, 1, 1, 1, 1, 1, 0 },  // 0
  { 0, 1, 1, 0, 0, 0, 0 },  // 1
  { 1, 1, 0, 1, 1, 0, 1 },  // 2
  { 1, 1, 1, 1, 0, 0, 1 },  // 3
  { 0, 1, 1, 0, 0, 1, 1 },  // 4
  { 1, 0, 1, 1, 0, 1, 1 },  // 5
  { 0, 0, 1, 1, 1, 1, 1 },  // 6
  { 1, 1, 1, 0, 0, 0, 0 },  // 7 
  { 1, 1, 1, 1, 1, 1, 1 },  // 8
  { 1, 1, 1, 0, 0, 1, 1 }   // 9
};

// Valeurs de sorties (/10 pour être < 1) souhaitées au niveau de la 4e couche du réseau neuronal. 
// Va servir pour l'apprentissage du réseau neuronal
const float expectedOutput[10][1] = {{0.0}, {0.1}, {0.2}, {0.3}, {0.4}, {0.5}, {0.6}, {0.7}, {0.8}, {0.9}};


NeuralNetwork NN(layers, NumberOf(layers)); // Creation du reseau de neurones

void setup()
{

  Serial.begin(115200);
  Serial.println("Apprentissage...");
  //Entrainement du réseau de neurones avec 8000 boucle d'apprentissages
  for (int i = 0; i < 8000; i++)
  {
    for (int j = 0; j < NumberOf(inputs); j++)
    {
      NN.FeedForward(inputs[j]); // Propagation avant (feedforward) des données depuis les neurones d'entrées (1ere couche) vers la couche de sortie (ici 1 donnée sur la 4e couche)
      NN.BackProp(expectedOutput[j]); // Rétropropagation pour ajuster l'apprentissage.
    }
  }
  Serial.println("Apprentissage terminé");

  //Après apprentissage on vérifie. 
  for (int i = 0; i < NumberOf(inputs); i++) //On parcoure les entrées
  {
    outputs = NN.FeedForward(inputs[i]); // Propagation des données dans le réseau et calcul de la sortie
    Serial.println(10*outputs[0]); //Afficher les sorties (comme on a fait sortie_souhaitée/10 on multiplie par 10)
  }

  NN.print(); // Afficher les poids et les biais pour chaque couche

}

void loop() {
  for (int i = 0; i < NumberOf(inputs); i++){

    outputs = NN.FeedForward(inputs[i]);
    for ( int j = 0; j < 7; j++ ) {
      Serial.print(inputs[i][j],0);
    }
    Serial.print(" = ");
    Serial.println(10*outputs[0], 0);
  }
  delay(2000);
}

 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.