Sıradaki

Xavier ve He ilklendirmesi

Zorluk: Orta

sinir ağları

Bir ağı eğitmeden önce ağırlıklarını (weight) doğru ölçekte rastgele başlatmalısın. Buna ilklendirme (initialization) denir. init_weights(layer_sizes, method="he", seed=0) fonksiyonunu yaz. Fonksiyon, katman (layer) boyutlarına göre weight matrislerini üretir.

layer_sizes = [2, 16, 1] şu ağı anlatır: 2 girdi, 16 nöronlu bir hidden layer ve 1 çıktı. İki ardışık boyut bir matris verir. Bu örnekte iki matris vardır: (2, 16) ve (16, 1). Genel olarak W(l)W^{(l)} matrisinin shape’i (d_in, d_out) olur.

Her eleman, ortalaması 0 olan bir normal dağılımdan (normal distribution) gelir. Standart sapma (std) yönteme göre değişir. dind_{\text{in}} layer’ın girdi, doutd_{\text{out}} çıktı sayısıdır:

sXavier=2din+doutsHe=2dins_{\text{Xavier}} = \sqrt{\frac{2}{d_{\text{in}} + d_{\text{out}}}} \qquad s_{\text{He}} = \sqrt{\frac{2}{d_{\text{in}}}}

Xavier hem girdi hem çıktı sayısına bakar. He yalnızca girdi sayısına bakar. Fonksiyon, her layer için bir matris içeren bir liste döndürür.

Örnekler

Girdi: layer_sizes = [2, 4, 1], method = 'he', seed = 0
Çıktı: (array([[ 0.12573022, -0.13210486, 0.64042265, 0.10490012], [-0.53566937, 0.36159505, 1.30400005, 0.94708096]]), array([[-0.49761596], [-0.8947881 ], [-0.4407216 ], [ 0.02922188]]))

Girdi: layer_sizes = [3, 5, 5, 2], method = 'xavier', seed = 1
Çıktı: (array([[ 0.1727921 , 0.41080907, 0.16521854, -0.65157862, 0.45267793], [ 0.22318729, -0.26847662, 0.29055905, 0.1822862 , 0.14706625], [ 0.01421112, 0.27335649, -0.36822704, -0.08145497, -0.24105966]]), array([[ 0.26781217, 0.01776427, -0.13079064, -0.34968009, -0.11501987], [ 0.00364129, -0.12325337, 0.57872293, 0.4502208 , -1.21246872], [-0.84479241, -0.07…

Girdi: layer_sizes = [10, 2, 10], method = 'he', seed = 42
Çıktı: (array([[ 0.13627362, -0.46509503], [ 0.33561198, 0.42063333], [-0.87252946, -0.58235238], [ 0.05717197, -0.14142799], [-0.00751371, -0.38149284], [ 0.39327873, 0.34783913], [ 0.02952983, 0.50411759], [ 0.20907653, -0.38428727], [ 0.16491036, -0.42882534], [ 0.39285492, -0.02232755]]), array([[-0.18486236, -0.68092954, 1.22254134,…

İpucu 1

zip(layer_sizes[:-1], layer_sizes[1:]) her layer’ın (d_in, d_out) çiftini verir. Matrisleri bir listede topla.

İpucu 2

Her layer için önce std’yi hesapla. Xavier’de paydada d_in + d_out, He’de yalnızca d_in vardır. np.sqrt kullan. Yöntemi döngüden önce, bir kez denetle.

İpucu 3

Tek bir rng oluştur ve bütün layer’larda onu kullan. Her layer’da yeniden default_rng(seed) çağırırsan bütün matrisler aynı sayılardan türer.

Gereksinimler

  • Dönüş değeri len(layer_sizes) - 1 uzunluğunda bir listedir. ll. eleman, shape’i (layer_sizes[l], layer_sizes[l + 1]) olan bir float array’idir.
  • Rastgele sayıları şu sırayla üret: önce rng = np.random.default_rng(seed) oluştur. Sonra her layer için, baştan sona sırayla, tek çağrıyla rng.normal(0.0, std, (d_in, d_out)) çağır. Aynı seed aynı matrisleri verir ve testler değerleri bu sıraya göre karşılaştırır. np.random.seed kullanma.
  • Yalnızca weight’leri döndür. Sapmalar (bias) sıfırla başlar ve bu fonksiyonun işi değildir.
  • method yalnızca "xavier" ya da "he" olabilir. Başka bir değerde ValueError fırlat.
  • layer_sizes’ı değiştirme.

Initialization, sinyalin layer’lar boyunca ne büyümesini ne de sönmesini sağlar. Bir nöronun çıktısı şu toplamdır:

z=∑iwixiz = \sum_i w_i x_i

Weight’ler bağımsızsa ve ortalamaları 0 ise zz‘nin varyansı din Var(w) E[x2]d_{\text{in}} \, \mathrm{Var}(w) \, \mathrm{E}[x^2] olur. Weight’lerin varyansı 1/din1/d_{\text{in}}‘den çok büyükse sinyal layer layer büyür, çok küçükse söner.

  • Xavier, girdi ve çıktı sayısının ortalamasına bakar. İleri geçişte (forward pass) aktivasyonların, geri geçişte (backward pass) gradyanların ölçeğini birlikte korumaya çalışır. tanh ve sigmoid için uygundur.
  • He, ReLU için düzeltme yapar. ReLU nöronların yaklaşık yarısını sıfırlar. Varyansı bu yüzden 2 ile çarpar.

Sıfırla ilklendirme işe yaramaz. Bir layer’ın bütün nöronları aynı değerle başlarsa aynı çıktıyı ve aynı gradyanı alır. Hepsi birlikte güncellenir ve hiçbir zaman birbirinden ayrılmaz. Rastgelelik bu simetriyi (symmetry) bozar.

Daha fazlası için Bir MLP eğitmek dersine bak.

Yöntemi denetle, tek bir rng oluştur ve her layer için standart sapmayı hesaplayıp matrisi çek:

import numpy as npdef init_weights(layer_sizes: list[int], method: str = "he", seed: int = 0) -> list[np.ndarray]:    if method not in ("xavier", "he"):        raise ValueError(f"Bilinmeyen yöntem: {method!r}")    rng = np.random.default_rng(seed)    weights = []    for d_in, d_out in zip(layer_sizes[:-1], layer_sizes[1:]):        if method == "xavier":            std = np.sqrt(2.0 / (d_in + d_out))        else:            std = np.sqrt(2.0 / d_in)        weights.append(rng.normal(0.0, std, (d_in, d_out)))    return weights

Sık yapılan hata, standart sapmayı varyansla karıştırmaktır. Formüldeki 2/din2/d_{\text{in}} varyanstır. rng.normal ise standart sapma ister, yani karekökü. Karekökü unutursan ölçek yanlış çıkar: din=50d_{\text{in}} = 50 için std 0,2 yerine 0,04 olur ve sinyal layer layer söner.

Bir başka sık hata, He’de d_in yerine d_out kullanmaktır. Katmanlar kare değilse ölçek yanlış olur.

Bu problemde bir sorun mu var?

solution.py
import numpy as npdef init_weights(layer_sizes: list[int], method: str = "he", seed: int = 0) -> list[np.ndarray]:    """Katman boyutlarına göre Xavier ya da He ilklendirmesiyle ağırlık matrisleri üretir."""    # Kodunu buraya yaz.    return [np.zeros((d_in, d_out)) for d_in, d_out in zip(layer_sizes[:-1], layer_sizes[1:])]

İçindekiler

Geri bildirim

Tür