{"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 Identification\nDog breed identification model using Tensorflow Keras. The dataset consists of 10k plus images of dogs belonging to 120 different breeds. Our work performed here is to train a model than can classify an image to its dog breed.\n\nThis Jupyter Notebook is written on Kaggle so the directories are related to kaggle's directory structure. You can access dataset [here](https://www.kaggle.com/competitions/dog-breed-identification/data)","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_hub as hub\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\nimport datetime\nfrom sklearn.model_selection import train_test_split\nfrom matplotlib.pyplot import imread","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-02-23T15:52:13.547322Z","iopub.execute_input":"2023-02-23T15:52:13.547740Z","iopub.status.idle":"2023-02-23T15:52:20.580648Z","shell.execute_reply.started":"2023-02-23T15:52:13.547654Z","shell.execute_reply":"2023-02-23T15:52:20.579691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(tf.__version__)\nprint(hub.__version__)\n\nif tf.config.list_physical_devices('GPU'):\n    print('GPU Available!')\nelse:\n    print('GPU Unavailable')","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:20.583832Z","iopub.execute_input":"2023-02-23T15:52:20.588009Z","iopub.status.idle":"2023-02-23T15:52:20.755731Z","shell.execute_reply.started":"2023-02-23T15:52:20.587950Z","shell.execute_reply":"2023-02-23T15:52:20.753616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Labels of Dataset\nReading the labels of the dataset to start working with them. The labels file is in `dog-breed-identification/labels.csv`","metadata":{}},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nlabels.describe()","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:20.763030Z","iopub.execute_input":"2023-02-23T15:52:20.763628Z","iopub.status.idle":"2023-02-23T15:52:20.828896Z","shell.execute_reply.started":"2023-02-23T15:52:20.763586Z","shell.execute_reply":"2023-02-23T15:52:20.828005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Frequency Distribution graph of each breed with its corresponding input\nWe are now ploting a frequency distribution graph of the dog breeds and the number of dogs belonging to it to get a visualised view of what we are dealing with.","metadata":{}},{"cell_type":"code","source":"labels['breed'].value_counts().plot.bar(figsize=(24,10))","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:20.831544Z","iopub.execute_input":"2023-02-23T15:52:20.831896Z","iopub.status.idle":"2023-02-23T15:52:22.436553Z","shell.execute_reply.started":"2023-02-23T15:52:20.831862Z","shell.execute_reply":"2023-02-23T15:52:22.435614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Filtering out more important aspects of dataset\nNow we will firstly create file paths from the labels. Then we will also get unique breeds list which should be equal to 120 and lastly we will booleanise our train images with breeds.","metadata":{}},{"cell_type":"code","source":"img_names_list = [\n    f'/kaggle/input/dog-breed-identification/train/{name}.jpg'\n    for name in labels['id']\n]\n\nlen(img_names_list) == len(labels['id'])","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:22.437588Z","iopub.execute_input":"2023-02-23T15:52:22.437951Z","iopub.status.idle":"2023-02-23T15:52:22.449063Z","shell.execute_reply.started":"2023-02-23T15:52:22.437915Z","shell.execute_reply":"2023-02-23T15:52:22.447862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"breeds_arr = labels['breed'].to_numpy()\nunique_breeds = np.unique(breeds_arr)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:22.450866Z","iopub.execute_input":"2023-02-23T15:52:22.451540Z","iopub.status.idle":"2023-02-23T15:52:22.463317Z","shell.execute_reply.started":"2023-02-23T15:52:22.451506Z","shell.execute_reply":"2023-02-23T15:52:22.462370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bool_breeds = [\n    breed == unique_breeds\n    for breed in breeds_arr\n]\nlen(bool_breeds)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:22.465241Z","iopub.execute_input":"2023-02-23T15:52:22.465862Z","iopub.status.idle":"2023-02-23T15:52:22.514718Z","shell.execute_reply.started":"2023-02-23T15:52:22.465829Z","shell.execute_reply":"2023-02-23T15:52:22.513824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(breeds_arr[0])\nprint(bool_breeds[0].astype(int))","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:22.516097Z","iopub.execute_input":"2023-02-23T15:52:22.516685Z","iopub.status.idle":"2023-02-23T15:52:22.523049Z","shell.execute_reply.started":"2023-02-23T15:52:22.516649Z","shell.execute_reply":"2023-02-23T15:52:22.521963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train and Validation sets\nNow here we are going to use only 1000 images for the initial training and testing of model which we will split in 4/1 ratio. Where 800 images are going to be used for training of the model and remaining 200 images will be used for the testing of the model.","metadata":{}},{"cell_type":"code","source":"NUM_IMAGES = 1000\nx = img_names_list\ny = bool_breeds\n\nx_train, x_val, y_train, y_val = train_test_split(\n    x[:NUM_IMAGES],\n    y[:NUM_IMAGES],\n    test_size = 0.2,\n    random_state = 42\n)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:22.524672Z","iopub.execute_input":"2023-02-23T15:52:22.525022Z","iopub.status.idle":"2023-02-23T15:52:22.532681Z","shell.execute_reply.started":"2023-02-23T15:52:22.524989Z","shell.execute_reply":"2023-02-23T15:52:22.531704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Image Processing\nWe are going to work with Tensorflow Keras model, for it work it needs images to be processed into tensors. We will reduce its size to only 224 of ratio 1 and change the color channel range between 0 and 1. The work will be performed by a function `preprocess`","metadata":{}},{"cell_type":"code","source":"img = imread(img_names_list[0])\ntf.constant(img[:2])","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:22.537576Z","iopub.execute_input":"2023-02-23T15:52:22.537838Z","iopub.status.idle":"2023-02-23T15:52:25.199715Z","shell.execute_reply.started":"2023-02-23T15:52:22.537814Z","shell.execute_reply":"2023-02-23T15:52:25.198808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 224\n\ndef preprocess(img_path):\n    image = tf.io.read_file(img_path)\n    image = tf.image.decode_jpeg(image, channels = 3)\n    image = tf.image.convert_image_dtype(image, tf.float32)\n    image = tf.image.resize(image, size = [IMG_SIZE, IMG_SIZE])\n    return image","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.203513Z","iopub.execute_input":"2023-02-23T15:52:25.205940Z","iopub.status.idle":"2023-02-23T15:52:25.213434Z","shell.execute_reply.started":"2023-02-23T15:52:25.205906Z","shell.execute_reply":"2023-02-23T15:52:25.212591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Converting data into batches\nThe model needs to be trained on the base of data batches, so we will devide our images into small batches of 32 images. The data batches will be generated on a shuffled dataset for increased efficiency. On these batches of data we will train and test our model.","metadata":{}},{"cell_type":"code","source":"def get_img_label(img_path, label):\n    image = preprocess(img_path)\n    return image, label","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.214922Z","iopub.execute_input":"2023-02-23T15:52:25.215593Z","iopub.status.idle":"2023-02-23T15:52:25.225045Z","shell.execute_reply.started":"2023-02-23T15:52:25.215557Z","shell.execute_reply":"2023-02-23T15:52:25.224193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(preprocess(x[42]), tf.constant(y[42]))","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.226466Z","iopub.execute_input":"2023-02-23T15:52:25.227047Z","iopub.status.idle":"2023-02-23T15:52:25.274411Z","shell.execute_reply.started":"2023-02-23T15:52:25.227012Z","shell.execute_reply":"2023-02-23T15:52:25.273427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32\n\ndef data_to_batches(\n    x,\n    y = None,\n    batch_size = BATCH_SIZE,\n    valid_data = False,\n    test_data = False\n):\n    if test_data:\n        print(\"Creating test data batches...\")\n        data = tf.data.Dataset.from_tensor_slices((tf.constant(x)))\n        data_batch = data.map(preprocess).batch(BATCH_SIZE)\n    \n    elif valid_data:\n        print(\"Creating validating data batches...\")\n        data = tf.data.Dataset.from_tensor_slices((\n            tf.constant(x),\n            tf.constant(y)\n        ))\n        data_batch = data.map(get_img_label).batch(BATCH_SIZE)\n    \n    else:\n        print(\"Creating training data batches...\")\n        data = tf.data.Dataset.from_tensor_slices((\n            tf.constant(x),\n            tf.constant(y)\n        ))\n        data = data.shuffle(buffer_size = len(x)) \n        data_batch = data.map(get_img_label).batch(BATCH_SIZE)\n        \n    return data_batch ","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.276005Z","iopub.execute_input":"2023-02-23T15:52:25.276738Z","iopub.status.idle":"2023-02-23T15:52:25.286453Z","shell.execute_reply.started":"2023-02-23T15:52:25.276690Z","shell.execute_reply":"2023-02-23T15:52:25.285331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = data_to_batches(x_train, y_train)\nval_data = data_to_batches(x_val, y_val, valid_data = True)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.288058Z","iopub.execute_input":"2023-02-23T15:52:25.288689Z","iopub.status.idle":"2023-02-23T15:52:25.455412Z","shell.execute_reply.started":"2023-02-23T15:52:25.288650Z","shell.execute_reply":"2023-02-23T15:52:25.454370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.element_spec,\nval_data.element_spec","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.456936Z","iopub.execute_input":"2023-02-23T15:52:25.457403Z","iopub.status.idle":"2023-02-23T15:52:25.464472Z","shell.execute_reply.started":"2023-02-23T15:52:25.457350Z","shell.execute_reply":"2023-02-23T15:52:25.463396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing Data Batches\n`show_25_images` is going to be used to get a visualisation of images in any data batch.","metadata":{}},{"cell_type":"code","source":"def show_25_images(img, label):\n    plt.figure(figsize = (15, 15))\n    for i in range(25):\n        ax = plt.subplot(5, 5, i + 1)\n        plt.imshow(img[i])\n        plt.title(unique_breeds[label[i].argmax()])\n        plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.466079Z","iopub.execute_input":"2023-02-23T15:52:25.466557Z","iopub.status.idle":"2023-02-23T15:52:25.474063Z","shell.execute_reply.started":"2023-02-23T15:52:25.466522Z","shell.execute_reply":"2023-02-23T15:52:25.473083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_imgs, train_labels = next(train_data.as_numpy_iterator())\nshow_25_images(train_imgs, train_labels)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:25.475517Z","iopub.execute_input":"2023-02-23T15:52:25.476267Z","iopub.status.idle":"2023-02-23T15:52:27.250979Z","shell.execute_reply.started":"2023-02-23T15:52:25.476224Z","shell.execute_reply":"2023-02-23T15:52:27.248233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_images, val_labels = next(val_data.as_numpy_iterator()) #We convert batches to numpy arrays and then we assign it\nshow_25_images(val_images, val_labels)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:27.252566Z","iopub.execute_input":"2023-02-23T15:52:27.253003Z","iopub.status.idle":"2023-02-23T15:52:28.793630Z","shell.execute_reply.started":"2023-02-23T15:52:27.252967Z","shell.execute_reply":"2023-02-23T15:52:28.792395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Building Model\nModel builing process includes creating callback functions and model training over a imagenet model.","metadata":{}},{"cell_type":"code","source":"INPUT_SHAPE = [None, IMG_SIZE, IMG_SIZE, 3]\nOUTPUT_SHAPE = len(unique_breeds)\n\nMODEL_URL = \"https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/5\"","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:28.795408Z","iopub.execute_input":"2023-02-23T15:52:28.795909Z","iopub.status.idle":"2023-02-23T15:52:28.801379Z","shell.execute_reply.started":"2023-02-23T15:52:28.795876Z","shell.execute_reply":"2023-02-23T15:52:28.800506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model(\n    input_shape = INPUT_SHAPE,\n    output_shape = OUTPUT_SHAPE,\n    model_url = MODEL_URL\n):\n    print(f'Building Model with: {model_url}')\n    model = tf.keras.Sequential([\n        hub.KerasLayer(model_url),\n        tf.keras.layers.Dense(units = output_shape, activation = 'softmax')\n    ]) \n    model.compile(\n        loss = tf.keras.losses.CategoricalCrossentropy(),\n        optimizer = tf.keras.optimizers.Adam(),\n        metrics = ['accuracy']\n    )\n    model.build(input_shape)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:28.804597Z","iopub.execute_input":"2023-02-23T15:52:28.805638Z","iopub.status.idle":"2023-02-23T15:52:28.814238Z","shell.execute_reply.started":"2023-02-23T15:52:28.805601Z","shell.execute_reply":"2023-02-23T15:52:28.813411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:28.815754Z","iopub.execute_input":"2023-02-23T15:52:28.816526Z","iopub.status.idle":"2023-02-23T15:52:34.346032Z","shell.execute_reply.started":"2023-02-23T15:52:28.816493Z","shell.execute_reply":"2023-02-23T15:52:34.344978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Creating Callbacks","metadata":{}},{"cell_type":"code","source":"%load_ext tensorboard\nos.makedirs('/kaggle/working/logs')","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:34.348163Z","iopub.execute_input":"2023-02-23T15:52:34.349620Z","iopub.status.idle":"2023-02-23T15:52:34.362341Z","shell.execute_reply.started":"2023-02-23T15:52:34.349582Z","shell.execute_reply":"2023-02-23T15:52:34.361416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_tensorboard_callback():\n    logdir = os.path.join(\n        '/kaggle/working/logs',\n        datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n    )\n    return tf.keras.callbacks.TensorBoard(logdir)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:34.364525Z","iopub.execute_input":"2023-02-23T15:52:34.364937Z","iopub.status.idle":"2023-02-23T15:52:34.372595Z","shell.execute_reply.started":"2023-02-23T15:52:34.364901Z","shell.execute_reply":"2023-02-23T15:52:34.371519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"early_stopping = tf.keras.callbacks.EarlyStopping(monitor = 'val_accuracy', patience = 3)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:34.375927Z","iopub.execute_input":"2023-02-23T15:52:34.376184Z","iopub.status.idle":"2023-02-23T15:52:34.381707Z","shell.execute_reply.started":"2023-02-23T15:52:34.376159Z","shell.execute_reply":"2023-02-23T15:52:34.380705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_EPOCHS = 100\n\ndef train_model():\n    model = create_model()\n    tensorboard = create_tensorboard_callback()\n    \n    model.fit(\n        x = train_data,\n        epochs = NUM_EPOCHS,\n        validation_data = val_data,\n        validation_freq = 1,\n        callbacks = [\n            tensorboard,\n            early_stopping\n        ]\n    )\n    \n    return model\n\nmodel = train_model()","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:52:34.382991Z","iopub.execute_input":"2023-02-23T15:52:34.383401Z","iopub.status.idle":"2023-02-23T15:53:34.692021Z","shell.execute_reply.started":"2023-02-23T15:52:34.383351Z","shell.execute_reply":"2023-02-23T15:53:34.690953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%tensorboard --logdir \"/kaggle/working/logs\"","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:34.693480Z","iopub.execute_input":"2023-02-23T15:53:34.693827Z","iopub.status.idle":"2023-02-23T15:53:39.290279Z","shell.execute_reply.started":"2023-02-23T15:53:34.693792Z","shell.execute_reply":"2023-02-23T15:53:39.289246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Making Predictions using our trained model","metadata":{}},{"cell_type":"code","source":"pred = model.predict(val_data, verbose = 1)\npred","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:39.298858Z","iopub.execute_input":"2023-02-23T15:53:39.299155Z","iopub.status.idle":"2023-02-23T15:53:40.270837Z","shell.execute_reply.started":"2023-02-23T15:53:39.299125Z","shell.execute_reply":"2023-02-23T15:53:40.269892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred.shape\nnp.sum(pred)\npred[0]\n# pred[0].argmax()\n# unique_breeds[26]","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.273504Z","iopub.execute_input":"2023-02-23T15:53:40.274111Z","iopub.status.idle":"2023-02-23T15:53:40.284196Z","shell.execute_reply.started":"2023-02-23T15:53:40.274072Z","shell.execute_reply":"2023-02-23T15:53:40.283151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# first prediction\nindex = 0\n\nprint(pred[0])\nprint(f'Max value (probabilty prediction): {np.max(pred[index])}')\nprint(f\"Sum: {np.sum(pred[index])}\")\nprint(f\"Max Index: {np.argmax(pred[index])}\")\nprint(f\"Predicted label: {unique_breeds[np.argmax(pred[index])]}\")","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.285772Z","iopub.execute_input":"2023-02-23T15:53:40.287782Z","iopub.status.idle":"2023-02-23T15:53:40.296626Z","shell.execute_reply.started":"2023-02-23T15:53:40.287745Z","shell.execute_reply":"2023-02-23T15:53:40.295411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_pred_label(pred_prob):\n     return unique_breeds[np.argmax(pred_prob)]","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.297939Z","iopub.execute_input":"2023-02-23T15:53:40.298978Z","iopub.status.idle":"2023-02-23T15:53:40.307567Z","shell.execute_reply.started":"2023-02-23T15:53:40.298941Z","shell.execute_reply":"2023-02-23T15:53:40.306394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_label = get_pred_label(pred[0])\npred_label","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.308987Z","iopub.execute_input":"2023-02-23T15:53:40.309769Z","iopub.status.idle":"2023-02-23T15:53:40.322328Z","shell.execute_reply.started":"2023-02-23T15:53:40.309734Z","shell.execute_reply":"2023-02-23T15:53:40.321256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def unbatch(data):\n    images = []\n    labels = []\n    \n    for img, label in data.unbatch().as_numpy_iterator():\n        images.append(img)\n        labels.append(unique_breeds[np.argmax(label)])\n    \n    return images, labels\n\nvalidation_images, validation_labels = unbatch(val_data)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.323834Z","iopub.execute_input":"2023-02-23T15:53:40.324854Z","iopub.status.idle":"2023-02-23T15:53:40.973208Z","shell.execute_reply.started":"2023-02-23T15:53:40.324819Z","shell.execute_reply":"2023-02-23T15:53:40.972154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_pred_label(validation_labels[0])\n\nif get_pred_label(pred[0]) == get_pred_label(validation_labels[1]):\n    print(f\"{get_pred_label(pred[0])} is corrected predicted\" )\nelse:\n    print(f\"{get_pred_label(pred[0])} is false predicted while true label is {get_pred_label(validation_labels[1])}\" )","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.978022Z","iopub.execute_input":"2023-02-23T15:53:40.978987Z","iopub.status.idle":"2023-02-23T15:53:40.987333Z","shell.execute_reply.started":"2023-02-23T15:53:40.978949Z","shell.execute_reply":"2023-02-23T15:53:40.986418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction Visualization","metadata":{}},{"cell_type":"code","source":"def plot_pred(\n    pred_prob,\n    label,\n    img,\n    n\n):\n    pred_prob, true_label, img = pred_prob[n], label[n], img[n]\n    pred_label = get_pred_label(pred_prob)\n    \n    plt.imshow(img)\n    plt.xticks([])\n    plt.yticks([])\n    \n    title_object = plt.title('{} {:2.0f}%--{}'.format(\n        pred_label,\n        np.max(pred_prob) * 100,\n        true_label\n    ), color = 'green')\n    \n    if pred_label != true_label:\n        plt.setp(title_object, color = 'r')\n    else: pass\n    ","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:40.988905Z","iopub.execute_input":"2023-02-23T15:53:40.989589Z","iopub.status.idle":"2023-02-23T15:53:41.002460Z","shell.execute_reply.started":"2023-02-23T15:53:40.989552Z","shell.execute_reply":"2023-02-23T15:53:41.001420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_pred(pred, validation_labels, validation_images, 1)\nval_labels","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:41.006538Z","iopub.execute_input":"2023-02-23T15:53:41.008995Z","iopub.status.idle":"2023-02-23T15:53:41.203502Z","shell.execute_reply.started":"2023-02-23T15:53:41.008960Z","shell.execute_reply":"2023-02-23T15:53:41.202325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_pred_conf(\n    pred_probs,\n    labels,\n    n\n):\n    pred_prob, true_label = pred_probs[n], labels[n]\n    pred_label = get_pred_label(pred_prob)\n    \n    indexes_10 = pred_prob.argsort()[-10:][::-1]\n    values_10 = pred_prob[indexes_10]\n    labels_10 = unique_breeds[indexes_10]\n    \n    plot = plt.bar(\n        np.arange(len(indexes_10)),\n        values_10,\n        color = 'grey'\n    )\n    plt.xticks(\n        np.arange(len(labels_10)),\n        labels = labels_10,\n        rotation = 'vertical'\n    )\n    \n    if np.isin(unique_breeds[true_label], labels_10):\n        plot[\n            np.argmax(unique_breeds[true_label] == labels_10)\n        ].set_color('green')\n    else: pass","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:41.209458Z","iopub.execute_input":"2023-02-23T15:53:41.209964Z","iopub.status.idle":"2023-02-23T15:53:41.222004Z","shell.execute_reply.started":"2023-02-23T15:53:41.209915Z","shell.execute_reply":"2023-02-23T15:53:41.221159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_pred_conf(pred, val_labels, 6)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:41.225183Z","iopub.execute_input":"2023-02-23T15:53:41.226766Z","iopub.status.idle":"2023-02-23T15:53:41.487841Z","shell.execute_reply.started":"2023-02-23T15:53:41.226733Z","shell.execute_reply":"2023-02-23T15:53:41.486948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i_multiplier = 10\nnum_rows = 3\nnum_col = 3\nnum_images = num_rows * num_col\n\nplt.figure(figsize = (10 * num_col, 5 * num_rows))\n\nfor i in range(num_images):\n    plt.subplot(num_rows, 2 * num_col, 2 * i + 1)\n    plot_pred(\n        pred,\n        validation_labels,\n        validation_images,\n        i+i_multiplier\n    )\n    plt.subplot(num_rows, 2 * num_col, 2 * i + 1)\n    plot_pred_conf(\n        pred,\n        val_labels,\n        i + i_multiplier\n    )\n    \nplt.tight_layout(h_pad = 1.0)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:41.491853Z","iopub.execute_input":"2023-02-23T15:53:41.494098Z","iopub.status.idle":"2023-02-23T15:53:43.258601Z","shell.execute_reply.started":"2023-02-23T15:53:41.494062Z","shell.execute_reply":"2023-02-23T15:53:43.257770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize =  (10 * num_col, 5 * num_rows))\nplt.subplot(num_rows, 2 * num_col, 2 * i + 1)\nplot_pred(\n    pred,\n    validation_labels,\n    validation_images,\n    i + i_multiplier\n)\nplt.subplot(num_rows, 2 * num_col, 2 * i + 1)\nplot_pred_conf(\n    pred,\n    val_labels,\n    i + i_multiplier\n)","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:43.259963Z","iopub.execute_input":"2023-02-23T15:53:43.260515Z","iopub.status.idle":"2023-02-23T15:53:43.484456Z","shell.execute_reply.started":"2023-02-23T15:53:43.260479Z","shell.execute_reply":"2023-02-23T15:53:43.483491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_model(model, suffix = None):\n    model_dir = os.path.join(\"/kaggle/model\", datetime.datetime.now().strftime(\"%Y%m%d-%H%M%s\"))\n    model_path = model_dir + '-' + suffix + '.h5'\n    print(f\"Saving model to :{model_path}...\")\n    model.save(model_path)\n    return model_path","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:43.485798Z","iopub.execute_input":"2023-02-23T15:53:43.486893Z","iopub.status.idle":"2023-02-23T15:53:43.493374Z","shell.execute_reply.started":"2023-02-23T15:53:43.486857Z","shell.execute_reply":"2023-02-23T15:53:43.492204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_model(model_path):\n    print(f\"Loading save model from :{model_path}...\")\n    model = tf.keras.models.load_model(model_path, custom_objects = {\"KerasLayer\":hub.KerasLayer})\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:43.494967Z","iopub.execute_input":"2023-02-23T15:53:43.495399Z","iopub.status.idle":"2023-02-23T15:53:43.503936Z","shell.execute_reply.started":"2023-02-23T15:53:43.495350Z","shell.execute_reply":"2023-02-23T15:53:43.503174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_model(model, suffix = \"1000-images-mobilenetV2-Adam\")","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:43.504964Z","iopub.execute_input":"2023-02-23T15:53:43.506643Z","iopub.status.idle":"2023-02-23T15:53:43.717249Z","shell.execute_reply.started":"2023-02-23T15:53:43.506607Z","shell.execute_reply":"2023-02-23T15:53:43.716285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = load_model('/kaggle/model/20230209-09421675935753-1000-images-mobilenetV2-Adam.h5')","metadata":{"execution":{"iopub.status.busy":"2023-02-23T15:53:43.718609Z","iopub.execute_input":"2023-02-23T15:53:43.719081Z","iopub.status.idle":"2023-02-23T15:53:44.020444Z","shell.execute_reply.started":"2023-02-23T15:53:43.719043Z","shell.execute_reply":"2023-02-23T15:53:44.018868Z"},"trusted":true},"execution_count":null,"outputs":[]}]}