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