{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-28T08:41:40.365107Z","iopub.execute_input":"2021-06-28T08:41:40.365551Z","iopub.status.idle":"2021-06-28T08:42:08.008527Z","shell.execute_reply.started":"2021-06-28T08:41:40.365464Z","shell.execute_reply":"2021-06-28T08:42:08.007597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# standard imports\nimport numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plte\n%matplotlib inline\nimport tensorflow as tf","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:08.010958Z","iopub.execute_input":"2021-06-28T08:42:08.011323Z","iopub.status.idle":"2021-06-28T08:42:14.638292Z","shell.execute_reply.started":"2021-06-28T08:42:08.011288Z","shell.execute_reply":"2021-06-28T08:42:14.637126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Get a look at labels","metadata":{}},{"cell_type":"code","source":"labels_csv = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nlabels_csv.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:14.640543Z","iopub.execute_input":"2021-06-28T08:42:14.641192Z","iopub.status.idle":"2021-06-28T08:42:14.704857Z","shell.execute_reply.started":"2021-06-28T08:42:14.641139Z","shell.execute_reply":"2021-06-28T08:42:14.703809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_csv.describe()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:14.706422Z","iopub.execute_input":"2021-06-28T08:42:14.706824Z","iopub.status.idle":"2021-06-28T08:42:14.758814Z","shell.execute_reply.started":"2021-06-28T08:42:14.706793Z","shell.execute_reply":"2021-06-28T08:42:14.757763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_csv['breed'].value_counts().plot.bar(figsize=(20,12));","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:14.760334Z","iopub.execute_input":"2021-06-28T08:42:14.760747Z","iopub.status.idle":"2021-06-28T08:42:17.045784Z","shell.execute_reply.started":"2021-06-28T08:42:14.760698Z","shell.execute_reply":"2021-06-28T08:42:17.044605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#median number of image in each class.\nlabels_csv['breed'].value_counts().median()","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.047363Z","iopub.execute_input":"2021-06-28T08:42:17.047802Z","iopub.status.idle":"2021-06-28T08:42:17.060770Z","shell.execute_reply.started":"2021-06-28T08:42:17.047754Z","shell.execute_reply":"2021-06-28T08:42:17.059469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#viewing any image from the train data.\nfrom IPython.display import Image\nImage('/kaggle/input/dog-breed-identification/train/0a0c223352985ec154fd604d7ddceabd.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.062269Z","iopub.execute_input":"2021-06-28T08:42:17.062568Z","iopub.status.idle":"2021-06-28T08:42:17.089653Z","shell.execute_reply.started":"2021-06-28T08:42:17.062538Z","shell.execute_reply":"2021-06-28T08:42:17.088468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Getting images and their labels","metadata":{}},{"cell_type":"code","source":"filenames = ['/kaggle/input/dog-breed-identification/train/' + fname + '.jpg' for fname in labels_csv['id']]\nfilenames[:5]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.092542Z","iopub.execute_input":"2021-06-28T08:42:17.092870Z","iopub.status.idle":"2021-06-28T08:42:17.104826Z","shell.execute_reply.started":"2021-06-28T08:42:17.092838Z","shell.execute_reply":"2021-06-28T08:42:17.103747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check wheather the the number of files matches number of actual images.\nif len(os.listdir('/kaggle/input/dog-breed-identification/train/')) == len(filenames):\n    print('Number of file matches number of actual images!')\nelse:\n    print('Number of file doesnot matches number of actual images!!')","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.106752Z","iopub.execute_input":"2021-06-28T08:42:17.107244Z","iopub.status.idle":"2021-06-28T08:42:17.124617Z","shell.execute_reply.started":"2021-06-28T08:42:17.107207Z","shell.execute_reply":"2021-06-28T08:42:17.123455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#visualizing images according to their index.\nImage(filenames[900])","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.126033Z","iopub.execute_input":"2021-06-28T08:42:17.126569Z","iopub.status.idle":"2021-06-28T08:42:17.145223Z","shell.execute_reply.started":"2021-06-28T08:42:17.126529Z","shell.execute_reply":"2021-06-28T08:42:17.143952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#finding the name of the above displayed dog.\nlabels_csv['breed'][900]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.146824Z","iopub.execute_input":"2021-06-28T08:42:17.147451Z","iopub.status.idle":"2021-06-28T08:42:17.153972Z","shell.execute_reply.started":"2021-06-28T08:42:17.147401Z","shell.execute_reply":"2021-06-28T08:42:17.152634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Turning our data into numbers","metadata":{}},{"cell_type":"code","source":"labels = labels_csv['breed']\nlabels = np.array(labels)\nlabels","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.155854Z","iopub.execute_input":"2021-06-28T08:42:17.156332Z","iopub.status.idle":"2021-06-28T08:42:17.168631Z","shell.execute_reply.started":"2021-06-28T08:42:17.156283Z","shell.execute_reply":"2021-06-28T08:42:17.167494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Check wheather the number of labels matches the number of filenames.\nif len(labels) == len(filenames):\n    print('Number of labels matches the number of filenames.')\nelse:\n    print('Number of labels doesnot matches the number of filenames')","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.170147Z","iopub.execute_input":"2021-06-28T08:42:17.170741Z","iopub.status.idle":"2021-06-28T08:42:17.181560Z","shell.execute_reply.started":"2021-06-28T08:42:17.170694Z","shell.execute_reply":"2021-06-28T08:42:17.180487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Finding the unique labels values\nunique_breed = np.unique(labels) \nunique_breed","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.182717Z","iopub.execute_input":"2021-06-28T08:42:17.183156Z","iopub.status.idle":"2021-06-28T08:42:17.208816Z","shell.execute_reply.started":"2021-06-28T08:42:17.183122Z","shell.execute_reply":"2021-06-28T08:42:17.207560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Turn single label into an array of boolean.\nprint(labels[0])\nlabels[0] == unique_breed","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.210370Z","iopub.execute_input":"2021-06-28T08:42:17.210705Z","iopub.status.idle":"2021-06-28T08:42:17.227026Z","shell.execute_reply.started":"2021-06-28T08:42:17.210666Z","shell.execute_reply":"2021-06-28T08:42:17.225603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Turning every label into an array of boolean\nboolean_labels = [labels == unique_breed for labels in labels]\nboolean_labels[:2]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.228726Z","iopub.execute_input":"2021-06-28T08:42:17.229370Z","iopub.status.idle":"2021-06-28T08:42:17.334724Z","shell.execute_reply.started":"2021-06-28T08:42:17.229316Z","shell.execute_reply":"2021-06-28T08:42:17.333444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Turining boolean arrays into integers.\nprint(labels[0])   #orginal index\nprint(np.where(unique_breed==labels[0]))    #index where labels occurs.\nprint(boolean_labels[0].argmax())     #index where label occurs in boolean array\nprint(boolean_labels[0].astype(int))   #there will be a 1 where sample label occurs","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.336363Z","iopub.execute_input":"2021-06-28T08:42:17.336907Z","iopub.status.idle":"2021-06-28T08:42:17.344843Z","shell.execute_reply.started":"2021-06-28T08:42:17.336858Z","shell.execute_reply":"2021-06-28T08:42:17.343559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating our own validation set","metadata":{}},{"cell_type":"code","source":"# setup x and y variables.\nX = filenames\ny = boolean_labels","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.346388Z","iopub.execute_input":"2021-06-28T08:42:17.346828Z","iopub.status.idle":"2021-06-28T08:42:17.356898Z","shell.execute_reply.started":"2021-06-28T08:42:17.346784Z","shell.execute_reply":"2021-06-28T08:42:17.356067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# First starting with ~1000 images because we have lots of data to train for the very first attempt\n\n#set number of images to set for the experiment.\nNUM_IMAGES = 1000 #@param {type:\"slider\",min:1000,max:10000}","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.358192Z","iopub.execute_input":"2021-06-28T08:42:17.358644Z","iopub.status.idle":"2021-06-28T08:42:17.369285Z","shell.execute_reply.started":"2021-06-28T08:42:17.358598Z","shell.execute_reply":"2021-06-28T08:42:17.368060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#let's split our data into train and validation.\nfrom sklearn.model_selection import train_test_split\n\n#spliting into training and validation of total size NUM_IMAGES.\n\nX_train,X_val,y_train,y_val = train_test_split(X[:NUM_IMAGES],\n                                                y[:NUM_IMAGES],\n                                                test_size=0.2,\n                                                random_state=42)\nlen(X_train),len(X_val),len(y_train),len(y_val)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:17.370884Z","iopub.execute_input":"2021-06-28T08:42:17.371312Z","iopub.status.idle":"2021-06-28T08:42:18.132485Z","shell.execute_reply.started":"2021-06-28T08:42:17.371265Z","shell.execute_reply":"2021-06-28T08:42:18.131304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train[:5],y_train[:5]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.134161Z","iopub.execute_input":"2021-06-28T08:42:18.134603Z","iopub.status.idle":"2021-06-28T08:42:18.143965Z","shell.execute_reply.started":"2021-06-28T08:42:18.134567Z","shell.execute_reply":"2021-06-28T08:42:18.142690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Preprocessing Images\nTurning images into tensors\n\nLet's write a function to preprocess the image. The function will do the following tasks.\n\n    The function will take an image filepath as input.\n    Use the tensorflow to read the file and save it to the variable.\n    Turn our variable (.jpg) into tensors.\n    Normalize our image(convert color channel from 0-255 to 0-1).|\n    Resize the image.\n    Return the modified variable.\n","metadata":{}},{"cell_type":"code","source":"# converting images to numpy array\n\nfrom matplotlib.pyplot import imread\nimage = imread(filenames[42])\nimage.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.145663Z","iopub.execute_input":"2021-06-28T08:42:18.146096Z","iopub.status.idle":"2021-06-28T08:42:18.170530Z","shell.execute_reply.started":"2021-06-28T08:42:18.146059Z","shell.execute_reply":"2021-06-28T08:42:18.169499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.174941Z","iopub.execute_input":"2021-06-28T08:42:18.175494Z","iopub.status.idle":"2021-06-28T08:42:18.185043Z","shell.execute_reply.started":"2021-06-28T08:42:18.175451Z","shell.execute_reply":"2021-06-28T08:42:18.184011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#lets conver them into tensor\ntf.constant(image)[:2]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.187790Z","iopub.execute_input":"2021-06-28T08:42:18.188195Z","iopub.status.idle":"2021-06-28T08:42:18.227543Z","shell.execute_reply.started":"2021-06-28T08:42:18.188102Z","shell.execute_reply":"2021-06-28T08:42:18.226499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Making a function to preprocess the data\n\n# Define image size\nIMG_SIZE = 224\n\ndef process_image(image_path):\n  \"\"\"\n  Takes an image file path and turns it into a Tensor.\n  \"\"\"\n  # Read in image file\n  image = tf.io.read_file(image_path)\n  # Turn the jpeg image into numerical Tensor with 3 colour channels (Red, Green, Blue)\n  image = tf.image.decode_jpeg(image, channels=3)\n  # Convert the colour channel values from 0-225 values to 0-1 values\n  image = tf.image.convert_image_dtype(image, tf.float32)\n  # Resize the image to our desired size (224, 244)\n  image = tf.image.resize(image, size=[IMG_SIZE, IMG_SIZE])\n  return image","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.228773Z","iopub.execute_input":"2021-06-28T08:42:18.229357Z","iopub.status.idle":"2021-06-28T08:42:18.236279Z","shell.execute_reply.started":"2021-06-28T08:42:18.229297Z","shell.execute_reply":"2021-06-28T08:42:18.234758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# Turning our data into batches\n\nWhy turn our data into batches?\n\nWe are trying to fit the 10000+ data images. They all might not fit into memory.\n\nSo,that's why we use 32(this is batch size) images at a time. we can change the batch size whenever we need.\n\nIn order to use the tensorflow effective we need to convert the images into tuple tensor which looks like (image,labels)\n","metadata":{}},{"cell_type":"code","source":"# Create a simple function to return a tuple (image, label)\ndef get_image_label(image_path, label):\n  \"\"\"\n  Takes an image file path name and the associated label,\n  processes the image and returns a tuple of (image, label).\n  \"\"\"\n  image = process_image(image_path)\n  return image, label","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.239191Z","iopub.execute_input":"2021-06-28T08:42:18.239665Z","iopub.status.idle":"2021-06-28T08:42:18.254754Z","shell.execute_reply.started":"2021-06-28T08:42:18.239617Z","shell.execute_reply":"2021-06-28T08:42:18.253527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the batch size, 32 is a good default\nBATCH_SIZE = 32\n\n# Create a function to turn data into batches\ndef create_data_batches(x, y=None, batch_size=BATCH_SIZE, valid_data=False, test_data=False):\n  \"\"\"\n  Creates batches of data out of image (x) and label (y) pairs.\n  Shuffles the data if it's training data but doesn't shuffle it if it's validation data.\n  Also accepts test data as input (no labels).\n  \"\"\"\n  # If the data is a test dataset, we probably don't have labels\n  if test_data:\n    print(\"Creating test data batches...\")\n    data = tf.data.Dataset.from_tensor_slices((tf.constant(x))) # only filepaths\n    data_batch = data.map(process_image).batch(BATCH_SIZE)\n    return data_batch\n  \n  # If the data if a valid dataset, we don't need to shuffle it\n  elif valid_data:\n    print(\"Creating validation data batches...\")\n    data = tf.data.Dataset.from_tensor_slices((tf.constant(x), # filepaths\n                                               tf.constant(y))) # labels\n    data_batch = data.map(get_image_label).batch(BATCH_SIZE)\n    return data_batch\n\n  else:\n    # If the data is a training dataset, we shuffle it\n    print(\"Creating training data batches...\")\n    # Turn filepaths and labels into Tensors\n    data = tf.data.Dataset.from_tensor_slices((tf.constant(x), # filepaths\n                                              tf.constant(y))) # labels\n    \n    # Shuffling pathnames and labels before mapping image processor function is faster than shuffling images\n    data = data.shuffle(buffer_size=len(x))\n\n    # Create (image, label) tuples (this also turns the image path into a preprocessed image)\n    data = data.map(get_image_label)\n\n    # Turn the data into batches\n    data_batch = data.batch(BATCH_SIZE)\n  return data_batch","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.256586Z","iopub.execute_input":"2021-06-28T08:42:18.257098Z","iopub.status.idle":"2021-06-28T08:42:18.268700Z","shell.execute_reply.started":"2021-06-28T08:42:18.257045Z","shell.execute_reply":"2021-06-28T08:42:18.267450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create training and validation data batches\ntrain_data = create_data_batches(X_train, y_train)\nval_data = create_data_batches(X_val, y_val, valid_data=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.270382Z","iopub.execute_input":"2021-06-28T08:42:18.270877Z","iopub.status.idle":"2021-06-28T08:42:18.476481Z","shell.execute_reply.started":"2021-06-28T08:42:18.270827Z","shell.execute_reply":"2021-06-28T08:42:18.475239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check out the different attributes of our data batches\ntrain_data.element_spec, val_data.element_spec","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.477961Z","iopub.execute_input":"2021-06-28T08:42:18.478318Z","iopub.status.idle":"2021-06-28T08:42:18.487314Z","shell.execute_reply.started":"2021-06-28T08:42:18.478284Z","shell.execute_reply":"2021-06-28T08:42:18.485827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualisation pour comprendre les batches","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Create a function for viewing images in a data batch\ndef show_25_images(images, labels):\n  \"\"\"\n  Displays 25 images from a data batch.\n  \"\"\"\n  # Setup the figure\n  plt.figure(figsize=(10, 10))\n  # Loop through 25 (for displaying 25 images)\n  for i in range(25):\n    # Create subplots (5 rows, 5 columns)\n    ax = plt.subplot(5, 5, i+1)\n    # Display an image\n    plt.imshow(images[i])\n    # Add the image label as the title\n    plt.title(unique_breed[labels[i].argmax()])\n    # Turn gird lines off\n    plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.490284Z","iopub.execute_input":"2021-06-28T08:42:18.491049Z","iopub.status.idle":"2021-06-28T08:42:18.502601Z","shell.execute_reply.started":"2021-06-28T08:42:18.490975Z","shell.execute_reply":"2021-06-28T08:42:18.501042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize training images from the training data batch\ntrain_images, train_labels = next(train_data.as_numpy_iterator())\nshow_25_images(train_images, train_labels)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:18.504619Z","iopub.execute_input":"2021-06-28T08:42:18.505130Z","iopub.status.idle":"2021-06-28T08:42:20.484547Z","shell.execute_reply.started":"2021-06-28T08:42:18.505074Z","shell.execute_reply":"2021-06-28T08:42:20.483457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize validation images from the validation data batch\nval_images, val_labels = next(val_data.as_numpy_iterator())\nshow_25_images(val_images, val_labels)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:20.485936Z","iopub.execute_input":"2021-06-28T08:42:20.486558Z","iopub.status.idle":"2021-06-28T08:42:22.563966Z","shell.execute_reply.started":"2021-06-28T08:42:20.486510Z","shell.execute_reply":"2021-06-28T08:42:22.563111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating and training a model.\n\nNow our data is ready now lets model our data.\n\nBefore we build a model, there are a few things we need to define:\n\n    The input shape (images, in the form of Tensors) to our model.\n    The output shape (image labels, in the form of Tensors) of our model.\n\n","metadata":{}},{"cell_type":"code","source":"# Setting up input shape to the model\nINPUT_SHAPE = [BATCH_SIZE, IMG_SIZE, IMG_SIZE, 3] # batch, height, width, colour channels\n\n# Setting up output shape of the model\nOUTPUT_SHAPE = len(unique_breed) # number of unique labels","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:22.565069Z","iopub.execute_input":"2021-06-28T08:42:22.565494Z","iopub.status.idle":"2021-06-28T08:42:22.569047Z","shell.execute_reply.started":"2021-06-28T08:42:22.565463Z","shell.execute_reply":"2021-06-28T08:42:22.568268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_SHAPE","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:22.569979Z","iopub.execute_input":"2021-06-28T08:42:22.570427Z","iopub.status.idle":"2021-06-28T08:42:22.584573Z","shell.execute_reply.started":"2021-06-28T08:42:22.570396Z","shell.execute_reply":"2021-06-28T08:42:22.583795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\npretrained_base = keras.applications.MobileNetV2(\n    input_shape = (224,224,3),\n    include_top=False, weights='imagenet'\n)\n\npretrained_base.trainable = False","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:22.585643Z","iopub.execute_input":"2021-06-28T08:42:22.586120Z","iopub.status.idle":"2021-06-28T08:42:24.058988Z","shell.execute_reply.started":"2021-06-28T08:42:22.586087Z","shell.execute_reply":"2021-06-28T08:42:24.057841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_augmentation = tf.keras.Sequential([\n  tf.keras.layers.experimental.preprocessing.RandomFlip(\"horizontal_and_vertical\"),\n  tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),\n])","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.060342Z","iopub.execute_input":"2021-06-28T08:42:24.060698Z","iopub.status.idle":"2021-06-28T08:42:24.081245Z","shell.execute_reply.started":"2021-06-28T08:42:24.060666Z","shell.execute_reply":"2021-06-28T08:42:24.080113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import layers\n\nmodel = keras.Sequential([\n    data_augmentation,\n    pretrained_base,\n    layers.Flatten(),\n    #layers.Dense(6, activation='relu'),\n    layers.Dense(120, activation='softmax'),\n])","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.082817Z","iopub.execute_input":"2021-06-28T08:42:24.083257Z","iopub.status.idle":"2021-06-28T08:42:24.100946Z","shell.execute_reply.started":"2021-06-28T08:42:24.083212Z","shell.execute_reply":"2021-06-28T08:42:24.099923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Compile the model\nmodel.compile(\n      loss=tf.keras.losses.CategoricalCrossentropy(), # Our model wants to reduce this (how wrong its guesses are)\n      optimizer=tf.keras.optimizers.Adam(), # A friend telling our model how to improve its guesses\n      metrics=[\"accuracy\"] # We'd like this to go up\n  )","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.104922Z","iopub.execute_input":"2021-06-28T08:42:24.105313Z","iopub.status.idle":"2021-06-28T08:42:24.125550Z","shell.execute_reply.started":"2021-06-28T08:42:24.105278Z","shell.execute_reply":"2021-06-28T08:42:24.124462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check details of model\n#model.summary()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"early_stopping = tf.keras.callbacks.EarlyStopping(\n    patience=5,\n    min_delta=0.01,\n    restore_best_weights=True,\n    )","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:45:03.371854Z","iopub.execute_input":"2021-06-28T08:45:03.372259Z","iopub.status.idle":"2021-06-28T08:45:03.377601Z","shell.execute_reply.started":"2021-06-28T08:45:03.372223Z","shell.execute_reply":"2021-06-28T08:45:03.376339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history =  model.fit(\n            x=train_data,\n            epochs=10,\n            validation_data=val_data,\n            validation_freq=1, # check validation metrics every epoch\n            verbose=1,\n            callbacks=[early_stopping])","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:45:04.950045Z","iopub.execute_input":"2021-06-28T08:45:04.950669Z","iopub.status.idle":"2021-06-28T08:48:34.246756Z","shell.execute_reply.started":"2021-06-28T08:45:04.950630Z","shell.execute_reply":"2021-06-28T08:48:34.245421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_df = pd.DataFrame(history.history)\nhistory_df.loc[:, ['loss', 'val_loss']].plot();","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:48:34.248536Z","iopub.execute_input":"2021-06-28T08:48:34.248840Z","iopub.status.idle":"2021-06-28T08:48:34.430761Z","shell.execute_reply.started":"2021-06-28T08:48:34.248810Z","shell.execute_reply":"2021-06-28T08:48:34.429898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_df.loc[:, ['accuracy', 'val_accuracy']].plot();","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:48:34.432584Z","iopub.execute_input":"2021-06-28T08:48:34.433237Z","iopub.status.idle":"2021-06-28T08:48:34.612531Z","shell.execute_reply.started":"2021-06-28T08:48:34.433188Z","shell.execute_reply":"2021-06-28T08:48:34.611796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(val_data, verbose=1) # verbose shows us how long there is to go\npredictions","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:48:34.613920Z","iopub.execute_input":"2021-06-28T08:48:34.614555Z","iopub.status.idle":"2021-06-28T08:48:40.728492Z","shell.execute_reply.started":"2021-06-28T08:48:34.614505Z","shell.execute_reply":"2021-06-28T08:48:40.727439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# First prediction\nprint(predictions[0])\nprint(f\"Max value (probability of prediction): {np.max(predictions[0])}\") # the max probability value predicted by the model\nprint(f\"Sum: {np.sum(predictions[0])}\") # because we used softmax activation in our model, this will be close to 1\nprint(f\"Max index: {np.argmax(predictions[0])}\") # the index of where the max value in predictions[0] occurs\nprint(f\"Predicted label: {unique_breed[np.argmax(predictions[0])]}\") # the predicted label","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:27.248971Z","iopub.execute_input":"2021-06-28T08:49:27.249592Z","iopub.status.idle":"2021-06-28T08:49:27.259754Z","shell.execute_reply.started":"2021-06-28T08:49:27.249542Z","shell.execute_reply":"2021-06-28T08:49:27.258721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Turn prediction probabilities into their respective label (easier to understand)\ndef get_pred_label(prediction_probabilities):\n  \"\"\"\n  Turns an array of prediction probabilities into a label.\n  \"\"\"\n  return unique_breed[np.argmax(prediction_probabilities)]\n\n# Get a predicted label based on an array of prediction probabilities\npred_label = get_pred_label(predictions[0])\npred_label","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:30.991063Z","iopub.execute_input":"2021-06-28T08:49:30.991418Z","iopub.status.idle":"2021-06-28T08:49:30.999666Z","shell.execute_reply.started":"2021-06-28T08:49:30.991385Z","shell.execute_reply":"2021-06-28T08:49:30.998288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a function to unbatch a batched dataset\ndef unbatchify(data):\n  \"\"\"\n  Takes a batched dataset of (image, label) Tensors and returns separate arrays\n  of images and labels.\n  \"\"\"\n  images = []\n  labels = []\n  # Loop through unbatched data\n  for image, label in data.unbatch().as_numpy_iterator():\n    images.append(image)\n    labels.append(unique_breed[np.argmax(label)])\n  return images, labels\n\n# Unbatchify the validation data\nval_images, val_labels = unbatchify(val_data)\nval_images[0], val_labels[0]","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:33.870093Z","iopub.execute_input":"2021-06-28T08:49:33.870490Z","iopub.status.idle":"2021-06-28T08:49:34.758587Z","shell.execute_reply.started":"2021-06-28T08:49:33.870455Z","shell.execute_reply":"2021-06-28T08:49:34.757479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_pred(prediction_probabilities, labels, images, n=1):\n  \"\"\"\n  View the prediction, ground truth label and image for sample n.\n  \"\"\"\n  pred_prob, true_label, image = prediction_probabilities[n], labels[n], images[n]\n  \n  # Get the pred label\n  pred_label = get_pred_label(pred_prob)\n  \n  # Plot image & remove ticks\n  plt.imshow(image)\n  plt.xticks([])\n  plt.yticks([])\n\n  # Change the color of the title depending on if the prediction is right or wrong\n  if pred_label == true_label:\n    color = \"green\"\n  else:\n    color = \"red\"\n\n  plt.title(\"{} {:2.0f}% ({})\".format(pred_label,\n                                      np.max(pred_prob)*100,\n                                      true_label),\n                                      color=color)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:39.445295Z","iopub.execute_input":"2021-06-28T08:49:39.445782Z","iopub.status.idle":"2021-06-28T08:49:39.454455Z","shell.execute_reply.started":"2021-06-28T08:49:39.445746Z","shell.execute_reply":"2021-06-28T08:49:39.452781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# View an example prediction, original image and truth label\nplot_pred(prediction_probabilities=predictions,\n          labels=val_labels,\n          images=val_images)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:42.108565Z","iopub.execute_input":"2021-06-28T08:49:42.109113Z","iopub.status.idle":"2021-06-28T08:49:42.215745Z","shell.execute_reply.started":"2021-06-28T08:49:42.109073Z","shell.execute_reply":"2021-06-28T08:49:42.214549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_pred(prediction_probabilities=predictions,\n          labels=val_labels,\n          images=val_images, n=2)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:45.026362Z","iopub.execute_input":"2021-06-28T08:49:45.026769Z","iopub.status.idle":"2021-06-28T08:49:45.121433Z","shell.execute_reply.started":"2021-06-28T08:49:45.026732Z","shell.execute_reply":"2021-06-28T08:49:45.120237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_pred(prediction_probabilities=predictions,\n          labels=val_labels,\n          images=val_images, n=3)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:49.586098Z","iopub.execute_input":"2021-06-28T08:49:49.586511Z","iopub.status.idle":"2021-06-28T08:49:49.689351Z","shell.execute_reply.started":"2021-06-28T08:49:49.586476Z","shell.execute_reply":"2021-06-28T08:49:49.688257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_pred(prediction_probabilities=predictions,\n          labels=val_labels,\n          images=val_images, n=42)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:49:53.681027Z","iopub.execute_input":"2021-06-28T08:49:53.681478Z","iopub.status.idle":"2021-06-28T08:49:53.791682Z","shell.execute_reply.started":"2021-06-28T08:49:53.681435Z","shell.execute_reply":"2021-06-28T08:49:53.790054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Predicted label: {unique_breed[np.argmax(predictions[0])]}\") # the predicted label","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.525204Z","iopub.status.idle":"2021-06-28T08:42:24.525779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.526954Z","iopub.status.idle":"2021-06-28T08:42:24.527413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_labels=[]\nfor i in range(200): \n    pred_labels.append(get_pred_label(predictions[i]))","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.528386Z","iopub.status.idle":"2021-06-28T08:42:24.528828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_labels","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.529693Z","iopub.status.idle":"2021-06-28T08:42:24.530125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"true_labels=[]\nfor i in range(200): \n    true_labels.append(labels[i])","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.531121Z","iopub.status.idle":"2021-06-28T08:42:24.531549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"true_labels","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.532433Z","iopub.status.idle":"2021-06-28T08:42:24.532923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import classification_report\n\nprint(classification_report(true_labels, pred_labels))","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.533786Z","iopub.status.idle":"2021-06-28T08:42:24.534246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score\naccuracy_score(true_labels, pred_labels)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.535260Z","iopub.status.idle":"2021-06-28T08:42:24.535775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nconfusion_matrix(true_labels, pred_labels)","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.536627Z","iopub.status.idle":"2021-06-28T08:42:24.537076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_labels=[]\nfor i in range(200): \n    pred_labels.append(get_pred_label(predictions[i]))\ny_test=val_labels\ny_pred=pred_labels\n#importing confusion matrix\nfrom sklearn.metrics import confusion_matrix\nconfusion = confusion_matrix(val_labels, pred_labels)\nprint('Confusion Matrix\\n')\nprint(confusion)\n\n#importing accuracy_score, precision_score, recall_score, f1_score\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score\nprint('\\nAccuracy: {:.2f}\\n'.format(accuracy_score(y_test, y_pred)))\n\nprint('Micro Precision: {:.2f}'.format(precision_score(y_test, y_pred, average='micro')))\nprint('Micro Recall: {:.2f}'.format(recall_score(y_test, y_pred, average='micro')))\nprint('Micro F1-score: {:.2f}\\n'.format(f1_score(y_test, y_pred, average='micro')))\n\nprint('Macro Precision: {:.2f}'.format(precision_score(y_test, y_pred, average='macro')))\nprint('Macro Recall: {:.2f}'.format(recall_score(y_test, y_pred, average='macro')))\nprint('Macro F1-score: {:.2f}\\n'.format(f1_score(y_test, y_pred, average='macro')))\n\nprint('Weighted Precision: {:.2f}'.format(precision_score(y_test, y_pred, average='weighted')))\nprint('Weighted Recall: {:.2f}'.format(recall_score(y_test, y_pred, average='weighted')))\nprint('Weighted F1-score: {:.2f}'.format(f1_score(y_test, y_pred, average='weighted')))\n\nfrom sklearn.metrics import classification_report\nprint('\\nClassification Report\\n')\nprint(classification_report(y_test, y_pred))","metadata":{"execution":{"iopub.status.busy":"2021-06-28T08:42:24.537888Z","iopub.status.idle":"2021-06-28T08:42:24.538339Z"},"trusted":true},"execution_count":null,"outputs":[]}]}