{"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":"code","source":"# Import the necessary packages\nimport os\nimport zipfile\nimport pandas as pd\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\nimport os\nimport matplotlib.pyplot as plt\nimport PIL\nimport seaborn as sns\nimport plotly\nimport plotly.graph_objs as go\nfrom sklearn.model_selection import train_test_split                   # sklearn use it for split/shuffle the data\nfrom sklearn.utils import shuffle\nfrom plotly.offline import iplot, init_notebook_mode\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.models import Model, load_model\nfrom tensorflow.keras.initializers import glorot_uniform\nfrom tensorflow.keras.utils import plot_model\nfrom IPython.display import display\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.optimizers import SGD\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Model, Sequential\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint, LearningRateScheduler","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:18:58.527458Z","iopub.execute_input":"2021-10-05T07:18:58.528489Z","iopub.status.idle":"2021-10-05T07:19:05.335281Z","shell.execute_reply.started":"2021-10-05T07:18:58.52844Z","shell.execute_reply":"2021-10-05T07:19:05.33448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# unzip the data files train and test\nimport os\nprint(os.listdir(\"../input\"))\n\nimport zipfile\n\nwith zipfile.ZipFile(\"../input/dogs-vs-cats-redux-kernels-edition/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"../input/dogs-vs-cats-redux-kernels-edition/test.zip\",\"r\") as z:\n    z.extractall(\".\")","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:05.336953Z","iopub.execute_input":"2021-10-05T07:19:05.337274Z","iopub.status.idle":"2021-10-05T07:19:20.042233Z","shell.execute_reply.started":"2021-10-05T07:19:05.337243Z","shell.execute_reply":"2021-10-05T07:19:20.041632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Input Train Data into DataFrame\ntrain = []                                     # create empty folder name as train\nlabel = []                                     # create empty folder name as label\n\n# os.listdir returns the list of files in the folder, in this case image class names\nfor i in os.listdir('/kaggle/working/train'):                             \n    \n    train_class = i.split(\".\", 1)\n    \n    for j in train_class[0:1]:\n        \n        train.append(i)                         # append image file into the new folder train\n        \n        label.append(j)                         # append the name of folder as the label of the image file\n        \nfull_df = pd.DataFrame({'Image': train,'Labels': label})  # create data frame from dictionary with 2 coloums Image and Labels\nfull_df","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:20.04474Z","iopub.execute_input":"2021-10-05T07:19:20.045118Z","iopub.status.idle":"2021-10-05T07:19:20.115572Z","shell.execute_reply.started":"2021-10-05T07:19:20.045062Z","shell.execute_reply":"2021-10-05T07:19:20.11495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# see number of cat and dog in train data set\nsns.countplot(label)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:20.11657Z","iopub.execute_input":"2021-10-05T07:19:20.117194Z","iopub.status.idle":"2021-10-05T07:19:20.403999Z","shell.execute_reply.started":"2021-10-05T07:19:20.117161Z","shell.execute_reply":"2021-10-05T07:19:20.403408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make sure same number of cat and dog in training set and validation set \ncat_df = full_df[full_df['Labels'] == 'cat']\ndog_df = full_df[full_df['Labels'] == 'dog']\n\ndog_df = shuffle(dog_df)                                              # Shuffle the data and split it into training and valid\n\ntrain_dog, valid_dog = train_test_split(dog_df, test_size = 0.20)     # Split all dog images 20% for validation and 80% for training\n\ncat_df = shuffle(cat_df)\n\ntrain_cat, valid_cat = train_test_split(cat_df, test_size = 0.20)     # Split all cat images 20% for validation and 80% for training\n\ntrain_full = pd.concat([train_cat, train_dog], axis=0)                # Concatenate 80% dog and cat images into train_full dataframe\nvalid_full = pd.concat([valid_cat, valid_dog], axis=0)                # Concatenate 20% dog and cat images into valid_full dataframe","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:20.405446Z","iopub.execute_input":"2021-10-05T07:19:20.406153Z","iopub.status.idle":"2021-10-05T07:19:20.43561Z","shell.execute_reply.started":"2021-10-05T07:19:20.406107Z","shell.execute_reply":"2021-10-05T07:19:20.435016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Preprocessing the training set and applying data augmentation\n\ntrain_datagen = ImageDataGenerator(rescale = 1./255,\n                                   shear_range = 0.2, ### Choose a shear_range\n                                   zoom_range = 0.2   ### Choose a zoom range\n                                   ) \n\n\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_full,\n    directory='/kaggle/working/train/',\n    x_col=\"Image\",\n    y_col=\"Labels\",\n    target_size=(64, 64),\n    color_mode=\"rgb\",\n    class_mode=\"binary\",\n    batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:20.436614Z","iopub.execute_input":"2021-10-05T07:19:20.43741Z","iopub.status.idle":"2021-10-05T07:19:20.668286Z","shell.execute_reply.started":"2021-10-05T07:19:20.437366Z","shell.execute_reply":"2021-10-05T07:19:20.66728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Preprocessing the validation set\nvalidation_generator = train_datagen.flow_from_dataframe(\n    valid_full,\n    directory='/kaggle/working/train/',\n    x_col=\"Image\",\n    y_col=\"Labels\",\n    target_size=(64, 64),\n    color_mode=\"rgb\",\n    class_mode=\"binary\",\n    batch_size=32)\n","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:20.66959Z","iopub.execute_input":"2021-10-05T07:19:20.669887Z","iopub.status.idle":"2021-10-05T07:19:20.741929Z","shell.execute_reply.started":"2021-10-05T07:19:20.66985Z","shell.execute_reply":"2021-10-05T07:19:20.740658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Initializing the CNN\ncnn = tf.keras.models.Sequential()\n\n# Note the input shape is the desired size of the image 64*64 with 3 bytes color\n# Create the first Convolutional Layer\ncnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu', input_shape=[64, 64, 3]))\n\n# Create a Pooling Layer\ncnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))\n\n# Create the second Convolutional Layer\ncnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu'))\n\n# Add another Pooling Layer\ncnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))\n\n# Flatten the results to feed into the CNN\ncnn.add(tf.keras.layers.Flatten())\n\n# Fully Connected Convolutional Neural Network with 128 neuron hidden layer\ncnn.add(tf.keras.layers.Dense(units=128, activation=  'relu' )) ### Choose Activation Function\n\n# Creating the Output Layer\ncnn.add(tf.keras.layers.Dense(units=1, activation=  'sigmoid' )) ### 'Sigmoid' use for Binary Classification\n\ncnn.summary()","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:20.743175Z","iopub.execute_input":"2021-10-05T07:19:20.743428Z","iopub.status.idle":"2021-10-05T07:19:20.885848Z","shell.execute_reply.started":"2021-10-05T07:19:20.7434Z","shell.execute_reply":"2021-10-05T07:19:20.885113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cnn.compile(optimizer = 'adam' , loss = 'binary_crossentropy', metrics = ['accuracy']) ### Choose adam Optimizer and binary_crossentropy","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:25.497733Z","iopub.execute_input":"2021-10-05T07:19:25.498033Z","iopub.status.idle":"2021-10-05T07:19:25.514995Z","shell.execute_reply.started":"2021-10-05T07:19:25.497995Z","shell.execute_reply":"2021-10-05T07:19:25.514057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#using early stopping to exit training if validation loss is not decreasing even after certain epochs (patience)\nearlystopping = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10)\n\n#save the best model with lower validation loss\ncheckpointer = ModelCheckpoint(filepath=\"Cats and Dogs Classification.hdf5\", verbose=1, save_best_only=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:26.64205Z","iopub.execute_input":"2021-10-05T07:19:26.642747Z","iopub.status.idle":"2021-10-05T07:19:26.647846Z","shell.execute_reply.started":"2021-10-05T07:19:26.64271Z","shell.execute_reply":"2021-10-05T07:19:26.646878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class myCallback(tf.keras.callbacks.Callback):\n        def on_epoch_end(self, epoch, logs={}):\n            if(logs.get('loss')<0.006):\n                print(\"\\nReached 99.8% accuracy so cancelling training!\")\n                self.model.stop_training = True\n    \n            callbacks = [checkpointer , earlystopping]","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:28.149354Z","iopub.execute_input":"2021-10-05T07:19:28.149844Z","iopub.status.idle":"2021-10-05T07:19:28.155495Z","shell.execute_reply.started":"2021-10-05T07:19:28.149797Z","shell.execute_reply":"2021-10-05T07:19:28.154773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Training our CNN on the training set and evaluating it on the test set\nhistory = cnn.fit(x = train_generator, validation_data = validation_generator, epochs = 25,callbacks=[checkpointer , earlystopping])","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:19:29.509387Z","iopub.execute_input":"2021-10-05T07:19:29.510058Z","iopub.status.idle":"2021-10-05T07:54:55.077462Z","shell.execute_reply.started":"2021-10-05T07:19:29.510016Z","shell.execute_reply":"2021-10-05T07:54:55.076148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'r', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.legend(loc=0)\nplt.figure()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:54:55.08162Z","iopub.execute_input":"2021-10-05T07:54:55.082038Z","iopub.status.idle":"2021-10-05T07:54:55.344709Z","shell.execute_reply.started":"2021-10-05T07:54:55.081982Z","shell.execute_reply":"2021-10-05T07:54:55.343853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images_dir = '/kaggle/working/test/'\n\n# Creat test_df and check the number of images in the test dataset\ntest = []\n\n# os.listdir returns the list of files in the folder, in this case image class names\nfor i in os.listdir(test_images_dir):\n    img = os.path.join(test_images_dir, i)\n    test.append(img)\n\nprint('Number of test images in the test dataset : {} \\n'.format(len(test)))\n\n# submission_df with 'image' columns\nsubmission_df = pd.DataFrame({'Image': test})\n\nnum_test_images = len(test)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:54:55.346394Z","iopub.execute_input":"2021-10-05T07:54:55.346892Z","iopub.status.idle":"2021-10-05T07:54:55.395414Z","shell.execute_reply.started":"2021-10-05T07:54:55.346848Z","shell.execute_reply":"2021-10-05T07:54:55.394704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install keras==2.1.2","metadata":{"execution":{"iopub.status.busy":"2021-10-05T07:54:55.397318Z","iopub.execute_input":"2021-10-05T07:54:55.397725Z","iopub.status.idle":"2021-10-05T07:55:06.260997Z","shell.execute_reply.started":"2021-10-05T07:54:55.397677Z","shell.execute_reply":"2021-10-05T07:55:06.259954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Input Test Data into DataFrame\ntest = []                                     # create empty folder name as test\nnum_id = []                                   # create empty folder name as id number\n\n# os.listdir returns the list of files in the folder, in this case image class names\nfor i in os.listdir('/kaggle/working/test'):                             \n    \n    test_class = i.split(\".\", 1)\n    \n    for j in test_class[0:1]:\n        \n        test.append(i)                         # append image file into the new folder train\n        \n        num_id.append(j)                         # append the name of folder as the label of the image file\n        \nsubmission_id = pd.DataFrame({'id': num_id})  # create data frame from dictionary with 2 coloums Image and Labels\nsubmission_id","metadata":{"execution":{"iopub.status.busy":"2021-10-05T08:37:35.147362Z","iopub.execute_input":"2021-10-05T08:37:35.1476Z","iopub.status.idle":"2021-10-05T08:37:35.183348Z","shell.execute_reply.started":"2021-10-05T08:37:35.147575Z","shell.execute_reply":"2021-10-05T08:37:35.182497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predict test data\nimg_id = []\npredict = []\n\nfrom keras.preprocessing import image\nfor i in range(0, submission_df.shape[0]):  \n   \n    path = submission_df['Image'][i]\n\n    img = image.load_img(path, target_size=(64, 64))\n    \n  # converting image to array\n    img = np.asarray(img, dtype= np.float32)\n    \n  # normalizing the image\n    img = img /255\n    \n  # reshaping the image in to a 4D array\n    img = img.reshape(-1,64,64,3)\n    \n    result_predict = cnn.predict(img)[0]\n        \n    predict.append(\"%.2f\"%result_predict)\n    \n    i_id = path.split(\".\", 1)\n    \n    img_id.append(i_id)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T08:28:12.233657Z","iopub.execute_input":"2021-10-05T08:28:12.234042Z","iopub.status.idle":"2021-10-05T08:37:35.067831Z","shell.execute_reply.started":"2021-10-05T08:28:12.234005Z","shell.execute_reply":"2021-10-05T08:37:35.06701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_label = pd.DataFrame({'label': predict})","metadata":{"execution":{"iopub.status.busy":"2021-10-05T08:37:35.0697Z","iopub.execute_input":"2021-10-05T08:37:35.069917Z","iopub.status.idle":"2021-10-05T08:37:35.077371Z","shell.execute_reply.started":"2021-10-05T08:37:35.069892Z","shell.execute_reply":"2021-10-05T08:37:35.076511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.concat([submission_id, submission_label], axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T08:37:35.184557Z","iopub.execute_input":"2021-10-05T08:37:35.184777Z","iopub.status.idle":"2021-10-05T08:37:35.191193Z","shell.execute_reply.started":"2021-10-05T08:37:35.184751Z","shell.execute_reply":"2021-10-05T08:37:35.190204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2021-10-05T08:37:35.192442Z","iopub.execute_input":"2021-10-05T08:37:35.192699Z","iopub.status.idle":"2021-10-05T08:37:35.209221Z","shell.execute_reply.started":"2021-10-05T08:37:35.192674Z","shell.execute_reply":"2021-10-05T08:37:35.208315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[['id', 'label']].to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-10-05T08:40:27.368442Z","iopub.execute_input":"2021-10-05T08:40:27.368839Z","iopub.status.idle":"2021-10-05T08:40:27.431494Z","shell.execute_reply.started":"2021-10-05T08:40:27.368806Z","shell.execute_reply":"2021-10-05T08:40:27.430615Z"},"trusted":true},"execution_count":null,"outputs":[]}]}