{"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":"## Import Toolkit","metadata":{}},{"cell_type":"code","source":"#import os libs\nimport os\nimport shutil\nimport itertools\nimport pathlib\nfrom PIL import Image\n#import Data handling\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nsns.set_style('whitegrid')\nfrom sklearn.metrics import confusion_matrix , classification_report, ConfusionMatrixDisplay\nfrom sklearn.model_selection import train_test_split\n#import Deep learning tools\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D , MaxPooling2D , Dense , BatchNormalization , Dropout,Flatten , Activation\nfrom tensorflow.keras.optimizers import Adam , Adamax\nfrom tensorflow.keras import regularizers\n\n#Warnings\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-09-26T10:33:02.996902Z","iopub.execute_input":"2023-09-26T10:33:02.997283Z","iopub.status.idle":"2023-09-26T10:33:03.005661Z","shell.execute_reply.started":"2023-09-26T10:33:02.997249Z","shell.execute_reply":"2023-09-26T10:33:03.004724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Upload Data","metadata":{}},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats/train.zip","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:07.595308Z","iopub.execute_input":"2023-09-26T09:28:07.595993Z","iopub.status.idle":"2023-09-26T09:28:19.639137Z","shell.execute_reply.started":"2023-09-26T09:28:07.595960Z","shell.execute_reply":"2023-09-26T09:28:19.638047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats/test1.zip","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:19.641089Z","iopub.execute_input":"2023-09-26T09:28:19.641484Z","iopub.status.idle":"2023-09-26T09:28:26.192125Z","shell.execute_reply.started":"2023-09-26T09:28:19.641448Z","shell.execute_reply":"2023-09-26T09:28:26.190932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path , dirs , files = next(os.walk('/kaggle/working/train'))\nfile_count = len(files)\nprint(file_count)\nbase_dir = '/kaggle/working/dogs_vs_cats_small'\nos.mkdir(base_dir)","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:26.195233Z","iopub.execute_input":"2023-09-26T09:28:26.195575Z","iopub.status.idle":"2023-09-26T09:28:26.233860Z","shell.execute_reply.started":"2023-09-26T09:28:26.195546Z","shell.execute_reply":"2023-09-26T09:28:26.232957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create Directories for Train , Test and Validation data","metadata":{}},{"cell_type":"code","source":"train_dir = os.path.join(base_dir , 'train')\nos.mkdir(train_dir) #make a new train directory inside my base directory\n\nvalid_dir= os.path.join(base_dir , 'validation')\nos.mkdir(valid_dir) #make a new validation directory inside my base directory\n\ntest_dir = os.path.join(base_dir , 'test')\nos.mkdir(test_dir) #make a new test directory inside my base directory\n\ntrain_cats_dir = os.path.join(train_dir , 'cats')\nos.mkdir(train_cats_dir) #make a new cats directory inside my train directory\n\ntrain_dogs_dir = os.path.join(train_dir , 'dogs')\nos.mkdir(train_dogs_dir) #make a new dogs directory inside my train directory\n\nvalid_cats_dir = os.path.join(valid_dir, 'cats')\nos.mkdir(valid_cats_dir) #make a new cats directory inside my validation directory\n\nvalid_dogs_dir = os.path.join(valid_dir , 'dogs')\nos.mkdir(valid_dogs_dir) #make a new dogs directory inside my validation directory\n\ntest_cats_dir = os.path.join(test_dir , 'cats')\nos.mkdir(test_cats_dir) #make a new cats directory inside my test directory\n\ntest_dogs_dir = os.path.join(test_dir , 'dogs')\nos.mkdir(test_dogs_dir) #make a new dogs directory inside my test directory","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:26.235397Z","iopub.execute_input":"2023-09-26T09:28:26.235835Z","iopub.status.idle":"2023-09-26T09:28:26.246434Z","shell.execute_reply.started":"2023-09-26T09:28:26.235801Z","shell.execute_reply":"2023-09-26T09:28:26.245296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dir_path = '/kaggle/working/train'\n\ncat_count = 0\ndog_count= 0\nfor i in os.listdir(dir_path):\n    if i.startswith('cat.'):\n        cat_count += 1\n    elif i.startswith('dog.'):\n        dog_count += 1\n        \nprint(f\"Number of cat images: {cat_count}\")\nprint(f\"Number of dog images: {dog_count}\")","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:26.248194Z","iopub.execute_input":"2023-09-26T09:28:26.248658Z","iopub.status.idle":"2023-09-26T09:28:26.283573Z","shell.execute_reply.started":"2023-09-26T09:28:26.248625Z","shell.execute_reply":"2023-09-26T09:28:26.282554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"original_dataset_dir = '/kaggle/working/train'\n\nfnames = ['cat.{}.jpg'.format(i) for i in range(10001)] #Move 10,000 cat images from the original dataset to the train cat directory\nfor fname in fnames:\n  src = os.path.join(original_dataset_dir , fname)\n  dst = os.path.join(train_cats_dir , fname)\n  shutil.copyfile(src , dst)\n\nfnames = ['cat.{}.jpg'.format(i) for i in range(10001,11251)] #Move 1250 cat images from the original dataset to the validation cat directory\nfor fname in fnames:\n  src = os.path.join(original_dataset_dir , fname)\n  dst = os.path.join(valid_cats_dir , fname)\n  shutil.copyfile(src,dst)\n\nfnames = ['cat.{}.jpg'.format(i) for i in range(11251,12500)] #Move 1250 cat images from the original dataset to the test cat directory\nfor fname in fnames:\n  src= os.path.join(original_dataset_dir , fname)\n  dst= os.path.join(test_cats_dir, fname)\n  shutil.copyfile(src,dst)\n\nfnames = ['dog.{}.jpg'.format(i) for i in range(10001)] #Move 10,000 dog images from the original dataset to the train cat directory\nfor fname in fnames:\n  src = os.path.join(original_dataset_dir , fname)\n  dst = os.path.join(train_dogs_dir ,fname)\n  shutil.copyfile(src,dst)\n\nfnames = ['dog.{}.jpg'.format(i) for i in range(10001,11251)] #Move 1250 dog images from the original dataset to the validation cat directory\nfor fname in fnames:\n  src = os.path.join(original_dataset_dir,fname)\n  dst = os.path.join(valid_dogs_dir , fname)\n  shutil.copyfile(src,dst)\n\nfnames = ['dog.{}.jpg'.format(i) for i in range(11251,12500)]#Move 1250 dog images from the original dataset to the test cat directory\nfor fname in fnames:\n  src= os.path.join(original_dataset_dir, fname)\n  dst = os.path.join(test_dogs_dir , fname)\n  shutil.copyfile(src, dst)","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:26.285119Z","iopub.execute_input":"2023-09-26T09:28:26.285584Z","iopub.status.idle":"2023-09-26T09:28:28.984578Z","shell.execute_reply.started":"2023-09-26T09:28:26.285549Z","shell.execute_reply":"2023-09-26T09:28:28.983334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Total training cat images {len(os.listdir(train_cats_dir))}')\nprint(f'Total validation cat images {len(os.listdir(valid_cats_dir))}')\nprint(f'Total test cat images {len(os.listdir(test_cats_dir))}')\nprint('\\n')\nprint(f'Total training dog images {len(os.listdir(train_dogs_dir))}')\nprint(f'Total validation cat images {len(os.listdir(valid_dogs_dir))}')\nprint(f'Total test cat images {len(os.listdir(test_dogs_dir))}')","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:28.986336Z","iopub.execute_input":"2023-09-26T09:28:28.986691Z","iopub.status.idle":"2023-09-26T09:28:29.010710Z","shell.execute_reply.started":"2023-09-26T09:28:28.986642Z","shell.execute_reply":"2023-09-26T09:28:29.009729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image Data Generator","metadata":{}},{"cell_type":"code","source":"img_size = (224 , 224)\nbatch_size = 32\nimg_shape = (img_size[0] , img_size[1] , 3)\n\ntr_gen = ImageDataGenerator()\nts_gen = ImageDataGenerator()\n\ntrain_gen = tr_gen.flow_from_directory(train_dir , target_size = img_size , class_mode = 'binary' , \n                                       color_mode = 'rgb' , shuffle = True , batch_size = batch_size)\n\nvalid_gen = ts_gen.flow_from_directory(valid_dir , target_size = img_size , class_mode = 'binary' , \n                                       color_mode = 'rgb' , shuffle = True , batch_size = batch_size)\n\ntest_gen = ts_gen.flow_from_directory(test_dir , target_size = img_size , class_mode = 'binary' , \n                                       color_mode = 'rgb' , shuffle = False , batch_size = batch_size)","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:29.012200Z","iopub.execute_input":"2023-09-26T09:28:29.012611Z","iopub.status.idle":"2023-09-26T09:28:31.685599Z","shell.execute_reply.started":"2023-09-26T09:28:29.012579Z","shell.execute_reply":"2023-09-26T09:28:31.684605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Show Sample From Train Data","metadata":{}},{"cell_type":"code","source":"g_dict = train_gen.class_indices\nclasses = list(g_dict.keys())\nimages, labels = next(train_gen)\nnum_samples = len(images)\n\nplt.figure(figsize=(20, 20))\n\nfor i in range(min(16, num_samples)):\n    plt.subplot(4, 4, i + 1)\n    image = images[i] / 255\n    plt.imshow(image)\n    class_index = int(labels[i])\n    class_name = classes[class_index]\n    plt.title(class_name, color='blue', fontsize=12)\n    plt.axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:31.689086Z","iopub.execute_input":"2023-09-26T09:28:31.689362Z","iopub.status.idle":"2023-09-26T09:28:35.907917Z","shell.execute_reply.started":"2023-09-26T09:28:31.689338Z","shell.execute_reply":"2023-09-26T09:28:35.906484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_shape = (img_size[0] , img_size[1] , 3)\nbase_model = tf.keras.applications.efficientnet.EfficientNetB5(include_top= False , weights= 'imagenet' ,\n                                                               input_shape= img_shape,pooling= 'max')\nbase_model.trainable= False\n\nnum_classes = len(classes)\n\nmodel = Sequential([\n    base_model,\n    BatchNormalization(axis = -1 , momentum = 0.99 , epsilon = 0.001),\n    Dense(256, kernel_regularizer = regularizers.l2(l= 0.016) , activity_regularizer = regularizers.l1(0.006),\n         bias_regularizer= regularizers.l1(0.006) , activation = 'relu'),\n    Dropout(rate = 0.4 , seed = 40),\n    Dense(1 , activation= 'sigmoid' )\n])\nmodel.compile(Adamax(learning_rate = 0.001) , loss = 'binary_crossentropy' , metrics= ['accuracy'])\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:35.909202Z","iopub.execute_input":"2023-09-26T09:28:35.909618Z","iopub.status.idle":"2023-09-26T09:28:49.861997Z","shell.execute_reply.started":"2023-09-26T09:28:35.909577Z","shell.execute_reply":"2023-09-26T09:28:49.861041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(x= train_gen , validation_data= valid_gen , epochs= 10 , verbose = 1 , validation_steps = None , shuffle = False)","metadata":{"execution":{"iopub.status.busy":"2023-09-26T09:28:49.863816Z","iopub.execute_input":"2023-09-26T09:28:49.864488Z","iopub.status.idle":"2023-09-26T09:59:55.466133Z","shell.execute_reply.started":"2023-09-26T09:28:49.864455Z","shell.execute_reply":"2023-09-26T09:59:55.465106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Performance","metadata":{}},{"cell_type":"code","source":"train_acc = history.history['accuracy']\ntrain_loss = history.history['loss']\n\nval_acc = history.history['val_accuracy']\nval_loss = history.history['val_loss']\n\nindex_loss = np.argmin(val_loss)\nindex_acc = np.argmax(val_acc)\n\nval_lowest = val_loss[index_loss]\nval_highest = val_acc[index_acc]\n\nEpochs = [i+1 for i in range(len(train_acc))]\n\nloss_label = f'Best Epoch = {str(index_loss + 1)}'\nacc_label = f'Best Epoch = {str(index_acc + 1)}'\n\nplt.figure(figsize= (20,8))\nplt.style.use('fivethirtyeight')\n\nplt.subplot(1,2,1)\nplt.plot(Epochs , train_loss , 'r', label = 'Training Loss')\nplt.plot(Epochs , val_loss , 'g' , label = 'Validation Loss')\nplt.scatter(index_loss +1 , val_lowest , s = 150 , c = 'blue' , label = loss_label)\nplt.title('Training vs Validation (loss)')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.subplot(1,2,2)\nplt.plot(Epochs , train_acc , 'r', label= 'Training Accuracy')\nplt.plot(Epochs , val_acc , 'g' , label = 'Validation Accuracy')\nplt.scatter(index_acc + 1 , val_highest , s= 150 , c = 'blue' , label= acc_label)\nplt.title('Training vs Validation (Accuracy)')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.tight_layout\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2023-09-26T10:15:17.086547Z","iopub.execute_input":"2023-09-26T10:15:17.087011Z","iopub.status.idle":"2023-09-26T10:15:18.013449Z","shell.execute_reply.started":"2023-09-26T10:15:17.086975Z","shell.execute_reply":"2023-09-26T10:15:18.012552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Evaluation","metadata":{}},{"cell_type":"code","source":"train_score = model.evaluate(train_gen , steps= 32 , verbose = 1)\nval_score = model.evaluate(valid_gen , steps = 32 , verbose = 1)\ntest_score = model.evaluate(test_gen , steps = 32 , verbose = 1)\n\nprint(f'Train loss = {train_score[0] }')\nprint(f'Train Accuracy = {train_score[1]}')\nprint(f'Validation loss = {val_score[0]}')\nprint(f'Validation Accuracy = {val_score[1]}')\nprint(f'Test loss = {test_score[0]}')\nprint(f'Test Accuracy = {test_score[1]}')","metadata":{"execution":{"iopub.status.busy":"2023-09-26T10:19:41.369047Z","iopub.execute_input":"2023-09-26T10:19:41.369465Z","iopub.status.idle":"2023-09-26T10:20:08.762844Z","shell.execute_reply.started":"2023-09-26T10:19:41.369436Z","shell.execute_reply":"2023-09-26T10:20:08.761745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Prediction","metadata":{}},{"cell_type":"markdown","source":"## Confusion Matrix and Classification Report","metadata":{}},{"cell_type":"code","source":"# Make predictions on the test set\npreds = model.predict(test_gen)\n\n# Convert the predictions to binary classes (0 or 1)\npredicted_classes = (preds > 0.5).astype(int)","metadata":{"execution":{"iopub.status.busy":"2023-09-26T10:29:03.660348Z","iopub.execute_input":"2023-09-26T10:29:03.660743Z","iopub.status.idle":"2023-09-26T10:29:19.264088Z","shell.execute_reply.started":"2023-09-26T10:29:03.660716Z","shell.execute_reply":"2023-09-26T10:29:19.263145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get the true labels from the generator\ntrue_classes = test_gen.classes\n\n# Calculate the confusion matrix\nconfusion = confusion_matrix(true_classes, predicted_classes)\n\n# Display the confusion matrix as a heatmap\ndisp = ConfusionMatrixDisplay(confusion_matrix=confusion, display_labels=test_gen.class_indices)\ndisp.plot(cmap='viridis', values_format='d')","metadata":{"execution":{"iopub.status.busy":"2023-09-26T10:33:10.879128Z","iopub.execute_input":"2023-09-26T10:33:10.879494Z","iopub.status.idle":"2023-09-26T10:33:11.259929Z","shell.execute_reply.started":"2023-09-26T10:33:10.879465Z","shell.execute_reply":"2023-09-26T10:33:11.258855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate and print the classification report\nclassification_rep = classification_report(true_classes, predicted_classes, target_names=test_gen.class_indices)\nprint(\"\\nClassification Report:\")\nprint(classification_rep)","metadata":{"execution":{"iopub.status.busy":"2023-09-26T10:34:04.703307Z","iopub.execute_input":"2023-09-26T10:34:04.703942Z","iopub.status.idle":"2023-09-26T10:34:04.723026Z","shell.execute_reply.started":"2023-09-26T10:34:04.703897Z","shell.execute_reply":"2023-09-26T10:34:04.721759Z"},"trusted":true},"execution_count":null,"outputs":[]}]}