{"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":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# LEAF DISEASE\n\n## INTRODUCTION\n\nCassava is a crucial food crop vulnerable to diseases that threaten global food security. This project develops a deep learning system to automatically classify cassava leaf diseases from images, enabling early detection and prevention. The model analyzes leaves across five categories including four common diseases and healthy specimens.\n\n\n\n## AIM\n\nThe goal is to create an accurate convolutional neural network that distinguishes between different cassava leaf conditions. The system will be trained and evaluated to reliably identify diseases while optimizing performance through advanced machine learning techniques.\n\n","metadata":{}},{"cell_type":"markdown","source":"### IMPORTS","metadata":{}},{"cell_type":"code","source":"#pip install opencv-python","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:09.913004Z","iopub.execute_input":"2025-04-21T19:58:09.913227Z","iopub.status.idle":"2025-04-21T19:58:09.916518Z","shell.execute_reply.started":"2025-04-21T19:58:09.913211Z","shell.execute_reply":"2025-04-21T19:58:09.915651Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# !pip install -U scikit-learn==1.3.2 imbalanced-learn==0.11.0 --quiet","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:09.917183Z","iopub.execute_input":"2025-04-21T19:58:09.917365Z","iopub.status.idle":"2025-04-21T19:58:09.930302Z","shell.execute_reply.started":"2025-04-21T19:58:09.917350Z","shell.execute_reply":"2025-04-21T19:58:09.929786Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# !pip install --upgrade tensorflow","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:09.932061Z","iopub.execute_input":"2025-04-21T19:58:09.932302Z","iopub.status.idle":"2025-04-21T19:58:09.945057Z","shell.execute_reply.started":"2025-04-21T19:58:09.932285Z","shell.execute_reply":"2025-04-21T19:58:09.944472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport random\nimport warnings\n\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport re\nfrom imblearn.over_sampling import SMOTE\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score,confusion_matrix, ConfusionMatrixDisplay\n\nfrom keras.models import Sequential, Model, load_model\nfrom keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Input, BatchNormalization, Reshape, GlobalAveragePooling2D,Activation\nfrom keras.regularizers import l2\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions\n\n\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:20:39.134490Z","iopub.execute_input":"2025-04-21T20:20:39.134805Z","iopub.status.idle":"2025-04-21T20:20:39.140407Z","shell.execute_reply.started":"2025-04-21T20:20:39.134780Z","shell.execute_reply":"2025-04-21T20:20:39.139810Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### READING DATA","metadata":{}},{"cell_type":"code","source":"df=pd.read_csv('/kaggle/input/cassava-leaf-disease-classification/train.csv')\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:23.224067Z","iopub.execute_input":"2025-04-21T19:58:23.224595Z","iopub.status.idle":"2025-04-21T19:58:23.267087Z","shell.execute_reply.started":"2025-04-21T19:58:23.224560Z","shell.execute_reply":"2025-04-21T19:58:23.266504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_path = \"/kaggle/input/cassava-leaf-disease-classification/train_images/\"\ndf['image_id'] = df['image_id'].apply(lambda x: img_path + x)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:23.267955Z","iopub.execute_input":"2025-04-21T19:58:23.268193Z","iopub.status.idle":"2025-04-21T19:58:23.279496Z","shell.execute_reply.started":"2025-04-21T19:58:23.268175Z","shell.execute_reply":"2025-04-21T19:58:23.278796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.rename(columns={'image_id': 'img'}, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:23.281136Z","iopub.execute_input":"2025-04-21T19:58:23.281326Z","iopub.status.idle":"2025-04-21T19:58:23.295770Z","shell.execute_reply.started":"2025-04-21T19:58:23.281310Z","shell.execute_reply":"2025-04-21T19:58:23.295055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.img[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:23.296373Z","iopub.execute_input":"2025-04-21T19:58:23.296633Z","iopub.status.idle":"2025-04-21T19:58:23.310024Z","shell.execute_reply.started":"2025-04-21T19:58:23.296606Z","shell.execute_reply":"2025-04-21T19:58:23.309495Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.label.value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:23.310719Z","iopub.execute_input":"2025-04-21T19:58:23.310958Z","iopub.status.idle":"2025-04-21T19:58:23.331883Z","shell.execute_reply.started":"2025-04-21T19:58:23.310934Z","shell.execute_reply":"2025-04-21T19:58:23.331171Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### EDA","metadata":{}},{"cell_type":"code","source":"selected_images = df.groupby('label', as_index=False).apply(lambda x: x.sample(n=3, random_state=1)).reset_index(drop=True)\n\nsns.set(style='whitegrid')\nfig, axes = plt.subplots(5, 3, figsize=(15, 8))\n\naxes = axes.flatten()\n\nfor ax, (img_path, label) in zip(axes, zip(selected_images['img'], selected_images['label'])):\n    img = Image.open(img_path)\n    ax.imshow(img)\n    ax.axis('off')\n    ax.set_title(label, fontsize=14)\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:23.332657Z","iopub.execute_input":"2025-04-21T19:58:23.332881Z","iopub.status.idle":"2025-04-21T19:58:25.624758Z","shell.execute_reply.started":"2025-04-21T19:58:23.332858Z","shell.execute_reply":"2025-04-21T19:58:25.623770Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8, 5))\nsns.countplot(x='label', data=df)\n\n# Add titles and labels\nplt.title('Distribution of Labels')\nplt.xlabel('Label')\nplt.ylabel('Count')\n\n# Display the plot\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:25.625640Z","iopub.execute_input":"2025-04-21T19:58:25.625867Z","iopub.status.idle":"2025-04-21T19:58:25.805092Z","shell.execute_reply.started":"2025-04-21T19:58:25.625848Z","shell.execute_reply":"2025-04-21T19:58:25.804213Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### PREPARING TEST DATA","metadata":{}},{"cell_type":"code","source":"img_width, img_height = 64, 64","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:25.806042Z","iopub.execute_input":"2025-04-21T19:58:25.806450Z","iopub.status.idle":"2025-04-21T19:58:25.810133Z","shell.execute_reply.started":"2025-04-21T19:58:25.806403Z","shell.execute_reply":"2025-04-21T19:58:25.809485Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x = []\ny = []\n\nfor img_path, label in zip(df['img'], df['label']):\n    img = cv2.imread(img_path)\n    if img is None:\n        continue\n\n    img = cv2.resize(img, (img_width, img_height))\n    img = img / 255.0\n    x.append(img)\n    y.append(label)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T19:58:25.810799Z","iopub.execute_input":"2025-04-21T19:58:25.811090Z","iopub.status.idle":"2025-04-21T20:02:10.735070Z","shell.execute_reply.started":"2025-04-21T19:58:25.811071Z","shell.execute_reply":"2025-04-21T20:02:10.734300Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x = np.array(x)\ny=df[[\"label\"]]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:02:10.735962Z","iopub.execute_input":"2025-04-21T20:02:10.736168Z","iopub.status.idle":"2025-04-21T20:02:11.474188Z","shell.execute_reply.started":"2025-04-21T20:02:10.736151Z","shell.execute_reply":"2025-04-21T20:02:11.473307Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### DATA AUGMENTATION","metadata":{}},{"cell_type":"code","source":"x_reshaped = x.reshape(x.shape[0], -1)  \ny_reshaped = y['label'].values \n\nsmote = SMOTE(random_state=42)\n\nx_resampled, y_resampled = smote.fit_resample(x_reshaped, y_reshaped)\nx_resampled_images = x_resampled.reshape(-1, img_width, img_height, 3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:02:18.635771Z","iopub.execute_input":"2025-04-21T20:02:18.636377Z","iopub.status.idle":"2025-04-21T20:02:35.963758Z","shell.execute_reply.started":"2025-04-21T20:02:18.636354Z","shell.execute_reply":"2025-04-21T20:02:35.963131Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(20,5))\ny_resampled_series = pd.Series(y_resampled)\nax=sns.countplot(x=y_resampled_series)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:02:35.965128Z","iopub.execute_input":"2025-04-21T20:02:35.965917Z","iopub.status.idle":"2025-04-21T20:02:36.146030Z","shell.execute_reply.started":"2025-04-21T20:02:35.965893Z","shell.execute_reply":"2025-04-21T20:02:36.145252Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train,x_test,y_train,y_test=train_test_split(x_resampled_images,y_resampled,test_size=.2,random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:02:36.146885Z","iopub.execute_input":"2025-04-21T20:02:36.147157Z","iopub.status.idle":"2025-04-21T20:02:37.979918Z","shell.execute_reply.started":"2025-04-21T20:02:36.147138Z","shell.execute_reply":"2025-04-21T20:02:37.979287Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## CNN","metadata":{}},{"cell_type":"code","source":"model = Sequential()\nmodel.add(Input(shape=(img_width, img_height, 3)))\nmodel.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Conv2D(256, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dense(len(df.label.unique()),activation='softmax'))\n\nmodel.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:02:48.297367Z","iopub.execute_input":"2025-04-21T20:02:48.297681Z","iopub.status.idle":"2025-04-21T20:02:51.359392Z","shell.execute_reply.started":"2025-04-21T20:02:48.297659Z","shell.execute_reply":"2025-04-21T20:02:51.358806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"early_stopping = EarlyStopping(monitor='val_accuracy', patience=5)\n\nhistory = model.fit(x_train, y_train, epochs=30, validation_data=(x_test, y_test), verbose=1, callbacks=[early_stopping])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:02:51.360610Z","iopub.execute_input":"2025-04-21T20:02:51.360836Z","iopub.status.idle":"2025-04-21T20:05:37.400566Z","shell.execute_reply.started":"2025-04-21T20:02:51.360819Z","shell.execute_reply":"2025-04-21T20:05:37.399818Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:05:37.401684Z","iopub.execute_input":"2025-04-21T20:05:37.401941Z","iopub.status.idle":"2025-04-21T20:05:37.422862Z","shell.execute_reply.started":"2025-04-21T20:05:37.401922Z","shell.execute_reply":"2025-04-21T20:05:37.422154Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history_df = pd.DataFrame(history.history)\nhistory_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:05:37.423703Z","iopub.execute_input":"2025-04-21T20:05:37.423933Z","iopub.status.idle":"2025-04-21T20:05:37.435027Z","shell.execute_reply.started":"2025-04-21T20:05:37.423916Z","shell.execute_reply":"2025-04-21T20:05:37.434472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ax = history_df[['accuracy','val_accuracy']].plot(title = \"Train and Validation Accuracies\" , marker='o')\nax.set(xlabel =\"Epochs\", ylabel = \"Accuracy\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:05:37.436830Z","iopub.execute_input":"2025-04-21T20:05:37.437033Z","iopub.status.idle":"2025-04-21T20:05:37.702784Z","shell.execute_reply.started":"2025-04-21T20:05:37.437017Z","shell.execute_reply":"2025-04-21T20:05:37.702019Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save('leaf_disease.keras')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:05:37.703478Z","iopub.execute_input":"2025-04-21T20:05:37.703684Z","iopub.status.idle":"2025-04-21T20:05:37.848882Z","shell.execute_reply.started":"2025-04-21T20:05:37.703668Z","shell.execute_reply":"2025-04-21T20:05:37.848305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_size = (img_width, img_height)\ntest_images = df.sample(n=12)\n\nimages = []\npredicted_classes = []\nactual_classes = []\n\nfor index, row in test_images.iterrows():\n    img_path = row['img']\n    actual_class = row['label']\n    img = image.load_img(img_path, target_size=img_size)\n    img_array = image.img_to_array(img)\n    img_array = np.expand_dims(img_array, axis=0)\n    img_array /= 255.0\n\n    predictions = model.predict(img_array)\n    predicted_class = np.argmax(predictions, axis=1)\n\n    images.append(img)\n    predicted_classes.append(predicted_class[0])\n    actual_classes.append(actual_class)\n\nclass_labels = {\n    0: \"CBB\",\n    1: \"CBSD\",\n    2: \"CGM\",\n    3: \"CMD\",\n    4: \"Healthy\"\n}\n\n\nnum_images = len(images)\ncols = 3\nrows = (num_images // cols) + (num_images % cols > 0)\n\nplt.figure(figsize=(15, rows * 5))\nfor i in range(num_images):\n    plt.subplot(rows, cols, i + 1)\n    plt.imshow(images[i])\n    plt.title(f'Actual: {class_labels[actual_classes[i]]}\\nPredicted: {class_labels[predicted_classes[i]]}')\n    plt.axis('off')\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:05:37.849547Z","iopub.execute_input":"2025-04-21T20:05:37.849765Z","iopub.status.idle":"2025-04-21T20:05:41.199244Z","shell.execute_reply.started":"2025-04-21T20:05:37.849748Z","shell.execute_reply":"2025-04-21T20:05:41.198392Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# MODEL TESTING","metadata":{}},{"cell_type":"markdown","source":"## READING TEST DATA","metadata":{}},{"cell_type":"code","source":"img_path = \"/kaggle/input/cassava-leaf-disease-classification/test_images/\"\nimg_list=[]\nimg_id=[]\nfor img in os.listdir(img_path):\n    img_list.append(img_path+\"/\"+img)\n    img_id.append(img)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:06:12.036602Z","iopub.execute_input":"2025-04-21T20:06:12.036908Z","iopub.status.idle":"2025-04-21T20:06:12.051384Z","shell.execute_reply.started":"2025-04-21T20:06:12.036888Z","shell.execute_reply":"2025-04-21T20:06:12.050645Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## PREDICT IMAGES","metadata":{}},{"cell_type":"code","source":"df_test=pd.DataFrame({\n    'img_id':img_id,\n    'img_file':img_list\n})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:09:11.166255Z","iopub.execute_input":"2025-04-21T20:09:11.166833Z","iopub.status.idle":"2025-04-21T20:09:11.171017Z","shell.execute_reply.started":"2025-04-21T20:09:11.166808Z","shell.execute_reply":"2025-04-21T20:09:11.170240Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_test=[]\nfor img in df_test['img_file']:\n    img=cv2.imread(img)\n    img=cv2.resize(img,(img_width,img_height))\n    img=img/255.0 \n    x_test.append(img)\nx_test=np.array(x_test)\nx_test = x_test.reshape((-1, img_width, img_height, 3))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:09:13.536189Z","iopub.execute_input":"2025-04-21T20:09:13.537008Z","iopub.status.idle":"2025-04-21T20:09:13.556965Z","shell.execute_reply.started":"2025-04-21T20:09:13.536979Z","shell.execute_reply":"2025-04-21T20:09:13.556401Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions=model.predict(x_test)\npredictions=predictions.argmax(axis=-1)\npredictions=np.array(predictions)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:09:20.521481Z","iopub.execute_input":"2025-04-21T20:09:20.522335Z","iopub.status.idle":"2025-04-21T20:09:20.593632Z","shell.execute_reply.started":"2025-04-21T20:09:20.522308Z","shell.execute_reply":"2025-04-21T20:09:20.593041Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test['label']=predictions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:10:33.718237Z","iopub.execute_input":"2025-04-21T20:10:33.718568Z","iopub.status.idle":"2025-04-21T20:10:33.724460Z","shell.execute_reply.started":"2025-04-21T20:10:33.718542Z","shell.execute_reply":"2025-04-21T20:10:33.723486Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test.to_csv('submission.csv',index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-21T20:10:41.166888Z","iopub.execute_input":"2025-04-21T20:10:41.167686Z","iopub.status.idle":"2025-04-21T20:10:41.178023Z","shell.execute_reply.started":"2025-04-21T20:10:41.167659Z","shell.execute_reply":"2025-04-21T20:10:41.177483Z"}},"outputs":[],"execution_count":null}]}