{"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":"# Introduction\n* The Notebook is created on Dog Breed Dataset.\n* The Notebook helps you to move one step further in transfer learning.\n* As there are 120 Different Breeds of Dog present in the Dataset it becomes difficult for a single pretrained model to give Good results.\n* Here we used 3 different pretrained models to extract features from the images and combined them and then trained a DNN model on these features.","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:54.727807Z","iopub.execute_input":"2023-06-04T14:56:54.728168Z","iopub.status.idle":"2023-06-04T14:56:55.468766Z","shell.execute_reply.started":"2023-06-04T14:56:54.728128Z","shell.execute_reply":"2023-06-04T14:56:55.468013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading Dataset","metadata":{}},{"cell_type":"code","source":"train_dir = '../input/dog-breed-identification/train'\ntest_dir = '../input/dog-breed-identification/test'","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:55.471378Z","iopub.execute_input":"2023-06-04T14:56:55.471771Z","iopub.status.idle":"2023-06-04T14:56:55.476104Z","shell.execute_reply.started":"2023-06-04T14:56:55.471707Z","shell.execute_reply":"2023-06-04T14:56:55.475041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = len(os.listdir('../input/dog-breed-identification/train'))\ntest_size = len(os.listdir('../input/dog-breed-identification/test'))\n\ntrain_size,test_size","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:55.477681Z","iopub.execute_input":"2023-06-04T14:56:55.478217Z","iopub.status.idle":"2023-06-04T14:56:55.789392Z","shell.execute_reply.started":"2023-06-04T14:56:55.478179Z","shell.execute_reply":"2023-06-04T14:56:55.788681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('../input/dog-breed-identification/labels.csv')\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:55.790635Z","iopub.execute_input":"2023-06-04T14:56:55.791001Z","iopub.status.idle":"2023-06-04T14:56:55.830653Z","shell.execute_reply.started":"2023-06-04T14:56:55.790972Z","shell.execute_reply":"2023-06-04T14:56:55.830010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Extracting different classes\ndog_breeds = sorted(df['breed'].unique())\nn_classes = len(dog_breeds)\nprint(n_classes)\ndog_breeds","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:55.834943Z","iopub.execute_input":"2023-06-04T14:56:55.836186Z","iopub.status.idle":"2023-06-04T14:56:55.848492Z","shell.execute_reply.started":"2023-06-04T14:56:55.836149Z","shell.execute_reply":"2023-06-04T14:56:55.847330Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Converting classes to numbers\nclass_to_num = dict(zip(dog_breeds,range(n_classes)))","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:55.851084Z","iopub.execute_input":"2023-06-04T14:56:55.851317Z","iopub.status.idle":"2023-06-04T14:56:55.856103Z","shell.execute_reply.started":"2023-06-04T14:56:55.851294Z","shell.execute_reply":"2023-06-04T14:56:55.854898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Function to load and convert images to array\nfrom keras.preprocessing.image import load_img\nfrom keras.utils import to_categorical\n\ndef images_to_array(data_dir,df,image_size):\n    image_names = df['id']\n    image_labels = df['breed']\n    data_size = len(image_names)\n    \n    X = np.zeros([data_size,image_size[0],image_size[1],image_size[2]],dtype = np.uint8)\n    y = np.zeros([data_size,1],dtype = np.uint8)\n    \n    for i in range(data_size):\n        img_name = image_names[i]\n        img_dir = os.path.join(data_dir,img_name+'.jpg')\n        img_pixels = load_img(img_dir,target_size=image_size)\n        X[i] = img_pixels\n        y[i] = class_to_num[image_labels[i]]\n        \n    y = to_categorical(y)\n    \n    ind = np.random.permutation(data_size)\n    X = X[ind]\n    y = y[ind]\n    print('Ouptut Data Size: ', X.shape)\n    print('Ouptut Label Size: ', y.shape)\n    return X, y     ","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:56:55.857361Z","iopub.execute_input":"2023-06-04T14:56:55.858155Z","iopub.status.idle":"2023-06-04T14:57:00.674043Z","shell.execute_reply.started":"2023-06-04T14:56:55.858112Z","shell.execute_reply":"2023-06-04T14:57:00.673066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Selecting image size according to pretrained models\nimg_size = (299,299,3)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:57:00.675475Z","iopub.execute_input":"2023-06-04T14:57:00.675861Z","iopub.status.idle":"2023-06-04T14:57:00.680700Z","shell.execute_reply.started":"2023-06-04T14:57:00.675819Z","shell.execute_reply":"2023-06-04T14:57:00.679832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X, y = images_to_array(train_dir,df,img_size)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:57:00.682330Z","iopub.execute_input":"2023-06-04T14:57:00.682754Z","iopub.status.idle":"2023-06-04T14:58:13.801518Z","shell.execute_reply.started":"2023-06-04T14:57:00.682699Z","shell.execute_reply":"2023-06-04T14:58:13.800500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Extracting Features","metadata":{}},{"cell_type":"code","source":"#Function to extract features from images\nfrom keras.models import Model\nfrom keras.layers import BatchNormalization, Dense, GlobalAveragePooling2D,Lambda, Dropout, InputLayer, Input\n\ndef get_features(model_name, data_preprocessor, input_size, data):\n    #Prepare pipeline.\n    input_layer = Input(input_size)\n    preprocessor = Lambda(data_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    #Extract feature.\n    feature_maps = feature_extractor.predict(data, batch_size=32, verbose=1)\n    print('Feature maps shape: ', feature_maps.shape)\n    return feature_maps","metadata":{"execution":{"iopub.status.busy":"2023-06-04T14:58:13.802831Z","iopub.execute_input":"2023-06-04T14:58:13.803186Z","iopub.status.idle":"2023-06-04T14:58:13.811683Z","shell.execute_reply.started":"2023-06-04T14:58:13.803154Z","shell.execute_reply":"2023-06-04T14:58:13.810672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Extracting 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-06-04T14:58:13.813071Z","iopub.execute_input":"2023-06-04T14:58:13.813651Z","iopub.status.idle":"2023-06-04T14:58:50.374250Z","shell.execute_reply.started":"2023-06-04T14:58:13.813611Z","shell.execute_reply":"2023-06-04T14:58:50.373168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Extracting 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-06-04T14:58:50.376285Z","iopub.execute_input":"2023-06-04T14:58:50.376692Z","iopub.status.idle":"2023-06-04T14:59:37.997949Z","shell.execute_reply.started":"2023-06-04T14:58:50.376630Z","shell.execute_reply":"2023-06-04T14:59:37.996900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Extracting 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-06-04T14:59:37.999443Z","iopub.execute_input":"2023-06-04T14:59:37.999840Z","iopub.status.idle":"2023-06-04T15:00:50.799404Z","shell.execute_reply.started":"2023-06-04T14:59:37.999791Z","shell.execute_reply":"2023-06-04T15:00:50.798469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#concatinating features\nfinal_features = np.concatenate([inception_features,\n                                 xception_features,\n                                 inc_resnet_features,], axis=-1)\nprint('Final feature maps shape', final_features.shape)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:50.801129Z","iopub.execute_input":"2023-06-04T15:00:50.801513Z","iopub.status.idle":"2023-06-04T15:00:50.891478Z","shell.execute_reply.started":"2023-06-04T15:00:50.801471Z","shell.execute_reply":"2023-06-04T15:00:50.890520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del X","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:50.893301Z","iopub.execute_input":"2023-06-04T15:00:50.893729Z","iopub.status.idle":"2023-06-04T15:00:50.905355Z","shell.execute_reply.started":"2023-06-04T15:00:50.893666Z","shell.execute_reply":"2023-06-04T15:00:50.904339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Building and training Model","metadata":{}},{"cell_type":"code","source":"#Callbacks\nfrom keras.callbacks import EarlyStopping\nEarlyStop_callback = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)\nmy_callback=[EarlyStop_callback]","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:50.907245Z","iopub.execute_input":"2023-06-04T15:00:50.907829Z","iopub.status.idle":"2023-06-04T15:00:50.915177Z","shell.execute_reply.started":"2023-06-04T15:00:50.907781Z","shell.execute_reply":"2023-06-04T15:00:50.914164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Building Model\nfrom keras.models import Sequential\nmodel = Sequential()\nmodel.add(InputLayer(final_features.shape[1:]))\nmodel.add(Dropout(0.7))\nmodel.add(Dense(120,activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:50.916862Z","iopub.execute_input":"2023-06-04T15:00:50.917304Z","iopub.status.idle":"2023-06-04T15:00:50.953807Z","shell.execute_reply.started":"2023-06-04T15:00:50.917254Z","shell.execute_reply":"2023-06-04T15:00:50.953139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Compiling Model\nmodel.compile(optimizer='adam',\n            loss='categorical_crossentropy',\n            metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:50.955619Z","iopub.execute_input":"2023-06-04T15:00:50.956195Z","iopub.status.idle":"2023-06-04T15:00:50.971205Z","shell.execute_reply.started":"2023-06-04T15:00:50.956158Z","shell.execute_reply":"2023-06-04T15:00:50.970423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Training Model\nhistory = model.fit(final_features,\n                  y,\n                  batch_size=32,\n                  epochs=51,\n                  validation_split=0.1,\n                  callbacks=my_callback)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:50.972598Z","iopub.execute_input":"2023-06-04T15:00:50.973063Z","iopub.status.idle":"2023-06-04T15:00:59.559768Z","shell.execute_reply.started":"2023-06-04T15:00:50.973022Z","shell.execute_reply":"2023-06-04T15:00:59.559029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading and Predicting test Images","metadata":{}},{"cell_type":"code","source":"#Converting test images to array\ndef images_to_array2(data_dir,df, img_size):\n    images_names = df['id']\n    data_size = len(images_names)\n    X = np.zeros([data_size, img_size[0], img_size[1], 3], dtype=np.uint8)\n    \n    for i in range(data_size):\n        image_name = images_names[i]\n        img_dir = os.path.join(data_dir, image_name+'.jpg')\n        img_pixels = load_img(img_dir, target_size=img_size)\n        X[i] = img_pixels\n        \n    print('Ouptut Data Size: ', X.shape)\n    return X","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:59.561177Z","iopub.execute_input":"2023-06-04T15:00:59.561520Z","iopub.status.idle":"2023-06-04T15:00:59.569393Z","shell.execute_reply.started":"2023-06-04T15:00:59.561489Z","shell.execute_reply":"2023-06-04T15:00:59.568475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df = pd.read_csv('../input/dog-breed-identification/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:00:59.571107Z","iopub.execute_input":"2023-06-04T15:00:59.571518Z","iopub.status.idle":"2023-06-04T15:01:00.010677Z","shell.execute_reply.started":"2023-06-04T15:00:59.571480Z","shell.execute_reply":"2023-06-04T15:01:00.009773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data = images_to_array2(test_dir, sample_df, img_size)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:01:00.012180Z","iopub.execute_input":"2023-06-04T15:01:00.012552Z","iopub.status.idle":"2023-06-04T15:02:11.341379Z","shell.execute_reply.started":"2023-06-04T15:01:00.012511Z","shell.execute_reply":"2023-06-04T15:02:11.340423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Extract test data features.\ninception_features = get_features(InceptionV3, inception_preprocessor, img_size, test_data)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:02:11.342879Z","iopub.execute_input":"2023-06-04T15:02:11.343243Z","iopub.status.idle":"2023-06-04T15:02:42.226056Z","shell.execute_reply.started":"2023-06-04T15:02:11.343203Z","shell.execute_reply":"2023-06-04T15:02:42.224549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xception_features = get_features(Xception, xception_preprocessor, img_size, test_data)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:02:42.227585Z","iopub.execute_input":"2023-06-04T15:02:42.227959Z","iopub.status.idle":"2023-06-04T15:03:29.464533Z","shell.execute_reply.started":"2023-06-04T15:02:42.227927Z","shell.execute_reply":"2023-06-04T15:03:29.463490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inc_resnet_features = get_features(InceptionResNetV2, inc_resnet_preprocessor, img_size, test_data)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:03:29.466072Z","iopub.execute_input":"2023-06-04T15:03:29.466411Z","iopub.status.idle":"2023-06-04T15:04:42.839530Z","shell.execute_reply.started":"2023-06-04T15:03:29.466379Z","shell.execute_reply":"2023-06-04T15:04:42.838578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_features = np.concatenate([inception_features,\n                                 xception_features,\n                                 inc_resnet_features],axis=-1)\nprint('Final feature maps shape', test_features.shape)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:04:42.841548Z","iopub.execute_input":"2023-06-04T15:04:42.841961Z","iopub.status.idle":"2023-06-04T15:04:42.931214Z","shell.execute_reply.started":"2023-06-04T15:04:42.841901Z","shell.execute_reply":"2023-06-04T15:04:42.929891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del test_data","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:04:42.933620Z","iopub.execute_input":"2023-06-04T15:04:42.934260Z","iopub.status.idle":"2023-06-04T15:04:43.094157Z","shell.execute_reply.started":"2023-06-04T15:04:42.934216Z","shell.execute_reply":"2023-06-04T15:04:43.093271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model.predict(test_features, batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:04:43.095849Z","iopub.execute_input":"2023-06-04T15:04:43.096235Z","iopub.status.idle":"2023-06-04T15:04:43.654123Z","shell.execute_reply.started":"2023-06-04T15:04:43.096193Z","shell.execute_reply":"2023-06-04T15:04:43.653363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for breed in dog_breeds:\n    sample_df[breed] = y_pred[:,class_to_num[breed]]\nsample_df.to_csv('pred.csv', index=None)","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:04:43.655594Z","iopub.execute_input":"2023-06-04T15:04:43.656161Z","iopub.status.idle":"2023-06-04T15:04:46.180899Z","shell.execute_reply.started":"2023-06-04T15:04:43.656117Z","shell.execute_reply":"2023-06-04T15:04:46.180025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-04T15:04:46.182325Z","iopub.execute_input":"2023-06-04T15:04:46.182703Z","iopub.status.idle":"2023-06-04T15:04:46.222952Z","shell.execute_reply.started":"2023-06-04T15:04:46.182660Z","shell.execute_reply":"2023-06-04T15:04:46.222016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}