Newsgroup: it.comp.os.linux.development
Titolo: NNF - Neural Net Framework

Ho scritto una piccola e leggera libreria in C per le reti neurali
feed-forward.
L'ho sviluppata su Linux ma č in standard C e usa solo formato testo
quindi portabile.
L'ho pubblicata sotto licenza LGPL.
http://nnf.sourceforge.net
Accetto critiche :)
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Pink Floyd wrote:
| Ho scritto una piccola e leggera libreria in C per le reti neurali
| feed-forward.
| L'ho sviluppata su Linux ma è in standard C e usa solo formato testo
| quindi portabile.
| L'ho pubblicata sotto licenza LGPL.
|
| 
http://nnf.sourceforge.net
|
| Accetto critiche :)
Non ho avuto modo di provarla, però devo dire che è veramente un lavoro
notevole, mi chiedevo come mai una persona giovane come te conosce
questi argomenti che si incontrano solitamente solo all'università (e
nemmeno ai primi anni). Inoltre sembri conoscere bene l'inglese e, oltre
al codice, hai persino scritto un tutorial sull'uso e sulle reti neurali
in genere... veramente complimenti! Ho dato una guardata veloce anche ai
tuoi altri progetti e devo dire che sono rimasto piacevolmente stupito
dal tuo impegno e dalla conoscenza che dimostri. A che età hai
incominciato ad interessarti di programmazione? Vedo che il tuo progetto
Botwar funziona solo con Windows, hai usato DirectDraw per la grafica?
Se si allora ti suggerisco, per i tuoi progetti futuri, di usare SDL
(
http://www.libsdl.org/index.php
), in linea di principio è molto simile
a DirectDraw e ha il vantaggio di funzionare senza problemi sia su
Windows che Linux che Mac.
Ad ogni modo, ancora complimenti, è un piacere vedere che c'è ancora
qualche giovane che si interessa di programmazione e non si ferma solo a
VB o simili!
Ciao,
~  Luca
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with MultiZilla - 
http://enigmail.mozdev.org
iD8DBQFCRLP7liez+Z59f3URAmZ1AKCEB3vQ6KRd4Ps4OCyWr2C9dAJhIACgm2Hw
FyV+ZPWvy1IdQSqB4mMrOKc=
=GPqq
-----END PGP SIGNATURE-----

 Accetto critiche :)
Ciao,
Devo ammettere che non č stato semplice riuscire a seguire la logica del
programma. Pur trattandosi di solo 6 paginette di codice implementa alcuni
concetti che non mi sono familiari e quindi mi sono serviti un paio di
giorni per comprendere la logica che sta dietro alle reti neurali
feed-forward, la matematica sottostante e la stessa implementazione che con
tutti i livelli di indirezione e manipčolazione di puntatori non risparmia
dal logorio i miei propri neuroni...
Beh, alla fine mi sembra di avere compreso quasi tutto e, visto che chiedi
il parere del NG, ho da fare dei commenti.
Prima di tutto vorrei dire che mi č piaciuto molto. Si tratta di un
bell'esercizio che in teoria dovrebbe essere fuori dalla tua portata,
immaginando che a soli 17 anni tu non abbia ancora incontrato a scuola ne'
lo studio delle funzioni esponenziali e circolari alla base delle funzioni
di attivazione (sigma logistica e sigma tangente iperbolica), nč tantomeno
le derivate parziali delle stesse (applicate al metodo di calcolo del
Delta). Immagino anche che le Reti Neurali, l'AI in genere e il C non faccia
parte dei programmi scolastici attuali, almeno per quanto ne so, a parte
forse la programmazione se studi presso qualche istituto tecnico (boh?).
Passiamo alle osservazioni e domande sulla tua implementazione...
(1) Se la mia scarsa conoscenza di Analisi non mi tradisce mi pare che il
calcolo del delta fa uso della derivata prima della funzione logistica.
Ipotizziamo che il nodo "j" č collegato in output con "k" e chiamiamo "d" il
valore desiderato, "a" il valore attuale, "w" i pesi delle connessioni, "x"
l'input dalla connessione, f(node) la funzione di attivazione dei nodi della
rete. Consideriamo solo i nodi di output perchč per gli altri la formula č
piů complicata ma il punto in questione č lo stesso:
weight(jk) = weight(jk) + epsilon * delta(k) * x(j);
delta(k) = ( d(k) - a(k) ) * ( a(k) * ( 1 - a(k) ) ).
Nell'ultima assegnazione, il primo termine della moltiplicazione č la
differenza tra l'output desiderato e l'effettivo, mentre il secondo termine
(che ho racchiuso entro parentesi non necessarie) mi sembra proprio la
derivata prima (simbolo "D" oppure f'()) della funzione sigmoidal logistic,
infatti:
f(node(k)) = 1 / ( 1 + expf(-x) ) = a(k);
f'(node(k)) = f(node(k)) * ( 1 - f(node(k) ) = D(a(k)).
Quindi questo metodo mi sembra solo applicabile alla scelta dell'utente di
fare funzionare la rete con la sigmoidal logistic e non puň funzionare con
le altre tre funzioni che in pratica sono inutilizzabili...
Mi sono perso qualcosa? Sbaglio ad arrivare a questa conclusione?
(2) Mi puoi spiegare la logica sottostante al calcolo dei valori random?
Voglio dire che non capisco (a) l'utilitŕ di fare scegliere il "range"
all'utente, (b) la necessitŕ di usare srand() in questo tipo di applicazioni
(e inoltre, non dovrebbe essere srandom()?) e (c) la stessa logica dello
statement
variabile = 2.0 * range * ( (float)random() / RAND_MAX - 0.5 );
Perchč questa costruzione cosě elaborata?
(3) Non sono sicuro di capire perchč il "bias" č aggiustato con "bias[y][z]
= epsilon * delta[y][z];"... Non dovrebbe essere "bias[y][z] += epsilon *
delta[y][z];" (Nota il "+=")? Su questo mio punto di vista ho parecchi
dubbi... Non ne sono neanche troppo convinto! Puoi spiegarmi perchč la
logica di adattamento del "bias" non segue da quella delle modifiche ai
"weight"?
(4) Hai usato puntatori a molti livelli di indirezione e questo in un certo
modo aiuta la ricerca dei nodi e dei pesi associati alle connessioni. Tenuto
conto che il numero di nodi č noto a tempo di compilazione del programma
utente io tenterei di distribuirli su un unico array e proverei ad usare un
altro meccanismo per riferirmi ad essi. Al momento non so se la
semplificazione e l'efficienza che si otterrebbe finirebbe per essere
superata dall'overhead per la gestione degli accessi...
Prima di scegliere l'attuale meccanismo di manipolazione dei nodi, hai per
caso provato a distribuirli in un unico grande array? Se si, quali sono
state le difficoltŕ che ti hanno fatto desistere? Troppo overhead per
accedervi?
Spero di leggerti quanto prima e nel frattempo ti faccio i miei migliori
auguri per i tuoi futuri studi, nella certezza che, se a 17 anni giŕ conosci
queste 'cosine', all'etŕ della laurea sarai ben piů avanti della maggioranza
degli altri colleghi.
Buon lavoro,
fabio de francesco
(fabiomdf)
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

per Luca:
Ti ringrazio per i complimenti che comunque ritengo esagerati...
Ho cominciato a programmare a settembre-ottobre di quest'anno (all'inizio
in C++). Adesso sto studiando l'assembly x86 e uso prevalentemente quello
e il C e se è proprio necessario anche C++.
Per quanto riguarda le SDL, ci avevo fatto veramente poco, ma poi ho
lasciato un po' da parte la programmazione grafica, ripromettendomi in
futuro di studiare le OpenGL.
Se vuoi altre informazioni la mia email è 
pink...@neoborn.com
per Fabio:
Rispondo subito alla tua email.


Corretti due piccoli bug, per favore riscaricate la libreria.
Raccomando per il momento di utilizzare solo la funzione logistica perchè
per le altre devo ancora scrivere un algoritmo di retropropagazione valido
(lo farò appena avrò tempo).
