Piszę prostą grę z zabawkami z zamiarem trenowania głębokiej sieci neuronowej. Zasady gry są z grubsza następujące:
- Gra ma planszę złożoną z sześciokątnych komórek.
- Obaj gracze mają tę samą kolekcję elementów, którą mogą dowolnie umieszczać na planszy.
- Umieszczanie różnych rodzajów elementów nagradza (lub zmniejsza punkty przeciwnika) w zależności od ich pozycji i konfiguracji.
- Kto ma więcej punktów, wygrywa.
Istnieją dodatkowe zasady (dotyczące zwrotów, liczby i rodzajów elementów itp.), Ale nie są one ważne w kontekście tego pytania. Chcę stworzyć głęboką sieć neuronową, która może się iteracyjnie uczyć, grając przeciwko sobie. Moje pytania dotyczą reprezentacji danych wejściowych i wyjściowych. W szczególności:
- Ponieważ wzór elementów ma znaczenie, myślałem, że będę miał przynajmniej kilka warstw splotowych. Płytka może być różnej wielkości, ale w zasadzie bardzo mała (6x10 w moich testach, do rozszerzenia o kilka komórek). Czy ma sens? Z jakiego rodzaju puli mogę korzystać?
- Jak reprezentować obie strony? W tym artykule o go autorzy używają dwóch matryc wejściowych, jednej dla białych kamieni i jednej dla czarnych kamieni. Czy to też może działać w tym przypadku? Ale pamiętaj, że mam różne rodzaje elementów, powiedzmy A, B, C i D. Czy powinienem używać matryc wejściowych 2x4? Wydaje mi się to bardzo rzadkie i mało skuteczne. Obawiam się, że będzie to zbyt rzadkie, aby działały warstwy splotowe.
- Pomyślałem, że wyjściem może być rozkład prawdopodobieństw na macierzy reprezentujący pozycje na planszy, plus osobna tablica prawdopodobieństw wskazująca, który element zagrać. Jednak muszę również przedstawić zdolność do przekazania tury, co jest bardzo ważne. Jak mogę to zrobić, nie zmniejszając jego znaczenia wśród innych prawdopodobieństw?
- A co najważniejsze , czy egzekwuję tylko wygrywające ruchy czy też przegrane ruchy? Egzekwowanie zwycięskich ruchów jest łatwe, ponieważ właśnie ustawiłem pożądane prawdopodobieństwa na 1. Jednak, kiedy przegrywam, co mogę zrobić? Ustawić prawdopodobieństwo przesunięcia na 0, a wszystkich pozostałych na tę samą wartość? Czy sensowne jest również wymuszanie ruchów przez różnicę wyniku końcowego, nawet jeśli byłoby to sprzeczne ze znaczeniem wyników, które są z grubsza prawdopodobieństwem?
Ponadto opracowałem silnik gry w node.js, myśląc o użyciu Synaptic jako frameworku, ale nie jestem pewien, czy może on działać z sieciami splotowymi (wątpię, że istnieje sposób na ustalenie wag związanych z lokalnymi polami percepcyjnymi). Wszelkie porady na temat innych bibliotek kompatybilnych z węzłem?
Odpowiedzi:
Aby przedstawić elementy, powinieneś być w stanie użyć jednej matrycy wejściowej. Wystarczy wyznaczyć liczbę całkowitą dla różnych rodzajów elementów. Białe kamienie mogą być dodatnimi liczbami całkowitymi, a czarne kamienie mogą być ujemnymi.
Możesz użyć sigmoid dla pewności pozycji planszy i liniowej aktywacji dla identyfikatora elementu. pass byłby kolejnym wyjściem sigmoidalnym. Nie sądzę, że będziesz musiał się martwić, że przepustka zostanie rozcieńczona. Ponieważ jest to tak cenna akcja, wynik będzie bardzo zależał od wyniku przejścia i będzie miał duży gradient. Jeśli musisz wybrać akcję przejścia z wysoką częstotliwością do celów uczenia się zbrojenia, po prostu przypisz większe prawdopodobieństwo akcji przejścia w funkcji losowego wyboru.
Ostateczna różnica wyniku ma duży wpływ na celowość ruchów. Duża różnica wyniku powinna mieć duży wpływ na funkcję. Dlatego warto uwzględnić różnicę wyniku w swojej funkcji straty.
Jest to rodzaj pracy wykonywanej przez Deep Q Learning. Być może będziesz też chciał się tym zająć.
źródło
Nie potrzebujesz warstw konwekcyjnych, ponieważ nie podajesz obrazu jako danych wejściowych (patrz poniżej). Alternatywnie możesz spróbować użyć obrazu planszy (z różnymi elementami o różnych kształtach). To też może działać. Potem wybrałbym 2 warstwy konwekcyjne, krok 1, rozmiar jądra równy połowie rozmiaru kawałka. Spróbowałbym tego z jednym maksymalnym pulowaniem.
W przeciwieństwie do innych odpowiedzi sugerowałbym użycie tensora 3d jako wejścia, przy liczbie kanałów równej różnym elementom. Pozostałe dwa równe wymiary odpowiadałyby liczbie komórek na płycie. Różne transformacje w twoim NN nie będą w stanie bardzo dobrze rozróżnić wielu liczb całkowitych. Dlatego lepiej jest mieć jedno-gorące kodowanie typów elementów.
Użyłbym tylko wektora z komponentami n + 1 dla wyjścia: n dla wszystkich możliwych ruchów i 1 dla podania. Kodowałby oczekiwaną nagrodę za każdy ruch, a nie prawdopodobieństwo.
Nie jestem pewien, co masz na myśli przez wymuszanie ruchów. Ale kiedy zamierzasz trenować z czymś takim jak Q-learning, sensowne byłoby wykonywanie całkowicie losowego ruchu co pewien czas z pewnym prawdopodobieństwem (powiedzmy 10% razy). Wyszukiwanie https://en.wikipedia.org/wiki/Reinforcement_learning
źródło