{"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: `With Features Extraction`\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/`**\n___\n## **Steps:**\n\n- #### Load Main Liberaries \n- #### Import & Check data\n- #### Build Models\n- #### Extract Features\n- #### Build simple ML Model\n- #### Train ML Model on Features\n- #### Evaluate ML Model\n- #### Create full process class for final submission\n___","metadata":{"tags":[]}},{"cell_type":"markdown","source":"### Import Basic Liberaries","metadata":{"tags":[]}},{"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\nimport seaborn as sns","metadata":{"id":"XAvHHmDsX-O8"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Import & Check data:\n","metadata":{"id":"uUXQnh2IXv4z","tags":[]}},{"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())","metadata":{"id":"LAokf0XRaNmp"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check Data Distribution\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=paths,loc=\"train\\\\\",labels=labels,true_labels=labels):\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(cv.imread(f\"{loc}{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_labels[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":"## Features Extraction\n____\n- #### Build Models\n    - `MobileNetV2`\n    - `VGG16`\n- #### Extract Features","metadata":{"id":"yVai4KVchpUx","tags":[]}},{"cell_type":"code","source":"from tensorflow.keras.applications.imagenet_utils import preprocess_input","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract(model,loc=\"train\\\\\",prep=preprocess_input,paths=paths,img_sz=244,bt_sz=32):\n    \"\"\"\n    Function to extract features from images\n        _________________________________________\n        Parameters:\n            - model : Deeplearning model\n            - loc   : Images Main Path\n            - prep  : Image Preprocessor \n            - paths : Images Files Name\n            - img_sz: Image Size\n            - bt_sz : Batch Size\n        _________________________________________\n        Return:\n            - Extracted Features.\n    \"\"\"\n    features=[]\n    for i in range(len(paths)//bt_sz):\n        im_pt = paths[i:i+bt_sz]\n        imgs = pd.Series(im_pt).map(lambda x:cv.resize(cv.imread(f\"{loc}{x}\"),(img_sz,img_sz))).to_list()\n        imgs = np.array(imgs)\n        prep_imgs = prep(imgs)\n        feat = model.predict(prep_imgs)\n        features.append(feat)\n    features = np.array(features)\n    shp = features.shape\n    features = features.reshape(-1,shp[2]*shp[3]*shp[4])\n    return features","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# MobileNetV2\nMODEL_PATH = \"https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/5\" \nmob_n=tf.keras.applications.mobilenet_v2.MobileNetV2(include_top=False,weights='imagenet')\nmob_n.summary()","metadata":{"id":"DZhrMlTrdw3w","outputId":"7cb0b2ed-eb92-4bac-e86c-02c61f7efba8","scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# VGG16\nvgg = tf.keras.applications.VGG16(include_top=False,weights='imagenet')\nvgg.summary()","metadata":{"scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mob_n_features = extract(model= mob_n)\nvgg_features = extract(model= vgg)","metadata":{"scrolled":true,"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shape = mob_n_features.shape\nfeat_labels = labels[:shape[0]]\n\nprint(mob_n_features.shape,len(feat_labels))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### ML Model\n- #### Build simple ML Model\n    - `Logistic Regression`\n- #### Train ML Model on Features\n- #### Evaluate ML Model\n- #### Create full process class for final submission","metadata":{"tags":[]}},{"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report, recall_score, f1_score, precision_score","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create Function to save time of retyping code\ndef ml_model(features,model=LogisticRegression,labels=feat_labels,\n             c=0.001, itr=10**5, n_j=-1, ver=4, test_sz=0.1, seed=55):\n    \"\"\"\n    Function to build and train ML model according extracted features\n        parameters:\n            - model    = ML Model\n            - features = Extracted Features\n            - labels   = Labels of Extracted Features\n            - c        = C for ML Model\n            - itr      = Max Iteration in ML Model\n            - ver      = Verbose\n            - test_sz  = test_size in train_test_split\n            - seed     = random_state in train_test_split\n        Return:\n            - clf  = Train ML Model\n            - x_tr = Train Features\n            - x_te = Test Features\n            - y_tr = Train Labels\n            - y_te = Test Labels\n    \"\"\"\n    # ML Model\n    clf = model(C=c,max_iter=itr,n_jobs=n_j,verbose=ver)\n    # Split Data\n    x_tr, x_te, y_tr, y_te = train_test_split(features,labels,test_size=test_sz,random_state=seed)\n    print(f\"Train Features Shape:{x_tr.shape}\", f\"Test Features Shape:{x_te.shape}\",\n          f\"Train Labels Shape:{len(y_tr)}\", f\"Test Labels Shape:{len(y_te)}\",end=\"\\n\")\n    # Train The Model\n    clf.fit(x_tr,y_tr)\n\n    return clf, x_tr, x_te, y_tr, y_te","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- #### Split images to match extracted features splits","metadata":{}},{"cell_type":"code","source":"train_imgs,test_imgs = train_test_split(paths[:shape[0]],test_size=0.1,random_state=55)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### `MobileNetV2:`","metadata":{}},{"cell_type":"markdown","source":"#### 1.Train:","metadata":{"tags":[]}},{"cell_type":"code","source":"mob_n_clf, mob_n_xtr, mob_n_xte, mob_n_ytr,mob_n_yte = ml_model(features=mob_n_features)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2.Predict:","metadata":{}},{"cell_type":"code","source":"mob_n_pred = mob_n_clf.predict(mob_n_xte)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 3.Evaluate:","metadata":{}},{"cell_type":"code","source":"print(classification_report(mob_n_yte,mob_n_pred))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.heatmap(pd.crosstab(mob_n_pred.reshape(-1),mob_n_yte),annot=True,fmt='0.0f')\nplt.xlabel(\"True\"),plt.ylabel(\"Predected\");","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 4.Visualize:","metadata":{}},{"cell_type":"code","source":"visualize(num=15,x=5,data=test_imgs,labels=mob_n_pred,true_labels=mob_n_yte)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"___\n### `VGG16:`","metadata":{"tags":[]}},{"cell_type":"markdown","source":"#### 1.Train:","metadata":{}},{"cell_type":"code","source":"vgg_clf, vgg_xtr, vgg_xte, vgg_ytr,vgg_yte = ml_model(features=vgg_features)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2.Predict:","metadata":{}},{"cell_type":"code","source":"vgg_pred = vgg_clf.predict(vgg_xte)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 3.Evaluate:","metadata":{}},{"cell_type":"code","source":"print(classification_report(vgg_yte,vgg_pred))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.heatmap(pd.crosstab(vgg_pred.reshape(-1),vgg_yte),annot=True,fmt='0.0f')\nplt.xlabel(\"True\"),plt.ylabel(\"Predected\");","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 4.Visualize:","metadata":{}},{"cell_type":"code","source":"visualize(num=15,x=5,data=test_imgs,labels=mob_n_pred,true_labels=mob_n_yte)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"_____\n### `Compare Models:`","metadata":{}},{"cell_type":"code","source":"scores = {}\nfor pred,na in zip([mob_n_pred,vgg_pred],[\"MobileNetV2\",\"VGG16\"]):\n    scores[na]=recall_score(mob_n_yte,pred), f1_score(mob_n_yte,pred), precision_score(mob_n_yte,pred)","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# Web APP : https://cats-dogs-classification-app.streamlit.app/","metadata":{"tags":[]}}]}