{"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":"<h1><center><u>Dogs🐶 Vs Cats🐱</u></center></h1>\n\n<center>\n<img src =\"https://storage.googleapis.com/kaggle-competitions/kaggle/3362/media/woof_meow.jpg\">\n</center>\n    \n<u>Problem Statement :</u> \n    \n    Create an algorithm to classify whether images contain either dog or a cat.\n    \n<u>More Insights About PS : </u> \n    \n    Web services are often protected with a challenge that's supposed to be easy for people to solve, but difficult for computers. Such a challenge is often called a CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) or HIP (Human Interactive Proof). HIPs are used for many purposes, such as to reduce email and blog spam and prevent brute-force attacks on web site passwords.\n    \n<u>Application Area :</u>\n    \n    CAPTCHA Application \n\n\n*I am new in Computer Vision field any feedback is much appreciated !","metadata":{"execution":{"iopub.status.busy":"2021-06-11T11:27:10.586794Z","iopub.execute_input":"2021-06-11T11:27:10.587275Z","iopub.status.idle":"2021-06-11T11:27:10.611054Z","shell.execute_reply.started":"2021-06-11T11:27:10.587182Z","shell.execute_reply":"2021-06-11T11:27:10.609325Z"}}},{"cell_type":"markdown","source":"Flow of this Notebook :\n\n    1. Import necessay libraries \n    \n    2. Prepare training dataset & Visualize it.\n    \n    3. Split dataset into training and validation set\n    \n    4. Build a predictive model\n    \n    5. Fit the predictive model onto the training data\n    \n    6. Prepare testing dataset & Visualize it.\n    \n    7. Predict on testing data\n    \n    8. Submission ","metadata":{}},{"cell_type":"markdown","source":"# **1. IMPORTING NECESSARY LIBRARIES** 📚 ⬇","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport os\nimport random \n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom keras.preprocessing import image\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:05.006729Z","iopub.execute_input":"2021-06-19T08:05:05.007128Z","iopub.status.idle":"2021-06-19T08:05:10.520481Z","shell.execute_reply.started":"2021-06-19T08:05:05.007044Z","shell.execute_reply":"2021-06-19T08:05:10.519661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **2. PREPARING TRAINING DATA** 📁","metadata":{}},{"cell_type":"markdown","source":"First thing first we need to create a dataset. Since the input is in file format.","metadata":{}},{"cell_type":"code","source":"import zipfile\n\nwith zipfile.ZipFile('../input/dogs-vs-cats/test1.zip', 'r') as zip_ref:\n    \n    zip_ref.extractall('./')\n    \nwith zipfile.ZipFile('../input/dogs-vs-cats/train.zip', 'r') as zip_ref:\n    \n    zip_ref.extractall('./')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:10.521872Z","iopub.execute_input":"2021-06-19T08:05:10.522205Z","iopub.status.idle":"2021-06-19T08:05:26.564355Z","shell.execute_reply.started":"2021-06-19T08:05:10.522169Z","shell.execute_reply":"2021-06-19T08:05:26.563527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Read input files to create training dataset\nfilenames = os.listdir('./train')\n\ncategories = []\n\nfor filename in filenames:\n    \n    category = filename.split('.')[0]\n    \n    if(category == 'dog'):\n        \n        categories.append('dog')\n        \n    else:\n        \n        categories.append('cat')\n        \n# create a dataframe\n\ndf = pd.DataFrame({\n        \n        'filename' : filenames,\n    \n        'category' : categories\n    \n    })","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.566211Z","iopub.execute_input":"2021-06-19T08:05:26.566557Z","iopub.status.idle":"2021-06-19T08:05:26.603469Z","shell.execute_reply.started":"2021-06-19T08:05:26.566521Z","shell.execute_reply":"2021-06-19T08:05:26.602762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2021-06-19T08:05:26.605009Z","iopub.execute_input":"2021-06-19T08:05:26.605355Z","iopub.status.idle":"2021-06-19T08:05:26.625303Z","shell.execute_reply.started":"2021-06-19T08:05:26.605320Z","shell.execute_reply":"2021-06-19T08:05:26.624350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.tail()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.626762Z","iopub.execute_input":"2021-06-19T08:05:26.627131Z","iopub.status.idle":"2021-06-19T08:05:26.637949Z","shell.execute_reply.started":"2021-06-19T08:05:26.627061Z","shell.execute_reply":"2021-06-19T08:05:26.637158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['category'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.640639Z","iopub.execute_input":"2021-06-19T08:05:26.640903Z","iopub.status.idle":"2021-06-19T08:05:26.656197Z","shell.execute_reply.started":"2021-06-19T08:05:26.640879Z","shell.execute_reply":"2021-06-19T08:05:26.655450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**VISUALIZING TRAINING DATASET** 📊","metadata":{}},{"cell_type":"code","source":"df['category'].value_counts().plot(kind = 'bar')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.658866Z","iopub.execute_input":"2021-06-19T08:05:26.659110Z","iopub.status.idle":"2021-06-19T08:05:26.833293Z","shell.execute_reply.started":"2021-06-19T08:05:26.659087Z","shell.execute_reply":"2021-06-19T08:05:26.832524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This dataset contains 25,000 images of dogs and cats (12,500 from each class).","metadata":{}},{"cell_type":"markdown","source":"**See sample image** 🐕","metadata":{}},{"cell_type":"code","source":"# sample image\n\nsample = random.choice(filenames)\n\nimage = image.load_img('./train/' + sample)\n\nplt.imshow(image)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.835955Z","iopub.execute_input":"2021-06-19T08:05:26.836287Z","iopub.status.idle":"2021-06-19T08:05:26.978299Z","shell.execute_reply.started":"2021-06-19T08:05:26.836254Z","shell.execute_reply":"2021-06-19T08:05:26.977478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **3. SPLITTING DATASET INTO TRAINING AND VALIDATION SET** ","metadata":{}},{"cell_type":"markdown","source":"We are done with the first step of creating a dataset. Now we have to split this dataset into training and validation dataset.","metadata":{}},{"cell_type":"code","source":"train_df, validate_df = train_test_split(df, test_size = 0.20, random_state = 42)\n\ntrain_df = train_df.reset_index(drop=True)\n\nvalidate_df = validate_df.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.979880Z","iopub.execute_input":"2021-06-19T08:05:26.980194Z","iopub.status.idle":"2021-06-19T08:05:26.990275Z","shell.execute_reply.started":"2021-06-19T08:05:26.980156Z","shell.execute_reply":"2021-06-19T08:05:26.989550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:26.991650Z","iopub.execute_input":"2021-06-19T08:05:26.992057Z","iopub.status.idle":"2021-06-19T08:05:27.002200Z","shell.execute_reply.started":"2021-06-19T08:05:26.992021Z","shell.execute_reply":"2021-06-19T08:05:27.001373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validate_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.003720Z","iopub.execute_input":"2021-06-19T08:05:27.004133Z","iopub.status.idle":"2021-06-19T08:05:27.015578Z","shell.execute_reply.started":"2021-06-19T08:05:27.004098Z","shell.execute_reply":"2021-06-19T08:05:27.014416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['category'].value_counts().plot(kind = 'bar')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.017155Z","iopub.execute_input":"2021-06-19T08:05:27.017745Z","iopub.status.idle":"2021-06-19T08:05:27.125268Z","shell.execute_reply.started":"2021-06-19T08:05:27.017709Z","shell.execute_reply":"2021-06-19T08:05:27.124567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validate_df['category'].value_counts().plot(kind = 'bar')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.126437Z","iopub.execute_input":"2021-06-19T08:05:27.126783Z","iopub.status.idle":"2021-06-19T08:05:27.243365Z","shell.execute_reply.started":"2021-06-19T08:05:27.126749Z","shell.execute_reply":"2021-06-19T08:05:27.242429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_train = train_df.shape[0]\n\ntotal_validate = validate_df.shape[0]\n\nprint(\"Total number of example in training dataset : {0}\".format(total_train))\n\nprint(\"Total number of example in validation dataset : {0}\".format(total_validate))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.244707Z","iopub.execute_input":"2021-06-19T08:05:27.245050Z","iopub.status.idle":"2021-06-19T08:05:27.250514Z","shell.execute_reply.started":"2021-06-19T08:05:27.245014Z","shell.execute_reply":"2021-06-19T08:05:27.249534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **4. BUILD A PREDICTIVE MODEL** 🏗","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\n\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten\n\nfrom tensorflow.keras import optimizers","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.252031Z","iopub.execute_input":"2021-06-19T08:05:27.252408Z","iopub.status.idle":"2021-06-19T08:05:27.259565Z","shell.execute_reply.started":"2021-06-19T08:05:27.252372Z","shell.execute_reply":"2021-06-19T08:05:27.258606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"First Model- Our first model will be the convnet which is stack of alternated conv2D(with relu activation) and MaxPooling2D layers.","metadata":{}},{"cell_type":"markdown","source":"- Conv Layer -> The matrix representation of the input image is multiplied element-wise with the kernel(filter) to produce a                  feature map, also known as a convolved feature or an activation map.The aim of this step is to reduce the size                  of the image and make processing faster and easier.\n               \n               Output of this layer must be equal to:- shape = math.floor(((n+2p-f)/s)+1, ((n+2p-f)/s)+1)\n\n\n- Pooling Layer -> Pooling enables the CNN to detect features in various images irrespective of the difference in lighting in                      the pictures and different angles of the images.\n                   \n               Output of maxpooling layer :- shape = math.floor(((n-f)/s)+1, ((n-f)/s)+1)\n             \n             \n- Flattening -> Flattening involves transforming the entire pooled feature map matrix into a single column which is then fed to                 the neural network for processing.","metadata":{}},{"cell_type":"code","source":"class Model:\n    \n    def __init__(self, IMG_WIDTH, IMG_HEIGHT, IMG_CHANNELS):\n        \n        self.IMG_WIDTH = IMG_WIDTH\n        \n        self.IMG_HEIGHT = IMG_HEIGHT\n               \n        self.IMG_CHANNELS = IMG_CHANNELS\n    \n    def create_model_one(self):\n        \n        model_one = Sequential()\n        \n        # Adding Layers to create a convolutional mask/kernel that is wind with layers input which helps produce a tensor of outputs\n        \n        # Layer 1\n        model_one.add(Conv2D(32, (3,3), activation = 'relu', input_shape = (150, 150, 3)))\n        \n        model_one.add(MaxPooling2D((2,2)))\n        \n        # Layer 2\n        model_one.add(Conv2D(64, (3,3), activation = 'relu'))\n        \n        model_one.add(MaxPooling2D((2,2)))\n        \n        # Layer 3\n        model_one.add(Conv2D(128, (3,3), activation = 'relu'))\n        \n        model_one.add(MaxPooling2D((2,2)))\n               \n        # Layer 4\n        model_one.add(Conv2D(128, (3,3), activation = 'relu'))\n        \n        model_one.add(MaxPooling2D((2,2)))\n           \n        model_one.add(Flatten())\n                      \n        model_one.add(Dense(512, activation = 'relu'))\n        \n        model_one.add(Dense(1, activation = 'sigmoid'))\n                      \n        return model_one\n    \n    def create_model_two(self):\n        \n        model_two = Sequential()\n        \n        # Adding Layers to create a convolutional mask/kernel that is wind with layers input which helps produce a tensor of outputs\n        \n        # Layer 1\n        model_two.add(Conv2D(32, (3,3), activation = 'relu', input_shape = (150, 150, 3)))\n        \n        model_two.add(MaxPooling2D((2,2)))\n        \n        # Layer 2\n        model_two.add(Conv2D(64, (3,3), activation = 'relu'))\n        \n        model_two.add(MaxPooling2D((2,2)))\n        \n        # Layer 3\n        model_two.add(Conv2D(128, (3,3), activation = 'relu'))\n        \n        model_two.add(MaxPooling2D((2,2)))\n               \n        # Layer 4\n        model_two.add(Conv2D(128, (3,3), activation = 'relu'))\n        \n        model_two.add(MaxPooling2D((2,2)))\n           \n        model_two.add(Flatten())\n        \n        # DropoutLayer for preventing model from overfitting\n        model_two.add(Dropout(0.5))\n                      \n        model_two.add(Dense(512, activation = 'relu'))\n        \n        model_two.add(Dense(1, activation = 'sigmoid'))\n                      \n        return model_two\n    \n        \n        ","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.261259Z","iopub.execute_input":"2021-06-19T08:05:27.261601Z","iopub.status.idle":"2021-06-19T08:05:27.276356Z","shell.execute_reply.started":"2021-06-19T08:05:27.261568Z","shell.execute_reply":"2021-06-19T08:05:27.275607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_WIDTH = 150\n\nIMG_HEIGHT = 150\n\nIMG_CHANNELS = 3\n\nmodel = Model(IMG_WIDTH, IMG_HEIGHT, IMG_CHANNELS)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.277663Z","iopub.execute_input":"2021-06-19T08:05:27.278032Z","iopub.status.idle":"2021-06-19T08:05:27.287399Z","shell.execute_reply.started":"2021-06-19T08:05:27.277997Z","shell.execute_reply":"2021-06-19T08:05:27.286614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Model 1**","metadata":{}},{"cell_type":"code","source":"model_1 = model.create_model_one()\n\nmodel_1.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:27.288625Z","iopub.execute_input":"2021-06-19T08:05:27.289075Z","iopub.status.idle":"2021-06-19T08:05:29.314537Z","shell.execute_reply.started":"2021-06-19T08:05:27.289041Z","shell.execute_reply":"2021-06-19T08:05:29.313754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Compiling Model 1\n\nSince it is a two class classification problem, therefore using binary_crossentropy as loss and using RMSprop as optimizer because we ended the network with a single sigmoidal unit.","metadata":{}},{"cell_type":"code","source":"from keras import optimizers\n\nmodel_1.compile(loss = 'binary_crossentropy', optimizer = optimizers.RMSprop(lr = 1e-4), metrics =['acc'])","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.315832Z","iopub.execute_input":"2021-06-19T08:05:29.316148Z","iopub.status.idle":"2021-06-19T08:05:29.330271Z","shell.execute_reply.started":"2021-06-19T08:05:29.316111Z","shell.execute_reply":"2021-06-19T08:05:29.329446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"📌 Currently data is in in jpeg format, so in order to feed those images to Neural Network we need to do the following steps\n\nStep 1 - Read the image file\n\nStep 2 - Decode those JPEG content to RGB grids of pixels\n\nStep 3 - Convert these into floating-point tensors\n\nStep 4 - Rescale the pixel values from range [0-255] to [0-1] as NN prefers to deal with smaller input values.","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.331671Z","iopub.execute_input":"2021-06-19T08:05:29.332129Z","iopub.status.idle":"2021-06-19T08:05:29.337818Z","shell.execute_reply.started":"2021-06-19T08:05:29.332089Z","shell.execute_reply":"2021-06-19T08:05:29.336646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div class=\"alert alert-block alert-info\">\n📌Generators in Python -: \nA Python generator is an object that acts as an iterator. Generators are built using the yield operator.\n</div>","metadata":{}},{"cell_type":"code","source":"train_imgdatagen = ImageDataGenerator(rescale = 1./255)\n\nvalid_imgdatagen = ImageDataGenerator(rescale = 1./255)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.339283Z","iopub.execute_input":"2021-06-19T08:05:29.339856Z","iopub.status.idle":"2021-06-19T08:05:29.346279Z","shell.execute_reply.started":"2021-06-19T08:05:29.339796Z","shell.execute_reply":"2021-06-19T08:05:29.345483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator_m1 = train_imgdatagen.flow_from_dataframe(\n                    train_df,\n                    \n                    \"./train\", \n                    \n                    x_col='filename',\n    \n                    y_col='category',\n                    \n                    target_size = (150, 150), # resize image to 150x150\n                    \n                    batch_size = 20,\n    \n                    class_mode = 'binary'\n                  )\n\n\nvalidation_generator_m1 = train_imgdatagen.flow_from_dataframe(\n                    validate_df,\n    \n                    \"./train\", \n                    \n                    x_col='filename',\n    \n                    y_col='category',\n                    \n                    target_size = (150, 150), # resize image to 150x150\n                    \n                    batch_size = 20,\n    \n                    class_mode = 'binary'\n                  )\n","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.347553Z","iopub.execute_input":"2021-06-19T08:05:29.347981Z","iopub.status.idle":"2021-06-19T08:05:29.591431Z","shell.execute_reply.started":"2021-06-19T08:05:29.347945Z","shell.execute_reply":"2021-06-19T08:05:29.590666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"That's correct training data contains 20000 images with 2 classes and also validation data contains 5000 images with 2 classes.\n\nNow lets look at the output of these generators :","metadata":{}},{"cell_type":"code","source":"for data_batch, labels_batch in train_generator_m1:\n    \n    print('Data batch shape: {0}'. format(data_batch.shape))\n    \n    print('Labels batch shape: {0}'. format(labels_batch.shape))\n    \n    break","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.595831Z","iopub.execute_input":"2021-06-19T08:05:29.596079Z","iopub.status.idle":"2021-06-19T08:05:29.650477Z","shell.execute_reply.started":"2021-06-19T08:05:29.596055Z","shell.execute_reply":"2021-06-19T08:05:29.649519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are 20 samples in each batch.","metadata":{}},{"cell_type":"markdown","source":"**Model 2 (Using Data augementation)**","metadata":{}},{"cell_type":"markdown","source":"📌 In this approach we try to generate more training samples from existing training data, by augementing the samples through a number of random transformation that yields believable looking images. The goal of this approach is that our model should not see the exact same image at training time which as a result helps our model to more aspects of data and generalize better.\n\nBut how can we do that? 🧐\n\nThis can be done by configuring some random changes on images using **ImageDataGenerator**.","metadata":{}},{"cell_type":"markdown","source":"If we use the below generator then we cant not completely get rid of overfitting","metadata":{}},{"cell_type":"code","source":"train_imgdatagen_m2 = ImageDataGenerator(\n                     rescale = 1./255,\n    \n                     rotation_range = 15,\n    \n                     width_shift_range = 0.1,\n    \n                     height_shift_range = 0.1,\n    \n                     shear_range = 0.1,\n    \n                     zoom_range = 0.2,\n    \n                     horizontal_flip = True\n                    )\n\nvalid_imgdatagen_m2 = ImageDataGenerator(\n                             rescale = 1./255\n                         )","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.653167Z","iopub.execute_input":"2021-06-19T08:05:29.653481Z","iopub.status.idle":"2021-06-19T08:05:29.658980Z","shell.execute_reply.started":"2021-06-19T08:05:29.653447Z","shell.execute_reply":"2021-06-19T08:05:29.658002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_2 = model.create_model_two()\n\nmodel_2.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.660466Z","iopub.execute_input":"2021-06-19T08:05:29.661057Z","iopub.status.idle":"2021-06-19T08:05:29.735144Z","shell.execute_reply.started":"2021-06-19T08:05:29.661019Z","shell.execute_reply":"2021-06-19T08:05:29.734230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_2.compile(loss = 'binary_crossentropy', optimizer = optimizers.RMSprop(lr = 1e-4), metrics =['acc'])","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.736452Z","iopub.execute_input":"2021-06-19T08:05:29.736919Z","iopub.status.idle":"2021-06-19T08:05:29.749169Z","shell.execute_reply.started":"2021-06-19T08:05:29.736881Z","shell.execute_reply":"2021-06-19T08:05:29.748314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator_m2 = train_imgdatagen_m2.flow_from_dataframe(\n                    train_df,\n                    \n                    \"./train\", \n                    \n                    x_col='filename',\n    \n                    y_col='category',\n                    \n                    target_size = (150, 150), # resize image to 150x150\n                    \n                    batch_size = 32,\n    \n                    class_mode = 'binary'\n                  )\n\n\nvalidation_generator_m2 = valid_imgdatagen_m2.flow_from_dataframe(\n                    validate_df,\n    \n                    \"./train\", \n                    \n                    x_col='filename',\n    \n                    y_col='category',\n                    \n                    target_size = (150, 150), # resize image to 150x150\n                    \n                    batch_size = 32,\n    \n                    class_mode = 'binary'\n                  )\n","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.750262Z","iopub.execute_input":"2021-06-19T08:05:29.750679Z","iopub.status.idle":"2021-06-19T08:05:29.978968Z","shell.execute_reply.started":"2021-06-19T08:05:29.750640Z","shell.execute_reply":"2021-06-19T08:05:29.978005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**MODEL 3**","metadata":{}},{"cell_type":"markdown","source":"**Can we get more accuracy? 💭**\n\nLet's try to build one more predictive model using a pretrained model.","metadata":{}},{"cell_type":"markdown","source":"**But why pretrained model? 🤷‍♂️**\n\nBecause probability of learned features across different problems is a key advantage of deep learning compared to many olders, shallow-learning approaches and it makes deep learning very effective for small-data problems.","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import VGG16","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.980269Z","iopub.execute_input":"2021-06-19T08:05:29.980607Z","iopub.status.idle":"2021-06-19T08:05:29.984802Z","shell.execute_reply.started":"2021-06-19T08:05:29.980570Z","shell.execute_reply":"2021-06-19T08:05:29.983788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conv_base = VGG16(weights = 'imagenet', include_top = False, input_shape = (150,150,3))\n\nconv_base.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:29.986086Z","iopub.execute_input":"2021-06-19T08:05:29.986471Z","iopub.status.idle":"2021-06-19T08:05:30.760478Z","shell.execute_reply.started":"2021-06-19T08:05:29.986417Z","shell.execute_reply":"2021-06-19T08:05:30.758493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"`The final feature map has a shape (4, 4, 512). That's the feature on top of which we will stick densely connected classifier.","metadata":{}},{"cell_type":"markdown","source":"Adding a densely connected classifier on top of convolution base","metadata":{}},{"cell_type":"code","source":"model_3 = Sequential()\n\nmodel_3.add(conv_base)\n\nmodel_3.add(Flatten())\n\nmodel_3.add(Dense(256, activation = 'relu'))\n\nmodel_3.add(Dense(1, activation = 'sigmoid'))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.763390Z","iopub.execute_input":"2021-06-19T08:05:30.763646Z","iopub.status.idle":"2021-06-19T08:05:30.832963Z","shell.execute_reply.started":"2021-06-19T08:05:30.763620Z","shell.execute_reply":"2021-06-19T08:05:30.832208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_3.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.835546Z","iopub.execute_input":"2021-06-19T08:05:30.835811Z","iopub.status.idle":"2021-06-19T08:05:30.844460Z","shell.execute_reply.started":"2021-06-19T08:05:30.835786Z","shell.execute_reply":"2021-06-19T08:05:30.843657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Freezing conv_base","metadata":{}},{"cell_type":"code","source":"print(\"The number of trainable weights before freezing the conv base: \", len(model_3.trainable_weights))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.845940Z","iopub.execute_input":"2021-06-19T08:05:30.846283Z","iopub.status.idle":"2021-06-19T08:05:30.855081Z","shell.execute_reply.started":"2021-06-19T08:05:30.846249Z","shell.execute_reply":"2021-06-19T08:05:30.854271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conv_base.trainable = False\n\nprint(\"The number of trainable weights after freezing the conv base: \", len(model_3.trainable_weights))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.857992Z","iopub.execute_input":"2021-06-19T08:05:30.858280Z","iopub.status.idle":"2021-06-19T08:05:30.865343Z","shell.execute_reply.started":"2021-06-19T08:05:30.858254Z","shell.execute_reply":"2021-06-19T08:05:30.864464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Fine Tuning : Freezing layers of conv_base upto specific one\n\n<div class=\"alert alert-block alert-info\">\n📌 Fine-tuning consists of unfreezing a few of the top layers of frozen model base used for feature extraction and jointly training both the newly added part of the model(in this case, the FCC) and these top layers. This is called fine-tuning because it slightly adjusts the more abstract representations of the model being reused, in order to make them more relevant for the problem.\n</div>","metadata":{}},{"cell_type":"code","source":"conv_base.trainable = True\n\nset_trainable = False\n\nfor layer in conv_base.layers:\n    \n    if layer.name == 'block5_conv1':\n        \n        set_trainable = True\n        \n    if set_trainable:\n        \n        layer.trainable = True\n        \n    else:\n        \n        layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.866780Z","iopub.execute_input":"2021-06-19T08:05:30.867889Z","iopub.status.idle":"2021-06-19T08:05:30.874775Z","shell.execute_reply.started":"2021-06-19T08:05:30.867799Z","shell.execute_reply":"2021-06-19T08:05:30.873328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Callbacks","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.875807Z","iopub.execute_input":"2021-06-19T08:05:30.876372Z","iopub.status.idle":"2021-06-19T08:05:30.882372Z","shell.execute_reply.started":"2021-06-19T08:05:30.876301Z","shell.execute_reply":"2021-06-19T08:05:30.881594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To prevent over fitting we will stop the learning after 10 epochs and val_loss value not decreased","metadata":{}},{"cell_type":"code","source":"earlystop = EarlyStopping(patience=10)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.883733Z","iopub.execute_input":"2021-06-19T08:05:30.884136Z","iopub.status.idle":"2021-06-19T08:05:30.892252Z","shell.execute_reply.started":"2021-06-19T08:05:30.884099Z","shell.execute_reply":"2021-06-19T08:05:30.891460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', \n                                            patience=2, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.893530Z","iopub.execute_input":"2021-06-19T08:05:30.893922Z","iopub.status.idle":"2021-06-19T08:05:30.901207Z","shell.execute_reply.started":"2021-06-19T08:05:30.893885Z","shell.execute_reply":"2021-06-19T08:05:30.900382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"callbacks = [earlystop, learning_rate_reduction]","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.903908Z","iopub.execute_input":"2021-06-19T08:05:30.904151Z","iopub.status.idle":"2021-06-19T08:05:30.910019Z","shell.execute_reply.started":"2021-06-19T08:05:30.904126Z","shell.execute_reply":"2021-06-19T08:05:30.909114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_3.compile(loss = 'binary_crossentropy', optimizer = optimizers.RMSprop(lr = 1e-5), metrics =['acc'])","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.911247Z","iopub.execute_input":"2021-06-19T08:05:30.911808Z","iopub.status.idle":"2021-06-19T08:05:30.928612Z","shell.execute_reply.started":"2021-06-19T08:05:30.911774Z","shell.execute_reply":"2021-06-19T08:05:30.927758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **5. FIT THE MODEL ONTO THE TRAINING DATA** 📈","metadata":{}},{"cell_type":"markdown","source":"MODEL 1","metadata":{}},{"cell_type":"code","source":"from PIL import Image","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.931542Z","iopub.execute_input":"2021-06-19T08:05:30.931813Z","iopub.status.idle":"2021-06-19T08:05:30.936418Z","shell.execute_reply.started":"2021-06-19T08:05:30.931789Z","shell.execute_reply":"2021-06-19T08:05:30.934617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_1 = model_1.fit(\n            train_generator_m1,\n    \n            epochs = 30,\n    \n            steps_per_epoch = 100,\n            \n            validation_data = validation_generator_m1,\n    \n            validation_steps = 50\n            )","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:05:30.939176Z","iopub.execute_input":"2021-06-19T08:05:30.939437Z","iopub.status.idle":"2021-06-19T08:10:22.366452Z","shell.execute_reply.started":"2021-06-19T08:05:30.939412Z","shell.execute_reply":"2021-06-19T08:10:22.365646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.mean(history_1.history['acc']))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:10:22.368207Z","iopub.execute_input":"2021-06-19T08:10:22.368552Z","iopub.status.idle":"2021-06-19T08:10:22.376059Z","shell.execute_reply.started":"2021-06-19T08:10:22.368513Z","shell.execute_reply":"2021-06-19T08:10:22.375133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.mean(history_1.history['val_acc']))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:10:22.377355Z","iopub.execute_input":"2021-06-19T08:10:22.377720Z","iopub.status.idle":"2021-06-19T08:10:22.386063Z","shell.execute_reply.started":"2021-06-19T08:10:22.377669Z","shell.execute_reply":"2021-06-19T08:10:22.384877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Saving the model","metadata":{}},{"cell_type":"code","source":"model_1.save('model_1.h5')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:10:22.387494Z","iopub.execute_input":"2021-06-19T08:10:22.388063Z","iopub.status.idle":"2021-06-19T08:10:22.454024Z","shell.execute_reply.started":"2021-06-19T08:10:22.388007Z","shell.execute_reply":"2021-06-19T08:10:22.453119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualizing Loss and accuracy during training 📊**","metadata":{}},{"cell_type":"code","source":"plt.plot(history_1.history['acc'], color = 'black')\n\nplt.plot(history_1.history['val_acc'], color = 'blue')\n\nplt.title('Training and validation accuracy of model 1')\n\nplt.xlabel('Epochs')\n\nplt.ylabel('Accuracy')\n\nplt.show()\n\nplt.plot(history_1.history['loss'], color = 'black')\n\nplt.plot(history_1.history['val_loss'], color = 'blue')\n\nplt.title('Training and validation loss of model 1')\n\nplt.xlabel('Epochs')\n\nplt.ylabel('Accuracy')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:10:22.455397Z","iopub.execute_input":"2021-06-19T08:10:22.455758Z","iopub.status.idle":"2021-06-19T08:10:22.713928Z","shell.execute_reply.started":"2021-06-19T08:10:22.455718Z","shell.execute_reply":"2021-06-19T08:10:22.713102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"MODEL 2","metadata":{}},{"cell_type":"code","source":"history_2 = model_2.fit(\n            train_generator_m2,\n    \n            epochs = 100,\n    \n            steps_per_epoch = 100,\n            \n            validation_data = validation_generator_m2,\n    \n            validation_steps = 50,\n    \n            callbacks = [earlystop, learning_rate_reduction]\n            )","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:10:22.715112Z","iopub.execute_input":"2021-06-19T08:10:22.715435Z","iopub.status.idle":"2021-06-19T08:28:17.861164Z","shell.execute_reply.started":"2021-06-19T08:10:22.715400Z","shell.execute_reply":"2021-06-19T08:28:17.860308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.mean(history_2.history['acc']))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:28:17.862916Z","iopub.execute_input":"2021-06-19T08:28:17.863567Z","iopub.status.idle":"2021-06-19T08:28:17.869241Z","shell.execute_reply.started":"2021-06-19T08:28:17.863524Z","shell.execute_reply":"2021-06-19T08:28:17.868487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.mean(history_2.history['val_acc']))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:28:17.870620Z","iopub.execute_input":"2021-06-19T08:28:17.871246Z","iopub.status.idle":"2021-06-19T08:28:17.883520Z","shell.execute_reply.started":"2021-06-19T08:28:17.871209Z","shell.execute_reply":"2021-06-19T08:28:17.882439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_2.save('model_2.h5')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:28:17.885079Z","iopub.execute_input":"2021-06-19T08:28:17.885755Z","iopub.status.idle":"2021-06-19T08:28:17.980060Z","shell.execute_reply.started":"2021-06-19T08:28:17.885718Z","shell.execute_reply":"2021-06-19T08:28:17.979088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history_2.history['acc'], color = 'black')\n\nplt.plot(history_2.history['val_acc'], color = 'blue')\n\nplt.title('Training and validation accuracy of model 2')\n\nplt.xlabel('Epochs')\n\nplt.ylabel('Accuracy')\n\nplt.show()\n\nplt.plot(history_2.history['loss'], color = 'black')\n\nplt.plot(history_2.history['val_loss'], color = 'blue')\n\nplt.title('Training and validation loss of model 2')\n\nplt.xlabel('Epochs')\n\nplt.ylabel('Accuracy')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:28:17.985635Z","iopub.execute_input":"2021-06-19T08:28:17.986001Z","iopub.status.idle":"2021-06-19T08:28:18.387589Z","shell.execute_reply.started":"2021-06-19T08:28:17.985960Z","shell.execute_reply":"2021-06-19T08:28:18.386804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"MODEL 3","metadata":{}},{"cell_type":"markdown","source":"Using the same ImageGenerators of model 2","metadata":{}},{"cell_type":"code","source":"history_3 = model_3.fit(\n            train_generator_m2,\n    \n            epochs = 30,\n    \n            steps_per_epoch = 100,\n            \n            validation_data = validation_generator_m2,\n    \n            validation_steps = 50,\n            \n            callbacks = callbacks\n            )","metadata":{"execution":{"iopub.status.busy":"2021-06-19T08:28:18.388751Z","iopub.execute_input":"2021-06-19T08:28:18.389185Z","iopub.status.idle":"2021-06-19T10:20:38.845572Z","shell.execute_reply.started":"2021-06-19T08:28:18.389151Z","shell.execute_reply":"2021-06-19T10:20:38.844495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.mean(history_3.history['acc']))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:38.847199Z","iopub.execute_input":"2021-06-19T10:20:38.847526Z","iopub.status.idle":"2021-06-19T10:20:38.859156Z","shell.execute_reply.started":"2021-06-19T10:20:38.847490Z","shell.execute_reply":"2021-06-19T10:20:38.858395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.mean(history_3.history['val_acc']))","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:38.860431Z","iopub.execute_input":"2021-06-19T10:20:38.860748Z","iopub.status.idle":"2021-06-19T10:20:38.877740Z","shell.execute_reply.started":"2021-06-19T10:20:38.860714Z","shell.execute_reply":"2021-06-19T10:20:38.877023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_3.save('model_3.h5')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:38.878631Z","iopub.execute_input":"2021-06-19T10:20:38.878962Z","iopub.status.idle":"2021-06-19T10:20:39.140623Z","shell.execute_reply.started":"2021-06-19T10:20:38.878932Z","shell.execute_reply":"2021-06-19T10:20:39.139800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history_3.history['acc'], color = 'black')\n\nplt.plot(history_3.history['val_acc'], color = 'blue')\n\nplt.title('Training and validation accuracy of model 3')\n\nplt.xlabel('Epochs')\n\nplt.ylabel('Accuracy')\n\nplt.show()\n\nplt.plot(history_3.history['loss'], color = 'black')\n\nplt.plot(history_3.history['val_loss'], color = 'blue')\n\nplt.title('Training and validation loss of model 3')\n\nplt.xlabel('Epochs')\n\nplt.ylabel('Accuracy')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.144776Z","iopub.execute_input":"2021-06-19T10:20:39.146714Z","iopub.status.idle":"2021-06-19T10:20:39.430889Z","shell.execute_reply.started":"2021-06-19T10:20:39.146661Z","shell.execute_reply":"2021-06-19T10:20:39.430163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **6. PREPARE TESTING DATASET AND VISULAIZE IT** 📷","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import load_model","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.432004Z","iopub.execute_input":"2021-06-19T10:20:39.432315Z","iopub.status.idle":"2021-06-19T10:20:39.436576Z","shell.execute_reply.started":"2021-06-19T10:20:39.432280Z","shell.execute_reply":"2021-06-19T10:20:39.435538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = load_model('model_3.h5')","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.437980Z","iopub.execute_input":"2021-06-19T10:20:39.438316Z","iopub.status.idle":"2021-06-19T10:20:39.714412Z","shell.execute_reply.started":"2021-06-19T10:20:39.438282Z","shell.execute_reply":"2021-06-19T10:20:39.713605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_filenames = os.listdir('./test1')\n\ntest_df = pd.DataFrame(\n         {\n             'id' : test_filenames\n         } \n         )","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.715623Z","iopub.execute_input":"2021-06-19T10:20:39.715973Z","iopub.status.idle":"2021-06-19T10:20:39.731419Z","shell.execute_reply.started":"2021-06-19T10:20:39.715937Z","shell.execute_reply":"2021-06-19T10:20:39.730751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.732633Z","iopub.execute_input":"2021-06-19T10:20:39.733005Z","iopub.status.idle":"2021-06-19T10:20:39.741609Z","shell.execute_reply.started":"2021-06-19T10:20:39.732969Z","shell.execute_reply":"2021-06-19T10:20:39.740660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_gen = ImageDataGenerator(rescale = 1./255)\n\ntest_generator = test_gen.flow_from_dataframe(    \n                    test_df,\n    \n                    \"./test1\", \n                    \n                    x_col='id',\n    \n                    y_col=None,\n                    \n                    target_size = (150, 150), # resize image to 150x150\n                    \n                    batch_size = 20,\n    \n                    class_mode = None,\n    \n                    shuffle=False,\n    \n                    validate_filenames=False\n                  )","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.743164Z","iopub.execute_input":"2021-06-19T10:20:39.743550Z","iopub.status.idle":"2021-06-19T10:20:39.777661Z","shell.execute_reply.started":"2021-06-19T10:20:39.743513Z","shell.execute_reply":"2021-06-19T10:20:39.776780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **7. PREDICTING ON TESTING DATA** 📈🤞","metadata":{}},{"cell_type":"code","source":"predictions = model.predict(test_generator)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:20:39.778814Z","iopub.execute_input":"2021-06-19T10:20:39.779134Z","iopub.status.idle":"2021-06-19T10:30:25.407823Z","shell.execute_reply.started":"2021-06-19T10:20:39.779101Z","shell.execute_reply":"2021-06-19T10:30:25.406789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = [1 if p > 0.5 else 0 for p in predictions]\n\ntest_df['category'] = pred","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:30:25.409371Z","iopub.execute_input":"2021-06-19T10:30:25.409752Z","iopub.status.idle":"2021-06-19T10:30:25.452173Z","shell.execute_reply.started":"2021-06-19T10:30:25.409710Z","shell.execute_reply":"2021-06-19T10:30:25.451348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['category'].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:30:25.453542Z","iopub.execute_input":"2021-06-19T10:30:25.453978Z","iopub.status.idle":"2021-06-19T10:30:25.581308Z","shell.execute_reply.started":"2021-06-19T10:30:25.453929Z","shell.execute_reply":"2021-06-19T10:30:25.580315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_map = dict((v,k) for k,v in train_generator_m2.class_indices.items())\n\ntest_df['category'] = test_df['category'].replace(label_map)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:30:25.582734Z","iopub.execute_input":"2021-06-19T10:30:25.583108Z","iopub.status.idle":"2021-06-19T10:30:25.590600Z","shell.execute_reply.started":"2021-06-19T10:30:25.583069Z","shell.execute_reply":"2021-06-19T10:30:25.589580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['category'] = test_df['category'].replace({ 'dog': 1, 'cat': 0 })","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:30:25.591821Z","iopub.execute_input":"2021-06-19T10:30:25.592356Z","iopub.status.idle":"2021-06-19T10:30:25.608144Z","shell.execute_reply.started":"2021-06-19T10:30:25.592316Z","shell.execute_reply":"2021-06-19T10:30:25.607286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['category'].value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:30:25.609468Z","iopub.execute_input":"2021-06-19T10:30:25.609883Z","iopub.status.idle":"2021-06-19T10:30:25.732461Z","shell.execute_reply.started":"2021-06-19T10:30:25.609842Z","shell.execute_reply":"2021-06-19T10:30:25.731477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **8. SUBMISSION** ✌🙌🎉","metadata":{}},{"cell_type":"code","source":"submission_df = test_df.copy()\n\nsubmission_df['id'] = submission_df['id'].str.split('.').str[0]\n\nsubmission_df['label'] = submission_df['category']\n\nsubmission_df.drop(['id', 'category'], axis=1, inplace=True)\n\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-19T10:30:25.733839Z","iopub.execute_input":"2021-06-19T10:30:25.734185Z","iopub.status.idle":"2021-06-19T10:30:25.999431Z","shell.execute_reply.started":"2021-06-19T10:30:25.734149Z","shell.execute_reply":"2021-06-19T10:30:25.998557Z"},"trusted":true},"execution_count":null,"outputs":[]}]}