Calculus Intuition

4 jam17 min baca
Tujuan

Paham turunan, gradient, dan chain rule **secara visual** — supaya saat backpropagation muncul di Fase 6, kamu sudah punya gambaran.

05 — Calculus Intuition

Estimasi: 4 jam Prasyarat: 04-linear-algebra.md Tujuan: Paham turunan, gradient, dan chain rule secara visual — supaya saat backpropagation muncul di Fase 6, kamu sudah punya gambaran.

WAJIB SEBELUM BACA: tonton 3Blue1Brown "Essence of Calculus" Episode 1-6 (~2 jam total). Episode 1-3 wajib, 4-6 sangat disarankan.


Pembukaan

Kalkulus terdengar mengintimidasi. Tapi untuk ML, kita cuma butuh 2 konsep:

  1. Turunan (derivative) — seberapa cepat sesuatu berubah
  2. Chain rule — turunan dari komposisi function

Selesai. Tidak perlu hafal rumus turunan trigonometri atau integral kompleks. Itu untuk physicist atau engineer mesin.


Kenapa Materi Ini Penting?

Setiap kali sebuah neural network "belajar", yang sebenarnya terjadi adalah turunan + chain rule. Tanpa kalkulus, training NN cuma sihir gelap.

flowchart LR
    D["📐 Derivative<br/>(slope)"] --> GD["⛰️ Gradient Descent<br/>(turun gunung loss)"]
    GD --> T["🔧 Update weight"]
    CR["🔗 Chain Rule"] --> BP["⏪ Backpropagation"]
    BP --> T
    T --> L["📉 Loss turun"]
Konsep Kalkulus Dipakai di Mana di AI/ML
Derivative Mengukur seberapa sensitif loss terhadap weight
Gradient (∇) Arah update weight di setiap step training
Chain rule Backpropagation — propagasi error mundur lewat layer
Partial derivative Update tiap parameter satu-satu (jutaan parameter)
Learning rate Ukuran langkah turun gunung

Bottom line: training ChatGPT = jalankan gradient descent miliaran kali pada loss function. Paham kalkulus = paham kenapa model bisa belajar.


Bagian 1 — Turunan (Derivative)

Intuisi

Turunan = rate of change = kemiringan.

Bayangkan kamu nyetir mobil:

  • Posisi mobil = function f(t)
  • Kecepatan = turunan f(t) terhadap t

Kecepatan mengukur: "seberapa cepat posisi berubah per satuan waktu?"

Analogi tambahan "speedometer": turunan itu seperti speedometer. Kalau posisi mobil = function dari waktu, turunan = jarum speedometer. Saat ngebut, turunan besar. Saat berhenti, turunan = 0. Saat mundur, turunan negatif.

flowchart LR
    F["📍 Position<br/>f(t)"] -->|"turunan d/dt"| V["🚗 Velocity<br/>f'(t)"]
    V -->|"turunan d/dt"| A["⚡ Acceleration<br/>f''(t)"]

Visualisasi

   y
   |       ╱
   |      ╱
   |    ╱
   |  ╱  ← turunan = kemiringan garis ini
   |╱
   ──────────── x

Turunan di titik tertentu = kemiringan garis singgung di titik itu.

Cara Membaca Diagram:

  • Node atas = titik (x, f(x)) tempat kita evaluasi turunan.
  • Node tengah = pertanyaan: garis di titik ini menanjak, datar, atau menurun?
  • 3 node bawah = tiga kemungkinan tanda f'(x).

Walkthrough Step-by-Step:

  1. Pilih titik di kurva, lihat kemiringan garis singgung.
  2. Kalau menanjak ke kanan → f'(x) > 0; datar → 0; turun → negatif.
  3. Tanda turunan = arah pergerakan lokal grafik.

Analogi Sehari-hari: speedometer mobil. Maju cepat = positif, berhenti = nol, mundur = negatif.

Diagram statis Mermaid sebagai fallback:

flowchart TD
    P["📍 Titik (x, f(x))"] --> Q1{"Garis<br/>menanjak?"}
    Q1 -->|Iya| Pos["📈 f'(x) > 0<br/>(slope positif)"]
    Q1 -->|"Datar"| Zero["➖ f'(x) = 0<br/>(puncak/lembah)"]
    Q1 -->|"Menurun"| Neg["📉 f'(x) < 0<br/>(slope negatif)"]

Notasi

dy/dx       — Leibniz notation
f'(x)       — Lagrange notation
∂y/∂x       — partial derivative (multi-variabel)

Semua artinya sama: turunan y terhadap x.

Contoh Sederhana

f(x) = x²

f'(x) = 2x

Berarti:

  • Di x=1, kemiringan = 2
  • Di x=2, kemiringan = 4
  • Di x=10, kemiringan = 20

Semakin x besar, kemiringan semakin tajam.

Worked Example — Hitung Turunan dari Definisi

Apa sebenarnya f'(x) = 2x itu? Mari turunkan dari definisi:

f'(x) = lim (h→0) [f(x+h) - f(x)] / h

Untuk f(x) = x²:
     = lim (h→0) [(x+h)² - x²] / h
     = lim (h→0) [x² + 2xh + h² - x²] / h
     = lim (h→0) [2xh + h²] / h
     = lim (h→0) [2x + h]
     = 2x

Intuisi: ambil 2 titik super dekat di kurva, hitung "rise/run". Kalau jarak h → 0, kita dapat slope di satu titik.

flowchart LR
    P1["📍 (x, f(x))"] --> Slope["📐 Rise / Run<br/>= Δf / Δx"]
    P2["📍 (x+h, f(x+h))"] --> Slope
    Slope --> Lim["⏬ h → 0"]
    Lim --> D["✨ f'(x)"]

Rumus Turunan Dasar (Sekedar Tahu)

f(x) f'(x)
c (konstanta) 0
x 1
xⁿ n × xⁿ⁻¹
ln(x) 1/x
sin(x) cos(x)
cos(x) -sin(x)

Tidak perlu hafal. PyTorch hitung otomatis (autograd). Yang penting paham konsep.


Bagian 2 — Partial Derivative

Kalau function punya banyak variabel, kita bisa ambil turunan terhadap satu variabel saja, anggap yang lain konstan.

f(x, y) = x²y + 3y

∂f/∂x = 2xy        (y dianggap konstan)
∂f/∂y = x² + 3     (x dianggap konstan)

Interpretasi

∂f/∂x = "kalau x berubah sedikit (y tetap), seberapa berubah f?"

Penting di ML karena loss function punya jutaan variabel (weight di NN).


Bagian 3 — Gradient (∇)

Gradient = vektor yang isinya semua partial derivative.

f(x, y) = x²y + 3y

∇f = [∂f/∂x, ∂f/∂y] = [2xy, x² + 3]

Intuisi Gradient

Gradient adalah vektor yang menunjuk arah kenaikan tercepat.

Bayangkan kamu di gunung:

  • Posisi = (x, y)
  • Ketinggian = f(x, y)
  • Gradient di posisi tsb = arah ke atas paling curam

Analogi "kompas pendaki": gradient itu seperti kompas yang selalu menunjuk ke puncak terdekat. Kalau kamu di lereng dan butuh naik secepat mungkin, ikuti gradient. Kalau butuh turun secepat mungkin, ikuti negatif gradient.

flowchart TD
    Pos["📍 Posisi (x, y)<br/>di lereng gunung"] --> Grad["🧭 ∇f<br/>arah naik tercuram"]
    Grad --> Up["⬆️ Ikuti +∇f<br/>= naik puncak"]
    Grad --> Down["⬇️ Ikuti -∇f<br/>= turun lembah<br/>(GRADIENT DESCENT!)"]
            
            |
            |  gradient
       ╱╲   |
      ╱  ╲  ↑
         
          

Negative Gradient = Arah Turun Tercepat

Untuk turun ke lembah (minimize loss), kita gerak ke arah negative gradient.

Itulah inti gradient descent.


Bagian 4 — Gradient Descent

Algoritma optimisasi paling penting di ML.

Algoritma

1. Mulai dari titik random
2. Hitung gradient di titik tsb
3. Step ke arah -gradient (turun)
4. Ulangi sampai konvergen

Visualisasi sebagai Flow

Cara Membaca Diagram:

  • Node Start = inisialisasi weight random.
  • Compute ∇L = hitung gradient di posisi sekarang.
  • w = w - α·∇L = step ke arah berlawanan gradient (turun gunung).
  • Decision Loss min? = cek konvergensi; loop balik atau lanjut ke Done.

Walkthrough Step-by-Step:

  1. Pilih titik awal random untuk weight.
  2. Hitung gradient di titik tsb (arah naik tercepat).
  3. Bergerak ke arah negatif gradient sejauh learning rate × gradient.
  4. Cek loss; kalau belum minimum, ulangi dari langkah 2.

Analogi Sehari-hari: turun gunung di tengah kabut. Setiap langkah, raba kemiringan kaki, lalu melangkah ke arah paling curam ke bawah.

Diagram statis Mermaid sebagai fallback:

flowchart LR
    S["📍 Start point<br/>(random weight)"] --> G["📐 Compute<br/>gradient ∇L"]
    G --> M["⬇️ Move opposite<br/>w = w - α·∇L"]
    M --> C{"Loss<br/>minimum?"}
    C -->|Belum| G
    C -->|Sudah| E["🎯 Done!<br/>(model trained)"]

Pseudocode

# Initialize random
w = np.random.randn(n)

learning_rate = 0.01

for step in range(1000):
    # Forward: compute loss
    loss = compute_loss(w)
    
    # Backward: compute gradient
    gradient = compute_gradient(w)
    
    # Update
    w = w - learning_rate * gradient

Visualisasi 2D

       Loss
        |
   ╱╲   |   ╱
  ╱  ╲  |  ╱
 ╱    ╲_|_╱   ← lembah (minimum)
                  ← konvergen ke sini

Algoritma turun selangkah demi selangkah.

Learning Rate

learning_rate mengontrol ukuran langkah.

  • Terlalu kecil → lambat sekali konvergen
  • Terlalu besar → lompat-lompat, mungkin malah divergen
  • Sweet spot → konvergen efisien

Salah satu hyperparameter paling penting di ML. Akan banyak di-tune.

flowchart TD
    LR["🎚️ Learning Rate α"] --> Small["🐢 α terlalu kecil<br/>(misal 0.0001)"]
    LR --> Just["✅ α pas<br/>(misal 0.01)"]
    LR --> Big["💥 α terlalu besar<br/>(misal 1.0)"]
    Small --> SR["Lambat banget,<br/>butuh ribuan epoch"]
    Just --> JR["Konvergen<br/>cepat & stabil"]
    Big --> BR["Lompat-lompat,<br/>loss naik (divergen)"]

Variants Modern

  • SGD (Stochastic Gradient Descent) — pakai sampel data, bukan semua
  • Mini-batch GD — pakai batch kecil
  • Momentum — tambahkan "inertia"
  • Adam — adaptive learning rate, paling populer
  • AdamW — variant Adam yang lebih bagus untuk transformer

Bagian 5 — Chain Rule (Inti Backpropagation!)

Wajib paham. Inti dari backpropagation.

Konsep

Kalau y bergantung pada u, dan u bergantung pada x, maka:

dy/dx = dy/du × du/dx

Analogi "rantai roda gigi": chain rule itu seperti rantai roda gigi. Kalau roda A muter 2x lebih cepat dari B, dan B muter 3x lebih cepat dari C, maka A muter 2×3=6x lebih cepat dari C. Setiap turunan = rasio kecepatan, dan kalikan rasio sepanjang rantai.

Cara Membaca Diagram:

  • Node kiri (x) = variabel input.
  • Node tengah (u = g(x)) = nilai antara, edge bertanda du/dx.
  • Node kanan (y = f(u)) = output akhir, edge dy/du.
  • Edge putus-putus = total turunan dy/dx = perkalian rasio.

Walkthrough Step-by-Step:

  1. Pecah fungsi komposit y = f(g(x)) jadi dua langkah: u = g(x) lalu y = f(u).
  2. Hitung du/dx (lokal) dan dy/du (lokal).
  3. Kalikan keduanya untuk total dy/dx.

Analogi Sehari-hari: kalau gaji naik 10% per pengalaman dan biaya hidup naik 5% per gaji, total dampak pengalaman ke biaya hidup = 10% × 5% = 0.5% per pengalaman.

Diagram statis Mermaid sebagai fallback:

flowchart LR
    X["📥 x"] -->|"du/dx"| U["🔁 u = g(x)"]
    U -->|"dy/du"| Y["📤 y = f(u)"]
    X -.->|"dy/dx = (dy/du) × (du/dx)"| Y

Contoh

y = sin(x²)

Dipecah:
u = x²
y = sin(u)

dy/du = cos(u)
du/dx = 2x

dy/dx = cos(u) × 2x = cos(x²) × 2x

Analogi Intuitif

Bayangkan rantai sebab-akibat:

Polusi → Sakit → Biaya rumah sakit

Kalau polusi bertambah 10%, dan sakit bertambah 20% per polusi, dan biaya bertambah 30% per sakit:

Total efek polusi terhadap biaya = 20% × 30% = 6% per peningkatan polusi.

Itulah chain rule.

Aplikasi di Neural Network

NN adalah chain of functions:

input → layer1 → layer2 → layer3 → output → loss

Untuk update weight di layer1, kita butuh ∂loss/∂W₁. Pakai chain rule:

∂loss/∂W₁ = ∂loss/∂output × ∂output/∂layer3 × ... × ∂layer1/∂W₁

Hitungnya mundur dari loss → input. Itulah backpropagation.

Insight: backpropagation = chain rule + bookkeeping. Algoritma yang sangat simple secara konsep, tapi powerful saat di-skalakan.

flowchart LR
    X["📥 input"] -->|forward| L1["Layer 1<br/>W₁"]
    L1 -->|forward| L2["Layer 2<br/>W₂"]
    L2 -->|forward| L3["Layer 3<br/>W₃"]
    L3 -->|forward| Loss["📉 Loss"]
    Loss -.->|"∂L/∂W₃"| L3
    L3 -.->|"chain rule"| L2
    L2 -.->|"chain rule"| L1
    L1 -.->|"∂L/∂W₁"| X

Forward (hitam) = prediksi. Backward (putus-putus) = chain rule untuk update weight.


Bagian 6 — PyTorch Autograd (Bagaimana Magic Bekerja)

PyTorch hitung gradient otomatis pakai autograd.

import torch

# Tensor dengan tracking gradient
x = torch.tensor(3.0, requires_grad=True)
y = x ** 2

# Backward (hitung gradient)
y.backward()

# Akses gradient
print(x.grad)    # 6.0  (turunan x² di x=3 = 2×3 = 6)

Cara Kerja (Konseptual)

  1. PyTorch track semua operasi yang melibatkan tensor dengan requires_grad=True
  2. Build computation graph secara dinamis
  3. Saat .backward() dipanggil, PyTorch traverse graph mundur, apply chain rule
  4. Gradient tersimpan di tensor.grad
# Example: 2 layer "NN"
W1 = torch.randn(3, 4, requires_grad=True)
W2 = torch.randn(2, 3, requires_grad=True)
x = torch.randn(4)
target = torch.tensor([1.0, 0.0])

# Forward
h = W1 @ x          # hidden layer
out = W2 @ h        # output

# Loss
loss = ((out - target) ** 2).sum()

# Backward — hitung semua gradient sekaligus!
loss.backward()

print(W1.grad.shape)   # (3, 4)
print(W2.grad.shape)   # (2, 3)

Magic banget. Yang dulunya manual hitung chain rule, sekarang 1 line .backward().


Bagian 7 — Loss Function & Optimization

Apa Itu Loss?

Loss = ukuran "seberapa salah" prediksi model.

Contoh sederhana (MSE - Mean Squared Error):

loss = mean((prediksi - target)²)

Tujuan Training

Minimize loss dengan tune weight.

Workflow Lengkap

for epoch in range(epochs):
    for batch in data:
        # 1. Forward pass
        prediction = model(batch.input)
        
        # 2. Compute loss
        loss = loss_fn(prediction, batch.target)
        
        # 3. Backward pass (compute gradients)
        loss.backward()
        
        # 4. Update weights (gradient descent step)
        optimizer.step()
        
        # 5. Reset gradients (penting!)
        optimizer.zero_grad()

5 step ini = inti semua deep learning dari classifier sederhana sampai ChatGPT.


Bagian 8 — Common Loss Functions (Sneak Peek)

Regression

  • MSE (Mean Squared Error) — most common

    L = mean((y_pred - y_true)²)
    
  • MAE (Mean Absolute Error) — robust ke outlier

    L = mean(|y_pred - y_true|)
    

Classification

  • Cross-Entropy — most common

    L = -sum(y_true × log(y_pred))
    
  • Binary Cross-Entropy — untuk 2 kelas

Tidak perlu hafal rumus

PyTorch sudah implement:

nn.MSELoss()
nn.CrossEntropyLoss()
nn.BCELoss()

Yang penting tahu kapan pakai mana.


Bagian 9 — Konvergensi & Local Minima

Local vs Global Minimum

   Loss
    |
    |  ╱╲      ╱╲
    | ╱  ╲    ╱  ╲
    |╱    ╲__╱    ╲___
    |     ↑       ↑
    |  local      global
    |  minimum    minimum

Gradient descent bisa stuck di local minimum.

Mitigasi

  • Random initialization dari banyak titik
  • Momentum untuk "lompat" lokal
  • Learning rate scheduling — turunkan saat mendekati optimum
  • Stochastic noise dari mini-batch — kadang membantu lompat

Kabar Baik untuk Deep Learning

Dalam ruang dimensi tinggi (ribuan/juta parameter), local minima jarang jadi masalah. Kebanyakan saddle point. Praktiknya, bisa konvergen ke local minimum yang good enough.


Cek Pemahaman

  • Bisa jelaskan turunan dengan analogi mobil + kecepatan?
  • Tahu apa itu gradient dan kenapa penting?
  • Bisa visualisasi gradient descent sebagai turun gunung?
  • Paham peran learning rate?
  • Bisa apply chain rule pada f(g(x))?
  • Tahu PyTorch autograd menghitung gradient otomatis?

Hubungan dengan AI/ML

flowchart TD
    Train["🎯 Training Loop"] --> FW["▶️ Forward Pass<br/>predict = model(x)"]
    FW --> Lo["📉 Loss<br/>loss = (predict - target)²"]
    Lo --> BW["⏪ Backward Pass<br/>(CHAIN RULE)"]
    BW --> Gr["📐 Gradient ∂L/∂w<br/>untuk semua weight"]
    Gr --> Up["⬇️ Gradient Descent<br/>w = w - α·∇L"]
    Up --> FW
Konsep Kalkulus Manifestasi di LLM
Derivative loss.backward() di PyTorch
Chain rule Backpropagation lewat 96+ layer di GPT-3
Gradient descent Setiap step training (jutaan step!)
Learning rate Hyperparameter lr di Adam/AdamW
Local minima Kenapa initialization & schedule penting
Vanishing gradient Kenapa pakai ReLU, ResNet, layer norm

Insight: GPT dilatih dengan jutaan step gradient descent pada terabytes data. Setiap step = forward + chain rule backward + update weight. Dilakukan miliaran kali.


Common Mistakes & FAQ

"Turunan vs Integral, beda apa?"

  • Turunan (derivative) = slope, "seberapa cepat berubah"
  • Integral = area di bawah kurva, "akumulasi total"

Ini saling kebalikan (Fundamental Theorem of Calculus). Tapi di ML hampir selalu pakai turunan, jarang integral. Jadi jangan bingung — fokus ke turunan saja.

"Kenapa minus gradient untuk turun?"

Gradient menunjuk arah naik tercepat. Untuk turun (minimize loss), kita gerak ke arah berlawanan. Itu sebabnya update rule:

w = w - α × ∇L     # MINUS, karena mau turun

Kalau pakai plus, model malah makin buruk (loss naik).

"Kapan training berhenti?"

Idealnya saat gradient ≈ 0 (sudah di lembah). Praktiknya:

  • Jumlah epoch tertentu
  • Validation loss berhenti turun (early stopping)
  • Time/compute budget habis

"Apa beda gradient descent vs SGD vs Adam?"

  • GD (full batch): hitung gradient pakai seluruh dataset → lambat di dataset besar
  • SGD: pakai 1 sample → cepat tapi noisy
  • Mini-batch SGD: pakai batch kecil (32-256 sample) → balance
  • Adam: SGD + adaptive learning rate per parameter + momentum → most popular

Default modern: AdamW untuk transformer.

"Gradient saya NaN, kenapa?"

Penyebab umum:

  • Learning rate kepedean → loss meledak
  • Tidak normalize input
  • Numerical instability (e.g. log(0))
  • Gradient explosion (perlu clip gradient)

Cek: loss.item() setelah beberapa step. Kalau NaN, turunkan lr atau add gradient clipping.

"Apa itu autograd magic?"

PyTorch mencatat computation graph saat forward pass. Setiap tensor.requires_grad=True ditrack. Saat .backward() dipanggil, PyTorch traverse graph mundur, apply chain rule otomatis. Tidak ada magic, cuma bookkeeping.


Challenge 3.5

Challenge 1 — Tonton 3B1B Calculus

Episode 1-6 dari Essence of Calculus. Tulis insight di jurnal.

Challenge 2 — Hitung Turunan Manual

Tanpa search, coba derive:

  1. f(x) = 3x²
  2. f(x) = 5x³ - 2x + 7
  3. f(x) = (x+1)(x-2)
  4. f(x) = sin(x) + cos(x)

Cek dengan WolframAlpha.

Challenge 3 — Implement Gradient Descent

Manual (NumPy, no PyTorch):

import numpy as np

# Goal: find x yang minimize f(x) = (x - 3)² + 2
# Solusi seharusnya: x = 3, f(x) = 2

def f(x):
    return (x - 3) ** 2 + 2

def df(x):
    return 2 * (x - 3)

# Gradient descent
x = 0.0    # starting point
learning_rate = 0.1

for i in range(50):
    grad = df(x)
    x = x - learning_rate * grad
    if i % 5 == 0:
        print(f"Step {i}: x={x:.4f}, f(x)={f(x):.4f}")

Eksperimen:

  • Ubah learning_rate ke 0.01, 0.5, 1.0, 1.5
  • Lihat efeknya: konvergen, lambat, divergen

Challenge 4 — PyTorch Autograd Demo

import torch

# Function: f(x) = x³ - 6x² + 11x - 6
x = torch.tensor(0.0, requires_grad=True)
y = x**3 - 6*x**2 + 11*x - 6

y.backward()
print(f"f(0) = {y.item()}")
print(f"f'(0) = {x.grad.item()}")

# Reset & coba x lain
x = torch.tensor(2.0, requires_grad=True)
y = x**3 - 6*x**2 + 11*x - 6
y.backward()
print(f"f(2) = {y.item()}")
print(f"f'(2) = {x.grad.item()}")

Challenge 5 — Linear Regression dari Nol

Implement linear regression dengan gradient descent:

import numpy as np

# Data sintetis: y = 2x + 1 + noise
np.random.seed(42)
X = np.random.randn(100)
y = 2 * X + 1 + np.random.randn(100) * 0.5

# Initialize parameters
w = 0.0
b = 0.0

learning_rate = 0.01
epochs = 1000

for epoch in range(epochs):
    # Forward: prediction
    y_pred = w * X + b
    
    # Loss: MSE
    loss = np.mean((y_pred - y) ** 2)
    
    # Gradient
    dw = np.mean(2 * (y_pred - y) * X)
    db = np.mean(2 * (y_pred - y))
    
    # Update
    w -= learning_rate * dw
    b -= learning_rate * db
    
    if epoch % 100 == 0:
        print(f"Epoch {epoch}: w={w:.4f}, b={b:.4f}, loss={loss:.4f}")

print(f"\nFinal: y = {w:.4f}x + {b:.4f}")
print(f"True:  y = 2x + 1")

Run, lihat konvergen ke ~2 dan ~1.

Challenge 6 — Visualisasi Gradient Descent

Pakai matplotlib:

  1. Plot function f(x) = (x-3)² + 2
  2. Mark titik awal
  3. Animasi step-by-step gradient descent
import numpy as np
import matplotlib.pyplot as plt

x_range = np.linspace(-2, 8, 100)
y_range = (x_range - 3)**2 + 2

fig, ax = plt.subplots()
ax.plot(x_range, y_range, label='f(x)')

x = 0.0
points = [x]
for _ in range(20):
    grad = 2 * (x - 3)
    x = x - 0.1 * grad
    points.append(x)

points_y = [(p-3)**2 + 2 for p in points]
ax.scatter(points, points_y, c='red', zorder=5)
ax.plot(points, points_y, 'r--')
ax.legend()
plt.show()

Challenge 7 — Chain Rule Practice

Tanpa search, derive:

  1. y = sin(x²)
  2. y = (3x + 1)⁵
  3. y = e^(x² - 1)
  4. y = ln(x² + 1)

Cek dengan WolframAlpha.

Challenge 8 — Refleksi

Tulis essay 400 kata: "Bagaimana neural network bisa belajar — dijelaskan untuk teman SMA".

Pakai analogi gunung berkabut + chain of effects.


Selanjutnya: 06-statistics-essentials.md — statistik & probabilitas yang kamu butuhkan untuk ML.