algoritmo nodi

annuncio pubblicitario
LE RETI NEURALI DI KOHONEN
Le reti neurali sono modelli matematici che tentano di emulare il sistema nervoso centrale umano.
Lo scopo finale delle reti neurali artificiali è realizzare i meccanismi di apprendimento del cervello
umano, facendo in modo che la rete interagisca con i dati senza intervento, oltre quello della
creazione.
Lo scopo di questi complessi metodi matematici è il tentativo di penetrare le leggi della natura
meglio delle tecniche di calcolo tradizionali. Si basano sul concetto che, in determinate situazioni, è
possibile far "apprendere" ad un apparato matematico determinate leggi che non si conoscono a
priori, semplicemente facendogli analizzare un elevato numero di casi reali. In parole più semplici,
le reti neurali rappresentano un potente, e non ancora completamente compreso, mezzo statistico.
Dopo aver processato una mole notevole di dati nella fase cosiddetta di apprendimento o
assimilazione, queste reti propongono una linearizzazione del problema cui si vuole dare una
soluzione per mezzo di una formula matematica che lega tra loro le diverse variabili, espressione
del problema stesso.
I campi di applicazione sono tutti quelli dove l'analisi statistica di tutte le variabili di un problema
risulti difficoltosa o dispendiosa in termini di calcolo, ma soprattutto dove non sia chiaro a priori
quali relazioni deterministiche esistano tra le diverse variabili che caratterizzano il problema.
Uno dei più grossi problemi di un modello computazionale matematico è la sua rigidità e
l'impossibilità di rispondere a stimoli esterni (input) in maniera diversa da ciò che viene
inizialmente immesso nell'elaboratore. In parole semplici, un computer, generalmente, può
riconoscere e rispondere solo a stimoli che sono stati codificati precedentemente; anche le risposte,
inoltre, sono sempre rigidamente decise a priori.
Per tentare di risolvere questo problema, è stato introdotto il concetto di rete neurale (artificiale),
preso in prestito dalla biologia, precisamente da ciò che sappiamo sul funzionamento cerebrale.
Una rete neurale artificiale (ANN, Artificial Neural Network) è formata da un certo numero di nodi
indipendenti, connessi gli uni agli altri mediante dei collegamenti. Questo è simile alla struttura del
nostro cervello, in cui le unità sono i neuroni e i collegamenti gli assoni e le sinapsi.
Un impulso (elettrico) viaggia all'interno del cervello seguendo i collegamenti: quando un neurone
riceve l'impulso, se questo è abbastanza forte il neurone si "attiva" e a sua volta invia il segnale a
tutti i neuroni ad esso collegati, che si comporteranno nella stessa maniera.
Una ANN funziona nello stesso modo: ogni unità è collegata ad altre unità, le quali, in presenza di
uno stimolo (input) di sufficiente intensità dalle unità poste "prima" di esse, si attivano e inviano il
segnale alle unità collegate. I collegamenti (o gli assoni, nel caso del cervello) hanno la capacità di
attenuare il segnale, in modo che questo viaggi secondo percorsi diversi e in alcune "direzioni" si
spenga (cioè non sia sufficiente ad attivare alcuni neuroni).
Una rete neurale possiede poi, di solito, un algoritmo che modifica i pesi (le attenuazioni) dei
collegamenti, in modo che essa si adatti a fornire un certo output in risposta ad un determinato
input.
Esistono vari tipi di reti neurali e dunque vari modi per classificarle. La classificazione più comune
è quella che le divide in supervisionate e non supervisionate.
Alle reti della prima categoria viene presentato un input e osservato l'output generato, a questo
punto, tenendo conto dell'output che si desiderava, vengono aggiornati i pesi dei collegamenti e
presentato alla rete un nuovo input. Questa procedura è detta "addestramento" della rete. La
"supervisione" consiste proprio nel conoscere che risposta ci si aspetta da un determinato input.
Una rete neurale è in grado, successivamente, di dare risposte coerenti anche ad input che non erano
stati presentati in fase di addestramento.
Le reti non supervisionate vengono generalmente utilizzate per effettuare classificazioni degli input,
come le famose Reti di Kohonen (SOM, Self-Organizing Maps), che hanno un'enormità di
applicazioni. Queste reti dividono gli input in categorie formate da input "simili" (secondo certi
criteri) tra di loro. Una SOM, oltretutto, crea una "mappa" degli input mettendo vicini tra di loro gli
input simili. Ad esempio è possibile fornire ad una SOM una serie di colori e fare in modo che essa
raggruppi i colori simili.
Le reti neurali, dunque, sono in grado di eseguire un'operazione impossibile a gran parte degli altri
metodi dell'Intelligenza Artificiale: rispondere coerentemente a input non codificati in precedenza.
Questa caratteristica è fondamentale per tutte quelle applicazioni che hanno a che fare con
l'ambiente esterno (è impossibile prevedere in fase di costruzione tutte le possibili situazioni),
oppure quelle in cui gli input si presentano "rumorosi" (cioè non precisi), come ad esempio il
riconoscimento di forme grafiche (ad esempio, caratteri, figure geometriche, volti umani),
nell'interpretazione di segnali, nel riconoscimento vocale, nel controllo di processi di vario tipo e
nei sistemi di supporto alle decisioni.
Il problema principale di una rete neurale, invece, è che essa è una "scatola chiusa", è cioè molto
difficile comprenderne il funzionamento e ci si deve spesso limitare a fidarsi dell'addestramento,
senza avere la possibilità di controllare cosa effettivamente avviene dentro la rete.
E’ importante sottolineare che il modo con cui una RN risponde ad un pattern dipende interamente
dai pesi delle connessioni.
APPRENDIMENTO
Il principio guida che permette alla rete di apprendere è quello di lasciare che la rete impari dai suoi
errori.
Le reti hanno, inizialmente, dei pesi scelti a caso (in particolare valori normalizzati, ovvero
compresi fra 0 e 1 o tra -0.5 e +0.5); a questo punto esistono diversi metodi con cui le reti
modificano automaticamente questi pesi fino ad assegnare loro quei valori che consentono di
rispondere nel modo desiderato ad una certa stimolazione esterna.
Tutti i metodi di apprendimento si dividono in due classi: metodo supervisionato e nonsupervisionato. Quello maggiormente considerato è quello supervisionato in cui esiste una specie di
"insegnante" esterno che di volta in volta dice alla rete quale è la prestazione desiderata.
La rete si modifica in conseguenza a tale insegnamento cosicché, dopo un certo numero di volte
(dell’ordine delle migliaia) che le è stato detto quale è l’output appropriato per un certo input,
diventa capace di produrre da sola l’output corretto per ogni input.
Un esempio di apprendimento supervisionato è quello della back-propagation (BP), cioè della
propagazione all’indietro dell’errore: la rete calcola, per ogni unità di output, l’errore cioè la
differenza tra lo stato di attivazione prodotto dalla rete e quello stabilito nell’input di insegnamento;
questo errore serve a modificare i pesi delle connessioni tra i neuroni.
Nei casi di apprendimento non-supervisionato la rete impara scoprendo regolarità negli stimoli
senza che nessuno le dica dall’esterno quali sono queste regolarità. Così accade nelle reti che
sviluppano "mappe di tratti" (feature maps) di Kohonen.
Le reti non danno risultati completamente corretti o completamente sbagliati, ma solo
approssimativamente corretti o sbagliati (non 1 o 0 ma 0.96 o 0.03). Inoltre, se una rete ha imparato,
ad esempio, a dare B in risposta ad A, quando le si presenta uno stimolo A’ che sia simile ad A,
risponde automaticamente e spontaneamente in modo sensato: o dà la stessa risposta data per A,
cioè B, o risponde con B’, cioè dà una risposta simile a quella data per A.
Questa capacità di estrapolare, di rispondere sensatamente al nuovo, è una delle più importanti
proprietà delle RN, e uno dei loro principali vantaggi rispetto ai sistemi simbolici tradizionali.
Le Reti di Kohonen permettono di classificare oggetti senza la supervisione esterna. Nascono dallo
studio della topologia della corteccia del cervello umano. Queste reti tengono conto non solo delle
connessioni sinottiche tra neuroni ma anche della influenza che può avere un neurone sul vicino. E’
stato osservato che, nel caso biologico, i neuroni che sono fisicamente vicini a neuroni attivi hanno i
legami più forti mentre quelli ad una particolare distanza hanno legami inibitori. A questa
caratteristica Kohonen attribuisce uno sviluppo nella capacità di realizzare delle mappe topologiche
localizzate nel cervello. Questa caratteristica è stata modellata da Kohonen restringendo la
variazione dei pesi ai neuroni vicini ad un neurone scelto.
Una Rete di Kohonen è costituita da una serie di neuroni di input che, come per le reti a multi strati,
servono solo a calcolare la somma pesata di tutti gli input e da un singolo strato bidimensionale di
neuroni, sono cioè organizzati su una griglia posta su un piano; tali neuroni calcolano l’output della
rete. Ciascun neurone di input è connesso a tutti i neuroni della griglia.
L’apprendimento è legato alle interconnessioni laterali tra neuroni vicini. L’algoritmo di
apprendimento di questo tipo di RN è il seguente:
1) Si definiscono con wij(t) (0 i n-1 dove n è il numero di input) il peso tra il neurone i-esimo di
input e il neurone j-esimo della griglia al tempo t. Con "tempo" si indica il passaggio del pattern di
apprendimento). I valori dei pesi vengono inizialmente posti casualmente tra 0 e 1. Si pone come
valore di Nj(0) il maggiore possibile (Nj() dovrebbe essere il numero di neuroni vicini al j-esimo
neurone).
2) Si presenta un input: x0(t), x1(t), x2(t),...,xn-1(t) dove xi(t) è l’i-esimo input.
3) Si calcolano le distanze dj tra l’input e ciascun neurone di output j:
(15)
4) Si seleziona il neurone a cui corrisponde la distanza minima. Indichiamo con j* tale neurone.
5) Si modificano i pesi dal neurone di input e il neurone j* e tutti i suoi vicini definiti all’interno
della superficie definita da Nj*(t).
I nuovi pesi sono:
(16)
Il termine (t) è la funzione guadagno (o velocità di adattazione) (0 (t) 1) che decresce nel tempo
in modo da rallentare di volta in volta l’adattamento dei pesi.
Anche le dimensioni di Nj*(t) decrescono nel tempo in modo da individuare una regione di neuroni
sulla griglia.
6) Si ripete tutto a partire dal punto 2).
Si osserva come l’algoritmo di apprendimento di questa rete è molto più semplice di quello delle
reti precedenti in cui è stato necessario calcolare una derivata; nel caso di Kohonen si confronta
semplicemente un pattern di input e il vettore dei pesi. Il neurone con il vettore dei pesi più vicino al
pattern di input viene selezionato (j*); questo nodo modifica il suo vettore dei pesi in modo da
allinearlo a quello degli input x cioè in modo da diminuire dj.
Si può inoltre osservare che vengono modificati anche i vettori dei pesi dei neuroni vicini a j*; il
motivo di ciò è che la rete sta cercando di creare regioni costituite da un ampio set di valori attorno
all’input con cui apprende (cioè non fa corrispondere un solo valore per un input ma un set di
valori), di conseguenza, i vettori che sono spazialmente vicini ai valori di training saranno
comunque classificati correttamente anche se la rete non li ha mai visti.
Questo dimostra le proprietà di generalizzare della rete.
Consideriamo ora come la rete apprende cioè come vengono variati i pesi. La funzione guadagno è
una funzione decrescente che inizialmente viene mantenuta alta (> 0.5) in modo da modificare
velocemente i pesi verso una prima mappatura approssimativa.
In seguito vengono eseguite delle mappature fini avvicinando i vettori dei pesi a quelli di input, per
eseguire queste variazioni fini si riduce sempre più.
Kohonen suggerisce un guadagno che decresce linearmente con il numero dei passaggi. Il processo
di apprendimento dal punto 2) al 6), deve essere eseguito dalle 100 alle 1000 volte circa. In questa
rete le somiglianze tra le classi vengono misurate con la distanza euclidea.
La regione dei vicini può essere scelta essere un quadrato, un cerchio o un esagono. Il valore di Nj*
(cioè il numero di vicini al neurone prescelto) deve essere scelto il maggiore possibile all’inizio e
decrescere anch’esso lentamente all’aumentare dei cicli di apprendimento.
IL PROGETTO
Public Osservazione As New List(Of Unità)
Public Nodi As New List(Of Nodo)
Il codice si basa su nodi e osservazioni; le due classi, sono ancora una volta esterne
Dim NRighe As Integer = 5
Dim NColonne As Integer = 5
Dim NVettorePesi As Integer = 5
Qui introduciamo i valori che serviranno per effettuare i cicli e rappresentano il numero di righe e di
colonne che formano la griglia dei nodi, e il numero di componenti del vettore dei pesi; questa
scrittura permette di cambiarli a piacere
For j As Integer = 0 To NColonne - 1
For i As Integer = 0 To NRighe - 1
SommaPesi = 0
Dim O As New Nodo
With O
For k As Integer = 0 To NVettorePesi - 1
Dim R As New Random
NumeroCasuale = R.NextDouble
SommaPesi = SommaPesi + NumeroCasuale
.Pesi.Add(NumeroCasuale)
Next k
.IndiceRiga = i
.IndiceColonna = j
For k As Integer = 0 To NVettorePesi - 1
.Pesi(k) = .Pesi(k) / SommaPesi
Next k
End With
Nodi.Add(O)
Next i
Next j
Con questo doppio ciclo inizializzo il vettore dei pesi con un numero casuale e riempio la lista dei
pesi
Dim somma As Double
For Each Riga As String In Righe
Dim ValoriSullaRiga() As String = Riga.Split(" ".ToCharArray,
StringSplitOptions.RemoveEmptyEntries)
somma = 0
Dim O As New Unità
With O
For k As Integer = 0 To NVettorePesi - 1
somma = somma + ValoriSullaRiga(k)
.X.Add(ValoriSullaRiga(k))
Next k
For k As Integer = 0 To NVettorePesi - 1
.X(k) = .X(k) / somma
Next k
End With
Osservazione.Add(O)
Next Riga
Con questo invece faccio passare le unità prima dentro la lista X poi una volta normalizzate, dentro
la lista osservazione
Dim IntornoNodo As Integer
Dim Intorno As Integer = 2
Dim perc As Double = 0.8
For Each riga As Unità In Osservazione
Qui introduco i riferimenti per creare l’intorno con numeri scelti arbitrariamente
DistanzaMinima(NVettorePesi, riga, Nodi)
Primo passo, calcolo della distanza tra le osservazioni sulle righe e i nodi attraverso i pesi)
For k As Integer = 0 To NVettorePesi - 1
Me.RichTextBox1.AppendText(vbCrLf & "unità X " & k & " : " &
riga.X(k))
Next k
For Each riga2 As Nodo In Nodi
IntornoNodo = Math.Abs(riga2.IndiceColonna riga.IndiceColonnaNodo + riga2.IndiceRiga - riga.IndiceRigaNodo)
If IntornoNodo = 0 Then
Me.RichTextBox1.AppendText(vbCrLf & "pesi winning node")
For k As Integer = 0 To NVettorePesi - 1
riga2.Pesi(k) = riga2.Pesi(k) + perc * (riga.X(k) riga2.Pesi(k))
Me.RichTextBox1.AppendText(vbCrLf & "peso " & k & " " &
riga2.Pesi(k))
Next k
ElseIf IntornoNodo <= Intorno Then
Me.RichTextBox1.AppendText(vbCrLf & "pesi nodo
nell'intorno")
For k As Integer = 0 To NVettorePesi - 1
riga2.Pesi(k) = riga2.Pesi(k) + perc / (2 * IntornoNodo)
* (riga.X(k) - riga2.Pesi(k))
Me.RichTextBox1.AppendText(vbCrLf & "peso " & k & " " &
riga2.Pesi(k))
Next k
Else
Me.RichTextBox1.AppendText(vbCrLf & "pesi nodo fuori
dall'intorno")
For k As Integer = 0 To NVettorePesi - 1
Me.RichTextBox1.AppendText(vbCrLf & "peso " & k & " " &
riga2.Pesi(k))
Next k
End If
Me.Disegna(Nodi)
Application.DoEvents()
Next riga2
Next riga
Attraverso questi cicli prima introduco l’intorno del nodo, in valore assoluto con la funzione
math.abs, poi allo stesso tempo, con un istruzione if-esle, distinguo i nodi vincenti come quelli con
intorno uguale a zero; i nodi dentro l’intorno come nodi che hanno distanza minore del valore
assegnato in precedenza (2); infine come nodo fuori dall’intorno tutti gli altri che non appartengono
alle categorie sopra citate. Notiamo che la parte grafica in questa applicazione è stata inserita in una
sub per poi essere richiamata nel ciclo, in modo da poter “aggiornare” l’output grafico del bitmap.
Sub Disegna(ByVal Nodi As List(Of Nodo))
Dim
Dim
Dim
Dim
minX
maxX
minY
maxY
As
As
As
As
Double
Double
Double
Double
=
=
=
=
0
5
0
5
'grafica("power")
Dim c As New List(Of Color)
c.Add(Color.Blue)
c.Add(Color.Red)
c.Add(Color.Green)
c.Add(Color.Pink)
c.Add(Color.BlueViolet)
Dim b As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(b)
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g.FillRectangle(Brushes.White, 0, 0, Me.PictureBox1.Width,
Me.PictureBox1.Height)
Dim VettorePuntiNodo As Point() = Me.CreaVettorePuntiNodo(Me.Nodi, minX,
maxX, b.Width, minY, maxY, b.Height)
Dim z As Integer
Dim i As Integer
For Each p As Point In VettorePuntiNodo
Dim col As Color = c(1)
g.FillEllipse(New SolidBrush(col), p.X + 35, p.Y - 37, 30, 30)
z += 1
i += 1
If i > c.Count - 1 Then i = 0
Next p
Dim sb As New System.Text.StringBuilder
For Each Nodo In Nodi
Dim XsuBitmap As Integer = Me.TrasformaX(Nodo.IndiceRiga, minX,
maxX, b.Width)
Dim YsuBitmap As Integer = Me.TrasformaY(Nodo.IndiceColonna, minY,
maxY, b.Height)
g.DrawString(Nodo.Pesi(0).ToString("0.0000")
Brushes.Blue, XsuBitmap + 35, YsuBitmap - 41)
g.DrawString(Nodo.Pesi(1).ToString("0.0000")
Brushes.Blue, XsuBitmap + 35, YsuBitmap - 52)
g.DrawString(Nodo.Pesi(2).ToString("0.0000")
Brushes.Blue, XsuBitmap + 35, YsuBitmap - 63)
g.DrawString(Nodo.Pesi(3).ToString("0.0000")
Brushes.Blue, XsuBitmap + 35, YsuBitmap - 74)
g.DrawString(Nodo.Pesi(4).ToString("0.0000")
Brushes.Blue, XsuBitmap + 35, YsuBitmap - 85)
& " ", Me.Font,
& " ", Me.Font,
& " ", Me.Font,
& " ", Me.Font,
& " ", Me.Font,
Next
Me.PictureBox1.Image = b
End Sub
La parte grafica non contiene novità rispetto ai precedenti lavori e si basa sulle stesse funzioni per la
creazione dei vettori
Function Dist(ByVal Vettore As Integer, ByVal Oss As Unità, _
ByVal B As Nodo) As Double
Dim Distanza As Double
Distanza = 0
For k As Integer = 0 To Vettore - 1
Distanza = Distanza + ((B.Pesi(k) - Oss.X(k)) ^ 2)
Next k
Distanza = Math.Sqrt(Distanza)
Return Distanza
End Function
Sub DistanzaMinima(ByVal Vettore As Integer, ByVal Oss As Unità, _
ByVal B As List(Of Nodo))
Dim Distanza As Double
Dim DistanzaMin As Double = Double.MaxValue
For Each riga As Nodo In B
Distanza = Dist(Vettore, Oss, riga)
If Distanza < DistanzaMin Then
DistanzaMin = Distanza
Oss.IndiceColonnaNodo = riga.IndiceColonna
Oss.IndiceRigaNodo = riga.IndiceRiga
End If
Next riga
End Sub
Le funzioni per il calcolo della distanza, con le quali valuto la vicinanza delle unità ai nodi,si
costruiscono cosi: prima introduco una distanza con formulazione simile a quella euclidea, poi
introduco quella definita come distanza minima
Scarica