GithubHelp home page GithubHelp logo

elucidation / tensorflow_chessbot Goto Github PK

View Code? Open in Web Editor NEW
497.0 26.0 90.0 59.68 MB

Predict chessboard FEN layouts from images using TensorFlow

Home Page: http://www.tetralark.com/tensorflow_chessbot/

License: MIT License

Jupyter Notebook 100.00%
tensorflow tensorflow-examples tensorflow-tutorials chess chessboard chessboard-detection chessboard-recognition

tensorflow_chessbot's Introduction

TensorFlow Chessbot - /u/ChessFenBot [◕ _ ◕]* I make FENs

CLI and Bot code lives on the chessfenbot branch

Live demo here using TensorflowJs

TL;DR:

Turn http://i.imgur.com/HnWYt8A.png1nkr4/1p3q1p/pP4pn/P1r5/3N1p2/2b2B1P/5PPB/2RQ1RK1

Prediction

A TensorFlow Convolutional Neural Network algorithm trained on 32x32 grayscale chess tiles predicts chessboards layouts from online chessboard screenshots.

  • 5x5x32 Input Convolution layer
  • 5x5x64 Convolution layer
  • 8x8x1024 Dense Fully Connected layer
  • 1024x13 Dropout + Softmax Readout layer

Yes, using a CNN is kinda overkill, but it is exciting.

Running Tensorflow_Chessbot on images locally and via URLs

On a linux machine which has Tensorflow and SciPy installed

Download the chessfenbot branch somewhere : tensorflow_chessbot/chessfenbot

Alternatively clone the chessfenbot branch

Now, to run pass the following arguments to tensorflow_chessbot.py

$ ./tensorflow_chessbot.py -h
usage: tensorflow_chessbot.py [-h] [--url URL] [--filepath FILEPATH]

Predict a chessboard FEN from supplied local image link or URL

optional arguments:
  -h, --help           show this help message and exit
  --url URL            URL of image (ex. http://imgur.com/u4zF5Hj.png)
  --filepath FILEPATH  filepath to image (ex. u4zF5Hj.png)

By default, it will try and load the URL http://imgur.com/u4zF5Hj.png and make a prediction in it, otherwise, you could pass a local file like so (for example with an image file u4zF5Hj.png located in the same directory):

./tensorflow_chessbot.py --filepath u4zF5Hj.png

Which should output something like:

./tensorflow_chessbot.py --filepath ./u4zF5Hj.png
Setting up CNN TensorFlow graph...
I tensorflow/core/common_runtime/local_device.cc:40] Local device intra op parallelism threads: 2
I tensorflow/core/common_runtime/direct_session.cc:58] Direct session inter op parallelism threads: 2
Loading model 'saved_models/model_10000.ckpt'
Model restored.
Certainty range [0.999545 - 1], Avg: 0.999977, Overall: 0.998546
Predicted FEN: 11111111/11111p11/11111k1P/11p1111P/1p1p1111/11111111/111K1111/11111111
Certainty: 99.9%
Done

Similarly, a URL can be tested by calling with a URL:

$ ./tensorflow_chessbot.py --url http://imgur.com/u4zF5Hj.png

Reddit Bot Deprecated

Code lives on the chessfenbot branch

/u/ChessFenBot used to (~2015-2016) automatically reply to reddit /r/chess new topic image posts that contain detectable online chessboard screenshots. A screenshot either ends in .png, .jpg, .gif, or is an imgur link.

It replies with a lichess analysis link for that layout and a predicted FEN.

predictor = ChessboardPredictor()
fen, certainty = predictor.makePrediction('http://imgur.com/u4zF5Hj.png')
print "Predicted FEN: %s" % fen
print "Certainty: %.1f%%" % (certainty*100)
Certainty range [0.999545 - 1], Avg: 0.999977, Overall: 0.998546
Predicted FEN: 8/5p2/5k1P/2p4P/1p1p4/8/3K4/8
Certainty: 99.9%
Done
[Finished in 1.8s]

ChessFenBot automatically replied to this reddit post, it processed the screenshot link url and responded with:

ChessFenBot [◕ _ ◕]* I make FENs


I attempted to generate a chessboard layout from the posted image, with an overall certainty of 99.9916%.

FEN: 1nkr4/1p3q1p/pP4pn/P1r5/3N1p2/2b2B1P/5PPB/2RQ1RK1

Here is a link to a Lichess Analysis - White to play


Yes I am a machine learning bot | How I work | Reply with a corrected FEN or Editor link) to add to my next training dataset

Workflow

There are three ipython notebooks which show the workflow from turning a screenshot of a chessboard into a set of 32x32 grayscale tiles, to generating those tiles for training and testing, and then the actual training and learning of the neural network from those trials using TensorFlow.

  1. tensorflow_compvision.ipynb - Computer Vision
  2. tensorflow_generate_training_data.ipynb - Generating a dataset from set of screenshots of chessboards in known configurations
  3. tensorflow_learn.ipynb - TensorFlow Neural Network Training & Prediction Basic Regression classifier, works for more common lichess.org and chess.com screenshots
  4. tensorflow_learn_cnn.ipynb - TensorFlow Convolutional Neural Network Training & Prediction tested with ~73% success rate on 71 chess subreddit posts

tensorflow_compvision.ipynb - 1. Computer Vision

Here is a screenshot with the detected lines of the chessboard overlaid, showing where we'll cut the image into tiles.

overlay lines


tensorflow_generate_training_data.ipynb - 2. Generating a dataset

Lichess.org provides a URL interface with a FEN string that loads a webpage with that board arrayed. A nice repo called pythonwebkit2png provides a way to render webpages programmatically, allowing us to generate several (80 in thise) random FEN strings, load the URL and take a screenshot all automatically.

random fen

Here is 5 example tiles and their associated label, a 13 length one-hot vector corresponding to 6 white pieces, 6 black pieces, and 1 empty space.

dataset example


tensorflow_learn.ipynb - 3. TensorFlow Neural Network Training & Prediction

We train the neural network on generated data from 80 lichess.org screenshots, which is 5120 tiles. We test it with 5 screenshots (320 tiles) as a quick sanity check. Here is a visualization of the weights for the white King, Queen and Rook.

Some weights

Finally we can make predictions on images passed by URL, the ones from lichess and visually similar boards work well, the ones that are too different from what we trained for don't work, suggesting that getting more data is in order. Here is a prediction on the image for this reddit post

Prediction


tensorflow_learn_cnn.ipynb - TensorFlow Convolutional Neural Network Training & Prediction

Built a slightly larger dataset of ~150 screenshots which is around 9600 tiles which includes randomized FEN diagrams from lichess.org, chess.com, and 2 FEN generated diagram sites.

Tested with ~73% success rate on 71 chess subreddit posts, good enough to make a first draft Reddit bot.


Ideation

Reddit post has an image link (perhaps as well as a statement "white/black to play").

Bot takes the image, uses some CV to find a chessboard on it, splits up into a set of images of squares. These are the inputs to the tensorflow CNN which will return probability of which piece is on it (or empty)

Dataset will include chessboard squares from chess.com, lichess Different styles of each, all the pieces

Generate synthetic data via added noise:

  • change in coloration
  • highlighting
  • occlusion from lines etc.

Take most probable set from TF response, use that to generate a FEN of the board, and bot comments on thread with FEN and link to lichess analysis

tensorflow_chessbot's People

Contributors

elucidation avatar ornicar avatar therealmitchconnors avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tensorflow_chessbot's Issues

Flip board if it's black to play

Realized the posts with black to play have images from black side viewpoint, so the board is transposed. Need to reverse FEN order before posting.

This comment refers to this issue also

Failure to detect chessboard in images that are chessboards

https://i.redd.it/yrl4gdw8iml31.jpg
https://i.redd.it/n66usnoq38m31.png
https://i.redd.it/nq65jjiohfm31.png

Why can't the bot detect a chessboard in the images above?

import subprocess, os
r = subprocess.check_output("cd C:\Users\Raymond\Desktop\Chess Bot\tensorflow_chessbot-chessfenbot && tensorflow_chessbot.py --url https://i.redd.it/yrl4gdw8iml31.jpg", shell=True)

the code above crashes and the traceback states that there is "no chessboard detected"

fail to load imgur direct links

Currently a direct imgur link fails since we check for imgur and assume it's a gallery, and then it tries to get the metadata. If this fails it should try loading the url directly.

Handle castling

https://www.reddit.com/r/chess/comments/46rf2l/nice_little_problem_white_to_move_what_is_the/d079vzs for example,

Lichess analysis has Black erroneously trying to castle queenside if the FEN doesn't indicate lack of castling ability, turning a 2-move mate into a 7-move mate.

One can check for castling ability by whether the kings have moved from their starting positions as a basic check.

Rules for Castling availability: If neither side can castle, this is "-". Otherwise, this has one or more letters: "K" (White can castle kingside), "Q" (White can castle queenside), "k" (Black can castle kingside), and/or "q" (Black can castle queenside).

We get something like KQkq for starting position, both sides can castle in both directions, or - if neither can

CV detection handle high-freq gradients (like hatch), pass full res to model

The chessboard detection routine looks for certain X and Y gradient patterns, and the hatched pattern often disrupts this at full resolution, but those gradients go away when blurred. Example image from Tomas original issue #41

image

Could be tackled by modifying the chessboard detection routine, either naively by blurring/reducing high frequency gradients like the hatch pattern, or something more sophisticated (probably unnecessary). And then once the board and tiles have been detected, use pass the the original image resolution tiles to the ML model.

secondary note is that the model is only trained on lichess/chess type images, so for these types of images the model will perform poorly. At some point consider retraining/fine tuning the model. Alternatively a simpler approach is since this style is common/uniform just do some simple CV-based approach and drop the ML

On Tue, Jul 25, 2023 at 9:30 AM Tomas Tillmann @.***>
wrote:

Yes, that seems to be the reason. Thanks.

Do you think it could be possible to do something about it though? I
experimted a bit, and if I blur the image, making the quality of the image
lower, it works correctly. But that feels like a hack ..., and it also
makes the work for the model harder, since the pieces are not as sharp as
they could be. Potentially leading to wrong piece prediction.

I think it would be very nice for the chessboard recognizer to understand
even if the black tiles are hatched and not fully black colored, where the
grid lines are. Do you think it could be done? Perhaps by feeding it boards
with hatched black tiles?

I feel like majority of chess pdf books are having black tiles hatched, so
it could be a really useful improvement.
To name some: The woodpecker method, Encyclopedia of chess tactics, ...


Reply to this email directly, view it on GitHub
#41 (comment),
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AADKF3ILYYFGFRWNGNJHIMDXR7YBFANCNFSM6AAAAAA2T2LIWQ
.
You are receiving this because you commented.Message ID:
@.***>

Originally posted by @Elucidation in #41 (comment)

Use characters to show chessboard instead of fen-to-image.com

Found this on the Sunfish readme

  8 ♖ ♘ ♗ ♕ ♔ ♗ · ♖
  7 ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
  6 · · · · · ♘ · ·
  5 · · · · · · · ·
  4 · · · · ♟ · · ·
  3 · · · · · · · ·
  2 ♟ ♟ ♟ ♟ · ♟ ♟ ♟
  1 ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
    a b c d e f g h

Could potentially draw the notation out in-comment instead of as an image, not sure if encoding is visible to all/majority of /r/chess users. Perhaps also link fen-to-image as a fallback?

Could also do a table

a b c
.

...

Auto-add comment corrections to dataset

Instead of manually adding images with the corrected fen to datasets, write a little praw script that scrapes replies to chessfenbot with corrected fens, for now have a human sanity check before appending to dataset.

Dataset will be generated by taking image files with the fen as the name and splitting up into tiles, then retrain model

Decide on whether/how to reply to comments

Brought to attention by one user replying to bot with an image expecting it to respond.

Could potentially check comments that call out to /u/ChessFenBot with images in them, and reply to the comment.

This adds extra checks, potential to be abused, and not sure how many users actually want that.

Check text posts with image links within text

Several posts are text posts without a submission url but contain an image url in the text (or multiple), potentially check this as well. Perhaps first successful image in text.

Include " w - -" and " b - -" in FEN notations

https://www.reddit.com/r/chess/comments/4b3h8s/that_felt_good/d15u5cySuggestion: one annoyance with these postings is that some chess interfaces reject the FEN because it does not include the color to move, castling, and en passant portions.
I suggest that the post include two copies of the FEN, one with " w - -" appended, and one with " b - -" appended. That will at least let the user pick one that has the right side to move and will be accepted by their GUI. They might still need to tweak it them for castling and en passant, but at least they can do that in their GUI once the basic position is entered.
You might even guess at the castling. Assume that if the king is on the original square castling is still allowed with any rook on its original square. Games where a king or rook move and then return to their original square are rare enough that this will be right most of the time. (Related issue #10)
That would match the convention generally followed in chess puzzles, which is that unless otherwise stated assume that kings and rooks on their original squares have not moved.

Tile Dataset

where can I find the tile dataset with pieces against different board backgrounds

Improve prediction of side to play

Currently side to play prediction is default white, unless the words 'black' is in the title (some variations on that have been tested).

If a title doesn't have that, then white to play is default, but there are images where the board is flipped and it's black to play. Worse still, there are images where it's white to play and the board is flipped to be from black viewpoint, or vice versa.

Currently the responses show a FEN with what chessfenbot thinks is most likely to play, and then a reversed board position below in case it was wrong. This adds extra clutter/confusion to every comment, but not having it means several comments will not have the correct FEN.

Perhaps a simple check of location of black pieces vs white on which side, to determine board orientation, and side to play (with words in title overloading).

Docker image fails to run on Mac

I've installed docker and followed the instruction to run chessfenbot in it:
docker run -dt --rm --name cfb -v auth_config.py:/tcb/auth_config.py elucidation/tensorflow_chessbot e1754c68589d2a796c6ddcd0c6655de8a9dda98afe28a39cbed5e120360d5646

But all I see is 'currently in /tcb' message, and then it stops.
I've tried :latest and v1.1.

Macos Sierra 10.12.

Memory leak

There's a memory leak in this library. If you loop getPrediction 100 times, you'll see the execution time gets slower and slower each time.

I narrowed it down to getTiles() function

Note orientation based on pieces in starting positions

Majority of screenshots are from normal chess or similar variants, so a reasonable way to check board orientation is for checking configuration of predicted pieces vs starting positions. If above a threshold, then switch orientation to that one.

Side to play defaults to orientation, replaced by 'white to' or 'black to' from title

This failure case is one example https://www.reddit.com/r/chess/comments/4bty2x/is_there_a_name_for_the_position_whites_pawns_are/d1cdf97?context=3

Model piece counts as training data attributes

Arguably given enough nodes and training data a neural network would eventually evolve the concept of counting; perhaps until then it makes sense for training data to include piece counts as attributes (e.g. 1 white king, 1 black king, etc.).

About project status

Hi, I was trying to do few test on the project but seems to be not working (at least for me) with the current version. I have found mixed python2 and 3 code, and another kind of issues on both branches.
So is there any stable version to test the project? Thanks.

Load i.redd.it image urls

Currently the bot is not able to load the images from i.redd.it links because of HTML Error 403: Forbidden, which is due to Reddit blocking bot bulk image retrieval.

def loadImageFromURL(img_url):
  """Load PIL image from URL, keep as color"""
   return PIL.Image.open(StringIO(urllib.urlopen(img_url).read()))

We can get around this using urllib2 Requests with a user agent in the header, as described on http://stackoverflow.com/questions/3336549/pythons-urllib2-why-do-i-get-error-403-when-i-urlopen-a-wikipedia-page

Chess board to FEN working correctly on DEMO, but not locally

Hi,

not sure what I'm doing wrong, for this image:
whole-board, the website demo returnes correct fen string, but local installation doesnt' work.

Interestingly, the example --url image works locally just fine.

pip list output:

absl-py              1.4.0
astor                0.8.1
beautifulsoup4       4.12.2
certifi              2023.7.22
charset-normalizer   3.2.0
gast                 0.2.2
google-pasta         0.2.0
grpcio               1.56.2
h5py                 2.10.0
idna                 3.4
importlib-metadata   6.7.0
Keras-Applications   1.0.8
Keras-Preprocessing  1.1.2
lxml                 4.9.3
Markdown             3.4.3
MarkupSafe           2.1.3
numpy                1.18.5
opt-einsum           3.3.0
Pillow               5.4.1
pip                  10.0.1
protobuf             3.20.3
requests             2.31.0
setuptools           68.0.0
six                  1.16.0
soupsieve            2.4.1
tensorboard          1.15.0
tensorflow           1.15.5
tensorflow-estimator 1.15.1
termcolor            2.3.0
typing-extensions    4.7.1
urllib3              1.26.6
Werkzeug             2.2.3
wheel                0.41.0
wrapt                1.15.0
zipp                 3.15.0

python --version output:

Python 3.7.0

Executing by: python .\tensorflow_chessbot.py --filepath "C:\Users\tomas\Pictures\Screenshots\whole-board.png"
Output:

--- Prediction on file C:\Users\tomas\Pictures\Screenshots\whole-board.png ---
         Loading model 'saved_models/frozen_graph.pb'
         Model restored.
Closing session.
Per-tile certainty:
[[0.982 1.    0.977 1.    0.749 1.    0.874 1.   ]
 [1.    1.    1.    1.    1.    1.    1.    1.   ]
 [1.    0.999 1.    0.998 1.    0.999 1.    1.   ]
 [1.    1.    0.817 1.    0.987 1.    0.999 1.   ]
 [0.999 1.    0.998 1.    0.641 1.    0.999 1.   ]
 [1.    0.989 0.82  0.996 0.921 0.802 0.435 0.995]
 [0.949 0.881 1.    1.    1.    0.998 0.966 0.999]
 [0.988 1.    0.584 1.    0.747 1.    0.979 1.   ]]
Certainty range [0.435048 - 1], Avg: 0.954174
---
Predicted FEN:
8/8/2P1P3/2N1N3/2r1bb2/8/PP4R1/2K3p1 w - - 0 1
Final Certainty: 43.5%

Thanks.

Improvement

Could be upgraded to read all images in a PDF and generate FENs. Could then replace the subscription based chessvision.ai

Relatively good quality image fails in a bad way

I admire your project very much. I created a tool with which you can drag-drop upload an image and recognize the FEN on it using your neural network ( https://github.com/pythonflaskserverapps/fenbot ).

I opened a thread about your project and later my tool on lichess: https://lichess.org/forum/general-chess-discussion/bot-that-recognizes-fen-on-arbitrary-screenshots-that-contain-a-chess-board.

In the thread a user posted this image which is relatively good quality but failed badly:

https://i.imgur.com/8yVD3g6.png

prediction: 1Q2Q3/8/p7/RPqq4/8/8/8/8 ( 45% certainty )

I wonder if you can give an explanation for what's going on here. Does the fact that the board is somewhat rotated play a role here?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.