rahulmishra/Multi-class-Classification
0
1import zipfile2 3# Download zip file of pizza_steak images4zip_ref = "https://huggingface.co/spaces/rahulmishra/Multi-class-Classification/resolve/main/10_food_classes_all_data.zip"5 6# Unzip the downloaded file7zip_ref = zipfile.ZipFile("10_food_classes_all_data.zip", "r")8zip_ref.extractall()9zip_ref.close()10 11import os12 13# Walk through 10_food_classes directory and list number of files14for dirpath, dirnames, filenames in os.walk("10_food_classes_all_data"):15 print(f"There are {len(dirnames)} directories and {len(filenames)} images in '{dirpath}'.")16 17train_dir = "10_food_classes_all_data/train/"18test_dir = "10_food_classes_all_data/test/"19 20# Get the class names for our multi-class dataset21import pathlib22import numpy as np23data_dir = pathlib.Path(train_dir)24class_names = np.array(sorted([item.name for item in data_dir.glob('*')]))25print(class_names)26 27# View an image28import matplotlib.pyplot as plt29import matplotlib.image as mpimg30import random31 32def view_random_image(target_dir, target_class):33 # Setup target directory (we'll view images from here)34 target_folder = target_dir+target_class35 36 # Get a random image path37 random_image = random.sample(os.listdir(target_folder), 1)38 39 # Read in the image and plot it using matplotlib40 img = mpimg.imread(target_folder + "/" + random_image[0])41 plt.imshow(img)42 plt.title(target_class)43 plt.axis("off");44 45 print(f"Image shape: {img.shape}") # show the shape of the image46 47 return img48 49# View a random image from the training dataset50import random51img = view_random_image(target_dir=train_dir,52 target_class=random.choice(class_names))53 54from tensorflow.keras.preprocessing.image import ImageDataGenerator55# Create ImageDataGenerator training instance with data augmentation56train_datagen_augmented = ImageDataGenerator(rescale=1/255.,57 rotation_range=20, # rotate the image slightly between 0 and 20 degrees (note: this is an int not a float)58 shear_range=0.2, # shear the image59 zoom_range=0.2, # zoom into the image60 width_shift_range=0.2, # shift the image width ways61 height_shift_range=0.2, # shift the image height ways62 horizontal_flip=True) # flip the image on the horizontal axis63 64# Create ImageDataGenerator training instance without data augmentation65train_datagen = ImageDataGenerator(rescale=1/255.) 66 67# Create ImageDataGenerator test instance without data augmentation68test_datagen = ImageDataGenerator(rescale=1/255.)69 70# Import data and augment it from training directory71print("Augmented training images:")72train_data_augmented = train_datagen_augmented.flow_from_directory(train_dir,73 target_size=(224, 224),74 batch_size=32,75 class_mode='categorical',76 shuffle=False) # Don't shuffle for demonstration purposes, usually a good thing to shuffle77 78# Create non-augmented data batches79print("Non-augmented training images:")80train_data = train_datagen.flow_from_directory(train_dir,81 target_size=(224, 224),82 batch_size=32,83 class_mode='categorical',84 shuffle=False) # Don't shuffle for demonstration purposes85 86print("Unchanged test images:")87test_data = test_datagen.flow_from_directory(test_dir,88 target_size=(224, 224),89 batch_size=32,90 class_mode='categorical')91 92# Get data batch samples93images, labels = train_data.next()94augmented_images, augmented_labels = train_data_augmented.next()95 96# Show original image and augmented image97random_number = random.randint(0, 32) # we're making batches of size 32, so we'll get a random instance98plt.imshow(images[random_number])99plt.title(f"Original image")100plt.axis(False)101plt.figure()102plt.imshow(augmented_images[random_number])103plt.title(f"Augmented image")104plt.axis(False);105 106import tensorflow as tf107from tensorflow.keras.models import Sequential108from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten, Dense109 110# Create our model (a clone of model_8, except to be multi-class)111model_9 = Sequential([112 Conv2D(10, 3, activation='relu', input_shape=(224, 224, 3)),113 Conv2D(10, 3, activation='relu'),114 MaxPool2D(),115 Conv2D(10, 3, activation='relu'),116 Conv2D(10, 3, activation='relu'),117 MaxPool2D(),118 Flatten(),119 Dense(10, activation='softmax') # changed to have 10 neurons (same as number of classes) and 'softmax' activation120])121 122# Compile the model123model_9.compile(loss="categorical_crossentropy", # changed to categorical_crossentropy124 optimizer=tf.keras.optimizers.Adam(),125 metrics=["accuracy"])126 127# Fit the model128history_9 = model_9.fit(train_data, # now 10 different classes 129 epochs=16,130 steps_per_epoch=len(train_data),131 validation_data=test_data,132 validation_steps=len(test_data))133 134def load_and_prep_image(filename, img_shape=224):135 """136 Reads an image from filename, turns it into a tensor137 and reshapes it to (img_shape, img_shape, colour_channel).138 """139 # Read in target file (an image)140 #img = tf.io.read_file(filename)141 #print(img)142 # Decode the read file into a tensor & ensure 3 colour channels 143 # (our model is trained on images with 3 colour channels and sometimes images have 4 colour channels)144 img = filename145 # img = tf.image.decode_image(img, channels=3)146 147 # Resize the image (to the same size our model was trained on)148 img = tf.image.resize(img, size = [img_shape, img_shape])149 print(img.shape)150 # Rescale the image (get all values between 0 and 1)151 img = img/255.152 return img153 154def pred_and_plot(filename):155 """156 Imports an image located at filename, makes a prediction on it with157 a trained model and plots the image with the predicted class as the title.158 """159 # Import the target image and preprocess it160 # print(filename.shape)161 img = load_and_prep_image(filename)162 163 # Make a prediction164 pred = model_9.predict(tf.expand_dims(img, axis=0))165 class_names = ['chicken_curry','chicken_wings', 'fried_rice', 'grilled_salmon','hamburger','ice_cream','pizza', 'ramen', 'steak', 'sushi']166 # Get the predicted class167 if len(pred[0]) > 1: # check for multi-class168 pred_class = class_names[pred.argmax()] # if more than one output, take the max169 else:170 pred_class = class_names[int(tf.round(pred)[0][0])] # if only one output, round171 return pred_class172 # Plot the image and predicted class173 plt.imshow(img)174 plt.title(f"Prediction: {pred_class}")175 plt.axis(False);176 177# Test our model on a custom image178#pred_and_plot("03-steak.jpeg")179 180#import cv2181#val = cv2.imread("03-steak.jpeg")182#val.shape183 184 185from pathlib import Path186# Create a list of example inputs to our Gradio demo187test_data_paths = list(Path(test_dir).glob("*/*.jpg"))188 189example_list = [[str(filepath)] for filepath in random.sample(test_data_paths, k=3)]190example_list191 192# Import/install Gradio 193import gradio as gr194 195print(f"Gradio version: {gr.__version__}")196 197import gradio as gr198 199# Create title, description and article strings200title = "Food Classifier"201description = "A CNN model to classify images of food as chicken_curry,chicken_wings, fried_rice, grilled_salmon, hamburger, ice_cream, pizza, ramen, steak and sushi."202 203 204# Create the Gradio demo205demo = gr.Interface(fn=pred_and_plot, # mapping function from input to output206 inputs=["image"], # what are the inputs?207 outputs=["text"], # our fn has two outputs, therefore we have two outputs208 examples=example_list, 209 title=title,210 description=description)211 212# Launch the demo!213demo.launch(inline=True)214 