📄 rbf.java
字号:
int x, y;
// Capa de Entrada
neuronasEntrada = new NeuronaSimple[numNeuronasEntrada];
for (x = 0; x < numNeuronasEntrada; x++)
neuronasEntrada[x] = new NeuronaSimple();
// Centros
neuronasCentro = new NeuronaCentro[num_centros];
for (x = 0; x < num_centros; x++)
neuronasCentro[x] = new NeuronaCentro(numNeuronasEntrada);
// Conectores Centros <-> Salida
conectorCS = new Conector[num_centros][numNeuronasSalida];
for (x = 0; x < num_centros; x++)
for (y = 0; y < numNeuronasSalida; y++)
conectorCS[x][y] = new Conector(pesoConectorMin, pesoConectorMax, momento);
// Conectores Bias <-> Salida
conectorBS = new Conector[numNeuronasSalida];
for (y = 0; y < numNeuronasSalida; y++)
conectorBS[y] = new Conector(pesoConectorMin, pesoConectorMax, momento);
// Capa de Salida
neuronasSalida = new NeuronaSimple[numNeuronasSalida];
for (x = 0; x < numNeuronasSalida; x++)
neuronasSalida[x] = new NeuronaSimple();
centroInsertado = new boolean[MAX_ITERACIONES];
errorIteracion = new float[MAX_ITERACIONES];
errorPatron = new float[numCasos];
// Se inicializan los centros
inicializeCenters(num_centros);
// Llamamos al recolector de basura
System.gc();
}
// INICIALIZECENTERS
protected void inicializeCenters(int num_centros) {
int y, x;
int delta = numCasos / num_centros;
numNeuronasCentro = num_centros;
// Para cada centro
for (y = 0; y < num_centros; y++)
// Se cargan sus valores con un vector de entrenamiento aleatorio
for (x = 0; x < numNeuronasEntrada; x++)
neuronasCentro[y].vectorValores[x] = valAtrib[y * delta][x];
setSigmas();
}
public void addListener(IRBFListener listener) {
this.listeners.add(listener);
}
public void removeListener(IRBFListener listener) {
this.listeners.remove(listener);
}
// TRAINING
protected void training_() {
this.train = true;
int y, aciertos, patronActual;
if (noHayConfiguracion())
return;
logger.info("RBF: Trainning started");
log("(-)(-)(-) TRAINING... (-)(-)(-)");
try {
for (iteracion = 0, aciertos = 0, lambda1Act = LAMBDA1, lambda2Act = LAMBDA2, ratioAprendizaje = RATIO_APRENDIZAJE; (aciertos < numCasos) && (iteracion < MAX_ITERACIONES); iteracion++) {
inicPatronesAleatorios();
// Para cada patron de entrenamiento
for (y = 0, aciertos = 0, errorIteracion[iteracion] = 0; y < numCasos; y++) {
patronActual = sigPatronAleatorio();
if (!this.train) {
for (int i = 0; i < listeners.size(); i++) {
listeners.get(i).trainningStopped();
}
return;
}
// 1.- Se carga el nuevo patron en la capa de entrada de la
// red
loadCase(patronActual);
// 2.- Se genera el valor de las neuronas de salida
generateOutput();
// 3.- Se calcula el error
calculateError(patronActual);
// 4.- Se aprende
learn(patronActual);
// 5.- Se mueven los centros mas cercanos
moveCenters(patronActual);
}
// Despues de pasar todos los patrones se hace el test de la red
aciertos = test();
for (int i = 0; i < listeners.size(); i++) {
listeners.elementAt(i).atStep(this.MAX_ITERACIONES, iteracion + 1, errorIteracion[iteracion] / numCasos, 0);
}
// Si se ha conseguido un error minimo se para el entrenamiento
if (errorIteracion[iteracion] / numCasos < MIN_ERROR_MED) {
break;
}
// Reduccion de LAMBDA1 y LAMBDA2
reduceLambdas();
// Insercion de un nuevo centro
insertNewCenter();
// Revisa sigma de cada centro
setSigmas();
}
Float[] toret = new Float[5];
toret[0] = errorIteracion[(iteracion < MAX_ITERACIONES) ? iteracion : iteracion - 1];
toret[1] = (errorIteracion[(iteracion < MAX_ITERACIONES) ? iteracion : iteracion - 1]) / numCasos;
toret[2] = new Float(aciertos);
toret[3] = new Float(numCasos);
toret[4] = new Float(numNeuronasCentro);
//Cuando finaliza el entrenamiento se hace un log
log("----- RESUMEN: training() -----");
log("Error total: " + errorIteracion[(iteracion < MAX_ITERACIONES) ? iteracion : iteracion - 1]);
log("Error medio: " + (errorIteracion[(iteracion < MAX_ITERACIONES) ? iteracion : iteracion - 1]) / numCasos);
log("Numero de aciertos: " + aciertos + "/" + numCasos);
log("Numero final de centros: " + numNeuronasCentro);
log("-------------------------------");
for (int i = 0; i < listeners.size(); i++) {
listeners.elementAt(i).trainningFinished(toret);
}
} catch (Exception ex) {
ex.printStackTrace();
ex.printStackTrace(new PrintWriter(fichLog));
}
logger.info("RBF: Trainning finished");
}
// LOADCASE
protected void loadCase(int patron) {
// Se establece el valor de las neuronas de entrada
for (int x = 0; x < numAtributos - numNeuronasSalida; x++)
neuronasEntrada[x].valor = valAtrib[patron][x];
}
// GENERATEOUTPUT
protected void generateOutput() {
int y, x;
float acumulador, sumValGauss;
// Se calcula el valor de los centros
for (y = 0, sumValGauss = 0; y < numNeuronasCentro; y++) {
// El valor del centro se calcula como multiplicacion de Gaussianas
// [Yaochu Jin]
/*
* for (x=0, acumulador=1; x < numNeuronasEntrada; x++) acumulador *=
* Math.exp( - Math.sqrt(Math.pow(neuronasEntrada[x].valor -
* neuronasCentro[y].vectorValores[x], 2)) /
* neuronasCentro[y].sigma); neuronasCentro[y].valor = acumulador;
* sumValGauss += neuronasCentro[y].valor;
*/
// El valor del centro se calcula con una unica Gaussiana [RBF
// clasica]
acumulador = distanciaEuclidea(getVectorEntrada(), neuronasCentro[y].vectorValores);
neuronasCentro[y].valor = (float) Math.exp(-acumulador / neuronasCentro[y].sigma);
sumValGauss += neuronasCentro[y].valor;
}
// Se normaliza la salida de cada Centro dependiendo del valor de
// SALIDA_NORMALIZADA
if (SALIDA_NORMALIZADA) {
for (y = 0; y < numNeuronasCentro; y++)
neuronasCentro[y].valor /= sumValGauss;
}
// Se calcula el valor de las neuronas de salida
for (y = 0; y < numNeuronasSalida; y++) {
// El acumulador se inicializa con el peso del conector de la
// neurona bias dependiendo del valor de BIAS
for (x = 0, acumulador = (BIAS ? conectorBS[y].pesoActual : 0); x < numNeuronasCentro; x++)
acumulador += neuronasCentro[x].valor * conectorCS[x][y].pesoActual;
neuronasSalida[y].valor = acumulador;
}
}
// CALCULATEERROR
protected void calculateError(int casoActual) {
int y;
// Se calcula el error de las neuronas de salida
for (y = 0; y < numNeuronasSalida; y++)
neuronasSalida[y].error = valAtrib[casoActual][numNeuronasEntrada + y] - neuronasSalida[y].valor;
}
// LEARN
protected void learn(int casoActual) {
int y, x;
float delta;
// Se modifican los pesos de los conectores Centros <-> Salida
for (y = 0; y < numNeuronasSalida; y++) {
for (x = 0; x < numNeuronasCentro; x++) {
delta = ratioAprendizaje * neuronasSalida[y].error * neuronasCentro[x].valor;
conectorCS[x][y].actualizarPeso(delta);
}
}
// Se modifican los pesos de los conectores Bias <-> Salida
if (BIAS) {
for (y = 0; y < numNeuronasSalida; y++) {
delta = ratioAprendizaje * neuronasSalida[y].error * 1;
conectorBS[y].actualizarPeso(delta);
}
}
}
// MOVECENTERS
protected void moveCenters(int casoActual) {
int y, x;
float distActual;
float disCentros[] = { Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE };
int posCentros[] = { 0, 0, 0 };
// Para cada centro se calcula su distancia con el patron de entrada
for (x = 0; x < numNeuronasCentro; x++) {
distActual = distanciaEuclidea(getVectorEntrada(), neuronasCentro[x].vectorValores);
if (distActual < disCentros[0]) {
disCentros[2] = disCentros[1];
disCentros[1] = disCentros[0];
disCentros[0] = distActual;
posCentros[2] = posCentros[1];
posCentros[1] = posCentros[0];
posCentros[0] = x;
} else if (distActual < disCentros[1]) {
disCentros[2] = disCentros[1];
disCentros[1] = distActual;
posCentros[2] = posCentros[1];
posCentros[1] = x;
} else if (distActual < disCentros[2]) {
disCentros[2] = distActual;
posCentros[2] = x;
}
}
// Se incrementa el error acumulado del centro ganador.
for (x = 0, distActual = 0; x < numNeuronasSalida; x++)
distActual += Math.abs(neuronasSalida[x].error);
neuronasCentro[posCentros[0]].errorAcumulado += Math.pow(distActual, 2);
if ((lambda1Act == 0) && (lambda2Act == 0))
return;
// Se mueve el centro mas cercano en un porcentaje LAMBDA1
// y los 2 siguientes en un porcentaje LAMBDA2
for (y = 0, distActual = 0; y < numNeuronasEntrada; y++) {
neuronasCentro[posCentros[0]].vectorValores[y] += (neuronasEntrada[y].valor - neuronasCentro[posCentros[0]].vectorValores[y]) * lambda1Act;
neuronasCentro[posCentros[1]].vectorValores[y] += (neuronasEntrada[y].valor - neuronasCentro[posCentros[1]].vectorValores[y]) * lambda2Act;
neuronasCentro[posCentros[2]].vectorValores[y] += (neuronasEntrada[y].valor - neuronasCentro[posCentros[2]].vectorValores[y]) * lambda2Act;
}
}
// NUEVOACIERTO
protected boolean nuevoAcierto() {
int y;
float errorParcial;
for (y = 0, errorParcial = 0; y < numNeuronasSalida; y++)
errorParcial += Math.abs(neuronasSalida[y].error);
return (errorParcial <= TOLERANCIA) ? true : false;
}
// REDUCELAMBDAS
protected void reduceLambdas() {
if (((iteracion + 1) % ((MAX_ITERACIONES * RATIO_ITERAC_LIMITE / 100) / 10)) == 0) {
if (lambda1Act > 0) {
lambda1Act -= deltaLambda1;
lambda1Act = (lambda1Act < 0) ? 0 : lambda1Act;
// log("\t>>> Nuevo valor de LAMBDA1 = " + lambda1Act);
}
if (lambda2Act > 0) {
lambda2Act -= deltaLambda2;
lambda2Act = (lambda2Act < 0) ? 0 : lambda2Act;
// log("\t>>> Nuevo valor de LAMBDA2 = " + lambda2Act);
// log("");
}
}
}
// INSERTNEWCENTER
protected void insertNewCenter() {
int y, x;
float distTemp, errorMax, distancia1, distancia2;
int patronErrorMax;
int deltaIteraciones, posIni, posFin;
int vecino1, vecino2, vecinoFinal;
float errorMedioInic = 0.0F;
float errorMedioFin = 0.0F;
float[] newCentro = new float[numNeuronasEntrada];
// Si se ha alcanzado MAX_CENTROS o la iteracion actual >
// RATIO_ITERAC_LIMITE DE MAX_ITERACIONES
if ((MAX_CENTROS == numNeuronasCentro) || ((iteracion + 1) > MAX_ITERACIONES * RATIO_ITERAC_LIMITE / 100))
return;
deltaIteraciones = ((MAX_ITERACIONES * RATIO_ITERAC_LIMITE / 100) / deltaCentros);
// Cada deltaIteraciones
if (((iteracion + 1) % deltaIteraciones) == 0) {
posIni = (iteracion + 1) - deltaIteraciones;
posFin = iteracion;
// Se calcula el error medio de la primera mitad de la ventana movil
for (y = 0; y < deltaIteraciones / 2; y++)
errorMedioInic += errorIteracion[posIni + y] / numCasos;
errorMedioInic /= (deltaIteraciones / 2);
// Se calcula el error medio de la segunda mitad de la ventana movil
for (y = 0; y < ((deltaIteraciones / 2) + (deltaIteraciones % 2)); y++)
errorMedioFin += errorIteracion[posFin - y] / numCasos;
errorMedioFin /= ((deltaIteraciones / 2) + (deltaIteraciones % 2));
// log("\t>>> deltaError = " + ((Math.abs(errorMedioInic -
// errorMedioFin) * 100) / errorMedioInic) + endl);
if (((Math.abs(errorMedioInic - errorMedioFin) * 100) / errorMedioInic) > ratioNuevoCentro)
return;
if (numNeuronasCentro > MAX_CENTROS) {
// Se buscan el patron que produzca un error mayor
for (y = 0, patronErrorMax = 0, errorMax = Float.MIN_VALUE; y < numCasos; y++) {
if (errorPatron[y] > errorMax) {
patronErrorMax = y;
errorMax = errorPatron[y];
}
}
for (y = 0; y < numNeuronasEntrada; y++)
newCentro[y] = valAtrib[patronErrorMax][y];
} else {
// Se buscan el centro con mayor error acumulado
for (y = 0, patronErrorMax = 0, errorMax = Float.MIN_VALUE; y < numNeuronasCentro; y++) {
if (errorMax < neuronasCentro[y].errorAcumulado) {
patronErrorMax = y;
errorMax = neuronasCentro[y].errorAcumulado;
}
}
// Se buscan los 2 vecinos mas cercanos
for (y = 0, vecino1 = 0, distancia1 = Float.MAX_VALUE; y < numNeuronasCentro; y++) {
if (y == patronErrorMax)
continue;
distTemp = distanciaEuclidea(neuronasCentro[vecino1].vectorValores, neuronasCentro[y].vectorValores);
if (distancia1 > distTemp) {
distancia1 = distTemp;
vecino1 = y;
}
}
for (y = 0, vecino2 = 0, distancia2 = Float.MAX_VALUE; y < numNeuronasCentro; y++) {
if (y == patronErrorMax || y == vecino1)
continue;
distTemp = distanciaEuclidea(neuronasCentro[vecino2].vectorValores, neuronasCentro[y].vectorValores);
if (distancia2 > distTemp) {
distancia2 = distTemp;
vecino2 = y;
}
}
vecinoFinal = (neuronasCentro[vecino1].errorAcumulado > neuronasCentro[vecino2].errorAcumulado) ? vecino1 : vecino2;
// Se calcula el nuevo centro como la media de las coordenadas
for (y = 0; y < numNeuronasEntrada; y++) {
newCentro[y] = (neuronasCentro[patronErrorMax].vectorValores[y] + neuronasCentro[vecinoFinal].vectorValores[y]) / 2;
}
}
// Se modifican las variables globales
neuronasCentro = nuevaNeuronaCentro(newCentro);
conectorCS = nuevoConector();
centroInsertado[iteracion] = true;
numNeuronasCentro++;
resetStatCentros();
// log("\t>>> " + numNeuronasCentro + " centros,\tnew[" +
// patronErrorMax + "]\r\n");
// log("\t>>> " + numNeuronasCentro + " centros,\tnew[" +
// patronErrorMax1 + "][" + patronErrorMax2 + "]\r\n");
}
}
// SETSIGMAS
protected void setSigmas() {
int x, y, posMax = 0, posMin = 0;
float distMax, distMin, distTemp;
if (numNeuronasCentro == 1)
neuronasCentro[0].sigma = 1;
// Para cada centro...
for (x = 0; x < numNeuronasCentro; x++) {
// Se calcula el centro mas lejano y el m�s cercano
for (y = 0, distMin = Float.MAX_VALUE, distMax = Float.MIN_VALUE; y < numNeuronasCentro; y++) {
if (x == y)
continue;
distTemp = distanciaEuclidea(neuronasCentro[x].vectorValores, neuronasCentro[y].vectorValores);
if (distTemp > distMax) {
distMax = distTemp;
posMax = y;
}
if (distTemp < distMin) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -