{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":13836,"databundleVersionId":1718836,"sourceType":"competition"}],"dockerImageVersionId":31012,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"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":{"iopub.status.busy":"2025-04-10T06:03:13.175565Z","iopub.execute_input":"2025-04-10T06:03:13.175817Z","iopub.status.idle":"2025-04-10T06:03:22.069298Z","shell.execute_reply.started":"2025-04-10T06:03:13.175801Z","shell.execute_reply":"2025-04-10T06:03:22.068411Z"},"_kg_hide-input":true,"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:03:22.070387Z","iopub.execute_input":"2025-04-10T06:03:22.070786Z","iopub.status.idle":"2025-04-10T06:03:25.431042Z","shell.execute_reply.started":"2025-04-10T06:03:22.070767Z","shell.execute_reply":"2025-04-10T06:03:25.430441Z"},"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load the training CSV\ndf = pd.read_csv('/kaggle/input/cassava-leaf-disease-classification/train.csv')\nlabel_map = {\n    0: \"Cassava Bacterial Blight (CBB)\",\n    1: \"Cassava Brown Streak Disease (CBSD)\",\n    2: \"Cassava Green Mottle (CGM)\",\n    3: \"Cassava Mosaic Disease (CMD)\",\n    4: \"Healthy\"\n}\ndf['label_name'] = df['label'].map(label_map)\ndf['image_path'] = '/kaggle/input/cassava-leaf-disease-classification/train_images/' + df['image_id']\ndf.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:03:25.431756Z","iopub.execute_input":"2025-04-10T06:03:25.432192Z","iopub.status.idle":"2025-04-10T06:03:25.463726Z","shell.execute_reply.started":"2025-04-10T06:03:25.432173Z","shell.execute_reply":"2025-04-10T06:03:25.463163Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom tensorflow.keras.datasets import cifar10\nimport cv2\nimport pandas as pd\nimport os\nimport numpy as np\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, Flatten, Input, MaxPooling2D,Dropout,BatchNormalization,Reshape\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nfrom sklearn.model_selection import train_test_split\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, Flatten, Input, MaxPooling2D,Dropout,BatchNormalization,Reshape\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nfrom sklearn.metrics import accuracy_score\nimport math\nfrom tensorflow.keras.models import load_model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:03:25.464333Z","iopub.execute_input":"2025-04-10T06:03:25.464518Z","iopub.status.idle":"2025-04-10T06:03:25.525468Z","shell.execute_reply.started":"2025-04-10T06:03:25.464503Z","shell.execute_reply":"2025-04-10T06:03:25.524753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(25, 8))\nax = sns.countplot(\n    x=df[\"label_name\"],\n    palette=\"viridis\",\n    order=df['label_name'].value_counts().index\n)\nax.set_title(\"Distribution of Cassava Leaf Disease Labels\", fontsize=22)\nax.set_xlabel(\"Disease Class\", fontsize=18)\nax.set_ylabel(\"Image Count\", fontsize=18)\nax.tick_params(labelsize=14)\n\n# Add value labels on top of bars\nfor p in ax.containers:\n    ax.bar_label(p, fontsize=14, color='black', padding=5)\nplt.xticks(rotation=15)\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:03:25.526515Z","iopub.execute_input":"2025-04-10T06:03:25.526773Z","iopub.status.idle":"2025-04-10T06:03:25.816659Z","shell.execute_reply.started":"2025-04-10T06:03:25.526751Z","shell.execute_reply":"2025-04-10T06:03:25.816025Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\nfrom tqdm import tqdm  # Optional: shows a progress bar\n\nx = []\nfor image_path in tqdm(df['image_path']):  # Using the precomputed full path\n    img = cv2.imread(image_path)\n    if img is not None:\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = cv2.resize(img, (32, 32))\n        img = img / 255.0\n        x.append(img)\n    else:\n        print(f\"Warning: Could not read image at path: {image_path}\")\n\nx = np.array(x)\nprint(\"Shape of image data:\", x.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:03:25.819176Z","iopub.execute_input":"2025-04-10T06:03:25.819368Z","iopub.status.idle":"2025-04-10T06:05:03.877335Z","shell.execute_reply.started":"2025-04-10T06:03:25.819353Z","shell.execute_reply":"2025-04-10T06:05:03.876530Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y=df[[\"label\"]]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:05:03.878073Z","iopub.execute_input":"2025-04-10T06:05:03.878293Z","iopub.status.idle":"2025-04-10T06:05:03.882719Z","shell.execute_reply.started":"2025-04-10T06:05:03.878276Z","shell.execute_reply":"2025-04-10T06:05:03.882158Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x.shape,y.shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:05:03.883456Z","iopub.execute_input":"2025-04-10T06:05:03.883723Z","iopub.status.idle":"2025-04-10T06:05:03.903501Z","shell.execute_reply.started":"2025-04-10T06:05:03.883694Z","shell.execute_reply":"2025-04-10T06:05:03.902950Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom collections import Counter\nfrom sklearn.neighbors import NearestNeighbors\n\nclass ManualSMOTE:\n    def __init__(self, sampling_strategy='auto', random_state=None, k_neighbors=5):\n        self.sampling_strategy = sampling_strategy\n        self.random_state = random_state\n        self.k_neighbors = k_neighbors\n\n    def fit_resample(self, X, y):\n        if self.random_state is not None:\n            np.random.seed(self.random_state)\n\n        X = np.array(X)\n        y = np.array(y)\n\n        class_counts = Counter(y)\n        max_count = max(class_counts.values())\n\n        new_X = []\n        new_y = []\n\n        for cls in class_counts:\n            X_cls = X[y == cls]\n            n_samples = len(X_cls)\n            n_generate = max_count - n_samples\n\n            if n_generate <= 0:\n                continue\n\n            nn = NearestNeighbors(n_neighbors=min(self.k_neighbors + 1, n_samples))\n            nn.fit(X_cls)\n            neighbors = nn.kneighbors(X_cls, return_distance=False)\n\n            for _ in range(n_generate):\n                i = np.random.randint(0, n_samples)\n                neighbor_idx = np.random.choice(neighbors[i][1:])  # skip self\n                diff = X_cls[neighbor_idx] - X_cls[i]\n                gap = np.random.rand()\n                new_sample = X_cls[i] + gap * diff\n                new_X.append(new_sample)\n                new_y.append(cls)\n\n        X_resampled = np.vstack([X, np.array(new_X)])\n        y_resampled = np.hstack([y, np.array(new_y)])\n\n        return X_resampled, y_resampled\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:05:07.213959Z","iopub.execute_input":"2025-04-10T06:05:07.214247Z","iopub.status.idle":"2025-04-10T06:05:11.617797Z","shell.execute_reply.started":"2025-04-10T06:05:07.214224Z","shell.execute_reply":"2025-04-10T06:05:11.617007Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_flat = x.reshape(x.shape[0], -1)\ny_flat = y['label'].values\n\nsmote = ManualSMOTE(random_state=42)\nx_resampled, y_resampled = smote.fit_resample(x_flat, y_flat)\nx_resampled_images = x_resampled.reshape(-1, 32, 32, 3)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_resampled_images.shape,y_resampled.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:05:34.466146Z","iopub.execute_input":"2025-04-10T06:05:34.466416Z","iopub.status.idle":"2025-04-10T06:05:34.472058Z","shell.execute_reply.started":"2025-04-10T06:05:34.466400Z","shell.execute_reply":"2025-04-10T06:05:34.471334Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(25,8))\ny_resampled_series = pd.Series(y_resampled)\nax=sns.countplot(x=y_resampled_series,palette=\"viridis\")\nfor p in ax.containers:\n    ax.bar_label(p, fontsize=12, color='black', padding=5);","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:05:43.740700Z","iopub.execute_input":"2025-04-10T06:05:43.740985Z","iopub.status.idle":"2025-04-10T06:05:43.935757Z","shell.execute_reply.started":"2025-04-10T06:05:43.740941Z","shell.execute_reply":"2025-04-10T06:05:43.935032Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Split into 80% train and 20% validation\nx_train, x_val, y_train, y_val = train_test_split(\n    x_resampled_images, y_resampled, test_size=0.2, random_state=42, stratify=y_resampled\n)\n\nprint(\"Train samples:\", len(x_train))\nprint(\"Validation samples:\", len(x_val))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:06:23.453063Z","iopub.execute_input":"2025-04-10T06:06:23.453610Z","iopub.status.idle":"2025-04-10T06:06:23.935939Z","shell.execute_reply.started":"2025-04-10T06:06:23.453586Z","shell.execute_reply":"2025-04-10T06:06:23.935295Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model=Sequential()\nmodel.add(Input(shape=(32,32,3)))\nmodel.add(Conv2D(64,kernel_size=(3,3),activation='relu',padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(128,kernel_size=(3,3),activation='relu',padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(256,kernel_size=(3,3),activation='relu',padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(512,kernel_size=(3,3),activation='relu',padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(1024,kernel_size=(3,3),activation='relu',padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\n\n\n\nmodel.add(Flatten())\n\nmodel.add(Dense(1024,activation='relu'))\nmodel.add(Dense(512,activation='relu'))\nmodel.add(Dense(256,activation='relu'))\nmodel.add(Dense(128,activation='relu'))\n\nmodel.add(Dropout(0.5))\nmodel.add(Dense(5,activation='softmax'))\n\nmodel.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:06:42.467734Z","iopub.execute_input":"2025-04-10T06:06:42.468478Z","iopub.status.idle":"2025-04-10T06:06:46.135354Z","shell.execute_reply.started":"2025-04-10T06:06:42.468446Z","shell.execute_reply":"2025-04-10T06:06:46.134797Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\n\n# Callbacks\ncheckpoint = ModelCheckpoint(\n    \"best_model.keras\",           # ✅ Updated extension\n    monitor='val_loss',\n    save_best_only=True,\n    mode='min',\n    verbose=1\n)\n\nreduce_lr = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.2,\n    patience=2,\n    min_lr=1e-5,\n    verbose=1\n)\n\nearly_stopping = EarlyStopping(\n    monitor='val_loss',\n    patience=3,\n    restore_best_weights=True,\n    verbose=1\n)\n\n# Fit the model\nhistory = model.fit(\n    x_train,\n    y_train,\n    validation_data=(x_val, y_val),\n    epochs=35,\n    batch_size=36,\n    verbose=1,\n    callbacks=[checkpoint, reduce_lr, early_stopping]\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:08:01.640533Z","iopub.execute_input":"2025-04-10T06:08:01.641033Z","iopub.status.idle":"2025-04-10T06:13:37.673590Z","shell.execute_reply.started":"2025-04-10T06:08:01.641007Z","shell.execute_reply":"2025-04-10T06:13:37.673002Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport os\nimport numpy as np\nimport pandas as pd\n\n# Load sample_submission.csv to get test image IDs\nsample_submission = pd.read_csv(\"/kaggle/input/cassava-leaf-disease-classification/sample_submission.csv\")\n\n# Path to test images\ntest_dir = \"/kaggle/input/cassava-leaf-disease-classification/test_images/\"\n\n# Preprocess all test images\ntest_images = []\ntest_image_ids = []\n\nfor image_id in sample_submission['image_id']:\n    image_path = os.path.join(test_dir, image_id)\n    img = cv2.imread(image_path)\n    if img is not None:\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = cv2.resize(img, (32, 32))\n        img = img / 255.0\n        test_images.append(img)\n        test_image_ids.append(image_id)\n    else:\n        print(f\"Could not load image: {image_id}\")\n\nx_test_final = np.array(test_images)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:15:04.838825Z","iopub.execute_input":"2025-04-10T06:15:04.839119Z","iopub.status.idle":"2025-04-10T06:15:04.852653Z","shell.execute_reply.started":"2025-04-10T06:15:04.839097Z","shell.execute_reply":"2025-04-10T06:15:04.851782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport pandas as pd\n\ntest_dir = \"/kaggle/input/cassava-leaf-disease-classification/test_images/\"\ntest_df = pd.read_csv(\"/kaggle/input/cassava-leaf-disease-classification/sample_submission.csv\")\n\nx_kaggle_test = []\n\nfor image_id in test_df['image_id']:\n    path = os.path.join(test_dir, image_id)\n    img = cv2.imread(path)\n    if img is not None:\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = cv2.resize(img, (32, 32))\n        img = img / 255.0\n        x_kaggle_test.append(img)\n    else:\n        print(f\"Could not read image: {image_id}\")\n\nx_kaggle_test = np.array(x_kaggle_test)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:18:46.288953Z","iopub.execute_input":"2025-04-10T06:18:46.289650Z","iopub.status.idle":"2025-04-10T06:18:46.305492Z","shell.execute_reply.started":"2025-04-10T06:18:46.289603Z","shell.execute_reply":"2025-04-10T06:18:46.304671Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_kaggle_pred_probs = model.predict(x_kaggle_test)\ny_kaggle_pred = np.argmax(y_kaggle_pred_probs, axis=1)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:18:49.715309Z","iopub.execute_input":"2025-04-10T06:18:49.715831Z","iopub.status.idle":"2025-04-10T06:18:49.779608Z","shell.execute_reply.started":"2025-04-10T06:18:49.715807Z","shell.execute_reply":"2025-04-10T06:18:49.779107Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = test_df.copy()\nsubmission['label'] = y_kaggle_pred\nsubmission.to_csv('submission.csv', index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-10T06:19:11.444189Z","iopub.execute_input":"2025-04-10T06:19:11.444678Z","iopub.status.idle":"2025-04-10T06:19:11.455523Z","shell.execute_reply.started":"2025-04-10T06:19:11.444657Z","shell.execute_reply":"2025-04-10T06:19:11.454801Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}