b belajar.myudak

Cross-entropy dari logits

Untuk batch berisi N contoh dan C kelas, logits[i] adalah skor mentah contoh ke-i, dan targets[i] adalah kelas yang benar. Kembalikan rata-rata cross-entropy:

L=1N∑i−log⁡softmax(zi)yiL = \frac{1}{N}\sum_{i} -\log \text{softmax}(z_i)_{y_i}

Hasilnya harus berhingga walau logits bernilai ±1000.

logits = [[0, 0]], targets = [0]          →  0.6931   // log 2: tebakan 50/50
logits = [[2, 1, 0.1]], targets = [0]     →  0.4170

Intuisi

Cross-entropy menghukum model berdasarkan seberapa kecil probabilitas yang diberikan ke jawaban yang benar. Jika p=1p = 1, loss-nya 0. Jika p=0.5p = 0.5, loss-nya log⁡2≈0.69\log 2 \approx 0.69. Jika p→0p \to 0, loss-nya →∞\to \infty. Model yang yakin tapi salah dihukum sangat berat.

Sebagai patokan, untuk CC kelas tebakan acak memberi loss log⁡C\log C. Untuk model bahasa karakter dengan 65 karakter, loss awal sekitar log⁡65≈4.17\log 65 \approx 4.17. Kalau loss awalmu jauh dari angka ini, ada yang salah dengan inisialisasi.

Kenapa langsung dari logits

−log⁡softmax(z)y=log⁡∑jezj−zy-\log \text{softmax}(z)_y = \log\sum_j e^{z_j} - z_y

Menghitung softmax dulu lalu log bisa menghasilkan log(0) = -inf. Bentuk log-sum-exp di atas stabil. Inilah alasan nn.CrossEntropyLoss di PyTorch menerima logits, bukan probabilitas.

Gradiennya indah

∂Li∂zi=softmax(zi)−onehot(yi)\frac{\partial L_i}{\partial z_i} = \text{softmax}(z_i) - \text{onehot}(y_i)

Gradien ini adalah “prediksi dikurangi kebenaran”, sama seperti regresi linear.

Penjelasan

Yang diminta. Rata-rata −log⁡pbenar-\log p_{\text{benar}} untuk batch logits (N, C) dengan label targets (N,). Hasilnya satu angka.

Ide kunci: jangan hitung softmax lalu log. Tulis langsung:

−log⁡softmax(z)y=−(zy−log⁡∑jezj)=log⁡∑jezj⏟log-sum-exp−zy-\log \text{softmax}(z)_y = -\Bigl(z_y - \log \sum_j e^{z_j}\Bigr) = \underbrace{\log \sum_j e^{z_j}}_{\text{log-sum-exp}} - z_y

Bagian log-sum-exp dihitung stabil dengan trik maksimum: log⁡∑jezj=m+log⁡∑jezj−m\log\sum_j e^{z_j} = m + \log\sum_j e^{z_j - m}.

Langkah di kode:

  1. m = logits.max(axis=1, keepdims=True) berbentuk (N, 1).
  2. lse = m[:, 0] + np.log(np.exp(logits - m).sum(axis=1)) berbentuk (N,).
  3. picked = logits[np.arange(N), targets]. Ini fancy indexing: baris ke-i, kolom targets[i], sehingga terambil logit kelas yang benar untuk setiap contoh.
  4. (lse - picked).mean(), diubah ke float.

Cek. Logits [0, 0]: kedua kelas 50/50, loss =log⁡2≈0.693= \log 2 \approx 0.693. Case [[1000, 0], [0, 1000]] dengan target [0, 0]: contoh pertama benar dan sangat yakin (loss ≈ 0), contoh kedua salah dan sangat yakin (loss ≈ 1000), sehingga rata-ratanya 500.

Yang dikembalikan: satu float.

Topik
losscross-entropylog-sum-exp
Petunjuk 1

CE untuk satu contoh = −log softmax(logits)[target] = log Σ_j exp(z_j) − z_target.

Petunjuk 2

Hitung log Σ exp dengan trik max: m + log Σ exp(z − m). Ambil logit target dengan logits[np.arange(N), targets].

Python 3.14 · NumPy

Pengaturan editor

Ukuran font
Ukuran huruf di editor.
Ukuran tab
Lebar indentasi. Otomatis: 2 spasi untuk TypeScript, 4 untuk Python.
Key bindings
Ganti ke mode Vim.
Nomor baris relatif
Nomor baris dihitung dari posisi kursor (berguna untuk gerakan Vim).
Word wrap
Baris panjang dilipat agar muat di lebar editor.
IntelliSense
Saran kode otomatis saat mengetik (Ctrl+Spasi tetap bisa dipakai saat mati).

Nilai ditulis sebagai JSON. Output yang diharapkan dihitung dari solusi referensi.