{"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":"2021-06-02T13:41:26.445529Z","iopub.execute_input":"2021-06-02T13:41:26.445941Z","iopub.status.idle":"2021-06-02T13:41:26.451443Z","shell.execute_reply.started":"2021-06-02T13:41:26.445905Z","shell.execute_reply":"2021-06-02T13:41:26.450268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Importing the Required Libraries\nimport numpy as np\nimport pickle\nimport cv2\nfrom os import listdir\nimport tensorflow as tf\nfrom tensorflow import keras \nfrom sklearn import preprocessing\nfrom tensorflow.python.keras import Sequential\n#from keras.models import Sequential\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.layers.convolutional import Conv2D\nfrom keras.layers.convolutional import MaxPooling2D\nfrom keras.layers.core import Activation, Flatten, Dropout, Dense\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.optimizers import Adam\nfrom keras.preprocessing import image\nfrom keras.preprocessing.image import img_to_array\nfrom sklearn.preprocessing import MultiLabelBinarizer\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport pandas as pd","metadata":{"execution":{"iopub.status.busy":"2021-06-02T13:41:27.262723Z","iopub.execute_input":"2021-06-02T13:41:27.26303Z","iopub.status.idle":"2021-06-02T13:41:27.269837Z","shell.execute_reply.started":"2021-06-02T13:41:27.263Z","shell.execute_reply":"2021-06-02T13:41:27.268849Z"},"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":"2021-06-02T13:41:29.884451Z","iopub.execute_input":"2021-06-02T13:41:29.884779Z","iopub.status.idle":"2021-06-02T13:41:29.891376Z","shell.execute_reply.started":"2021-06-02T13:41:29.884748Z","shell.execute_reply":"2021-06-02T13:41:29.890465Z"},"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":"2021-06-02T13:41:33.023822Z","iopub.execute_input":"2021-06-02T13:41:33.024163Z","iopub.status.idle":"2021-06-02T13:41:33.812927Z","shell.execute_reply.started":"2021-06-02T13:41:33.024128Z","shell.execute_reply":"2021-06-02T13:41:33.812087Z"},"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":"2021-06-02T13:41:34.031418Z","iopub.execute_input":"2021-06-02T13:41:34.031732Z","iopub.status.idle":"2021-06-02T13:41:34.080339Z","shell.execute_reply.started":"2021-06-02T13:41:34.031704Z","shell.execute_reply":"2021-06-02T13:41:34.079656Z"},"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":{"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":"2021-06-02T13:41:42.459354Z","iopub.execute_input":"2021-06-02T13:41:42.459659Z","iopub.status.idle":"2021-06-02T13:41:42.466205Z","shell.execute_reply.started":"2021-06-02T13:41:42.45963Z","shell.execute_reply":"2021-06-02T13:41:42.465344Z"},"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":"2021-06-02T13:41:43.257817Z","iopub.execute_input":"2021-06-02T13:41:43.258161Z","iopub.status.idle":"2021-06-02T13:41:43.265976Z","shell.execute_reply.started":"2021-06-02T13:41:43.258131Z","shell.execute_reply":"2021-06-02T13:41:43.265116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Selecting image size according to pretrained models\nimg_size = (224,224,3)","metadata":{"execution":{"iopub.status.busy":"2021-06-02T13:41:44.979453Z","iopub.execute_input":"2021-06-02T13:41:44.97978Z","iopub.status.idle":"2021-06-02T13:41:44.983466Z","shell.execute_reply.started":"2021-06-02T13:41:44.979751Z","shell.execute_reply":"2021-06-02T13:41:44.982624Z"},"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":"2021-06-02T13:41:45.589118Z","iopub.execute_input":"2021-06-02T13:41:45.589432Z","iopub.status.idle":"2021-06-02T13:43:23.79984Z","shell.execute_reply.started":"2021-06-02T13:41:45.589403Z","shell.execute_reply":"2021-06-02T13:43:23.797961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = tf.keras.applications.DenseNet201(\n    include_top=True,\n    weights=None,\n    input_tensor=None,\n    input_shape=(224,224,3),\n    pooling=\"avg\",\n    classes=120\n)\nmodel.summary()","metadata":{"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":"2021-06-02T13:44:06.94628Z","iopub.execute_input":"2021-06-02T13:44:06.946611Z","iopub.status.idle":"2021-06-02T13:44:06.976253Z","shell.execute_reply.started":"2021-06-02T13:44:06.94658Z","shell.execute_reply":"2021-06-02T13:44:06.97517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Training Model\nhistory = model.fit(X,\n                  y,\n                  batch_size=32,\n                  epochs=50,\n                  validation_split=0.1)","metadata":{"execution":{"iopub.status.busy":"2021-06-02T13:44:08.382535Z","iopub.execute_input":"2021-06-02T13:44:08.382874Z","iopub.status.idle":"2021-06-02T14:55:59.131093Z","shell.execute_reply.started":"2021-06-02T13:44:08.382842Z","shell.execute_reply":"2021-06-02T14:55:59.130298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Converting model to .tflite\nimport tensorflow as tf\nconverter = tf.lite.TFLiteConverter.from_keras_model(model)\ntflite_model = converter.convert()\n\nwith open('model.tflite', 'wb') as f:\n  f.write(tflite_model)","metadata":{"execution":{"iopub.status.busy":"2021-06-02T14:56:41.756175Z","iopub.execute_input":"2021-06-02T14:56:41.756502Z","iopub.status.idle":"2021-06-02T14:58:24.795779Z","shell.execute_reply.started":"2021-06-02T14:56:41.756472Z","shell.execute_reply":"2021-06-02T14:58:24.79493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nimport cv2\n\nimg = cv2.imread(\"../input/dog-breed-identification/test/000621fb3cbb32d8935728e48679680e.jpg\")\nimg = cv2.resize(img, (299,299))\nimg = np.array(img, dtype=\"float32\")\nimg = np.reshape(img, (1,299,299,3))","metadata":{"execution":{"iopub.status.busy":"2021-06-01T14:57:50.149415Z","iopub.execute_input":"2021-06-01T14:57:50.149739Z","iopub.status.idle":"2021-06-01T14:57:50.179355Z","shell.execute_reply.started":"2021-06-01T14:57:50.149707Z","shell.execute_reply":"2021-06-01T14:57:50.178609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"interpreter = tf.lite.Interpreter(model_path=\"./model.tflite\")\ninterpreter.allocate_tensors()\n\n# Get input and output tensors.\ninput_details = interpreter.get_input_details()\noutput_details = interpreter.get_output_details()\n\n# Test the model on random input data.\ninput_shape = input_details[0]['shape']\n\n#print(\"*\"*50, input_details)\ninterpreter.set_tensor(input_details[0]['index'], img)\n\ninterpreter.invoke()\n\n# The function `get_tensor()` returns a copy of the tensor data.\n# Use `tensor()` in order to get a pointer to the tensor.\noutput_data = interpreter.get_tensor(output_details[0]['index'])\nprint(dog_breeds[np.argmax(output_data[0])])","metadata":{"execution":{"iopub.status.busy":"2021-06-01T14:57:50.60406Z","iopub.execute_input":"2021-06-01T14:57:50.604484Z","iopub.status.idle":"2021-06-01T14:57:51.35793Z","shell.execute_reply.started":"2021-06-01T14:57:50.604443Z","shell.execute_reply":"2021-06-01T14:57:51.356999Z"},"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":{"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":{"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":{"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":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del X","metadata":{"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":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Compiling Model\nmodel.compile(optimizer='adam',\n            loss='categorical_crossentropy',\n            metrics=['accuracy'])","metadata":{"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=50,\n                  validation_split=0.1,\n                  callbacks=my_callback)","metadata":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df = pd.read_csv('../input/dog-breed-identification/sample_submission.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data = images_to_array2(test_dir, sample_df, img_size)","metadata":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xception_features = get_features(Xception, xception_preprocessor, img_size, test_data)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inc_resnet_features = get_features(InceptionResNetV2, inc_resnet_preprocessor, img_size, test_data)","metadata":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del test_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model.predict(test_features, batch_size=32)","metadata":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}