Doğrusal regresyon eğit
Zorluk: Zor Çözüldüdoğrusal modelleroptimizasyon
Bu problemde doğrusal regresyonu (linear regression) gradyan inişiyle (gradient descent) eğitirsin. Model, ağırlık (weight) ve sapma (bias) ile tahminlerini (prediction) üretir. Kayıp (loss) olarak ortalama kare hatayı (mean squared error, MSE) kullanırsın.
train(X, y, lr=0.1, epochs=100) fonksiyonunu yaz. Girdiler şunlardır:
X: şekli (shape)(n, d)olan bir dizi (array). Her satır bir örnek (sample), her sütun bir öznitelik (feature) taşır.y: hedef değerleri (target) içeren,(n,)shape’inde bir vektör.lr: öğrenme oranı (learning rate, ).epochs: epoch sayısı. Bir epoch, veri kümesinin (dataset) tamamı üzerinden bir turdur.
‘yi sıfır vektöründen, ‘yi ‘dan başlat. Her epoch’ta tüm örnekleri kullan. Bir epoch şu adımlardan oluşur:
- Tahminleri hesapla.
- İki gradyanı da aynı tahminlerden hesapla.
- İki parametreyi birden güncelle.
Güncelleme şudur:
Son epoch’tan sonra öğrenilen parametreleri (w, b) biçiminde bir tuple olarak döndür. w, (d,) shape’inde bir array’dir. b bir float’tur.
Örnekler
Girdi: X = [[0.0], [1.0], [2.0], [3.0], [4.0]], y = [1.0, 3.0, 5.0, 7.0, 9.0], lr = 0.05, epochs = 200
Çıktı: (array([2.00021768]), 0.9993794316260418)
Girdi: X = [[1.0, 2.0], [3.0, 1.0], [2.0, 2.0]], y = [3.0, 4.0, 5.0], lr = 0.1, epochs = 1
Çıktı: (array([1.66666667, 1.33333333]), 0.8)
Girdi: X = [[-1.0, 0.5], [0.0, -2.0], [1.5, 1.0], [2.0, -0.5]], y = [-2.0, 1.0, 3.0, 0.5], lr = 0.1, epochs = 50
Çıktı: (array([ 1.04945265, -0.05330975]), -0.04378417163098562)
İpucu 1
Döngünün içine bir epoch’u yaz:
- Tahminleri hesapla.
- Hatayı hesapla.
- İki gradyanı hesapla.
- İki parametreyi güncelle.
Gradyan hesabı MSE gradyanı problemindeki hesabın aynısıdır. Sonra bunu epochs kez tekrarla.
İpucu 2
w’yi değiştirmeden önce hem grad_w’yi hem grad_b’yi hesapla. Aksi hâlde b’nin gradyanı, güncellenmiş w’nin tahminlerinden çıkar.
İpucu 3
Küçük bir örnekle kendini kontrol et:
X = [[1.0], [2.0]],y = [1.0, 1.0],lr = 0.1ve bir epoch.- Sıfırdan başlayınca hatalar ve , gradyanlar ve olur.
- Sonuç ve çıkmalı.
Gereksinimler
X(n, d)vey(n,)shape’inde array’lerdir.lrpozitif birfloat’tur.epochs,0ya da daha büyük birint’tir.(w, b)biçiminde bir tuple döndür.w(d,)shape’inde bir NumPy array’i olmalı,(d, 1)bir sütun değil.btek birfloat’tur.np.sum’ın verdiğinp.float64de kabul edilir.w’yi sıfırlardan,b’yi0.0’dan başlat.epochs = 0ise(sıfırlar, 0.0)döndür.- Gradyanları, parametreleri güncellemeden önce, aynı tahminlerden hesapla.
w’yi güncelleyip tahminleri yeniden hesaplarsanb’nin gradyanı farklı çıkar. - Her epoch’ta bütün örnekleri kullanarak tek bir güncelleme yap. Örnek örnek ya da küçük gruplar hâlinde güncelleme yapma.
- Veriyi olduğu gibi kullan:
trainiçinde ölçekleme ya da başka bir ön işlem yapma. - Testlerdeki veriler küçüktür: feature değerleri en fazla 4 civarındadır.
lr = 0.1bu veriler için güvenlidir. - Metrekare gibi yüzlerle ölçülen ham feature’larda aynı
lrıraksar (divergence). Böyle bir veriyitrain’e vermeden önce kendin ölçekle ya dalr’yi küçült. X’i vey’yi değiştirme. Fonksiyon bittiğinde onu çağıran kodun array’leri aynı kalmalı.- Epoch’lar üzerinde bir
fordöngüsü kullan. Örnekler üzerinde döngü kullanma.
Gradient descent, loss’u en hızlı artıran yönün tersine küçük adımlar atar. Doğrusal regresyonda gradyanın formülü bilindiği için eğitim kısa bir döngüdür. Döngü üç adımdır:
- Tahmin et.
- Hatayı ve gradyanı hesapla.
- Parametreleri güncelle.
Her epoch tek bir adım atar, çünkü gradyan bütün örneklerden hesaplanır.
Küçük bir örnekte , ve olsun. Parametreler sıfırdan başlar. İki epoch şöyle ilerler:
| Epoch | Tahminler | Hatalar | Gradyan | Güncellenen |
|---|---|---|---|---|
| 1 | 0; 0 | −3; −5 | ||
| 2 | 2,1; 3,4 | −0,9; −1,6 |
Bu iki noktadan geçen doğru ‘dir. Parametreler ona, yani ve ‘e doğru ilerler.
Learning rate’i yanlış seçersen iki şey olur:
- Çok büyükse adımlar minimumu aşar, loss artar ve parametreler ıraksar.
- Çok küçükse yakınsama (convergence) yavaştır.
Feature’lar büyük ya da çok farklı ölçeklerdeyse aynı learning rate ıraksayabilir ve küçük olanı yavaşlatır. Bu yüzden gerçek veride feature’ları önce ölçeklersin (öznitelik ölçekleme, feature scaling) ve ölçekli veriyi train’e verirsin.
Doğrusal regresyonun çözümü kapalı formda (closed form) da bulunur. Ama gradient descent, kapalı formu olmayan modeller için de çalışan genel yöntemdir.
Daha fazlası için Doğrusal regresyon dersine bak.
Çözüm şu adımlardan oluşur:
- Parametreleri sıfırla.
- Her epoch’ta hatayı bir kez hesapla.
- İki gradyanı bu hatadan çıkar.
- İkisini birden uygula.
Kodda bu adımlar şöyle görünür:
import numpy as npdef train(X: np.ndarray, y: np.ndarray, lr: float = 0.1, epochs: int = 100) -> tuple[np.ndarray, float]: n, d = X.shape w = np.zeros(d) b = 0.0 for _ in range(epochs): error = X @ w + b - y # y_hat - y grad_w = 2 / n * (X.T @ error) grad_b = 2 / n * np.sum(error) w = w - lr * grad_w b = b - lr * grad_b return w, float(b)
Sık yapılan hata, w’yi güncelledikten sonra error’ı yeniden hesaplamaktır. O zaman b’nin gradyanı bu yeni hatadan çıkar. İki gradyan aynı adımın parçasıdır ve aynı tahminlerden gelmelidir.
Sonuç çoğu zaman yine yakınsar, bu yüzden hata fark edilmez. Ama değerler formülle uyuşmaz.
Bu problemde bir sorun mu var?