Structura rețelei

Created by Alin Brindusescu on 2011-01-22 15:39:26

In cele ce urmeaza voi prezenta citeva notiuni fundamentale necesare studiului retelelor neuronale. Vor fi discutate urmatoarele subiecte: unitati functionale, arhitectura retelei, funcionare, invatare. Asa cum in natura toate organismele sint formate din celule (unitati functionale) care se aseaza apoi intr-o anuita ordine pentru a forma un organism (arhitectura) si care au anumit ciclu de viata, la fel si in cazul retelelor neuronale vom avea unitati cu o funcionare simpla care se vor interconecta pentru a realiza operati mai complexe respectind o anumita arhitectura si care vor avea o functionare bine stabilita. Pe linga aceasta deoarece retelele neuronale modeleaza functionarea creierului uman mai e nevoie si de un proces de invatare astfel incit structura creata sa poata avea o anumita utilitate.

Deoarece retelele neuronale modeleaza functionarea creierului uman voi incepe prin a vorbi despre creierul uman si modul de functionare al neuronului biologic si abia apoi despre modelul artificial. nDin punctul de vedere al procesarii informatiei la nivelul creierului uman pot fi distinse 3 nivele:

  • nivel structural: neuroni, conexiuni, regiuni
  • nivel fiziologic: modul in care se proceseaza informatia la nivelul creierului din punct de vedere fizic si chimic
  • nivel cognitiv: modul in care oameni gindesc.
Inainte de a putea trece la un model artificial consider ca merita acordata putina atentie unor subiecte ca structura si organizarea creierului, paralelismul si robustetea de care da dovada creierul uman ca si sistem de comunicatii, invatarea, capacitatea de generalizare.
Modelul neuronului biologic
Cu toate ca celulele nervoase (neuroni) au multe caracteristici comune cu celelalte celule ale corpului uman ele se evidentiaza prin capacitatea de a capta, procesa si transmite semnale electromagnetice de-a lungul conexiunilor sinaptice.
Fig. 1. Neuronul biologic

Dupa cum se poate observa (fig.1) neuronul este compus din corp neuronal si una sau mai multe ramificatii. Ramificatiile sint de doua tipuri:
  • dendrite - conduc impulsul electromagnetic dinspre exterior spre corpul neuronal
  • axon - conduc impulsul electromagnetic dinspre corpul neuronal spre exterior.
Interactiunea dintre neuroni are loc prin intermediul unor puncte de contact dintre axonul unui neuron si dendrita altui neuron, numite sinapse (intre dendrita si axon exista un spatiu liber foarte mic, practic nu exista contact direct).La nivelul sinapselor au loc fenomene de natura fizico-chimica destul de complexe care in mare pot fi descrise astfel: membrana neuronului transmitator (membrana presinaptica) elibereaza un transmitator in spatiul sinaptic, membrana neuronului receptor (membrana postsinaptica) receptioneaza acest stimul si ca urmare are loc o modificare a permeabilitati ionice (depolarizare). Permeabilitatea membranei se modifica proportional cu suma algebrica a tuturor potentialelor receptionate in toate partile postsinaptice (toate dendritele) ale neuronului. Daca rezultatul depaseste o anumita valoare prag, atunci se genereaza un potential de actiune (PA) care se transmite de-a lungul axonului. Dupa efectul pe care il provoaca, sinapsele pot fi: excitatoare sau inhibitoare dupa cum depolarizarea provocata poate fi pozitiva respectiv negativa. S-a observat ca stimulind succesiv acceasi pereche de neuroni are loc o crestere a permeabilitatii sinapsei corespunzatoare, acest rezultat stind la baza procesului de invatare folosit in domeniul retelelor neuronale artificiale. Cercetarile in domeniu au aratat ca potentialele de actiune (PA) au amplitudinea constata, amplitudinea ne depinzind de intensitatea si durata stimulilor acestia influentind doar frecveta potentialelor de actiune. Un stimul suficient de intens si de durata provoaca nu doar un potential de actiune ci un tren de impulsuri (secventa de PA). La nivelul creierului neuroni se diferentiaza ca forma (piramidali, granulari, in forma de cos, etc) si functionalitate, s-a observat o corelatie intre forma si functionalitate, astfel celulele cu o forma piramidala sint excitatorii iar cele care au o forma de cos sint inhibitorii. Interconectarea celor aproximativ 1011 este asigurata de o retea de ramificatii cu o lungime totala de aproximativ 1014 m, fiecare neuron avind in medie 104 conexiuni. Prezenta unui asa numar mare de legaturi determina functionarea puternic paralela a creierului uman. Creierul uman are capacitatea de a invata si a generaliza. Astfel el este capabil sa analizeze probleme complexes si sa reactioneze intr-un mod adecvat ca raspuns la situatii noi.
Modelul neuronului artificial
Facind o comparatie cu neuronul biologic putem spune ca wi corespunde permeabilitatii sinaptice, corpul neuronal fiind implementat cu ajutorul functiilor G si f, y reprezinta semnalul transmis de-a lungul axonului, iar xi fiind transmitatori eliberati in spatiul sinaptic.
Fig. 2. Modelul neuronului artificial

Neronul artificial este complet codificat numeric si prelucrarile sint modelate matematic. Neuronul artificial efectueaza urmatoarele prelucrari:
  • integreaza - semnalele de intrare, xi, tinind cont de ponderea asociata
  • transforma semnalul "integrat", s, prin aplicarea unei functii de transfer, rezultind astfel un semnal de iesire.
In general ca si functie de integrare se foloseste o combinatie liniara intre parametrii de intrare si ponderile asociate. In tabelul 1 sint date citeva exemple de functii de integrare pentru neuronul din figura 2 dar si pentru cazul general (unde am considerat ca un neuron i primeste semnale, GW, de la iesirile altor N neuroni iar ponderile se afla intr-o matrice W).
Tabel 1. Exemple de functii de integrare

Exemplul fig.2Cazul general
Combinatie liniara
Distanta euclidiana
regula de propagare pentru
neuronul sigma-pi

Rezultatul functiei de integrare G, la care se adauga si x0 (intrare numita "offset"), notata in figura 2 cu s (s=G(X)-w0), va fi folosit ca valoare de intrare pentru functia de transfer f, in tabelul 2 avem prezentate citeva dintre cele mai folosite functii de transfer.
Tabel 2. Exemple de functii de transfer
Denumire y = f(s) Grafic
Functia treapta y = 0, daca s < 0
y = 1, daca s ≥ 0
Functia signum y = -1, daca s < 0
y = +1, daca s ≥ 0
Functia liniara y = s
Functia rampa y = -1, daca s < -1
y = s, daca -1 ≤ s ≤ 1
y = +1, daca s > 1
Functia sigmoidala
Functia tangenta
hiperbolica
Functia competitiva y = 1, pentru neuronul cu s maxim
y = 0, pentru toti ceilalti neuroni

Daca pentru functia de integrare se foloseste in general o combinatie liniara intre parametrii de intrare si ponderile asociate, functia de transfer este aleasa tininduse cont de modelul de retea neuronala folosit si de tipul de problemei pe care urmeaza sa o rezolvam (de exemplu daca stim ca avem de aproximat un anumit o anumita functie e bine sa alegem functia de transfer cea mai apropiata de tipul respectiv). Acest model matematic al neuronului artificial a fost propus pentru prima data de McCullogh si Pitts si cu toata simplitatea sa este un instrument de calcul extrem de puternic. Dupa rolul pe care il indeplinesc unitatile functionale in cadrul retelei putem sa le impartim in 3 categorii:
  • unitati de intrare - conecteaza reteaua la mediu. Au doar rolul de a retransmite semnalul primit de la mediu catre alte unitati din retea. Nu efectueaza nici un fel de procesari asupra semnalului.
  • unitati ascumse - sint conectate cu alte unitati ale retelei, nu comunica direct cu mediul. Primesc, proceseaza si distribuie semnalele catre alte unitati ale retelei.
  • unitati de iesire - colecteaza semnalele de la celelalte nivele, proceseaza semnalul si il transmit mediului extern.
Arhitectura
In mod normal o singura unitate functionala (un nenuron), cu oricit de multe intrari, nu este sufiecient. Avem nevoie de mai multi neuroni grupati pe nivele, cu diferite modalitati de interconectare. Arhitectura retelei se refera la modul in care sint amplasate unitatile functionale (topologie) si la modul de interconecare (conectivitate). Modul de interconectare al unitatilor functionale determina fluxul informational (modul in care informatia circula in cadrul retelei). Cele mai frecvente cazuri sint cele in care cele 3 tipuri de unitati functionale enumerate anterior formeaza multimi distincte, reteaua fiind organizate pe nivele (un nivel de intrare, unu sau mai multe nivele ascunse, un nivel de iesire), un caz particular fiind cel in care nivelele ascunse lipsesc (reteaua fiind constituita doar dintr-un nivel de intrare si unul de iesire). In figura nr. 3 avem o retea neuronala structurata pe nivele cu un nivel de intrare format in N unitati funcionale, 2 nivele ascunse formate din H1 respectiv H2 unitati functionale si un nivel de iesire format din M unitati functionale.
Fig. 3. Retea neuronala organizata pe nivele
Exista si tipuri de retele unde nu se face distinctie intre unitatile de intrare si iesire, toate unitatile preiau semnale din mediu, prelucreaza semnalele si transmit rezultatele atit mediului cit si altor unitati din retea.
In functie de modul de amplasare al unitatilor putem distinge urmatoarele tipuri:
  • retele unde pozitia unitatilor nu este importanta, ea nu influenteaza nici functionarea, nici algoritmii de invatare. Cu toate ca in reprezentarile schematice unitatile de acelasi nivel sint reprezentate grupat pozitia lor nu are nici un fel de importanta.
  • retele in care este esentiala organizarea geometrica. In acest tip de organizarea pozitia unitatilor functionale depinde de relatiile de vecinatate dintre unitati (aceste relatii de vecinatate intervin in algoritmul de functionare sau cel de invatare).
Fig. 4. Retea Kohonen (organizare geometrica a nivelului de iesire)
Bazate pe modul de amplasare a unitatilor avem umratoarele topologii pentru retelele neuronale:
  • topologie arbitrara - nu este definita nici o relatie de ordine pe multimea unitatilor functionale
  • topologie pe nivele - unitatile sint impartite in submultimi (nivele)
  • topologie cu structura geometrica - unitatile sint amplasate in nodurile unei grile unidimensionale, bidimensionale si mai nou chiar tridimensionale. In cazul amplasari unitatilor pe nivele conectivitatea dintre doua nivele poate fi totala, locala, partiala (fig. 5). Intre unitatile unui nivel putem avea conexiuni laterale (acest tip de conexiuni este specific retelelor care au o topologie cu structura geometrica), inverese (prin care o unitate este conectata cu ea insasi).
Fig. 5. Conectarea unitatilor de pe 2 nivele
Mai putem avea conexiuni peste nivele (in cazul retelelor cu mai multe nivele), conexiuni bidirectionale (specifice retelelor recurente), sau retele hibride in care avem conexiui uni si bi directionale (fig. 6).
Fig. 6. Conectarea nivelelor
Modul in care unitatile functionale sint interconectate determina fluxul informational:
  • feed-forward - flux unidirectional, dinspre intrare spre iesire (tipic retelelor organizate pe nivele in care nu exista conexiuni inverse. Pentru acest tip avem o functionare neiterativa , semnalul de iesire se calculeaza prin aplicarea unei functii asupra semnalului de intrare (fig.7).
  • feed-back - flux multidirectional, semnalul produs de o unitate ajunge inapoi la acea unitate. Acestui tip de flux informational ii este specifica o functionare iterativa pentru ca o singura trecere a semnalului de intrare nu este suficienta pentru obtinerea semnalului de iesire (fig. 8).
Fig. 7. Functionare neiterativa
Fig. 8. Functionare iterativa
Pe linga arhitectura, conectivitate mai e nevoie de inca ceva pentru ca o retea neuronala sa fie intr-adevar folositoare, si anume un proces de invatare prin care reteaua sa poate acumula cunostiinte (achizitie de cunoastere). Procesul de invatare este in fapt un proces de modificare a ponderilor asociate conexiunilor intre unitatile functionale ale retelei. Toti algoritmi de invatare au la baza variatii ale reguli enuntate in 1949 de Hebb. Ideea de baza e ca atunci cind doua unitati j si k sint activate simultan conexiunea dintre ele trebuie intarita:
unde γ este rata de invatare. O alta regula des folosita este regula delta sau Widrow-Hoff:
unde γ este rata de invatare iar dk este iesirea dorita. Avantajul cel mai mare al retelelor neuronale este ca datorita procesului de invatare nu este necesara o formalizare detaliu a problemei de rezolvat, sint suficiente exemple, reteaua acumulind cunostiinte pe baza lor. Un alt mare avantaj care rezulta din acest tip de functionare este ca reteaua este capabila sa furnizeze raspunsuri corecte si la date pentru care ea nu a fost antrenata, spunem ca reteau este capabila sa generalizeze. Pentru ca achizitia de cunoastere sa aiba loc avem nevoie de:
  • o multime de informatii (exemple)
  • un algoritm de invatre (adaptare)
Pe baza tipului de informatii pe care le avem disponibile pentru procesul de invatare, aceasta poate fi:
  • nesupervizata - in acest caz avem la dispozitie doar date de intrare pentru retea, ea descoperind trasaturile statistice ale populatiei. Sistemul dezvolta o reprezentare proprie a intrarilor.
  • supervizata - in acest caz avem la dispozitie un set de antrenare (un set de intrari impreuna cu iesirile corespunzatoare), reteaua adaprindu-si ponderile pentru a produce iesirea dorita atunci cind ca si date de intrare avem datele de intrare asociate. Aceasta asociere intre datele de intrare poate fi data de un factor extern sau chiar de reteaua insesi (auto-supervizata).
O prezentare aferenta acestui subiect este disponibila aici.



Biblioigrafie:

  1. Daniela Zaharie, "Curs Retele neuronale"
  2. Ben Krose and Patrick van der Smagt, "An introduction to Neural Network", Amsterdam, 1996, University of Amsterdam.
  3. Nikola K. Kasabov, "Foundation of Neural Networks, Fuzzy systems, and Knowledge Engineering", Cambridge, The MIT Press, 1998.
  4. Bernard Widrow and Michael A. Lehr, "30 Years of adaptive neural networks: Perceptron, Madaline, and Backpropagation",Proceedings of the IEEE, vol. 78 no.9, September 1990.
  5. Dave Anderson and George McNeill,"ARTIFICIAL NEURAL NETWORKS TECHNOLOGY", Kaman Sciences Corporation, 1992, New York.
  6. Dumitrescu, D., Costin, H. - Retele neuronale; teorie si aplicatii. Teora, Bucuresti, 1996.

See more in ROM

Retele neuronale: Notiuni introductive

Created by Alin Brindusescu on 2011-01-16 16:30:45

Domeniul retelelor neuronale a avut o viata zbuciumata cunoscind perioade in care activitatea de cercetare a fost exprem de intensa si perioade in care acesta a fost declarat complet "mort" pentru ca apoi sa revina in forta stirnind chiar mai mult interes, atit in rindul cercetatorilor cit si a publicului larg prin multitudinea de aplicatii practice pe care le are sau le poate avea.

Putina istorie
Pe la sfirsitul secolului XIX inceputul secolului XX au fost facuti primi paside catre cercetatori ca si Hermann von Helmholz, Ernest Mach si Ivan Pavlov care emit teorii asupra procesul de invatare, conditionarii, etc. Aceste teorii nu au adus nici un fel de modele matematice si nu pot fi considerate ca un inceput pentru domeniul retelelor neuronale.
Adevaratul inceput al acestui domeniu se situeaza la inceptul anilor ''40 cind Warren McCulloch si Walter Pitts pun in evidenta primul model formal al neuronului evidentiind capacitatea de calcul a acestuia si posibilitatea de implementare cu ajutorul circuitelor electronice.

Fig. 1. Citeva repere pe axa timpului

Pe la sfirsitul anilor ''40 Hebb, avind la baza teoriile lui Pavlov, enunta principiul adaptarii permeabilitatii sinaptice conform caruia de fiecare data cind o conexiune sinaptica este folosita permeabilitatea ei creste. Acest principiu sta la baza procesului de invatare prin modificarea ponderilor sinaptice.
In ani ''50 apare si plima aplicatie practica, Frank Rosenblatt realizeaza o implementare hard, numita perceptron, utilizata in recunoasterea caracterelor. Tot in ani ''50 Bernard Windrow si Ted Hoff dezvolta algoritmi de invatare pentru retele neuronale liniare cu un singur nivel de unitati functionale. Algoritmi sint bazati pe minimizarea erorii pe setul de date de antrenare.
In anul 1969 Marvin Minsky si Seymor Papert publica o carte numita "Perceptrons" care pune in evidenta limitarile la care sint supuse retelele neuronale cu un singur nivel de unitati functionale. Acesta parea a fi sfirsitul atit de noului domeniu al retelelor neuronale. Dupa publicarea acestui material, corelata cu lipsa unor echipamente de calcul digital suficient de puternice, face ca o mare parte din companiile care investeau in cercetarile din acest domeniu sa se reorienteze, iar o mare parte dintre cercetatori abandoneaza cercetarile.
Ani ''70 sint mult mai linistit si doar citiva cercetatori mai sint cu adevarat activi in domeniu. Printre ei merita amintiti Teuvo Kohonen, Sames Anderson precum si Stephen Grossberg (foarte activ in cercetarea retelelor cu auto-organizare).
Anii ''80 aduc pe linga noi descoperiri in domeniul retelelor neuronale si calculatoare digitale mai puternice capabile sa ajute cercetatorii in demersurile lor. Astfel ca la inceputul anilor ''80 o data cu o noua abordare a retelelor folosind formalismul fizicii statistice prin punerea in evidenta a a analogiei intre retelele recurente (destinate memorarii asociative) si sistemele de spini magnetici propusa de John Hopfield se marcheaza inceputul unei noi perioade de interes in domeniu caracterizata prin extinderea domeniilor de aplicabilitate si volumul mare de implementari soft si hard folosite in aplicatiile practice.
Astfel ca descrierea intr-o maniera accesibila a algoritmul de invatare al retelelor cu mai multe nivele bazat pe ideea minimizarii unei functii de eroare calculata pornind de la un set de antrenare de catre David Rumelhart si James McClelland nu face sa dea deci un impuls cercetarilor din domeniu. Algoritmul este cunoscut sub denumirea de backpropagation provenita de la faptul ca pentru determinarea ajustarilor ce vor fi aplicate ponderilor se propaga prin retea in sens invers un semnal de eroare.

Putina biologie
Pentru a putea citi aceste informatii dumneavoastra folositi o retea de 1011 neuroni biologici cu un numar de 104 conexiuni pe element. Cu toate ca neuroni biologici sint mult mai lenti decit circuitele electronice, avind un timp de raspuns de 10-3 ms fata de 10-9 ms cit au unele circuite electronice, datorita structuri puternic paralele pot procesa informatia mult mai repede si mai bine decit orice circuit electronic.

Fig. 2. Retea de neuroni biologici

nModul de functionare al neuronilor biologici este inca intens studiat, cu toate acestea pina in acest moment nu se cunosc inca multe din fenomenele care au loc in procesul de invarare. Cu toate ca la nivel biologic procesele care au loc la nivelul creierului sint mult mai complexe se pot evidentia citeva asemanari intre cele doua retele (arificiale si biologice). Astfel partile componente atit la nivel biologic dar si artificial, sint unitati simple care realizeaza diferite operati aritmetice puternic interconectate. De asemenea functionarea celor doua sisteme este determinata de conexiunile existente.

Fig. 3. Retea de neuroni artificiali

Calcul inteligent
Calculul neuronal (o alta denumire folosita pentru retele neuronale) alaturi de calculul fuzzy, calculul evolutiv si alte metode de calcul in care cercetarile sint in stadiu incipient (calcul molecular, calcul membranar, calcul cuantic) face parte dintr-un domeniu mult mai larg numit calcul inteligent. Toate aceste directii ale calcului inteligent incearca sa implementeze modele din lumea fizica si biologica pentru a putea rezolva anumite tipuri de probleme. Apare firesc intrebarea: de ce este nevoie de astfel de abordari in rezolvare problemelor? Cu toata progresele intregistrate in matematica si evolutia sistemelor de calcul din ultimi ani anumite tipuri de probleme nu se pot inca modela matematic sau implementarea acestora ar necesita timpi de calcul inacceptabili. Din acest punct de vedere am putea incadra problemele in doua clase:

  • probleme "rau-puse" - fie nu se cunoaste inca un algoritm care sa duca la un rezultat, fie timpul necesar rularii unui astfel de agoritm este inacceptabil;
  • probleme "bine-puse" - li se poate asocia un model formal pe baza caruia se poate dezvolta o metoda de rezolvare cu caracter algoritmic cu timpi de executie acceptabili.
Calculul inteligent este un domeniu al Inteligentei Artificiale care se ocupa cu rezvoltarea de tehnici de rezolvare a problemelor "rau-puse".
Calculul neuronal, ca parte a calcului inteligent se ocupa in general de rezolvarea problemelor de asociere (clasificare, aproximare, predictie, etc.). Principial pot reprezenta orice functie calculabila, dar ceea ce este mult mai important este ca pot invata orice astfel de functie pornind de la exemple.
Clase de probleme care se pot rezolva cu ajutorul retelelor neuronale:
  • Clasificare si recunoastere: pornind de la o descriere sintetica a unui obiect ii vom asocia un indicator al clasei careia apartine obiectul. Ex: recunoasterea caracterelor, recunoasterea vorbirii, clasifiacarea semnalelor (ex: clasificarea electrocardiogramelor in normale sau patologice), etc.
  • Gruparea si categorizarea datelor: similara problemei de clasificare cu diferenta ca antrenarea retelei se realizeaza pornind doar de la datele de intrare, fara a specifica si clasele carora le apartin. Clasele sint construite pornind doar de la similaritati existente in datele de intrare. Ex: analiza datelor si compresia datelor.
  • Aproximare si estimare: extragerea dependentei functionale dintre doua marimi pornind de la un set de valori ale celor doua marimi (in general valorile sint alterate de zgomot).
  • Predictie: aproximarea urmatoarei valori din serie. Ex: predictia evolutiei stocurilor, predictia in meteorologie, etc.
  • Optimizare: in determinarea unei valori care satisface anumite restrictii si care optimizeaza o functie obiectiv deoarece e suficient sa se obtina solutii suboptimale. Ex: proiectarea circuitelor electronice, alocrea resurselor, probleme de rutare in retea, etc.
  • Stocarea si regasirea informatiei dupa continut: RN permit stocarea informatiei astfel incit aceasta sa fie ulterior regasita pornind de la indicii legate de continut (indiciile pot fi portiuni din informatia stocata). Ex: proiectarea bazelor de date multimedia.
  • Modelare si control adaptiv: Controlul unui sistem dinamic se refera la a determinarea un semnal de control, u(t), care asigura producerea unui semnal de iesire dorit y(t). Reteaua neuronala este antrenata pornind de la un model de referinta.
  • Prelucrarea si analiza semnalelor.
Pina acum am discutat despre istorie, despre neuroni biologici, despre tipurile de probleme care pot fi rezolvate, dar totusi ce este o retea neuronala?
O retea neuronala este un ansamblu de unitati functionale amplasate in nodurile unui graf orientat si intre care circula semnale de-a lungul arcelor grafului.
Elemente definitorii:
  • Arhitectura: modul de amplasare si interconectare al unitatilor functionale. Determina fluxul informational
  • Functionarea: modul in care fiecare unitate functionala in parte si reteaua neuronala ca ansamblu transforma semnalele de intrare in semnale de iesire. Influentata de modul de interconectare al unitatilor functionale (arhitectura).
  • Adaptarea: specifica modul de stabilire al parametrilor ajustabili astfel incit reteaua sa fie capabila sa rezolve anumite probleme. Reguli de modificare a parametriolor -> algoritm de aplicare a acestor reguli.
O prezentare aferenta acestui subiect este disponibila aici.




Biblioigrafie:

  1. Daniela Zaharie, "Curs Retele neuronale"
  2. Ben Krose and Patrick van der Smagt, "An introduction to Neural Network", Amsterdam, 1996, University of Amsterdam.
  3. Nikola K. Kasabov, "Foundation of Neural Networks, Fuzzy systems, and Knowledge Engineering", Cambridge, The MIT Press, 1998.
  4. Bernard Widrow and Michael A. Lehr, "30 Years of adaptive neural networks:Perceptron, Madaline, and Backpropagation",Proceedings of the IEEE, vol. 78 no.9,September 1990.
  5. Dave Anderson and George McNeill,"ARTIFICIAL NEURAL NETWORKS TECHNOLOGY", Kaman Sciences Corporation, 1992, New York.
  6. Dumitrescu, D., Costin, H. - Retele neuronale; teorie si aplicatii. Teora, Bucuresti, 1996.

See more in ROM

Search

Ads