Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere)
Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere)
Quattro modi di indossarlo, stessa app del Plaud Note Pro e integrazione con il desktop. Il registratore IA da indossare di Plaud eccelle in mobilità, ma resta vincolato all'abbonamento ed è facile da perdere
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro
Xiaomi ha portato Redmi Watch 6 anche sul mercato italiano, puntando su un display AMOLED da 2,07 pollici con picco di luminosità a 2000 nit, frame in alluminio da 9,9mm e un'autonomia dichiarata di 12 giorni. Lo smartwatch gira su HyperOS 3 e integra GPS, Bluetooth 5.4 e oltre 150 sport mode. Il tutto a meno di 100 euro
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti
Con 22 tasti, il pulsante 5D, lo Shift Mode e il sensore PixArt 3395 da 26.000 DPI, il nuovo mouse wireless di Mad Catz si rivolge in modo preciso ai giocatori di MMO e RPG. Ma chi conosce già il R.A.T. 8+ ADV si accorgerà subito di quanto i due prodotti condividano, e di dove invece divergono
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 27-08-2010, 13:51   #1
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
[C++] Rete neurale, backpropagation - Uso del peso bias

Buondì.

In ottica di poter riutilizzare le reti neurali, stò scrivendo una libreria in C++. Le funzioni per l'utilizzo del percettrone fanno il loro dovere, ho invece un problema quando vengono aggiunti uno o più layer nascosti. Per allenare una rete di questo tipo utilizzo backpropagation, ma ho innanzi tutto dei dubbi sull'utilizzo del peso bias per ogni neurone.

Quello che faccio è aggiungere un neurone fittizio in tutti i layer. Questo varrà sempre 1 e trasferirà sempre uno, mente il suo peso di connessione varia come gli altri.
Non so se l'errore che ho dipende dall'uso errato che faccio del bias, o se è un'altro tipo di problema.

Non so se postare il codice può essere utile, comunque dovrebbe essere abbastanza chiaro dato il linguaggio utilizzato, il seguente è il metodo di addestramento backpropagation:

Codice:
int NeuralNet::Train_BackPropagation(vector<_PRECISION> des_out) {
	/* Backpropagation case */

	// Verifiy that the hidden layer exists
	if(des_out.size() != numOutputNeurons || numHiddenLayers <= 0 || numHiddenNeuronsPerLayer <= 0) return -1;

	_PRECISION error, delta_weight, prev_bp_err = 0, cur_bp_err = 0;

	for(u_int32_t l = layers.size()-1; l >= 0; l--) {	// For each layer, begin from output
		prev_bp_err = cur_bp_err;
		cur_bp_err = 0;
		if(!l) break;	// Input layer has no weights
		if(l==layers.size()-1) {// Output layer
			for(u_int32_t n = 0;n < layers[l]->getNeuronNum();n++) {	// For each neuron
				// Calculate delta error, dk = (rk - ok)*f'(netk)

				if(n==layers[l]->getNeuronNum()-1 && BIAS){				// for only bias neuron
					error  =
						(des_out[n-1] - layers[l]->getNeuron(n)->getPotential())*
						layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential());
				} else {
					error  =
						(des_out[n] - layers[l]->getNeuron(n)->getPotential())*
						layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential());
				}

				for(u_int32_t w = 0;w < layers[l]->getNeuron(n)->getWeightsNum(); w++) {// For each weight
					// Calculate delta weight, Dw = Wjk + n*dk*oj
					delta_weight = layers[l]->getNeuron(n)->getWeight(w) + l_rate*error*layers[l-1]->getNeuron(w)->getPotential();
					// Update weight
					layers[l]->getNeuron(n)->setWeight(w,delta_weight);
					// Product smmation of current error and current weight
					cur_bp_err += layers[l]->getNeuron(n)->getWeight(w)*error;
				}
			}
		} else { // Hidden layers and input
			for(u_int32_t n = 0;n < layers[l]->getNeuronNum(); n++) {// For each neuron
				// Calculate hidden layer error, remembering the previous propagated error
				error = layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential())*prev_bp_err;
				for(u_int32_t w = 0;w < layers[l]->getNeuron(n)->getWeightsNum(); w++) {// For each weight
					// Calculate delta weight, Dw = W + n*d*o
					delta_weight = layers[l]->getNeuron(n)->getWeight(w) + l_rate*error*layers[l]->getNeuron(n)->getPotential();
					// Update weight
					layers[l]->getNeuron(n)->setWeight(w,delta_weight);
					// Product smmation of current error and current weight
					cur_bp_err += layers[l]->getNeuron(n)->getWeight(w)*error;
				}
			}
		}
	}
	return 0;
}
Ho visto in molti esempi che vengono utilizzate matrici per lavorare con neuroni e rispettivi pesi di connessione, io ho preferito utilizzare questo stile perchè mi sembra più chiaro.

In questo momento stò cercando invano di addestrare la rete per eseguire l'operazione XOR.

Grazie per l'aiuto.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 27-08-2010, 14:21   #2
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Buondì.

Ho visto in molti esempi che vengono utilizzate matrici per lavorare con neuroni e rispettivi pesi di connessione, io ho preferito utilizzare questo stile perchè mi sembra più chiaro.

Grazie per l'aiuto.
Ciao, sulla questione del bias cerchero' di risponderti con calma stasera, intanto una mio opinione sul metodo di rappresentazione: meglio se usi le matrici, il codice diventa molto piu' compatto, piu' comprensibile (secondo me) e [b]molto[b] piu' efficiente.

La fase in avanti ad esempio la puoi implementare nel seguente modo:
Codice:
std::vector<Matrix> W(nLayers);
std::vector<Vector> input(nLayers+1);
/* ... */
for ( size_t i=0 ; i< W.size() ; ++i )
{
    input[i+1] = f( W*input[i] );
}
input.back() contiene l'output effettivo
Il feedback si scrive in modo parecchio simile.
f e' la versione vettoriale della funzione di attivazione (usarne una specifica per strato compila le cose un po' ma non molto).
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 27-08-2010, 14:39   #3
shinya
Senior Member
 
L'Avatar di shinya
 
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
Quote:
Originariamente inviato da marco.r Guarda i messaggi
[...]usarne una specifica per strato compila le cose un po' ma non molto.
Pun intended?? LOL
shinya è offline   Rispondi citando il messaggio o parte di esso
Old 27-08-2010, 15:47   #4
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da shinya Guarda i messaggi
Pun intended?? LOL
Direi lapsus freudiano... come quando scrivo server invece di serve :P
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 29-08-2010, 15:37   #5
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Il problema che ho durante l'addestramento per eseguire la XOR è che ho un output del genere, giusto in parte:

Codice:
BIT_1  BIT_2   XOR   NET_OUT DELTA
.....
1.000  1.000   0.000   1.048   -1.048
0.000  0.000   0.000   0.970   -0.970
0.000  1.000   1.000   1.018   -0.018
1.000  0.000   1.000   1.022   -0.022
1.000  1.000   0.000   1.045   -1.045
0.000  0.000   0.000   0.972   -0.972
0.000  1.000   1.000   1.017   -0.017
1.000  0.000   1.000   1.021   -0.021
1.000  1.000   0.000   1.042   -1.042
0.000  0.000   0.000   0.974   -0.974
0.000  1.000   1.000   1.016   -0.016
1.000  0.000   1.000   1.020   -0.020
1.000  1.000   0.000   1.040   -1.040
0.000  0.000   0.000   0.976   -0.976
0.000  1.000   1.000   1.016   -0.016
1.000  0.000   1.000   1.019   -0.019
1.000  1.000   0.000   1.037   -1.037
0.000  0.000   0.000   0.978   -0.978
....
mi da praticamente sempre uno...

Il codice è ora questo:

Codice:
int NeuralNet::Train_BackPropagation(vector<_PRECISION> des_out) {
	/* Backpropagation case */

	// Verifiy that the hidden layer exists
	if(des_out.size() != numOutputNeurons || numHiddenLayers <= 0 || numHiddenNeuronsPerLayer <= 0) return -1;

	_PRECISION error, delta_weight, prev_bp_err = 0, cur_bp_err = 0;

	for(u_int32_t l = layers.size()-1; l >= 0; l--) {	// For each layer, begin from output
		prev_bp_err = cur_bp_err;
		cur_bp_err = 0;
		if(!l) break;	// Input layer has no weights
		if(l==layers.size()-1) {// Output layer
			for(u_int32_t n = 0;n < layers[l]->getNeuronNum();n++) {	// For each neuron
				// Calculate delta error, dk = (rk - ok)*f'(netk)

				if(n==layers[l]->getNeuronNum()-1 && BIAS){				// for only bias neuron
					error  =
						(des_out[n-1] - layers[l]->getNeuron(n)->getValue())*
						layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential());
				} else {
					error  =
						(des_out[n] - layers[l]->getNeuron(n)->getValue())*
						layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential());
				}

				for(u_int32_t w = 0;w < layers[l]->getNeuron(n)->getWeightsNum(); w++) {// For each weight
					// Calculate delta weight, Dw = Wjk + -(n*dk*oj)
					delta_weight = layers[l]->getNeuron(n)->getWeight(w) + -(l_rate*error*layers[l-1]->getNeuron(w)->getValue());
					// Product smmation of current error and current weight
					cur_bp_err += layers[l]->getNeuron(n)->getWeight(w)*error;
					// Update weight
					layers[l]->getNeuron(n)->setWeight(w,delta_weight);
				}
			}
		} else { // Hidden layers and input
			for(u_int32_t n = 0;n < layers[l]->getNeuronNum(); n++) {// For each neuron
				// Calculate hidden layer error, remembering the previous propagated error
				error = layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential())*prev_bp_err;
				for(u_int32_t w = 0;w < layers[l]->getNeuron(n)->getWeightsNum(); w++) {// For each weight
					// Calculate delta weight, Dw = W + -(n*d*o)
					delta_weight = layers[l]->getNeuron(n)->getWeight(w) + -(l_rate*error*layers[l-1]->getNeuron(w)->getValue());
					// Product smmation of current error and current weight
					cur_bp_err += layers[l]->getNeuron(n)->getWeight(w)*error;
					// Update weight
					layers[l]->getNeuron(n)->setWeight(w,delta_weight);
				}
			}
		}
	}
	return 0;
}
@marco.r
ora mantegno questa struttura solo per non dover riscrivere tutto, credo che poi proverò ad utilizzare le matrici.

Nella prova che ho fatto con XOR, il bias non lo ho utilizzato, quindi nel codice la var. "BIAS" vale 0.

Non ho capito l'errore che faccio.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 01-09-2010, 18:41   #6
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 01-09-2010, 20:12   #7
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Il problema che ho durante l'addestramento per eseguire la XOR è che ho un output del genere, giusto in parte:
Per quante iterazioni fai andare avanti l'addestramento ?
E che coefficiente di apprendimento usi ? (Di solito l'errore calcolato non lo si scala tutto dal peso, ma solo una piccola parte, tipo l'1%).
Quote:
Codice:
BIT_1  BIT_2   XOR   NET_OUT DELTA
0.000  0.000   0.000   0.970   -0.970
Aspe', dici che non usi il vettore di bias ?
Che funzione di attivazione (schiacciamento) stai usando ?
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 01-09-2010, 22:59   #8
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Per quante iterazioni fai andare avanti l'addestramento ?
E che coefficiente di apprendimento usi ? (Di solito l'errore calcolato non lo si scala tutto dal peso, ma solo una piccola parte, tipo l'1%).
ma..
se l'ascio andare l'esecuzione il valore delta assume valori periodici... quindi non si arriva ma all'addestramento...
per quanto riguarda l'errore che calcolo, non ho capito bene, la riga dove calcolo l'errore del layer nascosto ad esempio è:
Codice:
error = layers[l]->getNeuron(n)->trans_func_derivate(layers[l]->getNeuron(n)->getPotential())*prev_bp_err;
quindi moltiplico il risultato della derivata con x uguale all' uscita del neurone corrente. (qui è giusto che utilizzo il potenziale e non il val. di trasf.?)

calcolo delta e aggiorno:
Codice:
// Calculate delta weight, Dw = W + -(n*d*o)
delta_weight = layers[l]->getNeuron(n)->getWeight(w) + -(l_rate*error*layers[l-1]->getNeuron(w)->getValue())
Codice:
layers[l]->getNeuron(n)->setWeight(w,delta_weight);
l'1% di "error" intendi?

Quote:
Aspe', dici che non usi il vettore di bias ?
Che funzione di attivazione (schiacciamento) stai usando ?
no, nell'esempio non ho utilizzato il bias.
tutto con funzione sigmoide.

c'è qualche erroraccio da qualche parte credo....
thanks.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2010, 00:38   #9
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
l'1% di "error" intendi?
no di delta. Non devi sommare direttamente il delta che trovi ma prima moltiplicarlo per un coefficiente relativamente basso, tipo 0.01 o 0.001 inm modo che il cambiamento dei pesi avventa molto lentamente.
Dal punto di vista matematico la backpropagation non e'altro che un metodo di ottimizzazione dove tu vuoi minimizzare la differenza tra output voluto e ottenuto.
La backpropagation lo fa con un metodo a discesa di gradiende ovveo, considera l'errore nel punto attuale (nello spazio dei pesi) e cerca di muoversi verso punti con errore piu'basso. Nel farlo pero'devi muoverti con calma, altrimenti rischi di impantanarti
Tu immagina di essere in mezzo ai monti, e il tuo errore e'la tua altitudine. Per minimizzarlo cosa fai ? Ti sposti verso dove la montagna scende, un passo alla volta.
Olra, se il passo e'piccolo funziona bene, ma se sei il gatto con gli stivali e fai salti da 500 metri puo' accadere che salti da una parte all'altra della valle, senza scendere di un cm, e poi tornare indietro al punto di prima, e cosi'via.
il discorso e'analogo
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2010, 00:40   #10
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
no, nell'esempio non ho utilizzato il bias.
tutto con funzione sigmoide.
Intervallo [0,1] o [-1,1] ?
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2010, 13:17   #11
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Intervallo [0,1] o [-1,1] ?
il mio intervallo dei pesi è [-1, 1].

Non posso provare subito ora, appena riesco faccio questa prova.

grazie .
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2010, 13:22   #12
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
il mio intervallo dei pesi è [-1, 1].

Non posso provare subito ora, appena riesco faccio questa prova.

grazie .
Se l'intervallo dei pesi' e' [-1,1], allora la funzione in 0 vale zero. Il che vuol dire che con un input di [0,0] per la funzione XOR il tuo output dovrebbe essere sempre zero. E' anche per questo che si introduce la funzione di bias. Se ottieni per l'input nullo un output non nullo probabilmente c'e' un errore gia' nella fase in avanti (se non usi il bias)
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2010, 13:27   #13
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Se l'intervallo dei pesi' e' [-1,1], allora la funzione in 0 vale zero. Il che vuol dire che con un input di [0,0] per la funzione XOR il tuo output dovrebbe essere sempre zero. E' anche per questo che si introduce la funzione di bias. Se ottieni per l'input nullo un output non nullo probabilmente c'e' un errore gia' nella fase in avanti (se non usi il bias)
Ok! Rivedrò le cose. Vediamo se vengo a capo del problema.
Farò sapere.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere) Plaud NotePin S, il registratore IA si fa indoss...
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro Redmi Watch 6 in prova: lo smartwatch con ampio ...
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ...
Radeon RX 9070 GRE, AMD la porta in tutto il mondo | Recensione Gigabyte Gaming OC Radeon RX 9070 GRE, AMD la porta in tutto il mon...
Reolink OMVI 3i WiFi: videosorveglianza più intelligente e facile da usare Reolink OMVI 3i WiFi: videosorveglianza pi&ugrav...
Virtua Fighter è tornato e non &e...
Il ritorno di Fumito Ueda, autore di Sha...
Cooler Master svela GPU Shield, la nuova...
Samsung Galaxy S27 Pro: sarà lui ...
Così Google ha ottimizzato Chrome...
Xiaomi non cambia idea: il display poste...
LG presenta in Italia le gamme TV Micro ...
Sette anni dopo l'annuncio, The Wolf Amo...
'Non avrete aumenti': la decisione shock...
TIM lancia il Pass Mondiali DAZN: 104 pa...
Tesla Roadster, promessa o miraggio? La ...
Mark Hamilton, la tavola periodica del m...
Hanger 13 annuncia Uomo d'Onore: espansi...
La battaglia delle HBM4 entra nel vivo: ...
Dopo 12 anni torna Alien: Isolation. Ecc...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:16.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v