Introduzione alle reti neurali artificiali

102
INTRODUZIONE ALLE RETI NEURALI ARTIFICIALI Matteo Tosato 2010/2011 Revisione 3.0

description

Reti neurali artificiali e sistemi neuro-fuzzy

Transcript of Introduzione alle reti neurali artificiali

Page 1: Introduzione alle reti neurali artificiali

INTRODUZIONE ALLE RETI NEURALI ARTIFICIALI

Matteo Tosato 2010/2011

Revisione 3.0

Page 2: Introduzione alle reti neurali artificiali

2

Matteo Tosato - Introduzione alle reti neurali artificiali

Sommario Introduzione storica...................................................... 4

- Ciò che l’occhio della rana comunica al cervello della rana, da Kant alle reti

neurali artificiali. .................................................... 4

- Anni 40’: il sogno booleano ............................................. 4

- Anni 50’: l’età dell’oro del sogno booleano ............................. 5

- Anni 80’: Il risveglio del sogno di Boole ............................... 8

- Ringraziamenti .......................................................... 9

Aspetti biologici........................................................ 10

Il neurone artificiale................................................... 13

- Considerazioni principali .............................................. 13

- Interpretazione vettoriale ............................................. 19

Apprendimento del perceptron............................................. 20

- La regola di Hebb ...................................................... 21

- La regola postsinaptica ................................................ 22

- La regola presinaptica ................................................. 22

- La regola delta ........................................................ 22

- Valutazione delle disuguaglianze ....................................... 27

Reti neurali MLP (Multi layer perceptron)................................ 29

- Reti neurali a due strati (M-Adeline) .................................. 30

- Architetture Feed-forward .............................................. 32

- Feed-forward ricorrenti ................................................ 34

- Error back-propagation (EBP) ........................................... 35

- Migliorie per l’algoritmo EBP .......................................... 42

- Algoritmo Resilient back-propagation (RPROP) ........................... 46

- Reti di Hopfield ....................................................... 48

Reti neurali auto-organizzanti........................................... 51

- Mappe di Kohonen ....................................................... 51

Esempio di rete SOM ................................................. 56

- Competitive learning reale ............................................. 63

Problemi e strategie..................................................... 67

- Neuro-fuzzy ............................................................ 67

- Reti ART ............................................................... 69

Metodologie di progettazione............................................. 70

- Il problema dei dati in ingresso ....................................... 73

Esempi di applicazioni pratiche.......................................... 74

- Intrusion detection .................................................... 74

- Previsione di fenomeni complessi ....................................... 84

Page 3: Introduzione alle reti neurali artificiali

3

Matteo Tosato - Introduzione alle reti neurali artificiali

- Analisi di segnale ..................................................... 86

Reti di reti neurali..................................................... 88

Conclusione e ringraziamenti............................................. 89

Appendice A – basi matematiche........................................... 90

Appendice B – Riferimenti................................................ 98

Appendice C – Aneuro32................................................... 99

Page 4: Introduzione alle reti neurali artificiali

4

Matteo Tosato - Introduzione alle reti neurali artificiali

Introduzione storica a cura di Andres Reyes

Ciò che l’occhio della rana comunica al cervello della rana, da Kant alle reti neurali

artificiali.

Figura 1: Walter Pitts

Walter Pitts nacque a Detroit il 23 aprile del 1923 e all'età di 15 anni scappò di casa

perché il padre voleva abbandonasse gli studi per il lavoro. Da qui la storia prosegue

con un aneddoto che amava raccontare il neuro-fisiologo Warren McCulloch (1898-1969) .

Il giovane Pitts arrivato a Chicago passò le sue ore nel parco vicino all'università

conversando di filosofia e logica con Bert.

Ignaro in realtà che fosse il famoso matematico Bertrand Russell (1872-1970) ospite

alla University of Chicago nell'anno accademico 1938-39 per un seminario. Sempre

secondo McCulloch, Russell consigliò a Pitts di leggere “La costituzione logica del

mondo” (1928) del logico Rudolf Carnap (1891-1970) membro del circolo di Vienna, che si

trovava a Chicago per il seminario di Russell. Pitts si accorse che il libro presentava

un errore ed andò a trovare Carnap in ufficio all'università, ma non essendosi

presentato solo mesi dopo Carnap seppe chi era il giovane e per aiutarlo gli trovò un

lavoro presso l'università.

Anni 40’: il sogno booleano

Nel 1943 il giovane Pitts e McCulloch proposero uno studio pionieristico "A logical

calculus of the ideas immanent in nervous activity" sulle reti neurali artificiali

(ANN) dimostrando che l'algebra di Boole poteva essere applicata allo studio delle reti

neurali biologiche , studiando come 1 (eccitato) e 0 (inibito) l'attività del neurone.

Page 5: Introduzione alle reti neurali artificiali

5

Matteo Tosato - Introduzione alle reti neurali artificiali

Inserendosi così negli intenti, già definiti dal matematico inglese George Boole fin

dal 1854, “di ricercare le leggi fondamentali di quelle operazioni dello spirito

mediante le quali si attua il ragionamento, dare loro un'espressione nel linguaggio

simbolico del calcolo, e costruire su questo fondamento la scienza della logica e il

suo metodo”.

Boole (1815-1864) riteneva che le sue ricerche fossero più un contributo alla

psicologia che alla matematica e che leggi da lui scoperte fossero realmente quelle del

pensiero perché dimostravano che la logica proposizionale e quella sillogistica

aristotelica erano due aspetti della stessa realtà. Bastava infatti sostituire "1 =

vero" e "0 = falso" come due insiemi che rappresentano il Tutto ed il Nulla.

Infine l'ingegnere Claude Shannon (1916-2001) nella sua tesi del 1937 “A Symbolic

Analysis of relay and Switching Circuits” evidenziò come l'algebra di Boole poteva

rappresentarsi anche come un interruttore aperto (0) o chiuso (1) mettendo così le basi

per la costruzione dei computers.

L'analogia tra circuiti elettrici e neuronali permetteva quindi di pensare

metaforicamente al cervello come a un computer biologico (wetware) e al computer come

un cervello elettronico permettendo così di risolvere il dualismo cartesiano in chiave

materialista.

Inoltre trasformava le reti neuronali in una macchina di Turing (TM) portando

all'identificazione dei processi cognitivi con quelli formali algoritmici di una

macchina dando così la possibilità di riprodurre meccanicamente la coscienza come

auspicato dalla nascente ricerca sull'intelligenza artificiale .

Posizione che sarebbe stata criticata negli anni '80 dal filosofo americano John Searle

con l'esperimento mentale della stanza cinese (“Menti, cervelli e programmi”,1980) e da

Thomas Nagel con la celeberrima frase:

”Che cosa si prova ad essere un pipistrello?”.

Per Searle,l'approccio computazionale fornisce solo un una dottrina formale del

funzionamento della mente,parla di operazioni mentali e di processi, ma solo raramente

di contenuti. Mentre sembra che l'intenzionalità sia una caratteristica della

coscienza, cioè la sua necessità di pensare qualcosa, vedere qualcosa, immaginare

qualcosa.

Con questa metodologia dunque non è possibile spiegare la questione dei qualia, le

qualità soggettive degli stati di coscienza, ciò che il filosofo americano Thomas Nagel

ha definito come l'effetto che fa essere un determinato tipo di essere.

Il modello proposto da McCulloch e Pitts mancava però di una caratteristica

fondamentale: la possibilità di apprendere.

Contributo che giunse nel 1949 dallo psicologo canadese Donald Hebb (1904-1985) che

propose nella sua opera “L'organizzazione del comportamento” un semplice meccanismo di

apprendimento: “quando un assone della cellula A prende parte ripetitivamente nel

processo di eccitamento della cellula B, qualche cambiamento strutturale o metabolico

subentra in una o entrambe le cellule in modo che l'efficienza di A, come cellula

eccitatrice di B, aumenti”.

Anni 50’: l’età dell’oro del sogno booleano

Page 6: Introduzione alle reti neurali artificiali

6

Matteo Tosato - Introduzione alle reti neurali artificiali

Alla fine degli anni '50 vennero pubblicate tre opere che incentivarono ulteriori

sviluppi delle reti neurali artificiali : “Pandemonium: A paradigm for learning” (1958)

di Selfridge, Il Perceptron (1958) di Rosenblatt e l'Adaline di Windrow e Hoff.

L'idea di Pandemonium, termine coniato dal poeta inglese John Milton nel “Paradiso

perduto”(1667), secondo Oliver Selfridge “era quella di avere un gruppo di demoni che

davano la voce a quelli del livello superiore, e questi a quelli di un livello ancora

superiore” cioè di disporre di diverse reti neurali , appunto di demoni, semi-

indipendenti che comunicavano il loro output per ogni singola proprietà per esempio di

un volto o di una parola (Pattern Recognition).

Figura 2: Modello del perceptron

L'idea dei demoni venne ripresa nel 1985 da Marvin Minsky come modello della mente come

società di multi-agenti (“La società della mente”,1985).

Nel 1958 lo psicologo Frank Rosenblatt scrisse “The Perceptron, a Probabilistic Model

for Information Storage and Organization in the Brain” rifiutando l'uso della logica

simbolica di Pitts e McCulloch a favore di metodi probabilistici. Il perceptron

risultava quindi un classificatore e riconoscitore di schemi che simulava la visione

umana.

Nel loro saggio “Adaptive Switching Circuits” (1960) Bernard Windrow e Marcian Hoff

introdussero una rete simile al perceptron, chiamata Adaline (Adaptive Linear Element)

ed in seguito la Madaline (Multiple Adaline) la prima rete ad essere applicata nel

mondo reale per la riduzione dell'eco nelle linee telefoniche.

La principale differenza con il modello di Rosenblatt era l'algoritmo di apprendimento

basato sulla minimizzazione della somma dei quadrati degli errori nelle sinapsi (delta

rule) e sulla somministrazione di esempi per ottenere l'output desiderato

(apprendimento supervisionato).

In questo contesto ritroviamo anche l'esperimento del 1959 condotto da Jerome Lettvin

(1920-2011), dal neuroscienziato cileno Humberto Maturana, da McCulloch e Pitts sulla

percezione visiva della rana:

“Ciò che l'occhio della rana comunica al cervello della rana”.

Page 7: Introduzione alle reti neurali artificiali

7

Matteo Tosato - Introduzione alle reti neurali artificiali

Figura 3: Pitts e Lettvin osservando una rana

Il rapporto fra vista e percezione, fra il vedere ed il decodificare un' immagine, è da

sempre uno degli argomenti alla base delle questioni legate all'esperienza cosciente.

Lo scopo dell'esperimento, richiamandosi alla “Critica della ragion pura” (1787) del

filosofo tedesco Immanuel Kant (1724-1804), era di dimostrare sperimentalmente le "basi

fisiologiche del sintetico a priori" cioè all'esistenza di filtri naturali che

selezionano i contenuti dell'esperienza.

Se ad esempio una mosca passasse davanti all'occhio della rana questa verrebbe

percepita e di riflesso mangiata però se dinanzi alla rana poniamo un oggetto statico,

anche una mosca uccisa dallo sperimentatore, non se la mangerebbe, non perché lo

decida, ma perché non la vede!

L'immagine della mosca si forma nella retina della rana però l'informazione non viene

elaborata dal cervello.

Le opere di Rosenblatt, Windrow e Hoff stimolarono numerose ricerche tuttavia

l‟entusiasmo cessò nel 1969 con il saggio “Perceptrons: An Introduction to

Computational Geometry” di Marvin Minsky e Seymour Papert in cui si dimostravano i

limiti del perceptron come l'impossibilità di realizzare funzioni linearmente

separabili come la Xor. Infatti ciò avrebbe richiesto l'addestramento dei neuroni

nascosti (Hidden Layer).

Page 8: Introduzione alle reti neurali artificiali

8

Matteo Tosato - Introduzione alle reti neurali artificiali

Termina così per più di un decennio ciò che il matematico Douglas Hofstadter , autore

di “Godel, Escher e Bach”, aveva definito come l'età dell'oro del sogno booleano

dell'intelligenza artificiale.

Figura 4: Marvin Minsky e Seymour Papert

Anni 80’: Il risveglio del sogno di Boole

Nel 1982 il finlandese Teuvo Kohonen, ispirandosi alla topologia della corteccia del

cervello, introdusse un nuovo tipo di ANN le SOM (self-organizing map) in grado di

sviluppare un comportamento auto-organizzante senza l‟addestramento da parte di un

supervisore, attraverso l‟eccitazione di neuroni vicini e l'inibizione di quelli

lontani.

Nel 1986 venne introdotto, grazie alle pubblicazioni degli psicologi David Rumelhart,

Geoffrey Hinton e Ronald Williams, l‟algoritmo di retro-propagazione (Error

BackPropagation EBP), capace di addestrare anche il livello di neuroni nascosti (hidden

layer) attraverso una modifica sistematica degli errori tra i nodi, superando così le

critiche degli anni 60'.

Bisogna però ricordare che tale algoritmo era già stato pensato nel 1974 da P. Werbos

nella sua tesi di dottorato.

Inoltre David Rumelhart (1942-2011) ed il suo collega James McClennand pubblicarono in

due volumi “Parallel Distributed Processing” (PDP) rilanciando così il programma

connessionista.

Proponevano quindi tre elementi predominanti nella riproduzione dell'attività cognitiva

attraverso le ANN: il processamento in parallelo, memoria distribuita ed adattabilità.

Al contrario di come avveniva nell'intelligenza artificiale: processamento sequenziale,

memoria localizzata ed istruzioni imperative.

Il connessionismo definiva l'intelligenza come apprendimento e non più come mera

elaborazione e programmazione di simboli infine come nel cervello i dati venivano

“evocati” e non “cercati”.

Page 9: Introduzione alle reti neurali artificiali

9

Matteo Tosato - Introduzione alle reti neurali artificiali

Ulteriore successo del connessionismo fu che Rumelhart e McClennand resero disponibili

per anni i sorgenti dei loro programmi agli studenti delle università dove insegnavano

esortandoli a testarli e a modificarli.

Ringraziamenti

Vorrei ringraziare il filosofo e neuro-psicologo Marco Mozzoni , direttore della

rivista di neuroscienze BrainFactor, per l'aiuto datomi nella stesura di questo breve

articolo introduttivo alle reti neurali.

Andres Reyes.

Page 10: Introduzione alle reti neurali artificiali

10

Matteo Tosato - Introduzione alle reti neurali artificiali

Aspetti biologici

Il cervello,

È l‟oggetto più complesso e misterioso che si conosca: 1.300-1.500 grammi di tessuto

gelatinoso composto da 100 miliardi di cellule (i neuroni), ognuna delle quali sviluppa

in media 10 mila connessioni con le cellule vicine. Durante la vita fetale l‟organismo

produce non meno di 250 mila neuroni il minuto. Ma 15-30 giorni prima della nascita, la

produzione si blocca e per il cervello comincia una seconda fase che durerà per tutta

la vita: la creazione di connessioni tra le cellule.

In questo processo, le cellule che falliscono le connessioni vengono eliminate, tanto

che al momento della nascita sono già dimezzate. Il cervello umano (più correttamente

"encefalo") è il risultato della sovrapposizione dei tre tipi di cervello apparsi nel

corso dell‟evoluzione dei vertebrati.

Dal basso (alla base del cranio), il cervello più antico, o romboencefalo,

specializzato nel controllo di funzioni involontarie come vigilanza, respirazione,

circolazione e tono muscolare. Comprende il cervelletto e le parti del midollo spinale

che si allungano nel cervello.

Salendo, c‟è il mesencefalo: una piccola porzione di tessuto nervoso costituita dai

cosiddetti peduncoli cerebrali e dalla lamina quadrigemina. Infine c‟è il prosencefalo,

la parte più "moderna", suddiviso in diencefalo e telencefalo. Il primo, chiamato anche

"sistema limbico", contiene strutture come talamo, ipotalamo, ipofisi e ippocampo, da

cui provengono sensazioni come fame, sete o desiderio sessuale. Infine, la parte più

recente in assoluto: la corteccia, dove hanno sede le funzioni intelligenza e

linguaggio.

Ma veniamo ai mattoni del cervello, i neuroni: cellule specializzate nel raccogliere,

elaborare e trasferire impulsi nervosi. Dal loro corpo cellulare si diramano vari

rametti, i dendriti, e un ramo più grosso, l‟assone.

I primi ricevono i segnali in arrivo, il secondo conduce i messaggi in uscita. Grazie a

dendriti e assoni, il numero totale delle connessioni che i neuroni di un cervello

umano riescono a stabilire supera il numero di tutti i corpi celesti presenti

nell‟universo.

L‟esistenza di queste connessioni, o sinapsi, fu scoperta alla fine del XIX secolo dal

fisiologo inglese Charles Scott Shemngton, anche se non si tratta di connessioni

fisiche perché tra due neuroni s‟interpone sempre una microscopica fessura.

Per superare questo varco, i segnali cambiano faccia: da elettrici, diventano chimici.

La terminazione dell‟assone rilascia sostanze, dette neurotrasmettitori, che sono

raccolte dagli appositi recettori presenti sulla membrana della cellula-obiettivo.

Catturato il neurotrasmettitore, il messaggio chimico viene riconvertito in impulso

elettrico.

Per rendere il viaggio più veloce, sull‟assone l‟impulso procede a balzi.

L‟assone, infatti, è ricoperto da un materiale isolante chiamato guaina mielinica, che

però lascia scoperti alcuni punti: i nodi di Ranvier. E saltando da un nodo all‟altro,

l‟impulso raggiunge i 400 km/h.

Page 11: Introduzione alle reti neurali artificiali

11

Matteo Tosato - Introduzione alle reti neurali artificiali

"Il cervello ha alcuni punti di contatto con i computer, ma anche una differenza

essenziale: è "plastico" Che cosa significa? Che ogni volta che lo usiamo, si

modifica".

Proprio qui volevo arrivare dove l'informatica di distrae e cambiando direzione

incontra la neurologia. Abbiamo già visto che due neuroni, per comunicare, si scambiano

sostanze chimiche che li inducono a generare particolari impulsi elettrici. Immaginate

di ripetere questo processo milioni, miliardi di volte e avrete descritto, anche se in

maniera semplificata, il trasferimento di un‟informazione (visiva, acustica...)

all‟interno di un circuito neuronale del cervello umano. Vediamo un caso semplice.

immaginiamo per esempio di cogliere un fiore mai visto prima e caratterizzato da un

profumo piacevolissimo. Questo tipo di informazione viaggerà dalla mucosa olfattiva (la

parte interna del naso che "sente" gli odori), lungo il nervo olfattivo, fino alla

parte della corteccia cerebrale organizzata per analizzare e comprendere i profumi. Nel

fare ciò, l‟informazione attraverserà un numero enorme di sinapsi creando l‟equivalente

di un "sentiero" neuronale. Al ripetersi dell‟esperienza, l‟informazione viaggerà

nuovamente lungo lo stesso percorso rinforzandolo ancora di più, proprio come il

passaggio di molte persone in un bosco crea un sentiero.

Una cosa però è certa: alla base della memoria c‟è la plasticità neuronale.

Con queste parole si definisce l‟abilità del cervello di plasmare se stesso attraverso

il continuo rimodellamento delle sinapsi vecchie e la creazione di sinapsi nuove. Il

cervello è infatti in costante rimodellamento, ed è proprio per questo che si deve

mantenerlo sempre in esercizio per garantirne l‟efficienza. Certo, è legittimo pensare

che l‟apprendimento sia qualcosa di più della ristrutturazione di un certo numero di

sinapsi... ma esiste una prova concreta che senza la plasticità neuronale non saremmo

più capaci di apprendere.

Concentriamoci su quella che è la struttura del neurone biologico, che abbiamo visto

essere struttura fondamentale.

Figura 5: Neurone

Le sinapsi quindi comprendono sia l'assone che i dentriti, possono essere eccitatorie

oppure inibitorie a seconda della loro capacità di trasporto del segnale.

Il neurone, dato che può emettere o meno un segnale elettrico avrà anche una soglia di

attivazione. Fin quando la membrana del neurone resta indisturbata non si origina alcun

potenziale d‟azione, ma se un qualsiasi evento provoca un sufficiente aumento del

potenziale del livello di -90mV verso il livello zero, è lo stesso voltaggio in aumento

Page 12: Introduzione alle reti neurali artificiali

12

Matteo Tosato - Introduzione alle reti neurali artificiali

che fa si che molti canali del sodio voltaggio dipendenti comincino ad aprirsi. Ciò

permette un rapido ingresso di ioni sodio, che provoca ancora un nuovo aumento del

potenziale di membrana, che fa aprire un numero ancora maggiore di canali del sodio

accrescendo il flusso di ioni sodio che entrano nella cellula. Il processo si

autoalimenta con un circolo vizioso di feedback positivo fino a che tutti i canali del

sodio non risultano totalmente aperti. Ma a questo punto in una successiva frazione di

millisecondo il potenziale di membrana in aumento provoca una chiusura dei canali del

sodio e una apertura di quelli del potassio, dopodiché il potenziale d‟azione termina.

Perché si inneschi il potenziale d‟azione è necessario che il potenziale di membrana

aumenti di 15/30mV, portando quest‟ultimo a circa -65mV (soglia di eccitazione). Quindi

non sempre è detto che la soglia di attivazione viene raggiunta, dipende proprio dalla

velocità del processo suddetto.

Figura 6: Attivazione neurone

Questo potenziale è diffuso lungo tutta la struttura neuronale, anche alle estremità

delle sinapsi la dove il segnale elettrico diventa chimico per passare al neurone

interconnesso. Se questo si verifica la sinapsi sarà quindi di eccitazione, altrimenti

di inibizione.

questo è quanto ci conviene sapere per comprendere come funziona il neurone, esistono

poi altre importanti questioni che si potrebbe citare per quanto riguarda tutta la

parte chimica, il neurone è in effetti un sistema pompa sodio-potassio.

I neuroni interconnessi formano una rete neurale, questa nel corso del tempo e delle

esperienze si modifica adattandosi alla nuova necessità di risolvere sempre problemi

differenti e prendere decisioni diverse. Le ricerche riguardo il funzionamento del

cervello hanno fatto grandi passi in avanti negli ultimi anni, diversi sono i progetti

interessanti ai quali attualmente si sta lavorando in tutto il mondo; c‟è chi ha come

obiettivo quello di costruire un cervello artificiale e chi mette a punto tecniche

sempre più sofisticate per l‟analisi del suo funzionamento. La seguente immagine mostra

una mappa del cervello ricostruita al computer.

Page 13: Introduzione alle reti neurali artificiali

13

Matteo Tosato - Introduzione alle reti neurali artificiali

Figura 7: Mappa 3D del cervello (non completa)

Il neurone artificiale

Considerazioni principali

Che cosa ha fatto l‟informatica dunque? Bè nulla di speciale se posso esprimere un

parere personale, ha spudoratamente copiato dalla Natura il principio di funzionamento

trovato nel neurone biologico, le equazioni che descrivono i neuroni come dei

generatori di elettricità furono scoperte da due premi Nobel di Cambridge.

Per applicare tale principio, il neurone è stato di molto

semplificato e adattato. Nonostante questo le sue proprietà

fondamentali sono state conservate.

La struttura base è costituita da „i‟ ingressi, una funzione

di attivazione „Ө‟, una uscita „y‟, un peso „w‟ per ogni

sinapsi ed un valore soglia „ט‟ il quale servirà eventualmente

per normalizzare gli input.

Page 14: Introduzione alle reti neurali artificiali

14

Matteo Tosato - Introduzione alle reti neurali artificiali

P

W1

W2

X1

X2

Wi

Xi

Ө(P) Y.

.

.

Figura 8: Neurone artificiale schematizzato

Il numero degli ingressi può variare da un minimo di 1 ad un valore positivo intero

qualunque. In figura, ciò che ho indicato con la lettera P all‟interno del neurone è il

suo potenziale. Questo potenziale si ottiene dalla sommatoria dei valori in input

tenendo conto del peso sinaptico ad essi associata.

Definiamo quindi la seguente formula per il potenziale P:

∑( )

Questo potenziale non è il valore trasferito al neurone successivo ma solo un valore

intermedio che verrà utilizzato della funzione al momento del trasferimento. La variabile „n‟ rappresenta ovviamente il numero di input presenti. La variabile

soglia , che viene sottratta ogni volta che l‟input viene moltiplicato al peso sinaptico, ha lo scopo di normalizzare tale input in modo che rientri in un valore

compreso tra -1 e 1. Ma questo non sempre viene fatto, spesso i dati sono normalizzati

prima di essere inseriti in ingresso.

Difficilmente una rete neurale può lavorare con input molto grandi e nello scopo

dell‟utilizzo avrebbe poco senso. Pensiamo a una immagine la quale ridotta in pixel

viene analizzata attraverso una rete neurale, ogni pixel può benissimo avere valore 0 o

1, ad indicare colore o bianco.

Il trasferimento, in questo caso, coincide anche con il valore di uscita Y definito

dalla formula seguente:

( ∑( )

)

Ci resta ora da definire la funzione di trasferimento . Essa dipende strettamente con quello che la rete neurale dovrà fare e dal tipo di

architettura scelta.

Di seguito presento le funzioni di utilizzo più comune. (Riporto grafico e sintassi di

matlab).

La prima che vediamo è chiamata funzione a gradino o binaria. Vi è solo una lieve

differenza fra le due. Questa è utilizzata nelle configurazioni semplici quando si ha

un solo elettrone ed un solo strato.

Page 15: Introduzione alle reti neurali artificiali

15

Matteo Tosato - Introduzione alle reti neurali artificiali

{

e {

Questa funzione viene utilizzata quando è prevista un‟uscita con valore zero oppure

eccitatoria, quindi quando input e output sono booleani. quella a gradino naturalmente

varia per il caso con x minore o uguale a zero dove il valore di y è -1.

Un‟altra funzione di uso comune è quella lineare anche chiamata identità, la bisettrice

del primo e terzo quadrante.

*

Per valori di y crescenti possiamo invece ricorrere alla funzione a saturazione

lineare.

{

La funzione sigmoidale è una delle più importanti, specie nelle reti dove viene

utilizzato l‟apprendimento back-propagation. Viene chiamata anche funzione logistica.

L‟equazione che la descrive è:

Page 16: Introduzione alle reti neurali artificiali

16

Matteo Tosato - Introduzione alle reti neurali artificiali

Essa è sempre crescente, è continua su tutto l‟asse dei reali ed è derivabile, vale 1 a

+∞ e 0 a -∞, questa funzione è la più utilizzata nelle reti multistrato dove è importante avere risultati nel continuo, però presenta un “problema”, essendoci un

esponenziale risulta piuttosto gravosa in termini di calcoli (considerate che ogni

neurone ha una funzione di attivazione e le uscite vanno calcolate miliardi di volte).

Quando si ha necessità di avere spesso valori in uscita inibitori possiamo utilizzare

la tangente iperbolica. La cui equazione è:

In ultimo le “radial basis functions”, simile alla funzione di Gauss:

Ora che conosciamo il neurone artificiale siamo in grado di affrontare le principali

configurazioni.

I neuroni possono essere combinati in tantissimi modi per ottenere la rete neurale dal

comportamento voluto. Nelle reti i neuroni si stimolano reciprocamente, quindi l‟uscita

y che abbiamo visto prima diventa l‟input di un altro neurone e via dicendo fino ad

arrivare ad una uscita non connessa che rappresenta l‟output dell‟intera rete. La rete

come per quelle biologiche, va a modificare i propri pesi sinaptici dei neuroni

attraverso algoritmi di apprendimento dipendenti dalla configurazione, in questo modo

si possono ottenere comportamenti diversi.

L‟output della rete potrà convergere, crescere oppure oscillare. Solitamente una rete

utile ha una uscita che converge verso il valore desiderato. Una NN con uscita sempre

Page 17: Introduzione alle reti neurali artificiali

17

Matteo Tosato - Introduzione alle reti neurali artificiali

crescente si dice che “esplode”, proprio perché la sua uscita diventerà presto

intrattabile. Una NN con uscita oscillatoria significa che compie un ciclo ripetitivo,

come vizioso.

Riassumendo, possiamo dire che una NN è composta da neuroni e che corregge i propri

pesi sinaptici ad ogni attivazione di questi.

La rete appena creata sarà inservibile per il suo scopo finale, perché avrà pesi

sinaptici non corretti. (e questo vale per le configurazioni più utilizzate). Dobbiamo

sottoporre tale rete ad un periodo di “training”. Durante questa fase dovremo fornire

in input un set di valori e il corretto output, in modo da correggere i pesi in maniera

opportuna. La rete in questo modo raggiunge il comportamento desiderato per tutta la

classe di input. Una volta che è stata raggiunta la precisione desiderata, i pesi

sinaptici vengono congelati e la NN è pronta all‟uso.

Le configurazioni più comuni sono NN non ricorrenti, totalmente connesse, a livelli,

simmetriche, auto associative, stocastiche e asincrone. Di seguito mostro alcuni

modelli.

Rete non ricorrente:

output

input In questo tipo di reti le connessioni vanno in un solo senso, dall‟input all‟output. E‟

esattamente il contrario delle reti chiamate “cicliche”.

Rete totalmente connessa:

In questo tipo di rete ogni neurone che la compone è connesso con tutti gli altri,

escluso se stesso. Si noti che un peso sinaptico con valore nullo corrisponde

all‟assenza di connessione, abbiamo visto prima l‟equazione del potenziale dove input

viene moltiplicato al peso, quindi con w = 0, l‟input non viene trasferito. Solitamente

in queste reti alcuni pesi vengono inizializzati a zero.

Rete a più livelli: (totalmente connessa a più livelli)

Page 18: Introduzione alle reti neurali artificiali

18

Matteo Tosato - Introduzione alle reti neurali artificiali

input

output

Reti in cui le unità sono organizzate in insiemi separati e disgiunti di cui

generalmente uno è detto di input, un altro di output e gli altri vengono detti

“nascosti” oppure “intermedi”.

Rete simmetrica:

Nelle reti simmetriche ogni connessione fra due qualsiasi neuroni è uguale in entrambi

i sensi: Wij = Wji

Rete auto associativa:

Quest‟ultimo tipo è utilizzato proprio per l‟intelligenza artificiale. Queste hanno il

compito di ricevere un segnale in input e farlo evolvere restituendo un output

leggermente modificato, proprio quelle che avviene nel cervello umano.

Per gli scopi più applicativi, vengono utilizzate quelle a più livelli interamente

interconnesse tra questi. A questa poi si dovrebbe aggiungere anche un ulteriore

configurazione, ovvero quelle a più livelli ricorrenti. Queste possono avere anche

sinapsi che collegano neuroni di uno stesso livello.

Page 19: Introduzione alle reti neurali artificiali

19

Matteo Tosato - Introduzione alle reti neurali artificiali

Ma la configurazione più semplice è quella che fa uso di un solo neurone. Essa trova

impiego oltre ai fini didattici, anche in diversi campi di applicazione. È infatti già

in grado di fare alcuni tipi di classificazioni, partiremo da questa e proseguendo,

vedremo i suoi limiti rispetto alle configurazioni più avanzate.

Interpretazione vettoriale

In questo paragrafo interpretiamo il comportamento del neurone artificiale in chiave

vettoriale.

Possiamo considerare i valori di input come componenti del vettore , e i valori dei

pesi sinaptici componenti del vettore .

Tale che:

* + e * +

La sommatoria eseguita dal neurone, corrisponde al prodotto scalare dei due vettori:

∑( )

Dove è l‟angolo formato dai due vettori.

X

W α

Secondo le considerazioni appena fatte, il prodotto interno dei due vettori corrisponde

alla risposta del neurone. Se immaginiamo di muovere i due vettori, il prodotto interno

sarà proporzionale al coseno dell‟angolo .

Immaginiamo la situazione seguente:

W2 = 0,8W1 = 0,3

X2 = 0,3X1 = 0,7

Con pesi normalizzati si ha:

Page 20: Introduzione alle reti neurali artificiali

20

Matteo Tosato - Introduzione alle reti neurali artificiali

|| |||| ||

|| |||| ||

La norma del vettore corrisponde alla sua lunghezza:

|| || √ √

Il prodotto interno sarà tanto maggiore quanto è minore la distanza dei due vettori

all‟interno dello stesso quadrante. Quando la risposta è uguale a 0 i due vettori sono

ortogonali fra di loro; quando è maggiore di 90° la situazione è simmetrica e l‟unità

assume valori negativi.

Prendendo come esempio il neurone con funzione di attivazione binaria, avremo che

l‟output può assumere valore attivo (1, vettori con distanza < 90°) o rimanere silente

(0, vettori con distanza > 90°).

In una rete di molti neuroni è possibile determinare quale neurone possiede valori

sinaptici più simili all‟input dato il suo valore di attivazione solo se i valori sono

normalizzati, ovvero se la loro somma risulta uguale all‟unità.

Apprendimento del perceptron

Il punto di forza assoluto delle ANN (Artificial neural networks) è l‟apprendimento.

Secondo Donald Hebb, a livello biologico un collegamento fra due neuroni subisce un

rinforzo nel momento in cui si ha una attivazione del rispettivo neurone postsinaptico.

Allo stesso modo, nelle reti artificiali avremo un aggiustamento in positivo del valore

sinaptico secondo un determinato algoritmo di addestramento.

1 0 0

1 0 1 0

Generalizzando, il processo di addestramento per una ANN si suddivide in 5 fasi, queste

sono valide in quasi ogni scenario di addestramento:

- Si crea la struttura dati necessaria; si può lavorare ad oggetti o con matrici,

quest‟ultimo prevede uno sforzo in più ma è altamente più efficiente e sintetico.

- I pesi vengono inizializzati, ad esempio con un valore casuale compreso tra -1 e 1.

- Viene eseguita la fase di training. Dovremo fornire alla rete neurale due input: gli

ingressi e le uscite (target, ovvero quello che la rete dovrebbe dare in uscita) Si

esegue la computazione secondo il principio di attivazione del neurone visto prima e

viene confrontato il risultato ottenuto con il desiderato.

Page 21: Introduzione alle reti neurali artificiali

21

Matteo Tosato - Introduzione alle reti neurali artificiali

- A questo punto vengono calcolate le variazioni dei pesi quindi aggiornati di

conseguenza. La fase di training viene ripetuta fino a che la rete non converge al

risultato desiderato.

- A questo punto la rete è pronta per l‟utilizzo.

Ogni ciclo a cui la rete è sottoposta durante la fase di training è detto un‟epoca.

Durante un‟epoca vengono presentati tutti gli input del training set. Ad esempio, per

un problema come l‟OR logico ne occorreranno davvero poche. L‟algoritmo di

apprendimento è quindi iterativo e viene eseguito per ogni esempio.

Notare che, in termini più generali, esistono due modalità con le quali correggere i

valori sinaptici. La prima, denominata addestramento „batch‟, consiste nell‟aggiornarne

i valori dopo la presentazione dell‟intero pattern set, ovvero dopo aver proposto alla

rete tutti gli esempi. L‟errore della rete per il pattern set è l‟errore quadratico

medio che analizzeremo in seguito.

Un‟altra modalità è detta „on-line‟. In questo caso la correzione dei pesi viene

eseguita ad ogni iterazione su singolo esempio.

La regola di Hebb

Donald Hebb, studioso originale e unico nel panorama della psicologia del „900, fu un

precursore di molte teorie e scoperte successive, e fu uno dei primi scienziati ad

approfondire il legame tra il sistema nervoso e comportamento.

Come abbiamo detto in precedenza, una connessione subisce un rinforzo quando si ha

un‟attivazione del suo neurone postsinaptico. Quando si utilizza questo metodo, il

valore di inizializzazione per i neuroni è 0.

La variazione sinaptica è definita dall‟equazione:

Dove è il tasso di apprendimento (learning rate), questo valore specifica la capacità di apprendimento della rete, può avere un valore compreso tra 0 e 1. Più

questo valore è alto più la rete apprenderà velocemente, ma sarà anche meno precisa, è

in definitiva, un parametro dinamico per risolvere eventuali problemi di prestazione e

precisione in fase di apprendimento.

Per ciascuna coppia di pattern si ha:

Questo metodo rappresenta la base su cui tutti o quasi i successivi metodi di

addestramento si sono sviluppati. Nonostante questo essa possiede molti limiti. Ad

esempio, data lo sola possibilità di aumentare il valore delle sinapsi, i pattern di

input non dovrebbero avere elementi in comune, perché questo causerebbe l‟attivazione

di tutti i corrispondenti neuroni attivati in precedenza per qual particolare input.

Questo effetto viene definito come “interferenza”. Pertanto la regola di Hebb permette

di apprendere solo pattern ortogonali, ovvero pattern la cui somma dei prodotti dei

singoli componenti è zero.

Page 22: Introduzione alle reti neurali artificiali

22

Matteo Tosato - Introduzione alle reti neurali artificiali

La regola postsinaptica

Stent (1987) e Singer (1973), viste le grosse limitazione della regola di Hebb misero a

punto un metodo chiamato regola postsinaptica che ha come obiettivo ridurre l‟effetto

di “interferenza” prima definito, quando si lavora con input parzialmente sovrapposti.

L‟idea sta nell‟aggiunta di una regola oltre quella di Hebb, la condizione permette di

diminuire il valore delle sinapsi quando l‟unità postsinaptica è attiva e l‟unità

presinaptica è inattiva:

( ( ) )

Nonostante l‟introduzione di questa regola riduca l‟effetto interferenza, essa tende a

creare sinapsi inibitorie quindi non è in grado di apprendere correttamente in caso di

input sovrapposti parzialmente.

La regola presinaptica

La regola presinaptica prevede una condizione simmetricamente opposta alla regola di

Stent-Singer. Il valore della sinapsi viene diminuito quando l‟unità postsinaptica è

inattiva e quella presinaptica è attiva:

( ( ) )

Questa funzione meglio della precedente quando molti pattern di input diversi

parzialmente sovrapposti debbono essere classificati con lo stesso pattern.

La regola delta

Ritornando ad una rappresentazione più astratta dei vettori sinaptici e di input,

prendiamo in esame un problema come quello dell‟operazione logica OR.

Tale operazione prevede due input che possono assumere valore 0 oppure 1. E prevede per

l‟uscita medesimi possibili valori. Si ha quindi una tabella di verità del tipo

seguente:

X1 X2 Y

0 0 0

0 1 1

1 0 1

1 1 1

Tabella 1: Tabella di verità OR logico

La rappresentazione n-dimensionale del problema OR è la seguente:

Page 23: Introduzione alle reti neurali artificiali

23

Matteo Tosato - Introduzione alle reti neurali artificiali

(1,1)

(1,0)(0,0)

(0,1)

X1

X2

Quando si parte con pesi sinaptici casuali, equivale ad avere in partenza una retta che

non separerà i punti in modo corretto. (sarà una retta con inclinazione e

posizionamento casuale)

Cambiando l‟inclinazione della retta, ovvero modificando il valore dei pesi sinaptici,

possiamo arrivare a separare gli input correttamente.

E‟ evidente anche la necessità di utilizzare anche delle soglie, chiamate „bias‟ per

poter traslare oltre che ruotare la retta.

Uno degli algoritmi notevoli che consente di effettuare questa operazione è appunto la

regola delta, anche chiamato algoritmo di addestramento specifico del perceptron.

Il principio è semplice, si basa sul calcolo dell‟errore in output.

Poi, su questo, si aggiornano i pesi in modo tale da convergere verso il risultato

corretto.

Definiamo l‟errore con la seguente equazione:

Il delta è l‟errore commesso della rete neurale per l‟esempio k-esimo, „Exp‟ è il

valore atteso mentre Y è l‟output dato dalla rete.

Da cui troviamo il “delta weight”, ovvero la variazione da applicare al peso:

Dove η è il “learning rate”, X è l‟input k-esimo della rete.

Dunque, l‟aggiornamento del peso sinaptico avviene seguendo la regola seguente:

( )

Quando il “delta error” raggiunge il valore desiderato, i pesi possono essere

“congelati”. E la rete è pronta per svolgere il suo lavoro.

Esempio addestramento perceptron tramite delta rule

Vediamo una rete a percettrone a livello di programmazione, con mio rammarico molti

libri trattano le reti neurali solo in modo teorico, senza fornire sorgenti in

linguaggio o pseudo-linguaggio di esempio nemmeno per le più semplici configurazioni.

Per questo motivo cerco dove possibile di fornire anche un minimo di materiale

esemplificativo.

Page 24: Introduzione alle reti neurali artificiali

24

Matteo Tosato - Introduzione alle reti neurali artificiali

All‟interno del sorgente, la prima cosa di cui occuparci è definire le strutture dati

che compongono la rete neurale. Qui sono possibili approcci diversi. Seguendo un metodo

prettamente logico, possiamo definire delle strutture dati o classi che descrivono ogni

parte della rete. Ad esempio ragionando ad oggetti, definiremo la classe neurone ed i

suoi metodi. Una classe neurone è adatta ad contenere già tutte le possibili funzioni

di trasferimento. Poi una classe sinapsi, una classe livello per le reti multilivello e

via discorrendo…

Oppure, possiamo utilizzare un approccio un po‟ meno ordinato ed utilizzare in modo

intelligente le matrici. Utilizzando le matrici si ha un notevole risparmio di risorse

e maggiore velocità di elaborazione.

Per la fase di training dobbiamo definire un metodo per fornire input e target alla

rete. Di norma sono utilizzati file .xml. Infatti la stessa rete neurale è utile per

scopi differenti, il file xml prepara questa al lavoro desiderato. Per semplicità noi

cominceremo da un file .dat che contiene i dati disposti semplicemente in righe. Per

l‟operazione OR ci basterà definire gli input. L‟output possiamo calcolarlo con

l‟operazione che fornisce il linguaggio. Se vi state chiedendo che utilità ha un rete

neurale che fa un‟operazione come l‟OR, già fornita dalla comodissima operazione C “|”,

vi rispondo che non serve a nulla, la presento al sol scopo di capire come sia

possibile impartire al calcolatore istruzioni sequenziali per descrivere una logica, in

comprensivo, non sequenziale.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

// Uncomment follow line to avoid debug messages

#define _DEBUG_

#define FAILURE 1

#define SUCCESS 0

// Define neurons

#define INPUT_N 2

#define OUTPUT_N 1

// Set precision

#define PRECISION double

// Define Learning rate

#define _L_RATE 0.5

// Define network desired accuracy

#define ACCEPTABLE_DELTA 0.05

// Training file

#define FTRAINING_PATH

"H:\\AI_sources\\Windows\\Learning\\test_nn01\\bin\\Debug\\training.dat"

// Perform training

int __n_network_training(const char*,unsigned int);

// Neural network weights

PRECISION weights[INPUT_N][OUTPUT_N];

PRECISION pot;

int input[INPUT_N];

PRECISION output[OUTPUT_N];

La matrice weights rappresenta tutti i pesi del percettrone che saranno solamente due

dati i soli due input. Come vedete ho definito anche il file training.dat il quale

Page 25: Introduzione alle reti neurali artificiali

25

Matteo Tosato - Introduzione alle reti neurali artificiali

contiene gli input 0 e 1 nelle loro combinazioni. La funzione __n_training() si occupa

dell‟addestramento della rete. La funzione è la seguente:

int __n_network_training(const char* path,unsigned int epochs) {

// Checks...

if(epochs <= 0) return FAILURE;

if(path <= 0) return FAILURE;

int input[2];

PRECISION exp_output,netout,pot,delta_err,delta[INPUT_N];

char*n = malloc(16);

char*nptr = n;

unsigned int k = 0, persistant_accuracy = 0;

input[0] = -1;

input[1] = -1;

// Get training set from file

FILE* fp = fopen(path,"r");

if(fp == NULL)return FAILURE;

char c = 0;

while(c != EOF || epochs > 0) {

while(input[0] == -1 || input[1] == -1)

{

c = (char)fgetc(fp);

if(c == ';') {

input[k] = atoi(n);

(k == 1) ? k = 0 : k++;

n = nptr;

} else {

sprintf(++n,"%c",c);

}

}

// Learn OR operation

exp_output = input[0] | input[1];

// Potential of output neurons

pot = weights[0][0] * input[0];

pot += weights[1][0] * input[1];

// Net output (with linear transfer function)

netout = (pot > 0.0) ? 1.0 : 0.0;

// Compute delta error

delta_err = exp_output - netout;

// Compute delta

delta[0] = delta_err * _L_RATE * input[0];

delta[1] = delta_err * _L_RATE * input[1];

// Update weigths

weights[0][0] += delta[0];

weights[1][0] += delta[1];

// Check neural network accuracy

if(persistant_accuracy >= 10) {

break;

} else {

if(delta_err < ACCEPTABLE_DELTA) {

persistant_accuracy++;

} else persistant_accuracy = 0;

}

#ifdef _DEBUG_

Page 26: Introduzione alle reti neurali artificiali

26

Matteo Tosato - Introduzione alle reti neurali artificiali

printf("in: %d - %d out: %lf\n",input[0],input[1],netout);

#endif

// Restore

input[0] = -1;

input[1] = -1;

// Decrement epochs

epochs--;

}

fclose(fp);

free(n);

return SUCCESS;

}

Dopo le inizializzazioni, un ciclo while() su occupa dell‟addestramento, vengono

prelevati i dati dal file di training. Questi sono memorizzati in questo modo:

0;0;0;1;1;0;1;1;0;0;0;1;1;0... E‟ una serie che si ripete. Il risultato target viene

calcolato con l‟OR canonico, poi viene calcolato il potenziale, subito dopo la funzione

di attivazione restituisce 1 se il potenziale è maggiore di 0, infine viene calcolato

il delta error e la variazione post-sinaptica che viene utilizzata poi per

l‟aggiornamento dei pesi.

La funzione main() è così definita:

int main()

{

char answer[16];

// Init

int x,y;

for(x=0;x<INPUT_N;x++) {

for(y=0;y<OUTPUT_N;y++) {

weights[x][y] = ((rand()%2000)/(PRECISION)(1000.0)-(PRECISION)1.0);

}

}

if(__n_network_training(FTRAINING_PATH,-1) == FAILURE) {

fprintf(stderr,"[+] FATAL! - Training failure... or epochs not

sufficient");

return FAILURE;

} else {

printf("[+] - Neural network trained!\n");

}

while(1) {

printf(" - Type first input: ");

scanf("%d",&input[0]);

printf(" - Type second input: ");

scanf("%d",&input[1]);

// Calculate potential of output neuron

pot = weights[0][0] * (PRECISION)input[0];

pot += weights[1][0] * (PRECISION)input[1];

// Net output (with linear transfer function)

output[0] = (pot > 0.0) ? 1.0 : 0.0;

printf(" - Network output: %f\n",output[0]);

printf("continue s/n?");

scanf("%16s",answer);

Page 27: Introduzione alle reti neurali artificiali

27

Matteo Tosato - Introduzione alle reti neurali artificiali

if(strcmp(answer,"s")) {

break;

}

}

return SUCCESS;

}

Prima vengono iniziati i pesi ad un valore casuale nel range -1:1.

Poi viene chiamata la funzione di addestramento.

A seguito viene chiesto all‟utente di inserire gli input, la rete calcola il risultato

correttamente.

La rete neurale è inoltre in grado di restituire valori corretti anche in presenza di

input non pulito (rumore in input). Ad esempio provate ad inserire 0.90 al posto di 1

oppure 0.20 al posto di 0. La rete restituisce comunque output coerenti, dato che la

funzione di attivazione fornisce una certa “tolleranza” d‟errore, Le reti neurali fanno

quindi parte delle tecnologie dette a “logica fuzzy”.

Più utilizziamo un learning rate basso, più tempo la rete ci metterà ad apprendere, più

sarà in grado di restituire output corretti anche in presenza di rumore.

Valutazione delle disuguaglianze

Il metodo che vedremo di seguito viene chiamato “valutazione delle disuguaglianze”.

Lo scopo di questo metodo sta nel poter valutare a priori, la dove è possibile, se

stiamo affrontando un problema che possiede delle soluzioni “linearmente separabili”.

Ovvero se esiste un retta in grado di separare gli input. Come è avvenuto nell‟esempio

OR oppure no.

Partiamo da un esempio, la tabella che segue mostra input ed output del “problema di

parità”. Qui abbiamo 3 input, quindi un neurone tridimensionale. L‟output dipende dal

numero di ingressi posti ad uno. Quando essi sono dispari l‟output del neurone deve

dare uno, quando sono pari 0.

X1 X2 X3 Y

0 0 0 0

0 0 1 1

0 1 0 1

0 1 1 0

1 0 0 1

1 0 1 0

1 1 0 0

1 1 1 1

Tabella 2: Tabella di verità del problema di parità

Abbiamo quindi due classi A e B.

*( ) ( ) ( ) ( )+

*( ) ( ) ( ) ( )+

Siccome non abbiamo un numero di input eccessivo, possiamo ancora rappresentare

graficamente le soluzioni:

Page 28: Introduzione alle reti neurali artificiali

28

Matteo Tosato - Introduzione alle reti neurali artificiali

X2

X1

X3

(1,0,0)

(1,1,0)(0,1,0)

(0,1,1)

(0,0,1)

(0,0,0)

(1,1,1)

(1,0,1)

I pallini bianchi sono l‟output pari a 0.

Ora partendo dall‟equazione utilizzata per trovare l‟output della rete Y:

( ∑( )

)

Possiamo considerare il valore soglia ט come un ulteriore peso “-W0”. Da questo deriva che:

( )

A questo punto per ogni serie di argomenti possiamo scrivere la relativa

disuguaglianza:

1) - (0,0,0) 2) – (0,0,1) 3) – (0,1,0) 4) – (0,1,1) 5) – (1,0,0) 6) – (1,0,1) 7) – (1,1,0) 8) – (1,1,1)

Ora qui è sufficiente trovare le contraddizioni per capire che il problema non è

risolvibile linearmente. Ne basta una, ad esempio la quarta si contraddice con la

numero 2 e 3. Dati n input sono presenti disuguaglianze.

Tornando alle due classi A e B e alle loro definizioni, possiamo dire che la prima

avrà:

E per la seconda:

Page 29: Introduzione alle reti neurali artificiali

29

Matteo Tosato - Introduzione alle reti neurali artificiali

Allora la serie di punti per i quali rappresentano un iperpiano bidimensionale in uno spazio tridimensionale che separa le soluzioni del

problema se questo è separabile linearmente.

Un altro principio molto importante è il teorema di Cover del 1965, di cui non sto a

riportare la dimostrazione. Esso afferma che dato un numero di input per

l‟addestramento non linearmente separabili, uno può probabilmente trasformare questo in

un set linearmente separabile proiettandolo in uno spazio multidimensionale attraverso

alcune trasformazioni non lineari.

La seguente equazione definisce C come il numero di funzioni a soglia lineari per un

problema ad n dimensioni. (n input):

( ) ∑(

)

La funzione parziale , viene sostituita dal numero di esempi, serie di valori per il

training di un‟epoca.

Reti neurali MLP (Multi layer perceptron)

Nei capitoli precedenti abbiamo descritto ampiamente il perceptron e capito cosa si

intende per separazione lineare degli input.

Nell‟esempio „OR‟ sono presenti i passaggi minimi necessari per avere una rete neurale

minimale, con un solo neurone, che simula la porta logica OR.

In questo capitolo inizieremo con il descrivere alcuni dei limiti di cui questa

configurazione soffre, e in seguito, vedremo che partendo dal perceptron è possibile

comporre reti più ampie componendole in più livelli.

Tornado alla rappresentazione n-dimensionale del problema OR, dove „n‟ corrisponde al

numero degli input del neurone:

(1,1)

(1,0)(0,0)

(0,1)

X1

X2

La combinazione di input 0,0 è l‟unica che fornisce 0 in output. Si dice quindi che

questo problema (l‟OR) ha soluzioni linearmente separabili.

Ora cercheremo di addestrare la rete per eseguire l‟operazione booleana Exclusive-

Or,(XOR). La seguente è la tabella di verità:

Page 30: Introduzione alle reti neurali artificiali

30

Matteo Tosato - Introduzione alle reti neurali artificiali

X1 X2 Y

0 0 0

0 1 1

1 0 1

1 1 0

Tabella 3: Tabella di verità XOR

Il grafico delle soluzioni sarà identico al precedente a parte la disposizione della

retta di colore rosso. O meglio, non si tratterà più di una retta.

Non riusciremo mai a separare le soluzioni con l‟ausilio una retta. Questo significa

che il percettrone bidimensionale non è in grado di risolvere problemi che hanno

soluzioni separabili non linearmente. Come in questo caso, il percettrone non può

risolvere il problema XOR.

Le soluzioni dell‟XOR non sono linearmente separabili.

Ci occorre un altro tipo di configurazione, il seguente grafico mostra come le

soluzioni vengono divise da una rete neurale completamente connessa tra i suoi 3

livelli:

(1,1)

(1,0)(0,0)

X1

X2

(0,1)

Reti neurali a due strati (M-Adeline)

Aggiungendo al percettrone un livello in più si ottiene una rete “M-Adeline” costituita

da 2 livelli distinti. Questa non consente ancora di risolvere il problema XOR, ma si

presta per introdurre un nuovo genere di algoritmi di addestramento, più complessi.

Metodi adeguati anche per reti con più di due livelli.

Page 31: Introduzione alle reti neurali artificiali

31

Matteo Tosato - Introduzione alle reti neurali artificiali

W3

W2

Wi

.

.

.

X1

X2

Xi

Y

Figura 9: M-Adeline

In questo caso, i neuroni di output devono avere una funzione di attivazione

derivabile, i neuroni di input una funzione binaria o continua. Questa configurazione è

in grado di distinguere gli input e suddividerli in classi diverse, l‟importante è che

ognuna sia linearmente separabile dall‟altra. E‟ sufficiente che ogni neurone di output

j rappresenti la corrispondente classe j e che, presentando input della classe j, si

abbia: ∑ ( ) ∑ ( ) per tutti gli indici k diversi da un determinato j.

La reti M-ADALINE possono essere addestrate tramite l‟algoritmo di “Windrow-Hoff”.

In modalità on-line viene riassunto nelle fasi seguenti:

- Si presentano sequenzialmente gli esempi del training set. Per ogni esempio k, ogni

neurone j fornirà generalmente un output diverso da quello target , con un

errore. Quindi avremo che l‟errore della rete è dato da ( ) e un errore quadratico medio E su tutti gli esempi dato da:

∑∑( )

- L‟errore ottenuto deve essere minimizzato aggiornando il valore dei pesi, questa

variazione delta è definita come: (ottenuta tramite la regola del gradiente da

):

∑[( ) ]

Qui a seconda della funzione di attivazione utilizzata avremo casi differenti, ad

esempio:

Funzione di trasferimento sigmoide:

( )

( ) ( )

∑[( ) ( ) ]

Funzione di trasferimento tangente iperbolica:

( )

( )

Page 32: Introduzione alle reti neurali artificiali

32

Matteo Tosato - Introduzione alle reti neurali artificiali

∑[( )( ) ]

Funzione di trasferimento lineare:

( ) ( )

∑[( ) ]

- Infine la correzione dei pesi sinaptici avviene sempre tramite la formula:

( ) ( ) .

- A questo punto viene valutato l‟errore e se ancora non soddisfacente viene ripetuto

il procedimento.

L‟algoritmo descritto viene eseguito effettuando le correzioni dei pesi sinaptici ad

ogni singolo esempio sottoposto:

[( ) ]

Architetture Feed-forward

Una rete MLP (Multi layer perceptron) è una rete i cui neuroni compongono più livelli

e, tra loro, sono completamente interconnessi. I livelli sono minimo 3, fra input,

output e nascosto.

Questi ultimi possono variare a qualsiasi numero.

Questa configurazione è una delle più utilizzate in assoluto ed è in grado di risolvere

molti problemi, quindi anche quelli che non hanno soluzioni separabili linearmente.

Si parla di configurazioni feed-forward perché gli input seguono una sola direzione,

dai neuroni di input a quelli di uscita, senza mai tornare indietro o passare a un

neurone vicino.

Se supponiamo di avere una rete con 3 input, ed un problema con soluzioni non

separabili, ora i neuroni facente parte del layer nascosto inseriscono piani aggiuntivi

consentendo la separazione dei vertici di classe A da quelli di classe B. Quindi per un

generico problema tridimensionale la rappresentazione grafica delle sue soluzioni

appare come la seguente:

Page 33: Introduzione alle reti neurali artificiali

33

Matteo Tosato - Introduzione alle reti neurali artificiali

X2

X1

X3

Figura 10: Piano bidimensionale di separazione in uno spazio tridimensionale

La struttura della rete è dunque come la seguente:

X1 X2 X3

Figura 11: Esempio di ANN feed-forward

Più layer nascosti inseriamo più siamo in grado di effettuare separazioni complesse.

I neuroni degli strati nascosti non possono avere funzioni di trasferimento lineare

altrimenti la rete sarebbe equivalente ad una a due strati e non potrebbe separare le

soluzioni in modo non lineare.

Per fissare il concetto, immaginiamo la seguente situazione di lavoro; due input ,

due numeri nascosti con pesi sinaptici rispettivi e un neurone

output O, con pesi sinaptici e .

X1

X2

N1

N2

OW21

W22

W12

W11

V1

V2

Page 34: Introduzione alle reti neurali artificiali

34

Matteo Tosato - Introduzione alle reti neurali artificiali

( ) ( ) ( ) ( )

Date le equazioni che abbiamo ricavato possiamo considerare

tutto come due input , un output O e pesi sinaptici .

A differenza dei livelli input ed output il cui numero di

neuroni è definibile, non c‟è un metodo altrettanto rigoroso

per definire il numero di livelli nascosti necessari e nemmeno

il numero dei neuroni necessari per ognuno di questi livelli.

La definizione del numero di livelli avviene per via di

osservazioni ripetute sull‟allenamento e tramite l‟esperienza

accumulata su problemi simili.

Feed-forward ricorrenti

Una configurazione particolare delle reti feed-forward è la cosiddetta “rete di Elman”.

Questa possiede oltre al primo strato di neuroni nascosti, anche un layer „contesto‟ in

cui vengono memorizzati gli stati di attivazione precedenti.

Questo ha lo stesso comportamento degli altri strati, in partenza il valore di

attivazione di questi neuroni sarà pari ad 1. Poi conterrà sempre il valore di uscita

del primo layer nascosto all‟istante .

Le connessioni sinaptiche dallo strato intermedio a quello di contesto valgono 1,

mentre quelle in direzione inversa sono inizializzate casualmente e soggette al

processo di addestramento in modo analogo a tutte le altre.

Questa configurazione permette alla rete di ricordarsi di ciò che è successo in

precedenza. E‟ un‟ottima soluzione quando si utilizza una rete per la previsione di

funzioni complesse.

I1

I2

I3

In

H1(t)

H2(t)

Hn(t)

yj

H1(t-1)

H2(t-1)

Hn(t-1)

Figura 12: Rete feed-forward con connessioni ricorrenti

Page 35: Introduzione alle reti neurali artificiali

35

Matteo Tosato - Introduzione alle reti neurali artificiali

Le connessioni segnate in rosso sono quelle di valore unitario che riportano le uscite

dei neuroni all‟ingresso del ciclo successivo.

Error back-propagation (EBP)

Uno degli algoritmi con cui è possibile addestrare reti di questo tipo è denominato

“Error back-propagation”.

Questo nome è dovuto al fatto che l‟errore calcolato su ciascun layer da partire

dall‟ultimo viene consegnato al layer precedente e così via.

La definizione matematica dell‟algoritmo è la seguente:

Partendo dall‟equazione dell‟errore quadratico medio, e applicando a questo la regola

del gradiente, ricaviamo l‟equazione per il calcolo della variazione dei pesi, riporto

tutti i passaggi:

( ) ( )

( )

( )

(∑ )

( ) ( ) (A)

Ponendo:

( ) ( ) (B) Si ottiene la seguente:

(C)

Questa regola viene utilizzata per aggiornare i pesi dei livelli output e nascosto.

Analogamente, per quanto riguarda le connessioni tra stato di input e strato nascosto:

( )

Se confrontiamo questa formula con la precedente formula A, al posto degli errori noti

( ) troviamo le derivate

, che dobbiamo ora calcolare retropropagando l‟errore

dallo strato output a ogni neurone nascosto:

∑(

) ∑( ) ( )

O anche applicando la formula B:

Page 36: Introduzione alle reti neurali artificiali

36

Matteo Tosato - Introduzione alle reti neurali artificiali

Ottenendo:

( )(∑ ) (D)

Che ponendo:

( ) .∑ / (E)

Assume anche la forma della C:

(F)

Le formule D,E,F sono valide per aggiornare i pesi dei livelli nascosto, input e anche,

in reti più generali, per le connessioni tra due strati nascosti consecutive. Ad

esempio se adottiamo la funzione sigmoide, è:

( )

( ) ( ) ( )

Dove k è proporzionale alla pendenza della sigmoide nel suo punto di flessione:

Normalmente si pone k = 1, altre volte k=1/T dove T è denominata temperatura per motivi

che vedremo in seguito. In ogni caso le formule A e D diventano rispettivamente:

( ) ( ) (A‟)

( )(∑ ) (D‟)

I pesi sinattici vengono aggiornati, ad ogni tempo t dell‟intervallo 1,2...,(t-

1),t,(t+1),...etc.

( ) ( ) (G)

( ) ( ) (H)

Per comprendere in modo completo le nuove nozioni, ricorriamo per esempio al problema

dell‟XOR.

In precedenza avevamo visto come la configurazione a singola unità è incapace di

risolvere il problema. Ora invece utilizzeremo una rete che abbia due input, due

neuroni nello strato nascosto ed un neurone come uscita. Introduciamo nella rete

neurale un peso fittizio. Il bias.

Questo corrisponde alla soglia vista per le funzioni di trasferimento binarie a soglia,

con la differenza che questa avrà la particolarità di essere variabile.

Il bias è rappresentabile nella rete come un neurone aggiuntivo nel layer precedente a

quelli che hanno funzioni sigmoidali. Nel nostro caso strati nascosti e di output

avranno funzioni a sigmoide, quindi il neurone bias lo introdurremo nei layer di input

e nascosto. Questo neurone trasferirà sempre il valore 1, mentre la sinapsi che collega

questo ai neuroni dello strato successivo ha un peso variabile come per gli altri casi.

La nostra rete:

Page 37: Introduzione alle reti neurali artificiali

37

Matteo Tosato - Introduzione alle reti neurali artificiali

ΣE

BIAS

WEIGHT

Figura 13: Esempio di rete MLP addestrata con EBP

In questo modo saremo in grado di inserire più livelli di separazione, quindi di

addestrare la nostra rete per eseguire l‟operazione XOR correttamente per tutte le

casistiche.

L‟errore commesso dallo strato di output sarà propagato all‟indietro. Faccio notare che

il numero di neuroni che compone il layer nascosto è variabile, più questo cresce più

il numero di iterazioni necessarie per l‟apprendimento sarà basso. Il numero minimo

necessario è naturalmente 2.

La regola di back-propagation presenta anche qualche controindicazione. In primis si

tratta di un processo molto oneroso in termini di impegno CPU, La funzione di

apprendimento può assumere un andamento molto complesso data la presenza di diverse

sequenze di operazioni non-lineari. I minimi locali rappresentano le zone più

pericolose perché l‟algoritmo può rimanerci intrappolato; Pericolose sono anche le zone

pianeggianti, ad esempio XOR ne possiede parecchie, queste sono zone ove i pesi sono

modificati in modo minimo rallentando la convergenza. Mentre valli troppo strette

potrebbero far saltare l‟algoritmo lontano dalla soluzione.

Esempio addestramento tramite EBP

Ci preoccuperemo poi di come migliorare l‟algoritmo per rendere la convergenza più

veloce. Nel seguente esempio addestriamo la rete in modalità batch.

#pragma once

#include "targetver.h"

#include <iostream>

#include <tchar.h>

#include <stdlib.h>

#include <cmath>

#include <time.h>

using namespace std;

#define u_int unsigned int

// Comment to avoid logger procedure

// #define LOG

/* NEURAL LEGEND

INPUT: Xi

HIDDEN: Zk

OUTPUT: Yj

Page 38: Introduzione alle reti neurali artificiali

38

Matteo Tosato - Introduzione alle reti neurali artificiali

WEIGHTS:

- HIDDEN: Wik (Bias: Wbik)

- OUTPUT: Wkj (Bias: Wbkj)

DELTA WEIGHTS:

- HIDDEN: DWik

- OUTPUT: DWkj

SUMMATION: SUM

FUNCTION: f() / derivate: f'()

ERRORS:

- HIDDEN: Ek

- OUTPUT: Ej

LEARNING RATE: N

EXPECTED VALUE: EXP

BIAS: B

*/

#include "stdafx.h"

/* MLP with 3 layers - back-propagation learning algorithm - XOR test*/

#ifdef LOG

FILE* log_file;

#endif

#define PRECISION double

#define MAX_PATH 256

#define DBG_LEN 256

const PRECISION __l_rate = 0.2;

const u_int INPUT_N = 2;

const u_int HIDDEN_N = 2;

const u_int OUTPUT_N = 1;

const u_int DEFAULT_EPOCHS = 200000;

const PRECISION M_E = 2.71828182845904523536;

const PRECISION accuracy_target = 0.1;

// ----------------------------------------

// Allocates neural network structures in data section

// ----------------------------------------

// ----- COMPONENT --------------------------------- SYMBOL ---

// Weights matrices

PRECISION W_hidden_in[HIDDEN_N][INPUT_N]; // Wik

PRECISION W_out_hidden[OUTPUT_N][HIDDEN_N]; // Wkj

// Weight vector on hidden layer

PRECISION Bias_hidden[HIDDEN_N]; // Wbik

// Weight vector on output layer

PRECISION Bias_out[OUTPUT_N]; // Wbkj

const PRECISION bias = 1.0; // B

// Errors vectors

PRECISION Error_hidden[HIDDEN_N]; // Ek

PRECISION Error_out[OUTPUT_N]; // Ej

// Delta weight matrices

PRECISION Delta_W_hidden[HIDDEN_N][INPUT_N]; // DWik

PRECISION Delta_W_output[OUTPUT_N][HIDDEN_N]; // DWkj

// Output vectors

PRECISION Out_hidden[HIDDEN_N]; // Zk

PRECISION Out_output[OUTPUT_N]; // Yj

PRECISION Net_out[OUTPUT_N]; // = Yj

// ------------------------------------------------------------

//Prototypes:

void Init_weights(void); // Weights initialization

PRECISION transf(PRECISION input); // Sigmoid function

bool Training(const char* training_path_file, u_int* epochs); // Training session

#ifdef LOG

void Init_logger(void); // Logger initialization

void Tolog(char*string); // Log routines

#endif

// -------------------------------------------------------------

// --- PROGRAM ENTRY POINT ---

// -------------------------------------------------------------

int main(int argc, char* argv[])

Page 39: Introduzione alle reti neurali artificiali

39

Matteo Tosato - Introduzione alle reti neurali artificiali

{

u_int epochs = 0;

char*pathfile = NULL;

if(argc > 1) {

pathfile = new(char[MAX_PATH]);

strncpy(pathfile,argv[1],MAX_PATH);

}

#ifdef LOG

Init_logger();

#endif

Init_weights();

if(Training(pathfile,&epochs) != true) {

cerr << "[+] WARNING - Neural network training failure" << endl;

} else cout << "[+] SUCCESS - Neural network MLP trained in " << epochs << " epochs!" << endl;

#ifdef LOG

fclose(log_file);

#endif

PRECISION input[2];

// Network simulation

while(1) {

cout << " First input <0|1>:";

cin >> input[0];

cout << " Second input <0|1>:";

cin >> input[1];

if(input[0] < 0 || input[0] > 1 ||

input[1] < 0 || input[1] > 1) {

cerr << "Input not valid. Retry." << endl;

continue;

}

// Propagate into layers...

for(int i = 0; i<HIDDEN_N; i++) {

// Propagate into hidden layer

Out_hidden[i] = transf(

input[0]*W_hidden_in[i][0]+

input[1]*W_hidden_in[i][1]+

bias*Bias_hidden[i]);

// Propagate into output layer

Out_output[0] += W_out_hidden[0][i]*Out_hidden[i];

}

Out_output[0] += Bias_out[0]*bias;

// Calculate net output

for(int i = 0; i<OUTPUT_N; i++) {

Net_out[i] = transf(Out_output[0]);

Out_output[0] = 0.0;

}

cout << "Network output: " << Net_out[0] << endl;

}

return 0;

}

// -------------------------------------------------------------

// --- TRAINING SESSION --- BACK-PROPAGATION ALGORITHM ---

// -------------------------------------------------------------

bool Training(const char* training_path_file, u_int* epochs) {

FILE* fp = NULL;

if(training_path_file != NULL) {

fp = fopen(training_path_file,"r");

if(!fp) {

cerr<<"[+] FATAL ERROR - Training file "<< training_path_file<<" not found!"<<endl;

return false;

}

}

char*n = new(char[16]);

char*nptr = n;

Page 40: Introduzione alle reti neurali artificiali

40

Matteo Tosato - Introduzione alle reti neurali artificiali

u_int k = 0, accuracy = 0;

char c = 0;

int set = 0;

u_int input[2]; // Xi

PRECISION Expected; // EXP

input[0] = -1;

input[1] = -1;

while(*epochs < DEFAULT_EPOCHS) {

// For training file

if(fp != NULL) {

while(input[0] == -1 || input[1] == -1) {

c = (char)fgetc(fp);

if(c == ';') {

input[k] = atoi(n);

(k == 1) ? k = 0 : k++;

n = nptr;

} else {

sprintf(++n,"%c",c);

}

}

} else {

// Otherwise generate appropriate training set

switch(set) {

case 0:

input[0] = 0;input[1] = 0;break;

case 1:

input[0] = 0;input[1] = 1;break;

case 2:

input[0] = 1;input[1] = 0;break;

case 3:

input[0] = 1;input[1] = 1;break;

default:

set = 0; continue;

}

set++;

}

// XOR

Expected = (PRECISION)(input[0] ^ input[1]);

// Propagate into layers...

//---------------------------------------//

// --- Zk = FhT(SUM(Xi*Wik)+(B*Wbik)) ---//

// --------------------------------------//

for(int i = 0; i<HIDDEN_N; i++) {

// Propagate into hidden layer

Out_hidden[i] = transf(

input[0]*W_hidden_in[i][0]+

input[1]*W_hidden_in[i][1]+

bias*Bias_hidden[i]);

// Propagate into output layer

//---------------------------------------//

// --- Yj = FhT(SUM(Wkj*Zk)+(B*Wbkj)) ---//

// --------------------------------------//

Out_output[0] += W_out_hidden[0][i]*Out_hidden[i];

}

Out_output[0] += Bias_out[0]*bias;

// Calculate net output

for(int i = 0; i<OUTPUT_N; i++) {

Net_out[i] = transf(Out_output[i]);

Out_output[i] = 0.0;

}

// Calculate error on output layer

//---------------------------------//

// --- Ej = (EXP - Yj)*Yj(1-Yj) ---//

// --------------------------------//

for(int i = 0; i<OUTPUT_N; i++)

Page 41: Introduzione alle reti neurali artificiali

41

Matteo Tosato - Introduzione alle reti neurali artificiali

Error_out[i] = (Expected - Net_out[i])*Net_out[i]*(1-Net_out[i]);

// Calculate delta weights of output layer

//-----------------------------//

// --- DWkj = (Wkj+N*Ej*Yj) ---//

// ----------------------------//

for(int i = 0; i<HIDDEN_N; i++)

Delta_W_output[0][i] = W_out_hidden[0][i]+__l_rate*Error_out[0]*Net_out[0];

// Calculate bias delta weight of output layer

//-----------------------------//

// --- Wbkj = (Wbkj+N*Ej*B) ---//

// ----------------------------//

for(int i = 0; i<OUTPUT_N; i++)

Bias_out[i] = Bias_out[i] + __l_rate*Error_out[i]*bias;

// Calculate error on hidden layer

//-------------------------------//

// --- Ek = (Zk*(1-Zk)*Ej*Wkj ---//

// ------------------------------//

for(int i = 0; i<HIDDEN_N; i++)

Error_hidden[i] = Out_hidden[i]*(1-Out_hidden[i])*Out_hidden[i]*W_out_hidden[0][i];

// Calculate delta weights of hidden layer

//-----------------------------//

// --- DWik = (Wik+N*Ek*Xi) ---//

// ----------------------------//

for(int i = 0; i<HIDDEN_N; i++)

Delta_W_hidden[i][0] = W_hidden_in[i][0]+__l_rate*Error_hidden[i]*input[0];

for(int i = 0; i<HIDDEN_N; i++) {

Delta_W_hidden[i][1] = W_hidden_in[i][1]+__l_rate*Error_hidden[i]*input[1];

Bias_hidden[i] = Bias_hidden[i]+__l_rate*Error_hidden[i]*bias;

}

// Update weights

//-------------------//

// --- Wik = DWik ---//

// ------------------//

for(int j = 0; j<INPUT_N; j++) {

for(int i = 0; i<HIDDEN_N; i++)

W_hidden_in[i][j] = Delta_W_hidden[i][j];

}

//-------------------//

// --- Wkj = DWkj ---//

// ------------------//

for(int j = 0; j<OUTPUT_N; j++) {

for(int i = 0; i<HIDDEN_N; i++)

W_out_hidden[j][i] = Delta_W_output[j][i];

}

(*epochs)++;

if(fabs(Net_out[0] - Expected) < accuracy_target)

accuracy++;

else

accuracy = 0;

if(accuracy == 25) {

delete n;

if(fp)fclose(fp);

return true;

}

// Uncomment for debug on prompt

/*

printf("[%u] IN: %d,%d OUT: %f EXP: %f ERR: %f\n",

*epochs,input[0],input[1],Net_out[0],Expected,fabs(Net_out[0] - Expected));

*/

#ifdef LOG

char*debug_str = new(char[DBG_LEN]);

sprintf(debug_str,"%u;%d;%d;%f;%f;%f\n",epochs,input[0],input[1],Expected,Net_out[0],fabs(Ne

t_out[0] - Expected));

Tolog(debug_str);

delete debug_str;

#endif

input[0] = -1;

Page 42: Introduzione alle reti neurali artificiali

42

Matteo Tosato - Introduzione alle reti neurali artificiali

input[1] = -1;

}

delete n;

if(fp)fclose(fp);

return false;

}

// -------------------------------------------------------------

// - TRANSFER FUNCTION FOR HIDDEN AND OUTPUT LAYER, SIGMOIDAL---

// -------------------------------------------------------------

PRECISION transf(PRECISION n) {

return(1/(1+pow(M_E,-n)));

}

// -------------------------------------------------------------

// --- WEIGHTS INITIALIZATION ---

// -------------------------------------------------------------

void Init_weights(void) {

srand((unsigned int)time(NULL));

for(int i = 0; i<INPUT_N; i++)

for(int j = 0; j<HIDDEN_N; j++)

W_hidden_in[j][i] = ((rand()%20000/10000.0)-1.0)+(rand()%10000/100000000.0f);

for(int i = 0; i<OUTPUT_N; i++)

for(int j = 0; j<HIDDEN_N; j++)

W_out_hidden[i][j] = ((rand()%20000/10000.0)-1.0)+(rand()%10000/100000000.0f);

for(int i = 0; i<HIDDEN_N; i ++)

Bias_hidden[i] = ((rand()%20000/10000.0)-1.0)+(rand()%10000/100000000.0f);

for(int i = 0; i<OUTPUT_N; i++)

Bias_out[i] = ((rand()%20000/10000.0)-1.0)+(rand()%10000/100000000.0f);

for(int i = 0; i<OUTPUT_N; i++)

Out_output[i] = 0.0;

}

// -------------------------------------------------------------

// --- LOG ROUTINES ---

// -------------------------------------------------------------

#ifdef LOG

void Init_logger(void) {

log_file = fopen("NN_log_file.dat","w");

fprintf(log_file,"N°;IN;OUT;EXPECTED;NET_OUTPUT;ERROR\n");

}

void Tolog(char*string) {

fprintf(log_file,string);

}

#endif

Migliorie per l’algoritmo EBP

Come abbiamo accennato, ci sono però due problemi fondamentali che rendono imperfetto

questo algoritmo:

- Il problema dei minimi locali.

Il minimo locale può essere rappresentato in una depressione nella funzione di training

in cui possiamo incappare e rimanervi bloccati.

Ecco come può essere raffigurato graficamente:

Page 43: Introduzione alle reti neurali artificiali

43

Matteo Tosato - Introduzione alle reti neurali artificiali

Nell‟esempio riportato abbiamo sperimentato quanto questa affermazione è vera. Difatti

il programma che addestra la rete FF per eseguire l‟operazione XOR soffre di blocchi

frequenti. Ovvero come nel grafico, l‟algoritmo rimane intrappolato in una depressione

che sembra essere la migliore soluzione che minimizza l‟errore, mentre in realtà non lo

è.

- Scarse performance.

EBP è uno dei più dispendiosi algoritmi di addestramento in termini di tempo CPU.

Questo perché le variazioni sinaptiche sono davvero minime, quindi servono molte

iterazioni per convergere al valore desiderato. Infatti ecco come l‟errore potrebbe

oscillare facendo crescere in maniera esponenziale il numero di epoche necessarie

all‟apprendimento del comportamento voluto:

Dovremmo essere in grado ora di fare considerazioni più complesse e più generali sui

problemi e soluzioni con cui abbiamo a che fare.

Se eseguite un buon numero di test sull‟esempio che abbiamo appena visto, vi capiterà

senz‟altro di accorgervi delle problematiche citate nel capitolo precedente.

Esistono un buon numero di migliorie che sono state introdotte con lo scopo di

migliorare l‟algoritmo. Ora ne vedremo alcune.

Il coefficiente “momentum”

- La prima è l‟introduzione di una variabile costante da moltiplicare alla variazione

delta dei pesi al tempo (t-1), ogni volta che un peso viene aggiornato, dunque la

funzione diventa ora:

( ) ( ) ( ) ( )

è un coefficiente come , anche esso compreso tra 0 ed 1. Il termine aggiuntivo rappresenta un “ricordo” dell‟aggiornamento avvenuti in precedenza.

Questa tecnica è implementabile nel codice di esempio visto prima, semplicemente

aggiungendo delle matrici di ugual grandezza a quelle utilizzate per immagazzinare i

valori delta dei pesi, ed utilizzarle per salvare la variazione all‟istante t-1.

Page 44: Introduzione alle reti neurali artificiali

44

Matteo Tosato - Introduzione alle reti neurali artificiali

Learning rate adattativo

- Un‟altra tecnica utilizzata (in aggiunta) è l‟introduzione del learning rate

“adattativo”. Questo significa che quando l‟algoritmo di addestramento rimane bloccato,

il learnig rate assume un valore più utile ad uscire del problema. Questa operazione

può essere fatta con diversi metodi:

Una prima versione utilizza metodi euristici, rappresentati da regole del tipo: “se

l‟errore è alto e la sua variazione delta è grande, allora occorre diminuire un po‟ il

learning rate”. Le regole possono essere applicate in modo autonomo, da un sistema

“espero” fuzzy, che assiste la rete neuronale durante l‟apprendimento.

Una seconda variante propone la modifica del learning rate non solo ad ogni ciclo t del

processo, ma anche per ogni connessione di peso. Indicando con ( ) il learning rate

relativo al tempo t e alla connessione di peso (t), la regola suggerita, che ha

consentito di accelerare la convergenza dell‟apprendimento, è:

( ) ( )

Dove il coefficiente u deve essere leggermente inferiore a 1 (tipicamente u = 0.7) o

leggermente superiore a 1 (u = 1.05) a seconda che siano dello stesso segno o meno le

due derivate:

( )

( )

Il coefficiente di momentum viene invece lasciato invariato nel tempo.

- Un‟altra variante propone la seguente legge per calcolare sia il valore del learning

rate che quello del momentum:

( ) ( ), - Dove, con riferimento ai pesi e al vettore di cui essi sono componenti, è

l‟angolo tra il vettore ( ) e il vettore gradiente dell‟errore grad E(t).

Parametri di libertà aggiuntivi

- Un‟altra ancora apporta una generalizzazione dell‟algoritmo BP, introducendo nuovi

gradi di libertà della rete. Per ogni neurone i viene usata la seguente funzione di

trasferimento di tipo sigmoidale:

(∑ )

Dove i parametri k, possono variare nel tempo nel corso dell‟apprendimento. Nel

BP classico le regole d‟apprendimento riguardano solo i pesi W e la soglia ,

assimilata generalmente ai pesi mediante bias. Indicheremo questo con: ( ). Le regole sono quelle già viste, del tipo:

Possiamo generalizzare l‟algoritmo BP, facendo variare tutti i parametri della sigmoide

prima introdotta: BP(W, ) aggiungendo alle regole precedenti le seguenti, ad esse analoghe:

Page 45: Introduzione alle reti neurali artificiali

45

Matteo Tosato - Introduzione alle reti neurali artificiali

Dove SIGMA, LAMBDA, KAPPA sono opportuni coefficienti di learning rate, compresi tra 0

e 1.

Modifica della funzione sigmoidale

In ultimo, segnalo una intelligente soluzione per il problema delle performance che mi

è capitato di trovare in rete. L‟idea verte a sostituire la funzione di trasferimento

dei neuroni con una equivalente o quasi dal punto di vista delle caratteristiche, ma

che sia meno impegnativa per quanto riguarda i calcoli.

La funzione sigmoide standard è:

Questa funzione presenta caratteristiche importantissime per noi. E‟ sempre crescente,

a vale 0 e a 1, è derivabile e continua su tutto l‟asse dei reali. E‟ la più

utilizzata di tutte proprio per questa particolarità. Essa ha solo un problema, al

denominatore è presente un esponenziale. Questo è molto dispendioso in termini di

impegno CPU. Dobbiamo tenere presente che ogni neurone della rete avrà una funzione di

trasferimento di questo tipo, e che questi valori vengono calcolati migliaia di volte

per ogni epoca. Ad ogni modo una soluzione è utilizzare funzioni di trasferimento

alternative. Ecco un esempio:

(

| |)

Questa funzione è del tutto simile in caratteristiche alla sigmoidale ma non ha

l‟esponenziale, questa è in grado di ridurre notevolmente il tempo impiegato dalla rete

per l‟addestramento. Non intendo il numero di epoche naturalmente ma il tempo CPU

dedicato. I seguenti sono i due grafici delle funzioni. Quello in verde è relativo a

quest‟ultima versione.

Ci sono altre migliorie possibili da applicare all‟algoritmo di addestramento back-

Page 46: Introduzione alle reti neurali artificiali

46

Matteo Tosato - Introduzione alle reti neurali artificiali

propagation, in generale però è possibile anche crearsi una propria regola di

miglioramento a quanto già fa BP secondo le proprie esigenze.

Algoritmo Resilient back-propagation (RPROP)

L‟algoritmo EBP che abbiamo affrontato, consente di addestrare una rete feed-forward.

Abbiamo visto che esso soffre di alcuni inconvenienti come i minimi locali e i problemi

legati alle prestazioni i quali poi dipendono dal tipo e potenza della CPU che deve

eseguire l‟addestramento.

RPROP sta per “Resilient propagation” ed è un nuovo sistema per l‟apprendimento

supervisionato. Ideato nel 1993 da Martin Riedmiller. Esso attua un adattamento diretto

sul peso in questione basandosi sul valore del gradiente locale. Il suo principio è

eliminare l‟influenza della dimensione (il valore assoluto che assumono) delle derivate

parziali sugli aggiornamenti dei pesi. Conseguenza di ciò, solo il segno di queste

viene valutato. Viene introdotta di fatto una nuova regola, la quale determina

l‟evoluzione del valore di aggiornamento ( ). La stima si basa appunto

sull‟osservazione del comportamento della derivata parziale durante i successivi due

step:

( )

{

( )

( )

( )

( )

( )

( )

( )

Dove

Ogni volta che la derivata parziale del peso corrispondente cambia il suo segno,

fatto che indica che l‟ultimo aggiornamento fatto è stato molto importante e che

l‟algoritmo ha saltato sopra un minimo locale, il valore di aggiornamento ( ) viene

diminuito dal fattore Se la derivata mantiene il suo segno, il valore di

aggiornamento è debolmente incrementato in modo da accelerare la convergenza nella

regione superficiale. Questo per ogni peso.

Una volta che il delta è stato adattato per ogni peso, il valore di aggiornamento segue

una semplice regola: se la derivata è positiva (incremento di errore), il peso viene

decrementato dal suo valore di aggiornamento, se la derivata è negativa, il valore di

aggiornamento viene aggiunto:

{

( )

( )

( )

( )

Quindi come al solito:

( ) ( ) ( )

Esiste anche una eccezione per le regole viste; se la derivata parziale cambia di segno

significa che lo step di aggiornamento precedente era troppo importante e il minimo è

andato perso, allora il precedente valore di aggiornamento viene invertito:

Page 47: Introduzione alle reti neurali artificiali

47

Matteo Tosato - Introduzione alle reti neurali artificiali

( ) ( )

( )

( )

A causa di questa regola, la derivata può cambiare il suo segno più di una volta. Per

evitare una doppia correzione del valore di aggiornamento, non ci sarà adattamento del

valore nello step successivo al cambiamento di segno. In pratica questo può essere

fatto settando la regola di aggiornamento nel modo seguente:

( )

La derivata parziale dell‟errore totale è resa da:

( )

( )

Quindi, la derivata parziale degli errori deve essere accumulata per tutti i patterns

di addestramento.

Se volessimo fare un confronto con l‟algoritmo classico visto in precedenza, diremmo

che la differenza sostanziale è espressa dalla seguente formula, ovvero quella che

determina il valore delta per l‟aggiornamento dei pesi sinaptici:

(

) [EBP]

(

) [RPROP]

gioca quindi un ruolo determinante nell‟aggiornamento dei pesi sinaptici.

I seguenti sono i valori più comuni da assegnare al fattore di incremento e decremento:

e

Per evitare che questi due valori crescano o diminuiscano senza controllo, vengono

solitamente impostati anche due limiti, uno inferiore ed uno superiore:

e

Mentre il valore iniziale di questi è solitamente posto a 0.1. ( )

Di seguito propongo infine lo “pseudo-codice” del nuovo algoritmo di training: [Martin

Riedmiller, Heinrich Braun; Institut fur Logik, Komplexitat und Deduktionssyteme -

University of Karlsruhe]

( )

( )

( )

*

Page 48: Introduzione alle reti neurali artificiali

48

Matteo Tosato - Introduzione alle reti neurali artificiali

(

( )

( ) ) *

( ) ( ( ) )

( ) (

( )) ( )

( ) ( ) ( )

( )

( )

+

(

( )

( ) ) *

( ) ( ( ) )

( )

+

(

( )

( ) ) *

( ) (

( )) ( )

( ) ( ) ( )

( )

( )

+

+

( )

La dimensione della derivata diminuisce esponenzialmente con la distanza tra il vettore

dei pesi e quello dei valori neurali del layer di output. Usando RPROP la dimensione

del valore di aggiornamento dei pesi dipende solo dalla sequenza dei segni assunti dal

gradiente locale calcolato.

Le reti neurali offrono un tipo di fuzzy logic estremamente adattabile, l‟importante è

averne appreso il funzionamento base, per poi procedere con le proprie configurazioni.

Quelle che abbiamo affrontato fino ad ora sono le configurazioni più utilizzate e più

utili nelle moderne applicazioni come pattern-recognition, classificazione di dati,

risoluzione di problemi di controllo automatico, sistemi adattativi ed altre faccende.

Reti di Hopfield

Nelle reti appena viste, generalmente chiamate “feed-forward”, i segnali in ingresso

andavano in una sola direzione, da qui i layer di input ed output. Naturalmente di reti

ce ne sono di altri tipi e le abbiamo visto nella prima parte del testo. Un tipo di

rete importante sono quelle che hanno neuroni con collegamenti, oltre che con quelli

del livello successivo, anche con neuroni dello stesso livello.

Page 49: Introduzione alle reti neurali artificiali

49

Matteo Tosato - Introduzione alle reti neurali artificiali

3 1 2

S1

S2S3

W2W3

Figura 14: Rete caotica semplice

La complessità di queste reti stà nel fatto che le sue unità rimangono attive anche

all‟istante successivo dalla ricevuta di input. La rete rimane perciò attivata per un

periodo limitato (transitorio) di tempo. Possono verificarsi diversi casi, la rete può

oscillare attraverso un numero finito T di stati, per poi ricominciare il ciclo. Oppure

oscillare attraverso un numeri infinito di stati, senza mai riconseguire uno stato già

visitato (Chaos deterministico).

La rete in figura può avere un comportamento assai complesso. Si consideri che ogni

neurone ha la seguente funzione di attivazione per ogni neurone:

( )

( )

I cui stati ( ) cambiano nel tempo t con le solite regole ( sono i pesi sinaptici):

( ) ( ( ) ( )) ( ) ( ( )) ( ) ( ( )) Se si definiscono i valori delle costanti nelle funzione di attivazione, lo stato

cambia nel tempo in modo complesso, al variare del parametro . Le variazioni di tale

parametro conferiscono alla rete comportamenti stabili, oscillatori oppure caotici. Le

versione discreta (DH Discrete Hopfield) ha N neuroni con stati bipolari ( ) ( ), funzione di trasferimento a gradino (detta anche signum, abbreviato generalmente in

sign o sgn) e connessioni simmetriche tra un neurone e qualsiasi altro, escludendo solo

le connessioni di un neurone con se stesso. Si hanno quindi N(N-1) connessioni e N(N-

1)/2 pesi sinaptici diversi. Indicando con il peso sinattico della connessione j->i

tra i due neuroni i,j si ha:

Per ogni neurone i, il potenziale si calcola:

( ) ∑( ( ))

Dato che ogni neurone hanno una funzione a gradino e che per ( ) , si mantiene lo stato precedente, la rete ha una funzione E, denominata “energia” per un‟analogia

formale con la energia meccanica:

∑∑( )

La quale diminuisce nel tempo:

Page 50: Introduzione alle reti neurali artificiali

50

Matteo Tosato - Introduzione alle reti neurali artificiali

,∑( ) -

Quindi l‟energia non cresce ma diminuisce, per

L‟attivazione dei neuroni può essere per via iterativa, in modo deterministico oppure

stocastico, sincrono o asincrono.

Restando sulla modalità deterministica, se i neuroni vengono attivati in parallelo

(sincronia), oltre a stati finali stabili si possono conseguire attrattori a ciclo

limite T = 2. Esaminiamo la rete:

S1

S2 S3

1,5

-2

1

I neuroni sono bipolari a soglia zero e per un totale di 6 connessioni.

Si può notare che con una attivazione asincrona si hanno due stati stabili (+1,-1,+1) e

(-1,+1,-1). Si ha infatti partendo dal primo stato e attivando sequenzialmente un

neurone per volta, la situazione seguente:

Tempo Stato rete (S1,S2,S3) Neurone

attivato

Potenziale neurone

attivato

Stato futuro del

neurone attivato

t (+1,-1,+1) S1 +0.5 +1

t+1 (+1,-1,+1) S2 -1 -1

t+2 (+1,-1,+1) S3 +3.5 +1

La sequenza viene ripetuta, quindi lo stato della rete si ripete ad oltranza e rimane

invariato. Lo stato (+1,-1,+1) è detto attrattore assieme allo stato (-1,+1,-1). La

rete evolve sempre verso questi stati. Naturalmente a seconda della modalità il

comportamento della rete di Hopfield cambia di conseguenza. Senza vedere tutti gli

altri casi preferisco soffermarmi su quelli che sono i possibili utilizzi delle reti di

Hopfield. I due principali sono come memoria associativa e come ottimizzatore.

L‟ottimizzazione è un problema particolarmente adatto alle reti di Hopfield proprio

perché queste convergono verso uno stato stabile. Un esempio classico è il problema del

commesso viaggiatore. Date N città e conoscendo le distanze tra due qualunque di

esse, si tratta di determinare un percorso di visite che soddisfa i vincoli e minimizza

il percorso globale, con ritorno alla città iniziale. Il problema TSP può inoltre

essere simmetrico o asimmetrico. Generalmente questi problemi vengono risolti con i

metodi della ricerca operativa, che spesso offrono prestazioni accettabili, conseguite

polinomiali. Tuttavia la programmazione lineare a numeri interi e la programmazione

dinamica possono solo trattare problemi con Molto più efficienti sono

alcuni moderni metodi come quello denominato “Branch and cut” e l‟algoritmo Lin-

Kerningham. L‟uso delle reti neuronali per risolvere problemi di questo tipo è stato

proposto inizialmente da Hopfield, con una versione analogica della sua rete. Questa

rete ha la proprietà di avere, come epifenomeno del normale funzionamento, una energia:

∑∑( )

Page 51: Introduzione alle reti neurali artificiali

51

Matteo Tosato - Introduzione alle reti neurali artificiali

La quale, come abbiamo visto, diminuisce monotonicamente nel tempo. L‟energia è

funzione quadratica degli stati e lineare dei pesi sinaptici . Se si riuscisse a

costruire una funzione costo F che fosse funzione quadratica delle variabili del

problema e ne soddisfacesse i vincoli, dall‟eguaglianza ( ) ( ) si potrebbero

ricavare i pesi che consentirebbero alla rete, partendo da valori casuali, di evolvere

verso uno stato finale che coincide con la soluzione ottimale (costo minimo e vincoli

soddisfatti). La funzione F dipende perciò dal problema e, per quanto di disegno

laborioso, non presenta difficoltà insormontabili.

Reti neurali auto-organizzanti

Mappe di Kohonen

Teuvo Kohonen (1934) è un ricercatore, ed è attualmente professore emerito

nell‟accademia Finlandese. Uno dei suoi più famosi contributi fu quello sulle reti

auto-organizzanti “SOM”.

Le reti SOM (Self-organizing maps) sono un particolare tipo di ANN che creano una forte

ed interessante analogia con le reti biologiche che compongono la corteccia celebrale.

Questa corteccia può essere paragonata al cappello di un fungo che avvolge il suo

gambo, i nuclei sottocorticali e il midollo spinale. Alla corteccia affluiscono le

informazioni visive, acustiche, olfattive e le sensazioni tattili e dolorose: ogni

sensazione è mappata e viene letta da una specifica area della corteccia. (area di

differenza sensoriale).

Insieme a quest‟area sensoriale, vi si trovano le aree motorie, che controllano la

funzione dei muscoli volontari. E‟ stato possibile tracciare una mappa dei neuroni

responsabili dei movimenti delle dita, della mano, delle braccia e di tutti gli altri

muscoli volontari. Siccome non tutte le aree muscolari sono uguali, c‟è una differenza

di sensibilità fra le diverse parti del corpo. La mappa dei movimenti, come quella

delle sensazioni viene definita con il termine di “omuncolo” che indica la

rappresentazione proporzionale delle funzioni motorie e sensoriali.

Figura 15: Omuncolo sensoriale e motorio

Le aree motorie si occupano di generare impulsi atti a contrarre le rispettive parti

del corpo formate da muscoli volontari, mentre le aree sensoriali raccolgono

informazioni dai vari organi recettori, più un‟area sensoriale è ampia più la

sensazione è ricca di dettagli.

Page 52: Introduzione alle reti neurali artificiali

52

Matteo Tosato - Introduzione alle reti neurali artificiali

Nelle reti SOM, i neuroni proiettano l‟input multidimensionale su una superfice di

neuroni artificiali, rappresentandolo in due dimensioni ed effettuandone quindi una

notevole compressione, pur conservando le similarità originarie. Inoltre la capacità di

scoprire, in modo autonomo, proprietà interessanti di un input multidimensionale

accomuna le reti SOM alla capacità degli organismi viventi di adattarsi all‟ambiente

senza la necessità di una guida esterna.

Le reti SOM sono in grado imparare in modo autonomo come classificare una serie di

input attraverso la competizione fra i suoi neuroni che compongono la superficie. Il

seguente schema mostra questo sistema di “Competitive learning” con „n‟ input e „m‟

output:

Xi -1X1 Xi Xi +1 Xn

Yj -1Y1 Yj Yj +1 Ym

WjnWjiWj1

Figura 16: Schema di rete "Competitive learning"

Dove m neuroni j (con attivazione ) sono connessi a n input , tramite pesi sinaptici

. Inoltre, ogni neurone j è connesso con tutti i neuroni k del suo strato (incluso

se stesso) tramite pesi sinaptici . I neuroni k vicini al neurone j lo eccitano

( ), mentre quelli lontani lo inibiscono( ). La seguente è la dinamica della rete:

( ) [∑( ) ∑( ( ))

]

Dove, se v è il vicinato, (i + k) varia tra (j - v) e (j + v); F è una funzione di

trasferimento non lineare con saturazione (per limitare il valore di ) e è un fattore di feed-back, compreso tra 0 e 1.

Presentando in input un vettore X, di n componenti , verrà attivato maggiormente un

certo neurone j( ( ) ( ) ),in base alla prima sommatoria dell‟equazione precedente. Nei tempi successivi entra in azione la seconda sommatoria e i neuroni in

un intorno di j si rafforzano mutualmente e indeboliscono i neuroni lontani. In questo

modo le uscite Y dei neuroni vanno a creare quella che viene chiamata “bolla di

attivazione”, centrata su j, con una certa estensione “orizzontale” e una certa

ampiezza “verticale”.

L‟estensione dipende dal rapporto tra feed-back positivi e negativi, la prevalenza dei

primi allargando la bolla e viceversa.

L‟ampiezza dipende dal fattore di feed-back e cresce con esso. Quindi, ogni input attiverà la sua bolla ed input simili attiveranno le bolle dei

neuroni limitrofi, mentre input differenti attivano bolle più lontane.

Il seguente è il grafico di distribuzione dei pesi “a capello messicano” in un intorno

del neurone di uscita Y.

Page 53: Introduzione alle reti neurali artificiali

53

Matteo Tosato - Introduzione alle reti neurali artificiali

Figura 17: Distribuzione dei pesi del tipo: "a cappello messicano" in un intorno del neurone Yk

E‟ possibile semplificare notevolmente la struttura della rete eliminando le

connessioni ricorrenti laterali “a cappello messicano”, se si definisce un vicinato di neuroni contemporaneamente attivi.

In tal caso la bolla si forma per definizione, dato che l‟attivazione iniziale di un

neurone j trascina quella dei neuroni vicini.

La struttura finale di una rete SOM utilizzata nelle applicazioni è quindi senza queste

connessioni laterali, costituita da m neuroni j, ciascuno collegato a n input i tramite

dei pesi sinaptici . Tutte le connessioni laterali vengono invece simulate

utilizzando un vicinato topologico. Normalmente questo è un quadrato. Ad esempio gli 8

neuroni adiacenti.

L‟apprendimento senza supervisione è piuttosto semplice, si istruisce la rete con m * n

pesi sinaptici, si presenta in input il generico vettore ( ) e si

determina quel vettore che rende massimo il prodotto scalare: ∑ ( ) . I

neuroni competono ed uno solo di essi vincerà. Questo, assieme a tutto il suo vicinato,

avvicina il relativo vettore a X:

( ) ( ) ( )

Dove è il coefficiente learning rate che già conosciamo, compreso tra i valori 0 ed 1. Questo

viene fatto diminuire nel tempo, partendo da 1.

Notate che il vettore dei pesi è quello relativo al

neurone vincente.

Queste reti sono state applicate con successo per

risolvere questioni riguardanti la classificazione

e la valutazioni di parametri. Ad esempio in

Germania, è stata sviluppata una rete di questo

tipo per la valutazione di circuiti integrati,

composta da 2500 neuroni con 10 input, ogni input

rappresenta un parametro del circuito da

analizzare. Come la quantità ed altri parametri di

fabbricazione.

Questa rete crea quindi diverse “bolle”, ognuna

delle quali attrarrà gli input simili.

Una rete di questo tipo viene quindi addestrata in

modo tale da avvicinare il vettore dei pesi appartenenti al neurone vincente, verso il

vettore degli input. (Immaginate di rappresentare graficamente i due vettori iscritti

in una circonferenza di raggio 1).

Aggiungendo la supervisione all‟algoritmo di addestramento si ottiene una rete

sicuramente più adatta alla classificazione. Pilotando il tipo di vettore di input è

possibile ottenere le bolle di attivazione desiderate. Il funzionamento della rete sarà

quindi quello di inserire gli input ricevuti in certe aree neurali in modo da compiere

Page 54: Introduzione alle reti neurali artificiali

54

Matteo Tosato - Introduzione alle reti neurali artificiali

delle classificazioni. Una rete SOM di grosse dimensioni riesce ad emulare almeno

parzialmente ciò che avviene nel cervello umano.

La rete di Kohonen lavora come una mappa e come un mappa viene costruita. Su questa

mappa andranno a formarsi le nostre aree di attivazione che corrispondono a certi tipi

di input esterni.

Il disegno è semplificato, ma ogni neurone è in realtà connesso ad ogni uscita tramite

sinapsi di peso differente. I neuroni di output assieme formano una mappa. Questa mappa

si attiverà in una certa zona e si indebolirà nelle altre visto il comportamento dei

neuroni dello strato di output a formare “il cappello messicano”.

L‟implementazione di questo tipo di rete non è molto più complesso del caso MLP. Sempre

con matrici multidimensionali è possibile rappresentare ogni parte fisica della rete:

neuroni e sinapsi. Riassumiamo qui di seguito quali sono le operazioni da compiere per

lavorare con SOM:

- Si inizializza un vettore per gli input ed uno per gli output.

- Si inizializza un vettore multidimensionale per i pesi tra input ed output.

- Una funzione learn() dovrà passare i valori di input normalizzati al vettore di

input.

- Una funzione exec() chiamata da learn() dovrà calcolare il valore per ogni neurone

dello strato di output.

- Un‟altra funzione dovrà scansionare il vettore di output in cerca del neurone

vincente.

- Questo viene passato ad una funzione che ha il compito di aggiornare il vettore dei

pesi per il neuronodo.

- Qui è possibile inserire una funzione adjust() di normalizzazione degli altri pesi

dei neuroni del vicinato.

- Una funzione test() si preoccuperà di testare la rete una volta che questa è arrivata

ad attivare diverse aree.

Tale configurazione è anche denominata “mappa di Kohonen”. Infatti rappresentando i

neuroni di output in righe e colonne a formare una matrice ad esempio 100x100, si

ottiene una mappa. I base a come i pesi sono stati inizializzati, la rete durante la

fase di apprendimento, si auto-organizzerà in aree. Una per ogni classe di input.

Un tipico esempio per comprendere come lavora questa configurazione è il riconoscimento

di profili altimetrici. Un profilo può essere rappresentato anche da pochi input. Ad

esempio 5.

Valori: 0,3 – 0,2 – 0,3 – 0,3 – 0,4

Page 55: Introduzione alle reti neurali artificiali

55

Matteo Tosato - Introduzione alle reti neurali artificiali

Valori: 0,1 – 0,2 – 0,5 – 0,4 – 0,2

Valori: 0,4 – 0,1 – 0,0 – 0,2 – 0,6

La mappa di Kohonen è rappresentata invece in questo modo:

O

Il pallino nella rete rappresenta il neurone vincente. Durante la classificazione degli

input possono verificarsi dei problemi. Ad esempio, il profilo piano si pone in una

situazione neutrale rispetto alle altre tipologie. Così facendo può essere inserito

all‟interno di altre classi.

Per evitare questo problema, legato a questo particolare caso, si può ricorrere a due

operazioni:

- la normalizzazione degli input, o “stretching” dei profili; questa avviene sottraendo

il valore di input più basso a ogni input, poi portare il valore più alto ad 1 e

dividere tutti gli altri input con questo valore massimo.

- L‟altra norma consiste nel tipo di funzione di trasferimento; invece di fare una

moltiplicazione tra valore input e peso, si può ricorrere alla differenza vettoriale

tra le due grandezze. Quindi la formula di trasferimento diventa:

00.000

00.001

1 2 3 4 5

00.000

00.001

00.001

1 2 3 4 5

00.000

00.001

00.001

1 2 3 4 5

Page 56: Introduzione alle reti neurali artificiali

56

Matteo Tosato - Introduzione alle reti neurali artificiali

∑[

(|

| )

]

Dove “e” vale 0.01.

Implementiamo una rete SOM per il riconoscimento dei profili altimetrici.

Dovremo anche predisporre una serie di set per il training e una serie di set per la

verifica. Possibilmente diversi, in modo da poter poi osservare la capacità di

generalizzazione della rete. I set possono essere inseriti uno per riga in un file, in

modo tale da poterli leggere con fscanf(). E saranno come quelli visti negli esempi

sopra.

Esempio di rete SOM

Il seguente è il codice della rete di Kohonen a scopo esemplificativo che utilizza già

la due ottimizzazioni di funzionalità che abbiamo descritto.

/*

* SOM [Self organizing map]

* by Matteo Tosato

* header file

*/

#ifndef _HSOM_H

#define _HSOM_H

#include <stdlib.h>

#include <math.h>

#include <string.h>

#include <time.h>

#include <stdio.h>

#include <unistd.h>

#define neuron_state_t double

#define BYTE char

#define DUMP 0

#define MAP 1

#define MAX_PATH 256

// Initial learning rate

const double __l_rate = 0.1;

// Uncomment to create log file with network results in append mode

// #define LOG

const unsigned int NUM_INPUT_N = 100; // GRAPHIC MAP 100 x 100

const unsigned int NUM_OUTPUT_N = 100; // Maximum size of input patterns

// Parameters structure:

struct param {

char* lrn_file;

char* val_file;

FILE* lrn;

FILE* val;

unsigned int iterations;

unsigned int pattrn_size;

double K;

BYTE print_mode;

unsigned int winner;

};

// Neural network structure:

struct SOM {

Page 57: Introduzione alle reti neurali artificiali

57

Matteo Tosato - Introduzione alle reti neurali artificiali

neuron_state_t IN[NUM_INPUT_N];

neuron_state_t OUT[NUM_OUTPUT_N];

neuron_state_t WEIGHTS[NUM_INPUT_N][NUM_OUTPUT_N];

};

#endif /* _HSOM_H */

Questo è il file di implementazione principale:

/*

* SOM [Self organizing map]

* by Matteo Tosato

*

* Kohonen neural networks, reproduces the "pseudo-biological networks behavior".

* Parameters:

* pattern dimension - training file - validation file - number of iterations (epoch) - [-d] Dump

results | [-g] MAP

*

* tosatz{at}tiscali{dot}it

*/

#include "hsom.h"

// Prototypes:

struct param* parameters_parser(int argc, char**argv);

void learn(struct param*,struct SOM*);

void exec(struct param*,struct SOM*);

void adjust(struct param*,struct SOM*);

void Init_weights(struct param*, struct SOM*);

void Test(struct param*, struct SOM*);

void dump(struct param*, struct SOM*);

void map(struct param*, struct SOM*);

void stretching(struct param*, struct SOM*);

/*****************************************

* Entry Point

******************************************/

int main(int argc, char** argv) {

struct SOM nn;

struct param *param;

if((param = parameters_parser(argc,argv)) == NULL) {

fprintf(stderr,"[+] FATAL - Arguments parsing failure.\n");

printf("Usage:\n %s <pattern dimension> <path training file> "

"<path validation file (test)> <number of iterations (epochs)>\n",argv[0]);

printf("\ntosatz{at}tiscali{dot}it\n");

return 1;

}

param->lrn = fopen(param->lrn_file,"r");

param->val = fopen(param->val_file,"r");

if(param->lrn == NULL || param->val == NULL) {

fprintf(stderr,"[+] FATAL - File not found\n");

return 1;

}

param->K = __l_rate;

Init_weights(param,&nn);

printf("[+] Learning ...");

learn(param, &nn);

printf(" Done!\n");

printf("[+] Testing ... \n\n");

Test(param,&nn);

fclose(param->lrn);

fclose(param->val);

delete param, &nn;

return 0;

}

/*****************************************

* Input stretching, (input normalization)

******************************************/

void stretching(struct param* p, struct SOM* nn) {

neuron_state_t MIN = 10;

neuron_state_t MAX = 0;

u_int max_index = 0;

Page 58: Introduzione alle reti neurali artificiali

58

Matteo Tosato - Introduzione alle reti neurali artificiali

// Search for minimum and maximum values:

for(u_int j = 0; j < p->pattrn_size; j++) {

if(nn->IN[j] < MIN) {

MIN = nn->IN[j];

}

if(nn->IN[j] > MAX) {

MAX = nn->IN[j];

max_index = j;

}

}

// Perform input normalization:

for(u_int j = 0; j < p->pattrn_size; j++) {

nn->IN[j] -= MIN;

}

nn->IN[max_index] = 1.0f;

for(u_int j = 0; j < p->pattrn_size; j++) {

if(j == max_index) continue;

nn->IN[j] = nn->IN[j] / MAX;

}

}

/*****************************************

* Network in learning step

******************************************/

void learn(struct param* p, struct SOM* nn) {

unsigned int j, c = 0;

// Begin

while(c < p->iterations) {

while(1) {

j = 0;

// Get input

while(j < p->pattrn_size) {

fscanf(p->lrn,"%lf",&nn->IN[j++]); // To input neurons

}

if(feof(p->lrn)) break;

exec(p,nn);

adjust(p,nn);

}

p->K = p->K/1.3;

fseek(p->lrn,0,0);

c++;

}

return;

}

/*****************************************

* Elaboration of inputs

******************************************/

void exec(struct param *p, struct SOM *nn) {

// Input normalization:

stretching(p,nn);

// For each output neuron calculate rispective value:

for(unsigned int k = 0; k < NUM_OUTPUT_N; k++)

nn->OUT[k] = 0;

for(unsigned int k = 0; k < NUM_OUTPUT_N; k++) {

for(unsigned int j = 0; j < p->pattrn_size; j++) {

//nn->OUT[k] += (nn->IN[j] * nn->WEIGHTS[j][k]); <-- normal

nn->OUT[k] += 1/(fabs(nn->IN[j] - nn->WEIGHTS[j][k]/100) + 0.01);

}

}

// Neighbourhood simulation, "Mexican bonnet weights":

for(unsigned int j = 0; j < NUM_OUTPUT_N; j++)

nn->OUT[j] += 0.1*(nn->OUT[j-1]+nn->OUT[j+1]-nn->OUT[j-2]-nn->OUT[j+2]);

// Search for winner neuron:

u_int winner = 0;

neuron_state_t winner_value = 0.0f;

Page 59: Introduzione alle reti neurali artificiali

59

Matteo Tosato - Introduzione alle reti neurali artificiali

for(unsigned int i = 0; i < NUM_OUTPUT_N; i++) {

if(nn->OUT[i] > winner_value) {

winner_value = nn->OUT[i];

winner = i;

}

}

p->winner = winner;

}

/*****************************************

* Simulation of the neighborhood

******************************************/

void adjust(struct param *p, struct SOM *nn) {

// Updating weights of winner neuron and and nearest neighbors:

for(unsigned int i = 0; i < p->pattrn_size; i++) {

nn->WEIGHTS[i][p->winner] =

nn->WEIGHTS[i][p->winner] + p->K * (nn->IN[i] - nn->WEIGHTS[i][p->winner]);

nn->WEIGHTS[i][p->winner - 1] =

nn->WEIGHTS[i][p->winner - 1] + p->K * (nn->IN[i] - nn->WEIGHTS[i][p->winner - 1]);

nn->WEIGHTS[i][p->winner - 2] =

nn->WEIGHTS[i][p->winner - 2] + p->K * (nn->IN[i] - nn->WEIGHTS[i][p->winner - 2]);

nn->WEIGHTS[i][p->winner + 1] =

nn->WEIGHTS[i][p->winner + 1] + p->K * (nn->IN[i] - nn->WEIGHTS[i][p->winner + 1]);

nn->WEIGHTS[i][p->winner + 2] =

nn->WEIGHTS[i][p->winner + 2] + p->K * (nn->IN[i] - nn->WEIGHTS[i][p->winner + 2]);

}

return;

}

/*****************************************

* Function for Test

******************************************/

void Test(struct param *p, struct SOM *nn) {

unsigned int k = 0;

char answer[8];

while(1)

{

endfile:

for(unsigned int j = 0; j < p->pattrn_size; j++) {

fscanf(p->val,"%lf",&nn->IN[j]);

}

if(feof(p->lrn)) {

rewind(p->val);

k = 0;

goto endfile;

}

k++;

exec(p,nn);

printf("[+] Test n° %u\n",k);

switch(p->print_mode) {

case DUMP: dump(p,nn); break;

case MAP: map(p,nn); break;

}

printf("[+] Continue? <y/n> ");

scanf("%s",answer);

if( (!strncmp(answer,"n",1)) || (!strncmp(answer,"N",1)) ) return;

else system("clear");

}

}

/*****************************************

* Collect parameters

******************************************/

struct param* parameters_parser(int argc, char**argv) {

if(argc < 4) return NULL;

struct param *p = new(struct param);

p->pattrn_size = atoi(argv[1]);

if(!(p->lrn_file = new(char[MAX_PATH]))) return NULL;

strncpy(p->lrn_file,argv[2],MAX_PATH - 1);

if(!(p->val_file = new(char[MAX_PATH]))) return NULL;

strncpy(p->val_file,argv[3],MAX_PATH - 1);

p->iterations = atoi(argv[4]);

Page 60: Introduzione alle reti neurali artificiali

60

Matteo Tosato - Introduzione alle reti neurali artificiali

if(!strcmp(argv[5],"-d")) {

p->print_mode = DUMP;

} else if(!strcmp(argv[5],"-g")) {

p->print_mode = MAP;

} else p->print_mode = 0;

return p;

}

/*****************************************

* Weights initialization

******************************************/

void Init_weights(struct param *p, struct SOM *nn) {

srand((unsigned int) time(NULL));

for(unsigned int i = 0; i < NUM_OUTPUT_N; i++) {

for(unsigned int k = 0; k < p->pattrn_size; k++) {

nn->WEIGHTS[k][i] =

fabs(((rand()%20000/10000.0)-1.0)+(rand()%10000/100000000.0f));

}

}

}

/*****************************************

* Dump values of input and output neurons

******************************************/

void dump(struct param* p, struct SOM* nn) {

printf("[+] Neural networks simulation results:\n");

printf("\n\n[+] INPUT NEURONS:");

for(unsigned int i = 0; i < p->pattrn_size; i++) {

printf("%lf ",nn->IN[i]);

}

printf("\n\n[+] OUTPUT NEURONS:");

for(unsigned int k = 0; k < NUM_OUTPUT_N; k++) {

printf("%lf ",nn->OUT[k]);

}

printf("\n\n");

// Send network results to log file

#ifdef LOG

u_int j = 0;

FILE* log_file = fopen("Results.txt","a");

fprintf(log_file," --- SON results: --- \n");

fprintf(log_file,"Input:\n");

while(nn->IN[j] > 0) {

fprintf(log_file,"%lf;",nn->IN[j++]);

}

fprintf(log_file,"\nOutput:\n");

for(j=0;j < NUM_OUTPUT_N;j++)

fprintf(log_file,"%lf;",nn->OUT[j]);

fclose(log_file);

#endif

}

/*****************************************

* Build a simple graphic Kohonen map

******************************************/

void map(struct param* p, struct SOM* nn) {

int c = 0, r = 0;

printf("\n\n\n");

printf("INPUTS:\n");

for(u_int j = 0; j < p->pattrn_size; j++) {

printf("%lf\n",nn->IN[j]);

}

printf("\n\n");

printf("0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9\n");

for(u_int j = 0; j < NUM_OUTPUT_N; j++) {

if(nn->OUT[j] == nn->OUT[p->winner])

printf("*");

else

printf("-");

if(++c == 10) {

printf(" %d\n",r++);

c = 0;

} else {

Page 61: Introduzione alle reti neurali artificiali

61

Matteo Tosato - Introduzione alle reti neurali artificiali

printf("---");

}

}

printf("Winner neuron: %d",p->winner);

printf("\n-----------------------------------------\n");

}

Di seguito sono mostrati i valori in input, il loro valore durante e al termine del

processo di stretching.

1° SET

0,34 0,24 0,34

0,50 0,40 0,57

0,80 0,70 1,00

0,41 0,31 0,44

0,10 0,00 0,00

2° SET

0,23 0,00 0,00

0,56 0,33 0,44

0,98 0,75 1,00

0,62 0,39 0,52

0,23 0,00 0,00

3° SET

0,20 0,00 0,00

0,20 0,00 0,00

0,30 0,10 1,00

0,20 0,00 0,00

0,20 0,00 0,00

4° SET

0,45 0,44 0,49

0,16 0,15 0,17

0,01 0,00 0,00

0,45 0,44 0,49

0,90 0,89 1,00

5° SET

0,90 0,89 1,00

0,70 0,69 0,78

0,30 0,29 0,33

0,12 0,11 0,12

0,01 0,00 0,00

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

Page 62: Introduzione alle reti neurali artificiali

62

Matteo Tosato - Introduzione alle reti neurali artificiali

6° SET

0,23 0,00 0,00

0,40 0,17 0,24

0,76 0,53 0,74

0,90 0,67 0,93

0,95 0,72 1,00

7° SET

0,01 0,00 0,00

0,30 0,29 0,42

0,70 0,69 1,00

0,40 0,39 0,57

0,10 0,09 0,13

8° SET

0,80 0,40 0,70

0,50 0,10 0,18

0,40 0,00 0,00

0,70 0,30 0,53

0,97 0,57 1,00

9° SET

0,40 0,00 0,00

0,40 0,00 0,00

0,40 0,00 0,00

0,50 0,10 1,00

0,40 0,00 0,00

10° SET

0,90 0,80 1,00

0,60 0,50 0,63

0,30 0,20 0,25

0,30 0,20 0,25

0,10 0,00 0,00

11° SET

0,20 0,00 0,00

0,20 0,00 0,00

0,30 0,10 0,17

0,50 0,30 0,50

0,80 0,60 1,00

La seguente è la mappa di Kohonen con i risultati, questi sono relativi ai vari set di

verifica qui sopra con il colore uguale.

0 1 2 3 4 5 6 7 8 9

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

000

001

001

1 2 3 4 5

Input

str 1°

Dopo stretching

Page 63: Introduzione alle reti neurali artificiali

63

Matteo Tosato - Introduzione alle reti neurali artificiali

11 0

1

2

3

4

1 , 5 , 10 6 , 7 5

6

7

4 , 8 2 , 3 8

9 9

Come è evidente dagli input rappresentati nei grafici, la fase di stretching è

importante per diminuire l‟influenza dei valori assoluti dei dati in input e rendere

importante l‟andamento del profilo altimetrico.

Se analizzate i valori di pendenza, possiamo concludere che la rete ha classificato i

set in modo abbastanza corretto.

Partendo dal codice e dal modello visto, è facile aggiungere l‟apprendimento

supervisionato. Questo si fa andando a verificare se la classificazione della rete è

corretta o meno. In caso affermativo, i pesi del neuro-nodo vincente e di tutto il suo

vicinato vengono aumentati, nel caso opposto i pesi andranno indeboliti.

Competitive learning reale

Il codice esemplificativo mostrato nel capitolo precedente prevede una notevole

semplificazione che viene fatta nelle configurazioni SOM.

Rivediamo invece l‟architettura di una rete SOM reale;

La parte principale di questa configurazione è costituita da una mappa, o comunque da

un vettore di neuroni che sono, tra loro, completamente interconnessi. Questa

caratteristica mette già in conto una certa difficoltà realizzativa.

Infatti dati 2000 neuroni avremmo sinapsi da tenere in considerazione

nei calcoli. Nell‟esempio evitavo questo problema simulando un vicinato virtuale ogni

volta che dovevo effettuare l‟aggiornamento dei pesi. Il disegno seguente mostra invece

una architettura completa:

Page 64: Introduzione alle reti neurali artificiali

64

Matteo Tosato - Introduzione alle reti neurali artificiali

Y0 Ys...

...

Ys*s

Ys+1

Layer di input

Layer di output

(mappa di Kohonen)

Figura 18: Apprendimento competitivo per il neurone Y0

Sono presenti tutte le connessioni sinaptiche che vanno dal layer di input alla mappa

di Kohonen e anche tutte le connessioni laterali di uno dei neuroni topologici.

Topologico perché il layer di output è disposto su un piano, la mappa appunto. L‟indice

s è pari al lato della mappa.

Oltre che essere connesso con tutti gli altri neuroni del piano, ogni neurone possiede

una connessioni anche con se stesso. Il funzionamento della rete tenendo in

considerazione tutte queste caratteristiche aumenta l‟impegno computazionale richiesto.

Di seguito rivedo tutti i calcoli e le considerazioni fatte precedentemente riguardo le

som, cercando di attenermi a questo modello reale. Comunque non dimentichiamo che molte

volte non è necessario questo approccio complesso, ma è sufficiente attenersi alla

versione semplificata.

- Per prima cosa occorre inizializzare i pesi delle sinapsi, a differenza delle sinapsi

tra input ed output che si inizializzano nel solito modo con valori casuali tra 0 e 1,

le connessioni laterali avranno inizialmente tutte un valore uguale dato dalla

relazione:

dove NY è il numero dei neuroni che compongono la mappa. Per costruire

la mappa ricorro a 400 neuroni (mappa di 20*20 neuroni).

- Vengono inizializzati i valori di uscita dei neuroni di input. Per quanto riguarda il

nostro problema dei profili altimetrici abbiamo bisogno di 5 neuroni in ingresso.

(nelle applicazioni pratiche in genere si hanno un numero di neuroni in ingresso e in

uscita molto più elevato rispetto ai numeri citati nel nostro esempio.)

- Il primo calcolo da affrontare è quello della distanza tra la generica unità e

l‟input. L‟equazione seguente esprime il calcolo della distanza:

√∑( )

(

)

In questa formula, gamma è il “fattore di coscienza del neurone”. Questo è una

variabile locale del neurone, quindi ogni neurone avrà il suo fattore di coscienza

inizializzato a priori, in genere in modo casuale. Non cambierà durante l‟esecuzione.

Delta invece dipende dall‟epoca corrente, varia secondo la relazione seguente:

Page 65: Introduzione alle reti neurali artificiali

65

Matteo Tosato - Introduzione alle reti neurali artificiali

esprime la frequenza di vincita del neurone, quini più esso vince, più è probabile

accada ancora per input simili, innalzando e quindi definendo, l‟area di attivazione.

L‟uscita finale del neurone di output è data da:

- Dopo che ogni neurone ha il suo valore di uscita, essi cominceranno a competere tra

loro (come nelle reti biologiche). La competizione neuronale nello strato di uscita ha

come obiettivo eleggere un vincitore e un “vicinato”. Il vicinato può essere più o meno

esteso, relativamente alle dimensioni della rete. Nel caso della nostra rete 20*20 un

vicinato iniziale di 2 o 3 neuroni (caselle nella mappa) è sufficiente.

- A questo punto ogni neurone di uscita prima di tutto rinforzerà se stesso secondo

l‟equazione:

Mentre verrà inibito da tutti gli altri secondo quest‟altra relazione:

( )

Dove rappresenta tutti gli altri neuroni. “A” rappresenta un certo potenziale

responsabile del valore finale del neurone, dato generalmente da una funzione a rampa.

La funzione rampa che ci occorre è molto semplice:

( ) 2

Quindi:

( )

Dove è definito come “primo” perché deve essere confrontato con il valore di uscita

attuale del neurone, finche essi saranno molto diversi l‟iterazione viene ripetuta per

ogni neurone nuovamente (ultimo punto). (Nella libreria realizzata ho evitato di

attendere una uguaglianza esatta tra il vecchio e il nuovo valore, perché genera un

enorme numero di cicli da compiere. Ho preferito usare invece un‟espressione del tipo

Page 66: Introduzione alle reti neurali artificiali

66

Matteo Tosato - Introduzione alle reti neurali artificiali

seguente:

if (Math.Abs(t - OutputValue) >= 0.01). Questo mi ha evitato un eccessivo rallentamento di tutto il processo di apprendimento senza causare difetti nel funzionamento.)

Quando la richiesta viene soddisfatta il valore del neurone viene impostato con

- Una volta che la mappa di Kohonen raggiunge lo stato “stabile” un altro algoritmo ha

il compito di ricercare attraverso la mappa il neurone vincente, ovvero quello con il

valore più alto. Questo, assieme al suo vicinato, verrà “premiato” rinforzando le loro

connessioni sinaptiche verso il layer di input.

Il vicinato non rimane sempre al suo valore prestabilito inizialmente, ma diminuisce

nel tempo, in modo da accentuare la punta della collina attivata nella mappa. La regola

che stabilisce la sua evoluzione è:

( )

Dove il valore delta riferisce sempre a quello citato prima.

Quindi per ogni unità “vicina”. Compreso il neurone vincente vengono aggiornati i pesi

sinaptici, ma solo delle sinapsi tra input ed output, quelle laterali non mutano:

( ) Dove epsilon è il learning rate, ancora non citato. Questo è una costante globale nella

maggior parte dei casi. Nella mia libreria, applicata alla classificazione dei profili

altimetrici, ho ottenuto risultati soddisfacenti quando questo è impostato a 0.5 /

0.65.

- Una volta aggiornati i valori sinaptici del neurone vincente e del suo vicinato,

manca l‟ultima operazione, ovvero l‟aggiornamento della frequenza di vincita. Per tutta

l‟area vincente avremo:

( ) Mentre per tutti gli altri neuroni avremo un leggera diminuzione della costante, che

però avrà limite inferiore maggiore o uguale a 0. (per non avere frequenze negative.

Inoltre specifico che la frequenza di vittoria iniziale per tutti i neuroni è 0).

Reti SOM di grosse dimensioni sono piuttosto lente se addestrate con algoritmi di

questo tipo.

Esse mostrano in questo caso, una analogia più completa verso le cugine biologiche.

Anche in questo caso la rete neurale ha come scopo principale la classificazione di

pattern.

Page 67: Introduzione alle reti neurali artificiali

67

Matteo Tosato - Introduzione alle reti neurali artificiali

Problemi e strategie

Neuro-fuzzy

Le reti neurali, sono utilizzate nel campo della ricerca scientifica nel tentativo di

riprodurre almeno in parte il funzionamento del cervello dell‟uomo. In campo

applicativo o se volgiamo industriale, le reti hanno assunto nell‟ultimo decennio una

posizione di rilievo, ed il loro utilizzo e potenzialità diventa sempre più presente

nelle aziende tecnologiche.

Molte volte le reti vengono affiancate a sistemi fuzzy, magari proprio dove questi

falliscono, negli esempi trattati abbiamo avuto a che fare con problemi molto semplici,

dove in realtà il problema poteva essere risolto anche senza una rete neurale. Molto

spesso i sistemi fuzzy implementati nel modo classico presentano in molti punti del

loro funzionamento varie criticità. Il numero dei controlli sui parametri può crescere

di molto, peggiorando le performance. In questi casi la rete neurale trova

applicazione. Pensate ad un complesso algoritmo di classificazione, questo può

presentare in alcuni suoi punti di funzionamento delle criticità anche mai identificate

durante la fase di test del sistema. Queste criticità possono presentarsi durante

l‟utilizzo del prodotto da parte di un cliente finale. La rete neurale diminuisce

questo rischio dato che non avrà nessun bisogno di sapere come trattare i dati in

input. La rete neurale può, come abbiamo visto oramai piuttosto bene, imparare la

soluzione corretta per quel problema, inoltre rimanendo una struttura dati “semplice”,

non può generare titubanze nel suo algoritmo che rimarrà sempre lo stesso.

La prima combinazione tra reti neurali e sistemi fuzzy logic di cui parleremo,

definisce la NN come struttura dominante. E il sistema fuzzy come assistente al sistema

di addestramento. Un sistema fuzzy può ad esempio intervenire sull‟aggiornamento dei

vari coefficienti di training di una Error Back Propagation, come il learning rate o

momentum, ad ogni presentazione di input. Il sistema fuzzy si servirà allora di

algoritmi euristici per determinare il tipo di variazione a cui sottoporre i

coefficienti.

Lo stesso procedimento può essere applicato alle reti di Kohonen.

In altre situazioni si parla di “equivalenza neuro-fuzzy”. Facciamo un esempio, abbiamo

due input e e un output Y. Ciascuno dei due punti ha tre funzioni di membership,

rispettivamente: , e l‟output sia a singleton. Il seguente è lo schema funzionale:

Page 68: Introduzione alle reti neurali artificiali

68

Matteo Tosato - Introduzione alle reti neurali artificiali

X1 X2

FUZZY 1 FUZZY 2

M11 M12 M13 M21 M22 M23

R1 R9R2

U9

U1

...

U2

R9 = M13 M23R1 = M11 M21

Z1 = 1 / ƩRk Z2 = Ʃ(Uk Rk)

Y = Z1 Z2

Il sistema ha 6 strati,

- Lo strato di input con e .

- Il secondo strato ha due sezioni chiamate “pseudo-reti”, queste possono essere delle

reti neurali o neuro-fuzzy a loro volta non definite ma atte a generare le 6 funzioni

membership „M‟ citate prima.

- Il terzo strato sono proprio le 6 funzioni membership - Questi definiscono le 9 regole secondo le seguenti equazioni:

Queste secondo le seguenti regole formano e .

∑( )

Con k = 1,2,..,9 come avete visto dalle formule, in questo caso adottiamo anche i pesi

„U‟. Mentre nel caso delle regole precedenti abbiamo adottato solamente la

moltiplicazione.

- Infine abbiamo il neurone di output „Y‟ che esegue il prodotto tra i due valori „Z‟.

Questo esempio ha gli strati uno, due e tre che eseguono la “fuzzificazione”, il quarto

strato esegue le inferenze e gli ultimi 2 strati effettuano la defuzzificazione.

Page 69: Introduzione alle reti neurali artificiali

69

Matteo Tosato - Introduzione alle reti neurali artificiali

Questo tipo di configurazioni possono arrivare ad essere molto molto complesse, forse

perdendo un po‟ della praticità e semplicità delle reti neurali pure. Invece è

frequente vedere configurazioni neurali dove gli input di una rete sono output di

un‟altra rete neurale. Sfruttando le diverse configurazioni e caratteristiche delle

reti, è possibile risolvere molti tipi di problemi. Una rete neurale, una volta che il

suo funzionamento è stato testato e addestrata per un certo compito è definibile come

una “black box”. Quindi, come è frequente fare nella progettazione software, una rete

viene trattata come oggetto e utilizzata per comporre un sistema più grande che ha

bisogno di sfumare i suoi valori. Per il sistema precedente si applica l‟algoritmo EBP

per trovare i valori con cui aggiornare i pesi.

( ) e ( ) ( ) ( ) ( )

Reti ART

Questo tipo di rete neurale è interessante circa la capacità di apprendere

continuamente e auto-modificarsi all‟occorrenza.

Questa categoria di reti si suddividono a loro volta in ART1, le quali trattano solo

input binari, ART2, con input analogici, Fuzzy-ART che usa le operazioni logiche fuzzy

ed infine HART che esegue classificazioni e gerarchie. Le reti ART hanno comunque

complessità minore rispetto le precedenti, ma sono molto utilizzate per risolvere

problemi in cui si deve applicare la logica fuzzy. Sono caratterizzate da un buon

compromesso stabilità-plasticità.

Per stabilità si intende la capacità di non dimenticare quello che è già stato appreso

dagli input precedenti. Infatti normalmente le comuni configurazioni si modificano

secondo gli input che ricevono senza tenere traccia degli stati sinaptici passati.

Per plasticità si intende invece la capacità di auto-modifica in funzione ai nuovi

input o alla necessità di saper fare nuove classificazioni sui dati. Vedremo anche che

queste reti possono aumentare o diminuire il numero dei neuroni nei suoi strati.

Queste reti sono nate con lo scopo di riprodurre una caratteristica importante delle

reti neurali biologiche. Ovvero la capacità di apprendere senza dimenticare i modelli

precedenti. Si può ad esempio pensare alla capacità del cervello, questo ricorda volti

visti non recentemente anche dopo averne acquisiti molti altri nuovi nel frattempo.

Nelle reti invece abbiamo visto che i nuovi modelli imparati sostituiscono quelli

precedenti. Questa rete riproduce il sistema biologico di memoria a breve termine e

lungo termine. Questi meccanismi sono siglati rispettivamente STM e LTM. La prima

apporta cambiamenti graduali nella seconda.

La rete è costituita in due strati, ed . Questi sono interconnessi da pesi

sinaptici top-down e botton-up. Essi costituiscono la STM. Il sistema di apprendimento

è semplice; i pesi sono inizializzati ad uno, = . Mentre l‟opposta sinapsi

dove N è il numero di neuroni dello strato . Gli input sono presentati allo strato .

Vengono calcolate le funzioni di scelta:

( ) | |

| |

Dove è il parametro di scelta il vettore dei pesi sinaptici, il simbolo

|A| denota la norma del vettore A, cioè la sommatoria dei suoi componenti scalari: |A|

= ∑ , l‟operatore logico fuzzy: equivale a MIN(X,W), cioè:

| | ∑ ( ) .

Le classificazioni quindi avranno luogo nel secondo livello . Il nodo di questo

Page 70: Introduzione alle reti neurali artificiali

70

Matteo Tosato - Introduzione alle reti neurali artificiali

livello che ha il maggior valore viene prescelto come categoria di X, purché venga soddisfatto il criterio: (di vigilanza)

| |

| |

Dove p è il parametro di vigilanza < 1.

Lo schema della rete:

j. . .

i. . .

M neuroni

N neuroni

LTM, WbLTM, Wf

F1

F2

Se il criterio di vigilanza viene soddisfatto i pesi sinaptici vengono aggiornati:

(

) ( )

Nel caso in cui il criterio di vigilanza non è soddisfatto si crea un nuovo nodo,

ovvero un nuovo neurone. Il suo peso sinattico verrà inizializzato con l‟equazione

appena mostrata. Quindi viene ripresentato l‟input nuovamente fino a che la stabilità

non viene raggiunta.

Concludendo questa panoramica sulle ART, abbiamo appreso che in ogni caso il lavoro di

queste è molto simile a quello delle MLP con EBP come algoritmo di apprendimento.

Inoltre queste ultime abbiamo visto essere molto utili quando il numero di classi

possibili non è predeterminato. Di conseguenza le reti ART risolvono questo particolare

problema.

Metodologie di progettazione

Siamo arrivati a trattare alcune tra le più utilizzate configurazioni di reti neurali.

Tra queste abbiamo parlato, dandone buona importanza, il percettrone, il quale ricordo

nonostante le limitate capacità di separazione, può essere impiegato largamente in

problemi di classificazione, le reti multilivello MLP con algoritmo di apprendimento

EBP, molto onerose in risorse hardware e più complesse dal punto di vista matematico,

le reti di Kohonen con la loro capacità auto-organizzante. Infine abbiamo speso un po‟

di parole anche nel fare una analogia tra le reti neurali e la logica fuzzy. Queste due

tecnologie abbiamo visto essere integrabili e in grado di dare entrambi risultati

“sfumati”.

In questa parte invece faremo un discorso meno tecnico che verte a definire i criteri

di progettazione e di scelta che oramai dovrebbero essere divenuti intuibili. Faremo

riferimento in particolare alle reti MLP, essendo quelle più utilizzate in ambito

pratico. Definibili in punti, i seguenti sono gli argomenti da trattare:

1. Scelta dell‟applicazione. 2. Analisi. 3. Pianificazione delle risorse. 4. Definizione di un criterio per le performance della rete che si desidera.

Page 71: Introduzione alle reti neurali artificiali

71

Matteo Tosato - Introduzione alle reti neurali artificiali

5. Progetto della rete neurale. 6. Preparazione degli esempi. 7. Processo di apprendimento. 8. Valutazione finale ed applicazione.

1) Le reti neurali sono convenienti quando l‟algoritmo non si conosce, oppure quando

pensare ad una soluzione algoritmica tradizionale è troppo complesso e dispendioso.

Quindi non vengono applicate quando esistono già algoritmi noti. Ad esempio, negli

esempi fatti per l‟OR ed XOR, la rete neurale non era affatto necessaria dato che la

procedura per eseguire un OR oppure un OR esclusivo è ben nota. Più utile invece nel

caso del riconoscimento dei profili altimetrici.

Riepilogando, una rete neurale è conveniente quando l‟applicazione è “a intensità dei

dati”. Piuttosto che a “intensità di calcoli” e i dati sono prevalentemente

qualitativi, imprecisi e disturbati.

Ai risultati di una rete neurale è consentito essere imprecisi ed in un certo range.

L‟applicazione implementata a reti neurali non può essere “mission critical”. Dato che

queste possono dare risultati imprecisi e parziali. Non devono avere potere

decisionale. Una rete fornisce un dato qualitativo, un andamento previsto, oppure un

dato certo in percentuale. Ciò nonostante una rete può svolgere compiti impossibili per

programmi sequenziali. Come per esempio imparare a fare nuovi tipi di operazioni per

cui non erano state programmate. Adattarsi alla nuova situazione, correggere gli

errori, ricostruire un pattern danneggiato senza sapere la sua forma originale. Ciò che

fa il cervello umano.

2) Come abbiamo visto, una applicazione solitamente non è interamente realizzabile con

un rete neurale. Une applicazione viene solitamente organizzata con moduli in cascata.

Una parte chiamata “ragionatore” può essere costituita da un algoritmo esperto fuzzy, e

da una parte a rete neurale che da al sistema la facoltà di “percepire” informazioni

nuove dall‟ambiente. Consideriamo un esempio reale; il “Phonetic Typewriter” è un

sistema ideato dallo stesso Kohonen. Si tratta di una macchina da scrivere comandata a

voce. Essa comprende 3 moduli in cascata; il primo si basa su algoritmi standard ed

esegue la conversione analogico / digitale e poi l‟analisi di Fourier del segnale

vocale in input (FFT = Fast Fourier Transform); il secondo modulo è una rete auto-

organizzante di Kohonen, questo ha il compito di classificare i fenomeni in input. Il

terzo ed ultimo modulo raffina i risultati ottenuti dalla SOM, ovvero verifica i

risultati dal punto di vista grammaticale.

L‟accoppiamento in cascata di un elemento “ragionatore” ed una rete neurale si presta

molto bene nelle applicazioni dove sono necessarie due parti di sistema, una per

dedurre, da un suono o immagine, ed una per ottenere un dato preciso basato su questa

deduzione. Questa composizione a cascata può essere estesa anche agli stessi moduli di

reti neurali, molte volte composti da più reti in cascata. Come abbiamo già detto,

output di alcune reti possono divenire input di altre.

3) Questo punto parla unicamente delle risorse umane vere e proprie, nel caso lavoriamo

in un team. In questo momento non ci interessa.

4) Anche il quarto punto lo possiamo tralasciare, riguarda la definizione di un

criterio di performance. Nel senso che la rete neurale da creare deve apportare un

reale beneficio. Questo deve essere noto a priori. Lo tralascio perché mi sembra troppo

ovvio, ritengo che da capire il discorso spese/guadagno sia semplice.

5) Il progetto della rete è invece parte fondamentale. Richiede innanzi tutto la

definizione degli input e degli output e degli attributi degli input. Se venissero

trascurati questi fattori durante la progettazione di una rete neurale, si può ottenere

un risultato insufficiente. Ovvero la rete non funzionerà. Una cosa molto importante da

tenere sempre a mente è che per una rete, la presentazione e la qualità degli input

durante il training è fondamentale. Molto spesso gli input hanno bisogno di essere

“normalizzati” per essere adatti a divenire input della rete neurale. Gli input, se

sono ad esempio simboli, possono essere codificati in numeri attraverso una semplice

codifica binaria. Qui è bene precisare che non si tratta della consueta codifica

Page 72: Introduzione alle reti neurali artificiali

72

Matteo Tosato - Introduzione alle reti neurali artificiali

binaria che siamo portati a pensare. La codifica seguente non andrebbe bene:

questo perché la rete neurale tenderebbe a “raggruppare” i

valori come simili più di quanto farebbe con ad esempio. In questo caso

bisogna adottare un codifica detta “binaria estesa”. Ad esempio:

In questo modo i valori sono “distanti” uguali. Nel caso delle reti possiamo pensare che si attivi solo un input, sempre in una diversa posizione per ogni simbolo.

La decodifica può avvenire ad esempio nel modo seguente, noti e :

V =

e

( )( )

Poi c‟è da pensare al numero degli strati nascosti da utilizzare nel caso delle reti

MLP e dal numero di neuroni per ognuno di questi livelli. Per determinare il numero

degli strati ci viene incontro un metodo abbastanza rigoroso. Ricordate quando abbiamo

parlato della proiezione degli input nello spazio n-dimensionale? Solitamente quando la

separabilità ha una iper-superficie convessa, basta un solo strato; in caso di

separabilità con iper-superficie concava saranno necessari due strati. Tuttavia non

esiste nessuna certezza matematica di questo, è comunque preferibile avere un solo

strato di neuroni nascosti, dato che con il crescere di questi, il numero dei pesi

sinaptici da aggiornare cresce anch‟esso, aumentando il costo in termini di risorse

hardware necessarie. E‟ anche vero che esiste un metodo, applicabile all‟algoritmo di

addestramento EBP che valuta durante questo, la possibilità, necessità di aumentare o

diminuire il numero dei neuroni. Questo metodo prende il nome di “Structural Learning”.

Esistono due varianti, nella si ha una rete inizialmente con poche neuroni e neuroni

intermedi vengono aggiunti secondo necessità, questo metodo è utile anche per

aggiornare una rete neurale esistente. La seconda variante elimina neuroni, partendo

ovviamente da una situazione di eccesso. Per questa esistono poi molte sotto varianti

che non vedremo, uno può anche, una volta nel contesto della sua applicazione,

inventare nuovi sistemi di adattamento strutturale automatici.

Un altro elemento da scegliere con attenzione riguarda il tipo di funzioni di

trasferimento da utilizzare. Noi abbiamo in precedenza visto ed anche utilizzato le più

diffuse. E‟ possibile comunque applicare qualsiasi tipo di funzione. L‟importante è che

siano continue, monotone e derivabili. Abbiamo già visto che non possono essere tutte

lineari. Come nel caso delle reti MLP. Negli strati intermedi le funzioni non hanno

scopo di essere lineari, come abbiamo visto per la rete XOR.

6) Siamo arrivati alla progettazione del training set, o degli esempi. Quando

l‟apprendimento della rete è supervisionato, abbiamo bisogno di preparare un efficiente

training set. Gli esempi devono essere preparati tenendo conto di fattori precisi. Nel

caso si parte da dati esistenti, prima di inserirli come input, dobbiamo eliminare gli

estranei e omogenizzare quelli necessari all‟applicazione, controllando le omonime

(dati diversi con lo stesso nome), e le sinonime (dati uguali ma con nome diverso),

controllare la congruenza delle unità di misura e la compresenza di dati gerarchici.

Inoltre il numero di esempi deve essere dimensionato alla complessità del problema.

Esistono regole più o meno corrette per fare una stima del numero di esempi necessari.

Una di questi è la seguente:

Un altro fattore estremamente importante è fornire alla rete neurale input rumorosi.

Ovvero non del tutto esatti. Ad esempio se l‟output corretto della rete per un

determinata iterazione del training set è 0.5, noi possiamo fornire alla rete come

valore atteso anche 0.48. In questo modo la rete addestrata è in grado di fare delle

generalizzazioni più efficaci. In questo procedimento non bisogna però esagerare,

dipende da quanto la generalizzazione è importante per la nostra applicazione, una

grande capacità di generalizzare è accompagnata naturalmente anche ad una minore

precisione.

7) Abbiamo già accennato in precedenza ai coefficienti di apprendimento, che come nel

caso dell‟esempio del capitolo sulle reti MLP essi sono determinanti. Nelle reti MLP

viene applicato l‟algoritmo BP in una delle sue varianti, la scelta del valore per

learning rate e momentum non sono dettate da metodi rigorosi, sono comunque valori

solitamente bassi, inferiori allo 0.5. Esiste poi la possibilità di implementare il

comportamento del learning rate come “adattativo”. Quando l‟algoritmo rimane bloccato

in un minimo locale, il learning rate viene aumentato / diminuito per dare il giusto

Page 73: Introduzione alle reti neurali artificiali

73

Matteo Tosato - Introduzione alle reti neurali artificiali

apporto di precisione alla rete senza prolungare eccessivamente la durata

dell‟addestramento.

In conclusione il problema / caratteristica delle reti neurali è che non ci sono metodi

precisi ne di progettazione ne di validazione, ci sono reti neurali adatte solo a

determinati compiti, non riutilizzabili, è bene salvare le varie configurazioni che

durante l‟utilizzo nelle applicazioni vengono aggiornate o cambiate, questo per poter

ritornare nello stato precedente nelle eventualità che anche i fattori esterni

ritornino ad uno dei loro stati passati.

Una buona idea è secondo me inserire tra le routine di chiamata delle librerie /

applicazioni neurali anche funzione per il salvataggio e ripristino dei pesi, o anche

del numero di neuroni correnti per ogni strato.

Il problema dei dati in ingresso

Forse il compito dove le reti neurali trovano maggior successo è quello che concerne la

visione artificiale. Esiste da più di una dozzina d‟anni una libreria open source

dedicata alla visione. OpenCV. Questa libreria permette la realizzazione di programmi

in grado di riconoscere oggetti tramite una periferica, tipo una telecamera. Nel campo

della videosorveglianza queste vengono pesantemente utilizzate. Si pensi ad esempio al

problema del riconoscimento di una figura umana in una scena dinamica. Un compito

assolutamente impossibile per un normale programma sequenziale. Oppure un sistema di

riconoscimento targhe, oppure ancora un sistema per riconoscere i visi all‟ingresso di

un ufficio.

Dato che sarebbe una pazzia partire a progettare un sistema del genere dal singolo

neurone (anche se qui non nego di aver parlato con persone potenzialmente in grado di

farlo) dobbiamo ricorrere a queste librerie, che più che fornirci il sistema neurale,

ci danno dei moduli già composti per trattare i dati che otteniamo dalle periferiche.

Infatti uno dei maggiori problemi che incontriamo quando lavoriamo con le reti neurali

consiste nel modo in cui trattare i dati in ingresso alla rete. Rimanendo sull‟esempio

della visione artificiale, possiamo pensare alla qualità delle immagini in arrivo da

una telecamera, esse possono arrivare con molteplici problemi e situazioni variabili;

immagini buie, sfocate, disturbate etc... A questo problema occorre rispondere con

faticose operazioni di correzione e revisione delle immagini in arrivo. Data una

immagine devono esserne evidenziate le caratteristiche salienti che ci interessano. Se

il nostro compito è quello di individuare all‟interno di un video una figura umana

dobbiamo cercare di mettere in evidenzia proprio le caratteristiche che ci interessano.

Ad esempio i contorni delle figure saranno di maggior importanza rispetto alla qualità

dei colori.

A questo proposito esistono filtri che ricalcano complesse e dispendiose operazioni

matematiche sulle immagini, che sono ovviamente trattate come matrici di pixel.

Questo problema del trattamento dei dati in ingresso esiste anche in tutti gli altri

ambiti di impiego.

Un‟altra questione è relativa a come codificare i dati in input. Ne abbiamo già

accennato; non sempre i dati da analizzare hanno un formato adatto per costituire

l‟input di una rete neurale. Le normalizzazioni o lo streching di questi valori spesso

non è sufficiente o è comunque impossibile da eseguire. Immaginiamo di dover

classificare delle forme di figure piane. Quello che è necessario è trovare un codifica

adatta. Oltre rappresentarne la caratteristica, occorre mantenere anche i fattori di

proporzione che le figure hanno tra loro, se questo non viene garantito, i risultati

Page 74: Introduzione alle reti neurali artificiali

74

Matteo Tosato - Introduzione alle reti neurali artificiali

generati saranno scorretti. Consideriamo una rete con tre input e le seguenti codifiche

dei dati;

001

001

010

010

011

100

L‟esempio sopra mostra sulla prima riga una codifica errata, mentre sulla seconda una

alternativa migliore. La prima codifica indicherebbe alla rete neurale un valore più

pesante per la figura a stella, quindi nella computazione totale, essa tenderebbe ad

avere molto più peso rispetto le altre.

La seconda codifica invece si limita a evidenziare la caratteristica senza influire sul

peso di essa.

Esempi di applicazioni pratiche

Intrusion detection

Presentiamo ora una serie di concetti strettamente legati alle conoscenze nel campo

delle telecomunicazioni, dei protocolli di rete e della sicurezza informatica. Cercherò

comunque di indicare delle linee generali applicabili anche ad altri ambiti, ma è

sicuramente ideale avere la conoscenza informatica di base almeno per quanto riguarda

reti e naturalmente, programmazione. Sarebbe stato forse peggio trattare degli esempi

come l‟applicazione delle reti neurali nell‟analisi finanziaria, lì occorrerebbe

davvero studiare molti concetti che riguardano l‟economia e la statistica per poi

applicare le reti nella progettazione di sistemi che effettuano delle previsioni su

tassi e tendenze.

Questo dimostra l‟incredibile varietà di campi disponibili in cui questa tecnologia può

essere impiegata. Recenti successi sono stati ottenuti nel campo medico grazie a reti

neurali per il riconoscimento di tumori nelle radiografie, piuttosto che reti neurali

impiegate nel campo delle biotecnologie.

Due parole su cosa significa analizzare il traffico di rete;

internet e le reti più in generale si basano su una serie di protocolli. I “protocolli”

sono una convenzione che i programmatori devono utilizzare nella scrittura delle parti

dei loro programmi che devono comunicare con altri computer nella rete. In questo modo

è possibile garantire una adeguata “compatibilità” tra tutti i tipi di sistemi che

devono poter comunicare indipendentemente dal tipo di piattaforma.

Prima di proseguire raccomando di approfondire questo aspetto se non lo si conosce di

già. Di seguito lascio alcuni spunti introduttivi. Saremo malgrado costretti ad

affrontare questioni molto tecniche e specifiche della progettazione di questi

protocolli, dato che noi dovremo monitorarne il

transito, occorre averne una profonda conoscenza.

http://it.wikipedia.org/wiki/Protocollo_di_rete

http://it.wikipedia.org/wiki/Modello_OSI

Page 75: Introduzione alle reti neurali artificiali

75

Matteo Tosato - Introduzione alle reti neurali artificiali

Alcuni cenni sulla programmazione di rete:

http://scuola.linux.it/docs/altre_scuole/planck/socket/progr-socket4.html

Dunque il problema che ci troviamo a dover risolvere non è poi dei più semplici. I

seguenti punti mostrano le più comuni situazioni in cui il traffico di rete è

considerato certamente anomalo:

- Flusso in entrata di un elevato numero di richieste di connessione.

- Flusso di un elevato numero di reply ARP senza precedenti richieste.

- Pacchetti con MTU superiore alla norma.

- Flusso elevato di richieste di ping.

- Pacchetti TCP desincronizzati.

Da queste semplici osservazioni è piuttosto complicato tentare di riconoscere se si

tratta di pacchetti legittimi, errori o tentativi di attacco. Un grande flusso di nuove

connessioni in entrata non è detto rappresenti sempre il tentativo di provocare

l‟interruzione dei servizi. Potrebbe essere che l‟host è in effetti in un momento di

grande utilizzo da parte dei client, oppure si potrebbe trattare di tentativo di

profiling verso l‟host.

La valutazione di questi aspetti può essere fatta con regole piuttosto semplici, non ci

occorre utilizzare metodi fuzzy. Il nostro obiettivo è capire, a prescindere dalle

informazioni inviate (cose difficile da fare senza rischiare di bloccare

accidentalmente connessioni legittime) se si tratta di una connessione instaurata da

un‟attaccante o da un regolare client. Almeno per quanto riguarda tutto il traffico

TCP, che è anche la tipologia di pacchetti più abbondante che transita sulle reti.

Sono necessarie delle osservazioni fatte sulle tempistiche di invio – ricezione.

Dobbiamo tener presente che nella maggior parte dei casi gli attacchi vengono

effettuati attraverso host “intermediari”. Chiamati anche bot. L‟attaccante infatti,

prima viola altri server meno controllati e ne acquisisce il controllo. Poi da questi

lancia il suo reale attacco. In questo modo esso aumenta la sua speranza di rimanere

nell‟anonimato. Più host intermediari usa più è probabile che la sua identità rimanga

non conosciuta.

Molti tipi di approcci sono stati utilizzati nel corso degli anni per sfruttare la

differenza che si ha nelle connessioni di questi attaccanti e quelle degli utenti

normali. L‟elemento che andremo a prendere in considerazione ora è il “Round trip time”

(RTT).

Di cosa si tratta? Per capirlo dobbiamo tenere ben presente il funzionamento del

protocollo TCP. Questo implementa un sistema di controllo per l‟affidabilità della

trasmissione dei dati. Esso si basa su una conferma di ricezione da parte del

ricevente. Il protocollo contiene difatti un campo “acknowledgement” atto a contenere

il numero di sequenza del prossimo pacchetto che egli si aspetta di ricevere. In questo

modo, i due host sono sincronizzati. E accetteranno pacchetti solo se essi risultano

attinenti al range (la finestra di TCP) aspettato. Si veda un adeguato approfondimento

all‟argomento.

L‟RTT corrisponde al tempo di andata e ritorno di un pacchetto dati da un client al

server. Ogni host tiene in memoria un tempo RTT previsto entro il quale l‟altro capo

della connessione dovrà rispondere. Se la conferma di ricezione non arriva nel tempo

previsto l‟host ritrasmetterà le informazioni.

L‟RTT previsto viene calcolato nel modo seguente:

( ) ( ( )) (( ) )

corrisponde al tempo RTT appena campionato. Tcp è così in grado di adattarsi alla

larghezza di banda e al traffico di rete, ed elimina il problema dei percorsi

differenti che vari pacchetti TCP della medesima connessione possono prendere. Quando

un pacchetto viene perso, non potendo il destinatario riceverlo esso non invierà

conferma e il timeout scadrà, a questo punto il mittente rispedisce i dati, quando

arriverà la conferma di ricezione, il mittente non ha modo di sapere se questa

Page 76: Introduzione alle reti neurali artificiali

76

Matteo Tosato - Introduzione alle reti neurali artificiali

riferisce al primo o al secondo pacchetto inviato, comunque incrementerà l‟RTT perché

considererà il primo pacchetto spedito. Tale fenomeno viene chiamato “ambiguità della

conferma di ricezione” e le conferme di ricezione di TCP sono dette “ambigue”.

Volendo si potrebbe fare in modo che TCP calcoli l‟RTT non dal pacchetto originale ma

dalla ritrasmissione, ma in questo modo si avrebbe un problema ancora maggiore dato che

l‟RTT finirebbe per diventare troppo breve a tal punto che TCP invierebbe ogni

pacchetto almeno due volte generando il doppio del traffico. Quindi nonostante il

problema dell‟ambiguità, TCP tende a tenere un tempo RTT “pessimista” come valore di

timeout.

Il seguente grafico mostra l‟andamento dell‟RTT durante un tipica connessione tra due

host di una rete LAN:

Questo grafico non mostra il valore timeout RTT di TCP, mostra il valore RTT campionato

sulla base dei pacchetti ricevuti.

Vediamo di capire come possiamo utilizzare questi dati per i nostri scopi.

Il calcolo del valore RTT permette di stimare il numero di host (quindi di

elaborazioni) presenti sul tratto “downstream” della connessione. Determinando una

certa “lunghezza” di connessione, possiamo capire se si tratta di una intrusione o

meno. Il nostro “sensore” viene posizionato nel modo seguente:

Page 77: Introduzione alle reti neurali artificiali

77

Matteo Tosato - Introduzione alle reti neurali artificiali

Host1 Host2 Host3 Victim

Attacker

Normal clientC1

Ci Cn-1Cn

Sensor

Figura 19: Schema attacco informatico mediante host intermediari

Possiamo considerare ogni pacchetto TCP “outcoming” e il rispettivo “echo”, quindi

calcolare la differenza temporale RTT del pacchetto in andata e ritorno. Questo tempo

può essere influenzato da molteplici fattori.

Dobbiamo considerare il tempo di propagazione ( ), quindi dipendente dalla distanza

fisica, il tempo impiegato dal calcolatore per processare il pacchetto ( ), il tempo di

accodamento che il pacchetto può avere nello stack TCP/IP ( ), e il tempo di

trasmissione ( ). Quindi possiamo riassumere il calcolo del RTT nel modo seguente:

( )

Generalmente è piuttosto costante per molti pacchetti. Quindi raggruppando il

calcolo può essere inteso anche come:

Dove è il ritardo non variabile o costante e è il ritardo variabile definito da

( ). Se ci sono K connessioni, (o k hosts) tra l‟attaccante e la vittima,

allora il valore rappresentato da rappresenta la parte di variazione di tutti i

ritardi lungo la catena di connessioni tra questi hosts:

Per poter calcolare questo valore dobbiamo iterare su ogni pacchetto in arrivo e se si

tratta di un pacchetto echo, confrontare questo con il relativo pacchetto di invio, se

non si tratta di un echo ma di un pacchetto outcoming, lo si accoda per essere

“matchato” dopo. Lo pseudo-codice:

(Han-Ching Wu And Shou-Hsuan Stephen Huang, Department of Computer Science, University

of Houston)

Initialize send queue;

while(there are some packets) {

read next packet P; {

if P is a send packet {

calculate TimeGap;

if TimeGap > threshold

reset Send queue;

else

insert packet P to Send queue;

Page 78: Introduzione alle reti neurali artificiali

78

Matteo Tosato - Introduzione alle reti neurali artificiali

}

else if P is an echo packet {

if (P.size is large) do nothing;

else {

S = dequeue(Send);

if((S.ack = P.seq) and (S.seq < P.ack)) {

Match P and S;

Compute RTT between P and S;

}

}

}

}

}

Sicuramente è una osservazione acuta il fatto di specificare che non tutti i valori RTT

della connessione saranno uguali. Questo dipende dalla fluttuazione del traffico di

rete. E‟ anche vero però che analizzando intervalli ristretti di tempo questo problema

scompare e tutti gli RTT saranno più o meno simili. Sulla base di questo è possibile

riconoscere, o meglio definire vari livelli del valore RTT e di conseguenza, stimare il

numero di “stepping-stones” (gli host presenti lungo la connessione).

I vantaggi di usare l‟intelligenza artificiale (NN, neural networks) invece di

algoritmi esperti fuzzy sono innanzi tutto una notevole flessibilità; questa è

importante perché le situazioni nelle quali un host si può trovare sono molto varie. Le

nn possiedono anche la capacità di analizzare dati non-lineari con multi-variabilità.

Non dovremo considerare connessione per connessione ma solo i pacchetti in se. Quando

vedremo una serie di valori RTT assolutamente fuori scala sapremo che quella

connessione è ipoteticamente una intrusione che sta utilizzando vari host intermediari

per nascondere la sua identità. Un messaggio sarà reso all‟amministratore che

effettuerà il dovuto controllo approfondito. Date le diverse situazioni possibili in

cui gli host si possono trovare, la rete neurale è la soluzione migliore circa

l‟adattabilità del sistema.

Vediamo per step le operazioni da compiere:

1 Per prima cosa occorre creare il sistema per il capture dei pacchetti ed il

filtraggio. Tramite una call-back i pacchetti TCP send o echo devono essere inseriti in

una coda pronti per essere processati.

2 Poi, secondo l‟algoritmo presentato prima, occorre calcolare il valore RTT

campionato, dobbiamo poi raggruppare questi in righe di n valori, dove n corrisponde al

numero di neuroni della rete neurale nel layer di input. Se per esempio abbiamo 500

valori RTT e 10 neuroni in ingresso, organizzeremo gli RTT in 50 righe, ovvero 50 set

per la rete. Ognuna di queste righe viene valutata dalla rete.

3 Una volta che la rete ha elaborato i set in input è in grado di valutare il numero di

“stepping-stone” presenti e confrontando questo valore con una media su tutti i

pacchetti è in grado di individuare le connessioni che stanno molto probabilmente

utilizzando sistemi intermediari per accedere. Poi queste possono essere ulteriormente

filtrate in base a criteri che eliminano evidenti falsi allarmi.

Ma la cosa interessante che occorre focalizzare è l‟estrema adattabilità del sistema

senza effettuare la ricompilazione, sarà sufficiente addestrare la rete in modo

diverso, per avere un comportamento differente.

Il tipo di rete neurale che può essere impiegato non è restrittivo al patto che sia una

feed-forward, dato il compito di “classificazione” che gli spetta. I neuroni nascosti e

il neurone di uscita devono avere una funzione non lineare. Può andare bene la

Page 79: Introduzione alle reti neurali artificiali

79

Matteo Tosato - Introduzione alle reti neurali artificiali

tangente, la sigmoide o anche la funzione seno. Un esempio di configurazione con 10

neuroni di input:

x1

x2

x3

x4

x5

X6

X7

X8

X9

x0

Y(Ʃ(x*w))

Y(Ʃ(x*w))

Y(Ʃ(x*w))

Y(Ʃ(x*w))

NetOut =

Y(Ʃ(Y(Ʃ(x*w1)*w2)))

Figura 20: Rete MLP per la valutazione degli RTTs

Scendiamo nel dettaglio della progettazione di un sistema di questo tipo. Nella maggior

parte dei casi, le spiegazioni teoriche di una cosa nascondono una miriade di questioni

pratiche che solitamente vengono tralasciate.

Di seguito vediamo come realizzare i vari moduli del nostro programma. Diamo per

assunto che la cosa può essere fatta sia come programma munito di interfaccia utente

grafica, (come ho fatto io per provare il sistema), o come modulo kernel. Detto questo

cambia poco per i moduli principali eccetto forse il modulo di cattura che a livello

kernel viene fatto in modo differente.

Appunto il processo di cattura dei pacchetti è la prima cosa che dobbiamo affrontare.

Un sistema di cattura è di fatto un driver in grado di passarci, tramite una funzione

callback, ogni pacchetto che transita sulla scheda di rete o attraverso il nostro host

in generale. Le modalità di esecuzione sono generalmente due, normale e promiscua. In

modalità normale il traffico acquisito sarà relativo ad una particolare scheda di rete,

tutti gli altri pacchetti che non sono indirizzati o non escono dall‟interfaccia non

sono considerati. La modalità promiscua invece opera nel modo inverso, tutti i

pacchetti vengono acquisiti indipendentemente dalla loro origine o dalla loro

destinazione.

Il pacchetto ci viene consegnato nella sua integrità, ovvero avremo un puntatore che

punta al primo byte dello strato di collegamento, generalmente ethernet.

Ethernet IP Data ...

Anche se lavoriamo a livello kernel avremo lo stesso risultato, ma non lo faremo

utilizzando dei driver di terze parti, nel caso di linux occorrerà utilizzare

l‟interfaccia “netfilter” per ricevere in modo seriale assieme agli altri moduli di

Page 80: Introduzione alle reti neurali artificiali

80

Matteo Tosato - Introduzione alle reti neurali artificiali

rete i puntatori ai pacchetti da analizzare. Inoltre lavorando a questo livello è

possibile bloccare i pacchetti prima che essi transitino nella scheda. Per esempio, se

il nostro modulo viene assemblato assieme ad un canonico firewall potremmo scegliere se

fornire un semplice sistema di segnalazione o permettere al nostro modulo di

intervenire in “real-time” sul traffico.

Ho utilizzato i driver libpcap per realizzare il modulo. Ho inserito tutte le procedure

in una classe appoggiandomi al framework Qt. Le funzioni native pcap da utilizzare sono

in ordine:

pcap_findalldevs(), per acquisire la lista di interfacce di rete disponibili.

pcap_lookupnet(), per acquisire informazioni addizionali sull‟interfaccia.

pcap_open_live(), per ottenere un handle di sessione.

pcap_datalink(), per verificare il livello di collegamento.

pcap_next_ex(), restituisce il prossimo pacchetto presente in stack.

Tutte le funzioni sono descritte all‟interno della documentazione che viene fornita

all‟interno dei sorgenti, oppure direttamente sul WEB all‟indirizzo seguente:

http://www.winpcap.org/docs/docs_412/html/main.html

Ogni pacchetto acquisito dovrà essere analizzato dall‟algoritmo proposto prima.

Ricordo che comunque l‟analisi che andremo a fare è bene farla non su tutte le porte

contemporaneamente, ovvero, è necessario filtrare i pacchetti in modo da non

considerare tutto il traffico delle altre applicazioni che non siano i vari client di

accesso remoto utilizzati dagli attaccanti, questi sono generalmente telnet, Open-ssh,

Putty e pochi altri. E‟ assolutamente inutile acquisire tutto il traffico TCP riferito

alla porta 80. Produrrebbe solo dei risultati confusionari dato che il traffico WEB

produce migliaia di pacchetti al minuto. Ed è anche inutile perché non è possibile

utilizzare quella porta da lato client se impegnata già a fare un altro tipo di

servizio, sia da parte dell‟utente legittimo che dall‟attaccante. A meno che l‟exploit

si trova nel web server, ma anche in questo caso, gli exploit aprono connessioni non di

certo dalla stessa porta di servizio.

L‟algoritmo lo abbiamo visto, qui vediamo come implementarlo in modo pratico. Innanzi

tutto vediamo di definire che cosa si intende per “pacchetto Send e Echo”. Un pacchetto

Send è definito come segmento in uscita dall‟interfaccia di rete dell‟host monitorato,

o come in questo caso, dall‟host su cui il nostro programma stà girando, esso contiene

dati. Questo pacchetto ha il flag ACK e PSH settato. Non ci interesseremo a quale

connessione appartiene, abbiamo detto che non ci importa di avere anche questa

variabile. Ci limiteremo a “match-are” tutti i pacchetti send ed echo.

Recuperiamo il flusso di una comune sessione TCP nella quale due host si sono scambiati

un certo numero di dati. Vi evidenzio i pacchetti Send ed Echo con i colori rosso e blu

rispettivamente.

|Time | 192.168.0.2 |

| | | 91.203.96.252 |

|11,995 | SYN | |Seq = 0

| |(6206) ------------------> (443) |

|12,090 | SYN, ACK | |Seq = 0 Ack = 1

| |(6206) <------------------ (443) |

|12,091 | ACK | |Seq = 1 Ack = 1

| |(6206) ------------------> (443) |

|12,091 | PSH, ACK - Len: 180 |Seq = 1 Ack = 1

| |(6206) ------------------> (443) |

|12,191 | ACK | |Seq = 1 Ack = 181

| |(6206) <------------------ (443) |

|12,193 | ACK - Len: 1360 |Seq = 1 Ack = 181

Page 81: Introduzione alle reti neurali artificiali

81

Matteo Tosato - Introduzione alle reti neurali artificiali

| |(6206) <------------------ (443) |

|12,196 | ACK - Len: 1360 |Seq = 1361 Ack = 181

| |(6206) <------------------ (443) |

|12,196 | ACK | |Seq = 181 Ack = 2721

| |(6206) ------------------> (443) |

|12,295 | ACK - Len: 1360 |Seq = 2721 Ack = 181

| |(6206) <------------------ (443) |

|12,295 | PSH, ACK - Len: 509 |Seq = 4081 Ack = 181

| |(6206) <------------------ (443) |

|12,295 | ACK | |Seq = 181 Ack = 4590

| |(6206) ------------------> (443) |

|12,328 | PSH, ACK - Len: 267 |Seq = 181 Ack = 4590

| |(6206) ------------------> (443) |

|12,469 | ACK | |Seq = 4590 Ack = 448

| |(6206) <------------------ (443) |

|12,469 | PSH, ACK - Len: 59 |Seq = 448 Ack = 4590

| |(6206) ------------------> (443) |

|12,565 | ACK | |Seq = 4590 Ack = 507

| |(6206) <------------------ (443) |

|12,565 | PSH, ACK - Len: 59 |Seq = 4590 Ack = 507

| |(6206) <------------------ (443) |

|12,572 | PSH, ACK - Len: 901 |Seq = 507 Ack = 4649

| |(6206) ------------------> (443) |

|12,722 | ACK | |Seq = 4649 Ack = 1408

| |(6206) <------------------ (443) |

|12,722 | PSH, ACK - Len: 517 |Seq = 1408 Ack = 4649

| |(6206) ------------------> (443) |

|12,827 | ACK | |Seq = 4649 Ack = 1925

| |(6206) <------------------ (443) |

|12,837 | PSH, ACK - Len: 229 |Seq = 4649 Ack = 1925

| |(6206) <------------------ (443) |

|12,838 | PSH, ACK - Len: 261 |Seq = 4878 Ack = 1925

| |(6206) <------------------ (443) |

|12,838 | ACK | |Seq = 1925 Ack = 5139

| |(6206) ------------------> (443) |

|12,838 | FIN, ACK | |Seq = 5139 Ack = 1925

| |(6206) <------------------ (443) |

|12,838 | ACK | |Seq = 1925 Ack = 5140

| |(6206) ------------------> (443) |

|12,938 | FIN, ACK | |Seq = 1925 Ack = 5140

| |(6206) ------------------> (443) |

|13,033 | ACK | |Seq = 5140 Ack = 1926

| |(6206) <------------------ (443) |

Abbiamo 3 valori RTT campionati.

0.204 s., 0.237 e 0.265.

Nell‟algoritmo utilizziamo la regola:

“if((S.ack = P.seq) and (S.seq < P.ack))”

questa ci impedisce di sbagliare la corrispondenza dei due pacchetti.

Riprendendo direttamente il mio codice avrò alcune routine che provvedono al

riconoscimento degli strati e all‟accesso a questi tramite un sistema di puntatori e

casting. Fino ad arrivare al riconoscimento del pacchetto Send, ovvero:

if(ip->saddr == localip && (tcp->flags & 0x10) && (tcp->flags & 0x18)) {

I flag che vado a controllare sono l‟ACK e PSH e naturalmente l‟indirizzo di origine,

che deve essere il mio. Queste regole classificano il pacchetto come “Send”. A questo

Page 82: Introduzione alle reti neurali artificiali

82

Matteo Tosato - Introduzione alle reti neurali artificiali

punto può essere inserito in un struttura FIFO come una coda. Infatti è il primo

pacchetto send a dover essere abbinato al primo pacchetto echo che rispetta le seguenti

regole:

}else if((ip->daddr == localip) && (tcp->flags & 0x10) && (tcp->flags & 0x18)) {

...

if((s_tcp->ack_n == tcp->seq_n) && (s_tcp->seq_n < tcp->ack_n)) {

Soltanto a questo punto possiamo calcolare il valore RTT della coppia di pacchetti.

I risultati dei campionamenti devono essere organizzati in “set” per la rete neurale.

Ovvero dato il numero N di neuroni che abbiamo scelto per lo strato di input della rete

dovremo organizzare i valori in array di N elementi e sottoporli alla rete. Se mi è

concesso di generalizzare la struttura della rete, possiamo riassumere con questo

schema:

∑ f.

.

.

RTT1

RTT2

RTTN

Il valore di uscita della rete da un‟idea del numero di “stepping-stones” rilevati

dalla serie di RTTs.

Ci sono comunque delle note da fare su questo sistema.

Non rappresenta una soluzione completamente sicura e applicabile in ogni circostanza.

Immaginiamo un server che offre un servizio di accesso remoto con SSH, (anche se questo

è abbastanza improbabile come servizio) ed esso sia pesantemente utilizzato. E‟

possibile che un attaccante si mischi nella folla sfruttando tutto il timeout di TCP

prima di inviare il pacchetto successivo. Questo potrebbe indurre al fallimento il

nostro sistema, dato che considererebbe i tempi RTT alti rilevati come “eccezioni”

dovute ad anomalie; e proprio il punto di forza delle reti neurali rischierebbe di

essere causa del fallimento del sistema di rilevamento. Pertanto in questi casi

occorrerebbe anche tenere come riferimento la connessione in se e andare a analizzare

gli RTT campionati solo relativi ad essa, questo per ogni connessione. Questo complica

le cose e più che altro, aumenta notevolmente il costo in potenza di calcolo necessario

per il sistema.

Generalmente possiamo tenere monitorate le porte di servizio. Ad esempio, abbiamo un

server web che può essere gestito da remoto tramite SSH, (questa è una situazione

piuttosto comune per la maggior parte dei server di servizi internet) quindi il numero

di connessioni previste sulla porta 22 sarà pari ad uno. Così, oltre a stabilire un

numero massimo di sessioni SSH, il sistema sarebbe in grado di valutare se l‟accesso è

tenuto da un client standard, oppure se esso sta utilizzando una lunga catena di

connessioni per nascondere la sua identità. In questo ultimo caso la connessione può

essere interrotta. L‟attaccante sarebbe così obbligato ad utilizzare una connessine

diretta per l‟accesso e così facendo, sarebbe velocemente smascherato tramite i sistemi

per la localizzazione dell‟IP utilizzabili dagli stessi provider proprietari delle

linee. Dal punto di vista dell‟utente è sufficiente segnalare l‟IP registrato nei log

che risulta autore di azioni sospette per far scattare tutta la questione.

Page 83: Introduzione alle reti neurali artificiali

83

Matteo Tosato - Introduzione alle reti neurali artificiali

Un sistema del genere è comunque supplementare ai sistemi anti-intrusione tradizionali.

Si tratta di tecniche nuove e piuttosto diverse dalle solite ma non le sostituiscono,

aggiungono solamente un certo grado di intelligenza.

I seguenti sono i tempi RTT che ho rilevato per connessioni dirette in Rete LAN,

ipotizzando di utilizzare una rete neurale a 6 neuroni di input, avremmo:

RTT set n°1

0.140795s. 0.700669s. 0.093393s. 0.123039s. 0.121076s. 0.10092s.

RTT set n°2

0.092423s. 0.092714s. 0.100824s. 0.094254s. 0.09343s. 0.764306s.

RTT set n°3

0.099924s. 0.099725s. 0.092682s. 0.100902s. 0.100548s. 0.492595s.

RTT set n°4

0.095503s. 0.099248s. 0.095705s. 0.095733s. 0.095373s. 0.094035s.

RTT set n°5

0.097204s. 0.096408s. 0.099615s. 0.799309s. 0.651773s. 0.095147s.

RTT set n°6

0.282706s. 0.099976s. 0.119879s. 0.199972s. 0.200492s. 0.100925s.

RTT set n°7

0.099749s. 0.099919s. 0.101313s. 0.100984s. 0.100547s. 0.099287s.

I valori sono tutti più o meno simili e, salvo casi particolari, non sono superiori ai

200 ms. (una media di 100 ms.) Per questo motivo sarebbe meglio utilizzare più neuroni

di input, magari tra 15 e 20. Per le connessioni provenienti da internet avremo valori

leggermente più alti.

Non c‟è un sistema univoco per effettuare la giusta valutazione (ovvero il tipo di

addestramento da fare), perché le situazione può essere davvero varia. Per questo

motivo la rete neurale risulta molto comoda, è sufficiente un riaddestramento per

modificare il criterio di valutazione. Potremmo anche insegnare alla rete ad

identificare solo le connessioni fidate.

Nel programma dovrò pensare ad un pannello dove questi parametri possono essere

settati. Dobbiamo rendere il sistema il più personalizzabile possibile. Ad esempio:

La schema di funzionamento del mio programma esemplificativo è infine il seguente:

Page 84: Introduzione alle reti neurali artificiali

84

Matteo Tosato - Introduzione alle reti neurali artificiali

Main

Packet capture

~

User Interface

~

IA pre-processor

~

General statistics

IA config

dialog

Capture

module

config

FIFO

Packets

Puntatori

pacchetti

Packet analyzer

and dumpFIFO

Il modulo IA è quello che gestisce la rete neurale e si preoccupa di eseguire il

rilevamento dei valori RTT anomali. In più si preoccupa di loggare tutta l‟attività su

file. I thread principali sono 3. E‟ bene infatti sfruttare, la dove possibile, le

architetture multi-core, dato che solo l‟elaborazione della rete neurale può arrivare

ad essere dispendiosa se sono presenti molti neuroni nel livello nascosto.

Previsione di fenomeni complessi

Le reti neurali possono essere utilizzate anche per prevedere il valore di una

(previsione uni-variata) o più (previsione multi-variata) variabili sulla base di dati

storici. Questa capacità è sfruttata molto nell‟ambito finanziario e statistico. Data

una funzione ( ), solitamente ne si esegue l‟analisi per mezzo della scomposizione in

componenti armoniche ideata dal celebre Fourier. Con le reti neurali è possibile fare a

meno di questa tecnica effettuando un addestramento mirato a prevedere (o classificare

se il nostro obiettivo non è la previsione), il comportamento della variabile nel tempo

futuro.

Nel caso della previsione multi-variata anche con serie di input differenti, è

l‟insieme di valori delle sequenze storiche di tutte le variabili di input che concorre

alla determinazione dell‟output di ognuna delle variabili su cui si vuole fare la

previsione. Per questo motivo è possibile avere bisogno di un numero enorme di neuroni

di input, rendendo difficile tutta l‟applicazione.

Si preferisce, in questi casi, utilizzare le reti neurali ricorrenti. Queste, come

abbiamo visto, hanno connessioni anche tra neuroni dello stesso livello, quindi la loro

memoria sarà estesa anche agli input precedenti.

Supponiamo di dover prevedere il comportamento di una singola variabile.

L‟addestramento consisterà nell‟inserire in input alla rete una serie di valori assunti

da x. In output la serie di valori che x assumerà. E così via per più serie, finché il

Page 85: Introduzione alle reti neurali artificiali

85

Matteo Tosato - Introduzione alle reti neurali artificiali

target di precisione della rete non viene raggiunto. A questo punto la rete sarà in

grado di prevedere valori successivi che x assumerà.

Dobbiamo anche considerare che la rete non imparerà solamente la relazione che esiste

tra i valori di input e quelli di uscita, ma anche quella esistente tra input

consecutivi. e . Questo è un indice della derivata in quel punto della funzione.

Di seguito lo schema ipotetico di una rete per la previsione uni-variata:

x107

x108

x109

x110

x111

x112

x113

x100

x101

x102

x103

x104

x105

x106R

ete

ne

ura

le

x114

x115

x116

x117

x118

x119

x120

Un davvero banale esempio può essere fatto con un segnale periodico. Naturalmente una

cosa di questo tipo a senso solo per il fine didattico. Ma nella realtà possiamo

applicare questa tecnica a qualsiasi segnale variabile difficilmente prevedibile. I

maggiori tipi di analisi che vengono fatti attualmente, oltre essere complessi da un

punto di vista realizzativo, incappano molto spesso in errori, dato che sistemi di

analisi che si basano su algoritmi sequenziali non hanno la capacità di

generalizzazione di una struttura neurale. Quindi all‟arrivo di dati in ingresso

affetti da un disturbo molto spesso questi sistemi non sono in grado di funzionare

correttamente.

Un esempio di risultato potrebbe essere il seguente:

Page 86: Introduzione alle reti neurali artificiali

86

Matteo Tosato - Introduzione alle reti neurali artificiali

Il numero di neuroni in input, in uscita e la struttura del training set sono variabili

che possono essere decise seguendo l‟equazione di convenienza seguente:

( )

Un altro aspetto importante è la normalizzazione. Non è infatti detto che i valori da

analizzare rimangano all‟interno di un range adatto alla nostra rete. Per questo motivo

deve essere fatta, anche in questo caso, una operazione di stretching sui valori.

Analisi di segnale

Tipicamente l‟analisi di una qualsiasi segnale aperiodico viene fatta attraverso la

trasformata di Fourier per suddividere la forma d‟onda in varie componenti. Attraverso

l‟analisi in frequenza è possibile fare delle considerazioni sulle caratteristiche che

ci interessano.

Anche se, la rete neurale non avrà bisogno necessariamente di scomporre il segnale in

più componenti, essa sarà comunque in grado di estrapolare le caratteristiche che

desideriamo dal segnale proprio come lo possiamo fare noi con la nostra testa. Tutto

dipende dall‟addestramento a cui la sottoponiamo preventivamente. Quando noi osserviamo

la forma d‟onda e tiriamo le conclusioni su “che cosa rappresentava” il segnale in quel

momento, facciamo anche noi delle associazioni come le fa la rete neurale. Una rete

neurale per quanto semplice, ricalca quello che può fare il cervello.

La lettura di un testo è un‟utile analogia, quando leggiamo non andiamo a valutare ogni

lettera, ogni sillaba, suono, punteggiatura, sintassi presente etc… ma sappiamo già che

suoni emettere per esprimere ciò che c‟è scritto. Questo perché siamo “abituati” a

farlo, la conoscenza necessaria è già diffusa tra le connessioni neurali.

(connessionismo) Lo stesso discorso vale per i sistemi basati su intelligenza

artificiale, non abbiamo più bisogno di implementare enormi e complessi sistemi di

analisi, che in molti casi sono anche irrealizzabili.

Ciò non obbliga comunque a bypassare Fourier, in certi casi rimane molto utile isolare

le caratteristiche del segnale per poi, in seguito, analizzarle con una rete. Le varie

componenti ricavate della trasformata possono divenire input di una rete neurale feed-

forward o di altra configurazione. Molte volte è sufficiente un percettrone per avere

già una certa possibilità di classificazione.

0

1

2

3

4

5

6

7

0 10 20 30 40 50 60

Futuro Sorico

Page 87: Introduzione alle reti neurali artificiali

87

Matteo Tosato - Introduzione alle reti neurali artificiali

Un esempio può essere il seguente, dato il segnale di origine:

Con l‟ausilio della trasformata di Fourier lo si scompone nelle sue componenti,

La FFT ha il compito di amplificare e di isolarne “le caratteristiche”.

Ogni caratteristica viene normalizzata e inserita nello strato di input.

i

h

k

y

.

.

.

.

.

.

.

.

.

.

.

.

ComponentiNeuroni di

Input

FFT

Neuroni

nascosti

Neurone

di outputSegnale

AD

converter

+

freq. divisor

Figura 21: Analisi di segnale tramite rete feed-forward

I due blocchi grigi, che rappresentano il convertitore analogico-digitale e il modulo

per la trasformata di Fourier veloce, possono anche essere realizzati via hardware.

Come anche la rete stessa del resto.

Lo schema illustrato si comporta da analizzatore del segnale. Stabilisce che cosa il

segnale rappresenta in base all‟addestramento cui è stata sottoposta.

Page 88: Introduzione alle reti neurali artificiali

88

Matteo Tosato - Introduzione alle reti neurali artificiali

Solitamente si insegna a riconoscere certi pattern che rappresentano fenomeni esterni.

Immaginiamo ad esempio, un dispositivo ricevitore con antenna.

La cosa più complicata da fare non è tanto realizzare il sistema, ma scegliere gli

esempi da sottoporre alla rete.

Reti di reti neurali

Utilizzando un approccio ingegneristico, possiamo pensare ad una rete neurale come un

blocco. Il famoso “black-block”. Con input ed output. Quando il funzionamento di un

blocco è stato puntualizzato, possiamo utilizzarlo dimenticandoci delle sue

caratteristiche interne, per produrre altri blocchi. Questo è quello che viene

solitamente fatto nell‟ingegneria, partendo dal blocco più piccolo e crescendo verso

quello più grande.

Allora nulla ci vieta di estendere questo approccio anche alle reti neurali. Quello che

otteniamo è la dispersione ulteriore del funzionamento. Incrementando le capacità di

generalizzazione del sistema.

Recenti studi hanno mostrato come questo approccio risulta valido anche nello studio di

patologie come la schizofrenia.

Un modello di questo tipo è il seguente:

... ...

...

Block 3

Block 2

Block 1

Dove il blocco 1 è una ulteriore “fuzzificazione” di 3 input originali. Pertanto il

blocco 2 si ritroverà a lavorare con una classe e altri input.

Nessuna complicazione dal punto di vista computazionale, dato che il blocco 2, utilizza

la classe in uscita dal blocco 1 al pari degli altri input.

Page 89: Introduzione alle reti neurali artificiali

89

Matteo Tosato - Introduzione alle reti neurali artificiali

Le cose possono divenire anche molto complicate e si possono mischiare anche più tipi

di configurazioni. Reti che utilizzano al loro interno reti auto-associative come

memorie, oppure reti auto-organizzanti che hanno input generati da altre reti, e via

dicendo...

... ...

...

Fuzzy - system

In base ai tipi di dati di cui si dispone si decide quali raggruppare in gruppi e

processare separatamente, oppure quali di questi vanno prima trattati da una ulteriore

rete, oppure quali devono essere normalizzati.

Non ci sono regole per decidere quale configurazione sia la migliore per ogni

problematica, molte decisioni vanno prese in base all‟esperienza che si accumula

durante i test.

Conclusione e ringraziamenti

Naturalmente le possibilità delle reti non si fermano a quello che abbiamo visto,

esistono molte altre varianti che meritano di essere prese in considerazione.

In questo testo ho cercato solo di fare una adeguata introduzione per i tipi e per le

applicazioni più diffuse oggi.

Di seguito, nei riferimenti, elenco le risorse utilizzate per lo studio e dove è

possibile trovare altre informazioni e tutti gli approfondimenti necessari.

Le reti neurali sono oggetti utili ed interessanti anche dal punto di vista delle

neuroscienze e sono il punto di partenza per la realizzazione di una intelligenza non

biologica. (vedi il progetto “Blue Brain”).

Ci sono anche importanti implicazioni nella filosofia. Sul tema della coscienza e della

fenomenologia.

Ringraziamenti particolari:

Page 90: Introduzione alle reti neurali artificiali

90

Matteo Tosato - Introduzione alle reti neurali artificiali

- Flavio Bernardotti, fonte di informazioni e risorse.

- Andres Reyes, introduzione storica.

Appendice A – basi matematiche

Quando si lavora con le reti neurali è utile usare alcuni costrutti matematici. Questi

sono quelli di norma utilizzati nella risoluzione di molti problemi in ambiti

scientifici. Nelle ANN è infatti possibile incappare in questioni, che dal punto di

vista matematico, possono divenire anche abbastanza complesse.

In configurazioni semplici, dove i neuroni avranno al massimo funzioni di trasferimento

binarie non avremo molta necessità di ricorrere alla matematica. Diversa è la questione

quando utilizziamo algoritmi più complessi con back-propagation o una delle sue

varianti. Inoltre, alcune operazioni sui pesi possono divenire molto più veloci quando

utilizziamo alcune delle regole offerte dall‟algebra lineare per quanto riguarda le

operazioni sulle matrici. Abbiamo visto infatti che il miglior modo di lavorare con le

reti, è di definirle come matrici, ciò rende meno dispendioso il processo dal punto di

vista dell‟impiego di tempo CPU e memoria, rispetto all‟approccio ad oggetti.

Partendo proprio da questo ultimo punto, vediamo alcuni concetti di algebra lineare che

possono risultare molto utili nel lavoro con le reti.

- Cenni sui vettori

Ogni parte della rete può in effetti essere intesa come un vettore di elementi, negli

esempi riportati nella prima parte, ho sempre preferito utilizzare proprio degli array

C per contenere i valori potenziali dei neuroni, il valore dei pesi, etc... tutti

questi oggetti possono essere considerati come vettori e matrici. Possiamo descrivere

un vettore nel seguente modo:

(

)

Una prima cosa che si può vedere riguardo al semplice vettore è la trasposizione. Il

seguente è il vettore trasposto di x:

( )

Gli elementi del vettore sono chiamati “componenti”. Un vettore può essere

rappresentato graficamente come una freccia in uno spazio di n dimensioni, dove n è la

dimensione del vettore.

Due vettori possono essere moltiplicati, moltiplicando fra loro ogni elemento. Molto

semplicemente nel modo seguente:

(

)

(

)

(

)

Page 91: Introduzione alle reti neurali artificiali

91

Matteo Tosato - Introduzione alle reti neurali artificiali

E‟ chiaro che graficamente questa operazione corrisponde ad un allungamento del

vettore, in questo caso doppio. Oppure in caso fosse stato un vettore composto da

componenti il cui valore era 0,5 sarebbe stata una riduzione.

Stessa cosa vale per l‟addizione, con la differenza che dal punto di vista geometrico

questa corrisponde alla diagonale del parallelogramma con due lati individuati dai due

vettori.

- Prodotto interno

Un caso più interessante è invece il prodotto interno. Questo corrisponde esattamente

al calcolo del potenziale del neurone.

(

)

(

)

∑( )

- Norma

La norma di un vettore corrisponde alla sua lunghezza.

‖ ‖ √ √

La normalizzazione di un vettore consiste nel dividere il vettore per la propria norma.

Cosa significa? A volte gli input di una rete neurale possono arrivare da dispositivi,

che per loro natura, possono essere affetti da oscillazioni. Pensate ad esempio a dei

sensori esterni che hanno una qualche funzione di trasduzione, questi possono fornire

input scorretti come intensità che potrebbero portare la rete neurale a errori. Per

questo motivo gli input vengono in certi casi normalizzati. Questo processo avviene

dividendo ogni componente per la norma vettoriale:

√∑

Il seguente grafico mostra il processo di normalizzazione su due input, i quali vengono

normalizzati per rientrare tra i valori 0 e 1:

Page 92: Introduzione alle reti neurali artificiali

92

Matteo Tosato - Introduzione alle reti neurali artificiali

2.0

2.00.5

0.5

1.0 1.5

1.5

1.0

x1

x2

x1

x2

Nel campo delle reti, la norma viene utilizzata per calcolare la distanza di due

vettori. Ad esempio la distanza del vettore degli input al vettore dei pesi, oppure il

vettore di output rispetto quello della risposta desiderata. Per questo si ricorre alla

norma della differenza:

‖ ‖ √( ) ( ) ( )

Questo calcolo nel caso di vettori binari, ovvero con componenti * +, da in output la

distanza di Hamming tra i due vettori. La distanza di Hamming può essere utile in

alcuni casi. Essa è definita come il numero di componenti corrispondenti differenti tra

due vettori. Invece per un solo vettore binario tale distanza può essere intesa come la

distanza tra questo e il vettore nullo, un vettore ove tutti i componenti sono posti a

0.

- Disuguaglianza di Cauchy-Schwartz

Questa dice che il valore assoluto del prodotto interno di due vettori X,W è minore o

uguale al prodotto tra le norme dei due vettori.

| | || || || ||

Quindi esisterà un angolo tra i due vettori:

|| || || ||

Quindi il prodotto interno dei due vettori è anche definibile con:

|| || || ||

Questo ci indica che il prodotto interno dei due vettori sarà proporzionale al coseno

dell‟angolo che viene a formarsi. Siccome:

Page 93: Introduzione alle reti neurali artificiali

93

Matteo Tosato - Introduzione alle reti neurali artificiali

Il prodotto interno, quindi la risposta del neurone, sarà tanto maggiore quanto minore

è la distanza tra il vettore di input e il vettore dei pesi.

- Cenni sulle matrici

Una matrice è definibile come una raccolta di M righe per N colonne di numeri reali.

[

]

Solitamente i suoi componenti si indicano con in modo da identificare un componente

nella matrice utilizzando due indici, rispettivamente per la riga e la colonna.

L‟addizione tra due matrici è possibile solo se le due hanno numero di righe e colonne

uguali.

Invece è possibile moltiplicare una matrice per un vettore. Ad esempio data la matrice

W seguente:

[

]

E un vettore X:

[

]

Che deve avere stesso numero di componenti del numero di colonne della matrice W, è

possibile definire un nuovo vettore Wx moltiplicando ogni componente della matrice con

il componente del vettore corrispondente di colonna. Questo per ogni riga:

[

] [

] [( ) ( ) ( )( ) ( ) ( )

] 0

1

Se consideriamo che la matrice W può corrispondere benissimo a due vettori di pesi

sinaptici, quindi per due neuroni, e il vettore X al vettore di input, questo calcolo

consente di calcolare in un solo passo tutti i nuovi valori per i neuroni di output.

Infatti abbiamo due prodotti interni nel vettore finale Wx.

La moltiplicazione tra due matrici A*B è possibile solo se la matrice A ha numero di

colonne uguale alle righe della matrice B, in questo caso il prodotto finale ij

corrisponde al prodotto del vettore della riga i della prima matrice con il vettore

della colonna j della seconda matrice. Ad esempio:

0

1 [

]

[,( ) ( ) ( )- ,( ) ( ) ( )-

,( ) ( ) ( )- ,( ) ( ) ( )-] 0

1

Naturalmente la moltiplicazione tra matrici non è commutativa, ovvero ,

perché il risultato dei due prodotti sarebbe molto diverso.

Page 94: Introduzione alle reti neurali artificiali

94

Matteo Tosato - Introduzione alle reti neurali artificiali

La matrice unitaria I è una matrice quadrata in cui ciascun componente ij è dato dal

delta di “Kronecker” ( )

( ) {

Per cui:

[

]

Il prodotto tra una matrice A e la matrice I corrispondente restituisce sempre la

matrice originaria:

Come per il vettore trasposto anche per la matrice è possibile fare lo stesso

ragionamento.

[

] e 0

1

E‟ facilmente intuibile che è possibile calcolare anche i prodotti I risultati

però sono diversi.

- Metodo di eliminazione di Gauss (rango della matrice)

Il metodo di eliminazione di Gauss permette di ottenere una matrice equivalente che

possiede un numero crescente di zero iniziali sulle righe.

[

] [

]

Dove il simbolo * rappresenta qualsiasi valore risultato da altre operazioni. Vi sono

solo tre operazioni che è possibile fare sulla matrice:

1. La moltiplicazione di una riga per uno scalare diverso da 0, ad esempio:

2. Scambio di righe:

3. Addizione del multiplo di una riga a un‟altra riga:

Operando in serie in questo modo e ripetendo da capo il procedimento si arriva ad

ottenere una matrice che non può essere più ridotta. Arrivati a questo punto il numero

delle righe che non hanno componenti uguali a zero viene detto rango della matrice.

Questo procedimento possiede un grosso numero di applicazioni, tra cui la soluzione di

un sistema di equazioni lineari omogenee a N incognite disposte in forma matriciale.

Un esempio:

Page 95: Introduzione alle reti neurali artificiali

95

Matteo Tosato - Introduzione alle reti neurali artificiali

[

] [

] [

] [

] [

]

- Derivata

Solitamente quando si lavora con le reti neurali si può arrivare ad utilizzare concetti

di analisi matematica abbastanza ricorrentemente. La derivata in primis è molto

utilizzata, dato che è necessaria per l‟algoritmo di apprendimento supervisionato back-

propagation “EBP”. Qui vediamo di riassumere brevemente che cosa è la derivata e come

si calcola.

Dal punto di vista matematico la derivata si definisce come limite del rapporto

incrementale fra la variazione dei valori della funzione e quella della variabile

indipendente, al tendere a zero di quest‟ultima.

Ammettiamo di voler descrivere il movimento di un soggetto che si muove lungo una guida

rettilinea; diciamo la posizione (rispetto ad un punto fissato) dell‟auto al tempo t.

Il tachimetro dell‟auto segna, al tempo , una certa velocità, che chiamiamo ( ). La

velocità media nell‟intervallo [ - è data dal rapporto fra lo spazio percorso ed il

tempo impiegato a percorrerlo, quindi:

, - ( ) ( )

Quindi la velocità al tempo 0 segnata sul tachimetro è il limite della velocità media

quando l‟ampiezza dell‟intervallo tende a zero:

( )

( ) ( )

Graficamente la derivata è una secante di una qualsiasi funzione,

Il tutto si può sintetizzare come segue: abbiamo una funzione ( ) , ed un punto

fissato ( ). Consideriamo una piccola variazione e definiamo il rapporto

incrementale della funzione nel punto con incremento h come:

Page 96: Introduzione alle reti neurali artificiali

96

Matteo Tosato - Introduzione alle reti neurali artificiali

( ) ( )

( ) ( )

Il rapporto incrementale rappresenta una velocità media, il coefficiente angolare di

una retta secante, un tasso medio di crescita, e così via.

Ci interessa studiare il limite per h che tende a zero:

( )

( ) ( )

Se il limite esiste è derivabile in .

La derivata consente di trovare nella funzione eventuali minimi,

Noi nell‟algoritmo Error back-propagation avremo bisogno di calcolarci la derivata

della funzione di trasferimento che sceglieremo di utilizzare, dato che la impiegheremo

per calcolare l‟errore del singolo nodo dello strato di output e nascosto.

E‟ importante anche il concetto di gradiente. Il gradiente di una funzione f(x)

vettoriale (ovvero che produce un numero in uscita) può essere inteso come un vettore

composto dalle derivate dei suoi componenti. Lo abbiamo incontrato nell‟algoritmo EBP.

- Integrale

Potremmo anche incappare nel calcolo integrale. Ma a parte il suo utilizzo nelle reti

neurali, la definizione di integrale è bene saperla, dato il suo impiego nella maggior

parte dei campi scientifici. Si pensi solo all‟analisi di Fourier.

Il concetto di integrale è piuttosto semplice in se.

Si consideri la relazione tra velocità e tempo. Se poi il moto è anche uniformemente

accelerato avremo un grafico come il seguente:

Trovare lo spazio percorso non è complicato dato che , ci basta trovare l‟area

del trapezio che si forma. Ma come possiamo fare in caso avessimo un moto non uniforme?

0

1

2

3

4

5

0 1 2 3

Ve

loci

Tempo

Velocità-tempo

Page 97: Introduzione alle reti neurali artificiali

97

Matteo Tosato - Introduzione alle reti neurali artificiali

In questo caso calcolare l‟area che c‟è tra la funzione l‟asse x non può essere fatta

con una semplice moltiplicazione, si può pensare allora di costruire nel grafico una

serie di rettangoli aventi per base un segmento ricavato sull‟asse delle x e come

valore massimo un valore del tratto di funzione y rispettivo. In questo modo tentiamo

di avvicinarci all‟area reale facendo la somma di tutte le aree dei rettangoli.

Graficamente;

Naturalmente non riusciamo a riprodurre esattamente l‟area. Possiamo solo avere una

delle due situazioni:

∑ ( ) ( )

oppure,

∑ ( ) ( )

Dove ( ) definisce un segmento sull‟asse delle x, ovvero la base del rettangolo;

f() identifica il punto minore della funzione nell‟intervallo; F() identifica invece il

maggiore.

Il trucco per trovare l‟area giusta sta nel scegliere dei rettangoli dalla base molto

piccola. Se facciamo tendere il numero di rettangoli ad infinito otteniamo l‟area

corretta. Quindi:

∑ ( ) ( )

∑ ( ) ( )

0

1

2

3

4

0 1 2 3 4V

elo

cità

Tempo

Velocità-tempo

0

2

4

6

8

10

0 1 2 3 4 5 6 7 8 9 10

Ve

loci

Tempo

Velocità-tempo

Page 98: Introduzione alle reti neurali artificiali

98

Matteo Tosato - Introduzione alle reti neurali artificiali

La notazione degli integrali definisce con la „s‟ medioevale la sommatoria e con il

termine dx, l‟infinitesimo, ovvero il segmento che costituisce la base dei rettangoli.

∑ ( ) ( )

∫ ( )

∑ ( ) ( )

Detto questo è facile definire la funzione integrale e quindi l‟integrale definito.

L‟integrale è detto definito quando sarà considerato entro un certo range, di

conseguenza se rendiamo variabile uno degli estremi abbiamo un funzione. Al variare

dell‟estremo x, il valore integrale si avvicina o si allontana dall‟ipotetica area

vista prima.

( ) ∫ ( )

Questa è una funzione crescente, dato che x è un punto sull‟asse compreso fra a e b.

Il teorema fondamentale del calcolo integrale dice che la derivata della funzione è

uguale alla funzione di partenza. Indicando la derivata rispetto ad x con D avremo:

( ) ,∫ ( ) - ( )

Appendice B – Riferimenti

- Analysis and Applications of Artificial Neural Networks 1Ed, Prentice Hall

- Process Neural Networks, Xingui He e Shaohua Xu, advanced topics in science and

technologiy in cina

- Veelenturf L.P.J. Analysis and Applications of Artificial Neural Networks (1Ed,

Prentice Hall, 1995)

- Artificial Intelligence Structures and Strategies for Complex Problem Solving

Third Edition, George F. Luger, William A. Stubblefield

- A Direct Adaptive Method for Faster Backpropagation Learning: The RPROP Algorithm

, Martin Riedmiller and Heinrich Braun, Institut fur Logik, Komplexitat und

Deduktionssyteme.

- Novel Algorithms and Techniques in Telecommunications, Automation and Industrial

Electronics

- Novel Algorithms and Techniques in Telecommunications and Networking

- Pratical Neural Network Recipes in C++

- Reti neurali e fuzzy logic su personal computer – Luca Marchese

- An Improved Backpropagation Method with Adaptive Learning Rate V.P. Plagianakos,

D.G. Sotiropoulos, and M.N. Vrahatis University of Patras, Department of

Mathematics, Division of Computational Mathematics & Informatics

- Neural Networks, (Neural Networks & Artificial Intelligence), Università Italiana

Cracking – Italian University of Cracking

- http://it.wikipedia.org/wiki/Rete_neurale

Page 99: Introduzione alle reti neurali artificiali

99

Matteo Tosato - Introduzione alle reti neurali artificiali

- http://www.willamette.edu/~gorr/classes/cs449/intro.html

- http://www.semeion.it/

- http://www.synaptics.org/synaptics/research.htm

- http://www.ra.cs.uni-tuebingen.de/SNNS/ (Software)

- http://www.heatonresearch.com/encog (Framework, Java e C#)

- http://www.bernardotti.it/portal/ (Forum CV e AI)

- AI framework in C#, Aneuro32

Appendice C – Aneuro32

Di seguito presento alcuni esempi di semplici programmi in C# che utilizzano il

framework „aneuro32‟ (https://github.com/Matteo87/Aneuro32) che ho sviluppato a fronte

di integrare varie configurazioni di reti neurali artificiali e altri paradigmi del

natural computing in un unico SDK.

Addestramento M-Adeline tramite algoritmo Windrow-Hoff per operatore AND:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using aneuro32.Nn.Structure.FeedForward; using aneuro32.Functions; using aneuro32.Learning.Supervised.Propagation; using aneuro32.Misc; namespace M_Adeline_testApp { class Program { static void Main(string[] args) { // input set double[][] input = { new double[] {0,0}, new double[] {0,1}, new double[] {1,0}, new double[] {1,1} }; // target set double[][] target = { new double[] {0}, new double[] {0}, new double[] {0}, new double[] {1} }; // Creating neural network: MAdeline MyNet = new MAdeline(2); // Add bias: MyNet.AddBiasWeight(); // Connects units: MyNet.Build(); // Creating training object: WindrowHoff trainingAlg = new WindrowHoff( ref MyNet, // Network input, // input set target, // target set activation_mode.sigmoid, // Transfer function 0.001, // Target MSE

Page 100: Introduzione alle reti neurali artificiali

100

Matteo Tosato - Introduzione alle reti neurali artificiali

0.5 // Learning rate ); bool retVal; // Training loop: do { retVal = trainingAlg.iteration(); if (retVal != true) { Console.WriteLine("Training error: " + trainingAlg.NetworkError); // Check for error break; } } while (!trainingAlg.isTrained); // Testing network: int j = 0; Console.WriteLine("Net test:"); foreach (double[] _in in input) { MyNet.SetInput(input[j]); MyNet.Exec(); Console.WriteLine("\nPattern n° "+j); Console.WriteLine("Input: " + input[j][0] + " " + input[j][1]); Console.WriteLine("Output: " + MyNet.output.OutputValue.ToString("0.00") + " Ideal: " + target[j][0]); j++; } Console.WriteLine("\nNet final error: "+trainingAlg.CurrentMeanSquareError.ToString("0.######")); Console.WriteLine("Total epoch: "+trainingAlg.CurrentEpoch); List<double> weights = MyNet.SaveWeights(); Console.WriteLine("\nNet final weights: "); foreach (double d in weights) { Console.WriteLine(d.ToString("0.######")); } Console.ReadLine(); } } }

Ouput:

Net test:

Pattern n° 0

Input: 0 0

Output: 0,00 Ideal: 0

Pattern n° 1

Input: 0 1

Output: 0,02 Ideal: 0

Pattern n° 2

Input: 1 0

Output: 0,02 Ideal: 0

Pattern n° 3

Input: 1 1

Output: 0,97 Ideal: 1

Net final error: 0,001

Total epoch: 8217

Net final weights:

6,305019

6,304662

-9,533159

Page 101: Introduzione alle reti neurali artificiali

101

Matteo Tosato - Introduzione alle reti neurali artificiali

Addestramento MLP tramite algoritmo Error back-propagation con learning rate adattativo

per operatore XOR:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using aneuro32; using aneuro32.Nn.Structure.FeedForward; using aneuro32.Learning.Supervised.Propagation; namespace DebugProp0 { class Program { static void Main() { double[][] xorInput = { new double[] {0.0,0.0}, new double[] {0.0,1.0}, new double[] {1.0,0.0}, new double[] {1.0,1.0} }; double[][] xorOutput = { new double[] {0.0}, new double[] {1.0}, new double[] {1.0}, new double[] {0.0} }; IFFNeuralNetwork MyNet; PropagationBase MyTrainingAlg; TextWriter outStrm = Console.Out; TextReader inStrm = Console.In; // Build ANN MyNet = new ffnetwork(); // Adding Layers MyNet.AddNewLayer(2); MyNet.AddNewLayer(4); MyNet.AddNewLayer(1); // Adding bias neurons MyNet.AddBiasWeight(); // Connects all MyNet.Build(); // Training instance MyTrainingAlg = new ShiffmanVariantBackpropagation( ref MyNet, xorInput, xorOutput ); // Training process ... do { if (MyTrainingAlg.iteration() != true) break; } while (MyTrainingAlg.isTrained != true); // Exit training, check result and run an example outStrm.WriteLine("Testing... "); outStrm.WriteLine(); double[] res; int j = 0; foreach (double[] pattern in xorInput) { outStrm.WriteLine(); outStrm.WriteLine("Pattern 1°: " + pattern[0] + " " + pattern[1]); MyNet.SetInput(pattern); MyNet.Exec(); res = MyNet.GetOutput(); outStrm.WriteLine("NetOutput: " + res[0] + " Ideal output: " + xorOutput[j++][0]); } outStrm.WriteLine("Total Epochs: " + MyTrainingAlg.CurrentEpoch + ", Final error: " + MyTrainingAlg.GetMeanSquareError()); inStrm.ReadLine(); // Wait for user input } } }

Page 102: Introduzione alle reti neurali artificiali

102

Matteo Tosato - Introduzione alle reti neurali artificiali

Output:

Testing...

Pattern 1°: 0 0

NetOutput: 0,0215273578662015 Ideal output: 0

Pattern 1°: 0 1

NetOutput: 0,977569795574149 Ideal output: 1

Pattern 1°: 1 0

NetOutput: 0,977554230396672 Ideal output: 1

Pattern 1°: 1 1

NetOutput: 0,0229820784372725 Ideal output: 0

Total Epochs: 5003, Final error: 0,000999927837006829