java - repo-inteligencia-artificial - Repositrio para projetos de IA - Google Project Hosting
https://code.google.com/p/repo-inteligencia-artificial/source/browse/trunk/perceptronMultiCamadas/src/perceptronmulticamadas/PerceptronMultiCamadas. 1/6 package perceptronmulticamadas; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; /** * * @author Anderson e Maria */ public class PerceptronMultiCamadas { // variaveis globais private static ArrayList<float[]> entrada; private static ArrayList<float[]> entradaTeste; private static ArrayList<float[]> valoresDesejados; private static ArrayList<float[]> valoresDesejadosTeste; private static ArrayList<float[][]> matrizPesosAnteriores; private static ArrayList<float[][]> matrizPesosAtual; // mtodo que converte uma ArrayList<float[]> para String formato impressao public static String arraylistToString(ArrayList<float[]> resultado) { String resultadoString = ""; for (float[] y : resultado) { resultadoString += ""+Arrays.toString(y)+"\n"; } return "["+resultadoString.replaceAll("]",";").replaceAll("]]","],\n").replaceAll("\\["," ")+"]\n"; }
// mtodo que converte uma ArrayList<float[][]> para String formato impressao public static String arraylistMatrizToString(ArrayList<float[][]> resultado) { String resultadoString = "["; for (float[][] y : resultado) { resultadoString += ""+Arrays.deepToString(y).replaceAll("],",";\n").replaceAll("]]","],\n").replaceAll("\\["," ")+"\n"; } return resultadoString+"]"; }
public static String matrizToString(float[][] matriz){ return " ["+Arrays.deepToString(matriz).replaceAll("],",";\n").replaceAll("]]","],\n").replaceAll("\\["," ")+"}\n"; }
public static ArrayList<float[]> classificacaoAmostras(ArrayList<float[][]> pesosCamadas,int[] qtdNeuronios, int qtdCamadaIntermediaria) { ArrayList<float[]> saidasCamadas; ArrayList<float[]> saidaClassificacao = new ArrayList<float[]>(); ArrayList<float[]> derivadaSigmoidI; boolean ehUltimaCamada = false; for (int k = 0; k < entradaTeste.size(); k++) { //laco para cada padrao k de amostras saidasCamadas = new ArrayList<float[]>(); derivadaSigmoidI = new ArrayList<float[]>(); //Fase forward backpropagation // System.out.println("entradaTeste.get("+k+") :\n"+Arrays.toString(entradaTeste.get(k))+"\n"); float[] I = combinacaoMatrizes(pesosCamadas.get(0), entradaTeste.get(k), qtdCamadaIntermediaria); // primeira camada saidasCamadas.add(g(I, ehUltimaCamada)); derivadaSigmoidI.add(glinha(I)); //calculando g'(I) para a primeira camada //System.out.println("Camada 0: \n" + Arrays.toString(I) + "\n" + "Sada da camada 0: \n" + Arrays.toString(saidasCamadas.get(0)) + "\n"); // camadas intermediarias e a final for (int i = 1; i < pesosCamadas.size(); i++) { if (i == (pesosCamadas.size() - 1)) { ehUltimaCamada = true; } I = combinacaoMatrizes(pesosCamadas.get(i), saidasCamadas.get(i - 1), qtdNeuronios[i]); saidasCamadas.add(g(I, ehUltimaCamada)); derivadaSigmoidI.add(glinha(I)); //calculando g'(I) para as camadas intermediarias e primeira //System.out.println("Camada " + i + ":\n " + Arrays.toString(I) + "\n" + "Sada da camada " + i + ":\n " + Arrays.toString(saidasCamadas.get(i)) + "\n"); for (int j = 0; j < derivadaSigmoidI.size(); j++) { //System.out.println("G'(I) da camada "+j+":"+Arrays.toString(derivadaSigmoidI.get(j))); } } ehUltimaCamada = false; saidaClassificacao.add(saidasCamadas.get(saidasCamadas.size()-1)); } return saidaClassificacao; //retorna a sada da ltima camada } 25/7/2014 PerceptronMultiCamadas.java - repo-inteligencia-artificial - Repositrio para projetos de IA - Google Project Hosting https://code.google.com/p/repo-inteligencia-artificial/source/browse/trunk/perceptronMultiCamadas/src/perceptronmulticamadas/PerceptronMultiCamadas. 2/6 public static void leArquivo(String path, int qtdValoresDesejados) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(path))); entrada = new ArrayList<float[]>(); valoresDesejados = new ArrayList<float[]>(); String[] line = null; String temp; while ((temp = reader.readLine()) != null) { line = temp.split("\\ "); float[] lineFloat = new float[line.length- qtdValoresDesejados]; for (int i = 0; i < line.length - qtdValoresDesejados; i++) { lineFloat[i] = Float.parseFloat(line[i]); } entrada.add(lineFloat); lineFloat = new float[qtdValoresDesejados]; int j = 0; for (int i = line.length - qtdValoresDesejados; i < line.length; i++) { lineFloat[j++] = Float.parseFloat(line[i]); } valoresDesejados.add(lineFloat); } }
public static void leArquivoTeste(String path, int qtdValoresDesejados) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(path))); entradaTeste = new ArrayList<float[]>(); valoresDesejadosTeste = new ArrayList<float[]>(); String[] line = null; String temp; while ((temp = reader.readLine()) != null) { line = temp.split("\\ "); float[] lineFloat = new float[line.length- qtdValoresDesejados]; for (int i = 0; i < line.length - qtdValoresDesejados; i++) { lineFloat[i] = Float.parseFloat(line[i]); } entradaTeste.add(lineFloat); lineFloat = new float[qtdValoresDesejados]; int j = 0; for (int i = line.length - qtdValoresDesejados; i < line.length; i++) { lineFloat[j++] = Float.parseFloat(line[i]); } valoresDesejadosTeste.add(lineFloat); } } public static float[][] gerarMatrizPeso(int linhas, int colunas) { float[][] matrizPeso = new float[linhas][colunas]; for (int i = 0; i < linhas; i++) { for (int j = 0; j < colunas; j++) { matrizPeso[i][j] = (float) Math.random(); } } return matrizPeso; } public static ArrayList<float[][]> inicializarRede(int qtdNeuronios[], int camadas, int qtdEntrada) { ArrayList<float[][]> pesosCamadas = new ArrayList<float[][]>(); pesosCamadas.add(gerarMatrizPeso(qtdNeuronios[0], qtdEntrada)); //adiciona a matriz de peso da primeira camada for (int i = 1; i < camadas; i++) { pesosCamadas.add(gerarMatrizPeso(qtdNeuronios[i], qtdNeuronios[i - 1]+1)); } return pesosCamadas; } public static float[] combinacaoMatrizes(float[][] pesosCamada, float[] entrada, int tamanhoI) { float[] resultado = new float[tamanhoI]; for (int i = 0; i < pesosCamada.length; i++) { for (int j = 0; j < pesosCamada[0].length; j++) { resultado[i] += pesosCamada[i][j] * entrada[j]; } } return resultado; } public static float sigmoid(float u) { return (float) (1 / (1 + Math.pow(Math.E, (-0.5 * u)))); // o beta da formula eh 0.5 } public static float derivadaSigmoid(float u) { return (float) 0.5 * sigmoid(u) * (1 - sigmoid(u)); // o beta da formula eh 0.5 } public static float[] g(float[] I, boolean ultimaCamada) { float[] Y; if (ultimaCamada == false) {//flag para verificao se ultima camada, evitar o bias na saida da ultima camada Y = new float[I.length + 1]; // +1 espaco para o bias 25/7/2014 PerceptronMultiCamadas.java - repo-inteligencia-artificial - Repositrio para projetos de IA - Google Project Hosting https://code.google.com/p/repo-inteligencia-artificial/source/browse/trunk/perceptronMultiCamadas/src/perceptronmulticamadas/PerceptronMultiCamadas. 3/6 Y[0] = -1; for (int i = 1; i < I.length + 1; i++) { Y[i] = sigmoid(I[i - 1]); } } else { Y = new float[I.length]; // Sem espao para p/ bias caso ultima camada for (int i = 0; i < I.length; i++) { Y[i] = sigmoid(I[i]); } } return Y; } public static float[] glinha(float[] I) { //calculando a derivada de I float[] Y = new float[I.length]; for (int i = 0; i < I.length; i++) { Y[i] = derivadaSigmoid(I[i]); } return Y; } public static float[] gradienteUltimaCamada(float[] valoresDesejados, float[] saidas, float[] derivadaI) { float[] delta = new float[saidas.length]; for (int i = 0; i < saidas.length; i++) { delta[i] = (valoresDesejados[i] - saidas[i]) * derivadaI[i]; } return delta; } public static float[] gradienteCamadasIntermediarias(float[] gradienteAnterior, float[][] pesosCamadaAnterior, float[] derivadaCamadaAtual) { float[] delta = new float[derivadaCamadaAtual.length]; float[] acumula = new float[pesosCamadaAnterior[0].length]; float[] acumulaAnterior = new float[pesosCamadaAnterior[0].length]; for (int i = 0; i < pesosCamadaAnterior.length; i++) { for (int j = 0; j < pesosCamadaAnterior[0].length; j++) { acumula[i] += pesosCamadaAnterior[i][j] * gradienteAnterior[i]; } for (int j = 0; j < pesosCamadaAnterior[0].length; j++) { acumula[j] = acumula[j] + acumulaAnterior[j]; } acumulaAnterior = (float[]) acumula.clone(); //metodo copia de vetor }
EQM_anterior = EQM_atual; for (int k = 0; k < entrada.size(); k++) { // Fase Forward // System.out.println("entrada0: "+Arrays.toString(entrada.get(k))); float[] I = combinacaoMatrizes(pesosCamadas.get(0), entrada.get(k), qtdCamadaIntermediaria); // primeira camada // System.out.println("saida I0:"+Arrays.toString(I)); saidasCamadas.add(g(I, ehUltimaCamada)); // System.out.println("saida Y(I0):"+Arrays.toString(saidasCamadas.get(0))); derivadaSigmoidI.add(glinha(I)); //calculando g'(I) para a primeira camada //System.out.println("Camada 0: \n" + Arrays.toString(I) + "\n" + "Sada da camada 0: \n" + Arrays.toString(saidasCamadas.get(0)) + "\n"); // camadas intermediarias e a final for (int i = 1; i < pesosCamadas.size(); i++) { if (i == (pesosCamadas.size() - 1)) { ehUltimaCamada = true; } I = combinacaoMatrizes(pesosCamadas.get(i), saidasCamadas.get(i - 1), qtdNeuronios[i]); // System.out.println("saida I"+i+Arrays.toString(I)); saidasCamadas.add(g(I, ehUltimaCamada)); // System.out.println("saida Y(I"+i+"): "+Arrays.toString(saidasCamadas.get(i))); derivadaSigmoidI.add(glinha(I)); //calculando g'(I) para as camadas intermediarias e primeira //System.out.println("Camada " + i + ":\n " + Arrays.toString(I) + "\n" + "Sada da camada " + i + ":\n " + Arrays.toString(saidasCamadas.get(i)) + "\n"); // for (int j = 0; j < derivadaSigmoidI.size(); j++) { //System.out.println("G'(I) da camada "+j+":"+Arrays.toString(derivadaSigmoidI.get(j))); // } } ehUltimaCamada = false;
// System.out.println("Saida das camadas da rede para amostra "+k+"\n: "+arraylistToString(saidasCamadas)+"\n"); // System.out.println("Matrizes de Pesos para amostra "+k+"\n: "+arraylistMatrizToString(pesosCamadas)+"\n"); // calculo de E(k) e 'quase EQM' float E = E(saidasCamadas.get(saidasCamadas.size() - 1), valoresDesejados.get(k)); // System.out.println("Y(I1): "+Arrays.toString(saidasCamadas.get(saidasCamadas.size() - 1))); // System.out.println("desejados: "+Arrays.toString(valoresDesejados.get(k))); // System.out.println("Erro e(k):"+E); EQM_atual += E; //System.out.println("\nErro E(k): " + E + "\n"); matrizPesosAtual=new ArrayList<float[][]>(pesosCamadas); //System.out.println("Matriz de pesos Atual: "+arraylistMatrizToString(matrizPesosAtual)+"\n"); //System.out.println("Matriz de pesos Anteriores: "+arraylistMatrizToString(matrizPesosAnteriores)+"\n"); // Fase Backward //calculo gradiente ultima camada e atualizacao de pesos da ultima camada gradienteLast = gradienteUltimaCamada(valoresDesejados.get(k), saidasCamadas.get(saidasCamadas.size()-1), derivadaSigmoidI.get(derivadaSigmoidI.size()- 1)); // System.out.println("Gradiente Ultima Camada:"+Arrays.toString(gradienteLast)); //System.out.println("Gradiente ultima camada:\n"+Arrays.toString(gradienteLast)); pesosCamadas.set(pesosCamadas.size() - 1, novoPeso(pesosCamadas.get(pesosCamadas.size()-1), taxaAprendizagem, gradienteLast, saidasCamadas.get(saidasCamadas.size()-2),comMomentum,matrizPesosAnteriores.get(pesosCamadas.size()-1))); // System.out.println("Matriz pesos ultima camada atualizada: \n"+Arrays.deepToString(pesosCamadas.get(pesosCamadas.size()-1)).replaceAll("],", "],\n")+"\n"); //calculo gradiente camadas intermediarias e atualizacao de pesos camadas intermediarias for (int i = pesosCamadas.size() - 2; i >= 1; i--) { // o pesosCamas.size - 2 pra garantir que no comeamos pela ultima camada. gradiente = gradienteCamadasIntermediarias(gradienteLast, pesosCamadas.get(i + 1), derivadaSigmoidI.get(i)); // System.out.println("Gradiente camada "+i+"\n: " + Arrays.toString(gradiente)); pesosCamadas.set(i, novoPeso(pesosCamadas.get(i), taxaAprendizagem, gradiente, saidasCamadas.get(i-1),comMomentum, matrizPesosAnteriores.get(i))); // System.out.println("Matriz pesos camada "+i+" atualizada:\n"+Arrays.deepToString(pesosCamadas.get(i)).replaceAll("],", "],\n")); gradienteLast = gradiente; // guarda o ultimo gradiente para o calculo do proximo } //calculo gradiente da primeira camada e atualizacao de pesos da primeira camada gradiente = gradienteCamadasIntermediarias(gradienteLast, pesosCamadas.get(1), derivadaSigmoidI.get(0)); // System.out.println("Gradiente 1a camada:\n" + Arrays.toString(gradiente)); //revisar calculo do gradiente das outras camadas. pesosCamadas.set(0, novoPeso(pesosCamadas.get(0), taxaAprendizagem, gradiente, entrada.get(k),comMomentum,matrizPesosAnteriores.get(0))); 25/7/2014 PerceptronMultiCamadas.java - repo-inteligencia-artificial - Repositrio para projetos de IA - Google Project Hosting https://code.google.com/p/repo-inteligencia-artificial/source/browse/trunk/perceptronMultiCamadas/src/perceptronmulticamadas/PerceptronMultiCamadas. 5/6
//atualizacao vetor de pesos das outras camadas derivadaSigmoidI.clear(); saidasCamadas.clear(); } // calculo EQM EQM_atual /= entrada.size(); System.out.println(EQM_atual); //System.out.println("EQM Atual: "+EQM_atual); //System.out.println("EQM Anterior: "+EQM_anterior+"\n"); epocas++; } System.out.println("O treinamento teve "+epocas+" epocas.\n"); return pesosCamadas; }
// Pos-processa as saidas dos testes para normaliza-las public static ArrayList<float[]> posProcessar(ArrayList<float[]> resultadoAntes){ ArrayList<float[]> resultadoPosProcessado = new ArrayList<float[]>(); float[] novo; for (int i = 0; i < resultadoAntes.size(); i++) { novo = new float[resultadoAntes.get(0).length]; for (int j = 0; j < resultadoAntes.get(0).length; j++) { // 1 , se y i 0.5 if(resultadoAntes.get(i)[j] >= (float) 0.5){ novo[j] = 1; } // 0, se y i < 0.5 else{ novo[j] = 0; } } resultadoPosProcessado.add(novo); } return resultadoPosProcessado; } public static void main(String[] args) throws Exception { // Definio dos parmetros do algoritmo int qtdTreino = 3; int qtdEntrada = 5; //4 entradas + 1 entrada do bias int[] qtdNeuronios = {5,3}; int qtdValoresDesejados = 3; int qtdNeuronios1aCamadaIntermediaria = 5; // qtd neuronios na 1a camada intermediaria float erro = (float) 0.000001; float taxaAprendizagem = (float) 0.1; // Leitura de arquivos de entrada leArquivo("treina.txt", qtdValoresDesejados); leArquivoTeste("teste.txt", qtdValoresDesejados); // Variaveis para armazenar saidas do treinamento e da classificacao ArrayList<float[][]> resultadoBackNormal; // arraylist pesos resultado treinamento normal ArrayList<float[][]> resultadoBackMomentum; // arraylist pesos resultado treinamento momentum ArrayList<float[]> resultadoClassificacaoNormal; // saida da ultima camada rede teste ArrayList<float[]> resultadoClassificacaoMomentum; //saida da ultima camada rede teste momentum
// Loop principal treinamentos + classificacoes for (int k = 0; k < qtdTreino; k++) { if(k==1){ qtdNeuronios[0]=10; // segundo treinamento com 10 neuronios camada intermediaria qtdNeuronios1aCamadaIntermediaria = 10; } if(k==2){ qtdNeuronios[0]=15; // terceiro treinamento com 15 neuronios camada intermediaria qtdNeuronios1aCamadaIntermediaria=15; } // Inicializacao das matrizes de pesos ArrayList<float[][]> pesosInicial = inicializarRede(qtdNeuronios, qtdNeuronios.length, qtdEntrada); System.out.print("Matriz peso inicial:\n"+arraylistMatrizToString(pesosInicial));
System.out.println("--------- Treinamento " + k + " -----------\n"); System.out.println("Treinamento Backpropagation Normal\n"); // Fase de Treinamento backpropagation normal; new ArrayList...pesosInicial para passar por valor e no referencia resultadoBackNormal = backpropagation(new ArrayList<float[][]>(pesosInicial), erro, qtdNeuronios, qtdValoresDesejados, qtdNeuronios1aCamadaIntermediaria, taxaAprendizagem, false); // Exibe resultado do treinamento System.out.print("Resultado Treinamento Back Normal:\n"+arraylistMatrizToString(resultadoBackNormal)); // Classificacao do backpropagation normal resultadoClassificacaoNormal = classificacaoAmostras(resultadoBackNormal, qtdNeuronios, 25/7/2014 PerceptronMultiCamadas.java - repo-inteligencia-artificial - Repositrio para projetos de IA - Google Project Hosting https://code.google.com/p/repo-inteligencia-artificial/source/browse/trunk/perceptronMultiCamadas/src/perceptronmulticamadas/PerceptronMultiCamadas. 6/6 qtdNeuronios1aCamadaIntermediaria); // Exibe Classificacao Back Normal System.out.println("Resultado Classificacao Back Normal:\n"+arraylistToString(resultadoClassificacaoNormal)+"\n"); // Exibe Classificacao Pos-processada Back Momentum System.out.println("Resultado Normal PosProcessado:\n"+arraylistToString(posProcessar(resultadoClassificacaoNormal))+"\n"); System.out.println("Treinamento Backpropagation com Momentum\n"); // Fase de Treinamento do backpropagation com momentum; new ArrayList...pesosInicial para passar por valor e no referencia resultadoBackMomentum = backpropagation(new ArrayList<float[][]>(pesosInicial), erro, qtdNeuronios, qtdValoresDesejados, qtdNeuronios1aCamadaIntermediaria, taxaAprendizagem, true); // Exibe resultado do treinamento System.out.println("Resultado Treinamento Back Momentum:\n"+arraylistMatrizToString(resultadoBackMomentum)+"\n"); // Classificacao do backpropagation com momentum resultadoClassificacaoMomentum = classificacaoAmostras(resultadoBackMomentum, qtdNeuronios, qtdNeuronios1aCamadaIntermediaria); // Exibe Classificacao Back Momentum System.out.println("Resultado Classificacao Back Momentum:\n"+arraylistToString(resultadoClassificacaoMomentum)+"\n"); // Exibe Classificacao Pos-processada Back Momentum System.out.println("Resultado Momentum PosProcessado:\n"+arraylistToString(posProcessar(resultadoClassificacaoMomentum))+"\n");
// limpando as variaveis para o novo treinamento resultadoBackNormal.clear(); resultadoBackMomentum.clear(); resultadoClassificacaoNormal.clear(); resultadoClassificacaoMomentum.clear(); } } }