{"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":"**CLASSIFYING DOG BREEDS USING TRANFER LEARNING MODEL RESNET50V2.**\n\n**HERE I HAVE TAKEN ONLY 10 SELECTED CLASSES,BUT THIS MODEL CAN BE USED FOR ENTIRE SET ALSO**\n","metadata":{}},{"cell_type":"code","source":"#importing libraries\nimport numpy as np\nimport tensorflow as tf\nfrom keras.applications.resnet_v2 import ResNet50V2\nfrom tensorflow import keras\nfrom keras.preprocessing.image import ImageDataGenerator\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.266031Z","iopub.execute_input":"2021-07-01T09:12:51.266522Z","iopub.status.idle":"2021-07-01T09:12:51.274014Z","shell.execute_reply.started":"2021-07-01T09:12:51.266460Z","shell.execute_reply":"2021-07-01T09:12:51.273035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#defining directories\ntrain_path = '../input/dog-breed-identification/train'\ntest_path = '../input/dog-breed-identification/test'\n\n#reading dataset labels\ntrain_labels = pd.read_csv('../input/dog-breed-identification/labels.csv')\ntest_labels = pd.read_csv('../input/dog-breed-identification/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.276497Z","iopub.execute_input":"2021-07-01T09:12:51.276780Z","iopub.status.idle":"2021-07-01T09:12:51.583922Z","shell.execute_reply.started":"2021-07-01T09:12:51.276755Z","shell.execute_reply":"2021-07-01T09:12:51.583026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_labels.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.585752Z","iopub.execute_input":"2021-07-01T09:12:51.586130Z","iopub.status.idle":"2021-07-01T09:12:51.596214Z","shell.execute_reply.started":"2021-07-01T09:12:51.586093Z","shell.execute_reply":"2021-07-01T09:12:51.595194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_labels.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.597993Z","iopub.execute_input":"2021-07-01T09:12:51.598471Z","iopub.status.idle":"2021-07-01T09:12:51.625828Z","shell.execute_reply.started":"2021-07-01T09:12:51.598437Z","shell.execute_reply":"2021-07-01T09:12:51.624930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#in train_labels ids are not in jpg format, hence converting them to jpg\ntrain_labels['id'] = train_labels['id'].apply(lambda x: x + \".jpg\")\ntest_labels['id'] = test_labels['id'].apply(lambda x: x + \".jpg\")","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.627183Z","iopub.execute_input":"2021-07-01T09:12:51.627687Z","iopub.status.idle":"2021-07-01T09:12:51.643069Z","shell.execute_reply.started":"2021-07-01T09:12:51.627616Z","shell.execute_reply":"2021-07-01T09:12:51.642308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#here i am training model for selected,training all breeds will take hours\n\nx = train_labels.breed.unique()\ninclude = ['beagle', 'chihuahua', 'doberman','french_bulldog', 'golden_retriever', 'malamute', 'pug', 'saint_bernard', 'scottish_deerhound','tibetan_mastiff']\nfor i in x :\n    if i not in include:\n        train_labels = train_labels.drop(train_labels[ train_labels['breed'] == i ].index)\nprint(train_labels.shape)\ntrain_labels.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.645053Z","iopub.execute_input":"2021-07-01T09:12:51.645590Z","iopub.status.idle":"2021-07-01T09:12:51.858060Z","shell.execute_reply.started":"2021-07-01T09:12:51.645556Z","shell.execute_reply":"2021-07-01T09:12:51.857320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(18,4))\ncp = sns.countplot(x = 'breed', data = train_labels)\n","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:51.860677Z","iopub.execute_input":"2021-07-01T09:12:51.861049Z","iopub.status.idle":"2021-07-01T09:12:52.034317Z","shell.execute_reply.started":"2021-07-01T09:12:51.861013Z","shell.execute_reply":"2021-07-01T09:12:52.033396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train_datagen is used for feature scaling and image augmentation (image augmentation is applied to avoid overfitting).\ntrain_datagen = ImageDataGenerator(\n                                   rescale = 1./255, \n                                   validation_split = 0.2,\n                                   shear_range = 0.2, \n                                   zoom_range = 0.2, horizontal_flip = True, \n                                   width_shift_range = 0.2,\n                                   height_shift_range = 0.2,\n                                   rotation_range = 20,\n                                   brightness_range=[0.2,1.0])\n\n#defining training set, here size of image is reduced to 224x224, batch of images is kept as 32 and class is defined as 'categorical'.\ntrain_set = train_datagen.flow_from_dataframe(dataframe = train_labels,\n                                                 directory = train_path,\n                                                 x_col = \"id\",\n                                                 y_col = \"breed\",\n                                                 batch_size = 16,\n                                                 subset=\"training\",\n                                                 class_mode = \"categorical\",\n                                                 target_size = (224,224),\n                                                 seed = 42,\n                                                 shuffle = True)","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:52.036050Z","iopub.execute_input":"2021-07-01T09:12:52.036420Z","iopub.status.idle":"2021-07-01T09:12:52.273584Z","shell.execute_reply.started":"2021-07-01T09:12:52.036384Z","shell.execute_reply":"2021-07-01T09:12:52.272631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#defining validation set, here size of image is reduced to 224x224, batch of images is kept as 32 and class is defined as 'categorical' and subset as 'validation'.\nvalidate_set = train_datagen.flow_from_dataframe(dataframe = train_labels,\n                                                 directory = train_path,\n                                                 x_col = \"id\",\n                                                 y_col = \"breed\",\n                                                 batch_size = 16,\n                                                 subset=\"validation\",\n                                                 class_mode = \"categorical\",\n                                                 target_size = (224,224),\n                                                 seed = 42,\n                                                 shuffle = True)","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:52.274949Z","iopub.execute_input":"2021-07-01T09:12:52.275311Z","iopub.status.idle":"2021-07-01T09:12:52.296485Z","shell.execute_reply.started":"2021-07-01T09:12:52.275273Z","shell.execute_reply":"2021-07-01T09:12:52.295670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#only rescaling is applied\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n#defining test set\ntest_set = test_datagen.flow_from_dataframe(dataframe = test_labels,\n                                                 directory = test_path,\n                                                 x_col = \"id\",\n                                                 y_col = None,\n                                                 batch_size = 16,\n                                                 class_mode = None,\n                                                 seed = 42,\n                                                 shuffle=False,\n                                                 target_size = (224,224))","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:12:52.298923Z","iopub.execute_input":"2021-07-01T09:12:52.299180Z","iopub.status.idle":"2021-07-01T09:13:04.862569Z","shell.execute_reply.started":"2021-07-01T09:12:52.299155Z","shell.execute_reply":"2021-07-01T09:13:04.861665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set.batch_size","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:13:04.863875Z","iopub.execute_input":"2021-07-01T09:13:04.864222Z","iopub.status.idle":"2021-07-01T09:13:04.871827Z","shell.execute_reply.started":"2021-07-01T09:13:04.864185Z","shell.execute_reply":"2021-07-01T09:13:04.870540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"1e-4","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:50:05.584490Z","iopub.execute_input":"2021-07-01T09:50:05.584811Z","iopub.status.idle":"2021-07-01T09:50:05.589885Z","shell.execute_reply.started":"2021-07-01T09:50:05.584779Z","shell.execute_reply":"2021-07-01T09:50:05.588768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#defining resnet50v2\nresnet = ResNet50V2(input_shape = [224,224,3], weights = 'imagenet', include_top = False)\n\n#we have to take pre trained weights, we don't want to train the weights again\nfor layer in resnet.layers:\n    layer.trainable = False\n\n#flattening the output of resnet for fully connected layer.\nx = keras.layers.Flatten()(resnet.output)\n\n#dropping out 40% to avoid overfitting\nx = keras.layers.Dropout(0.4)(x)\n\n#final layer will have 10 neurons\npred = keras.layers.Dense(10, activation='softmax')(x)\n\n#creating the model \nmodel = tf.keras.models.Model(inputs=resnet.input, outputs=pred)\n\n#taking learning rate as 0.00001\nopt = tf.keras.optimizers.Adam(learning_rate = 1e-5)\nmodel.compile(optimizer=opt,loss='categorical_crossentropy',metrics=['accuracy'])\n\n#defining train step and validate step (total value/batch size)\ntrain_step = train_set.n//train_set.batch_size\nvalidate_step = validate_set.n//validate_set.batch_size\n\n#training model\nresnet50 = model.fit(train_set,validation_data = validate_set,epochs = 30,steps_per_epoch = train_step, validation_steps = validate_step)","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:13:04.873245Z","iopub.execute_input":"2021-07-01T09:13:04.873604Z","iopub.status.idle":"2021-07-01T09:19:47.374524Z","shell.execute_reply.started":"2021-07-01T09:13:04.873568Z","shell.execute_reply":"2021-07-01T09:19:47.373693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#evaluating model\nmodel.evaluate(validate_set)","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:19:47.376054Z","iopub.execute_input":"2021-07-01T09:19:47.376431Z","iopub.status.idle":"2021-07-01T09:19:50.162823Z","shell.execute_reply.started":"2021-07-01T09:19:47.376391Z","shell.execute_reply":"2021-07-01T09:19:50.162078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#predicting output\nSTEP_SIZE_TEST=test_set.n//test_set.batch_size\n\n#if we don't reset we'll get output in an unordered complex manner\ntest_set.reset()\n\npred=model.predict(test_set,steps=STEP_SIZE_TEST,verbose=1)","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:19:50.164084Z","iopub.execute_input":"2021-07-01T09:19:50.164430Z","iopub.status.idle":"2021-07-01T09:20:34.905993Z","shell.execute_reply.started":"2021-07-01T09:19:50.164393Z","shell.execute_reply":"2021-07-01T09:20:34.905182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(resnet50.history['accuracy'])\nplt.plot(resnet50.history['val_accuracy'])\nplt.title('Model accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()\n\nplt.plot(resnet50.history['loss'])\nplt.plot(resnet50.history['val_loss'])\nplt.title('Model loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Test'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:20:34.907648Z","iopub.execute_input":"2021-07-01T09:20:34.908249Z","iopub.status.idle":"2021-07-01T09:20:35.191301Z","shell.execute_reply.started":"2021-07-01T09:20:34.908208Z","shell.execute_reply":"2021-07-01T09:20:35.190351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pred will be only probabilities, therefore take=ing class of highest probability.\npredicted_class_indices=np.argmax(pred,axis=1)\n\n#labels include class indices of train set\nlabels = (train_set.class_indices)\n\n#creating a dictionery\nlabels = dict((v,k) for k,v in labels.items())\n\n#predictions include names of predictions instead of number\npredictions = [labels[k] for k in predicted_class_indices]","metadata":{"execution":{"iopub.status.busy":"2021-07-01T09:20:35.192610Z","iopub.execute_input":"2021-07-01T09:20:35.193008Z","iopub.status.idle":"2021-07-01T09:20:35.205648Z","shell.execute_reply.started":"2021-07-01T09:20:35.192967Z","shell.execute_reply":"2021-07-01T09:20:35.204685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**NOTE:TRAINING AND VAILDATING WAS DONE FOR 10 CLASSES ONLY BUT WE ARE TESTING IT ON DATASET CONTAINING ALL THE CLASSES(TOTOAL 120).**\n\n**THEREFORE WE'LL BE GETTING BAD VALUES FOR THE CLASSES WHICH AREN'T TRAINED**","metadata":{}}]}