{"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":"","metadata":{}},{"cell_type":"markdown","source":" **Dog Breed Classification**","metadata":{}},{"cell_type":"code","source":"import os\nimport warnings\nimport random\nfrom shutil import copyfile\nimport numpy as np\nimport pandas as pd\nimport itertools\n#data visualization libraries\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pathlib\n#deep learning libraries\nimport tensorflow as tf\nfrom keras.optimizers import Adam\nfrom keras.layers import Conv2D, Flatten, Dense, MaxPooling2D, Dropout\nfrom keras.models import Sequential\nfrom mpl_toolkits.axes_grid1 import ImageGrid\nfrom keras.preprocessing.image import ImageDataGenerator\n#importing ResNet50 model\nfrom tensorflow.keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:23:49.398375Z","iopub.execute_input":"2021-06-16T19:23:49.398771Z","iopub.status.idle":"2021-06-16T19:23:56.902384Z","shell.execute_reply.started":"2021-06-16T19:23:49.398687Z","shell.execute_reply":"2021-06-16T19:23:56.901156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"#train and test directories\ndir_train='../input/dog-breed-identification/train'\ndir_test='../input/dog-breed-identification/test'\n\n#labels have image name and dog breed in a csv file and sample_submission contain details of test set\ndf_train= pd.read_csv('../input/dog-breed-identification/labels.csv',dtype=str)\ndf_test= pd.read_csv('../input/dog-breed-identification/sample_submission.csv',dtype=str)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:23:56.904243Z","iopub.execute_input":"2021-06-16T19:23:56.904617Z","iopub.status.idle":"2021-06-16T19:23:57.537867Z","shell.execute_reply.started":"2021-06-16T19:23:56.904576Z","shell.execute_reply":"2021-06-16T19:23:57.536785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#images are in jpg format and to match their names in csv file we appending 'jpg' in it\ndef append_ext(fn):\n    return fn+\".jpg\"","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:23:57.540604Z","iopub.execute_input":"2021-06-16T19:23:57.541093Z","iopub.status.idle":"2021-06-16T19:23:57.547618Z","shell.execute_reply.started":"2021-06-16T19:23:57.54105Z","shell.execute_reply":"2021-06-16T19:23:57.54589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"id\"] = df_train[\"id\"].apply(append_ext)\ndf_test[\"id\"] = df_test[\"id\"].apply(append_ext)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:23:57.550176Z","iopub.execute_input":"2021-06-16T19:23:57.5508Z","iopub.status.idle":"2021-06-16T19:23:57.577151Z","shell.execute_reply.started":"2021-06-16T19:23:57.550753Z","shell.execute_reply":"2021-06-16T19:23:57.575939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Training Data***","metadata":{}},{"cell_type":"code","source":"#As instructed all other breeds except suggested ones are deleted\ninc_breed=['beagle','chihuahua','doberman','french_bulldog','golden_retriever','malamute','pug','saint_bernard', 'scottish_deerhound',\n'tibetan_mastiff']\nfor i,breed in df_train.iterrows():\n    if breed[1] not in inc_breed:\n        df_train=df_train.drop([i])\n       \nlen(df_train)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:23:57.579085Z","iopub.execute_input":"2021-06-16T19:23:57.579508Z","iopub.status.idle":"2021-06-16T19:24:04.819777Z","shell.execute_reply.started":"2021-06-16T19:23:57.579464Z","shell.execute_reply":"2021-06-16T19:24:04.818665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Training set and Test set***","metadata":{}},{"cell_type":"code","source":"print(df_train.head())\ndf_test.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:04.821483Z","iopub.execute_input":"2021-06-16T19:24:04.821935Z","iopub.status.idle":"2021-06-16T19:24:04.86479Z","shell.execute_reply.started":"2021-06-16T19:24:04.821856Z","shell.execute_reply":"2021-06-16T19:24:04.863677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Training Images***","metadata":{}},{"cell_type":"code","source":"#display some images with help of matplotlib\nsource_path = \"../input/dog-breed-identification/train\"\nsub_class = os.listdir(source_path)\n\nfig = plt.figure(figsize=(10,5))\nfor i in range(len(sub_class[:8])):\n    plt.subplot(2,4,i+1)\n    imag = plt.imread(os.path.join(source_path,sub_class[i+7]))\n    plt.imshow(imag, cmap=plt.get_cmap('gray'))\n    plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:04.866177Z","iopub.execute_input":"2021-06-16T19:24:04.866856Z","iopub.status.idle":"2021-06-16T19:24:06.095744Z","shell.execute_reply.started":"2021-06-16T19:24:04.86678Z","shell.execute_reply":"2021-06-16T19:24:06.094729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Data Preprocessing***","metadata":{}},{"cell_type":"code","source":"#Generating batches of tensor image data with real-time data augmentation.\ntrain_datagen=ImageDataGenerator( rescale=1./255.,\n                                  rotation_range = 20,\n                                  brightness_range=[0.2,1.0],\n                                  width_shift_range = 0.2,\n                                  height_shift_range = 0.2,\n                        \n                                  horizontal_flip = True,\n                                \n                                  validation_split=0.1\n                                  )","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:06.099133Z","iopub.execute_input":"2021-06-16T19:24:06.099541Z","iopub.status.idle":"2021-06-16T19:24:06.106914Z","shell.execute_reply.started":"2021-06-16T19:24:06.099501Z","shell.execute_reply":"2021-06-16T19:24:06.105457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Generating batches of tensor image data with real-time data augmentation for training set.\ntrain_generator=train_datagen.flow_from_dataframe(\ndirectory=dir_train,\ndataframe=df_train,\nx_col=\"id\",\ny_col=\"breed\",\nsubset=\"training\",\nbatch_size=32,\nseed=42,\nshuffle=True,\nclass_mode=\"categorical\",\ntarget_size=(224,224)\n\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:06.109788Z","iopub.execute_input":"2021-06-16T19:24:06.110556Z","iopub.status.idle":"2021-06-16T19:24:07.916145Z","shell.execute_reply.started":"2021-06-16T19:24:06.110508Z","shell.execute_reply":"2021-06-16T19:24:07.914781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Validation Data***","metadata":{}},{"cell_type":"code","source":"#Generating batches of tensor image data with real-time data augmentation for validation set set.\nvalidation_generator=train_datagen.flow_from_dataframe(\ndirectory=dir_train,\ndataframe=df_train,\nx_col=\"id\",\ny_col=\"breed\",\nsubset=\"validation\",\nbatch_size=32,\nseed=42,\nshuffle=True,\nclass_mode=\"categorical\",\ntarget_size=(224,224)\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:07.917712Z","iopub.execute_input":"2021-06-16T19:24:07.918442Z","iopub.status.idle":"2021-06-16T19:24:07.951736Z","shell.execute_reply.started":"2021-06-16T19:24:07.918396Z","shell.execute_reply":"2021-06-16T19:24:07.950599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Test Data***","metadata":{}},{"cell_type":"code","source":"test_datagen=ImageDataGenerator(rescale=1./255.)\n#Generating batches of tensor image data with real-time data augmentation for Test set.\n\ntest_generator=test_datagen.flow_from_dataframe(\ndirectory=dir_test,\ndataframe=df_test,\nx_col=\"id\",\ny_col=None,\nbatch_size=32,\nseed=42,\nshuffle=False,\nclass_mode=None,\ntarget_size=(224,224),\n)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:07.954458Z","iopub.execute_input":"2021-06-16T19:24:07.955125Z","iopub.status.idle":"2021-06-16T19:24:28.543663Z","shell.execute_reply.started":"2021-06-16T19:24:07.955082Z","shell.execute_reply":"2021-06-16T19:24:28.542626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes=len(inc_breed)\nclasses","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:28.545476Z","iopub.execute_input":"2021-06-16T19:24:28.545925Z","iopub.status.idle":"2021-06-16T19:24:28.557605Z","shell.execute_reply.started":"2021-06-16T19:24:28.545879Z","shell.execute_reply":"2021-06-16T19:24:28.556403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Using Pretrained Model : ResNet50***","metadata":{}},{"cell_type":"code","source":"#Freezing Resnet50 model to avoid weight updation\npretrained_model =ResNet50(\n        weights='imagenet',\n        include_top=False ,\n        input_shape=(224,224,3)\n    )","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:28.560325Z","iopub.execute_input":"2021-06-16T19:24:28.561049Z","iopub.status.idle":"2021-06-16T19:24:36.146661Z","shell.execute_reply.started":"2021-06-16T19:24:28.561001Z","shell.execute_reply":"2021-06-16T19:24:36.145285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#defing model\nmodel =Sequential([ \n        pretrained_model,  \n        Flatten(),\n#         tf.keras.layers.GlobalAveragePooling2D(),\n        Dense(2048, activation='relu'),\n        Dropout(0.5),\n\n        Dense(256, activation='relu'),\n        Dropout(0.5),\n        Dense(64, activation='relu'),\n        Dropout(0.3),\n    \n        Dense(10, activation='softmax')\n    ])","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:36.152131Z","iopub.execute_input":"2021-06-16T19:24:36.15476Z","iopub.status.idle":"2021-06-16T19:24:36.823403Z","shell.execute_reply.started":"2021-06-16T19:24:36.154699Z","shell.execute_reply":"2021-06-16T19:24:36.822295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#as mentioned f1score, recall, precision are defined as our judging criteria for model\nfrom keras import backend as bd\n\ndef recall_m(y_true, y_pred):\n    true_positives =bd.sum(bd.round(bd.clip(y_true*y_pred,0,1)))\n    possible_positives =bd.sum(bd.round(bd.clip(y_true,0,1)))\n    recall =true_positives/(possible_positives+bd.epsilon())\n    return recall\n\ndef precision_m(y_true, y_pred):\n    true_positives =bd.sum(bd.round(bd.clip(y_true*y_pred,0,1)))\n    predicted_positives =bd.sum(bd.round(bd.clip(y_pred,0,1)))\n    precision = true_positives / (predicted_positives+bd.epsilon())\n    return precision\n\ndef f1_m(y_true, y_pred): \n    precision =precision_m(y_true,y_pred)\n    recall =recall_m(y_true,y_pred)\n    return (2*((precision*recall)/(precision+recall+bd.epsilon())))","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:36.826036Z","iopub.execute_input":"2021-06-16T19:24:36.826761Z","iopub.status.idle":"2021-06-16T19:24:36.837099Z","shell.execute_reply.started":"2021-06-16T19:24:36.826714Z","shell.execute_reply":"2021-06-16T19:24:36.835737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#stochastic gradient descent is used as optimizer and categorical_crossentropy is used for multiclass classification.\nopt=Adam(lr=1e-4)\nmodel.compile(optimizer=opt,loss='categorical_crossentropy',metrics=['acc',f1_m,precision_m, recall_m])","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:36.838512Z","iopub.execute_input":"2021-06-16T19:24:36.839034Z","iopub.status.idle":"2021-06-16T19:24:36.86498Z","shell.execute_reply.started":"2021-06-16T19:24:36.838944Z","shell.execute_reply":"2021-06-16T19:24:36.863648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:36.868846Z","iopub.execute_input":"2021-06-16T19:24:36.869259Z","iopub.status.idle":"2021-06-16T19:24:36.899556Z","shell.execute_reply.started":"2021-06-16T19:24:36.869227Z","shell.execute_reply":"2021-06-16T19:24:36.898421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Model Fitting***","metadata":{}},{"cell_type":"code","source":"#model fitting with 50 epochs\nstep_size_ =train_generator.n//train_generator.batch_size\nvalid_step_size_ =validation_generator.n//validation_generator.batch_size\nhistory =model.fit(train_generator,\n                    steps_per_epoch=step_size_,\n                    validation_data=validation_generator,\n                    validation_steps=valid_step_size_ ,\n                    epochs=50,\n#                     \n                   )","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:24:36.900989Z","iopub.execute_input":"2021-06-16T19:24:36.901421Z","iopub.status.idle":"2021-06-16T19:38:18.700566Z","shell.execute_reply.started":"2021-06-16T19:24:36.90138Z","shell.execute_reply":"2021-06-16T19:38:18.699313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Plotting Curves***","metadata":{}},{"cell_type":"code","source":"#plot of epoch vs accuracy for trainig set and epoch vs validation_accuracy for validation set\nacc=history.history['acc']\nval_acc=history.history['val_acc']\nloss=history.history['loss']\nval_loss=history.history['val_loss']\n\nepochs=range(len(acc))\n\nfig=plt.figure(figsize=(14,7))\nplt.plot(epochs,acc,'r', label='training Accuracy')\nplt.plot(epochs,val_acc,'b', label='Validation Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('accuracy')\nplt.title(' training vs validation accuracy')\nplt.legend(loc='lower right')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:38:18.704162Z","iopub.execute_input":"2021-06-16T19:38:18.704481Z","iopub.status.idle":"2021-06-16T19:38:18.933714Z","shell.execute_reply.started":"2021-06-16T19:38:18.704449Z","shell.execute_reply":"2021-06-16T19:38:18.931955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#plot of epoch vs loss for trainig set and epoch vs validation_loss for validation set\n\nfig2=plt.figure(figsize=(14,7))\nplt.plot(epochs,loss,'r', label='training Accuracy')\nplt.plot(epochs,val_loss,'b', label='Validation Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('accuracy')\nplt.title(' training vs validation accuracy')\nplt.legend(loc='upper right')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:38:18.937234Z","iopub.execute_input":"2021-06-16T19:38:18.937854Z","iopub.status.idle":"2021-06-16T19:38:19.160142Z","shell.execute_reply.started":"2021-06-16T19:38:18.937765Z","shell.execute_reply":"2021-06-16T19:38:19.158973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#judging criterias of our model\nloss, accuracy, f1_score, precision, recall = model.evaluate(validation_generator,batch_size=32)\n\nprint(\"Loss:\", loss)\nprint(\"Accuracy:\", accuracy)\nprint(\"F1 Score:\", f1_score)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:38:19.161738Z","iopub.execute_input":"2021-06-16T19:38:19.162521Z","iopub.status.idle":"2021-06-16T19:38:21.628329Z","shell.execute_reply.started":"2021-06-16T19:38:19.162471Z","shell.execute_reply":"2021-06-16T19:38:21.627167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***Saving the Model for in future use","metadata":{}},{"cell_type":"code","source":"#saving model for further use \nmodel.save(\"DogClassificationByResNet2.h5\")","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:38:21.630063Z","iopub.execute_input":"2021-06-16T19:38:21.630543Z","iopub.status.idle":"2021-06-16T19:38:30.327693Z","shell.execute_reply.started":"2021-06-16T19:38:21.630482Z","shell.execute_reply":"2021-06-16T19:38:30.326321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***model prediction on test data(sample_submission.csv)***","metadata":{}},{"cell_type":"code","source":"#prediction on test set using test generator\npred=model.predict(test_generator)","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:38:30.333897Z","iopub.execute_input":"2021-06-16T19:38:30.334658Z","iopub.status.idle":"2021-06-16T19:40:08.045489Z","shell.execute_reply.started":"2021-06-16T19:38:30.334605Z","shell.execute_reply":"2021-06-16T19:40:08.044355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#sample test file\ndf_submission = pd.read_csv('/kaggle/input/dog-breed-identification/sample_submission.csv', usecols= inc_breed+['id'])\ndf_submission.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:40:08.047367Z","iopub.execute_input":"2021-06-16T19:40:08.047798Z","iopub.status.idle":"2021-06-16T19:40:08.236944Z","shell.execute_reply.started":"2021-06-16T19:40:08.047754Z","shell.execute_reply":"2021-06-16T19:40:08.235816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"***updating the values of probability***","metadata":{}},{"cell_type":"code","source":"#prediction on sample test file    \ndf_submission.iloc[:,1:] = pred\ndf_submission.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:40:08.238537Z","iopub.execute_input":"2021-06-16T19:40:08.239004Z","iopub.status.idle":"2021-06-16T19:40:08.293264Z","shell.execute_reply.started":"2021-06-16T19:40:08.238957Z","shell.execute_reply":"2021-06-16T19:40:08.291792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#size of data\ndf_submission.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-16T19:40:08.295092Z","iopub.execute_input":"2021-06-16T19:40:08.295729Z","iopub.status.idle":"2021-06-16T19:40:08.303025Z","shell.execute_reply.started":"2021-06-16T19:40:08.29568Z","shell.execute_reply":"2021-06-16T19:40:08.301491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}