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, 10 de junio de 2019
Perceptrón multicapa. Propagación hacia adelante.
Descripción:
En base a los valores de entrada Dxx (dataset), Wxxx (pesos) y WBxx (bias pesos), se visualiza la base conceptual para el cálculo de las salidas de las neuronas (Yxx) de una red neuronal tipo perceptrón multicapa. Todo ese proceso se le llama propagación hacia delante.
Nomenclatura:
Y[k][j]: Salida neurona (capa, posición j-enésima)
W[k][j][i]: Peso (capa, neurona destino, neurona origen)
WB[k][j]: Pesos Bias (capa, posición j-enésima)
F: Función Activación
Dataset:
D[row][col]: Dataset (fila, columna)
0 1 2 col(n)
0 D00 D01 D02 .
1 D10 D11 D12 .
2 D20 D21 D22 .
. . . . .
row(n)
Código Java:
package forward;
import java.util.ArrayList;
import java.util.List;
public class Forward {
public static void main(String[] args) {
//sketch: num neuronas
List<Integer> nN = new ArrayList<>();
nN.add(2);
nN.add(3);
nN.add(2);
nN.add(1);
int r = 0; // num. registro del dataset
int nK = nN.size(); // num. de capas = 4
int nE = nN.get(0); // num. de entradas = 2
int nS = nN.get(nK - 1); // num. de salidas = 1
String tmp;
// 0.0:-------------------------------------------------------------------
System.out.println("Forward:\n");
int k = 1;
for (int j = 0; j < nN.get(k); j++) {
tmp = "";
for (int i = 0; i < nE; i++) {
tmp += String.format("( D[%d][%d] * W[%d][%d][%d] ) + ", r, i, k, j, i);
}
System.out.format("Y[%d][%d] = F{ %s( -1 * WB[%d][%d] ) }\n", k, j, tmp, k, j);
}
// 0.1:-------------------------------------------------------------------
System.out.println("");
for (k = 2; k < nK; k++) {
for (int j = 0; j < nN.get(k); j++) {
tmp = "";
for (int i = 0; i < nN.get(k - 1); i++) {
tmp += String.format("( Y[%d][%d] * W[%d][%d][%d] ) + ", k - 1, i, k, j, i);
}
System.out.format("Y[%d][%d] = F{ %s( -1 * WB[%d][%d] ) }\n", k, j, tmp, k, j);
}
System.out.println("");
}
}
}
Resultado:
run:
Forward:
Y[1][0] = F{ ( D[0][0] * W[1][0][0] ) + ( D[0][1] * W[1][0][1] ) + ( -1 * WB[1][0] ) }
Y[1][1] = F{ ( D[0][0] * W[1][1][0] ) + ( D[0][1] * W[1][1][1] ) + ( -1 * WB[1][1] ) }
Y[1][2] = F{ ( D[0][0] * W[1][2][0] ) + ( D[0][1] * W[1][2][1] ) + ( -1 * WB[1][2] ) }
Y[2][0] = F{ ( Y[1][0] * W[2][0][0] ) + ( Y[1][1] * W[2][0][1] ) + ( Y[1][2] * W[2][0][2] ) + ( -1 * WB[2][0] ) }
Y[2][1] = F{ ( Y[1][0] * W[2][1][0] ) + ( Y[1][1] * W[2][1][1] ) + ( Y[1][2] * W[2][1][2] ) + ( -1 * WB[2][1] ) }
Y[3][0] = F{ ( Y[2][0] * W[3][0][0] ) + ( Y[2][1] * W[3][0][1] ) + ( -1 * WB[3][0] ) }
BUILD SUCCESSFUL (total time: 0 seconds)
domingo, 21 de abril de 2019
Crear una tabla (dataset) usando listas.
En Java no existe el concepto de Listas Multidimensionales. Para ello mediante código se puede simular listas multidimensionales creando listas dentro de otras listas:
List<List<Double>> dataset1 = new ArrayList<List<Double>>();
En el ejemplo se crea una tabla de 3x10 mediante listas con la que se llenará con valores numéricos para luego imprimirlo en pantalla.
Código (DataSets1.java):
package datasets1;
import java.util.ArrayList;
import java.util.List;
public class DataSets1 {
public static void main(String[] args) {
//Dataset 2d
List<List<Double>> dataset1 = new ArrayList<List<Double>>();
//Agregar 3 sublistas (columnas)
for (int i = 0; i < 3; i++) {
dataset1.add(new ArrayList<Double>());
}
/*
@ Añadir datos al dataset (suma)
*/
//operando 1
dataset1.get(0).add(48.0);
dataset1.get(0).add(1.0);
dataset1.get(0).add(41.0);
dataset1.get(0).add(6.0);
dataset1.get(0).add(5.0);
dataset1.get(0).add(18.0);
dataset1.get(0).add(35.0);
dataset1.get(0).add(2.0);
dataset1.get(0).add(44.0);
dataset1.get(0).add(24.0);
//operando 2
dataset1.get(1).add(33.0);
dataset1.get(1).add(38.0);
dataset1.get(1).add(25.0);
dataset1.get(1).add(27.0);
dataset1.get(1).add(42.0);
dataset1.get(1).add(12.0);
dataset1.get(1).add(39.0);
dataset1.get(1).add(17.0);
dataset1.get(1).add(14.0);
dataset1.get(1).add(37.0);
//resultado 1
dataset1.get(2).add(81.0);
dataset1.get(2).add(39.0);
dataset1.get(2).add(66.0);
dataset1.get(2).add(33.0);
dataset1.get(2).add(47.0);
dataset1.get(2).add(30.0);
dataset1.get(2).add(74.0);
dataset1.get(2).add(19.0);
dataset1.get(2).add(58.0);
dataset1.get(2).add(61.0);
//imprimir dataset1
System.out.println("'operando1', 'operando2', 'resultado1'");
for (int i = 0; i <= dataset1.get(0).size() - 1; i++) {
for (int j = 0; j < dataset1.size(); j++) {
System.out.print(dataset1.get(j).get(i) + ";\t");
}
System.out.println("");
}
}
}
Resultado:
run:
'operando1', 'operando2', 'resultado1'
48.0; 33.0; 81.0;
1.0; 38.0; 39.0;
41.0; 25.0; 66.0;
6.0; 27.0; 33.0;
5.0; 42.0; 47.0;
18.0; 12.0; 30.0;
35.0; 39.0; 74.0;
2.0; 17.0; 19.0;
44.0; 14.0; 58.0;
24.0; 37.0; 61.0;
BUILD SUCCESSFUL (total time: 0 seconds)
List<List<Double>> dataset1 = new ArrayList<List<Double>>();
En el ejemplo se crea una tabla de 3x10 mediante listas con la que se llenará con valores numéricos para luego imprimirlo en pantalla.
Código (DataSets1.java):
package datasets1;
import java.util.ArrayList;
import java.util.List;
public class DataSets1 {
public static void main(String[] args) {
//Dataset 2d
List<List<Double>> dataset1 = new ArrayList<List<Double>>();
//Agregar 3 sublistas (columnas)
for (int i = 0; i < 3; i++) {
dataset1.add(new ArrayList<Double>());
}
/*
@ Añadir datos al dataset (suma)
*/
//operando 1
dataset1.get(0).add(48.0);
dataset1.get(0).add(1.0);
dataset1.get(0).add(41.0);
dataset1.get(0).add(6.0);
dataset1.get(0).add(5.0);
dataset1.get(0).add(18.0);
dataset1.get(0).add(35.0);
dataset1.get(0).add(2.0);
dataset1.get(0).add(44.0);
dataset1.get(0).add(24.0);
//operando 2
dataset1.get(1).add(33.0);
dataset1.get(1).add(38.0);
dataset1.get(1).add(25.0);
dataset1.get(1).add(27.0);
dataset1.get(1).add(42.0);
dataset1.get(1).add(12.0);
dataset1.get(1).add(39.0);
dataset1.get(1).add(17.0);
dataset1.get(1).add(14.0);
dataset1.get(1).add(37.0);
//resultado 1
dataset1.get(2).add(81.0);
dataset1.get(2).add(39.0);
dataset1.get(2).add(66.0);
dataset1.get(2).add(33.0);
dataset1.get(2).add(47.0);
dataset1.get(2).add(30.0);
dataset1.get(2).add(74.0);
dataset1.get(2).add(19.0);
dataset1.get(2).add(58.0);
dataset1.get(2).add(61.0);
//imprimir dataset1
System.out.println("'operando1', 'operando2', 'resultado1'");
for (int i = 0; i <= dataset1.get(0).size() - 1; i++) {
for (int j = 0; j < dataset1.size(); j++) {
System.out.print(dataset1.get(j).get(i) + ";\t");
}
System.out.println("");
}
}
}
Resultado:
run:
'operando1', 'operando2', 'resultado1'
48.0; 33.0; 81.0;
1.0; 38.0; 39.0;
41.0; 25.0; 66.0;
6.0; 27.0; 33.0;
5.0; 42.0; 47.0;
18.0; 12.0; 30.0;
35.0; 39.0; 74.0;
2.0; 17.0; 19.0;
44.0; 14.0; 58.0;
24.0; 37.0; 61.0;
BUILD SUCCESSFUL (total time: 0 seconds)
lunes, 17 de diciembre de 2018
Graficando red neuronal (perceptrón).
Desde Netbeans en modo diseño se añaden los componentes siguiendo esta estructura:
-----------------------------------------------------------------
. JFrame (title: "Graficando perceptrón")
. jPanel1 (aqui se graficará la red neuronal)
. jToolBar1 (barra de opciones)
. jLabel1 (texto: "Estructura")
. jTextField1 (texto: "2,4,4,1")
. jButton1 (texto: "Graficar")
. jButton2 (texto: "Limpiar")
-----------------------------------------------------------------
Código 1 (Muro.java):
package centrar;
public class Muro extends javax.swing.JFrame {
public Muro() {
initComponents();
this.setLocationRelativeTo(null);
}
private void initComponents() { ... } // <- código generado automáticament por Netbeans
private void jButtonGraficarActionPerformed(java.awt.event.ActionEvent evt) {
Dibujar t = new Dibujar(jPanel1.getGraphics(), jPanel1.getWidth(), jPanel1.getHeight(), jTextField1.getText());
}
private void jButtonLimpiarActionPerformed(java.awt.event.ActionEvent evt) {
this.jPanel1.repaint();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Muro().setVisible(true);
}
});
}
private javax.swing.JButton jButtonGraficar;
private javax.swing.JButton jButtonLimpiar;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
private javax.swing.JToolBar.Separator jSeparator1;
private javax.swing.JToolBar.Separator jSeparator2;
private javax.swing.JTextField jTextField1;
private javax.swing.JToolBar jToolBar1;
}
Código 2 (Dibujar.java):
package centrar;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.util.ArrayList;
import java.util.List;
public class Dibujar {
Graphics g;
Graphics2D g2;
public Dibujar(Graphics g, int width, int height, String estruct) {
g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.BLACK);
// tipos grosores pinceles
Stroke stroke02 = new BasicStroke(0.2f);
Stroke stroke04 = new BasicStroke(0.4f);
g2.setStroke(stroke02);
// añadir datos estructura perceptrón
List<Integer> estructura = new ArrayList<>();
for (String aux1 : estruct.split(",")) {
estructura.add(Integer.parseInt(aux1));
}
int maxX = estructura.size();
int maxY = maximo(estructura);
int nParticionesX = maxX + 2; // se suma 2 para margen superior e inferior
int nParticionesY = maxY + 2; // se suma 2 para margen superior e inferior
int uX = width / nParticionesX;
int uY = height / nParticionesY;
float uSeparadorX = (nParticionesX - estructura.size()) / 2f;
float uSeparadorY;
int posIniX = (int) Math.round(uX * uSeparadorX);
int posIniY;
int[][][] recopilador = new int[maxX][maxY][2]; // k, x, y
// capa 0: pre-logical posiciones
for (int x = 0; x < estructura.size(); x++) {
for (int y = 0; y < estructura.get(x); y++) {
uSeparadorY = (nParticionesY - estructura.get(x)) / 2f;
posIniY = (int) Math.round(uY * uSeparadorY);
recopilador[x][y][0] = (posIniX + (int) uX * x) + (int) (uX / 2);
recopilador[x][y][1] = (posIniY + (int) uY * y) + (int) (uY / 2);
}
}
// capa 1: graficar neuronas
int radio = (int) Math.round(uY / 2f);
for (int x = 0; x < estructura.size(); x++) {
for (int y = 0; y < estructura.get(x); y++) {
centrarCirculo(g2, recopilador[x][y][0], recopilador[x][y][1], radio);
}
}
// capa 2: graficar enlaces
int x1, y1, x2, y2;
g2.setColor(Color.DARK_GRAY);
g2.setStroke(stroke04);
for (int x = 0; x < estructura.size() - 1; x++) {
for (int y = 0; y < estructura.get(x); y++) {
for (int k = 0; k < estructura.get(x + 1); k++) {
x1 = recopilador[x][y][0];
y1 = recopilador[x][y][1];
x2 = recopilador[x + 1][k][0];
y2 = recopilador[x + 1][k][1];
g2.drawLine(x1, y1, x2, y2);
}
}
}
}
private void centrarCirculo(Graphics g2, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g2.fillOval(x, y, r, r);
}
/* Busca número mayor del listado de la estructura
* Utilizado para acomodar la gráfica al tamaño de la ventana
*/
private int maximo(List<Integer> estructura) {
int max = 0;
for (int i = 0; i < estructura.size(); i++) {
if (estructura.get(i) >= max) {
max = estructura.get(i);
}
}
return max;
}
}
Resultado:
sábado, 8 de diciembre de 2018
Graficando tablero de ajedrez.
Desde Netbeans y en modo diseño se agrega un jFrame con la opción marcada "Grid Layout" y en propiedades activamos el check [v] undecorated. Se añade luego un jPanel que servirá de lienzo para graficar el tablero.
Para las figuras he instalado una fuente gratuita llamada "Chess Cases".
Código1 (Tabla.java):
package ajedrez;
public class Tabla extends javax.swing.JFrame {
public Tabla() {
initComponents();
this.setBounds(0, 0, 512, 512);
this.setLocationRelativeTo(null);
this.jPanel1.setBounds(0, 0, 512, 512);
this.jPanel1.setBackground(new java.awt.Color(190, 190, 190));
}
private void initComponents() { ... } // Código generado automáticamente por Netbeans.
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
Dibujar t = new Dibujar(jPanel1.getGraphics(), this.jPanel1.getWidth());
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Tabla().setVisible(true);
}
});
}
private javax.swing.JPanel jPanel1;
}
Código2 (Dibujar.java):
package ajedrez;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Stroke;
public class Dibujar {
Rectangle rect = new Rectangle();
public Dibujar(Graphics g, int xy) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.GRAY);
// Crea tablero
int casillas = 8;
int radio = xy / casillas;
for (int j = 0; j < casillas; j++) {
for (int i = 0; i < casillas; i++) {
if ((j % 2) != 0) {
g2.fillRect(2 * radio * i, radio * j, radio, radio);
}
if ((i % 2 != 0)) {
g2.fillRect(radio * i, 2 * radio * j, radio, radio);
}
}
}
// Remarcar contorno
Stroke pincel = new BasicStroke(2f);
g2.setColor(Color.BLACK);
g2.setStroke(pincel);
g2.drawRect(0, 0, xy - 1, xy - 1);
// Piezas
Font font = new Font("Chess Cases", Font.TRUETYPE_FONT, 46);
String piezas = "tmvwlvmt";
for (int i = 0; i < casillas; i++) {
// Inserción piezas negras
g.setColor(Color.BLACK);
rect.setBounds(radio * i, 0, radio, radio);
centrarTexto(g, piezas.charAt(i) + "", rect, font);
rect.setBounds(radio * i, radio, radio, radio);
centrarTexto(g, "o", rect, font);
// Inserción piezas blancas
g.setColor(Color.WHITE);
rect.setBounds(radio * i, radio * 7, radio, radio);
centrarTexto(g, piezas.charAt(i) + "", rect, font);
rect.setBounds(radio * i, radio * 6, radio, radio);
centrarTexto(g, "o", rect, font);
}
}
private void centrarTexto(Graphics g, String texto, Rectangle r, Font f) {
FontMetrics medir = g.getFontMetrics(f);
int x = r.x + (r.width - medir.stringWidth(texto)) / 2;
int y = r.y + ((r.height - medir.getHeight()) / 2) + medir.getAscent();
g.setFont(f);
g.drawString(texto, x, y);
}
}
Resultado:
Suscribirse a:
Entradas (Atom)
Con la tecnología de Blogger.