Escolar Documentos
Profissional Documentos
Cultura Documentos
Red de Perceptrones
Dr. Ing. Marcelo Risk
Instituto Tecnolgico de Buenos Aires
ndice
1. Introduccin
1.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
11
23
23
23
24
24
24
Introduccin
Velocidad procesamiento
Neuronas-compuertas
Peso
Consumo
Procesamiento de la visin
Cerebro humano
103 ms (0.25 MHz)
109 con 103 conexiones c/u
1.5 kg
1016 Joule
100 pasos
Computadora
109 ms (2.5 GHz)
50 millones
kgs a tons
106 Joule
billones de pasos
Las RNA heredan la terminologa de las redes naturales, provenientes de la biologa, el cuadro 2 muestra las correspondencias entre dichos trminos y los correspondientes a la estadstica.
Cuadro 2: Correspondencia entre la terminologa de las RNA y la estadstica.
RNA
Estadstica
Nodos de entrada Variables independientes
Nodos de salida
Variables dependientes
Aprendizaje
Parametrizacin
Pesos
Parmetros
2.
x0k =+1
Xk
Pesos
Peso de
umbral
W1k
X1k
Entrada de corte
sk
W2k
X2k
X3k
yk
+1
W3k
-1
Salida
Lineal
Salida
Binaria
(+1,-1)
Dispositivo
de umbral
Wnk
Xnk
Wk
Xk
Error
Lineal
Algoritmo
LMS
ADALINE
dk
Entrada de
Respuesta Deseada
(seal de entrenamiento)
W0
X1
W1
W2
S(n)
+1
Y(n)
-1
X2
(2)
1 e2S(n)
(4)
1 + e2S(n)
En una implementacin prctica de una neurona, es conveniente incluir todas
las alternativas posibles de cuantificacin y clculo error, de manera de poder implementar ms de un algoritmo de optimizacin.
Por ejemplo si se utiliza en lugar del error lineal instantneo, el error a la salida
del cuantificador, el algoritmo de optimizacin de coeficientes se denomina regla del
Perceptron, desarrollada por F. Rosenblatt.
La diferencia entre el error cuadrtico medio tomado de la salida lineal, con el
error tomado a la salida de la funcin sigmoidea es una respuesta ms abrupta por
parte del error sigmoideo.
Y (n) = SIG[S(n)] = tanh[S(n)] =
X0 = +1
X1
X2
W1
W0
W2
W3
+1
S(n)
+1
Y1(n)
-1
Y2(n)
-1
X3
W4
X4
e(n)
d(n)
e1(n)
d1(n)
e2(n)
d2(n)
Figura 4: Diagrama en bloques del adaline completo, con salidas y errores lineales,
sigmoideos y signo.
En dicha figura 4 podemos apreciar que para cada error debe suministrarse la
salida deseada.
Cuando se conectan ms de una neurona, se conforma una red neuronal, es
necesario en la mayora de las aplicaciones conectar varias neuronas, debido a que
aumenta notablemente la capacidad de reconocimiento de patrones.
Las redes neuronales se organizan en capas, formadas por una cantidad de neuronas cada una de ellas, generalmente son de dos o tres capas, denominndose las
capas en las cuales entra el vector de entrada y donde se genera el vector de salida,
capas de entrada y salida, respectivamente; las capas restantes entre la entrada y la
salida se denominan capas ocultas.
La figura 5 muestra un diagrama general de una red neuronal de tres capas, note
que el vector de entrada ingresa a todas las neuronas de la primera capa, la cual
genera un vector de salida de dicha capa, que sirve para alimentar las neuronas de
6
Capa
de entrada
Capa
de salida
Vector
de entrada
Vector
de salida
Capa
oculta
{tanh[S(n)]}
= 1 {tanh[S(n)]}2 = 1 Y 2 (n)
{S(n)}
(5)
De esta forma la ecuacin que optimiza los pesos por el mtodo de los cuadrados
7
3.
(6)
// NEURAL3.H
#include
#include
#include
#include
<math.h>
<stdlib.h>
<iostream.h>
<fstream.h>
class CombinadorLinealAdaptativo{
public:
float *Xk;
float *Wk;
float Sk;
float Ek;
float Eks;
float Ekd;
float Dk;
float Yk;
float yk;
float Alfa;
int Cantidad;
CombinadorLinealAdaptativo();
8
W210
W310
X2
X3
W312
W212
W112
W012
W311
W211
W111
W011
W110
W010
X1
X0
W410
W411
W412
Algoritmo
LMS
+1
Algoritmo
LMS
+1
Algoritmo
LMS
+1
SIG
S12
SIG
S11
SIG
S10
SIG
SIG
SIG
Y12
Y11
Y10
W221
W121
W021
W220
W120
W020
W420
W421
Algoritmo
LMS
+1
Algoritmo
LMS
+1
SIG
S21
SIG
S20
SIG
SIG
d1
Y1
d0
Y0
Calcula( void);
CantidadSynapsis( int n = 50);
LlenaPesos( float *Array, int cantidad);
LlenaEntradas( float *Array, int cantidad);
LlenaPesos( float *Array);
LlenaEntradas( float *Array);
LlenaSalidaDeseada( float Salida);
LlenaAlfa( float a);
*C100;
*C101;
*C102;
*C103;
*C104;
*C105;
*C106;
*C107;
*C108;
*C109;
10
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
// segunda capa
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
CombinadorLinealAdaptativo
*C110;
*C111;
*C112;
*C113;
*C114;
*C115;
*C116;
*C117;
*C118;
*C119;
*C20;
*C21;
*C22;
*C23;
Red Neural();
Red Neural( int inputs);
~Red Neural();
void
void
void
void
float
float
float
float
};
3.0.2.
MuestraSalidaDigital1(
MuestraSalidaDigital2(
MuestraSalidaDigital3(
MuestraSalidaDigital4(
void);
void);
void);
void);
// NEURAL3.CPP
#include "neural3.h"
#include <stdlib.h>
#define ALFAINICIAL 1e-3
CombinadorLinealAdaptativo::CombinadorLinealAdaptativo( int n){
Alfa = ALFAINICIAL;
Ek = 1.0;
Dk = 1.0;
11
Eks = 1.0;
Ekd = 1.0;
Cantidad = n + 1;
Xk = new float[Cantidad];
Wk = new float[Cantidad];
for( int j = 0; j < Cantidad; j++){
Xk[j] = 0.0;
Wk[j] = float(random(1000))/10000.0;
}
}
CombinadorLinealAdaptativo::CombinadorLinealAdaptativo(){
Alfa = ALFAINICIAL;
Ek = 1.0;
Dk = 1.0;
Eks = 1.0;
Ekd = 1.0;
}
void CombinadorLinealAdaptativo::CantidadSynapsis( int n){
Cantidad = n + 1;
Xk = new float[Cantidad];
Wk = new float[Cantidad];
for( int j = 0; j < Cantidad; j++){
Xk[j] = 0.0;
Wk[j] = float(random(1000))/1000000.0;
}
}
CombinadorLinealAdaptativo::CombinadorLinealAdaptativo(){
delete Xk;
delete Wk;
}
void CombinadorLinealAdaptativo::LlenaPesos( float *Array, int Cantidad){
for( int j = 0; j < Cantidad; j++)
Wk[j] = Array[j];
}
void CombinadorLinealAdaptativo::LlenaPesos( float *Array){
for( int j = 0; j < Cantidad; j++)
Wk[j] = Array[j];
}
void CombinadorLinealAdaptativo::CalculaNuevoSet( void){
12
void){
float CombinadorLinealAdaptativo::MuestraSalidaSigmoidea(
return yk;
}
float CombinadorLinealAdaptativo::MuestraSalidaDigital(
return Yk;
}
void){
float CombinadorLinealAdaptativo::MuestraErrorLineal(
return Ek;
}
void){
void){
float CombinadorLinealAdaptativo::MuestraErrorSigmoidea(
return Eks;
}
float CombinadorLinealAdaptativo::MuestraErrorDigital(
return Ekd;
}
void){
void){
ofstream A;
A.open( name);
if( !A)
return -1;
A << Cantidad << endl;
for( int j = 0; j < Cantidad; j++){
A << Wk[j] << endl;
}
A.close();
return 0;
}
int CombinadorLinealAdaptativo::LeePesos( char *name){
ifstream A;
A.open( name);
if( !A)
return -1;
int j;
A >> j;
if( j != Cantidad)
return -2;
for( int j = 0; j < Cantidad; j++){
A << Wk[j];
}
A.close();
return 0;
}
RedNeural::RedNeural(){
NumberInputs = 50;
C100 = new CombinadorLinealAdaptativo(NumberInputs);
C101 = new CombinadorLinealAdaptativo(NumberInputs);
C102 = new CombinadorLinealAdaptativo(NumberInputs);
C103 = new CombinadorLinealAdaptativo(NumberInputs);
C104 = new CombinadorLinealAdaptativo(NumberInputs);
C105 = new CombinadorLinealAdaptativo(NumberInputs);
C106 = new CombinadorLinealAdaptativo(NumberInputs);
C107 = new CombinadorLinealAdaptativo(NumberInputs);
C108 = new CombinadorLinealAdaptativo(NumberInputs);
C109 = new CombinadorLinealAdaptativo(NumberInputs);
C110 = new CombinadorLinealAdaptativo(NumberInputs);
C111 = new CombinadorLinealAdaptativo(NumberInputs);
C112 = new CombinadorLinealAdaptativo(NumberInputs);
C113 = new CombinadorLinealAdaptativo(NumberInputs);
C114 = new CombinadorLinealAdaptativo(NumberInputs);
15
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
delete
C101;
C102;
C103;
C104;
C105;
C106;
C107;
C108;
C109;
C110;
C111;
C112;
C113;
C114;
C115;
C116;
C117;
C118;
C119;
delete
delete
delete
delete
}
C20;
C21;
C22;
C23;
C118->LlenaEntradas( d, NumberInputs);
C119->LlenaEntradas( d, NumberInputs);
float salida[20];
salida[0] = C100->MuestraSalidaSigmoidea();
salida[1] = C101->MuestraSalidaSigmoidea();
salida[2] = C102->MuestraSalidaSigmoidea();
salida[3] = C103->MuestraSalidaSigmoidea();
salida[4] = C104->MuestraSalidaSigmoidea();
salida[5] = C105->MuestraSalidaSigmoidea();
salida[6] = C106->MuestraSalidaSigmoidea();
salida[7] = C107->MuestraSalidaSigmoidea();
salida[8] = C108->MuestraSalidaSigmoidea();
salida[9] = C108->MuestraSalidaSigmoidea();
salida[10] = C110->MuestraSalidaSigmoidea();
salida[11] = C111->MuestraSalidaSigmoidea();
salida[12] = C112->MuestraSalidaSigmoidea();
salida[13] = C113->MuestraSalidaSigmoidea();
salida[14] = C114->MuestraSalidaSigmoidea();
salida[15] = C115->MuestraSalidaSigmoidea();
salida[16] = C116->MuestraSalidaSigmoidea();
salida[17] = C117->MuestraSalidaSigmoidea();
salida[18] = C118->MuestraSalidaSigmoidea();
salida[19] = C119->MuestraSalidaSigmoidea();
C20->LlenaEntradas(
C21->LlenaEntradas(
C22->LlenaEntradas(
C23->LlenaEntradas(
}
salida,
salida,
salida,
salida,
20);
20);
20);
20);
C113->LlenaEntradas(
C114->LlenaEntradas(
C115->LlenaEntradas(
C116->LlenaEntradas(
C117->LlenaEntradas(
C118->LlenaEntradas(
C119->LlenaEntradas(
d,
d,
d,
d,
d,
d,
d,
NumberInputs);
NumberInputs);
NumberInputs);
NumberInputs);
NumberInputs);
NumberInputs);
NumberInputs);
float salida[20];
salida[0] = C100->MuestraSalidaDigital();
salida[1] = C101->MuestraSalidaDigital();
salida[2] = C102->MuestraSalidaDigital();
salida[3] = C103->MuestraSalidaDigital();
salida[4] = C104->MuestraSalidaDigital();
salida[5] = C105->MuestraSalidaDigital();
salida[6] = C106->MuestraSalidaDigital();
salida[7] = C107->MuestraSalidaDigital();
salida[8] = C108->MuestraSalidaDigital();
salida[9] = C108->MuestraSalidaDigital();
salida[10] = C110->MuestraSalidaDigital();
salida[11] = C111->MuestraSalidaDigital();
salida[12] = C112->MuestraSalidaDigital();
salida[13] = C113->MuestraSalidaDigital();
salida[14] = C114->MuestraSalidaDigital();
salida[15] = C115->MuestraSalidaDigital();
salida[16] = C116->MuestraSalidaDigital();
salida[17] = C117->MuestraSalidaDigital();
salida[18] = C118->MuestraSalidaDigital();
salida[19] = C119->MuestraSalidaDigital();
C20->LlenaEntradas(
C21->LlenaEntradas(
C22->LlenaEntradas(
C23->LlenaEntradas(
}
salida,
salida,
salida,
salida,
20);
20);
20);
20);
salida[0]
salida[1]
salida[2]
salida[3]
=
=
=
=
deseada[0]
deseada[1]
deseada[2]
deseada[3]
C20->MuestraSalidaSigmoidea();
C21->MuestraSalidaSigmoidea();
C22->MuestraSalidaSigmoidea();
C23->MuestraSalidaSigmoidea();
+ salida[2]*C22->Wk[13] + salida[3]*C23->Wk[13];
error[14] = salida[0]*C20->Wk[14] + salida[1]*C21->Wk[14]
+ salida[2]*C22->Wk[14] + salida[3]*C23->Wk[14];
error[15] = salida[0]*C20->Wk[15] + salida[1]*C21->Wk[15]
+ salida[2]*C22->Wk[15] + salida[3]*C23->Wk[15];
error[16] = salida[0]*C20->Wk[16] + salida[1]*C21->Wk[16]
+ salida[2]*C22->Wk[16] + salida[3]*C23->Wk[16];
error[17] = salida[0]*C20->Wk[17] + salida[1]*C21->Wk[17]
+ salida[2]*C22->Wk[17] + salida[3]*C23->Wk[17];
error[18] = salida[0]*C20->Wk[18] + salida[1]*C21->Wk[18]
+ salida[2]*C22->Wk[18] + salida[3]*C23->Wk[18];
error[19] = salida[0]*C20->Wk[19] + salida[1]*C21->Wk[19]
+ salida[2]*C22->Wk[19] + salida[3]*C23->Wk[19];
error[0] = error[0]*(1.0- (C100->MuestraSalidaSigmoidea()
*C100->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C101->MuestraSalidaSigmoidea()
*C101->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C102->MuestraSalidaSigmoidea()
*C102->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C103->MuestraSalidaSigmoidea()
*C103->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C104->MuestraSalidaSigmoidea()
*C104->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C105->MuestraSalidaSigmoidea()
*C105->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C106->MuestraSalidaSigmoidea()
*C106->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C107->MuestraSalidaSigmoidea()
*C107->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C108->MuestraSalidaSigmoidea()
*C108->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C109->MuestraSalidaSigmoidea()
*C109->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C110->MuestraSalidaSigmoidea()
*C110->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C111->MuestraSalidaSigmoidea()
*C111->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C112->MuestraSalidaSigmoidea()
*C112->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C113->MuestraSalidaSigmoidea()
*C113->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C114->MuestraSalidaSigmoidea()
*C114->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C115->MuestraSalidaSigmoidea()
21
*C115->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C116->MuestraSalidaSigmoidea()
*C116->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C117->MuestraSalidaSigmoidea()
*C117->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C118->MuestraSalidaSigmoidea()
*C118->MuestraSalidaSigmoidea()));
error[0] = error[0]*(1.0- (C119->MuestraSalidaSigmoidea()
*C119->MuestraSalidaSigmoidea()));
C100->CalculaNuevoSet(
C101->CalculaNuevoSet(
C102->CalculaNuevoSet(
C103->CalculaNuevoSet(
C104->CalculaNuevoSet(
C105->CalculaNuevoSet(
C106->CalculaNuevoSet(
C107->CalculaNuevoSet(
C108->CalculaNuevoSet(
C109->CalculaNuevoSet(
C110->CalculaNuevoSet(
C111->CalculaNuevoSet(
C112->CalculaNuevoSet(
C113->CalculaNuevoSet(
C114->CalculaNuevoSet(
C115->CalculaNuevoSet(
C116->CalculaNuevoSet(
C117->CalculaNuevoSet(
C118->CalculaNuevoSet(
C119->CalculaNuevoSet(
}
error[0]);
error[1]);
error[2]);
error[3]);
error[4]);
error[5]);
error[6]);
error[7]);
error[8]);
error[9]);
error[10]);
error[11]);
error[12]);
error[13]);
error[14]);
error[15]);
error[16]);
error[17]);
error[18]);
error[19]);
return C23->MuestraSalidaDigital();
}
3.1.
3.1.2.
OCHO.TXT
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0 0 0 0
10 10 10 10
10 0 0 0
10 0 0 0
10 10 10 10
10 0 0 0
10 0 0 0
10 10 10 10
0 0 0 0
0 0 0 0
0
10
10
10
10
10
10
10
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0
10 10 10 10 10 0 0 0
10 0 0 0 10 0 0 0
10 0 0 0 10 0 0 0
10 10 10 10 10 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
SEIS.TXT
23
Por otro lado la red R2 se entrena con las grillas de los nmeros 5 y 6, buscando
las salidas deseadas (1,1,1) y (-1,-1,-1) respectivamente.
Las grillas se encuentran en archivos de texto, con los elementos de la misma
separados por tabulador y retorno de carro, como se muestra a continuacin:
3.1.3.
CINCO.TXT
0
0
0
0
0
0
0
0
0
0
3.1.4.
0
0
0
0
0
0
0
0
0
0
0 0 0 0
10 10 10 10
10 0 0 0
10 0 0 0
10 10 10 10
0 0 0 0
0 0 0 0
10 10 10 10
0 0 0 0
0 0 0 0
0
10
0
0
10
10
10
10
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
SEIS2.TXT
0 10 0 0 0 0 0 0 0 0
0 0 10 0 0 0 10 0 10 0
0 0 10 0 0 0 0 0 0 0
0 0 10 0 0 0 0 0 0 0
0 0 10 10 10 10 10 10 0 0
0 0 10 0 0 0 10 0 0 0
0 0 10 0 0 0 10 0 0 0
0 10 10 10 10 10 10 0 0 0
0 0 0 10 0 0 0 0 0 0
0 0 0 0 0 0 10 0 0 0
3.1.5.
// NUMERO.CPP
#include
#include
#include
#include
"neural3.h"
<stdlib.h>
<iostream.h>
<fstream.h>
float numero[10][10];
24
float
float
float
float
*num1
*num2
*num3
*num4
=
=
=
=
new
new
new
new
float[100];
float[100];
float[100];
float[100];
num3[l++] = numero[j][k];
}
cout << endl;
}
// Lee numero 6 con ruido
numero2.close();
numero2.open("SEIS2.TXT");
l = 0;
for( j = 0; j < 10; j++){
for( k = 0; k < 10; k++){
numero2 >> numero[j][k];
cout << numero[j][k] << "\t";
num4[l++] = numero[j][k];
}
cout << endl;
}
float error, error1, error2;
int pasada = 1;
cout << "Comienza entrenamiento ..." << endl << endl;
for( j = 0; j < 3000; j++){
R.deseada[0] = -1.0;
R.deseada[1] = 1.0;
R.deseada[2] = 1.0;
R.deseada[3] = -1.0;
R.CalculaNuevoSet( num2); // seis
R.deseada[0] = 1.0;
R.deseada[1] = 1.0;
R.deseada[2] = -1.0;
R.deseada[3] = -1.0;
R.CalculaNuevoSet( num1); // ocho
R.deseada[0] = 1.0;
R.deseada[1] = -1.0;
R.deseada[2] = 1.0;
R.deseada[3] = -1.0;
R.CalculaNuevoSet( num3); // cinco
}
cout << "Fin entrenamiento ..." << endl << endl;
R.LlenaEntradas( num2);
cout << "Muestra numero 6 (-1,1,1,-1): ";
cout << R.MuestraSalidaDigital1() << " " << R.MuestraSalidaDigital2();
26
num1;
num2;
num3;
num4;
Referencias
[1] Ricardo Armentano, Javier Fochesatto, and Marcelo Risk. Anlisis de Seales
y Sistemas. Editorial Rocamora, 1996.
[2] Sid Deutsch and Alice Deutsch. Understanding the nervous system, an engineering point of view. IEEE Press, 1993.
[3] William T. Keeton. Biological science. W.W. Norton and company, third edition
edition, 1980.
[4] Ral Rojas. Neural networks: a systematic approach. Springer, 1996.
[5] Bernard Widrow and Michael Lehr. 30 years of adaptive neural networks: perceptron, madaline, and backpropagation. Proceedings of the IEEE, 78(9):14151442,
1990.
27