I'm doing some research on neural network too. For now I'm more interested in learning and hopefully can add some elos to my engine. Would be a nice side effect <E>:)
Just wanted to share what I'm doing. Seems other developers are doing something similar and may share their experiences.
- I'm using a simple network now, 768x192x1 (64 x 6 piece type x 2). I looked at SF NNUE, and plan to switch to something similar, depending on the results. I will have to create the code in tucano to forward propagate, so I decided to start with a smaller nn. I saw Halogen engine is using a small nn too, but seems SF is the desired model?
- Using tensorflow/keras to train (see code below). To test the process I just started with 10m positions, but next step I plan to generate 100m. Also if I have the motivation I may write my own training code.
- To label the positions I'm using a 10 depth tucano search. Was wondering if it is enough to just use the eval value of self-play games at 1+0.05sec. Searches are at least depth 9, and we just need to extract the position + eval from the pgn and no need to search again at depth 10?
- Another idea I would like to test, is to generate from each position all available moves and included also this new positions and evals. Of course some moves will make sense, but others will be bad, I wonder if this will augment the data? In this case have to extract the positions and do the 10 depth search for each move.
So far I'm building my process, and learning about NN, it is good when you have a motivation.
I think in terms of research I wonder what terms or combination makes the NN eval better than hce, probably we will be able to see by comparing positions where NN eval is good, and hce is bad.
Alcides.
Code: Select all
import pandas as pd
import tensorflow as tf
print("create train dataset...")
train_dataset = tf.data.experimental.make_csv_dataset(file_pattern="data.10m.csv",batch_size=10000,label_name="Result",num_epochs=1)
print("create validation dataset...")
valid_dataset = tf.data.experimental.make_csv_dataset(file_pattern="data.1m.csv",batch_size=10000,label_name="Result",num_epochs=1)
features, labels = next(iter(train_dataset))
def pack_features_vector(features, labels):
features = tf.stack(list(features.values()), axis=1)
return features, labels
print("pack features...")
train_dataset = train_dataset.map(pack_features_vector)
valid_dataset = valid_dataset.map(pack_features_vector)
print("create save model callback...")
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath="pesos.h5", save_weights_only=True, verbose=1)
print('building the model...')
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(768,)))
model.add(tf.keras.layers.Dense(192, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(1))
adam = tf.keras.optimizers.Adam(learning_rate=1)
print(model.summary())
model.compile(optimizer=adam, loss='mean_squared_error', metrics=['accuracy'])
print('model.fit...')
model.fit(train_dataset, use_multiprocessing=True, workers=8, epochs=10, callbacks=[cp_callback], validation_data=valid_dataset)