{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"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":"none","dataSources":[{"sourceId":70497,"databundleVersionId":7713244,"sourceType":"competition"},{"sourceId":8175825,"sourceType":"datasetVersion","datasetId":4839356}],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install rembg","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:41:33.151Z","iopub.execute_input":"2024-05-07T06:41:33.1513Z","iopub.status.idle":"2024-05-07T06:41:48.744339Z","shell.execute_reply.started":"2024-05-07T06:41:33.151273Z","shell.execute_reply":"2024-05-07T06:41:48.743204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom pathlib import Path\nimport numpy as np\nimport pandas as pd\nfrom keras.callbacks import LearningRateScheduler\nimport matplotlib.pyplot as plt\nfrom keras import backend as K \nfrom zipfile import ZipFile\nfrom os import listdir, walk\nfrom os.path import isfile, join\nfrom tensorflow.keras.layers import Dropout\n\nimport tensorflow as tf\nfrom tensorflow.keras import Input, Model\nfrom tensorflow.keras.applications import ResNet152V2, Xception, InceptionV3, MobileNetV2\nfrom tensorflow.keras.applications.imagenet_utils import preprocess_input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense\nfrom tensorflow.keras.optimizers import Adam, SGD\nfrom tensorflow.keras import layers\nfrom sklearn.utils.class_weight import compute_class_weight\nimport os \nK.clear_session()\n# Set seeds for reproducibility\nnp.random.seed(42)\ntf.random.set_seed(42)","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:41:48.746356Z","iopub.execute_input":"2024-05-07T06:41:48.746697Z","iopub.status.idle":"2024-05-07T06:42:01.01905Z","shell.execute_reply.started":"2024-05-07T06:41:48.746663Z","shell.execute_reply":"2024-05-07T06:42:01.018242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 224\n\ndatagen = ImageDataGenerator(\n        rescale=1/255.,\n        horizontal_flip=True,\n        vertical_flip=True,\n        samplewise_center=True,\n        zoom_range=0.1,\n        width_shift_range=0.1,\n        height_shift_range=0.1,\n        rotation_range=10,\n        )","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:01.020095Z","iopub.execute_input":"2024-05-07T06:42:01.020577Z","iopub.status.idle":"2024-05-07T06:42:01.025664Z","shell.execute_reply.started":"2024-05-07T06:42:01.020552Z","shell.execute_reply":"2024-05-07T06:42:01.024659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_it = datagen.flow_from_directory('/kaggle/input/fresh-and-rotten-combined/oranges/train', \n                                       target_size=(IMG_SIZE, IMG_SIZE), \n                                       color_mode='rgb', \n                                       class_mode=\"categorical\",\n                                       shuffle=True,\n                                       seed=42)","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:01.028389Z","iopub.execute_input":"2024-05-07T06:42:01.028717Z","iopub.status.idle":"2024-05-07T06:42:02.68308Z","shell.execute_reply.started":"2024-05-07T06:42:01.028688Z","shell.execute_reply":"2024-05-07T06:42:02.682283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_counts = train_it.classes\nunique_classes = np.unique(class_counts)\nclass_frequency = {class_name: np.sum(class_counts == class_idx) for class_name, class_idx in train_it.class_indices.items()}\n\nprint(\"Class frequency:\")\nfor class_name, count in class_frequency.items():\n    print(f\"{class_name}: {count} items\")","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:02.684489Z","iopub.execute_input":"2024-05-07T06:42:02.685054Z","iopub.status.idle":"2024-05-07T06:42:02.694058Z","shell.execute_reply.started":"2024-05-07T06:42:02.685018Z","shell.execute_reply":"2024-05-07T06:42:02.693145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_it = datagen.flow_from_directory('/kaggle/input/fresh-and-rotten-combined/oranges/test', \n                                       target_size=(IMG_SIZE, IMG_SIZE), \n                                       color_mode='rgb', \n                                       class_mode=\"categorical\",\n                                       shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:02.695603Z","iopub.execute_input":"2024-05-07T06:42:02.695943Z","iopub.status.idle":"2024-05-07T06:42:02.897586Z","shell.execute_reply.started":"2024-05-07T06:42:02.695912Z","shell.execute_reply":"2024-05-07T06:42:02.896598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_counts = valid_it.classes\nunique_classes = np.unique(class_counts)\nclass_frequency = {class_name: np.sum(class_counts == class_idx) for class_name, class_idx in train_it.class_indices.items()}\n\nprint(\"Class frequency:\")\nfor class_name, count in class_frequency.items():\n    print(f\"{class_name}: {count} items\")","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:02.898665Z","iopub.execute_input":"2024-05-07T06:42:02.898968Z","iopub.status.idle":"2024-05-07T06:42:02.905725Z","shell.execute_reply.started":"2024-05-07T06:42:02.898943Z","shell.execute_reply":"2024-05-07T06:42:02.904551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get a batch of images and labels from the train and test datasets\ntrain_images, train_labels = next(train_it)\ntest_images, test_labels = next(valid_it)","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:02.907128Z","iopub.execute_input":"2024-05-07T06:42:02.907427Z","iopub.status.idle":"2024-05-07T06:42:04.085396Z","shell.execute_reply.started":"2024-05-07T06:42:02.907401Z","shell.execute_reply":"2024-05-07T06:42:04.084303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = MobileNetV2(\n    weights='imagenet',\n    input_shape=(IMG_SIZE, IMG_SIZE, 3),\n    include_top=False)\n\nbase_model.trainable = False","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:04.086673Z","iopub.execute_input":"2024-05-07T06:42:04.087016Z","iopub.status.idle":"2024-05-07T06:42:06.711876Z","shell.execute_reply.started":"2024-05-07T06:42:04.086987Z","shell.execute_reply":"2024-05-07T06:42:06.711083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the input shape for the model, assuming IMG_SIZE x IMG_SIZE images with 3 color channels (RGB)\ninputs = Input(shape=(IMG_SIZE, IMG_SIZE, 3))\n\n# Connect the input to a pre-trained base model, with training set to False to freeze the base model's weights\nx = base_model(inputs, training=False)\n\n# Apply Global Average Pooling to reduce spatial dimensions and extract important features\nx = GlobalAveragePooling2D()(x)\n\n# Connect the output of the Global Average Pooling layer to a Dense layer with softmax activation\n# The number of units in the Dense layer is set to the number of classes in the training dataset\noutputs = Dense(len(train_it.class_indices), activation='softmax')(x)\n\nmodel = Model(inputs, outputs)","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:06.715166Z","iopub.execute_input":"2024-05-07T06:42:06.715461Z","iopub.status.idle":"2024-05-07T06:42:06.739617Z","shell.execute_reply.started":"2024-05-07T06:42:06.715437Z","shell.execute_reply":"2024-05-07T06:42:06.73889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 10\nopt = tf.keras.optimizers.SGD(learning_rate=0.0001, decay=0.01 / 40, momentum=0.9, nesterov=True)\nmodel.compile(loss='categorical_crossentropy', optimizer=opt, metrics=[\"accuracy\"])","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:06.740809Z","iopub.execute_input":"2024-05-07T06:42:06.741211Z","iopub.status.idle":"2024-05-07T06:42:06.760361Z","shell.execute_reply.started":"2024-05-07T06:42:06.741176Z","shell.execute_reply":"2024-05-07T06:42:06.759433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    train_it,\n    epochs=epochs,\n    validation_data=valid_it,\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-07T06:42:06.761441Z","iopub.execute_input":"2024-05-07T06:42:06.761711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from keras.models import Sequential\n# from keras.layers import BatchNormalization, Conv2D, MaxPooling2D, Flatten, Dropout, Dense, Activation\n# from keras import backend as K\n# from keras.regularizers import l2\n\n# K.clear_session()\n# class LeNet:\n#     @staticmethod\n#     def build(width, height, depth, classes):\n#     # initialize the model\n#         model = Sequential()\n#         inputShape = (height, width, depth)\n        \n#         # if we are using \"channels first\", update the input shape\n#         if K.image_data_format() == \"channels_first\":\n#             inputShape = (depth, height, width)\n        \n#         # first set of CONV => RELU => POOL layers\n#         model.add(Conv2D(20, (5, 5), padding=\"same\",\n#         input_shape=inputShape))\n#         model.add(Activation(\"relu\"))\n#         model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))\n#         model.add(Dropout(0.25))\n        \n#         # second set of CONV => RELU => POOL layers\n#         model.add(Conv2D(50, (5, 5), padding=\"same\"))\n#         model.add(Activation(\"relu\"))\n#         model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))\n#         model.add(Dropout(0.25))\n        \n#         # first (and only) set of FC => RELU layers\n#         model.add(Flatten())\n#         model.add(Dense(500))\n#         model.add(Activation(\"relu\"))\n#         model.add(Dropout(0.25))\n        \n#         # softmax classifier\n#         model.add(Dense(classes))\n#         model.add(Activation(\"softmax\"))\n        \n#         # return the constructed network architecture\n#         return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = LeNet.build(width=224, height=224, depth=3, classes=2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# epochs = 30\n# opt = tf.keras.optimizers.legacy.SGD(lr=0.0001, decay=0.01 / 40, momentum=0.9, nesterov=True)\n\n# model.compile(loss = 'categorical_crossentropy' , optimizer=opt, metrics = [\"accuracy\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# history = model.fit(\n#     train_it,\n#     epochs=epochs,\n#     validation_data=valid_it,\n# )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save_weights('/kaggle/working/oranges_weights.weights.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline\n\n# plot the training loss and accuracy\nplt.style.use(\"ggplot\")\nplt.plot(np.arange(0, 10), history.history[\"accuracy\"], label=\"train_acc\")\nplt.plot(np.arange(0, 10), history.history[\"val_accuracy\"], label=\"val_acc\")\nplt.title(\"Training Accuracy on Fruits\")\nplt.xlabel(\"Epoch #\")\nplt.ylabel(\"Accuracy\")\nplt.legend()\nplt.show()\nplt.savefig('accuracy_graph_leNet')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline\n\n# plot the training loss and accuracy\nplt.style.use(\"ggplot\")\nplt.plot(np.arange(0, 10), history.history[\"loss\"], label=\"train_loss\")\nplt.plot(np.arange(0, 10), history.history[\"val_loss\"], label=\"val_loss\")\nplt.title(\"Training Loss on Fruits\")\nplt.xlabel(\"Epoch #\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.show()\nplt.savefig('loss_graph_leNet')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nfrom sklearn.metrics import confusion_matrix\n\n# Make predictions on the validation data\npredictions = model.predict(valid_it)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get true labels from the validation iterator\ntrue_labels = valid_it.classes\n\n# Convert predicted probabilities to class indices\npredicted_labels = np.argmax(predictions, axis=1)\n\n# Compute confusion matrix\nconf_matrix = confusion_matrix(true_labels, predicted_labels)\n\nprint(\"Confusion Matrix:\")\nprint(conf_matrix)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare for submission\nfiles = [f for f in listdir('/kaggle/input/fresh-and-rotten-combined/oranges/test/freshoranges') if isfile(join('/kaggle/input/fresh-and-rotten-combined/oranges/test/freshoranges', f))]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport matplotlib.pyplot as plt\n\ndef reshape_image(image, new_width=900, new_height=900):\n    # Open the image\n    \n    # Get the dimensions of the original image\n    original_width, original_height = image.size\n    \n    # Calculate the coordinates for cropping\n    left = (original_width - new_width) / 2\n    top = (original_height - new_height) / 2\n    right = (original_width + new_width) / 2\n    bottom = (original_height + new_height) / 2\n    \n    # Crop the image\n    cropped_image = image.crop((left, top, right, bottom))\n    \n    return cropped_image\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from rembg import remove\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport numpy as np\n\nresult_dict = {\n    'ID': [],\n    'Code': [],\n}\n\nfor file in files:\n    img_path = f'/kaggle/input/fresh-and-rotten-combined/oranges/test/freshoranges/{file}'\n    \n    # Open image using PIL\n    image = Image.open(img_path)\n    removed_image = remove(image)  # Assuming this function doesn't change image size\n    \n    # Create a white canvas with the same size as the removed image\n    white_canvas = Image.new('RGB', removed_image.size, (255, 255, 255))\n    \n    # Paste the removed image onto the white canvas\n    white_canvas.paste(removed_image, (0, 0), removed_image)\n    \n    # Check image mode and convert to RGB if necessary\n    if white_canvas.mode != 'RGB':\n        white_canvas = white_canvas.convert('RGB')\n    \n    # Resize image\n    white_canvas = white_canvas.resize((224, 224))\n    \n    # Convert image to numpy array\n    image_array = np.array(white_canvas)\n    \n    # Normalize pixel values to range [0, 1]\n    image_array = image_array / 255.0\n    \n    # Reshape array to match model input shape\n    image_array = image_array.reshape(1, 224, 224, 3)\n    \n    # Perform prediction\n    pred = np.argmax(model.predict(image_array)) + 1\n    \n    # Append results to result_dict\n    result_dict['ID'].append(file)\n    result_dict['Code'].append(pred)\n    if pred == 1:\n        pred_label = 'fresh oranges'\n    elif pred == 2:\n        pred_label = 'rotten oranges'\n    \n    # Display image with prediction\n    plt.imshow(white_canvas)\n    plt.title(f'Prediction: {pred_label}')\n    plt.axis('off')\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}