Seorang seniman muda tidak belajar teori seni — dia mempelajari ribuan lukisan secara langsung. Lama-lama dia bisa meniru gaya siapapun dan menciptakan karya baru yang belum ada. Neural Network persis begitu: belajar dari data, menemukan pola tersembunyi, lalu bisa mengaproksimasi fungsi apapun — termasuk dinamika sistem yang sangat nonlinier yang sulit dimodelkan secara matematis!
Teorema Universal Approximation (Cybenko, 1989) menyatakan bahwa satu hidden layer NN dengan neuron yang cukup dapat mengaproksimasi fungsi kontinu apapun dengan akurasi sembarang. Ini dasar mengapa NN sangat kuat untuk identifikasi sistem nonlinier.
Layer 2 (output): ŷ = W²·h + b² (linear output untuk regresi)
Fungsi aktivasi σ(z):
Sigmoid : σ(z) = 1 / (1 + e⁻ᶻ) output (0,1)
Tanh : σ(z) = (eᶻ−e⁻ᶻ)/(eᶻ+e⁻ᶻ) output (−1,1)
ReLU : σ(z) = max(0, z) paling umum sekarang
| Jenis NN | Cocok untuk | Keunggulan vs Fuzzy |
|---|---|---|
| MLP (Feedforward) | Identifikasi sistem statis nonlinier | Lebih mudah di-train, representasi kompak |
| RNN / NARX | Sistem dinamis dengan memori | Bisa menangkap temporal dependencies |
| LSTM / GRU | Sistem dengan long-range dependencies | Mengatasi vanishing gradient RNN |
| RBFN | Kontrol real-time, interpolasi lokal | Training sangat cepat, interpretable |
Mobil bermasalah (output salah). Mekanik tidak langsung bongkar semua komponen. Dia telusuri mundur dari gejala: knalpot keluar asap hitam → campuran bahan bakar terlalu kaya → injektor kotor. Backpropagation persis begini: mulai dari error output, telusuri mundur layer demi layer, hitung berapa besar kontribusi masing-masing weight terhadap error, lalu update semua weight sekaligus!
Forward pass: Hitung ŷ dari input x
Backward pass:
δ_output = (ŷ − y) · σ'(z_out)
δ_hidden = (W²ᵀ · δ_output) · σ'(z_hid)
Update weights (gradient descent):
W¹ ← W¹ − α · δ_hidden · xᵀ
W² ← W² − α · δ_output · hᵀ
α = learning rate (mirip γ di MRAC!)
💡 Koneksi Backprop dengan Gradient Descent di Kontrol Adaptif
MIT Rule dalam MRAC (θ̇ = −γ·e·φ) adalah gradient descent satu parameter. Backpropagation adalah gradient descent untuk ribuan parameter sekaligus (semua bobot NN) menggunakan chain rule. Konsepnya sama — bedanya hanya skala!
GPS lama butuh peta yang dibuat manusia. GPS modern belajar dari jutaan laporan perjalanan pengguna — tanpa seseorang mendefinisikan setiap jalan. NN Identifier seperti GPS modern: belajar memetakan u(t) → y(t) langsung dari data historis, tanpa perlu tahu persamaan fisika sistemnya!
NN Identifier : ŷ(k+1) = NN_θ(y(k), y(k-1), u(k), u(k-1))
Training: minimasi J = Σ (y(k+1) − ŷ(k+1))²
Update : θ ← θ − α · ∇_θ J (online atau offline)
Setelah training: NN_θ ≈ model sistem nyata!
| Mode Training | Kapan Digunakan | Kelebihan |
|---|---|---|
| Offline (batch) | Ada data historis yang cukup | Stabil, bisa gunakan optimizer canggih (Adam) |
| Online (incremental) | Sistem berubah seiring waktu | Adaptif real-time, tidak butuh data awal banyak |
| Hybrid | Praktek umum di industri | Offline untuk inisialisasi, online untuk fine-tuning |
1. Direct Inverse Control
NN belajar inverse model sistem: diberikan y_target, keluarkan u yang diperlukan. Training offline dengan data u→y, lalu dibalik menjadi y→u.
⚡ Sederhana tapi tidak ada jaminan stabilitas loop tertutup.
2. Internal Model Control (IMC)
NN identifier (model maju) dipakai untuk hitung feedback internal. Kontroller didesain berdasarkan model NN. Stabil jika model akurat.
⚡ Populer di industri kimia dan proses.
3. Model Predictive NN (NNMPC)
NN identifier digunakan sebagai model prediksi di dalam MPC. Optimisasi dilakukan di setiap langkah untuk mencari u optimal.
⚡ Paling kuat tapi komputasi paling berat.
4. NN + MRAC Hybrid
NN digunakan untuk kompensasi ketidakpastian dalam MRAC. NN belajar bagian yang tidak bisa dimodelkan secara linier.
⚡ Jaminan stabilitas dari MRAC, akurasi dari NN.
✅ Kapan Pilih NN untuk Kontrol Adaptif?
- Sistem sangat nonlinier dan model fisika sulit dibuat
- Ada data historis yang cukup untuk training awal
- Tidak ada ahli yang bisa membuat fuzzy rule (tidak ada prior knowledge)
- Kebutuhan akurasi sangat tinggi dan komputasi mencukupi
Untuk memahami kalimat "dia akhirnya menang", kita butuh konteks kalimat sebelumnya. Feedforward NN hanya melihat satu "kalimat" (snapshot saat ini). NARX (Nonlinear AutoRegressive with eXogenous inputs) seperti membaca novel — menyimpan "memori" output dan input masa lalu untuk prediksi yang lebih akurat. Ini sangat penting untuk sistem kontrol yang dinamiknya bergantung pada sejarah!
Input vektor: φ(k) = [y(k), .., y(k-n_y), u(k), .., u(k-n_u)]
n_y = jumlah lag output, n_u = jumlah lag input
Persamaan ini sangat mirip dengan model ARX di STR (Sesi 5)!
Perbedaannya: di STR model LINIER, di NARX NN bisa NONLINIER.
💡 NARX vs Model ARX di STR
- ARX (Sesi 5): y(k) = a₁y(k-1) + b₁u(k-1) — linier, parameter θ diestimasi RLS
- NARX (Sesi 10): y(k) = NN(y(k-1), u(k-1)) — nonlinier, bobot NN ditraining backprop
- NARX adalah "upgrade" dari ARX untuk sistem nonlinier — prinsip lag input/output sama, tapi fungsinya diganti dengan NN!
Turbin gas memiliki hubungan nonlinier antara bukaan valve bahan bakar (u) dan daya output (y). Kita latih NN untuk mempelajari hubungan ini dari data simulasi, lalu gunakan untuk prediksi dan kontrol.
import numpy as np import matplotlib.pyplot as plt # ========================================== # NN IDENTIFIER DARI NOL (hanya NumPy) # Identifikasi dinamika turbin gas nonlinier # ========================================== np.random.seed(42) # === GENERATE DATA SISTEM NYATA (nonlinier) === # Turbin gas: y(k+1) = 0.7*y(k) + (1-exp(-u(k))) + 0.1*y(k)*u(k) + noise def true_system(y_prev, u): return 0.7*y_prev + (1 - np.exp(-u)) + 0.1*y_prev*u N_train = 800; N_test = 200; N = N_train + N_test u_all = 2*np.random.rand(N) - 0.5 # input bervariasi (-0.5 to 1.5) y_all = np.zeros(N); y_all[0] = 0.5 for k in range(1, N): y_all[k] = true_system(y_all[k-1], u_all[k-1]) + 0.02*np.random.randn() # === BUAT DATASET: Input = [y(k), u(k)], Output = y(k+1) === X = np.column_stack([y_all[:-1], u_all[:-1]]) Y = y_all[1:] X_train, Y_train = X[:N_train], Y[:N_train] X_test, Y_test = X[N_train:], Y[N_train:] # === NORMALISASI === X_mean, X_std = X_train.mean(0), X_train.std(0) + 1e-8 Y_mean, Y_std = Y_train.mean(), Y_train.std() + 1e-8 Xn_tr = (X_train - X_mean) / X_std Yn_tr = (Y_train - Y_mean) / Y_std Xn_te = (X_test - X_mean) / X_std # === NEURAL NETWORK: 2 → 16 → 1 === n_in=2; n_hid=16; n_out=1 W1 = np.random.randn(n_in, n_hid) * 0.3 b1 = np.zeros(n_hid) W2 = np.random.randn(n_hid, n_out) * 0.3 b2 = np.zeros(n_out) def relu(z): return np.maximum(0, z) def relu_d(z): return (z > 0).astype(float) def forward(X): z1 = X @ W1 + b1; h1 = relu(z1) z2 = h1 @ W2 + b2 return z2.flatten(), z1, h1 # === TRAINING (Batch Gradient Descent) === lr = 0.005; epochs = 300; losses = [] for ep in range(epochs): yp, z1, h1 = forward(Xn_tr) loss = np.mean((yp - Yn_tr)**2) losses.append(loss) # Backprop dL_dyp = 2*(yp - Yn_tr) / len(Yn_tr) dL_dW2 = h1.T @ dL_dyp.reshape(-1,1) dL_db2 = dL_dyp.sum() dL_dh1 = dL_dyp.reshape(-1,1) @ W2.T dL_dz1 = dL_dh1 * relu_d(z1) dL_dW1 = Xn_tr.T @ dL_dz1 dL_db1 = dL_dz1.sum(0) W1 -= lr*dL_dW1; b1 -= lr*dL_db1 W2 -= lr*dL_dW2; b2 -= lr*dL_db2 if ep % 50 == 0: print(f"Epoch {ep:3d}: Loss = {loss:.6f}") # === TEST === yp_test_n, _, _ = forward(Xn_te) yp_test = yp_test_n * Y_std + Y_mean # denormalisasi rmse = np.sqrt(np.mean((yp_test - Y_test)**2)) # === PLOT === fig, axes = plt.subplots(3, 1, figsize=(12, 9)) axes[0].semilogy(losses, color='orange', lw=1.8) axes[0].set_xlabel('Epoch'); axes[0].set_ylabel('MSE Loss (log scale)') axes[0].set_title('Training Loss — NN Belajar Dinamika Turbin Gas') axes[0].grid(alpha=0.3) t_test = np.arange(len(Y_test)) axes[1].plot(t_test, Y_test, 'b', lw=2, label='Output Aktual (sistem nyata)') axes[1].plot(t_test, yp_test, 'orange', lw=1.5, ls='--', label=f'Prediksi NN (RMSE={rmse:.4f})') axes[1].set_ylabel('Output y') axes[1].set_title('Test Set: Output Aktual vs Prediksi NN') axes[1].legend(); axes[1].grid(alpha=0.3) err_test = Y_test - yp_test axes[2].plot(t_test, err_test, 'tomato', lw=1.2, label='Error prediksi') axes[2].axhline(0, color='lime', ls='--') axes[2].fill_between(t_test, err_test, 0, alpha=0.2, color='tomato') axes[2].set_xlabel('Waktu (k)'); axes[2].set_ylabel('Error') axes[2].set_title('Residual Error — Mendekati Nol = NN Akurat!') axes[2].legend(); axes[2].grid(alpha=0.3) plt.tight_layout(); plt.show() print(f"\n✅ RMSE Test: {rmse:.4f}") print(f"NN berhasil mempelajari dinamika nonlinier turbin tanpa model fisika!")
📊 Interpretasi Hasil
- Plot 1 (Loss): Turun eksponensial — NN belajar dengan baik dari data training
- Plot 2 (Prediksi): Kurva oranye sangat dekat dengan biru — NN berhasil mempelajari dinamika nonlinier
- Plot 3 (Error): Error mendekati nol — model NN bisa digunakan sebagai pengganti model fisika
- NN identifier ini bisa dijadikan "model maju" di dalam NNMPC atau MRAC-NN hybrid!
⚠️ Perbandingan NN vs Fuzzy untuk Kontrol Adaptif
- NN: Belajar otomatis dari data, tidak butuh pakar. Tapi "black box" — sulit diinterpretasi.
- Fuzzy: Interpretable (aturan bisa dibaca manusia), butuh pengetahuan pakar. Tidak perlu data banyak.
- Neuro-Fuzzy (ANFIS): Kombinasi keduanya! NN digunakan untuk mengoptimasi parameter membership function fuzzy. Sesi 11 membahas ini.
🧠 Kuis Pemahaman Sesi 10
1. Apa keunggulan utama Neural Network dibanding model state-space linier untuk identifikasi sistem?
2. Backpropagation dalam NN dan MIT Rule dalam MRAC memiliki kesamaan konsep, yaitu?
3. NARX (Nonlinear AutoRegressive with eXogenous) cocok untuk sistem dinamis karena?