Jump to content
Fórum Script Brasil
  • 0

Aonde foi que eu errei?


cezarvaz
 Share

Question

Oi pessoal!

Boa tarde a todos

estou implementando IA com classes de tipos de  redes neurais e deu um erro na linha 59 e não sei

aonde eu errei.

Se alguém puder me ajudar, PLZ!!!!

#include <iostream>
 #include <iomanip> 
 using namespace std;
class IArt{ // Classe base - Inteligencia Artificial.    
    
    private:    
        long semente;  
        double beta, alfa;
        int numTraining, ciclos,cicloatual,numOutputs, numInputs;
        double* bias1;    double* net1;    double* fnet1;    double* deltabs1;
        double** pesos1; double** deltapesos1; 
                     
    public:
        void set_Semente(long num) { semente = num; } 
        long get_Semente() { return semente; }
        
        void set_Beta(double num) { beta = num; } 
        double get_Beta() { return beta; }
        
        void set_Alfa(double num) { alfa = num; } 
        double get_Alfa() { return alfa; }  
        
        void set_NumTraining(int num) { numTraining = num; } 
        int get_NumTraining() { return numTraining; }
           
        void set_Ciclos(int num) { ciclos = num; } 
        int get_Ciclos() { return ciclos; }
        
        void set_CicloAtual(int num) { cicloatual = num; } 
        int get_CicloAtual() { return cicloatual; }
        
        void set_NumOutputs(int num) { 
            numOutputs = num; 
            bias1 = new double[numOutputs]; 
            net1 = new double[numOutputs];
            fnet1 = new double[numOutputs];
            deltabs1 = new double[numOutputs];    
        } 
        int get_NumOutputs() { return numOutputs; }
        
        void set_NumInputs(int num) { numInputs = num; } 
        int get_NumInputs() { return numInputs; }
        
        void set_Bias1(int index, double value) { bias1[index]=value; } 
        int get_Bias1(int index) { return bias1[index]; }
        
        void set_Net1(int index, double value) { net1[index]=value; } 
        int get_Net1(int index) { return net1[index]; }
        
        void set_Fnet1(int index, double value) { fnet1[index]=value; } 
        int get_Fnet1(int index) { return fnet1[index]; }       
        
        void set_Deltabs1(int index, double value) { deltabs1[index]=value; } 
        int get_Deltabs1(int index) { return deltabs1[index]; } 
        
        void set_Pesos1(int row, int col, double value) { pesos1[row][col] = value; } 
        double get_Pesos1(int row, int col) { return pesos1[row][col]; }
        
        void Init_Pesos1(int row, int col) { pesos1 = new double[row][col]; }  <<<<<<<<<<<<<<<<Aqui!
        
};
    
class Preceptron : public IArt { // Define classe Preceptron.
        
    public:        
    void mostrar();
};  
      
    void Preceptron::mostrar(){
        cout << "semente: " << get_Semente() << "\n";  
        cout << "beta: " << get_Beta() << "\n"; 
        cout << "alfa: " << get_Alfa() << "\n"; 
        cout << "numTraining: " << get_NumTraining() << "\n"; 
        cout << "ciclos: " << get_Ciclos() << "\n"; 
        cout << "ciclo atual : " << get_CicloAtual() << "\n";  
        cout << "numOutputs : " << get_NumOutputs() << "\n";
        cout << "numInputs : " << get_NumInputs() << "\n";
    }      
         
int main() {
    Preceptron p1, p2;
    p1.set_Semente(13);
    p1.set_Beta(0.0); 
    p1.set_Alfa(1.0);  
    p1.set_NumTraining(4); 
    p1.set_Ciclos(2);
    p1.set_CicloAtual(0);
    p1.set_NumOutputs(1);
    p1.set_NumInputs(2);
    p1.Init_Pesos1(p1.get_NumOutputs(),p1.get_NumInputs());
    
    p1.mostrar();
    cout << "\n"; 
    return 0;
}

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

  • 0
#include <iostream>
#include <iomanip>
using namespace std;
class IArt { // Classe base - Inteligencia Artificial.

private:
    long semente;
    double beta, alfa;
    int numTraining, ciclos, cicloatual, numOutputs, numInputs;
    double* bias1;    double* net1;    double* fnet1;    double* deltabs1;
    double** pesos1; double** deltapesos1;
    int _row, _col;
public:
    void set_Semente ( long num ) { semente = num; }
    long get_Semente() { return semente; }
    
    void set_Beta ( double num ) { beta = num; }
    double get_Beta() { return beta; }
    
    void set_Alfa ( double num ) { alfa = num; }
    double get_Alfa() { return alfa; }
    
    void set_NumTraining ( int num ) { numTraining = num; }
    int get_NumTraining() { return numTraining; }
    
    void set_Ciclos ( int num ) { ciclos = num; }
    int get_Ciclos() { return ciclos; }
    
    void set_CicloAtual ( int num ) { cicloatual = num; }
    int get_CicloAtual() { return cicloatual; }
    
    void set_NumOutputs ( int num ) {
        numOutputs = num;
        bias1 = new double[numOutputs];
        net1 = new double[numOutputs];
        fnet1 = new double[numOutputs];
        deltabs1 = new double[numOutputs];
    }
    int get_NumOutputs() { return numOutputs; }
    
    void set_NumInputs ( int num ) { numInputs = num; }
    int get_NumInputs() { return numInputs; }
    
    void set_Bias1 ( int index, double value ) { bias1[index] = value; }
    int get_Bias1 ( int index ) { return bias1[index]; }
    
    void set_Net1 ( int index, double value ) { net1[index] = value; }
    int get_Net1 ( int index ) { return net1[index]; }
    
    void set_Fnet1 ( int index, double value ) { fnet1[index] = value; }
    int get_Fnet1 ( int index ) { return fnet1[index]; }
    
    void set_Deltabs1 ( int index, double value ) { deltabs1[index] = value; }
    int get_Deltabs1 ( int index ) { return deltabs1[index]; }
    
    void set_Pesos1 ( int row, int col, double value ) { pesos1[row][col] = value; }
    double get_Pesos1 ( int row, int col ) { return pesos1[row][col]; }
    
    void Init_Pesos1 ( int row, int col ) {
        _col = col;
        _row = row;
        pesos1 = new double*[_row];
        for ( int i; i < _col; i++ ) {
                pesos1[i] = new double[_col];
        }
    }
    
    //destrutor... muito importante para liberar a memoria dinamica
    ~IArt(){
        std::cout << "Leberando recursos..." << endl;
        //liberando a matriz
        for ( int i; i < _col; i++ ) {
                delete[] pesos1[i];
        }
        delete[] pesos1;
    } 
    
};

class Preceptron : public IArt { // Define classe Preceptron.

public:
    void mostrar();
};

void Preceptron::mostrar() {
    cout << "semente: " << get_Semente() << "\n";
    cout << "beta: " << get_Beta() << "\n";
    cout << "alfa: " << get_Alfa() << "\n";
    cout << "numTraining: " << get_NumTraining() << "\n";
    cout << "ciclos: " << get_Ciclos() << "\n";
    cout << "ciclo atual : " << get_CicloAtual() << "\n";
    cout << "numOutputs : " << get_NumOutputs() << "\n";
    cout << "numInputs : " << get_NumInputs() << "\n";
}

int main() {
    Preceptron p1, p2;
    p1.set_Semente ( 13 );
    p1.set_Beta ( 0.0 );
    p1.set_Alfa ( 1.0 );
    p1.set_NumTraining ( 4 );
    p1.set_Ciclos ( 2 );
    p1.set_CicloAtual ( 0 );
    p1.set_NumOutputs ( 1 );
    p1.set_NumInputs ( 2 );
    p1.Init_Pesos1 ( p1.get_NumOutputs(), p1.get_NumInputs() );
    
    p1.mostrar();
    cout << "\n";
    return 0;
}

 

Link to comment
Share on other sites

  • 0

Valeu pela excelente resposta, mas pra variar ainda tem duas dúvidas na finalização.

1.O código tem agora um problema de passar as matrizes entrada e saida que não consigo resolver,

2.Nunca utilizei o destrutor, talvez porque meus códigos até então eram pequenos, qual seria a

localização dele no código? 

Agradeço a gentileza, vou ajudar os outros integrantes deste forum com alguma coisa que eu saiba responder.

Abração a todos...

 #include <iostream>
 #include <iomanip> 
 #include <stdlib.h>
 #include <time.h>
 using namespace std;
class IArt{ // Classe base - Inteligencia Artificial.    
    
    private:    
        long semente;  
        double beta, alfa;
        int numTraining, ciclos,cicloatual,numOutputs, numInputs,linha,coluna;
        double *bias1;    double *net1;    double *fnet1;    double *deltabs1;
        double **pesos1; double **deltapesos1;
        double **erro1; double **erro2;
          double **entradas; double **saidas;
        
     public:
        void set_Semente(long num) { semente = num; } 
        long get_Semente() { return semente; }
        
        void set_Beta(double num) { beta = num; } 
        double get_Beta() { return beta; }
        
        void set_Alfa(double num) { alfa = num; } 
        double get_Alfa() { return alfa; }  
        
        void set_NumTraining(int num) { numTraining = num; } 
        int get_NumTraining() { return numTraining; }
           
        void set_Ciclos(int num) { ciclos = num; } 
        int get_Ciclos() { return ciclos; }
        
        void set_CicloAtual(int num) { cicloatual = num; } 
        int get_CicloAtual() { return cicloatual; }
        
        void set_NumOutputs(int num) { 
            numOutputs = num; 
            bias1 = new double[numOutputs]; 
            net1 = new double[numOutputs];
            fnet1 = new double[numOutputs];
            deltabs1 = new double[numOutputs];    
        } 
        int get_NumOutputs() { return numOutputs; }
        
        void set_NumInputs(int num) { numInputs = num; } 
        int get_NumInputs() { return numInputs; }
        
        void set_Bias1(int index, double value) { bias1[index]=value; } 
        int get_Bias1(int index) { return bias1[index]; }
        
        void set_Net1(int index, double value) { net1[index]=value; } 
        int get_Net1(int index) { return net1[index]; }
        
        void set_Fnet1(int index, double value) { fnet1[index]=value; } 
        int get_Fnet1(int index) { return fnet1[index]; }       
        
        void set_Deltabs1(int index, double value) { deltabs1[index]=value; } 
        int get_Deltabs1(int index) { return deltabs1[index]; } 
        
        void set_Pesos1(int row, int col, double value) { pesos1[row][col] = value; } 
        double get_Pesos1(int row, int col) { return pesos1[row][col]; }
        void init_Pesos1(int row, int col) {
            pesos1 = new double*[row];
            for(int i = 0; i < row; i++)
                pesos1 = new double[col];
        }
        
        void set_DeltaPesos1(int row, int col, double value) { deltapesos1[row][col] = value; }
        double get_DeltaPesos1(int row, int col) { return deltapesos1[row][col]; }
        void init_DeltaPesos1(int row, int col) {
            deltapesos1 = new double*[row];
            for(int i = 0; i < row; i++)
                deltapesos1 = new double[col];
        }
        
        void set_Erro1(int row, int col, double value) { erro1[row][col] = value; }
        double get_Erro1(int row, int col) { return erro1[row][col]; }
        void init_Erro1(int row, int col) {
            erro1 = new double*[row];
            for(int i = 0; i < row; i++)
                erro1 = new double[col];
        }

        void set_Erro2(int row, int col, double value) { erro2[row][col] = value; }
        double get_Erro2(int row, int col) { return erro2[row][col]; }
        void init_Erro2(int row, int col) {
            erro2 = new double*[row];
            for(int i = 0; i < row; i++)
                erro2 = new double[col];
        }
        
        double get_Entradas(int row, int col) { return entradas[row][col]; }
        double get_Saidas(int row, int col) { return saidas[row][col]; }
};
    
class Preceptron : public IArt { // Classe Preceptron.
    public:
    void mostrar();
    void randomize();
    void Forward();
};  
    void Preceptron::randomize(){
        srand(time(NULL));
        int Random = rand() % get_Semente();
        cout<<Random<<"\n";
        
        for (int j=0; j<get_NumOutputs(); j++){
            set_Bias1(j,0.0);
            set_Deltabs1(j, 0.0d);
            
            for (int i=0; i<get_NumInputs(); i++){
                set_Pesos1(j,i,3.0);
                set_DeltaPesos1(j,i,0.0d);
            }
        }
    }
    
    void Preceptron::Forward(){
         for(int kl=0; kl< get_Ciclos(); kl++){
                set_CicloAtual(get_CicloAtual()+ 1);
                
            for(int itr=0; itr<get_NumTraining(); itr++) {
                double ea,eb;
                for (int j=0;j<get_NumOutputs();j++) {
                    set_Net1(j, get_Bias1(j));
                    for(int i=0;i<get_NumInputs();i++){
                        set_Net1(j,get_Net1(j)+ (get_Pesos1(j, i)* get_Entradas(itr,i)));
                    }
                    if (get_Net1(j)>= 0.)
                        ea=1.;
                    else
                        ea=0.;
                        set_Fnet1(j,(double) (ea));
                }
                //Ajuste de pesos BackWard
                for(int j=0;j<get_NumOutputs();j++) {
                    set_Erro2(itr,j, (get_Saidas(itr,j) - get_Fnet1(j)));
                    cout<<"Ciclo:"<<"\t"<<get_CicloAtual()<<"\t"<<"Exemplo:"<<"\t"<<itr+1<<"\n";
                    cout<<"Saída desejada:"<<"\t"<<get_Saidas(itr,j)<<"\t"<<"Saída calculada:"<<"\t"<<get_Fnet1(j)<<"\n";
                    cout<<"Erro:"<<"\t"<<get_Erro2(itr,j)<<"\n";
                }
                for(int j=0;j<get_NumOutputs();j++) {
                    set_Deltabs1(j,( get_Alfa() * get_Erro2(itr,j)));
                        for(int ii=0;ii<get_NumInputs();ii++) {
                            set_DeltaPesos1(j,ii, (get_Alfa() * get_Erro2(itr,j))*(get_Entradas(itr,ii)));
                        }
                }
                for(int j=0;j<get_NumOutputs();j++) {
                    set_Bias1(j, get_Deltabs1(j) + get_Bias1(j));
                    cout<<"bias:"<<"\t"<< j<<"\t"<< get_Bias1(j)<<"\n";
                    for(int ii=0;ii<get_NumInputs();ii++){
                        set_Pesos1(j,ii, get_Pesos1(j,ii)+(get_DeltaPesos1(j,ii)));
                        cout<<"Peso:"<<"\t"<<j<<"\t"<<ii<<"\t"<<get_Pesos1(j,ii)<<"\n";
                    }
                }
            }
         }
    }
    
    void Preceptron::mostrar(){
        cout << "semente: " << get_Semente() << "\n";  
        cout << "beta: " << get_Beta() << "\n"; 
        cout << "alfa: " << get_Alfa() << "\n"; 
        cout << "numTraining: " << get_NumTraining() << "\n"; 
        cout << "ciclos: " << get_Ciclos() << "\n"; 
        cout << "ciclo atual : " << get_CicloAtual() << "\n";  
        cout << "numOutputs : " << get_NumOutputs() << "\n";
        cout << "numInputs : " << get_NumInputs() << "\n";
    }      
         
int main() {
    Preceptron p1, p2;
    p1.set_Semente(13); p1.set_Beta(0.0); p1.set_Alfa(1.0); p1.set_NumTraining(4);
    p1.set_Ciclos(2); p1.set_CicloAtual(0); p1.set_NumOutputs(1); p1.set_NumInputs(2);
    
    p1.init_Pesos1(p1.get_NumOutputs(),p1.get_NumInputs());
    p1.init_DeltaPesos1(p1.get_NumOutputs(),p1.get_NumInputs());
    p1.init_Erro1(p1.get_NumTraining(),p1.get_NumOutputs());
    p1.init_Erro2(p1.get_NumTraining(),p1.get_NumOutputs());
    
    p1.randomize();

     double entradasIniciais [4][2]  = {{0,0},{0,1},{1,0},{1,1}};
    entradas = entradasIniciais;
    p1.get_Entradas(entradas);
    double saidasIniciais [4][1]  = {{0},{0},{0},{1}};
    saidas = saidasIniciais;

    
    p1.mostrar();
    cout << "\n"; 
    return 0;
}

Link to comment
Share on other sites

  • 0

você está cometendo muitos erros. Uma matriz não é mais que um vetor de vetores, na seguinte imagem você pode ver bem ilustrado o que é uma matriz. Primeiro você deve saber que é um vetor, certamente você sabe que é um vetor, mas mesmo assim vamos fazer um repasso... Um vetor nada mais é que um conjunto de variáveis alojadas na memoria RAM de forma consecutiva, e que seu primeiro elemento é apontado por um ponteiro, um vetor pode guardar dados de qualquer tipo básico ou complexo, com básico me refiro a int, char, etc, e com complexo me refiro a structs, classes, etc, incluindo outros vetores(matriz) e por suposto um vetor pode alojar direções de memoria. Para que isso fique mais claro, imaginamos que podemos fazer hipoteticamente falando, algo como isso:
int vetor1[10];
int vetor2[10];
int vetor3[10];
int *matriz[3];

E agora podemos fazer algo como isso:
matriz[0] = &vetor1[0];
matriz[1] = &vetor2[0];
matriz[2] = &vetor3[0];

Pois justamente esse é o conceito de uma matriz... um vetor de ponteiros no qual cada casinha desse vetor guarda a direção dos primeiros elementos de outros vetores, que nada mais são que ponteiros. A Essa altura você deve se estar perguntando por que estou te contando tudo isso, e é bem por que você esta tratando uma matriz como se de um vetor se tratara.
Na linha 63 por exemplo, mais ou menos, você deu a ordem de reservar um vetor de ponteiros pesos1 = new double*[row];
, esse vetor deveria guardar  tantos outros vetores como filas existam em cada uma de suas casinhas, não obstante você está tratando esse vetor de ponteiros como se fosse um simples ponteiro, e não é um ponteiro se não um vetor, por isso mostra uma e outra vez o mesmo erro em todas as instruções que você tenta reservar memoria dinâmica no seu programa(...cannot convert 'double*' to 'double**' in assignment|), o erro diz que não é possivel converter um ponteiro a ponteiro duplo, veja abaixo o erro:

No seu código você aloca memoria tal qual:

        for ( int i = 0; i < row; i++ )
            pesos1 = new double[col];

 Porem deveria ser:

        for ( int i = 0; i < row; i++ )
            pesos1[i] = new double[col];

 

Se não qual o sentido que teria usar um loop? Pense nisso >_<, você está sobre escrevendo o mesmo ponteiro com cada new se fosse possível fazer o que você está fazendo, por isso o erro.

Sobre o construtor, ele deve estar contido na parte publica, porem não tem inconvenientes você declará-lo na parte privada da classe, pois se isso for feito você não poderá invocá-lo, isso pode ser feito com construtores também, um exemplo pode ser o tal padrão singleton no qual tanto destrutores como os construtores são declarados como privados impossibilitando que o usuário crie objetos de essa classe, pois somente pode haver uma instancia de esta classe, de aí vem o nome single+ton(padrão single). Leia mais sobre o padrão singleton em google, é muito interessante. ;)

 

Link to comment
Share on other sites

  • 0

Baita explicação!!!!!

eu não tinha este entendimento muito concreto, valeu pela maneira simples e direta de explicar!

Neste meu trabalho, estou traduzindo um código de Java para C++ e estou engatinhando em POO

Fiz alterações no código e agora me resta passar as matrizes. O conhecimento para ler txt com os dados necessários

como matrizes e substituir o comando abaixo eu sei, basta eu saber como passar a matriz para a classe preceptron, pois os cálculos 

estão prontos, com isso eu aprendo POO e IA também.

Quando eu conseguir este passo em POO poderei fazer outras coisas também, se puderes me aturar mais um pouco agradeço a ajuda!!!

double entradasIniciais [4][2]  = {{0,0},{0,1},{1,0},{1,1}};
    entradas = entradasIniciais;
    p1.set_Entradas(4,2);
double saidasIniciais [4][1]  = {{0},{0},{0},{1}};
    p1.set_Saidas(4,1);
    saidas = saidasIniciais;

Segue o novo código ;-)

 #include <iostream>
 #include <iomanip> 
 #include <stdlib.h>
 #include <time.h>
 using namespace std;
class IArt{ // Classe base - Inteligencia Artificial.    
    
    private:    
        long semente;  
        double beta, alfa;
        int numTraining, ciclos,cicloatual,numOutputs, numInputs,linha,coluna;
        double *bias1;    double *net1;    double *fnet1;    double *deltabs1;
        double **pesos1; double **deltapesos1;
        double **erro1; double **erro2;

        
     public:
     double **entradas; double **saidas;
        void set_Semente(long num) { semente = num; } 
        long get_Semente() { return semente; }
        
        void set_Beta(double num) { beta = num; } 
        double get_Beta() { return beta; }
        
        void set_Alfa(double num) { alfa = num; } 
        double get_Alfa() { return alfa; }  
        
        void set_NumTraining(int num) { numTraining = num; } 
        int get_NumTraining() { return numTraining; }
           
        void set_Ciclos(int num) { ciclos = num; } 
        int get_Ciclos() { return ciclos; }
        
        void set_CicloAtual(int num) { cicloatual = num; } 
        int get_CicloAtual() { return cicloatual; }
        
        void set_NumOutputs(int num) { 
            numOutputs = num; 
            bias1 = new double[numOutputs]; 
            net1 = new double[numOutputs];
            fnet1 = new double[numOutputs];
            deltabs1 = new double[numOutputs];    
        } 
        int get_NumOutputs() { return numOutputs; }
        
        void set_NumInputs(int num) { numInputs = num; } 
        int get_NumInputs() { return numInputs; }
        
        void set_Bias1(int index, double value) { bias1[index]=value; } 
        int get_Bias1(int index) { return bias1[index]; }
        
        void set_Net1(int index, double value) { net1[index]=value; } 
        int get_Net1(int index) { return net1[index]; }
        
        void set_Fnet1(int index, double value) { fnet1[index]=value; } 
        int get_Fnet1(int index) { return fnet1[index]; }       
        
        void set_Deltabs1(int index, double value) { deltabs1[index]=value; } 
        int get_Deltabs1(int index) { return deltabs1[index]; } 
        
        void set_Pesos1(int row, int col, double value) { pesos1[row][col] = value; } 
        double get_Pesos1(int row, int col) { return pesos1[row][col]; }
        void init_Pesos1(int row, int col) {
            pesos1 = new double*[row];
            for(int i = 0; i < row; i++)
                pesos1 = new double[col];
        }
        
        void set_DeltaPesos1(int row, int col, double value) { deltapesos1[row][col] = value; }
        double get_DeltaPesos1(int row, int col) { return deltapesos1[row][col]; }
        void init_DeltaPesos1(int row, int col) {
            deltapesos1 = new double*[row];
            for(int i = 0; i < row; i++)
                deltapesos1 = new double[col];
        }
        
        void set_Erro1(int row, int col, double value) { erro1[row][col] = value; }
        double get_Erro1(int row, int col) { return erro1[row][col]; }
        void init_Erro1(int row, int col) {
            erro1 = new double*[row];
            for(int i = 0; i < row; i++)
                erro1 = new double[col];
        }

        void set_Erro2(int row, int col, double value) { erro2[row][col] = value; }
        double get_Erro2(int row, int col) { return erro2[row][col]; }
        void init_Erro2(int row, int col) {
            erro2 = new double*[row];
            for(int i = 0; i < row; i++)
                erro2 = new double[col];
        }
        
        void set_Entradas(int row, int col) {
            entradas = new double*[row];
            for(int i = 0; i < row; i++){
                entradas = new double[col];
            }
        }
        double get_Entradas(int row, int col) { return entradas[row][col]; }
        
        void set_Saidas(int row, int col) {
            saidas = new double*[row];
            for(int i = 0; i < row; i++)
                saidas = new double[col];
        }
        double get_Saidas(int row, int col) { return saidas[row][col]; }
};
    
class Preceptron : public IArt { // Classe Preceptron.
    public:
    void mostrar();
    void randomize();
    void Forward();

};  
    void Preceptron::randomize(){
        srand(time(NULL));
        int Random = rand() % get_Semente();
        cout<<Random<<"\n";
        
        for (int j=0; j<get_NumOutputs(); j++){
            set_Bias1(j,0.0);
            set_Deltabs1(j, 0.0d);
            
            for (int i=0; i<get_NumInputs(); i++){
                set_Pesos1(j,i,3.0);
                set_DeltaPesos1(j,i,0.0d);
            }
        }
    }
    
    void Preceptron::Forward(){
        
         for(int kl=0; kl< get_Ciclos(); kl++){
                set_CicloAtual(get_CicloAtual()+ 1);
                
            for(int itr=0; itr<get_NumTraining(); itr++) {
                double ea,eb;
                for (int j=0;j<get_NumOutputs();j++) {
                    set_Net1(j, get_Bias1(j));
                    for(int i=0;i<get_NumInputs();i++){
                        set_Net1(j,get_Net1(j)+ (get_Pesos1(j, i)* get_Entradas(itr,i)));
                    }
                    if (get_Net1(j)>= 0.)
                        ea=1.;
                    else
                        ea=0.;
                        set_Fnet1(j,(double) (ea));
                }
                //Ajuste de pesos BackWard
                for(int j=0;j<get_NumOutputs();j++) {
                    set_Erro2(itr,j, (get_Saidas(itr,j) - get_Fnet1(j)));
                    cout<<"Ciclo:"<<"\t"<<get_CicloAtual()<<"\t"<<"Exemplo:"<<"\t"<<itr+1<<"\n";
                    cout<<"Saída desejada:"<<"\t"<<get_Saidas(itr,j)<<"\t"<<"Saída calculada:"<<"\t"<<get_Fnet1(j)<<"\n";
                    cout<<"Erro:"<<"\t"<<get_Erro2(itr,j)<<"\n";
                }
                for(int j=0;j<get_NumOutputs();j++) {
                    set_Deltabs1(j,( get_Alfa() * get_Erro2(itr,j)));
                        for(int ii=0;ii<get_NumInputs();ii++) {
                            set_DeltaPesos1(j,ii, (get_Alfa() * get_Erro2(itr,j))*(get_Entradas(itr,ii)));
                        }
                }
                for(int j=0;j<get_NumOutputs();j++) {
                    set_Bias1(j, get_Deltabs1(j) + get_Bias1(j));
                    cout<<"bias:"<<"\t"<< j<<"\t"<< get_Bias1(j)<<"\n";
                    for(int ii=0;ii<get_NumInputs();ii++){
                        set_Pesos1(j,ii, get_Pesos1(j,ii)+(get_DeltaPesos1(j,ii)));
                        cout<<"Peso:"<<"\t"<<j<<"\t"<<ii<<"\t"<<get_Pesos1(j,ii)<<"\n";
                    }
                }
            }
         }
    }
    
    void Preceptron::mostrar(){
        cout << "semente: " << get_Semente() << "\n";  
        cout << "beta: " << get_Beta() << "\n"; 
        cout << "alfa: " << get_Alfa() << "\n"; 
        cout << "numTraining: " << get_NumTraining() << "\n"; 
        cout << "ciclos: " << get_Ciclos() << "\n"; 
        cout << "ciclo atual : " << get_CicloAtual() << "\n";  
        cout << "numOutputs : " << get_NumOutputs() << "\n";
        cout << "numInputs : " << get_NumInputs() << "\n";
    }      
         
int main() {
    Preceptron p1, p2;
    p1.set_Semente(13); p1.set_Beta(0.0); p1.set_Alfa(1.0); p1.set_NumTraining(4);
    p1.set_Ciclos(2); p1.set_CicloAtual(0); p1.set_NumOutputs(1); p1.set_NumInputs(2);
    
    p1.init_Pesos1(p1.get_NumOutputs(),p1.get_NumInputs());
    p1.init_DeltaPesos1(p1.get_NumOutputs(),p1.get_NumInputs());
    p1.init_Erro1(p1.get_NumTraining(),p1.get_NumOutputs());
    p1.init_Erro2(p1.get_NumTraining(),p1.get_NumOutputs());
    
    p1.randomize();

     double entradasIniciais [4][2]  = {{0,0},{0,1},{1,0},{1,1}};
    entradas = entradasIniciais;
    p1.set_Entradas(4,2);
    double saidasIniciais [4][1]  = {{0},{0},{0},{1}};
    p1.set_Saidas(4,1);
    saidas = saidasIniciais;
    
    p1.mostrar();
    cout << "\n"; 
    return 0;
}

Link to comment
Share on other sites

  • 0

No caso double entradasIniciais [4][2]  = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};, trata-se de uma matriz(vetor de vetores) tipo C, como expliquei lá em cima, uma matriz não é mais que um conjunto de dados básico, esse tipo de matrizes são provenientes de C, em C não podemos copiar matriz1 = matriz2, pois recorde que em C não existem as classes, uma matriz não é uma classe, se fosse uma classe você poderia ter um construtor de cópia, um exemplo é a classe string, se você declarar um string mais ou menos como string vetor; posteriormente você pode copiar vetor1=vetor2, nesse caso trato o string como vetores para o exemplo mas poderia ser string matriz[10], logo você poderia fazer matriz = outramatriz, claramente sabemos que o tipo string em c++ é uma classe, e também sabemos que as classes são como navalhas suíças, elas tem muitas funções em uma só, nesse caso a classe string está preparada para receber outra string por causa do seu construtor de cópia e justamente esse construtor de cópia faz o trabalho por você se você estiver tratando com objetos da classe string, mas com arrays de C a coisa muda, é você que tem que fazer todo o trabalho:

#include <iostream>
using namespace std;
const int linhas = 4;
const int colunas = 2;

void printMatriz(double m[linhas][colunas]);

int main() {
    
    double entradas [linhas][colunas];
    double entradasIniciais [linhas][colunas]  = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
    //entradas = entradasIniciais; <- Errado nao funciona, entradasIniciais é um conjunto de dados basico, as matrizes sao de C, atribuiçoes devem ser feitas manualmente.
    
    
    //forma correta de copiar uma matriz
    for ( int i = 0; i < linhas; i++ ) {
        for ( int x = 0; x < colunas; x++ ) {
            entradas[i][x] = entradasIniciais[i][x];
        }
    }
    
    //comprovamos que se copiou corretamente
    cout << "entradaInicial=";
    printMatriz(entradasIniciais);
    
    cout << "\nentrada=";
    printMatriz(entradas);
    
    return 0;
}

void printMatriz(double m[linhas][colunas]){
    cout << '{';
    for ( int i = 0; i < linhas; i++ ) {
        cout << '{';
        for ( int x = 0; x < colunas; x++ ) {
            cout << m[i][x] ;
            if(x==0){
                cout << ',';    
            }
        }
        if (i != linhas-1){
            cout << "},";
            cout << ' ';
        }
    }
    cout << "}}";
}


Um truque pode ser usando a função memcpy que simplesmente faz copias de um pedaço da memória a outro. Exemplo:
 

#include <iostream>
#include <string.h> //<- para poder usar memcpy
using namespace std;
const int linhas = 4;
const int colunas = 2;

void printMatriz(double m[linhas][colunas]);

int main() {
    
    double entradas [linhas][colunas];
    double entradasIniciais [linhas][colunas]  = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
    //entradas = entradasIniciais; <- Errado nao funciona, entradasIniciais é um conjunto de dados basico, as matrizes sao de C, atribuiçoes devem ser feitas manualmente.
    
    //Outraforma de copiar uma matriz é usando memcpy(void * destino, void * fonte, size_t bytes);
    memcpy(entradas, entradasIniciais, (linhas*colunas)*sizeof(double)); //(linhas*colunas)*sizeof(double) é o tamanho que ocupa a matriz na memoria
    
    //comprovamos que se copiou corretamente
    cout << "entradaInicial=";
    printMatriz(entradasIniciais);
    
    cout << "\nentrada=";
    printMatriz(entradas);
    
    return 0;
}

void printMatriz(double m[linhas][colunas]){
    cout << '{';
    for ( int i = 0; i < linhas; i++ ) {
        cout << '{';
        for ( int x = 0; x < colunas; x++ ) {
            cout << m[i][x] ;
            if(x==0){
                cout << ',';    
            }
        }
        if (i != linhas-1){
            cout << "},";
            cout << ' ';
        }
    }
    cout << "}}";
}

O problema é que com memória dinâmica e outros casos particulares você tem que tomar muito cuidado com essa função, pois alguns programadores costumam obter o tamanho da matriz usando sizeof(matriz) para logo passar esse tamanho para memcpy, isso funciona bem se declaramos a matriz como por exemplo double matriz[10][10] e logo depois passamos isso a memcpy memcpy(...,...,sizeof(matriz)), dentro da mesma função, mas quando passamos a matriz a outra função sizeof(matriz) já não funciona, pois em vez de devolver o tamanho da matriz o sizeof retorna o tamanho do ponteiro duplo, isso a causa por que em C++ sempre passamos ponteiros de forma implícita, faça provas, passe uma matriz a uma função, faça o o cout sizeof em ambas funções e veja o que acontece. Outra forma que falha memcpy é usando new, quando você usa new para reservar a memória para a matriz como te expliquei no inicio, ao tentar fazer sizeof da matriz você vai obter o tamanho do ponteiro e não da matriz, por isso pode falhar memcpy, então tome cuidado, para não ter problema, use memcpy dentro da mesma função onde a matriz foi declarada para obter o tamanho da matriz correto, se passar a matriz a outra função e tentar usar sizeof dentro dessa outra função pode dar erro, e se for alocar memória para a matriz com new, nem dentro de mesma função vai funcionar pois você só vai obter o tamanho do ponteiro, e não vai servir para indicar a memcpy o tamanho do tramo a ser copiado, por isso prefiro fazer (linha*coluna)*sizeof(tipo_do_dado) do que sizeof(matriz), pois com (linha*coluna)*sizeof(tipo_do_dado) você sempre vai obter o tamanho das matriz corretamente. Ah! Lembre sempre que uma matriz tenha tamanho suficiente para conter a outra.

para poder fazer matriz1 = matriz2 você deveria usar a biblioteca STL com seus respectivos containers, mais concretamente o tal STL vector: http://www.cplusplus.com/reference/vector/vector/operator=/, esse container possui o tal operador de cópia que te permite você fazer matrix1=matriz2, porem stl vector é um vetor, ele é criado de tal forma que para declarar ele você faria tal como stl::vector<double> vetor; más isso seria apenas um vetor, porem como falei, uma matriz trata-se de vetor de vetores, então a parada ficaria mais ou menos tal como stl::vector<stl::vector<double>> matriz;, algo complicado porem como falei, nesse caso stl vector trata-se de uma classe, você poderia aproveitar de todas as funções que incluem a classe vetctor, é uma ferramenta potente, pois imagine que nesse vector você usa push_back e o vetor poderia crescer "infinitamente" dependendo da sua RAM claro.

Te aconselho usar containars para trabalhos importantes, eles podem te diminuir e muito o tempo de programaçao, pois você não teria que se preucupar por coisas como espaço, copiar uma matriz a outra, etc, você simplesmente se centraria em criar sua aplicação, tudo são facilidades, para os estudos melhor usar arrays, pois as STL se baseiam sobre arrays, matrizes, memória dinâmica..., então se você chegar a dominar tais temas, certamente você poderá dominar os containers.


Espero ter sido de ajuda.
Sorte.

Esqueci de adjuntar a imagem que ilustra o que é realmente uma matriz anteriormente, deixo ela aqui: mem.png

Como você pode apreciar double **M; aponta a primeira posição do vetor m[0] depois cada posição desse vetor contem a direção dos outros vetores, por isso tenha sempre presente na sua mente, pensou em matriz é pensar em vetor de vetores. Quando vamos usar new para reservar a memória você pode apreciar bem o processo, pois ele é bem transparente, o que acontece é que quando vamos declarar uma matriz dentro de main, o linguagem é bem amigável e te permite você fazer coisas como int m[10][10] para declarar uma matriz, porem com memória dinâmica, você precisa trabalhar com ponteiros, chegado esse momento é quando você se da conta como é a mecânica interna do programa e a memória. Certamente você sabe que em qualquer escopo você pode fazer int n; mas se o n for dinâmico você precisa primeiro de um ponteiro int *ponteiro_a_n = new int;, esse é o mesmo caso das matrizes, em main ela é bonitinha tal como int matriz[y][x], mas com memória dinâmica isso se transforma nesse bicho aqui-> saidas = new double*[row]; for ( int i = 0; i < row; i++ )     saidas = new double[col]; por botar um exemplo, tudo são facilidades do linguagem como falei, java oculta muito isso ao programador. hehe

49190f2e14cc93379a226081df5cb136.jpg

XDD

Link to comment
Share on other sites

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.

 Share

  • Forum Statistics

    • Total Topics
      149.6k
    • Total Posts
      646.2k
×
×
  • Create New...