{"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":"# Dog Breed Identification\n___\n**Description :** \n___\n- You are provided with a training set and a test set of images of dogs. Each image has a filename that is its unique id. The dataset   comprises 120 breeds of dogs. The goal of the competition is to create a classifier capable of determining a dog's breed from a photo. The list of breeds is as follows: 120 breed\n\n___\n**Files Descriptions :**\n- `train.zip` - The training set, you are provided the breed for these dogs\n- `test.zip` - The test set, you must predict the probability of each breed for each image\n- `sample_submission.csv` - A sample submission file in the correct format\n- `labels.csv` - The breeds for the images in the train set\n\n","metadata":{"id":"DBXs0ObF-eGJ","tags":[]}},{"cell_type":"markdown","source":"## Importing , Preprocessing Data :\n___\n- `Read` Images\n- `Resize` Images\n- Convert Type to `tf.float32`\n- Normalize by dividing on `255`\n___","metadata":{"id":"2eJ-et5dW06W","tags":[]}},{"cell_type":"code","source":"# Basic imports \nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport cv2 as cv \nimport os\nimport tensorflow as tf\nimport tensorflow_hub as hub\nimport time\nimport datetime","metadata":{"id":"E2D-4ThP-dF-"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"/kaggle/input/dog-breed-identification\")","metadata":{"id":"pkhfb9Kj-ssk"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv(\"labels.csv\")\nlabels","metadata":{"id":"ROXvaq0P_BVb","outputId":"c8ff4d93-7cfd-4d06-de61-190c0e6834c5"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.breed.value_counts().plot(kind='bar',figsize=(30,10),title='Breeds Names');","metadata":{"id":"loavojU4_OV9","outputId":"5d761280-8bc8-4204-8b55-bcdfe120a483"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SZ=224\nbat=32","metadata":{"id":"0kGAPWAWKI3Y"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# read images in grey mode\n\ntrain_paths = labels.id.map(lambda x:f\"train//{x}.jpg\")\n\n# Minimize comp power \n# read images\n\nimgs = labels.id.map(lambda x:tf.constant(cv.resize(cv.imread(f\"train//{x}.jpg\"),(IMG_SZ,IMG_SZ)),tf.float32)/255).to_list()\nimgs = np.array(imgs)\n\ngr_imgs = labels.id.map(lambda x:tf.constant(cv.resize(cv.imread(f\"train//{x}.jpg\",0),(IMG_SZ,IMG_SZ)),tf.float32)/255).to_list()\ngr_imgs = np.array(gr_imgs)","metadata":{"id":"WUulwEJX_Zk6","outputId":"755218fc-4e48-43ab-8fed-b27570a44603","scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(imgs[5])\nplt.title(labels.breed[5])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(gr_imgs[5],cmap='gray')\nplt.title(labels.breed[5])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\n\n\n\ny_train=labels.breed\n\nunique=labels.breed.unique()\n\ny_train=np.array([list(map(lambda y : x==y , unique )) for x in y_train])\n\nlen(unique),y_train.shape","metadata":{"id":"g5n_eqgGCBVB"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train[20],labels.breed.unique()[y_train[20].argmax()],labels.breed[20]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Building Models\n___\n- MOBILENET_VS_130_224\n    ____\n- VGG:\n    - `16`\n    - `19`\n    _____\n- RESNET_V2:\n    - `50`\n    - `101`\n    - `152`\n    ____","metadata":{"tags":[]}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nimport tensorflow_hub as hub\nfrom keras.layers import Flatten, Dense, Input, MaxPooling2D, Dropout, GlobalMaxPool2D, Lambda, GlobalAveragePooling2D, BatchNormalization, Add\nfrom keras.models import Model,load_model\nfrom keras.callbacks import TensorBoard,EarlyStopping,ModelCheckpoint\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport datetime\nfrom sklearn.metrics import classification_report","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IN_SHP=imgs[0].shape\nOUT_SHP=len(set(labels.breed))\nnp.random.seed(42)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Create callbacks\n%load_ext tensorboard","metadata":{"id":"XTMFNPK2sxLe"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def evaluate(val=np.arange(5),mo=None,X=None,Y=None,uni=None):\n    \"\"\"\n    Function to evaluate Model and plot custome plot contains :\n    ____________________________________________________________\n    - Image \n    - Horizontal bar plot of highest 5 predictions\n    - Title show if it's True or False and the right breed\n    ____________________________________________________________\n    - mo  : The Model\n    - X   : Features for predictions\n    - Y   : True Labels \" Predictions \"\n    - uni : Set of Breeds \n    \"\"\"\n    pre=mo.predict(X)\n    for i in val:\n        cols = np.array(['green','gray','gray','gray','gray'])\n        resu=pd.DataFrame(data=(uni,pre[i].round(4)*100)).T.sort_values(by=[1],ascending=False)[:5]\n\n        plt.figure(figsize=(20,5))\n        ax_1=plt.subplot(1,2,1)\n        ax_1.margins(2,2)\n        ax_1.imshow(cv.cvtColor(imgs[i],cv.COLOR_BGR2RGB),cmap='gray')\n        ax_2=plt.subplot(1,2,2)\n        ax_2.margins(.5,.1)\n        # ax_2.barh(resu[0],resu[1],color=['salmon','gray','k','k','k'])\n\n        if pre[i].argmax()==Y[i].argmax():\n            ax_2.barh(resu[0],resu[1],color = cols)\n            plt.title(f\"{uni[pre[i].argmax()]} By {np.round(pre[i][pre[i].argmax()]*100,2)}%\",color='green')\n        else:\n            cols[0] = 'gray'\n            cols[resu[0]==uni[Y[i].argmax()]] = 'green'\n            ax_2.barh(resu[0],resu[1],color=cols)\n            plt.title(f\"{uni[pre[i].argmax()]} By {np.round(pre[i][pre[i].argmax()]*100,2)}% , True : {uni[Y[i].argmax()]}\",color='red')\n    return pre","metadata":{"id":"Gi6M0f4mWG44","tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### MOBILENET_VS_130_224\n- `Try single pretrained model`","metadata":{"jp-MarkdownHeadingCollapsed":true,"tags":[]}},{"cell_type":"code","source":"IN_SHP=imgs[0].shape\nOUT_SHP=len(set(labels.breed))\nMODEL_PATH = r\"https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/5\"\n\ni=Input(IN_SHP)\n\nx=hub.KerasLayer(MODEL_PATH)(i)\n\nx=Dropout(0.2)(x)\nx=BatchNormalization()(x)\nx=Dense(1024,activation='relu')(x)\n\nx=Dropout(0.2)(x)\nx=BatchNormalization()(x)\nx=Dense(512,activation='relu')(x)\n\nx=Dropout(0.2)(x)\nx=BatchNormalization()(x)\nx=Dense(1024,activation='relu')(x)\n\nx=Dense(OUT_SHP,activation='softmax')(x)\n\nmodel=Model(i,x)\n\nmodel.compile(optimizer=\"adam\",loss=\"categorical_crossentropy\",metrics=['accuracy'])\n\nmodel.summary()","metadata":{"id":"U5nQI3qjNJPE","outputId":"db3a46fb-babf-4a5e-f776-b3958927450a","scrolled":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def tb_call():\n    loc=os.path.join(\"logs\",\n                     datetime.datetime.now().strftime(\"%Y-%m-%d -- %H-%M-%S\"))\n    return TensorBoard(loc)\ntb_call_1=tb_call()\nes_call=EarlyStopping(\"val_accuracy\",verbose=1,patience=3)\nmc_call=ModelCheckpoint(r\"checkpoint\\mobilenet_v2_130_224_best.h5\",\n                        monitor='val_accuracy', save_best_only=True, mode='max', verbose=2)","metadata":{"id":"9n9d7qtns8Ln"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EP=50\nBT_SZ=128\n\ndata_gen=ImageDataGenerator(horizontal_flip=True,vertical_flip=True,width_shift_range=0.1,height_shift_range=0.1)\n\nx_tr,x_val,y_tr,y_val = train_test_split(imgs,y_train,test_size=0.1)\n\ndata=data_gen.flow(x_tr,y_tr,batch_size=BT_SZ)\n\n# val_data=data_gen.flow(x_val,y_val,batch_size=BT_SZ)\n\nmodel.fit(data,\n          validation_data=(x_val,y_val),\n          batch_size=BT_SZ,epochs=EP,\n          callbacks=[es_call,mc_call])","metadata":{"scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(x_val,y_val)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### VGG19 + InceptionResNetV2 + Xception + NASNetLarge : \n___\n- `Fearures Extraction`","metadata":{"tags":[]}},{"cell_type":"code","source":"from sklearn.preprocessing import PolynomialFeatures","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_features(model, preprocessor, input_size, imgs):\n    \"\"\"\n    Function to extract features from images using fine tunned models\n    \"\"\"\n\n    x = Input(input_size)\n    \n    x = Lambda(preprocessor)(x)\n    \n    x = model(x)\n    \n    fe_mo = Model(inputs = input_layer, outputs = base_model)\n    \n    features = fe_mo.predict(imgs, verbose=1)\n    print('Feature maps shape: ', features.shape)\n    return features","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load and use fine tuned models to extract features\n\n# MobileNet\nmb_fein = tf.keras.applications.mobilenet_v3.preprocess_input\nmb_clf = load_model(r\"checkpoint\\mobilenet_v2_130_224_best.h5\",custom_objects={'KerasLayer':hub.KerasLayer})\nmb_fe = get_features(mb_clf,mb_fein, IN_SHP, imgs)\n\n# ResNet\nres_fein = tf.keras.applications.resnet_v2.preprocess_input\nres_clf = load_model(r\"checkpoint\\RESNET152v2.h5\")\nres_fe = get_features(res_clf, res_fein, IN_SHP, imgs)\n\n# Xception\nxc_fein = tf.keras.applications.xception.preprocess_input\nxc_clf = load_model(r\"checkpoint\\xception.h5\")\nxc_fe = get_features(xc_clf, xc_fein, IN_SHP, imgs)\n\n# NASNET\nnan_fein = tf.keras.applications.nasnet.preprocess_input\nnan_clf = load_model(r\"checkpoint\\NASNET.h5\")\nnan_fe = get_features(nan_clf, nan_fein, IN_SHP, imgs)\n\n# VGG\nvg_fein = tf.keras.applications.vgg19.preprocess_input\nvg_clf = load_model(r\"checkpoint\\VGG.h5\")\nvg_fe = get_features(vg_clf, vg_fein, IN_SHP, imgs)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ad_fe = Add()([mb_fe,res_fe,xc_fe,nan_fe,vg_fe])\nad_fe = PolynomialFeatures(3).fit_transform(ad_fe)\nad_fe.shape","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Prepare Deep net\n\ni = Input(shape=ad_fe.shape[1])\n\nx = Dropout(0.7)(i)\n# x = BatchNormalization()(x)\nx = Dense(120,activation='relu')(x)\n\n# x = Dropout(0.7)(x)\n# x = BatchNormalization()(x)\nx = Dense(240,activation='relu')(x)\n\n# x = Dropout(0.2)(x)\n# x = BatchNormalization()(x)\nx = Dense(120,activation='relu')(x)\n\nx=Dense(OUT_SHP,activation= 'softmax')(x)\n\nn_model = Model(i,x)\n\nn_model.compile(optimizer='adam',\n                loss='categorical_crossentropy',\n                metrics=['accuracy'])\n\n#Training the model. \nn_model.fit(ad_fe, y_train,\n            batch_size=120,\n            epochs=20,\n            validation_split=0.1)","metadata":{"tags":[],"scrolled":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_xtr,n_xte,n_ytr,n_yte = train_test_split(ad_fe,y_train)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ev=evaluate(val=np.arange(20,len(n_xte),500),mo=n_model,X=n_xte,Y=n_yte,uni=unique)","metadata":{"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_model.evaluate(n_xte,n_yte)","metadata":{},"execution_count":null,"outputs":[]}]}