Macademia'nın robotik ve mühendislik programı · ücretsiz seviye tespiti ve kişisel öğrenme yolu

Bölüm 2 · Öğrenmenin motoru · Ders 9

Geri yayılım: altı ağırlıktan hangisi suçlu?

Suç çıkıştan başlar, katman katman geriye akar

Veri. Bir robot tutucusunun iki sensörü var: parmak basıncı ve kayma titreşimi. Bu okumalar (ölçekli: 1,0 ve 0,5) küçük bir ağa girer: 2 girdi → 2 gizli nöron → 1 çıktı, toplam altı ağırlık. Nesne sağlam tutulduğu için doğru cevap 1,0; ağ ise 0,701 diyor. Altı ağırlık bu cevabı birlikte üretti: hangisi ne kadar suçlu?

2 sensör → 2 gizli nöron → 1 çıktıaltı ağırlık
1 / 76
geri_yayilim.pypython
  1. import numpy as np
  2. sig = lambda z: 1 / (1 + np.exp(-z))
  3. x = np.array([1.0, 0.5]) # basınç, kayma (ölçekli)
  4. target, lr = 1.0, 3.0 # sağlam kavrama = 1
  5. W1 = np.array([[0.6, 0.6], [-0.5, 0.4]]) # girdi → gizli
  6. W2 = np.array([1.1, 0.3]) # gizli → çıkış
  7. def forward(W1, W2):
  8. h = sig(x @ W1) # gizli katman
  9. return h, sig(h @ W2) # çıktı
  10. L = lambda W1, W2: (forward(W1, W2)[1] - target) ** 2
  11. history = {'step': [], 'loss': [], 'output': [], 'grad_norm_W1': [], 'grad_norm_W2': []} # eğitim geçmişi
  12. for step in range(61):
  13. h, out = forward(W1, W2) # ileri geçiş
  14. loss = (out - target) ** 2 # kayıp
  15. d_out = 2 * (out - target) * out * (1 - out) # çıkışın suçu
  16. gW2 = d_out * h # suç × taşıdığı değer
  17. d_h = d_out * W2 * h * (1 - h) # suç bir katman geri
  18. gW1 = np.outer(x, d_h) # suç × girdi
  19. for k, v in zip(history, (step, loss, out, np.linalg.norm(gW1), np.linalg.norm(gW2))): history[k].append(float(v)) # katman başına gradyan normu
  20. if step == 0: # kontrol: oynat ve ölç
  21. E = np.zeros((2, 2)); E[0, 0] = 1e-6
  22. num = (L(W1 + E, W2) - L(W1 - E, W2)) / 2e-6
  23. print(f"{gW1[0, 0]:.9f} = {num:.9f} ?")
  24. W1 -= lr * gW1; W2 -= lr * gW2 # güncelleme
  25. if step in (0, 1, 60):
  26. print(step, f"{out:.3f}", f"{loss:.4f}") # adım, çıktı, kayıp
  27. for k in ('loss', 'output', 'grad_norm_W1', 'grad_norm_W2'): # son ölçümler tablosu
  28. print(f'{k:<14}{history[k][-1]:>12.6f}')
  29. import csv
  30. with open('egitim_gecmisi.csv', 'w', newline='') as f: # geçmişi CSV'ye yaz
  31. csv.writer(f).writerows([list(history), *zip(*history.values())]) # satır başına bir adım
  32. try:
  33. import matplotlib.pyplot as plt # varsa grafik çiz
  34. fig, ax = plt.subplots(1, 2, figsize=(9, 3.2))
  35. ax[0].plot(history['step'], history['loss']); ax[0].set_yscale('log'); ax[0].set_title('loss')
  36. for k in ('grad_norm_W1', 'grad_norm_W2'): ax[1].plot(history['step'], history[k], label=k)
  37. ax[1].legend(); plt.show()
  38. except ImportError:
  39. print('matplotlib yok: grafik atlandı')

Eğitim paneli

Eğitim çalıştırılıyor…

Sahnedeki her sayı, aynı algoritmanın tarayıcında yapılan gerçek çalıştırmasından gelir (sabit tohum, her seferinde aynı sonuç). Python kodunu kendi bilgisayarında çalıştırırsan rastgele başlangıçlar farklı olacağı için sayılar biraz değişebilir.

Bu dersin kodu verisini kendi içinde üretir; indirilecek dosya yok. Kodu yine de aşağıda tarayıcında çalıştırabilirsin.

Kodu tarayıcıda çalıştırPython · NumPy · matplotlib · Pyodide

Python ve NumPy bu sayfada, tarayıcında çalışır (Pyodide). Kodu değiştirip yeniden çalıştırabilirsin; dersin veri setleri çalışma klasöründe hazır. Kod matplotlib kullanırsa grafikler çıktının altında görünür, yazdığı dosyalar (ör. egitim_gecmisi.csv) indirilebilir.

geri_yayilim.pypython

Çıktı

Çıktı burada görünecek.

Nasıl çalışır

  1. İleri geçiş: girdiler gizli katmandan geçer, tek bir sayı çıkar. Kayıp = (çıktı − hedef)²: 0,09.
  2. Bir ağırlığın gradyanı: onu çok az oynatınca kaybın ne kadar değiştiği. Her ağırlığı tek tek oynatmak yerine kısayol kullanılır.
  3. Kısayol: bir nöronun suçu bir kez hesaplanır. Ona giren her ağırlığın gradyanı = o suç × ağırlığın taşıdığı değer. Suç çıkıştan başlar ve katman katman geriye aktarılır.
  4. Güncelleme: her ağırlık kendi gradyanının tersine kayar. Altı gradyan da negatif, altı ağırlık da artar; çıktı 1 adımda 0,769, 60 adımda 0,968 olur.
  5. Şunu dene: öğrenme oranını 0,5 yap, 60 adımda çıktı ancak 0,907 olur; 6 yap, 0,978’e çıkar.

Neden önemli

Geri yayılım, milyonlarca ağırlıklı bir ağı eğitmeyi mümkün kılan hesaptır: tek bir ileri ve tek bir geri geçişle bütün gradyanlar çıkar. Görüntüden nesne tanıyan, robot kolunu yöneten ya da dil üreten her ağ böyle eğitilir. PyTorch'taki loss.backward() tam olarak bu işi yapar.

ESOF 323, 11. hafta: robotlarda derin öğrenme →
Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç