{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":6972318,"sourceType":"datasetVersion","datasetId":4006081}],"dockerImageVersionId":30558,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"**the purpose of this project is to showcase the power of CNN architucture in dealing with small data and how to avoid overfitting**\n***using only 1000 samples for each category***","metadata":{}},{"cell_type":"markdown","source":"--------------------------------------------------------------------------------------------------\n# Table of contents:\n\n1.   **Dealing with data**:\n         *Unzipping the data \n         *making directories for each category for training ,validation and test data(1000 samples  for each category)\n          \n1.    **Building Basic CNN architecture**\n         *visulaiztion of the performance : Loss/accuracy figure\n         *interpretation of overfitting from the figure \n1.                           *** Importatnt skill*** \n                ---- **visualization the CNN's layeres** ---\n         \n1.    **building models using techniques of avoiding overfitting**\n          * Data augmentation \n          *+ Dropout\n          *visulaiztion of the performance : Loss/accuracy figure\n     \n  ------------------------------------------------------------------------------------------------\n     ","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","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ***unzipping the data ***\n\n","metadata":{}},{"cell_type":"code","source":"if not os.path.exists(\"/kaggle/working/train\"):\n    !unzip -q /kaggle/input/dogs-vs-cats/train.zip\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '/kaggle/working/train'\nlen(os.listdir(train_path))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **visualization**","metadata":{}},{"cell_type":"code","source":"import matplotlib.image as mpimg\nimport matplotlib.pyplot as plt \nimport random\nimages=os.listdir(train_path)\nplt.figure(figsize=(16,16))\nfor i in range(7): \n    img = random.choice([x for x in images])\n    fig = plt.subplot(4,4,i+1)\n    img = mpimg.imread(os.path.join(train_path, img)) \n    fig.imshow(img)\n    \n    \n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **oraganisation of the directories : cats / dogs**\n","metadata":{}},{"cell_type":"code","source":"# store our smaller dataset\nbase_dir ='/kaggle/working//cats_and_dogs_small'\ntry:\n  os.mkdir(base_dir)\nexcept:\n  pass","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = os.path.join(base_dir, 'train')\ntry:\n  os.mkdir(train_dir)\nexcept:\n  pass  \nvalidation_dir = os.path.join(base_dir, 'validation')\ntry:\n  os.mkdir(validation_dir)\nexcept:\n  pass   \ntest_dir = os.path.join(base_dir, 'test')\ntry:\n  os.mkdir(test_dir)\nexcept:\n  pass   ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Directory with our training cat pictures\ntrain_cats_dir = os.path.join(train_dir, 'cats')\ntry:\n  os.mkdir(train_cats_dir)\nexcept:\n  pass   \n\n# Directory with our training dog pictures\ntrain_dogs_dir = os.path.join(train_dir, 'dogs')\ntry:\n  os.mkdir(train_dogs_dir)\nexcept:\n  pass   \n\n# Directory with our validation cat pictures\nvalidation_cats_dir = os.path.join(validation_dir, 'cats')\ntry:\n  os.mkdir(validation_cats_dir)\nexcept:\n  pass \n\n# Directory with our validation dog pictures\nvalidation_dogs_dir = os.path.join(validation_dir, 'dogs')\ntry:\n  os.mkdir(validation_dogs_dir)\nexcept:\n  pass   \n\n# Directory with our validation cat pictures\ntest_cats_dir = os.path.join(test_dir, 'cats')\ntry:\n  os.mkdir(test_cats_dir)\nexcept:\n  pass   \n\n# Directory with our validation dog pictures\ntest_dogs_dir = os.path.join(test_dir, 'dogs')\ntry:\n  os.mkdir(test_dogs_dir)\nexcept:\n  pass   ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images[:20]","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\n#store only 1000 samples for each category for training data \n\nfnames_dog=['dog.{}.jpg'.format(i) for i in range(1000) ]\nfnames_cat=['cat.{}.jpg'.format(i) for i in range(1000) ]\nfor fname in fnames_dog :\n    src = os.path.join(train_path, fname)\n    path=os.path.join(train_dogs_dir,fname)\n    shutil.copyfile(src,path)\nfor fname in fnames_cat:\n    src = os.path.join(train_path, fname)\n    path=os.path.join(train_cats_dir,fname)\n    shutil.copyfile(src,path)\n    \n\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#store only 500 samples for each category for validation data \nfnames_cat = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]\nfnames_dog = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]\nfor fname in fnames_dog :\n    src = os.path.join(train_path, fname)\n    path=os.path.join(validation_dogs_dir,fname)\n    shutil.copyfile(src,path)\nfor fname in fnames_cat:\n    src = os.path.join(train_path, fname)\n    path=os.path.join(validation_cats_dir,fname)\n    shutil.copyfile(src,path)\n    \n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#store only 500 samples for each category for vtest data \nfnames_cat = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]\nfnames_dog = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]\nfor fname in fnames_dog :\n    src = os.path.join(train_path, fname)\n    path=os.path.join(test_dogs_dir,fname)\n    shutil.copyfile(src,path)\nfor fname in fnames_cat:\n    src = os.path.join(train_path, fname)\n    path=os.path.join(test_cats_dir,fname)\n    shutil.copyfile(src,path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#verification\nprint('total training cat images:', len(os.listdir(train_cats_dir)))\nprint('total training dog images:', len(os.listdir(train_dogs_dir)))\nprint('total training cat images:', len(os.listdir(validation_cats_dir)))\nprint('total training cat images:', len(os.listdir(validation_dogs_dir)))\nprint('total training cat images:', len(os.listdir(test_cats_dir)))\nprint('total training cat images:', len(os.listdir(test_dogs_dir)))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1.Builduing CNN Architucture ","metadata":{}},{"cell_type":"markdown","source":"**Building our network**\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import layers\nfrom tensorflow.keras import models\n\nmodel = models.Sequential()\nmodel.add(layers.Conv2D(32, (3, 3), activation='relu',\n                        input_shape=(150, 150, 3)))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(64, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(512, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import optimizers\n\nmodel.compile(loss='binary_crossentropy',\n              optimizer=optimizers.RMSprop(lr=1e-4),\n              metrics=['acc'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data preprocessing**","metadata":{}},{"cell_type":"code","source":"#python generator \nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# All images will be rescaled by 1./255\ntrain_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntrain_generator = train_datagen.flow_from_directory(\n        # This is the target directory\n        train_dir,\n        # All images will be resized to 150x150\n        target_size=(150, 150),\n        batch_size=20,\n        # Since we use binary_crossentropy loss, we need binary labels\n        class_mode='binary')\nvalidation_generator = test_datagen.flow_from_directory(\n        validation_dir,\n        target_size=(150, 150),\n        batch_size=20,\n        class_mode='binary')\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for data_batch, labels_batch in train_generator:\n    print('data batch shape:', data_batch.shape)\n    print('labels batch shape:', labels_batch.shape)\n    break","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**fitting the data**","metadata":{}},{"cell_type":"code","source":"\nhistory = model.fit(\n      train_generator,\n    #cuz there are 2000 sapmples=100*20(batch-size(20images))\n      steps_per_epoch=100,\n      epochs=30,\n      validation_data=validation_generator,\n      validation_steps=50)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#saving the model\nimport joblib\njoblib.dump(model, 'model.pkl')\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ****evaluation of the performance ****","metadata":{}},{"cell_type":"markdown","source":"**plotting the accuracy/loss of the model over training / validation data**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n#acc for the training data\nacc = history.history['acc']\n#acc for the validation data\nval_acc = history.history['val_acc']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.interpretation of the performance ","metadata":{}},{"cell_type":"markdown","source":"**as we see , there is overfitting ( the training acc increases lineraly untill it reaches 100% and the loss reaches 0% (decreasing linearly)**\n","metadata":{}},{"cell_type":"markdown","source":"techniques to this problem : \n1. **Data augmentation (adding more data from the original)**\n1. **droping out**\n1. **regularization**\n1. **transfer learning models**\n","metadata":{}},{"cell_type":"markdown","source":"# important skill:\n# Visualizing intermediate activations","metadata":{}},{"cell_type":"markdown","source":"**For a specefic image :**","metadata":{}},{"cell_type":"code","source":"img_path = '/kaggle/input/cattttt/1sbnkirc.png'\n\n# We preprocess the image into a 4D tensor\nfrom tensorflow.keras.preprocessing import image\nimport numpy as np\n\nimg = image.load_img(img_path, target_size=(150, 150))\nimg_tensor = image.img_to_array(img)\nimg_tensor = np.expand_dims(img_tensor, axis=0)\n# Remember that the model was trained on inputs\n# that were preprocessed in the following way:\nimg_tensor /= 255.\n\n\nprint(img_tensor.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.imshow(img_tensor[0])\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import models\n\n# Extracts the outputs of the top 8 layers:\nlayer_outputs = [layer.output for layer in model.layers[:8]]\n# Creates a model that will return these outputs, given the model input:\nactivation_model = models.Model(inputs=model.input, outputs=layer_outputs)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# This will return a list of 5 Numpy arrays:\n# one array per layer activation\nactivations = activation_model.predict(img_tensor)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"first_layer_activation = activations[0]\nprint(first_layer_activation.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It's a 148x148 feature map with 32 channels","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.matshow(first_layer_activation[0, :, :, 3], cmap='viridis')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can conclude that the kernel of this resulat is for detecting  the edges , ","metadata":{}},{"cell_type":"markdown","source":"# Complete visualization of all activations ","metadata":{}},{"cell_type":"code","source":"import tensorflow.keras as keras\n\n# These are the names of the layers, so can have them as part of our plot\nlayer_names = []\nfor layer in model.layers[:8]:\n    layer_names.append(layer.name)\n\nimages_per_row = 16\n\n# Now let's display our feature maps\nfor layer_name, layer_activation in zip(layer_names, activations):\n    # This is the number of features in the feature map\n    n_features = layer_activation.shape[-1]\n\n    # The feature map has shape (1, size, size, n_features)\n    size = layer_activation.shape[1]\n\n    # We will tile the activation channels in this matrix\n    n_cols = n_features // images_per_row\n    display_grid = np.zeros((size * n_cols, images_per_row * size))\n\n    # We'll tile each filter into this big horizontal grid\n    for col in range(n_cols):\n        for row in range(images_per_row):\n            channel_image = layer_activation[0,\n                                             :, :,\n                                             col * images_per_row + row]\n            # Post-process the feature to make it visually palatable\n            channel_image -= channel_image.mean()\n            channel_image /= channel_image.std()\n            channel_image *= 64\n            channel_image += 128\n            channel_image = np.clip(channel_image, 0, 255).astype('uint8')\n            display_grid[col * size : (col + 1) * size,\n                         row * size : (row + 1) * size] = channel_image\n\n    # Display the grid\n    scale = 1. / size\n    plt.figure(figsize=(scale * display_grid.shape[1],\n                        scale * display_grid.shape[0]))\n    plt.title(layer_name)\n    plt.grid(False)\n    plt.imshow(display_grid, aspect='auto', cmap='viridis')\n    \nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# data augmentation","metadata":{}},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1/255,\n    #transformers of the image , randomly \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      #filling the missing pixels with the values of the nearst pixels when the zoom  for example                     \n      fill_mode='nearest')\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#looking the one augemented image \nfrom tensorflow.keras.preprocessing import image\n\nfnames = [os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)]\nimg_pth=fnames[0]\nimg = image.load_img(img_pth, target_size=(150, 150))\n\n\n#numpy array\nx_img = image.img_to_array(img)\nx_img = x_img.reshape((1,) + x_img.shape)\ni=0\n\nfor batch in datagen.flow(x_img, batch_size=1):\n    plt.figure(i)\n    plt.imshow(image.array_to_img(batch[0]))\n    i+=1\n    if i==4:\n        break \nplt.show()\n\n    \n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2.Model with data augmentation and dropout","metadata":{}},{"cell_type":"code","source":"model = models.Sequential()\nmodel.add(layers.Conv2D(32, (3, 3), activation='relu',\n                        input_shape=(150, 150, 3)))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(64, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2, 2)))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(512))#, kernel_regularizer=regularizers.l2(0.001), activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))\nprint(model.summary())\nmodel.compile(loss='binary_crossentropy',\n              optimizer=optimizers.RMSprop(lr=1e-4),\n              metrics=['acc'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#using data augementation\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\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n        # This is the target directory\n        train_dir,\n        # All images will be resized to 150x150\n        target_size=(150, 150),\n        batch_size=20,\n        # Since we use binary_crossentropy loss, we need binary labels\n        class_mode='binary')\n\n\n\nvalidation_generator = test_datagen.flow_from_directory(\n        validation_dir,\n        target_size=(150, 150),\n        batch_size=20,\n        class_mode='binary')\n\nhistory = model.fit_generator(\n      train_generator,\n      steps_per_epoch=100,\n      epochs=30,\n      validation_data=validation_generator,\n      validation_steps=50)","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# #plotting the acc/loss (model using data augmenation )","metadata":{}},{"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transfer Learning :MobileNet \n    1. Using Data Augmentation \n    2.adding dropout\n\n","metadata":{}},{"cell_type":"markdown","source":"**building network**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D,Dropout\n\n# Load MobileNetV2 as the base model (without the top layers)\nbase_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\n\n# UnFreeze FEw layers of the base model\nfor layer in base_model.layers[:-23]:\n    layer.trainable = False\n\n# Create a custom CNN architecture on top of MobileNetV2\nmodel = Sequential()\n\n# Add the MobileNetV2 base model\nmodel.add(base_model)\n\n# Add a Global Average Pooling layer to reduce spatial dimensions\nmodel.add(GlobalAveragePooling2D())\n\n# Add fully connected layers for classification\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid'))  # Assuming binary classification (cat/dog)\n\n# Compile the model\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n\n# Display the model summary\nmodel.summary()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-17T02:15:18.419537Z","iopub.execute_input":"2023-11-17T02:15:18.419991Z","iopub.status.idle":"2023-11-17T02:15:20.278584Z","shell.execute_reply.started":"2023-11-17T02:15:18.419958Z","shell.execute_reply":"2023-11-17T02:15:20.277524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Processing data ","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping\n\n# Define image size and batch size\nimg_size = (224, 224)\nbatch_size = 32\n\n# Create data generators with augmentation for training data\ntrain_datagen = ImageDataGenerator(\n)\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size=img_size,\n    batch_size=batch_size,\n    class_mode='binary'  # Adjust based on your task\n)\n\nvalidation_generator = validation_datagen.flow_from_directory(\n    validation_dir,\n    target_size=img_size,\n    batch_size=batch_size,\n    class_mode='binary'  # Adjust based on your task\n)\n\n\n# Define EarlyStopping callback\n\nearly_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)\n# Train the model\nhistory = model.fit(\n    train_generator,\n    steps_per_epoch=train_generator.samples // batch_size,\n    epochs=10,  # Adjust as needed\n    validation_data=validation_generator,\n    validation_steps=validation_generator.samples // batch_size,  callbacks=[early_stopping] )\n","metadata":{"execution":{"iopub.status.busy":"2023-11-17T02:15:30.098927Z","iopub.execute_input":"2023-11-17T02:15:30.099333Z","iopub.status.idle":"2023-11-17T02:15:30.151663Z","shell.execute_reply.started":"2023-11-17T02:15:30.099297Z","shell.execute_reply":"2023-11-17T02:15:30.150408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Plotting loss/accuracy for validation/train data ","metadata":{}},{"cell_type":"code","source":"acc = 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, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluation of test data","metadata":{}},{"cell_type":"code","source":"test= ImageDataGenerator(rescale=1./255)\n\ntest_generator = test.flow_from_directory(\n    test_dir,\n    target_size=img_size,\n    batch_size=batch_size,\n    class_mode='binary'  # Adjust based on your task\n)\n\n\n\nacc = model.evaluate(test_generator)\nprint(\"Model accuracy on test data:\", acc[1] * 100, \"%\")\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Still overfitting**\n\n1. Let's hypertunne somme parameters like adding more options for data augmenetation\n1. change the architucture of the model","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nfrom tensorflow.keras.applications import MobileNet\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# Load the pre-trained MobileNet model without the top (fully connected) layers\nbase_model = MobileNet(weights='imagenet', include_top=False)\n\n# Create a Sequential model\nmodel = Sequential()\n\n# Add the MobileNet base model to the Sequential model\nmodel.add(base_model)\n\n# Add custom layers for binary classification\nmodel.add(GlobalAveragePooling2D())\nmodel.add(Dense(1024, activation='relu'))\nmodel.add(Dense(1, activation='sigmoid'))\n\n# Freeze the pre-trained layers\nfor layer in base_model.layers:\n    layer.trainable = False\n\n# Compile the model\nmodel.compile(optimizer=Adam(lr=1e-4), loss='binary_crossentropy', metrics=['accuracy'])\n\n# Data 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\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\n# Load and preprocess the data using generators\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,  \n    target_size=(224, 224),\n    batch_size=32,\n    class_mode='binary')\n\nvalidation_generator = test_datagen.flow_from_directory(\n    validation_dir, \n    target_size=(224, 224),\n    batch_size=32,\n    class_mode='binary')\n\n# Train the model\nhistory = model.fit(\n    train_generator,\n    steps_per_epoch=len(train_generator),\n    epochs=10,\n    validation_data=validation_generator,\n    validation_steps=len(validation_generator))\n\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluate the model on test data\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,  \n    target_size=(224, 224),\n    batch_size=32,\n    class_mode='binary')\n\ntest_loss, test_acc = model.evaluate(test_generator, steps=len(test_generator))\nprint(f'Test accuracy: {test_acc}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = 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, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'b', label='Validation acc')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'bo', label='Training loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-17T01:44:28.962550Z","iopub.execute_input":"2023-11-17T01:44:28.962965Z","iopub.status.idle":"2023-11-17T01:44:29.221608Z","shell.execute_reply.started":"2023-11-17T01:44:28.962936Z","shell.execute_reply":"2023-11-17T01:44:29.220651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predcition(Test data)","metadata":{}},{"cell_type":"markdown","source":"> from tensorflow.keras.preprocessing import image\n> #scaling data test\n> test=os.listdir(test_path)\n> fnames = [os.path.join('/kaggle/working/test1', fname) for fname in test]\n> submission=[]\n> for i in range (len(fnames)): \n>     \n>     img = image.load_img(fnames[i], target_size=(150, 150))\n>     x_img = image.img_to_array(img)\n>     x_img = x_img.reshape((1,) + x_img.shape)\n>     x_img=x_img/255\n>     predictions=model.predict(x_img)\n>     class_index = np.argmax(predictions)\n>     submission.append({'id':i ,'label':class_index})\n> \n> \n> \n>     \n>     \n>     \n>     \n> \n> \n> ","metadata":{"execution":{"iopub.status.busy":"2023-11-17T01:45:50.444230Z","iopub.execute_input":"2023-11-17T01:45:50.444879Z","iopub.status.idle":"2023-11-17T01:45:50.512183Z","shell.execute_reply.started":"2023-11-17T01:45:50.444849Z","shell.execute_reply":"2023-11-17T01:45:50.510382Z"}}},{"cell_type":"markdown","source":"# Submission file","metadata":{}},{"cell_type":"markdown","source":"submission = pd.DataFrame(submission)\nsubmission.to_csv('submission.csv', index=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-17T02:37:54.595413Z","iopub.execute_input":"2023-11-17T02:37:54.595794Z","iopub.status.idle":"2023-11-17T02:37:54.627931Z","shell.execute_reply.started":"2023-11-17T02:37:54.595767Z","shell.execute_reply":"2023-11-17T02:37:54.626202Z"}}}]}