Rock Paper Scissor using Keras | Python

In this blog, we will learn about Rock, Paper, and Scissor’s classification by Keras transfer learning with Python programming.

This will be the image classification task, we will classify if the image is of Rock, Paper, or the Scissor.

We will use the dataset from the Kaggle.

Let’s get started.

Python code

Firstly, we will import all the Python libraries that would be necessary for the program. We will use:

  • os module to interact with the operating system.
  • Matplotlib for plotting the images.
  • Keras for Deep Learning.
import os
from keras.layers import Dense,Dropout,Conv2D,MaxPool2D,Flatten,GlobalAveragePooling2D
from keras.models import Model
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam
import matplotlib.pyplot as plt

Now, we will do the preprocessing of the data. We will be doing it using Keras ImgeDataGenerator. Also, we will do Data Augmentation such as Zoom, Width, and Horizontal shift, etc to avoid overfitting of the Data. We will make the image size to (64,64) and class model to categorical as we have 3 classes.

train_gen = ImageDataGenerator(rescale=1/255.0,zoom_range=0.2,width_shift_range=0.2,height_shift_range=0.2)
train = train_gen.flow_from_directory(
    "../ROCK-PAPER-SCISSOR/rps/rps",
    target_size=(64,64),
    class_mode="categorical",
    shuffle=True
)

test_gen = ImageDataGenerator(rescale=1/255.0)
test = test_gen.flow_from_directory(
    "../ROCK-PAPER-SCISSOR/rps-test-set/rps-test-set",
    target_size=(64,64),
    class_mode="categorical",
    shuffle=True
)

pred_gen = ImageDataGenerator(rescale=1/255.0)
pre = pred_gen.flow_from_directory(
    "../ROCK-PAPER-SCISSOR/rps-val-set",
    target_size=(64,64),
    
)
Output: 
Found 2520 images belonging to 3 classes.
Found 372 images belonging to 3 classes.
Found 33 images belonging to 1 class.

From the output, we can see the dataset contains 2520 images in the training set and 372 in the validation set.

Now, we will make the Deep Learning model, for that we will use the VGG model and take the input size as that of our image.

from keras.applications.vgg16 import VGG16
model = VGG16(include_top=False,input_shape=(64,64,3))
model.summary()

Output:
Model: "vgg16"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         [(None, 64, 64, 3)]       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 64, 64, 64)        1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 64, 64, 64)        36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 32, 32, 64)        0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 32, 32, 128)       73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 32, 32, 128)       147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 16, 16, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 16, 16, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 16, 16, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 16, 16, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 8, 8, 256)         0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 8, 8, 512)         1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 8, 8, 512)         2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 8, 8, 512)         2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 4, 4, 512)         0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 4, 4, 512)         2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 4, 4, 512)         2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 4, 4, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 2, 2, 512)         0         
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0

There are 14 million parameter in the model and if we train on these many parameters, our model will overfit. So, we will make our own model with the help of VGG. We will make the trainable parameters of the layer to False so that there are zero trainable parameters.

for i in model.layers[:-1]:
  i.trainable=False

Now, we will add our custom model to the VGG model output. We will use GlobalAveragePooling Layer and Dense Layer and also Dropout to avoid overfitting.

a= GlobalAveragePooling2D()(model.output)
b=Dropout(0.5)(a)
c=Dense(16,activation='relu')(b)
e=Dropout(0.3)(c)
f=Dense(3,activation='softmax')(e)
model_new = Model(inputs=model.input, outputs=f)
model_new.summary()
Output:
Model: "functional_23"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         [(None, 64, 64, 3)]       0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 64, 64, 64)        1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 64, 64, 64)        36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 32, 32, 64)        0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 32, 32, 128)       73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 32, 32, 128)       147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 16, 16, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 16, 16, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 16, 16, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 16, 16, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 8, 8, 256)         0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 8, 8, 512)         1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 8, 8, 512)         2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 8, 8, 512)         2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 4, 4, 512)         0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 4, 4, 512)         2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 4, 4, 512)         2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 4, 4, 512)         2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 2, 2, 512)         0         
_________________________________________________________________
global_average_pooling2d_10  (None, 512)               0         
_________________________________________________________________
dropout_19 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_23 (Dense)             (None, 16)                8208      
_________________________________________________________________
dropout_20 (Dropout)         (None, 16)                0         
_________________________________________________________________
dense_24 (Dense)             (None, 3)                 51        
=================================================================
Total params: 14,722,947
Trainable params: 8,259
Non-trainable params: 14,714,688

After creating the model, we will compile the model using Adam as the optimizer and categorical cross-entropy as the loss.

adam = Adam(learning_rate=0.0009)
model_new.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])

Finally, we will train the model on the training set.

his=model_new.fit_generator(train,epochs=50,validation_data= test)

Checking model training accuracy.

model_new.evaluate(train)

Output:
79/79 [==============================] - 16s 204ms/step - loss: 0.1315 - accuracy: 0.9671
[0.1314919888973236, 0.9670634865760803]

Checking test accuracy.

model_new.evaluate(test)
Output:
12/12 [==============================] - 2s 144ms/step - loss: 0.5316 - accuracy: 0.7554
[0.5316319465637207, 0.8853763389587402]

We are getting 88.5% test accuracy which is good.

Also, we can plot the model training and validation accuracy and loss graph using matplotlib.

plt.style.use("seaborn")
plt.plot(his.history['val_loss'],label='val_loss')
plt.plot(his.history['loss'],label='loss')
plt.plot(his.history['val_accuracy'],label="val_accuracy")
plt.plot(his.history['accuracy'],label='acc')
plt.legend()
plt.show()

Conclusion

In this tutorial, we understood how to classify images using Rock, Paper Scissor dataset with the help of the Keras Python module.

If you have any doubts or have suggestions related to the tutorial, you can write in the comment box below.

Leave a Reply

Your email address will not be published. Required fields are marked *