{"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":"# Cat vs. Dog Image Classification\n## Exercise 1: Building a Convnet from Scratch\n\nIn this exercise, we will build a classifier model from scratch that is able to distinguish dogs from cats. We will follow these steps:\n\n1. Explore the example data\n2. Build a small convnet from scratch to solve our classification problem\n3. Evaluate training and validation accuracy\n\nLet's go!","metadata":{}},{"cell_type":"markdown","source":"![Image](http://www.google.com/url?sa=i&url=https%3A%2F%2Fkili-technology.com%2Fdata-labeling%2Fcomputer-vision%2Fimage-annotation%2Fprogramming-image-classification-with-machine-learning&psig=AOvVaw3B-GAz7UNSmcUBHzVexuke&ust=1680054409303000&source=images&cd=vfe&ved=0CBEQjRxqFwoTCKDjg8TA_f0CFQAAAAAdAAAAABAK)","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-03-28T07:02:23.433134Z","iopub.execute_input":"2023-03-28T07:02:23.433873Z","iopub.status.idle":"2023-03-28T07:02:23.513001Z","shell.execute_reply.started":"2023-03-28T07:02:23.433826Z","shell.execute_reply":"2023-03-28T07:02:23.511782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n!unzip /kaggle/input/dogs-vs-cats/test1.zip\n!unzip /kaggle/input/dogs-vs-cats/train.zip\n","metadata":{"_kg_hide-input":true,"_kg_hide-output":false,"execution":{"iopub.status.busy":"2023-03-28T07:02:23.514768Z","iopub.execute_input":"2023-03-28T07:02:23.515588Z","iopub.status.idle":"2023-03-28T07:02:45.635356Z","shell.execute_reply.started":"2023-03-28T07:02:23.515536Z","shell.execute_reply":"2023-03-28T07:02:45.633998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Reading the images: ","metadata":{}},{"cell_type":"code","source":"from glob import glob\nfile_name=glob('./train/*.jpg')\nimages=os.listdir('./train')\ncategories=['cat' if 'cat' in image else 'dog' for image in images  ]\ndf=pd.DataFrame({'filename':file_name,'category':categories})\nprint(df.shape)\ndf.head()\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:02:45.639945Z","iopub.execute_input":"2023-03-28T07:02:45.640313Z","iopub.status.idle":"2023-03-28T07:02:45.762752Z","shell.execute_reply.started":"2023-03-28T07:02:45.640275Z","shell.execute_reply":"2023-03-28T07:02:45.761527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Splitting the data in train and valid**","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_df,valid_df=train_test_split(df, train_size=0.8)\ntrain_df=train_df.reset_index(drop=True)\nvalid_df=valid_df.reset_index(drop=True)\ntrain_df.shape, valid_df.shape","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:02:45.764985Z","iopub.execute_input":"2023-03-28T07:02:45.766032Z","iopub.status.idle":"2023-03-28T07:02:46.748809Z","shell.execute_reply.started":"2023-03-28T07:02:45.765975Z","shell.execute_reply":"2023-03-28T07:02:46.747459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#reading test images\nfilename=os.listdir('./test1/')\ntest_df=pd.DataFrame({'filename':filename})\ntest_df","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:02:46.750629Z","iopub.execute_input":"2023-03-28T07:02:46.751086Z","iopub.status.idle":"2023-03-28T07:02:46.773967Z","shell.execute_reply.started":"2023-03-28T07:02:46.751025Z","shell.execute_reply":"2023-03-28T07:02:46.773051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  Data Preprocessing :","metadata":{}},{"cell_type":"markdown","source":"This code is using the ImageDataGenerator class from Keras to generate batches of image data from dataframes containing the image filenames and corresponding labels.\n\nFirst, the rescale parameter is set to 1/255, which will rescale the pixel values of each image to be between 0 and 1.\n\nNext, three data generators are created using the flow_from_dataframe() method:\n\ntrain_data: a generator for the training data, which takes in the training dataframe, specifies the column containing the image filenames (x_col), the column containing the corresponding labels (y_col), the class mode (binary for a binary classification problem), the target image size (150x150), and the batch size (32).\nvalid_data: a generator for the validation data, which is set up similarly to the train_data generator, but uses the validation dataframe.\ntest_data: a generator for the test data, which takes in a dataframe containing the test image filenames and any associated metadata, specifies the directory where the images are located (directory), sets y_col to None since the labels are not provided, and uses the None class mode.","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n#used to rescale the data\ndata_gen=ImageDataGenerator(rescale=1/255)\n\ntrain_data=data_gen.flow_from_dataframe(dataframe=train_df,\n                                       x_col='filename',\n                                       y_col='category',\n                                       class_mode='binary',\n                                       target_size=(150,150),\n                                       batch_size=32)\nvalid_data=data_gen.flow_from_dataframe(dataframe=valid_df,\n                                       x_col='filename',\n                                       y_col='category',\n                                       class_mode='binary',\n                                       target_size=(150,150),\n                                       batch_size=32)\n                                       \ntest_data=data_gen.flow_from_dataframe(dataframe=test_df,\n                                       directory=\"./test1/\",\n                                       x_col='filename',\n                                       y_col=None,\n                                       class_mode=None,\n                                       target_size=(150,150),\n                                       batch_size=32)\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:02:46.775781Z","iopub.execute_input":"2023-03-28T07:02:46.776806Z","iopub.status.idle":"2023-03-28T07:03:02.364186Z","shell.execute_reply.started":"2023-03-28T07:02:46.776766Z","shell.execute_reply":"2023-03-28T07:03:02.363127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Modeling**:","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D,MaxPooling2D,Flatten,Dense,Input, Dropout\n\n#convolution layers extracts 16 filter of 3x3\nmodel=Sequential([\n    Input(shape=(150,150,3)),\n    Conv2D(16,3, activation='relu', padding='same'),\n    MaxPooling2D(),\n    Conv2D(32,3,activation='relu', padding='same'),\n    MaxPooling2D(),\n    Conv2D(64,3,activation='relu', padding='same'),\n    MaxPooling2D(),\n    Conv2D(128,3,activation='relu', padding='same'),\n    MaxPooling2D(),\n    Flatten(),\n    Dense(128,activation='relu'),\n    Dropout(0.5),\n    Dense(1,activation='sigmoid')\n\n    \n])\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:03:02.365991Z","iopub.execute_input":"2023-03-28T07:03:02.366776Z","iopub.status.idle":"2023-03-28T07:03:07.629796Z","shell.execute_reply.started":"2023-03-28T07:03:02.366728Z","shell.execute_reply":"2023-03-28T07:03:07.628605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:51:23.174343Z","iopub.status.idle":"2023-03-28T07:51:23.174854Z","shell.execute_reply.started":"2023-03-28T07:51:23.174588Z","shell.execute_reply":"2023-03-28T07:51:23.174614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**RMSprop**:\n***\nRMSprop (Root Mean Square Propagation) is an optimization algorithm used in neural networks to update the weights during training. It was introduced by Geoff Hinton in a course on Coursera.\n\nRMSprop is a variant of stochastic gradient descent (SGD) which tries to resolve the problems of SGD, such as the problem of the diminishing learning rate. The RMSprop algorithm maintains an exponentially-weighted moving average of the squared gradients, which allows it to divide the learning rate by an estimate of the standard deviation of the gradients.","metadata":{}},{"cell_type":"code","source":"from keras.optimizers import RMSprop\nmodel.compile(loss='binary_crossentropy',metrics=['acc'], optimizer=RMSprop(learning_rate=0.00001))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\nbatch_size=32\nhistory1 = model.fit(\n    train_data,\n    steps_per_epoch=train_data.samples // batch_size,\n    epochs=15,\n    validation_data=valid_data,\n    validation_steps=valid_data.samples // batch_size\n)","metadata":{"execution":{"iopub.status.idle":"2023-03-28T07:23:43.507101Z","shell.execute_reply.started":"2023-03-28T07:03:07.703559Z","shell.execute_reply":"2023-03-28T07:23:43.50596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data augumentation:\n\nData augmentation is a technique used in machine learning and computer vision to increase the size of a training dataset by generating new samples from existing ones by applying random transformations such as rotation, zooming, flipping, shifting, changing brightness or contrast, and adding noise or other distortions. This helps to create more diverse and representative samples that can improve the generalization and robustness of the model by reducing overfitting and increasing its ability to recognize and classify objects under different conditions and variations","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Set up the data paths\ntrain_dir = '/kaggle/input/dogs-vs-cats/train.zip'\nvalidation_dir = '/kaggle/input/dogs-vs-cats/test1.zip'\n\n# Define the input shape of the images\ninput_shape = (150, 150, 3)\n\n# Define the batch size\nbatch_size = 32\n\n# Create data generators with image augmentation\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=40,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest'\n)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n\ntrain_data=train_datagen.flow_from_dataframe(dataframe=train_df,\n                                       x_col='filename',\n                                       y_col='category',\n                                       class_mode='binary',\n                                       target_size=(150,150),\n                                       batch_size=32)\nvalid_data=test_datagen.flow_from_dataframe(dataframe=valid_df,\n                                       x_col='filename',\n                                       y_col='category',\n                                       class_mode='binary',\n                                       target_size=(150,150),\n                                       batch_size=32)\n\n\n# Define the model architecture\nmodel = tf.keras.models.Sequential([\n    tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),\n    tf.keras.layers.MaxPooling2D((2, 2)),\n    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),\n    tf.keras.layers.MaxPooling2D((2, 2)),\n    tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),\n    tf.keras.layers.MaxPooling2D((2, 2)),\n    tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),\n    tf.keras.layers.MaxPooling2D((2, 2)),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(512, activation='relu'),\n    tf.keras.layers.Dense(1, activation='sigmoid')\n])\n\n# Compile the model\nmodel.compile(loss='binary_crossentropy',\n              optimizer=tf.keras.optimizers.RMSprop(lr=1e-4),\n              metrics=['acc'])\n\n# Train the model\nhistory2 = model.fit(\n    train_data,\n    steps_per_epoch=100,\n    epochs=20,\n    validation_data=valid_data,\n    validation_steps=50\n)\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:23:43.509844Z","iopub.execute_input":"2023-03-28T07:23:43.510163Z","iopub.status.idle":"2023-03-28T07:35:33.424932Z","shell.execute_reply.started":"2023-03-28T07:23:43.510135Z","shell.execute_reply":"2023-03-28T07:35:33.423898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plotting the accuracy and error \npd.DataFrame(history2.history).plot();\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:35:33.426376Z","iopub.execute_input":"2023-03-28T07:35:33.426656Z","iopub.status.idle":"2023-03-28T07:35:33.810506Z","shell.execute_reply.started":"2023-03-28T07:35:33.426629Z","shell.execute_reply":"2023-03-28T07:35:33.809331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\nfrom keras.optimizers import Adam\nfrom keras.models import Model\n\n\n# Load the pre-trained ResNet50 model without the top layers\nbase_model = ResNet50(weights='imagenet', include_top=False, input_shape=(150, 150, 3))\n\n# Add new layers on top of the pre-trained model\nx = Flatten()(base_model.output)\nx = Dense(256, activation='relu')(x)\nx = Dense(1, activation='sigmoid')(x)\n\n# Define the new model\nmodel = Model(inputs=base_model.input, outputs=x)\n\n# Compile the model with an Adam optimizer and binary cross-entropy loss\nmodel.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])\n\n# Train the model on the training data and validate on the validation data\nhistory3 = model.fit(\n    train_data,\n    steps_per_epoch=100,\n    epochs=15,\n    validation_data=valid_data,\n    validation_steps=50,\n    verbose=2\n)\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:35:33.811669Z","iopub.execute_input":"2023-03-28T07:35:33.812036Z","iopub.status.idle":"2023-03-28T07:50:37.330329Z","shell.execute_reply.started":"2023-03-28T07:35:33.811992Z","shell.execute_reply":"2023-03-28T07:50:37.329247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame(history3.history).plot();\n","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:50:37.333992Z","iopub.execute_input":"2023-03-28T07:50:37.335197Z","iopub.status.idle":"2023-03-28T07:50:37.597519Z","shell.execute_reply.started":"2023-03-28T07:50:37.33515Z","shell.execute_reply":"2023-03-28T07:50:37.596558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**In the use of the predefined model can yeilds the better training and validation accuracy as \nwell as the miniimum loss  with having the 97% accuracy**","metadata":{}},{"cell_type":"markdown","source":"# Generating the submission file:","metadata":{}},{"cell_type":"code","source":"prediction_probabilities = model.predict(test_data, verbose=1)\nprediction_probabilities","metadata":{"execution":{"iopub.status.idle":"2023-03-28T07:57:48.869419Z","shell.execute_reply.started":"2023-03-28T07:57:07.341712Z","shell.execute_reply":"2023-03-28T07:57:48.868259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_examples = len(test_df)\ncounter = range(1, num_examples +1)\nprint(len(num_examples))\nprint(len(prediction_probabilities))\n\nsolution = pd.DataFrame({\"id\": counter, \"label\": list(prediction_probabilities)})\ncols = ['label']\n\nfor col in cols:\n    solution[col] = solution[col].map(lambda x: str(x).lstrip('[').rstrip(']')).astype(float)\n\nsolution.to_csv(\"dogsVScats.csv\", index=False)\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2023-03-28T07:55:17.538362Z","iopub.execute_input":"2023-03-28T07:55:17.538859Z","iopub.status.idle":"2023-03-28T07:55:17.544592Z","shell.execute_reply.started":"2023-03-28T07:55:17.538815Z","shell.execute_reply":"2023-03-28T07:55:17.54337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}