{"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":"markdown","source":"## Imports","metadata":{"execution":{"iopub.status.busy":"2021-06-10T13:46:25.465915Z","iopub.execute_input":"2021-06-10T13:46:25.466526Z","iopub.status.idle":"2021-06-10T13:46:25.47009Z","shell.execute_reply.started":"2021-06-10T13:46:25.466472Z","shell.execute_reply":"2021-06-10T13:46:25.469269Z"}}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport tensorflow_hub as hub\nimport keras\nimport os\nimport albumentations as A\nimport PIL\n\n\n%matplotlib inline\n\nfrom PIL import Image as PIL_Image\nfrom numpy import asarray\nfrom albumentations.pytorch import ToTensorV2 \nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom IPython.display import Image\nfrom functools import partial\nfrom matplotlib.pyplot import imread\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D , MaxPool2D , Flatten , Dropout \nfrom sklearn.metrics import classification_report\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score\nfrom sklearn.metrics import confusion_matrix","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:06.411673Z","iopub.execute_input":"2021-06-11T14:55:06.412235Z","iopub.status.idle":"2021-06-11T14:55:06.429500Z","shell.execute_reply.started":"2021-06-11T14:55:06.412194Z","shell.execute_reply":"2021-06-11T14:55:06.427045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Constants","metadata":{}},{"cell_type":"code","source":"#just a sample\nNUM_IMAGES = 3000\n\n# Define image size\nIMG_SIZE = 224\n\n# Define the batch size, 32 is a good default\nBATCH_SIZE = 32\n\nAUTOTUNE = tf.data.experimental.AUTOTUNE","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2021-06-11T14:55:06.431630Z","iopub.execute_input":"2021-06-11T14:55:06.432370Z","iopub.status.idle":"2021-06-11T14:55:06.454700Z","shell.execute_reply.started":"2021-06-11T14:55:06.432327Z","shell.execute_reply":"2021-06-11T14:55:06.453528Z"},"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-11T14:55:06.460491Z","iopub.execute_input":"2021-06-11T14:55:06.461042Z","iopub.status.idle":"2021-06-11T14:55:06.499295Z","shell.execute_reply.started":"2021-06-11T14:55:06.460989Z","shell.execute_reply":"2021-06-11T14:55:06.498175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_df.describe()","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:06.501317Z","iopub.execute_input":"2021-06-11T14:55:06.501989Z","iopub.status.idle":"2021-06-11T14:55:06.533745Z","shell.execute_reply.started":"2021-06-11T14:55:06.501942Z","shell.execute_reply":"2021-06-11T14:55:06.532710Z"},"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-11T14:55:06.535629Z","iopub.execute_input":"2021-06-11T14:55:06.535978Z","iopub.status.idle":"2021-06-11T14:55:08.891171Z","shell.execute_reply.started":"2021-06-11T14:55:06.535945Z","shell.execute_reply":"2021-06-11T14:55:08.889343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#show one image\n\nImage('../input/dog-breed-identification/train/001cdf01b096e06d78e9e5112d419397.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:08.893351Z","iopub.execute_input":"2021-06-11T14:55:08.893775Z","iopub.status.idle":"2021-06-11T14:55:08.908770Z","shell.execute_reply.started":"2021-06-11T14:55:08.893739Z","shell.execute_reply":"2021-06-11T14:55:08.906592Z"},"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-11T14:55:08.911430Z","iopub.execute_input":"2021-06-11T14:55:08.912274Z","iopub.status.idle":"2021-06-11T14:55:08.927502Z","shell.execute_reply.started":"2021-06-11T14:55:08.912223Z","shell.execute_reply":"2021-06-11T14:55:08.925460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# verify each image has is  path\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-11T14:55:08.929501Z","iopub.execute_input":"2021-06-11T14:55:08.930087Z","iopub.status.idle":"2021-06-11T14:55:08.948434Z","shell.execute_reply.started":"2021-06-11T14:55:08.930044Z","shell.execute_reply":"2021-06-11T14:55:08.946347Z"},"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-11T14:55:08.952455Z","iopub.execute_input":"2021-06-11T14:55:08.953040Z","iopub.status.idle":"2021-06-11T14:55:08.964934Z","shell.execute_reply.started":"2021-06-11T14:55:08.952981Z","shell.execute_reply":"2021-06-11T14:55:08.963489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(labels_df['breed'][25])","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:08.967197Z","iopub.execute_input":"2021-06-11T14:55:08.967656Z","iopub.status.idle":"2021-06-11T14:55:08.975917Z","shell.execute_reply.started":"2021-06-11T14:55:08.967605Z","shell.execute_reply":"2021-06-11T14:55:08.974772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## turning labels 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-11T14:55:08.977718Z","iopub.execute_input":"2021-06-11T14:55:08.978494Z","iopub.status.idle":"2021-06-11T14:55:08.992471Z","shell.execute_reply.started":"2021-06-11T14:55:08.978441Z","shell.execute_reply":"2021-06-11T14:55:08.991650Z"},"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-11T14:55:08.993869Z","iopub.execute_input":"2021-06-11T14:55:08.994419Z","iopub.status.idle":"2021-06-11T14:55:09.012571Z","shell.execute_reply.started":"2021-06-11T14:55:08.994382Z","shell.execute_reply":"2021-06-11T14:55:09.011085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# labels encoding\n\nunique_breed = np.unique(labels)\nlen(unique_breed)","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.014367Z","iopub.execute_input":"2021-06-11T14:55:09.014703Z","iopub.status.idle":"2021-06-11T14:55:09.038988Z","shell.execute_reply.started":"2021-06-11T14:55:09.014671Z","shell.execute_reply":"2021-06-11T14:55:09.037761Z"},"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-11T14:55:09.040501Z","iopub.execute_input":"2021-06-11T14:55:09.041127Z","iopub.status.idle":"2021-06-11T14:55:09.170294Z","shell.execute_reply.started":"2021-06-11T14:55:09.041087Z","shell.execute_reply":"2021-06-11T14:55:09.168730Z"},"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-11T14:55:09.174973Z","iopub.execute_input":"2021-06-11T14:55:09.175538Z","iopub.status.idle":"2021-06-11T14:55:09.188581Z","shell.execute_reply.started":"2021-06-11T14:55:09.175493Z","shell.execute_reply":"2021-06-11T14:55:09.186600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## creating sets","metadata":{}},{"cell_type":"code","source":"# setup x and y variables.\n\nX = filenames\ny = boolean_labels","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.192183Z","iopub.execute_input":"2021-06-11T14:55:09.192960Z","iopub.status.idle":"2021-06-11T14:55:09.220216Z","shell.execute_reply.started":"2021-06-11T14:55:09.192894Z","shell.execute_reply":"2021-06-11T14:55:09.217332Z"},"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-11T14:55:09.223653Z","iopub.execute_input":"2021-06-11T14:55:09.224552Z","iopub.status.idle":"2021-06-11T14:55:09.262112Z","shell.execute_reply.started":"2021-06-11T14:55:09.224398Z","shell.execute_reply":"2021-06-11T14:55:09.260177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocessing \n","metadata":{}},{"cell_type":"code","source":"# show shape from one image\n\nimage = imread(filenames[42])\nimage.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.266712Z","iopub.execute_input":"2021-06-11T14:55:09.267554Z","iopub.status.idle":"2021-06-11T14:55:09.283635Z","shell.execute_reply.started":"2021-06-11T14:55:09.267487Z","shell.execute_reply":"2021-06-11T14:55:09.282096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#lets conver them into tensor\n# tf.constant(image)[:2]","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.285180Z","iopub.execute_input":"2021-06-11T14:55:09.285541Z","iopub.status.idle":"2021-06-11T14:55:09.295277Z","shell.execute_reply.started":"2021-06-11T14:55:09.285507Z","shell.execute_reply":"2021-06-11T14:55:09.293361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def transfrom_image(image_path):    \n#     transform = A.Compose(\n#         [A.CLAHE(),\n#          A.RandomRotate90(),\n#          A.Transpose(),\n#          A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.50,\n#                             rotate_limit=45, p=.75),\n#          A.Blur(blur_limit=3),\n#          A.OpticalDistortion(),\n#          A.GridDistortion(),\n#          A.HueSaturationValue()\n#         ]      \n#     )\n#     image = image_to_array(image_path)\n#     augmented_image = transform(image=image)['image']\n    \n#     return augmented_image","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.300407Z","iopub.execute_input":"2021-06-11T14:55:09.300865Z","iopub.status.idle":"2021-06-11T14:55:09.311325Z","shell.execute_reply.started":"2021-06-11T14:55:09.300825Z","shell.execute_reply":"2021-06-11T14:55:09.310185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def image_to_array(image_path):\n#     \"\"\"Return array that represents the images\"\"\"\n    \n#     image = tf.keras.preprocessing.image.load_img(image_path)\n#     input_arr = keras.preprocessing.image.img_to_array(image)\n#     image = np.array([input_arr])\n   \n#     return image\n    ","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.313514Z","iopub.execute_input":"2021-06-11T14:55:09.313883Z","iopub.status.idle":"2021-06-11T14:55:09.333200Z","shell.execute_reply.started":"2021-06-11T14:55:09.313846Z","shell.execute_reply":"2021-06-11T14:55:09.330747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def process_image(image_path):\n    \"\"\"\n    Takes an image file path and turns it into a Tensor.\n    \"\"\"\n    print(\"image_path\",image_path)\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.int32)\n    # Resize the image to our desired size (224, 244)\n    image = tf.image.resize(image, size=[IMG_SIZE, IMG_SIZE])\n\n\n    return image\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.335906Z","iopub.execute_input":"2021-06-11T14:55:09.336725Z","iopub.status.idle":"2021-06-11T14:55:09.352262Z","shell.execute_reply.started":"2021-06-11T14:55:09.336646Z","shell.execute_reply":"2021-06-11T14:55:09.347405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a simple function to return a tuple (image, label)\n\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-11T14:55:09.356458Z","iopub.execute_input":"2021-06-11T14:55:09.357324Z","iopub.status.idle":"2021-06-11T14:55:09.372487Z","shell.execute_reply.started":"2021-06-11T14:55:09.357250Z","shell.execute_reply":"2021-06-11T14:55:09.371500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## create batches","metadata":{}},{"cell_type":"code","source":"# Create a function to turn data into batches\n\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((x)) # only filepaths  \n        data = data.map(process_image)\n        data_batch = data.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        \n        data = tf.data.Dataset.from_tensor_slices((x, # filepaths\n                                           y)) # labels\n        data = data.map(get_image_label)\n        data_batch = data.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((x, # filepaths\n                                          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        \n    return data_batch","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.377183Z","iopub.execute_input":"2021-06-11T14:55:09.377624Z","iopub.status.idle":"2021-06-11T14:55:09.392377Z","shell.execute_reply.started":"2021-06-11T14:55:09.377586Z","shell.execute_reply":"2021-06-11T14:55:09.390186Z"},"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","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.394976Z","iopub.execute_input":"2021-06-11T14:55:09.395585Z","iopub.status.idle":"2021-06-11T14:55:09.417435Z","shell.execute_reply.started":"2021-06-11T14:55:09.395525Z","shell.execute_reply":"2021-06-11T14:55:09.415085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create training and validation data batches\n\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-11T14:55:09.420749Z","iopub.execute_input":"2021-06-11T14:55:09.421343Z","iopub.status.idle":"2021-06-11T14:55:09.753900Z","shell.execute_reply.started":"2021-06-11T14:55:09.421287Z","shell.execute_reply":"2021-06-11T14:55:09.752460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check out the different attributes of our data batches\n\ntrain_data.element_spec, val_data.element_spec","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.755744Z","iopub.execute_input":"2021-06-11T14:55:09.756182Z","iopub.status.idle":"2021-06-11T14:55:09.764832Z","shell.execute_reply.started":"2021-06-11T14:55:09.756144Z","shell.execute_reply":"2021-06-11T14:55:09.763451Z"},"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# 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\nNUM_EPOCHS = 100\n\npretrained_model = tf.keras.applications.MobileNetV2(input_shape = INPUT_SHAPE[1:], include_top = False, weights = \"imagenet\")\npretrained_model.trainable = False","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:09.766313Z","iopub.execute_input":"2021-06-11T14:55:09.766822Z","iopub.status.idle":"2021-06-11T14:55:11.375272Z","shell.execute_reply.started":"2021-06-11T14:55:09.766759Z","shell.execute_reply":"2021-06-11T14:55:11.374286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"  # Setup the model layers\nmodel = tf.keras.Sequential([pretrained_model,                                 \n                             tf.keras.layers.GlobalAveragePooling2D(),\n                             tf.keras.layers.Flatten(),\n                             tf.keras.layers.Dense(OUTPUT_SHAPE, activation=\"relu\"),                            \n                             tf.keras.layers.Dense(OUTPUT_SHAPE, activation=\"softmax\")                                     \n                                ])","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:11.376605Z","iopub.execute_input":"2021-06-11T14:55:11.377181Z","iopub.status.idle":"2021-06-11T14:55:11.845896Z","shell.execute_reply.started":"2021-06-11T14:55:11.377142Z","shell.execute_reply":"2021-06-11T14:55:11.844774Z"},"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  )\n\n# Build the model\nmodel.build(INPUT_SHAPE) # Let the model know what kind of inputs it'll be getting\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:11.849871Z","iopub.execute_input":"2021-06-11T14:55:11.850221Z","iopub.status.idle":"2021-06-11T14:55:11.872230Z","shell.execute_reply.started":"2021-06-11T14:55:11.850187Z","shell.execute_reply":"2021-06-11T14:55:11.870111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers[:20]:\n    layer.trainable=False\nfor layer in model.layers[20:]:\n    layer.trainable=True","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:11.874008Z","iopub.execute_input":"2021-06-11T14:55:11.874355Z","iopub.status.idle":"2021-06-11T14:55:11.900318Z","shell.execute_reply.started":"2021-06-11T14:55:11.874323Z","shell.execute_reply":"2021-06-11T14:55:11.899013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(\n        featurewise_center=True,\n        featurewise_std_normalization=True,\n        rotation_range=20,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        horizontal_flip=True,\n        validation_split=0.2)","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:11.902062Z","iopub.execute_input":"2021-06-11T14:55:11.902439Z","iopub.status.idle":"2021-06-11T14:55:11.916229Z","shell.execute_reply.started":"2021-06-11T14:55:11.902408Z","shell.execute_reply":"2021-06-11T14:55:11.914845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from os.path import isfile, join, abspath, exists, isdir, expanduser\n\n#Extracting different classes\ndog_breeds = sorted(labels_df['breed'].unique())\nn_classes = len(dog_breeds)\n\n#Converting classes to numbers\nclass_to_num = dict(zip(dog_breeds,range(n_classes)))\n\nimage_size = (224,224,3)\ndata_dir = \"../input/dog-breed-identification/train\"\n\"\"\"Return arrays that represents the images and processed target given where the images are saved, the dataframe that contains the id and the breeds and the image size\"\"\"\nimage_names = labels_df['id']\nimage_labels = labels_df['breed']\ndata_size = len(image_names)\n\nX = np.zeros([data_size,image_size[0],image_size[1],image_size[2]],dtype = np.uint8)\ny = np.zeros([data_size,1],dtype = np.uint8)\n\nfor i in range(data_size):\n    img_name = image_names[i]\n    img_dir = join(data_dir,img_name+'.jpg')\n    img_pixels = load_img(img_dir,target_size=image_size)\n    X[i] = img_pixels\n    y[i] = class_to_num[image_labels[i]]\n\ny = to_categorical(y)\n\nind = np.random.permutation(data_size)\nX = X[ind]\ny = y[ind]\nprint('Ouptut Data Size: ', X.shape)\nprint('Ouptut Label Size: ', y.shape)\n ","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:11.918070Z","iopub.execute_input":"2021-06-11T14:55:11.918570Z","iopub.status.idle":"2021-06-11T14:55:58.135372Z","shell.execute_reply.started":"2021-06-11T14:55:11.918520Z","shell.execute_reply":"2021-06-11T14:55:58.133808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#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-11T14:55:58.137112Z","iopub.execute_input":"2021-06-11T14:55:58.137461Z","iopub.status.idle":"2021-06-11T14:55:58.725919Z","shell.execute_reply.started":"2021-06-11T14:55:58.137430Z","shell.execute_reply":"2021-06-11T14:55:58.724811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1./255.,validation_split=0.2)\n\n\ntrain_generator = datagen.flow(X_train,\n                               y_train,\n                               batch_size=32,\n                               shuffle=True,\n                               seed=42,\n                               subset='training')\n\nvalid_generator = datagen.flow(X_val,\n                               y_val,\n                               batch_size=32,\n                               seed=42,\n                               subset='validation')\n\n\nSTEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID=valid_generator.n//valid_generator.batch_size\n\nhistory = model.fit(train_generator,\n          steps_per_epoch=STEP_SIZE_TRAIN,\n          validation_data=valid_generator,\n          validation_steps=STEP_SIZE_VALID,\n           epochs=NUM_EPOCHS,\n            validation_freq=1,\n            callbacks=early_stopping)\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T14:55:58.727400Z","iopub.execute_input":"2021-06-11T14:55:58.728043Z","iopub.status.idle":"2021-06-11T15:04:47.877601Z","shell.execute_reply.started":"2021-06-11T14:55:58.727993Z","shell.execute_reply":"2021-06-11T15:04:47.876426Z"},"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-11T15:04:47.879354Z","iopub.execute_input":"2021-06-11T15:04:47.879701Z","iopub.status.idle":"2021-06-11T15:04:48.264842Z","shell.execute_reply.started":"2021-06-11T15:04:47.879670Z","shell.execute_reply":"2021-06-11T15:04:48.263443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predictions","metadata":{}},{"cell_type":"code","source":"# # Make predictions on the validation data (not used to train on)\n# predictions = model.predict(X_val, verbose=1) # verbose shows us how long there is to go\n# predictions.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-11T15:04:48.266377Z","iopub.execute_input":"2021-06-11T15:04:48.266681Z","iopub.status.idle":"2021-06-11T15:05:05.565374Z","shell.execute_reply.started":"2021-06-11T15:04:48.266642Z","shell.execute_reply":"2021-06-11T15:05:05.564262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Turn prediction probabilities into their respective label (easier to understand)\n\n# def 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-11T15:05:05.566922Z","iopub.execute_input":"2021-06-11T15:05:05.567342Z","iopub.status.idle":"2021-06-11T15:05:05.572201Z","shell.execute_reply.started":"2021-06-11T15:05:05.567299Z","shell.execute_reply":"2021-06-11T15:05:05.571165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Unbatchify the validation data\n# val_images, val_labels = unbatchify(val_data)","metadata":{"execution":{"iopub.status.busy":"2021-06-11T15:05:05.573724Z","iopub.execute_input":"2021-06-11T15:05:05.574114Z","iopub.status.idle":"2021-06-11T15:05:07.822928Z","shell.execute_reply.started":"2021-06-11T15:05:05.574082Z","shell.execute_reply":"2021-06-11T15:05:07.821825Z"},"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-11T15:05:07.824623Z","iopub.execute_input":"2021-06-11T15:05:07.825319Z","iopub.status.idle":"2021-06-11T15:05:07.834027Z","shell.execute_reply.started":"2021-06-11T15:05:07.825256Z","shell.execute_reply":"2021-06-11T15:05:07.832862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot_pred(predictions, y_val, X_val, n=2\n#          )","metadata":{"execution":{"iopub.status.busy":"2021-06-11T15:10:48.475967Z","iopub.execute_input":"2021-06-11T15:10:48.476338Z","iopub.status.idle":"2021-06-11T15:10:48.607846Z","shell.execute_reply.started":"2021-06-11T15:10:48.476306Z","shell.execute_reply":"2021-06-11T15:10:48.606760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # pred_labels=[]\n# for i in range(len(val_labels)): \n#     pred_labels.append(get_pred_label(predictions[i]))\n# y_test=val_labels\n# y_pred=pred_labels\n\n# confusion = confusion_matrix(val_labels, pred_labels)\n# print('Confusion Matrix\\n')\n# print(confusion)\n\n\n# print('\\nAccuracy: {:.2f}\\n'.format(accuracy_score(y_test, y_pred)))\n\n# print('Micro Precision: {:.2f}'.format(precision_score(y_test, y_pred, average='micro')))\n# print('Micro Recall: {:.2f}'.format(recall_score(y_test, y_pred, average='micro')))\n# print('Micro F1-score: {:.2f}\\n'.format(f1_score(y_test, y_pred, average='micro')))\n\n# print('Macro Precision: {:.2f}'.format(precision_score(y_test, y_pred, average='macro')))\n# print('Macro Recall: {:.2f}'.format(recall_score(y_test, y_pred, average='macro')))\n# print('Macro F1-score: {:.2f}\\n'.format(f1_score(y_test, y_pred, average='macro')))\n\n# print('Weighted Precision: {:.2f}'.format(precision_score(y_test, y_pred, average='weighted')))\n# print('Weighted Recall: {:.2f}'.format(recall_score(y_test, y_pred, average='weighted')))\n# print('Weighted F1-score: {:.2f}'.format(f1_score(y_test, y_pred, average='weighted')))\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T15:05:07.937414Z","iopub.execute_input":"2021-06-11T15:05:07.938256Z","iopub.status.idle":"2021-06-11T15:05:08.019274Z","shell.execute_reply.started":"2021-06-11T15:05:07.938202Z","shell.execute_reply":"2021-06-11T15:05:08.018225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print('\\nClassification Report\\n')\n# print(classification_report(y_test, y_pred))\n","metadata":{"execution":{"iopub.status.busy":"2021-06-11T15:05:08.021007Z","iopub.execute_input":"2021-06-11T15:05:08.021704Z","iopub.status.idle":"2021-06-11T15:05:08.051662Z","shell.execute_reply.started":"2021-06-11T15:05:08.021655Z","shell.execute_reply":"2021-06-11T15:05:08.050620Z"},"trusted":true},"execution_count":null,"outputs":[]}]}