Uczenie Maszynowe – dowolne topologie i rekurencyjne sieci neuronowe

Ćwiczenie Dowolne topologie sieci i rekurencyjne sieci neuronowe
Cel Zapoznanie się z metodami reprezentacji i przekształcania sieci neuronowych o dowolnych topologiach
Zagadnienia Topologie rekurencyjne; ewolucyjne dostrajanie topologii i wag; sztuczne sieci neuronowe czasu rzeczywistego
Narzędzia
Symulator Framsticks
Materiały

Zadanie 13. Sieci rekurencyjne o regularnych topologiach
(będzie o tym cały przedmiot w kolejnym semestrze...)

  • Płytka RNN, głęboka RNN, dwukierunkowa RNN
  • Problemy z uczeniem – zanikający/gwałtownie rosnący gradient
  • GRU, LSTM i inne
  • Łączenie z konwolucją (np. opisz co widać na obrazie, odpowiedz na pytanie o filmie, wymyśl dźwięk odpowiadający niememu filmowi, ...)
  • Mechanizm uwagi
  • Generatywność

Zadanie 14. Kodowanie sieci neuronowych o dowolnej topologii

  • Narysuj kilka sieci neuronowych o "złośliwych" (szczególnych) topologiach.
  • Zastanów się, jak można takie sieci efektywnie reprezentować (zakodować)? Zapisz reprezentacje sieci z poprzedniego podpunktu.
  • Zastanów się, kiedy można zakończyć symulowanie działania (tj. obliczanie wyjść) sieci neuronowych z połączeniami zwrotnymi, i jak to wygląda w przypadku sieci feed-forward?
  • Jakim algorytmem można by uczyć sieć neuronową o dowolnej (zmieniającej się?) topologii?
  • Jaka jest liczba wszystkich możliwych do reprezentowania sieci w przypadku ustalonej topologii? A jaka w przypadku zmiennej topologii? A jaka jest liczba różnych "znaczeń" (efektów działania) ?
  • Zaproponuj operator zmiany sieci – taki, żeby z dowolnej sieci można było stosując wielokrotnie ten operator dojść do dowolnej innej sieci.
  • Zaproponuj operator "krzyżowania", który z dwóch dowolnych sieci stworzy trzecią. Jakie cechy powinien mieć taki operator? Jak powinny wyglądać krzyżówki sieci narysowanych w pierwszym punkcie; jak należałoby zrealizować idealne krzyżowanie?
  • Zapoznaj się z reprezentacjami f1 i f0 – w szczególności ze sposobem kodowania sieci neuronowych. Przykład:
    f1f0
    X[Nu,0:5,1:6][Nu,-1:8,-1:9]
    //0
    p:
    n:d=Nu
    n:d=Nu
    c:0, 0, 5.0
    c:0, 1, 6.0
    c:1, 0, 8.0
    c:1, 0, 9.0
  • Napisz w dowolnym języku/narzędziu sparametryzowany generator warstwowych-sieci-feed-forward (podajemy liczbę neuronów w warstwach, np. 2-4-7-3) albo każdy-z-każdym (podajmy sumaryczną liczbę neuronów) dla f0 lub f1. Włącz Framsticks.exe i zweryfikuj działanie generatora wklejając genotypy (okienko gene pool, przycisk "New") i obserwując schemat sieci.
    Załącz plik ze źródłem skryptu do emaila ze sprawozdaniem.

Zadanie 15. Optymalizacja wag i topologii

  1. Mutacja.
    • Ustaw we Framsticks parametry mutacji (Experiment->Genetics) w f0 i f1 tak, żeby dotyczyły tylko dodawania/usuwania neuronów i dodawania/usuwania połączeń między neuronami (zatem zmieniania "mózgu", a nie zmieniania "ciała"). Po kliknięciu na przycisk x=, w drzewku parametrów, w gałęziach genetyki f0 i f1 ustaw zatem wszystkie prawdopodobieństwa na zero oprócz:
      • f0, Neurons, New oraz Delete
      • f0, Connections, New oraz Delete,
      • f1, Neuron net, Add/remove a neuron oraz Add/remove neural connection.
      W sekcji "Neurons to add" zostaw włączony tylko jeden rodzaj neuronu – Nu.
    • Stwórz pięć razy sekwencję 200 mutantów zaczynając od sieci z jednym neuronem dla wybranej reprezentacji:
      f1f0
      X[Nu]
      //0
      p:
      n:d=Nu
      W konsoli (Window->Console) generowanie pojedynczej sekwencji realizuje skrypt:
      // Make mutant sequence.
      // Ensure there is one genotype in the gene pool! 
      //
      var ile=200;
      var genepool=GenePools[0]; //use first group of genotypes (first gene pool)
      for(var n=0;n<ile;n++)
      {
         var last=genepool.size-1;
         var g=genepool.add(genepool[last].geno); //copy last genotype
         g.mutate(); //mutate copied genotype
         g.name="mutant "+n; //set its name to a consecutive number
         Simulator.print(""+n+" "+g.numneurons+" "+g.numconnections); //print data for a chart
      }
      

      Upewnij się, że w sekwencji mutantów zachodzą tylko zmiany sieci neuronowej (nie zmienia się "ciało").

      Co można powiedzieć o tych sekwencjach? Jakie ścieżki przeszukiwania reprezentują te sekwencje w przestrzeni wszystkich sieci? Jakie własności powinien mieć operator mutacji, a czego nie powinien robić? Pomocniczo zrób dwa wykresy (na każdym pięć linii): liczby neuronów i liczby połączeń neuronowych w funkcji n.

    • Powtórz ten eksperyment dla sieci wygenerowanej przez napisany wcześniej generator. Jak teraz ocenisz powstałe sekwencje sieci?
  2. Krzyżowanie.
    • Wybierz jedną z reprezentacji: f0 lub f1.
    • Stwórz dwie sieci neuronowe o tej samej topologii, różniące się tylko wagami.
    • Dokonaj ich krzyżowania. W konsoli:
      // Cross over two neural networks.
      // Ensure there are two genotypes in the gene pool!
      //
      var genepool=GenePools[0]; //use first group of genotypes (first gene pool)
      var geno=GenMan.crossOver(genepool[0].geno, genepool[1].geno); //cross over #0 and #1
      geno.name="child"; //set descendant's name
      genepool.add(geno); //add the child genotype to the gene pool
      
      Czy rezultat spełnia postulaty dobrego krzyżowania odkryte w zadaniu 14? Jak będzie działała sieć potomna w porównaniu do działania sieci-rodziców?
    • Powtórz tę operację kilka razy. Czy krzyżowanie jest deterministyczne?
    • Powtórz to zadanie (krzyżowanie) dla pary sieci neuronowych o bardzo różnych topologiach (możesz tu wykorzystać generator sieci pełnej lub warstwowej, który napisałeś wcześniej). Jaki sens ma krzyżowanie różniących się sieci?
  3. Ukierunkowanie: selekcja czyli dobór (dla chętnych).

    Powyżej poznaliśmy przykładowe reprezentacje sieci neuronowych o dowolnej topologii oraz operatory tworzące nowe sieci na podstawie istniejących. To pozwala już prowadzić przeszukiwanie przestrzeni sieci neuronowych. Teraz do tego procesu dołączymy przykładowe, najprostsze ukierunkowanie (cel). Kryterium jakości sieci będzie mianowicie ich wielkość rozumiana jako liczba neuronów + liczba połączeń.

    Ustaw Gene pool capacity = 50, Selection->Unchanged = 0, Fitness->Brain neurons i Brain connections na 1 (reszta 0), Starting energy = 1, Populations->Creatures->Neural net simulation = Immediate, Performance calculation = Immediate.

    Zostaw w puli genów najprostszego, jednego osobnika, uruchom ewolucję i obserwuj jak zmienia się Fitness osobników oraz genotypy.