{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n\nprint(tf.__version__)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:25:08.911958Z","iopub.execute_input":"2026-07-29T15:25:08.912445Z","iopub.status.idle":"2026-07-29T15:25:08.918120Z","shell.execute_reply.started":"2026-07-29T15:25:08.912415Z","shell.execute_reply":"2026-07-29T15:25:08.917291Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ntrain_df = pd.read_csv(\"/kaggle/input/competitions/plant-pathology-2021-fgvc8/train.csv\")\n\ntrain_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:27:35.691261Z","iopub.execute_input":"2026-07-29T15:27:35.691758Z","iopub.status.idle":"2026-07-29T15:27:35.749757Z","shell.execute_reply.started":"2026-07-29T15:27:35.691729Z","shell.execute_reply":"2026-07-29T15:27:35.749053Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"classes = [\n    \"complex\",\n    \"frog_eye_leaf_spot\",\n    \"healthy\",\n    \"powdery_mildew\",\n    \"rust\",\n    \"scab\"\n]\n\nfor c in classes:\n    train_df[c] = train_df[\"labels\"].apply(\n        lambda x: int(c in x.split())\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:27:48.078984Z","iopub.execute_input":"2026-07-29T15:27:48.079775Z","iopub.status.idle":"2026-07-29T15:27:48.142088Z","shell.execute_reply.started":"2026-07-29T15:27:48.079745Z","shell.execute_reply":"2026-07-29T15:27:48.141501Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:27:58.150059Z","iopub.execute_input":"2026-07-29T15:27:58.150913Z","iopub.status.idle":"2026-07-29T15:27:58.165576Z","shell.execute_reply.started":"2026-07-29T15:27:58.150864Z","shell.execute_reply":"2026-07-29T15:27:58.164659Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_DIR = \"/kaggle/input/datasets/ankursingh12/resized-plant2021/img_sz_256\"\n\ntrain_df[\"filepath\"] = (\n    IMAGE_DIR + \"/\" + train_df[\"image\"]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:28:31.983535Z","iopub.execute_input":"2026-07-29T15:28:31.984421Z","iopub.status.idle":"2026-07-29T15:28:31.992441Z","shell.execute_reply.started":"2026-07-29T15:28:31.984390Z","shell.execute_reply":"2026-07-29T15:28:31.991538Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:28:40.114661Z","iopub.execute_input":"2026-07-29T15:28:40.115093Z","iopub.status.idle":"2026-07-29T15:28:40.128964Z","shell.execute_reply.started":"2026-07-29T15:28:40.115065Z","shell.execute_reply":"2026-07-29T15:28:40.128085Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain_data, val_data = train_test_split(\n    train_df,\n    test_size=0.2,\n    random_state=42\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:28:48.435134Z","iopub.execute_input":"2026-07-29T15:28:48.435541Z","iopub.status.idle":"2026-07-29T15:28:48.819706Z","shell.execute_reply.started":"2026-07-29T15:28:48.435511Z","shell.execute_reply":"2026-07-29T15:28:48.818674Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\n\nIMG_SIZE = 224\nBATCH_SIZE = 32\n\ndef load_image(path, label):\n    image = tf.io.read_file(path)\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))\n    image = tf.keras.applications.mobilenet_v2.preprocess_input(image)\n\n    return image, label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:05.812058Z","iopub.execute_input":"2026-07-29T15:31:05.812955Z","iopub.status.idle":"2026-07-29T15:31:05.817645Z","shell.execute_reply.started":"2026-07-29T15:31:05.812923Z","shell.execute_reply":"2026-07-29T15:31:05.816680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_ds = tf.data.Dataset.from_tensor_slices(\n    (\n        train_data[\"filepath\"].values,\n        train_data[classes].values.astype(\"float32\")\n    )\n)\n\ntrain_ds = (\n    train_ds\n    .map(load_image, num_parallel_calls=tf.data.AUTOTUNE)\n    .shuffle(1000)\n    .batch(BATCH_SIZE)\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:06.585299Z","iopub.execute_input":"2026-07-29T15:31:06.586080Z","iopub.status.idle":"2026-07-29T15:31:06.617569Z","shell.execute_reply.started":"2026-07-29T15:31:06.586046Z","shell.execute_reply":"2026-07-29T15:31:06.616931Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_ds = tf.data.Dataset.from_tensor_slices(\n    (\n        val_data[\"filepath\"].values,\n        val_data[classes].values.astype(\"float32\")\n    )\n)\n\nval_ds = (\n    val_ds\n    .map(load_image)\n    .batch(BATCH_SIZE)\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:07.219573Z","iopub.execute_input":"2026-07-29T15:31:07.220036Z","iopub.status.idle":"2026-07-29T15:31:07.246755Z","shell.execute_reply.started":"2026-07-29T15:31:07.220008Z","shell.execute_reply":"2026-07-29T15:31:07.246008Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model = tf.keras.applications.MobileNetV2(\n\n    input_shape=(224,224,3),\n    include_top=False,\n    weights=\"imagenet\"\n)\n\nbase_model.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:07.887272Z","iopub.execute_input":"2026-07-29T15:31:07.887866Z","iopub.status.idle":"2026-07-29T15:31:08.615187Z","shell.execute_reply.started":"2026-07-29T15:31:07.887835Z","shell.execute_reply":"2026-07-29T15:31:08.614528Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inputs = tf.keras.Input(shape=(224,224,3))\n\nx = base_model(inputs, training=False)\n\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\n\nx = tf.keras.layers.Dropout(0.3)(x)\n\noutputs = tf.keras.layers.Dense(\n    6,\n    activation=\"sigmoid\"\n)(x)\n\nmodel = tf.keras.Model(inputs, outputs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:19.694086Z","iopub.execute_input":"2026-07-29T15:31:19.694779Z","iopub.status.idle":"2026-07-29T15:31:19.721351Z","shell.execute_reply.started":"2026-07-29T15:31:19.694749Z","shell.execute_reply":"2026-07-29T15:31:19.720387Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(\n\n    optimizer=\"adam\",\n\n    loss=tf.keras.losses.BinaryCrossentropy(),\n\n    metrics=[\n        tf.keras.metrics.BinaryAccuracy(),\n        tf.keras.metrics.AUC(multi_label=True)\n    ]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:30.398035Z","iopub.execute_input":"2026-07-29T15:31:30.398492Z","iopub.status.idle":"2026-07-29T15:31:30.417569Z","shell.execute_reply.started":"2026-07-29T15:31:30.398462Z","shell.execute_reply":"2026-07-29T15:31:30.416801Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n\n    train_ds,\n\n    validation_data=val_ds,\n\n    epochs=10\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:31:38.709482Z","iopub.execute_input":"2026-07-29T15:31:38.710294Z","iopub.status.idle":"2026-07-29T15:35:34.522795Z","shell.execute_reply.started":"2026-07-29T15:31:38.710262Z","shell.execute_reply":"2026-07-29T15:35:34.521576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model.trainable = True\n\nfor layer in base_model.layers[:-30]:\n    layer.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:35:54.354083Z","iopub.execute_input":"2026-07-29T15:35:54.354517Z","iopub.status.idle":"2026-07-29T15:35:54.361481Z","shell.execute_reply.started":"2026-07-29T15:35:54.354484Z","shell.execute_reply":"2026-07-29T15:35:54.360626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(\n\n    optimizer=tf.keras.optimizers.Adam(1e-5),\n\n    loss=\"binary_crossentropy\",\n\n    metrics=[\n        tf.keras.metrics.BinaryAccuracy(),\n        tf.keras.metrics.AUC(multi_label=True)\n    ]\n)\n\nmodel.fit(\n    train_ds,\n    validation_data=val_ds,\n    epochs=5\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:36:03.977168Z","iopub.execute_input":"2026-07-29T15:36:03.977982Z","iopub.status.idle":"2026-07-29T15:38:24.170947Z","shell.execute_reply.started":"2026-07-29T15:36:03.977950Z","shell.execute_reply":"2026-07-29T15:38:24.170154Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\n\n# Predict probabilities\ny_pred_prob = model.predict(val_ds)\n\n# Convert probabilities to 0/1 predictions\nthreshold = 0.5\ny_pred = (y_pred_prob >= threshold).astype(int)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:38:35.134431Z","iopub.execute_input":"2026-07-29T15:38:35.135449Z","iopub.status.idle":"2026-07-29T15:38:46.907352Z","shell.execute_reply.started":"2026-07-29T15:38:35.135415Z","shell.execute_reply":"2026-07-29T15:38:46.906282Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_true = np.concatenate([labels.numpy() for _, labels in val_ds])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:38:59.936971Z","iopub.execute_input":"2026-07-29T15:38:59.937791Z","iopub.status.idle":"2026-07-29T15:39:02.028544Z","shell.execute_reply.started":"2026-07-29T15:38:59.937761Z","shell.execute_reply":"2026-07-29T15:39:02.027668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import multilabel_confusion_matrix\n\ncm = multilabel_confusion_matrix(y_true, y_pred)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:39:10.168884Z","iopub.execute_input":"2026-07-29T15:39:10.169681Z","iopub.status.idle":"2026-07-29T15:39:10.189655Z","shell.execute_reply.started":"2026-07-29T15:39:10.169639Z","shell.execute_reply":"2026-07-29T15:39:10.188761Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:41:13.442541Z","iopub.execute_input":"2026-07-29T15:41:13.443400Z","iopub.status.idle":"2026-07-29T15:41:13.449759Z","shell.execute_reply.started":"2026-07-29T15:41:13.443366Z","shell.execute_reply":"2026-07-29T15:41:13.448954Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom sklearn.metrics import ConfusionMatrixDisplay\n\nclasses = [\n    \"complex\",\n    \"frog_eye_leaf_spot\",\n    \"healthy\",\n    \"powdery_mildew\",\n    \"rust\",\n    \"scab\"\n]\n\nfig, axes = plt.subplots(2, 3, figsize=(15, 10))\n\nfor i, ax in enumerate(axes.ravel()):\n    disp = ConfusionMatrixDisplay(\n        confusion_matrix=cm[i],\n        display_labels=[\"No\", \"Yes\"]\n    )\n    disp.plot(ax=ax, colorbar=False)\n    ax.set_title(classes[i])\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:39:24.346476Z","iopub.execute_input":"2026-07-29T15:39:24.347262Z","iopub.status.idle":"2026-07-29T15:39:25.239041Z","shell.execute_reply.started":"2026-07-29T15:39:24.347233Z","shell.execute_reply":"2026-07-29T15:39:25.238291Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import classification_report\n\nprint(classification_report(\n    y_true,\n    y_pred,\n    target_names=classes\n))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-29T15:39:59.906918Z","iopub.execute_input":"2026-07-29T15:39:59.907689Z","iopub.status.idle":"2026-07-29T15:39:59.936730Z","shell.execute_reply.started":"2026-07-29T15:39:59.907660Z","shell.execute_reply":"2026-07-29T15:39:59.935933Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}