Gli algoritmi genetici

annuncio pubblicitario
Gli algoritmi genetici
Un altro importante metodo di calcolo, e di simulazione, molto recente, ma molto
potente e versatile è rappresentato da quella famiglia di tecniche di ottimizzazione che
vanno sotto il nome di algoritmi genetici, il cui inventore è considerato John Holland,
che nel 1975 pubblicò il volume Adaptation in Natural and Artificial Sistems, dove per
la prima volta vengono descritti.
La peculiarità di queste tecniche deriva dal fatto che si ispirano all’evoluzione naturale e
sono quindi fondate sui principi darwinisti della selezione e dell’adattamento, nonché,
naturalmente, su meccanismi di riproduzione e di mutazione.
Nel corso dei vari paragrafi prenderemo in considerazioni gli svariati modi in cui è
possibile implementare ed utilizzare gli algoritmi genetici, oltre a mettere in risalto
come l’integrazione di questi con le reti neurali del connessionismo abbia dato luogo a
notevoli ed interessanti risvolti nell’ambito di svariate ricerche, non ultima quella che
più ci interessa, la psicologia, permettendo un nuovo approccio ai fenomeni psicologici
teso a sottolineare soprattutto l’importante ruolo svolto dall’interazione fra l’individuo
ed il suo ambiente fisico durante il processo di formazione delle capacità sensomotorie e
cognitive. In particolare, questo genere di ricerche, a cui ci rivolgeremo anche noi per la
parte sperimentale, si svolgono nel già accennato ambito della Vita artificiale (definito
anche con il nome di Psicologia sintetica o Neuroetologia computazionale), che, quindi,
verrà diffusamente trattato.
Evoluzione naturale e artificiale
I sistemi biologici presentano molte caratteristiche che li rendono estremamente adatti
all’ambiente in cui vivono, infatti, capacità di adattamento e robustezza nella
conservazione delle caratteristiche positive sono i tratti salienti di questi ultimi, ma,
come sappiamo, essi non sono il frutto di un progetto determinato a priori, ma il
risultato di un processo evolutivo della durata di millenni e basato sulla riproduzione
selettiva degli individui migliori. Nel fondamentale libro L’origine delle specie [1859]
Darwin, nel cercare di spiegare come si siano “potuti sviluppare e perfezionare tutti i
finissimi adattamenti di una parte dell’organismo rispetto ad un’altra e alle condizioni di
vita, e di un organismo rispetto ad una altro organismo”, introduce il concetto di lotta
per la vita, grazie alla quale “qualsiasi variazione, anche se lieve, qualunque ne sia
l’origine, purché risulti in qualsiasi grado utile ad un individuo appartenente a qualsiasi
specie, nei suoi rapporti infinitamente complessi con gli altri viventi e col mondo
esterno, contribuirà alla conservazione di quell’individuo e, in genere, sarà ereditata dai
suoi discendenti. Quindi, anche i discendenti avranno migliori possibilità di
sopravvivere…” ed è proprio alla conservazione delle variazioni favorevoli e
all’eliminazione di quelle nocive che Darwin da il nome di selezione naturale. Il
principio della selezione naturale, quindi, è quello che ha determinato negli organismi
biologici l’adattamento a nuovi ambienti e la differenziazione fra le varie specie, ma su
quali siano gli effettivi meccanismi dell’evoluzione il dibattito è ancora aperto, anche se
vi è un generale accordo su alcuni principi di base quali, ad esempio:
• L’evoluzione naturale agisce sul materiale genetico (genotipo) di un individuo e non
sulle sue caratteristiche fisiche, il fenotipo, quindi ogni variazione che rende un
individuo più efficiente di un altro emerge solo dal patrimonio genetico, ed in questo
non influirà affatto ciò che i genitori avranno eventualmente appreso nella loro vita.
• Il processo di selezione naturale favorisce la riproduzione di quegli individui che
hanno delle caratteristiche che migliorano l’adattabilità all’ambiente, eliminando
attraverso una minore potenzialità riproduttiva, quelle che, al contrario, risultano
penalizzanti. Quindi, dal punto di vista genetico possiamo dire che la selezione
naturale favorisce, attraverso la riproduzione degli individui migliori, quelle
particolari combinazioni genetiche che danno vita ad un organismo più efficiente.
Ciò che viene selezionato, quindi, è principalmente il genotipo di un individuo e non
il fenotipo. In questo senso il fenotipo è solo il vettore di una configurazione
genetica grazie al quale è possibile la perpetrazione delle migliori tra queste ultime.
• Il nucleo centrale del processo evolutivo è costituito dai meccanismi biologici della
riproduzione, infatti, la variabilità generazionale di una specie (in altre parole, le
costanti e determinanti differenze che caratterizzano tutti gli individui di una specie
fra di loro lungo le varie generazioni) è determinata dalla ricombinazione genetica
che avviene nel momento della riproduzione e dalle piccole mutazioni casuali che
possono intervenire a carico del codice genetico. Saranno proprio questi meccanismi
a stabilire le differenze e le uguaglianze fra un individuo ed i suoi genitori.
• L’evoluzione naturale opera su intere popolazioni di individui attraverso processi
ciclici e generazionali determinati esclusivamente dalle contingenze ambientali e
dalle interazioni fra i vari organismi.
A partire da queste considerazioni passiamo ad esaminare cosa c’è in comune fra
l’evoluzione dei sistemi biologici e gli algoritmi genetici.
E’ stato detto che questi ultimi si ispirano all’evoluzione naturale ed in effetti gli
elementi fondamentali degli algoritmi genetici sono riconducibili ai principi di base che
sono stati elencati riguardo all’evoluzione naturale: gli algoritmi genetici operano su
popolazioni di cromosomi artificiali che vengono fatti riprodurre selettivamente sulla
base delle prestazioni dei loro fenotipi rispetto ad un problema da risolvere, quindi,
anche per l’evoluzione artificiale valgono i principi della riproduzione selettiva degli
individui migliori, della ricombinazione genetica, che i biologi chiamano crossover, e
delle piccole mutazioni casuali dei cromosomi.
Naturalmente i cromosomi artificiali degli algoritmi genetici sono delle semplificazioni
di ciò che è realmente il genoma di un organismo biologico, ma la logica che sta alla
base li comprende entrambi. Tanto in natura quanto in ambiente artificiale il codice
genetico è un tipo di codifica che permette di contenere e trasmettere in maniera
semplice e robusta una grandissima quantità di informazioni. Le lunghe sequenze
nucleotidiche che costituiscono la molecola di acido deossiribonucleico, comunemente
detto DNA, costituiscono l’intera e sola informazione che permette ad una singola
cellula di generare nel tempo quel complesso di strutture, a volte di notevole
complessità, che abbiamo chiamato fenotipo. La funzione dei cromosomi artificiali è
esattamente la stessa, infatti essi contengono l’informazione per generare un fenotipo
che, nel caso degli algoritmi genetici è una proposta di soluzione ad un problema, ma
,quando si applicano alle reti neurali, divengono i registi di complesse operazioni
matematiche che portano a risultati sorprendenti.
In ultima analisi, un cromosoma è semplicemente una sequenza di simboli, ciò che è
importante è il tipo di codificazione, che dipende in larga parte dal problema che
dobbiamo risolvere e quindi dal genere di risposte che ci aspettiamo di ottenere. Un tipo
di codificazione molto frequente è il codice binario ed in questo caso il cromosoma di
un individuo risulta una stringa di lunghezza finita composta di zero e di uno, ma i
simboli potrebbero essere di qualsiasi genere.
Negli algoritmi genetici, inoltre, al di là del tipo di codifica scelto per il genotipo, svolge
un ruolo di fondamentale importanza la cosiddetta funzione di fitness, o funzione di
valutazione, che serve per giudicare le prestazioni di ciascun fenotipo rispetto al
problema da risolvere e che nel caso degli algoritmi genetici prende il posto
dell’ambiente esterno, che sarebbe il suo corrispettivo biologico, infatti, così come in
natura l’efficienza di un individuo si misura sulla base delle sue capacità di adattamento
all’ambiente, i cromosomi artificiali vengono selezionati in base alla loro capacità di
sviluppare un fenotipo che sia il più adatto a fornire una risposta adeguata al problema.
Quindi, per affrontare un problema attraverso gli algoritmi genetici bisogna innanzitutto
stabilire il tipo di rappresentazione genetica e la funzione di fitness e, successivamente,
si passa a creare la popolazione vera e propria, che consiste in un certo numero di
stringhe genetiche scelte a caso. In seguito ciascuna stringa di questa generazione
iniziale verrà a turno decodificata e valutata in base alla funzione di fitness:
naturalmente, data la scelta casuale delle stringhe genetiche, i rispettivi fenotipi saranno
tutti diversi fra loro e di conseguenza ciascuna stringa avrà un valore di fitness
differente. A questo punto entra in gioco la selezione, che premia con la riproduzione
solo le stringhe che hanno sviluppato i fenotipi migliori rispetto alla media di tutte le
fitness della popolazione, quindi l’operatore della riproduzione selettiva svolge un ruolo
analogo alla legge di sopravvivenza del più forte in natura.
I modi per realizzare la riproduzione selettiva sono diversi, ma generalmente si fa
ricorso ad un particolare metodo detto della ruota della fortuna truccata(fig.1). Esso
consiste nell’assegnare ad ogni individuo della generazione una casella su questa
ipotetica ruota della fortuna, quest’ultima avrà, quindi, tante caselle quanti sono gli
individui della generazione, ma la dimensione di ciascuna casella sarà proporzionale ai
valori di fitness ottenuti dai rispettivi individui. La riproduzione selettiva consiste nel
girare la ruota tante volte quanti sono gli individui della popolazione e nel creare ogni
volta una copia della stringa genetica dell’individuo corrispondente alla casella
prescelta, in questo modo, tanto più grande sarà il valore di fitness, e quindi l’ampiezza
della casella, tanto maggiore sarà la probabilità che questa venga sorteggiata.
Le nuove stringhe così create vengono poi accoppiate fra di loro ed elaborate
dall’operatore predisposto alla ricombinazione genetica: il crossover. Per ciascuna delle
coppie così create viene scelto a caso un punto di incrocio attorno al quale avviene lo
scambio del materiale genetico (fig.2). Al termine della ricombinazione ogni nuovo
individuo così ottenuto subisce un processo di mutazione casuale con cui vengono scelti
casualmente alcuni componenti del genoma che vengono sostituiti da altri. Nel caso di
un genoma codificato in sistema binario viene scelto casualmente un componente (ma
possono anche essere di più), un 1 ad esempio, e viene sostituito con uno 0.
Al termine di questo laborioso processo riproduttivo si otterranno un certo numero di
stringhe genetiche, direttamente discendenti dalla generazione precedente, della quale
avranno conservato pregi e difetti (più spesso difetti), ma variamente ricombinati fra di
loro, dando luogo ad una nuova generazione che subirà dal principio il processo che a
cui erano stati sottoposti i loro genitori: quindi, codifica del materiale genetico,
valutazione della fitness, riproduzione e così via. Questo ciclo generazionale viene
ripetuto per un certo numero di volte, finché uno degli individui della generazione più
recente rappresenterà una soluzione soddisfacente al problema che ci eravamo posti di
risolvere.
Fitness=20
Fitness=10
Fitness=2
Fig.1 Esempio di un operatore di riproduzione selettiva realizzato
attraverso una ruota della fortuna truccata. Ogni casella della
ruota corrisponde ad un individuo e l’ampiezza delle caselle è
direttamente proporzionale alla fitness dello stesso.
Punto di
crossover
figlio 1
genitore 1
figlio 2
genitore 2
Fig.2 Esemplificazione di una ricombinazione genetica fra due
stringhe.
Esempi concreti
Per dare una dimensione concreta a quanto è stato detto in precedenza, passeremo alla
discussione di due tipi differenti di algoritmi genetici: il primo, molto semplice, si
applica completamente alla descrizione che abbiamo fatto poc’anzi, mentre il secondo,
più complesso e affascinante, se vogliamo, presenterà un altro modo di utilizzare e
codificare gli algoritmi genetici.
Massimizzare una funzione1
In questo esempio vedremo come opera un programma di algoritmi genetici
nell’affrontare un problema consistente nel trovare valori di x che massimizzino la
funzione f(x) = x2 , dove x può variare tra 0 e 31.
Per prima cosa bisogna scegliere che tipo di codifica utilizzare per creare la
rappresentazione genetica: in questo caso si è optato per una codifica binaria con
stringhe genetiche della lunghezza di 5 unità ciascuna, in modo tale da codificare i
numeri da 0, che corrisponde allo 00000 in sistema binario, al 31 (11111 in sistema
binario)2. A questo punto generiamo una piccola popolazione composta di sole quattro
stringhe genetiche prese a caso. Ogni stringa viene codificata, ovvero si converte dal
sistema binario a quello decimale, e si valuta la sua fitness applicando la funzione
potenza al numero decimale ottenuto. Al termine di tale valutazione ogni stringa riceve
una probabilità di riproduzione proporzionale alla propria fitness e, a partire da questa,
vengono generate un certo numero di copie per ogni stringa. Queste nuove stringhe
vengono poi accoppiate e passate all’operatore di ricombinazione genetica che sceglierà
un punto di incrocio, in questo caso la probabilità di crossover è Pc = 1, cioè tutte le
coppie. Infine ciascun elemento generato dalla ricombinazione genetica viene mutato
dall’operatore di mutazione casuale con una probabilità Pm = 0,001 ( i risultati prodotti
dalle prime due generazioni sono riportati nella Tav.1). Già dalla prima attivazione
possiamo notare due indici evolutivi molto importanti: il valore massimo e quello medio
della fitness, infatti la popolazione è costituita da diversi individui che hanno prestazioni
diverse e, di conseguenza, diversi valori di fitness, quindi il valore medio è sempre
inferiore a quello massimo, che è l’espressione del migliore individuo della
popolazione. Questo risultato, da un punto di vista evolutivo, è molto interessante
poiché mette in evidenza come le capacità di adattamento esibite da una specie in
generale, anche in natura, non sono mai le migliori in assoluto, ma solo quelle che
garantiscono un rapporto favorevole fra nascita e morte degli individui e, di
conseguenza, la sopravvivenza della specie. Sotto questo aspetto gli algoritmi genetici
ci danno anche una conferma di quanto faceva notare Jacques Monod in Il caso e la
necessità [1970] quando afferma che uno dei meriti del neo-darwinismo del primo
1
2
Esempio trato da D. Floreano, Manuale sulle reti neurali.
La trasformazione da numero binario a numero decimale è dato dalla formula:
N −1
x = ∑ i2 p
p =0
dove p indica la posizione del numero intero binario a partire dalla ultima cifra, la numero 0, N è il
numero di cifre e i è il valore binario dell’intero corrispondetnte, 0 o 1. Per esempio:
10011 = 1 . 24 + 0 . 23 + 0 . 22 + 1 . 21 + 1 . 20 = 16 + 2 + 1 = 19
novecento è stato quello di sottolineare che “…il fattore decisivo della selezione non è
costituito dalla lotta per la vita, ma dal tasso differenziale di riproduzione in seno ad una
specie”, infatti ciò che è importante per una specie è la presenza di individui capaci di
riprodursi e di perpetuarla, mentre l’adattamento ambientale diviene una sorta di
conseguenza imposta da finalità riproduttive.
Tav.1 Risultati prodotti dall’algoritmo genetico descritto nel paragrafo.
Stringa
numero
Popolaz.
Iniziale
Decodificazione
x
Valuta–
zione
funzione
Probabilità
riproduz.
Numero
di figli
Numero
di figli
effettivo
1
2
3
4
01101
11000
01000
10011
13
24
8
19
169
576
64
361
0,14
0,49
0,06
0,31
0,58
1,97
0,22
1,23
1
2
0
1
1170
293
576
1,00
0,25
0,49
4,00
1,00
1,97
4
1
2
Decodificazione
x
Valutazione
funzione
12
25
27
16
144
625
729
256
Somma
Media
Massimo
Coppie
con
crossover
(!)
Incrocio
Pc=1,0
0110!1
1100!0
11!000
10!011
01100
11001
11011
10000
Mutazioni Nuova
Pm=0,00 popoloz.
1
01100
11001
11011
10000
Somma
Media
Massimo
01100
11001
11011
10000
1754
439
729
Algoritmi genetici e reti neurali
Tanto gli algoritmi genetici quanto le reti neurali sono tecnologie che prendono
ispirazione dalla biologia, in particolare, ai processi biologici di adattamento, e la loro
peculiarità sta nel fatto che si svolgono su scale temporali molto diverse. Infatti,
l’evoluzione filogenetica ha luogo attraverso il succedersi di numerose generazioni di
individui, mentre il sistema nervoso si sviluppa in un arco di tempo ben più ristretto e
compreso fra il concepimento3 e la morte di uno stesso individuo. Solo di recente alcuni
ricercatori si sono rivolti all’integrazione di queste due tecnologie “cercando di creare
dei sistemi di calcolo che possiedano una potenza adattiva maggiore di quella fornita
singolarmente da ciascuno dei due approcci” (Floreano, Manuale sulle reti neurali).
Queste ricerche, oltre a suscitare un notevole interesse dal punto di vista ingegneristico,
sono anche un utile e potente strumento per l’investigazione computazionale di
tematiche inerenti la psicologia, la biologia, l’etologia e le neuroscienze.
Le domande che sorgono nel momento in cui ci accingiamo a studiare il sistema
nervoso sono numerose e siamo spesso privi degli strumenti utili a fare chiarezza.
Sappiamo che il sistema nervoso degli organismi viventi è determinato nella sua
struttura, in gran parte, dal codice genetico e sappiamo pure che questa struttura viene
poi sviluppata e raffinata dai processi di apprendimento: qual è il vantaggio apportato da
questa combinazione? Quali sono i livelli di interazione fra i due processi nello sviluppo
del sistema nervoso? Queste sono solo alcune delle domande che ci si propone di
investigare attraverso questi nuovi metodi di ricerca, che hanno il vantaggio di metterci
difronte a generazioni e generazioni di organismi dei quali conosciamo perfettamente
struttura e funzionamento del sistema nervoso e del codice genetico. Tutte condizioni
precluse alla biologia classica, così come a tutte le altre scienze che abbiamo citato
poc’anzi.
Per quanto riguarda gli indirizzi di ricerca che sono attivi in questo campo, nonostante
la novità del settore e la poca sistematicità che in questo momento lo caratterizza, ne
possiamo comunque individuare alcuni che approssimativamente raggruppano gli
orientamenti principali della disciplina e le differenze si ritrovano in ciò che si decide di
fare evolvere: in particolare, ricerche improntate sull’evoluzione dei pesi sinaptici,
sull’evoluzione dell’architettura della rete neurale oppure sull’evoluzione delle regole di
apprendimento.
Vediamo ora come funzionano questi nuovi sistemi.
Rappresentazione genetica di una rete neurale4
Se vogliamo combinare gli algoritmi genetici alle reti neurali la prima cosa da fare è
scegliere una rappresentazione genetica per la rete neurale. Nella maggior parte delle
ricerche, per la rappresentazione dei pesi sinaptici si utilizzano codici binari o
direttamente numeri reali. Nel primo caso la codifica del codice genetico è un po’ più
complessa rispetto al secondo, infatti in quest’ultimo il genoma di ciascun individuo è
costituito semplicemente dai valori numerici dei pesi sinaptici che costituiscono la rete,
mentre nel primo è necessario un passaggio in più che permetta la codifica dei numeri
reali dei pesi sinaptici in sistema binario e poi costituisca il genoma sulla base di tale
3
Utilizziamo il termine “concepimento” e non “nascita” in quanto numerose ricerche nel campo della
neurobiologia e della psicobiologia, alla quali noi stessi facciamo riferimento, sottolineano il
determinante ruolo svolto da tutti quei processi di sviluppo embrionale, e quindi di carattere prettamente
genetico, che sottendono allo sviluppo di un sistema nervoso efficiente.
4
Nell’affrontare questo e gli altri temi a seguire faremo riferimento in modo pressocché esclusivo ad
alcune ricerche nell’ambito della vita artificiale, che è il settore di nostro primario interesse, svolte
principalmente dai componenti, effettivi o associati, del gruppo di ricerca sulla vita artificiale del C.N.R.
(Istituto di psicologia).
codifica, quindi, il rapporto fra fenotipo (la rete neurale) e genotipo in questo caso è più
complesso. In effetti, già dalla scelta del tipo di rappresentazione per il materiale
genetico siamo indirizzati verso l’uno o l’altro degli indirizzi di ricerca che abbiamo
citato prima.
Se scegliamo di rappresentare il genoma semplicemente attraverso la sequenza dei pesi
sinaptici non possiamo pensare di fare evolvere la rete neurale anche nella sua
architettura, poiché, per potere estrarre i pesi sinaptici in maniera da poter ricostituire la
rete neurale a partire da essi, la rete deve avere una architettura già determinata. E’
come se, trovandoci davanti ad un archivio dai cassetti numerati, volessimo prendere le
schede contenute nei cassetti e modificarle, ricostituendo poi l’archivio con le schede
modificate. Sulla base delle sole schede non possiamo modificare la struttura di tutto
l’archivio, infatti, l’unica libertà che abbiamo è quella di prendere una scheda e
modificarla o riporla in un cassetto differente da quello da cui l’avevamo prelevata, ma
in questo caso, al limite, aumentiamo solo il disordine dello schedario, ma non la sua
struttura classificatoria. Allo stesso modo, le connessioni di una rete neurale sono un po’
come le caselle numerate dello schedario e se noi preleviamo solo i pesi sinaptici
connessi ad esse (le schede dello schedario) l’unica cosa che possiamo fare è modificarli
o scambiarli fra di loro, ma per ricostituire una rete funzionale a partire da essi dovremo
nuovamente associarli alle stesse connessioni da cui li avevamo estratti. Diversamente,
attraverso una rappresentazione genetica in codi ce binario abbiamo molta più libertà
nel decidere cosa associare alla varie stringhe di numeri che compongono il genoma.
Possiamo codificare non solo i pesi sinaptici della rete, ma anche molte cose in più
come la posizione dei neuroni attivi all’interno della rete, la lunghezza delle loro
connessioni e la loro soglia. In questo modo, nel codice genetico riusciamo a contenere
quel quantitativo di informazioni necessarie a fare evolvere oltre che i pesi sinaptici
anche l’architettura della stessa rete. Ritornando all’esempio dell’archivio: con una
codifica binaria avremmo la possibilità di creare una sorta di genoma dell’archivio
stesso nel quale, oltre alle schede contenute nei cassetti, potremmo inserire altre
informazioni che ci permetterebbero di generare, a partire da esso, un nuovo schedario
sulla base del precedente e diverso da questo non solo per il contenuto delle schede o
per la loro disposizione, ma anche per il numero e la disposizione (l’ordine) dei cassetti.
Valutazione, riproduzione e mutazioni
Quando, nei paragrafi precedenti, parlammo degli elementi funzionali degli algoritmi
genetici, oltre al tipo di codifica scelto per il genoma, descrivemmo anche la funzione
selettiva svolta dalla valutazione della fitness del fenotipo e dei metodi riproduttivi e di
mutazione. Naturalmente, anche per gli algoritmi genetici associati alle reti neurali
valgono gli stessi principi.
Negli algoritmi genetici, per valutare la fitness dei vari individui che costituiscono la
popolazione bisogna innanzitutto generare il fenotipo a partire dal genotipo, essendo
proprio questo a fornire la prestazione che verrà valutata e nel nostro caso, come
abbiamo già avuto modo di notare, il fenotipo è costituito da una rete neurale alla quale
vengono sottoposti alcuni problemi da risolvere, quindi la popolazione sarà costituita da
una serie di reti neurali tutte diverse fra di loro sotto qualche aspetto, che può andare
dalla semplice differenza dei pesi sinaptici alla differenza nell’architettura. In base ai
risultati ottenuti dai vari fenotipi vengono selezionate le stringhe genetiche migliori ed
avviene la riproduzione. Anche in questo caso la riproduzione può essere sessuata o
asessuata: nel caso della riproduzione sessuata il metodo di accoppiamento fra le varie
stringhe genetiche e la riproduzione è lo stesso che abbiamo descritto in precedenza ed
il prodotto della riproduzione sarà, naturalmente, un’altra rete neurale differente dai
genitori sotto qualche aspetto. Nel caso della riproduzione asessuata invece agisce il
solo operatore di mutazione che modifica il genoma in maniera casuale: nel caso della
codifica binaria la mutazione avviene nella maniera consueta, mentre, nel caso in cui il
genoma sia costituito dalla sequenza dei pesi sinaptici, l’operatore generalmente agisce
sommando o sottraendo un piccolo numero preso a caso ad alcuni pesi del genoma,
anch’essi scelti a caso.
Come si può notare, in questo genere di esperimenti è preponderante la presenza di
variabili casuali, quindi, l’evoluzione di questi oggetti è in gran parte governata dal caso
e ciò che li rende estremamente interessanti e che, nonostante il caso, o forse proprio
grazie ad esso, riescono a migliorare continuamente le loro prestazioni e a raggiungere
delle soluzioni veramente interessanti, e spesso inaspettate, per i problemi che devono
risolvere. Il principio, teoricamente poco chiaro, ma in pratica molto efficace, che sta
alla base di tutto questo era stato già individuato più di un secolo fa: “…qualsiasi
modificazione – che comparisse casualmente nel corso delle età, e che fosse tale da
favorire in qualsiasi modo gli individui di una specie qualunque, rendendoli meglio
adatti alle nuove condizioni – tenderebbe a conservarsi e, quindi, la selezione naturale
potrebbe esercitare liberamente il suo lavoro di perfezionamento”5. Le parole sono di
Charles Darwin, presenti ne L’origine della specie [1859]. Prima di continuare vorrei
spendere qualche parola sulla frase appena riportata. Le parole “casualmente” e “in
qualsiasi modo” sono state messe in risalto proprio per rilevare l’estrema parentela che
lega i principi dell’evoluzione naturale con quelli dell’evoluzione artificiale. Sulla
casualità dei fattori che determinano le variazioni in natura la letteratura è vasta:
sostituzione di una singola coppia di nucleotidi ad un’altra, sostituzione di una o più
coppie di nucleotidi, nonché svariate alterazioni a carico del testo genetico che
provocano l’inversione o la ripetizione di segmenti del DNA, sono solo alcune delle
cause, non prevedibili, dell’estrema variabilità presente in natura. Ugualmente, il
significato di “in qualsiasi modo”, sta ad intendere che non esiste una direzione
determinata verso la quale si debba orientare l’evoluzione, il principio che sta alla base
dell’evoluzione non è, quindi, teleonomico, ma ogni novità generata dal caso si
confronta l’ambiente in maniera del tutto paritetica alle altre e sarà solo l’ambiente,
inteso in senso molto generico, a stabilire quali novità sono favorevoli e quali no. Allo
stesso modo, il principio di evoluzione che regola il funzionamento degli algoritmi
genetici non solo è casuale, come abbiamo già visto, ma non è neppure orientato, infatti,
le variazioni evolutive che si riscontriamo negli organismi artificiali sono sorprendenti
tanto quanto quelle naturali, restando pur sempre nei limiti del paragone. Quando
vediamo degli organismi artificiali in azione ci rendiamo conto di come, anche in una
realtà tanto semplificata, le possibilità di variazione comportamentale siano enormi.
Sarebbe addirittura possibile associare delle “personalità” a questi organismi, che nella
ricerca di una soluzione ad un problema percorrono tante strade ed alcune di esse, non
necessariamente uguali, risultano vincenti sulle altre, dando luogo a generazioni molto
varie di organismi che, pur dinanzi allo stesso problema, lo affrontano e lo risolvono in
modo del tutto differente.
Simulazioni di vita artificiale
5
Le parole in corsivo non sono presenti nel testo originale.
Avendo più volte accennato agli organismi artificiali, è giunto il momento di calarci
nella realtà di quelle che sono le simulazioni di vita artificiale6 e lo faremo attraverso
alcuni esempi.. Nell’introduzione, e poi più volte nel corso della nostra discussione,
abbiamo detto che le simulazioni vita artificiale sono uno dei metodi che ci permettono
di studiare le complesse interazioni fra le varie componenti di una sistema naturale dal
punto di vista ecologico. Vediamo in concreto in cosa consiste una simulazione di
questo genere.
Gli strumenti utilizzati per compiere tali simulazioni, oltre all’indispensabile computer,
sono gli algoritmi genetici applicati alle reti neurali. Come abbiamo già detto, il primo
passo che dobbiamo compiere è la scelta della rappresentazione genetica per la rete
neurale che dovremo usare: in questo primo esempio sceglieremo di rappresentare la
rete attraverso la sequenza dei suoi pesi sinaptici, quindi il genoma di ciascun individuo
della popolazione sarà costituito da una serie di numeri reali che rappresentano i pesi
sinaptici: ciò che vogliamo fare evolvere sono proprio tali pesi.
Adesso dobbiamo assegnare un compito ai nostri individui, in modo da avere un
parametro per valutare la fitness di ciascuno di essi: decidiamo di generare un ambiente
di ampiezza definita (una griglia bidimensionale formata da 10 x 10 celle) all’interno
del quale disporremo casualmente degli elementi di cibo. Il compito degli organismi è
quello di trovare gli elementi di cibo sparsi nell’ambiente e mangiarli (Fig. 6). Ogni
elemento mangiato farà aumentare la fitness di una unità.
Ora che sappiamo il compito da svolgere bisogna mettere il nostro organismo in gradi di
poterlo compiere, dobbiamo quindi dotarlo di un sistema sensoriale che gli permetta di
“vedere” dove si trovano i pezzetti di cibo e di un sistema motorio, che lo faccia
materialmente muovere all’interno dell’ambiente, per andare a mangiarli. Tutto questo
lo otteniamo grazie alla rete neurale, che sta alla base del sistema nervoso
dell’organismo (in effetti, l’organismo, essendo un sistema computazionale, è costituito
dalla sola rete neurale). Nel caso del nostro esempio la rete è composta:
- da un sistema sensoriale composto da due neuroni di input che registrano
rispettivamente l’angolo (misurato in senso orario a partire dalla direzione verso cui
è rivolto l’organismo) e la distanza euclidea dell’elemento di cibo più vicino;
- da quattro neuroni nello strato nascosto;
- da un sistema motorio costituito da due neuroni di output con valore di attivazione
binario: 0,0 “stai fermo”; 0,1 “gira a destra di 90°”; 1,0 “gira a sinistra di 90°”; 1,1
“un passo avanti”.
Lo schema della rete neurale è rappresentato nella figura 7.
6
Per una trattazione più esauriente rispetto a questo genere di ricerche rimando a Intervista sulle reti
neurali [1991] e Mente [in corso di pubblicazione] entrambi di D. Parisi, all’interno dei quali sono
contenuti, tra l’altro, molti e più significativi esempi sulle simulazioni di vita artificiale.
Fig. 6 Schema dell’ambiente all’interno del quale “vive” il nostro organismo
artificiale (rappresentato dal cerchietto nero). Le celle colorate in
nero sono quelle che contengono il cibo.
Neuroni motori
Interneuroni
Neuroni sensoriali
Fig.7 Rappresentazione schematica della rete neurale usata nella simulazione.
La vita di ogni individuo della popolazione è di 5000 cicli, ovvero, dopo 5000
attivazioni della rete, corrispondenti ad altrettante azioni dell’individuo stesso, esso
muore ed è a questo punto che entrano in azione gli operatori di selezione e di
mutazione per effettuare la riproduzione.
La riproduzione è asessuata e premia solo il 20% degli organismi della popolazione.
Questo significa che dei 100 individui della generazione iniziale, sulla base della
valutazione della fitness di ciascuno, vengono selezionati solo i primi venti (i venti che
hanno mangiato più elementi di cibo degli altri, per intenderci) ed ognuno di essi darà
luogo a 5 figli, che saranno materialmente generati dall’operatore di mutazione,
attraverso una casuale modificazione dei pesi sinaptici della rete neurale del genitore. In
questo modo, se i primi 20 organismi generano 5 figli ciascuno, avremo 20 x 5 = 100,
ovvero ricostituiremo la popolazione nello stesso numero di individui della generazione
precedente. Questo ciclo di attivazione, selezione e riproduzione viene reiterato per 100
volte, generando, quindi, 100 generazioni successive.
Riassumendo, la situazione sperimentale è questa: abbiamo una popolazione di 100
organismi artificiali, ognuno dei quali viene posto in un ambiente di grandezza definita
nel quale sono presenti degli elementi di cibo ed il loro compito è quello di mangiare il
maggior numero possibile di questi elementi. Ognuno degli organismi ha a disposizione
un totale di 5000 passi per portare a termine il compito. Al raggiungimento di questo
tetto verranno selezionati i venti individui che avranno mangiato più cibo e si faranno
riprodurre. Questo ciclo viene reiterato per 100 volte.
Cosa osserviamo a mano a mano che le generazioni si succedono? Qual è il risultato di
queste operazioni?
Una volta lanciato il programma di simulazione notiamo che gli organismi delle
generazioni iniziali hanno la tendenza a muoversi nell’ambiente in maniera del tutto
disordinata e solo casualmente si imbattono negli elementi di cibo. Le fitness individuali
di questi organismi, nella maggior parte dei casi, sono molto basse ed il valore medio lo
è ancora di più, ma, con il susseguirsi delle generazioni, le fitness individuali crescono
piuttosto rapidamente, così come la media, fino a raggiungere valori che indicano
l’individuazione della quasi totalità degli elementi di cibo presenti nell’ambiente.
La conclusione che possiamo trarre da questa semplice simulazione è che i meccanismi
di selezione e di mutazione casuale effettivamente agiscono nel senso
dell’ottimizzazione delle prestazioni di una popolazione. Infatti, il sistema selettivo che
abbiamo utilizzato premia solo i migliori, garantendo ad essi la trasmissione del loro
patrimonio genetico alle generazioni successive. Il principio della mutazione, poi,
proprio per la sua casualità non è indirizzato al miglioramento: una dimostrazione di ciò
è la comparsa, nel corso delle varie generazioni, di individui che peggiorano, anche
molto sensibilmente, le prestazioni ottenute dai rispettivi genitori, e questa è un’altra
piccola conferma della bontà del principio di selezione naturale, quanto meno inteso in
senso negativo. Se le capacità adattive globali di una specie non migliorano in maniera
apprezzabile, quanto meno viene garantito il mantenimento delle condizioni attuali
attraverso l’eliminazione di quei fattori che risultano svantaggiosi.
Un altro modo per sviluppare una simulazione di vita artificiale consiste nel fare
evolvere l’intera architettura di una rete neurale e non solo i suoi pesi sinaptici. In
questo caso la situazione è parecchio più complessa di quella precedente, a partire dalla
scelta della rappresentazione genetica: non possiamo più accontentarci di un genoma
costituito dai soli pesi sinaptici, ma dobbiamo rivolgerci ad un tipo di rappresentazione
che permetta operazioni del genere che ci proponiamo. Di questo abbiamo già detto,
quindi passeremo subito ad una descrizione pratica di come funzioni un sistema del
genere.
Il nostro scopo è sempre quello di generare degli organismi artificiali che debbano
svolgere un determinato compito7.
Questa volta i nostri organismi artificiali vivono in un ambiente formato da uno spazio
bidimensionale diviso in celle (20 x 20), al centro del quale si trova un’area specifica
(target area) che deve essere raggiunta da ciascun individuo della popolazione (formata
da 100 individui), mentre in due dei quattro angoli del quadrato sono situati due fari (in
inglese landmark). Ogni volta che un organismo raggiunge l’area target la sua fitness
viene incrementata di una unità.
Ogni organismo è dotato anche questa volta di un sistema sensoriale che gli permette di
conoscere l’angolo (sempre rispetto alla direzione verso cui è rivolto) e la distanza dai
due landmark presenti nell’ambiente. Inoltre, è dotato di un sistema motorio uguale a
quello che abbiamo descritto in precedenza (quindi formato da due neuroni), che gli
permette di andare avanti, girare a destra e a sinistra e di stare fermo. Quello che cambia
7
Questo esempio è tratto da una simulazione realmente eseguita da Orazio Miglino, Stefano Nolfi e
Domenico Parisi e riportata, insieme alla discussione sul relativo esperimento, nell’articolo Discontinuity
in evolution: how different levels of organisation imply pre-adaptation.
completamente è il genotipo degli organismi, che questa volta è rappresentato da una
stringa di 0 e di 1 (lunga 1600 bit) ed è diviso in blocchi, in modo tale che ogni blocco
corrisponde ad un singolo neurone che può essere espresso nel processo di sviluppo.
Ciascun blocco contiene le istruzioni che determinano le proprietà di sviluppo del
neurone corrispondente (fig.8).
Come abbiamo visto ci sono, dunque, vari tipi neuroni, per l’esattezza tre: neuroni
sensoriali, interneuroni (che corrispondono alle unità nascoste) e neuroni motori. Il
genotipo è costituito da 40 blocchi, ciò significa che il sistema nervoso di ogni
organismo può essere costituito da 40 neuroni al massimo. I primi 8 blocchi
corrispondono ai neuroni sensoriali, i seguenti 27 blocchi corrispondono agli
interneuroni e gli ultimi 5 ai neuroni motori.
Ciascuno dei 40 blocchi specifica le seguenti istruzioni:
- gene che determina l’espressione del neurone: il gene che decide sulla esecuzione o
meno delle altre istruzioni contenute nel blocco.
- gene che stabilisce la posizione fisica del neurone: specifica le coordinate cartesiane
del neurone all’interno del sistema nervoso.
- geni che determinano la struttura dell’assone: stabiliscono la lunghezza e l’angolo
dei vari segmenti che costituiscono l’assone del neurone.
- geni dei pesi sinaptici: assegnano il peso sinaptico corrispondente all’assone.
- geni della soglia: determinano la soglia di attivazione del neurone.
- gene del tipo di neurone: stabilisce che tipo di codifica deve svolgere il neurone. Nel
caso dei neuroni sensoriali determina se il neurone codificherà l’angolo o la distanza
dai due landmarks, mentre, nel caso dei neuroni motori, stabilisce in quale delle due
posizioni richieste dal sistema motorio dovrà operare.
Genotipo
Geni
espress. neurone
posizione fisica x
posizione fisica y
angolazione assonale
lunghezza assonale
soglia neurone
.
.
.
peso sinaptico
tipo di neurone
Fig.8 Rappresentazione del genotipo che contiene le istruzioni per lo sviluppo
di una rete neurale. I blocchi inattivi, corrispondenti a neuroni
inespressi, sono neri, quelli attivi sono bianchi.
Il risultato delle istruzioni dettate dal genotipo è una rete neurale costituita da quei
neuroni che sono stati geneticamente attivati e sviluppati e che hanno stabilito delle
connessioni fra di loro. Si possono osservare la fase di sviluppo assonale e la rete
neurale che ne consegue nelle figure 8 e 9.
Questi tipo di codifica genetica permette, quindi, di fare evolvere l’architettura delle reti
neurali e non solo i pesi sinaptici e questo ci mette nelle condizioni di esplorare in
maniera ancora più approfondita i rapporti intercorrenti fra genotipo, fenotipo e
comportamento. L’esperimento in questione, ad esempio, ha messo in luce l’importanza
della variabilità genetica e del materiale non funzionale allo sviluppo del fenotipo
nell’adattamento, infatti, affinché si presenti una mutazione vantaggiosa è necessario
che si creino le condizioni adatte, tanto dal punto di vista genetico quanto da quello
fenotipico, e questo è possibile solo quando i meccanismi di riproduzione e di sviluppo
di una specie hanno ha disposizione un grande numero di possibilità espressive
differenti. Proprio l’analisi dei risultati della simulazione appena descritta ha permesso
di notare come le piccole variazioni strutturali di una rete neurale fossero spesso
ininfluenti ai fini di un immediato miglioramento delle prestazioni, ma col passare delle
generazioni le prestazioni miglioravano solo in quelle reti che avevano sviluppato
un’architettura tale da permettere la comparsa delle variazioni vantaggiose. Questo
significa che, sebbene le piccole variazioni nell’architettura di una rete neurale non
siano utili nel breve periodo, lo diventano nel lungo periodo, ponendo le basi per la
comparsa di mutazioni capaci di migliorare le capacità adattive della specie.
Fig.9 Sviluppo dei neuroni e ramificazione degli assoni in base alle
istruzioni della stringa genetica.
Fig.10 Schema della rete neurale derivante dalle connessioni stabilite
durante il processo di sviluppo dei neuroni e di ramificazione
degli assoni. Lo strato in basso contiene i neuroni sensoriali,
mentre quello più in alto contiene i neuroni motori.
Conclusione
Ora che conosciamo cosa sono gli algoritmi genetici e la vita artificiale in generale, ed i
loro rapporti con l’evoluzionismo e la biologia, è bene ricordare che, in merito a queste
ricerche, le opinioni della comunità scientifica sono contrastanti. Se, da un lato, c’è chi
accoglie con favore la possibilità, offerta dalla vita artificiale, di studiare l’emergere di
comportamenti intelligenti a partire da una semplice organizzazione autonoma della
materia, da un altro c’è chi non è convinto del carattere altamente riduzionistico
implicito in tali modelli di simulazione. Le critiche, a tal proposito, giungono da più
parti, tanto nell’ambito psicologico, quanto da quello filosofico, e sono di varia natura.
C’è chi resta perplesso difronte ai riferimenti darwinistici, sostenedo, ad esempio, che
l’interazione fra organismo e ambiente, riscontrabile in natura, è molto più complessa di
quella che è possibile riprodurre nelle simulazioni, che, effettivamente, non tengono
conto di molti fattori, a cominciare dalla competizione riproduttiva presente tra gli
individui di una stessa specie, fino alle mutevoli ed inafferrabili influenze reciproche
operate dalle numerosissime specie viventi che condividono, a vari livelli, lo stesso
habitat ecologico, oppure chi ritiene semplicistico ridurre il comportamento ad una
interazioni di elementi materiali, ritenendo più opportuno continuare a studiarlo
attraverso i metodi classici della psicologia sperimentale.
In ultima analisi, però, queste critiche (come altre dello stesso genere) ne sottendono
una assai più generale, che accusa la vita artificiale di eccessivo riduzionismo nella sua
ricerca delle basi evolutive e neurobiologiche del comportamento, rifiutando, in
generale, l’accostamento di sistemi tanto diversi (quali il sistema nervoso biologico e le
reti neurali, ad esempio) sotto il comune denominatore dei sistemi complessi. A partire
da questa considerazione, si conclude affermando la sostanziale ininfluenza dei risultati
delle simulazioni nei confronti dei sistemi biologici, restringendo, di fatto, il campo
delle ricerche al solo ambito delle scienze dell’artificiale, senza attribuire ad esse un
valore conoscitivo più generale. In altre parole, non sarebbe possibile estendere i
risultati delle simulazioni nell’ambito più generale della psicobiologia (a cui farebbero
riferimento) a causa dell’incapacità di questi modelli di cogliere il reale nesso fra le
varie componenti dei sistemi che pretenderebbero di simulare e perché, soprattutto per
gli psicologi, risulta semplicistico cercare nella biologia le radici del comportamento.
Da parte nostra riconosciamo il valore e la consistenza di queste critiche, ma riteniamo
altresì che sia proprio il ricorso alla teoria dei sistemi complessi che ne permetta,
almeno parzialmente, il superamento, infatti grazie ad essi abbiamo la possibilità di
interpretare la realtà in una nuova maniera, secondo cui, “il comportamento e la vita
mentale emergono dalle interazioni fra numerosissimi elementi che sono le singole
cellule del sistema nervoso, le diverse componenti del corpo (molecole, cellule, organi,
sistemi), i segmenti di meteriale genetico che costituiscono i geni. Lo studio di queste
componenti e delle loro interazioni è essenziale per capire la natura delle proprietà
globali di un individuo che chiamiamo comportamento e vita mentale. Nello stesso
tempo, però, il comportamento e la vita mentale non possono essere “ridotte” alle
cellule nervose, alle componenti del corpo e ai geni, in quanto il comportamento e la
vita mentale sono proprietà emergenti di sistemi complessi di cui le cellule nervose, le
singole parti del corpo e i geni sono le componenti. Come nel caso di tutti i sistemi
complessi, non è possibile prevedere o dedurre le caratteristiche del comportamento e
della vita mentale conoscendo queste componenti e le loro interazioni”8.
8
Parisi, in corso di stampa, pag. 46
Scarica