Teknik-Informatika-PSDKU-Ng.../backend/Training.ipynb

851 lines
59 KiB
Plaintext

{
"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
}