{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":70497,"databundleVersionId":7713244,"sourceType":"competition"}],"dockerImageVersionId":30665,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## **if you like my kernel,please consider upvoting**","metadata":{}},{"cell_type":"markdown","source":"**and it's no rocket science,its fun.** then let's go","metadata":{}},{"cell_type":"markdown","source":"![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOWc4OTJtaDc4ZDRwOHMydzc4bWs5NnhiNWJ5N3Uwdjd3MXJ6anhycSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/Y1vDOyW1OmQH8tt2W3/giphy.gif)","metadata":{}},{"cell_type":"markdown","source":"# we will talk about binary classification\nBinary classification is the task of classifying the elements of a set into one of two groups (each called class) on the basis of a classification rule.\nfor example you classify sex , between male and female :","metadata":{}},{"cell_type":"markdown","source":"![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExeWM5bDFvYnY3djR4cjlkY240bzR2b3d3OHQ0dTk0ZXZtNnFlbjV5cyZlcD12MV9naWZzX3NlYXJjaCZjdD1n/CkHI2JsOnxqmjGYmB3/giphy.gif)","metadata":{}},{"cell_type":"markdown","source":"### Loading required libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport cv2\nimport os\nimport glob\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport tensorflow as tf\nfrom tensorflow.keras.applications.vgg16 import VGG16\nfrom keras.layers import Activation,Dense, Dropout, Flatten, Conv2D, ReLU\nfrom keras.models import Model\nfrom keras.applications.inception_v3 import InceptionV3\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping\nfrom keras.optimizers import SGD, Adam\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import roc_curve, auc, precision_recall_curve, f1_score\nfrom tensorflow.keras.utils import plot_model\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nfrom sklearn.model_selection import train_test_split\nimport itertools","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:17:58.517992Z","iopub.execute_input":"2024-03-19T14:17:58.518388Z","iopub.status.idle":"2024-03-19T14:18:18.024916Z","shell.execute_reply.started":"2024-03-19T14:17:58.518361Z","shell.execute_reply":"2024-03-19T14:18:18.024072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Setting our directories","metadata":{}},{"cell_type":"code","source":"train_p = '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/'\ntest_p = '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_test/test/'","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:18.026239Z","iopub.execute_input":"2024-03-19T14:18:18.027237Z","iopub.status.idle":"2024-03-19T14:18:18.031695Z","shell.execute_reply.started":"2024-03-19T14:18:18.027199Z","shell.execute_reply":"2024-03-19T14:18:18.030623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data descriptions\n\n**train folder** - the training set in 6 sub-folders of freshapples, freshbanana, freshoranges, rottenapples, rottenbanana, rottenoranges\n\n**test folder** - the test set in 6 sub-folders of freshapples, freshbanana, freshoranges, rottenapples, rottenbanana, rottenoranges\n\n**validation folder** - unseen images of freshapples, freshbanana, freshoranges, rottenapples, rottenbanana, rottenoranges\nsampleSubmission.csv - a sample submission file in the correct format with the following code:\n\"1\" for fresh apples; \"2\" for fresh banana; \"3\" for fresh oranges; \"4\" for rotten apples; \"5\" for rotten banana; \"6\" for rotten oranges","metadata":{}},{"cell_type":"markdown","source":"### Setting our labels","metadata":{}},{"cell_type":"code","source":"labels = ['freshapples' , 'freshbanana' , 'freshoranges' , 'rottenapples' , 'rottenbanana' , 'rottenoranges']","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:18.034564Z","iopub.execute_input":"2024-03-19T14:18:18.034896Z","iopub.status.idle":"2024-03-19T14:18:18.068180Z","shell.execute_reply.started":"2024-03-19T14:18:18.034872Z","shell.execute_reply":"2024-03-19T14:18:18.067278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### funny for loop to get num(images) in each category","metadata":{}},{"cell_type":"code","source":"# Count images in each folder class\nfor label in labels:\n    class_path = os.path.join(train_p, label)\n    num_images = len(os.listdir(class_path))\n    print(f\"The class {label} contains {num_images} images.\")","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:18.069277Z","iopub.execute_input":"2024-03-19T14:18:18.069626Z","iopub.status.idle":"2024-03-19T14:18:18.097105Z","shell.execute_reply.started":"2024-03-19T14:18:18.069595Z","shell.execute_reply":"2024-03-19T14:18:18.096289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create a DataFrame with the image file paths and labels\n","metadata":{}},{"cell_type":"code","source":"train_data_df = pd.DataFrame({'filename': train_p, 'class': labels})","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:18.098448Z","iopub.execute_input":"2024-03-19T14:18:18.098790Z","iopub.status.idle":"2024-03-19T14:18:18.106327Z","shell.execute_reply.started":"2024-03-19T14:18:18.098759Z","shell.execute_reply":"2024-03-19T14:18:18.105358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create the data generators\n","metadata":{}},{"cell_type":"markdown","source":"The provided code utilizes the `ImageDataGenerator` and `flow_from_directory` functions from Keras to generate batches of tensor image data with real-time data augmentation. Here's an explanation of the key parameters used in the code:\n\n- **ImageDataGenerator**: This class provides a way to augment images in real-time during model training. It allows for various transformations and preprocessing of the input images.\n\n- **rescale**: The rescale parameter is used to normalize the pixel values of the images. In this case, it rescales the pixel values to be in the range [0, 1] by dividing by 255.\n\n- **flow_from_directory**: This function generates batches of data from the specified directory. It automatically infers the classes from the subdirectory names and generates batches of augmented data.\n\n  - **directory**: The path to the target directory containing the subdirectories of images.\n  \n  - **batch_size**: The size of the batches of data. In this case, each batch will contain 32 images.\n  \n  - **target_size**: The dimensions to which all images found will be resized. In this case, the images will be resized to (244, 244) pixels.\n  \n  - **class_mode**: This parameter specifies the type of label arrays that are returned. In this case, it is set to 'categorical', which will return 2D one-hot encoded labels.\n\n  - **shuffle**: Whether to shuffle the data. It is set to True, which means the data will be shuffled.\n\n  - **seed**: An optional random seed for shuffling and transformations.\n\n  - **color_mode**: This parameter specifies the color mode of the images. It is set to 'rgb', indicating that the images will have 3 color channels (red, green, blue).\n\nBy using the `ImageDataGenerator` and `flow_from_directory` functions, the code sets up a data generator for training a model on a set of images organized into class-specific subdirectories.\n\nIf you have any further questions or need additional assistance, feel free to ask!","metadata":{}},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale=1./255)\ntrain_generator = train_datagen.flow_from_directory(\n    '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/',\n    batch_size=32,\n    target_size=(244,244),\n    class_mode='categorical',\n    shuffle=True,\n    seed=42,\n    color_mode = 'rgb'\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:18.107691Z","iopub.execute_input":"2024-03-19T14:18:18.107994Z","iopub.status.idle":"2024-03-19T14:18:22.192221Z","shell.execute_reply.started":"2024-03-19T14:18:18.107971Z","shell.execute_reply":"2024-03-19T14:18:22.191494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the test data generators\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_datagen.flow_from_directory(\n   '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_test/test/',\n    batch_size=32,\n    target_size=(244,244),\n    class_mode='categorical',\n    shuffle=True,\n    seed=42,\n    color_mode = 'rgb'\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:22.193315Z","iopub.execute_input":"2024-03-19T14:18:22.193661Z","iopub.status.idle":"2024-03-19T14:18:22.397876Z","shell.execute_reply.started":"2024-03-19T14:18:22.193625Z","shell.execute_reply":"2024-03-19T14:18:22.397046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**then we can see the diffrance between length of train data and generated train data**","metadata":{}},{"cell_type":"code","source":"len(train_p)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:01:23.894029Z","iopub.execute_input":"2024-03-19T15:01:23.894788Z","iopub.status.idle":"2024-03-19T15:01:23.900821Z","shell.execute_reply.started":"2024-03-19T15:01:23.894749Z","shell.execute_reply":"2024-03-19T15:01:23.899868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_generator)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:01:25.786122Z","iopub.execute_input":"2024-03-19T15:01:25.786941Z","iopub.status.idle":"2024-03-19T15:01:25.792753Z","shell.execute_reply.started":"2024-03-19T15:01:25.786912Z","shell.execute_reply":"2024-03-19T15:01:25.791782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://media.giphy.com/media/l1J9FiGxR61OcF2mI/giphy.gif?cid=790b7611a2wakneze816oqn8bpb43ypgbcqyw84tox1tmfbn&ep=v1_gifs_search&rid=giphy.gif&ct=g)","metadata":{}},{"cell_type":"markdown","source":"### lets get a view about sample of each class","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n# Read and display images from each class\nimage_paths = ['/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/freshapples/Screen Shot 2018-06-08 at 4.59.36 PM.png',\n               '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/freshbanana/Screen Shot 2018-06-12 at 10.00.00 PM.png',\n               '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/freshoranges/Screen Shot 2018-06-12 at 11.50.19 PM.png',\n               '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/rottenapples/Screen Shot 2018-06-07 at 2.15.20 PM.png',\n               '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/rottenbanana/Screen Shot 2018-06-12 at 8.47.14 PM.png',\n               '/kaggle/input/csc532-fruits-categorical-classification-2024/csc532_2024_train/train/rottenoranges/Screen Shot 2018-06-12 at 11.18.28 PM.png']\n\nfig, axes = plt.subplots(2, 3, figsize=(8, 6))\n\n# Display images from each class\nfor i, ax in enumerate(axes.flat):\n    img = mpimg.imread(image_paths[i])\n    ax.imshow(img)\n    ax.axis('off')  \n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:22.409858Z","iopub.execute_input":"2024-03-19T14:18:22.410148Z","iopub.status.idle":"2024-03-19T14:18:23.037062Z","shell.execute_reply.started":"2024-03-19T14:18:22.410124Z","shell.execute_reply":"2024-03-19T14:18:23.036160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## A brief intro to VGG16","metadata":{}},{"cell_type":"markdown","source":"## What Is VGG16?\nVGG16 is a deep convolutional neural network model used for image classification tasks. The network is composed of 16 layers of artificial neurons, which each work to process image information incrementally and improve the accuracy of its predictions.\n\nInstead of having a large number of hyper-parameters, VGG16 uses convolution layers with a 3x3 filter and a stride 1 that are in the same padding and maxpool layer of 2x2 filter of stride 2. It follows this arrangement of convolution and max pool layers consistently throughout the whole architecture. In the end it has two fully connected layers, followed by a softmax for output. \n\nIn VGG16, ‘VGG’ refers to the Visual Geometry Group of the University of Oxford, while the ‘16’ refers to the network’s 16 layers that have weights. This network is a pretty large network, and it has about 138 million parameters.","metadata":{}},{"cell_type":"markdown","source":"![](data:image/png;base64,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)","metadata":{}},{"cell_type":"markdown","source":"## How Is VGG16 Used?\n","metadata":{}},{"cell_type":"code","source":"# pre-trained VGG16 model\nbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(244, 244, 3))","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:23.038243Z","iopub.execute_input":"2024-03-19T14:18:23.038855Z","iopub.status.idle":"2024-03-19T14:18:24.946124Z","shell.execute_reply.started":"2024-03-19T14:18:23.038822Z","shell.execute_reply":"2024-03-19T14:18:24.945190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The code `base_model = VGG16(weights='imagenet', include_top=False, input_shape=(244, 244, 3))` initializes the VGG16 model with pre-trained ImageNet weights, while excluding the fully connected layers at the top of the network. Here's a breakdown of the parameters used:\n\n- **weights**: This parameter is set to 'imagenet', indicating that the model should be initialized with pre-trained weights from the ImageNet dataset. This allows the model to leverage the knowledge gained from training on a large dataset of diverse images.\n\n- **include_top**: By setting this parameter to False, the fully connected layers at the top of the network are excluded. This is useful when using the model for feature extraction or when adding custom fully connected layers for a specific classification task.\n\n- **input_shape**: This parameter specifies the shape of the input images that the model will expect. In this case, the input images are expected to have a shape of (244, 244, 3), representing a height of 244 pixels, a width of 244 pixels, and 3 color channels (RGB).\n\nBy using these parameters, the code initializes a VGG16 model with pre-trained weights, excluding the fully connected layers, and setting the input shape to (244, 244, 3).\n\nIf you have any further questions or need additional assistance, feel free to ask!","metadata":{}},{"cell_type":"code","source":"# Freeze all layers except for the last 5\nfor layer in base_model.layers[:-5]:\n    layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:24.947449Z","iopub.execute_input":"2024-03-19T14:18:24.947868Z","iopub.status.idle":"2024-03-19T14:18:24.954035Z","shell.execute_reply.started":"2024-03-19T14:18:24.947829Z","shell.execute_reply":"2024-03-19T14:18:24.952974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"When the code `for layer in base_model.layers[:-5]: layer.trainable = False` is executed, it iterates through all the layers of the VGG16 base model except for the last 5 layers and sets the `trainable` attribute of each of those layers to `False`. This effectively freezes the weights of all the layers except for the last 5 layers.\n\nFreezing the layers in this manner is a common technique in transfer learning and fine-tuning pre-trained models. By freezing the majority of the layers, you can retain the pre-trained weights and features learned from a large dataset (such as ImageNet), while only allowing the last few layers to be trained on your specific dataset. This can be beneficial when you have a relatively small dataset and want to prevent overfitting or when you want to speed up the training process.\n\nBy setting the `trainable` attribute to `False` for the majority of the layers, you reduce the number of parameters that need to be updated during training, which can lead to faster convergence and better generalization performance.","metadata":{}},{"cell_type":"code","source":"# Add new classification layers on top of the pre-trained layers\nnum_classes = 6\nx = Flatten()(base_model.output)\nx = Dense(256, activation='relu')(x)\nx = Dropout(0.5)(x) # Add a dropout layer with a rate of 0.5\npredictions = Dense(num_classes, activation='softmax')(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:24.955452Z","iopub.execute_input":"2024-03-19T14:18:24.955853Z","iopub.status.idle":"2024-03-19T14:18:24.990332Z","shell.execute_reply.started":"2024-03-19T14:18:24.955816Z","shell.execute_reply":"2024-03-19T14:18:24.989627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- **num_classes = 6**: This variable represents the number of classes in the classification task. In this case, there are 6 classes corresponding to the different types of fruits.\n\n- **x = Flatten()(base_model.output)**: The output of the pre-trained VGG16 model is flattened to convert the 3D output into a 1D feature vector. This prepares the features extracted by the VGG16 model for input to the new classification layers.\n\n- **x = Dense(256, activation='relu')(x)**: A fully connected (dense) layer with 256 units and ReLU activation function is added. This layer helps in learning non-linear relationships in the feature representation obtained from the VGG16 model.\n\n- **x = Dropout(0.5)(x)**: A dropout layer is added with a dropout rate of 0.5. Dropout is a regularization technique that helps prevent overfitting by randomly setting a fraction of input units to 0 at each update during training.\n\n- **predictions = Dense(num_classes, activation='softmax')(x)**: The final dense layer with a softmax activation function is added. This layer produces the output probabilities for each class, and the class with the highest probability is predicted as the output class.\n\nBy adding these layers, the code constructs a new classification head on top of the pre-trained VGG16 base model, allowing it to be fine-tuned for the specific fruit classification task.","metadata":{}},{"cell_type":"markdown","source":"### let's get a summary about the base model","metadata":{}},{"cell_type":"code","source":"base_model.summary()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:24.991309Z","iopub.execute_input":"2024-03-19T14:18:24.991549Z","iopub.status.idle":"2024-03-19T14:18:25.029624Z","shell.execute_reply.started":"2024-03-19T14:18:24.991528Z","shell.execute_reply":"2024-03-19T14:18:25.028784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create the final model\n","metadata":{}},{"cell_type":"code","source":"model = Model(inputs=base_model.input, outputs=predictions)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:25.030932Z","iopub.execute_input":"2024-03-19T14:18:25.031290Z","iopub.status.idle":"2024-03-19T14:18:25.041027Z","shell.execute_reply.started":"2024-03-19T14:18:25.031259Z","shell.execute_reply":"2024-03-19T14:18:25.040201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Compile the model with Adam optimizer","metadata":{}},{"cell_type":"code","source":"opt = Adam(learning_rate=0.0001)\nmodel.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:25.042315Z","iopub.execute_input":"2024-03-19T14:18:25.042600Z","iopub.status.idle":"2024-03-19T14:18:25.059634Z","shell.execute_reply.started":"2024-03-19T14:18:25.042577Z","shell.execute_reply":"2024-03-19T14:18:25.058913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- **opt = Adam(learning_rate=0.0001)**: This line initializes the Adam optimizer with a learning rate of 0.0001. The Adam optimizer is an extension to stochastic gradient descent and is known for its efficiency and effectiveness in training deep learning models.\n\n- **model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])**: This line compiles the model for training. It specifies the following:\n  - **loss='categorical_crossentropy'**: This parameter sets the loss function to categorical cross-entropy, which is commonly used for multi-class classification problems. It measures the difference between the predicted probability distribution and the actual probability distribution of the classes.\n  - **optimizer=opt**: This parameter specifies the optimizer to be used during training, which in this case is the Adam optimizer with a learning rate of 0.0001.\n  - **metrics=['accuracy']**: This parameter specifies the evaluation metric to be used during training. In this case, it uses accuracy as the metric to monitor the model's performance during training.\n\nBy compiling the model with these settings, the code prepares the model for training using the specified optimizer, loss function, and evaluation metric.","metadata":{}},{"cell_type":"markdown","source":"### Define the callbacks\n","metadata":{}},{"cell_type":"code","source":"reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, min_lr=0.00001)\nearly_stop = EarlyStopping(monitor='val_loss', patience=5)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:25.060581Z","iopub.execute_input":"2024-03-19T14:18:25.060876Z","iopub.status.idle":"2024-03-19T14:18:25.065656Z","shell.execute_reply.started":"2024-03-19T14:18:25.060852Z","shell.execute_reply":"2024-03-19T14:18:25.064693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNGR2N3AwNm1ycnc0ejQ3Ym9zOXR2ejQ0anN2emZmcmV0NnN5eTFrMSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/zCpYQh5YVhdI1rVYpE/giphy.gif)","metadata":{}},{"cell_type":"markdown","source":"The `ReduceLROnPlateau` and `EarlyStopping` are both callbacks in Keras that are used to monitor the training process and adjust the learning rate or stop training based on certain conditions. Here's a brief explanation of each:\n\n### ReduceLROnPlateau Callback:\nThe `ReduceLROnPlateau` callback is used to reduce the learning rate when a monitored metric has stopped improving. It is commonly used to prevent the training process from getting stuck in a local minimum by reducing the learning rate when the model's performance stagnates.\n\n- **Monitor**: The quantity to be monitored during training, typically a validation loss or a validation metric.\n- **Factor**: The factor by which the learning rate will be reduced. The new learning rate is calculated as `new_lr = lr * factor`.\n- **Patience**: The number of epochs with no improvement after which the learning rate will be reduced.\n- **Min_lr**: The lower bound for the learning rate. Once the learning rate reaches this value, it will not be reduced further.\n\n### EarlyStopping Callback:\nThe `EarlyStopping` callback is used to stop training when a monitored metric has stopped improving. It helps prevent overfitting by stopping training early if the model's performance on a validation set begins to degrade.\n\n- **Monitor**: The quantity to be monitored during training, such as a validation loss or a validation metric.\n- **Patience**: The number of epochs with no improvement after which training will be stopped.\n- **Min_delta**: The minimum change in the monitored quantity to qualify as an improvement.\n- **Mode**: Specifies whether the monitored quantity should be increasing or decreasing to be considered an improvement.\n\nThese callbacks are useful for improving the training process and preventing overfitting by dynamically adjusting the learning rate and stopping training when necessary.","metadata":{}},{"cell_type":"markdown","source":"### summary after building our model","metadata":{}},{"cell_type":"code","source":"model.summary()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:25.066668Z","iopub.execute_input":"2024-03-19T14:18:25.066991Z","iopub.status.idle":"2024-03-19T14:18:25.115473Z","shell.execute_reply.started":"2024-03-19T14:18:25.066954Z","shell.execute_reply":"2024-03-19T14:18:25.114702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train the model\n","metadata":{}},{"cell_type":"code","source":"num_epochs = 30\nhistory = model.fit(train_generator,\n                              epochs = num_epochs,\n                              steps_per_epoch = len(train_generator),\n                              validation_data = test_generator,\n                              validation_steps = len(test_generator),\n                              callbacks = [reduce_lr, early_stop]\n                   )","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:18:25.116620Z","iopub.execute_input":"2024-03-19T14:18:25.116952Z","iopub.status.idle":"2024-03-19T14:27:54.784580Z","shell.execute_reply.started":"2024-03-19T14:18:25.116923Z","shell.execute_reply":"2024-03-19T14:27:54.783782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save the model","metadata":{}},{"cell_type":"code","source":"model.save('VGG16.h5')","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:27:54.785929Z","iopub.execute_input":"2024-03-19T14:27:54.786223Z","iopub.status.idle":"2024-03-19T14:27:55.084544Z","shell.execute_reply.started":"2024-03-19T14:27:54.786198Z","shell.execute_reply":"2024-03-19T14:27:55.083538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### just one funny chart to determine loss","metadata":{}},{"cell_type":"code","source":"# Plot training & validation loss values\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-19T14:27:55.333552Z","iopub.execute_input":"2024-03-19T14:27:55.333827Z","iopub.status.idle":"2024-03-19T14:27:55.620595Z","shell.execute_reply.started":"2024-03-19T14:27:55.333802Z","shell.execute_reply":"2024-03-19T14:27:55.619670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Evaluate the model on the test generator\n","metadata":{}},{"cell_type":"code","source":"test_loss, test_acc = model.evaluate(test_generator, verbose=0)\nprint(\"Test accuracy:\", test_acc)\nprint(\"Test loss:\", test_loss)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:22:11.428727Z","iopub.execute_input":"2024-03-19T15:22:11.429440Z","iopub.status.idle":"2024-03-19T15:22:40.941284Z","shell.execute_reply.started":"2024-03-19T15:22:11.429410Z","shell.execute_reply":"2024-03-19T15:22:40.940269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## inceptionV3","metadata":{}},{"cell_type":"code","source":"# Set hyperparameters\nbatch_size = 32\nepochs = 30\nimg_size = (224, 224)\n# Get the number of classes\nnum_classes = len(train_generator.class_indices)\n# Create the base InceptionV3 model with imagenet weights and without the top layers\nbase_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(244, 244, 3))\n# Freeze the weights of the pre-trained layers in the base model\nfor layer in base_model.layers:\n    layer.trainable = False\n# Add new layers on top of the base model\nx = base_model.output\nx = GlobalAveragePooling2D()(x)\nx = Dense(1024, activation='relu')(x)\npredictions = Dense(num_classes, activation='softmax')(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:40:26.929649Z","iopub.execute_input":"2024-03-19T15:40:26.930051Z","iopub.status.idle":"2024-03-19T15:40:28.724947Z","shell.execute_reply.started":"2024-03-19T15:40:26.930019Z","shell.execute_reply":"2024-03-19T15:40:28.724168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the final model\nmodel2 = Model(inputs=base_model.input, outputs=predictions)\n# Compile the model with Adam optimizer\nopt = Adam(learning_rate=0.0001)\nmodel2.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])\n# Set callbacks\nearly_stop = EarlyStopping(monitor='val_loss', patience=5, verbose=1, restore_best_weights=True)\nreduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=2, verbose=1, min_lr=1e-7)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:40:31.036168Z","iopub.execute_input":"2024-03-19T15:40:31.036885Z","iopub.status.idle":"2024-03-19T15:40:31.088432Z","shell.execute_reply.started":"2024-03-19T15:40:31.036853Z","shell.execute_reply":"2024-03-19T15:40:31.087538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model with data generators and callbacks\nhistory = model2.fit(\n    train_generator,\n    steps_per_epoch=len(train_generator),  # Set to the number of batches in the training generator\n    epochs=epochs,\n    validation_data=test_generator,\n    validation_steps=len(test_generator),  # Set to the number of batches in the test generator\n    callbacks=[early_stop, reduce_lr]\n)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:40:33.117217Z","iopub.execute_input":"2024-03-19T15:40:33.118120Z","iopub.status.idle":"2024-03-19T15:48:06.155714Z","shell.execute_reply.started":"2024-03-19T15:40:33.118084Z","shell.execute_reply":"2024-03-19T15:48:06.154786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Evaluate the model on the test generator\n","metadata":{}},{"cell_type":"code","source":"test_loss, test_acc = model2.evaluate(test_generator, verbose=0)\nprint(\"Test accuracy:\", test_acc)\nprint(\"Test loss:\", test_loss)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T15:48:16.386360Z","iopub.execute_input":"2024-03-19T15:48:16.386743Z","iopub.status.idle":"2024-03-19T15:48:36.509566Z","shell.execute_reply.started":"2024-03-19T15:48:16.386702Z","shell.execute_reply":"2024-03-19T15:48:36.508519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## finally we finished it","metadata":{}},{"cell_type":"markdown","source":"![](https://media.giphy.com/media/26u4lOMA8JKSnL9Uk/giphy.gif?cid=790b7611aavemjmysh22jc14jbpgtn31xylyb8uvmlm2qwag&ep=v1_gifs_search&rid=giphy.gif&ct=g)","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}