{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":7327,"databundleVersionId":861871,"sourceType":"competition"}],"dockerImageVersionId":30665,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for 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","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## This Notebook Is Created With The Help Of This Notebook :->\nhttps://www.kaggle.com/code/deepakat002/inception-xception-nasnetlarge-inceptionres","metadata":{}},{"cell_type":"markdown","source":"## Let's Visualize The Image","metadata":{}},{"cell_type":"code","source":"import os\nimport random\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nfrom tqdm.autonotebook import tqdm\nimport gc\n\n\ndef plot_random_images(dir_path, num_images, folder_name):\n    # Get a list of all the image file names in the directory\n    image_files = [f for f in os.listdir(dir_path) if f.endswith('.jpg') or f.endswith('.png')]\n\n    # Shuffle the list of image file names\n    random.shuffle(image_files)\n\n    # Get the first num_images from the shuffled list\n    image_files = image_files[:num_images]\n\n    # Calculate the number of rows and columns for the plot\n    num_rows = (num_images + 3) // 4\n    num_cols = min(num_images, 4)\n\n    # Create a figure to plot the images\n    fig = plt.figure(figsize=(10, 10*num_rows/num_cols))\n\n    # Loop through the selected images and plot each one\n    for i in range(num_images):\n        # Open the image file\n        img_path = os.path.join(dir_path, image_files[i])\n        img = Image.open(img_path)\n\n        # Add a subplot to the figure and plot the image\n        ax = fig.add_subplot(num_rows, num_cols, i+1)\n        ax.imshow(img,cmap=\"gray\")\n\n        # Remove the axis labels\n        ax.set_xticks([])\n        ax.set_yticks([])\n\n        # Add the image name as x-axis label\n        ax.set_xlabel(image_files[i], fontsize=8, wrap=True)\n\n    # Set the title of the plot to the folder name\n    plt.suptitle(folder_name, fontsize=16)\n\n    # Adjust the spacing between the subplots\n    plt.subplots_adjust(wspace=0.05, hspace=0.05)\n\n    # Show the plot\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_dir = \"/kaggle/input/dog-breed-identification/train\"\ntesting_dir  = \"/kaggle/input/dog-breed-identification/test\"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_random_images(training_dir, 3, \"Train_Images\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_random_images(testing_dir, 3, \"Testing Images\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\n\n#Create list of alphabetically sorted labels.\nclasses = sorted(list(set(labels['breed'])))\nn_classes = len(classes)\nprint('Total unique breed :----> {}'.format(n_classes), \"\\n\")\n\nclass_to_num =  dict(zip(classes, range(n_classes)))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nimport os","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Converting Image To Array","metadata":{}},{"cell_type":"code","source":"input_shape = (331,331,3)\n\ndef images_to_array(directory, label_dataframe = labels, target_size = input_shape):\n    image_labels = label_dataframe['breed']\n    images = np.zeros([len(label_dataframe), target_size[0], target_size[1], \n                       target_size[2]],dtype=np.uint8) #as we have huge data and limited ram memory. uint8 takes less memory\n    y = np.zeros([len(label_dataframe),1],dtype = np.uint8)\n    \n    for ix, image_name in enumerate(tqdm(label_dataframe['id'].values)):\n        img_dir = os.path.join(directory, image_name+'.jpg')\n        img = load_img(img_dir, target_size = target_size)\n        images[ix] = img\n        del img\n        dog_breed = image_labels[ix]\n        y[ix] = class_to_num[dog_breed]\n        \n    y = to_categorical(y)\n    return images,y\n        \n        ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time \nt = time.time()\n\nX,y = images_to_array('/kaggle/input/dog-breed-identification/train', labels[:])\n\nprint('runtime in seconds: {}'.format(time.time() - t))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"## Now We will Define The CallBack Function Using Tensorflow","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.callbacks import ReduceLROnPlateau,EarlyStopping\n\n## Learning Rate Annealer \nlrr = ReduceLROnPlateau(monitor = \"val_acc\", factor = .01, patience = 3, \n                       min_lr= 1e-5, verbose = 1)\n## Prepare Callbacks\nEarlyStop = EarlyStopping(monitor='val_loss', patience = 10, \n                          restore_best_weights = True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\n\n# Hyperparameters\nbatch_size= 128\nepochs=50\nlearn_rate=.001\n\nadam=Adam(learning_rate=learn_rate, beta_1=0.9, beta_2=0.999, epsilon=None,  amsgrad=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.layers import (Input, Lambda , Dense, Flatten, \n                                     ReLU, LeakyReLU, PReLU, BatchNormalization,\n                                    Conv2D, MaxPool2D, Dropout, \n                                     GlobalAveragePooling2D)\n\nfrom tensorflow.keras.models import (Model, Sequential)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## function to extract features from the dataset by a given pretrained model\nimg_size = (331,331,3)\n\ndef get_features(model_name, model_preprocessor, input_size, data):\n    input_layer = Input(input_size)\n    preprocessor = Lambda(model_preprocessor)(input_layer)\n    base_model   = model_name(weights='imagenet', include_top=False,\n                            input_shape = input_size)(preprocessor)\n    avg = GlobalAveragePooling2D()(base_model)\n    feature_extractor = Model(inputs = input_layer, outputs = avg)\n    \n    #Extract feature.\n    \n    feature_maps = feature_extractor.predict(data, verbose=1)\n    print(\"{0} Feature Map Shape Are {1}\".format(model_name, feature_maps.shape))\n    return feature_maps","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract features using InceptionV3 \n\nfrom keras.applications.inception_v3 import InceptionV3, preprocess_input\ninception_preprocessor = preprocess_input\ninception_features = get_features(InceptionV3,\n                                  inception_preprocessor,\n                                  img_size, X)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract features using Xception \nfrom keras.applications.xception import Xception, preprocess_input\nxception_preprocessor = preprocess_input\nxception_features = get_features(Xception,\n                                 xception_preprocessor,\n                                 img_size, X)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract features using InceptionResNetV2 \nfrom keras.applications.inception_resnet_v2 import InceptionResNetV2, preprocess_input\ninc_resnet_preprocessor = preprocess_input\ninc_resnet_features = get_features(InceptionResNetV2,\n                                   inc_resnet_preprocessor,\n                                   img_size, X)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract features using NASNetLarge \nfrom keras.applications.nasnet import NASNetLarge, preprocess_input\nnasnet_preprocessor = preprocess_input\nnasnet_features = get_features(NASNetLarge,\n                               nasnet_preprocessor,\n                               img_size, X)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Creating final featuremap by combining all extracted features\n\nfinal_features = np.concatenate([inception_features,\n                                 xception_features,\n                                 nasnet_features,\n                                 inc_resnet_features,], axis=-1) #axis=-1 to concatinate horizontally\n\nprint('Final feature maps shape', final_features.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model Building ","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import optimizers\n\nmodel = Sequential()\nmodel.add(Dropout(0.7, input_shape=(final_features.shape[1],)))\nmodel.add(Dense(n_classes, activation='softmax'))\n\n# Create optimizer instance\nadam = optimizers.Adam()\n\nmodel.compile(optimizer=adam,\n              loss='categorical_crossentropy',\n              metrics=['accuracy'])\n\n# Training the model.\nhistory = model.fit(final_features, y,\n                    batch_size=batch_size,\n                    epochs=epochs,\n                    validation_split=0.2,\n                    callbacks=[lrr, EarlyStop])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# #deleting to free up ram memory\n\n# del inception_features\n# del xception_features\n# del nasnet_features\n# del inc_resnet_features\n# del final_features\n# del X\ngc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import load_img\n\ndef images_to_array_test(test_path, img_size=(331, 331, 3)):\n    \"\"\"\n    Load images from the specified test directory and convert them into numpy arrays.\n\n    Parameters:\n    - test_path (str): Path to the directory containing the test images.\n    - img_size (tuple): Target size of the images in the format (height, width, channels).\n\n    Returns:\n    - images (numpy.ndarray): A 4D numpy array containing the loaded images, with shape (num_samples, height, width, channels).\n    \"\"\"\n    # Get the list of filenames in the test directory\n    test_filenames = [os.path.join(test_path, fname) for fname in os.listdir(test_path)]\n\n    # Get the number of images in the test directory\n    data_size = len(test_filenames)\n\n    # Create an empty array to store the images\n    images = np.zeros([data_size, img_size[0], img_size[1], 3], dtype=np.uint8)\n\n    # Load each image from the test directory\n    for ix, img_path in enumerate(tqdm(test_filenames, desc='Loading images')):\n        img = load_img(img_path, target_size=img_size)  # Load the image\n        images[ix] = img  # Store the image in the array\n        del img  # Delete the image object to free up memory\n\n    print('Output Data Size:', images.shape)\n    return images","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data = images_to_array_test(testing_dir, img_size)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Extract test data features.\ndef extact_features(data):\n    inception_features = get_features(InceptionV3, inception_preprocessor, img_size, data)\n    xception_features = get_features(Xception, xception_preprocessor, img_size, data)\n    nasnet_features = get_features(NASNetLarge, nasnet_preprocessor, img_size, data)\n    inc_resnet_features = get_features(InceptionResNetV2, inc_resnet_preprocessor, img_size, data)\n\n    final_features = np.concatenate([inception_features,\n                                     xception_features,\n                                     nasnet_features,\n                                     inc_resnet_features],axis=-1)\n    \n    print('Final feature maps shape', final_features.shape)\n    \n    #deleting to free up ram memory\n    del inception_features\n    del xception_features\n    del nasnet_features\n    del inc_resnet_features\n    gc.collect()\n    \n    \n    return final_features\n\ntest_features = extact_features(test_data)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Free up some space.\ndel test_data\ngc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Predict test labels given test data features.\n\npred = model.predict(test_features)\n\npredicted_labels = [classes[np.argmax(pred_i)] for pred_i in pred]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction On The Test DataFrame","metadata":{}},{"cell_type":"code","source":"test_df  = pd.DataFrame(os.listdir(testing_dir),columns  = ['ImageName'])\ntest_df[\"ImagePath\"] = test_df['ImageName'].apply(lambda x: training_dir + \"/\" + x)\ntest_df['predicted_labels'] = predicted_labels\ntest_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Validating Train DataFrame","metadata":{}},{"cell_type":"code","source":"train_data = images_to_array_test(training_dir, img_size)\ntrain_feature = extact_features(train_data)\n#Free up some space.\ndel train_data\ngc.collect()\n\n#Predict test labels given test data features.\n\npred_train = model.predict(train_feature)\n\npredicted_labels_train = [classes[np.argmax(pred_i)] for pred_i in pred_train]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df  = pd.DataFrame(os.listdir(training_dir),columns  = ['ImageName'])\ntrain_df[\"ImagePath\"] = train_df['ImageName'].apply(lambda x: training_dir + \"/\" + x)\ntrain_df['ImageName'] = train_df['ImageName'].apply(lambda x: x.split(\".\")[0])\n\nlabel_df = pd.read_csv(\"/kaggle/input/dog-breed-identification/labels.csv\").rename(columns ={\"id\":\"ImageName\", \"breed\":\"Actual_Breed\"})\ntrain_df = train_df.merge(label_df, on = ['ImageName'])\n\ntrain_df['Pred_Breed'] = predicted_labels_train","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Plotting Accuracy","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12,5))\n\nplt.subplot(1,2,1)\nplt.plot(history.history['loss'], label='Training Loss')\nplt.plot(history.history['val_loss'], 'ro', label='Validation Loss')\nplt.title('Loss')\nplt.grid(True)\nplt.legend()\n\nplt.subplot(1,2,2)\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], 'ro', label='Validation Accuracy')\nplt.title('Accuracy')\nplt.grid(True)\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}