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