CHESS CONFIGURATION
FEN Generator for Chess Configuration Chalenge
A solution code for Chess Configuration Chalenge
This trained model may be used for solution others puzzles of the chelenge.😉
Chess FEN Generator¶
Original: \ https://www.kaggle.com/koryakinp/chess-fen-generator
Download Data¶
In [1]:
!pip install --upgrade fastai git+https://gitlab.aicrowd.com/yoogottamk/aicrowd-cli.git >/dev/null
%load_ext aicrowd.magic
In [2]:
API_KEY = '' #Please enter your API Key [https://www.aicrowd.com/participants/me]
%aicrowd login --api-key $API_KEY
In [3]:
%aicrowd dataset download --challenge chess-configuration -j 3
In [4]:
!rm -rf data
!mkdir data
!unzip -q train.zip -d data/
!unzip -q val.zip -d data/
!unzip -q test.zip -d data/
!mv train.csv data/train.csv
!mv val.csv data/val.csv
!mv sample_submission.csv data/sample_submission.csv
Import packages¶
In [5]:
import numpy as np
import pandas as pd
import os
import glob
import re
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from random import shuffle
from skimage.util.shape import view_as_blocks
from skimage import io, transform
from sklearn.model_selection import train_test_split
from keras.models import Sequential, load_model
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D
import warnings
warnings.filterwarnings('ignore')
Data Import¶
In [6]:
#DATADIR = 'D:/Datasets/CHESS/CONFIGURATION/'
DATADIR = './data/'
In [7]:
train_df = pd.read_csv(DATADIR+"train.csv")
val_df = pd.read_csv(DATADIR+"val.csv")
test_df = pd.read_csv(DATADIR+"sample_submission.csv")
In [8]:
train_size = 10000
val_size = 4000
test_size = 10000
train = [f'{DATADIR}train/{i}.jpg' for i in train_df.ImageID]
val = [f'{DATADIR}val/{i}.jpg' for i in val_df.ImageID]
test = [f'{DATADIR}test/{i}.jpg' for i in test_df.ImageID]
train = train[:train_size]
val = val[:val_size]
In [9]:
mpimg.imread(test[0]).shape
Out[9]:
Function to extract FEN¶
In [10]:
def fen_from_filename(filename):
base = os.path.basename(filename)
image_id = int(os.path.splitext(base)[0])
#print(image_id)
fen = train_df.iloc[image_id].label
return fen
Examples:¶
In [11]:
print(fen_from_filename(train[0]))
print(fen_from_filename(train[1]))
print(fen_from_filename(train[2]))
Plotting samples¶
In [12]:
f, axarr = plt.subplots(1,3, figsize=(120, 120))
for i in range(0,3):
axarr[i].set_title(fen_from_filename(train[i]), fontsize=70, pad=30)
axarr[i].imshow(mpimg.imread(train[i]))
axarr[i].axis('off')
Functions to convert FEN to one-hot encoded vectors and vice-versa¶
In [13]:
piece_symbols = 'prbnkqPRBNKQ'
def onehot_from_fen(fen):
eye = np.eye(13)
output = np.empty((0, 13))
fen = re.sub('[/]', '', fen)
for char in fen:
if(char in '12345678'):
output = np.append(
output, np.tile(eye[12], (int(char), 1)), axis=0)
else:
idx = piece_symbols.index(char)
output = np.append(output, eye[idx].reshape((1, 13)), axis=0)
return output
def fen_from_onehot(one_hot):
output = ''
for j in range(8):
for i in range(8):
if(one_hot[j][i] == 12):
output += ' '
else:
output += piece_symbols[one_hot[j][i]]
if(j != 7):
output += '/'
for i in range(8, 0, -1):
output = output.replace(' ' * i, str(i))
return output
Function to proccess an image:¶
- downsample an image to 200 by 200 pixel
- split an image of the chess board to 64 images of individual squares
- drop redundant dimensions, reshape
In [14]:
DOWNSAMPLE_SIZE = 200 # must be % 8 = 0 and < img.shape
SQUARE_SiZE = int(DOWNSAMPLE_SIZE/8)
def process_image(img, size = DOWNSAMPLE_SIZE):
downsample_size = size
square_size = int(downsample_size/8)
img_read = io.imread(img)
img_read = transform.resize(
img_read, (downsample_size, downsample_size), mode='constant')
tiles = view_as_blocks(img_read, block_shape=(square_size, square_size, 3))
tiles = tiles.squeeze(axis=2)
return tiles.reshape(64, square_size, square_size, 3)
Functions for sampling batches for training and evaluation:¶
In [15]:
def train_gen(features, labels, batch_size):
for i, img in enumerate(features):
y = onehot_from_fen(fen_from_filename(img))
x = process_image(img)
yield x, y
def pred_gen(features, batch_size):
for i, img in enumerate(features):
yield process_image(img)
Define a model:¶
In [16]:
# CNN model
model = Sequential()
model.add(Convolution2D(32, (3, 3), input_shape=(SQUARE_SiZE, SQUARE_SiZE, 3)))
model.add(Activation('relu'))
model.add(Convolution2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(Convolution2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.4))
model.add(Dense(13))
model.add(Activation('softmax'))
model.compile(
loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
Train the model:¶
In [17]:
model.fit_generator(train_gen(train, None, 64), steps_per_epoch=train_size)
Out[17]:
Testing the model:¶
In [18]:
res = (
model.predict_generator(pred_gen(val, 64), steps=val_size)
.argmax(axis=1)
.reshape(-1, 8, 8)
)
Calculating an accuracy of the model:¶
In [19]:
def fen_from_filename_val(filename):
base = os.path.basename(filename)
image_id = int(os.path.splitext(base)[0])
#print(image_id)
fen = val_df.iloc[image_id].label
return fen
In [20]:
pred_fens = np.array([fen_from_onehot(one_hot) for one_hot in res])
val_fens = np.array([fen_from_filename_val(fn) for fn in val])
final_accuracy = (pred_fens == val_fens).astype(float).mean()
print("Final Accuracy: {:1.5f}%".format(final_accuracy))
Sample images and display predicted FEN¶
In [21]:
def display_with_predicted_fen(image):
pred = model.predict(process_image(image)).argmax(axis=1).reshape(-1, 8, 8)
fen = fen_from_onehot(pred[0])
imgplot = plt.imshow(mpimg.imread(image))
plt.axis('off')
plt.title(fen)
plt.show()
In [22]:
display_with_predicted_fen(test[0])
display_with_predicted_fen(test[1])
display_with_predicted_fen(test[2])
Prediction and submite¶
In [23]:
preds = (
model.predict_generator(pred_gen(test, 64), steps=test_size)
.argmax(axis=1)
.reshape(-1, 8, 8)
)
In [24]:
test_df['label'] = [fen_from_onehot(i) for i in preds ]
In [25]:
test_df
Out[25]:
In [26]:
test_df.to_csv("FENGenerator_submission.csv", index=False)
In [27]:
try:
from google.colab import files
files.download('FENGenerator_submission.csv')
except:
print("Option Only avilable in Google Colab")
In [28]:
from google.colab import drive
drive.mount('/content/drive')
In [29]:
model.save('/content/drive/MyDrive/Datasets/CHESS/FENGenerator_model')
Load Model¶
In [30]:
new_model = load_model('/content/drive/MyDrive/Datasets/CHESS/FENGenerator_model')
In [31]:
def display_with_predicted_fen(image):
pred = new_model.predict(process_image(image)).argmax(axis=1).reshape(-1, 8, 8)
fen = fen_from_onehot(pred[0])
imgplot = plt.imshow(mpimg.imread(image))
plt.axis('off')
plt.title(fen)
plt.show()
In [32]:
display_with_predicted_fen(test[0])
display_with_predicted_fen(test[1])
display_with_predicted_fen(test[2])
Content
Comments
You must login before you can post a comment.