{"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":"### Please check this video for better understanding :)","metadata":{}},{"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 \n\nfrom keras import Sequential\nfrom keras.callbacks import EarlyStopping\n\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\n# from keras import regularizers\nfrom tensorflow.keras.models import Model\n\n\nfrom keras.preprocessing.image import load_img\n# from keras.preprocessing.image import img_to_array\n# from keras.applications.imagenet_utils import decode_predictions\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 5GB 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","execution":{"iopub.status.busy":"2022-02-25T18:07:35.912277Z","iopub.execute_input":"2022-02-25T18:07:35.912673Z","iopub.status.idle":"2022-02-25T18:07:42.265576Z","shell.execute_reply.started":"2022-02-25T18:07:35.912638Z","shell.execute_reply":"2022-02-25T18:07:42.264317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## End to End Dog Breed Multi Class Classification\n### 1.Problem\nThere are 120 breeds of dog in the data. We have to identify according to their breeds.\n### 2.Data\nThere are training set and a test set of images of dogs. Each image has a filename that is its unique id. The dataset comprises 120 breeds of dogs.\n* train.zip - the training set, you are provided the breed for these dogs\n* test.zip - the test set, you must predict the probability of each breed for each image\n* sample_submission.csv - a sample submission file in the correct format\n* labels.csv - the breeds for the images in the train set\n\n### Evaluation\nCross entropy loss.\n### Features\n* we are dealing with the unstructure data set.\n* There are about 10000+ images in the training data.\n* There are about 10000+ images in the test data.\n\nNow Since we have unstructured data we have to work with the library like tensorflow. so lets import the necessary libraries and directly jump into the project","metadata":{}},{"cell_type":"code","source":"\n# 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":"2022-02-25T18:07:42.268033Z","iopub.execute_input":"2022-02-25T18:07:42.268868Z","iopub.status.idle":"2022-02-25T18:07:42.826516Z","shell.execute_reply.started":"2022-02-25T18:07:42.268819Z","shell.execute_reply":"2022-02-25T18:07:42.825227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#reading labels csv file\n\nlabels = pd.read_csv('../input/labels1/labels.csv')\nlabels.head()","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2022-02-25T18:07:42.828371Z","iopub.execute_input":"2022-02-25T18:07:42.82919Z","iopub.status.idle":"2022-02-25T18:07:43.530687Z","shell.execute_reply.started":"2022-02-25T18:07:42.829135Z","shell.execute_reply":"2022-02-25T18:07:43.525364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#describe\nlabels.describe()","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.531649Z","iopub.status.idle":"2022-02-25T18:07:43.532223Z"},"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 plant species\n\nplt.figure(figsize = (15,30))\nax0 =sns.countplot(y=labels['class'],order=labels['class'].value_counts().index)\nbarw(ax0)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.533879Z","iopub.status.idle":"2022-02-25T18:07:43.534893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# #total unique Species\n\n# labels['class'].nunique()","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.536497Z","iopub.status.idle":"2022-02-25T18:07:43.537544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Observation:**\n1. We have total 4 unique species\n2. We have atleast 50 images per category of species","metadata":{}},{"cell_type":"code","source":"# Lets check one image\nfrom IPython.display import display, Image\nImage(\"../input/training/009_003.jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.539318Z","iopub.status.idle":"2022-02-25T18:07:43.540211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nif len(os.listdir('../input/training/')) == 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":"2022-02-25T18:07:43.541907Z","iopub.status.idle":"2022-02-25T18:07:43.542861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#Create list of alphabetically sorted labels.\nclasses = sorted(list(set(labels['class'])))\nn_classes = len(classes)\nprint('Total unique species {}'.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\n","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.544526Z","iopub.status.idle":"2022-02-25T18:07:43.545579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**One-hot Encoding:**\nSince the output of our predictor for each input is a vector of probabilities for each class we must convert out label dataset to be the same format. That is for each input a row vector of length num_classes with a 1 at the index of the label and 0's everywhere else.","metadata":{}},{"cell_type":"code","source":"\ninput_shape = (331,331,3)\n\n\ndef images_to_array(directory, label_dataframe, target_size = input_shape):\n    \n    image_labels = label_dataframe['class']\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        species = image_labels[ix]\n        y[ix] = class_to_num[species]\n    \n    y = to_categorical(y)\n    \n    return images,y","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.547347Z","iopub.status.idle":"2022-02-25T18:07:43.54843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time \nt = time.time()\n\nX,y = images_to_array('../input/training', labels[:])\n\nprint('runtime in seconds: {}'.format(time.time() - t))","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.549961Z","iopub.status.idle":"2022-02-25T18:07:43.550967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# y[0]","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.552646Z","iopub.status.idle":"2022-02-25T18:07:43.553792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# X[0]","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.555383Z","iopub.status.idle":"2022-02-25T18:07:43.556296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Another way to create one hot encoded vectors\n# dummy = pd.get_dummies(df_50['class'])\n\n# classes = dummy.columns \n# print('we have total {} number of unique dog breeds'.format(len(classes)))\n\n#convert this into np.array\n\n# y = np.array(dummy)\n# # we can delete the dummy because we dont need it anymore ----- > We are saving RAM\n\n# del dummy\n\n# y[0:2]","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.557816Z","iopub.status.idle":"2022-02-25T18:07:43.558767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# np.where(y[5]==1)[0][0]\n\n# lets check some plants and their species\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\n    ","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.560424Z","iopub.status.idle":"2022-02-25T18:07:43.561328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Creating callbacks:\n\n(things to help our model)\n\nCallbacks are helper functions a model can use during training to do things such as save a models progress, check a models progress or stop training early if a model stops improving.\n\nReduceLROnPlateau: Reduce learning rate when a metric has stopped improving.","metadata":{}},{"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)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.56302Z","iopub.status.idle":"2022-02-25T18:07:43.564162Z"},"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":"2022-02-25T18:07:43.565847Z","iopub.status.idle":"2022-02-25T18:07:43.56679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Building:\n\n* The basic idea here is to extract features from the data set from pretrained models and create a simple deep net by using all those features combined.\n* So we will GlobalAveragePooling2D to extract a pooled output from our selected models\n* img_size = You can change this shape according to the documentation of the pretrained model\n* Keras documentation for all models: https://keras.io/api/applications/\n\n","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"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":"2022-02-25T18:07:43.568494Z","iopub.status.idle":"2022-02-25T18:07:43.569418Z"},"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":"2022-02-25T18:07:43.570961Z","iopub.status.idle":"2022-02-25T18:07:43.571874Z"},"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":"2022-02-25T18:07:43.57348Z","iopub.status.idle":"2022-02-25T18:07:43.574405Z"},"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":"2022-02-25T18:07:43.576012Z","iopub.status.idle":"2022-02-25T18:07:43.57706Z"},"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":"2022-02-25T18:07:43.57859Z","iopub.status.idle":"2022-02-25T18:07:43.584466Z"},"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":"2022-02-25T18:07:43.586296Z","iopub.status.idle":"2022-02-25T18:07:43.587476Z"},"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)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.589207Z","iopub.status.idle":"2022-02-25T18:07:43.590329Z"},"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":"2022-02-25T18:07:43.592087Z","iopub.status.idle":"2022-02-25T18:07:43.5932Z"},"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":"2022-02-25T18:07:43.595004Z","iopub.status.idle":"2022-02-25T18:07:43.596181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sample_df.shape","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.597964Z","iopub.status.idle":"2022-02-25T18:07:43.599121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testname=['009_005','009_014','009_016','009_023','009_027','009_032','009_038','009_041','014_005','014_014','014_016','014_023','014_027','014_032','014_038','014_041','014_047','021_005','021_014','021_016','021_023','021_027','021_032','021_038','021_041','021_047','028_005','028_014','028_016','028_023','028_027','028_032','028_036','028_038','028_041']","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.60091Z","iopub.status.idle":"2022-02-25T18:07:43.602407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(testname)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.604313Z","iopub.status.idle":"2022-02-25T18:07:43.605482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tqdm(testname)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.607208Z","iopub.status.idle":"2022-02-25T18:07:43.608367Z"},"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(testname)):\n        img_dir = os.path.join('../input/testing5/', 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('../input/testing5/', img_size)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.610182Z","iopub.status.idle":"2022-02-25T18:07:43.611321Z"},"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":"2022-02-25T18:07:43.613069Z","iopub.status.idle":"2022-02-25T18:07:43.614196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Free up some space.\ndel test_data\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.616019Z","iopub.status.idle":"2022-02-25T18:07:43.617215Z"},"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":"2022-02-25T18:07:43.619016Z","iopub.status.idle":"2022-02-25T18:07:43.620121Z"},"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":"2022-02-25T18:07:43.62187Z","iopub.status.idle":"2022-02-25T18:07:43.623051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"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()\n","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.624742Z","iopub.status.idle":"2022-02-25T18:07:43.625882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Append test image ID's to predictions DataFrame\ntest_path = \"../input/testing5\"\npreds_df[\"id\"] = [os.path.splitext(path)[0] for path in os.listdir(test_path)]\npreds_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.627758Z","iopub.status.idle":"2022-02-25T18:07:43.629053Z"},"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":"2022-02-25T18:07:43.630838Z","iopub.status.idle":"2022-02-25T18:07:43.631985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Testing with custom input:","metadata":{}},{"cell_type":"code","source":"#Custom input\n\nImage('../input/testing5/009_041.jpg')","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.63375Z","iopub.status.idle":"2022-02-25T18:07:43.634961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#reading the image and converting it into an np array\n\nimg_g = load_img('../input/testing5/009_041.jpg',target_size = img_size)\nimg_g = np.expand_dims(img_g, axis=0) # as we trained our model in (row, img_height, img_width, img_rgb) format, np.expand_dims convert the image into this format\n# img_g","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.636677Z","iopub.status.idle":"2022-02-25T18:07:43.637865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_g.shape","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.639657Z","iopub.status.idle":"2022-02-25T18:07:43.640875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# #Predict test labels given test data features.\ntest_features = extact_features(img_g)\npredg = model.predict(test_features)\nprint(f\"Predicted label: {classes[np.argmax(predg[0])]}\")\nprint(f\"Probability of prediction): {round(np.max(predg[0])) * 100} %\")","metadata":{"execution":{"iopub.status.busy":"2022-02-25T18:07:43.642618Z","iopub.status.idle":"2022-02-25T18:07:43.643758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Please upvote this notebook :)\n\n#### Special Thanks to :\n1. https://www.kaggle.com/phylake1337/0-18-loss-simple-feature-extractors","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}