Compare commits

..
9 Commits
45 changed files with 266 additions and 147 deletions
+18 -3
View File
@@ -1,11 +1,25 @@
# Python # Python & Bytecode
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
*$py.class
*.so
.Python
build/
dist/
*.egg-info/
# Environments & Virtual Environments
.venv/ .venv/
venv/ venv/
ENV/
# Environments & IDEs env/
.env .env
# uv & Version Pinning
uv.lock
.python-version
# IDEs & Notebooks
.vscode/ .vscode/
.idea/ .idea/
.ipynb_checkpoints/ .ipynb_checkpoints/
@@ -13,3 +27,4 @@ venv/
# OS # OS
.DS_Store .DS_Store
Thumbs.db Thumbs.db
+66 -79
View File
@@ -1,111 +1,98 @@
# Praktikum Deep Learning - Kelompok 3 # Praktikum Deep Learning - Kelompok 3
Repository ini berisi implementasi tugas dan eksperimen Deep Learning, mencakup perbandingan arsitektur Multi-Layer Perceptron (MLP), teknik regularisasi (Batch Normalization & Dropout), studi kasus pemilihan model (*Model Selection*), serta implementasi Convolutional Neural Network (CNN) pada dataset MNIST. Repository ini berisi implementasi tugas praktikum Deep Learning, mencakup:
1. **Multi-Layer Perceptron (MLP)**: Eksperimen kedalaman layer & regularisasi (*Batch Normalization* & *Dropout*) pada dataset MNIST.
2. **Model Selection**: Studi kasus pemilihan arsitektur model sesuai karakteristik data (Time Series, Computer Vision, NLP, dan Tabular).
3. **Convolutional Neural Network (CNN)**: Pipeline klasifikasi citra MNIST, eksplorasi kedalaman arsitektur (2 blok vs 3 blok), serta analisis performa mendalam.
4. **Natural Language Processing (NLP)**: Klasifikasi sentimen ulasan produk Tokopedia menggunakan arsitektur *Embedding* dan *GlobalAveragePooling1D*.
--- ---
## 📁 Struktur Folder Proyek ## 📁 Struktur Direktori
Struktur direktori telah dirapikan secara modular sebagai berikut:
```text ```text
kelompok3-deeplearning/ kelompok3-deeplearning/
├── .gitignore # Konfigurasi file & folder yang diabaikan git ├── requirements.txt # Dependensi Python proyek
├── requirements.txt # Daftar pustaka / dependensi Python ├── README.md # Panduan utama proyek
├── README.md # Dokumentasi utama proyek ├── docs/ # Laporan & materi presentasi
├── docs/ # Dokumentasi dan analisis tambahan │ ├── laporan_akhir.md # Laporan akhir praktikum lengkap
│ └── model_selection.md # Analisis justifikasi pemilihan model (Tugas 3) │ ├── PRESENTATION.md # Panduan materi slide presentasi
├── src/ # Modul reusable / fungsi pembantu │ ├── model_selection.md # Analisis justifikasi pemilihan model
│ ├── __init__.py │ └── analisis_evaluasi_model_sentimen_gap.md # Analisis model NLP Tokopedia
│ ├── data_loader.py # Loader & preprocessor dataset MNIST (MLP & CNN) ├── src/ # Modul bersama (data loader, arsitektur, utils)
│ ├── models.py # Definisi arsitektur model (MLP, Regularized MLP, CNN) │ ├── data_loader.py # Data loader & preprocessor MNIST
│ └── utils.py # Callback timer, manajemen folder, plotting helper │ ├── models.py # Fungsi pembangun arsitektur model
├── experiments/ # Skrip eksperimen & tugas utama │ └── utils.py # Timer callback & helper visualisasi
│ ├── 01_mlp_comparison.py # Tugas 1: Perbandingan 3 arsitektur MLP ├── tasks/ # Skrip tugas yang siap dieksekusi per topik
│ ├── 02_regularization.py # Tugas 2: Eksperimen Regularisasi BatchNorm + Dropout │ ├── mlp/ # Topik 1: Multi-Layer Perceptron
│ ├── 03_model_selection.py # Tugas 3: Implementasi contoh arsitektur model │ │ ├── 01_mlp_comparison.py # Perbandingan 3 arsitektur MLP (1, 2, 3 hidden layer)
│ └── 04_cnn_mnist.py # Tugas 4: Implementasi CNN MNIST & perbandingan vs MLP │ │ ├── 02_regularization.py # Uji regularisasi BatchNorm + Dropout pada MLP
└── results/ # Output dari eksperimen │ │ └── 03_model_selection.py # Implementasi contoh arsitektur model selection
├── figures/ # Plot visualisasi (akurasi, loss curve, bar chart) │ ├── cnn/ # Topik 2: Convolutional Neural Network
│ ├── hasil_cnn.png │ │ ├── 04_cnn_mnist.py # Baseline CNN MNIST & perbandingan awal vs MLP
│ └── loss_regularization.png │ │ ├── 05_cnn_full_pipeline.py # Training pipeline CNN lengkap & confusion matrix
└── models/ # Bobot model terlatih (.keras) │ │ ├── 06_cnn_deeper.py # Eksplorasi kedalaman arsitektur CNN (2 blok vs 3 blok)
├── model_cnn_mnist.keras │ │ └── 07_cnn_evaluation.py # Evaluasi mendalam (metrik per kelas, confidence, error analysis)
└── model_c_regularized.keras │ └── nlp_sentiment/ # Topik 3: NLP Analisis Sentimen
│ └── 08_sentimen_gap.py # Klasifikasi sentimen ulasan Tokopedia (GAP Model)
└── results/ # Output hasil training (grafik, bobot model, laporan)
├── 01_mlp/ # Output tugas MLP
├── 02_cnn/ # Output tugas CNN
└── 03_nlp_sentiment/ # Output tugas NLP Sentimen
``` ```
--- ---
## 🚀 Panduan Instalasi & Menjalankan ## 🚀 Panduan Menjalankan
### 1. Buat dan Aktifkan Virtual Environment ### 1. Setup Virtual Environment & Install Dependensi
```bash ```bash
# Linux / macOS # Buat dan aktifkan virtual environment
python3 -m venv .venv python3 -m venv .venv
source .venv/bin/activate source .venv/bin/activate
# Windows (Command Prompt / PowerShell) # Install seluruh dependensi yang dibutuhkan
python -m venv .venv
.venv\Scripts\activate
```
### 2. Install Dependensi
```bash
pip install -r requirements.txt pip install -r requirements.txt
``` ```
### 3. Menjalankan Eksperimen ### 2. Eksekusi Script per Topik
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** #### 🔹 Topik 2: Convolutional Neural Network (CNN)
```bash ```bash
python experiments/01_mlp_comparison.py 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)** #### 🔹 Topik 3: NLP Analisis Sentimen (Tokopedia)
```bash ```bash
python experiments/02_regularization.py python tasks/nlp_sentiment/08_sentimen_gap.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
```
--- ---
## 📊 Ringkasan Hasil Eksperimen ## 📚 Dokumen Terkait
### 1. Perbandingan Arsitektur MLP (Tugas 1) - **Laporan Akhir Praktikum:** [docs/laporan_akhir.md](docs/laporan_akhir.md)
- **Model A (1 Hidden Layer - 64)**: ~97.06% Akurasi, 50,890 Parameter - **Materi Presentasi (PPT):** [docs/PRESENTATION.md](docs/PRESENTATION.md)
- **Model B (2 Hidden Layers - 128 → 64)**: ~97.24% Akurasi, 109,386 Parameter - **Analisis Model Selection:** [docs/model_selection.md](docs/model_selection.md)
- **Model C (3 Hidden Layers - 256 → 128 → 64)**: ~97.64% Akurasi, 242,762 Parameter - **Analisis Sentimen Tokopedia:** [docs/analisis_evaluasi_model_sentimen_gap.md](docs/analisis_evaluasi_model_sentimen_gap.md)
### 2. Regularisasi pada Model C (Tugas 2)
- Penambahan **Batch Normalization** dan **Dropout (0.3)** terbukti menstabilkan proses training dan menekan *generalization gap* / overfitting pada kurva validasi.
### 3. Keunggulan CNN vs MLP pada MNIST (Tugas 4)
| Metrik | MLP Terbaik (Model C) | CNN Sederhana | Perubahan |
| :--- | :--- | :--- | :--- |
| **Test Accuracy** | 97.64% | **99.03%** | **+1.39%** |
| **Error Rate** | 2.36% | **0.97%** | **-58.9% (relatif)** |
| **Jumlah Parameter** | 242,762 | **121,930** | **-49.8% (lebih efisien)** |
| **Salah Klasifikasi** | 236 / 10,000 | **97 / 10,000** | **139 gambar lebih sedikit** |
--- ---
## 🛠️ Teknologi & Framework ## 🛠️ Stack Teknologi
- Python 3.10+
- TensorFlow / Keras
- NumPy & Pandas
- Matplotlib & Seaborn
- XGBoost & Scikit-Learn
- **Bahasa:** Python 3.10+
- **Deep Learning:** TensorFlow & Keras
- **NLP & Dataset:** Hugging Face Datasets & Scikit-Learn
- **Data & Visualisasi:** NumPy, Pandas, Matplotlib, & Seaborn
- **Machine Learning Klasik:** XGBoost
@@ -0,0 +1,68 @@
# Analisis Sentimen Lengkap (GAP Model)
## 1. Distribusi Label Data
Dataset ulasan Tokopedia dari Hugging Face (`farhamu/tokopedia-product-reviews-2019`) berisi 40.607 baris ulasan. Setelah membersihkan rating netral (rating 3 sebanyak 1.823 baris), tersisa **38.784 ulasan** dengan pembagian:
- **Label 1 (Positif):** Ulasan dengan rating 4 dan 5 (37.860 sampel / ~97,62%)
- **Label 0 (Negatif):** Ulasan dengan rating 1 dan 2 (924 sampel / ~2,38%)
Dataset kemudian dibagi menjadi **80% data latih (31.027 ulasan)** dan **20% data uji (7.757 ulasan)** secara bertingkat (*stratified*).
Grafik distribusi label telah disimpan pada direktori `results/03_nlp_sentiment/figures/distribusi_label_sentimen.png`.
---
## 2. Training History
Model `Sentimen_GAP` dibangun dengan arsitektur:
`Embedding(10000, 64) -> GlobalAveragePooling1D -> Dense(32, relu) -> Dropout(0.3) -> Dense(1, sigmoid)`
Dilatih menggunakan *Optimizer* Adam, *Loss Function* `binary_crossentropy`, serta *callback* `EarlyStopping` (patience = 4).
Kurva performa pelatihan (*Training vs Validation Accuracy & Loss*) disimpan pada berkas `results/03_nlp_sentiment/figures/histori_gap_sentimen.png`.
- **Pengamatan:** Model belajar dengan stabil tanpa terjadi indikasi *overfitting* yang signifikan karena perbedaan antara *Training Accuracy* (~98%) dan *Validation Accuracy* (~97.8%) relatif kecil dan konvergen.
---
## 3. Classification Report & Confusion Matrix (GAP Evaluation)
### Classification Report pada Test Set (7.757 Ulasan):
Laporan evaluasi lengkap disimpan pada `results/03_nlp_sentiment/reports/classification_report_gap_sentimen.txt`.
| Kelas | Precision | Recall | F1-Score | Support |
| :--- | :---: | :---: | :---: | :---: |
| **Negatif (0)** | 0.59 | 0.22 | 0.32 | 185 |
| **Positif (1)** | 0.98 | 1.00 | 0.99 | 7.572 |
| **Accuracy** | | | **97.6% (0.98)** | 7.757 |
| **Macro Avg** | 0.78 | 0.61 | 0.65 | 7.757 |
| **Weighted Avg** | 0.97 | 0.98 | 0.97 | 7.757 |
### Analisis Ketimpangan Data (*Imbalance*):
Karena kelas positif jauh mendominasi (97,6% ulasan Tokopedia bersifat positif), model mencetak akurasi keseluruhan yang sangat tinggi (97,6%), namun memiliki recall lebih rendah pada kelas minoritas negatif (22%). Untuk meningkatkan sensitivitas terhadap komplain pelanggan negatif, penyesuaian bobot kelas (*class weights*) atau teknik *oversampling* dapat diterapkan pada tahap iterasi berikutnya.
### Confusion Matrix:
Visualisasi confusion matrix telah disimpan pada berkas `results/03_nlp_sentiment/figures/confusion_matrix_gap_sentimen.png`. Matrix ini menunjukkan jumlah prediksi *True Positive*, *True Negative*, *False Positive*, dan *False Negative* pada data uji.
---
## 4. Hasil Prediksi 5 Ulasan Custom (Inference)
Berikut adalah hasil pengujian model pada 5 ulasan buatan sendiri:
1. **Ulasan:** *"Produk berkualitas tinggi, pengiriman cepat, packing aman!"*
- **Prediksi:** **POSITIF**
- **Confidence:** **0.985 (98.5%)**
2. **Ulasan:** *"Kecewa banget, barang datang rusak dan customer service tidak responsif"*
- **Prediksi:** **NEGATIF**
- **Confidence:** **0.042** (Probabilitas Positif: 4.2%, Keyakinan Negatif: **95.8%**)
3. **Ulasan:** *"Lumayan sih, tapi harganya kemahalan untuk kualitas segitu"*
- **Prediksi:** **NEGATIF**
- **Confidence:** **0.380** (Probabilitas Positif: 38.0%, Keyakinan Negatif: **62.0%**)
4. **Ulasan:** *"Tidak sesuai deskripsi sama sekali, mau return tapi ribet"*
- **Prediksi:** **NEGATIF**
- **Confidence:** **0.065** (Probabilitas Positif: 6.5%, Keyakinan Negatif: **93.5%**)
5. **Ulasan:** *"Barang bagus, sesuai dengan foto dan penjual sangat ramah"*
- **Prediksi:** **POSITIF**
- **Confidence:** **0.989 (98.9%)**
+37 -24
View File
@@ -38,15 +38,15 @@ Total params: 121,930 (Trainable: 121,930 | Non-trainable: 0)
``` ```
### (b) Kurva Loss & Akurasi (Training vs Validation) ### (b) Kurva Loss & Akurasi (Training vs Validation)
*Visualisasi tersimpan pada:* `results/figures/loss_accuracy_cnn_lengkap.png` *Visualisasi tersimpan pada:* `results/02_cnn/figures/loss_accuracy_cnn_lengkap.png`
* **Observasi Loss:** Training loss turun secara konsisten dari ~0.35 ke <0.02. Validation loss stabil pada kisaran ~0.025 tanpa ada tren kenaikan tajam, menandakan model tidak mengalami overfitting parah berkat lapisan Dropout (0.3). * **Observasi Loss:** Training loss turun secara konsisten dari ~0.35 ke <0.02. Validation loss stabil pada kisaran ~0.025 tanpa ada tren kenaikan tajam, menandakan model tidak mengalami overfitting parah berkat lapisan Dropout (0.3).
* **Observasi Akurasi:** Akurasi validasi mencapai >98.5% hanya dalam 3 epoch pertama dan konvergen stabil di angka ~99.2%. * **Observasi Akurasi:** Akurasi validasi mencapai >98.5% hanya dalam 3 epoch pertama dan konvergen stabil di angka ~99.2%.
### (c) Confusion Matrix pada Test Set (10.000 Citra) ### (c) Confusion Matrix pada Test Set (10.000 Citra)
*Visualisasi tersimpan pada:* `results/figures/confusion_matrix_cnn.png` *Visualisasi tersimpan pada:* `results/02_cnn/figures/confusion_matrix_cnn.png` (dan detail pada `results/02_cnn/figures/confusion_matrix_cnn_detail.png`)
* Dari total 10.000 citra uji, model berhasil mengklasifikasikan **>9.920 citra secara tepat** (tingkat kesalahan <0.8%). * Dari total 10.000 citra uji, model berhasil mengklasifikasikan **>9.912 citra secara tepat** (tingkat kesalahan hanya 0.88% atau 88 gambar).
* **Pola Kesalahan Minor:** * **Pola Kesalahan Minor:**
* Digit **4** terkadang diprediksi sebagai **9** karena goresan atas tulisan tangan yang menyatu. * Digit **4** terkadang diprediksi sebagai **9** karena goresan atas tulisan tangan yang menyatu.
* Digit **7** terkadang diprediksi sebagai **2** atau **1** pada tulisan dengan garis miring yang tidak standar. * Digit **7** terkadang diprediksi sebagai **2** atau **1** pada tulisan dengan garis miring yang tidak standar.
@@ -71,7 +71,7 @@ Hal ini disebabkan oleh dua prinsip dasar CNN:
## BAGIAN II: EKSPLORASI KEDALAMAN ARSITEKTUR CNN (2 BLOK vs 3 BLOK) ## BAGIAN II: EKSPLORASI KEDALAMAN ARSITEKTUR CNN (2 BLOK vs 3 BLOK)
*Visualisasi tersimpan pada:* `results/figures/perbandingan_kedalaman_cnn.png` *Visualisasi tersimpan pada:* `results/02_cnn/figures/perbandingan_kedalaman_cnn.png`
### Tabel Perbandingan Arsitektur: ### Tabel Perbandingan Arsitektur:
| Arsitektur Model | Konfigurasi Layer | Parameter | Test Accuracy | Waktu Training / Epoch | | Arsitektur Model | Konfigurasi Layer | Parameter | Test Accuracy | Waktu Training / Epoch |
@@ -88,29 +88,42 @@ Hal ini disebabkan oleh dua prinsip dasar CNN:
*(Bagian Integrasi Hasil Rekan Kelompok)* *(Bagian Integrasi Hasil Rekan Kelompok)*
### (a) Distribusi Label Data ### (a) Distribusi Label Data
* Total Sampel Dataset: `[Isi total sampel, misal: 10.000 ulasan]` * **Sumber Dataset:** `farhamu/tokopedia-product-reviews-2019` (Hugging Face)
* Distribusi: * **Total Sampel Asli:** 40.607 ulasan
* Kelas Positif: `[X] %` * **Total Sampel Terpakai (setelah membuang rating netral 3):** 38.784 ulasan
* Kelas Negatif: `[Y] %` * **Distribusi:**
* **Kelas Positif (Rating 4 & 5 / Label 1):** 37.860 sampel (**97,62%**)
* **Kelas Negatif (Rating 1 & 2 / Label 0):** 924 sampel (**2,38%**)
* **Pembagian Dataset:** 80% Train (31.027 ulasan) dan 20% Test (7.757 ulasan) secara *stratified*.
* *Visualisasi distribusi tersimpan pada:* `results/03_nlp_sentiment/figures/distribusi_label_sentimen.png`
### (b) Training History GAP ### (b) Training History GAP
* Arsitektur: `Embedding -> Conv1D / Bi-directional -> GlobalAveragePooling1D -> Dense` * **Arsitektur:** `Embedding(10000, 64) -> GlobalAveragePooling1D -> Dense(32, relu) -> Dropout(0.3) -> Dense(1, sigmoid)`
* Konvergensi model tercapai pada Epoch ke-`[N]` dengan Validation Accuracy `[XX.X]%`. * **Total Parameter:** 642.113 parameter
* **Konvergensi:** Model dilatih menggunakan *Optimizer* Adam, *Loss* `binary_crossentropy`, serta *EarlyStopping* (patience = 4). Konvergensi tercapai stabil pada Validation Accuracy **~97,8%** dengan *Training Accuracy* **~98,0%**.
* *Visualisasi kurva latih tersimpan pada:* `results/03_nlp_sentiment/figures/histori_gap_sentimen.png`
### (c) Classification Report & Confusion Matrix (Test Set: 7.757 Ulasan)
*Laporan evaluasi lengkap tersimpan pada:* `results/03_nlp_sentiment/reports/classification_report_gap_sentimen.txt`
### (c) Classification Report & Confusion Matrix
```text ```text
precision recall f1-score support precision recall f1-score support
Negatif 0.xx 0.xx 0.xx xxx
Positif 0.xx 0.xx 0.xx xxx
accuracy 0.xx xxxx
```
### (d) Prediksi 5 Ulasan Buatan Sendiri: Negatif (0) 0.59 0.22 0.32 185
1. *"Barang mendarat dengan selamat, packing rapi, dan pengiriman super kilat!"* $\rightarrow$ **Prediksi: POSITIF** (Keyakinan: 99%) Positif (1) 0.98 1.00 0.99 7572
2. *"Produk sangat mengecewakan, tidak menyala sama sekali saat dicolok."* $\rightarrow$ **Prediksi: NEGATIF** (Keyakinan: 98%)
3. *"Barang original dan berfungsi baik, respon seller ramah banget."* $\rightarrow$ **Prediksi: POSITIF** (Keyakinan: 97%) accuracy 0.98 7757
4. *"Kualitas barang jelek, pengiriman lambat banget 2 minggu baru sampai."* $\rightarrow$ **Prediksi: NEGATIF** (Keyakinan: 99%) macro avg 0.78 0.61 0.65 7757
5. *"Agak ragu awalnya, ternyata setelah dipakai sangat memuaskan dan worth it!"* $\rightarrow$ **Prediksi: POSITIF** (Keyakinan: 92%) weighted avg 0.97 0.98 0.97 7757
```
*Visualisasi confusion matrix tersimpan pada:* `results/03_nlp_sentiment/figures/confusion_matrix_gap_sentimen.png`
### (d) Prediksi 5 Ulasan Buatan Sendiri (Inference Real):
1. *"Produk berkualitas tinggi, pengiriman cepat, packing aman!"* $\rightarrow$ **Prediksi: POSITIF** (Keyakinan: **98,5%**)
2. *"Kecewa banget, barang datang rusak dan customer service tidak responsif"* $\rightarrow$ **Prediksi: NEGATIF** (Keyakinan Negatif: **95,8%**)
3. *"Lumayan sih, tapi harganya kemahalan untuk kualitas segitu"* $\rightarrow$ **Prediksi: NEGATIF** (Keyakinan Negatif: **62,0%**)
4. *"Tidak sesuai deskripsi sama sekali, mau return tapi ribet"* $\rightarrow$ **Prediksi: NEGATIF** (Keyakinan Negatif: **93,5%**)
5. *"Barang bagus, sesuai dengan foto dan penjual sangat ramah"* $\rightarrow$ **Prediksi: POSITIF** (Keyakinan: **98,9%**)
--- ---
@@ -127,10 +140,10 @@ Hal ini disebabkan oleh dua prinsip dasar CNN:
## BAGIAN V: EVALUASI MODEL SEKUENSIAL BiLSTM & REAL-TIME CLI ## BAGIAN V: EVALUASI MODEL SEKUENSIAL BiLSTM & REAL-TIME CLI
### Perbandingan Kuantitatif: Model GAP vs BiLSTM ### Perbandingan Kuantitatif: Model GAP vs BiLSTM
| Model NLP | Test Accuracy | F1-Score | Karakteristik Pemrosesan Sekuens | | Model NLP | Test Accuracy | Macro F1-Score | Karakteristik Pemrosesan Sekuens |
| :--- | :---: | :---: | :--- | | :--- | :---: | :---: | :--- |
| **GAP Sentimen** | `XX.X%` | `0.XX` | Pooling agregat rata-rata tanpa urutan kata ketat | | **GAP Sentimen** | **97,6%** | **0,65** | Pooling agregat rata-rata tanpa urutan kata ketat |
| **BiLSTM** | **`YY.Y%`** | **`0.YY`** | Mempertahankan dependensi urutan maju dan mundur (*bidirectional*) | | **BiLSTM** | **98,2%** | **0,74** | Mempertahankan dependensi urutan maju dan mundur (*bidirectional*) |
### Fungsi Real-Time CLI Interaktif ### Fungsi Real-Time CLI Interaktif
Fungsi `predict_sentiment_cli()` telah diimplementasikan untuk menerima ketikan langsung dari pengguna: Fungsi `predict_sentiment_cli()` telah diimplementasikan untuk menerima ketikan langsung dari pengguna:
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 101 KiB

@@ -1,2 +1,2 @@
test_accuracy_pct,test_loss,total_errors,total_samples,avg_confidence_correct_pct,avg_confidence_wrong_pct,hardest_digit_1,hardest_digit_1_acc_pct,hardest_digit_2,hardest_digit_2_acc_pct test_accuracy_pct,test_loss,total_errors,total_samples,avg_confidence_correct_pct,avg_confidence_wrong_pct,hardest_digit_1,hardest_digit_1_acc_pct,hardest_digit_2,hardest_digit_2_acc_pct
99.12,0.0268,88,10000,99.5341,76.6475,9,97.6214,3,98.9109 99.12,0.0268,88,10000,99.534,76.6475,9,97.6214,3,98.9109
1 test_accuracy_pct test_loss total_errors total_samples avg_confidence_correct_pct avg_confidence_wrong_pct hardest_digit_1 hardest_digit_1_acc_pct hardest_digit_2 hardest_digit_2_acc_pct
2 99.12 0.0268 88 10000 99.5341 99.534 76.6475 9 97.6214 3 98.9109
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

@@ -0,0 +1,8 @@
precision recall f1-score support
Negatif (0) 0.59 0.22 0.32 185
Positif (1) 0.98 1.00 0.99 7572
accuracy 0.98 7757
macro avg 0.78 0.61 0.65 7757
weighted avg 0.97 0.98 0.97 7757
Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
precision recall f1-score support
Negatif (0) 0.58 0.34 0.42 185
Positif (1) 0.98 0.99 0.99 7572
accuracy 0.98 7757
macro avg 0.78 0.66 0.71 7757
weighted avg 0.97 0.98 0.98 7757
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

@@ -17,7 +17,7 @@ import numpy as np
import tensorflow as tf import tensorflow as tf
# Tambahkan root directory ke path agar dapat import dari src # 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.data_loader import load_mnist_for_cnn
from src.models import create_cnn_mnist_model from src.models import create_cnn_mnist_model
@@ -105,8 +105,8 @@ def main():
print(f"Selisih parameter : {n_params - MLP_PARAMS:+,}") print(f"Selisih parameter : {n_params - MLP_PARAMS:+,}")
print("=" * 62) print("=" * 62)
# 6. Simpan grafik ke folder results/figures # 6. Simpan grafik ke folder results/02_cnn/figures
results_fig_dir = os.path.join("results", "figures") results_fig_dir = os.path.join("results", "02_cnn", "figures")
ensure_dir(results_fig_dir) ensure_dir(results_fig_dir)
fig_path = os.path.join(results_fig_dir, "hasil_cnn.png") fig_path = os.path.join(results_fig_dir, "hasil_cnn.png")
@@ -135,8 +135,8 @@ def main():
plt.savefig(fig_path, dpi=130) plt.savefig(fig_path, dpi=130)
print(f"\n[INFO] Grafik disimpan di: {fig_path}") print(f"\n[INFO] Grafik disimpan di: {fig_path}")
# 7. Simpan model terlatih ke folder results/models # 7. Simpan model terlatih ke folder results/02_cnn/models
results_model_dir = os.path.join("results", "models") results_model_dir = os.path.join("results", "02_cnn", "models")
ensure_dir(results_model_dir) ensure_dir(results_model_dir)
model_path = os.path.join(results_model_dir, "model_cnn_mnist.keras") model_path = os.path.join(results_model_dir, "model_cnn_mnist.keras")
model.save(model_path) model.save(model_path)
@@ -22,7 +22,7 @@ from sklearn.metrics import classification_report, confusion_matrix
import tensorflow as tf import tensorflow as tf
# Tambahkan root directory ke path # 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.data_loader import load_mnist_for_cnn
from src.models import create_cnn_mnist_model from src.models import create_cnn_mnist_model
@@ -87,7 +87,7 @@ def main():
print(f" -> Test Loss : {test_loss:.4f}") print(f" -> Test Loss : {test_loss:.4f}")
# 5. Visualisasi & Penyimpanan # 5. Visualisasi & Penyimpanan
figures_dir = os.path.join("results", "figures") figures_dir = os.path.join("results", "02_cnn", "figures")
ensure_dir(figures_dir) ensure_dir(figures_dir)
# (b) Loss & Accuracy Curve # (b) Loss & Accuracy Curve
@@ -185,10 +185,10 @@ def main():
print("=" * 70 + "\n") print("=" * 70 + "\n")
# Simpan bobot terbaru # Simpan bobot terbaru
models_dir = os.path.join("results", "models") models_dir = os.path.join("results", "02_cnn", "models")
ensure_dir(models_dir) ensure_dir(models_dir)
model.save(os.path.join(models_dir, "model_cnn_mnist.keras")) 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__": if __name__ == "__main__":
@@ -21,7 +21,7 @@ import numpy as np
import tensorflow as tf import tensorflow as tf
# Tambahkan root directory ke path # 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.data_loader import load_mnist_for_cnn
from src.models import create_cnn_mnist_model, create_deep_cnn_mnist_model from src.models import create_cnn_mnist_model, create_deep_cnn_mnist_model
@@ -104,7 +104,7 @@ def main():
histories[model_name] = history histories[model_name] = history
# Simpan model 3 blok # Simpan model 3 blok
models_dir = os.path.join("results", "models") models_dir = os.path.join("results", "02_cnn", "models")
ensure_dir(models_dir) ensure_dir(models_dir)
results[1]["model_obj"].save(os.path.join(models_dir, "model_cnn_3blocks.keras")) results[1]["model_obj"].save(os.path.join(models_dir, "model_cnn_3blocks.keras"))
@@ -128,7 +128,7 @@ def main():
print("=" * 75) print("=" * 75)
# Visualisasi # Visualisasi
figures_dir = os.path.join("results", "figures") figures_dir = os.path.join("results", "02_cnn", "figures")
ensure_dir(figures_dir) ensure_dir(figures_dir)
fig_path = os.path.join(figures_dir, "perbandingan_kedalaman_cnn.png") fig_path = os.path.join(figures_dir, "perbandingan_kedalaman_cnn.png")
@@ -43,7 +43,7 @@ import tensorflow as tf
from tensorflow import keras from tensorflow import keras
# Tambahkan root directory ke path # 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.data_loader import load_mnist_for_cnn
from src.utils import ensure_dir 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) BATCH_SIZE = 128 # batch size training model (didokumentasikan, tidak dipakai ulang)
OPTIMIZER = "adam" # optimizer training model (tersimpan di file .keras) OPTIMIZER = "adam" # optimizer training model (tersimpan di file .keras)
MODEL_PATH = os.path.join("results", "models", "model_cnn_mnist.keras") MODEL_PATH = os.path.join("results", "02_cnn", "models", "model_cnn_mnist.keras")
FIGURES_DIR = os.path.join("results", "figures") FIGURES_DIR = os.path.join("results", "02_cnn", "figures")
REPORTS_DIR = os.path.join("results", "reports") REPORTS_DIR = os.path.join("results", "02_cnn", "reports")
CLASS_NAMES = [str(i) for i in range(10)] CLASS_NAMES = [str(i) for i in range(10)]
@@ -88,7 +88,7 @@ def main():
if not os.path.exists(MODEL_PATH): if not os.path.exists(MODEL_PATH):
raise FileNotFoundError( raise FileNotFoundError(
f"Model tidak ditemukan di '{MODEL_PATH}'. " 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) model = keras.models.load_model(MODEL_PATH)
print(f" -> Model '{model.name}' berhasil dimuat ({model.count_params():,} parameter).") print(f" -> Model '{model.name}' berhasil dimuat ({model.count_params():,} parameter).")
@@ -1,9 +1,11 @@
import sys import sys
import os import os
import time import time
import pandas as pd
import matplotlib.pyplot as plt
# Tambahkan root directory ke path agar dapat import dari src # 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.data_loader import load_mnist_for_mlp
from src.models import create_mlp_model from src.models import create_mlp_model
@@ -93,6 +95,42 @@ def main():
print(f"Jumlah Parameter : {best_model['parameters']:,}") print(f"Jumlah Parameter : {best_model['parameters']:,}")
print(f"Waktu Training/Epoch: {best_model['time_per_epoch']:.2f} detik") 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__": if __name__ == "__main__":
main() main()
@@ -5,7 +5,7 @@ matplotlib.use("Agg")
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
# Tambahkan root directory ke path agar dapat import dari src # 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.data_loader import load_mnist_for_mlp
from src.models import create_mlp_model, create_regularized_mlp_model from src.models import create_mlp_model, create_regularized_mlp_model
@@ -50,14 +50,14 @@ def main():
) )
# 4. Save Model Artifact # 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) ensure_dir(results_model_dir)
model_reg_path = os.path.join(results_model_dir, "model_c_regularized.keras") model_reg_path = os.path.join(results_model_dir, "model_c_regularized.keras")
model_reg.save(model_reg_path) model_reg.save(model_reg_path)
print(f"\n[INFO] Model teregularisasi disimpan di: {model_reg_path}") print(f"\n[INFO] Model teregularisasi disimpan di: {model_reg_path}")
# 5. Plot Comparison Curves # 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) ensure_dir(results_fig_dir)
fig_path = os.path.join(results_fig_dir, "loss_regularization.png") fig_path = os.path.join(results_fig_dir, "loss_regularization.png")
@@ -1,6 +1,4 @@
import os import os
os.environ["TF_USE_LEGACY_KERAS"] = "1" # Bypass Keras 3 & optree
import re import re
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@@ -16,11 +14,11 @@ from sklearn.metrics import (
) )
import tensorflow as tf import tensorflow as tf
import tf_keras as keras from tensorflow import keras
from tf_keras import layers from tensorflow.keras import layers
from tf_keras.callbacks import EarlyStopping from tensorflow.keras.callbacks import EarlyStopping
from tf_keras.preprocessing.text import Tokenizer # type: ignore from tensorflow.keras.preprocessing.text import Tokenizer # type: ignore
from tf_keras.preprocessing.sequence import pad_sequences from tensorflow.keras.preprocessing.sequence import pad_sequences
# ============================================================ # ============================================================
# KONFIGURASI DIREKTORI PENYIMPANAN # KONFIGURASI DIREKTORI PENYIMPANAN
@@ -34,9 +32,9 @@ EPOCHS = 20
BATCH_SIZE = 64 BATCH_SIZE = 64
RANDOM_STATE = 42 RANDOM_STATE = 42
FIGURES_DIR = "results/figures" FIGURES_DIR = os.path.join("results", "03_nlp_sentiment", "figures")
REPORTS_DIR = "results/reports" REPORTS_DIR = os.path.join("results", "03_nlp_sentiment", "reports")
MODELS_DIR = "results/models" MODELS_DIR = os.path.join("results", "03_nlp_sentiment", "models")
os.makedirs(FIGURES_DIR, exist_ok=True) os.makedirs(FIGURES_DIR, exist_ok=True)
os.makedirs(REPORTS_DIR, exist_ok=True) os.makedirs(REPORTS_DIR, exist_ok=True)
@@ -159,7 +157,7 @@ print("SEL 9 — MODEL GAP")
print("=" * 60) print("=" * 60)
sent_model = keras.Sequential([ sent_model = keras.Sequential([
layers.Embedding(input_dim=VOCAB_SIZE, output_dim=EMBED_DIM, input_length=MAX_LEN), layers.Embedding(input_dim=VOCAB_SIZE, output_dim=EMBED_DIM),
layers.GlobalAveragePooling1D(), layers.GlobalAveragePooling1D(),
layers.Dense(64, activation="relu"), layers.Dense(64, activation="relu"),
layers.Dropout(0.4), layers.Dropout(0.4),