Xavier ve He ilklendirmesi
Zorluk: Orta Çözüldü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 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. layer’ın girdi, çıktı sayısıdır:
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) - 1uzunluğunda bir listedir. . eleman, shape’i(layer_sizes[l], layer_sizes[l + 1])olan birfloatarray’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ıylarng.normal(0.0, std, (d_in, d_out))çağır. Aynıseedaynı matrisleri verir ve testler değerleri bu sıraya göre karşılaştırır.np.random.seedkullanma. - Yalnızca weight’leri döndür. Sapmalar (bias) sıfırla başlar ve bu fonksiyonun işi değildir.
methodyalnızca"xavier"ya da"he"olabilir. Başka bir değerdeValueErrorfı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:
Weight’ler bağımsızsa ve ortalamaları 0 ise ‘nin varyansı olur. Weight’lerin varyansı ‘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 varyanstır. rng.normal ise standart sapma ister, yani karekökü. Karekökü unutursan ölçek yanlış çıkar: 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?