{"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":"### `Kaggle Competition`\n# Dogs-Cats Calssification:\n____\n## **Description:**\n\n- The training archive contains 25,000 images of dogs and cats. Train your algorithm on these files and predict the labels for test1.zip (1 = dog, 0 = cat).\n\n- **LINK: `https://www.kaggle.com/competitions/dogs-vs-cats/`**","metadata":{}},{"cell_type":"markdown","source":"- #### Import Basic Liberaries","metadata":{}},{"cell_type":"code","source":"##Import basic liberaries:\nimport os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2 as cv\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split","metadata":{"id":"XAvHHmDsX-O8"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import, Extract and Check data:\n","metadata":{"id":"uUXQnh2IXv4z"}},{"cell_type":"code","source":"paths = np.array(os.listdir(\"train\\\\\"))\nlabels = np.array(pd.Series(paths).map(lambda x:1 if x.split('.')[0]=='dog' else 0).to_list())\n\nx_tr, x_val, y_tr, y_val = train_test_split(paths, labels, test_size=0.1, random_state=55)","metadata":{"id":"LAokf0XRaNmp"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IM_SZ = 150","metadata":{"id":"s1pJLJ3DeClm"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Images\nx_tr,x_val = pd.Series(x_tr).map(lambda x:tf.constant(cv.resize(cv.imread(f\"train\\\\{x}\"),(IM_SZ,IM_SZ)),tf.float32)/255).to_list(),\\\n             pd.Series(x_val).map(lambda x:tf.constant(cv.resize(cv.imread(f\"train\\\\{x}\"),(IM_SZ,IM_SZ)),tf.float32)/255).to_list()\n\nx_tr,x_val = np.array(x_tr), np.array(x_val)","metadata":{"id":"FeOw-7axa8KU"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check Data Distribution\n\npd.Series(labels).value_counts().plot(kind='bar',color=['gray','salmon'])\nplt.xticks([0,1],[\"dog\",\"cat\"]);","metadata":{"id":"KswvT32tiVOu","outputId":"b7aad154-3bf7-419c-aefc-04b1d26037b2"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize(num=12,x=4,data=x_tr,labels=y_tr,true_labels=y_tr):\n    \"\"\"\n    Function to visualize some images in grid.\n    _________________________________________________\n        Parameters:\n            num(int)           : Numper of images\n            x(int)             : Grid rows numper\n            y(int)             : Grid columns numper\n            data(matrix)       : Images to print\n            labels(array)      : Labels of images\n            true_lables(array) : True Labels of Images\n                                 for test evaluation.\n        _____________________________________________\n        Returns:\n            Grid of images.\n    \"\"\"\n    y=int(np.ceil(num/x))\n    # Figure Size\n    plt.figure(figsize=(2*x,2*y))\n    # Create titled grid plots\n    for i in range(num):\n        plt.subplot(y,x,i+1)\n        ind = np.random.randint(0,len(data))\n        plt.imshow(cv.cvtColor(data[ind],cv.COLOR_BGR2RGB))\n        lab = lambda x:\"Cat\" if x == 0 else \"Dog\"\n        col = lambda x,y:\"green\" if x == y else 'red'\n        plt.title(lab(labels[ind]), color= col(lab(labels[ind]), lab(true_lables[ind])))\n        plt.axis(\"off\")\n    plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize()","metadata":{"id":"-87ONBc5lc52","outputId":"5fa168a3-43d4-4621-fcd1-a44a8d83886c"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Transfer Learning\n____\n- #### Load important liberaries\n- #### Prepair data\n- #### Build Models\n    - `MobileNetV2`\n    - `Xciption`\n- #### Train Models\n- #### Evaluate Models\n- #### Compare Models\n- #### Create Final Submition","metadata":{"id":"yVai4KVchpUx","tags":[]}},{"cell_type":"markdown","source":"- ### `Prepair Data:` \n- #### Load important liberaries","metadata":{}},{"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 tensorflow.keras.layers.experimental import preprocessing\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, recall_score, f1_score, precision_score\nimport seaborn as sns","metadata":{"id":"xXPZhQwzmNpg"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- #### Main Parameters","metadata":{"tags":[]}},{"cell_type":"code","source":"EP = 32\nBT_SZ = 512\nIN_SHP = x_tr[0].shape\nOUT_SHP = 2","metadata":{"id":"zagdgoqcvSSg"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- #### Explore augmentation and how augmented data looks","metadata":{}},{"cell_type":"code","source":"#Data augmentation\n\naug = ImageDataGenerator(horizontal_flip=True,vertical_flip=True,\n                         width_shift_range=0.1,height_shift_range=0.1,\n                         rotation_range=90)\n\naug_da = aug.flow(x_tr,y_tr,EP)\n\nvisualize(data=aug_da[0][0],labels=aug_da[0][1],true_lables=aug_da[0][1])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_aug = ImageDataGenerator()\ntr_data = data_aug.flow(x_tr,y_tr,EP)","metadata":{"id":"R5ILJF94s9SZ"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(data=tr_data[0][0],labels=tr_data[0][1],true_labels=tr_data[0][1])","metadata":{"id":"M0nQbJHo32zT","outputId":"4f9b4339-be4c-4ca7-d02a-126c79fcf117"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### `MobileNetV2`","metadata":{"id":"WAE20UCRxDmR","tags":[]}},{"cell_type":"markdown","source":"- ### `Build Model:`","metadata":{"tags":[]}},{"cell_type":"code","source":"# Loading Model with URL\n\nMODEL_PATH = \"https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/5\" \nBASE_MODEL=tf.keras.applications.mobilenet_v2.MobileNetV2(include_top=False,weights='imagenet',classes=2)\nBASE_MODEL.trainable = False","metadata":{"id":"DZhrMlTrdw3w","outputId":"7cb0b2ed-eb92-4bac-e86c-02c61f7efba8"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i = Input(IN_SHP)\n\n# Augmentation\nx = preprocessing.RandomFlip(\"horizontal\")(i)\nx = preprocessing.RandomRotation(0.1)(x)\n\nx = BASE_MODEL(i,training=False)\n\n# Adding Simple CNN at end\nx=Dropout(0.2)(x)\nx=BatchNormalization()(x)\nx=Dense(1024,activation='relu')(x)\n\nx = GlobalAveragePooling2D()(x)\nx = Dropout(0.2)(x)\nx = Dense(1,activation = 'sigmoid')(x)\n\nmo_clf = Model(i,x)\n\nmo_clf.compile(optimizer='adam',loss=\"binary_crossentropy\",metrics=['binary_accuracy'])","metadata":{"id":"EUx6hIFmjWXg"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mo_clf.summary()","metadata":{"id":"gsckbieD1IIb","outputId":"af629eac-f3be-47ca-b3c1-deb49f2df125"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- ### `Train Model:`\n- #### Setting EarlyStopping callback to avoid overfiting","metadata":{}},{"cell_type":"code","source":"es_call=EarlyStopping(\"val_binary_accuracy\",verbose=1,patience=3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mo_clf.fit(tr_data,epochs=EP,batch_size=BT_SZ,validation_data=(x_val,y_val),callbacks=[es_call])","metadata":{"scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- ### `Evaluate Model:`","metadata":{}},{"cell_type":"code","source":"mo_predict = mo_clf.predict(x_val)\n\n# Round prediction to 0, 1\nmo_predict = mo_predict.round()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ev = mo_clf.evaluate(x_val,y_val)\nprint(f\"MobileNetV2 Eval_Loss: {ev[0]:0.4f} \\nMobileNetV2 Eval_Accuracy: {ev[1]*100:0.2f}%\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(data=x_val,labels=mo_predict,true_lables=y_val)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(classification_report(y_val,mo_predict,target_names=['Cat','Dog']))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.heatmap(pd.crosstab(mo_predict.reshape(-1),y_val),annot=True,fmt='0.0f')\nplt.xlabel(\"True\"),plt.ylabel(\"Predected\");","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"___\n### `Xception:`","metadata":{"id":"25o32RS249rp","tags":[]}},{"cell_type":"markdown","source":"- ### `Build Model:`","metadata":{}},{"cell_type":"code","source":"BASE_MODEL_2=tf.keras.applications.Xception(include_top=False,weights='imagenet')\nBASE_MODEL_2.trainable = False","metadata":{"id":"pQbVkf-51l5i"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"i = Input(IN_SHP)\n\n# Augmentation\nx = preprocessing.RandomFlip(\"horizontal\")(i)\nx = preprocessing.RandomRotation(0.1)(x)\n\n# Xception Required rescaling\n# 2 because we normailzed images while importing\n# if not we use 1 / 127.5\nx= tf.keras.layers.Rescaling(scale=2, offset=-1)(x)\n\nx = BASE_MODEL_2(i,training=False)\n\n\n# Adding Simple CNN at end\nx=Dropout(0.2)(x)\nx=BatchNormalization()(x)\nx=Dense(1024,activation='relu')(x)\n\nx = GlobalAveragePooling2D()(x)\nx = Dropout(0.2)(x)\nx = Dense(1,activation = 'sigmoid')(x)\n\nxc_clf = Model(i,x)\n\nxc_clf.compile(\n    optimizer=tf.keras.optimizers.Adam(0.001),\n    loss='binary_crossentropy',\n    metrics=[tf.keras.metrics.BinaryAccuracy()],\n)","metadata":{"id":"dYBhsQBa4_hm"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xc_clf.summary()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- ### `Train Model:`","metadata":{}},{"cell_type":"code","source":"# Setting Callback\nes_call_2=EarlyStopping(\"val_binary_accuracy\",verbose=1,patience=3)\n\n\nxc_clf.fit(tr_data,epochs=EP,batch_size=BT_SZ,validation_data=(x_val,y_val),callbacks=[es_call_2])","metadata":{"scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- ### `Evaluate Model`","metadata":{}},{"cell_type":"code","source":"xc_predict = xc_clf.predict(x_val)\n\n# Round prediction to 0, 1\nxc_predict = xc_predict.round()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xc_ev = mo_clf.evaluate(x_val,y_val)\nprint(f\"MobileNetV2 Eval_Loss: {xc_ev[0]:0.4f} \\nMobileNetV2 Eval_Accuracy: {xc_ev[1]*100:0.2f} %\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(data=x_val,labels=xc_predict,true_lables=y_val)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(classification_report(y_val,xc_predict,target_names=['Cat','Dog']))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.heatmap(pd.crosstab(xc_predict.reshape(-1),y_val),annot=True,fmt='0.0f')\nplt.xlabel(\"True\"),plt.ylabel(\"Predected\");","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"_____\n- ## `Compare Models:`","metadata":{}},{"cell_type":"code","source":"scores = {}\nfor pre,na in zip([mo_predict,xc_predict],[\"MobileNetV2\",'Xception']):\n    scores[na]=recall_score(y_val,pre), f1_score(y_val,pre), precision_score(y_val,pre)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(scores)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame(scores,index=[\"Recall\",\"F1\",\"Precision\"]).T.plot(kind='barh',xticks=np.arange(0.0,1.05,0.05),color=['gray','salmon','cornflowerblue'],figsize=(20,10));","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"___\n- ## `Final Submission:`\n- #### Create Full Process Class\n- #### Export Submission File\n- #### Visualize Some Data","metadata":{}},{"cell_type":"code","source":"class tr_lr:\n    \"\"\"\n    Initialize the TrLr class.\n\n    Parameters:\n        model: Machine learning model for predictions.\n        data: List of image filenames.\n        loc: Location of the image files (default is \"test1\\\\\").\n        IM_SZ: Image size (default is 150).\n        vis: Visualization parameter (unused).\n        vis_num: Number of images to visualize (default is 12).\n        vis_x: Number of rows in the visualization grid (default is 4).\n    \"\"\"\n    \n    def __init__(self,model,data,loc=\"test1\\\\\",IM_SZ=150,vis=None,vis_num=12,vis_x=4):\n        \"\"\"\n        Prepare and preprocess image data.\n\n        Parameters:\n            data: List of image filenames.\n\n        Returns:\n            Preprocessed image data as a NumPy array.\n        \"\"\"\n        self.loc     = loc\n        self.model   = model\n        self.data    = data\n        self.IM_SZ   = IM_SZ\n        self.vis     = vis\n        self.vis_num = vis_num\n        self.vis_x   = vis_x\n        \n    def prepair(self):\n        \"\"\"\n        Prepare and preprocess image data.\n\n        Parameters:\n            data: List of image filenames.\n\n        Returns:\n            Preprocessed image data as a NumPy array.\n        \"\"\"\n        \n        X = pd.Series(self.data).map(lambda x:tf.constant(cv.resize(cv.imread(f\"{self.loc}{x}\"),\n                                                                    (self.IM_SZ,self.IM_SZ)),tf.float32)/255).to_list()\n        X = np.array(X)\n        return X\n    \n    def predicts(self):\n        \"\"\"\n        Make predictions using the provided machine learning model.\n\n        Returns:\n            Tuple containing predicted values, labels, and images.\n        \"\"\"\n        \n        clf = self.model\n        imgs = tr_lr.prepair(self)\n        pred = clf.predict(imgs)\n        pred = pred.round()\n        \n        conv = lambda x:\"Cat\" if x == 0 else \"Dog\"\n        labels = list(map(conv,pred))\n        return pred,labels,imgs\n    \n    def final_sub(self):\n        \"\"\"\n        Generate the final submission CSV file.\n\n        Returns:\n            Pandas DataFrame with ID and label columns.\n        \"\"\"\n        \n        pred = tr_lr.predicts(self)[0].reshape(-1)\n        ids = np.array(pd.Series(os.listdir(self.loc)).map(lambda x:x.split('.')[0]).to_list())\n        csv = pd.DataFrame({\"id\":ids,'label':pred}).sort_values(\"id\")\n        csv.to_csv(\"tr_lr_final_submission.csv\",index=False)\n        return csv\n    \n    def cl_visualize(self,vis_num,vis_x):\n        \"\"\"\n        Function to visualize images in a grid.\n\n        Parameters:\n            vis_num: Number of images.\n            vis_x: Number of rows in the visualization grid.\n        \"\"\"\n        \n        _, labels, imgs = tr_lr.predicts(self)\n\n        y=int(np.ceil(self.vis_num/self.vis_x))\n        # Figure Size\n        plt.figure(figsize=(2*self.vis_x,2*y))\n        # Create titled grid plots\n        for i in range(self.vis_num):\n            plt.subplot(y,self.vis_x,i+1)\n            ind = np.random.randint(0,len(imgs))\n            plt.imshow(cv.cvtColor(imgs[ind],cv.COLOR_BGR2RGB))\n            plt.title(labels[ind])\n            plt.axis(\"off\")\n        plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"te_paths = pd.Series(os.listdir(\"test1\\\\\"))\n\nfull = tr_lr(model=mo_clf,data=te_paths)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"full.cl_visualize(vis_num=12,vis_x=4)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"full.final_sub()","metadata":{"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}