{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#Importing required libraries\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport os\nimport gc\n\nfrom sklearn.model_selection import train_test_split\n\n\nimport tensorflow as tf\nfrom tqdm.autonotebook import tqdm\n\nimport numpy as np #\nimport pandas as pd \nfrom keras import Sequential\nfrom keras.callbacks import EarlyStopping\nfrom keras.optimizers import Adam, SGD\nfrom keras.callbacks import ReduceLROnPlateau\nfrom keras.layers import Flatten,Dense,BatchNormalization,Activation,Dropout\nfrom keras.layers import Lambda, Input, GlobalAveragePooling2D,BatchNormalization\nfrom keras.utils import to_categorical\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.utils import load_img\n","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:03.855662Z","iopub.execute_input":"2023-03-02T10:13:03.856016Z","iopub.status.idle":"2023-03-02T10:13:12.444110Z","shell.execute_reply.started":"2023-03-02T10:13:03.855980Z","shell.execute_reply":"2023-03-02T10:13:12.442927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check for GPU\nprint(\"GPU\", \"available (YESS!!!!)\" if tf.config.list_physical_devices(\"GPU\") else \"not available :(\")\ntf.config.list_physical_devices(\"GPU\")","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:12.446273Z","iopub.execute_input":"2023-03-02T10:13:12.448317Z","iopub.status.idle":"2023-03-02T10:13:12.673157Z","shell.execute_reply.started":"2023-03-02T10:13:12.448282Z","shell.execute_reply":"2023-03-02T10:13:12.672003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#reading labels csv file\n\nlabels = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nlabels.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:12.674675Z","iopub.execute_input":"2023-03-02T10:13:12.675062Z","iopub.status.idle":"2023-03-02T10:13:12.732600Z","shell.execute_reply.started":"2023-03-02T10:13:12.675022Z","shell.execute_reply":"2023-03-02T10:13:12.731665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#describe\nlabels.describe()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:12.735592Z","iopub.execute_input":"2023-03-02T10:13:12.735986Z","iopub.status.idle":"2023-03-02T10:13:12.762691Z","shell.execute_reply.started":"2023-03-02T10:13:12.735948Z","shell.execute_reply":"2023-03-02T10:13:12.761541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#function to show bar length\ndef barw(ax): \n    \n    for p in ax.patches:\n        val = p.get_width() #height of the bar\n        x = p.get_x()+ p.get_width() # x- position \n        y = p.get_y() + p.get_height()/2 #y-position\n        ax.annotate(round(val,2),(x,y))\n        \n#finding top dog brands\n\nplt.figure(figsize = (15,30))\nax0 =sns.countplot(y=labels['breed'],order=labels['breed'].value_counts().index)\nbarw(ax0)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:12.764008Z","iopub.execute_input":"2023-03-02T10:13:12.764338Z","iopub.status.idle":"2023-03-02T10:13:15.147641Z","shell.execute_reply.started":"2023-03-02T10:13:12.764304Z","shell.execute_reply":"2023-03-02T10:13:15.146731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Lets check one image\nfrom IPython.display import display, Image\nImage(\"../input/dog-breed-identification/train/43572ba7edf772a95f539e57afd9eb43.jpg\")","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:15.148587Z","iopub.execute_input":"2023-03-02T10:13:15.148928Z","iopub.status.idle":"2023-03-02T10:13:15.166753Z","shell.execute_reply.started":"2023-03-02T10:13:15.148893Z","shell.execute_reply":"2023-03-02T10:13:15.165618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nif len(os.listdir('/kaggle/input/dog-breed-identification/train/')) == len(labels['id']):\n    print('Number of file matches number of actual images!')\nelse:\n    print('Number of file doesnot matches number of actual images!!')","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:15.168376Z","iopub.execute_input":"2023-03-02T10:13:15.169159Z","iopub.status.idle":"2023-03-02T10:13:15.406338Z","shell.execute_reply.started":"2023-03-02T10:13:15.169122Z","shell.execute_reply":"2023-03-02T10:13:15.404977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#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\n\n#Map each label string to an integer label.\nclass_to_num = dict(zip(classes, range(n_classes)))\nclass_to_num","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:15.408078Z","iopub.execute_input":"2023-03-02T10:13:15.409217Z","iopub.status.idle":"2023-03-02T10:13:15.423146Z","shell.execute_reply.started":"2023-03-02T10:13:15.409175Z","shell.execute_reply":"2023-03-02T10:13:15.421986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (331,331,3)\n\n\ndef images_to_array(directory, label_dataframe, target_size = input_shape):\n    \n    image_labels = label_dataframe['breed']\n    images = np.zeros([len(label_dataframe), target_size[0], target_size[1], 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#         img = np.expand_dims(img, axis=0)\n#         img = processed_image_resnet(img)\n#         img = img/255\n        images[ix]=img\n#         images[ix] = img_to_array(img)\n        del img\n        \n        dog_breed = image_labels[ix]\n        y[ix] = class_to_num[dog_breed]\n    \n    y = to_categorical(y)\n    \n    return images,y","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:13:15.424850Z","iopub.execute_input":"2023-03-02T10:13:15.425712Z","iopub.status.idle":"2023-03-02T10:13:15.435117Z","shell.execute_reply.started":"2023-03-02T10:13:15.425658Z","shell.execute_reply":"2023-03-02T10:13:15.434150Z"},"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":{"execution":{"iopub.status.busy":"2023-03-02T10:13:15.440507Z","iopub.execute_input":"2023-03-02T10:13:15.441556Z","iopub.status.idle":"2023-03-02T10:15:24.283301Z","shell.execute_reply.started":"2023-03-02T10:13:15.441511Z","shell.execute_reply":"2023-03-02T10:15:24.282370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# np.where(y[5]==1)[0][0]\n\n# lets check some dogs and their breeds\nn=25\n\n# setup the figure \nplt.figure(figsize=(20,20))\n\nfor i in range(n):\n#     print(i)\n    ax = plt.subplot(5, 5, i+1)\n    plt.title(classes[np.where(y[i] ==1)[0][0]])\n    plt.imshow(X[i].astype('int32')) # .astype('int32') ---> as imshow() needs integer data to read the image","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:15:24.288828Z","iopub.execute_input":"2023-03-02T10:15:24.291064Z","iopub.status.idle":"2023-03-02T10:15:28.524999Z","shell.execute_reply.started":"2023-03-02T10:15:24.291024Z","shell.execute_reply":"2023-03-02T10:15:28.523502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Learning Rate Annealer\nlrr= ReduceLROnPlateau(monitor='val_acc', factor=.01, patience=3, min_lr=1e-5,verbose = 1)\n\n#Prepare call backs\nEarlyStop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:15:28.526735Z","iopub.execute_input":"2023-03-02T10:15:28.527384Z","iopub.status.idle":"2023-03-02T10:15:28.532790Z","shell.execute_reply.started":"2023-03-02T10:15:28.527348Z","shell.execute_reply":"2023-03-02T10:15:28.531654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hyperparameters\nbatch_size= 128\nepochs=50\nlearn_rate=.001\nsgd=SGD(lr=learn_rate,momentum=.9,nesterov=False)\nadam=Adam(lr=learn_rate, beta_1=0.9, beta_2=0.999, epsilon=None,  amsgrad=False)","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:15:28.534130Z","iopub.execute_input":"2023-03-02T10:15:28.535182Z","iopub.status.idle":"2023-03-02T10:15:28.553175Z","shell.execute_reply.started":"2023-03-02T10:15:28.535149Z","shell.execute_reply":"2023-03-02T10:15:28.552105Z"},"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\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    feature_maps = feature_extractor.predict(data, verbose=1)\n    print('Feature maps shape: ', feature_maps.shape)\n    return feature_maps","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:15:28.554575Z","iopub.execute_input":"2023-03-02T10:15:28.554891Z","iopub.status.idle":"2023-03-02T10:15:28.561661Z","shell.execute_reply.started":"2023-03-02T10:15:28.554862Z","shell.execute_reply":"2023-03-02T10:15:28.560783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract features using InceptionV3 \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":{"execution":{"iopub.status.busy":"2023-03-02T10:15:28.564002Z","iopub.execute_input":"2023-03-02T10:15:28.565166Z","iopub.status.idle":"2023-03-02T10:16:27.495989Z","shell.execute_reply.started":"2023-03-02T10:15:28.565116Z","shell.execute_reply":"2023-03-02T10:16:27.494886Z"},"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":{"execution":{"iopub.status.busy":"2023-03-02T10:16:27.504262Z","iopub.execute_input":"2023-03-02T10:16:27.506546Z","iopub.status.idle":"2023-03-02T10:17:30.762302Z","shell.execute_reply.started":"2023-03-02T10:16:27.506506Z","shell.execute_reply":"2023-03-02T10:17:30.758105Z"},"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":{"execution":{"iopub.status.busy":"2023-03-02T10:17:30.763706Z","iopub.execute_input":"2023-03-02T10:17:30.764301Z","iopub.status.idle":"2023-03-02T10:19:01.550644Z","shell.execute_reply.started":"2023-03-02T10:17:30.764262Z","shell.execute_reply":"2023-03-02T10:19:01.549373Z"},"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":{"execution":{"iopub.status.busy":"2023-03-02T10:19:01.552454Z","iopub.execute_input":"2023-03-02T10:19:01.552857Z","iopub.status.idle":"2023-03-02T10:22:27.146366Z","shell.execute_reply.started":"2023-03-02T10:19:01.552818Z","shell.execute_reply":"2023-03-02T10:22:27.145132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del X #to free up some ram memory\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:22:27.148219Z","iopub.execute_input":"2023-03-02T10:22:27.148585Z","iopub.status.idle":"2023-03-02T10:22:28.027811Z","shell.execute_reply.started":"2023-03-02T10:22:27.148548Z","shell.execute_reply":"2023-03-02T10:22:28.026644Z"},"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":{"execution":{"iopub.status.busy":"2023-03-02T10:22:28.029878Z","iopub.execute_input":"2023-03-02T10:22:28.030166Z","iopub.status.idle":"2023-03-02T10:22:28.191128Z","shell.execute_reply.started":"2023-03-02T10:22:28.030139Z","shell.execute_reply":"2023-03-02T10:22:28.189959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Prepare Deep net\n\nmodel = Sequential()\n# model.add(Dense(1028,input_shape=(final_features.shape[1],)))\nmodel.add(Dropout(0.7,input_shape=(final_features.shape[1],)))\nmodel.add(Dense(n_classes,activation= 'softmax'))\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":{"execution":{"iopub.status.busy":"2023-03-02T10:22:28.192832Z","iopub.execute_input":"2023-03-02T10:22:28.193496Z","iopub.status.idle":"2023-03-02T10:22:35.463647Z","shell.execute_reply.started":"2023-03-02T10:22:28.193454Z","shell.execute_reply":"2023-03-02T10:22:35.462651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#deleting to free up ram memory\n\ndel inception_features\ndel xception_features\ndel nasnet_features\ndel inc_resnet_features\ndel final_features\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:22:35.465242Z","iopub.execute_input":"2023-03-02T10:22:35.465835Z","iopub.status.idle":"2023-03-02T10:22:35.723283Z","shell.execute_reply.started":"2023-03-02T10:22:35.465791Z","shell.execute_reply":"2023-03-02T10:22:35.722122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Function to read images from test directory\n\ndef images_to_array_test(test_path, img_size = (331,331,3)):\n    test_filenames = [test_path + fname for fname in os.listdir(test_path)]\n\n    data_size = len(test_filenames)\n    images = np.zeros([data_size, img_size[0], img_size[1], 3], dtype=np.uint8)\n    \n    \n    for ix,img_dir in enumerate(tqdm(test_filenames)):\n#         img_dir = os.path.join(directory, image_name + '.jpg')\n        img = load_img(img_dir, target_size = img_size)\n#         img = np.expand_dims(img, axis=0)\n#         img = processed_image_resnet(img)\n#         img = img/255\n        images[ix]=img\n#         images[ix] = img_to_array(img)\n        del img\n    print('Ouptut Data Size: ', images.shape)\n    return images\n\ntest_data = images_to_array_test('/kaggle/input/dog-breed-identification/test/', img_size)","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:22:35.724949Z","iopub.execute_input":"2023-03-02T10:22:35.725326Z","iopub.status.idle":"2023-03-02T10:24:48.418595Z","shell.execute_reply.started":"2023-03-02T10:22:35.725290Z","shell.execute_reply":"2023-03-02T10:24:48.417488Z"},"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":{"execution":{"iopub.status.busy":"2023-03-02T10:24:48.420354Z","iopub.execute_input":"2023-03-02T10:24:48.421105Z","iopub.status.idle":"2023-03-02T10:31:36.265478Z","shell.execute_reply.started":"2023-03-02T10:24:48.421061Z","shell.execute_reply":"2023-03-02T10:31:36.264393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Free up some space.\ndel test_data\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:31:36.275134Z","iopub.execute_input":"2023-03-02T10:31:36.275475Z","iopub.status.idle":"2023-03-02T10:31:36.703780Z","shell.execute_reply.started":"2023-03-02T10:31:36.275441Z","shell.execute_reply":"2023-03-02T10:31:36.702685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Predict test labels given test data features.\n\npred = model.predict(test_features)","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:31:36.705255Z","iopub.execute_input":"2023-03-02T10:31:36.705760Z","iopub.status.idle":"2023-03-02T10:31:38.806973Z","shell.execute_reply.started":"2023-03-02T10:31:36.705719Z","shell.execute_reply":"2023-03-02T10:31:38.805896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# First prediction\nprint(pred[0])\nprint(f\"Max value (probability of prediction): {np.max(pred[0])}\") # the max probability value predicted by the model\nprint(f\"Sum: {np.sum(pred[0])}\") # because we used softmax activation in our model, this will be close to 1\nprint(f\"Max index: {np.argmax(pred[0])}\") # the index of where the max value in predictions[0] occurs\nprint(f\"Predicted label: {classes[np.argmax(pred[0])]}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:31:38.809846Z","iopub.execute_input":"2023-03-02T10:31:38.810141Z","iopub.status.idle":"2023-03-02T10:31:38.823804Z","shell.execute_reply.started":"2023-03-02T10:31:38.810114Z","shell.execute_reply":"2023-03-02T10:31:38.822829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create pandas DataFrame with empty columns\npreds_df = pd.DataFrame(columns=[\"id\"] + list(classes))\npreds_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:31:38.830247Z","iopub.execute_input":"2023-03-02T10:31:38.830538Z","iopub.status.idle":"2023-03-02T10:31:38.865042Z","shell.execute_reply.started":"2023-03-02T10:31:38.830513Z","shell.execute_reply":"2023-03-02T10:31:38.863879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Append test image ID's to predictions DataFrame\ntest_path = \"/kaggle/input/dog-breed-identification/test/\"\npreds_df[\"id\"] = [os.path.splitext(path)[0] for path in os.listdir(test_path)]\npreds_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:31:38.866404Z","iopub.execute_input":"2023-03-02T10:31:38.866905Z","iopub.status.idle":"2023-03-02T10:31:39.067703Z","shell.execute_reply.started":"2023-03-02T10:31:38.866864Z","shell.execute_reply":"2023-03-02T10:31:39.066559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_df.loc[:,list(classes)]= pred\n\npreds_df.to_csv('submission.csv',index=None)\npreds_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-02T10:31:39.069601Z","iopub.execute_input":"2023-03-02T10:31:39.070331Z","iopub.status.idle":"2023-03-02T10:31:41.021475Z","shell.execute_reply.started":"2023-03-02T10:31:39.070293Z","shell.execute_reply":"2023-03-02T10:31:41.020215Z"},"trusted":true},"execution_count":null,"outputs":[]}]}