1

So, I'm making a rock paper scissors prediction using multiclass classification, but I have several problems with this code

(1) The data sorting code

import pandas
import sklearn
from sklearn import datasets
import zipfile
import os
from sklearn.model_selection import train_test_split
!pip install split_folders
import splitfolders
import shutil
import numpy

!wget --no-check-certificate \
  https://github.com/dicodingacademy/assets/releases/download/release/rockpaperscissors.zip \
  -O /tmp/rockpaperscissors.zip  

lclzip = "/tmp/rockpaperscissors.zip"
zipref = zipfile.ZipFile(lclzip, "r")
zipref.extractall("/tmp")
zipref.close()

basedir = "/tmp/rockpaperscissors"
shutil.rmtree(os.path.join(basedir, "rps-cv-images"))
os.remove(os.path.join(basedir, "README_rpc-cv-images.txt"))
for dir in os.listdir(basedir):
  os.makedirs(basedir + "/train/" + dir, exist_ok = True)
  os.makedirs(basedir + "/val/" + dir, exist_ok = True)
  all = os.listdir(os.path.join(basedir, dir))
  numpy.random.shuffle(all)
  train, val = numpy.split(numpy.array(all), [int(len(all)*0.6)])
  train = [basedir + "/" + dir + "/" + name for name in train.tolist()]
  val = [basedir + "/" + dir + "/" + name for name in val.tolist()]
  for name in train:
    shutil.copy(name, basedir + "/train/" + dir)
  for name in val:
    shutil.copy(name, basedir + "/val/" + dir)
os.listdir(basedir)

(2) The model making code

import tensorflow
from tensorflow.keras.preprocessing.image import ImageDataGenerator

datagentrain = ImageDataGenerator(
    rescale = 1./255,
    rotation_range = 20,
    horizontal_flip = True,
    shear_range = 0.2,
    fill_mode = "nearest"
)
datagenval = ImageDataGenerator(
    rescale = 1./255
)
traingenerator = datagentrain.flow_from_directory(
    os.path.join(basedir, "train"),
    target_size = (150,150),
    batch_size = 4,
    class_mode = "categorical"
)
valgenerator = datagenval.flow_from_directory(
    os.path.join(basedir, "val"),
    target_size = (150,150),
    batch_size = 4,
    class_mode = "categorical"
)
model = tensorflow.keras.models.Sequential([
    tensorflow.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),
    tensorflow.keras.layers.MaxPooling2D(2, 2),
    tensorflow.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tensorflow.keras.layers.MaxPooling2D(2,2),
    tensorflow.keras.layers.Conv2D(128, (3,3), activation='relu'),
    tensorflow.keras.layers.MaxPooling2D(2,2),
    tensorflow.keras.layers.Conv2D(512, (3,3), activation='relu'),
    tensorflow.keras.layers.MaxPooling2D(2,2),
    tensorflow.keras.layers.Flatten(),
    tensorflow.keras.layers.Dense(512, activation='relu'),
    tensorflow.keras.layers.Dense(3, activation='softmax')
])
model.compile(
    loss='categorical_crossentropy',
    optimizer = 'adam',
    metrics = ["accuracy"]
)
model.fit(
      traingenerator,
      steps_per_epoch=25,  
      epochs=40,
      validation_data=valgenerator,
      validation_steps=5, 
      verbose=2)

(3) The model prediction code

import numpy as np
from google.colab import files
from tensorflow.keras.preprocessing import image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
%matplotlib inline
 
uploaded = files.upload()
 
for fn in uploaded.keys():
 
  path = fn
  img = image.load_img(path, target_size=(150,150))
 
  imgplot = plt.imshow(img)
  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  images = np.vstack([x])
 
  classes = model.predict(images, batch_size=10)  
  print(fn)
  print(classes)
  max = 0
  temp = 0
  for n in range(len(classes[0])):
    if classes[0][n] > max:
      max = classes[0][n]
      temp = n
  if temp == 0:
    print('paper')
  elif temp == 1:
    print('rock')
  elif temp == 2:
    print('scissors')

For one, everytime I run it back, the (rock,paper,scissors) position constantly changes, so I can't make the temp position check in (3) consistent

But, even before that, for some reason, the results are sometimes only [[1 0 0]] and nothing else (In other cases, it's [[0 1 0]]). Only when scissors position is at 2 that it has any merit in giving something else.

So, I'm confused in where I'm going wrong: Is it the scuffed way of seperating the train and val sources in (1), the lack of labelling consistency in (2) (if it is, I have no idea how to label), or this is only natural?

I thought that I used the class_mode wrong since I used sparse prior, so I changed it to categorical. In addition, I tried maybe changing the final Dense layer to 2, but nothing.

I really don't know what to do or even what to change. I would like some insight on this scenario and thank you prior

0 Answers0