{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":93122,"databundleVersionId":11101269,"sourceType":"competition"}],"dockerImageVersionId":30886,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# ","metadata":{}},{"cell_type":"code","source":"\nfrom keras.models import Sequential, Model, load_model\nfrom keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Input, Flatten, SeparableConv2D\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\ndf = pd.read_csv('/kaggle/input/durian-hackathon-durian-disease-classification/train.csv')\n\n\nprint(df.head()) \n\ncases_count = df['label'].value_counts(278)\nprint(cases_count)\n\nplt.figure(figsize=(10, 6))\nsns.barplot(x=cases_count.index, y=cases_count.values)\nplt.title(\"Number of images per class\", fontsize=14)\nplt.xlabel(\"Class\", fontsize=12)\nplt.ylabel(\"Count\", fontsize=12)\nplt.show()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-16T04:24:38.342728Z","iopub.execute_input":"2025-02-16T04:24:38.343090Z","iopub.status.idle":"2025-02-16T04:24:38.534726Z","shell.execute_reply.started":"2025-02-16T04:24:38.343065Z","shell.execute_reply":"2025-02-16T04:24:38.533450Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.python.client import device_lib\nprint(device_lib.list_local_devices())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T04:45:44.457089Z","iopub.execute_input":"2025-02-16T04:45:44.457452Z","iopub.status.idle":"2025-02-16T04:46:08.046398Z","shell.execute_reply.started":"2025-02-16T04:45:44.457422Z","shell.execute_reply":"2025-02-16T04:46:08.045573Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/durian-hackathon-durian-disease-classification/train.csv')\n\n# Get the counts for each class\ncases_count = df['label'].value_counts()\nprint(cases_count)\n\n# Plot the results \nplt.figure(figsize=(10,8))\nsns.barplot(x=cases_count.index, y= cases_count.values)\nplt.title('Number of images', fontsize=14)\nplt.xlabel('class', fontsize=12)\nplt.ylabel('Count', fontsize=12)\n# plt.xticks(range(len(cases_count.index)), ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'])\nplt.show()\ndel cases_count","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T04:26:22.768996Z","iopub.execute_input":"2025-02-16T04:26:22.769393Z","iopub.status.idle":"2025-02-16T04:26:22.962613Z","shell.execute_reply.started":"2025-02-16T04:26:22.769360Z","shell.execute_reply":"2025-02-16T04:26:22.961746Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.595727Z","iopub.execute_input":"2025-02-16T03:15:03.596016Z","iopub.status.idle":"2025-02-16T03:15:03.603416Z","shell.execute_reply.started":"2025-02-16T03:15:03.595995Z","shell.execute_reply":"2025-02-16T03:15:03.602556Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain_df, validate_df = train_test_split(df, test_size=0.15, stratify=df['label'])\ntrain_df = train_df.reset_index(drop=True)\nvalidate_df = validate_df.reset_index(drop=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.604929Z","iopub.execute_input":"2025-02-16T03:15:03.605177Z","iopub.status.idle":"2025-02-16T03:15:03.618969Z","shell.execute_reply.started":"2025-02-16T03:15:03.605158Z","shell.execute_reply":"2025-02-16T03:15:03.618203Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df['label'] = train_df['label'].astype(str)\nvalidate_df['label'] = validate_df['label'].astype(str)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.620046Z","iopub.execute_input":"2025-02-16T03:15:03.62028Z","iopub.status.idle":"2025-02-16T03:15:03.63302Z","shell.execute_reply.started":"2025-02-16T03:15:03.620262Z","shell.execute_reply":"2025-02-16T03:15:03.632215Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.633823Z","iopub.execute_input":"2025-02-16T03:15:03.634022Z","iopub.status.idle":"2025-02-16T03:15:03.649803Z","shell.execute_reply.started":"2025-02-16T03:15:03.634005Z","shell.execute_reply":"2025-02-16T03:15:03.649066Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df['label'].value_counts().sort_index().plot.bar()\nvalidate_df['label'].value_counts().sort_index().plot.bar()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.650554Z","iopub.execute_input":"2025-02-16T03:15:03.65084Z","iopub.status.idle":"2025-02-16T03:15:03.802453Z","shell.execute_reply.started":"2025-02-16T03:15:03.650819Z","shell.execute_reply":"2025-02-16T03:15:03.801631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image_size = 224\ntarget_size = (image_size, image_size)\ninput_shape = (image_size, image_size, 3)\n\nbatch_size = 8\nnum_class = 4\nepochs =  17","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.803294Z","iopub.execute_input":"2025-02-16T03:15:03.803592Z","iopub.status.idle":"2025-02-16T03:15:03.807534Z","shell.execute_reply.started":"2025-02-16T03:15:03.803562Z","shell.execute_reply":"2025-02-16T03:15:03.806768Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    rotation_range=15,  # More rotation\n    width_shift_range=0.2,\n    brightness_range=[0.6, 1.4],  # Stronger brightness augmentation\n    fill_mode='reflect'  # Better fill handling\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df, \n    \"/kaggle/input/durian-hackathon-durian-disease-classification/Images\", \n    x_col='id',\n    y_col='label',\n    target_size=target_size,\n    class_mode='categorical',\n    batch_size=batch_size\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.810303Z","iopub.execute_input":"2025-02-16T03:15:03.810562Z","iopub.status.idle":"2025-02-16T03:15:03.922828Z","shell.execute_reply.started":"2025-02-16T03:15:03.81054Z","shell.execute_reply":"2025-02-16T03:15:03.922101Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch=next(train_generator)  # returns the next batch of images and labels \nprint(batch[0].shape) # batch[0] is the images, batch[1] are the labels\n\nfor i in range(0,4):\n    img=batch[0][i] \n    plt.imshow(img)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:03.924516Z","iopub.execute_input":"2025-02-16T03:15:03.924799Z","iopub.status.idle":"2025-02-16T03:15:04.889774Z","shell.execute_reply.started":"2025-02-16T03:15:03.924777Z","shell.execute_reply":"2025-02-16T03:15:04.888925Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"validation_datagen = ImageDataGenerator(rescale=1./255)\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    validate_df, \n    \"/kaggle/input/durian-hackathon-durian-disease-classification/Images\", \n    x_col='id',\n    y_col='label',\n    target_size=target_size,\n    class_mode='categorical',\n    batch_size=batch_size\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:04.890497Z","iopub.execute_input":"2025-02-16T03:15:04.890712Z","iopub.status.idle":"2025-02-16T03:15:04.91521Z","shell.execute_reply.started":"2025-02-16T03:15:04.890693Z","shell.execute_reply":"2025-02-16T03:15:04.914314Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nimport os\n\nbase_model = tf.keras.applications.VGG16(\n    input_shape=input_shape,\n    include_top=False,\n    weights='imagenet'\n)\n\nbase_model.trainable = False\n\nx = base_model.output\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\nx = tf.keras.layers.Dropout(0.2)(x)\noutput = tf.keras.layers.Dense(num_class, activation=\"softmax\")(x)\n\nmodel = keras.Model(inputs = base_model.input,\n                    outputs = output)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:04.916077Z","iopub.execute_input":"2025-02-16T03:15:04.916354Z","iopub.status.idle":"2025-02-16T03:15:05.162392Z","shell.execute_reply.started":"2025-02-16T03:15:04.916322Z","shell.execute_reply":"2025-02-16T03:15:05.161711Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n\n# Using Adam optimizer (without weight decay)\noptimizer = Adam(learning_rate=0.001)\n\n# Checkpoint to save the best model based on validation accuracy\ncheckpoint = ModelCheckpoint(\"best_model.keras\", monitor='val_accuracy', save_best_only=True)\n\n# Early stopping to prevent overfitting (stops training if val_loss doesn't improve for 30 epochs)\nearlyStopping = EarlyStopping(monitor='val_loss', patience=30, verbose=0, mode='min')\n\n# Another checkpoint saving based on val_loss\nmcp_save = ModelCheckpoint('best_model.keras', save_best_only=True, monitor='val_loss', mode='min')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:05.16312Z","iopub.execute_input":"2025-02-16T03:15:05.163326Z","iopub.status.idle":"2025-02-16T03:15:05.170007Z","shell.execute_reply.started":"2025-02-16T03:15:05.163308Z","shell.execute_reply":"2025-02-16T03:15:05.16918Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:05.170897Z","iopub.execute_input":"2025-02-16T03:15:05.171155Z","iopub.status.idle":"2025-02-16T03:15:05.189379Z","shell.execute_reply.started":"2025-02-16T03:15:05.171135Z","shell.execute_reply":"2025-02-16T03:15:05.188741Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(train_generator, \n                validation_data = validation_generator,\n                epochs = epochs,\n                batch_size = batch_size,\n                callbacks=[earlyStopping, mcp_save])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:15:05.190177Z","iopub.execute_input":"2025-02-16T03:15:05.190456Z","iopub.status.idle":"2025-02-16T03:18:24.040535Z","shell.execute_reply.started":"2025-02-16T03:15:05.190426Z","shell.execute_reply":"2025-02-16T03:18:24.039846Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def tta_predict(model, image, num_augments=5):\n    aug_images = np.array([train_datagen.random_transform(image) for _ in range(num_augments)])\n    preds = model.predict(aug_images)\n    return np.mean(preds, axis=0)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.041447Z","iopub.execute_input":"2025-02-16T03:18:24.041709Z","iopub.status.idle":"2025-02-16T03:18:24.045813Z","shell.execute_reply.started":"2025-02-16T03:18:24.041665Z","shell.execute_reply":"2025-02-16T03:18:24.045009Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12))\nax1.plot(history.history['loss'], color='b', label=\"Training loss\")\nax1.plot(history.history['val_loss'], color='r', label=\"validation loss\")\n\nax2.plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\nax2.plot(history.history['val_accuracy'], color='r',label=\"Validation accuracy\")\n\nlegend = plt.legend(loc='best', shadow=True)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.046592Z","iopub.execute_input":"2025-02-16T03:18:24.046854Z","iopub.status.idle":"2025-02-16T03:18:24.404496Z","shell.execute_reply.started":"2025-02-16T03:18:24.046823Z","shell.execute_reply":"2025-02-16T03:18:24.403522Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = pd.read_csv('/kaggle/input/durian-hackathon-durian-disease-classification/submit.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.405306Z","iopub.execute_input":"2025-02-16T03:18:24.405589Z","iopub.status.idle":"2025-02-16T03:18:24.411395Z","shell.execute_reply.started":"2025-02-16T03:18:24.40556Z","shell.execute_reply":"2025-02-16T03:18:24.410534Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.412244Z","iopub.execute_input":"2025-02-16T03:18:24.412545Z","iopub.status.idle":"2025-02-16T03:18:24.425485Z","shell.execute_reply.started":"2025-02-16T03:18:24.412511Z","shell.execute_reply":"2025-02-16T03:18:24.424656Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.tail()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.426347Z","iopub.execute_input":"2025-02-16T03:18:24.426635Z","iopub.status.idle":"2025-02-16T03:18:24.441458Z","shell.execute_reply.started":"2025-02-16T03:18:24.4266Z","shell.execute_reply":"2025-02-16T03:18:24.44063Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_gen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_gen.flow_from_dataframe(\n    test_df, \n    \"/kaggle/input/durian-hackathon-durian-disease-classification/Images\", \n    x_col='id',\n    y_col=None,\n    class_mode=None,\n    target_size=target_size,\n    batch_size=batch_size,\n    shuffle=False\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.442392Z","iopub.execute_input":"2025-02-16T03:18:24.442656Z","iopub.status.idle":"2025-02-16T03:18:24.573762Z","shell.execute_reply.started":"2025-02-16T03:18:24.442635Z","shell.execute_reply":"2025-02-16T03:18:24.573152Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = load_model('/kaggle/working/best_model.keras')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.574592Z","iopub.execute_input":"2025-02-16T03:18:24.574894Z","iopub.status.idle":"2025-02-16T03:18:24.827495Z","shell.execute_reply.started":"2025-02-16T03:18:24.574871Z","shell.execute_reply":"2025-02-16T03:18:24.826832Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predict = model.predict(test_generator)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:24.828139Z","iopub.execute_input":"2025-02-16T03:18:24.828352Z","iopub.status.idle":"2025-02-16T03:18:30.184024Z","shell.execute_reply.started":"2025-02-16T03:18:24.828327Z","shell.execute_reply":"2025-02-16T03:18:30.183265Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df['predict'] = np.argmax(predict, axis=-1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:30.187214Z","iopub.execute_input":"2025-02-16T03:18:30.187443Z","iopub.status.idle":"2025-02-16T03:18:30.191303Z","shell.execute_reply.started":"2025-02-16T03:18:30.187423Z","shell.execute_reply":"2025-02-16T03:18:30.190542Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_map = dict((v,k) for k,v in train_generator.class_indices.items())\ntest_df['predict'] = test_df['predict'].replace(label_map)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:30.192226Z","iopub.execute_input":"2025-02-16T03:18:30.192493Z","iopub.status.idle":"2025-02-16T03:18:30.205591Z","shell.execute_reply.started":"2025-02-16T03:18:30.192461Z","shell.execute_reply":"2025-02-16T03:18:30.204866Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df['predict'].value_counts().plot.bar()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:30.206339Z","iopub.execute_input":"2025-02-16T03:18:30.206582Z","iopub.status.idle":"2025-02-16T03:18:30.344464Z","shell.execute_reply.started":"2025-02-16T03:18:30.206562Z","shell.execute_reply":"2025-02-16T03:18:30.343755Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(test_df.head()) ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:30.345282Z","iopub.execute_input":"2025-02-16T03:18:30.345484Z","iopub.status.idle":"2025-02-16T03:18:30.351091Z","shell.execute_reply.started":"2025-02-16T03:18:30.345466Z","shell.execute_reply":"2025-02-16T03:18:30.350233Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df.to_csv('../working/submission.csv', index=False)\nfrom IPython.display import FileLink\nFileLink(r'submission.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-16T03:18:30.351857Z","iopub.execute_input":"2025-02-16T03:18:30.35212Z","iopub.status.idle":"2025-02-16T03:18:30.365558Z","shell.execute_reply.started":"2025-02-16T03:18:30.3521Z","shell.execute_reply":"2025-02-16T03:18:30.364793Z"}},"outputs":[],"execution_count":null}]}