Sıradaki

Ters dropout

Zorluk: Kolay

düzenlileştirme

Dropout, eğitim sırasında her birimi (unit) pp olasılıkla rastgele düşürür (sıfırlar) ve ağın tek bir birime fazla güvenmesini engeller. Ters dropout (inverted dropout) bunu yaparken kalan birimleri hemen büyütür; böylece çıkarımda (inference) hiçbir şey değiştirmek gerekmez.

dropout(x, p, training, seed=0) fonksiyonunu yaz. x herhangi bir şekilde (shape) bir dizidir (array), p bir birimin düşürülme olasılığıdır (0≤p<10 \le p < 1), training bir bool’dur ve seed (tohum) maskeyi belirler.

Eğitimde (training=True) maskeyi şöyle üret:

rng = np.random.default_rng(seed)mask = rng.random(x.shape) >= p

True olan birimler kalır, False olanlar düşer. Kalanları 1/(1−p)1/(1-p) ile ölçekle:

y=x⊙m1−p,mi∈{0,1},P(mi=1)=1−py = \frac{x \odot m}{1 - p}, \qquad m_i \in \{0, 1\}, \quad P(m_i = 1) = 1 - p

Çıkarımda (training=False) xx‘i olduğu gibi döndür. Shape’i x ile aynı olan tek bir array döndür.

Örnekler

Girdi: x = [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [-1.0, -2.0, -3.0, -4.0]], p = 0.5, training = True, seed = 0
Çıktı: array([[ 2., 0., 0., 0.], [10., 12., 14., 16.], [-2., -4., -6., -0.]])

Girdi: x = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], p = 0.25, training = True, seed = 7
Çıktı: array([ 1.33333333, 2.66666667, 4. , 0. , 6.66666667, 8. , 0. , 10.66666667])

Girdi: x = [[1.0, -2.0, 3.0], [4.0, 5.0, -6.0]], p = 0.5, training = False, seed = 3
Çıktı: array([[ 1., -2., 3.], [ 4., 5., -6.]])

İpucu 1

rng.random(x.shape), [0, 1) aralığından x ile aynı shape’te rastgele sayılar verir. Bunların p’den büyük ya da eşit olması, bir birimin kalma olasılığını 1−p1 - p yapar.

İpucu 2

Kalan birimlerin sayısı ortalamada 1−p1-p katına iner; ölçekleme bunu telafi eder. Maskeyi x ile çarptıktan sonra 1−p1 - p‘ye böl.

İpucu 3

training yanlışsa maskeye hiç bakma. Fonksiyonun ilk satırında x’i döndürmek yeter.

Gereksinimler

  • Maskeyi tarifteki gibi üret: rng = np.random.default_rng(seed) ve rng.random(x.shape) >= p. Aynı seed aynı maskeyi vermelidir; np.random.seed kullanma.
  • Eğitimde kalan birimleri 1/(1−p)1/(1-p) ile çarp, düşenleri 00 yap.
  • Çıkarımda dropout hiçbir şey yapmaz: ne birim düşer ne ölçekleme olur. p ve seed çıktıyı etkilemez.
  • Dönüş değeri x ile aynı shape’te bir NumPy array’i.
  • p = 0 iken eğitimde de x aynen döner.
  • x’i değiştirme. Fonksiyon bittiğinde çağıran kodun array’i aynı kalır.

Ters dropout, beklenen değeri korur. Bir birimin değeri xx olsun. 1−p1 - p olasılıkla kalır ve x/(1−p)x/(1-p) olur; pp olasılıkla düşer ve 00 olur. Beklenen değer:

(1−p)⋅x1−p+p⋅0=x(1-p)\cdot\frac{x}{1-p} + p\cdot 0 = x

Yani eğitimde çıktı ortalama olarak xx‘e eşittir. Örneğin p=0,5p = 0{,}5 iken kalan birimler 22 ile çarpılır ve bir birimin ortalama katkısı 0,5⋅2=10{,}5 \cdot 2 = 1 olur.

Ölçeklemeyi eğitimde yapmak, çıkarımı basit tutar: çıkarımda hiçbir birim düşmez ve çıktı olduğu gibi geçer. Ölçeklemeyi çıkarıma bırakan eski yöntemde ise çıkarımda her çıktı (1−p)(1-p) ile çarpılmak zorundadır.

Dropout bir düzenlileştirme (regularization) yöntemidir. Her adımda farklı bir alt ağ eğitilir, bu yüzden ağ tek bir birimin varlığına güvenemez. Bu, aşırı öğrenmeyi (overfitting) azaltır.

Daha fazlası için Normalizasyon ve düzenlileştirme dersine bak.

Çıkarımda x’i döndür; eğitimde maskeyi üret, x’e uygula ve 1−p1 - p‘ye böl:

import numpy as npdef dropout(x: np.ndarray, p: float, training: bool, seed: int = 0) -> np.ndarray:    if not training:        return x.copy()    rng = np.random.default_rng(seed)    mask = rng.random(x.shape) >= p    return x * mask / (1.0 - p)

Sık yapılan hata, ölçeklemeyi unutmak ya da ters yöne uygulamaktır. Ölçeksiz dropout’ta eğitimde çıktının ortalaması 1−p1-p katına iner. Çıkarımda da 1/(1−p)1/(1-p) ile çarparsan ters dropout’un amacını bozarsın.

Bir diğer hata pp‘yi kalma olasılığı sanmaktır: bu problemde pp düşürme olasılığıdır.

Bu problemde bir sorun mu var?

solution.py
import numpy as npdef dropout(x: np.ndarray, p: float, training: bool, seed: int = 0) -> np.ndarray:    """Eğitimde birimleri p olasılıkla düşürür ve kalanları 1 / (1 - p) ile ölçekler; çıkarımda x'i değiştirmeden döndürür."""    # Kodunu buraya yaz.    return np.zeros_like(x)

İçindekiler

Geri bildirim

Tür