From fe63a50997b8dbf2b6ce1d6952404dfdb68a1a04 Mon Sep 17 00:00:00 2001 From: matthewflrnt Date: Sun, 27 Sep 2026 18:50:08 +0700 Subject: [PATCH] refactor: restrukturisasi folder eksperimen ke tasks modular --- README.md | 86 +++++++++++-------- {experiments => tasks/cnn}/04_cnn_mnist.py | 10 +-- .../cnn}/05_cnn_full_pipeline.py | 8 +- {experiments => tasks/cnn}/06_cnn_deeper.py | 6 +- .../cnn}/07_cnn_evaluation.py | 10 +-- .../mlp}/01_mlp_comparison.py | 40 ++++++++- .../mlp}/02_regularization.py | 6 +- .../mlp}/03_model_selection.py | 0 .../nlp_sentiment}/08_sentimen_gap.py | 6 +- 9 files changed, 112 insertions(+), 60 deletions(-) rename {experiments => tasks/cnn}/04_cnn_mnist.py (94%) rename {experiments => tasks/cnn}/05_cnn_full_pipeline.py (96%) rename {experiments => tasks/cnn}/06_cnn_deeper.py (97%) rename {experiments => tasks/cnn}/07_cnn_evaluation.py (97%) rename {experiments => tasks/mlp}/01_mlp_comparison.py (61%) rename {experiments => tasks/mlp}/02_regularization.py (94%) rename {experiments => tasks/mlp}/03_model_selection.py (100%) rename {experiments => tasks/nlp_sentiment}/08_sentimen_gap.py (97%) diff --git a/README.md b/README.md index a88d662..0df9762 100644 --- a/README.md +++ b/README.md @@ -6,32 +6,48 @@ Repository ini berisi implementasi tugas dan eksperimen Deep Learning, mencakup ## 📁 Struktur Folder Proyek -Struktur direktori telah dirapikan secara modular sebagai berikut: +Struktur direktori dirapikan secara modular dan terkelompok berdasarkan topik tugas: ```text kelompok3-deeplearning/ ├── .gitignore # Konfigurasi file & folder yang diabaikan git ├── requirements.txt # Daftar pustaka / dependensi Python ├── README.md # Dokumentasi utama proyek -├── docs/ # Dokumentasi dan analisis tambahan -│ └── model_selection.md # Analisis justifikasi pemilihan model (Tugas 3) -├── src/ # Modul reusable / fungsi pembantu +├── docs/ # Dokumentasi dan analisis laporan +│ ├── laporan_akhir.md +│ ├── PRESENTATION.md +│ ├── model_selection.md +│ └── analisis_evaluasi_model_sentimen_gap.md +├── src/ # Modul reusable / fungsi pembantu bersama │ ├── __init__.py │ ├── data_loader.py # Loader & preprocessor dataset MNIST (MLP & CNN) │ ├── models.py # Definisi arsitektur model (MLP, Regularized MLP, CNN) │ └── utils.py # Callback timer, manajemen folder, plotting helper -├── experiments/ # Skrip eksperimen & tugas utama -│ ├── 01_mlp_comparison.py # Tugas 1: Perbandingan 3 arsitektur MLP -│ ├── 02_regularization.py # Tugas 2: Eksperimen Regularisasi BatchNorm + Dropout -│ ├── 03_model_selection.py # Tugas 3: Implementasi contoh arsitektur model -│ └── 04_cnn_mnist.py # Tugas 4: Implementasi CNN MNIST & perbandingan vs MLP -└── results/ # Output dari eksperimen - ├── figures/ # Plot visualisasi (akurasi, loss curve, bar chart) - │ ├── hasil_cnn.png - │ └── loss_regularization.png - └── models/ # Bobot model terlatih (.keras) - ├── model_cnn_mnist.keras - └── model_c_regularized.keras +├── tasks/ # Skrip tugas yang dikelompokkan berdasarkan topik +│ ├── mlp/ # Topik 1: Multi-Layer Perceptron (MNIST) +│ │ ├── 01_mlp_comparison.py # Eksperimen perbandingan 3 arsitektur MLP +│ │ ├── 02_regularization.py # Eksperimen regularisasi (BatchNorm + Dropout) +│ │ └── 03_model_selection.py # Studi kasus pemilihan arsitektur model +│ ├── cnn/ # Topik 2: Convolutional Neural Network (MNIST) +│ │ ├── 04_cnn_mnist.py # Baseline CNN vs MLP +│ │ ├── 05_cnn_full_pipeline.py # Pipeline CNN lengkap (Loss/Acc curve, Confusion Matrix) +│ │ ├── 06_cnn_deeper.py # Eksplorasi kedalaman CNN (2 blok vs 3 blok) +│ │ └── 07_cnn_evaluation.py # Evaluasi mendalam (per-class metrics, confidence, misclassified) +│ └── nlp_sentiment/ # Topik 3: NLP Analisis Sentimen (Tokopedia) +│ └── 08_sentimen_gap.py # Klasifikasi sentimen ulasan Tokopedia (GlobalAveragePooling1D) +└── results/ # Output terorganisir per kelompok tugas + ├── 01_mlp/ + │ ├── figures/ # Visualisasi grafik MLP & regularisasi + │ ├── models/ # Model terlatih MLP (.keras) + │ └── reports/ # Laporan & ringkasan metrik MLP (.csv) + ├── 02_cnn/ + │ ├── figures/ # Visualisasi grafik, confusion matrix, error analysis CNN + │ ├── models/ # Model terlatih CNN (.keras) + │ └── reports/ # Classification report (.txt, .csv) & evaluasi CNN + └── 03_nlp_sentiment/ + ├── figures/ # Distribusi label, kurva training, confusion matrix GAP + ├── models/ # Model terlatih sentiment GAP (.keras) + └── reports/ # Classification report sentimen (.txt) ``` --- @@ -56,29 +72,27 @@ python -m venv .venv pip install -r requirements.txt ``` -### 3. Menjalankan Eksperimen +### 3. Menjalankan Tugas -Semua skrip eksperimen berada di dalam folder `experiments/`: +#### 🔹 Topik 1: Multi-Layer Perceptron (MLP) +```bash +python tasks/mlp/01_mlp_comparison.py +python tasks/mlp/02_regularization.py +python tasks/mlp/03_model_selection.py +``` -- **Eksperimen 1: Perbandingan Arsitektur MLP** - ```bash - python experiments/01_mlp_comparison.py - ``` +#### 🔹 Topik 2: Convolutional Neural Network (CNN) +```bash +python tasks/cnn/04_cnn_mnist.py +python tasks/cnn/05_cnn_full_pipeline.py +python tasks/cnn/06_cnn_deeper.py +python tasks/cnn/07_cnn_evaluation.py +``` -- **Eksperimen 2: Regularisasi (BatchNorm + Dropout)** - ```bash - python experiments/02_regularization.py - ``` - -- **Eksperimen 3: Contoh Model Selection (LSTM, CNN, NLP, XGBoost)** - ```bash - python experiments/03_model_selection.py - ``` - -- **Eksperimen 4: CNN MNIST vs MLP** - ```bash - python experiments/04_cnn_mnist.py - ``` +#### 🔹 Topik 3: NLP Analisis Sentimen +```bash +python tasks/nlp_sentiment/08_sentimen_gap.py +``` --- diff --git a/experiments/04_cnn_mnist.py b/tasks/cnn/04_cnn_mnist.py similarity index 94% rename from experiments/04_cnn_mnist.py rename to tasks/cnn/04_cnn_mnist.py index 019ce12..6146c19 100644 --- a/experiments/04_cnn_mnist.py +++ b/tasks/cnn/04_cnn_mnist.py @@ -17,7 +17,7 @@ import numpy as np import tensorflow as tf # Tambahkan root directory ke path agar dapat import dari src -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from src.data_loader import load_mnist_for_cnn from src.models import create_cnn_mnist_model @@ -105,8 +105,8 @@ def main(): print(f"Selisih parameter : {n_params - MLP_PARAMS:+,}") print("=" * 62) - # 6. Simpan grafik ke folder results/figures - results_fig_dir = os.path.join("results", "figures") + # 6. Simpan grafik ke folder results/02_cnn/figures + results_fig_dir = os.path.join("results", "02_cnn", "figures") ensure_dir(results_fig_dir) fig_path = os.path.join(results_fig_dir, "hasil_cnn.png") @@ -135,8 +135,8 @@ def main(): plt.savefig(fig_path, dpi=130) print(f"\n[INFO] Grafik disimpan di: {fig_path}") - # 7. Simpan model terlatih ke folder results/models - results_model_dir = os.path.join("results", "models") + # 7. Simpan model terlatih ke folder results/02_cnn/models + results_model_dir = os.path.join("results", "02_cnn", "models") ensure_dir(results_model_dir) model_path = os.path.join(results_model_dir, "model_cnn_mnist.keras") model.save(model_path) diff --git a/experiments/05_cnn_full_pipeline.py b/tasks/cnn/05_cnn_full_pipeline.py similarity index 96% rename from experiments/05_cnn_full_pipeline.py rename to tasks/cnn/05_cnn_full_pipeline.py index 6eebde8..336d2f0 100644 --- a/experiments/05_cnn_full_pipeline.py +++ b/tasks/cnn/05_cnn_full_pipeline.py @@ -22,7 +22,7 @@ from sklearn.metrics import classification_report, confusion_matrix import tensorflow as tf # Tambahkan root directory ke path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from src.data_loader import load_mnist_for_cnn from src.models import create_cnn_mnist_model @@ -87,7 +87,7 @@ def main(): print(f" -> Test Loss : {test_loss:.4f}") # 5. Visualisasi & Penyimpanan - figures_dir = os.path.join("results", "figures") + figures_dir = os.path.join("results", "02_cnn", "figures") ensure_dir(figures_dir) # (b) Loss & Accuracy Curve @@ -185,10 +185,10 @@ def main(): print("=" * 70 + "\n") # Simpan bobot terbaru - models_dir = os.path.join("results", "models") + models_dir = os.path.join("results", "02_cnn", "models") ensure_dir(models_dir) model.save(os.path.join(models_dir, "model_cnn_mnist.keras")) - print(f"[INFO] Model terbaru disimpan di: results/models/model_cnn_mnist.keras") + print(f"[INFO] Model terbaru disimpan di: {os.path.join(models_dir, 'model_cnn_mnist.keras')}") if __name__ == "__main__": diff --git a/experiments/06_cnn_deeper.py b/tasks/cnn/06_cnn_deeper.py similarity index 97% rename from experiments/06_cnn_deeper.py rename to tasks/cnn/06_cnn_deeper.py index 43c929f..9805b42 100644 --- a/experiments/06_cnn_deeper.py +++ b/tasks/cnn/06_cnn_deeper.py @@ -21,7 +21,7 @@ import numpy as np import tensorflow as tf # Tambahkan root directory ke path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from src.data_loader import load_mnist_for_cnn from src.models import create_cnn_mnist_model, create_deep_cnn_mnist_model @@ -104,7 +104,7 @@ def main(): histories[model_name] = history # Simpan model 3 blok - models_dir = os.path.join("results", "models") + models_dir = os.path.join("results", "02_cnn", "models") ensure_dir(models_dir) results[1]["model_obj"].save(os.path.join(models_dir, "model_cnn_3blocks.keras")) @@ -128,7 +128,7 @@ def main(): print("=" * 75) # Visualisasi - figures_dir = os.path.join("results", "figures") + figures_dir = os.path.join("results", "02_cnn", "figures") ensure_dir(figures_dir) fig_path = os.path.join(figures_dir, "perbandingan_kedalaman_cnn.png") diff --git a/experiments/07_cnn_evaluation.py b/tasks/cnn/07_cnn_evaluation.py similarity index 97% rename from experiments/07_cnn_evaluation.py rename to tasks/cnn/07_cnn_evaluation.py index 28c1245..b8777ff 100644 --- a/experiments/07_cnn_evaluation.py +++ b/tasks/cnn/07_cnn_evaluation.py @@ -43,7 +43,7 @@ import tensorflow as tf from tensorflow import keras # Tambahkan root directory ke path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from src.data_loader import load_mnist_for_cnn from src.utils import ensure_dir @@ -56,9 +56,9 @@ EPOCHS = 10 # epoch training model (didokumentasikan, tidak dipakai ula BATCH_SIZE = 128 # batch size training model (didokumentasikan, tidak dipakai ulang) OPTIMIZER = "adam" # optimizer training model (tersimpan di file .keras) -MODEL_PATH = os.path.join("results", "models", "model_cnn_mnist.keras") -FIGURES_DIR = os.path.join("results", "figures") -REPORTS_DIR = os.path.join("results", "reports") +MODEL_PATH = os.path.join("results", "02_cnn", "models", "model_cnn_mnist.keras") +FIGURES_DIR = os.path.join("results", "02_cnn", "figures") +REPORTS_DIR = os.path.join("results", "02_cnn", "reports") CLASS_NAMES = [str(i) for i in range(10)] @@ -88,7 +88,7 @@ def main(): if not os.path.exists(MODEL_PATH): raise FileNotFoundError( f"Model tidak ditemukan di '{MODEL_PATH}'. " - f"Jalankan dahulu experiments/05_cnn_full_pipeline.py (skrip Anggota 1)." + f"Jalankan dahulu tasks/cnn/05_cnn_full_pipeline.py (skrip Anggota 1)." ) model = keras.models.load_model(MODEL_PATH) print(f" -> Model '{model.name}' berhasil dimuat ({model.count_params():,} parameter).") diff --git a/experiments/01_mlp_comparison.py b/tasks/mlp/01_mlp_comparison.py similarity index 61% rename from experiments/01_mlp_comparison.py rename to tasks/mlp/01_mlp_comparison.py index b3f7215..1e364d5 100644 --- a/experiments/01_mlp_comparison.py +++ b/tasks/mlp/01_mlp_comparison.py @@ -1,9 +1,11 @@ import sys import os import time +import pandas as pd +import matplotlib.pyplot as plt # Tambahkan root directory ke path agar dapat import dari src -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from src.data_loader import load_mnist_for_mlp from src.models import create_mlp_model @@ -93,6 +95,42 @@ def main(): print(f"Jumlah Parameter : {best_model['parameters']:,}") print(f"Waktu Training/Epoch: {best_model['time_per_epoch']:.2f} detik") + # 5. Simpan Hasil ke Folder results/01_mlp + REPORTS_DIR = os.path.join("results", "01_mlp", "reports") + FIGURES_DIR = os.path.join("results", "01_mlp", "figures") + os.makedirs(REPORTS_DIR, exist_ok=True) + os.makedirs(FIGURES_DIR, exist_ok=True) + + df_results = pd.DataFrame(results) + csv_path = os.path.join(REPORTS_DIR, "perbandingan_mlp.csv") + df_results.to_csv(csv_path, index=False) + print(f"\n[OK] Ringkasan CSV disimpan ke : {csv_path}") + + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) + names = ["Model A\n(1 Layer)", "Model B\n(2 Layer)", "Model C\n(3 Layer)"] + accs = [r["accuracy"] for r in results] + bars1 = ax1.bar(names, accs, color=["#4C72B0", "#55A868", "#C44E52"]) + ax1.set_title("Perbandingan Test Accuracy (%)", fontsize=12, fontweight="bold") + ax1.set_ylabel("Accuracy (%)") + ax1.set_ylim([max(0, min(accs) - 2), 100]) + for bar in bars1: + yval = bar.get_height() + ax1.text(bar.get_x() + bar.get_width()/2, yval + 0.2, f"{yval:.2f}%", ha='center', va='bottom') + + times = [r["time_per_epoch"] for r in results] + bars2 = ax2.bar(names, times, color=["#4C72B0", "#55A868", "#C44E52"]) + ax2.set_title("Waktu Training per Epoch (detik)", fontsize=12, fontweight="bold") + ax2.set_ylabel("Detik / Epoch") + for bar in bars2: + yval = bar.get_height() + ax2.text(bar.get_x() + bar.get_width()/2, yval + 0.05, f"{yval:.2f}s", ha='center', va='bottom') + + plt.tight_layout() + fig_path = os.path.join(FIGURES_DIR, "perbandingan_3_model_mlp.png") + plt.savefig(fig_path, dpi=130) + plt.close() + print(f"[OK] Grafik perbandingan disimpan ke: {fig_path}") + if __name__ == "__main__": main() diff --git a/experiments/02_regularization.py b/tasks/mlp/02_regularization.py similarity index 94% rename from experiments/02_regularization.py rename to tasks/mlp/02_regularization.py index a149351..9a081f9 100644 --- a/experiments/02_regularization.py +++ b/tasks/mlp/02_regularization.py @@ -5,7 +5,7 @@ matplotlib.use("Agg") import matplotlib.pyplot as plt # Tambahkan root directory ke path agar dapat import dari src -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from src.data_loader import load_mnist_for_mlp from src.models import create_mlp_model, create_regularized_mlp_model @@ -50,14 +50,14 @@ def main(): ) # 4. Save Model Artifact - results_model_dir = os.path.join("results", "models") + results_model_dir = os.path.join("results", "01_mlp", "models") ensure_dir(results_model_dir) model_reg_path = os.path.join(results_model_dir, "model_c_regularized.keras") model_reg.save(model_reg_path) print(f"\n[INFO] Model teregularisasi disimpan di: {model_reg_path}") # 5. Plot Comparison Curves - results_fig_dir = os.path.join("results", "figures") + results_fig_dir = os.path.join("results", "01_mlp", "figures") ensure_dir(results_fig_dir) fig_path = os.path.join(results_fig_dir, "loss_regularization.png") diff --git a/experiments/03_model_selection.py b/tasks/mlp/03_model_selection.py similarity index 100% rename from experiments/03_model_selection.py rename to tasks/mlp/03_model_selection.py diff --git a/experiments/08_sentimen_gap.py b/tasks/nlp_sentiment/08_sentimen_gap.py similarity index 97% rename from experiments/08_sentimen_gap.py rename to tasks/nlp_sentiment/08_sentimen_gap.py index a7cd5cd..3020c7d 100644 --- a/experiments/08_sentimen_gap.py +++ b/tasks/nlp_sentiment/08_sentimen_gap.py @@ -32,9 +32,9 @@ EPOCHS = 20 BATCH_SIZE = 64 RANDOM_STATE = 42 -FIGURES_DIR = "results/figures" -REPORTS_DIR = "results/reports" -MODELS_DIR = "results/models" +FIGURES_DIR = os.path.join("results", "03_nlp_sentiment", "figures") +REPORTS_DIR = os.path.join("results", "03_nlp_sentiment", "reports") +MODELS_DIR = os.path.join("results", "03_nlp_sentiment", "models") os.makedirs(FIGURES_DIR, exist_ok=True) os.makedirs(REPORTS_DIR, exist_ok=True)