Oppure

Loading
02/01/12 15:23
web_pirate
Sto cercando di compilare questo sorgente:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define file_name "training_set.txt"
#define LEARNING_RATE 0.5

float sig(float x){
	return 1/(1+pow(M_E, -x));
}

float *rete_neurale(float *input, float **w_x_h, float *bias_h, float *neur_h, float **w_h_y, float *bias_y, int n_output){
float *output=malloc(n_output*sizeof(float));
float somma=0;
int i, j;
int n_in=sizeof(input)/sizeof(input[0]);
int n_h=sizeof(neur_h)/sizeof(neur_h[0]);

	for(i=0;n_h;i++){
		neur_h[i]=0;
	}

	for(i=0;i<n_in;i++){
		for(j=0;j<n_h;j++){
			if(i==n_in-1){
				neur_h[j]+=input[i]*w_x_h[i][j]+bias_h[j];
				neur_h[j]=sig(neur_h[j]);
			}else{
				neur_h[j]+=input[i]*w_x_h[i][j];
			}
		}
	}

	for(i=0;i<n_h;i++){
		for(j=0;j<n_output;j++){
			if(i==n_h-1){
				output[j]+=neur_h[i]*w_h_y[i][j]+bias_y[j];
				output[j]=sig(output[j]);
			}else{
				output[j]+=neur_h[i]*w_h_y[i][j];
			}
		}
	}

return output;
}

float aggiusta_peso(float peso, float delta, float learning_rate, float in){
	return peso+(delta*learning_rate*in);
}

float aggiusta_bias(float bias, float delta, float err){
	return bias+delta*err;
}

float max(float *arr){
int i;
float max1=1;

	for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++){
		if(arr[i]>max1){
			max1=arr[i];
		}
	}

return max1;
}

int main(){
int i, j, e, y;
int n_in=2, n_h=2, n_out=2, n_es=2, epoch;
float input[n_in];
float w_x_h[n_in][n_h];
float delta_h[n_h];
float bias_h[n_h];
float neur_h[n_h];
float w_h_y[n_h][n_out];
float delta_y[n_out];
float bias_y[n_out];
float *output;
float err_out[n_out], err_h[n_h], global_err;
float es_in[n_es][n_in], es_out[n_es][n_out];
float max;
FILE *fp;

	printf("\nInput: ");
	scanf("%d", &n_in);

	printf("\nNeuroni strato nascosto: ");
	scanf("%d", &n_h);

	printf("\nOutput: ");
	scanf("%d", &n_out);

	printf("\nNumero elementi training set: ");
	scanf("%d", &n_es);

	printf("\nEpoche di apprendimento: ");
	scanf("%d", &epoch);

	for(i=0;i<n_in;i++){
		for(j=0;j<n_h;j++){
			w_x_h[i][j]=0.5;
		}
	}

	for(i=0;i<n_h;i++){
		for(j=0;j<n_out;j++){
			w_h_y[i][j]=0.5;
		}
	}

	for(i=0;i<n_h;i++){
		bias_h[i]=0.5;
	}

	for(i=0;i<n_out;i++){
		bias_y[i]=0.5;
	}

	fp=fopen(file_name, "r");
	
	if(!fp){
		printf("\nImpossibile aprire il training set.\n");
		return 0;
	}else{
		printf("\nAccesso al training set.");
	}

	fseek(fp, 0, SEEK_SET);

	for(e=0;e<n_es;e++){
		for(i=0;i<n_in;i++){
			fscanf(fp, "%f", &es_in[e][i]);
		}

		for(i=0;i<n_out;i++){
			fscanf(fp, "%f", &es_out[e][i]);
		}
	}

	for(e=0;e<epoch;e++){
		printf("\n");
		global_err=0;
		for(i=0;i<n_es;i++){
			for(j=0;j<n_in;j++){
				input[j]=es_in[i][j];
			}

			output=rete_neurale(input, w_x_h, bias_h, neur_h, w_h_y, bias_y, n_out);
			
			for(j=0;j<n_out;j++){
				err_out[j]=es_out[i][j]-output[j];
			}

			for(j=0;j<n_out;j++){
				delta_y[j]=err_out[j]*(output[j]*(1-output[j]));
			}

			for(j=0;j<n_h;j++){
				err_h[j]=0;
			}

			for(j=0;j<n_h;j++){
				for(y=0;y<n_out;y++){
					err_h[j]=err_h[j]+(delta_y[y]*w_h_y[j][y]);
				}
			}

			for(j=0;j<n_h;j++){
				delta_h[j]=err_h[j]*(neur_h[j]*(1-neur_h[j]));
			}

			for(j=0;j<n_h;j++){
				for(y=0;y<n_out;y++){
					w_h_y[j][y]=aggiusta_peso(w_h_y[j][y], delta_y[y], LEARNING_RATE, neur_h[j]);
				}
			}

			for(j=0;j<n_out;j++){
				bias_y[j]=aggiusta_bias(bias_y[j], delta_y[j], err_out[j]);
			}

			for(j=0;j<n_in;j++){
				for(y=0;y<n_h;y++){
					w_x_h[j][y]=aggiusta_peso(w_x_h[j][y], delta_h[y], LEARNING_RATE, input[j]);
				}
			}

			for(j=0;j<n_h;j++){
				bias_h[j]=aggiusta_bias(bias_h[j], delta_h[j], err_h[j]);
			}

		printf("\n");
		for(j=0;j<n_in;j++){
			printf("%f ", es_in[i][j]);
		}
		printf("=");
		for(j=0;j<n_out;j++){
			printf("%f (%f)", output[j], es_out[i][j]);
		}
		}
	}
					
return 0;
}

ma gcc mi da come messaggio:
neural.c: In function ‘main’:
neural.c:150:4: warning: passing argument 2 of ‘rete_neurale’ from incompatible pointer type [enabled by default]
neural.c:12:8: note: expected ‘float **’ but argument is of type ‘float (*)[(long unsigned int)(n_h)]’
neural.c:150:4: warning: passing argument 5 of ‘rete_neurale’ from incompatible pointer type [enabled by default]
neural.c:12:8: note: expected ‘float **’ but argument is of type ‘float (*)[(long unsigned int)(n_out)]’

Qual'è il problema? O.o
aaa
02/01/12 16:47
Se leggi il messaggio d'errore c'è scritto che

nella riga 150, quindi in

output=rete_neurale(input, w_x_h, bias_h, neur_h, w_h_y, bias_y, n_out);

il secondo parametro, quindi

w_x_h

è di tipo incompatibile con quanto si aspetta la funzione.

Ed in effetti il compilatore ha ragione.
02/01/12 18:47
web_pirate
Il warning non lo da più se metto un (float**) prima di w_x_h. E' la soluzione giusta? Ho sempre avuto dei dubbi su questo "argomento", dove posso approfondire? Comunque ora, scomparsi i warning, quando eseguo il programma, arriva alla funzione rete_neurale(...) e mi fa un errore di segmentazione. Dite che ho sbagliato ad allocare la memoria per l'array di ritorno "output" della suddetta funzione?
aaa
02/01/12 19:25
Postato originariamente da web_pirate:

Il warning non lo da più se metto un (float**) prima di w_x_h. E' la soluzione giusta?


No

Ho sempre avuto dei dubbi su questo "argomento", dove posso approfondire?


Tutti i libri di C (spero tu ne abbia studiato almeno uno) parlando di array/matrici/puntatori.

Comunque ora, scomparsi i warning, quando eseguo il programma, arriva alla funzione rete_neurale(...) e mi fa un errore di segmentazione.


Ovvio, non hai affatto risolto ...

Dite che ho sbagliato ad allocare la memoria per l'array di ritorno "output" della suddetta funzione?


No ... il problema è che se il parametro è un doppio puntatore, tu devi passare un doppio puntatore. Altrimenti devi cambiare il tipo di parametro.