Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

Archivo del blog

lunes, 15 de diciembre de 2014

Red neuronal artificial (IV): Graficando las señales de salida de las neuronas en tiempo de ejecución.

En esta nueva entrada creamos nuestro proyecto con una interface gráfica (GUI) para que sea más fácil tratar de cambiar los parámetros que les vamos poner en tiempo de ejecución.
También trataremos de ver en pantalla mediante una gráfica jFreechart la peculiar conducta de los resultados de las salidas de las neuronas.

Primeramente desde NetBeans y en modo de diseño creamos la siguiente interface gráfica:




Código 1: (RedNeuronalG.java):

package redNeuronalG1;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.Timer;
import org.jfree.data.xy.XYSeries;

public class RedNeuronalG extends javax.swing.JFrame {

    int nNeuronas = 50;
    int nEnlaces = 600;
    int nVer = 5;
    int FrecuenciaRefresco;
    int ciclos = 1;

    ArrayList<Integer>[] E;
    ArrayList<Integer>[] S;
    ArrayList<Double>[] w;
    double[] y;
    Grafica g;
    XYSeries[] series;
    Timer timer;

    public RedNeuronalG() {
        initComponents();
        restablecer();
        actualizar();
    }

    private void initComponents() { ... }// </editor-fold>    
   
    private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) {                                             
        try {
            timer.stop();
        } catch (Exception ex) { }

        restablecer();
        jPanelGrafica1.removeAll();
        jPanelGrafica1.repaint();
        g = new Grafica(jPanelGrafica1, series, nVer, false);
    }                                             

    private void jButtonCrearRedActionPerformed(java.awt.event.ActionEvent evt) {                                                
        if (jButtonPlay.isEnabled() == false && jButtonPausa.isEnabled() == false) {
            jButtonPlay.setEnabled(true);
            jButtonPausa.setEnabled(true);
            jButtonReset.setEnabled(true);
        }
        actualizar();
        crearRed();
    }                                               


    private void jButtonPlayActionPerformed(java.awt.event.ActionEvent evt) {                                            
        if (jButtonPlay.isEnabled()) {
            jButtonPlay.setEnabled(false);
            jButtonPausa.setEnabled(true);
        }
        actualizar();
        timer = new Timer(FrecuenciaRefresco, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                Calcular();
            }
        });
        timer.start();
    }                                           

    private void jButtonPausaActionPerformed(java.awt.event.ActionEvent evt) {                                             
        if (jButtonPausa.isEnabled()) {
            jButtonPausa.setEnabled(false);
            jButtonPlay.setEnabled(true);
        }
        timer.stop();
    }                                            

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new RedNeuronalG().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButtonCrearRed;
    private javax.swing.JButton jButtonPausa;
    private javax.swing.JButton jButtonPlay;
    private javax.swing.JButton jButtonReset;
    private javax.swing.JLabel jLabelEnlaces;
    private javax.swing.JLabel jLabelFrecuenciaRefresco;
    private javax.swing.JLabel jLabelNeuronas;
    private javax.swing.JLabel jLabelNeuronasMostrar;
    private javax.swing.JLabel jLabelTiempo;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanelGrafica1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSpinner jSpinnerCiclos;
    private javax.swing.JSpinner jSpinnerFrecuenciaRefresco;
    private javax.swing.JSpinner jSpinnerNeuronas;
    private javax.swing.JSpinner jSpinnerNeuronasMostrar;
    private javax.swing.JSpinner jSpinnerNumeroSinapsis;
    // End of variables declaration                   

    private void actualizar() {
        nNeuronas = (int) jSpinnerNeuronas.getValue();
        nEnlaces = (int) jSpinnerNumeroSinapsis.getValue();
        nVer = (int) jSpinnerNeuronasMostrar.getValue();
        ciclos = (int) jSpinnerCiclos.getValue();
        FrecuenciaRefresco = (int) jSpinnerFrecuenciaRefresco.getValue();
        // Control rango maximos minimos jSpinners
        if (nNeuronas <= 1) {
            jSpinnerNeuronas.setValue(1);
        } else if (nEnlaces <= 1) {
            jSpinnerNumeroSinapsis.setValue(1);
        } else if (ciclos <= 0) {
            jSpinnerCiclos.setValue(1);
        } else if (nVer >= nNeuronas){
            jSpinnerNeuronasMostrar.setValue(nNeuronas);
            nVer = nNeuronas;
        }
    }

    private void restablecer() {
        //Configuracion inicial por defecto
        jButtonPlay.setEnabled(false);
        jButtonPausa.setEnabled(false);
        jSpinnerNeuronas.setValue(50);
        jSpinnerNumeroSinapsis.setValue(600);
        jSpinnerCiclos.setValue(100);
        jSpinnerNeuronasMostrar.setValue(5);
    }

    private void crearRed() {
        S = new ArrayList[nNeuronas];
        E = new ArrayList[nNeuronas];
        AleatoriedadCondicionada ac = new AleatoriedadCondicionada();
        Random r1 = new Random();
        int nSalidas = 1; //como minimo debe tener una salida
        int neurona;
        //Crea red neuronal aleatoria
        for (int i = 0; i < S.length; i++) {
            S[i] = new ArrayList();
            E[i] = new ArrayList();
            //Salidas maxima por neurona            
            nSalidas = r1.nextInt(nEnlaces / nNeuronas) + 1;
            for (int j = 0; j < nSalidas; j++) {
                neurona = r1.nextInt(nNeuronas);
                //Aplicación de la Aleatoriedad Condicionada
                neurona = (int) Math.rint(ac.getSalida((double) nNeuronas, neurona));
                if (r1.nextBoolean()) {
                    // Conexion hacia delante
                    neurona = i + neurona;
                    if (neurona > nNeuronas) {
                        neurona = neurona - nNeuronas;
                    }
                } else {
                    // Conexion hacia atras
                    neurona = i - neurona;
                    if (neurona < 0) {
                        neurona = neurona + nNeuronas;
                    }
                }
                //evita repeticiones de enlaces a la misma neurona
                if (S[i].contains(neurona) == false) {
                    S[i].add(neurona);
                }
            }
        }
        //Busqueda enlaces de entrada de cada neurona.
        for (int i = 0; i < S.length; i++) {
            for (int j = 0; j < E.length; j++) {
                if (S[i].contains(j)) {
                    E[j].add(i);
                }
            }
        }
        //Añadiendo Pesos (w) a los enlaces
        w = new ArrayList[nNeuronas];
        int aux = 0;
        for (int i = 0; i < E.length; i++) {
            w[i] = new ArrayList();
            aux = E[i].size();
            for (int j = 0; j < aux; j++) {
                //Rango bipolar entre -1 y 1
                int tmp = r1.nextBoolean() ? 1 : -1;
                w[i].add(r1.nextDouble() * tmp);
            }
        }
        y = new double[nNeuronas];
        //Inicializando valores de salida (y)
        for (int i = 0; i < nNeuronas; i++) {
            y[i] = 1;
        }
        Calcular();
    }

    private void Calcular() {
        series = new XYSeries[nNeuronas];
        //Inicializando array de series
        for (int i = 0; i < nNeuronas; i++) {
            series[i] = new XYSeries("" + i);
        }
        int cont = 0;
        while (cont < (int) jSpinnerCiclos.getValue()) {
            for (int i = 0; i < nNeuronas; i++) {
                double tmp = 0;
                for (int j = 0; j < E[i].size(); j++) {
                    tmp += (y[E[i].get(j)] * w[i].get(j));
                }
                y[i] = Math.tanh(tmp);
                series[i].add(cont, y[i]);
            }
            cont++;
        }
        nVer = (int)jSpinnerNeuronasMostrar.getValue();
        nVer = nVer >= nNeuronas ? nNeuronas:nVer;
        jSpinnerNeuronasMostrar.setValue(nVer);
        g = new Grafica(jPanelGrafica1, series, nVer, true);
    }

}


Código 2 (AleatoriedadCondicionada.java):

package redNeuronalG1;

public class AleatoriedadCondicionada {
    public double getSalida(double x, double y) {
        double c = Math.atan(10);
        return ((Math.atan(((y*100/x)/10)-10)*100/c)+100)*x/100;
    }    
}


Código 3 (Grafica.java):

package redNeuronalG1;

import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Grafica {

    public Grafica(JPanel jPanel1, XYSeries[] series, int mostrar, boolean x) {

        XYSeriesCollection dataset = new XYSeriesCollection();

        //Rango maximo y mínimo del eje Y de la grafica (1 a -1)
        series[0].add(0, 0.999);
        series[0].add(0, -0.999);

        if (x) {
            for (int i = 0; i < mostrar; i++) {
                dataset.addSeries(series[i]);
            }
        }

        JFreeChart chart = ChartFactory.createXYLineChart(
                "Gráfica Red Neuronal",
                "Ciclos ->",
                "Amplitud Señal->",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                false,
                false
        );
        //Mostramos la grafica dentro del jPanel1
        ChartPanel panel = new ChartPanel(chart);
        jPanel1.removeAll();
        jPanel1.setLayout(new java.awt.BorderLayout());
        jPanel1.add(panel);
        jPanel1.validate();
    }

}


Resultado:
































viernes, 12 de diciembre de 2014

Red neuronal artificial (III). Añadiendo pesos a los enlaces y cálculo de salidas.

Una vez creada la estructura básica de la red, voy a ir añadiendo valores aleatorios a los enlaces (pesos - w). Hecho esto ya se puede calcular los valores de salida de cada neurona (y).
Las formulas utilizadas para los cálculos son los mismos que ver referencia.


Código 1 (RedNeuronal1.java): 

package redneuronal1;

import java.util.ArrayList;
import java.util.Random;

public class RedNeuronal1 {

    public static void main(String[] args) {

        int nNeuronas = 9;
        int nEnlaces = 50;

        ArrayList<Integer>[] S = new ArrayList[nNeuronas];
        ArrayList<Integer>[] E = new ArrayList[nNeuronas];

        AleatoriedadCondicionada ac = new AleatoriedadCondicionada();
        Random r1 = new Random();        
        int nSalidas = 1;
        int neurona;

        //Crea red neuronal aleatoria
        for (int i = 0; i < S.length; i++) {
            S[i] = new ArrayList();
            E[i] = new ArrayList();

            //Salidas maxima por neurona            
            nSalidas = r1.nextInt(nEnlaces / nNeuronas) + 1;
            for (int j = 0; j < nSalidas; j++) {

                neurona = r1.nextInt(nNeuronas);

                //Aplicación de la Aleatoriedad Condicionada
                neurona = (int) Math.rint(ac.getSalida(nNeuronas, neurona));
                if (r1.nextBoolean()) {
                    //Conexión hacia delante
                    neurona = i + neurona;
                    if (neurona > nNeuronas) {
                        neurona = neurona - nNeuronas;
                    }
                } else {
                    //Conexión hacia atrás
                    neurona = i - neurona;
                    if (neurona < 0) {
                        neurona = neurona + nNeuronas;
                    }
                }
                //Evitar enlaces repetidos a la misma neurona
                if (S[i].contains(neurona) == false) {
                    S[i].add(neurona);
                }
            }
        }

        //Búsqueda enlaces de entrada de cada neurona
        for (int i = 0; i < S.length; i++) {
            for (int j = 0; j < E.length; j++) {
                if (S[i].contains(j)) {
                    E[j].add(i);
                }
            }
        }

        //Añadiendo Pesos (w) a los enlaces
        ArrayList<Double>[] w = new ArrayList[nNeuronas];
        int aux = 0;
        for (int i = 0; i < E.length; i++) {
            w[i] = new ArrayList();
            aux = E[i].size();
            for (int j = 0; j < aux; j++) {
                w[i].add(Math.rint(r1.nextDouble() * 10000) / 10000);
            }
        }

        //Cálculo de salidas (y)
        //Inicializando valores de salida
        double[] y = new double[nNeuronas];
        for (int i = 0; i < nNeuronas; i++) {
            y[i] = 1.0;
        }

        //Realización de los cálculos (y)
        double tmp = 0;
        for (int i = 0; i < nNeuronas; i++) {
            tmp = 0;
            for (int j = 0; j < E[i].size(); j++) {
                tmp += (y[E[i].get(j)] * w[i].get(j));
            }
            y[i] = Math.rint(Math.tanh(tmp) * 10000) / 10000;
        }

        //Mostrar enlaces de Entrada (E)
        System.out.println("\n* Enlaces entrada:");
        for (int i = 0; i < E.length; i++) {
            System.out.println("Enlaces entradas Neurona [" + i + "]: " + E[i].toString());
        }

        //Mostrar enlaces de Salidas (S)
        System.out.println("\n* Enlaces salida:");
        for (int i = 0; i < S.length; i++) {
            System.out.println("Enlaces salidas Neurona [" + i + "]: " + S[i].toString());
        }

        //Mostrar valor Pesos (w)
        System.out.println("\n* Pesos:");
        for (int i = 0; i < E.length; i++) {
            System.out.println("w[" + i + "]: " + w[i].toString());
        }

        //Mostrar Salidas calculadas (y):
        System.out.println("\n* Salidas:");
        for (int i = 0; i < nNeuronas; i++) {
            System.out.println("y[" + i + "] = " + y[i]);
        }

    }

}


Código 2 (AleatoriedadCondicionada.java):

package redneuronal1;
public class AleatoriedadCondicionada {    
    public double getSalida(double x, double num) {
        double c = Math.atan(10);
        return ((Math.atan(((num*100/x)/10)-10)*100/c)+100)*x/100;
    }
}


Resultado:

run:

* Enlaces entrada:
Enlaces entradas Neurona [0]: [2, 4]
Enlaces entradas Neurona [1]: [1]
Enlaces entradas Neurona [2]: [2, 3]
Enlaces entradas Neurona [3]: [3, 7]
Enlaces entradas Neurona [4]: [0, 4, 6]
Enlaces entradas Neurona [5]: [0, 3]
Enlaces entradas Neurona [6]: [2, 7]
Enlaces entradas Neurona [7]: [5, 7]
Enlaces entradas Neurona [8]: [8]

* Enlaces salida:
Enlaces salidas Neurona [0]: [5, 4]
Enlaces salidas Neurona [1]: [1]
Enlaces salidas Neurona [2]: [0, 2, 6]
Enlaces salidas Neurona [3]: [5, 3, 2]
Enlaces salidas Neurona [4]: [0, 4]
Enlaces salidas Neurona [5]: [7]
Enlaces salidas Neurona [6]: [4]
Enlaces salidas Neurona [7]: [6, 3, 7]
Enlaces salidas Neurona [8]: [8]

* Pesos:
w[0]: [0.8555, 0.6536]
w[1]: [0.819]
w[2]: [0.9977, 0.1134]
w[3]: [0.2289, 0.5195]
w[4]: [0.315, 0.3569, 0.5067]
w[5]: [0.9875, 0.9863]
w[6]: [0.5892, 0.3078]
w[7]: [0.5503, 0.1076]
w[8]: [0.3883]

* Salidas:
y[0] = 0.9068
y[1] = 0.6745
y[2] = 0.8045
y[3] = 0.6342
y[4] = 0.8175
y[5] = 0.9089
y[6] = 0.6537
y[7] = 0.5426
y[8] = 0.3699

BUILD SUCCESSFUL (total time: 0 seconds)


jueves, 11 de diciembre de 2014

Red neuronal artificial (II). Generando estructura de red neuronal aleatoria condicionada.

La siguiente fase y teniendo en cuenta el post anterior creamos nuestra primera estructura de red neuronal aleatoria condicionada. Decimos que es condicionada porque hay más probabilidades de que haya más enlaces de entre neuronas cercanas  que de entre neuronas alejadas.


Ejemplo:

* Propiedades de la red neuronal:

Número de neuronas = 9
Número de enlaces usados = 17
Enlaces aleatorios condicionados por una curva cotangente.


* Posible resultado (aleatorio condicionado):

SALIDAS:
neuroS[0]: [0, 1]
neuroS[1]: [1, 6]
neuroS[2]: [2]
neuroS[3]: [3]
neuroS[4]: [3]
neuroS[5]: [5, 6, 7]
neuroS[6]: [4, 6]
neuroS[7]: [2, 5, 7, 8]
neuroS[8]: [8]

ENTRADAS:
neuroE[0]: [0]
neuroE[1]: [0, 1]
neuroE[2]: [2, 7]
neuroE[3]: [3, 4]
neuroE[4]: [6]
neuroE[5]: [5, 7]
neuroE[6]: [1, 5, 6]
neuroE[7]: [5, 7]
neuroE[8]: [7, 8]


Esquema visual:


























Código 1: (RedNeuronal1.java):

package redneuronal1;

import java.util.ArrayList;
import java.util.Random;

public class RedNeuronal1 {

    public static void main(String[] args) {

        int nNeuronas = 50;
        int nEnlaces = 500;

        ArrayList<Integer>[] neuroS = new ArrayList[nNeuronas];
        ArrayList<Integer>[] neuroE = new ArrayList[nNeuronas];

        AleatoriedadCondicionada ac = new AleatoriedadCondicionada();
        Random r1 = new Random();
        neuroS[0] = new ArrayList();
        int nSalidas;
        int neurona;

        //Crea red neuronal aleatoria
        for (int i = 0; i < neuroS.length; i++) {
            neuroS[i] = new ArrayList();
            neuroE[i] = new ArrayList();
            nSalidas = r1.nextInt(nEnlaces / nNeuronas) + 1;
            for (int j = 0; j < nSalidas; j++) {

                neurona = r1.nextInt(nNeuronas);

                //Aplicación de la Aleatoriedad Condicionada
                neurona = (int) Math.rint(ac.getSalida(nNeuronas, neurona));
                if (r1.nextBoolean()) {
                    //Conexion hacia delante
                    neurona = i + neurona;
                    if (neurona > nNeuronas) {
                        neurona = neurona - nNeuronas;
                    }
                } else {
                    //Conexion hacia atrás
                    neurona = i - neurona;
                    if (neurona < 0) {
                        neurona = neurona + nNeuronas;
                    }
                }
                //evita repeticiones
                if (neuroS[i].contains(neurona) == false) { 
                    neuroS[i].add(neurona); //salida
                }
            }
        }

        //Traspaso entradas a partir de las salidas
        for (int i = 0; i < neuroS.length; i++) {
            for (int j = 0; j < neuroE.length; j++) {
                if (neuroS[i].contains(j)) {
                    neuroE[j].add(i);
                }
            }
        }

        //mostrar resultados
        for (int i = 0; i < neuroS.length; i++) {
            System.out.println("neuroS[" + i + "]: " + neuroS[i].toString());
        }
        System.out.println("\n");
        for (int i = 0; i < neuroE.length; i++) {
            System.out.println("neuroE[" + i + "]: " + neuroE[i].toString());
        }

        //Recuento número de enlaces usados
        int nSinapsis = 0;
        for (int i = 0; i < neuroS.length; i++) {
            nSinapsis += neuroS[i].size();
        }
        System.out.println("\nNúmero de enlaces: " + nSinapsis);

    }

}


Código 2: (AleatoriedadCondicionada.java):

package redneuronal1;

public class AleatoriedadCondicionada {
    double c = Math.atan(10);
    double entrada, salida;

    public double getSalida(double nNeuro, double num) {
        entrada = num * 100 / nNeuro;       
        salida = (Math.atan((entrada / 10) - 10) * 100 / c) + 100;        
        salida = salida * nNeuro / 100;   
        return salida; 
    }

}


Resultado:

neuroS[0]: [9, 0, 30, 47]
neuroS[1]: [6, 1, 2]
neuroS[2]: [5]
neuroS[3]: [0, 35, 26, 8, 2, 6, 7]
neuroS[4]: [4, 49, 13, 6, 27]
neuroS[5]: [23, 41, 5, 49, 47, 6, 2, 35]
neuroS[6]: [29]
neuroS[7]: [7, 1]
neuroS[8]: [16, 10, 26, 1, 0, 8, 13, 9]
neuroS[9]: [9, 14, 10, 0, 6]
neuroS[10]: [22, 10, 12]
neuroS[11]: [13, 5, 29, 11, 17, 18, 16, 9]
neuroS[12]: [44, 30, 1, 13, 9, 11]
neuroS[13]: [14, 21, 15]
neuroS[14]: [14]
neuroS[15]: [38, 10, 14, 16, 15, 13, 7, 8]
neuroS[16]: [23, 14, 16, 21, 13, 17, 15]
neuroS[17]: [19, 47, 23, 16, 7, 14]
neuroS[18]: [18, 5, 36, 31, 17]
neuroS[19]: [18, 46, 3, 22]
neuroS[20]: [47, 40]
neuroS[21]: [21, 16, 23, 20]
neuroS[22]: [19, 25, 16, 6, 15, 21, 27]
neuroS[23]: [17, 22]
neuroS[24]: [22, 23, 21]
neuroS[25]: [33, 26, 23, 22, 25]
neuroS[26]: [24, 26, 25, 23, 34, 27]
neuroS[27]: [40, 24]
neuroS[28]: [1, 31, 23]
neuroS[29]: [25, 26, 33, 17, 28]
neuroS[30]: [33, 30, 35, 27]
neuroS[31]: [49, 38, 33]
neuroS[32]: [32, 29, 30, 34, 39]
neuroS[33]: [30, 49, 35, 44, 31]
neuroS[34]: [34, 36, 29, 47, 40, 48]
neuroS[35]: [34, 35, 42, 17]
neuroS[36]: [36, 40]
neuroS[37]: [5, 37]
neuroS[38]: [41, 8]
neuroS[39]: [7, 38, 37]
neuroS[40]: [40, 43, 41, 39, 42, 35]
neuroS[41]: [40]
neuroS[42]: [40, 49, 5, 36, 24, 6, 38]
neuroS[43]: [49]
neuroS[44]: [45, 49, 21, 41, 43, 48]
neuroS[45]: [47, 1, 45]
neuroS[46]: [35, 34, 3, 46]
neuroS[47]: [48, 1, 5, 37]
neuroS[48]: [48, 2, 44, 37]
neuroS[49]: [41]


neuroE[0]: [0, 3, 8, 9]
neuroE[1]: [1, 7, 8, 12, 28, 45, 47]
neuroE[2]: [1, 3, 5, 48]
neuroE[3]: [19, 46]
neuroE[4]: [4]
neuroE[5]: [2, 5, 11, 18, 37, 42, 47]
neuroE[6]: [1, 3, 4, 5, 9, 22, 42]
neuroE[7]: [3, 7, 15, 17, 39]
neuroE[8]: [3, 8, 15, 38]
neuroE[9]: [0, 8, 9, 11, 12]
neuroE[10]: [8, 9, 10, 15]
neuroE[11]: [11, 12]
neuroE[12]: [10]
neuroE[13]: [4, 8, 11, 12, 15, 16]
neuroE[14]: [9, 13, 14, 15, 16, 17]
neuroE[15]: [13, 15, 16, 22]
neuroE[16]: [8, 11, 15, 16, 17, 21, 22]
neuroE[17]: [11, 16, 18, 23, 29, 35]
neuroE[18]: [11, 18, 19]
neuroE[19]: [17, 22]
neuroE[20]: [21]
neuroE[21]: [13, 16, 21, 22, 24, 44]
neuroE[22]: [10, 19, 23, 24, 25]
neuroE[23]: [5, 16, 17, 21, 24, 25, 26, 28]
neuroE[24]: [26, 27, 42]
neuroE[25]: [22, 25, 26, 29]
neuroE[26]: [3, 8, 25, 26, 29]
neuroE[27]: [4, 22, 26, 30]
neuroE[28]: [29]
neuroE[29]: [6, 11, 32, 34]
neuroE[30]: [0, 12, 30, 32, 33]
neuroE[31]: [18, 28, 33]
neuroE[32]: [32]
neuroE[33]: [25, 29, 30, 31]
neuroE[34]: [26, 32, 34, 35, 46]
neuroE[35]: [3, 5, 30, 33, 35, 40, 46]
neuroE[36]: [18, 34, 36, 42]
neuroE[37]: [37, 39, 47, 48]
neuroE[38]: [15, 31, 39, 42]
neuroE[39]: [32, 40]
neuroE[40]: [20, 27, 34, 36, 40, 41, 42]
neuroE[41]: [5, 38, 40, 44, 49]
neuroE[42]: [35, 40]
neuroE[43]: [40, 44]
neuroE[44]: [12, 33, 48]
neuroE[45]: [44, 45]
neuroE[46]: [19, 46]
neuroE[47]: [0, 5, 17, 20, 34, 45]
neuroE[48]: [34, 44, 47, 48]
neuroE[49]: [4, 5, 31, 33, 42, 43, 44]

Número de enlaces: 207

martes, 9 de diciembre de 2014

Red neuronal artificial (I). Generando conexiones aleatorias condicionadas.

Este es el primer post de una serie de posts que voy a ir creando sobre redes neuronales artificiales. El fin último es conseguir crear una red neuronal artificial básica, con su respectiva estructura conexial entre neuronas, sus entradas y salidas y estudiar así su comportamiento según los estímulos que le vayamos dando.

En este primer apartado la idea es conseguir que los enlaces entre neuronas cercanas sean más probables que las alejadas entre sí. Es decir vamos a crear una generador de números aleatorios con la propiedad de que haya más probabilidades de que salgan más números con valores bajos que de valores altos. De esta forma obtenemos la base para crear los enlaces entre neuronas de uma manera más parecida a una estructura de red neuronal biológica.

Para conseguir el objetivo me he basado en la gráfica de la curvatura de una linea cotangente. El número aleatorio que le demos (eje X), nos lo convierte en otro número de valor más reducido (eje Y).

Ejemplo visual: si le damos una entrada de valor 80, teniendo en cuenta la curvatura de la gráfica nos debería devolver un valor de 25 aproximadamente.



























Código: 

package atan;

import java.util.Scanner;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Atan {

    public static void main(String[] args) {

        XYSeries series = new XYSeries("Atan (x) -> -10 to 0");

        // Introduccion de datos
        double c = Math.abs(Math.atan(-10));
        double esc; // escala %

        for (int i = 0; i < 11; i++) {
            esc = Math.atan(i - 10) * 100 / c;
            series.add(i * 10, esc + 100);
        }

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        JFreeChart chart = ChartFactory.createXYLineChart(
                "Escala aTangente", // Título
                "Número Entrada (x) ->", // Etiqueta Coordenada X
                "Número Salida  (y) ->", // Etiqueta Coordenada Y
                dataset, // Datos
                PlotOrientation.VERTICAL,
                false, 
                false,
                false
        );

        // Mostramos la grafica en pantalla
        ChartFrame frame = new ChartFrame("Ejemplo Grafica Lineal", chart);
        frame.pack();
        frame.setVisible(true);
        
        for (int i = 0; i < 4; i++) {
            System.out.println("\nIngrese número 1 al 100");
            Scanner entrada = new Scanner(System.in);
            double num = entrada.nextInt();

            esc = Math.atan((num / 10) - 10) * 100 / c;

            System.out.println("entrada = " + num);
            System.out.println("salida  = " + (esc + 100));
        }

    }

}


Resutado:

run:

Ingrese número 1 al 100
80
entrada = 80.0
salida  = 24.741493404500787

Ingrese número 1 al 100
40
entrada = 40.0
salida  = 4.451008982239117

Ingrese número 1 al 100
99
entrada = 99.0
salida  = 93.22501681994844

Ingrese número 1 al 100

...


Nota:  Hay la hipótesis de que obteniendo la gráfica de una red neuronal biológica mediante electrodos y siguiendo el mismo procedimiento anterior (aleatoriedad condicionada) se podría recrear de manera aproximada dicha estructura artificialmente en tiempo récord. Se ha recreado la red neuronal de un gusano compuesto de 302 neuronas y 6.393 conexiones siguiendo las conexiones entre ellas una a una (se tardó más de una década en conseguirlo). Un ser más complejo como el ser humano que contiene 100 mil millones de neuronas y billones de enlaces entre sí se haría impracticable a no ser que se obtenga la gráfica de curvatura neuronal y aplicándole el procedimiento aquí expuesto.

jueves, 23 de octubre de 2014

Gráficas con JFreeChart (VIII). Ejemplo práctico basado en la Teoría del Caos.

Este ejemplo nos proponemos a demostrar gráficamente la rica conducta caótica de una ecuación demográfica interada.
Para ello necesitamos que la gráfica se vaya actualizando automáticamente a medida que vayamos modificando los distintos valores de entrada de la ecuación.

Empezamos por crear un nuevo proyecto de tipo JFrame y en modo de diseño le agregamos un jPanel para mostrar la gráfica. También añadimos 4 jSpinner con sus correspondientes jLabels y un jButton para restablecer las entradas a valores predeterminados.
Debería quedar algo parecido a eso:




Código:

package freejchartpanel1;

import javax.swing.JOptionPane;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Ventana1 extends javax.swing.JFrame {

    public double k;
    public double poblacion;
    public double tasaNatalidad;
    public int generaciones;

    public Ventana1() {
        initComponents();
        restablecer();
        actualizar();
    }

    
    private void initComponents() { ... }// Aquí va código generado por Netbeans

    private void jSpinnerPoblacionInicialStateChanged(javax.swing.event.ChangeEvent evt) {                                                     
        actualizar();
        ejecutar();
    }

    private void jSpinnerCapacidadCargaStateChanged(javax.swing.event.ChangeEvent evt) {                                                   
        actualizar();
        ejecutar();
    } 

    private void jSpinnerNatalidadStateChanged(javax.swing.event.ChangeEvent evt) {                                              
        actualizar();
        ejecutar();
    }                                              

    private void jSpinnerGeneracionesStateChanged(javax.swing.event.ChangeEvent evt) {                                                 
        actualizar();
        ejecutar();
    }                                                 

    private void jButtonRestablecerActionPerformed(java.awt.event.ActionEvent evt) {                                                  
        restablecer();
    }                                                  

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Ventana1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButtonRestablecer;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JSpinner jSpinnerCapacidadCarga;
    private javax.swing.JSpinner jSpinnerGeneraciones;
    private javax.swing.JSpinner jSpinnerNatalidad;
    private javax.swing.JSpinner jSpinnerPoblacionInicial;
    // End of variables declaration                   

    private void actualizar() {

        k = Double.parseDouble(jSpinnerCapacidadCarga.getValue().toString());
        poblacion = Double.parseDouble(jSpinnerPoblacionInicial.getValue().toString());
        tasaNatalidad = Double.parseDouble(jSpinnerNatalidad.getValue().toString()) / 100;
        generaciones = Integer.parseInt(jSpinnerGeneraciones.getValue().toString());

        // Control rango maximos minimos jSpinners
        if (k <= 1) {
            jSpinnerCapacidadCarga.setValue(1);
        } else if (poblacion >= k) {
            jSpinnerPoblacionInicial.setValue(k);
        } else if (poblacion <= 1) {
            jSpinnerPoblacionInicial.setValue(1);
        } else if (tasaNatalidad <= 0) {
            jSpinnerNatalidad.setValue(0);
        } else if (generaciones <= 0) {
            jSpinnerGeneraciones.setValue(0);
        }

    }

    private void restablecer() {

        jSpinnerCapacidadCarga.setValue(10000);
        jSpinnerPoblacionInicial.setValue(7000);
        jSpinnerNatalidad.setValue(120); // %
        jSpinnerGeneraciones.setValue(30);

    }

    private void ejecutar() {

        int extincion = 0;

        XYSeries series = new XYSeries("");

        for (int i = 0; i < generaciones; i++) {
            series.add(i, poblacion);
            poblacion = (poblacion * tasaNatalidad * (k - poblacion)) / k;
            if (poblacion <= 0) {
                extincion = i + 1;
                series.add(i + 1, 0);
                break;
            }
        }

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        JFreeChart chart = ChartFactory.createXYLineChart(
                "Índice Demográfico",
                "Generación ->",
                "Población ->",
                dataset,
                PlotOrientation.VERTICAL,
                false,
                false,
                false
        );

        // Mostramos la grafica dentro del jPanel1
        ChartPanel panel = new ChartPanel(chart);
        jPanel1.removeAll();
        jPanel1.setLayout(new java.awt.BorderLayout());
        jPanel1.add(panel);
        jPanel1.validate();

        if (extincion != 0) {
            JOptionPane.showMessageDialog(null, "Extinción en la Generación " + (extincion));
        }

    }

}


Resultado:



Con la tecnología de Blogger.