Pytanie:
Trenowanie sieci neuronowej na danych szachowych
Finn Eggers
2020-07-26 12:29:42 UTC
view on stackexchange narkive permalink

Pisałem silnik szachowy z przyjacielem i sam silnik już jest naprawdę dobry (2700+ CCRL). Mieliśmy pomysł, aby użyć sieci neuronowej, aby uzyskać lepszą ocenę pozycji.

Wejście do sieci

ponieważ wynik sieci w dużym stopniu zależy od tego, która strona ma się poruszyć, używamy pierwszej połowy danych wejściowych, aby przeanalizować pozycję, kto ma się poruszyć, a drugą połowę dla przeciwnika. W rzeczywistości mamy dla każdego elementu i dla każdego kwadratu dane wejściowe, które dawałyby 12x64 wejścia. Mieliśmy pomysł, aby uwzględnić również pozycję króla przeciwnika. Więc każda strona miała wejścia 6x64 i to dla każdego kwadratu królem przeciwnika może być -> 6x64x64. W sumie daje to binarne wartości wejściowe 12x64x64, z których maksymalnie 32 są ustawione.

Warstwy

Następna warstwa składa się z 64 neuronów, gdzie pierwsze 32 neurony akceptują tylko dane wejściowe z pierwszej połowy cech wejściowych, a ostatnie 32 akceptują tylko dane wejściowe z drugiej połowy cech wejściowych.

Następuje po warstwie z w pełni połączonymi 32 neuronami, a warstwa wyjściowa ma tylko jedno wyjście.

Funkcja aktywacji

Używamy LeakyReLU na obu ukrytych warstwach i liniowej funkcji aktywacji na wyjściu.

Szkolenie

Początkowo chciałem wyszkolić sieć na około 1 milionie stanowisk, ale to trwa wieki. Sama pozycja ma wartość docelową w zakresie od -20 do 20. Używam stochastycznego zejścia w gradiencie, używając ADAMa z szybkością uczenia się 0,0001 i MSE jako funkcją straty.

Problem polega na tym, że nawet wytrenowanie 1 miliona pozycji zajmuje bardzo dużo czasu. Celem jest późniejsze trenowanie na pozycjach 300M.

Nie jestem pewien, gdzie mógłbym poprawić postępy w treningu

Poniżej znajdują się wykresy, które pokazują postęp szkolenia w 1000 iteracji

enter image description here

Zmiana dla każdej iteracji wygląda następująco:

enter image description here

Mam nadzieję, że ktoś mógłby mi podać jedną lub dwie wskazówki, co mógłbym poprawić, aby szybciej wytrenować sieć. Jestem bardzo zadowolony z każdej porady!

Pozdrowienia, Finn

Edytuj 1

Zgodnie z sugestią, powinienem zmienić moją sieć na keras. Mam problemy z uruchomieniem rzadkich danych wejściowych.

  import keras
z keras.layers importuje dane wejściowe, Concatenate, Dense, LeakyReLU
z keras.models importuj model
z zaplecza importu keras jako K
importuj numpy jako np







# trainX1 = tf.SparseTensor (indices = [[0,0], [0,1]], values ​​= [1, 2], dense_shape = [1,24576])
# trainX2 = tf.SparseTensor (indices = [[0,0], [0,1]], values ​​= [1, 2], dense_shape = [1,24576])
#
# trainY = np.random.rand (1)


trainX1 = np.random.random ((10000,24576))
trainX2 = np.random.random ((10000,24576))

trainY = np.zeros ((10000,1))



# wejście gracza do ruchu
activeInput = Input ((64 * 64 * 6,))
inactiveInput = Input ((64 * 64 * 6,))


denseActive = Gęsty (64) (activeInput)
denseInactive = Gęsty (64) (inactiveInput)


act1 = LeakyReLU (alpha = 0,1) (denseActive)
act2 = LeakyReLU (alpha = 0,1) (denseInactive)

concat_layer = Concatenate () ([akt1, akt2])
dense1 = Gęsty (32) (concat_layer)

act3 = LeakyReLU (alfa = 0,1) (gęsty1)

wyjście = Gęsty (1, aktywacja = "liniowa") (akt3)

model = Model (wejścia = [activeInput, inactiveInput], wyjścia = wyjście)
model.compile (strata = 'mse', optymalizator = 'adam', metrics = ['dokładność'])

# print (model.summary ())

print (model.fit ([pociągX1, pociągX2], pociągY, epoki = 1))

 

Jeśli użyję sparse = True dla warstwy gęstej, pojawi się kilka wyjątków. Cieszę się, gdyby ktoś mógł mi pomóc w tworzeniu rzadkich wektorów wejściowych.

Na jakim sprzęcie działa i co masz na myśli mówiąc „długi czas”?
Sam zaimplementowałem kod w c ++.Iteracje do przodu 1M trwają około 1 sekundy, a iteracje treningowe 1M trwają około 15 sekund.Trenuję na jednym rdzeniu na moim AMD ryzen 3950x
Więc nie ma GPU?Czy korzystasz z frameworka głębokiego uczenia w języku C ++, czy kodowałeś go od podstaw?Spojrzałbym na porównanie go ze skromnym GPU
Może po prostu wypróbuj go na Colab z GPU?Ponadto, jeśli nie wiesz, co robisz i nie masz wystarczająco dużo czasu na optymalizację kodu, użycie gotowego oprogramowania, takiego jak TensorFlow lub PyTorch, byłoby bardziej wydajne.
Nie używam GPU.Napisałem wszystko od zera, ale trochę wiem, co robię. Zaimplementowałem pełną obsługę AVX2.Myślę, że sama prędkość naprawdę nie jest problemem.Problem polega raczej na tym, że po prostu nie zbiegają się tak szybko, jak powinno
https://github.com/Luecx/Koivisto/tree/nnSearch/src_files/nn To jest przy okazji kod.Backprop ma w sobie eta, ale w rzeczywistości nie jest używany.materiał szkoleniowy znajduje się w data-> Trainer.cpp
Jak szybko ** powinien ** być zbieżny na jednym procesorze?
To jest dobre pytanie.Patrząc na kilka wykresów adama dla innych scenariuszy, wygląda na to, że 200 lub 300 iteracji powinno wystarczyć.To znaczy, oczywiście, nie możesz ich tak porównywać
Tak, trudno jest tak porównać, dlatego uważam, że powinieneś spróbować GPU - po prostu najpierw porównać.
@RobertLong: nie można porównać z GPU, jeśli kod nie jest zaimplementowany w językach GPU, takich jak CUDA ...
@MichaelM Mówię, że powinni wdrożyć to w Torch lub podobnym.
Wygląda na to, że możesz zwiększyć tempo uczenia się ... „0.0001” wydaje się strasznie powolne, biorąc pod uwagę, że Twoja sieć robi znaczący postęp w dół ... co powinno przynajmniej nieznacznie poprawić szybkość treningu.
Jakich wyjściowych danych treningowych używasz?Czy symulujesz pełne gry?
Użyłem mojego silnika do wygenerowania małego zestawu testowego zawierającego około 750 tys. Pozycji, które zostały ocenione za pomocą wyszukiwania na głębokość 8.odbyła się dyskusja, w wyniku której wyszukiwanie na większej głębokości spowodowałoby zbyt duży szum.w zasadzie sieć jest tak mała, że nie zrozumiałaby tych ukrytych rzeczy
Trenuję więc tylko na jednej pozycji -> eval depth 8 z poprzedniego silnika
„używamy pierwszej połowy danych wejściowych do analizowania pozycji„ Nie używasz poprawnie słowa „parsuj”.Wydaje się, że masz na myśli „reprezentować”.Parsowanie oznacza wydobywanie znaczenia z reprezentacji, a nie tworzenie go.
@Acccumulation tak, masz rację.to było pierwsze słowo, które przyszło mi do głowy.mój błąd :)
Dwa odpowiedzi:
Robert Long
2020-07-26 13:01:27 UTC
view on stackexchange narkive permalink

Myślę, że powinieneś rozważyć uruchomienie go na GPU.Google Colab jest darmowy, a Amazon AWS jest bardzo tani.Wydaje się, że wiesz, co robisz, więc prawdopodobnie możesz bardzo szybko rozpocząć korzystanie z PyTorch.Kiedy porównasz wydajność tej samej sieci zaimplementowanej na GPU z konfiguracją z jednym procesorem, będziesz w stanie lepiej wiedzieć, gdzie iść dalej.

problem polega na tym, że po prostu włożenie go do GPU najprawdopodobniej nie pomoże.największym problemem jest tutaj ogromny rozmiar danych wejściowych.Udało mi się poradzić sobie z rzadkimi danymi wejściowymi na procesorze i efektywnie używam tylko około 1000 obciążeń na iterację pierwszej warstwy.gdybym użył tensorflow lub pytorch lub czegoś takiego, nie byłby w stanie zrozumieć tego rzadkiego wejścia
Latarka obsługuje rzadkie tensory
mhm, spojrzę na to.Dziękuję Ci
Bez obaw.Powodzenia, to ciekawy projekt!
Uruchomiłem Keras z obsługą GPU i zastanawiałem się, jak dokładnie ten rzadki typ może być użyty w keras / tf. Jeśli nie masz nic przeciwko, spójrz na wprowadzoną przeze mnie edycję :)
Mówiłem o Torch, a nie TensorFlow, ale powinien być dostępny w TF.Rzucę okiem, kiedy wrócę do domu
Dziękuję Ci bardzo :).Chodzi o to, że prawdopodobnie chcę użyć jakiegoś programu ładującego dane, aby ostatecznie trenować na 300M punktach danych, co tworzy rzadkie dane wejściowe ... Nie wiem nawet, od czego powinienem zacząć.Prawdopodobnie spróbuję uruchomić pytorch
Jeśli chodzi o twoją edycję, czy określiłeś rzadkie dla warstwy gęstej i wejściowej?Niestety pytania dotyczące programowania są tutaj nie na temat!
Tak, ale nie wiem, jak ustawić macierze na rzadkie.Prawdopodobnie przeniosę to konkretne pytanie do stackoverflow.dziękuję za pomoc :)
Nie ma problemu.Wypróbuj także forum dyskusyjne tf
Przekonwertowałem dane na keras ... potrzeba było około 300 iteracji, aby strata spadła poniżej 5 :)
Świetny !!!To więcej niż 3-krotna poprawa.Jeśli jest to dokładnie ta sama architektura sieciowa z takimi samymi stratami, aktywacjami, szybkością uczenia się itp., To musisz mieć błąd w kodzie C ++.Z drugiej strony, ten rodzaj pokazuje, dlaczego prawdopodobnie nie jest dobrym pomysłem zrobienie własnego (chociaż jestem pewien, że jest to wspaniałe doświadczenie edukacyjne)
cóż, nie jest jasne, jaki jest tego powód.mam na myśli keras itp. używają wielu sztuczek, aby przyspieszyć trening.po prostu fakt, że nie muszę podawać wskaźnika uczenia się, wiele mówi ...
mam po prostu nadzieję, że kiedy przeniosę ciężary, wynik będzie taki sam :)
Zakładam, że próbowałeś zwiększyć współczynnik uczenia się w swoim kodzie?
Tak.błąd zaczął wzrastać.zarówno dla sgd, jak i adam
player1
2020-07-29 23:18:52 UTC
view on stackexchange narkive permalink

Możesz także wypróbować przyjazną dla procesora alternatywę NNUE.Obecnie jest on opracowywany do gry w szachy przez zespół Stockfisha i wydaje się dawać dobre wyniki.Jest łatwy w obsłudze i szkoleniu sieci i powinien być dużo łatwiejszy niż trudny sposób.Pracowałem w zespole Stockfish i myślę, że mógłbym ci również pomóc z twoim silnikiem, jeśli chcesz (pracuję również nad własnym silnikiem szachowym).Pozdrawiam i powodzenia!

właśnie tego próbujemy :)
Byłoby wspaniale, gdybyś mógł nam pomóc!Jeśli chcesz, możesz dodać mnie na discordzie: Luecx # 0540
W jakim języku używasz silnika?
C ++.Dodałem również obsługę AVX
Ok dobrze.Czy obsługuje polecenia UCI?
tak oczywiście :)


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 4.0, w ramach której jest rozpowszechniana.
Loading...