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
Zmiana dla każdej iteracji wygląda następująco:
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.