Gradient check
Untuk loss
L(W)=Nk1n,j∑((XW)nj−Ynj)2hitung ∂L/∂W secara numerik: geser setiap entri W sebesar ±h (beda tengah, h = 1e-5). Hasilnya akan dibandingkan dengan gradien analitik Nk2X⊤(XW−Y), jadi kamu bisa mengecek keduanya sendiri dengan print.
W = [[1]], X = [[1]], Y = [[0]] → [[2.0]]
Untuk apa
Gradien hasil backprop yang salah adalah bug yang paling licin di ML: kode tetap berjalan, loss kadang tetap turun pelan-pelan, tapi model tidak pernah benar-benar bagus. Gradient check membandingkan gradien analitik dengan gradien numerik:
rel_err=max(∣ganalitik∣+∣gnumerik∣, 10−12)∣ganalitik−gnumerik∣Patokan kasarnya: <10−7 bagus, 10−5 masih wajar, dan >10−3 hampir pasti ada bug.
Tips
- Pakai
float64, janganfloat32. - Cek dengan jaringan dan batch yang kecil: biayanya 2 kali forward per parameter.
- Matikan dropout dan semua sumber keacakan saat mengecek.
- Titik patah ReLU di 0 bisa membuat galat besar walau kodenya benar. Hindari input yang tepat 0.
Penjelasan
Yang diminta. Gradien ∂L/∂W untuk L(W)=mean((XW−Y)2), dihitung numerik: geser setiap entri W sedikit dan lihat perubahan loss.
Ide kunci. Ini beda tengah dari soal O1, tapi diterapkan ke setiap parameter satu per satu:
∂Wij∂L≈2hL(W+hEij)−L(W−hEij)Eij adalah matriks yang bernilai 1 hanya di posisi (i,j).
Langkah di kode:
loss = lambda M: ((X @ M - Y) ** 2).mean().for idx in np.ndindex(*W.shape)mengunjungi semua indeks(i, j).- Simpan
old = W[idx], setW[idx] = old + hlalu hitungup, setW[idx] = old - hlalu hitungdown, lalu kembalikanW[idx] = old. Tanpa langkah terakhir ini, entri berikutnya dihitung dariWyang sudah rusak. G[idx] = (up - down) / (2 * h).
Kenapa berguna. Gradien analitiknya Nk2X⊤(XW−Y). Jika backprop-mu memberi angka yang berbeda jauh dari gradien numerik, ada bug. Cobalah print keduanya dan bandingkan.
Biaya. 2 kali forward per parameter. Untuk jaringan berjuta parameter ini terlalu mahal, karena itu gradient check hanya dipakai untuk debugging pada model kecil.
Yang dikembalikan: array berbentuk sama dengan W.
Topik
Petunjuk 1
Untuk setiap entri W[i, j]: geser ke +h, hitung loss; geser ke −h, hitung loss; selisihnya dibagi 2h.
Petunjuk 2
np.ndindex(*W.shape) memberi semua indeks. Jangan lupa mengembalikan W[i, j] ke nilai aslinya setelah selesai.
Nilai ditulis sebagai JSON. Output yang diharapkan dihitung dari solusi referensi.