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.

miércoles, 17 de diciembre de 2014

Red neuronal artificial (V): Añadiendo entradas manualmente en tiempo de ejecución.

Añadir entradas en una red neuronal manualmente y en tiempo de ejecución podría ser considerado como el órgano de los sentidos (vista, tacto...). Cuando la neurona recibe la acción directa del "medio externo", el estímulo recibido afectará a los valores de las salidas de la red. Ese cambio se verá reflejado en la gráfica.


Primero añadiré al proyecto un jTable1 de 4 columnas con estas características:

Title    Type     Editable
Act      Boolean     V 
Id       Integer     -
Entrada  Float       V
Salida   Double      -



























Código (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 javax.swing.table.DefaultTableModel;
import org.jfree.data.xy.XYSeries;

public class RedNeuronalG extends javax.swing.JFrame {

    int nNeuronas;
    int nEnlaces;
    int ciclos = 1;  
    
    ArrayList<Integer>[] E;
    ArrayList<Integer>[] S;
    ArrayList<Double>[] w;     
    double[] y;
    
    Random r1;
    Timer timer;
    
    Grafica g;
    XYSeries[] series;    
    DefaultTableModel model;

    public RedNeuronalG() {
        initComponents();
        model = (DefaultTableModel) jTable1.getModel();
        g = new Grafica(jTable1, jPanelGrafica1, series, false);
        restablecer();
        actualizar();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    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(jTable1, jPanelGrafica1, series, false);
    }
    
    private void jButtonGenerarActionPerformed(java.awt.event.ActionEvent evt) {                                               
        if (jButtonPlay.isEnabled() == false && jButtonDetener.isEnabled() == false) {
            jButtonPlay.setEnabled(true);
            jButtonDetener.setEnabled(true);
            jButtonReset.setEnabled(true);
        }
        actualizar();
        ejecutar();
    }                                              


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

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

    private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {                                     
        Calcular();
    }                                    

    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 jButtonDetener;
    private javax.swing.JButton jButtonGenerar;
    private javax.swing.JButton jButtonPlay;
    private javax.swing.JButton jButtonReset;
    private javax.swing.JLabel jLabelCiclos;
    private javax.swing.JLabel jLabelNumeroNeuronas;
    private javax.swing.JLabel jLabelNumeroSinapsis;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanelGrafica1;
    private javax.swing.JPanel jPanelTable1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSpinner jSpinnerCiclos;
    private javax.swing.JSpinner jSpinnerNumeroEnlaces;
    private javax.swing.JSpinner jSpinnerNumeroNeuronas;
    private javax.swing.JTable jTable1;
    // End of variables declaration                   

    private void actualizar() {

        //Actualizar tamaño del jTable
        int nFilas = (int) jSpinnerNumeroNeuronas.getValue();
        while (nFilas != jTable1.getRowCount()) {
            if (nFilas > jTable1.getRowCount()) {
                model.addRow(new Object[]{false, null, null, null, null, null});
            } else if (nFilas < jTable1.getRowCount()) {
                model.removeRow(jTable1.getRowCount() - 1);
            }
        }

        //Actualizar valores variables de entrada
        nNeuronas = (int) jSpinnerNumeroNeuronas.getValue();
        nEnlaces = (int) jSpinnerNumeroEnlaces.getValue();
        ciclos = (int) jSpinnerCiclos.getValue();

        // Control rango maximos minimos jSpinners
        if (nNeuronas <= 1) {
            jSpinnerNumeroNeuronas.setValue(1);
        } else if (nEnlaces <= 1) {
            jSpinnerNumeroEnlaces.setValue(1);
        } else if (ciclos <= 0) {
            jSpinnerCiclos.setValue(1);
        }

    }

    private void restablecer() {

        //Configuracion inicial por defecto
        jButtonPlay.setEnabled(false);
        jButtonDetener.setEnabled(false);

        jSpinnerNumeroNeuronas.setValue(50);
        jSpinnerNumeroEnlaces.setValue(300);
        jSpinnerCiclos.setValue(100);

        for (int i = 0; i < jTable1.getRowCount(); i++) {
            jTable1.setValueAt(false, i, 0);
            jTable1.setValueAt(null, i, 2);
        }

        jTable1.setValueAt(true, 0, 0);
        jTable1.setValueAt(true, 1, 0);
        jTable1.setValueAt(true, 2, 0);

    }

    private void ejecutar() {

        S = new ArrayList[nNeuronas];
        E = new ArrayList[nNeuronas];

        AleatoriedadCondicionada ac = new AleatoriedadCondicionada();
        r1 = new Random();
        int nSalidas = 1; //una salida como mínimo
        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()) {
                    //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;
                    }
                }
                //evita repeticiones de enlaces a la misma neurona
                if (S[i].contains(neurona) == false) {
                    S[i].add(neurona);
                }
            }
        }

        //agrega los enlaces que faltan para llegar al número exacto
        int recuento = RecuentoEnlaces();
        while (recuento < nEnlaces) {
            int aux = r1.nextInt(nNeuronas);
            int aux2 = r1.nextInt(nNeuronas);
            S[aux].add(aux2);
            recuento++;
        }

        RecuentoEnlaces();

        //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);
            }
        }

        //Calculo de salidas     
        //Inicializando valores de salida (y)
        y = new double[nNeuronas];
        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));
                }
                
                //entrada manual de datos
                tmp = AgregarEntradas(i, tmp);

                y[i] = Math.tanh(tmp);
                series[i].add(cont, y[i]);
            }
            cont++;
        }
        
        FillTable1(); // Llenar jTable1 con los datos actualizados
        g = new Grafica(jTable1, jPanelGrafica1, series, true);
    }

    private void FillTable1() {
        for (int i = 0; i < nNeuronas; i++) {
            jTable1.setValueAt(i, i, 1); // Id neurona
            jTable1.setValueAt(y[i], i, 3); // Resultado salida
        }
    }

    private int RecuentoEnlaces() {
        int nEnlaces = 0;
        for (ArrayList<Integer> S1 : S) {
            nEnlaces += S1.size();
        }
        return nEnlaces;
    }

    private double AgregarEntradas(int i, double tmp) {
        if (jTable1.getValueAt(i, 2) != null) {
            tmp += (float) jTable1.getValueAt(i, 2);
        }
        return tmp;
    }


}


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 javax.swing.JTable;
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(JTable jTable1, JPanel jPanel1, XYSeries[] series, boolean x) {

        XYSeriesCollection dataset = new XYSeriesCollection();

        int aux = jTable1.getRowCount();

        if (x) {
            //se agrega a la gráfica las neuronas marcadas con el checkbox del jTable1
            for (int i = 0; i < aux; i++) {
                if ((boolean) jTable1.getValueAt(i, 0)) {
                    dataset.addSeries(series[i]);
                }
            }
        }

        JFreeChart chart = ChartFactory.createXYLineChart(
                "",
                "",
                "",
                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();
    }


}


No hay comentarios:

Publicar un comentario

Con la tecnología de Blogger.