Poker hand images database created by Samy Zafrany. It consists of 49,759 192x192 pixels rgb color images. It is divided to two HDF5 datasets:
These datasets can be dowloaded from:
The poker hand images in these datasets are based on a larger numerical database of poker hands (consisting of 1,025,010 instances of poker hands) which was created by
Robert Cattral (cattral@gmail.com)
Franz Oppacher (oppacher@scs.carleton.ca)
Carleton University, Department of Computer Science
Intelligent Systems Research Unit
1125 Colonel By Drive, Ottawa, Ontario, Canada, K1S5B6
https://archive.ics.uci.edu/ml/datasets/Poker+Hand
Our aim in this study unit is to introduce and explore our Poker Hands Image database. Your aim is to build a Convolutional Neural Network for recognizing images of poker hands. That is, you CNN will accept an image of a Poker hand and it will have to classify it as a "Royal Flush", "Three of a kind", "Four of a kind", "Two Pairs", etc ...
In the tutorial end we will sketch additional ideas for using this database for course projects.
A Poker hand consists of exactly 11 features:
S1 - Suit of card 1
Ordinal (1-4) representing: Hearts=1, Spades=2, Diamonds=3, Clubs=4
1 | heart | ♥ |
2 | spade | â™ |
3 | diamond | ♦ |
4 | club | ♣ |
C1 - Rank of card 1
Numerical (1-13) representing: Ace=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , Jack=11, Queen=12, King=13
S2 - Suit of card 2
Ordinal (1-4) representing: Hearts=1, Spades=2, Diamonds=3, Clubs=4
C2 - Rank of card 2
Numerical (1-13) representing: Ace=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , Jack=11, Queen=12, King=13
S3 - Suit of card 3
Ordinal (1-4) representing: Hearts=1, Spades=2, Diamonds=3, Clubs=4
C3 - Rank of card 3
Numerical (1-13) representing: Ace=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , Jack=11, Queen=12, King=13
S4 - Suit of card 4
Ordinal (1-4) representing: Hearts=1, Spades=2, Diamonds=3, Clubs=4
C4 - Rank of card 4
”
Numerical (1-13) representing: Ace=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , Jack=11, Queen=12, King=13
S5 - Suit of card 5
Ordinal (1-4) representing: Hearts=1, Spades=2, Diamonds=3, Clubs=4
C5 - Rank of card 5
Numerical (1-13) representing: Ace=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , Jack=11, Queen=12, King=13
CLASS of a Poker Hand (or Poker hand type):
A integer 0-9:
CLASS | Description |
0 | Nothing in hand; not a recognized poker hand |
1 | One pair; one pair of equal ranks within five cards |
2 | Two pairs; two pairs of equal ranks within five cards |
3 | Three of a kind; three equal ranks within five cards |
4 | Straight; five cards, sequentially ranked with no gaps |
5 | Flush; five cards with the same suit |
6 | Full house; pair + different rank three of a kind |
7 | Four of a kind; four equal ranks within five cards |
8 | Straight flush; straight + flush |
9 | Royal flush; {Ace, King, Queen, Jack, Ten} + flush |
The following poker hand has the following 11 features. Note that the last feature is 3 which according to the above table indicates "Three of a kind".
This is better understood from the following table:
1 | 13 | 3 | 12 | 2 | 12 | 1 | 9 | 4 | 12 | 3 |
♥ | K | ♦ | Q | ♠| Q | ♥ | 9 | ♣ | Q | Theree of a kind |
features = ['S1', 'C1', 'S2', 'C2', 'S3', 'C3', 'S4', 'C4', 'S5', 'C5', 'CLASS']
# Let's keep a map of poker hand class id to class name
# There are exactly 10 type of poker hands
poker_hand_types = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
hand_name = {
0: 'Nothing in hand',
1: 'One pair',
2: 'Two pairs',
3: 'Three of a kind',
4: 'Straight',
5: 'Flush',
6: 'Full house',
7: 'Four of a kind',
8: 'Straight flush',
9: 'Royal flush',
}
# These are css/html styles for good looking ipython notebooks
from IPython.core.display import HTML
css = open('style-notebook.css').read()
HTML('<style>{}</style>'.format(css))
Lets explore our HDF5 files to help you get started with your deep learning project: to predict the Poker hand type (feature 11) from the first 10 features.
We first show how to parse an HDF5 to collect poker hands in numerical form. After collecting the numerical data we perform some statistical calculations on it.
from __future__ import print_function # we want to enable Python 3
import h5py
import numpy as np
# This is how you open an HDF5 file
f = h5py.File('train.h5', 'r')
# We will collect all the images in one long Python list
images = []
# We will collect all classes in the following list
y_train = []
# Poker hands in text form
hands = []
# Our HDF5 file has a special key for the number of images
num_images = f.get('num_images').value
for i in range(num_images):
cls_key = 'cls_' + str(i)
img_key = 'img_' + str(i)
hnd_key = 'hnd_' + str(i)
# This is the poker hand class
cls = int(np.array(f.get(cls_key)))
y_train.append(cls)
# This is image i
img = np.array(f.get(img_key))
images.append(img)
# This is the poker hand text form
h = np.array(f.get(hnd_key))
hands.append(h)
# Do not forget to close the HDF5 file!
f.close()
import matplotlib.pyplot as plt
%matplotlib inline
def draw_hand(i):
print("Image id:", i)
print("Features:", hands[i])
c = y_train[i]
img = images[i]
print("Class: %d (%s)" % (c, hand_name[c]))
plt.title(hand_name[c], fontsize=18, fontweight='bold', y=1.02)
ticks=[0,32,64,96,128,160,192]
plt.xticks(ticks, fontsize=12)
plt.yticks(ticks, fontsize=12)
plt.imshow(img, cmap='jet')
plt.show()
Let's draw a few samples of poker hands. We hav 40,000 of them, numbered from 0 to 39,999.
draw_hand(15)
draw_hand(543)
draw_hand(39234)
At this stage we can build a pandas dataframe for the numerical hands. We start with a dataframe for the 10 features and later add the class column.
import pandas as pd
data = pd.DataFrame(hands, columns=features[0:10])
# We add the poker hand type as the 11th column
data['CLASS'] = y_train
# View the last 5 records of our data set
data.head(5)
# Let's count how many poker hands belong to each type
nb_classes = 10 # we have 10 classes of poker hand types
class_count = {}
for i in range(nb_classes):
class_count[i] = len(data[data.CLASS==i])
print(class_count)
This is hardly readable. Let's translate it to a more human readable form.
for i in poker_hand_types:
print("%s: %d" % (hand_name[i], class_count[i]))
The classes are imbalanced, which usually does not help the training process. But there's not much we can do: there are only 17 Straight Flush hands in the Poker game, and only 8 Royal Flush hands. Your neural network will learn a lot about "One Pair" (8372 hands) but very little about "Royal Flash" (only 8 hands).
It is usually a good practice to keep this in mind and draw a class distribution bar chart before you start building and training deep learning models. The bar chart will give you a thick visual clue regarding imbalance.
plt.bar(poker_hand_types, [class_count[i] for i in poker_hand_types], align='center')
plt.xlabel('Poker hand id')
plt.ylabel('Number of instances')
Now that you have your datasets ready, your project is to build a convolutional neural network for recognizing these Poker hands.
It could happen that our database is not big enough for training a neural network to predict the Poker hand type in a very high precision. We can start with an easier challenges like building high precision neural networks to:
It would be interesting to compare the complexities of the various neural networks for solving these problems.
Note that you may need extract special training and validation datasets for each problem. So you will have to unfold the images from the above datasets and reorganize them to suite your problem (which is another challenge by itself). Or you may want to create your own set of poker hands from the 52 cards deck. We will later add a section for describing how to do it.