Hola amigos en esta ocasión les comparto una aplicación que se realizo en un curso de Inteligencia Artificial que estuve llevando en la universidad espero les sea de utilidad como es de costumbre comenzare con algo de teoría para luego compartir con ustedes el código fuente de la aplicación.
Una red neuronal artificial es un procesador distribuido en paralelo de forma masiva que tiene una tendencia natural para almacenar conocimiento de forma experimental y lo hace disponible para su uso.
Dado un panel de entrada compuesto por una matriz de 7x5 puntos, se consideran 12 clases diferentes donde se pretenden clasificar las muestras que se introducen. Los patrones que definen correctamente a cada una de las clases son los números del 0 al 9, el punto y el guión (figura 3).
Cuando a la entrada se presente una muestra distinta de los patrones correctos, el sistema presentará a su salida la información decodificada de la clase a la que pertenece la muestra, o bien, de la clase a la cual se aproxima más. En base a este planteamiento, la red neuronal dispone de 35 entradas que se corresponden con los puntos de la matriz numerados en la figura 4. El valor de cada entrada puede ser 0 si el punto es blanco y 1 si el punto es negro. Por otro lado, dispone de 12 salidas, una por cada clase. Cuando se introduzca una muestra a la entrada únicamente se activará la salida de la clase a la que pertenezca, permaneciendo las 11 restantes desactivadas con valores próximos a cero. Se considera que una salida está activada cuando su valor es próximo a la unidad.
RESULTADOS DE LA SIMULACIÓN:
Se realizo la implementación de una red neuronal en Java.En él se ha programado un perceptrón multinivel con 35 entradas y 12 salidas. También dispone de dos capas ocultas a las cuales se les puede modificar el número de sus neuronas. La red neuronal se ha entrenado con el algoritmo back propagation fijando el valor del momento en 0.8 y el factor de aprendizaje en 0.2. En este proceso únicamente se han usado doce muestras diferentes, es decir, los doce patrones sin ningún punto erróneo.
En la tabla I se muestran los resultados obtenidos para una red neuronal de tamaño 35-30-20-12. Se aprecia que tras el proceso de entrenamiento, el sistema responde de forma casi ideal cuando se introduce un patrón sin error.
IMPLEMENTACIÓN:
package digitos;
import javax.swing.JOptionPane;
public class digitos {
int filas_entrada = 7;
int col_entrada = 5;
int neuronas_entrada = 35;
int neuronas_oculta = 4;
int neuronas_salida = 6;
int i, j, k;
int respuesta;
int[][] patron = new int[5][7];
double[][] pesos_entrada_oculta = {{1.658270037469468, -0.49277400626557, 0.8458827274104553, -2.648551432075224},
{1.1603936240938337, -2.518757565059801, -0.21162501186454472, 0.4483509644280242},
{0.9770989216075385, -1.1100683771308992, 0.5996520501870459, -1.5726273589648947},
{-0.013373815758508401, -1.8088573544737623, -0.1806466969385013, 1.5619996308946966},
{1.5477043440927314, -0.7451285620786131, 0.9078974238442922, -2.35721899617673},
{1.6375625959682456, 0.05352515438526517, -1.7744239541344213, 1.4633986290892553},
{-0.4895683338278625, 1.8177553658981087, 1.2455793786819767, -2.190482442936407},
{-1.6471092496923165, 3.229636202454947, 1.2981497902378096, -0.7057775268591435},
{-1.5667407635246655, -1.3245937353788448, 2.136912211349784, 0.006483361683210399},
{-0.30620712895539964, -2.082257488430547, -0.7831144540926332, 2.860170068975273},
{1.90730880729867, 1.786324022652642, -2.7987064218352016, -0.01985271542781151},
{0.6073378720265543, 2.964084801890168, -0.8036519556281736, -0.11124911355434831},
{0.8920664710707924, 1.2889968423497409, 1.4524992877441234, -4.5753301334234395},
{0.5438102680069633, 2.732096021393861, -2.46484031199823, 1.077136757466367},
{-0.5920084064677441, -2.0176453417628553, -0.8929972447944864, 2.9295974905024473},
{-1.2273348838814682, 0.9665674119959388, -1.5098278165865484, 2.3855936692870223},
{0.00303354357445883, 0.001581271588014359, 0.5078086841379089, -0.15023910421206893},
{-0.2793511488473059, 1.4245803844405784, -0.8720662059686077, -0.5734228021484368},
{-2.0275946046978293, -3.0777889662395226, 2.599080818031238, 1.6382349764441964},
{1.7261757824595334, 1.8271668605813292, -2.6230163017984798, -0.023102087227872905},
{-1.0400284786362686, 0.7483028076885504, -1.4201964658386028, 2.5893497462079242},
{-1.2173094553360448, 1.0413190887119863, -1.3232448940438146, 2.7280471684208245},
{-2.0889500107780266, 1.2113367713729557, 1.834844976337663, 0.48588965399759093},
{-1.3959767352554984, 1.340974141434604, 0.4669554523335953, 0.8396877795787216},
{0.5504882733683742, -0.007280194521717799, -1.049601349327548, 0.10628579988651637},
{1.443454707114963, -1.1329167860893807, -1.202733639186253, -1.1206540048585907},
{-0.4331284905557263, -1.5624137840495447, 1.116280151906849, 1.4607759610209936},
{-0.5819930384824622, 1.758192614385909, 0.9171022839298032, -2.0753538337866986},
{-1.3256304624056356, 1.044596834400223, 0.26717962626473013, 1.1753997160814336},
{1.5797847092614183, -1.103413366841749, -1.1869484693704706, -1.0426817633297494},
{-0.42533166857338317, -1.5201849827392802, 0.8863374072683927, 1.5286999085413167},
{0.7681134972990639, -0.9328664559674184, 0.3210235342096992, -1.6081085875846808},
{0.8656526958020259, -1.075079526248985, 0.4316305641408157, 1.4876790164633573},
{-0.3418033974126609, 0.26137924890846875, 0.44588921383473606, -0.44772778571106026},
{-0.5446034869269726, -1.7972802169693622, 1.143196716800601, 1.244775128422288}};
double[][] pesos_oculta_salida = {{0.43621096542085136, -4.4770098664620495, -3.4380683245083805, 1.8296159164887345, -8.118120689656921, 5.695458556119513},
{-1.027258581059679, 5.023126898792579, -7.757507526435068, -7.156764734520939, 4.478145059142636, 2.0603488963286387},
{-8.390374693334456, 2.4451631927893267, 1.1247117391293466, 3.3697153535415416, -1.6716192668623555, -5.293714775954221},
{5.151637910542471, -7.364970554525968, 4.923974784168798, -6.575339204075441, 4.552711228559867, -6.736958999045322}};
double[] bias_entrada = {-0.4332161363101981,
-0.5121521114762152,
-0.39471528129652694,
-0.5445351790184725,
-0.4226637563836109,
-0.5350195879964442,
-0.3350043955733998,
-0.38791367789336956,
-0.3785593217087376,
-0.5461130438610313,
-0.554558738450257,
-0.44288964426354815,
-0.4380540832801621,
-0.5350394221895475,
-0.5580057611292775,
-0.5560034483432901,
-0.12912939908250873,
-0.4139805211691567,
-0.48481548633114296,
-0.5388170156483836,
-0.5565657646610173,
-0.5633684138684646,
-0.26352247776223936,
-0.17951484914217863,
-0.3253386781429675,
-0.5422856630504476,
-0.3859925425287016,
-0.2926752007933522,
-0.33661294128974667,
-0.5351966380727077,
-0.43172146451991633,
-0.3614435550912756,
-0.3009252579538338,
0.13116124654486072,
-0.42061848358615506,};
double[] bias_oculta = {-0.5396208362695601,
0.2293253598179893,
0.9023280877608804,
-0.5367884581404073};
double[] bias_salida = {-1.3662965402953284,
-2.7832950402557444,
-1.5508290258166995,
-0.47188562328444716,
-4.298755314842922,
-2.4180200713742552,};
int[] entrada = new int[neuronas_entrada];
double[] sumatoria_entrada = new double[neuronas_entrada];
double[] sigmoidal_entrada = new double[neuronas_entrada];
double[] oculta = new double[neuronas_oculta];
double[] sumatoria_oculta = new double[neuronas_oculta];
double[] sigmoidal_oculta = new double[neuronas_oculta];
double[] salida = new double[neuronas_salida];
double[] sumatoria_salida = new double[neuronas_salida];
double[] sigmoidal_salida = new double[neuronas_salida];
public digitos(int patrones[][])
{
this.patron=patrones;
}
public void reconocimiento()
{
//procesamiento de la capa de entrada
//linealizar el patron de entrada
for (i = 0; i < filas_entrada; i++) {
for (j = 0; j < col_entrada; j++) {
entrada[i * col_entrada + j] = patron[i][j];
}
}
//1.2 sumar la entrada con el bias y calcular sigmidal
for (i = 0; i < neuronas_entrada; i++) {
sumatoria_entrada[i] = entrada[i] + bias_entrada[i];
sigmoidal_entrada[i] = 1 / (1 + Math.exp(-1 * sumatoria_entrada[i]));
}
//2. procesamiento de la capa oculta
// 2.1 sumatoria de productos de entrada por peso
for (j = 0; j < neuronas_oculta; j++) {
oculta[j] = 0;
for (i = 0; i < neuronas_entrada; i++) {
oculta[j] += sigmoidal_entrada[i] * pesos_entrada_oculta[i][j];
}
}
//2.2 sumatoria mas bias y calculo de sigmoidal
for (i = 0; i < neuronas_oculta; i++) {
sumatoria_oculta[i] = oculta[i] + bias_oculta[i];
sigmoidal_oculta[i] = 1 / (1 + Math.exp(-1 * sumatoria_oculta[i]));
}
//3. procesamiento de la capa salida
//3.1 suamtoria de productos de salida x peso
for (j = 0; j < neuronas_salida; j++) {
salida[j] = 0;
for (i = 0; i < neuronas_oculta; i++) {
salida[j] += sigmoidal_oculta[i] * pesos_oculta_salida[i][j];
}
}
//3.2 sumatoria mas bias y calculo de sigmoidal
for (i = 0; i < neuronas_salida; i++) {
sumatoria_salida[i] = salida[i] + bias_salida[i];
sigmoidal_salida[i] = 1 / (1 + Math.exp(-1 * sumatoria_salida[i]));
System.out.println("Sigmoidal [" + i + "]- " + sigmoidal_salida[i]);
}
// 4.construyendo la interface de salida
double mayor = -0.999;
int neurona_activada = -1;
for (i = 0; i < neuronas_salida; i++) {
if (sigmoidal_salida[i] > mayor) {
mayor = sigmoidal_salida[i];
neurona_activada = i;
}
}
if (mayor > 0.80 ) { // heuristica para saber si el patron es coherente
switch (neurona_activada) {
case 0:
respuesta=0;
System.out.println("RESPUESTA:"+respuesta);
break;
case 1:
respuesta=1;
System.out.println("RESPUESTA:"+respuesta);
break;
case 2:
respuesta=2;
System.out.println("RESPUESTA:"+respuesta);
break;
case 3:
respuesta=3;
System.out.println("RESPUESTA:"+respuesta);
break;
case 4:
respuesta=4;
System.out.println("RESPUESTA:"+respuesta);
break;
case 5:
respuesta=5;
System.out.println("RESPUESTA:"+respuesta);
break;
}
} else
{
respuesta=-1;
System.out.println("RESPUESTA:"+respuesta);
}
}
public int getReconocimiento()
{
return respuesta;
}
}
RESULTADOS OBTENIDOS EN LA IMPLEMENTACIÓN