{"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":"markdown","source":"# Dog Breed classification","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport tensorflow as tf\nimport tensorflow_hub as hub\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D , MaxPool2D , Flatten , Dropout ","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:30.325023Z","iopub.execute_input":"2021-06-11T07:44:30.325371Z","iopub.status.idle":"2021-06-11T07:44:30.333035Z","shell.execute_reply.started":"2021-06-11T07:44:30.325340Z","shell.execute_reply":"2021-06-11T07:44:30.331780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data","metadata":{}},{"cell_type":"code","source":"#show labels\n\nlabels_df = pd.read_csv('../input/dog-breed-identification/labels.csv')\nlabels_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:30.349880Z","iopub.execute_input":"2021-06-11T07:44:30.350230Z","iopub.status.idle":"2021-06-11T07:44:30.375970Z","shell.execute_reply.started":"2021-06-11T07:44:30.350196Z","shell.execute_reply":"2021-06-11T07:44:30.374977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_df.describe()","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:30.377517Z","iopub.execute_input":"2021-06-11T07:44:30.377838Z","iopub.status.idle":"2021-06-11T07:44:30.409309Z","shell.execute_reply.started":"2021-06-11T07:44:30.377807Z","shell.execute_reply":"2021-06-11T07:44:30.408164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# visualize data\n\nlabels_df['breed'].value_counts().plot.bar(figsize=(10,10))","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:30.410818Z","iopub.execute_input":"2021-06-11T07:44:30.411128Z","iopub.status.idle":"2021-06-11T07:44:32.811756Z","shell.execute_reply.started":"2021-06-11T07:44:30.411097Z","shell.execute_reply":"2021-06-11T07:44:32.810796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_df['breed'].value_counts().median()","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.813231Z","iopub.execute_input":"2021-06-11T07:44:32.813498Z","iopub.status.idle":"2021-06-11T07:44:32.822809Z","shell.execute_reply.started":"2021-06-11T07:44:32.813472Z","shell.execute_reply":"2021-06-11T07:44:32.822116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#show one image\nfrom IPython.display import Image\nImage('../input/dog-breed-identification/train/001cdf01b096e06d78e9e5112d419397.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.823800Z","iopub.execute_input":"2021-06-11T07:44:32.824075Z","iopub.status.idle":"2021-06-11T07:44:32.843518Z","shell.execute_reply.started":"2021-06-11T07:44:32.824049Z","shell.execute_reply":"2021-06-11T07:44:32.842522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Format data","metadata":{"execution":{"iopub.status.busy":"2021-06-08T07:26:33.659309Z","iopub.execute_input":"2021-06-08T07:26:33.660069Z","iopub.status.idle":"2021-06-08T07:26:33.664414Z","shell.execute_reply.started":"2021-06-08T07:26:33.66002Z","shell.execute_reply":"2021-06-08T07:26:33.663349Z"}}},{"cell_type":"code","source":"#create image path in data\n\nfilenames = [\"../input/dog-breed-identification/train/\" + fname + \".jpg\"for fname in labels_df['id']]\nfilenames[22]","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.846022Z","iopub.execute_input":"2021-06-11T07:44:32.846336Z","iopub.status.idle":"2021-06-11T07:44:32.860047Z","shell.execute_reply.started":"2021-06-11T07:44:32.846307Z","shell.execute_reply":"2021-06-11T07:44:32.859326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# verify each image has is  path\n\nimport os\n\nif len(os.listdir(\"../input/dog-breed-identification/train/\")) == len (filenames):\n    print (\"ok\")\nelse:\n    print (\"not ok\")","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.861847Z","iopub.execute_input":"2021-06-11T07:44:32.862289Z","iopub.status.idle":"2021-06-11T07:44:32.879641Z","shell.execute_reply.started":"2021-06-11T07:44:32.862251Z","shell.execute_reply":"2021-06-11T07:44:32.878807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check one image and is label\n\nImage(filenames[25])","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.880874Z","iopub.execute_input":"2021-06-11T07:44:32.881359Z","iopub.status.idle":"2021-06-11T07:44:32.891083Z","shell.execute_reply.started":"2021-06-11T07:44:32.881324Z","shell.execute_reply":"2021-06-11T07:44:32.890360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(labels_df['breed'][25])","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.892399Z","iopub.execute_input":"2021-06-11T07:44:32.892841Z","iopub.status.idle":"2021-06-11T07:44:32.899820Z","shell.execute_reply.started":"2021-06-11T07:44:32.892808Z","shell.execute_reply":"2021-06-11T07:44:32.898888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## turning data into numbers","metadata":{}},{"cell_type":"code","source":"# tunr labels into numpy array\n\nlabels = labels_df['breed']\nlabels = np.array(labels)\nlabels","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.901416Z","iopub.execute_input":"2021-06-11T07:44:32.902093Z","iopub.status.idle":"2021-06-11T07:44:32.915561Z","shell.execute_reply.started":"2021-06-11T07:44:32.901969Z","shell.execute_reply":"2021-06-11T07:44:32.914367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check everything is ok\n\nif len(labels) == len(filenames):\n    print('everything is ok')\nelse:\n    print ('ouch')","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.917089Z","iopub.execute_input":"2021-06-11T07:44:32.917570Z","iopub.status.idle":"2021-06-11T07:44:32.929837Z","shell.execute_reply.started":"2021-06-11T07:44:32.917529Z","shell.execute_reply":"2021-06-11T07:44:32.928547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# labels encoding\n\nunique_breed = np.unique(labels)\nunique_breed","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:32.931196Z","iopub.execute_input":"2021-06-11T07:44:32.931495Z","iopub.status.idle":"2021-06-11T07:44:32.957574Z","shell.execute_reply.started":"2021-06-11T07:44:32.931467Z","shell.execute_reply":"2021-06-11T07:44:32.956577Z"},"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-11T07:44:32.958642Z","iopub.execute_input":"2021-06-11T07:44:32.959014Z","iopub.status.idle":"2021-06-11T07:44:32.972804Z","shell.execute_reply.started":"2021-06-11T07:44:32.958986Z","shell.execute_reply":"2021-06-11T07:44:32.972093Z"},"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-11T07:44:32.975357Z","iopub.execute_input":"2021-06-11T07:44:32.975683Z","iopub.status.idle":"2021-06-11T07:44:33.091526Z","shell.execute_reply.started":"2021-06-11T07:44:32.975655Z","shell.execute_reply":"2021-06-11T07:44:33.090502Z"},"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-11T07:44:33.093385Z","iopub.execute_input":"2021-06-11T07:44:33.093725Z","iopub.status.idle":"2021-06-11T07:44:33.101145Z","shell.execute_reply.started":"2021-06-11T07:44:33.093694Z","shell.execute_reply":"2021-06-11T07:44:33.100041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## creating sets","metadata":{}},{"cell_type":"code","source":"# setup x and y variables.\nX = filenames\ny = boolean_labels","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:33.102665Z","iopub.execute_input":"2021-06-11T07:44:33.103338Z","iopub.status.idle":"2021-06-11T07:44:33.118211Z","shell.execute_reply.started":"2021-06-11T07:44:33.103296Z","shell.execute_reply":"2021-06-11T07:44:33.117210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#just a sample\nNUM_IMAGES = 1000 ","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:33.119426Z","iopub.execute_input":"2021-06-11T07:44:33.119708Z","iopub.status.idle":"2021-06-11T07:44:33.131082Z","shell.execute_reply.started":"2021-06-11T07:44:33.119682Z","shell.execute_reply":"2021-06-11T07:44:33.130072Z"},"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-11T07:44:33.132791Z","iopub.execute_input":"2021-06-11T07:44:33.133263Z","iopub.status.idle":"2021-06-11T07:44:33.147325Z","shell.execute_reply.started":"2021-06-11T07:44:33.133211Z","shell.execute_reply":"2021-06-11T07:44:33.146257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocessing\n\n\nPreprocessing Images\n\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\n","metadata":{}},{"cell_type":"code","source":"from matplotlib.pyplot import imread\nimage = imread(filenames[42])\nimage.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:33.149319Z","iopub.execute_input":"2021-06-11T07:44:33.149602Z","iopub.status.idle":"2021-06-11T07:44:33.162412Z","shell.execute_reply.started":"2021-06-11T07:44:33.149574Z","shell.execute_reply":"2021-06-11T07:44:33.161320Z"},"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-11T07:44:33.164536Z","iopub.execute_input":"2021-06-11T07:44:33.165336Z","iopub.status.idle":"2021-06-11T07:44:33.177026Z","shell.execute_reply.started":"2021-06-11T07:44:33.165290Z","shell.execute_reply":"2021-06-11T07:44:33.176110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fonction for preprocessing\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-11T07:44:33.178519Z","iopub.execute_input":"2021-06-11T07:44:33.178882Z","iopub.status.idle":"2021-06-11T07:44:33.186907Z","shell.execute_reply.started":"2021-06-11T07:44:33.178850Z","shell.execute_reply":"2021-06-11T07:44:33.185918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## creat batches","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-11T07:44:33.188301Z","iopub.execute_input":"2021-06-11T07:44:33.188614Z","iopub.status.idle":"2021-06-11T07:44:33.200256Z","shell.execute_reply.started":"2021-06-11T07:44:33.188574Z","shell.execute_reply":"2021-06-11T07:44:33.199375Z"},"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-11T07:44:33.201588Z","iopub.execute_input":"2021-06-11T07:44:33.202169Z","iopub.status.idle":"2021-06-11T07:44:33.213274Z","shell.execute_reply.started":"2021-06-11T07:44:33.202136Z","shell.execute_reply":"2021-06-11T07:44:33.212181Z"},"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-11T07:44:33.214656Z","iopub.execute_input":"2021-06-11T07:44:33.214966Z","iopub.status.idle":"2021-06-11T07:44:33.331975Z","shell.execute_reply.started":"2021-06-11T07:44:33.214937Z","shell.execute_reply":"2021-06-11T07:44:33.330889Z"},"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-11T07:44:33.333312Z","iopub.execute_input":"2021-06-11T07:44:33.333611Z","iopub.status.idle":"2021-06-11T07:44:33.338902Z","shell.execute_reply.started":"2021-06-11T07:44:33.333580Z","shell.execute_reply":"2021-06-11T07:44:33.338215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## create model","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\n\n\nbase_model = tf.keras.applications.MobileNetV2(input_shape = INPUT_SHAPE[1:], include_top = False, weights = \"imagenet\")\nbase_model.trainable = False","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:33.340038Z","iopub.execute_input":"2021-06-11T07:44:33.340466Z","iopub.status.idle":"2021-06-11T07:44:34.448965Z","shell.execute_reply.started":"2021-06-11T07:44:33.340434Z","shell.execute_reply":"2021-06-11T07:44:34.448226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Setup the model layers\nmodel = tf.keras.Sequential([base_model,   \n                             tf.keras.layers.Flatten(),\n                             tf.keras.layers.Dense(OUTPUT_SHAPE, activation=\"softmax\")                                  \n                            ])\n\n\n\n# 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)\n\n# Build the model\nmodel.build(INPUT_SHAPE) # Let the model know what kind of inputs it'll be getting","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:34.450260Z","iopub.execute_input":"2021-06-11T07:44:34.450745Z","iopub.status.idle":"2021-06-11T07:44:34.885600Z","shell.execute_reply.started":"2021-06-11T07:44:34.450714Z","shell.execute_reply":"2021-06-11T07:44:34.884561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create early stopping (once our model stops improving, stop training)\nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor=\"val_accuracy\",\n                                                  patience=3) # stops after 3 rounds of no improvements","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:34.886967Z","iopub.execute_input":"2021-06-11T07:44:34.887251Z","iopub.status.idle":"2021-06-11T07:44:34.893699Z","shell.execute_reply.started":"2021-06-11T07:44:34.887223Z","shell.execute_reply":"2021-06-11T07:44:34.892686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_EPOCHS = 100\n\n# Fit the model to the data passing it the callbacks we created\nhistory = model.fit(x=train_data,\n    epochs=NUM_EPOCHS,\n    validation_data=val_data,\n    validation_freq=1, # check validation metrics every epoch\n    callbacks=early_stopping)\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:44:34.895033Z","iopub.execute_input":"2021-06-11T07:44:34.895364Z","iopub.status.idle":"2021-06-11T07:47:46.371007Z","shell.execute_reply.started":"2021-06-11T07:44:34.895332Z","shell.execute_reply":"2021-06-11T07:47:46.369835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_df = pd.DataFrame(history.history)\nhistory_df.loc[:, ['loss', 'val_loss']].plot();\nhistory_df.loc[:, ['accuracy', 'val_accuracy']].plot();","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:47:46.372672Z","iopub.execute_input":"2021-06-11T07:47:46.372991Z","iopub.status.idle":"2021-06-11T07:47:46.719208Z","shell.execute_reply.started":"2021-06-11T07:47:46.372959Z","shell.execute_reply":"2021-06-11T07:47:46.718290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make predictions on the validation data (not used to train on)\npredictions = model.predict(val_data, verbose=1) # verbose shows us how long there is to go\n# predictions","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:47:46.720499Z","iopub.execute_input":"2021-06-11T07:47:46.720794Z","iopub.status.idle":"2021-06-11T07:47:52.699519Z","shell.execute_reply.started":"2021-06-11T07:47:46.720767Z","shell.execute_reply":"2021-06-11T07:47:52.698551Z"},"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","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:54:23.505399Z","iopub.execute_input":"2021-06-11T07:54:23.505799Z","iopub.status.idle":"2021-06-11T07:54:23.510275Z","shell.execute_reply.started":"2021-06-11T07:54:23.505762Z","shell.execute_reply":"2021-06-11T07:54:23.509457Z"},"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)\n# val_images[0], val_labels[0]","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:54:25.252817Z","iopub.execute_input":"2021-06-11T07:54:25.253352Z","iopub.status.idle":"2021-06-11T07:54:26.151230Z","shell.execute_reply.started":"2021-06-11T07:54:25.253320Z","shell.execute_reply":"2021-06-11T07:54:26.150215Z"},"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-11T07:54:28.684883Z","iopub.execute_input":"2021-06-11T07:54:28.685311Z","iopub.status.idle":"2021-06-11T07:54:28.692552Z","shell.execute_reply.started":"2021-06-11T07:54:28.685272Z","shell.execute_reply":"2021-06-11T07:54:28.691325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_pred(predictions, val_labels, val_images, n=7)","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:54:33.701572Z","iopub.execute_input":"2021-06-11T07:54:33.702026Z","iopub.status.idle":"2021-06-11T07:54:33.806670Z","shell.execute_reply.started":"2021-06-11T07:54:33.701982Z","shell.execute_reply":"2021-06-11T07:54:33.805750Z"},"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))\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T07:54:40.849818Z","iopub.execute_input":"2021-06-11T07:54:40.850159Z","iopub.status.idle":"2021-06-11T07:54:40.921142Z","shell.execute_reply.started":"2021-06-11T07:54:40.850130Z","shell.execute_reply":"2021-06-11T07:54:40.920371Z"},"trusted":true},"execution_count":null,"outputs":[]}]}