Implementazione in Java di plugin Maven per algoritmi di addestramento per reti neurali artificiali
Upcoming SlideShare
Loading in...5
×
 

Implementazione in Java di plugin Maven per algoritmi di addestramento per reti neurali artificiali

on

  • 196 views

L’idea del progetto di questa tesi è applicare all’addestramento di reti neurali artificiali le funzionalità di uno strumento di gestione di progetti software, in questo caso Maven, per rendere ...

L’idea del progetto di questa tesi è applicare all’addestramento di reti neurali artificiali le funzionalità di uno strumento di gestione di progetti software, in questo caso Maven, per rendere configurabili e componibili in modo dichiarativo, e possibilmente estendibili, sia l’algoritmo di addestramento che le componenti di supporto, come la persistenza della rete neurale e la gestione dei dati dell’insieme di addestramento. Tale idea è nata dall’analogia tra progetti software e addestramento di reti neurali artificiali. Prima dell’introduzione di strumenti di gestione, ciascun progetto software possedeva una propria organizzazione del processo di compilazione, test, deploy, di versionamento e di gestione delle dipendenze. Maven introduce un’interfaccia comune ed un insieme di convenzioni che, oltre a rendere portabile il progetto, ne semplifica il processo di build. Le reti neurali vengono costruite e addestrate usando strumenti di calcolo matematico o scrivendo un eseguibile che utilizzi una libreria dedicata. Il codice per l’addestramento è sviluppato per lo specifico problema, talvolta scartato una volta terminato il suo compito. Nonostante l’addestramento di reti neurali non sia deterministico come un processo di compilazione, ma adotti una serie di tecniche ed euristiche per trovare soluzioni non ottime, sono state cercate delle caratteristiche comuni ai due processi. Si vuole quindi introdurre Maven per definire un prototipo di interfaccia comune all’addestramento di reti neurali artificiali, tenendo conto delle problematiche di questo tipo di processo. Il meccanismo sviluppato per consentire configurabilità e componibilità delle componenti introduce il concetto di servizi: tipologie di oggetti a ciascuna delle quali è associata una factory col compito di configurare le istanze create. Nella configurazione da iniettare attraverso una factory sono tenuti distinti i puri dati, come parametri numerici o stringhe, e servizi collaboratori dotati di comportamento. Attraverso questa distinzione è possibile rappresentare in formato puramente testuale la gerarchia di composizione di un qualunque servizio. Le responsabilità del gestore di progetti sono importare le factory da librerie dichiarate come dipendenze, costruire i servizi in base alla struttura gerarchica specificata nel descrittore di progetto ed utilizzarli per effettuare l’addestramento.

Statistics

Views

Total Views
196
Views on SlideShare
196
Embed Views
0

Actions

Likes
0
Downloads
4
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Implementazione in Java di plugin Maven per algoritmi di addestramento per reti neurali artificiali Implementazione in Java di plugin Maven per algoritmi di addestramento per reti neurali artificiali Document Transcript

  • Universit`a degli Studi di Trieste Facolt`a di Ingegneria Dipartimento di Elettrotecnica, Elettronica ed Informatica Corso di Laurea in Ingegneria dell’Informazione – curriculum Informatica Tesi di Laurea in Sistemi Operativi IMPLEMENTAZIONE IN JAVA DI PLUGIN MAVEN PER ALGORITMI DI ADDESTRAMENTO PER RETI NEURALI ARTIFICIALI Laureando: Relatore: Francesco Komauli Prof. Ing. Enzo Mumolo Anno Accademico 2012-2013
  • Indice 1 Introduzione 5 1.1 Obiettivi della tesi . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2 Organizzazione della tesi . . . . . . . . . . . . . . . . . . . . . . . 6 1.3 Strumenti utilizzati . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.4 Codice sorgente del progetto . . . . . . . . . . . . . . . . . . . . . 7 2 Maven 8 2.1 Modello concettuale di progetto . . . . . . . . . . . . . . . . . . . 8 2.1.1 Dependency management . . . . . . . . . . . . . . . . . . 8 2.1.2 Repository remote . . . . . . . . . . . . . . . . . . . . . . 8 2.1.3 Portabilit`a . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2 Convention over Configuration . . . . . . . . . . . . . . . . . . . 9 2.3 Estensione del framework . . . . . . . . . . . . . . . . . . . . . . 9 3 Multilayer perceptron 11 3.1 Il modello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.2 Addestramento . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.2.1 Batch back propagation . . . . . . . . . . . . . . . . . . . 13 3.2.2 Parametrizzazione dell’algoritmo . . . . . . . . . . . . . . 14 3.3 Generalizzazione . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4 Plugin Maven per multilayer perceptron 16 4.1 Layout di un progetto . . . . . . . . . . . . . . . . . . . . . . . . 16 4.2 Addestramento . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.3 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.4 Rappresentazione di multilayer perceptron . . . . . . . . . . . . . 19 4.4.1 Funzioni di attivazione . . . . . . . . . . . . . . . . . . . . 19 4.4.2 Neuroni . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.4.3 Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.4.4 Multilayer perceptron . . . . . . . . . . . . . . . . . . . . 20 5 Servizi 22 5.1 Motivazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.2 Identificazione e configurazione . . . . . . . . . . . . . . . . . . . 22 5.3 Descrizione gerarchica . . . . . . . . . . . . . . . . . . . . . . . . 23 5.4 Generazione di servizi . . . . . . . . . . . . . . . . . . . . . . . . 23 5.5 Definizione di servizi . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.6 Pubblicazione delle factory . . . . . . . . . . . . . . . . . . . . . 25 5.6.1 Recupero delle configurazioni dal classpath . . . . . . . . 25 5.6.2 Recupero delle librerie . . . . . . . . . . . . . . . . . . . . 26 5.7 Organizzazione delle dipendenze per il plugin Maven per multi- layer perceptron . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 6 Risultati sperimentali 28 6.1 Dominio di apprendimento . . . . . . . . . . . . . . . . . . . . . . 28 6.2 Scelta della funzione d’errore . . . . . . . . . . . . . . . . . . . . 28 6.3 Topologia del multilayer perceptron . . . . . . . . . . . . . . . . 30 6.4 Risultati dell’addestramento . . . . . . . . . . . . . . . . . . . . . 30 3
  • 7 Modelli di Markov nascosti (HMM) 33 7.1 Introduzione ai processi stocastici . . . . . . . . . . . . . . . . . . 33 7.2 I tre problemi principali degli HMM . . . . . . . . . . . . . . . . 36 7.2.1 Il primo problema . . . . . . . . . . . . . . . . . . . . . . 36 7.2.2 Il secondo problema . . . . . . . . . . . . . . . . . . . . . 37 7.2.3 Il terzo problema . . . . . . . . . . . . . . . . . . . . . . . 37 7.3 Risultati sperimentali . . . . . . . . . . . . . . . . . . . . . . . . 38 8 Volterra vs. NN 40 9 Conclusioni 44 9.1 Risultati ottenuti . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 9.2 Vantaggi dovuti all’uso di Maven . . . . . . . . . . . . . . . . . . 44 9.3 Sviluppi futuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 A Esempio di progetto per multilayer perceptron: xor 47 B Implementazione dell’algoritmo di back-propagation 51 B.1 Fase feedforward . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 B.2 Fase di back propagation . . . . . . . . . . . . . . . . . . . . . . . 52 B.3 Aggiornamento dei pesi . . . . . . . . . . . . . . . . . . . . . . . 53 4
  • Ringraziamenti Desidero ringraziare la mia famiglia per il sostegno datomi in questi mesi di duro lavoro. Ringrazio il professor Enzo Mumolo per avermi dato l’opportunit`a di approfondire un argomento interessante come le reti neurali artificiali. Vorrei ringraziare i miei amici per essermi stati sempre accanto ed avermi consigliato. Infine ringrazio i miei colleghi senza i quali non avrei sviluppato un approccio critico all’architettura e al design del software. 5
  • 1 Introduzione L’idea del progetto di questa tesi `e applicare all’addestramento di reti neurali artificiali le funzionalit`a di uno strumento di gestione di progetti software, in questo caso Maven, per rendere configurabili e componibili in modo dichiarativo, e possibilmente estendibili, sia l’algoritmo di addestramento che le componen- ti di supporto, come la persistenza della rete neurale e la gestione dei dati dell’insieme di addestramento. Tale idea `e nata dall’analogia tra progetti software e addestramento di re- ti neurali artificiali. Prima dell’introduzione di strumenti di gestione, ciascun progetto software possedeva una propria organizzazione del processo di compi- lazione, test, deploy, di versionamento e di gestione delle dipendenze. Maven introduce un’interfaccia comune ed un insieme di convenzioni che, oltre a rendere portabile il progetto, ne semplifica il processo di build. Le reti neurali vengono costruite e addestrate usando strumenti di calcolo matematico o scrivendo un eseguibile che utilizzi una libreria dedicata. Il codice per l’addestramento `e sviluppato per lo specifico problema, talvolta scartato una volta terminato il suo compito. Nonostante l’addestramento di reti neurali non sia deterministico come un processo di compilazione, ma adotti una serie di tecniche ed euristiche per trovare soluzioni non ottime, sono state cercate delle caratteristiche comuni ai due processi. Si vuole quindi introdurre Maven per definire un prototipo di interfaccia comune all’addestramento di reti neurali artificiali, tenendo conto delle proble- matiche di questo tipo di processo. Il meccanismo sviluppato per consentire configurabilit`a e componibilit`a delle componenti introduce il concetto di servizi: tipologie di oggetti a ciascuna delle quali `e associata una factory col compito di configurare le istanze create. Nel- la configurazione da iniettare attraverso una factory sono tenuti distinti i puri dati, come parametri numerici o stringhe, e servizi collaboratori dotati di com- portamento. Attraverso questa distinzione `e possibile rappresentare in formato puramente testuale la gerarchia di composizioe di un qualunque servizio. Le responsabilit`a del gestore di progetti sono importare le factory da li- brerie dichiarate come dipendenze, costruire i servizi in base alla struttura gerarchica specificata nel descrittore di progetto ed utilizzarli per effettuare l’addestramento. Il progetto `e inserito nel contesto di un esperimento che vede confrontate tra loro tre tipologie di classificatori: Multilayer Perceptron, Hidden Markov Model e Serie di Volterra. Nello specifico caso del riconoscimento di lettere pronunciate dell’alfabeto inglese, vengono analizzate le diverse capacit`a di generalizzazione di ciascun modello. 1.1 Obiettivi della tesi L’obiettivo principale della tesi `e fornire un’implementazione di plugin Maven per ciascuna tipologia di classificatori. Ciascun plugin deve poter compiere l’addestramento di classificatori, sviluppato in modo tale da rendere ogni com- ponente configurabile e componibile, con un livello di dettaglio che consenta di affrontare problemi specifici come quello particolare del riconoscimento di lette- re pronunciate. Allo stesso tempo si cerca di minimizzare la quantit`a di codice dedicata esclusivamente alla sua risoluzione. 6
  • Si intende quindi fare uso dei plugin sviluppati per confrontare le capacit`a di generalizzazione delle tipologie di classificatori sopra menzionati. 1.2 Organizzazione della tesi Nella Sezione 2 viene descritto cosa sia Maven, quale sia il suo funzionamento ed i vantaggi che ha portato alla gestione di progetti software grazie all’introduzione di un modello di progetto. La Sezione 3 introduce il modello teorico del multilayer perceptron. Inoltre viene presentato uno degli algoritmi adatti al suo addestramento, quello di batch back propagation. La sezione 4 presenta il plugin Maven per multilayer perceptron, descrivendo le fasi di addestramento e test e fornendo esempi sul suo utilizzo, tra cui come strutturare la configurazione e come rappresentare un multilayer perceptron. Il meccanismo dei servizi che sta alla base del funzionamento del plugin `e presentato nella Sezione 5. Viene spiegato come i servizi possano essere utilizzati programmaticamente, in che modo ne vengano definiti di nuovi e come renderli disponibili attraverso i repository Maven. Nella Sezione 6 viene descritto come il plugin sia stato utilizzato per l’ad- destramento di un multilayer perceptron il cui compito `e classificare le lettere pronunciate dell’alfabeto inglese. Sono dati i parametri della rete neurale e del- l’algoritmo di back propagation, e una descrizione del preprocessamento degli esempi. Per l’addestramento `e stata impiegata una particolare funzione d’errore adatta al tipo di problema, detta classification figure of merit. Infine vengono presentati i risultati ottenuti. La sezione 7 introduce il modello di Hidden Markov Model, esponendo quali siano le problematiche collegate al suo utilizzo per la classificazione di segnali ed i relativi algoritmi, tra cui l’algoritmo di Baum-Welch per l’addestramento di un HMM. Sono poi esposti i risultati ottenuti per il riconoscimento di lettere pronunciate dell’alfabeto inglese. Nella sezione 8 vengono presentate le Serie di Volterra, il cui modello pu`o essere dedotto da quello delle reti neurali attraverso un’approssimazione poli- nomiale delle non-linearit`a che contraddistinguono i neuroni artificiali. Sono dati inoltre alcuni risultati preliminari dell’applicazione di serie volterriane al problema di classificazione di lettere pronunciate dell’alfabeto inglese. Per ultima, la Sezione 9 contiene le conclusioni relative al progetto di questa tesi ed i risultati ottenuti. Inoltre `e data una lista degli sviluppi che non si sono potuti avviare o portare a termine, o che si sono delineati come deduzioni dal lavoro svolto. Nell’appendice `e presentato un’esempio completo di utilizzo del plugin Ma- ven per multilayer perceptron (Appendice A) e una descrizione dell’implemen- tazione dell’algoritmo di batch back propagation (Appendice B). 1.3 Strumenti utilizzati Una parte del software, riguardante Hidden Markov Model e Serie di Volterra, `e stata sviluppata nel linguaggio C. Il software che si occupa del preprocessamento dei file di esempio `e stato implementato in C, ed in Java quello che converte i ri- sultati del preprocessamento in formato json. Il plugin per multilayer perceptron `e invece scritto interamente in Java 1.7. 7
  • Oltre all’ambiente di build Maven, descritto nella Sezione 2, `e stato utiliz- zato lo strumento di continuous integration Jenkins1 . Si tratta di una webapp generalmente impiegata per effettuare build automatizzate, che richiede il sup- porto di un servlet container per la sua esecuzione. Nel caso di questa tesi `e stato utilizzato il server Tomcat2 . Tra le varie funzionalit`a vi `e la possibilit`a di memorizzare le ultime build effettuate, per poter confrontare i risultati e generare reportistica. Le build possono essere avviate manualmente, venir temporizzate o lanciate in risposta a degli eventi, come l’aggiornamento di una repository attraverso un sistema di version control. Oltre ad ospitare il progetto del plugin in Java, Jenkins `e stato configurato per l’addestramento di multilayer perceptron attraverso il suo interfacciamento con Maven. 1.4 Codice sorgente del progetto Il progetto `e suddiviso in due repository, versionato con il sistema di controllo di versione Mercurial3 , ed i suoi sorgenti sono ospitati sul sito BitBucket: Genesis : https://bitbucket.org/0xdeadc0de/genesis/ libreria contenente le difinizioni di servizio e factory, e l’implementazione di application context che li gestisce; Seshat : https://bitbucket.org/0xdeadc0de/seshat/ definizioni delle interfacce dei servizi per mulilayer perceptron, plugin Maven e implementazioni di servizi basilari per il suo funzionamento. 1 Jenkins CI: http://jenkins-ci.org/ 2 Apache Tomcat: http://tomcat.apache.org/ 3 Mercurial SCM: http://mercurial.selenic.com/ 8
  • 2 Maven Una definizione formale di Maven4 `e che si tratta di uno strumento di gestione di progetti, il quale provvede un insieme di standard, un lifecycle di progetto, un meccanismo di gestione delle dipendenze, e la logica per eseguire goal di plugin in determinate fasi di un lifecycle. Non si tratta quindi di uno strumento di build incentrato solo su compilazione e distribuzione del codice, ma fornisce un soprainsieme di funzionalit`a. 2.1 Modello concettuale di progetto Un progetto in generale consiste in codice sorgente e un insieme di risorse. Maven consente di aggiungere al progetto una descrizione, come nome, licenza e informazioni sugli sviluppatori. Ma le informazioni pi`u importanti sono le coordinate che lo identificano: groupId : famiglia di progetti, data ad esempio dal nome dell’azienda o associazione; artifactId : identificativo del progetto, solitamente una versione codificata del nome; version : numero di versione che pu`o essere di tipo stabile (release), men- tre per le versioni ancora in fase di sviluppo viene aggiunto il suffisso -SNAPSHOT; packaging : `e la tipologia di artefatto, inteso come risultato prodotto dalla compilazione, e definisce un proprio insieme di goal in determinate fasi del lifecycle; di default `e jar e altri packaging integrati in Maven sono war, ear e pom. La definizione di un modello per i progetti consente di implementare funzio- nalit`a aggiuntive rispetto a un sistema unicamente dedicato alla build. 2.1.1 Dependency management Poich´e ciascun progetto `e univocamente identificato da groupId, artifactId e version, si possoo usare queste coordinate per dichiarare dipendenze. 2.1.2 Repository remote Sfruttando lo stesso meccanismo delle dipendenze, si possono usare le coordi- nate dei progetti per creare repository di artefatti. Maven gestisce gli artefatti attraverso un repository locale e uno o pi`u repository remoti. Tutte gli artefatti dichiarati come dipendenze vengono installati nel repository locale, e inclusi nel classpath al momento dell’esecuzione di un plugin. Esiste un repository principale di riferimento: il Central Maven Reposito- ry5 . Qui sono pubblicati tuti gli artefatti che passano i criteri di accettazione necessari ad ottenere uno spazio. Quando vi sia la necessit`a di condividere delle librerie ma senza dover depo- sitarle sul repository centrale, come nel caso di aziende, dipartimenti o gruppi 4 Apache Maven: https://maven.apache.org/ 5 The Central Repository. http://search.maven.org/ 9
  • di sviluppo, `e possibile gestire un repository personalizzato attraverso la we- bapp Nexus6 . Questo servizio si interpone tra i repository locali degli utenti e quello centrale, arricchendo la collezione di librerie con quelle sviluppate dal gruppo. I repository personalizzati possono essere resi pubblici, e aggiungendoli alla configurazione della propria installazione di Maven vengono inclusi durante la ricerca di librerie. 2.1.3 Portabilit`a Maven definisce un’interfaccia comune a ciascun progetto, permettendo di com- pilare un clone di progetto di terze parti semplicemente attraverso il comando mvn install. Inoltre non `e pi`u necessario per gli IDE definire un proprio sistema di metadati per il progetto, in quanto attraverso il Project Object Model (POM) dispongono di una sorgente di informazioni comune. 2.2 Convention over Configuration Maven adotta il paradigma Convention over Configuration. Secondo i suoi det- tami, un sistema deve poter funzionare senza richiedere parametri non stretta- mente necessari, assumendo per questi dei valori di default. Senza customizza- zione, Maven assume che il codice sorgente sia in ${basedir}/src/main/java/ e quello di test in ${basedir}/src/main/test/ mentre la tipologia di artefatto sia jar. I risultati della build vengono infine posti nel path ${basedir}/target/ L’adozione del paradigma Convention over Configuration non si limita alla definizione di directory per il progetto. I plugin fondamentali applicano un insieme di convenzioni per la compilazione dei sorgenti, per la distribuzione degli artefatti, per la generazione della documentazione e per molti altri processi. Quando si seguono le convenzioni si ha il vantaggio di dover fornire a Maven una configuraziuone minima, mentre nel caso sia necessario modificare un certo comportamento `e possibile modificare i parametri di default. 2.3 Estensione del framework Il nucleo di Maven comprende solo alcune funzionalit`a di base, come il parsing di xml ed esecuzione di un lifecycle. Infatti il suo design prevede che la maggior parte delle responsabilit`a siano delegate a un insieme di plugin Maven, che interagiscono con il lifecycle e forniscono dei goal da poter collegarvi. I plugin sono a loro volta dei progetti Maven, e sono installabili in un repository allo stesso modo degli altri artefatti. Un goal di un plugin rappresenta uno specifico task che contribuisce alla build o alla gestione di un progetto Maven. In Maven `e possibile definire dei lifecycle aventi una nuova lista di fasi. I goal vengono eseguiti durante la fase a 6 Nexus: http://www.sonatype.org/nexus/ 10
  • cui sono stati assegnati, imponendo l’ordine con cui le fasi sono state dichiarate nel rispettivo lifecycle. 11
  • 3 Multilayer perceptron Questa sezione introduce i multilayer perceptron, una tra le tipologie di reti neurali artificiali pi`u comunemente usate. Viene presentato inoltre l’algoritmo di addestramento back propagation, nella sua variante batch. 3.1 Il modello I multilayer perceptron sono formati da unit`a chiamate neuroni, interconnesse tra loro da collegamenti sinaptici, a ciascuna delle quali viene associato un peso. Il livello di attivazione di una sinapsi `e determinato moltiplicando il valore di output del neurone sorgente per il peso. Ogni unit`a effettua la somma dei propri input, rappresentanti i livelli di attivaione delle sinapsi in ingresso, a cui viene aggiunto un eventuale termine costante detto bias. La somma complessiva viene mappata da una funzione non lineare denomina- ta funzione di attivazione, il cui risultato rappresenta l’output del neurone. Due tra le funzioni di attivazione pi`u comunemente usate sono la funzione logistica (Figura 1) e la tangente iperbolica (Figura 2). Figura 1: funzione logistica 1 1+e−x Figura 2: tangente iperbolica ex −e−x ex+e−x 12
  • Detti w = (w1, . . . , ws) i pesi delle sinapsi e b il bias, il vettore in ingresso x = (x1, . . . , xs) viene mappato dal neurone nel valore di output y attraverso y = f( b + s i=1 xiwi ) (1) I multilayer perceptron sono organizzati in layer, composti da neuroni che ottengono i propri input unicamente dai neuroni del layer precedente, cos`ı come i propri output sono usati solo da quelli del layer successivo. Figura 3: multilayer perceptron formato da due layer, uno nascosto e quello di output; all’interno dei neuroni, rappresentati come cerchi, avviene la som- ma degli input pesati dalle sinapsi e la mappatura attraverso la funzione di attivazione, come specificato dall’Equazione 1 L’operazione effettuata da un multilayer perceptron `e la mappatura di un vettore di dimensione pari al layer di input in un vettore composto dai valori di output dei neuroni dell’ultimo layer. I segnali vengono mappati attraverso ciascun layer per attivare le sinapsi di quello successivo. Il comportamento di un multilayer perceptron, ovvero la trasformazione ef- fettuata sui vettori in ingresso, dipende dai pesi delle sinapsi e dai bias dei singoli neuroni. `E attraverso la variazione di questi pesi che un multilayer perceptron viene addestrato a svolgere una determinata operazione. 3.2 Addestramento L’addestramento di un multilayer perceptron avviene applicando un vettore in ingresso e confrontando il vettore prodotto in uscita con uno desiderato. Ta- le metodo `e detto di apprendimento supervisionato in quanto sono note delle coppie di segnali di input e output desiderato (xk, dk), di cui si vuole che ven- ga riprodotta la corrispondenza da parte del multilayer perceptron addestra- to. La differenza tra output effettivo ok e desiderato dk fornisce l’errore di riconoscimento: ek = ok − dk (2) Tale errore viene mappato attraverso una funzione d’errore o di costo, che fornisce una misura scalare dello scostamento della rete neurale dal suo com- portamento ideale. Una funzione spesso usata `e l’errore quadratico Ek = ek 2 2 (3) ma altre funzioni possono essere impiegate in base al tipo di problema di rico- noscimento da risolvere, dove l’errore quadratico non sia la miglior misura della 13
  • deviazione dal comportamento ideale. Ek = C(ek) (4) La funzione di costo C dovrebbe essere scelta in modo che rappresenti pi`u verosimilmente le relative importanze degli errori nel contesto in cui la rete neu- rale viene applicata. In generale una funzione di errore ha un minimo assoluto per e = 0. Considerando l’intero insieme di esempi per l’addestramento, lo scostamento della rete neurale dal comportamento ideale si misura attraverso la somma dei singoli errori: E = k Ek (5) Dato un inseme di esempi per l’addestramento e fissata la struttura del multilayer perceptron, l’errore `e funzione dei soli pesi. Una tra le procedure pi`u semplici per la minimizzazione dell’errore E(w) `e il metodo del gradiente: consiste nell’iterare passi, nello spazio dei pesi, proporzionali all’opposto del gradiente della funzione da ottimizzare. I pesi sono aggiornati ad ogni passo con w = w − η · E(w) (6) dove per semplicit`a w indica il vettore contenente tutti i pesi della rete. Se l’er- rore presenta una debole regolarit`a e il parametro η `e sufficientemente piccolo, le iterazioni convergono verso un minimo locale di E. Il parametro η `e noto come learning rate. In questo metodo la parte critica risulta essere il calcolo delle componenti del gradiente ∂E/∂wi. Per le reti neurali feedforward, ed in particolare per i multilayer perceptron, questo calcolo assume una forma semplice. 3.2.1 Batch back propagation L’algoritmo consiste nella costruzione di una rete neurale detta rete di back propagation, richiedendo per`o che le funzioni di attivazione e la funzione d’errore siano differenziabili. Detto wij il peso della sinapsi in ingresso nel neurone i e proveniente dal neurone j, e definendo il livello di attivazione di un neurone come la somma di bias e degli input pesati si = bi + j xjwij (7) tale rete ha le componenti non lineari dell’originale sostituite da guadagni co- stanti gi = fi (si) (8) dove fi `e la derivata della funzione di attivazione associata al neurone i. Inol- tre la struttura viene trasposta invertendo la direzione delle sinapsi e delle diramazioni, sostituendo i nodi di somma in divergenze e viceversa. La singola iterazione dell’algoritmo prevede quindi di applicare alla rete di back propagation i valori ∂Ek/∂oi e calcolare gli output dei neuroni con ¯yi = gi · j ¯xjwji (9) 14
  • Le componenti del gradiente dei pesi posono essere ottenuti attraverso la seguente regola: ∂Ek ∂wij = yi ¯yj (10) Per l’equazione (5) le componenti del gradiente sono date dalla somma delle componenti valutate per ogni singolo esempio, con ∂E ∂wij = k ∂Ek ∂wij (11) Questi valori vengono quindi usati per aggiornare i valori dei pesi come evidenziato nell’equazione (6). L’attributo batch dell’algoritmo sta proprio a significare che prima di effettuare l’aggiornamento dei pesi vengono valutati gli errori, e quindi i gradienti, di tutti gli esempi dell’insieme di addestramento. 3.2.2 Parametrizzazione dell’algoritmo L’algoritmo di back propagation converge per un learning rate η al di sotto di un certo valore ηmax. Tale massimo dipende dalla rete neurale, dall’insie- me di esempi e dalla funzione di costo, e non pu`o essere determinato a priori. Diminuendo il valore di η al di sotto di ηmax la velocit`a di convergenza pu`o ral- lentare notevolente, rendendo la scelta del learning rate uno degli aspetti critici dell’addestramento di una rete neurale. Inoltre la superficie dell’errore pu`o presentare delle brusche variazioni, nelle quali l’uso di un learning rate elevato porterebbe a oscillazioni divergenti intorno a queste aree. Una delle soluzioni adottate `e l’utilizzo di learning rate ηij distinti per ogni peso, adattati ad ogni iterazione dell’algoritmo in base ai segni di due gradienti successivi. Un’altra tecnica simula l’inerzia dello spostamento lungo la superficie del- l’errore, accumulando le direzioni dei gradienti precedenti. Aggiungendo un termine accumulatore all’equazione (6) si ottiene wn+1 = wn − ( η · E(wn) + α · ∆wn−1 ) (12) Il termine 0 ≤ α < 1 consente di aumentare la velocit`a lungo discese ripide evitando movimenti oscillatori. Tuttavia quando troppa inerzia venisse accumu- lata, lo spostamento successivo porterebbe ad uscire dall’intorno di un minimo locale raggiunto. 3.3 Generalizzazione Nell’addestramento di una rete neurale artificiale, spesso l’insieme di esempi rappresenta un sottoinsieme relativamente piccolo dei possibili input che la rete dovr`a riconoscere. Una volta addestrata deve essere in grado di classificare pattern non presenti nell’insieme di addestramento. La condizione ideale per l’addestramento sarebbe minimizzare la funzione di costo calcolata su tutti gli elementi dell’universo degli input, ma ci`o risulta impossibile per universi infiniti o non del tutto noti, o per un costo computazionale troppo elevato. Per questo l’insieme di addestramento andrebbe selezionato in modo da rappresentare tutte le caratteristiche dell’universo degli input. 15
  • Una rete neurale che riconosca correttamente gli elementi dell’universo come quelli dell’insieme di addestramento ha ottenuto la capacit`a di generalizzare la propria classificazione. Per valutare l’entit`a del livello di generalizzazione viene utilizzato un insieme di esempi disgiunto da quello di addestramento, detto insieme di test. Si ha cos`ı modo di valutare la generalizzazione della rete neurale e adattare di conseguenza la struttura della rete o l’insieme di addestramento. 16
  • 4 Plugin Maven per multilayer perceptron In seguito `e presentato il funzionamento del plugin, assieme a una configurazione di progetto di multilayer perceptron d’esempio. Sono definiti due goal: il primo per l’addestramento del multilayer percep- tron, il secondo per verificarne la capacit`a di generalizzazione. 4.1 Layout di un progetto Il plugin definisce una nuova tipologia di progetto: multilayer-perceptron Su un progetto avente questo tipo, Maven esegue i goal definiti dal plugin in- vece che quelli standard del lifecycle di default, cos`ı da effettuare l’addestra- mento della rete neurale e, dopo aver terminato, testare le sue capacit`a di generalizzazione. Per abilitarne l’esecuzione, il plugin va dichiarato nella sezione riguardante la build all’interno del descrittore di progetto pom.xml. Oltre alle sue coordi- nate Maven, sono fondamentali la sua configurazione e le dipendenze a tempo di esecuzione che gli vengono attribuite. La dichiarazione di dipendenze per il plugin `e il meccanismo con cui altre librerie vengono aggiunte al classpath e rese disponibili durante la sua esecuzione, lasciando a Maven il compito di recuperarle automaticamente, da remoto se necessario. Listing 1: dichiarazione del plugin per multilayer perceptron nel pom; le esten- sioni del plugin sono abilitate per permettere l’override del lifecycle Maven con il packaging multilayer-perceptron 1 <project> 2 ... 3 <packaging>multilayer-perceptron</packaging> 4 <build> 5 <plugins> 6 <plugin> 7 <groupId>dev.deadc0de.seshat</groupId> 8 <artifactId>multilayer-perceptron-maven-plugin</artifactId> 9 <version>0.2</version> 10 <extensions>true</extensions> 11 <configuration> 12 <!-- configurazione del plugin --> 13 </configuration> 14 <dependencies> 15 <!-- dipendenze da aggiungere durante l’esecuzione --> 16 </dependencies> 17 </plugin> 18 </plugins> 19 </build> 20 </project> Oltre alla configurazione del plugin, nel progetto vanno inseriti file contenenti le strutture dati con cui operare. Si tratta di fornire i descrittori dei multilayer perceptron che si vogliono addestrare e gli esempi da utilizzare durante le fasi di addestramento e di test. La disposizione di tali file segue la convenzione7 di layout di un progetto Maven: i file contenenti il codice dell’applicativo vanno collocati, a partire dalla root del progetto, nella cartella src/main/source-type/ 7 I parametri sono modificabili, tuttavia si incoraggia a mantenere la configurazione predefinita come vuole il paradigma Convention over Configuration. 17
  • Project root pom.xml src main examples examples-set-1.json examples-set-2.json multilayer-perceptron network-a.json network-b.json network-c.json test examples examples-set-3.json examples-set-4.json examples-set-5.json Figura 4: possibile disposizione dei file all’interno di un progetto di multilayer perceptron; nell’esempio il loro contenuto `e interpretato come json in quanto il marshaller di default del plugin fa uso di tale formato mentre per i test in src/test/source-type/ La cartella da cui il plugin recupera i descrittori per le reti neurali da addestrare `e multilayer-perceptron, mentre gli esempi sono cercati in examples, sia nell’albero main che in quello di test. Un esempio di disposizio- ne dei file in un progetto per multilayer perceptron `e rappresentato in Figura 4. 4.2 Addestramento Il primo dei due goal definiti dal plugin `e train. Il suo compito `e caricare la struttura del multilayer perceptron e gli esempi per fornirli all’algoritmo di addestramento, dopodich´e persistere la nuova struttura con i pesi modificati. La configurazione del goal di addestramento viene letta dal pom a partire dal tag <trainingMethod>. Qui vengono specificati il tipo di algoritmo da utilizzare, i suoi parametri e i collaboratori. 18
  • Listing 2: configurazione del servizio di training in cui vengono specificati tipo e parametri dell’algoritmo e quali collaboratori utilizzare; tra questi la funzione d’errore e il logger 1 <configuration> 2 <trainingMethod> 3 <name>batchBackPropagation</name> 4 <configuration> 5 <learningRate>0.001</learningRate> 6 <momentum>0.5</momentum> 7 <tolerance>0.1</tolerance> 8 <maximumIterations>1000</maximumIterations> 9 </configuration> 10 <collaborators> 11 <collaborator> 12 <role>errorFunction</role> 13 <name>meanSquaredError</name> 14 </collaborator> 15 <collaborator> 16 <role>logger</role> 17 <name>maven</name> 18 </collaborator> 19 </collaborators> 20 </trainingMethod> 21 ... 22 </configuration> 4.3 Test Il secondo goal test carica un multilayer perceptron addestrato precedente- mente da target/multilayer-perceptron/ e un insieme di esempi per valutarne il livello di generalizzazione raggiunto dalla rete neurale. Di ogni esempio viene calcolato l’output e confrontato con quello atteso: il test passa se l’errore, calcolato con una funzione impostata, non supera una certa soglia prestabilita. Al termine viene dato un resoconto del numero di test passati e falliti. Nonostante vi siano similitudini con i test unitari, la fase di test per un mul- tilayer perceptron non prevede il fallimento della build in quanto generalmente ci si aspetta un certo numero di esempi non riconosciuti. Allo stesso modo del goal di addestramento, quello di test recupera dal pom la propria configurazione a partire dal tag <test>. Listing 3: configurazione del servizio di test con specificati la sua tipologia e il logger da utilizzare 1 <configuration> 2 ... 3 <test> 4 <name>errorFunctio</name> 5 <configuration> 6 <tolerance>0.1</tolerance> 7 </configuration> 8 <collaborators> 9 <collaborator> 10 <role>errorFunction</role> 11 <name>meanSquaredError</name> 12 </collaborator> 13 <collaborator> 14 <role>logger</role> 15 <name>maven</name> 16 </collaborator> 17 </collaborators> 18 </test> 19 </configuration> 19
  • 4.4 Rappresentazione di multilayer perceptron Per descrivere un’istanza di multilayer perceptron `e stata definita una struttura dati versatile capace di rappresentare le informazioni con il massimo livello di dettaglio ed avere un formato conciso nel caso pi`u generico. Ad esempio `e possibile definire una funzione di attivazione diversa per ogni neurone, oppure specificarne una sola per tutta la rete neurale, o ancora applicare certe funzioni di attivazione solo ad alcuni neuroni mentre ai rimanenti viene assegnata quella globale. 4.4.1 Funzioni di attivazione L’entit`a base della struttura `e il servizio generico, inteso come funzione di attivazione o come collaboratore. Un servizio `e definito da tre parametri: name Il nome del servizio rappresentato come stringa. configuration Una mappa di stringhe contenente i parametri che costituiscono i dati del servizio. Pu`o non essere specificata se non vi sono parametri o se il servizio prevede dei valori predefiniti. collaborators Una mappa che associa ricorsivamente altri oggetti di questo a dei ruoli, come per la configurazione pu`o essere omessa. Listing 4: definizione di una tangente iperbolica traslata nel tempo di 1 1 { 2 "name": "shift", 3 "configuration": { 4 "shift": "1.0" 5 }, 6 "collaborators": { 7 "inner": { 8 "name": "tanh" 9 } 10 } 11 } 4.4.2 Neuroni Il componente fondamentale di un multilayer perceptron `e il neurone, definito attraverso i parametri: function Entit`a di tipo servizio che rappresenta la funzione di attivazione del neu- rone. Se non specificata verr`a fatto riferimento ad una funzione definita a un livello superiore. bias Livello di attivazione intrinseco del neurone che si somma alle sollecitazioni dalle sinapsi, nullo se non specificato. 20
  • weights Lista di pesi delle sinapsi che collegano il neurone a quelli del layer pre- cedente. Se specificati la lunghezza della lista deve corrispondere con la dimensione del layer precedente, mentre se omessi sono considerati nulli. 4.4.3 Layer I neuroni sono aggregati in layer, la dimensione dei quali `e definita come il numero di neuroni contenuti. Il formato di un layer presenta due alternative: contenere le definizioni di ciascun neurone oppure specificare solo la propria dimensione. Nel secondo caso tutti i pesi dei neuroni sono considerati nulli e la funzione di attivazione `e quella globale. L’entit`a che definisce un layer `e composta dai parametri: function Funzione di attivazione globale da usare come default per tutti i neuroni contenuti nel layer. neurons Una lista contenente le entit`a dei neuroni che vanno a comporre il layer. size Specifica direttamente il numero di neuroni contenuti, attribuendogli pesi nulli e funzione di attivazione globale. Se specificato assieme alla lista di neuroni del punto precedente, il parametro viene ignorato in favore di quello contenente maggiori dettagli. 4.4.4 Multilayer perceptron Infine l’entit`a di pi`u alto livello `e il multilayer perceptron. Anche qui vi sono due formati alternativi: uno consente di specificare ciascun layer mentre l’altro permette di indicare unicamente le loro dimensioni. L’entit`a espone i seguenti parametri: function Funzione di attivazione globale da usare dove n´e il neurone n´e il layer che lo contiene ne abbiano specificata una. sources Numero di neuroni in ingresso, adibiti a ricevere la propria ativazione da sorgenti esterne. Interpreta il ruolo dell’input layer, anche se i suoi neuroni non possiedono una funzione di attivazione. layers Lista di layer che costituiscono il multilayer perceptron. Tutti i neuroni di un layer devono avere, dove specificate, un numero di sinapsi pari alla dimensione del layer precedente, o del numero di sorgenti se si tratta del primo layer. La dimensione dell’ultimo layer definisce la dimensione dell’output del multilayer perceptron. sizes Lista di dimensioni che i layer devono avere, i cui neuroni hanno pesi nulli e funzione di attivazione globale. Se specificato assieme alla lista di 21
  • layer del punto precedente, il parametro viene ignorato in favore di quello contenente maggiori dettagli. In seguito `e riportato un documento json contenente un multilayer percep- tron descritto usando la forma estesa della struttura dati, specificando i dettagli di tutti i neuroni che lo compongono. Listing 5: multilayer perceptron addestrato per riconoscere la funzione booleana xor 1 { 2 "sources": 2, 3 "layers": [ 4 { 5 "neurons": [ 6 { 7 "function": { "name": "tanh" }, 8 "bias": -1.1656643239012312, 9 "weights": [0.8590827611395182, 0.8583199921043884] 10 }, { 11 "function": { "name": "tanh" }, 12 "bias": -0.4244875431029639, 13 "weights": [1.7354223753836655, 1.7325046953575243] 14 } 15 ] 16 }, { 17 "neurons": [ 18 { 19 "function": { "name": "tanh" }, 20 "bias": -0.6540816448579929, 21 "weights": [-1.730661310571226, 1.6476378061166113] 22 } 23 ] 24 } 25 ] 26 } Quando interessa definire unicamente le dimensioni della rete neurale, ad esempio per indicare la struttura della rete da addestrare, `e possibile utilizzare la forma contratta. Listing 6: multilayer perceptron formato da un hidden layer ed un output layer avente come funzione di attivazione per tutti i suoi neuroni la tangente iperbolica 1 { 2 "function": { "name": "tanh" }, 3 "sources": 2, 4 "sizes": [2, 1] 5 } 22
  • 5 Servizi I componenti fondamentali su cui si appoggia l’architettura del plugin Maven per multilayer perceptron sono i servizi. Essi rappresentano singole unit`a funzionali configurabili e componibili tra loro. In questo capitolo `e mostrato il modo in cui vengono istanziati programmaticamente e come definire nuovi servizi. Per evitare che librerie di reti neurali artificiali dipendano dal plugin nel- l’esporre i propri oggetti come servizi, quest’ultimi non devono implementare o estendere alcun componente del framework. In questo modo per`o ottenere informazioni sulle loro caratteristiche e renderli utilizzabili `e possibile solo at- traverso la costruzione di un layer che faccia da collante tra i servizi e il plugin. Le definizioni dei servizi sono quindi delegate a factory che si occupano di attri- buire loro un nome, un tipo, un insieme di parametri e dei ruoli di collaboratori da cui un servizio dipende. 5.1 Motivazioni Esistono gi`a librerie e framework che si occupano dell’inizializzazione di applica- tion context, in cui gli oggetti di un’applicazione vengono composti in maniera dichiarativa attraverso dependency injection e resi disponibili al suo avvio. Il pi`u famoso tra quelli in ambiente Java `e il framework Spring8 . Nelle prime fasi del progetto, Spring `e stato utilizzato per la creazione e composizione dei servizi, ma la configurazione del progetto risultava prolissa, complicata e troppo legata all’effettiva implementazione dei servizi. Era inoltre impossibile definire dei collaboratori di default. Come passaggio successivo sono state introdotte le factory, ma non `e sta- to trovato un modo che permettesse al meccanismo di generazione di essere configurato in maniera semplice. Infine si `e optato per l’implementazione di una libreria dedicata al partico- lare problema di inizializzazione di oggetti avente come obiettivi la minimizza- zione della configurazione, da fornire all’application context per la generazione di un servizio, e la semplicit`a di definizione delle factory, attraverso un mecca- nismo dichiarativo di dependency injection e la possibilit`a di definire parametri e collaboratori di default. 5.2 Identificazione e configurazione Il tipo associato ad un servizio rappresenta la categoria a cui appartiene ed `e definito come il tipo restituito dalla sua factory. Pu`o quindi essere un’interfaccia che la classe del servizio implementa, una superclasse o la classe stessa. Per distinguere servizi dello stesso tipo, ad ognuno di essi `e attribuito un nome. Un servizio viene quindi univocamente identificato dal suo nome e dal suo tipo. Prima di poter essere utilizzato, il servizio potrebbe richiedere un’inizializ- zazione con argomenti i cui valori vadano a formare il suo stato. Tali argomen- ti possono essere puri dati, come numeri e stringhe, oppure oggetti dotati di comportamento le cui funzionalit`a sono usate dal servizio. I parametri sono i nomi attribuiti ai dati richiesti per l’inizializzazione, ed un insieme di associazioni parametro-valore va a formare la configurazione del ser- 8 Spring: http://spring.io/ 23
  • vizio. I collaboratori appartengono invece alla categoria di oggetti con compor- tamento, utilizzabili attraverso l’associazione di ciascuno con un ruolo. Questi oggetti sono a loro volta servizi. 5.3 Descrizione gerarchica La composizione di servizi forma una struttura gerarchica ad albero dove nei nodi si collocano nome, tipo e parametri, mentre i ruoli sono rappresentati dalle relazioni genitore-figlio. Come foglie vi sono istanze di servizi con un livello di astrazione sufficientemente basso da non richiedere collaboratori. Con questa disposizione risulta semplice trasporre la gerarchia in un documento puramente descrittivo. In seguito `e mostrato l’oggetto necessario ad una factory per istanziare e configurare il servizio. Listing 7: un descrittore di servizio contiene il suo nome oltre ad una sua configurazione e associazioni tra ruoli e altri descrittori di collaboratori 1 public class ServiceDescriptor { 2 3 public final String name; 4 public final Map<String, String> configuration; 5 public final Map<String, ServiceDescriptor> collaborators; 6 } L’informazione riguardante il tipo `e assente, poich´e `e la factory a determi- nare il tipo del servizio generato. Lo stesso vale per i tipi di eventuali colla- boratori: ottenendo dal descrittore unicamente il nome vengono completate le informazioni richieste per identificarli univocamente. 5.4 Generazione di servizi Il compito per una factory di un servizio `e generare un’istanza dello stesso a partire da un oggetto descrittivo, del tipo mostrato precedentemente. La definizione di factory prevede un unico metodo create che usa la descrizione fornita per istanziare un servizio. Listing 8: una factory di servizi ha un unico metodo il cui compito `e generare un’istanza a partire da un oggetto descrittore 1 public interface ServiceFactory<S> { 2 3 S create(ServiceDescriptor service); 4 } Oltre ad applicare una configurazione, la factory deve interagire con altre per richiedere la generazione dei collaboratori da iniettare nel servizio. Allo scopo di rendere implicita la richiesta di generare i collaboratori necessari ad altre factory, `e stato sviluppato un’application context che funga da intermediario aggregando in un unico oggetto la funzionalit`a di generazione dei servizi. Listing 9: application context che si occupa di generare servizi usando le factory 1 public interface Context { 2 3 <S> S generate(Class<S> serviceType, ServiceDescriptor service); 4 5 <S> Map<String, ServiceFactory<S>> load(Class<S> serviceType); 6 } 24
  • L’application context pu`o quindi generare un servizio a partire dal suo tipo e da un descrittore che ne descriva la composizione, Listing 10: esempio di generazione di un servizio attraverso l’application context 1 Context context = ... 2 3 Map<String, String> configuration = ... 4 Map<String, ServiceDescriptor> collaborators = ... 5 ServiceDescriptor trainingMethodDescriptor = new ServiceDescriptor( 6 "batchBackPropagation", 7 configuration, 8 collaborators 9 ); 10 11 MultilayerPerceptronTrainingMethod trainingMethod = context.generate( 12 MultilayerPerceptronTrainingMethod.class, 13 trainingMethodDescriptor 14 ); Ciascuna factory necessita per`o di un riferimento all’application context per poter generare collaboratori, e deve esporre il nome e il tipo del proprio servizio in modo da poter essere recuperata quando richiesta. `E stato quindi aggiunto un meccanismo di definizione delle factory attraverso una particolare scrittura di metodi all’interno di classi di configurazione, per ridurre l’interazione espli- cita tra factory nell’istanziazione dei collaboratori. La definizione di servizi attraverso questo metodo `e spiegata nella sezione successiva. 5.5 Definizione di servizi Attraverso la classe CofigurationContext, implementazione di application context, la definizione delle factory assume una forma del tipo dell’esempio dato nel listato sottostante. Listing 11: definizione di factory per funzioni di attivazione 1 public class ActivationFunctionConfiguration implements Configuration { 2 3 public ActivationFunction tanh() { 4 return new HyperbolicTangent(); 5 } 6 7 public ActivationFunction logistic() { 8 return new LogisticFunction(); 9 } 10 11 public ActivationFunction scale( 12 @Role("inner") ActivationFunction inner, 13 @Parameter("scale") 14 @Parser(ParseDouble.class) @Default("1.0") Double scale) { 15 return new Scale(inner, scale); 16 } 17 18 public ActivationFunction shift( 19 @Role("inner") ActivationFunction inner, 20 @Parameter("shift") 21 @Parser(ParseDouble.class) @Default("0.0") Double shift) { 22 return new Shift(inner, shift); 23 } 24 } Le factory cos`ı dichiarate sono interpretate nel seguente modo: • il tipo di servizio `e rappresentato dal tipo restituito dal metodo; • il nome corrisponde col nome del metodo; • gli argomenti annotati con @Parameter vengono mappati in base al nome specificato nell’annotazione; 25
  • • gli argomenti annotati con @Role vengono popolati con un collaboratore del tipo dell’argomento; • se un argomento ha come tipo Context, in questo viene passato l’appli- cation context nel quale si trova la factory. Inoltre `e possibile specificare un valore da utilizzare nel caso il parametro non sia presente nella configurazione attraverso l’annotazione @Default. Essendo i valori della configurazione unicamente stringhe, l’annotazione @Parser per- mette di convertire automaticamente la stringa in un oggetto specificando la classe con cui effettuare la trasformazione. Attraverso l’uso di annotazioni e definendo ciascuna factory come un singolo metodo risulta pi`u chiaro quale sia la sua parametrizzazione e pi`u semplice la sua implementazione, lasciando all’application context il compito di istanziare i suoi collaboratori. 5.6 Pubblicazione delle factory Uno dei punti di forza del plugin Maven per multilayer perceptron `e la mo- dularit`a dei servizi di cui pu`o disporre. In seguito viene brevemente spiegato come le factory di servizi possono essere rese disponibili al plugin durante la sua esecuzione. 5.6.1 Recupero delle configurazioni dal classpath Vi sono diversi modi per caricare classi dal classpath conoscendo solo alcune delle loro caratteristiche, come l’interfaccia implementata, un’annotazione o un particolare pattern cotenuto nel nome della classe. Il plugin in particolare fa uso della funzionalit`a fornita da ServiceLoader9 , appartenente a libreria standard Java. Per dichiarare dei servizi10 di un determinato tipo, si aggiunge nel percorso META-INF/services/ del jar un file che abbia per nome quello completo della classe in questione, comprensivo del package in cui `e contenuta. All’interno del file si possono specificare i nomi, sempre includendo il package di appartenenza, delle classi che implementano o estendono il suddetto tipo, con la restrizione che abbiano il costruttore vuoto. Utilizzando il metodo load di ServiceLoader, passando come parametro la classe del servizio, viene restituita la sequenza delle istanze di tutte le classi dichiarate all’interno del rispettivo file. Le classi sviluppate seguendo la convenzione di ConfigurationContext, delle quali ogni metodo viene trasformato in factory, non hanno per`o alcun elemento distintivo che le renda caricabili attraverso ServiceLoader. Nella libreria dei servizi `e stata definita appositamente l’interfaccia Configuration pensata per il ruolo di marker interface11 , da far implementare a tutte le classi di configurazione che definiscono al loro interno metodi per factory. Si possono cos`ı esporre al ServiceLoader le classi di configurazione che si intende esportare. 9 Per maggiori informazioni sul funzionamento di ServiceLoader si consulti la documentazione Java. http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html 10 In questo caso il termine servizi non si rifrisce a quelli delle sezioni precedenti, ma alle classi caricate attraverso ServiceLoader (in questo caso le factory). 11 Una marker interface `e un’interfaccia, solitamente priva di metodi, il cui scopo `e aggiun- gere metadati alla classe che la implementa. Il ruolo delle marker interface `e stato in seguito preso in carico dalle annotazioni, ma nella libreria standard sono ancora presenti. Ad esempio sono dei marker le interfacce Serializable e Cloenable. 26
  • Oltre a caricare tutte le implementazioni di Configuration, il plugin iniet- ta nel context di cui fa uso una sua classe di configurazione contenente factory strettamente correlate al suo funzioamento. Ad esempio `e presente come servizio un adapter per il logger di Maven. 5.6.2 Recupero delle librerie Alcune librerie di reti neurali artificali di terze parti si trovano gi`a in Maven Central. Prima che il plugin per multilayer perceptron raggiunga una maturit`a tale da poter essere caricato nel repository centrale, `e possibile eseguirlo instal- landolo localmente12 o su un repository Nexus. Lo stesso vale per le librerie di servizi. 5.7 Organizzazione delle dipendenze per il plugin Maven per multilayer perceptron Per disaccoppiare il plugin Maven dalle implementazioni di servizi, le interfacce e gli oggetti rappresentanti dati sono stati inseriti in librerie separate dall’artefatto del plugin. Inoltre sono stati divisi tra due librerie distinte, una per gli elementi riguardanti le definizioni generali di factory e servizi, l’altra contenente tipi specializzati per i multilayer perceptron. In questo modo viene resa disponibile l’astrazione dei servizi ad altre librerie e plugin per altre tipologie di reti neurali artificiali. Alle due librerie fanno riferimento anche tutti gli artefatti contenenti fac- tory. Questi possono contenere al loro interno le implementazioni dei servizi, come la libreria di built-in fornita col plugin per i servizi base, oppure essere di adattamento per librerie gi`a esistenti. Nel descrittore di progetto, tra le dipendenze del plugin `e sufficiente indicare l’artefatto contenente le factory, in quanto le dipendenze transitive sono risolte automaticamente da Maven. `E necessario per`o che tutte le dipendenze siano reperibili in almeno uno dei repository che si vanno ad utilizzare. 12 Clonando i sorgenti ed eseguendo il comando mvn install nella home del progetto. 27
  • multilayer perceptron services services multilayer perceptron maven plugin multilayer perceptron builtins Services and factories library Service adapters and factories Multilayer perceptron library Maven framework Maven components Interfaces declarations Library code Figura 5: grafo delle dipendenze che mostra come gli artefatti del plugin, dei servizi generali e di quelli per multilayer perceptron si pongono tra una libreria di reti neurali artificiali e framework Maven (le librerie sviluppate sono quelle evidenziate con doppio contorno) 28
  • 6 Risultati sperimentali In questa sezione `e riportato come sia stato eseguito l’addestramento di un multilayer perceptron per il riconoscimento di lettere prounciate dell’alfabeto inglese. La rete neurale classifica una lettera attivando maggiormente uno tra i suoi 26 nodi di output, secondo l’ordine alfabetico. I risultati ottenuti servono poi come riferimento per il paragone tra multilayer perceptron e le altre tipologie di reti utilizzate: Hidden Markov Model e serie di Volterra. 6.1 Dominio di apprendimento Gli esempi di lettere pronunciate sono divisi in un insieme di addestramento e uno di test. In quello di addestramento sono presenti per ogni lettera 10 pronunce effettuate dalla setssa persona. Sono presenti gli alfabeti pronunciati da 16 persone diverse, di cui 8 donne e 8 uomini, per un totale di 4.160 esempi. Nell’insieme di test vi sono le pronunce delle stesse persone, ma diverse da quelle dell’insieme di addestramento e in numero di 16, per un totale di 6.656 esempi. Alla rete neurale in questione non sono dati in input le ampiezze del segnale campionato rappresentante la pronuncia di una lettera, ma ciascun esempio viene preprocessato come segue. 1. In primo luogo la registrazione viene troncata in testa e in coda per rimuovere le parti che non comprendono il segnale d’interesse. 2. Per omogenizzare la dimensione dei segnali, questi vengono espansi o compressi per avere la durata di un secondo. 3. Come ultimo passaggio vengono estratti i coefficienti cepstrali di ciascun segnale, suddividendolo in 50 frame e prendendo 12 coefficienti per frame, per un totale di 600 coefficienti cepstrali per segnale. Il vettore contenente i 600 coefficienti cepstrali `e infine utilizzato come esem- pio per l’addestramento o per il test del multilayer perceptron, inserito all’in- terno del progetto in formato json. 6.2 Scelta della funzione d’errore In un articolo, A. Waibel introduce una funzione d’errore che pi`u si adatta al riconoscimento di un dato insieme di suoni rispettio alla classica funzione di errore MSE13 . Il MSE compara i livelli di attivazione dell’output della rete neurale con quelli di un insieme ideale di attivazioni per un dato stimolo in input. L’obiettivo in questo caso `e minimizzare ciascuna differenza per raggiungere la corrispodenza tra attivazioni dell’output e quelle ideali. La funzione introdotta, chiamata Classification Figure of Merit (CFM), usa invece le attivazioni ideali solo per identificare il nodo di output corrispondente con la classificazione corretta. La funzione CFM cerca quindi di massimizzare la differenza tra l’attivazione del nodo corretto e quelle di tutti gli altri nodi. 13 Errore quadratico medio, dall’Inglese Mean Squared Error. 29
  • La funzione CFM `e definita come CFM = 1 N − 1 · N n=1 n=c α 1 + e−(β∆n−γ) (13) dove • ∆n = Oc − On • Oc `e il livello di attivazione del nodo relativo alla corretta classificazione c (1 per a, 2 per b, ecc. . . ) • On `e il livello di attivazione del nodo n relativo ad una classificazione sbagliata • N `e il numero di classi (in questo caso le 26 lettere dell’alfabeto inglese) • α `e l’ampiezza della sigmoide • β `e la rapidit`a con cui la sigmoide cresce, detta anche discontinuit`a della sigmoide • γ `e il ritardo della sigmoide, che causa uno scostamento laterale del grafico verso destra quando positivo Le derivate parziali rispetto all’output, necessarie per il metodo di discesa del gradiente, sono date da ∂CFM ∂On = −αβ N − 1 · yn(1 − yn) (14) ∂CFM ∂Oc = αβ N − 1 · N n=1 n=c yn(1 − yn) (15) dove yn `e la sigmoide yn = 1 1 + e−(β∆n−γ) (16) Poich´e l’obiettivo della funzione CFM `e massimizzare la differenza tra livello di attivazione del nodo corretto e quelli dei restanti nodi, va utilizzata invertendo la variabile ∆n affinch´e porti a scendere anzich´e salire lungo il gradiente. La funzione CFM cos`ı definita `e monotona solo per N = 2, mentre per N ≥ 3 `e necessario applicare una modifica, ponendo CFMM = CFMn(min ∆n) (17) dove CFMn(∆) = α 1 + e−(β∆n−γ) (18) che rende la funzione monotona per output di dimensione maggiore di due, ma riduce la rapidit`a della ricerca del minimo in quanto produce un gradiente di magnitudine minore rispetto all’Equazione 13. 30
  • 6.3 Topologia del multilayer perceptron La dimensione dell’input layer `e quella corrispondente al numero di coefficienti cepstrali calcolati per ciascun esempio, ovvero 600. L’output layer contiene 26 nodi, ognuno associato ad una lettera dell’alfabeto inglese. Le quantit`a di hidden layer e le loro rispettive dimensioni sono state ottenute per prove successive, e i risultati di maggior generalizzazione sono stati ottenuti utilizzando un multilayer perceptron con due hidden layer rispettivamente di 140 e 80 neuroni. Listing 12: topologia finale del multilayer perceptron 1 { 2 "function":{"name":"tanh"}, 3 "sources":600, 4 "sizes":[140,80,26] 5 } Per l’addestramento `e stato usato l’algoritmo di batch back propagation, con i parametri contenuti nella seguente configurazione. Listing 13: parametrizzazione dell’addestramento 1 <configuration> 2 <trainingMethod> 3 <name>batchBackPropagation</name> 4 <configuration> 5 <learningRate>0.005</learningRate> 6 <tolerance>0.15</tolerance> 7 <momentum>0.5</momentum> 8 <maximumIterations>1000</maximumIterations> 9 </configuration> 10 <collaborators> 11 <collaborator> 12 <role>errorFunction</role> 13 <name>classificationFigureOfMerit</name> 14 </collaborator> 15 <collaborator> 16 <role>logger</role> 17 <name>maven</name> 18 </collaborator> 19 </collaborators> 20 </trainingMethod> 21 <test> 22 <name>maximumActivation</name> 23 <collaborators> 24 <collaborator> 25 <role>logger</role> 26 <name>maven</name> 27 </collaborator> 28 </collaborators> 29 </test> 30 </configuration> 6.4 Risultati dell’addestramento La funzione di test usata verifica quale sia il nodo col livello di attivazione pi`u alto, determinando un successo se `e quello associato alla lettera corretta. Il multilayer perceptron col quale si `e raggiunto il maggior numero di esempi riconosciuti ne ha classificati correttamente 4.525 su 6.586, circa il 68.72%.14 In seguito si riportano i dati per le singole lettere. 14 Il numero di esempi di test `e minore di quello riportato in precedenza in quanto alcuni file sono mancanti ed altri hanno causato errori nel processo di estrazione dei coefficienti cepstrali. 31
  • A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 % 10 % 20 % 30 % 40 % 50 % 60 % 70 % 80 % 90 % 100 % Percentualediclassificazionicorrette Nella Tabella 1 `e riportata invece la matrice di confusione di questa rete neurale. 32
  • ABCDEFGHIJKLMNOPQRSTUVWXYZ A176110101260534000100003023000 B38005323031001000022000141512000 C42215744079010001015000801100110 D0321713201120000010120002405220014 E070917709300000001200031030100 F000001930011170200212520021900 G25117210138605000301240029020008 H30400400196015000000061021300 I0000101024800000000100001030 J1100000105015950103001002024501 K4900001418138128001010032004400 L0000000010023840701000000000 M000000000301217060001210002000 N40000110010342186004230002010 O0000100030030024400000001000 P313014500910003002093302381121000 Q00201061000423012030322500000 R0000000070021000023900000040 S010102606002601350018270021000 T124210530341200201002320178065002 U00003050000032001900121900001 V126042120640000000170001001270008 W1000001211010010000013237010 X001001407007005000028000019400 Y0000000020000010020000002500 Z310685091001200011210011031100143 Tabella1:matricedicofusionechemostrailnumerodilettereclassificatedalmultilayerperceptroninbaseallaletterapronunciatadata ininput;lerigheindicanolaletteradiinputmentrelecolonnequellainoutput 33
  • 7 Modelli di Markov nascosti (HMM) Il metodo statistico maggiormente utilizzato per caratterizzare le propriet`a spet- trali dei segnali acustici, in particolare vocali, `e il modello di Markov nascosto (HMM, dall’inglese Hidden Markov Model). L’idea su cui si fonda l’uso di un sistema statistico, di questo o di altro tipo, `e che i segnali possano essere op- portunamente modellizzati da un processo parametrico casuale, i cui parametri possano essere stimati con una certa precisione. 7.1 Introduzione ai processi stocastici Per la classificazione di sorgenti sonore, mediante l’analisi di segnali divisi in blocchi, `e possibile utilizzare i processi stocastici tempo discreti. In quest’ambito il modello pi`u semplice `e rappresentato dai processi di Markov, da cui gli HMM derivano. Processi di Markov tempo discreti Si consideri un sistema descrivibile, ad ogni istante, con lo stato in cui si trova, ci siano N stati distinti {1, 2, . . . , N}. Ad istanti di tempo regolarmente spaziati, il sistema subisce un cambiamento di stato (ma pu`o esser preso in considerazione anche il caso che rimanga nello stesso) in accordo ad un insieme di probabilit`a associate allo stato di partenza. Gli istanti di tempo associati alle variazioni di stato possono essere indicati con t = 1, 2, . . . e lo stato attuale al tempo t con qt. Una descrizione probabilistica completa del sistema richiederebbe la specificazione dello stato corrente e di tutti quelli precedenti. Nel caso che questa descrizione possa venir troncata allo stato presente e ad un solo stato precedente, il sistema prende il nome di catena o processo di Markov discreto del primo ordine. In altri termini: P[qt = j|qt−1 = i, qt−2 = k, . . . ] = P[qt = j|qt−1 = i] (19) Inoltre considerando i soli processi dove il secondo membro dell’equazione 19 `e indipendente dal tempo, si arriva ad un insieme di probabilit`a di transizione di stato aij della forma: aij = P[qt = j|qt−1 = i] con 1 ≤ i, j ≤ N (20) e che soddisfano alle seguenti propriet`a: aij ≥ 0 ∀i, j e N j=1 aij = 1 ∀i (21) in quanto obbediscono alle costrizioni stocastiche standard. Il processo stoca- stico visto pu`o essere chiamato modello di Markov osservabile, in quanto la sua uscita coincide con lo stato al particolare istante di tempo, ed ogni stato cor- risponde ad un evento osservabile. In figura 6 viene riportato l’esempio di una catena di Markov a 4 stati. 34
  • 1 2 3 4 a11 a14 a41 a13 a33 a32a21 a22 Figura 6: Catena di Markov a 4 stati Modelli di Markov nascosti (HMM) Finora si sono considerati modelli di Markov nei quali ogni stato corrispon- deva ad un evento osservabile; questi processi risultano inadatti ai fini della modellizzazione di molti problemi di interesse pratico. Risulta quindi neces- sario estendere la trattazione per includere il caso nel quale l’osservazione `e una funzione probabilistica dello stato, cio`e il modello risultante `e un processo doppiamente stocastico. In questi casi vi sono due processi, uno visibile ed uno nascosto, che pu`o essere osservato solo attraverso un altro insieme di processi stocastici che producono la sequenza di osservazione. Esempio Un classico esempio usato per spiegare la definizione dei modelli di Markov nascosti `e il modello ad urne e palline. Ci siano N urne in una stanza, con- tenenti un grande numero di palline colorate, e siano M i colori distinti che le palline possono assumere. Si pu`o pensare che il processo fisico per ottenere le osservazioni sia il seguente: 1. Con una procedura casuale viene scelta un’urna e da tale urna viene prelevata una pallina a caso. Il colore `e registrato come osservazione. 2. La pallina viene rimessa nell’urna e, a meno che non si voglia terminare cos`ı le osservazioni, si ripete il passo 1. Questo processo genera una sequenza finita di colori che si possono pensare come l’uscita di un HMM. Un possibile HMM che modellizza il sistema urne-palline `e quello nel quale ogni stato corrisponde ad una specifica urna e, ad ogni stato, sono associate tante probabilit`a quanti sono i colori che la pallina pu`o assume- re. Siccome `e possibile ritrovare gli stessi colori in tutte la urne a disposizione, l’unica differenza `e la quantit`a di palline presenti relativamente ai vari colori. Un’osservazione isolata di una particolare pallina colorata non dice nulla sul- l’urna da cui `e stata estratta, ma `e possibile fare delle ipotesi probabilistiche. Si pu`o pensare ad un esperimento in cui una persona estrae una serie di palline dalle urne, scegliendo quest’ultime a caso di volta in volta, e annota il colore delle palline, ma non le urne dalle quali vengono estratte. Dai dati registrati 35
  • sarebbe possibile indovinare, in termini probabilistici, la sequenza con la qua- le sono state scelte le urne. Sarebbe, cio`e, possibile estrarre informazioni sul processo nascosto “scelta dell’urna” tramite il processo osservabile “estrazione della pallina colorata”. Formalizzazione L’esempio visto d`a un’idea di cosa sia un HMM e di come possa essere applicato ad alcune semplici situazioni. Un modello di Markov nascosto, per osservazioni di simboli discreti, `e caratterizzato dai seguenti aspetti: • N, il numero di stati del modello. Sebbene gli stati siano nascosti, per molte applicazioni pratiche vi `e un significato fisico attribuito agli stati o agli insiemi di stati del modello. Solitamente gli stati sono interconnessi in modo tale che qualsiasi stato possa essere raggiunto da qualsiasi altro. Ci sono comunque altre possibili connessioni interessanti anche nel campo del riconoscimento vocale. I singoli stati si possono indicare con {1, 2, . . . , N} e lo stato al tempo t con qt. • M, il numero di simboli distinti d’osservazione per stato. I simboli d’osser- vazione corrispondono all’uscita fisica del sistema che viene modellizzato. I simboli individuali si possono denotare con V = {v1, v2, . . . , vM }. • A = {aij}, l’insieme delle probabilit`a delle transizioni di stato, dove aij = P[qt+1 = j|qt = i] con 1 ≤ i, j ≤ N. Nel caso particolare in cui ogni stato `e raggiungibile da ogni altro in un singolo passo (modello ergodico), avremo aij > 0 ∀i, j. Per altri tipi di HMM avremo aij = 0 per una o pi`u coppie i, j. • B = {bj(k)}, l’insieme delle distribuzioni di probabilit`a dei simboli d’os- servazione, dove bj(k) = P[Ot = vk|qt = j] `e la probabilit`a che lo stato j produca il simbolo k. • π = {πi}, la distribuzione dello stato iniziale, dove πi = P[q1 = i] con 1 ≤ i ≤ N. Si osserva quindi che, per una completa descrizione di un HMM, `e necessa- rio specificare i parametri N e M, dire quali sono i simboli di osservazione e specificare i tre insiemi di distribuzione della probabilit`a A, B, π. Per indicare appropriatamente un modello `e possibile utilizzare una notazione compatta del tipo λ = (A, B, π). Dati tutti i parametri che lo caratterizzano, un HMM pu`o essere visto come un generatore che fornisce una sequenza di osservazione O = (o1, o2, . . . , oT ), dove ot `e uno dei simboli dell’insieme V , e T `e il numero di osservazioni della sequenza. La procedura di generazione pu`o essere schematizzata nei seguenti punti: 1. Scelta dello stato iniziale q1 in accordo con π. 2. Impostazione di t a 1. 3. Scelta di ot = vk in accordo alla bi(k). 4. Passaggio al prossimo stato secondo le aij. 36
  • 5. Se t < T, allora incremento di t e ritorno al passo 3, altrimenti fine della procedura. Tale procedura pu`o essere usata anche come modello, per comprendere come una data sequenza di osservazione sia stata generata. 7.2 I tre problemi principali degli HMM Per l’utilizzo pratico degli HMM sorgono tre problemi basilari da risolvere: 1. Data la sequenza di osservazione O = (o1, o2, . . . , oT ) e un modello λ = (A, B, π), com’`e possibile calcolare efficientemente la quantit`a P(O|λ), cio`e la probabilit`a che la sequenza O sia stata prodotta dal modello λ? 2. Data la sequenza di osservazione O = (o1, o2, . . . , oT ) e un modello λ = (A, B, π), com’`e possibile scegliere una corrispondente sequenza di stati q = (q1, q2, . . . , qT ) che sia ottima secondo certi criteri scelti? 3. Com’`e possibile aggiustare i parametri del modello λ = (A, B, π) in modo da massimizzare P(O|λ), data una certa O? 7.2.1 Il primo problema Calcolo diretto di P(O|λ) Il metodo pi`u semplice e diretto per risolvere il primo problema `e l’enu- merazione di tutte le possibili sequenze di stati di lunghezza T. Tuttavia il calcolo diretto di P(O|λ) richiede circa 2 T NT operazioni. Tale calcolo diventa inaccessibile anche per piccoli valori di N ed `e dunque necessario l’uso di procedure pi`u efficienti. Forward-backward procedure Un sistema efficace per il calcolo di P(O|λ) si basa sulla cosidetta procedura in avanti o forward procedure. Si pu`o definire una variabile forward nel seguente modo: αt(i) = P(o1o2 . . . ot, qt = i|λ) (22) Basandosi su questa definizione `e possibile elaborare un algoritmo indut- tivo per il calcolo di P(O|λ): 1. Inizializzazione: α1(i) = π bi(o1) con 1 ≤ i ≤ N 2. Induzione: αt+1(j) = N i=1 αt(i) aij bj(ot+1) con 1 ≤ t ≤ T − 1 e 1 ≤ j ≤ N 3. Conclusione: P(O|λ) = N i=1 αT (i) 37
  • Backward procedure Un’altra tecnica utilizzabile per il calcolo di P(O|λ) `e basata sulla pro- cedura all’indietro o backward procedure. La variabile backward βt(i) `e definibile nel seguente modo: βt(i) = P(ot+1ot+2 . . . oT |qt = i, λ) (23) Data questa definizione, il procedimento ricorsivo per il calcolo di P(O|λ) pu`o essere impostato come segue: 1. Inizializzazione: βT (i) = 1 con 1 ≤ i ≤ N 2. Induzione: βt(i) = N j=1 aij bj(ot+1) βt+1(j) con t = T − 1, T − 2, . . . , 1 e 1 ≤ i ≤ N 3. Conclusione: P(O|λ) = N i=1 π bi(o1) β1(i) Anche in questo caso l’ordine computazionale dell’algoritmo `e di sole N2 T operazioni. 7.2.2 Il secondo problema Per il secondo problema non esiste una soluzione esatta, ma un ventaglio di pos- sibili risultati che dipendono dai criteri di ottimalit`a scelti. Il criterio pi`u usato consiste nel trovare la migliore sequenza di stati (percorso) ossia massimizzare P(q|O, λ), che `e equivalente a massimizzare P(q, O|λ). Una tecnica formale per trovare questa sequenza di stati, basata sulla programmazione dinamica, `e l’al- goritmo di Viterbi. 7.2.3 Il terzo problema Il terzo e di gran lunga il pi`u difficile problema degli HMM `e la determinazione di un metodo per ricalcolare i parametri del modello λ = (A, B, π), con lo scopo di massimizzare P(O|λ). Non esiste nessun metodo per trovare analiticamente l’insieme dei parametri del modello, in modo da massimizzare in forma stretta la probabilit`a della sequenza di osservazione partendo da un insieme finito di dati di addestramento. `E possibile, invece, scegliere un modello λ = (A, B, π) tale che la probabilit`a P(O|λ) sia massimizzata localmente. Un metodo di ot- timizzazione utilizzabile `e noto come algoritmo di Baum-Welch ed `e un proce- dimento iterativo che ristima i parametri del modello usando la minimizzazione del gradiente. Le formule per la ristima dei parametri di un HMM, sono: πj = γ1(j) (Frequenza attesa dello stato j all’istante t = 1) (24) 38
  • aij = Numero atteso di transizioni dallo stato i allo stato j Numero atteso di transizioni dallo stato i = T −1 t=1 ξt(i, j) T −1 t=1 γt(i) (25) bj(k) = Frequenza attesa dello stato j e simbolo vk Frequenza attesa dello stato j = t:ot=vk γt(j) T t=1 γt(j) (26) dove ξt(i, j) = P(qt = i, qt+1 = j, O|λ) P(O|λ) = αt(i) aij bj(ot+1) βt+1(j) P(O|λ) = αt(i) aij bj(ot+1) βt+1(j) N i=1 N j=1 αt(i) aij bj(ot+1) βt+1(j) (27) e γt(i) = N j=1 ξt(i, j) (28) Utilizzando iterativamente la procedura descritta, usando λρ al posto di λ e ripetendo il calcolo delle restime, `e possibile migliorare P(O|λ) fino al raggiungimento del punto limite. 7.3 Risultati sperimentali L’addestramento di un modello di Markov discreto, utilizzando 8 stati, ha dato come risultato la capacit`a di classificazione riportata nel successivo grafico. A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 % 10 % 20 % 30 % 40 % 50 % 60 % Percentualediclassificazionicorrette Nella Tabella 2 `e riportata la matrice di confusione del HMM addestrato. 39
  • ABCDEFGHIJKLMNOPQRSTUVWXYZ A6823140131112203437423205112331204 B324322270143419337101120116915411324 C26591424020315441543104113302518 D51833030211231455800162009911430525 E113101769014131073430192121736260520 F16221257161191721912524027272227111 G437142006643151382107100681561214 H4722081942619301064032251312501216 I120121206088262115590631021134389 J322333112445739642042110033280258 K413527054101372741033018051270196 L1210211708122117124145230215012123 M124511101215126873323310023046178 N15010103418204415100031042212302510 O1311413032161123151152461011131046 P124818340113318116530323101982370216 Q91216111664121100647034551552148 R30115302133274414461118213290039 S30218001113597101121409283040511190 T5711162901974201284401641028113280415 U150021302191364310050020105058044 V52121618010281684251510013335550719 W113518001123460509401472145169 X132416176813161121803241354511838136 Y13214918381115242991610250411143 Z781461107441656273011214319201591 Tabella2:matricedicofusionechemostrailnumerodilettereclassificatedalHMMinbaseallaletterapronunciatadataininput;le righeindicanolaletteradiinputmentrelecolonnequellainoutput 40
  • 8 Volterra vs. NN In un sistema lineare, si pu`o sempre definire una risposta impulsiva h(t) che relaziona, tramite un integrale di convoluzione, il segnale di ingresso x(t) con il segnale di uscita y(t): y(t) = +∞ −∞ h(τ)x(t − τ)dτ (29) Naturalmente questo viene interpretato nel seguente modo: l’uscita y(t) `e da- ta dalla composizione degli effetti dell’ingresso x(t) in tutti gli istanti precedenti, pesati tramite una funzione peso h(t) denominata risposta impulsiva. Nel caso di sistemi non lineari, Norbert Wiener pens`o di estendere la pre- cedente relazione utilizzando la serie funzionale di Volterra, ovvero esprimendo l’uscita y(t) come una serie di funzioni (integrali): y(t) = +∞ −∞ h1(τ)x(t − τ)dτ+ +∞ −∞ h2(τ1, τ2)x(t − τ1)x(t − τ2)dτ1dτ2+ +∞ −∞ h3(τ1, τ2, τ3)x(t − τ1)x(t − τ2)x(t − τ3)dτ1dτ2dτ3 + . . . (30) Questa serie, detta ‘serie di Volterra’, converge alla soluzione sotto ipotesi nor- malmente verificate. Le funzioni hn(dτ1, dτ2, ..., dτn) possono essere viste come le risposte impulsive non lineari di ordine n e vengono chiamate Nuclei (kernel) di Volterra. L’espansione a tempo discreto e memoria limitata diventa perci`o: y(t) = +∞ −∞ h1(l)x(t − l)+ +∞ −∞ +∞ −∞ h2(l1, l2)x(t − l1)x(t − l2)+ +∞ −∞ +∞ −∞ +∞ −∞ h3(l1, l2, l3)x(t − l1)x(t − l2)x(t − l3) + . . . (31) Consideriamo ora un neurone artificiale feedforward time delay. Per sem- plificare consideriamo una rete con cinque ingressi. Se rappresentiamo la non linearit`a con una sigmoide, allora g(x) = (1 + e−x )−1 . Se la rappresentia- mo con la tangente iperbolica, allora g(x) = ex −e−x ex+e−x . In ogni caso, abbiamo y(n) = g( 4 i=0 wix(n − i)). Introduciamo ora una approssimazione polinomiale della nonlinearit`a. Si pu`o verificare che una buona approssimazione polinomiale tra -4 e 4 `e data da un polinomio di terzo grado: g(x) ≈ a3x3 +a2x2 +a1x+a0. Quindi: y(n) = a3[ 4 i=0 wix(n−i)]3 +a2[ 4 i=0 wix(n−i)]2 +a1[ 4 i=0 wix(n−i)]+a0 = a3 4 i 4 j 4 k wiwjwkx(n − i)x(n − j)x(n − k) + a2 4 i 4 j wiwjx(n − i)x(n − j) + a1 4 i wix(n − i) + a0 che `e una serie discreta di Volterra non lineare nei coefficienti. 41
  • Figura 7: Neurone artificile Lo stesso tipo di approssimazione si ha quando consideriamo una intera rete neurale, visualizzata nella seguente figura. Naturalmente ogni nodo della figura rappresenta una sommatoria e una nonlinearit`a. Figura 8: Semplice rete neurale time delayed Questa rete `e descritta dalle relazioni: y(n) = f[ i qi5zi(n)] zj(n) = f[ i wijx(n − i)] Assumiamo ora che non ci sia nonlinearit`a sull’ultimo neurone ma solo sullo strato intermedio. Allora le equazioni diventano: y(n) = j qj5zj(n) 42
  • zj(n) = f[ i wijx(n − i)] = = a3[ i wijx(n − i)]3 + a2[ i wijx(n − i)]2 + a1 i wijx(n − i) + a0 = = a3 i k l wijwkjwljx(n−i)x(n−k)x(n−l)+a2 i k wijwkjx(n−i)x(n−k)+ +a1 i wijx(n − i) Quindi: y(n) = j qj5zj(n) = j qj5a3 i k l wijwkjwljx(n − i)x(n − k)x(n − l)+ + j qj5a2 i k wijwkjx(n − i)x(n − k) + j qj5a1 i wijx(n − i) = = i k l j qj5a3wijwkjwljx(n − i)x(n − k)x(n − l)+ + i k j qj5a2wijwkjx(n − i)x(n − k) + i j qj5a1wijx(n − i) (32) In conclusione, Il calcolo della rete neurale di Figura 8 equivale approssima- tivamente al calcolo di una serie discreta di Volterra del terzo ordine. La serie di Volterra non pu`o essere tuttavia usata per stimare i pesi della rete. Tuttavia se si inglobano i coefficienti e si stimano con una tecnica adattativa, il risultato dovrebbe essere lo stesso. Il vantaggio `e che la stima dei coefficienti della serie di Volterra `e velocissima nel caso che si consideri una serie lineare nei coefficienti. Per provare quanto detto, `e stato realizzato un sistema come illustrato nella seguente figura. Figura 9: Sistema adattativo realizzato 43
  • Il sistema `e stato provato nel contesto del riconoscimento delle lettere del- l’alfabeto pronunciate a voce. Per motivi di tempo `e stata fatta una prova limitata ad alcune lettere. Inoltre `e stata provata una serie di Volterra del se- condo ordine, non del terzo. In sintesi, l’uso del sistema `e stato il seguente: per ogni lettera `e stata stimata una serie di Volterra fornendo in ingresso il segnale corrispondente alla lettera e un segnale desiderato pari a 1. In questo modo i coefficienti della serie venivano stimati in modo tale da fornire in uscita un valore elevato, mentre per tutte le altre lettere veniva fornito un segnale nega- tivo. Pur nel contesto molto limitato che `e stato provato, i risultati sono stati le seguenti percentuali di riconoscimento delle lettere. A B C D E F G H 0 % 10 % 20 % 30 % 40 % 50 % 60 % Percentualediclassificazionicorrette 44
  • 9 Conclusioni Non tutti gli obiettivi citati nell’introduzione della tesi sono stati raggiunti. Dei tre plugin preventivati, solo quello per multilayer perceptron `e stato portato a termine e di quello per HMM `e stata implementata una versione incompleta. Gli addestramenti su HMM e serie di Volterra sono stati eseguiti attraverso un’implementazione in C dei relativi algoritmi di addestramento. 9.1 Risultati ottenuti Il modello di multilayer perceptron si `e rivelato essere superiore, come qua- lit`a della classificazione, a quello di Hidden Markov Model. I risultati sono comparati nel seguente grafico. A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 % 10 % 20 % 30 % 40 % 50 % 60 % 70 % 80 % 90 % 100 % Percentualediclassificazionicorrette Multilayer Perceptron Hidden Markov Model Il lavoro riguardante i sistemi volterriani necessita ancora di approfondimenti che, per motivi di tempo, non si sono potuti portare a termine. 9.2 Vantaggi dovuti all’uso di Maven Il plugin sviluppato ha semplificato il processo di addestramento di multilayer perceptron. `E stato possibile installare il plugin e le librerie su diverse macchi- ne su cui si trovasse Maven clonando i sorgenti ed eseguendo il comando mvn install, rendendo immediatamente disponibile l’ambiente di addestramento. Alla prima esecuzione del plugin, le dipendenze ancora mancanti vengono scari- cate ed installate nel repository locale, senza dover preoccuparsi di recuperarle manualmente. Il progetto di multilayer perceptron presentato nella Sezione 6 non `e stato l’unico. Sono state addestrate anche reti a singolo neurone di output per il riconoscimento di un’unica lettera, dando responso negativo nel caso di una delle altre venticinque, per le quali si `e dovuto unicamente cambiare i valori di output atteso per ciascun esempio. 45
  • Alcuni di questi progetti sono stati gestiti dallo strumento di continuous integration Jenkins, menzionato nella Sezione 1.3. Gli addestramenti vengono avviati manualmente attraverso l’interfaccia web del tool, oppure in risposta ad aggiornamenti dei repository Mercurial remoti in cui sono versionati i vari progetti. Al termine di ogni addestramento viene avviato uno step aggiuntivo per copiare la rete neurale addestrata in una cartella differente. Per gli adde- stramenti pi`u lunghi, al termine della build viene fatta inviare una notifica via mail includendo i log dell’esecuzione con i risultati dei test. La possibilit`a di definire e integrare nuovi servizi pu`o permettere l’integra- zione con tool esistenti o di svilupparne di nuovi. Utilizzando un logger che scrive su file in formato csv, `e stata creata una semplice pagina web che mostra l’avanzamento dell’addestramento, attraverso un grafico rappresentante l’errore in una data iterazione. Figura 10: semplice implementazione di una pagina web che mostra l’avanza- mento dell’addestramento, i cui dati vengono recuperati da un file csv scritto da un apposito logger 9.3 Sviluppi futuri Modularizzazione degli artefatti Oltre al plugin per multilayer perceptron, alcuni sviluppi sono stati fatti su plugin per HMM e serie di Volterra. `E risultato che, per riutilizzare parte delle componenti sviluppate per il primo plugin, la libreria contenente le interfacce dei servizi per multilayer perceptron deve essere frammentata. Infatti risulta conveniente che funzioni, marshaller e altre tipologie di ser- vizi non strettamente legate ai multilayer perceptron risiedano in artefatti separati. Generalizzazione del plugin I servizi come metodi di addestramento o di test sono stati legati ad uti- lizzare l’oggetto MultilayerPerceptronDescriptor come formato si scambio, passato esplicitamente ai servizi generati da parte del plugin. Aggiungendo un servizio che racchiuda questa particolare implementazio- ne `e possibile astrarre il plugin in modo tale che possa eseguire qualsiasi 46
  • metodo di addestramento, senza dover limitarsi all’ambito dei multilayer perceptron. Questo suggerisce che una possibile estensione del framework vada, in- vece che in direzione dello sviluppo di molteplici plugin, in quella nella generalizzazione di quello attuale. Servizi integrati Al momento della stesura di questa tesi, l’unico caso di servizio fornito direttamente dal plugin `e l’implementazione di un logger che delega il proprio compito a quello di Maven. Vi sono altre tipologie di servizi che possono astrarre alcune carateristiche del contesto di esecuzione attraverso il framework Maven, come: • astrazione delle risorse e delle gerarchie di cartelle all’interno del progetto; • accesso ai risultati di sottoprogetti per rendere possibile la combina- zione di pi`u classificatori in uno composito; • logging orientato ai dati che utilizzi json come formato di scambio. Validazione dei descrittori di servizio L’implementazione di application context cerca di generare un servizio basandosi su un suo descrittore, istanziando ricorsivamente i collaboratori attraverso le factory, e nel caso manchi una delle factory richieste la gene- razione del servizio viene interrotta con un’eccezione. Un tentativo fallito di generazione di un servizio con un descrittore non valido, ad esempio a causa di una svista nella configurazione, in una fase diversa da quella iniziale potrebbe causare la perdita dei dati dell’esecuzione del plugin in corso, che in ogni caso verrebbe interrotta. Dotare l’application context di un metodo che verifichi la coerenza di un descrittore con le factory inserite nel contesto, senza la necessit`a di istanziare servizio e collaboratori, garantirebbe al plugin di poter fallire subito nella fase di validazione del progetto. Parallelizzazione L’algoritmo di back propagation pu`o essere eseguito in parallelo per cia- scun esempio dell’insieme di addestramento, poich´e i pesi del multilayer perceptron non vengono aggiornati fino a quando tutti i gradienti siano stati calcolati. Anche il calcolo delle attivazioni dei neuroni di un layer `e un operazione parallelizzabile. Nell’implementazione dell’algoritmo fatta per questa tesi la parallelizzazio- ne non `e stata introdotta, ma con la successiva release di Java sono previsti nuovi strumenti che la rendono implicita e di pi`u facile realizzazione. Si `e quindi scelto di attendere la nuova versione per passare ad implementazioni degli algoritmi che traggano vantaggio dal calcolo parallelo. 47
  • A Esempio di progetto per multilayer percep- tron: xor La funzione booleana xor, o or esclusivo, `e un esempio classico usato per intro- durre i multilayer perceptron, in quanto le classi dei risultati non sono linear- mente separabili sul piano degli input e quindi non riconoscibili dal perceptron. Per la semplicit`a di descrizione del problema, e per seguire la tradizione, verr`a utilizzato anche come esempio di utilizzo del plugin. Una possibile struttura di multilayer perceptron per il riconoscimento dello xor `e composta da un singolo hidden layer di tre neuroni. Come funzione di attivazione si pu`o optare per la tangente iperbolica, una sigmoide che mappa R nell’intervallo (−1, 1). Listing 14: Struttura di multilayer perceptron per il riconoscimento della funzione xor 1 { 2 "function": {"name": "tanh"}, 3 "sources": 2, 4 "sizes": [3, 1] 5 } Riguardo gli esempi, che risultano essere le quattro combinazioni di v e f rappresentabili con 1 e −1 rispettivamente, si richiedono come valori di output dei numeri vicini agli estremi dell’intervallo invece che gli estremi stessi: in questo modo si hanno degli output comunque distinguibili, evitando di avere i pesi delle sinapsi con modulo molto elevato al termine dell’addestramento. Vista la semplicit`a della rete neurale, sar`a utilizzato lo stesso insieme di esempi sia durante l’addestramento che per i test. Listing 15: Esempi usati per addestrare e testare il multilayer perceptron 1 [ 2 {"label":"(f,f)", "input":[-1, -1], "output":[-0.9]}, 3 {"label":"(f,v)", "input":[-1, 1], "output":[0.9]}, 4 {"label":"(v,f)", "input":[1, -1], "output":[0.9]}, 5 {"label":"(v,v)", "input":[1, 1], "output":[-0.9]} 6 ] Nella sezione build del descrittore di progetto viene inserita la configurazio- ne del plugin, dichiarando quali siano i servizi di addestramento e test, i loro parametri e collaboratori. Ad esempio, come metodo di addestramento si im- posta batchBackPropagation con alcuni collaboratori configurati, tra cui la funzione d’errore da applicare all’output per il calcolo del gradiente e il si- stema di logging su cui scrivere. Allo stesso modo si configura come metodo di test errorFunction, che applica una funzione d’errore all’output della rete neurale e fa fallire un test se tale errore superasse una soglia impostata. Nel Listato 16 `e mostrata la configurazione dei servizi con i relativi col- laboratori. Tutti i collaboratori elencati, tranne il logger, sono definiti come default dei servizi batchBackPropagation e errorFunction e quindi si pu`o rimuovere la loro dichiarazione nel descrittore di progetto, ma sono stati comunque inclusi per rendere pi`u chiaro l’esempio. 48
  • Listing 16: Configurazione del plugin per l’addestramento e i test 1 <project ...> 2 ... 3 <build> 4 <plugins> 5 <plugin> 6 <groupId>dev.deadc0de.seshat</groupId> 7 <artifactId>multilayer-perceptron-maven-plugin</artifactId> 8 <version>0.2</version> 9 <extensions>true</extensions> 10 <configuration> 11 <trainingMethod> 12 <name>batchBackPropagation</name> 13 <configuration> 14 <learningRate>0.1</learningRate> 15 <tolerance>0.1</tolerance> 16 <maximumIterations>100</maximumIterations> 17 </configuration> 18 <collaborators> 19 <collaborator> 20 <role>errorFunction</role> 21 <name>meanSquaredError</name> 22 </collaborator> 23 <collaborator> 24 <role>logger</role> 25 <name>maven</name> 26 </collaborator> 27 </collaborators> 28 </trainingMethod> 29 <test> 30 <name>errorFunction</name> 31 <configuration> 32 <tolerance>0.1</tolerance> 33 </configuration> 34 <collaborators> 35 <collaborator> 36 <role>errorFunction</role> 37 <name>meanSquaredError</name> 38 </collaborator> 39 <collaborator> 40 <role>logger</role> 41 <name>maven</name> 42 </collaborator> 43 </collaborators> 44 </test> 45 </configuration> 46 </plugin> 47 </plugins> 48 </build> 49 ... 50 </project> L’addestramento pu`o essere avviato con Maven specificando il goal compile, mentre per includere anche i test bisogna utilizzare il goal test. Un esempio di output `e mostrato nel Listato 17. 49
  • Listing 17: Output dell’esecuzione del plugin 1 [INFO] Scanning for projects... 2 [INFO] 3 [INFO] --------------------------------------------------------------------- 4 [INFO] Building xor 0.1-SNAPSHOT 5 [INFO] --------------------------------------------------------------------- 6 [INFO] 7 [INFO] --- multilayer-perceptron-maven-plugin:0.2:train (default-train) @xor 8 [INFO] 9 [INFO] training multilayer perceptron xor.json 10 [INFO] [training] 1 1.0577789368410564 11 [INFO] [training] 2 0.9885083556940348 12 [INFO] [training] 3 0.9458603410983543 13 [INFO] [training] 4 0.9202124244755882 14 [INFO] [training] 5 0.90355341414942 15 [INFO] [training] 6 0.8913060072739769 16 [INFO] [training] 7 0.8809773245010678 17 [INFO] [training] 8 0.87102088381477 18 [INFO] [training] 9 0.8602198833772078 19 [INFO] [training] 10 0.8473065655208513 20 [INFO] [training] 11 0.8306467948990252 21 [INFO] [training] 12 0.807954836291371 22 [INFO] [training] 13 0.7763650154458812 23 [INFO] [training] 14 0.7343599500240797 24 [INFO] [training] 15 0.6878857061865924 25 [INFO] [training] 16 0.6508250216167939 26 [INFO] [training] 17 0.62399128582203 27 [INFO] [training] 18 0.5992830855625152 28 [INFO] [training] 19 0.572576981607567 29 [INFO] [training] 20 0.5418213611696449 30 [INFO] [training] 21 0.5056650660387366 31 [INFO] [training] 22 0.46319086073992954 32 [INFO] [training] 23 0.414251902799329 33 [INFO] [training] 24 0.3598769994659289 34 [INFO] [training] 25 0.30279199367372855 35 [INFO] [training] 26 0.24755011655934944 36 [INFO] [training] 27 0.19877179547675805 37 [INFO] [training] 28 0.15872945262040172 38 [INFO] [training] 29 0.12724096023604806 39 [INFO] [training] 30 0.10296446553114157 40 [INFO] [training] 31 0.08433460718411209 41 [INFO] multilayer perceptron xor.json trained 42 [INFO] 43 [INFO] --- multilayer-perceptron-maven-plugin:0.2:test (default-test) @xor 44 [INFO] 45 [INFO] testing multilayer perceptron xor.json 46 [INFO] [test] [(f,f)] failed: error 0.13514183344893027 above tolerance 0.1 47 [INFO] [test] [(f,v)] passed: error 0.04541332828458146 48 [INFO] [test] [(v,f)] passed: error 0.09370783118674461 49 [INFO] [test] [(v,v)] passed: error 0.06307543581619203 50 [INFO] test executed 4: passed 3, failed 1 51 [INFO] --------------------------------------------------------------------- 52 [INFO] BUILD SUCCESS 53 [INFO] --------------------------------------------------------------------- 54 [INFO] Total time: 0.768s 55 [INFO] Finished at: Sat Mar 01 16:12:53 CET 2014 56 [INFO] Final Memory: 6M/114M 57 [INFO] --------------------------------------------------------------------- Il file contenente il multilayer perceptron addestrato viene salvato nella cartella target/multilayer-perceptron. L’oggetto json che lo descrive conterr`a i pesi delle sinapsi calcolate durante l’addestramento. 50
  • Listing 18: La struttura del multilayer perceptron addestrato 1 { 2 "sources":2, 3 "layers":[ 4 { 5 "neurons":[ 6 { 7 "function":{"name":"tanh","configuration":{},"collaborators":{}}, 8 "bias":-0.737718409408805, 9 "weights":[-0.287079403737907,0.636592260627277] 10 },{ 11 "function":{"name":"tanh","configuration":{},"collaborators":{}}, 12 "bias":-0.319036398379351, 13 "weights":[-1.015886690995409,-0.617654172805915] 14 },{ 15 "function":{"name":"tanh","configuration":{},"collaborators":{}}, 16 "bias":-1.371909790612952, 17 "weights":[1.2360994927055501,1.253533726132772] 18 } 19 ] 20 },{ 21 "neurons":[ 22 { 23 "function":{"name":"tanh","configuration":{},"collaborators":{}}, 24 "bias":-0.3955449936389208, 25 "weights":[0.799872659949049,-1.040302630959267,-1.34014482170830] 26 } 27 ] 28 } 29 ] 30 } 51
  • B Implementazione dell’algoritmo di back-propagation In seguito `e descritta l’implementazione dell’algoritmo di back propagation, nel- la variante batch dove tutti i gli esempi del training set sono valutati prima di procedere all’aggiornamento dei pesi. Inoltre `e stato specializzato per il parti- colare caso dei multilayer perceptron, a partire dall’algoritmo per reti neurali feedforward descritto nella Sezione 3. Dal punto di vista implementativo, seppur nell’ambito di un linguaggio orien- tato agli oggetti come Java, si `e optato per un approccio funzionale. Alla base dell’astrazione vi `e il considerare il multilayer perceptron come una sequenza di mappature: tutte le operazioni sono legate alla trasformazione di un segnale du- rante l’attraversamento di un layer, avendo come dati l’input e la struttura (bias, pesi delle sinapsi e funzioni di attivazione). Diventa quindi possibile limitarsi a considerare un layer per volta, semplificando notevolmente l’implementazio- ne. Un ulteriore vantaggio dato dal paradigma funzionale `e la possibilit`a di parallelizzare alcune parti dell’algoritmo. All’inizio dell’addestramento i pesi del multilayer perceptron vengono inizia- lizzati con valori casuali, in quanto se nulli non permetterebbero la propagazioe dell’errore all’indietro. Dato un esempio dotato del vettore di input e di quello di output desiderato, l’algoritmo si divide nelle due fasi esposte in seguito. B.1 Fase feedforward Le informazioni raccolte durante la fase feedforward sono: • l’input in ingresso a ciascun layer; • i valori delle derivate di ciascun neurone calcolate attraverso il livello di attivazione; • l’output del multilayer perceptron. Per ottenerle `e sufficiente effettuare una riduzione15 sul multilayer perceptron, visto come lista di layer, applicando ad ogni layer una funzione che, dato un accumulatore contenente i dati raccolti per i layer precedenti, vi aggiunga quelli del layer corrente. La funzione combinante di feedforward `e strutturata come segue: • in input sono dati un accumulatore, contenente derivate e input di tutti i layer precedenti, l’output del layer precedente e i dati del layer corrente: bias bi, pesi delle sinapsi wi e funzione di attivazione fi di ciascun neurone i; • vengono calcolati i livelli di attivazione si del layer, con si = bi + j xjwij (33) dove il vettore x rappresenta l’output generato dai neuroni del layer pre- cedente, e il peso wij `e associato alla sinapsi che dal neurone j del layer precedente arriva al neurone i; 15 Nella programmazione funzionale, l’operazione di riduzione consiste nella combinazione di elementi di una struttura dati ricorsiva attraverso una funzione combinante: dato un valore di partenza, detto accumulatore, la funzione viene applicata sistematicamente al successivo elemento usando il valore attuale dell’accumulatore ed aggiornandolo col nuovo valore appena calcolato. 52
  • • viene calcolata la derivata della funzione di attivazione per ciascun neu- rone, con gi = fi (si); • viene infine calcolato l’output del layer con oi = fi(gi); • l’input del layer, ovvero l’output di quello precedente, e le derivate sono aggiunte all’accumulatore e viene restituito l’output del layer corrente. I parametri iniziali della riduzione sono un accumulatore vuoto e l’input del multilayer perceptron. B.2 Fase di back propagation Attraverso la funzione d’errore scelta per l’addestramento viene calcolato il suo gradiente, confrontando l’output desiderato con quello ottenuto al termine della fase feedforward. L’obiettivo `e ottenere le componenti del gradiente per tutti i pesi del multilayer perceptron a partire dal gradiente dell’errore. Nella fase di back propagation, la lista contenente gli input e le derivate dei layer viene inver- tita ed utilizzata per propagare all’indietro l’errore, accumulando nel frattempo le componenti del gradiente per ciascun layer visitato. Come nel caso della fase feedforward, viene definita una funzione combinante di back propagation, con il seguente comportamento: • in input sono dati un accumulatore, contenente le componenti parziali del gradiente per i layer successivi (considerati nell’ordine originale del multilayer perceptron), l’output di back propagation del layer successivo e i dati del layer corrente; • viene calcolata l’attivazione di backpropagation del layer, moltiplicando l’input per le derivate delle funzioni di attivazione calcolate nella fase feedfroward, con ¯si = ¯xigi; • il gradiente per i pesi delle sinapsi si ottiene moltiplicando l’attivazione di back propagation ¯s per l’input della fase feedforward x ∆wij = j ¯sixj (34) mentre il gradiente del bias ∆wi0 `e dato semplicemente dall’attivazione ¯si; • infine l’output viene calcolato percorrendo al contrario le sinapsi, con ¯oj = i ¯siwij (35) • il gradiente del layer viene aggiunto all’accumulatore e viene restituito l’output da passare al layer precedente. I parametri iniziali della riduzione sono un accumulatore vuoto e il gra- diente della funzione d’errore come input. Al termine l’output viene scartato, mentre le componenti raccolte nell’accumulatore vanno a formare il gradiente del multilayer perceptron. 53
  • B.3 Aggiornamento dei pesi I gradienti calcolati per ogni singolo esempio vengono sommati, attraveso una riduzione, ottenendo il gradiente ∆w per l’intero insieme di addestramento. Pri- ma che ai pesi del multilayer perceptron venga sottratta la relativa componente del gradiente, questo viene moltiplicato per il learning rate η ed eventualmen- te sommato con il gradiente dell’iterazione precedente, pesato con il valore del momentum α: ∆wn = η · E(wn) + α · ∆wn−1 (36) I pesi vengono quindi aggiornati attraverso l’equazione wn+1 = wn − ∆wn (37) 54
  • Riferimenti bibliografici [1] David J.C. MacKay, Information Theory, Inference and Learning Algorithms. Cambridge University Press, UK, 4th printing, 2005. [2] Simon Haykin, Neural Networks, a Comprehensive Foundation. Prentice Hall International, Inc. , New Jersey, 2nd Edition, 1999. [3] Luis B. Almeida, Multilayer Perceptrons. Handbook of Neural Computa- tion, 1997. [4] Alexander H. Waibel, John B. Hampshire, A Novel Objective Function for Improved Phoneme Recognition Using Time-Delay Neural Networks. IEEE Transactions on Neural Networks, vol. 1, no. 2, June 1990. [5] Enzo Mumolo, Alberto Carini, Volterra Adaptive Prediction of Speech with Application to Waveform Coding. 1995. [6] Tim O’Brien, John Casey, Brian Fox, Bruce Snyder, Jason Van Zyl, Eric Redmond, Maven: the Definitive Guide. Sonatype, 2008. 55