PDA

View Full Version : [C] Problemi con rete neurale feedforward


Teo@Unix
15-08-2010, 21:11
Ciao ho un problema nell'addestramento di una semplice rete neurale del tipo in oggetto.
Il mio intento è eseguire una somma.

Sono alle prime armi in questo campo.
Sono riuscito a creare la struttura della rete composta dai 3 layer: input, nascosto e di output.
Per l'apprendimento utilizzo l'algoritmo "Widrow*Hoff", un algoritmo di
apprendimento supervisionato che calcola i pesi necessari partendo da pesi casuali, e apportando a questi delle modifiche progressive in modo da convergere alla soluzione finale.

Il mio problema è che diverge alla grande :D ...
nel senso che già dopo aver ciclato per due "epoche" ci si accorge subito che non stà funzionando.
Il delta output e l'errore tendono all'infinito sin dal terzo ciclo di addestramento.....

Di seguito inserisco il main che da un'idea sul programma in termini generali....

spero che qualcuno mi possa dare un mano....
nel caso posso allegare tutti i sorgenti se volete provarla direttamente. (ho il progetto codeblocks per Linux)

Delle formule credo di esserne sicuro.
(Come funzione di trasferimento ho utilizzato l'identità per semplicità)

per l'addestramento uso un file di testo dove ho inserito sequenzialmente addendi più risultato per n volte...

il main:
int main(int argc,const char**argv)
{
DEBUG = 0;
int num;
switch(argc) {
case 2: {
if(!strncmp(argv[1],"-d",2))
DEBUG = 1;
break;
}
case 3: {
if(!strncmp(argv[1],"-f",2)) {
num = atoi(argv[2]);
gen_file_t(num);
return 0;
}
}
case 1: break;
default: {
fprintf(stderr,"Warning! - too many arguments\n");
goto ERR;
}
}

int fd;
int i,j,x=0;
int status;
float temp, des_out, out_delta, net_output;

neuralnet *net = init_net();

net->input_layer = new_layer(numb_neurons);
net->hidden_layer = new_layer(numb_neurons);
net->output_layer = new_layer(numb_neurons);

// 16 neurons for each layer
add_neurons(net->input_layer);
add_neurons(net->hidden_layer);
add_neurons(net->output_layer);

// Link input layer to hidden layer and the hidden layer to output layer
link_layers(net->input_layer,net->hidden_layer);
link_layers(net->hidden_layer,net->output_layer);

//Open training file
fd = open_training_file();

if(fd<=0) {
fprintf(stderr,"Fail to open %s, check it\n",TRAINING_FILE);
free(net);
return -1;
}

// loop for max_epochs time
for(j = 0; j < net->max_epochs; j++) {
// Read the two input
do {
x++;
// And check if get_data() return a negative value
if((status = get_data(&temp,fd)) < 0) {
fprintf(stderr,"Invalid input data\n");
free(net);
return -1;
}
// loop for every elements of input layer
for(i = 0; i < net->input_layer->num_elements; i++) {
// The post-synaptic potential value of neuron is just read from input, and the
// transfer value will be equal because our transfer function is an identity
net->input_layer->elements[i]->prop_value = (_PRECISION)temp;
net->input_layer->elements[i]->trans_value = (_PRECISION)temp;
}
propagate_into_layer(net->hidden_layer);
propagate_into_layer(net->output_layer);
} while(x<2);
x=0;

// Get desired output
if((status = get_data(&des_out,fd)) < 0) {
fprintf(stderr,"Invalid input data\n");
free(net);
return -1;
}
// Calculate variation of synaptic weights and update
out_delta = compute_output_delta(net->output_layer->elements[0]->prop_value,des_out); // Dj = (Yj-dj)f'(Pj)
update_output_weights(net->output_layer,out_delta,net->l_rate); // DWij = -nDjXi
update_output_weights(net->hidden_layer,out_delta,net->l_rate);

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);
}
close(fd);
free(net);
return 0;
ERR:
fprintf(stderr,"Usage: ./%s -d | -f <numb>\n"
"'-d' for debug messages\n"
"'-f' <numb> generate a training file, 'numb' is number of sums\n",argv[0]);
return 1;
}

l'ouput immondo è questo:
matteo@Moon:~/ANNs/sum_ai/bin/Debug$ ./sum_ai -d
DES=162.755081 ERROR=142.230316 OUT=20.524765 DELTA=-142.230316
DES=94.228630 ERROR=-184006353.771370 OUT=184006448.000000 DELTA=184006352.000000
DES=148.786011 ERROR=-267646241709250664464384.000000 OUT=267646241709250664464384.000000 DELTA=267646241709250664464384.000000
DES=51.351055 ERROR=inf OUT=-inf DELTA=-inf
DES=47.134418 ERROR=inf OUT=-inf DELTA=-inf
DES=72.565201 ERROR=-nan OUT=-nan DELTA=-nan
DES=105.249115 ERROR=nan OUT=nan DELTA=nan
DES=142.260590 ERROR=nan OUT=nan DELTA=nan
DES=21.730181 ERROR=nan OUT=nan DELTA=nan
DES=41.741848 ERROR=nan OUT=nan DELTA=nan
DES=154.875870 ERROR=nan OUT=nan DELTA=nan
DES=106.160805 ERROR=nan OUT=nan DELTA=nan
.....

"DES" sarebbe l'ouput desiderato "OUT" l'ouput della rete (qui prendo uno dei neuroni in uscita) e, come potete tristemente vedere, diverge a meno infinito.... :(

grazie per l'aiuto. :)

marco.r
15-08-2010, 22:09
E' difficile dire qualcosa di preciso dato che manca la parte piu' "succosa" del codice.
In ogni caso:

* quanti sono i neuroni per i vari strati ? Immagino 2 di ingresso e uno di uscita, ma in mezzo ?
* usa un solo elemento di training che e' piu' semplice capire il comportamento dell'algortimo.
* fai una esecuzione in cui stampi a console tutti i pesi e i delta che hai calcolato; ho il dubbio che il problema sia proprio nel calcolo dei delta, visto che ottieni valori sballati dal primo passo.

Teo@Unix
15-08-2010, 22:44
E' difficile dire qualcosa di preciso dato che manca la parte piu' "succosa" del codice.
è vero.

* quanti sono i neuroni per i vari strati ? Immagino 2 di ingresso e uno di uscita, ma in mezzo ?

in realtà ho provato in due modi.
utilizzo 16 neuroni per ogni layer, sono 3 layer in totale.
ma ho provato anche con uno.... il numero è definito da una variabile globale che vado a cambiare.
essendo i neuroni (tra layer) interconnessi tutti con tutti, prendo l'uscita di uno di quelli nel layout di output

* usa un solo elemento di training che e' piu' semplice capire il comportamento dell'algortimo.

qui che cosa intendi? non dovrei più eseguire una somma quindi?

* fai una esecuzione in cui stampi a console tutti i pesi e i delta che hai calcolato; ho il dubbio che il problema sia proprio nel calcolo dei delta, visto che ottieni valori sballati dal primo passo.
si questo era il dubbio che mi è sorto durante il debug.
è evidente, non riesco a capire dove sia il punto.
Ho provato ad inserire un'asserzione ogni volta che un peso di una sinapsi viene aggiornato, ci sono ora un sacco di righe in più a video...
ti posto quelle significative (credo), quando passa al ciclo successivo, o meglio credo che sia quando c'è la prpagazione al layout di output; il valore delta e peso assumono valori sicuramente sbagliati.
synapsi 15: weight: 7392.921875, delta: 7392.902832
synapsi 0: weight: -18187784191737856.000000, delta: -18187784191737856.000000

per una comprensione chiara probabilmente occorre vedere il codice dell'esempio per intero, potrei allegarlo.

il file che uso per il training è costituito così nelle prime righe:
66.757889;95.997185;162.755074;85.691956;8.536676;94.228632;85.233665

Ti ringrazio per l'aiuto.

marco.r
15-08-2010, 23:01
è vero.

in realtà ho provato in due modi.
utilizzo 16 neuroni per ogni layer, sono 3 layer in totale.
ma ho provato anche con uno.... il numero è definito da una variabile globale che vado a cambiare.
essendo i neuroni (tra layer) interconnessi tutti con tutti, prendo l'uscita di uno di quelli nel layout di output

qui che cosa intendi? non dovrei più eseguire una somma quindi?

Aspe', forse allora non capisco correttamente come stai procedendo.
Che tipo di somma vuoi imparare ?
Se ad esempio ti interessa la somma di due numeri (diciamo float), il metodo piu' semplice (o perlomeno che viene in mente a me), e' quello di utilizzare due neuroni nello strato di ingresso e uno di uscita.
Ognuno dei due neuroni di ingresso riceve come segnale il valore da sommare, e il segnale di uscita dell'unico neurone del terzo strato ti da il risultato.
Quindi quando parlo di un singolo elemento di training intendo tre valori numerici: la coppia di ingresso (e.g. 21 e -0.5) e il risultato (20.5).
Stai procedendo differentemente ? Se si', come ?

Teo@Unix
15-08-2010, 23:22
si esatto la somma di due float.

E per il training, due addendi e il risultato, esattamente come hai detto.

La rete però ha 16 neuroni per ogni layer. Non so se questo è un problema. Ma ragionando credo che vada bene se ne prendo uno per l'uscita.

Probabilmente sbaglio a passargli gli input:
- il primo valore (il primo addendo) lo passo a tutti i neuroni in input,
- propago nel layer nascosto, poi propago sull'output
- introduco il secondo addendo
- ripropago nei due layer.
- Solo a questo punto vado a calcolare il delta con il valore che trovo in output della rete e il terzo dato che acquisisco quindi faccio gli aggiornamenti, come si vede dal codice.

marco.r
15-08-2010, 23:58
si esatto la somma di due float.

E per il training, due addendi e il risultato, esattamente come hai detto.

La rete però ha 16 neuroni per ogni layer. Non so se questo è un problema. Ma ragionando credo che vada bene se ne prendo uno per l'uscita.

Probabilmente sbaglio a passargli gli input:
- il primo valore (il primo addendo) lo passo a tutti i neuroni in input,
- propago nel layer nascosto, poi propago sull'output
- introduco il secondo addendo
- ripropago nei due layer.
- Solo a questo punto vado a calcolare il delta con il valore che trovo in output della rete e il terzo dato che acquisisco quindi faccio gli aggiornamenti, come si vede dal codice.
E' un metodo che non ho mai visto usare :mbe: sicuro sia giusto ?
Non ha molto senso dare lo stesso input a piu' neuroni perche' vuol dire che svolgono lo stesso ruolo, e' una duplicazione inutile e dannosa che complica solo i conti e la funzione generata.
Inoltre non capisco come calcoli il risultato. Propagando il valore del secondo addendo sovrascrivi tutti i valori generati dal primo, come "introduci" il secondo addendo ?

Teo@Unix
16-08-2010, 00:08
E' un metodo che non ho mai visto usare :mbe: sicuro sia giusto ?
Non ha molto senso dare lo stesso input a piu' neuroni perche' vuol dire che svolgono lo stesso ruolo, e' una duplicazione inutile e dannosa che complica solo i conti e la funzione generata.
Inoltre non capisco come calcoli il risultato. Propagando il valore del secondo addendo sovrascrivi tutti i valori generati dal primo, come "introduci" il secondo addendo ?

già. Scusa sono alle prime armi in questo campo.
Faccio così,
mantengo parte delle funzioni che dovrebbero essere corrette.
Ristrutturo l'esempio utilizzando come hai detto due neuroni in input, uno in uscita. A una cosa, nel layer intermedio, quanti è bene inserirne? O lascio perdere e uso solo due layer per ora?

A questo punto prova a rieseguire. Sbagliavo il principio.
E' che la guida che mi ha introdotto a quanto pare è fatta con i piedi.:mad: Ho ho trovato un libro....
mi accorgo che in molti punti è cannata. Anche le funzioni in C di esempio hanno errori vari che avevo corretto.

Teo@Unix
16-08-2010, 10:45
ciao,

allora ho modificato l'esempio.

Ho fatto in modo che il numero dei neuroni per ogni layer è deciso da variabili globali.

Ho mantenuto 3 livelli.
2 neuroni in input, uno per addendo.
3 nel layer nascosto.
1 in quello di uscita.

A questo punto purtroppo ho l'identico problema. Il procedimento che seguo è:
- far leggere i due input ai due neuroni del primo strato. Un per uno.
- Propago attraverso i layer.
- Confronto il valore desiderato con l'ouput e aggiorno i pesi sinattici.
- Stampo i risultati
ripeto.

A questo punto ci deve essere qualche altro errore...
Il calcolo del delta è il seguente:
_PRECISION compute_output_delta(_PRECISION output_prop_value, _PRECISION des_out) {
_PRECISION delta;
// Dj = (Yj-dj)f'(Pj)
delta = (output_prop_value - des_out) * linear_derivate(output_prop_value);
return delta;
}
Dove output_prop_value è il risultato della rete, des_out quello corretto.
il risultato di linear_derivate() sarà sempre uno. Ma non penso sia questa funzione il problema...

potenziale:
_PRECISION potential(neuron* nPtr) {
_PRECISION aux_value = 0;
int i=0;
for(i=0;i<nPtr->num_in_links;i++)
// The potential value is the summation of synapse weights multiplied with their transfer values
aux_value += (nPtr->in_links[i]->weight * nPtr->in_links[i]->in->trans_value);
return aux_value;
}

cosa più strana sono i risultati:
matteo@Moon:~/ANNs/sum_ai/bin/Debug$ ./sum_ai -d
DES=162.755081 ERROR=162.755081 OUT=0.000000 DELTA=-162.755081
DES=94.228630 ERROR=94.228630 OUT=0.000000 DELTA=-94.228630
DES=148.786011 ERROR=-99988507983723.218750 OUT=99988507983872.000000 DELTA=99988507983872.000000
DES=51.351055 ERROR=-41592171424451106627584687724390514688.000000 OUT=41592171424451106627584687724390514688.000000 DELTA=41592171424451106627584687724390514688.000000
DES=47.134418 ERROR=inf OUT=-inf DELTA=-inf
DES=72.565201 ERROR=-nan OUT=-nan DELTA=-nan


l'ouput è inizialmente 0..... :confused:

Teo@Unix
16-08-2010, 15:28
Ho mantenuto 3 livelli.
2 neuroni in input, uno per addendo.
3 nel layer nascosto.
1 in quello di uscita.

A questo punto purtroppo ho l'identico problema. Il procedimento che seguo è:
- far leggere i due input ai due neuroni del primo strato. Un per uno.
- Propago attraverso i layer.
- Confronto il valore desiderato con l'ouput e aggiorno i pesi sinattici.
- Stampo i risultati
ripeto.


potete indicarmi se il procedimento è corretto? In particolare la propagazione attraverso i restanti due layer. grazie.

B|4KWH|T3
16-08-2010, 20:43
potete indicarmi se il procedimento è corretto? In particolare la propagazione attraverso i restanti due layer. grazie.

Io toglierei il layer nascosto.

L'addizione è una funzione lineare, dovrebbe bastare un percettrone.

Teo@Unix
16-08-2010, 21:11
grazie,

è esatto.
Ho capito che l'aggiornamento dei pesi fatto in quel modo, non supporta più di 2 layer.
Questo perchè è impossibile determinare l'errore per i neuroni sul layer nascosto essendo appunto intermedio.
(ERRORE = Ydesideato - Yrete)

Infatti utilizzando due neuroni in input e uno per l'ouput sembra ok.

Ho ancora una perplessità.
Se utilizzo come training per la somma valori tra 0 e 100 non funziona correttamente. Ho l'errore che permane molto alto. So che le reti non sono certo usate per le somme, ma voglio capire se sbaglio io qualcosa oppure c'è un'altra ragione......
Cmq se utilizzo input tra 0 e 1 lavora correttamente.

La funzione di trasf. che ho usato è la saturazione lineare, quindi restituisce valori tra 0 e 1, in accordo con il peso... non capisco perchè su una guida c'era indicata l'identità.......

Datemi un parere sull'ouput: (e se quello che sto dicendo è corretto)

matteo@Moon:~/ANNs/sum_ai/bin/Debug$ ./sum_ai
DES=0.691885 ERROR=0.367688 OUT=0.324197 DELTA=0.367688
DES=1.784865 ERROR=0.831504 OUT=0.953361 DELTA=0.831504
DES=1.125133 ERROR=0.126342 OUT=0.998791 DELTA=0.126342
DES=0.171665 ERROR=0.008836 OUT=0.162829 DELTA=0.008836
DES=0.531222 ERROR=0.048165 OUT=0.483057 DELTA=0.048165
DES=1.563073 ERROR=0.094668 OUT=1.468405 DELTA=0.094668
DES=1.521969 ERROR=0.042583 OUT=1.479386 DELTA=0.042583
DES=1.446336 ERROR=-0.009548 OUT=1.455884 DELTA=-0.009548
DES=1.141066 ERROR=0.015600 OUT=1.125466 DELTA=0.015600
DES=0.504797 ERROR=-0.009949 OUT=0.514746 DELTA=-0.009949
DES=0.349549 ERROR=0.005565 OUT=0.343984 DELTA=0.005565
DES=1.641087 ERROR=-0.003137 OUT=1.644224 DELTA=-0.003137
DES=0.577347 ERROR=-0.009224 OUT=0.586571 DELTA=-0.009224
DES=1.534388 ERROR=0.001723 OUT=1.532665 DELTA=0.001723
DES=1.645598 ERROR=-0.000407 OUT=1.646005 DELTA=-0.000407
DES=0.789530 ERROR=0.003343 OUT=0.786187 DELTA=0.003343
DES=1.267519 ERROR=-0.011191 OUT=1.278710 DELTA=-0.011191
DES=0.560583 ERROR=0.005589 OUT=0.554994 DELTA=0.005589
DES=0.402530 ERROR=0.008367 OUT=0.394163 DELTA=0.008367
DES=0.545942 ERROR=-0.002994 OUT=0.548936 DELTA=-0.002994
DES=0.839283 ERROR=-0.011968 OUT=0.851251 DELTA=-0.011968
DES=0.362268 ERROR=0.007815 OUT=0.354453 DELTA=0.007815
DES=1.021461 ERROR=0.024671 OUT=0.996790 DELTA=0.024671
DES=1.279987 ERROR=-0.005000 OUT=1.284986 DELTA=-0.005000
DES=0.998938 ERROR=-0.003917 OUT=1.002855 DELTA=-0.003917
DES=1.305514 ERROR=0.007587 OUT=1.297927 DELTA=0.007587
DES=0.971595 ERROR=-0.001120 OUT=0.972715 DELTA=-0.001120
DES=0.569764 ERROR=-0.005455 OUT=0.575219 DELTA=-0.005455
DES=0.875260 ERROR=-0.000212 OUT=0.875472 DELTA=-0.000212
DES=1.168121 ERROR=-0.001626 OUT=1.169747 DELTA=-0.001626
DES=0.196045 ERROR=0.000688 OUT=0.195357 DELTA=0.000688
DES=0.858341 ERROR=-0.007866 OUT=0.866207 DELTA=-0.007866
DES=0.532047 ERROR=-0.001696 OUT=0.533743 DELTA=-0.001696
DES=0.856216 ERROR=0.005069 OUT=0.851147 DELTA=0.005069
DES=1.151172 ERROR=0.006237 OUT=1.144935 DELTA=0.006237
DES=0.868329 ERROR=-0.003296 OUT=0.871625 DELTA=-0.003296
DES=1.511173 ERROR=0.002040 OUT=1.509133 DELTA=0.002040
DES=1.351708 ERROR=0.004169 OUT=1.347539 DELTA=0.004169
DES=1.039200 ERROR=-0.003276 OUT=1.042476 DELTA=-0.003276
DES=0.695161 ERROR=0.001313 OUT=0.693848 DELTA=0.001313
DES=1.416479 ERROR=0.001566 OUT=1.414913 DELTA=0.001566
DES=0.386624 ERROR=-0.000414 OUT=0.387038 DELTA=-0.000414
DES=0.947277 ERROR=0.003804 OUT=0.943473 DELTA=0.003804
DES=0.937016 ERROR=0.002491 OUT=0.934525 DELTA=0.002491
DES=1.060540 ERROR=0.004055 OUT=1.056485 DELTA=0.004055
DES=0.343396 ERROR=-0.000738 OUT=0.344134 DELTA=-0.000738
DES=1.062788 ERROR=0.002792 OUT=1.059996 DELTA=0.002792
DES=0.720148 ERROR=-0.000827 OUT=0.720975 DELTA=-0.000827
DES=0.620662 ERROR=0.000488 OUT=0.620174 DELTA=0.000488
DES=0.529412 ERROR=0.000717 OUT=0.528695 DELTA=0.000717
DES=0.978521 ERROR=-0.001175 OUT=0.979696 DELTA=-0.001175
DES=0.762289 ERROR=-0.006032 OUT=0.768321 DELTA=-0.006032
DES=0.628338 ERROR=-0.002359 OUT=0.630697 DELTA=-0.002359
DES=1.022328 ERROR=-0.005409 OUT=1.027737 DELTA=-0.005409
DES=0.745693 ERROR=-0.001541 OUT=0.747234 DELTA=-0.001541
DES=0.705675 ERROR=-0.001219 OUT=0.706894 DELTA=-0.001219
DES=1.718164 ERROR=-0.000602 OUT=1.718766 DELTA=-0.000602
DES=0.550246 ERROR=-0.000311 OUT=0.550557 DELTA=-0.000311
DES=1.048688 ERROR=0.000764 OUT=1.047924 DELTA=0.000764
DES=1.487978 ERROR=-0.000728 OUT=1.488706 DELTA=-0.000728
DES=0.592400 ERROR=-0.001159 OUT=0.593559 DELTA=-0.001159
DES=1.365812 ERROR=0.000378 OUT=1.365434 DELTA=0.000378
DES=1.033112 ERROR=0.003239 OUT=1.029873 DELTA=0.003239
DES=0.250023 ERROR=-0.000023 OUT=0.250046 DELTA=-0.000023

marco.r
17-08-2010, 13:25
grazie,

è esatto.
Ho capito che l'aggiornamento dei pesi fatto in quel modo, non supporta più di 2 layer.
Questo perchè è impossibile determinare l'errore per i neuroni sul layer nascosto essendo appunto intermedio.
(ERRORE = Ydesideato - Yrete)

Ops, davo per scontato che facessi la retropropazione dell'errore. Se non lo facevi e vuoi capirne di piu' cerca backpropagation su google. Comincia a dare una occhiata qui:
http://en.wikipedia.org/wiki/Backpropagation


Ho ancora una perplessità.
Se utilizzo come training per la somma valori tra 0 e 100 non funziona correttamente. Ho l'errore che permane molto alto. So che le reti non sono certo usate per le somme, ma voglio capire se sbaglio io qualcosa oppure c'è un'altra ragione......
Cmq se utilizzo input tra 0 e 1 lavora correttamente.

Se utilizzi una funzione di saturazione tra 0 e 1 ovviamente non puoi ottenere valori fuori da quel range ! La soluzione e' usare una semplice combinazione lineare (nel tuo caso la soluzione corretta, visto che vuoi approssimare una combinmazione lineare, e dovresti ottenere 1 come pesi), oppure mappi il range di valori che ti interessa ottenere nell'intervallo [0,1]

Teo@Unix
17-08-2010, 16:40
Ops, davo per scontato che facessi la retropropazione dell'errore. Se non lo facevi e vuoi capirne di piu' cerca backpropagation su google. Comincia a dare una occhiata qui:
http://en.wikipedia.org/wiki/Backpropagation

Si, infatti! Sarà il passo successivo. Mi sembra di capire da quello che stò leggendo che sono anche le più utilizzate.


Se utilizzi una funzione di saturazione tra 0 e 1 ovviamente non puoi ottenere valori fuori da quel range ! La soluzione e' usare una semplice combinazione lineare (nel tuo caso la soluzione corretta, visto che vuoi approssimare una combinmazione lineare, e dovresti ottenere 1 come pesi), oppure mappi il range di valori che ti interessa ottenere nell'intervallo [0,1]

Infatti ho fatto così, ma se io volessi eseguire delle somme con input tra 0 e 100 per esempio, che funzione dovrei scegliere?
Se io usassi una lineare f(x)=x non avrei poi ouput enormi?

Quando calcolo il delta
// DWij = n*Dj*Xi
sPtr->delta = sPtr->in->trans_value*delta*l_rate;
qui sPtr->delta verrebbe alto, dato che in->trans_value può assumere valori anche fino a 100
di conseguenza quando aggiorno i pesi:
for(j=0; j < nPtr->num_in_links; j++) {
sPtr = nPtr->in_links[j];
sPtr->weight += sPtr->delta; // Increase or reduce weight (Hebb)
sPtr->delta = 0; // Reset delta
}
non penso funzioni weight non verrebbe troppo alto? Oppure mi stò sbagliando?

Praticamente è il problema cha avevo prima. Dove è sbagliato il mio ragionamento? So che sono domande banali, ma sono esattamente all'inizio.

Grazie.

Unrue
17-08-2010, 20:13
Si, infatti! Sarà il passo successivo. Mi sembra di capire da quello che stò leggendo che sono anche le più utilizzate.



Infatti ho fatto così, ma se io volessi eseguire delle somme con input tra 0 e 100 per esempio, che funzione dovrei scegliere?
Se io usassi una lineare f(x)=x non avrei poi ouput enormi?

Quando calcolo il delta
// DWij = n*Dj*Xi
sPtr->delta = sPtr->in->trans_value*delta*l_rate;
qui sPtr->delta verrebbe alto, dato che in->trans_value può assumere valori anche fino a 100
di conseguenza quando aggiorno i pesi:
for(j=0; j < nPtr->num_in_links; j++) {
sPtr = nPtr->in_links[j];
sPtr->weight += sPtr->delta; // Increase or reduce weight (Hebb)
sPtr->delta = 0; // Reset delta
}
non penso funzioni weight non verrebbe troppo alto? Oppure mi stò sbagliando?

Praticamente è il problema cha avevo prima. Dove è sbagliato il mio ragionamento? So che sono domande banali, ma sono esattamente all'inizio.

Grazie.

L'output di una rete addestrata con backpropagation non dovrebbe mai essere troppo grande, ma normalizzato in un range ben definito. Questo per evitare di fare grossi aggiornamenti dei pesi e/o di saturare le funzioni di attivazione. La normalizzazione puoi farla anche sull'input.Ti consiglio quindi inanzitutto di normalizzare output ed input e successivamente di utilizzare un algoritmo tipo questo:

http://www.faqs.org/faqs/ai-faq/neural-nets/part3/section-6.html

che è una piccola aggiunta alla backpropagation per evitare pesi grandi.

Teo@Unix
17-08-2010, 20:51
L'output di una rete addestrata con backpropagation non dovrebbe mai essere troppo grande, ma normalizzato in un range ben definito. Questo per evitare di fare grossi aggiornamenti dei pesi e/o di saturare le funzioni di attivazione. La normalizzazione puoi farla anche sull'input.Ti consiglio quindi inanzitutto di normalizzare output ed input e successivamente di utilizzare un algoritmo tipo questo:

http://www.faqs.org/faqs/ai-faq/neural-nets/part3/section-6.html

che è una piccola aggiunta alla backpropagation per evitare pesi grandi.

ti ringrazio,
ma non sto utilizzando backpropagation.
Praticamente stò utilizzando un percettrone. Semplicemente mi chiedo come procedere se voglio addestrare la rete per eseguire una somma ma con input più grandi, non tanto perchè mi interessa la somma..... era solo per concludere l'esempio che avevo fatto.

Unrue
17-08-2010, 22:20
ti ringrazio,
ma non sto utilizzando backpropagation.
Praticamente stò utilizzando un percettrone. Semplicemente mi chiedo come procedere se voglio addestrare la rete per eseguire una somma ma con input più grandi, non tanto perchè mi interessa la somma..... era solo per concludere l'esempio che avevo fatto.

E lo stesso, i concetti che ti ho esposto sono comunque applicabili ad algoritmi adattivi come Widrow-Huff o backpropagation e rispondono ad alcuni dei tuoi quesiti.

Teo@Unix
17-08-2010, 22:38
credo di aver capito.

Ora vedrò di guardarmi la backpropagation.

Senza normalizzare nulla l'esempio funziona bene con valori tra 0 e 1.

Grazie a tutti.