Sıradaki

MSE gradyanı

Zorluk: Orta

kalkülüsdoğrusal modeller

Bu problemde doğrusal bir modelin ortalama kare hatasının (mean squared error, MSE) gradyanını (gradient) hesaplarsın. Gradyanı ağırlıklara (weight) ve sapmaya (bias) göre alırsın.

Gradyan inişi (gradient descent), parametreleri kaybı (loss) azaltan yönde oynatır. Bu yön gradyanın tersidir. Gradyan loss’u en hızlı artıran yönü gösterir, bu yüzden işareti doğru olmalı.

mse_gradient(X, y, w, b) 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.
  • w: her feature için bir weight içeren, (d,) shape’inde bir vektör.
  • b: tek bir sayı.

Model y^=Xw+b\hat{\mathbf{y}} = X\mathbf{w} + b tahminlerini (prediction) üretir. MSE şudur:

L=1N∑i=1N(y^i−yi)2L = \frac{1}{N}\sum_{i=1}^{N} (\hat{y}_i - y_i)^2

Gradyanın her bileşeni bir kısmi türevdir (partial derivative). Kısmi türev, diğer parametreler sabitken tek bir parametre değişince loss’un ne kadar değiştiğini gösterir. Gradyanın iki parçası vardır:

∂L∂w,∂L∂b\frac{\partial L}{\partial \mathbf{w}}, \qquad \frac{\partial L}{\partial b}

Birincisi her weight için bir sayı, ikincisi tek bir sayı verir.

(grad_w, grad_b) çiftini bir tuple olarak döndür. grad_w, (d,) shape’inde bir array’dir. grad_b bir float’tur.

Örnekler

Girdi: X = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], y = [3.0, 5.0, 7.0], w = [0.5, -0.5], b = 1.0
Çıktı: (array([-32.33333333, -41.33333333]), -9.0)

Girdi: X = [[1.0, 2.0, 3.0]], y = [4.0], w = [0.0, 0.0, 0.0], b = 0.0
Çıktı: (array([ -8., -16., -24.]), -8.0)

Girdi: X = [[-1.0, 2.0, 0.5], [3.0, -2.0, 1.0], [0.0, 1.5, -3.0]], y = [2.0, -1.0, 0.5], w = [-0.5, 1.0, 2.0], b = -1.5
Çıktı: (array([-4. , -3.83333333, 11.66666667]), -5.666666666666666)

İpucu 1

Tek bir örneğin hatası e=y^−ye = \hat{y} - y, loss’u e2e^2‘dir. Bir parametre artınca tahmin şöyle değişir:

  • wjw_j bir miktar artarsa tahmin o miktarın xjx_j katı kadar artar.
  • bb aynı miktar artarsa tahmin o miktarın 11 katı kadar artar.

e2e^2‘nin türevini bu iki bilgiden çıkar.

İpucu 2

Tüm örneklerin gradyanı, tek tek gradyanların ortalamasıdır. Her wjw_j için bu, ii üzerinden bir toplamdır. Bütün jj‘lerin toplamını tek bir matris çarpımı olarak yazabilirsin.

X (n, d), hata (n,) shape’indedir. Sonucun (d,) shape’inde olması için hata vektörünü X’in hangi hâliyle çarpacağına bak.

İpucu 3

Önce hata vektörünü hesapla: error = y_hat - y. Sonra iki gradyanı çıkar:

  • grad_w, X.T @ error’ın 2/N2/N katıdır.
  • grad_b, hataların toplamının 2/N2/N katıdır.

Gereksinimler

  • X (n, d), y (n,) ve w (d,) shape’inde array’lerdir. b bir float’tur. En az bir örnek vardır.
  • (grad_w, grad_b) biçiminde bir tuple döndür. grad_w (d,) shape’inde bir NumPy array’i olmalı, (d, 1) bir sütun değil.
  • grad_b tek bir float’tur. np.sum’ın verdiği np.float64 de kabul edilir.
  • Gradyan loss’u artıran yönü gösterir: hatayı y^−y\hat{y} - y sırasıyla al. İşareti ters çıkan bir gradyan, gradient descent’i loss’u azaltmak yerine artırmaya iter.
  • Gradyan, NN örneğin ortalamasıdır, toplamı değil.
  • X’i, y’yi ve w’yi değiştirme. Fonksiyon bittiğinde onu çağıran kodun array’leri aynı kalmalı.
  • Örnekler üzerinde döngü kullanma: bir matris çarpımı ve bir toplam yeter.

Gradyan, her parametre için bir kısmi türev içerir. Tek bir örnekte hata e=y^−ye = \hat{y} - y, loss e2e^2‘dir. wjw_j için türev iki adımda çıkar:

  1. wjw_j küçük bir δ\delta kadar artarsa tahmin xjδx_j\delta kadar artar, yani ee de xjδx_j\delta kadar artar.
  2. e2e^2 ise hatadaki değişimin 2e2e katı kadar artar.

Bias her tahmine doğrudan eklenir. Bu yüzden çarpanı xjx_j yerine 11‘dir. İki türev şöyledir:

∂(e2)∂wj=2e xj,∂(e2)∂b=2e\frac{\partial (e^2)}{\partial w_j} = 2e\,x_j, \qquad \frac{\partial (e^2)}{\partial b} = 2e

NN örneğin ortalamasını alıp hepsini matris biçiminde yazınca gradyan şu olur:

∂L∂w=2NX⊤(y^−y),∂L∂b=2N∑i=1N(y^i−yi)\frac{\partial L}{\partial \mathbf{w}} = \frac{2}{N}X^\top(\hat{\mathbf{y}} - \mathbf{y}), \qquad \frac{\partial L}{\partial b} = \frac{2}{N}\sum_{i=1}^{N}(\hat{y}_i - y_i)
  • Birincisi, her feature için o feature’ın değerleriyle hataların çarpımlarının ortalamasının iki katıdır.
  • İkincisi, hataların ortalamasının iki katıdır.

Küçük bir örnek: tek feature’lı iki örnekte x=(1,2)x = (1, 2), y=(3,5)y = (3, 5), w=0w = 0 ve b=0b = 0 olsun. Tahminler 00 ve 00, hatalar −3-3 ve −5-5 çıkar:

∂L∂w=22(1⋅(−3)+2⋅(−5))=−13,∂L∂b=22(−3−5)=−8\frac{\partial L}{\partial w} = \frac{2}{2}\bigl(1\cdot(-3) + 2\cdot(-5)\bigr) = -13, \qquad \frac{\partial L}{\partial b} = \frac{2}{2}(-3 - 5) = -8

İkisi de negatiftir. Gradient descent parametrelerden gradyanı çıkarır. Bu yüzden hem ww hem bb artar ve tahminler target’lara yaklaşır.

Bu sade form, MSE ile doğrusal modelin birleşiminden çıkar. Her model ve loss için böyle kısa bir formül yoktur. Sinir ağlarında gradyanı elle türetmek yerine geri yayılımla (backpropagation) hesaplarsın.

Türettiğin bir gradyandan emin değilsen, onu Sayısal gradyan problemindeki yöntemle karşılaştırabilirsin.

Daha fazlası için Doğrusal regresyon dersine bak.

Çözüm üç adımdır:

  1. Hatayı hesapla.
  2. Weight gradyanı için hatayı X⊤X^\top ile çarp. Bias gradyanı için hataları topla.
  3. İkisini de 2/N2/N ile ölçekle.

Kodda bu üç adım şöyle görünür:

import numpy as npdef mse_gradient(X: np.ndarray, y: np.ndarray, w: np.ndarray, b: float) -> tuple[np.ndarray, float]:    n = X.shape[0]    y_hat = X @ w + b    error = y_hat - y    grad_w = 2 / n * (X.T @ error)    grad_b = 2 / n * np.sum(error)    return grad_w, float(grad_b)

Sık yapılan hata, farkı ters sırada almaktır: y - y_hat. Gradyanın işareti değişir ve gradient descent loss’u azaltmak yerine artırır.

Bir diğer hata, X.T @ error yerine X @ error yazmaktır. n ile d farklıysa shape hatası çıkar. n == d ise sessizce yanlış bir sonuç çıkar.

Bu problemde bir sorun mu var?

solution.py
import numpy as npdef mse_gradient(X: np.ndarray, y: np.ndarray, w: np.ndarray, b: float) -> tuple[np.ndarray, float]:    """Ortalama kare hatanın ağırlıklara ve sapmaya göre gradyanını (grad_w, grad_b) döndürür."""    # Kodunu buraya yaz.    return np.zeros_like(w), 0.0

İçindekiler

Geri bildirim

Tür