You are on page 1of 10

/******************************************************************

* Red Neuronal Artificial con Arduino (Sketch)


* Se configure la red en la seccin de Configuracin de Red
******************************************************************/
#include <math.h>
/******************************************************************
* Configuracin de Red - por red
******************************************************************/
const int ContPatron = 10;
const int NodosEntrada = 7;
const int NodosOcultos = 8;
const int NodosSalida = 4;
const float RangoAprend = 0.3;
const float Momento = 0.9;
const float PesoMaxInicial = 0.5;
const float Exito = 0.0004;
const byte Input[ContPatron][NodosEntrada] = {
{ 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
};
const byte Deseado[ContPatron][NodosSalida] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 1 },
{ 0, 0, 1, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 1 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 1 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 1 }
};
/******************************************************************
* Termina Configuracin de red
******************************************************************/
int i, j, p, q, r;
int ReportaCada1000;
int RandomIndice[ContPatron];
long CicloEntrena;
float Rando;
float Error;
float Accum;
float Oculto[NodosOcultos];
float Salida[NodosSalida];

float OcultoPesos[NodosEntrada+1][NodosOcultos];
float SalidaPesos[NodosOcultos+1][NodosSalida];
float OcultoDelta[NodosOcultos];
float SalidaDelta[NodosSalida];
float CambiaOcultoPesos[NodosEntrada+1][NodosOcultos];
float CambiaSalidaPesos[NodosOcultos+1][NodosSalida];

void setup(){
Serial.begin(9600);
randomAlimenta(analogRead(3));
ReportaCada1000 = 1;
for( p = 0 ; p < ContPatron ; p++ ) {
RandomIndice[p] = p ;
}
}
void loop (){
/******************************************************************
* Inicia pesos ocultos OcultoPesos y reemplaza CambiaOcultoPesos
******************************************************************/
for( i = 0 ; i < NodosOcultos ; i++ ) {
for( j = 0 ; j <= NodosEntrada ; j++ ) {
CambiaOcultoPesos[j][i] = 0.0 ;
Rando = float(random(100))/100;
OcultoPesos[j][i] = 2.0 * ( Rando - 0.5 ) * PesoMaxInicial ;
}
}

/******************************************************************
* Inicia salida de pesos SalidaPesos y reemplaza CambiaSalidaPesos
******************************************************************/
for( i = 0 ; i < NodosSalida ; i ++ ) {
for( j = 0 ; j <= NodosOcultos ; j++ ) {
CambiaSalidaPesos[j][i] = 0.0 ;
Rando = float(random(100))/100;
SalidaPesos[j][i] = 2.0 * ( Rando - 0.5 ) * PesoMaxInicial ;
}
}
Serial.println("Inicio Salidas sin entrenar: ");
toTerminal();
/******************************************************************
* Inicio de entrenamiento
******************************************************************/
for( CicloEntrena = 1 ; CicloEntrena < 2147483647 ; CicloEntrena++) {
/******************************************************************
* Randomiza el orden de entrenamiento de patrones
******************************************************************/
for( p = 0 ; p < ContPatron ; p++) {
q = random(ContPatron);
r = RandomIndice[p] ;
RandomIndice[p] = RandomIndice[q] ;
RandomIndice[q] = r ;
}
Error = 0.0 ;

/******************************************************************
* Ciclo a traves de cada entrenamiento de patron en el orden radnomizado
******************************************************************/
for( q = 0 ; q < ContPatron ; q++ ) {
p = RandomIndice[q];
/******************************************************************
* Calcula activacion capa oculta Oculto
******************************************************************/
for( i = 0 ; i < NodosOcultos ; i++ ) {
Accum = OcultoPesos[NodosEntrada][i] ;
for( j = 0 ; j < NodosEntrada ; j++ ) {
Accum += Input[p][j] * OcultoPesos[j][i] ;
}
Oculto[i] = 1.0/(1.0 + exp(-Accum)) ;
}
/******************************************************************
* Calcula activacion capa de salida Salida y calcula errores
******************************************************************/
for( i = 0 ; i < NodosSalida ; i++ ) {
Accum = SalidaPesos[NodosOcultos][i] ;
for( j = 0 ; j < NodosOcultos ; j++ ) {
Accum += Oculto[j] * SalidaPesos[j][i] ;
}
Salida[i] = 1.0/(1.0 + exp(-Accum)) ;
SalidaDelta[i] = (Deseado[p][i] - Salida[i]) * Salida[i] * (1.0 - Salida[i]) ;
Error += 0.5 * (Deseado[p][i] - Salida[i]) * (Deseado[p][i] - Salida[i]) ;

}
/******************************************************************
* errores, propagacin hacia atras a capa oculta
******************************************************************/
for( i = 0 ; i < NodosOcultos ; i++ ) {
Accum = 0.0 ;
for( j = 0 ; j < NodosSalida ; j++ ) {
Accum += SalidaPesos[i][j] * SalidaDelta[j] ;
}
OcultoDelta[i] = Accum * Oculto[i] * (1.0 - Oculto[i]) ;
}
/******************************************************************
* Actualizar a pesos ocultos
******************************************************************/
for( i = 0 ; i < NodosOcultos ; i++ ) {
CambiaOcultoPesos[NodosEntrada][i] = RangoAprend * OcultoDelta[i] +
Momento * CambiaOcultoPesos[NodosEntrada][i] ;
OcultoPesos[NodosEntrada][i] += CambiaOcultoPesos[NodosEntrada][i] ;
for( j = 0 ; j < NodosEntrada ; j++ ) {
CambiaOcultoPesos[j][i] = RangoAprend * Input[p][j] * OcultoDelta[i] +
Momento * CambiaOcultoPesos[j][i];
OcultoPesos[j][i] += CambiaOcultoPesos[j][i] ;
}
}
/******************************************************************
* Actualizar

Oculto-->Salida Pesos

******************************************************************/

for( i = 0 ; i < NodosSalida ; i ++ ) {


CambiaSalidaPesos[NodosOcultos][i] = RangoAprend * SalidaDelta[i] +
Momento * CambiaSalidaPesos[NodosOcultos][i] ;
SalidaPesos[NodosOcultos][i] += CambiaSalidaPesos[NodosOcultos][i] ;
for( j = 0 ; j < NodosOcultos ; j++ ) {
CambiaSalidaPesos[j][i] = RangoAprend * Oculto[j] * SalidaDelta[i] +
Momento * CambiaSalidaPesos[j][i] ;
SalidaPesos[j][i] += CambiaSalidaPesos[j][i] ;
}
}
}
/******************************************************************
* Cada 1000 ciclos se enva datos a la terminal para mostrar
******************************************************************/
ReportaCada1000 = ReportaCada1000 - 1;
if (ReportaCada1000 == 0)
{
Serial.println();
Serial.println();
Serial.print ("Ciclo Entrenamiento: ");
Serial.print (CicloEntrena);
Serial.print (" Error = ");
Serial.println (Error, 5);
toTerminal();
if (CicloEntrena==1)
{
ReportaCada1000 = 999;

}
else
{
ReportaCada1000 = 1000;
}
}
/******************************************************************
* termina si el rango de error es menor que el pre determinado
******************************************************************/
if( Error < Exito ) break ;
}
Serial.println ();
Serial.println();
Serial.print ("Ciclo Entrenamiento: ");
Serial.print (CicloEntrena);
Serial.print (" Error = ");
Serial.println (Error, 5);

toTerminal();
Serial.println ();
Serial.println ();
Serial.println ("Set Entranamiento Resuelto! ");
Serial.println ("--------");
Serial.println ();
Serial.println ();
ReportaCada1000 = 1;

}
void toTerminal()
{
for( p = 0 ; p < ContPatron ; p++ ) {
Serial.println();
Serial.print (" Entrenamiento Patron: ");
Serial.println (p);
Serial.print (" Entrada ");
for( i = 0 ; i < NodosEntrada ; i++ ) {
Serial.print (Input[p][i], DEC);
Serial.print (" ");
}
Serial.print (" Deseado ");
for( i = 0 ; i < NodosSalida ; i++ ) {
Serial.print (Deseado[p][i], DEC);
Serial.print (" ");
}
/******************************************************************
* Calcula capa de activacion oculta Oculto
******************************************************************/
for( i = 0 ; i < NodosOcultos ; i++ ) {
Accum = OcultoPesos[NodosEntrada][i] ;
for( j = 0 ; j < NodosEntrada ; j++ ) {
Accum += Input[p][j] * OcultoPesos[j][i] ;
}
Oculto[i] = 1.0/(1.0 + exp(-Accum)) ;

}
/******************************************************************
* Calcula capa activacion salida y errores
******************************************************************/
for( i = 0 ; i < NodosSalida ; i++ ) {
Accum = SalidaPesos[NodosOcultos][i] ;
for( j = 0 ; j < NodosOcultos ; j++ ) {
Accum += Oculto[j] * SalidaPesos[j][i] ;
}
Salida[i] = 1.0/(1.0 + exp(-Accum)) ;
}
Serial.print (" Salida ");
for( i = 0 ; i < NodosSalida ; i++ ) {
Serial.print (Salida[i], 5);
Serial.print (" ");
}
}
}

You might also like