{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":7327,"databundleVersionId":861871,"sourceType":"competition"}],"dockerImageVersionId":30805,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report\n\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:17.599241Z","iopub.execute_input":"2024-12-15T14:52:17.599797Z","iopub.status.idle":"2024-12-15T14:52:18.502196Z","shell.execute_reply.started":"2024-12-15T14:52:17.599767Z","shell.execute_reply":"2024-12-15T14:52:18.501501Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Loading Dataset","metadata":{}},{"cell_type":"code","source":"train_dir = '../input/dog-breed-identification/train'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:18.503535Z","iopub.execute_input":"2024-12-15T14:52:18.503922Z","iopub.status.idle":"2024-12-15T14:52:18.508207Z","shell.execute_reply.started":"2024-12-15T14:52:18.503894Z","shell.execute_reply":"2024-12-15T14:52:18.507275Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_size = len(os.listdir('../input/dog-breed-identification/train'))\n\ntrain_size","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:18.509121Z","iopub.execute_input":"2024-12-15T14:52:18.509379Z","iopub.status.idle":"2024-12-15T14:52:18.526426Z","shell.execute_reply.started":"2024-12-15T14:52:18.509352Z","shell.execute_reply":"2024-12-15T14:52:18.525529Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv('../input/dog-breed-identification/labels.csv')\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:18.528107Z","iopub.execute_input":"2024-12-15T14:52:18.528355Z","iopub.status.idle":"2024-12-15T14:52:18.553744Z","shell.execute_reply.started":"2024-12-15T14:52:18.528331Z","shell.execute_reply":"2024-12-15T14:52:18.552983Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Extracting different classes\ndog_breeds = sorted(df['breed'].unique())\nn_classes = len(dog_breeds)\nprint(n_classes)\ndog_breeds","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:18.554670Z","iopub.execute_input":"2024-12-15T14:52:18.554909Z","iopub.status.idle":"2024-12-15T14:52:18.563325Z","shell.execute_reply.started":"2024-12-15T14:52:18.554885Z","shell.execute_reply":"2024-12-15T14:52:18.562380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Converting classes to numbers\nclass_to_num = dict(zip(dog_breeds,np.arange(n_classes)))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:18.564415Z","iopub.execute_input":"2024-12-15T14:52:18.564765Z","iopub.status.idle":"2024-12-15T14:52:18.572730Z","shell.execute_reply.started":"2024-12-15T14:52:18.564729Z","shell.execute_reply":"2024-12-15T14:52:18.572018Z"}},"outputs":[],"execution_count":null},{"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=df['breed'],order=df['breed'].value_counts().index)\nbarw(ax0)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:18.573872Z","iopub.execute_input":"2024-12-15T14:52:18.574200Z","iopub.status.idle":"2024-12-15T14:52:20.225903Z","shell.execute_reply.started":"2024-12-15T14:52:18.574164Z","shell.execute_reply":"2024-12-15T14:52:20.223128Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_test, y_train, y_test = train_test_split(df.drop('breed', axis = 1), df['breed'], test_size=0.2, random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:20.226867Z","iopub.execute_input":"2024-12-15T14:52:20.227177Z","iopub.status.idle":"2024-12-15T14:52:20.247376Z","shell.execute_reply.started":"2024-12-15T14:52:20.227144Z","shell.execute_reply":"2024-12-15T14:52:20.246488Z"}},"outputs":[],"execution_count":null},{"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 = list(df['id'])\n    image_labels = list(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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:20.248209Z","iopub.execute_input":"2024-12-15T14:52:20.248516Z","iopub.status.idle":"2024-12-15T14:52:22.936210Z","shell.execute_reply.started":"2024-12-15T14:52:20.248482Z","shell.execute_reply":"2024-12-15T14:52:22.935260Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"list(X_train['id'])[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:22.940435Z","iopub.execute_input":"2024-12-15T14:52:22.940948Z","iopub.status.idle":"2024-12-15T14:52:22.948211Z","shell.execute_reply.started":"2024-12-15T14:52:22.940917Z","shell.execute_reply":"2024-12-15T14:52:22.947161Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Selecting image size according to pretrained models\nimg_size = (299,299,3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:22.949550Z","iopub.execute_input":"2024-12-15T14:52:22.949830Z","iopub.status.idle":"2024-12-15T14:52:22.964591Z","shell.execute_reply.started":"2024-12-15T14:52:22.949805Z","shell.execute_reply":"2024-12-15T14:52:22.963779Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train['breed'] = y_train\nX_test['breed'] = y_test\nX_train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:22.965668Z","iopub.execute_input":"2024-12-15T14:52:22.965920Z","iopub.status.idle":"2024-12-15T14:52:22.982317Z","shell.execute_reply.started":"2024-12-15T14:52:22.965894Z","shell.execute_reply":"2024-12-15T14:52:22.981520Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ntrain_data, train_labels = images_to_array(train_dir, X_train, img_size)\ntest_data, test_labels = images_to_array(train_dir, X_test, img_size)\n\nprint(f'Output Train Data Size {train_data.shape}')\nprint(f'Output Train Label Size {train_labels.shape}')\nprint(f'Output Test Data Size {test_data.shape}')\nprint(f'Output Test Label Size {test_labels.shape}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:22.983563Z","iopub.execute_input":"2024-12-15T14:52:22.984348Z","iopub.status.idle":"2024-12-15T14:52:47.300870Z","shell.execute_reply.started":"2024-12-15T14:52:22.984304Z","shell.execute_reply":"2024-12-15T14:52:47.297539Z"}},"outputs":[],"execution_count":null},{"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(dog_breeds[np.where(train_labels[i] ==1)[0][0]])\n    plt.axis(False)\n    plt.imshow(train_data[i].astype('int32')) # .astype('int32') ---> as imshow() needs integer data to read the image\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:47.302264Z","iopub.execute_input":"2024-12-15T14:52:47.304713Z","iopub.status.idle":"2024-12-15T14:52:50.159243Z","shell.execute_reply.started":"2024-12-15T14:52:47.304667Z","shell.execute_reply":"2024-12-15T14:52:50.158186Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:50.160479Z","iopub.execute_input":"2024-12-15T14:52:50.160780Z","iopub.status.idle":"2024-12-15T14:52:50.168771Z","shell.execute_reply.started":"2024-12-15T14:52:50.160752Z","shell.execute_reply":"2024-12-15T14:52:50.167907Z"}},"outputs":[],"execution_count":null},{"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, train_data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:52:50.169835Z","iopub.execute_input":"2024-12-15T14:52:50.170095Z","iopub.status.idle":"2024-12-15T14:53:28.032592Z","shell.execute_reply.started":"2024-12-15T14:52:50.170054Z","shell.execute_reply":"2024-12-15T14:53:28.031619Z"}},"outputs":[],"execution_count":null},{"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, train_data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:53:28.033999Z","iopub.execute_input":"2024-12-15T14:53:28.034272Z","iopub.status.idle":"2024-12-15T14:54:14.614756Z","shell.execute_reply.started":"2024-12-15T14:53:28.034246Z","shell.execute_reply":"2024-12-15T14:54:14.613710Z"}},"outputs":[],"execution_count":null},{"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, train_data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:54:14.616048Z","iopub.execute_input":"2024-12-15T14:54:14.616345Z","iopub.status.idle":"2024-12-15T14:55:20.381944Z","shell.execute_reply.started":"2024-12-15T14:54:14.616311Z","shell.execute_reply":"2024-12-15T14:55:20.380917Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:55:20.383649Z","iopub.execute_input":"2024-12-15T14:55:20.383974Z","iopub.status.idle":"2024-12-15T14:55:20.451970Z","shell.execute_reply.started":"2024-12-15T14:55:20.383927Z","shell.execute_reply":"2024-12-15T14:55:20.451002Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"del train_data\ndel inception_features\ndel xception_features\ndel inc_resnet_features","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:55:20.453234Z","iopub.execute_input":"2024-12-15T14:55:20.453637Z","iopub.status.idle":"2024-12-15T14:55:20.465759Z","shell.execute_reply.started":"2024-12-15T14:55:20.453594Z","shell.execute_reply":"2024-12-15T14:55:20.464854Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Building and training Model","metadata":{}},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:55:20.467092Z","iopub.execute_input":"2024-12-15T14:55:20.467779Z","iopub.status.idle":"2024-12-15T14:55:20.497409Z","shell.execute_reply.started":"2024-12-15T14:55:20.467735Z","shell.execute_reply":"2024-12-15T14:55:20.496590Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Compiling Model\nmodel.compile(optimizer='adam',\n            loss='categorical_crossentropy',\n            metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:55:20.498585Z","iopub.execute_input":"2024-12-15T14:55:20.499239Z","iopub.status.idle":"2024-12-15T14:55:20.510868Z","shell.execute_reply.started":"2024-12-15T14:55:20.499198Z","shell.execute_reply":"2024-12-15T14:55:20.510268Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Training Model\nepochs =100\nhistory = model.fit(final_features,\n                  train_labels,\n                  batch_size=32,\n                  epochs=epochs,\n                  validation_split=0.1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:55:20.512432Z","iopub.execute_input":"2024-12-15T14:55:20.512816Z","iopub.status.idle":"2024-12-15T14:56:03.828804Z","shell.execute_reply.started":"2024-12-15T14:55:20.512776Z","shell.execute_reply":"2024-12-15T14:56:03.827827Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Loading and Predicting test Images","metadata":{}},{"cell_type":"code","source":"# visualizing losses and accuracy\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\ntrain_loss=history.history['loss']\nval_loss=history.history['val_loss']\ntrain_acc=history.history['accuracy']\nval_acc=history.history['val_accuracy']\n\nepochs = range(len(train_acc))\n\n\n# Visualizing losses\nplt.figure(figsize=(15, 10))\nplt.plot(epochs, train_loss, 'r', label='train_loss')\nplt.plot(epochs, val_loss, 'b', label='val_loss')\nplt.title('DenseNet40 Train loss vs Val los', fontsize=24)\nplt.xlim(xmin=0, xmax=max(epochs))\nplt.ylim(ymin=0, ymax=1)\nplt.xlabel('Epoch', fontsize=20)\nplt.ylabel('Loss', fontsize=20)\nplt.xticks(fontsize=20)\nplt.yticks(fontsize=20)\nplt.legend(fontsize=20)\nplt.show()\n\n# Visualizing accuracy\nplt.figure(figsize=(15, 10))\nplt.plot(epochs, train_acc, 'r', label='train_acc')\nplt.plot(epochs, val_acc, 'b', label='val_acc')\nplt.title('DenseNet40 Train accuracy vs Val accuracy', fontsize=24)\nplt.xlim(xmin=0, xmax=max(epochs))\nplt.ylim(ymin=0, ymax=1)\nplt.xlabel('Epoch', fontsize=20)\nplt.ylabel('Accuracy', fontsize=20)\nplt.xticks(fontsize=20)\nplt.yticks(fontsize=20)\nplt.legend(fontsize=20)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:56:03.830438Z","iopub.execute_input":"2024-12-15T14:56:03.831130Z","iopub.status.idle":"2024-12-15T14:56:04.399610Z","shell.execute_reply.started":"2024-12-15T14:56:03.831087Z","shell.execute_reply":"2024-12-15T14:56:04.398661Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Extract test data features.\ninception_features = get_features(InceptionV3, inception_preprocessor, img_size, test_data)\nxception_features = get_features(Xception, xception_preprocessor, img_size, test_data)\ninc_resnet_features = get_features(InceptionResNetV2, inc_resnet_preprocessor, img_size, test_data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:56:04.400636Z","iopub.execute_input":"2024-12-15T14:56:04.400919Z","iopub.status.idle":"2024-12-15T14:57:15.443325Z","shell.execute_reply.started":"2024-12-15T14:56:04.400891Z","shell.execute_reply":"2024-12-15T14:57:15.442372Z"}},"outputs":[],"execution_count":null},{"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":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:57:15.444797Z","iopub.execute_input":"2024-12-15T14:57:15.445078Z","iopub.status.idle":"2024-12-15T14:57:15.465680Z","shell.execute_reply.started":"2024-12-15T14:57:15.445050Z","shell.execute_reply":"2024-12-15T14:57:15.464853Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"del test_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:57:15.466622Z","iopub.execute_input":"2024-12-15T14:57:15.466870Z","iopub.status.idle":"2024-12-15T14:57:15.472562Z","shell.execute_reply.started":"2024-12-15T14:57:15.466846Z","shell.execute_reply":"2024-12-15T14:57:15.471751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.evaluate(test_features, test_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:57:15.476924Z","iopub.execute_input":"2024-12-15T14:57:15.477241Z","iopub.status.idle":"2024-12-15T14:57:15.940852Z","shell.execute_reply.started":"2024-12-15T14:57:15.477215Z","shell.execute_reply":"2024-12-15T14:57:15.939967Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model.predict(test_features, batch_size=32)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:57:15.942185Z","iopub.execute_input":"2024-12-15T14:57:15.942885Z","iopub.status.idle":"2024-12-15T14:57:16.405456Z","shell.execute_reply.started":"2024-12-15T14:57:15.942838Z","shell.execute_reply":"2024-12-15T14:57:16.404744Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"report = classification_report(np.argmax(test_labels, axis=1), np.argmax(y_pred, axis=1), \n                                target_names=dog_breeds)\n\nprint(report)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-15T14:57:16.414479Z","iopub.execute_input":"2024-12-15T14:57:16.414755Z","iopub.status.idle":"2024-12-15T14:57:16.434650Z","shell.execute_reply.started":"2024-12-15T14:57:16.414728Z","shell.execute_reply":"2024-12-15T14:57:16.433793Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}