#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define SET_FILE "training_set.txt"
//Numero elementi
int N_IN;
int N_H;
int N_O;
int N_ES=2;
int EPOCH;
//Elementi
float *neur_in;
float *w_in_hid;
float *neur_hid;
float *w_hid_out;
float *neur_out;
float *err_out;
float *err_hid;
float *delta_out;
float *delta_hid;
float var_w;
float rate;
float bias_hid=0.5, bias_out=0.5;
float max=0;
//Esempi
float *es_in;
float *es_out;
float sig(float x){
return 1/(1+pow(M_E,-x));
}
void alloca_obj(){
neur_in=malloc(N_IN*sizeof(float));
w_in_hid=malloc(N_IN*N_H*sizeof(float));
neur_hid=malloc(N_IN*sizeof(float));
w_hid_out=malloc(N_IN*N_O*sizeof(float));
neur_out=malloc(N_IN*sizeof(float));
es_in=malloc(N_ES*N_IN*sizeof(float));
es_out=malloc(N_ES*N_O*sizeof(float));
err_out=malloc(N_O*sizeof(float));
err_hid=malloc(N_H*sizeof(float));
delta_out=malloc(N_O*sizeof(float));
delta_hid=malloc(N_H*sizeof(float));
}
void max_in(){
int i;
for(i=0;i<N_ES*N_IN;i++){
if(es_in[i]>max){
max=es_in[i];
}
}
for(i=0;i<N_ES*N_O;i++){
if(es_out[i]>max){
max=es_out[i];
}
}
}
void att_to_zero(){
int i;
for(i=0;i<N_H;i++){
neur_hid[i]=0;
}
for(i=0;i<N_O;i++){
neur_out[i]=0;
}
}
void output(){
int i, j;
att_to_zero();
for(i=0;i<N_IN;i++){
for(j=0;j<N_H;j++){
neur_hid[j]+=neur_in[i]*w_in_hid[N_H*i+j]+bias_hid;
}
}
for(i=0;i<N_H;i++){
neur_hid[i]=sig(neur_hid[i]);
}
for(i=0;i<N_H;i++){
for(j=0;j<N_O;j++){
neur_out[j]+=neur_hid[i]*w_hid_out[N_O*i+j]+bias_out;
}
}
for(i=0;i<N_O;i++){
neur_out[i]=sig(neur_out[i]);
}
}
void w_rand(){
int i;
for(i=0;i<N_IN*N_H;i++){
w_in_hid[i]=0.5;
}
for(i=0;i<N_H*N_O;i++){
w_hid_out[i]=0.5;
}
}
void read_training_set(FILE *fp){
int i, j;
char ch;
for(i=0;i<N_ES;i++){
for(j=0;j<N_IN;j++){
fscanf(fp, "%f\t", &es_in[N_IN*i+j]);
}
for(j=0;j<N_O;j++){
fscanf(fp, "%f\t", &es_out[N_O*i+j]);
}
}
}
void training(){
int i, j, y, ep;
for(ep=0;ep<EPOCH;ep++){
printf("\nEPOCA N.%d _____________________________________________________\n", ep+1);
for(i=0;i<N_ES;i++){
for(j=0;j<N_IN;j++){
neur_in[j]=es_in[N_IN*i+j]/max;
}
output();
for(j=0;j<N_IN;j++){
neur_in[j]=es_in[N_IN*i+j]*max;
}
for(j=0;j<N_O;j++){
err_out[j]=es_out[N_O*i+j]-neur_out[j]*max;
}
for(y=0;y<N_O;y++){
delta_out[y]=err_out[y]*(neur_out[y]*(1-neur_out[y]));
}
for(j=0;j<N_H;j++){
err_hid[j]=0;
for(y=0;y<N_O;y++){
err_hid[j]+=delta_out[y]*w_hid_out[N_O*j+y];
}
}
for(j=0;j<N_H;j++){
delta_hid[j]=err_hid[j]*(neur_hid[j]*(1-neur_hid[j]));
}
for(j=0;j<N_H;j++){
for(y=0;y<N_O;y++){
w_hid_out[N_O*j+y]+=rate*delta_out[y]*neur_hid[j];
bias_out+=rate*delta_out[y];
}
}
for(j=0;j<N_IN;j++){
for(y=0;y<N_H;y++){
w_in_hid[N_H*j+y]+=rate*delta_hid[y]*neur_in[j];
bias_hid+=rate*delta_hid[y];
}
}
printf("\n-------------------\n");
for(y=0;y<N_O;y++){
printf("%f -> ", neur_out[y]*max);
printf("%f ", es_out[N_O*i+y]);
}
printf("\n-------------------\n");
for(j=0;j<N_O;j++){
printf("Errore: %f\n", err_out[j]);
}
}
}
}
int main(){
int i, j;
FILE *fp;
printf("\nStabilire learning rate: ");
scanf("%f", &rate);
//printf("\nNumero esempi: ");
//scanf("%d", &N_ES);
printf("\nNeuroni in strato di input - in riferimento al file training_set.txt -: ");
scanf("%d", &N_IN);
printf("\nNeuroni in strato nascosto: ");
scanf("%d", &N_H);
printf("\nNeuroni in strato di output - in riferimento al file training_set.txt -: ");
scanf("%d", &N_O);
printf("\nStabilire numero di epoche di apprendimento: ");
scanf("%d", &EPOCH);
fp=fopen(SET_FILE, "r");
alloca_obj();
read_training_set(fp);
fclose(fp);
w_rand();
max_in();
training();
printf("\nRete addestrata! Inserire nuovi inputs: \n");
for(i=0;i<N_IN;i++){
printf("Input n.%d: ", i+1);
scanf("%f", &neur_in[i]);
neur_in[i]/=max;
}
output();
printf("\n");
for(i=0;i<N_O;i++){
printf("%f ", neur_out[i]*max);
}
return 0;
}