PYANN: PYthon Artificial Neural Network Carli Samuele Matricola: 4036768 E-mail: [email protected] Febbraio 2008 INDICE 1 Implementazione 1.1 Struttura del codice . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 La classe FFnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rappresentazione delle informazioni . . . . . . . . . . . . . . 1.2.1 Propagazione in avanti . . . . . . . . . . . . . . . . . . . . . 1.2.2 Propagazione all’indietro . . . . . . . . . . . . . . . . . . . . 1.3 La classe networkTrainer . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Inizializzazione di una nuova rete . . . . . . . . . . . . . . . Calcolo del Mean Square Error e della sommatoria dei gradienti 1.4 Algoritmi implementati in networkTrainer . . . . . . . . . . . . . . . 1.4.1 Sequential Backpropagation . . . . . . . . . . . . . . . . . . 1.4.2 Batch Backpropagation . . . . . . . . . . . . . . . . . . . . 1.4.3 Batch Backpropagation con momento . . . . . . . . . . . . . 1.4.4 Batch Backpropagation con momento e superSAB . . . . . . 1.4.5 Batch Resilient Backpropagation . . . . . . . . . . . . . . . 1 1 1 2 2 3 7 7 8 10 10 10 11 11 12 2 La rete in funzione 2.1 Come si usa . . . . . . . . . . . . . . . 2.2 Confronto fra i metodi di apprendimento 2.2.1 Velocità di convergenza . . . . . 2.2.2 Backpropagation con momento . . . . . 3 Optical Character Recognition 3.1 Caratteristiche delle reti . . . . . . . . . . 3.1.1 Comunicazione con la rete: codifica 3.1.2 Addestramento delle reti . . . . . . 3.1.3 Scelta della dimensione della rete . 3.1.4 Riconoscimento di caratteri . . . . iii . . . . . . . . . . . . . . . . . . . . 15 15 18 18 19 . . . . . . . . . . di Input e Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 23 23 23 24 26 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv 3.2 3.1.5 Discriminazione tra caratteri Un semplice sistema OCR: SPOCR 3.2.1 Come si usa . . . . . . . . 3.2.2 Alcuni risultati . . . . . . . Riconoscimento di numeri . Riconoscimento di caratteri Stringhe miste . . . . . . . e . . . . . . lettere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 26 26 30 30 36 40 CAPITOLO 1 Implementazione della rete: Multilayer Perceptron 1.1 Struttura del codice La struttura che si è scelto per implementare la rete ed i relativi algoritmi di apprendimento è costituito da due moduli; il primo è orientato al calcolo efficiente della propagazione in avanti e indietro lungo la rete, mentre l’altro è orientato all’utilizzo e alla memorizzazione delle strutture necessarie all’esecuzione degli algoritmi. Come si vedrà in seguito, questi due moduli, benché definiscano delle interfacce Object Oriented indipendenti, sono implementati utilizzando legami molto stretti di relazioni di uso e introspezione che di fatto annullano l’interoperabilità e l’indipendenza a cui punta il design OO. Questa implementazione, che si trova a metà tra programmazione funzionale e programmazione orientata agli oggetti, è stata scelta per motivi di leggibilità ed efficienza del codice (a scapito della riusabilità e della mantenibilità, visto il fine didattico del lavoro) senza però precludere la possibilità di implementare efficacemente tali interfacce nel pieno rispetto dei principi di design o con linguaggi che obbligano a mantenere l’incapsulamento dell’informazione. 1.2 La classe FFnet Questa classe descrive una rete FeedForward completamente connessa, mentre la sua interfaccia fornisce i metodi necessari a ottenere il risultato di una propagazione in avanti o indietro di un array di valori (comprensivo o meno dei risultati intermedi) e quelli preposti al salvataggio o al caricamento di una rete esistente. 1 2 Rappresentazione delle informazioni Le informazioni di cui la rete necessita per portare a termine una propagazione in avanti si limitano alle dimensioni dei vari layers e ovviamente ai pesi delle connessioni tra i vari neuroni. Queste informazioni vengono immagazzinate in due array, di cui uno tridimensionale, che vengono creati dal costruttore al momento dell’instanziazione della rete: Listing 1.1: Rappresentazione delle informazioni c l a s s FFnet : def init ( self ): s e l f . L a y e r D i m e n s i o n s = [ ] #[ ] s e l f . LayerConnections = [ ] #[ ] [ ] [ ] L’array LayerDimensions contiene le dimensioni dei vari layer, a partire dal numero di input della rete. LayerConnections è invece un array tridimensionale in cui la prima dimensione seleziona il layer (0: [input → firstHidden], 1: [firstHidden → secondHidden] e cosı̀ via fino al layer di output), la seconda il neurone di output e l’ultima il neurone di input. LayerConnections[0][0][0] conterrà quindi il peso che collega il primo input del layer di input al primo neurone del primo layer nascosto, mentre LayerConnections[l][i][j] indica il peso che collega il j-esimo neurone del layer l all’i-esimo del layer l + 1. Indicheremo da ora in poi tale peso l come wji . Quest’ordine di rappresentazione all’interno dell’array è stato scelto al fine di migliorare l’efficienza dell’algoritmo di propagazione in avanti, che necessita di accedere in blocco ai pesi delle connessioni esistenti tra un neurone e tutti quelli del layer precedente. 1.2.1 Propagazione in avanti In questa implementazione si è scelto di utilizzare come funzione di trasferimento dei neuroni la funzione tanh(x); questo implica che la rete abbia valori normalizzati in ingresso e uscita nel range [−1, 1]. Per calcolare l’output di un neurone è pertanto necessario un metodo che implementi la funzione: ! nl X l (1.1) ol+1 = tanh olj wji i j=0 per ogni neurone del layer l + 1, che propaghi anche i valori fino all’ultimo layer della rete (Listati 1.2 e 1.4). In ogni layer (tranne quello di output) l’ultimo neurone è fittizio e con uscita sempre pari a +1, in modo da fornire ai neuroni successivi una soglia di input. Per migliorare il comportamento della rete si può allargare la zona lineare della tanh per mezzo di due parametri: ! nl X l ol+1 = atanh b olj wji (1.2) i j=0 3 In questa implementazione si è scelto di usare i due parametri a = 1.7159, b = 32 come consigliato in vari articoli al riguardo. Si mette inoltre a disposizione il metodo CompleteRun che restituisce anche tutti i valori inerenti ai layers intermedi (Listato 1.3). Listing 1.2: Propagazione attraverso i vari layers def Run ( s e l f , i n p u t A r r a y ) : outArray = inputArray for i in xrange (1 , len ( s e l f . LayerDimensions ) ) : outArray = ( s e l f . layerCompute ( outArray , i )) return outArray Listing 1.3: Propagazione attraverso i vari layers memorizzando i valori intermedi def completeRun ( s e l f , i n p u t A r r a y ) : outArray = [ ] o u t A r r a y . append ( i n p u t A r r a y ) for i in xrange (1 , len ( s e l f . LayerDimensions ) ) : o u t A r r a y . append ( s e l f . l a y e r C o m p u t e ( o u t A r r a y [ i −1] , i ) ) return outArray Listing 1.4: Calcolo dell’output di un layer def l a y e r C o m p u t e ( s e l f , i n p u t A r r a y , OTL ) : sumArray = [ ] # number o f i n p u t s f o r t h e l a y e r i n p u t s = s e l f . L a y e r D i m e n s i o n s [ o u t L a y e r I n d e x −1] # number o f o u t p u t s f o r t h e l a y e r outputs = s e l f . LayerDimensions [ outLayerIndex ] for n in xrange ( outputs ) : sum = 0 for w in xrange ( inputs ) : sum += i n p u t A r r a y [ w] ∗ s e l f . LayerConnections [ outLayerIndex −1][ n ] [ w] sum += s e l f . L a y e r C o n n e c t i o n s [ o u t L a y e r I n d e x −1] [ n ] [ w+1] sumArray . append ( 1 . 7 1 5 9 ∗ math . t a n h ( 0 . 6 6 6 7 ∗ sum ) ) r e t u r n sumArray 1.2.2 Propagazione all’indietro Si è scelto di includere anche l’algoritmo di propagazione all’indietro all’interno di questa classe, in quanto questo è comune a molti metodi di apprendimento ed è 4 strettamente legato al tipo di funzione di trasferimento dei neuroni. In questo modo per cambiare funzione di trasferimento è sufficiente fornire una diversa implementazione di FFnet e gli algoritmi di apprendimento continueranno a funzionare senza modifiche. Lo scopo di questo metodo è quello di propagare il gradiente locale (δj ) all’indietro attraverso tutti i layer, in quanto la correzione che verrà applicata al peso wji è una funzione di δj (∆wji = f (δj )). Gli algoritmi che si servono di questo metodo mirano alla ricerca del minimo della funzione errore medio: ξavg N 1 X = ξ(n) N n=1 (1.3) con n che indica l’iterazione corrente. L’errore è quindi definito come: ξ(n) = 1 X 2 e (n); 2 j∈outputs j ej (n) = dj (n) − oj (n) (1.4) dove dj e oj sono rispettivamente il valore desiderato e l’output ottenuto sul bit j all’iterazione n. Il potenziale che si crea all’input di un neurone è: vjl+1 (n) = lastN euron X l wij (n)oli (n) (1.5) i=0 da cui l’output del neurone: l+1 ol+1 j (n) = ϕ(vj (n)) (1.6) A questo punto possiamo esprimere il gradiente in questo modo: ∂ξ(n) ∂ξ(n) ∂ej (n) ∂oj (n) ∂vj (n) = ∂wij (n) ∂ej (n) ∂oj (n) ∂vj (n) ∂wij (n) (1.7) Vediamo in dettaglio come si comportano le componenti dell’equazione (1.7). Derivando entambi i membri della prima parte della (1.4) rispetto a ej (n) si ottiene: ∂ξ(n) = ej (n) ∂ej (n) (1.8) e derivando la seconda parte rispetto a oj (n): ∂ej (n) = −1 ∂oj (n) (1.9) Derivando la (1.6) rispetto a vj (n) si ottiene: ∂oj (n) ∂ϕj (vj (n)) = ϕ′j (vj (n)) = ∂vj (n) ∂vj (n) (1.10) 5 e infine, derivando la (1.5) rispetto a wij (n): ∂vj (n) = oi (n) ∂wij (n) (1.11) Combinando opportunamente i risultati fin qui ottenuti si può quindi affermare che: ∂ξ(n) = −ej (n)ϕ′j (vj (n))oi (n) ∂wij (n) (1.12) e per comodità definire: δj (n) = − ∂ξ(n) ∂ξ(n) ∂ej (n) ∂oj (n) = = ej (n)ϕ′j (vj (n)) ∂vj (n) ∂ej (n) ∂oj (n) ∂vj (n) (1.13) che è il dato che i vari algoritmi di apprendimento utilizzano per determinare la correzione dei pesi delle connessioni e che occorre quindi calcolare in questo algoritmo. Manca da determinare come si calcola la ϕ′j (vj (n)) nel caso specifico di questa implementazione, ovvero quando ϕ(vj (n)) = a ∗ tanh(bvj (n)) con entrambi i parametri strettamente positivi e costanti. Per mezzo di trasformazioni algebriche possiamo ottenere: ϕ(vj (n)) = absech(bvj (n)) ∂vj (n) (1.14) b 2 = ab(1 − tanh (bvj (n))) = [a − oj (n)][a + oj (n)] a Questo approccio funziona egregiamente per quanto riguarda i neuroni di output, in quanto è possibile determinare direttamente l’errore (1.4) e di conseguenza il gradiente locale (1.13). Le cose non sono cosı̀ semplici quando si procede con i layer nascosti; l’errore relativo a ogni neurone nascosto dovrebbe essere determinato ricorsivamente in termini degli errori di tutti gli altri neuroni a cui è direttamente connesso, e ciò implica un’implementazione molto difficoltosa e poco efficiente. Possiamo però ridefinire il gradiente locale δj (n) (1.13), per un neurone nascosto j, in questi termini: δj (n) = − ∂ξ(n) ∂oi (n) ∂ξ(n) ′ =− ϕ (vj (n)) ∂oi (n) ∂vj (n) ∂oi (n) j (1.15) Per calcolare la derivata parziale di ξ(n) rispetto a oi (n) possiamo procedere in questo modo. Dalla definizione (1.4) si ricava direttamente: X ∂ek (n) ∂ξ(n) = ek (n) ∂oi (n) k∈outputs ∂oi (n) (1.16) che in base ai risultati ottenuti precedentemente può essere riscritta in questo modo: X ∂ek (n) ∂vk (n) ∂ξ(n) = ek (n) ∂oi (n) k∈outputs ∂vk (n) ∂oi (n) (1.17) 6 Si nota che, in base alle definizioni: ek (n) = dk (n) − ok (n) = dk (n) − ϕk (vk (n)) (1.18) ∂ek (n) = −ϕ′k (vk (n)) ∂vk (n) (1.19) e quindi: inoltre il campo locale indotto di un neurone k vale: vk (n) ≈ m X wjk oj (n) (1.20) j=0 dove m è il numero di neuroni di input per il neurone in considerazione. Differenziando rispetto a oj (n) si ricava: ∂vk (n) = wjk (n) (1.21) ∂oj (n) e infine: X X ∂ξ(n) =− ek (n)ϕ′k (n)wjk (n) = − δk (n)wjk (n) ∂oj (n) k k (1.22) possiamo quindi concludere che l’algoritmo di backpropagation può essere implementato calcolando il gradiente locale in questo modo: X δj (n) = ϕ′j (vj (n)) δk (n)wjk (n) (1.23) k Abbiamo quindi trovato un metodo che ci consente di calcolare il gradiente in funzione soltanto dell’uscita che il neurone aveva senza bisogno di memorizzare altri dati aggiuntivi e in modo molto semplice e quindi veloce, come si vede dall’implementazione realizzata (listati 1.5 e 1.4). Listing 1.5: Propagazione all’indietro del gradiente def completeBackRun ( s e l f , o u t p u t D e l t a A r r a y , completeRunAA ) : delta = [] d e l t a . append ( o u t p u t D e l t a A r r a y ) f o r i i n x r a n g e ( l e n ( s e l f . L a y e r D i m e n s i o n s ) −1 ,1 , −1): d e l t a . append ( s e l f . l a y e r B a c k C o m p u t e ( d e l t a [ l e n ( s e l f . L a y e r D i m e n s i o n s )−1− i ] , completeRunAA [ i −1] , i ) ) return d e l t a Listing 1.6: Calcolo del gradiente per un layer def l a y e r B a c k C o m p u t e ( s e l f , d e l t a A r r a y , i n p u t A r r a y , outLayerIndex ): 7 #backcompute one l a y e r , i n p u t A r r a y i s t h e o l d l a y e r i n p u t sumArray = [ ] i n p u t s = s e l f . L a y e r D i m e n s i o n s [ o u t L a y e r I n d e x −1] outputs = s e l f . LayerDimensions [ outLayerIndex ] for w in xrange ( inputs ) : #t = 1−( i n p u t A r r a y [ w] ∗ i n p u t A r r a y [ w ] ) #u s i n LeCun p a r a m e t e r s t = 0.3885∗(1.7159 − i n p u t A r r a y [w] ) ∗ (1.7159+ i n p u t A r r a y [ w ] ) sum = 0 for n in xrange ( outputs ) : sum += d e l t a A r r a y [ n ] ∗ s e l f . LayerConnections [ outLayerIndex −1][ n ] [ w] sumArray . append ( ( sum∗ t ) ) sum = 0 r e t u r n sumArray 1.3 La classe networkTrainer Questa classe implementa vari metodi di apprendimento per fare il training ad una rete di tipo FFnet. Per motivi di leggibilità ed efficienza del codice i metodi che implementano i vari algoritmi di apprendimento vanno direttamente a modificare i parametri della rete FFnet e sono quindi strettamente legati alla loro rappresentazione. É comunque facile in qualsiasi momento staccare la rappresentazione interna di FFnet da questi metodi aggiungendo a quest’ultima dei metodi ad hoc che permettono la modifica dei singoli pesi delle connessioni ed aggiornando quindi di conseguenza le implementazioni dei metodi di apprendimento (rendendo il tutto più lento ma guadagnando in manutenibilità ed estendibilità del codice). Listing 1.7: Strutture dati comuni a molti algoritmi di apprendimento self self self self self self self . n e t w o r k = FFnet ( ) . LR = 0 . 0 5 .M = 0 . 0 5 . LayerCorrections = [ ] . CLR = [ ] # [ ] [ ] [ ] .DW = [ ] # [ ] [ ] [ ] . W e i g h t S c a l e = 1000 1.3.1 Inizializzazione di una nuova rete La prima cosa da fare dopo aver istanziato un networkTrainer è quella di inizializzare una nuova rete. In questo modo infatti si allocano le strutture dati necessarie 8 al funzionamentio dei vari algoritmi di apprendimento e si inizializzano le connessioni neuronali della rete con dei valori random. A questo punto si può iniziare l’apprendimento della nuova rete oppure caricare una rete già esistente per proseguire un apprendimento precedente. La scelta dei valori random per le connessioni viene fatta su una distribuzione √ uniforme (−w < 0 < +w). Gli estremi −w, +w, simmetrici, sono scelti come 1/ N dove N è il numero di connessioni entranti in un neurone (variabile da layer a layer); questo per evitare che il neurone possa andare in saturazione con un input mediamente nullo. Listing 1.8: Inizializzazione def i n i t i a l i z e N e t w o r k ( s e l f , a r r a y L a y e r ) : s e l f . n e t w o r k = FFnet ( ) s e l f . network . LayerDimensions = a r r a y L a y e r f o r l i n x r a n g e ( l e n ( a r r a y L a y e r ) −1): inputs = arrayLayer [ l ] o u t p u t s = a r r a y L a y e r [ l +1] W = [] A = [] LR = [ ] w e i g t h R a n g e = 1 / ( math . s q r t ( i n p u t s +1)) i f s e l f . WeightScale > weigthRange : for i in xrange ( outputs ) : w = [] a = [] lr = [] f o r j i n x r a n g e ( i n p u t s +1): w . append ( random . u n i f o r m ( −weigthRange , weigthRange ) ) a . append ( 0 ) l r . append ( s e l f . LR ) W. append (w) A . append ( a ) LR . append ( l r ) s e l f . n e t w o r k . L a y e r C o n n e c t i o n s . append (W) s e l f . L a y e r C o r r e c t i o n s . append (A) s e l f .DW. append (A) s e l f . CLR . append ( LR ) Calcolo del Mean Square Error e della sommatoria dei gradienti Il calcolo dell’MSE viene effettuato da tutti gli algoritmi di apprendimento servendosi del metodo evaluateMSE (1.9), molto semplice e veloce. Per semplificare la 9 propagazione all’indietro dell’errore viene fornito il metodo addPatternDW che si occupa di calcolare e propagare all’indietro l’errore relativo al pattern fornito, e di sommare il risultato agli eventuali altri risultati ottenuti precedentemente, semplificando e velocizzando di molto la realizzazione di apprendimenti batch (1.10). L’esecuzione di quest’ultimo metodo inoltre restituisce il valore di output della rete che può essere usato per calcolare l’MSE senza ripetere inutilmente una propagazione in avanti. Questo metodo, in quanto legato strettamente alla funzione di trasferimento del neurone dovrebbe legittimamente trovarsi nella classe FFnet; si è scelto di tenerlo qui per velocizzare l’esecuzione della rete. Listing 1.9: Calcolo del MSE def evaluateMSE ( s e l f , netOutputAA , outputAA ) : s MSE = 0 o u t p u t s = l e n ( outputAA [ 0 ] ) f o r i i n x r a n g e ( l e n ( outputAA ) −1): t = 0 for j in xrange ( outputs ) : t += ( math . pow ( netOutputAA [ i ] [ j ] −outputAA [ i ] [ j ] , 2 ) ) MSE +=t /2 r e t u r n (MSE/ l e n ( outputAA ) ) Listing 1.10: Calcolo dell’errore e dei gradienti def addPatternDW ( s e l f , i n p u t A r r a y , o u t p u t A r r a y ) : delta = [] f o r w a r d V a l u e s = s e l f . n e t w o r k . completeRun ( i n p u t A r r a y ) for i in xrange ( len ( outputArray ) ) : d e l t a . append ( 0 . 3 8 8 5 ∗ ( f o r w a r d V a l u e s [ l e n ( forwardValues ) −1][ i ] − outputArray [ i ])∗(1.7159 − f o r w a r d V a l u e s [ l e n ( f o r w a r d V a l u e s ) −1] [ i ])∗(1.7159+ forwardValues [ l e n ( forwardValues ) −1][ i ] ) ) b a c k w a r d V a l u e s = s e l f . n e t w o r k . completeBackRun ( delta , forwardValues ) for outLayerIndex in xrange (1 , l e n ( s e l f . network . LayerDimensions ) ) : i n p u t s = s e l f . network . LayerDimensions [ o u t L a y e r I n d e x −1]+1 outputs = s e l f . network . LayerDimensions [ outLayerIndex ] for n in xrange ( outputs ) : f o r w i n x r a n g e ( i n p u t s −1): 10 s e l f .DW[ o u t L a y e r I n d e x − 1 ] [ n ] [ w ] +=f o r w a r d V a l u e s [ o u t L a y e r I n d e x − 1 ] [w] ∗ (− b a c k w a r d V a l u e s [ l e n ( b a c k w a r d V a l u e s )− ( o u t L a y e r I n d e x −1) −1][ n ] ) s e l f .DW[ o u t L a y e r I n d e x − 1 ] [ n ] [ w+1]+= (− b a c k w a r d V a l u e s [ l e n ( b a c k w a r d V a l u e s )− ( o u t L a y e r I n d e x −1) −1][ n ] ) r e t u r n f o r w a r d V a l u e s [ l e n ( f o r w a r d V a l u e s ) −1] 1.4 Algoritmi implementati in networkTrainer Diamo adesso una breve descrizione dei vari algoritmi di apprendimento forniti dalla classe networkTrainer, i dettagli implementativi e i relativi parametri saranno discussi più approfonditamente nel capitolo 2; il codice non viene riportato qui in quanto risulterebbe lungo e illeggibile, ma è reperibile, di facile lettura e ben commentato all’interno del file FFnet.py. Tutti i metodi batch proposti sono implementati in modo da permetterne l’esecuzione su un singolo pattern; questo permette di realizzare facilmente gli stessi algoritmi di apprendimento che operano statisticamente su campioni in ordine casuale. 1.4.1 Sequential Backpropagation Questo algoritmo implementa la backpropagation sequenziale sui pattern in ingresso. Dato un Training Set, per ogni pattern, dal primo all’ultimo si calcola la variazione richiesta ad ogni peso della rete e la si applica prima di procedere con il pattern successivo. Si procede quindi al calcolo del Mean Square Error e si itera da capo se non è stato raggiunto il valore richiesto. I pesi delle connessioni vengono aggiornati secondo la δ-rule: l l (1.24) ∆wji (n) = ηδjji (n)oiji (n) dove lji indica il layer a cui punta il peso wji e n il pattern di apprendimento; ogni pattern causa una modifica ai pesi della rete. 1.4.2 Batch Backpropagation Questo algoritmo implementa la backpropagation in modalità batch sui pattern in ingresso. Dato un training set, si calcola la somma dei gradienti locali per ogni neurone, e si va a modificare la rete secondo la media dei gradienti. Dopo ogni modifica si va a calcolare il mean square error e si decide se iterare ancora sullo stesso training set. I pesi delle connessioni vengono aggiornati secondo la δ-rule modificata 11 in qesto modo: N η X lji l ∆wji = δj (n)oiji (n) N n=0 (1.25) dove N indica il numero di pattern di apprendimento. In questo caso i pesi vengono modificati una sola volta dopo aver calcolato e mediato i contributi di tutti i campioni di apprendimento; l’apprendimento della rete in questo caso può risultare più lento rispetto alla backpropagation sequenziale ma ha il vantaggio di proseguire in modo più stabile. 1.4.3 Batch Backpropagation con momento L’algoritmo di backpropagation con momento ha la particolarità di aggiungere un fattore inerziale al sistema. Questo permette di aumentare la stabilità dell’apprendimento e di velocizzarlo notevolmente quando la rete deve muoversi nella stessa direzione per diverse iterazioni consecutive. La δ-rule per la modifica dei pesi diventa: N η X lji l δj (n)oiji (n) ∆wji = αdji + N n=0 (1.26) dove dji indica la variazione del peso wji all’iterazione precedente e α permette di modificare l’incidenza dell’inerzia sul sistema. 1.4.4 Batch Backpropagation con momento e superSAB L’idea che sta alla base dell’algoritmo superSAB è che generamente i pesi dovranno muoversi lungo direzioni diverse a velocità diverse. Risulta quindi sensato fare in modo che ogni peso abbia il proprio learning rate e che questo possa variare durante l’esecuzione della rete. In linea di principio il learning rate di un peso dovrà aumentare se per due passi consecutivi questo si è mosso nella stessa direzione, e diminuire altrimenti. La δ-rule per la modifica dei pesi viene quindi modificata a partire da quella per la backpropagation con momento: N ηji X lji l ∆wji = αdji + δ (n)oiji (n) N n=0 j (1.27) dove si nota come ogni peso abbia il proprio learning rate ηji . Mancano da definire i due parametri ηdown e ηup che servono per la modifica dei learning rate secondo la regola: sign(wji (k)) = sign(wji (k − 1)) → ηji (k) = ηup ηji (k − 1) (1.28) sign(wji (k)) 6= sign(wji (k − 1)) → ηji (k) = ηdown ηji (k − 1) dove (k) indica l’iterazione a cui è riferito il valore, e che ovviamente devono rispettare la condizione: 0 < ηdown < 1 < ηup 12 1.4.5 Batch Resilient Backpropagation L’idea che sta alla base dell’algoritmo Rprop è molto simile a quella alla base del metodo superSAB: anche in questo caso i pesi hanno uno sviluppo indipendente l’uno dall’altro e cerca di mitigare il problema di trovare un appropriato learning rate di partenza per l’addestramento. Per un pattern di apprendimento i pesi vengono aggiornati secondo la regola: ∂ξ (k) k >0 −∆ , se ji ∂wji ∆wji = ∂ξ (k) k +∆ , se <0 ji ∂wji 0, altrimenti (1.29) ed i valori di aggiornamento: ∂ξ (k−1) ∂ξ (k) + k−1 >0 η ∆ , se ji ∂wji ∂wji k ∆ji = ∂ξ (k−1) ∂ξ (k) − k−1 η ∆ , se <0 ji ∂w ∂w ji ji ∆ji , altrimenti (1.30) dove l’apice rapprensenta il passo corrente dell’algoritmo, e in modo simile a come si fa con il metodo superSAB si usano i due parametri: 0 < η− < 1 < η+ per determinare la velocità di variazione degli aggiornamenti. In modalità batch la regola di apprendimento per i pesi diventa: −∆kji PN ∂ξ (k) (n) , se >0 n=1 N ∂wji +∆kji PN ∂ξ (k) (n) ∆wji = , se <0 n=1 N ∂w ji 0, altrimenti (1.31) 13 e quella che riguarda i valori di aggiornamento di conseguenza: PN ∂ξ (k−1) (n) ∂ξ (k) (n) + k−1 η ∆ , se >0 ji n=1 ∂wji ∂wji k PN ∂ξ (k−1) (n) ∂ξ (k) (n) ∆ji = − k−1 <0 η ∆ , se ji n=1 ∂wji ∂wji ∆ji , altrimenti dove N rappresenta il numero di patterns su cui si sta addestrando la rete. (1.32) 14 CAPITOLO 2 La rete in funzione 2.1 Come si usa Il modo più semplice e veloce di capire come funziona PYANN è di vedere un breve esempio di utilizzo. La prima operazione da fare è aprire una shell di python: $ python Python 2.4.4 (#2, Aug 16 2007, 00:34:54) [GCC 4.1.3 20070812 (prerelease) (Debian 4.1.2-15)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> e importare la libreria FFnet: >>> import FFnet >>> Predisporre l’ambiente per l’addestramento di una rete è altrettanto semplice: >>> nn = FFnet.networkTrainer() >>> nn.initializeNetwork([2,3,1]) >>> abbiamo appena creato una rete con 2 input, 3 neuroni nello strato nascosto e un neurone di output. Supponiamo di voler addestrare la rete per risolvere il problema dello XOR binario, e creiamo quindi due array che contengono i quattro input e i quattro corrispettivi output necessari per l’addestramento: 15 16 >>>inp = [[1,1],[1,-1],[-1,1],[-1,-1]] >>>out = [[1],[-1],[-1],[1]] >>> La rete è pronta per essere addestrata, procediamo con un apprendimento Batch Backpropagation: >>> .MSE .MSE .MSE .MSE .MSE .MSE .MSE .MSE .MSE .MSE nn.batchBackprop(0.1,inp,out,1000) all’iterazione: 1 -- 0.388085350486 all’iterazione: 2 -- 0.378556363768 all’iterazione: 3 -- 0.370077743732 all’iterazione: 4 -- 0.362553681581 all’iterazione: 5 -- 0.355893789813 all’iterazione: 6 -- 0.3500135965 all’iterazione: 7 -- 0.344834782053 all’iterazione: 8 -- 0.340285214681 all’iterazione: 9 -- 0.336298834097 all’iterazione: 10 -- 0.332815425727 ... .MSE .MSE .MSE .MSE .MSE .MSE .MSE .MSE all’iterazione: all’iterazione: all’iterazione: all’iterazione: all’iterazione: all’iterazione: all’iterazione: all’iterazione: 198 199 200 201 202 203 204 205 --------- 0.112859960367 0.110932740132 0.109020671091 0.107124300597 0.105244157119 0.103380749549 0.101534566564 0.0997060760546 >>> lo standar adottato per i parametri dei metodi prevede che il primo rappresenti l’MSE a cui si vuole fermare l’apprendimento, il secondo e il terzo gli array di input e output per l’addestramento, l’ultimo il numero massimo di iterazioni dopo il quale l’addestramento verrà fermato in qualunque caso. Eseguire la rete su un campione di input è altrettando semplice: >>> for i in inp: ... print "Input: ",i," Output: ",nn.network.Run(i) ... Input: [1, 1] Output: [0.42546470370636524] 17 Input: Input: Input: >>> [1, -1] Output: [-0.53737323228771272] [-1, 1] Output: [-0.51107110534015399] [-1, -1] Output: [0.29444082430963386] Per salvare la rete appena addestrata: >>> nn.saveNetwork("./retediprova.net") >>> Per caricarla in un ambiente che non comprende tutte le strutture di addestramento (e quindi che occupa molta meno memoria) ed utilizzarla su un campione di input: >>> newnn = FFnet.FFnet() >>> newnn.loadNetwork("./retediprova.net") >>> for i in inp: ... print "Input: ",i," Output: ",newnn.Run(i) ... Input: [1, 1] Output: [0.42546470370636524] Input: [1, -1] Output: [-0.53737323228771272] Input: [-1, 1] Output: [-0.51107110534015399] Input: [-1, -1] Output: [0.29444082430963386] >>> Lo stesso metodo loadNetwork può essere utilizzato su un oggetto di tipo networkTrainer per continuare l’addestramento di una rete già esistente: >>> nn.initializeNetwork([2,3,1]) >>> nn.loadNetwork("./retediprova.net") >>> nn.batchBackprop(0.01,inp,out,15) .MSE all’iterazione: 1 -- 0.0978957246156 .MSE all’iterazione: 2 -- 0.0961039371024 .MSE all’iterazione: 3 -- 0.0943311162516 .MSE all’iterazione: 4 -- 0.0925776423665 .MSE all’iterazione: 5 -- 0.090843873069 .MSE all’iterazione: 6 -- 0.0891301431143 .MSE all’iterazione: 7 -- 0.0874367642713 .MSE all’iterazione: 8 -- 0.0857640252636 .MSE all’iterazione: 9 -- 0.0841121917723 .MSE all’iterazione: 10 -- 0.0824815064989 .MSE all’iterazione: 11 -- 0.0808721892835 .MSE all’iterazione: 12 -- 0.0792844372804 .MSE all’iterazione: 13 -- 0.0777184251847 .MSE all’iterazione: 14 -- 0.0761743055096 .MSE all’iterazione: 15 -- 0.0746522089114 18 >>> for ... ... Input: Input: Input: Input: >>> 2.2 i in inp: print "Input: ",i," Output: ",nn.network.Run(i) [1, 1] Output: [0.49090573269571275] [1, -1] Output: [-0.60803683757966709] [-1, 1] Output: [-0.58478215022839564] [-1, -1] Output: [0.38456170666793915] Confronto fra i metodi di apprendimento e importanza dei parametri I metri di giudizio più importanti per la valutazione dei metodi di apprendimento sono la velocità di convergenza e la qualità della soluzione trovata. Quest’ultima ovviamente dipende dallo scopo che si vuole raggiungere: se si vuole un semplice riconoscitore di oggetti noti una rete in overfit può essere più che utile (o addirittura necessaria); se si vuole invece discriminare tra categorie di oggetti non noti (che non fanno parte del campione di addestramento) è invece molto importante che la rete sia in grado di generalizzare (e quindi che non sia in overfit). 2.2.1 Velocità di convergenza Consideriamo una rete con 3 input, due layer nascosti con 5 neuroni ciascuno e un solo output, per risolvere il problema XOR ternario. In tabella 2.1 possiamo vedere una stima indicativa del numero medio di iterazioni necessarie per arrivare ad un M SE = 0.1 (su 100 prove), con un learning rate di partenza pari a 0.4 e fattore di momento pari a 0.1 per tutti gli algoritmi (e un limite massimo di iterazioni pari a 1000). Confontiamo questi dati con quelli delle tabelle 2.2 e 2.3 che stimano il numero di iterazioni richieste nella stessa situazione ma con learning rate rispettivamente pari a 0.2 e 0.1. Per tutti i metodi batch, come era lecito aspettarsi, al diminuire del learning rate sale il numero di iterazioni di apprendimento da fare (ad eccezione della Resilient Backpropagation che non fa uso di questo parametro). Apparentemente l’algoritmo di backpropagation sequenziale sembra comportarsi in modo anomalo ma i motivi di questo andamento sono da ricercarsi nella stabilità della discesa verso il minimo; al crescere del learning rate infatti è facile che questo algoritmo non abbia un andamento regolare discendente dell’MSE ma che quest’ultimo oscilli anche di parecchio, finendo quindi per allungare il tempo richiesto per l’apprendimento. Dalle stesse tabelle è inoltre molto facile confrontare il comportamento dei vari metodi batch. In prima analisi sembra che il metodo con momento e superSAB si comporti in modo leggermente migliore al decrescere del learning rate di partenza; questo perchè un learning rate alto nelle prime iterazioni potrebbe portare dei pesi che devono 19 muoversi poco molto lontano dalla loro posizione finale, mentre un learning rate basso permette alla rete in poche iterazioni di aggiustare la velocità di apprendimento di ogni peso in base alla propria rilevanza effettiva. In figura 2.1 si può vedere una misura molto più accurata di quanto anticipato dalle tabelle 2.1,2.2 e 2.3. Non si nota molta differenza tra la backpropagation batch senza momento e quella con momento: la seconda è leggermente più efficace, ma il guadagno in velocità è piccolo e diminuisce con l’aumentare della rilevanza del risultato della propagazione all’indietro rispetto al momento (mantenuto costante per tutte le prove). Il metodo superSAB invece ha un costo pressochè costante e indipendente dal learning rate di partenza, contrariamente a quanto si poteva ipotizzare dai risultati, meno precisi, indicati nelle tabelle. Tabella 2.1: Learning rate 0.4 Metodo media iterazioni Linear Backpropagation 999 Batch Backpropagation 65 Batch Backpropagation con Momento 48 Batch Backpropagation con Momento e SuperSAB 108 Batch Resilient Backpropagation 35 Tabella 2.2: Learning rate 0.2 Metodo media iterazioni Linear Backpropagation 504 Batch Backpropagation 118 Batch Backpropagation con Momento 104 Batch Backpropagation con Momento e SuperSAB 108 Batch Resilient Backpropagation 33 Tabella 2.3: Learning rate 0.1 Metodo media iterazioni Linear Backpropagation 471 Batch Backpropagation 229 Batch Backpropagation con Momento 214 Batch Backpropagation con Momento e SuperSAB 99 Batch Resilient Backpropagation 34 2.2.2 Backpropagation con momento Il grafico 2.2 mostra il comportamento dell’algoritmo di backpropagation con momento al variare sia del learning rate che del fattore momento nel caso dello XOR ternario. Si vede facilmente che il termine di momento migliora di tanto l’apprendimento in caso di learning rate bassi, ma il guadagno che se ne riceve, sebbene sempre presente, 20 1000 sequential bakpropagation Batch backpropagation Moment batch backpropagation MomentsuperSAB batch backpropagation 900 800 700 600 500 400 300 200 100 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Figura 2.1: Numero medio di iterazioni di apprendimento richieste al variare del learning rate. 21 perde di importanza all’aumentare del learning rate. In questa situazione specifica il caso ottimo si ha quando sia il learning rate che il momento hanno fattore 21 . 22 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 500 450 400 350 300 250 200 150 100 50 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Figura 2.2: Comportamento al variare del learning rate per alcuni coefficienti di momento. CAPITOLO 3 Un esempio concreto: Optical Character Recognition Come riassunto del lavoro presento un semplice sistema in grado, data un’immagine contente una stringa di caratteri, di riconoscere le lettere o i numeri che la compongono. 3.1 3.1.1 Caratteristiche delle reti Comunicazione con la rete: codifica di Input e Output La rete prende in input un’immagine in formato jpeg contenente un solo carattere, scalato in modo da occupare la regione di spazio più ampia possibile all’interno dell’immagine. Quello che si fa è quindi di creare un array contenente la matrice di pixel dell’immagine per righe, assegnando ad ogni pixel valore 1 o -1 in funzione del colore colore più vicino al nero o al bianco. Per quanto riguarda l’output si utilizza un file di codifica che esplicita l’associazione simbolo/output della rete. In particolare il file di codifica utilizzato è quello nel listing 3.1. 3.1.2 Addestramento delle reti Le reti vengono addestrate in questo modo: 1. Si scelgono 100 campioni in maniera random nel trainset 2. Si eseguono 10 iterazioni dell’algoritmo BatchMsuperSAB 3. Si eseguono 100 iterazioni dell’algoritmo BatchRprop 23 24 Listing 3.1: Codifica per i numeri 0 1 2 3 4 5 6 7 8 9 11000000000000000000 00110000000000000000 00001100000000000000 00000011000000000000 00000000110000000000 00000000001100000000 00000000000011000000 00000000000000110000 00000000000000001100 00000000000000000011 4. Se si è raggiunto l’errore desiderato oppure 10000 iterazioni termina, altrimenti torna al punto 1. Questo sistema si è rivelato leggermente più veloce sia del metodo batch che del metodo completamente stocastico. 3.1.3 Scelta della dimensione della rete Per capire quale sia la dimensione della rete che rappresenta il miglior compromesso tra capacità di generalizzazione e dimensioni l’unico sistema disponibile è quello di fare delle prove su alcune dimensioni differenti e fare un confronto. Come dimensione dell’immagine di input si usa un quadrato di 20×20, e la codifica utilizzata per i numeri (Listing 3.1) prevede 20 outputs. Le dimensioni scelte per il confronto sono elencate in tabella (3.1). Tutte le reti sono state addestrate allo stesso modo (come descritto nella sezione 3.1.2), su un campione di 72 fonts. Il test è invece stato eseguito su un campione di circa 1300 fonts (senza overlap con quello di addestramento), con i risultati mostrati in tabella (3.2). Per risposta corretta si intende ovviamente che la rete ha correttamente riconosciuto il numero, per risposta errata si intende che la rete ha dato in output un numero ma che questo non corrisponde con quello disegnato nell’immagine, e per risposta non valida si intende che la rete ha prodotto un output che non appartiene all’insieme di codifiche definito nel listing 3.1. Dai risultati si capisce innanzitutto che la struttura della rete conta molto rispetto al numero di neuroni totale. A parità di neuroni infatti, la rete di dimensioni 400 × 20 × 20 × 20 ha una performance visibilmente migliore della sua controparte 400 × 40 × 20; la prima è anche più veloce in quanto ha solo 8800 connessioni rispetto alla seconda che ne ha 16800. Le capacità di generalizzazione crescono con il numero di neuroni e con il numero di layer e come era lecito aspettarsi, la rete più grande offre le prestazioni migliori (ma una computazione decisamente più lenta e onerosa in termini di memoria occupata). Visti i risultati ottenuti dal test, la scelta per la dimensione della rete è caduta su 400 × 60 × 45 × 30 × 20, che dovrebbe risultare in un buon compromesso 25 Tabella 3.1: Dimensioni delle reti messe a confronto 1. 400 × 20 × 20 2. 400 × 40 × 20 3. 400 × 80 × 20 4. 400 × 160 × 20 5. 400 × 20 × 20 × 20 6. 400 × 40 × 20 × 20 7. 400 × 80 × 40 × 20 8. 400 × 160 × 80 × 20 9. 400 × 20 × 20 × 20 × 20 10. 400 × 40 × 30 × 20 × 20 11. 400 × 80 × 60 × 40 × 20 Tabella 3.2: Test sugli stessi campioni per diverse dimensioni delle reti Dimensione rete Risposte corrette Risposte non valide Risposte errate 400 × 20 × 20 2917 5654 1819 400 × 40 × 20 2731 6187 1472 400 × 80 × 20 3075 6104 1211 400 × 160 × 20 3234 5952 1204 400 × 20 × 20 × 20 3968 3240 3182 400 × 40 × 20 × 20 3734 4557 2099 400 × 80 × 40 × 20 4506 3077 2807 400 × 160 × 80 × 20 4396 3777 2217 400 × 20 × 20 × 20 × 20 4479 2760 3151 400 × 40 × 30 × 20 × 20 4727 2439 3224 400 × 80 × 60 × 40 × 20 4822 2537 3031 26 Tabella 3.3: Test su sei reti di dimensione 400 × 60 × 45 × 30 × 20 Dimensione rete Risposte corrette Risposte non valide Risposte errate 400 × 60 × 45 × 30 × 20 8689 1225 476 tra prestazioni della rete e velocità di addestramento. In tabella (3.3) si vedono i risultati del test effettuato sulle sei reti addestrate con questa dimensione, le stesse con cui si sono svolti i test riportati in sezione 3.2.2. 3.1.4 Riconoscimento di caratteri Per semplicità e brevità di addestramento ci limiteremo a riconoscere solo lettere maiuscole. Come nel caso dei numeri la rete prende in input un’immagine in formato jpeg contenente una sola lettera e restituisce un output in base alla codifica 3.2. L’addestramento è stato fatto sullo stesso campione di 72 fonts usato per il caso dei numeri (per un totale di 1872 campioni), ma questa volta le reti hanno una dimensione maggiore: 400 × 250 × 150 × 100 × 52. 3.1.5 Discriminazione tra caratteri e lettere Sullo stesso campione di font sono state addestrate anche un piccolo numero di reti che hanno la funzione di discriminare tra lettere e numeri, e che vengono usate per instradare il carattere da riconoscere verso il gruppo di reti piu adatto. Queste reti lavorano con la codifica indicata nel listing 3.3 3.2 Un semplice sistema OCR: SPOCR SimplePythonOCR è un semplice tool che utilizza più reti neurali per effettuare il riconoscimento di caratteri. 3.2.1 Come si usa L’utilizzo di SPOCR è molto semplice: è infatti sufficiente eseguire il comando: $python SPOCR.py <immagine.jpg> dove immagine.jpg è una o più immagini JPEG contenenti uno o più caratteri (su una sola riga), e si ottiene una risposta del tipo: $ python SPOCR.py TESTS/10numbers-1.jpg SPOCR initialized loading ./RESOURCES/NUMBERS/net1.net ... loading ./RESOURCES/NUMBERS/net2.net ... 27 Figura 3.1: Font usati per il training sui numeri 28 Listing 3.2: Codifica per le lettere maiuscole Q W E R T Y U I O P A S D F G H J K L Z X C V B N M 1100000000000000000000000000000000000000000000000000 0011000000000000000000000000000000000000000000000000 0000110000000000000000000000000000000000000000000000 0000001100000000000000000000000000000000000000000000 0000000011000000000000000000000000000000000000000000 0000000000110000000000000000000000000000000000000000 0000000000001100000000000000000000000000000000000000 0000000000000011000000000000000000000000000000000000 0000000000000000110000000000000000000000000000000000 0000000000000000001100000000000000000000000000000000 0000000000000000000011000000000000000000000000000000 0000000000000000000000110000000000000000000000000000 0000000000000000000000001100000000000000000000000000 0000000000000000000000000011000000000000000000000000 0000000000000000000000000000110000000000000000000000 0000000000000000000000000000001100000000000000000000 0000000000000000000000000000000011000000000000000000 0000000000000000000000000000000000110000000000000000 0000000000000000000000000000000000001100000000000000 0000000000000000000000000000000000000011000000000000 0000000000000000000000000000000000000000110000000000 0000000000000000000000000000000000000000001100000000 0000000000000000000000000000000000000000000011000000 0000000000000000000000000000000000000000000000110000 0000000000000000000000000000000000000000000000001100 0000000000000000000000000000000000000000000000000011 Listing 3.3: Codifica per la discriminazione LETTER 0011 NUMBER 1100 29 Figura 3.2: Font usati per il training sulle lettere 30 Figura 3.3: Test scrittura correttamente riconosciuto loading ./RESOURCES/NUMBERS/net3.net ... loading ./RESOURCES/NUMBERS/net4.net ... Resources loaded Considering: TESTS/10numbers-1.jpg 0 - [’90.1’, ’92.3’, ’85.0’, ’98.0’, ’91.3’] 1 - [’65.5’, ’84.9’, ’85.6’, ’78.6’, ’78.6’] 2 - [’80.6’, ’83.5’, ’63.9’, ’84.8’, ’76.1’] 3 - [’86.4’, ’58.4’, ’72.1’, ’73.9’, ’70.1’] 4 - [’97.2’, ’93.1’, ’91.2’, ’97.3’, ’94.7’] Not recognized - [’54.7’, ’42.2’, ’61.7’, ’45.3’, ’43.8’] 6 - [’94.9’, ’93.3’, ’84.7’, ’99.5’, ’93.1’] Not recognized - [’43.1’, ’52.1’, ’34.8’, ’37.1’, ’31.9’] 8 - [’83.0’, ’95.1’, ’93.6’, ’92.6’, ’91.1’] 9 - [’95.1’, ’99.2’, ’97.3’, ’93.7’, ’96.3’] Per ogni carattere individuato nell’immagine il programma stampa quello che ha riconosciuto grazie alla media dei risultati di tutte le reti, e per ogni rete stampa un indice del livello di fiducia che ogni singola rete ha avuto sul proprio risultato (somma mediata di tutti gli output della rete); l’ultimo risultato indica il grado di fiducia medio per tutte le reti. 3.2.2 Alcuni risultati Riconoscimento di numeri Proviamo adesso a riconoscere dei numeri scritti a mano e tipografici utilizzando una composizione di sei reti addestrate sui 720 campioni di numeri, 72 per ogni numero. (vedi fig. 3.1). Caso in figura (3.3) L’esecuzione delle reti riporta: Considering: TESTS/4numbers-man1.jpg 1 - [’97.09’, ’97.78’, ’95.86’, ’95.38’, ’98.85’, ’93.36’, ’96.39’] 2 - [’100.3’, ’100.2’, ’98.84’, ’101.2’, ’99.96’, ’101.4’, ’100.3’] 31 Figura 3.4: Test scrittura correttamente riconosciuto Figura 3.5: Test scrittura correttamente riconosciuto 3 4 - [’75.94’, ’93.56’, ’82.17’, ’86.27’, ’78.66’, ’85.94’, ’83.76’] [’99.07’, ’96.86’, ’99.18’, ’98.09’, ’98.71’, ’99.07’, ’98.50’] In questo caso tutte le reti hanno riconosciuto tutti i numeri. Un indice di fiducia maggiore di 100 si può ottenere in quanto la funzione di trasferimento dei neuroni può, come valore di output, salire leggermente sopra 1. Caso in figura (3.4) Considering: TESTS/4numbers-man2.jpg 1 - [’90.91’, ’99.66’, ’94.97’, ’96.58’, 2 - [’90.22’, ’90.12’, ’73.83’, ’91.69’, 3 - [’73.49’, ’44.08’, ’63.39’, ’68.83’, 4 - [’98.54’, ’99.04’, ’97.16’, ’99.79’, ’87.34’, ’86.11’, ’64.48’, ’99.45’, ’97.03’, ’77.52’, ’55.84’, ’100.0’, ’94.32’] ’82.64’] ’57.04’] ’99.01’] ’89.24’, ’98.63’, ’75.20’, ’100.6’, ’98.78’, ’90.65’, ’61.97’, ’99.57’, ’96.59’] ’94.03’] ’71.80’] ’98.95’] Caso in figura (3.5) Considering: TESTS/4numbers-man3.jpg 1 - [’99.34’, ’98.77’, ’96.82’, ’96.61’, 2 - [’93.45’, ’95.13’, ’87.82’, ’98.50’, 3 - [’90.89’, ’58.84’, ’76.79’, ’73.82’, 4 - [’96.91’, ’100.1’, ’98.32’, ’98.11’, Caso in figura (3.6) Considering: TESTS/5numbers-man1.jpg 5 - [’87.30’, ’70.70’, ’65.76’, ’75.18’, ’82.48’, ’74.52’, ’75.86’] 6 - [’99.81’, ’99.98’, ’96.05’, ’98.92’, ’99.04’, ’95.48’, ’98.21’] 7 - [’76.16’, ’92.19’, ’85.75’, ’78.63’, ’88.65’, ’82.03’, ’83.90’] 32 Figura 3.6: Test scrittura correttamente riconosciuto Figura 3.7: Test scrittura, 9 non riconosciuto ma unica alternativa 8 9 - [’96.28’, ’97.88’, ’100.1’, ’98.61’, ’94.77’, ’97.80’, ’97.59’] [’88.49’, ’82.70’, ’79.68’, ’84.12’, ’90.60’, ’95.74’, ’86.42’] Caso in figura (3.7) Considering: TESTS/5numbers-man2.jpg 5 - [’100.9’, ’99.94’, ’98.67’, ’95.27’, 6 - [’74.04’, ’85.85’, ’69.23’, ’63.84’, 7 - [’62.56’, ’79.77’, ’70.77’, ’71.55’, 8 - [’94.28’, ’98.19’, ’99.75’, ’96.34’, Not recognized -- may be: | 9 | - [’74.29’, ’79.51’, ’87.89’, ’82.86’, ’95.67’, ’94.37’, ’66.65’, ’93.52’, ’98.19’, ’83.40’, ’70.15’, ’99.96’, ’98.11’] ’73.71’] ’70.08’] ’97.01’] ’82.34’, ’83.89’, ’81.40’] Quando la rete non riconosce un carattere si stampano tutti i caratteri corrispondenti a tutti gli output positivi della rete, per avere un’idea di quanto lontano fosse l’output della rete dalla risposta reale. In questo caso c’era un solo output positivo invece di una coppia. Caso in figura (3.8) Considering: TESTS/5numbers-man3.jpg Figura 3.8: Test scrittura correttamente riconosciuto 33 Figura 3.9: Test scrittura correttamente riconosciuto Figura 3.10: Test scrittura, 5,6,8,9 non riconosciuti 5 6 7 8 9 - [’80.01’, [’79.15’, [’82.96’, [’82.59’, [’97.89’, ’82.76’, ’74.81’, ’90.51’, ’85.46’, ’82.07’, ’95.55’, ’84.29’, ’84.48’, ’92.44’, ’77.92’, ’86.95’, ’82.24’, ’87.14’, ’93.81’, ’93.70’, ’94.11’, ’95.36’, ’83.73’, ’85.47’, ’89.85’, ’87.18’, ’84.03’, ’86.86’, ’94.62’, ’96.18’, ’86.65’] ’79.26’] ’85.95’] ’87.89’] ’89.53’] Considering: TESTS/mistonumeri.jpg 3 - [’88.60’, ’85.06’, ’93.94’, ’86.75’, 2 - [’54.11’, ’59.27’, ’71.01’, ’78.15’, 8 - [’76.46’, ’71.19’, ’62.59’, ’72.60’, 5 - [’97.96’, ’92.28’, ’92.45’, ’95.93’, 0 - [’77.79’, ’64.23’, ’64.09’, ’70.36’, 0 - [’76.94’, ’73.57’, ’78.10’, ’93.87’, 8 - [’94.19’, ’93.86’, ’95.78’, ’98.81’, 6 - [’69.39’, ’60.78’, ’70.92’, ’73.53’, 7 - [’61.99’, ’43.20’, ’52.06’, ’69.19’, 9 - [’92.51’, ’89.13’, ’98.05’, ’88.49’, 4 - [’98.86’, ’98.03’, ’97.00’, ’96.23’, ’83.63’, ’69.94’, ’62.71’, ’93.11’, ’69.36’, ’77.42’, ’89.02’, ’61.52’, ’43.50’, ’90.23’, ’95.51’, ’75.56’, ’58.67’, ’78.01’, ’99.58’, ’69.34’, ’77.98’, ’95.88’, ’65.46’, ’40.67’, ’98.76’, ’94.10’, ’85.59’] ’62.22’] ’67.90’] ’95.22’] ’61.86’] ’78.65’] ’94.59’] ’60.53’] ’43.60’] ’92.86’] ’96.62’] ’83.57’, ’76.97’, ’78.99’, ’93.66’, ’84.30’, ’86.87’, ’78.84’, ’95.24’, ’92.87’, ’80.45’, ’77.90’] ’76.20’] ’91.17’] ’88.87’] ’78.74’] Caso in figura (3.9) Caso in figura (3.10) Considering: TESTS/10numbers-0.jpg 0 - [’72.54’, ’79.74’, ’75.94’, ’77.64’, 4 - [’81.29’, ’71.81’, ’83.45’, ’70.23’, 2 - [’96.37’, ’88.23’, ’93.95’, ’95.67’, 5 - [’87.85’, ’71.40’, ’90.95’, ’96.46’, 4 - [’80.91’, ’79.53’, ’71.48’, ’80.63’, Not recognized - may be: | 3 | 6 | 5 | 34 Figura 3.11: Test scrittura, 7 non riconosciuto Figura 3.12: Test scrittura, 7 non riconosciuto - [’46.81’, ’49.75’, Not recognized - may be: | - [’61.51’, ’58.42’, 7 - [’80.48’, ’79.64’, Not recognized - may be: | 4 | 7 | - [’47.02’, ’60.24’, Not recognized - may be: | - [’73.57’, ’85.32’, ’46.72’, ’49.32’, ’64.59’, ’62.27’, ’49.97’] ’66.60’, ’66.91’, ’76.75’, ’71.17’, ’58.74’] ’71.37’, ’86.86’, ’75.23’, ’79.16’, ’77.58’] ’54.86’, ’36.08’, ’55.70’, ’49.58’, ’45.62’] ’74.96’, ’89.25’, ’78.44’, ’84.19’, ’71.31’] Caso in figura (3.11) Considering: TESTS/10numbers-1.jpg 0 - [’90.19’, ’92.30’, ’85.03’, ’98.03’, 1 - [’65.51’, ’84.94’, ’85.65’, ’78.67’, 2 - [’80.67’, ’83.51’, ’63.94’, ’84.81’, 3 - [’86.43’, ’58.46’, ’72.18’, ’73.97’, 4 - [’97.29’, ’93.15’, ’91.27’, ’97.30’, 5 - [’54.70’, ’42.27’, ’61.78’, ’45.36’, 6 - [’94.97’, ’93.36’, ’84.75’, ’99.59’, Not recognized - may be: | 2 | 7 | 3 | 5 | 9 | - [’43.17’, ’52.15’, ’34.86’, ’37.15’, 8 - [’83.07’, ’95.18’, ’93.64’, ’92.66’, 9 - [’95.12’, ’99.26’, ’97.37’, ’93.72’, ’91.04’, ’57.44’, ’81.95’, ’72.33’, ’95.40’, ’77.68’, ’88.26’, ’94.24’, ’86.25’, ’72.64’, ’72.92’, ’90.94’, ’70.10’, ’96.42’, ’91.80’] ’76.18’] ’74.62’] ’70.36’] ’94.22’] ’53.70’] ’92.89’] ’46.44’, ’41.92’, ’31.93’] ’95.78’, ’85.10’, ’90.91’] ’95.64’, ’101.1’, ’97.04’] In questo caso sul 7 c’erano molti output positivi sparsi per l’array di output. Caso in figura (3.12) Considering: TESTS/10numbers-2.jpg 35 Figura 3.13: Test scrittura, 1,2,5,7 non riconosciuti 0 - [’89.29’, ’89.78’, ’82.45’, 1 - [’72.70’, ’75.61’, ’82.01’, 2 - [’93.11’, ’74.95’, ’71.32’, 3 - [’89.30’, ’95.74’, ’97.15’, 4 - [’98.22’, ’93.57’, ’98.21’, 5 - [’67.02’, ’48.08’, ’63.79’, 6 - [’99.01’, ’91.44’, ’91.70’, Not recognized - may be: | 2 | 7 | 1 | 3 | - [’39.89’, ’50.97’, ’39.95’, 8 - [’86.57’, ’101.5’, ’94.36’, 9 - [’92.30’, ’99.14’, ’91.76’, ’96.94’, ’79.00’, ’87.55’, ’95.89’, ’97.87’, ’55.57’, ’97.67’, ’89.53’, ’75.41’, ’90.08’, ’94.57’, ’97.68’, ’77.01’, ’90.72’, ’95.32’, ’92.68’, ’77.56’, ’98.96’, ’98.60’, ’80.05’, ’91.04’, ’90.55’] ’78.83’] ’80.15’] ’95.27’] ’97.36’] ’61.68’] ’93.60’] ’36.85’, ’39.39’, ’36.08’, ’33.00’] ’93.01’, ’88.11’, ’92.98’, ’92.76’] ’93.08’, ’92.12’, ’97.72’, ’94.35’] Caso in figura (3.13) Considering: TESTS/10numbers-3.jpg Not recognized - may be: | - [’76.24’, ’77.05’, ’80.67’, ’85.01’, Not recognized - may be: | - [’90.99’, ’88.47’, ’86.63’, ’81.72’, 2 - [’91.73’, ’87.88’, ’85.91’, ’90.14’, 3 - [’97.80’, ’78.18’, ’85.21’, ’97.47’, 4 - [’92.52’, ’87.61’, ’84.46’, ’95.66’, Not recognized - may be: | 3 | 5 | - [’70.72’, ’57.22’, ’55.45’, ’60.22’, 6 - [’86.55’, ’83.40’, ’77.99’, ’83.16’, Not recognized - may be: | 2 | 4 | 7 | 1 | 3 | - [’43.37’, ’49.01’, ’39.74’, ’33.72’, 8 - [’81.69’, ’79.79’, ’76.54’, ’89.17’, 9 - [’82.56’, ’85.25’, ’86.65’, ’73.52’, ’64.74’, ’70.83’, ’71.33’] ’79.12’, ’79.64’, ’89.71’, ’91.30’, ’81.37’, ’83.40’, ’85.55’, ’88.63’, ’81.74’] ’86.45’] ’88.83’] ’90.03’] ’53.86’, ’64.52’, ’47.97’] ’80.58’, ’74.18’, ’80.15’] ’38.10’, ’37.76’, ’34.46’] ’83.84’, ’73.38’, ’77.90’] ’82.36’, ’85.03’, ’82.46’] 36 Figura 3.14: Test scrittura manuale correttamente riconosciuto Riconoscimento di caratteri Proviamo adesso a riconoscere dei caratteri scritti a mano e tipografici utilizzando una composizione di quattro reti addestrate su 1872 campioni, 72 per ogni lettere dell’alfabeto. (vedi fig. 3.2). Caso in figura (3.14) L’esecuzione delle reti riporta: Considering: TESTS/letters/m1.jpg A - [’96.51’, ’99.97’, ’97.32’, ’94.26’, B - [’102.2’, ’97.92’, ’99.42’, ’92.56’, C - [’72.48’, ’86.73’, ’69.93’, ’77.39’, D - [’93.95’, ’96.91’, ’98.89’, ’84.75’, E - [’84.34’, ’86.33’, ’79.25’, ’92.64’, F - [’96.72’, ’94.68’, ’95.32’, ’93.06’, G - [’94.05’, ’93.34’, ’95.71’, ’96.34’, H - [’98.33’, ’97.65’, ’98.36’, ’98.79’, I - [’85.45’, ’84.83’, ’91.03’, ’83.16’, J - [’79.69’, ’80.66’, ’85.26’, ’72.80’, K - [’93.35’, ’90.68’, ’95.06’, ’92.76’, L - [’99.43’, ’100.1’, ’98.45’, ’99.35’, M - [’93.07’, ’89.20’, ’92.52’, ’86.42’, N - [’95.19’, ’93.23’, ’98.59’, ’99.35’, O - [’95.30’, ’95.08’, ’95.74’, ’94.71’, P - [’89.97’, ’94.05’, ’93.15’, ’92.93’, Q - [’98.71’, ’99.21’, ’97.50’, ’97.67’, R - [’77.36’, ’83.27’, ’82.42’, ’68.93’, S - [’82.35’, ’89.41’, ’94.49’, ’88.33’, T - [’97.09’, ’95.51’, ’94.47’, ’96.93’, U - [’97.25’, ’94.48’, ’99.89’, ’98.46’, V - [’96.89’, ’98.90’, ’95.64’, ’96.94’, W - [’93.97’, ’91.60’, ’94.88’, ’93.28’, X - [’92.84’, ’95.65’, ’94.02’, ’90.72’, Y - [’88.11’, ’79.89’, ’84.35’, ’91.39’, Z - [’84.53’, ’96.45’, ’97.08’, ’95.41’, ’97.02’] ’98.03’] ’76.24’] ’93.62’] ’84.96’] ’94.94’] ’94.86’] ’98.28’] ’86.11’] ’78.37’] ’92.96’] ’99.33’] ’89.91’] ’96.59’] ’95.21’] ’92.52’] ’98.27’] ’77.30’] ’88.65’] ’96.00’] ’97.52’] ’97.09’] ’93.37’] ’93.31’] ’85.55’] ’93.37’] 37 Figura 3.15: Test scrittura manuale correttamente riconosciuto Caso in figura (3.15) L’esecuzione delle reti riporta: Considering: TESTS/letters/m2.jpg A - [’97.09’, ’98.99’, ’99.15’, ’96.62’, B - [’94.76’, ’92.86’, ’90.33’, ’85.83’, C - [’92.03’, ’94.14’, ’95.24’, ’94.46’, D - [’99.08’, ’96.43’, ’101.3’, ’99.29’, E - [’99.76’, ’100.1’, ’100.2’, ’100.0’, F - [’98.11’, ’91.68’, ’94.38’, ’92.84’, G - [’92.04’, ’85.22’, ’91.31’, ’89.56’, H - [’94.85’, ’92.77’, ’94.37’, ’86.14’, I - [’65.48’, ’67.36’, ’68.46’, ’63.22’, J - [’78.72’, ’87.81’, ’88.80’, ’83.49’, K - [’94.19’, ’93.30’, ’90.80’, ’97.44’, L - [’98.87’, ’98.98’, ’96.92’, ’96.48’, M - [’82.65’, ’85.77’, ’92.31’, ’85.53’, N - [’99.77’, ’97.93’, ’97.43’, ’97.57’, O - [’87.74’, ’88.84’, ’93.26’, ’85.78’, P - [’97.08’, ’98.46’, ’97.92’, ’100.1’, Q - [’89.51’, ’90.17’, ’87.86’, ’92.59’, R - [’95.49’, ’94.37’, ’93.97’, ’92.05’, S - [’92.55’, ’93.44’, ’97.45’, ’97.72’, T - [’96.26’, ’95.84’, ’92.86’, ’97.43’, U - [’93.38’, ’92.52’, ’98.05’, ’94.98’, V - [’93.15’, ’93.30’, ’90.36’, ’91.99’, W - [’95.02’, ’95.51’, ’97.37’, ’93.26’, X - [’94.53’, ’96.24’, ’94.80’, ’92.85’, Y - [’98.08’, ’97.49’, ’97.64’, ’98.81’, Z - [’76.75’, ’81.10’, ’87.13’, ’86.93’, Caso in figura (3.16) L’esecuzione delle reti riporta: Considering: TESTS/letters/a1.jpg ’97.97’] ’90.65’] ’93.97’] ’99.03’] ’100.0’] ’93.53’] ’89.53’] ’92.03’] ’65.99’] ’84.62’] ’93.93’] ’97.81’] ’86.03’] ’98.17’] ’88.44’] ’98.41’] ’90.03’] ’93.97’] ’95.29’] ’95.60’] ’94.27’] ’92.20’] ’95.27’] ’94.61’] ’98.01’] ’82.98’] 38 Figura 3.16: Test B,E,F,H,I,K,M,N,T,U,V,Z scrittura tipografica, non A - [’80.91’, ’88.35’, ’88.91’, ’72.70’, ’82.64’] Not recognized - may be: | B | H | - [’39.12’, ’54.72’, ’61.45’, ’39.40’, ’37.96’] C - [’95.53’, ’96.25’, ’95.87’, ’97.98’, ’96.41’] D - [’35.05’, ’35.94’, ’63.06’, ’49.56’, ’37.93’] Not recognized - may be: | D | S | B | J | A | X | R | C | P | N | Y | M | H | L | K | Z | V | E | G | T | O | F - [’79.87’, ’83.31’, ’82.53’, ’80.43’, ’81.52’] Not recognized - may be: | D | S | B | J | A | X | R | C | P | N | Y | M | H | L | K | Z | V | E | G | T - [’61.79’, ’79.19’, ’75.68’, ’66.52’, ’69.73’] G - [’99.33’, ’96.97’, ’97.28’, ’99.84’, ’98.35’] Not recognized - may be: | J | W | Y | H | O | - [’43.13’, ’41.28’, ’49.24’, ’37.70’, ’34.71’] Not recognized - may be: | I | D | S | B | J | A | X | R | C | P | W | Q | Y | M | H | L | K | Z | V | E - [’87.04’, ’86.25’, ’88.10’, ’91.42’, ’88.20’] J - [’71.90’, ’65.74’, ’62.09’, ’53.83’, ’63.15’] Not recognized - may be: | I | A | X | C | U | M | H | L | K | V - [’47.37’, ’34.51’, ’54.45’, ’42.72’, ’32.48’] L - [’90.35’, ’86.94’, ’82.22’, ’87.98’, ’86.87’] Not recognized - may be: | I | D | S | X | R | C | P | U | Y | M - [’37.55’, ’50.56’, ’54.08’, ’41.30’, ’36.06’] Not recognized - may be: | X | N | L | - [’56.23’, ’36.54’, ’54.12’, ’42.36’, ’40.50’] O - [’98.56’, ’99.22’, ’97.55’, ’98.65’, ’98.50’] P - [’55.36’, ’51.47’, ’58.24’, ’63.97’, ’54.54’] Q - [’93.63’, ’96.47’, ’95.34’, ’91.06’, ’94.13’] riconosciuti | U | W | Q | | U | W | Q | O | F | | N | U | G | T | O | F | | F | | L | K | V | E | T | F | 39 Figura 3.17: Test scrittura tipografica, non riconosciuti B,E,F,H,I,M,Q,T,V,W,Y R - [’65.98’, ’58.03’, ’58.47’, ’63.02’, ’57.95’] S - [’93.58’, ’97.69’, ’97.39’, ’97.35’, ’96.50’] Not recognized - may be: | I | S | B | J | A | X | R | C | P | U | M | L | K | Z | V | E | G | T | O | F - [’65.21’, ’48.03’, ’71.81’, ’46.06’, ’54.20’] Not recognized - may be: | U | L | - [’54.97’, ’53.70’, ’67.55’, ’61.19’, ’57.69’] Not recognized - may be: | U | V | - [’70.47’, ’80.94’, ’61.20’, ’75.36’, ’71.36’] W - [’79.94’, ’83.29’, ’78.25’, ’70.06’, ’77.37’] X - [’88.73’, ’87.74’, ’85.77’, ’90.89’, ’88.28’] Y - [’88.38’, ’88.05’, ’88.70’, ’91.29’, ’89.11’] Not recognized - may be: | I | D | S | B | J | A | X | R | C | P | H | L | K | Z | V | E | G | T | O | F - [’57.39’, ’55.80’, ’67.01’, ’45.34’, ’54.10’] Caso in figura (3.17) L’esecuzione delle reti riporta: Considering: TESTS/letters/a2.jpg A - [’66.43’, ’72.35’, ’68.74’, ’74.47’, ’70.31’] Not recognized - may be: | - [’71.22’, ’78.14’, ’82.00’, ’67.37’, ’73.74’] C - [’91.27’, ’91.00’, ’95.56’, ’94.18’, ’93.01’] D - [’80.93’, ’82.73’, ’80.48’, ’82.98’, ’80.94’] Not recognized - may be: | H | F | - [’47.74’, ’66.73’, ’59.29’, ’57.62’, ’49.90’] Not recognized - may be: | H | F | - [’46.79’, ’47.87’, ’54.22’, ’49.47’, ’41.78’] | W | Q | Y | | W | Y | M | 40 G - [’95.95’, ’95.81’, ’96.93’, ’96.90’, ’96.40’] H - [’75.59’, ’89.28’, ’85.17’, ’64.98’, ’77.96’] Not recognized - may be: | I | S | B | J | A | X | R | C | P | W | Y | M | Z | V | E | G | T | F | - [’37.49’, ’38.27’, ’53.58’, ’38.69’, ’33.60’] J - [’64.90’, ’59.28’, ’67.65’, ’70.12’, ’63.02’] K - [’80.19’, ’76.30’, ’69.95’, ’78.27’, ’75.16’] L - [’82.39’, ’79.16’, ’77.35’, ’87.43’, ’81.58’] Not recognized - may be: | M | H | - [’77.32’, ’80.43’, ’83.77’, ’69.40’, ’76.79’] N - [’78.10’, ’86.21’, ’85.88’, ’67.79’, ’79.41’] O - [’95.74’, ’84.16’, ’88.69’, ’94.00’, ’90.55’] P - [’83.10’, ’74.66’, ’83.23’, ’81.29’, ’80.57’] Not recognized - may be: | - [’84.00’, ’86.57’, ’83.49’, ’84.47’, ’83.73’] R - [’82.02’, ’84.75’, ’85.15’, ’80.90’, ’82.92’] S - [’94.42’, ’95.64’, ’98.94’, ’98.46’, ’96.86’] Not recognized - may be: | I | D | S | B | J | A | X | R | C | P | U | W | Y | M | H | L | K | Z | V | E | G | T | O | F | - [’66.14’, ’74.22’, ’71.51’, ’57.23’, ’66.04’] U - [’76.42’, ’70.77’, ’78.25’, ’64.54’, ’72.16’] Not recognized - may be: | V | F | - [’64.55’, ’58.96’, ’52.59’, ’60.78’, ’55.35’] Not recognized - may be: | - [’80.31’, ’84.27’, ’85.47’, ’83.54’, ’83.30’] X - [’69.51’, ’83.18’, ’74.61’, ’83.47’, ’77.41’] Not recognized - may be: | Y | F | - [’57.52’, ’58.46’, ’48.31’, ’62.26’, ’53.63’] Z - [’36.73’, ’44.80’, ’42.21’, ’55.09’, ’37.54’] Stringhe miste SPOCR ha anche quattro reti addestrate alla discriminazione tra lettere e numeri, che consentono di indirizzare l’immagine verso il giusto insieme di reti per il riconosci- 41 Figura 3.18: Test caratteri misti Figura 3.19: Test caratteri misti mento. Caso in figura (3.18) L’esecuzione delle reti riporta: Considering: TESTS/mixed/mixed1.jpg Not recognized - may be: | - [’76.05’, ’78.95’, ’79.86’, ’83.47’, ’76.87’, ’68.05’, ’73.08’] 3 - [’93.12’, ’85.48’, ’92.67’, ’82.14’, ’74.31’, ’86.60’, ’85.72’] H - [’96.42’, ’97.18’, ’96.60’, ’96.11’, ’96.57’] 5 - [’88.69’, ’99.85’, ’94.28’, ’92.32’, ’97.34’, ’90.14’, ’93.77’] N - [’99.83’, ’96.79’, ’96.93’, ’96.57’, ’97.53’] 1 - [’94.78’, ’91.74’, ’99.31’, ’92.69’, ’96.44’, ’97.55’, ’95.42’] P - [’90.17’, ’87.26’, ’92.47’, ’93.62’, ’90.88’] K - [’94.05’, ’92.91’, ’92.55’, ’95.38’, ’93.72’] 2 - [’80.01’, ’73.67’, ’81.59’, ’75.10’, ’88.44’, ’80.39’, ’78.45’] F - [’93.92’, ’89.28’, ’89.61’, ’92.30’, ’91.28’] Z - [’68.62’, ’81.89’, ’80.08’, ’79.89’, ’77.11’] 9 - [’101.9’, ’99.93’, ’100.1’, ’98.24’, ’99.22’, ’100.4’, ’99.98’] Caso in figura (3.19) L’esecuzione delle reti riporta: Considering: TESTS/mixed/mixed2.jpg 3 - [’67.80’, ’82.11’, ’79.37’, ’76.79’, L - [’98.35’, ’96.21’, ’92.43’, ’98.07’, 1 - [’96.44’, ’95.37’, ’95.28’, ’96.75’, 7 - [’97.47’, ’97.99’, ’94.61’, ’97.26’, E - [’95.40’, ’89.11’, ’88.70’, ’89.27’, ’55.34’, ’63.35’, ’69.03’] ’96.26’] ’94.81’, ’99.07’, ’96.29’] ’93.09’, ’97.34’, ’96.29’] ’89.92’] 42 Figura 3.20: Test caratteri misti G 6 P K R 5 S - [’93.83’, [’85.43’, [’89.24’, [’94.78’, [’94.08’, [’71.51’, [’84.88’, ’90.05’, ’99.61’, ’97.14’, ’93.18’, ’94.76’, ’76.57’, ’88.09’, ’91.05’, ’91.90’, ’98.16’, ’96.62’, ’96.71’, ’86.51’, ’89.91’, ’88.68’, ’94.99’, ’98.19’, ’90.36’, ’81.12’, ’74.93’, ’75.84’, ’90.82’] ’98.07’, ’97.37’, ’94.56’] ’95.68’] ’93.70’] ’91.42’] ’91.70’, ’84.45’, ’80.95’] ’83.85’] Caso in figura (3.20) L’esecuzione delle reti riporta: Considering: TESTS/mixed/mixed3.jpg P - [’75.61’, ’88.36’, ’81.79’, ’92.77’, Y - [’96.21’, ’94.60’, ’93.63’, ’95.93’, A - [’91.21’, ’95.29’, ’90.30’, ’80.48’, N - [’96.46’, ’97.95’, ’99.03’, ’96.61’, N - [’97.39’, ’96.83’, ’95.44’, ’94.58’, O - [’92.20’, ’95.24’, ’96.26’, ’99.98’, C - [’91.94’, ’92.05’, ’92.04’, ’85.24’, R - [’91.97’, ’94.15’, ’86.56’, ’90.12’, 4 - [’97.13’, ’96.62’, ’91.60’, ’94.14’, L - [’98.28’, ’98.34’, ’95.73’, ’99.53’, 7 - [’95.70’, ’93.64’, ’96.83’, ’97.95’, 5 - [’69.65’, ’74.45’, ’86.76’, ’73.84’, 8 - [’89.37’, ’98.53’, ’87.21’, ’91.90’, ’84.64’] ’95.09’] ’89.32’] ’97.51’] ’96.06’] ’95.85’] ’90.32’] ’90.70’] ’96.41’, ’97.97’] ’95.81’, ’87.60’, ’77.05’, ’94.69’, ’95.10’] ’97.94’, ’96.31’] ’78.08’, ’78.40’] ’94.42’, ’88.84’] ELENCO DELLE FIGURE 2.1 2.2 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.20 Numero medio di iterazioni di learning rate. . . . . . . . . . Comportamento al variare del momento. . . . . . . . . . . apprendimento richieste al variare del . . . . . . . . . . . . . . . . . . . . . learning rate per alcuni coefficienti di . . . . . . . . . . . . . . . . . . . . . Font usati per il training sui numeri . . . . . . . . . . . . . . . . . . Font usati per il training sulle lettere . . . . . . . . . . . . . . . . . Test scrittura correttamente riconosciuto . . . . . . . . . . . . . . . Test scrittura correttamente riconosciuto . . . . . . . . . . . . . . . Test scrittura correttamente riconosciuto . . . . . . . . . . . . . . . Test scrittura correttamente riconosciuto . . . . . . . . . . . . . . . Test scrittura, 9 non riconosciuto ma unica alternativa . . . . . . . . Test scrittura correttamente riconosciuto . . . . . . . . . . . . . . . Test scrittura correttamente riconosciuto . . . . . . . . . . . . . . . Test scrittura, 5,6,8,9 non riconosciuti . . . . . . . . . . . . . . . . Test scrittura, 7 non riconosciuto . . . . . . . . . . . . . . . . . . . Test scrittura, 7 non riconosciuto . . . . . . . . . . . . . . . . . . . Test scrittura, 1,2,5,7 non riconosciuti . . . . . . . . . . . . . . . . Test scrittura manuale correttamente riconosciuto . . . . . . . . . . Test scrittura manuale correttamente riconosciuto . . . . . . . . . . Test scrittura tipografica, non riconosciuti B,E,F,H,I,K,M,N,T,U,V,Z Test scrittura tipografica, non riconosciuti B,E,F,H,I,M,Q,T,V,W,Y . Test caratteri misti . . . . . . . . . . . . . . . . . . . . . . . . . . . Test caratteri misti . . . . . . . . . . . . . . . . . . . . . . . . . . . Test caratteri misti . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 20 22 27 29 30 31 31 32 32 32 33 33 34 34 35 36 37 38 39 41 41 42 44 ELENCO DELLE TABELLE 2.1 2.2 2.3 Learning rate 0.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . Learning rate 0.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . Learning rate 0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 19 3.1 3.2 3.3 Dimensioni delle reti messe a confronto . . . . . . . . . . . . . . . . Test sugli stessi campioni per diverse dimensioni delle reti . . . . . . Test su sei reti di dimensione 400 × 60 × 45 × 30 × 20 . . . . . . . 25 25 26 45