# UAS — Pembelajaran Mesin Mendalam [KOMB] (2024) — Jawaban Versi Sederhana

> Ujian Akhir Semester · Semester Gasal 2024/2025 · Universitas Gadjah Mada
> Jawaban untuk `UAS_Deep Learning_2024.md`, ditulis dengan bahasa sederhana (kalimat pendek, istilah dijelaskan).
> Versi lengkap dan teknis: `UAS_Deep Learning_2024 - Answer.md`.

| Field | Value |
|---|---|
| **Mata Kuliah** | Pembelajaran Mesin Mendalam [KOMB] |
| **Jenis Ujian** | Ujian Akhir Semester (UAS) |
| **Semester** | Gasal 2024/2025 |
| **Tanggal** | Rabu, 4 Desember 2024 |
| **Waktu** | 10:00–12:00 (120 menit) |
| **Dosen** | Wahyono, Ph.D. |
| **Sifat Ujian** | Open Book, Tanpa Alat Elektronik |

**Institusi:** Program Studi Sarjana Ilmu Komputer, FMIPA, Universitas Gadjah Mada

> **Bobot nilai:** Soal 1 = 100 poin (a=10, b=15, c=15, d=20, e=40). Soal 2 = 100 poin (a=20, b=20, c=25, d=35).

---

## Soal 1a — Pengaruh Hiperparameter pada Akurasi CNN (10 poin)

**Apa itu hiperparameter?** Angka-angka yang kita tentukan sendiri sebelum melatih model (bukan hasil belajar model). Empat yang ditanyakan:

### 1. Ukuran kernel

Kernel itu "jendela kecil" yang digeser di atas gambar.

- **Kernel kecil (3×3)** → jendela sempit. Parameternya sedikit. Kalau ditumpuk dua lapis, hasilnya seperti satu kernel 5×5 tetapi parameternya **lebih sedikit** dan lebih banyak proses non-linear. Ini yang dipakai VGG.
- **Kernel besar (5×5, 7×7, 11×11)** → jendela luas, bisa langsung melihat pola besar. Tetapi parameternya naik cepat (kuadrat), pelatihan jadi lambat, dan mudah **overfitting** (hafal data latihan, jelek di data baru).

**Kesimpulan:** biasanya kernel 3×3 yang ditumpuk lebih baik daripada satu kernel besar.

### 2. Jumlah kernel

Ini menentukan berapa banyak "peta fitur" (feature map) yang dihasilkan tiap lapis. Anggap saja: makin banyak, makin kaya representasinya.

- **Terlalu sedikit** → model kurang pintar, tidak bisa membedakan kelas sulit (**underfitting**).
- **Terlalu banyak** → parameter membengkak, pelatihan lama, mudah **overfitting**.
- Kurva akurasinya biasanya **naik lalu datar** (plateau).

### 3. Jumlah layer (kedalaman)

Tiap layer mempelajari hal berbeda: lapis awal menangkap garis dan warna, lapis tengah menangkap tekstur, lapis dalam menangkap bentuk objek.

- Menambah layer biasanya **menaikkan akurasi**, sampai titik tertentu.
- Tapi ada masalah: **vanishing gradient** (sinyal error menyusut sampai lapis awal tidak belajar apa-apa), **degradasi** (jaringan yang terlalu dalam justru error latihannya naik), dan waktu latih bertambah.

### 4. Learning rate

Ini hiperparameter **paling penting**. Ukurannya menentukan seberapa besar langkah model saat memperbaiki diri.

| Learning rate | Akibatnya |
|---|---|
| **Terlalu besar** | Model "melompat-lompat", loss naik-turun, bisa meledak. Tidak pernah konvergen → akurasi jelek |
| **Terlalu kecil** | Belajar sangat lambat, bisa berhenti sebelum sampai titik terbaik → akurasi kurang optimal |
| **Pas** | Loss turun stabil, akurasi terbaik |

**Tips:** pakai learning rate besar di awal lalu kecilkan pelan-pelan (learning rate schedule), atau pakai optimizer adaptif seperti Adam.

### Ringkasan

| Hiperparameter | Kalau dinaikkan | Kalau diturunkan |
|---|---|---|
| Ukuran kernel | Jangkauan luas, parameter naik | Parameter turun, perlu lebih banyak layer |
| Jumlah kernel | Kapasitas naik, risiko overfit naik | Underfitting |
| Jumlah layer | Fitur lebih kaya, vanishing gradient naik | Kapasitas kurang |
| Learning rate | Model meledak | Belajar lambat |

**Intinya:** hiperparameter tidak berdiri sendiri. Menambah kedalaman tanpa menambah data justru menurunkan akurasi.

---

## Soal 1b — Depthwise Convolution Mengurangi Parameter MobileNet (15 poin)

### Masalahnya dulu: konvolusi biasa itu mahal

Konvolusi biasa memakai satu kernel untuk **semua** kanal input sekaligus.

Rumus parameternya:

```text
Parameter = K × K × C_in × C_out
```

Lihat bagian **C_in × C_out**. Inilah sumber ledakan parameter. Kalau C_in = C_out = 64 dan K = 3, hasilnya 3×3×64×64 = **36.864 parameter** hanya untuk satu lapis.

### Solusinya: pecah jadi dua langkah

MobileNet memecah satu konvolusi mahal menjadi dua konvolusi murah.

**Langkah 1 — Depthwise convolution.**
Setiap kanal input dapat kernel 3×3 **sendiri-sendiri**. Tidak ada pencampuran antar-kanal.

```text
Parameter = K × K × C_in
```

Perhatikan: **C_out hilang** dari rumus. Untuk K=3, C_in=64 → 3×3×64 = **576 parameter**.

**Langkah 2 — Pointwise convolution (kernel 1×1).**
Di sini baru kanal dicampur. Kernel 1×1 hanya melihat satu piksel, jadi tugasnya murni mencampur kanal.

```text
Parameter = C_in × C_out
```

Untuk 64 × 64 → **4.096 parameter**.

### Hasil perbandingan

| Cara | Parameter |
|---|---|
| Konvolusi biasa 3×3 | 36.864 |
| Depthwise 3×3 | 576 |
| Pointwise 1×1 | 4.096 |
| **Total cara MobileNet** | **4.672** |

**Pengurangannya: 4.672 / 36.864 ≈ 0,13** → parameter jadi **~8× lebih sedikit** (berkurang sekitar 87%).

### Kenapa bisa begitu?

Karena perkalian **C_in × C_out** yang tadinya mahal diubah menjadi **penjumlahan**. Idenya: urusan "melihat ruang" (spasial) dan urusan "mencampur kanal" dipisah.

### Catatan MobileNet

- Blok MobileNet: depthwise 3×3 → BatchNorm → ReLU → pointwise 1×1 → BatchNorm → ReLU.
- Hasilnya model hanya ~4,2 juta parameter, cukup untuk dijalankan di ponsel.
- Ada dua tombol pengatur di papernya: **width multiplier** (menipiskan model) dan **resolution multiplier** (mengecilkan gambar input).

---

## Soal 1c — Residual Connection di ResNet vs Vanishing Gradient (15 poin)

### Masalahnya: vanishing gradient

Saat melatih, error dikirim mundur dari lapis akhir ke lapis awal. Di setiap lapis, nilainya **dikalikan**.

Kalau tiap lapis mengalikan dengan angka kecil (misal 0,5), maka setelah 10 lapis: 0,5¹⁰ ≈ 0,001. Sinyalnya **hampir nol**. Akibatnya lapis awal tidak pernah diperbaiki. Inilah **vanishing gradient**.

Ada masalah kedua namanya **degradasi**: pada jaringan biasa yang sangat dalam, error latihannya **naik** padahal seharusnya turun. Ini bukan karena overfitting, tapi karena pelatihannya jadi sangat sulit.

### Solusinya: jalur pintas (shortcut)

ResNet menambahkan **jalur pintas** yang melewati blok:

```text
y = F(x) + x
```

Artinya: hasil blok = (apa yang dipelajari blok) **+ (masukan aslinya)**. Bagian `+ x` tidak punya parameter sama sekali.

### Kenapa ini menyelesaikan masalah?

**1. Ada jalur bebas untuk gradien.**
Saat error dikirim mundur, turunannya jadi:

```text
∂y/∂x = 1 + (sesuatu yang kecil)
```

Perhatikan angka **1** di situ. Angka 1 ini seperti **jalan tol** untuk gradien. Walaupun bagian `F` hampir tidak mengubah apa pun, gradien tetap bisa lewat jalur pintas dengan utuh. Tidak lagi menyusut sampai nol.

**2. Jaringan lebih dalam tidak mungkin jadi lebih buruk.**
Kalau sebuah blok tidak berguna, model bisa membuat `F = 0`, sehingga blok itu hanya menyalurkan input apa adanya. Jadi menambah layer tidak merusak apa pun.

**3. Informasi mengalir lancar** ke depan dan ke belakang.

**4. Gratis.** Jalur pintas tidak menambah parameter dan hampir tidak menambah perhitungan.

### Hasilnya

Dengan cara ini ResNet bisa melatih jaringan **152 lapis** dan menang juara 1 di ILSVRC 2015. Bahkan di CIFAR-10 mereka mencoba **1000 lapis**. Sebelumnya, jaringan sedalam itu tidak bisa dilatih sama sekali.

---

## Soal 1d — GoogleNet (Inception) Mengatasi Pelatihan Jaringan Dalam (20 poin)

### Masalah yang mau dipecahkan

Soal bilang: makin banyak layer, makin bagus akurasinya. **Tapi** pelatihannya jadi lebih rumit dan lama. Kenapa rumit?

1. Parameter dan perhitungan **meledak**. Bagian fully connected di ujung jaringan sangat boros parameter.
2. **Vanishing gradient** — jaringan 20+ lapis sulit dilatih.
3. **Overfitting** karena parameternya terlalu banyak.
4. Biaya komputasi jadi penghalang utama untuk memperdalam jaringan.

### Tiga ide GoogleNet

**Ide 1 — Modul Inception: lihat beberapa skala sekaligus.**
Satu modul menjalankan konvolusi 1×1, 3×3, 5×5, **dan** max pooling **bersamaan**, lalu hasilnya digabung. Jadi jaringan tidak perlu memilih satu ukuran kernel saja — ia melihat semuanya. Jaringan tumbuh **dalam dan lebar sekaligus**.

**Ide 2 — Konvolusi 1×1 sebagai penghemat (ini kuncinya).**
Masalahnya, kalau semua cabang dijalankan apa adanya, biayanya meledak. Solusinya: sebelum konvolusi 3×3 dan 5×5, sisipkan dulu **konvolusi 1×1** untuk **memangkas jumlah kanal**. Konvolusi 1×1 sangat murah, tapi bisa memotong biaya konvolusi besar secara drastis.

Hasilnya: jaringan bisa makin dalam dan lebar **tanpa menambah biaya komputasi**. Inilah jawaban inti soal ini.

**Ide 3 — Hemat parameter.**
- Lapisan fully connected besar di ujung **dibuang**, diganti global average pooling. Puluhan juta parameter hilang, overfitting turun drastis.
- Ditambah **dua auxiliary classifier** di tengah jaringan supaya gradien tetap kuat (melawan vanishing gradient) dan sebagai regularisasi.
- Ditambah **dropout**.

### Hasilnya

GoogLeNet = **22 lapis** dengan hanya **~5 juta parameter**. Bandingkan AlexNet yang ~60 juta parameter — jadi **12× lebih hemat**. Tapi errornya cuma 6,67% di ImageNet dan menang ILSVRC 2014.

### Intinya

GoogleNet tidak memakai satu trik saja. Ia **mengubah cara menghitung biaya**: modul Inception membuat jaringan tumbuh besar tanpa menambah anggaran komputasi (karena tiap cabang bekerja pada kanal yang sudah dipangkas), membuang fully connected layer, dan menambah auxiliary classifier. Jadi: **dalam dan lebar, tapi parameter dan perhitungan tetap kecil.**

---

## Soal 1e — Arsitektur, Ukuran Activation Map, dan Jumlah Parameter (40 poin)

### Rumus yang dipakai

- Konvolusi tanpa padding (valid), stride 1: `ukuran baru = ukuran lama − K + 1`
- Max pooling 2×2, stride 2: `ukuran baru = (ukuran lama − 2) / 2 + 1` (dibulatkan ke bawah)
- Parameter konvolusi: `(K × K × jumlah kanal input + 1) × jumlah kernel` — **bias dihitung** (+1)
- Parameter dense: `jumlah input × jumlah neuron + jumlah neuron`
- Pooling tidak punya parameter

### Diagram arsitektur

```text
   Input
   1×24×24
      │
      ▼
┌────────────────────────────┐
│ Conv 3×3, 10 kernel        │   params = 100
│ ReLU                       │
└────────────────────────────┘
      │  10×22×22
      ▼
┌────────────────────────────┐
│ Conv 5×5, 10 kernel        │   params = 2.510
│ ReLU                       │
└────────────────────────────┘
      │  10×18×18
      ▼
┌────────────────────────────┐
│ Max Pool 2×2, stride 2     │   params = 0
└────────────────────────────┘
      │  10×9×9
      ▼
┌────────────────────────────┐
│ Conv 3×3, 8 kernel         │   params = 728
│ ReLU                       │
└────────────────────────────┘
      │  8×7×7
      ▼
┌────────────────────────────┐
│ Conv 5×5, 8 kernel         │   params = 1.608
│ ReLU                       │
└────────────────────────────┘
      │  8×3×3
      ▼
┌────────────────────────────┐
│ Max Pool 2×2, stride 2     │   params = 0
└────────────────────────────┘
      │  8×1×1
      ▼
   Flatten  ──────────────►  8 angka
      │
      ▼
┌────────────────────────────┐
│ Dense 15 (ReLU)            │   params = 135
└────────────────────────────┘
      │  15
      ▼
┌────────────────────────────┐
│ Dense 5 (Softmax)          │   params = 80
└────────────────────────────┘
      │
      ▼
   5 kelas
```

### Ukuran activation map tiap lapisan

| # | Lapisan | Hitungan | Ukuran | Parameter |
|---|---|---|---|---|
| 0 | Input | — | **1×24×24** | 0 |
| 1 | Conv 3×3, 10 kernel | 24−3+1 = 22 | **10×22×22** | 100 |
| 2 | Conv 5×5, 10 kernel | 22−5+1 = 18 | **10×18×18** | 2.510 |
| 3 | Max Pool 2×2 | (18−2)/2+1 = 9 | **10×9×9** | 0 |
| 4 | Conv 3×3, 8 kernel | 9−3+1 = 7 | **8×7×7** | 728 |
| 5 | Conv 5×5, 8 kernel | 7−5+1 = 3 | **8×3×3** | 1.608 |
| 6 | Max Pool 2×2 | (3−2)/2+1 = 1 | **8×1×1** | 0 |
| 7 | Flatten | 8×1×1 | **8** | 0 |
| 8 | Dense 15 | — | **15** | 135 |
| 9 | Dense 5 (output) | — | **5** | 80 |

### Cara menghitung parameternya (satu per satu)

**Lapis 1** — Conv 3×3, input 1 kanal:
Satu kernel = 3×3×1 = 9 bobot, tambah 1 bias = 10.
`10 × 10 kernel = 100`

**Lapis 2** — Conv 5×5, input 10 kanal:
Satu kernel = 5×5×10 = 250 bobot, tambah 1 bias = 251.
`251 × 10 kernel = 2.510`

**Lapis 4** — Conv 3×3, input 10 kanal:
`(3×3×10 + 1) × 8 = 91 × 8 = 728`

**Lapis 5** — Conv 5×5, input 8 kanal:
`(5×5×8 + 1) × 8 = 201 × 8 = 1.608`

**Lapis 8** — Dense 15, input 8:
`8 × 15 + 15 = 120 + 15 = 135`

**Lapis 9** — Dense 5, input 15:
`15 × 5 + 5 = 75 + 5 = 80`

### Total parameter

| Lapisan | Parameter |
|---|---|
| Conv 3×3 (10 kernel) | 100 |
| Conv 5×5 (10 kernel) | 2.510 |
| Max Pool | 0 |
| Conv 3×3 (8 kernel) | 728 |
| Conv 5×5 (8 kernel) | 1.608 |
| Max Pool | 0 |
| Flatten | 0 |
| Dense 15 | 135 |
| Dense 5 | 80 |
| **TOTAL** | **5.161** |

> **Total parameter = 5.161** (bias dihitung di semua lapisan).

### Catatan tambahan (untuk nilai plus)

- **Kalau bias konvolusi tidak dihitung:** 5.125. **Kalau semua bias tidak dihitung:** 5.105. Jawaban 5.161 yang dipakai karena soal biasanya minta bias dihitung.
- **Hal menarik:** setelah pooling terakhir, ukurannya sudah **8×1×1**. Jadi Flatten di sini sama saja dengan global average pooling — tidak ada informasi ruang yang tersisa. Praktisnya, seluruh lapis 1–5 hanya jadi pencari fitur, dan pengklasifikasi akhir bekerja pada 8 angka saja.
- **Kalau pembulatan pooling pakai ceil (bukan floor):** lapis 6 jadi 2×2, sehingga Dense 15 jadi `8×4×15+15 = 495` → total **5.521**. Karena itu, tuliskan asumsi pembulatan Anda di lembar jawaban.

---

## Soal 2a — Cara Kerja RNN dan Kendala Utamanya (20 poin)

### Kenapa data berurutan butuh RNN?

Data berurutan (teks, suara, deret waktu) punya sifat khusus: **urutannya penting**, **panjangnya berubah-ubah**, dan **bagian awal bisa memengaruhi bagian akhir**. MLP tidak punya konsep "sebelumnya". CNN hanya melihat jendela kecil dengan ukuran tetap.

### Cara kerjanya

RNN memproses data **satu langkah demi satu langkah**, sambil menyimpan **hidden state** (`h_t`). Hidden state ini ibarat **memori** yang merangkum semua yang sudah dibaca.

```text
h_t = tanh(W_hh · h_{t-1} + W_xh · x_t + b_h)
y_t = softmax(W_hy · h_t + b_y)
```

Tiga hal penting:

1. **Bobotnya dipakai bersama.** Bobot yang sama dipakai di setiap langkah. Jadi jumlah parameter tidak bergantung pada panjang data, dan model bisa menerima panjang berapa pun.
2. **Di-unroll sepanjang waktu.** Secara konsep, jaringan direplikasi T kali dan dirangkai. Pelatihannya pakai **Backpropagation Through Time (BPTT)**.
3. **Output tiap langkah bergantung pada seluruh riwayat** yang sudah diringkas ke `h_t`.

### Kendala utama

| # | Kendala | Penjelasan sederhana |
|---|---|---|
| 1 | **Vanishing gradient** | Gradien dikalikan berulang sehingga menyusut. Akibatnya RNN **tidak bisa belajar hubungan jarak jauh** (misalnya kata ke-1 dengan kata ke-20). |
| 2 | **Exploding gradient** | Kalau sebaliknya, gradien meledak → pelatihan tidak stabil, loss jadi NaN. Perlu gradient clipping. |
| 3 | **Memori jangka pendek** | `h_t` ukurannya tetap, tapi harus memuat seluruh riwayat. Informasi lama tertimpa informasi baru. |
| 4 | **Tidak bisa diparalelkan** | Langkah ke-t harus menunggu langkah ke-(t−1). Pelatihan jadi lambat untuk data panjang. **Ini alasan utama Transformer dibuat.** |
| 5 | **Sulit dilatih** | Sangat sensitif terhadap learning rate dan inisialisasi. Butuh banyak trik. |
| 6 | **Gagal pada data sangat panjang** | Bahkan LSTM tidak praktis untuk puluhan ribu langkah. |

### Cara mengatasinya

Pakai LSTM/GRU (punya gerbang), gradient clipping, inisialisasi ortogonal, truncated BPTT, layer normalization, dan attention.

---

## Soal 2b — Update Gate dan Reset Gate pada GRU (20 poin)

**Apa itu GRU?** Versi sederhana dari LSTM. Punya **2 gerbang** saja (LSTM punya 3), dan tidak punya cell state terpisah. Gerbang itu semacam "keran" yang mengatur seberapa banyak informasi boleh lewat.

### 1. Reset gate (gerbang reset)

```text
r_t = σ(W_r · [h_{t-1}, x_t])
```

Gerbang ini menentukan **seberapa banyak memori lama dipakai saat menghitung isi memori baru**.

```text
h̃_t = tanh(W · [r_t ⊙ h_{t-1}, x_t])
```

- **r_t ≈ 0** → memori lama "dibuang dulu", memori baru hanya melihat input saat ini. Berguna kalau konteks sebelumnya tidak relevan (misalnya topik tiba-tiba berubah).
- **r_t ≈ 1** → seluruh memori lama dipakai.
- Karena `r_t` berupa vektor, **tiap bagian memori bisa direset sendiri-sendiri**. Jadi model bisa membuang sebagian memori saja.

### 2. Update gate (gerbang update)

```text
z_t = σ(W_z · [h_{t-1}, x_t])
```

Gerbang ini menentukan **berapa banyak memori lama yang disimpan** dan berapa banyak yang diganti dengan yang baru.

```text
h_t = (1 − z_t) ⊙ h_{t-1} + z_t ⊙ h̃_t
```

- **z_t ≈ 1** → `h_t` hampir sama dengan `h_{t-1}`. Memori lama **disimpan**, informasi baru diabaikan.
- **z_t ≈ 0** → memori lama **ditimpa** dengan yang baru.

*(Catatan: di paper aslinya, notasinya kebalikan. Tuliskan konvensi yang Anda pakai.)*

### Bagaimana kedua gerbang memengaruhi aliran informasi

**a. Penjumlahan (bukan perkalian) = jalan tol gradien.**
Perhatikan rumusnya: `h_t` dibentuk dari **penjumlahan** `h_{t-1}` dan `h̃_t`, bukan perkalian berantai seperti RNN biasa. Karena itu gradien bisa mengalir lancar saat `z_t ≈ 1`. Ini **mirip sekali dengan residual connection di ResNet**. Inilah sebabnya GRU jauh lebih tahan vanishing gradient daripada RNN biasa.

**b. Pembagian tugas yang rapi.**
- **Reset gate** mengatur **isi** memori — apakah konteks lama masih relevan.
- **Update gate** mengatur **durasi** memori — berapa lama informasi disimpan.

**c. Lebih hemat daripada LSTM.**
GRU hanya 2 gerbang, LSTM 3. Parameter GRU **~25% lebih sedikit** dan pelatihannya lebih cepat. Di banyak tugas, akurasinya setara LSTM — malah di dataset kecil GRU sering lebih baik karena tidak mudah overfitting.

---

## Soal 2c — Contoh Nyata di Mana GRU Lebih Baik daripada LSTM (25 poin)

### Contoh utama: deteksi kata kunci di perangkat kecil (keyword spotting)

**Situasinya.** Kita mau membuat alat yang mendeteksi kata pemicu (misalnya "nyalakan lampu") **langsung di perangkat** seperti jam pintar atau mikrokontroler. Perangkatnya cuma punya RAM ratusan kilobyte dan **tidak punya GPU**.

**Kenapa GRU lebih cocok:**

| Alasan | Penjelasan sederhana |
|---|---|
| **Parameternya lebih sedikit** | GRU ~25% lebih kecil dari LSTM. Di perangkat kecil, batasnya adalah **memori dan daya baterai**, bukan akurasi sempurna. |
| **Lebih cepat** | Perhitungan tiap langkah lebih ringan → respons langsung, baterai lebih hemat. |
| **Datanya sedikit** | Data berlabel untuk kata pemicu mahal. Model yang lebih kecil = risiko overfitting lebih rendah. |
| **Hubungannya tidak panjang** | Kata pemicu hanya ~0,5–1 detik. LSTM yang dirancang untuk hubungan sangat panjang tidak memberi keuntungan. |
| **Lebih cepat konvergen** | Pelatihan lebih cepat, penting untuk pengembangan produk. |

### Contoh pendukung lainnya

1. **Deteksi kejang dari sinyal EEG (data medis kecil).** Data pasien jumlahnya sedikit dan beragam. GRU dengan kapasitas lebih kecil lebih mudah digeneralisasi.
2. **Prediksi lalu lintas jangka pendek.** Polanya tidak terlalu panjang. GRU memberi akurasi setara LSTM tapi pelatihannya lebih cepat — penting karena model harus dilatih ulang berkala.
3. **Pengenalan aktivitas manusia dari sensor jam pintar.** Datanya pendek (beberapa detik), sumber dayanya terbatas.
4. **Pemodelan musik dan sinyal suara.** Makalah asli GRU (Cho dkk., 2014) menemukan bahwa **GRU setara atau lebih baik daripada LSTM pada pemodelan musik dan sinyal suara, dengan parameter lebih sedikit dan konvergensi lebih cepat**.

### Jujur: kapan LSTM tetap lebih baik?

Keunggulan GRU **bukan mutlak**. LSTM lebih baik kalau:
- hubungan antar-data **sangat panjang** (ratusan sampai ribuan langkah);
- data latihnya **sangat banyak** — kapasitas ekstra LSTM jadi berguna;
- tugasnya butuh pemisahan tegas antara "memori internal" dan "output".

**Kalimat kunci untuk jawaban:** GRU lebih baik kalau **memori, kecepatan, dan waktu latih jadi kendala utama, datanya terbatas, dan hubungannya tidak terlalu panjang** — yaitu kondisi khas perangkat kecil dan aplikasi real-time.

---

## Soal 2d — Tantangan Melatih LSTM untuk Pengenalan Suara (35 poin)

### Gambaran masalahnya

Pengenalan suara itu mengubah **gelombang suara** jadi **teks**. Sulit karena:
- suara tiap orang berbeda (penutur, aksen, mikrofon, derau, gema);
- panjang suara dan panjang teks **tidak sama**;
- tidak ada penanda "frame ini milik huruf apa".

### Tantangan 1 — Sekuensnya sangat panjang

**Masalah.** Suara 16 kHz = 16.000 sampel per detik. Kalimat 10 detik = 160.000 langkah. BPTT penuh akan kehabisan memori.

**Solusi.**
- **Ubah jadi frame**: pakai MFCC atau log-mel spectrogram dengan frame 20–25 ms → jadi ~100 frame/detik. Sekuensnya terpangkas ~160×.
- **Taruh CNN di depan LSTM** (arsitektur CNN–LSTM) untuk meringkas waktu.
- **Truncated BPTT** — pelatihan per potongan, bukan seluruh kalimat.
- **Bucketing** — kelompokkan kalimat berdasarkan panjangnya supaya padding tidak boros.

### Tantangan 2 — Tidak tahu bagian suara mana cocok dengan huruf mana

**Masalah.** Ini disebut masalah *alignment*.

**Solusi.**
- **CTC (Connectionist Temporal Classification).** Menambahkan simbol *blank*, lalu menjumlahkan probabilitas **semua** penyelarasan yang mungkin. Jadi model bisa dilatih **tanpa anotasi batas**. Ini metode standar untuk LSTM-CTC.
- **Attention encoder–decoder** (misalnya Listen-Attend-Spell): encoder merangkum suara, decoder menghasilkan teks sambil menyelaraskan sendiri.

### Tantangan 3 — Vanishing/exploding gradient

**Masalah.** Hubungan antar-kata yang berjauhan bisa hilang, dan pelatihan jadi tidak stabil.

**Solusi.**
- **Gradient clipping** — wajib untuk mengatasi exploding gradient.
- **Layer normalization**, **residual connection**, dan **variational dropout** (dropout diterapkan pada state, bukan input).
- **Inisialisasi ortogonal/identitas** untuk matriks rekuren.
- **Bidirectional LSTM** untuk mode offline (bisa melihat konteks kiri dan kanan).
- Pindah ke **Transformer/Conformer** kalau data dan komputasi tersedia.

### Tantangan 4 — Butuh data banyak, mudah overfitting

**Masalah.** LSTM punya jutaan parameter dan sangat rakus data, sedangkan transkripsi audio mahal.

**Solusi.**
- **Augmentasi data**: ubah kecepatan dan pitch, tambahkan derau dan gema, simulasi mikrofon berbeda, dan **SpecAugment** (menutup blok waktu/frekuensi pada spectrogram).
- **Dropout**, weight decay, early stopping.
- **Pretraining tanpa label** (self-supervised): **wav2vec 2.0**, **HuBERT**, **WavLM**. Latih dulu dari audio tak berlabel, baru fine-tune dengan data berlabel sedikit. Ini mengubah banyak hal — kebutuhan label turun drastis.
- **CMVN** untuk menyeragamkan kanal, dan **speaker adaptation**.

### Tantangan 5 — Suara yang mirip (homofon)

**Masalah.** "to", "two", dan "too" terdengar sama. Model akustik saja tidak cukup.

**Solusi.** Gabungkan dengan **model bahasa**. Pakai beam search yang menggabungkan skor akustik + **model bahasa** + kamus pengucapan. Ini menurunkan word error rate secara signifikan.

### Tantangan 6 — Tidak bisa diparalelkan, latensi tinggi

**Masalah.** Rekurensi harus berurutan, jadi pelatihan lambat dan inferensi streaming butuh latensi rendah.

**Solusi.**
- Pelatihan terdistribusi, presisi campuran (fp16), kernel cuDNN.
- **Chunking** + state carry-over untuk inferensi streaming.
- Pakai **Conformer/Transformer** yang jauh lebih paralel.

### Rangkuman

| # | Tantangan | Solusi utama |
|---|---|---|
| 1 | Sekuens sangat panjang | Frame MFCC 10 ms, CNN front-end, truncated BPTT, bucketing |
| 2 | Alignment suara ↔ teks | **CTC**, atau attention encoder–decoder |
| 3 | Vanishing/exploding gradient | Gradient clipping, LayerNorm, residual, variational dropout, BiLSTM |
| 4 | Data terbatas → overfitting | Augmentasi, **SpecAugment**, dropout, **pretraining tanpa label** (wav2vec 2.0/HuBERT), CMVN |
| 5 | Homofon | **Model bahasa** + kamus pengucapan (beam search) |
| 6 | Sekuensial & latensi | fp16 + distribusi, chunked streaming, Transformer/Conformer |

**Kesimpulan.** Tantangan LSTM untuk pengenalan suara bukan satu masalah saja, tapi gabungan dari **panjang sekuens, penyelarasan, gradien, kelangkaan data, dan ambiguitas suara**. Solusinya bertingkat: olah representasinya (frame + subsampling), pakai loss yang tepat (**CTC**), pakai teknik optimasi (clipping, normalisasi, dropout), augmentasi dan pretraining, lalu gabungkan dengan **model bahasa**.

---

## Referensi

1. K. He dkk., *Deep Residual Learning for Image Recognition*, arXiv:1512.03385 (2015) — ResNet, `y = F(x) + x`, 152 lapis, juara ILSVRC 2015.
2. A. G. Howard dkk., *MobileNets: Efficient CNNs for Mobile Vision Applications*, arXiv:1704.04861 (2017) — depthwise separable convolution, pengurangan 8–9×.
3. C. Szegedy dkk., *Going Deeper with Convolutions*, arXiv:1409.4842 (2014) — modul Inception, GoogLeNet 22 lapis.
4. K. Cho dkk., *Learning Phrase Representations using RNN Encoder-Decoder*, arXiv:1406.1078 (EMNLP 2014) — paper asli GRU.
5. S. Hochreiter & J. Schmidhuber, *Long Short-Term Memory*, Neural Computation (1997) — LSTM.
6. A. Graves dkk., *Connectionist Temporal Classification*, ICML 2006 — CTC.
7. D. S. Park dkk., *SpecAugment*, arXiv:1904.08779 (2019) — augmentasi audio.
8. J. Chung dkk., *Empirical Evaluation of Gated Recurrent Neural Networks*, arXiv:1412.3555 (2014) — perbandingan GRU vs LSTM.
9. Semua hitungan pada Soal 1e diperiksa dengan skrip Python. Hasil: ukuran `1×24×24 → 10×22×22 → 10×18×18 → 10×9×9 → 8×7×7 → 8×3×3 → 8×1×1`, total **5.161 parameter**.

---

*Jawaban versi sederhana. Soal mengikuti `UAS_Deep Learning_2024.md`. Versi teknis lengkap: `UAS_Deep Learning_2024 - Answer.md`.*
