İçeriğe geç
3/3030 bölümden 3. bölüm

Yokuş Aşağı: Gradient Descent ve Herkesin Atladığı İki Adım

Öğrenme oranının kesin tavanını hesapla; 3.600 yönde kaba kuvvet aramanın gradient’ı kendi kendine buluşunu izle.

Bu sayfada

Önceki bölüm bir vadiyle bitmişti.

Mecazi bir vadiyle değil: gerçek bir eğriyle; loss’un tek bir parametreye karşı çizildiği, aşağı inip yeniden yukarı çıktığı bir eğri. Altındaki loss da düzenli görünsün diye seçilmemişti — ölçümlerdeki gürültü hakkında bir ifadeden türetilmişti ve karesel hata, bir konvansiyon değil sonuç olarak ortaya çıkmıştı.

Yani elimizde dibi olan bir manzara ve dibin doğru yer olduğuna inanmak için bir neden var. Elimizde olmayan şey, oraya gitmenin yolu.

Bu bölüm o yolu kuruyor ve bu, kursun geri kalanındaki her modeli eğiten algoritma — istisnasız hepsini; yüz milyarlarca parametreli olanlar dahil. Yaklaşık yirmi satıra sığıyor. Zor iki kısım o yirmi satırda değil ve neredeyse her açıklamanın atladığı iki şey de bunlar:

  • Eksi işareti neden var. Güncelleme gradient’ı çıkarır. Her tutorial bunu yazar; çok azı gradient’ın neden yukarı giden yön olduğunu söyler. Oysa eksi işaretini bir inanç eylemi olmaktan çıkaran tek gerçek budur.
  • Adım ne kadar büyük olmalı. “Çok büyükse dağılır, çok küçükse yavaştır” doğru ve işe yaramazdır. Kesin bir sayı vardır, loss’tan hesaplanabilir ve bu bölüm onu iki kez hesaplar — bir kez oyuncak bir parabol için, bir kez de gerçek veri için.

Bu bölüm kendi başına anlaşılabilsin diye yeniden ifade edelim: Bölüm 1’deki taşıma bandından gelen sekiz parça, ama bu kez farklı bir soru soruyoruz. Kabul mü ret mi değil — o sonra geri gelecek — bir parçanın ağırlığını genişliğinden tahmin et.

belt.pyPYTHON
import numpy as np

WIDTH  = np.array([18.0, 19.5, 20.2, 21.0, 24.0, 25.5, 23.0, 26.0])
WEIGHT = np.array([47.0, 52.0, 49.0, 55.0, 61.0, 66.0, 70.0, 58.0])

x = WIDTH  - WIDTH.mean()      # 22.15 mm
y = WEIGHT - WEIGHT.mean()     # 57.25 g

Ölçümler, Bölüm 1’deki gibi ve bu bölüm bitmeden faiziyle geri dönecek bir nedenle merkezlenmiş durumda. Model bir doğru, y^=ax+b\hat{y} = a x + b, loss ise önceki bölümün türettiği ortalama karesel hata:

L(a,b)=1ni=1n(axi+byi)2L(a, b) = \frac{1}{n} \sum_{i=1}^{n} \left(a x_i + b - y_i\right)^2

İki parametre. Neden sadece birçok değer denemiyoruz? Gerçekten yapalım — a=0a = 0’den 55’e ve b=5b = -5’den 55’e, 0.010.01 adımlı bir grid:

TEXT
grid 501 x 1001 = 501,501 evaluations in 3.67 s
  best found: a = 2.1000, b = -0.0000, L = 24.592450

İki sayıyı iki ondalık basamağa sabitlemek için yarım milyon değerlendirme — ve bu saniye tek bir makinedeki duvar saatidir; yeniden çalıştırınca üç ile altı arasında herhangi bir yere düşer. Tekrarlanabilen kısım değerlendirme sayısı ve minimumdur. Bu bölümün sonunda gradient descent, sekiz adımda dört ondalık basamağa ve otuz altı adımda tam float64 cevaba ulaşacak.

Ama argüman hız değil; tüm kursun yönünü belirleyen nokta bu. Grid search, PP parametre ve her biri için kk değer olduğunda kPk^P değerlendirmeye mal olur. Eksen başına bin değerle:

modelparametrelergrid değerlendirmeleri
bu doğru210610^{6}
Bölüm 5’in XOR ağı9102710^{27}
küçük bir çok katmanlı ağ20.0001060,00010^{60{,}000}

Üçüncü satır büyük bir sayı değil, anlamsız bir sayı — gözlemlenebilir evrende kabaca 108010^{80} atom var. Modeller büyüdükçe arama yavaşlamaz; var olmaktan çıkar. Bundan sonra gelen her şey o tablo yüzünden var.

Bir an için b=0b = 0’ü sabitleyelim; böylece tek parametre ve tek eğri olur, yani son bölümün seni bıraktığı resim. Üzerinde bir nokta al, a=1a = 1, ve sor: aa’ü küçük bir hh kadar dürtersem loss, dürtme birimi başına ne kadar hareket eder?

L(a+h)L(a)h\frac{L(a + h) - L(a)}{h}

Bu oran bir yükselme/basma oranıdır — eğri üzerindeki iki noktadan geçen doğrunun eğimi. hh küçüldükçe iki nokta birbirine kayar ve doğru teğete dönüşür. Onun eğimi türev L(a)L'(a)’dir: loss’un aa’deki birim değişim başına değişme hızı. Hiçbir şeyin yaklaşık değeri değil, sonsuz küçük bir nicelik de değil. Sıradan oranların limiti.

Çalıştırmaya değer, çünkü sayılar tanımın söylemediği bir şey söyler:

slope.pyPYTHON
def loss1(a):
    return np.mean((a * x - y) ** 2)

for h in [1.0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14]:
    q = (loss1(1.0 + h) - loss1(1.0)) / h
    print(f"h = {h:<8.0e}   slope estimate = {q:.10f}   error = {abs(q + 16.385):.3e}")
TEXT
h = 1e+00      slope estimate = -8.9400000000    error = 7.445e+00
h = 1e-02      slope estimate = -16.3105500000   error = 7.445e-02
h = 1e-04      slope estimate = -16.3842555001   error = 7.445e-04
h = 1e-06      slope estimate = -16.3849925556   error = 7.444e-06
h = 1e-08      slope estimate = -16.3850003787   error = 3.787e-07
h = 1e-10      slope estimate = -16.3850444324   error = 4.443e-05
h = 1e-12      slope estimate = -16.3851154866   error = 1.155e-04
h = 1e-14      slope estimate = -17.0530256582   error = 6.680e-01

Burada iki şey oluyor ve ikisi de taşıyıcı kolon.

Hata, belirsiz biçimde hh ile orantılı değil — tam olarak 7.445h7.445\,h. hh’ü yüze böl, hata da yüze bölünür; her seferinde dört anlamlı basamağa kadar. O sabit süs değildir: loss’un ikinci türevinin yarısıdır ve iki bölüm sonra gelecek bir fikrin ilk görünümüdür — bir noktanın yakınında bir eğrinin, bir doğru artı h2h^2 ile orantılı bir düzeltme gibi görünmesi.

Sonra desen bozulur. h=108h = 10^{-8}’in altında tahmin kötüleşir ve 101410^{-14}’de ikinci basamakta yanlıştır. Matematiksel hiçbir şey olmadı; önceki bölümün kayan nokta kutusu devreye girdi. L(a+h)L(a+h) ve L(a)L(a) ilk on basamaklarında aynıdır; onları çıkarmak bu basamakları yok eder ve enkazı minicik bir sayıya bölmek geriye kalanı büyütür. En iyi bir hh vardır — burada 10810^{-8} civarında, yaklaşık makine epsilonunun karekökü — ve daha küçüğe gitmek daha dikkatli olmak değil, daha az dikkatli olmaktır. Bunu hatırla; bu bölümün sonundaki bir fonksiyon buna bağlı.

Ölçüm yerine kalkülüsle bulunan kesin eğim 16.385-16.385’dir. Yani ölçmeyi bırakıp türetmeye başlayabiliriz.

Kursun geri kalanının üzerine kurulduğu fikir şu; bir kez, yalın biçimde söyleyelim.

İki fonksiyonu bileştirmek, birini diğerine beslemektir: (fg)(x)=f(g(x))(f \circ g)(x) = f(g(x)). Daha fazlası değil.

Derin bir ağ bileşime benzemez. Tam olarak bileşimdir. Bir katman bir fonksiyondur; katmanları üst üste koymak onları bileştirmektir; “derinlik”, zincirdeki fonksiyon sayısıdır. Bölüm 5 bir ağ kurduğunda f4f3f2f1f_4 \circ f_3 \circ f_2 \circ f_1 kuruyor olacak, başka hiçbir şey değil. Bu da bizim amaçlarımız için kalkülüsün en önemli kuralının, bir bileşimin türevini alan kural olduğu anlamına gelir:

ddxf(g(x))=f(g(x))g(x)\frac{d}{dx} f(g(x)) = f'(g(x)) \cdot g'(x)

Hızlar çarpılır. gg, xx’ten üç kat hızlı değişiyorsa ve ff, gg’den iki kat hızlı değişiyorsa, ff, xx’den altı kat hızlı değişir. Bütün içerik budur; on katmandan geri geçen bir sinyalin on sayıyla çarpılmasının nedeni de budur — bu yüzden Bölüm 6, bu sayıların hepsi birden biraz birden küçük olduğunda ne olduğuna bir bölüm ayırır.

Bunu loss’umuza uygula. Kalıntıyı ri=axi+byir_i = a x_i + b - y_i olarak yaz; böylece L=1nri2L = \frac{1}{n}\sum r_i^2. Her rir_i, aa’ye, türevi xix_i olan iç fonksiyon axia x_i üzerinden bağlıdır. Zincir kuralı, terim terim:

La=1ni2rixi,Lb=1ni2ri1\frac{\partial L}{\partial a} = \frac{1}{n}\sum_i 2 r_i \cdot x_i, \qquad \frac{\partial L}{\partial b} = \frac{1}{n}\sum_i 2 r_i \cdot 1

Bu kıvrımlı \partial sembolleri bir kısmi türevi işaretler: bir değişkene göre türev al ve diğer her şeyi sabit kabul et. Yeni bir şey olmuyor — öncekiyle aynı limit, sadece bir eksen boyunca alınıyor. Kısmi türevleri bir vektörde topla ve gradient elde edersin:

L=(La, Lb)\nabla L = \left( \frac{\partial L}{\partial a},\ \frac{\partial L}{\partial b} \right)

(a,b)=(1,4)(a, b) = (1, 4) noktasında bu vektör (16.385, 8.0)(-16.385,\ 8.0)’dir. İki sayı. Soru, ne anlama geldikleri; herkesin atladığı ilk adım da bu.

Gradient, eksenler boyunca eğimlerden oluşan bir vektördür. Kanıtladığımız tek şey bu. Bunları bir vektörde bir araya getirmenin belirli bir yöne işaret eden bir şey üretmesi bariz değildir — bariz olmamalıdır.

O yüzden gerçekten istediğimiz şeyi tanımlayalım. Bir birim vektör u\mathbf{u} seç, yani bir yön. Yönlü türev, o yönde yürürken loss’un değişme hızıdır:

DuL=limh0L(θ+hu)L(θ)hD_{\mathbf{u}} L = \lim_{h \to 0} \frac{L(\boldsymbol{\theta} + h\mathbf{u}) - L(\boldsymbol{\theta})}{h}

Zincir kuralı bunu hesaplanabilir bir şeye dönüştürür. u\mathbf{u} boyunca yürümek aa’i u1u_1 hızıyla ve bb’yi u2u_2 hızıyla değiştirir; katkılar toplanır:

DuL=Lau1+Lbu2=LuD_{\mathbf{u}} L = \frac{\partial L}{\partial a} u_1 + \frac{\partial L}{\partial b} u_2 = \nabla L \cdot \mathbf{u}

Herhangi bir yöndeki değişim hızı, gradient ile o yönün dot product’ıdır. Ve şimdi vurucu nokta, tek satırlık geometri. Dot product’ı vektörler arasındaki ϕ\phi açısıyla yazarsak,

Lu=Lucosϕ=Lcosϕ\nabla L \cdot \mathbf{u} = \lVert \nabla L \rVert \, \lVert \mathbf{u} \rVert \cos\phi = \lVert \nabla L \rVert \cos\phi

çünkü u\mathbf{u}’in uzunluğu 1’dir. Kontrol ettiğin tek şey cosϕ\cos\phi’dir; bu ϕ=0\phi = 0’de en büyük, yarım turda, yani ϕ=180\phi = 180 derecede en küçüktür. Dolayısıyla:

  • En dik çıkış L\nabla L’in kendisi boyuncadır ve oradaki eğim tam olarak L\lVert \nabla L \rVert’dır.
  • En dik iniş L-\nabla L boyuncadır ve oradaki eğim L-\lVert \nabla L \rVert’dir.
  • Gradient’a dik yönde loss hiç değişmez. Kontur haritasındaki çizgilerin gradient’ı dik açılarla kesmesinin nedeni budur.

Eksi işareti budur. Bir konvansiyon değil, birinin seçtiği işaret çevirmesi değil: en hızlı azalış yönü negatif gradient’tır, çünkü cosϕ\cos\phi yarım turda minimize edilir; başka hiçbir nedenle değil.

Bu tüm yönlerle ilgili bir iddia olduğuna göre, tüm yönlere karşı test et. 3.600 tanesini örnekle, derecenin onda biri başına bir tane, ve her birini dürterek ölç:

directions.pyPYTHON
theta = np.array([1.0, 4.0])
g = grad(theta)
print("gradient      ", g)
print("its length    ", np.linalg.norm(g))
print("its angle     ", np.degrees(np.arctan2(g[1], g[0])) % 360, "degrees")

best = max(
    ((loss(theta + 1e-6 * u) - loss(theta - 1e-6 * u)) / 2e-6, np.degrees(ang))
    for ang, u in (
        (a, np.array([np.cos(a), np.sin(a)])) for a in np.arange(3600) * 2 * np.pi / 3600
    )
)
print("steepest slope", best[0], "at", best[1], "degrees")
TEXT
gradient       [-16.385   8.   ]
its length     18.23371122399386
its angle      153.97598928042032 degrees
steepest slope 18.233709624837502 at 154.0 degrees

Gradient hakkında hiçbir şey bilmeyen, 3.600 yön üzerinde çalışan bir arama, en dik tırmanışını 154,0 derecede buluyor — aramanın 0,1 derecelik çözünürlüğü içinde gradient’ın kendi yönü. Orada bulduğu eğim, 18,2337, gradient’ın uzunluğu ile altı basamakta aynı. Teorem, gradient’ların ne anlama geldiğine dair bir hikâye değil; ölçülebilir bir gerçek ve ölçüm de bu.

Küçük bir yokuş aşağı adım neden gerçekten işe yarar

Bölüme bağlantı: Küçük bir yokuş aşağı adım neden gerçekten işe yarar

Şimdi atlanan ikinci adım. Hangi yönün aşağı olduğunu biliyoruz. Ama buradan, o yönde yürümenin loss’u düşüreceği sonucu çıkmaz; çünkü “aşağı”, sonsuz küçük bir dürtme hakkında bir ifadedir, bir adım ise sonsuz küçük değildir.

Köprü doğrusallaştırmadır. Bir noktanın yakınında, düzgün bir fonksiyon teğeti artı bir düzeltmedir:

L(θ+δ)=L(θ)+Lδ+O(δ2)L(\boldsymbol{\theta} + \boldsymbol{\delta}) = L(\boldsymbol{\theta}) + \nabla L \cdot \boldsymbol{\delta} + O(\lVert\boldsymbol{\delta}\rVert^2)

Bu birinci dereceden Taylor açılımıdır. Atılan O(δ2)O(\lVert\boldsymbol{\delta}\rVert^2) eğriliktir — eğim tablosunun tahminini tam olarak 7.445h7.445\,h kadar yanlış yapan aynı terim. Atmayı düşündüğümüz adımı yerine koy, δ=ηL\boldsymbol{\delta} = -\eta \nabla L:

L(θηL)L(θ)ηL2L(\boldsymbol{\theta} - \eta \nabla L) \approx L(\boldsymbol{\theta}) - \eta \lVert \nabla L \rVert^2

Loss ηL2\eta \lVert \nabla L \rVert^2 kadar düşer. Bunun her parçası negatif değildir, yani vaat gerçektir — yeterince küçük bir η\eta için, çünkü ihmal edilen terim η2\eta^2 gibi büyür ve sonunda onu yer. Bütün teori bu. İşte vaadin tutulması ve sonra bozulması:

TEXT
eta = 0.2       promised    66.49364500   delivered   -16.01619240   ratio -0.240868
eta = 0.1       promised    33.24682250   delivered    12.61936315   ratio  0.379566
eta = 0.01      promised     3.32468225   delivered     3.11840766   ratio  0.937957
eta = 0.001     promised     0.33246822   delivered     0.33040548   ratio  0.993796
eta = 0.0001    promised     0.03324682   delivered     0.03322620   ratio  0.999380
eta = 1e-05     promised     0.00332468   delivered     0.00332448   ratio  0.999938

Aşağıdan oku. η\eta küçüldükçe gerçekleşen düşüş vaat edilene yakınsar — oran 0,99938, sonra 0,99994 — bu Taylor teoreminin doğru çıkmasıdır. Yukarıdan oku ve η=0.2\eta = 0.2’de gerçekleşen “düşüş” eksi on altıdır. Adım yokuş aşağı gitti ve loss yükseldi.

Yani güncelleme kuralı

θθηL(θ)\boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \eta \nabla L(\boldsymbol{\theta})

ve kimsenin söylemediği bir koşulla gelir: η\eta yeterince küçük olmalıdır. Tam olarak neye göre yeterince küçük olduğu, sonraki bölümün konusu.

learning rate’in bir tavanı vardır ve hesaplanabilir

Bölüme bağlantı: learning rate’in bir tavanı vardır ve hesaplanabilir

En basit vadiyle başla, f(x)=x2f(x) = x^2; burada f(x)=2xf'(x) = 2x. Gradient descent’in bir adımı şudur:

xxη2x=x(12η)x \leftarrow x - \eta \cdot 2x = x\,(1 - 2\eta)

Konum her adımda (12η)(1 - 2\eta) ile çarpılır. Bu geometrik bir dizidir ve geometrik dizilerin tam olarak bir kuralı vardır: çarpan mutlak değerce 1’den küçükse küçülürler, değilse büyürler. Yani 12η<1\lvert 1 - 2\eta \rvert < 1, yani 0<η<10 < \eta < 1.

Sınır tam olarak η=1\eta = 1’dedir. “1 civarında” değil, “1 genellikle çok büyüktür” değil. η=1\eta = 1’de çarpan 1-1’dir ve nokta sonsuza kadar xx ile x-x arasında seker; ne yaklaşır ne kaçar. Altında yakınsar; üstünde dağılır. Aralık η=0.5\eta = 0.5’de yeniden ikiye ayrılır; orada çarpan işaret değiştirir: bunun altında yaklaşma monotoniktir, üstünde nokta taşar ve taraf değiştirerek ilerler; tam olarak 0.50.5’te çarpan 0’dır ve tek bir adım minimuma iner.

Dört satır cebirden dört rejim. Git ve sınırları kendin aş:

14 adım, x = -0.0836 noktasında bitti.

Verileri tablo olarak gör
Adımxf(x)
0⁨-1.9000⁩⁨3.6100⁩
1⁨-1.5200⁩⁨2.3104⁩
2⁨-1.2160⁩⁨1.4787⁩
3⁨-0.9728⁩⁨0.9463⁩
4⁨-0.7782⁩⁨0.6057⁩
5⁨-0.6226⁩⁨0.3876⁩
6⁨-0.4981⁩⁨0.2481⁩
7⁨-0.3985⁩⁨0.1588⁩
8⁨-0.3188⁩⁨0.1016⁩
9⁨-0.2550⁩⁨0.0650⁩
10⁨-0.2040⁩⁨0.0416⁩
11⁨-0.1632⁩⁨0.0266⁩
12⁨-0.1306⁩⁨0.0170⁩
13⁨-0.1045⁩⁨0.0109⁩
14⁨-0.0836⁩⁨0.0070⁩
Gradyan inişi, etkileşimli

x=1.9x = -1.9’ten başlayan 0,1 oranıyla on dört adım, 0.0836-0.0836’te biter. Oranı 0,5’e çıkar ve daha ilk adım dibe iner. 0,9’a çıkar ve 0,1’in bittiği aynı 0.0836-0.0836’de biter — aynı mesafe, ters stil; çünkü 12η\lvert 1 - 2\eta \rvert ikisi için de 0,8’dir — ama oraya bir kenardan aşağı yürümek yerine vadinin iki yakası arasında zikzak çizerek gider.

Ve şimdi ilginç olan:

14 adım, x = -1.9000 noktasında bitti.

Verileri tablo olarak gör
Adımxf(x)
0⁨-1.9000⁩⁨3.6100⁩
1⁨1.9000⁩⁨3.6100⁩
2⁨-1.9000⁩⁨3.6100⁩
3⁨1.9000⁩⁨3.6100⁩
4⁨-1.9000⁩⁨3.6100⁩
5⁨1.9000⁩⁨3.6100⁩
6⁨-1.9000⁩⁨3.6100⁩
7⁨1.9000⁩⁨3.6100⁩
8⁨-1.9000⁩⁨3.6100⁩
9⁨1.9000⁩⁨3.6100⁩
10⁨-1.9000⁩⁨3.6100⁩
11⁨1.9000⁩⁨3.6100⁩
12⁨-1.9000⁩⁨3.6100⁩
13⁨1.9000⁩⁨3.6100⁩
14⁨-1.9000⁩⁨3.6100⁩
Gradyan inişi, etkileşimli

Tam sınırda. 1 oranıyla on dört adım ve 1.9-1.9’de biter: tam başladığı yerde, hiçbir şey yapmadan sadece sekmiş olarak. Bir dürtme daha yukarıda sekme sabit kalmak yerine büyür; 1,2’de dört adımda grafiğin dışına çıkar. Çok büyük bir oran yavaş yakınsamaz. Yakınsamaz.

Şimdi aynı argümandan çıkan genel kural. 12η1 - 2\eta çarpanı aslında 1ηf1 - \eta f'' idi ve bir minimumun yakınında çok parametreli bir loss, her yön için böyle bir sayıya sahiptir — ikinci türevler matrisinin özdeğerleri. Her yönün aynı anda kararlı olması gerekir, bu yüzden tavan en büyüğü tarafından belirlenir:

η<2λmax\eta < \frac{2}{\lambda_{\max}}

f(x)=x2f(x) = x^2 için f=2f'' = 2, tavan 1’dir; az önce türettiğimiz de buydu. Bizim bant verimizde ikinci türev matrisi, AA girdilerin iki sütunlu matrisi olmak üzere 2nAA\frac{2}{n} A^{\top} A’dir ve özdeğerleri 2 ile 14,89’dur; dolayısıyla tavan 2/14.89=0.134322 / 14.89 = 0.13432’tir. Bu, içinde beş anlamlı basamak olan bir tahmindir. Test et:

TEXT
lr=0.1343    -> L =      24.5924
lr=0.13431   -> L =      24.5924
lr=0.13432   -> L =       4707.8       BLEW UP
lr=0.13433   -> L =  4.00452e+16       BLEW UP
lr=0.1344    -> L = 1.18229e+107       BLEW UP

Bir satır lineer cebir ile for döngüsünün yüz bin iterasyonu arasında beş ondalık basamaklık uyum.

Ve işte Bölüm 1’in geri geldiği yer. Yukarıdaki her şey merkezlenmiş ölçümleri kullandı. Aynı kodu ham milimetreler ve gramlar üzerinde çalıştır ve özdeğerler 2 ve 14,89 yerine 0,0298 ve 998,1 olur. Tavan 0,134’ten 0,002004’e çöker — yine aynı kesinlikle; lr=0.002003’de yakınsar, lr=0.002004’da patlar.

Tavandan daha kötüsü, özdeğerler arasındaki orandır. Koşul sayısı, vadinin yuvarlaktan ne kadar uzak olduğunu ölçer: uzun ince bir hendek, dik duvarlar için yeterince küçük bir oranı zorunlu kılar; sonra hendeğin tabanı da aynı sürünme hızıyla yürünür. Bizimki merkezlenmişte 7,44 iken hamda 33.452 olur. Her sürümün alabileceği en iyi oranla:

özelliklerkoşul sayısıen iyi oranoptimumun %1 yakınına kadar adım
merkezlenmiş7,440,118410
ham milimetreler ve gramlar33.4520,002003779.513

Aynı veri, aynı kod, sonunda aynı cevap — ve sekiz bin kat iş; çünkü kimse ortalamayı çıkarmadı. Bölüm 1’de aynı ihmal perceptron’a epoch sayısında altı bin kat maliyet çıkarmıştı ve oradaki teşhis geometrikti: veri orijinden uzakta yüzüyordu. Burada optimizasyon kılığına girmiş aynı geometri var ve input normalizasyonunun hijyen tavsiyesi değil aritmetik olmasının nedeni bu.1

Yukarıdakilerin hiçbiri bir library gerektirmedi. İşte tüm optimiser.

descent.pyPYTHON
def loss(theta):
    a, b = theta
    return np.mean((a * x + b - y) ** 2)


def grad(theta):
    a, b = theta
    residual = a * x + b - y
    return np.array([np.mean(2 * residual * x), np.mean(2 * residual)])


def descend(theta, lr, steps):
    theta = np.array(theta, dtype=float)
    for _ in range(steps):
        theta = theta - lr * grad(theta)   
    return theta


theta = descend([0.0, 0.0], lr=0.05, steps=60)
print(theta, loss(theta))
TEXT
[ 2.10040296e+00 -2.76445533e-15] 24.592448791134984

Bu sekiz nokta için closed-form en küçük kareler cevabı a=2.100403a = 2.100403, b=0b = 0 ve loss 24.59244924.592449’dur. Döngü, bir closed form’un var olduğunu bilmeden bunu sekiz anlamlı basamağa kadar buldu — bu önemli, çünkü Bölüm 5’ten itibaren böyle bir form olmayacak.

Yörünge; çünkü asıl mesele onu izlemek:

TEXT
   0 a=0.000000 b=0.000000 L=57.437500
   1 a=1.563750 b=0.000000 L=26.736582
   2 a=1.963288 b=-0.000000 L=24.732418
   5 a=2.098116 b=-0.000000 L=24.592488
  10 a=2.100400 b=-0.000000 L=24.592449
  60 a=2.100403 b=-0.000000 L=24.592449

Mesafenin çoğu ilk iki adımda kat edilir; çünkü gradient dipten en uzakken en büyüktür ve yaklaştıkça küçülür. Gradient descent bir minimumun yakınında otomatik olarak yavaşlar. Bu bir özelliktir ve Bölüm 6’da aynı zamanda bir problemdir.

Şimdiye kadarki argümanda bir delik var. Adım L=0\nabla L = \mathbf{0} olduğunda durur ve biz buna “minimum” diyorduk. Gradient’ı sıfır olan nokta bir kritik noktadır ve minimum olmak, kritik nokta olmanın yollarından yalnızca biridir:

  • bir yerel minimum: her yönde yokuş yukarı, ama her yerdeki bu tür noktaların en düşüğü olmak zorunda değil;
  • bir yerel maksimum: her yönde yokuş aşağı;
  • bir eyer noktası: bazı yönlerde yokuş yukarı, bazı yönlerde yokuş aşağı. f(x,y)=x2y2f(x,y) = x^2 - y^2 yüzeyi f=(2x,2y)\nabla f = (2x, -2y)’a sahiptir; bu ifade orijinde sıfırdır ve fonksiyon aynı anda xx ekseni boyunca minimum, yy ekseni boyunca maksimumdur.

Gradient descent bunları ayırt edemez; çünkü yalnızca gradient’a bakar ve gradient üçünde de sıfırdır.

Bizim doğrumuzun tek bir kritik noktası var ve o da cevap — lineer model üzerindeki karesel hata loss’u konvekstir, tek bir kâsedir ve üzerinde descent, global minimumu bulmada başarısız olamaz. Bu özellik kursla temas edince hayatta kalmaz. Bir neural network’ün loss’u konveks değildir ve Bölüm 5’ten itibaren “minimum” diye tekil bir şey yoktur: farklı derinliklerde birçok tane vardır ve hangisini alacağın nereden başladığına bağlıdır. Bu bir cümledir ve bir cümle olarak kalacak; çünkü teori büyüktür, pratik sonuç küçüktür.

Tüm sonucu tek bir eğride görebilirsin. Farklı derinliklerde iki vadisi olan f(x)=x44x22+x10f(x) = \tfrac{x^4}{4} - \tfrac{x^2}{2} + \tfrac{x}{10}’ü al:

TEXT
   x =  -1.046681   f(x) =  -0.352386   minimum
   x =   0.101031   f(x) =   0.005026   maximum
   x =   0.945649   f(x) =  -0.152639   minimum

40 adım, x = 0.9456 noktasında bitti.

Verileri tablo olarak gör
Adımxf(x)
0⁨0.1100⁩⁨0.0050⁩
1⁨0.1122⁩⁨0.0050⁩
2⁨0.1149⁩⁨0.0049⁩
3⁨0.1182⁩⁨0.0049⁩
4⁨0.1223⁩⁨0.0048⁩
5⁨0.1275⁩⁨0.0047⁩
6⁨0.1338⁩⁨0.0045⁩
7⁨0.1416⁩⁨0.0042⁩
8⁨0.1513⁩⁨0.0038⁩
9⁨0.1633⁩⁨0.0032⁩
10⁨0.1781⁩⁨0.0022⁩
11⁨0.1962⁩⁨0.0007⁩
12⁨0.2183⁩⁨-0.0014⁩
13⁨0.2453⁩⁨-0.0046⁩
14⁨0.2779⁩⁨-0.0093⁩
15⁨0.3170⁩⁨-0.0160⁩
16⁨0.3633⁩⁨-0.0253⁩
17⁨0.4172⁩⁨-0.0377⁩
18⁨0.4783⁩⁨-0.0535⁩
19⁨0.5455⁩⁨-0.0721⁩
20⁨0.6163⁩⁨-0.0922⁩
21⁨0.6869⁩⁨-0.1116⁩
22⁨0.7526⁩⁨-0.1277⁩
23⁨0.8092⁩⁨-0.1393⁩
24⁨0.8540⁩⁨-0.1463⁩
25⁨0.8868⁩⁨-0.1499⁩
26⁨0.9091⁩⁨-0.1516⁩
27⁨0.9236⁩⁨-0.1522⁩
28⁨0.9325⁩⁨-0.1525⁩
29⁨0.9379⁩⁨-0.1526⁩
30⁨0.9411⁩⁨-0.1526⁩
31⁨0.9430⁩⁨-0.1526⁩
32⁨0.9441⁩⁨-0.1526⁩
33⁨0.9448⁩⁨-0.1526⁩
34⁨0.9451⁩⁨-0.1526⁩
35⁨0.9454⁩⁨-0.1526⁩
36⁨0.9455⁩⁨-0.1526⁩
37⁨0.9455⁩⁨-0.1526⁩
38⁨0.9456⁩⁨-0.1526⁩
39⁨0.9456⁩⁨-0.1526⁩
40⁨0.9456⁩⁨-0.1526⁩
Gradyan inişi, etkileşimli

x=0.11x = 0.11’ten kırk adım, 0.94560.9456’da yerleşir — iki vadiden sığ olanı. Şimdi başlangıç noktasını bir tık sola, 0.100.10’a taşı. Aynı oran, aynı kırk adım ve bu kez loss’un 0.199747 daha düşük olduğu 1.0461-1.0461’te yerleşir. Su ayrımı 0.1010310.101031’deki tümsektir ve iki cevap arasındaki tüm fark, başlamış olduğun tarafın hangisi olduğudur.

Sığ vadiye inmek loss açısından %56,7 daha kötüdür ve algoritmanın bunu bilmesinin yolu yoktur; çünkü bir vadinin içinden bakınca her yön yokuş yukarıdır. Gradient descent içinde bunun bir onarımı yoktur ve gelmeyecek. Pratikte olan şey, bunun bu resmin ima ettiğinden çok daha az önemli olduğunun bulunmasıdır — gerçek bir ağın çok yüksek boyutlarında kritik noktaların çoğu tuzak değil eyer noktası çıkar,2 ve Bölüm 5 küçük bir ağın gerçekten ne sıklıkla takıldığını ölçecek.

Daha ucuz adımlar: stochastic, minibatch, momentum

Bölüme bağlantı: Daha ucuz adımlar: stochastic, minibatch, momentum

Yukarıdaki grad hakkında seni rahatsız etmesi gereken bir şey var: her adım için tüm dataset’i topluyor. Sekiz parça hiçbir şey. Bir milyon, parametreleri bir kez hareket ettirmek için bir milyon gradient hesaplaması demektir.

Kaçış şu: gradient bir ortalamadır ve bir ortalama bir örneklemden tahmin edilebilir. Rastgele küçük bir avuç üzerinde hesapla — bir minibatch — ve onunla adım at. Tahmin gürültülüdür; aynı zamanda yanlı değildir ve yüzlerce ucuz gürültülü adım, pahalı tek bir kesin adımı yener. Yüz bin sentetik parçada, adımlar yerine örnek başına gradient’ları sayarsak:

yöntemoptimumun %0,1 yakınına kadar adımörnek başına gradient’lar
full batch7700.000
32’lik minibatch1003.200
tek seferde bir örnek17.58017.580

Aynı yere ulaşmak için iki yüz on dokuz kat daha az aritmetik. Ve uç nokta — her seferinde bir örnek, Robbins ve Monro’nun özgün stochastic approximation’ı3kazanan değildir: 32’lik batch’lerden beş kat kötüdür; çünkü matris çarpan donanımda 32 örnek neredeyse 1 örnekten fazla maliyet getirmezken, gürültü batch size’ın kareköküyle düşer. Bu trade-off, okuyacağın her eğitim script’inde bir batch_size olmasının nedenidir.

Momentum diğer ucuz düzeltmedir ve doğrudan hendeği hedefler. Kötü koşullanmış bir vadide adımlar dar yönde zikzak çizerken uzun yönde sürünür. Momentum geçmiş gradient’ların kayan ortalamasını tutar; böylece salınan bileşenler birbirini götürür, tutarlı olan birikir:4

vβv+L(θ),θθηv\mathbf{v} \leftarrow \beta \mathbf{v} + \nabla L(\boldsymbol{\theta}), \qquad \boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \eta \mathbf{v}

İki ekstra satır. Ham, merkezlenmemiş bantta — koşul sayısı 33.452, elimizdeki en kötü durum — düz descent’in alabileceği en iyi oranda:

TEXT
momentum beta=0.0   ->    79,513 steps to 1%
momentum beta=0.9   ->     1,609 steps to 1%
momentum beta=0.99  ->       461 steps to 1%

İki satır kod için 172 kat. Bölüm 6 bunu Adam’a dönüştürür; mekanizma zaten burada.

Bu bölümdeki her gradient elle türetildi ve bu yüzden yanlış olabilir. Çözüm, baştaki eğim tablosudur: türevi sayısal olarak ölç ve karşılaştır. Aynı hh için çok daha doğru olan ve önde gelen hata terimini iptal eden central difference’ı kullan, L(θ+h)L(θh)2h\frac{L(\theta+h) - L(\theta-h)}{2h}.

gradcheck.pyPYTHON
def numeric_grad(f, theta, h=1e-5):
    theta = np.asarray(theta, dtype=float)
    out = np.zeros_like(theta)
    for i in range(theta.size):
        bump = np.zeros_like(theta)
        bump[i] = h
        out[i] = (f(theta + bump) - f(theta - bump)) / (2 * h)     
    return out


def gradcheck(f, df, theta, h=1e-5):
    analytic = np.asarray(df(theta), dtype=float)
    numeric = numeric_grad(f, theta, h)
    return np.max(np.abs(analytic - numeric) / np.maximum(1e-8, np.abs(analytic) + np.abs(numeric)))

Karşılaştırmanın göreli formu önemlidir: 10410^{-4} mutlak fark, büyüklüğü 10310^{-3} olan bir gradient üzerinde felakettir ve 10610^{6} büyüklüğündekinde önemsizdir.

TEXT
relative error: 1.8929136036763527e-11
with 2 dropped: 0.33333333331650744

İlk satır yukarıdaki elle türetilmiş gradient. İkincisi, bir bileşende 2 çarpanı unutulmuş aynı fonksiyon — tek karakterlik bir yazım hatası — ve kontrol bunu anında yakalar. Yaklaşık 10710^{-7} altındaki her şey uyumdur; 10410^{-4} üzerindeki her şey bug’dır. Bu fonksiyonu sakla: Bölüm 5 onu bir automatic differentiation engine’i debug etmek için kullanacak ve yanlış bir gradient’ın bulunabilir olmasının tek nedeni o.

Bu bölümdeki her şey, hiç açıkça söylenmemiş tek bir varsayıma dayanıyordu: L/θ\partial L / \partial \theta’ü yazabiliyor olman.

İki parametreli bir doğru için bu bir satır cebirdi. Neredeyse hemen bir satır olmaktan çıkar. Bir symbolic algebra system’den, bir ağın loss’unun tek bir birinci katman weight’ine göre, tek bir örnek için türevini iste ve cevaptaki aritmetiği say:

bir kısmi türevdeki işlemler
dört gizli birim, bir katman40
dört gizli birim, iki katman301
dört gizli birim, üç katman1.717

Üçüncü satır 57 parametreli bir ağ — Bölüm 6’da dipnot olacak kadar küçük bir ağ — ve gradient’ını elle yazmak tek bir eğitim örneği için yaklaşık 97.869 işlem demektir. Bunu kurtaran bir notasyon yok. Onu kurtaran şey, bir bileşime uygulanan zincir kuralının muazzam bir yapıya sahip olduğu, aynı ara niceliklerin tekrar tekrar ortaya çıktığı ve bunları doğru sırayla hesaplamanın tüm türevleri kabaca tek bir forward pass fiyatına verdiği gözlemidir. Bu Bölüm 5.

Ama önce daha küçük bir problem var ve hemen bekliyor.

Artık herhangi bir türevlenebilir loss üzerinde yokuş aşağı yuvarlanacak bir makinemiz var. Onu bandın asıl sorusuna yönelt — kabul mü ret mi, hedef 1 ya da 0 — çıktıya bir sigmoid koy ki olasılık tahmin etsin ve karesel hatayı minimize et. Çalışır. Ama en çok yanıldığında neredeyse hiç hareket etmez ve gradient bunun nedenini söyler:

çıktı zztahmingerçekkaresel hatayla gradientcross-entropy ile gradient
000.500012.5×1012.5 \times 10^{-1}5.0×1015.0 \times 10^{-1}
2-20.119211.850×1011.850 \times 10^{-1}8.808×1018.808 \times 10^{-1}
6-60.002514.921×1034.921 \times 10^{-3}9.975×1019.975 \times 10^{-1}
10-104.54×1054.54 \times 10^{-5}19.079×1059.079 \times 10^{-5}1.0001.000

Kendinden emin biçimde, feci şekilde yanlış olan bir model — cevap 1 iken 0.0000454 tahmin eden — 9×1059 \times 10^{-5} karesel hata gradient’ı üretir. Başının dertte olduğuna dair hiçbir fikri yoktur. Henüz türetmediğimiz bir loss’tan gelen diğer sütun 1.0 bildirir: maksimum aciliyet, tam da hak edildiği yerde.

Bu da sonraki bölümün açtığı soruyu doğurur. Önceki bölüm bir loss’un gürültü hakkında bir varsayım olduğunu ve karesel hatanın Gaussian gürültü varsaydığını söyledi. Evet-hayır cevabının nasıl bir gürültü modeli vardır — ve aynı türetmeyi onun üzerinde yürütünce hangi loss çıkar?


Yöntem bunların hepsinden daha eski: Cauchy, 1847’de Académie des Sciences’a verdiği bir notta, denklem sistemlerini karesel kalıntılarının toplamı üzerinde yokuş aşağı yürüyerek çözmenin bir yolu olarak tarif etti. Bu bölümle birlikte okunmaya değer diğerleri: Sebastian Ruder’in An overview of gradient descent optimization algorithms çalışması (arXiv:1609.04747); momentum’dan Adam’a kadar konuyu okunabilir on dört sayfada kapsar. Nocedal ve Wright’ın Numerical Optimization kitabının 3. bölümü (2. baskı, Springer, 2006); teorem 3.3, bir kuadratik üzerinde steepest descent’in yakınsama hızını koşul sayısı cinsinden verir — koşullanmanın adım sayısını neden belirlediğinin teorisi budur, gerçi yukarıda ölçülen sabit adımlı 2/λmax2/\lambda_{\max} tavanı yerine line search’i ele alır. Ya da aynı zemini daha az makineyle işleyen Deisenroth, Faisal ve Ong’un Mathematics for Machine Learning kitabının §5.8 ve §7.1 bölümleri; Prince’in Understanding Deep Learning kitabının §6.1’i ve Goodfellow, Bengio ve Courville’in Deep Learning kitabının §4.3’ü; burada yer olduğundan daha fazla ölçümle minibatch analizini veren Dive into Deep Learning §12.1–12.3; ve learning rate’i türetmekten çok ayarlanan bir şey olarak en pratik biçimde ele alan Géron’un Hands-On Machine Learning kitabının 4. bölümü (3. baskı). MIT 6.390 notları, gradient descent’i sınıflandırmadan önce koyar; bu kursun yaptığı gibi ve aynı nedenle.

  1. LeCun, Y., Bottou, L., Orr, G. B. and Müller, K.-R. Efficient BackProp, Neural Networks: Tricks of the Trade içinde (Springer, 1998), ss. 9–50. Bölüm 4.3 öneriyi, bölüm 5.1 ise yukarıdaki ayrıntı kutusunda kullanılan argümanı verir: input’ları merkezlemek ve ölçeklemek ikinci türev matrisinin özdeğerlerini, dolayısıyla adım sayısını değiştirir; yalnızca sayısal konforu değil.

  2. Dauphin, Y. N., Pascanu, R., Gulcehre, C., Cho, K., Ganguli, S. and Bengio, Y. Identifying and attacking the saddle point problem in high-dimensional non-convex optimization, arXiv:1406.2572 (2014). Yüksek boyutlarda kritik noktaların ezici çoğunlukla yerel minimumlardan ziyade eyer noktaları olduğu argümanı; çünkü bir minimum, binlerce yönün her birinin aynı anda yukarı kıvrılmasını gerektirir.

  3. Robbins, H. and Monro, S. A Stochastic Approximation Method. Annals of Mathematical Statistics 22(3), ss. 400–407 (1951). Doğru biçimde küçülen bir step size verildiğinde, gradient’ın gürültülü bir tahmininin yeterli olduğunu ortaya koyan makale.

  4. Polyak, B. T. Some methods of speeding up the convergence of iteration methods. USSR Computational Mathematics and Mathematical Physics 4(5), ss. 1–17 (1964). Yukarıdaki momentum güncellemesi olan heavy-ball method; backpropagation bu alana ulaşmadan yirmi iki yıl önce.

Seçimi LIA'ya bırakmaya hazır mısın?

Tüm yapay zeka modelleriyle tek yerde üret — bugün ücretsiz başla.