• 0

Question

Pessoal, não sei se alguém aqui e capaz de me ajudar, mas vocês são minha esperanca. Estou desenvolvendo um codigo de rede neural que preciso entregar na faculdade (não e faculdade de programacao, sou ate bem leigo nisso), e consegui resultados incriveis para uma unica entrada e saida. Porem quando ponho uma serie de dados a saida curiosamente e aproximadamente a media dos dados de entrada.

Tentei de tudo: Alterei a taxa de aprendizado, o layout da camada, o numero de repeticoes, numero de padroes de entrada, etc. Nada deu certo. Segue abaixo o codigo de teste que fiz.

O que diabos esta errado?!!!!!

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define PI 3.14159265
#define AN (2*PI)/360

struct neuronio {
    float *pesos;
    float *inputs;
    float delta;
    float somatorio;
    float somatorio_delta;
    float resultado;
};

struct camada {
    int NoNeuronios;
    struct neuronio *neuronio;
};

struct network {
    int NoCamdas;
    struct camada *camada;
};

float sigmoide (float value){
    float resultado;
    resultado = 1/(1+exp(-value));
    //resultado = 20*(1/(1+pow(1.1,-value)));
    return resultado;
}

float derivada_sigmoide (float value){
    float resultado;
    resultado = exp(-value)/(2*exp(-value) + pow(exp(-value),2) + 1);
    //resultado = (20*pow((11/10),-value))*((log(11/10))/(pow((11/10),-2*value)+2*pow((11/10),-value)+1));
    return resultado;
}

void zerarSomatorios(int Layout[], struct network *rede, int num_camadas){
    //ZERA OS SOMATORIOS DOS NEURONIOS
    for (int i = 0; i < num_camadas; i++){                  //CORRE AS CAMADAS
        for (int j = 0; j < Layout; j++){                //CORRE OS NEURONIOS
            //printf("%i##\n",j);
            //printf("%f\n",(*rede).camada.neuronio[j].somatorio);
            rede -> camada.neuronio[j].somatorio = 0.0;
            //printf("%f\n\n",(*rede).camada.neuronio[j].somatorio);
        }
    }
}

void zerarSomatoriosDeltas(int Layout[], struct network *rede, int num_camadas){
    //ZERA OS SOMATORIOS DOS NEURONIOS
    for (int i = 0; i < num_camadas; i++){                  //CORRE AS CAMADAS
        for (int j = 0; j < Layout; j++){                //CORRE OS NEURONIOS
            rede -> camada.neuronio[j].somatorio_delta = 0.0;
        }
    }
}

int main()
{
    int a = 0;
    int aux = 0;
    int repeticoes = 50;
    int Layout[] = {5,3,1};
    int inputs[] = {1,5,3};
    float saidas[90][2];
    float y = 0.9;
    //float force[] = {2.0, 0.1};
    float obj = 0.4;
    int vp[2];
    float entrada[180] = {};
    float objetivo[10];
    srand((unsigned)time(NULL));
    
    //INICIALIZA A SERIE DE TESTE
    for (int i = 0; i < 180; i++){
        entrada = sin(i*2*AN);
        //printf("%f\n",entrada);
    }
    
    //#######################################PROCESSOS ESTRUTURAIS DA REDE#####################################################
    
    //INICIALIZA A REDE
    struct network rede;
    
    //INICIALIZA A QUANTIDADE DE CAMADAS
    //rede.camada = new camada[sizeof(Layout)/sizeof(int)];
    rede.camada = malloc((sizeof(Layout)/sizeof(int))*sizeof(struct camada));

    //INICIALIZAÇÃO DA QUANTIDADE DE NEURONIOS POR CAMADA
    for (int i = 0; i < sizeof(Layout)/sizeof(int); i++){
        //rede.camada.neuronio = new neuronio[Layout];
        rede.camada.neuronio = malloc(Layout*sizeof(struct neuronio));
    }

    //INICIALIZAÇÃO DA QUANTIDADE DE PESOS E ENTRADAS DOS NEURONIOS DE CADA CAMADA
    for (int i = 0; i < sizeof(Layout)/sizeof(int); i++){
        for (int j = 0; j < Layout; j++){
            //rede.camada.neuronio[j].pesos = new float[inputs];
            rede.camada.neuronio[j].pesos = malloc(inputs*sizeof(float));
            //rede.camada.neuronio[j].inputs = new float[inputs];
            rede.camada.neuronio[j].inputs = malloc(inputs*sizeof(float));
        }
    }
    
    //INICIALIZA OS PESOS DOS NEURONIOS
    for (int i = 0; i < sizeof(Layout)/sizeof(int); i++){   //CORRE AS CAMADAS
        printf("PESOS CAMADA %i\n",i);
        for (int j = 0; j < Layout; j++){                //CORRE OS NEURONIOS
            printf("\tPESOS NEURONIO %i\n",j);
            for (int k = 0; k < inputs; k++){            //CORRE OS PESOS
                if(rand()%2 == 0){
                    rede.camada.neuronio[j].pesos[k] = ((float)rand()/RAND_MAX)*1;
                }else{
                    rede.camada.neuronio[j].pesos[k] = ((float)rand()/RAND_MAX)*(-1.0);
                }
                printf("\t\tPESO %i: %f\n",k,rede.camada.neuronio[j].pesos[k]);
            }
        }
    }
    //###############################FIM DOS PROCESSOS ESTRUTURAIS########################################
    printf("\n\n");
    
    for (int i = 0; i < sizeof(vp)/sizeof(int); i++){
        vp = rand()%(89 - Layout[0]); 
    }
    
    for (int loop = 0; loop < repeticoes; loop++){
    for (int padrão = 0; padrão < (sizeof(vp)/(sizeof(int))); padrão++){
    //*******************************PROCESSOS DE EXECUCAO DA REDE***************************************
    a = 0;
    aux = 0.3;
   
    for (int camada_atual = 0; camada_atual < sizeof(Layout)/sizeof(int); camada_atual++){
        
    zerarSomatorios(Layout, &rede, sizeof(Layout)/sizeof(int));
    
    //PROCESSO DA PRIMEIRA CAMADA
    if (camada_atual == 0){
        printf("CAMADA SETADA %i\n",camada_atual);
        aux = vp[padrão]+Layout[0];
        obj = entrada[aux];
        //obj = entrada[vp[padrão]+Layout[0]];
        for (int i = 0; i < Layout[0]; i++){  //CORRE OS NEURONIOS DA PRIMEIRA CAMADA
            printf("\tNEURONIO SETADO %i\n",i);
            printf("\t\tENTRADA %f\tRESULTADO %f\n",entrada[vp[padrão]+i],sigmoide(entrada[vp[padrão] + i]));
            rede.camada[0].neuronio.resultado = sigmoide(entrada[vp[padrão] + i]);
            objetivo[padrão] = obj;//entrada[vp[padrão] + i + 1]; 
            //printf("%f\n",(entrada[vp[padrão] + i]));
        }
    }        
     
       else {       
       
       //PROCESSO DAS DEMAIS CAMADAS
       printf("CAMADA SETADA %i\n",camada_atual);
       for (int i = 0; i < Layout[camada_atual]; i++){             //CORRE O NUMERO DE NEURONIOS CAMADA ATUAL
         printf("\tNEURONIO SETADO %i\n\t\t",i);
        for (int j = 0; j < inputs[camada_atual]; j++){                //CORRE 0 NUMERO DE ENTRADAS DA CAMADA ATUAL A PARTIR DE UM PONTO
            printf("ENTRADA %i: %f * PESO %i: %f + ",j,rede.camada[camada_atual].neuronio.inputs[j],j,rede.camada[camada_atual].neuronio.pesos[j]);
            rede.camada[camada_atual].neuronio.somatorio += rede.camada[camada_atual].neuronio.inputs[j] * rede.camada[camada_atual].neuronio.pesos[j]; //PROCESSO SOMATORIO
            //printf("%f * %f\n", rede.camada[camada_atual].neuronio.inputs[j],rede.camada[camada_atual].neuronio.pesos[j]);
            //printf("VALOR DO SOMATORIO DO NEURONIO ATUAL ATE AGORA: %f\t\t%i\n", rede.camada[camada_atual].neuronio.somatorio,loop);
            rede.camada[camada_atual].neuronio.resultado = sigmoide(rede.camada[camada_atual].neuronio.somatorio); //PROCESSO FUNCAO DE ATIVACAO
            
        }
        printf("\n\t\tSOMATORIO: %f\t RESULTADO %f\n", rede.camada[camada_atual].neuronio.somatorio, rede.camada[camada_atual].neuronio.resultado);
    }         
       }
    
        //REPASSADOR DOS RESULTADOS PARA OS NEURONIOS DA CAMADA ADIANTE    
        if (camada_atual != (sizeof(Layout)/sizeof(int))-1){    
                for (int j = 0; j < Layout[camada_atual+1]; j++){          //CORRE O NUMERO DE NEURONIOS NA CAMADA POSTERIOR
                       for (int k = 0; k < Layout[camada_atual]; k++){          //CORRE OS NEURONIOS DA CAMADA ATUAL
                        rede.camada[camada_atual+1].neuronio[j].inputs[k] = rede.camada[camada_atual].neuronio[k].resultado;
                     }
                }
        }
        
        saidas[padrão][0] = rede.camada[2].neuronio[0].resultado;
        saidas[padrão][1] = obj;
    }
    //printf("Neuronio de saida 0: %.10f\n\n", rede.camada[2].neuronio[0].resultado);
    //************************************FIM DA EXECUCAO DA REDE*********************************************************
    
    
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INICIO DO ALGORITMO BACKPROPAGATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    zerarSomatoriosDeltas(Layout, &rede, sizeof(Layout)/sizeof(int));
    //int E, e;
    //while (E > e){
        for (int k = 0; k < sizeof(Layout)/sizeof(int); k++){
                
        }
        
        //DELTA DA CAMADA DE SAIDA
        //DELTA = F'(X)*(OBJETIVO - F(X))
        for (int i = 0; i < Layout[(sizeof(Layout)/sizeof(int))-1]; i++){ //CORRE OS NEURONIOS
            rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.delta = derivada_sigmoide(rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.somatorio) * ((obj - rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.resultado));
            //rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.delta = derivada_sigmoide(rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.somatorio) * ((sin(entrada[padrão])+cos(entrada[padrão])) - rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.resultado);
            //printf("\nDERIVADA %f\n", derivada_sigmoide(rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.somatorio));
            //printf("\n%f\n",objetivo[padrão]);
             //printf("\nDELTA %.30f\n", rede.camada[(sizeof(Layout)/sizeof(int))-1].neuronio.delta);
         }
         
         
        //SOMATORIO_DELTA
        for (int i = 1; i > 0; i--){   //CORRE AS CAMADAS INTERMEDIARIAS
    
            for (int j = 0; j < Layout; j++){                //CORRE OS NEURONIOS DA CAMADA SETADA
                  
                  for (int k = 0; k < Layout[i+1]; k++){            //CORRE NEURONIOS DA CAMADA POSTERIOR
                      rede.camada.neuronio[j].somatorio_delta += rede.camada[i+1].neuronio[k].pesos[j] * rede.camada[i+1].neuronio[k].delta;
                }
            }
        }
        
        //DELTA DAS CAMADAS INTERMEDIARIAS
        //DELTA = F'(X)*SOMATORIO(PESOS ASSOCIADOS A SUA SAIDA * DELTAS DOS NEURONIOS REPECTIVOS AOS PESOS CITADOS)
        for (int k = (sizeof(Layout)/sizeof(int))-2; k > 0; k--){ //CORRE AS CAMADAS INTERMEDIARIAS
            for (int j = 0; j < Layout[k]; j++){                   //CORRE OS NEURONIOS
                rede.camada[k].neuronio[j].delta = derivada_sigmoide(rede.camada[k].neuronio[j].somatorio) * rede.camada[k].neuronio[j].somatorio_delta;
            }
        }
        
        //AJUSTE DOS PESOS: VARIACAO PESO = y * SOMATORIO( DELTA * SAIDAS DA CAMADA ATENRIOR )
        for (int k = 1; k < sizeof(Layout)/sizeof(int); k++){        //CORRE AS CAMADA (EXCETO A PRIMEIRA)
            for (int n = 0; n < Layout[k]; n++){                    //CORRE OS NEURONIOS
                for (int p = 0; p < Layout[k-1]; p++){                //CORRE OS PESOS
                    rede.camada[k].neuronio[n].pesos[p] += y*(rede.camada[k].neuronio[n].delta * rede.camada[k].neuronio[n].inputs[p]);
                }
            }
        }
    //}*/
    
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FIM DO ALGORITMO BACKPROPAGATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    printf("\n\n");
    //printf("Neuronio de saida %i: %.15f\n\n", padrão, saidas[padrão]);
    }
    for (int p = 0; p < 2; p++){
         printf("Neuronio de saida 0: %.15f\t Objetivo %.15f\n\n", saidas[p][0], saidas[p][1]);
    }
   
    }

    return 0;
}
 

Share this post


Link to post
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this