Está en la página 1de 27

BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA

FACULTAD DE CIENCIAS DE LA ELECTRÓNICA


LICENCIATURA EN INGENIERÍA MECATRÓNICA
APLICACIONES DE CONTROL POR IA
JORGE ALBERTO GUZMAN PEREZ - 201837024

CÓDIGO 001: Tiempo de ejecución del perceptrón

Objetivos:
 Programar la sigmoide y verificar el tiempo de ejecución.
 Familiarizar con el ambiente sketch

// Codigo ejemplo 001 para curso de aplicaciones de control por IA


// Objetivo del codigo:
// Demostrar los tiempo de ejecución y control de tiempos,
// cuando se hace emulación de punto flotante
// Particular
// Manejo de los puertos de com para echoterminal
// Validación de datos resultados de operaciones
// Medición de tiempos de ejecución
//
// Otoño 2023
// Notas:
// Se emplea el LED verde del RGB colocado en el puerto P2_1
// En este Código realizamos el calculo de una función trigonometrica como ejemplo
// Zona de librerias

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.print("Codigo ejemplo 001, iniciando");
Serial.println("... demonios funciona x2");
delay(150);
pinMode(75, OUTPUT); // Led verde del RGB
digitalWrite(75,1); // apagar el LED
}
// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned int ti,tt,i; // Variables locales: tiempo inicia - final y contador
float f_res,f_val=-5.00; // Variables locales: resultado de la función y valor para
cargar
digitalWrite(75,0); // prendemos el LED
Serial.println("Calculo de 200 funciones 4.0*seno(pi*f_val/2) con valores decimales
(float)!");
ti=micros(); // guardamos el tiempo antes de realizar los ciclos
for (i=0;i<=199;i++) // ciclo para hacer muchas veces el calculo
{
f_res=4.0*exp(f_val*3.1416/2);
//f_res=f_val;
f_val=f_val+0.05;
}
tt=micros()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
//i=tt*1000; // tiempo transcurrido en micro segundos
Serial.print("Tiempo transcurrido son: ");
Serial.print(tt);//Serial.print(String(tt, DEC));
Serial.println(" milisegundos.");
Serial.print("En promedio cada calculo de c/u tardo: ");
//f_val=tt*1000.0/200.0;
f_val=tt/200.0;
Serial.print(f_val, 4);
Serial.println(" microsegundos.");
Serial.print(f_res, 4);
Serial.println("\n");
digitalWrite(75,1); // prendemos el LED
delay(1000); // Esperamos 1segundo para continuar
}
// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// END

Resultados:

Conclusiones:
Se tuvo que modificar el valor de los baudios, con los que funciona el programa porque estaba devolviendo
caracteres sin sentido, al azar.
Se puede observar que la versión que se maneja no proyecta una consola externa, pero despliega una
ventana con los resultados.
CÓDIGO 001.1: Gráfica Sigmoide

Objetivo:
 Programar la sigmoide y verificar el tiempo de ejecución. Mostrar la gráfica de la sigmoide
 Familiarizar con el ambiente sketch

// Codigo ejemplo 001.1 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Evaluación de una función sigmoide variando la constante de
// activación y visualizando gráficamente.
// Particular
// Manejo de los puertos de com para plot
// Validación de datos resultados de operaciones

// Emplear el serial ploter

// Zona de librerias

// Zona de constantes y variables globales


const int cuentas=200; //Cuantas cuentas por loop
const float paso=0.05; //Paso entre cada vuelta del loop de calculo
float c[]={1,5,9}; //Variable de la constante de activación de la sigmoide
int activa=0,j; //Variable para ayudar a cambiar entre valores de c

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial, sin mensaje a consola
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned int ti,tt,i; // Variables locales: tiempo inicia - final y
contador
float f_res[cuentas],f_val=-5.00; // Variables locales: resultado de la sigmoide y valor
para cargar
// f_val variable que guarda el incremento del paso
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo antes de realizar los ciclos
for (i=0;i<=cuentas-1;i++) // ciclo para hacer muchas veces el calculo
{
f_res[i]=f_sigmoide(c[activa]*f_val); //Invocamos y calculamos la sigmoide con el
valor c definido
f_val=f_val+paso; //Actualizamos el parametro de eval de la sigmoide
Serial.println(10.0*f_res[i], 4); //Se multiplica por 10 para que sea mas visible la
grafica
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
if (activa>=2)
activa=0;
else
activa=activa+1;
delay(1000); // Esperamos 1segundo para continuar graficando
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Funcion sigmoide implementada con valores float


float f_sigmoide(float valor)
{
float temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-valor)); // calculo de la sigmoide
return temp;
}

Resultados:

Conclusiones:
Se puede observar, que la salida oscila entre valores de 10 a -10 y la gráfica característica de la función
sigmoide.
CÓDIGO 002: Perceptrón Función OR
Objetivo:
 Programar el perceptrón para el ejemplo de la OR.
 Comparar resultados con los datos de la hoja de cálculo.

// Codigo ejemplo 002 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Perceptron simple de 2 entradas y 1 salida, ejemplo OR
// Particular
// Programar el perceptron como funcion

// Zona de librerias

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.print("Codigo ejemplo 002, iniciando");
Serial.println("...");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float y[4];
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
for (i=0;i<=3;i++)
{
y[i]=perceptron(x1[i],x2[i]);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Funcion del perceptron basico, 2 - 1


float perceptron(float x1, float x2)
{
float w1=1,w2=1,bias=0.5;
float temp=0.0;
temp=w1*x1+w2*x2-bias; // Calculo de la funcion de entrada
temp=f_sigmoide(temp); // Invokamos la funcion de activacion
return temp;
}

// Funcion sigmoide implementada con valores float


float f_sigmoide(float valor)
{
float c=4.0,temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}

Resultados:
Conclusiones:

Para obtener resultados más cercanos a la tabla de la respuesta de la compuerta OR, es necesario modificar
los valores de los pesos y del BIAS, en orden de acrecentar la diferencia entre valores de activación.
CÓDIGO 003: RNA multicapa XOR
Objetivos:
 Programar la RNA multicapa para el ejemplo de la XOR
 Comparar resultados con los datos de la hoja de calculo

// Codigo ejemplo 003 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Implementar una RNA de 3 capas de 2 entradas y 1 salida, ejemplo XOR
// Particular
// Modelar los parametros de las Neuronas
// Construir funciones para el manejo de multimes neuronas

// Red neuronal de 5 elementos, en 3 capas


// Capa de entrada 2 neuronas
// Capa intermedia - oculta 2 neuronas
// Capa de salida 1 neurona
/*
x1 --->(N1)--->(N3)
\ / \
\ (N5)---> y
/ \ /
X2 --->(N2)--->(N4)
*/

// Zona de librerias

// Zona de variables y constantes globales

// Parametros de la RNA MC
// conforme al ejemplo, los valores en diapositiva son:
// Pesos
const float w13=1.0, w14=1.0, w23=1.0, w24=1.0, w35=1.0, w45=-1.0;
// bias de c/neurona
const float b3=0.5, b4=1.5, b5=0.5;
// constante para activación de la sigmoide
const float c3=4.0,c4=4.0,c5=4.0;

// para desarrollar los calculos se tienen que generar


// variables intermedias asi como las generales de E/S
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float x3[4], x4[4], x5[4];
float y3[4],y4[4],y5[4];

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.println("Codigo ejemplo 003, iniciando!");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
// Generamos un ciclo para evaluar los 4 casos de las entradas x1 y x2
for (i=0;i<=3;i++)
{
// se procesa la capa intermedia
y3[i]=perceptron(x1[i],x2[i],w13,w23,b3,c3);
y4[i]=perceptron(x1[i],x2[i],w14,w24,b4,c4);
// se procesa la capa de salida
y5[i]=perceptron(y3[i],y4[i],w35,w45,b5,c5);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y5[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Perceptron de 2 entradas y 1 salida (parametro de regreso), con todos los parametros


float perceptron(float x1, float x2, float w1, float w2, float bias,float c)
{
float temp=0.0;
temp=w1*x1+w2*x2-bias; // Calculo de la funcion de entrada
temp=f_sigmoide(temp,c); // Invokamos la funcion de activacion
return temp;
}
// Funcion sigmoide con parametro de activacion
float f_sigmoide(float valor, float c)
{
float temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}

Resultados:

Conclusiones:
Se puede observar que los valores de la hoja de Excel, son idénticos a los obtenidos con el código, del
perceptrón para el problema XOR.
CODIGO 004: Valores de Salida de -5 a 5

Objetivo:
 A partir del código 001, hacer la modificación al código para enviar los cálculos de la sigmoide para
valores de entrada de -5 a 5.
 Comparar con datos de Excel.

// Codigo ejemplo 001.1 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Evaluación de una función sigmoide variando la constante de
// activación y visualizando gráficamente.
// Particular
// Manejo de los puertos de com para plot
// Validación de datos resultados de operaciones

// Emplear el serial ploter

// Zona de librerias

// Zona de constantes y variables globales


const int cuentas=200; //Cuantas cuentas por loop
const float paso=0.05; //Paso entre cada vuelta del loop de calculo
float c[]={1,5,9}; //Variable de la constante de activación de la sigmoide
int activa=0,j; //Variable para ayudar a cambiar entre valores de c

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial, sin mensaje a consola
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned int ti,tt,i; // Variables locales: tiempo inicia - final y
contador
float f_res[cuentas],f_val=-5.00; // Variables locales: resultado de la sigmoide y valor
para cargar
// f_val variable que guarda el incremento del paso
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo antes de realizar los ciclos
for (i=0;i<=cuentas-1;i++) // ciclo para hacer muchas veces el calculo
{
f_res[i]=f_sigmoide(c[activa]*f_val); //Invocamos y calculamos la sigmoide con el
valor c definido
f_val=f_val+paso; //Actualizamos el parametro de eval de la sigmoide
Serial.println(5.0*f_res[i], 4); //Se multiplica por 5 para obtener el valor solicitado
en la actividad
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos

if (activa>=2)
activa=0;
else
activa=activa+1;
delay(1000); // Esperamos 1segundo para continuar graficando
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Funcion sigmoide implementada con valores float


float f_sigmoide(float valor)
{
float temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-valor)); // calculo de la sigmoide
return temp;
}

Resultados:

Conclusiones:

Para este ejercicio solo hizo falta modificar el valor del producto por el cual se multiplicaba la señal en la
línea 48 del código 001 original.
CODIGO 005. Perceptrón con pesos modificados

Objetivos:
 Utilizando el Código 002, hacer la modificación al código donde se varíen los pesos y el bias del
perceptrón, comprar con resultados de cálculos del Excel.

// Codigo ejemplo 002 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Perceptron simple de 2 entradas y 1 salida, ejemplo OR
// Particular
// Programar el perceptron como funcion

// Zona de librerias

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.print("Codigo ejemplo 002, iniciando");
Serial.println("...");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float y[4];
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
for (i=0;i<=3;i++)
{
y[i]=perceptron(x1[i],x2[i]);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Funcion del perceptron basico, 2 - 1


float perceptron(float x1, float x2)
{
float w1=2.5,w2=3,bias=0.5;
float temp=0.0;
temp=w1*x1+w2*x2-bias; // Calculo de la funcion de entrada
temp=f_sigmoide(temp); // Invokamos la funcion de activacion
return temp;
}

// Funcion sigmoide implementada con valores float


float f_sigmoide(float valor)
{
float c=4.0,temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}

Resultados:
Conclusiones:

Se puede observar, que efectivamente los valores del Excel y del programa coinciden satisfactoriamente.
CODIGO 006. Perceptrón con función escalón unitario

Objetivos:
 Utilizando el Código 003, cambiar la función de modificación de la sigmoide a escalón.
 Implementar entradas digitales mediante botón y la salida sea para un LED.

// Red neuronal de 5 elementos, en 3 capas


// Capa de entrada 2 neuronas
// Capa intermedia - oculta 2 neuronas
// Capa de salida 1 neurona
/*
x1 --->(N1)--->(N3)
\ / \
\ (N5)---> y
/ \ /
X2 --->(N2)--->(N4)
*/
// Parametros de la RNA MC
// conforme al ejemplo, los valores en diapositiva son:
// Pesos
const float w13=1.0, w14=1.0, w23=1.0, w24=1.0, w35=1.0, w45=-1.0;
// bias de c/neurona
const float b3=0.5, b4=1.5, b5=0.5;

// para desarrollar los calculos se tienen que generar


// variables intermedias asi como las generales de E/S
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float x3[4], x4[4], x5[4];
float y3[4],y4[4],y5[4];

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.println("Codigo ejemplo 003, iniciando!");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
// Generamos un ciclo para evaluar los 4 casos de las entradas x1 y x2
for (i=0;i<=3;i++)
{
// se procesa la capa intermedia
y3[i]=perceptron(x1[i],x2[i],w13,w23,b3,c3);
y4[i]=perceptron(x1[i],x2[i],w14,w24,b4,c4);
// se procesa la capa de salida
y5[i]=perceptron(y3[i],y4[i],w35,w45,b5,c5);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y5[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Perceptron de 2 entradas y 1 salida (parametro de regreso), con todos los parametros


float perceptron(float x1, float x2, float w1, float w2, float bias,float c)
{
float temp=0.0;
temp=w1*x1+w2*x2-bias; // Calculo de la funcion de entrada
temp=f_step(temp,c); // Invokamos la funcion de activacion
return temp;
}

// Funcion sigmoide con parametro de activacion


float f_step(float valor, float c)
{
float temp=0.0; // variable temporal para el proceso
if (valor >= 0) {temp=1;}
if (valor < 0) {temp=-1;}
//temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}
Resultados:

Conclusiones:

Se logró el funcionamiento esperado, modificando la función de activación, la modificación se puede


encontrar en las líneas 90 a 104 del código 006, que parte del código 003 original.
CÓDIGO 007 Perceptrón para AND de 2 entradas.

Objetivos:
El alumno desarrollará el siguiente código y comparará los resultados con cuentas hechas en hoja de
cálculo: Perceptrón que compute la AND de 2 entradas.

// Codigo ejemplo 002 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Perceptron simple de 2 entradas y 1 salida, ejemplo OR
// Particular
// Programar el perceptron como funcion

// Zona de librerias

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.print("Codigo 007, iniciando");
Serial.println("...");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float y[4];
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
for (i=0;i<=3;i++)
{
y[i]=perceptron(x1[i],x2[i]);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Funcion del perceptron basico, 2 - 1


float perceptron(float x1, float x2)
{
float w1=-6,w2=-6,bias=1;
float temp=0.0;
temp=(w1*x1)*(w2*x2)-bias; // Calculo de la funcion de entrada
temp=f_sigmoide(temp); // Invokamos la funcion de activacion
return temp;
}

// Funcion sigmoide implementada con valores float


float f_sigmoide(float valor)
{
float c=4.0,temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}

Resultados:
Conclusión:

La modificación de este código, radica principalmente en los pesos (w1=-6, w2=-6) y el bias (bias=1), con los
valores previamente buscados en el Excel.
CÓDIGO 008. Perceptrón para NAND de dos entradas
Objetivo:
El alumno desarrollará el siguiente código y comparará los resultados con cuentas hechas en hoja de
cálculo: Perceptrón que compute la NAND de 2 entradas.

// Codigo ejemplo 002 para curso de aplicacones de control por IA


// Objetivo del codigo:
// Perceptron simple de 2 entradas y 1 salida, ejemplo OR
// Particular
// Programar el perceptron como funcion

// Zona de librerias

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.print("Codigo 008, iniciando");
Serial.println("...");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float y[4];
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
for (i=0;i<=3;i++)
{
y[i]=perceptron(x1[i],x2[i]);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Funcion del perceptron basico, 2 - 1


float perceptron(float x1, float x2)
{
float w1=-6,w2=-6,bias=1;
float temp=0.0;
temp=1-((w1*x1)*(w2*x2)-bias); // Calculo de la funcion de entrada
temp=f_sigmoide(temp); // Invokamos la funcion de activacion
return temp;
}

// Funcion sigmoide implementada con valores float


float f_sigmoide(float valor)
{
float c=4.0,temp=0.0; // variable temporal para el proceso
temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}

Resultados:
Conclusiones:
Para obtener este resultado, es necesario agregar una capa extra de negación, de esta manera, podemos
basar nuestro codigo en el codigo 007, anterior, correspondiente a la compuerta AND
CÓDIGO 009. RNA compuerta NOR de 2 entradas
Objetivo:
El alumno desarrollará el siguiente código y comparará los resultados con cuentas hechas en hoja de
cálculo: RNA MC (como el de la XOR) que compute la NOR de 2 entradas

//CODIGO NOR, DOS ENTRADAS UNA SALIDA

// Red neuronal de 5 elementos, en 3 capas


// Capa de entrada 2 neuronas
// Capa intermedia - oculta 2 neuronas
// Capa de salida 1 neurona
/*
x1 --->(N1)--->(N3)
\ / \
\ (N5)---> y
/ \ /
X2 --->(N2)--->(N4)
*/

// Zona de librerias

// Zona de variables y constantes globales

// Parametros de la RNA MC
// conforme al ejemplo, los valores en diapositiva son:
// Pesos
const float w13=1.0, w14=1.0, w23=1.0, w24=1.0, w35=1.0, w45=-1.0;
// bias de c/neurona
const float b3=5, b4=1.5, b5=0.4;
// constante para activación de la sigmoide
const float c3=1,c4=c3,c5=c4;

// para desarrollar los calculos se tienen que generar


// variables intermedias asi como las generales de E/S
float x1[]={0.0,0.0,1.0,1.0};
float x2[]={0.0,1.0,0.0,1.0};
float x3[4], x4[4], x5[4];
float y3[4],y4[4],y5[4];

// Siempre los codigos desarrollados en ambiente wire ejecutan 1ro la función setup
void setup()
{
Serial.begin(115200); // Iniciamos com serial
Serial.println("Codigo ejemplo 003, iniciando!");
delay(150);
pinMode(16, OUTPUT); // Pin 16 como salida
digitalWrite(16,1); // apagar el LED del pin 16
}

// La funcion loop seria el equivalente al main(), solo recordar que estamos dentro de
// un ciclo, el codigo que se coloca aqui se ejecuta siempre como un ciclo while.
void loop()
{
unsigned ti,tt,i; // Variables locales: tiempo inicia - final
// Variables locales para las entradas y salida del perceptron
String mensaje; // Para generar la tabla de salida
digitalWrite(16,0); // prendemos el LED
ti=millis(); // guardamos el tiempo inicial
// Generamos un ciclo para evaluar los 4 casos de las entradas x1 y x2
for (i=0;i<=3;i++)
{
// se procesa la capa intermedia
y3[i]=perceptron(x1[i],x2[i],w13,w23,b3,c3);
y4[i]=perceptron(x1[i],x2[i],w14,w24,b4,c4);
// se procesa la capa de salida
y5[i]=perceptron(y3[i],y4[i],w35,w45,b5,c5);
}
tt=millis()-ti; // guardamos el tiempo transcurrido al terminar los ciclos
i=tt*1000; // tiempo transcurrido en micro segundos
mensaje=String("|| X1 | X2 || Y ||");
Serial.println(mensaje);
for (i=0;i<=3;i++)
{
mensaje=String("||"+String(x1[i],4)+"|"+String(x2[i],4)+"||"+String(y5[i],4)+"||");
Serial.println(mensaje);
}
Serial.print("El codigo se ejecuto en: ");
Serial.print(String(i, 4));
Serial.println(" microsegundos.");
Serial.println("\n");
delay(1000); // Esperamos 1segundo para continuar
}

// Zona de funciones
// Aqui colocaremos las diferentes funciones para hacer las pruebas objetivo del codigo

// Perceptron de 2 entradas y 1 salida (parametro de regreso), con todos los parametros


float perceptron(float x1, float x2, float w1, float w2, float bias,float c)
{
float temp=0.0;
temp= ( w1*x1 + w2*x2 - bias); // Calculo de la funcion de entrada
temp=f_step(temp,c); // Invokamos la funcion de activacion
return temp;
}

// Funcion sigmoide con parametro de activacion


float f_step(float valor, float c)
{
float temp=0.0; // variable temporal para el proceso
if (valor >= 0) {temp=1;}
if (valor < 0) {temp=-1;}
//temp=1/(1+exp(-c*valor)); // calculo de la sigmoide
return temp;
}

Resultados:

Conclusiones.
Al pasar los cálculos de las conexiones del bias, en el Excel se obtiene el resultado esperado, sin embargo,
en el código, nos arroja un error, no se detecta cual es el fallo.

También podría gustarte