Skip to content

Commit

Permalink
Refactor autoencoder model (#8)
Browse files Browse the repository at this point in the history
reflects API changes made in chess-position parent repo
  • Loading branch information
patrickfrank1 authored Feb 5, 2022
1 parent 74b7636 commit 1251c12
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 162 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
cogram_test.ipynb

# Data and models
data/*
data/pgn/*
!data/pgn/README.md
!data/pgn/lichess_db_standard_rated_2013-01-truncated.pgn
Expand Down
31 changes: 26 additions & 5 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
preprocess:
pgn_path: "./data/pgn/lichess_db_standard_rated_2013-01.pgn"
save_path: "./data/tensors/lichess_db_standard_rated_2013-01_v2.h5"
game_filter: "none"
game_processor: "positions_to_tensor"
pgn_path: ./data/pgn/lichess_db_standard_rated_2013-01.pgn
save_path: ./data/tensors/lichess_db_standard_rated_2013-01_v2.h5
game_filter: none
game_processor: positions_to_tensor
chunk_size: 100000
number_games: 100
number_games: 100
train:
data:
format: tensor
train_dir: ./data/tensors/train
train_batch_size: 256
test_dir: ./data/tensors/test
test_batch_size: 256
model:
loss: binary_crossentropy
train_steps_per_epoch: 20
test_steps_per_epoch: 5
tf_callbacks: [checkpoints]
save_dir: ./models
evaluate:
data:
test_dir: ./data/tensors/test
test_batch_size: 64
model_dir: ./models
eval:
number_examples: 10
result_dir: ./results
122 changes: 67 additions & 55 deletions evaluate_model.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import chess
import yaml
import json
from pathlib import Path
Expand All @@ -6,75 +7,86 @@
import tensorflow as tf
from tensorflow import keras

from chesspos.preprocessing import SampleGenerator, bitboard_to_board
from chesspos.models import DenseAutoencoder, CnnAutoencoder
from chesspos.preprocessing import SampleGenerator, tensor_to_board, board_to_tensor
from chesspos.models import ResnetAutoencoder

evaluate_data_params = yaml.safe_load(open(Path(__file__).with_name('params.yaml')))['evaluate']['data']
evaluate_eval_params = yaml.safe_load(open(Path(__file__).with_name('params.yaml')))['evaluate']['eval']
evaluate_data_params = yaml.safe_load(open(Path(__file__).with_name('params_tensor.yaml')))['evaluate']['data']
evaluate_eval_params = yaml.safe_load(open(Path(__file__).with_name('params_tensor.yaml')))['evaluate']['eval']
model_params = yaml.safe_load(open(Path(__file__).with_name('params_tensor.yaml')))['train']['model']

sample_preprocessor = lambda samples: tuple([samples.reshape((*samples.shape, 1)), samples.reshape((*samples.shape, 1))])

test_generator = SampleGenerator(
sample_dir = evaluate_data_params['test_dir'],
batch_size = evaluate_data_params['test_batch_size']
sample_dir = evaluate_data_params['test_dir'],
sample_preprocessor = sample_preprocessor,
batch_size = evaluate_data_params['test_batch_size'],
sample_type = np.float32,
)
test_generator.set_subsampling_functions(['singlets'])
test_generator.construct_generator()

autoencoder = CnnAutoencoder(
input_size = None,
embedding_size = None,
hidden_layers = None,
loss = None,
train_generator = None,
test_generator = test_generator,
save_dir = evaluate_data_params['model_dir'],
train_steps_per_epoch = None,
test_steps_per_epoch = None,
tf_callbacks = None
autoencoder = ResnetAutoencoder(
train_generator=test_generator,
test_generator=test_generator,
train_steps_per_epoch=model_params['train_steps_per_epoch'],
test_steps_per_epoch=model_params['test_steps_per_epoch'],
save_dir=model_params['save_dir'],
output_to_board = tensor_to_board,
board_to_input = board_to_tensor,
loss = model_params['loss'],
tf_callbacks = model_params['tf_callbacks'] + [
keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0.03, patience=5, verbose=1, mode='min', restore_best_weights=True),
#keras.callbacks.TensorBoard(log_dir=model_params['save_dir'], histogram_freq=1, write_images=True, embeddings_freq=1)
]
)

autoencoder.load()
examples = evaluate_eval_params['number_examples']
examples_out = ""

best_samples = autoencoder.get_best_samples(examples, 10*examples)
for i in range(examples):
best_sample_bitboard = best_samples[i]['position'].reshape((773, -1))
best_sample_position = bitboard_to_board(best_sample_bitboard)
examples_out += str(best_samples[i]['loss']) + '\n\n'
examples_out += autoencoder.compare_sample_to_prediction(best_sample_bitboard)
start_board = chess.Board()
prediction = autoencoder.predict_from_board([start_board])
prediction = prediction[0,:,:,:,0]
prediction = autoencoder.binarize_array(prediction)
print(prediction[:,:,0])
print(prediction[:,:,1])
print(tensor_to_board(prediction).__str__())

# best_samples = autoencoder.get_best_samples(examples)
# for i in range(examples):
# best_sample_input = best_samples[i]['input']
# examples_out += str(best_samples[i]['loss']) + '\n\n'
# examples_out += autoencoder.compare_input_to_prediction(best_sample_input)

worst_samples = autoencoder.get_worst_samples(examples, 10)
for i in range(examples):
worst_sample_bitboard = worst_samples[i]['position'].reshape((773, -1))
worst_sample_position = bitboard_to_board(worst_sample_bitboard)
examples_out += str(worst_samples[i]['loss']) + '\n'
examples_out += autoencoder.compare_sample_to_prediction(worst_sample_bitboard)
# worst_samples = autoencoder.get_worst_samples(examples)
# for i in range(examples):
# worst_sample_input = worst_samples[i]['input']
# examples_out += str(worst_samples[i]['loss']) + '\n'
# examples_out += autoencoder.compare_input_to_prediction(worst_sample_input)

print(examples_out)
#print(examples_out)

with open(evaluate_eval_params['result_dir']+'/examples.out', 'w') as file:
file.write(examples_out)
# with open(evaluate_eval_params['result_dir']+'/examples.out', 'w') as file:
# file.write(examples_out)


with open(evaluate_eval_params['result_dir']+'/scores.json', 'w') as file:
json.dump(
{
'train_loss': autoencoder.train_history['loss'][-1],
'test_loss': autoencoder.train_history['val_loss'][-1]
},
file,
indent=2
)
# with open(evaluate_eval_params['result_dir']+'/scores.json', 'w') as file:
# json.dump(
# {
# 'train_loss': autoencoder.train_history['loss'][-1],
# 'test_loss': autoencoder.train_history['val_loss'][-1]
# },
# file,
# indent=2
# )

with open(evaluate_eval_params['result_dir']+'/test_scores.json', 'w') as file:
json.dump(
{
'val_loss': [{
'epoch': i,
'train_loss': autoencoder.train_history['loss'][i],
'val_loss': autoencoder.train_history['val_loss'][i]
} for i in range(len(autoencoder.train_history['val_loss']))]
},
file,
indent=2
)
# with open(evaluate_eval_params['result_dir']+'/test_scores.json', 'w') as file:
# json.dump(
# {
# 'val_loss': [{
# 'epoch': i,
# 'train_loss': autoencoder.train_history['loss'][i],
# 'val_loss': autoencoder.train_history['val_loss'][i]
# } for i in range(len(autoencoder.train_history['val_loss']))]
# },
# file,
# indent=2
# )
19 changes: 15 additions & 4 deletions extract_positions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from typing import Callable
import h5py
import yaml
import logging
import argparse
from pathlib import Path
from chesspos.preprocessing import (
PgnExtractor, get_game_processor, get_game_filter
)
import chess

from chesspos.preprocessing import *

if __name__ == "__main__":

Expand All @@ -16,11 +17,21 @@
args = parser.parse_args()
params = yaml.safe_load(open(Path(__file__).with_name(args.config)))['preprocess']

game_filter = None
if params['game_filter'] == 'custom':
def custom_filter(header: chess.pgn.Headers):
return filter_by_elo(header, white_elo_range=[2600,4000], black_elo_range=[2600,4000]) and \
filter_by_time_control(header, time_range=[5,60])
game_filter = custom_filter
else:
game_filter = get_game_filter(params['game_filter'])


position_extractor = PgnExtractor(
pgn_path=params['pgn_path'],
save_path=params['save_path'],
game_processor=get_game_processor(params['game_processor']),
game_filter=get_game_filter(params['game_filter']),
game_filter=game_filter,
chunk_size=params['chunk_size'],
log_level=logging.INFO
)
Expand Down
27 changes: 0 additions & 27 deletions params.yaml

This file was deleted.

27 changes: 0 additions & 27 deletions params_tensor.yaml

This file was deleted.

Loading

0 comments on commit 1251c12

Please sign in to comment.