Este código es traducido de su original para el MindStorm RXC. Es un algoritmo de propagación hacia atras "Backpropagation Network". Nos tomamos el trabajo de
traducirlo para el nuevo modelo. Disfrutenlo.
El código y su explicación se encuentran en la siguiente dirección:
http://www.javaworld.com/javaworld/jw-05-2005/jw-0516-lego.html
import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.Motor;
import lejos.nxt.SensorConstants;
import lejos.nxt.SensorPort;
import lejos.nxt.Sound;
public class AlgoritmoAprendizaje {
public static LegoMindstormBP bpn = new LegoMindstormBP();
public static void main(String args[]) throws InterruptedException
{
int i, white;
int inp[] = {0,0,0};
int out[] = {0,0};
Sound.beep();
LCD.drawString( "Train",10,10 );
// Train bpn 500 epochs, sit down and wait about 5 minutes!
for(i=0;i<500;i++) {
bpn.train(1);
LCD.drawInt( bpn.trainedEpochs,0,10);
}
SensorPort.S1.setTypeAndMode(SensorConstants.TYPE_SWITCH,
SensorConstants.MODE_BOOLEAN );
SensorPort.S2.setTypeAndMode(SensorConstants.TYPE_SWITCH,
SensorConstants.MODE_RAW );
SensorPort.S3.setTypeAndMode(SensorConstants.TYPE_LIGHT_ACTIVE,
SensorConstants.MODE_BOOLEAN );
Sound.twoBeeps();
SensorPort.S2.activate();
white = SensorPort.S2.readRawValue();
Motor.A.setPower(1);
Motor.C.setPower(1);
Sound.twoBeeps();
while( !Button.ENTER.isPressed() ) {
LCD.drawInt(SensorPort.S2.readRawValue(),0,20 );
if( SensorPort.S1.readBooleanValue() )
inp[0] = 1; // Sensor 1 on
else
inp[0] = 0; // Sensor 1 off
if( SensorPort.S2.readRawValue() > white + 50 )
inp[1] = 1; // Sensor 2 over black floor
else
inp[1] = 0; // Sensor 2 over white floor
if( SensorPort.S3.readBooleanValue() )
inp[2] = 1; // Sensor 3 on
else
inp[2] = 0; // Sensor 3 off
bpn.test( inp, out );
if( out[0] == 1 )
Motor.A.forward();
else
Motor.A.backward();
if( out[1] == 1 )
Motor.C.forward();
else
Motor.C.backward();
Thread.sleep( 500 );
} // while()
SensorPort.S2.passivate();
Motor.A.stop();
Motor.C.stop();
Sound.beep();
} // main()
} // class LMbpn
class LegoMindstormBP {
public static int data1[][] = {{0,0,0}, {1,1}};
public static int data2[][] = {{1,0,0}, {1,0}};
public static int data3[][] = {{0,0,1}, {0,1}};
public static int data4[][] = {{0,1,0}, {0,0}};
public static double input[] = {0,0,0,1};
public static double w1[][] = {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}};
public static double hidden[] = {0,0,1};
public static double w2[][] = {{0,0}, {0,0}, {0,0}};
public static double output[] = {0,0};
public static double delta2[] = {0,0};
public static double delta1[] = {0,0,0};
public static int trainedEpochs = 0;
LegoMindstormBP() {
byte i, j;
// Initialize weights randomly between 0.1 and 0.9
for(i=0; i< w1.length; i++)
for(j=0; j< w1[i].length; j++)
w1[i][j] = Math.random()*0.8+0.1;
for(i=0; i< w2.length; i++)
for(j=0; j< w2[i].length; j++)
w2[i][j] = Math.random()*0.8+0.1;
}
public static void train(int e) {
for(int i=0; i< e; i++) {
// Call method learn with training data
learn( data1[0], data1[1] );
learn( data2[0], data2[1] );
learn( data3[0], data3[1] );
learn( data4[0], data4[1] );
trainedEpochs++;
}
}
public static void learn( int inp[], int out[] ) {
int i, j;
double sum, out_j;
// Initialize input units
for(i=0; i< inp.length; i++)
input[i] = inp[i];
// Calculate hidden units
for(j=0; j< hidden.length-1; j++) {
sum = 0;
for(i=0; i< input.length; i++)
sum = sum + w1[i][j]*input[i];
hidden[j] = 1 / ( 1 + Math.exp(-sum));
}
// Calculate output units
for(j=0; j< output.length; j++) {
sum = 0;
for(i=0; i< hidden.length; i++)
sum = sum + w2[i][j]*hidden[i];
output[j] = 1 / (1 + Math.exp(-sum));
}
// Calculate delta2 errors
for(j=0; j< output.length; j++) {
if( out[j] == 0 )
out_j = 0.1;
else if( out[j] == 1 )
out_j = 0.9;
else
out_j = out[j];
delta2[j] = output[j]*(1-output[j])*(out_j-output[j]);
}
// Calculate delta1 errors
for(j=0; j< hidden.length; j++) {
sum = 0;
for(i=0; i< output.length; i++)
sum = sum + delta2[i]*w2[j][i];
delta1[j] = hidden[j]*(1-hidden[j])*sum;
}
// Adjust weights w2
for(i=0; i< hidden.length; i++)
for(j=0; j< output.length; j++)
w2[i][j] = w2[i][j] + 0.35*delta2[j]*hidden[i];
// Adjust weights w1
for(i=0; i< input.length; i++)
for(j=0; j< hidden.length; j++)
w1[i][j] = w1[i][j] + 0.35*delta1[j]*input[i];
}
public static void test(int inp[], int out[]) {
int i, j;
double sum;
// Initialize input units
for(i=0; i< inp.length; i++)
input[i] = inp[i];
// Calculate hidden units
for(j=0; j< hidden.length-1; j++) {
sum = 0;
for(i=0; i< input.length; i++)
sum = sum + w1[i][j]*input[i];
hidden[j] = 1 / ( 1 + Math.exp(-sum));
}
// Calculate output units
for(j=0; j< output.length; j++) {
sum = 0;
for(i=0; i< hidden.length; i++)
sum = sum + w2[i][j]*hidden[i];
output[j] = 1 / (1 + Math.exp(-sum));
}
// Assign output to param out[]
for(i=0; i< output.length; i++)
if( output[i] >= 0.5 )
out[i] = 1;
else
out[i] = 0;
}
}
viernes 2 de noviembre de 2007
Red neuronal para LeJOS MindStorm NXT
Publicado por
Daniel Gómez
en
9:38 AM
Suscribirse a:
Enviar comentarios (Atom)
1 comentarios:
Hola,felicidades por la web!
Soy aficionado a lego desde pequeño, y acabo de hacerme con un NXT.
Al sentirme algo limitado con el software visual Labview, he decidido buscar algo con mas potencia.. y aqui estoy.
He instalado leJOS sin problemas, sin embargo, se echa en falta una explicación más amplia sobre el uso de los comandos de leJOS, así como el soporte donde picar codigo, no soy experto en java pero si conozco otros lenguajes...
Publicar un comentario en la entrada