next up previous contents index
Next: Test di valutazione Up: Reti Neurali Previous: La soluzione è...   Indice   Indice analitico

Eseguire le modifiche

Trovato il nuovo valore del campo "delta" per ogni sinapsi, basterà ciclare in tutta la rete e per ogni sinapsi applicare quel delta sul peso:

//STEP 6:Update all weights
commit_weight_changes(net->output_layer);
commit_weight_changes(net->hidden_layer);
[...]
//COMMIT_WEIGHT_CHANGES
void commit_weight_changes(layer* lPtr){
    int i,j;
    neurodo* nPtr;
    sinapsi* sPtr;
    for(i=0;i < lPtr->num_elements;i++){
        nPtr = lPtr->elements[i];
        for(j=0;j < nPtr->num_in_links;j++){
            sPtr = nPtr->in_links[j];
	    sPtr->weight += sPtr->delta;
            sPtr->delta = 0;
        }
    }
}
Per il layer hidden e output, e per ogni neurodo in essi, applichiamo il delta al peso delle sinapsi in entrata al neurodo. Da notare che dopo questa operazione il valore di "delta" viene resettato.

Forse non ci crederete, ma effettuando queste operazioni più e più volte, ovvero nell'ordine dei 300-400 cicli, la rete avrà imparato ad eseguire le somme con un margine di errore che va da fino a . Non male vero? Ognuno di questi cicli verrà chiamato "epoca".

Riassumiamo perciò tutto in un bel for nel main(), e eseguiamolo per un numero di volte pari a max_epochs (che possiamo variare a nostro piacimento in init_net())

for(j=0;j< net->max_epochs;j++){
    //STEP 1:Read input values
    for(i=0;i < net->input_layer->num_elements;i++){
        if((status = get_data(&temp,fd)) < 0){
            fprintf(stderr,"errore irreversibile, closing...\n");
            free_memory_nnet(net);
            return -1;
        }
        net->input_layer->elements[i]->prop_value=(_PRECISION)temp;
        net->input_layer->elements[i]->actv_value=(_PRECISION)temp;		
    }
    //STEP 2:Propagate values into hidden layer
    propagate_into_layer(net->hidden_layer);
    //STEP 3:Propagate values into output layer
    propagate_into_layer(net->output_layer);
    //STEP 4:Compute delta rule for the output layer
    if((status = get_data(&des_out,fd)) < 0){
        fprintf(stderr,"errore irreversibile, closing...\n");
	return -1;
    } else {
        out_delta = compute_output_delta(net->output_layer->elements[0]->prop_value,des_out);
        update_output_weights(net->output_layer,out_delta,net->l_rate);
    }
    //STEP 5:Compute delta rule for the hidden layer
    update_hidden_weights(net->hidden_layer,out_delta,net->l_rate);
    //STEP 6:Update all weights
    commit_weight_changes(net->output_layer);
    commit_weight_changes(net->hidden_layer);
    net_output = net->output_layer->elements[0]->prop_value;
    printf("DES=%f\tERROR=%f\tOUT=%f\tDELTA=%f\n",des_out,
    		(des_out-net_output),net_output,out_delta);
} //END MAIN LOOP
Questo è il cuore dell'apprendimento della nostra rete: vengono riassunti i 6 passi fondamentali che ho spiegato prima, con le varie chiamate alle funzioni da noi già analizzate. In più c'è la stampa di informazioni di debug sul risultato ottenuto dopo ogni epoca. Quello che voi dovreste vedere eseguendo il programma è che dopo un pò il valore di ERROR assume valori sempre più piccoli tendendo (si spera) a qualcosa di simile allo 0.


next up previous contents index
Next: Test di valutazione Up: Reti Neurali Previous: La soluzione è...   Indice   Indice analitico
blacksheep & 2006-11-22