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

Projeler · Proje 2

Robot kol hedefe uzanır

Üç eklemli kolun ters kinematiğini küçük bir sinir ağı öğrenir

Senaryo. Masaya vidalı üç eklemli bir kol: taban sağa sola döner, omuz ve dirsek yukarı aşağı. Kamera bir parçanın yerini (x, y, z) söylüyor; kolun ucunu oraya götürmek için üç motorun hangi açıya döneceğini bulmamız gerek. Açılardan uç noktasını hesaplamak kolay (ileri kinematik), tersi zor. Formül türetmek yerine kolu rastgele açılarda gezdirip nereye vardığını kaydediyor ve tersini bir ağa öğretiyoruz.

Amaç. Kolun hiç görmediği 200 hedefte ortalama uzaklık 2 cm’nin altına inince eğitim biter.

3B sahne yükleniyor…

eğitim adımı 0 · ortalama hata 98,5 cm
Sürükle: döndür · iki parmak / tekerlek: yakınlaş

Eğitim paneli

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

Model bu sayfada, tarayıcında sıfırdan eğitilir (sabit tohum: aynı ayarlarla her seferinde aynı sonuç). Eğitim her karede küçük parçalar hâlinde yapılır; sekme ya da sahne görünmezken durur.

Adımlar

  1. Veri: kol rastgele açılara getirilir, ileri kinematikle ucun vardığı nokta hesaplanır. Her örnek bir (nokta, açılar) çiftidir. Yalnız “dirsek yukarı” duruşlar kullanılır; aynı noktaya iki farklı duruşla varılabildiği için ağın kafası karışmasın.
  2. Ağ ters yönde çalışır: nokta girer, açılar çıkar. Taban açısı doğrudan değil, kosinüs ve sinüsüyle öğrenilir; böylece −120° ile +120° arasında atlama olmaz.
  3. Her adımda 32 örneklik bir mini grupta tahmin edilen açılar gerçek açılarla karşılaştırılır; ortalama kare hata geri yayılımla ağırlıklara paylaştırılır ve Adam küçük bir adım atar.
  4. Asıl ölçüt açı hatası değil, ucun hedefe uzaklığıdır: ağın verdiği açılar ileri kinematikten geçirilir ve kolun hiç görmediği 200 hedefte ortalama uzaklık (cm) ölçülür.
  5. Sahnede kol sekiz hedefe sırayla uzanır. Eğitimin başında uç hedefin çok uzağında kalır; hata düştükçe kıskaç hedefe oturur ve aradaki çizgi kırmızıdan yeşile döner.

Model

Çok katmanlı sinir ağı ile regresyon: 3 girdi (hedef), iki tanh gizli katman, 4 çıktı (taban açısının kosinüs ve sinüsü, omuz ve dirsek açısı). Kayıp ortalama kare hata, ağırlıklar geri yayılım ve Adam ile güncellenir; doğrusal regresyon, sinir ağı, gradyan inişi ve geri yayılım derslerindeki parçaların aynısı.

Kullanılan dersler: Doğrusal regresyon ve gradyan inişi · Küçük bir sinir ağı · Gradyan inişi: kayıp arazisinde yokuş aşağı · Geri yayılım: altı ağırlıktan hangisi suçlu? · Aşırı öğrenme ve doğrulama

Kendin dene

  1. Gizli nöron sayısını 4’e indir. Ağ bu kadar az nöronla kolun eğri yüzeyini çizemez: hata 7 cm civarında takılır ve 24.000 adımlık bütçe hedefe ulaşmadan biter. 8 nöronla 3 cm civarında kalır; 32 nöron 7.600 adımda 2 cm’nin altına iner.
  2. Öğrenme oranını 0,03’e çıkar. Adımlar büyüdüğü için hata düzgün inmez, zıplar: 3.000. adımdaki hata 1.000. adımdakinden kötüdür ve hedefe 7.600 yerine 18.800 adımda ulaşılır.
  3. Eğitim örneğini 50’ye indir. Eğitim kaybı 2.000 örnektekinden bile düşer (0,00004), ama kolun görmediği hedeflerde hata 6–7 cm’de kalır: ağ 50 duruşu ezberlemiştir, aradaki boşlukları bilmez. Aşırı öğrenme dersindeki durumun aynısı.

Python karşılığı

robot_kol.pypython
  1. import numpy as np
  2. h0, L1, L2 = 0.2, 0.5, 0.4 # omuz yüksekliği, üst kol, ön kol (m)
  3. lo = np.radians([-120, 15, -140]); hi = np.radians([120, 100, -20]) # eklem sınırları, dirsek yukarı
  4. def fk(q): # ileri kinematik
  5. r = L1 * np.cos(q[:, 1]) + L2 * np.cos(q[:, 1] + q[:, 2])
  6. z = h0 + L1 * np.sin(q[:, 1]) + L2 * np.sin(q[:, 1] + q[:, 2])
  7. return np.c_[r * np.cos(q[:, 0]), r * np.sin(q[:, 0]), z]
  8. rng = np.random.default_rng(1)
  9. q = rng.uniform(lo, hi, (2000, 3)) # rastgele duruşlar
  10. X = fk(q) / 0.9; X[:, 2] -= h0 / 0.9 # girdi: uç noktası
  11. mid, half = (lo + hi) / 2, (hi - lo) / 2
  12. Y = np.c_[np.cos(q[:, 0]), np.sin(q[:, 0]), ((q - mid) / half)[:, 1:]] # çıktı: açılar
  13. sizes = [3, 32, 32, 4]
  14. W = [rng.normal(0, 1 / np.sqrt(a), (a, b)) for a, b in zip(sizes, sizes[1:])]
  15. B = [np.zeros(b) for b in sizes[1:]]
  16. def net(A): # ileri hesap: her katmanın çıktısı
  17. a = [A]
  18. for k in range(3): z = a[-1] @ W[k] + B[k]; a.append(np.tanh(z) if k < 2 else z)
  19. return a
  20. def ik(P): # ters kinematik: ağın cevabı
  21. o = net((P - [0, 0, h0]) / 0.9)[-1]
  22. return np.c_[np.arctan2(o[:, 1], o[:, 0]), mid[1:] + o[:, 2:] * half[1:]]
  23. qt = rng.uniform(lo, hi, (200, 3)); test = fk(qt) # kolun hiç görmediği 200 hedef
  24. Yt = np.c_[np.cos(qt[:, 0]), np.sin(qt[:, 0]), ((qt - mid) / half)[:, 1:]]
  25. hata = lambda P: np.linalg.norm(fk(ik(P)) - P, axis=1).mean() * 100 # ucun hedefe ortalama uzaklığı (cm)
  26. history = {'step': [], 'loss': [], 'val_loss': [], 'test_err_cm': []} # eğitim geçmişi
  27. kayip = []
  28. for step in range(1, 20001):
  29. i = rng.integers(0, len(X), 32) # mini grup
  30. a = net(X[i]) # ileri
  31. kayip.append(((a[-1] - Y[i]) ** 2).mean()) # ortalama kare hata
  32. d = 2 * (a[-1] - Y[i]) / a[-1].size # ortalama kare hatanın türevi
  33. for k in (2, 1, 0): # geri yayılım
  34. gW, gB = a[k].T @ d, d.sum(0)
  35. if k: d = (d @ W[k].T) * (1 - a[k] ** 2)
  36. W[k] -= 0.01 * gW; B[k] -= 0.01 * gB # basitlik için düz adım (projede Adam)
  37. if step % 1000 == 0: # her 1000 adımda geçmişe bir satır
  38. val = ((net((test - [0, 0, h0]) / 0.9)[-1] - Yt) ** 2).mean() # doğrulama kaybı: saklı hedefler
  39. for k, v in zip(history, (step, np.mean(kayip), val, hata(test))): history[k].append(v if isinstance(v, int) else float(v))
  40. kayip = []
  41. for k in history: print(f'{k:<12}{history[k][-1]:>12.5f}') # son ölçümler tablosu
  42. print(hata(test), 'cm') # saklı hedeflerde ortalama uzaklık
  43. import csv
  44. with open('egitim_gecmisi.csv', 'w', newline='') as f: # geçmişi CSV'ye yaz
  45. csv.writer(f).writerows([list(history), *zip(*history.values())])
  46. try:
  47. import matplotlib.pyplot as plt # varsa grafik çiz
  48. for k in ('loss', 'val_loss'): plt.plot(history['step'], history[k], label=k)
  49. plt.yscale('log'); plt.xlabel('step'); plt.ylabel('MSE'); plt.legend(); plt.show()
  50. except ImportError:
  51. print('matplotlib yok: grafik atlandı')

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.

robot_kol.pypython

Çıktı

Çıktı burada görünecek.
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ç