Initial commit

This commit is contained in:
Tariskadebby 2026-05-31 10:11:09 +07:00
commit cdc09228cd
34506 changed files with 7393 additions and 0 deletions

View File

@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}

1
backend/Procfile Normal file
View File

@ -0,0 +1 @@
web: gunicorn app:app

850
backend/Training.ipynb Normal file
View File

@ -0,0 +1,850 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "85737c4d-3fa6-48fe-be63-d66915079cb9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"BASE_DIR: C:\\Corn_Detection\\backend\n"
]
}
],
"source": [
"import os\n",
"import numpy as np\n",
"import tensorflow as tf\n",
"import matplotlib.pyplot as plt\n",
"import pickle\n",
"import seaborn as sns\n",
"\n",
"from tensorflow.keras.applications import MobileNetV2\n",
"from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\n",
"from tensorflow.keras.models import Model\n",
"from tensorflow.keras.optimizers import Adam\n",
"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
"from tensorflow.keras.applications.mobilenet_v2 import preprocess_input\n",
"from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n",
"\n",
"from sklearn.utils.class_weight import compute_class_weight\n",
"from sklearn.metrics import classification_report, confusion_matrix\n",
"\n",
"# ======================\n",
"# PATH (FIX UNTUK JUPYTER)\n",
"# ======================\n",
"BASE_DIR = os.getcwd()\n",
"\n",
"MODEL_DIR = os.path.join(BASE_DIR, \"model\")\n",
"os.makedirs(MODEL_DIR, exist_ok=True)\n",
"\n",
"MODEL_PATH = os.path.join(MODEL_DIR, \"model_feature_extraction.h5\")\n",
"BEST_MODEL_PATH = os.path.join(MODEL_DIR, \"model.h5\")\n",
"HISTORY_PATH = os.path.join(MODEL_DIR, \"history.pkl\")\n",
"\n",
"TRAIN_DIR = os.path.join(BASE_DIR, \"dataset_split\", \"train\")\n",
"VAL_DIR = os.path.join(BASE_DIR, \"dataset_split\", \"val\")\n",
"TEST_DIR = os.path.join(BASE_DIR, \"dataset_split\", \"test\")\n",
"\n",
"IMG_SIZE = (224, 224)\n",
"BATCH_SIZE = 16\n",
"EPOCHS = 10\n",
"LEARNING_RATE = 1e-4\n",
"\n",
"print(\"BASE_DIR:\", BASE_DIR)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "4047d127-0dfa-46c0-8997-8f3243471553",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 8606 images belonging to 4 classes.\n",
"Found 1843 images belonging to 4 classes.\n",
"Found 1847 images belonging to 4 classes.\n",
"\n",
"Class Indices:\n",
"{'hawar_daun': 0, 'karat_daun': 1, 'non_jagung': 2, 'sehat': 3}\n",
"Jumlah kelas: 4\n"
]
}
],
"source": [
"train_datagen = ImageDataGenerator(\n",
" preprocessing_function=preprocess_input,\n",
" horizontal_flip=True,\n",
" rotation_range=20,\n",
" zoom_range=0.15,\n",
" width_shift_range=0.1,\n",
" height_shift_range=0.1\n",
")\n",
"\n",
"val_test_datagen = ImageDataGenerator(\n",
" preprocessing_function=preprocess_input\n",
")\n",
"\n",
"train_gen = train_datagen.flow_from_directory(\n",
" TRAIN_DIR,\n",
" target_size=IMG_SIZE,\n",
" batch_size=BATCH_SIZE,\n",
" class_mode=\"categorical\",\n",
" shuffle=True\n",
")\n",
"\n",
"val_gen = val_test_datagen.flow_from_directory(\n",
" VAL_DIR,\n",
" target_size=IMG_SIZE,\n",
" batch_size=BATCH_SIZE,\n",
" class_mode=\"categorical\",\n",
" shuffle=False\n",
")\n",
"\n",
"test_gen = val_test_datagen.flow_from_directory(\n",
" TEST_DIR,\n",
" target_size=IMG_SIZE,\n",
" batch_size=BATCH_SIZE,\n",
" class_mode=\"categorical\",\n",
" shuffle=False\n",
")\n",
"\n",
"print(\"\\nClass Indices:\")\n",
"print(train_gen.class_indices)\n",
"\n",
"num_classes = len(train_gen.class_indices)\n",
"print(\"Jumlah kelas:\", num_classes)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e05a4e8f-7b8a-46e2-a3e0-47f2d0f9d40f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Class Weight:\n",
"hawar_daun : 1.121\n",
"karat_daun : 0.860\n",
"non_jagung : 1.229\n",
"sehat : 0.884\n"
]
}
],
"source": [
"y_train = train_gen.classes\n",
"\n",
"class_weights = compute_class_weight(\n",
" class_weight=\"balanced\",\n",
" classes=np.unique(y_train),\n",
" y=y_train\n",
")\n",
"\n",
"class_weights_dict = dict(zip(np.unique(y_train), class_weights))\n",
"\n",
"print(\"\\nClass Weight:\")\n",
"for class_id, weight in class_weights_dict.items():\n",
" class_name = list(train_gen.class_indices.keys())[class_id]\n",
" print(f\"{class_name} : {weight:.3f}\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5e95506f-108e-466e-a50e-672a19f5e441",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"__________________________________________________________________________________________________\n",
" Layer (type) Output Shape Param # Connected to \n",
"==================================================================================================\n",
" input_1 (InputLayer) [(None, 224, 224, 3)] 0 [] \n",
" \n",
" Conv1 (Conv2D) (None, 112, 112, 32) 864 ['input_1[0][0]'] \n",
" \n",
" bn_Conv1 (BatchNormalizati (None, 112, 112, 32) 128 ['Conv1[0][0]'] \n",
" on) \n",
" \n",
" Conv1_relu (ReLU) (None, 112, 112, 32) 0 ['bn_Conv1[0][0]'] \n",
" \n",
" expanded_conv_depthwise (D (None, 112, 112, 32) 288 ['Conv1_relu[0][0]'] \n",
" epthwiseConv2D) \n",
" \n",
" expanded_conv_depthwise_BN (None, 112, 112, 32) 128 ['expanded_conv_depthwise[0][0\n",
" (BatchNormalization) ]'] \n",
" \n",
" expanded_conv_depthwise_re (None, 112, 112, 32) 0 ['expanded_conv_depthwise_BN[0\n",
" lu (ReLU) ][0]'] \n",
" \n",
" expanded_conv_project (Con (None, 112, 112, 16) 512 ['expanded_conv_depthwise_relu\n",
" v2D) [0][0]'] \n",
" \n",
" expanded_conv_project_BN ( (None, 112, 112, 16) 64 ['expanded_conv_project[0][0]'\n",
" BatchNormalization) ] \n",
" \n",
" block_1_expand (Conv2D) (None, 112, 112, 96) 1536 ['expanded_conv_project_BN[0][\n",
" 0]'] \n",
" \n",
" block_1_expand_BN (BatchNo (None, 112, 112, 96) 384 ['block_1_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_1_expand_relu (ReLU) (None, 112, 112, 96) 0 ['block_1_expand_BN[0][0]'] \n",
" \n",
" block_1_pad (ZeroPadding2D (None, 113, 113, 96) 0 ['block_1_expand_relu[0][0]'] \n",
" ) \n",
" \n",
" block_1_depthwise (Depthwi (None, 56, 56, 96) 864 ['block_1_pad[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_1_depthwise_BN (Batc (None, 56, 56, 96) 384 ['block_1_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_1_depthwise_relu (Re (None, 56, 56, 96) 0 ['block_1_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_1_project (Conv2D) (None, 56, 56, 24) 2304 ['block_1_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_1_project_BN (BatchN (None, 56, 56, 24) 96 ['block_1_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_2_expand (Conv2D) (None, 56, 56, 144) 3456 ['block_1_project_BN[0][0]'] \n",
" \n",
" block_2_expand_BN (BatchNo (None, 56, 56, 144) 576 ['block_2_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_2_expand_relu (ReLU) (None, 56, 56, 144) 0 ['block_2_expand_BN[0][0]'] \n",
" \n",
" block_2_depthwise (Depthwi (None, 56, 56, 144) 1296 ['block_2_expand_relu[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_2_depthwise_BN (Batc (None, 56, 56, 144) 576 ['block_2_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_2_depthwise_relu (Re (None, 56, 56, 144) 0 ['block_2_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_2_project (Conv2D) (None, 56, 56, 24) 3456 ['block_2_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_2_project_BN (BatchN (None, 56, 56, 24) 96 ['block_2_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_2_add (Add) (None, 56, 56, 24) 0 ['block_1_project_BN[0][0]', \n",
" 'block_2_project_BN[0][0]'] \n",
" \n",
" block_3_expand (Conv2D) (None, 56, 56, 144) 3456 ['block_2_add[0][0]'] \n",
" \n",
" block_3_expand_BN (BatchNo (None, 56, 56, 144) 576 ['block_3_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_3_expand_relu (ReLU) (None, 56, 56, 144) 0 ['block_3_expand_BN[0][0]'] \n",
" \n",
" block_3_pad (ZeroPadding2D (None, 57, 57, 144) 0 ['block_3_expand_relu[0][0]'] \n",
" ) \n",
" \n",
" block_3_depthwise (Depthwi (None, 28, 28, 144) 1296 ['block_3_pad[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_3_depthwise_BN (Batc (None, 28, 28, 144) 576 ['block_3_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_3_depthwise_relu (Re (None, 28, 28, 144) 0 ['block_3_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_3_project (Conv2D) (None, 28, 28, 32) 4608 ['block_3_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_3_project_BN (BatchN (None, 28, 28, 32) 128 ['block_3_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_4_expand (Conv2D) (None, 28, 28, 192) 6144 ['block_3_project_BN[0][0]'] \n",
" \n",
" block_4_expand_BN (BatchNo (None, 28, 28, 192) 768 ['block_4_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_4_expand_relu (ReLU) (None, 28, 28, 192) 0 ['block_4_expand_BN[0][0]'] \n",
" \n",
" block_4_depthwise (Depthwi (None, 28, 28, 192) 1728 ['block_4_expand_relu[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_4_depthwise_BN (Batc (None, 28, 28, 192) 768 ['block_4_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_4_depthwise_relu (Re (None, 28, 28, 192) 0 ['block_4_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_4_project (Conv2D) (None, 28, 28, 32) 6144 ['block_4_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_4_project_BN (BatchN (None, 28, 28, 32) 128 ['block_4_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_4_add (Add) (None, 28, 28, 32) 0 ['block_3_project_BN[0][0]', \n",
" 'block_4_project_BN[0][0]'] \n",
" \n",
" block_5_expand (Conv2D) (None, 28, 28, 192) 6144 ['block_4_add[0][0]'] \n",
" \n",
" block_5_expand_BN (BatchNo (None, 28, 28, 192) 768 ['block_5_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_5_expand_relu (ReLU) (None, 28, 28, 192) 0 ['block_5_expand_BN[0][0]'] \n",
" \n",
" block_5_depthwise (Depthwi (None, 28, 28, 192) 1728 ['block_5_expand_relu[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_5_depthwise_BN (Batc (None, 28, 28, 192) 768 ['block_5_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_5_depthwise_relu (Re (None, 28, 28, 192) 0 ['block_5_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_5_project (Conv2D) (None, 28, 28, 32) 6144 ['block_5_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_5_project_BN (BatchN (None, 28, 28, 32) 128 ['block_5_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_5_add (Add) (None, 28, 28, 32) 0 ['block_4_add[0][0]', \n",
" 'block_5_project_BN[0][0]'] \n",
" \n",
" block_6_expand (Conv2D) (None, 28, 28, 192) 6144 ['block_5_add[0][0]'] \n",
" \n",
" block_6_expand_BN (BatchNo (None, 28, 28, 192) 768 ['block_6_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_6_expand_relu (ReLU) (None, 28, 28, 192) 0 ['block_6_expand_BN[0][0]'] \n",
" \n",
" block_6_pad (ZeroPadding2D (None, 29, 29, 192) 0 ['block_6_expand_relu[0][0]'] \n",
" ) \n",
" \n",
" block_6_depthwise (Depthwi (None, 14, 14, 192) 1728 ['block_6_pad[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_6_depthwise_BN (Batc (None, 14, 14, 192) 768 ['block_6_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_6_depthwise_relu (Re (None, 14, 14, 192) 0 ['block_6_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_6_project (Conv2D) (None, 14, 14, 64) 12288 ['block_6_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_6_project_BN (BatchN (None, 14, 14, 64) 256 ['block_6_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_7_expand (Conv2D) (None, 14, 14, 384) 24576 ['block_6_project_BN[0][0]'] \n",
" \n",
" block_7_expand_BN (BatchNo (None, 14, 14, 384) 1536 ['block_7_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_7_expand_relu (ReLU) (None, 14, 14, 384) 0 ['block_7_expand_BN[0][0]'] \n",
" \n",
" block_7_depthwise (Depthwi (None, 14, 14, 384) 3456 ['block_7_expand_relu[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_7_depthwise_BN (Batc (None, 14, 14, 384) 1536 ['block_7_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_7_depthwise_relu (Re (None, 14, 14, 384) 0 ['block_7_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_7_project (Conv2D) (None, 14, 14, 64) 24576 ['block_7_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_7_project_BN (BatchN (None, 14, 14, 64) 256 ['block_7_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_7_add (Add) (None, 14, 14, 64) 0 ['block_6_project_BN[0][0]', \n",
" 'block_7_project_BN[0][0]'] \n",
" \n",
" block_8_expand (Conv2D) (None, 14, 14, 384) 24576 ['block_7_add[0][0]'] \n",
" \n",
" block_8_expand_BN (BatchNo (None, 14, 14, 384) 1536 ['block_8_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_8_expand_relu (ReLU) (None, 14, 14, 384) 0 ['block_8_expand_BN[0][0]'] \n",
" \n",
" block_8_depthwise (Depthwi (None, 14, 14, 384) 3456 ['block_8_expand_relu[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_8_depthwise_BN (Batc (None, 14, 14, 384) 1536 ['block_8_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_8_depthwise_relu (Re (None, 14, 14, 384) 0 ['block_8_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_8_project (Conv2D) (None, 14, 14, 64) 24576 ['block_8_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_8_project_BN (BatchN (None, 14, 14, 64) 256 ['block_8_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_8_add (Add) (None, 14, 14, 64) 0 ['block_7_add[0][0]', \n",
" 'block_8_project_BN[0][0]'] \n",
" \n",
" block_9_expand (Conv2D) (None, 14, 14, 384) 24576 ['block_8_add[0][0]'] \n",
" \n",
" block_9_expand_BN (BatchNo (None, 14, 14, 384) 1536 ['block_9_expand[0][0]'] \n",
" rmalization) \n",
" \n",
" block_9_expand_relu (ReLU) (None, 14, 14, 384) 0 ['block_9_expand_BN[0][0]'] \n",
" \n",
" block_9_depthwise (Depthwi (None, 14, 14, 384) 3456 ['block_9_expand_relu[0][0]'] \n",
" seConv2D) \n",
" \n",
" block_9_depthwise_BN (Batc (None, 14, 14, 384) 1536 ['block_9_depthwise[0][0]'] \n",
" hNormalization) \n",
" \n",
" block_9_depthwise_relu (Re (None, 14, 14, 384) 0 ['block_9_depthwise_BN[0][0]']\n",
" LU) \n",
" \n",
" block_9_project (Conv2D) (None, 14, 14, 64) 24576 ['block_9_depthwise_relu[0][0]\n",
" '] \n",
" \n",
" block_9_project_BN (BatchN (None, 14, 14, 64) 256 ['block_9_project[0][0]'] \n",
" ormalization) \n",
" \n",
" block_9_add (Add) (None, 14, 14, 64) 0 ['block_8_add[0][0]', \n",
" 'block_9_project_BN[0][0]'] \n",
" \n",
" block_10_expand (Conv2D) (None, 14, 14, 384) 24576 ['block_9_add[0][0]'] \n",
" \n",
" block_10_expand_BN (BatchN (None, 14, 14, 384) 1536 ['block_10_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_10_expand_relu (ReLU (None, 14, 14, 384) 0 ['block_10_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_10_depthwise (Depthw (None, 14, 14, 384) 3456 ['block_10_expand_relu[0][0]']\n",
" iseConv2D) \n",
" \n",
" block_10_depthwise_BN (Bat (None, 14, 14, 384) 1536 ['block_10_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_10_depthwise_relu (R (None, 14, 14, 384) 0 ['block_10_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_10_project (Conv2D) (None, 14, 14, 96) 36864 ['block_10_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_10_project_BN (Batch (None, 14, 14, 96) 384 ['block_10_project[0][0]'] \n",
" Normalization) \n",
" \n",
" block_11_expand (Conv2D) (None, 14, 14, 576) 55296 ['block_10_project_BN[0][0]'] \n",
" \n",
" block_11_expand_BN (BatchN (None, 14, 14, 576) 2304 ['block_11_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_11_expand_relu (ReLU (None, 14, 14, 576) 0 ['block_11_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_11_depthwise (Depthw (None, 14, 14, 576) 5184 ['block_11_expand_relu[0][0]']\n",
" iseConv2D) \n",
" \n",
" block_11_depthwise_BN (Bat (None, 14, 14, 576) 2304 ['block_11_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_11_depthwise_relu (R (None, 14, 14, 576) 0 ['block_11_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_11_project (Conv2D) (None, 14, 14, 96) 55296 ['block_11_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_11_project_BN (Batch (None, 14, 14, 96) 384 ['block_11_project[0][0]'] \n",
" Normalization) \n",
" \n",
" block_11_add (Add) (None, 14, 14, 96) 0 ['block_10_project_BN[0][0]', \n",
" 'block_11_project_BN[0][0]'] \n",
" \n",
" block_12_expand (Conv2D) (None, 14, 14, 576) 55296 ['block_11_add[0][0]'] \n",
" \n",
" block_12_expand_BN (BatchN (None, 14, 14, 576) 2304 ['block_12_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_12_expand_relu (ReLU (None, 14, 14, 576) 0 ['block_12_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_12_depthwise (Depthw (None, 14, 14, 576) 5184 ['block_12_expand_relu[0][0]']\n",
" iseConv2D) \n",
" \n",
" block_12_depthwise_BN (Bat (None, 14, 14, 576) 2304 ['block_12_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_12_depthwise_relu (R (None, 14, 14, 576) 0 ['block_12_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_12_project (Conv2D) (None, 14, 14, 96) 55296 ['block_12_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_12_project_BN (Batch (None, 14, 14, 96) 384 ['block_12_project[0][0]'] \n",
" Normalization) \n",
" \n",
" block_12_add (Add) (None, 14, 14, 96) 0 ['block_11_add[0][0]', \n",
" 'block_12_project_BN[0][0]'] \n",
" \n",
" block_13_expand (Conv2D) (None, 14, 14, 576) 55296 ['block_12_add[0][0]'] \n",
" \n",
" block_13_expand_BN (BatchN (None, 14, 14, 576) 2304 ['block_13_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_13_expand_relu (ReLU (None, 14, 14, 576) 0 ['block_13_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_13_pad (ZeroPadding2 (None, 15, 15, 576) 0 ['block_13_expand_relu[0][0]']\n",
" D) \n",
" \n",
" block_13_depthwise (Depthw (None, 7, 7, 576) 5184 ['block_13_pad[0][0]'] \n",
" iseConv2D) \n",
" \n",
" block_13_depthwise_BN (Bat (None, 7, 7, 576) 2304 ['block_13_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_13_depthwise_relu (R (None, 7, 7, 576) 0 ['block_13_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_13_project (Conv2D) (None, 7, 7, 160) 92160 ['block_13_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_13_project_BN (Batch (None, 7, 7, 160) 640 ['block_13_project[0][0]'] \n",
" Normalization) \n",
" \n",
" block_14_expand (Conv2D) (None, 7, 7, 960) 153600 ['block_13_project_BN[0][0]'] \n",
" \n",
" block_14_expand_BN (BatchN (None, 7, 7, 960) 3840 ['block_14_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_14_expand_relu (ReLU (None, 7, 7, 960) 0 ['block_14_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_14_depthwise (Depthw (None, 7, 7, 960) 8640 ['block_14_expand_relu[0][0]']\n",
" iseConv2D) \n",
" \n",
" block_14_depthwise_BN (Bat (None, 7, 7, 960) 3840 ['block_14_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_14_depthwise_relu (R (None, 7, 7, 960) 0 ['block_14_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_14_project (Conv2D) (None, 7, 7, 160) 153600 ['block_14_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_14_project_BN (Batch (None, 7, 7, 160) 640 ['block_14_project[0][0]'] \n",
" Normalization) \n",
" \n",
" block_14_add (Add) (None, 7, 7, 160) 0 ['block_13_project_BN[0][0]', \n",
" 'block_14_project_BN[0][0]'] \n",
" \n",
" block_15_expand (Conv2D) (None, 7, 7, 960) 153600 ['block_14_add[0][0]'] \n",
" \n",
" block_15_expand_BN (BatchN (None, 7, 7, 960) 3840 ['block_15_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_15_expand_relu (ReLU (None, 7, 7, 960) 0 ['block_15_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_15_depthwise (Depthw (None, 7, 7, 960) 8640 ['block_15_expand_relu[0][0]']\n",
" iseConv2D) \n",
" \n",
" block_15_depthwise_BN (Bat (None, 7, 7, 960) 3840 ['block_15_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_15_depthwise_relu (R (None, 7, 7, 960) 0 ['block_15_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_15_project (Conv2D) (None, 7, 7, 160) 153600 ['block_15_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_15_project_BN (Batch (None, 7, 7, 160) 640 ['block_15_project[0][0]'] \n",
" Normalization) \n",
" \n",
" block_15_add (Add) (None, 7, 7, 160) 0 ['block_14_add[0][0]', \n",
" 'block_15_project_BN[0][0]'] \n",
" \n",
" block_16_expand (Conv2D) (None, 7, 7, 960) 153600 ['block_15_add[0][0]'] \n",
" \n",
" block_16_expand_BN (BatchN (None, 7, 7, 960) 3840 ['block_16_expand[0][0]'] \n",
" ormalization) \n",
" \n",
" block_16_expand_relu (ReLU (None, 7, 7, 960) 0 ['block_16_expand_BN[0][0]'] \n",
" ) \n",
" \n",
" block_16_depthwise (Depthw (None, 7, 7, 960) 8640 ['block_16_expand_relu[0][0]']\n",
" iseConv2D) \n",
" \n",
" block_16_depthwise_BN (Bat (None, 7, 7, 960) 3840 ['block_16_depthwise[0][0]'] \n",
" chNormalization) \n",
" \n",
" block_16_depthwise_relu (R (None, 7, 7, 960) 0 ['block_16_depthwise_BN[0][0]'\n",
" eLU) ] \n",
" \n",
" block_16_project (Conv2D) (None, 7, 7, 320) 307200 ['block_16_depthwise_relu[0][0\n",
" ]'] \n",
" \n",
" block_16_project_BN (Batch (None, 7, 7, 320) 1280 ['block_16_project[0][0]'] \n",
" Normalization) \n",
" \n",
" Conv_1 (Conv2D) (None, 7, 7, 1280) 409600 ['block_16_project_BN[0][0]'] \n",
" \n",
" Conv_1_bn (BatchNormalizat (None, 7, 7, 1280) 5120 ['Conv_1[0][0]'] \n",
" ion) \n",
" \n",
" out_relu (ReLU) (None, 7, 7, 1280) 0 ['Conv_1_bn[0][0]'] \n",
" \n",
" global_average_pooling2d ( (None, 1280) 0 ['out_relu[0][0]'] \n",
" GlobalAveragePooling2D) \n",
" \n",
" dropout (Dropout) (None, 1280) 0 ['global_average_pooling2d[0][\n",
" 0]'] \n",
" \n",
" dense (Dense) (None, 4) 5124 ['dropout[0][0]'] \n",
" \n",
"==================================================================================================\n",
"Total params: 2263108 (8.63 MB)\n",
"Trainable params: 5124 (20.02 KB)\n",
"Non-trainable params: 2257984 (8.61 MB)\n",
"__________________________________________________________________________________________________\n"
]
}
],
"source": [
"base_model = MobileNetV2(\n",
" include_top=False,\n",
" weights=\"imagenet\",\n",
" input_shape=(224, 224, 3)\n",
")\n",
"\n",
"# TANPA FINE-TUNING\n",
"base_model.trainable = False\n",
"\n",
"x = base_model.output\n",
"x = GlobalAveragePooling2D()(x)\n",
"x = Dropout(0.3)(x)\n",
"output = Dense(num_classes, activation=\"softmax\")(x)\n",
"\n",
"model = Model(inputs=base_model.input, outputs=output)\n",
"\n",
"model.compile(\n",
" optimizer=Adam(learning_rate=LEARNING_RATE),\n",
" loss=\"categorical_crossentropy\",\n",
" metrics=[\"accuracy\"]\n",
")\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "2cead982-6b0b-4b15-b37d-fc6866d972be",
"metadata": {},
"outputs": [],
"source": [
"checkpoint = ModelCheckpoint(\n",
" BEST_MODEL_PATH,\n",
" monitor=\"val_accuracy\",\n",
" save_best_only=True,\n",
" verbose=1\n",
")\n",
"\n",
"earlystop = EarlyStopping(\n",
" monitor=\"val_accuracy\",\n",
" patience=3,\n",
" restore_best_weights=True,\n",
" verbose=1\n",
")\n",
"\n",
"callbacks = [checkpoint, earlystop]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "406e979f-5bb1-4e79-8a7c-a1110a346a00",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Training...\n",
"Epoch 1/10\n",
"538/538 [==============================] - ETA: 0s - loss: 0.6850 - accuracy: 0.7490\n",
"Epoch 1: val_accuracy improved from -inf to 0.96473, saving model to C:\\Corn_Detection\\backend\\model\\model.h5\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Corn_Detection\\backend\\venv310\\lib\\site-packages\\keras\\src\\engine\\training.py:3000: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.\n",
" saving_api.save_model(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"538/538 [==============================] - 365s 675ms/step - loss: 0.6850 - accuracy: 0.7490 - val_loss: 0.1894 - val_accuracy: 0.9647\n",
"Epoch 2/10\n",
"200/538 [==========>...................] - ETA: 3:23 - loss: 0.2057 - accuracy: 0.9525"
]
}
],
"source": [
"print(\"\\nTraining...\")\n",
"\n",
"history = model.fit(\n",
" train_gen,\n",
" validation_data=val_gen,\n",
" epochs=EPOCHS,\n",
" class_weight=class_weights_dict,\n",
" callbacks=callbacks,\n",
" verbose=1\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "096ef183-2cf7-46e4-85bc-19a8e56c6890",
"metadata": {},
"outputs": [],
"source": [
"# ===============================\n",
"# LOAD MODEL TERBAIK (WAJIB!)\n",
"# ===============================\n",
"from tensorflow.keras.models import load_model\n",
"\n",
"print(\"\\nLoad Best Model...\")\n",
"best_model = load_model(BEST_MODEL_PATH)\n",
"\n",
"print(\"\\nEvaluasi Test Set (Best Model)\")\n",
"loss_test, acc_test = best_model.evaluate(test_gen)\n",
"\n",
"print(f\"Akurasi: {acc_test*100:.2f}%\")\n",
"print(f\"Loss : {loss_test:.4f}\")\n",
"\n",
"# ===============================\n",
"# PREDIKSI\n",
"# ===============================\n",
"test_gen.reset()\n",
"\n",
"y_pred = best_model.predict(test_gen)\n",
"y_pred_classes = np.argmax(y_pred, axis=1)\n",
"y_true = test_gen.classes\n",
"\n",
"class_labels = list(test_gen.class_indices.keys())\n",
"\n",
"print(\"\\nClassification Report:\")\n",
"print(classification_report(y_true, y_pred_classes, target_names=class_labels))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75ebe283-6e4a-4a9c-a229-720ecbb29697",
"metadata": {},
"outputs": [],
"source": [
"cm = confusion_matrix(y_true, y_pred_classes)\n",
"\n",
"plt.figure(figsize=(6,5))\n",
"sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',\n",
" xticklabels=class_labels,\n",
" yticklabels=class_labels)\n",
"\n",
"plt.title(\"Confusion Matrix\")\n",
"plt.xlabel(\"Predicted\")\n",
"plt.ylabel(\"Actual\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1f02d9a3-49f3-46f5-8f5e-f4ae3782d35e",
"metadata": {},
"outputs": [],
"source": [
"history_data = history.history\n",
"epochs_range = range(1, len(history_data[\"accuracy\"]) + 1)\n",
"\n",
"plt.figure(figsize=(12,5))\n",
"\n",
"# Accuracy\n",
"plt.subplot(1,2,1)\n",
"plt.plot(epochs_range, history_data[\"accuracy\"])\n",
"plt.plot(epochs_range, history_data[\"val_accuracy\"])\n",
"plt.title(\"Accuracy\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.ylabel(\"Accuracy\")\n",
"plt.legend([\"Train\", \"Val\"])\n",
"plt.grid()\n",
"\n",
"# Loss\n",
"plt.subplot(1,2,2)\n",
"plt.plot(epochs_range, history_data[\"loss\"])\n",
"plt.plot(epochs_range, history_data[\"val_loss\"])\n",
"plt.title(\"Loss\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.ylabel(\"Loss\")\n",
"plt.legend([\"Train\", \"Val\"])\n",
"plt.grid()\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9fc5de31-6604-495a-acda-d746c702ce60",
"metadata": {},
"outputs": [],
"source": [
"model.save(MODEL_PATH)\n",
"\n",
"with open(HISTORY_PATH, \"wb\") as f:\n",
" pickle.dump(history.history, f)\n",
"\n",
"print(\"Model & history tersimpan!\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

143
backend/app.py Normal file
View File

@ -0,0 +1,143 @@
from flask import Flask, request, jsonify, render_template
from werkzeug.utils import secure_filename
from flask_cors import CORS
from src.predict import predict_image
import os
# =========================
# KONFIGURASI PATH
# =========================
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
UPLOAD_FOLDER = os.path.join(BASE_DIR, "temp")
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg"}
# =========================
# INIT FLASK
# =========================
app = Flask(
__name__,
template_folder="templates",
static_folder="static"
)
CORS(app)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
# =========================
# HELPER FUNCTION
# =========================
def allowed_file(filename):
return "." in filename and \
filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
# =========================
# ROUTE HALAMAN WEB
# =========================
@app.route("/")
def index():
return render_template("index.html")
@app.route("/deteksi")
def deteksi():
return render_template("deteksi.html")
@app.route("/edukasi")
def edukasi():
return render_template("edukasi.html")
@app.route("/tentang")
def tentang():
return render_template("tentang.html")
# =========================
# API PREDIKSI
# =========================
@app.route("/predict", methods=["POST"])
def predict():
# =====================
# VALIDASI FILE
# =====================
if "image" not in request.files:
return jsonify({
"error": "File gambar tidak ditemukan"
}), 400
image_file = request.files["image"]
if image_file.filename == "":
return jsonify({
"error": "Nama file kosong"
}), 400
if not allowed_file(image_file.filename):
return jsonify({
"error": "Format file tidak didukung"
}), 400
# =====================
# SIMPAN FILE
# =====================
filename = secure_filename(image_file.filename)
image_path = os.path.join(
app.config["UPLOAD_FOLDER"],
filename
)
try:
# =====================
# SAVE FILE
# =====================
image_file.save(image_path)
print("\n=========================")
print("FILE BERHASIL DIUPLOAD")
print(image_path)
print("=========================")
# =====================
# PREDIKSI MODEL
# =====================
result = predict_image(image_path)
print("\nHASIL PREDIKSI:")
print(result)
# =====================
# RETURN JSON
# =====================
return jsonify(result)
except Exception as e:
print("\n❌ ERROR:")
print(e)
return jsonify({
"error": "Gagal melakukan prediksi"
}), 500
finally:
# =====================
# HAPUS FILE SEMENTARA
# =====================
if os.path.exists(image_path):
os.remove(image_path)
# =========================
# MAIN
# =========================
if __name__ == "__main__":
app.run(
debug=True
)

BIN
backend/contoh_dataset.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Some files were not shown because too many files have changed in this diff Show More