.. _sec_sgd:
Rasgele Gradyan İnişi
=====================
Daha önceki bölümlerde, eğitim prosedürümüzde rasgele gradyan inişi
kullanmaya devam ettik, ancak, neden çalıştığını açıklamadık. Üzerine
biraz ışık tutmak için, :numref:`sec_gd` içinde gradyan inişinin temel
prensiplerini tanımladık. Bu bölümde, *rasgele gradyan iniş*\ ini daha
ayrıntılı olarak tartışmaya devam ediyoruz.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
%matplotlib inline
import math
from d2l import mxnet as d2l
from mxnet import np, npx
npx.set_np()
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
%matplotlib inline
import math
import torch
from d2l import torch as d2l
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
%matplotlib inline
import math
import tensorflow as tf
from d2l import tensorflow as d2l
.. raw:: html
.. raw:: html
Rasgele Gradyan Güncellemeleri
------------------------------
Derin öğrenmede, amaç işlevi genellikle eğitim veri kümelerindeki her
örnek için kayıp fonksiyonlarının ortalamasıdır. :math:`n` örnekten
oluşan bir eğitim veri kümesi verildiğinde, :math:`f_i(\mathbf{x})`'in
:math:`i.` dizindeki eğitim örneğine göre kayıp işlevi olduğunu
varsayarız, burada :math:`\mathbf{x}` parametre vektörüdür. Sonra şu
amaç fonksiyonuna varırız
.. math:: f(\mathbf{x}) = \frac{1}{n} \sum_{i = 1}^n f_i(\mathbf{x}).
:math:`\mathbf{x}`'teki amaç fonksiyonunun gradyanı böyle hesaplanır:
.. math:: \nabla f(\mathbf{x}) = \frac{1}{n} \sum_{i = 1}^n \nabla f_i(\mathbf{x}).
Gradyan inişi kullanılıyorsa, her bağımsız değişken yineleme için
hesaplama maliyeti :math:`\mathcal{O}(n)`'dir ve :math:`n` ile doğrusal
olarak büyür. Bu nedenle, eğitim veri kümesi daha büyük olduğunda, her
yineleme için gradyan iniş maliyeti daha yüksek olacaktır.
Rasgele gradyan iniş (SGD), her yinelemede hesaplama maliyetini düşürür.
Rasgele gradyan inişin her yinelemesinde, rastgele veri örnekleri için
:math:`i\in\{1,\ldots, n\}` dizinden eşit olarak örneklemleriz ve
:math:`\mathbf{x}`'i güncelleştirmek için :math:`\nabla f_i(\mathbf{x})`
gradyanını hesaplarız:
.. math:: \mathbf{x} \leftarrow \mathbf{x} - \eta \nabla f_i(\mathbf{x}),
burada :math:`\eta` öğrenme oranıdır. Her yineleme için gradyan inişinin
hesaplama maliyetinin :math:`\mathcal{O}(n)`'den :math:`\mathcal{O}(1)`
sabitine düştüğünü görebiliriz. Dahası, rasgele gradyan
:math:`\nabla f_i(\mathbf{x})`'in :math:`\nabla f(\mathbf{x})`'in tam
gradyanının tarafsız bir tahmini olduğunu vurgulamak istiyoruz, çünkü
.. math:: \mathbb{E}_i \nabla f_i(\mathbf{x}) = \frac{1}{n} \sum_{i = 1}^n \nabla f_i(\mathbf{x}) = \nabla f(\mathbf{x}).
Bu, ortalama olarak rasgele gradyanın, gradyanın iyi bir tahmini olduğu
anlamına gelir.
Şimdi, bir rasgele gradyan inişini benzetmek için gradyana ortalaması 0
ve varyansı 1 olan rastgele gürültü ekleyerek gradyan inişiyle
karşılaştıracağız.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def f(x1, x2): # Amaç fonksiyonu
return x1 ** 2 + 2 * x2 ** 2
def f_grad(x1, x2): # Amaç fonksiyonun gradyanı
return 2 * x1, 4 * x2
def sgd(x1, x2, s1, s2, f_grad):
g1, g2 = f_grad(x1, x2)
# Gürültülü gradyan benzetimi
g1 += np.random.normal(0.0, 1, (1,))
g2 += np.random.normal(0.0, 1, (1,))
eta_t = eta * lr()
return (x1 - eta_t * g1, x2 - eta_t * g2, 0, 0)
def constant_lr():
return 1
eta = 0.1
lr = constant_lr # Sabit öğrenme oranı
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 50, x1: -0.472513, x2: 0.110780
/home/d2l-worker/miniconda3/envs/d2l-tr-release-0/lib/python3.9/site-packages/numpy/core/shape_base.py:65: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
ary = asanyarray(ary)
.. figure:: output_sgd_baca77_15_1.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def f(x1, x2): # Amaç fonksiyonu
return x1 ** 2 + 2 * x2 ** 2
def f_grad(x1, x2): # Amaç fonksiyonun gradyanı
return 2 * x1, 4 * x2
def sgd(x1, x2, s1, s2, f_grad):
g1, g2 = f_grad(x1, x2)
# Gürültülü gradyan benzetimi
g1 += torch.normal(0.0, 1, (1,))
g2 += torch.normal(0.0, 1, (1,))
eta_t = eta * lr()
return (x1 - eta_t * g1, x2 - eta_t * g2, 0, 0)
def constant_lr():
return 1
eta = 0.1
lr = constant_lr # Sabit öğrenme oranı
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 50, x1: 0.174384, x2: -0.102252
/home/d2l-worker/miniconda3/envs/d2l-tr-release-0/lib/python3.9/site-packages/numpy/core/shape_base.py:65: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
ary = asanyarray(ary)
/home/d2l-worker/miniconda3/envs/d2l-tr-release-0/lib/python3.9/site-packages/torch/functional.py:478: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2895.)
return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]
.. figure:: output_sgd_baca77_18_1.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def f(x1, x2): # Amaç fonksiyonu
return x1 ** 2 + 2 * x2 ** 2
def f_grad(x1, x2): # Amaç fonksiyonun gradyanı
return 2 * x1, 4 * x2
def sgd(x1, x2, s1, s2, f_grad):
g1, g2 = f_grad(x1, x2)
# Gürültülü gradyan benzetimi
g1 += tf.random.normal([1], 0.0, 1)
g2 += tf.random.normal([1], 0.0, 1)
eta_t = eta * lr()
return (x1 - eta_t * g1, x2 - eta_t * g2, 0, 0)
def constant_lr():
return 1
eta = 0.1
lr = constant_lr # Sabit öğrenme oranı
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 50, x1: 0.120303, x2: -0.076531
/home/d2l-worker/miniconda3/envs/d2l-tr-release-0/lib/python3.9/site-packages/numpy/core/shape_base.py:65: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
ary = asanyarray(ary)
.. figure:: output_sgd_baca77_21_1.svg
.. raw:: html
.. raw:: html
Gördüğümüz gibi, rasgele gradyan inişindeki değişkenlerin yörüngesi,
:numref:`sec_gd` içinde gradyan inişinde gözlemlediğimizden çok daha
gürültülüdür. Bunun nedeni, gradyanın rasgele doğasından
kaynaklanmaktadır. Yani, en düşük seviyeye yaklaştığımızda bile,
:math:`\eta \nabla f_i(\mathbf{x})` aracılığıyla anlık gradyan
tarafından aşılanan belirsizliğe hala tabiyiz. 50 adımdan sonra bile
kalite hala o kadar iyi değil. Daha da kötüsü, ek adımlardan sonra
iyileşmeyecektir (bunu onaylamak için daha fazla sayıda adım denemenizi
öneririz). Bu bize tek alternatif bırakır: Öğrenme oranı :math:`\eta`'yı
değiştirmek. Ancak, bunu çok küçük seçersek, ilkin bir ilerleme
kaydetmeyeceğiz. Öte yandan, eğer çok büyük alırsak, yukarıda görüldüğü
gibi iyi bir çözüm elde edemeyiz. Bu çelişkili hedefleri çözmenin tek
yolu, optimizasyon ilerledikçe öğrenme oranını *dinamik* azaltmaktır.
Bu aynı zamanda ``sgd`` adım işlevine ``lr`` öğrenme hızı işlevinin
eklenmesinin de sebebidir. Yukarıdaki örnekte, ilişkili 'lr' işlevini
sabit olarak ayarladığımız için öğrenme hızı planlaması için herhangi
bir işlevsellik uykuda kalmaktadır.
Dinamik Öğrenme Oranı
---------------------
:math:`\eta`'nın zamana bağlı öğrenme hızı :math:`\eta(t)` ile
değiştirilmesi, optimizasyon algoritmasının yakınsamasını kontrol
etmenin karmaşıklığını arttırır. Özellikle, :math:`\eta`'nın ne kadar
hızlı sönmesi gerektiğini bulmamız gerekiyor. Çok hızlıysa, eniyilemeyi
erken bırakacağız. Eğer çok yavaş azaltırsak, optimizasyon için çok
fazla zaman harcarız. Aşağıdakiler, :math:`\eta`'nın zamanla
ayarlanmasında kullanılan birkaç temel stratejidir (daha sonra daha
gelişmiş stratejileri tartışacağız):
.. math::
\begin{aligned}
\eta(t) & = \eta_i \text{ eğer } t_i \leq t \leq t_{i+1} && \text{parçalı sabit} \\
\eta(t) & = \eta_0 \cdot e^{-\lambda t} && \text{üstel sönüm} \\
\eta(t) & = \eta_0 \cdot (\beta t + 1)^{-\alpha} && \text{polinomsal sönüm}
\end{aligned}
İlk *parçalı sabit* senaryosunda, öğrenme oranını düşürüyoruz, mesela
optimizasyondaki ilerleme durduğunda. Bu, derin ağları eğitmek için
yaygın bir stratejidir. Alternatif olarak çok daha saldırgan bir *üstel
sönüm* ile azaltabiliriz. Ne yazık ki bu genellikle algoritma
yakınsamadan önce erken durmaya yol açar. Popüler bir seçim,
:math:`\alpha = 0.5` ile *polinom sönüm*\ dür. Dışbükey optimizasyon
durumunda, bu oranın iyi davrandığını gösteren bir dizi kanıt vardır.
Üstel sönmenin pratikte neye benzediğini görelim.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def exponential_lr():
# Bu fonksiyonun dışında tanımlanan ve içinde güncellenen global değişken
global t
t += 1
return math.exp(-0.1 * t)
t = 1
lr = exponential_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=1000, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 1000, x1: -0.820458, x2: 0.004701
.. figure:: output_sgd_baca77_27_1.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def exponential_lr():
# Bu fonksiyonun dışında tanımlanan ve içinde güncellenen global değişken
global t
t += 1
return math.exp(-0.1 * t)
t = 1
lr = exponential_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=1000, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 1000, x1: -0.895644, x2: -0.085209
.. figure:: output_sgd_baca77_30_1.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def exponential_lr():
# Bu fonksiyonun dışında tanımlanan ve içinde güncellenen global değişken
global t
t += 1
return math.exp(-0.1 * t)
t = 1
lr = exponential_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=1000, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 1000, x1: -0.763287, x2: -0.058114
.. figure:: output_sgd_baca77_33_1.svg
.. raw:: html
.. raw:: html
Beklendiği gibi, parametrelerdeki varyans önemli ölçüde azaltılır.
Bununla birlikte, bu, :math:`\mathbf{x} = (0, 0)` eniyi çözümüne
yakınsamama pahasına gelir. Hatta sonra 1000 yineleme adımında sonra
bile eniyi çözümden hala çok uzaktayız. Gerçekten de, algoritma
yakınsamada tam anlamıyla başarısız. Öte yandan, öğrenme oranının adım
sayısının ters karekökü ile söndüğü polinom sönmesi kullanırsak
yakınsama sadece 50 adımdan sonra daha iyi olur.
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def polynomial_lr():
# Bu fonksiyonun dışında tanımlanan ve içinde güncellenen global değişken
global t
t += 1
return (1 + 0.1 * t) ** (-0.5)
t = 1
lr = polynomial_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 50, x1: 0.025029, x2: 0.115820
.. figure:: output_sgd_baca77_39_1.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def polynomial_lr():
# Bu fonksiyonun dışında tanımlanan ve içinde güncellenen global değişken
global t
t += 1
return (1 + 0.1 * t) ** (-0.5)
t = 1
lr = polynomial_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 50, x1: 0.123653, x2: 0.020916
.. figure:: output_sgd_baca77_42_1.svg
.. raw:: html
.. raw:: html
.. raw:: latex
\diilbookstyleinputcell
.. code:: python
def polynomial_lr():
# Bu fonksiyonun dışında tanımlanan ve içinde güncellenen global değişken
global t
t += 1
return (1 + 0.1 * t) ** (-0.5)
t = 1
lr = polynomial_lr
d2l.show_trace_2d(f, d2l.train_2d(sgd, steps=50, f_grad=f_grad))
.. raw:: latex
\diilbookstyleoutputcell
.. parsed-literal::
:class: output
epoch 50, x1: -0.119864, x2: -0.093422
.. figure:: output_sgd_baca77_45_1.svg
.. raw:: html
.. raw:: html
Öğrenme oranının nasıl ayarlanacağı konusunda çok daha fazla seçenek
var. Örneğin, küçük bir hızla başlayabilir, sonra hızlıca yükseltebilir
ve daha yavaş da olsa tekrar azaltabiliriz. Hatta daha küçük ve daha
büyük öğrenme oranları arasında geçiş yapabiliriz. Bu tür ayarlamaların
çok çeşidi vardır. Şimdilik kapsamlı bir teorik analizin mümkün olduğu
öğrenme oranı ayarlamalarına odaklanalım, yani dışbükey bir ortamda
öğrenme oranları üzerine. Genel dışbükey olmayan problemler için anlamlı
yakınsama garantileri elde etmek çok zordur, çünkü genel olarak doğrusal
olmayan dışbükey problemlerin en aza indirilmesi NP zorludur. Bir
araştırma için örneğin, Tibshirani'nin 2015'teki mükemmel `ders
notları `__\ na
bakınız.
Dışbükey Amaç İşlevleri için Yakınsaklık Analizi
------------------------------------------------
Dışbükey amaç fonksiyonları için rasgele gradyan inişinin aşağıdaki
yakınsama analizi isteğe bağlıdır ve öncelikle problem hakkında daha
fazla sezgi iletmek için hizmet vermektedir. Kendimizi en basit
kanıtlardan biriyle sınırlıyoruz :cite:`Nesterov.Vial.2000`. Önemli
ölçüde daha gelişmiş ispat teknikleri mevcuttur, örn. amaç fonksiyonu
özellikle iyi-huyluysa.
:math:`f(\boldsymbol{\xi}, \mathbf{x})`'in amaç işlevinin
:math:`\boldsymbol{\xi}`'nin tümü için :math:`\mathbf{x}`'de dışbükey
olduğunu varsayalım. Daha somut olarak, rasgele gradyan iniş
güncellemesini aklımızda bulunduruyoruz:
.. math:: \mathbf{x}_{t+1} = \mathbf{x}_{t} - \eta_t \partial_\mathbf{x} f(\boldsymbol{\xi}_t, \mathbf{x}),
burada :math:`f(\boldsymbol{\xi}_t, \mathbf{x})`, bir dağılımdan
:math:`t` adımında çekilen :math:`\boldsymbol{\xi}_t` eğitim örneğine
göre amaç fonksiyonudur ve :math:`\mathbf{x}` model parametresidir.
Aşağıda
.. math:: R(\mathbf{x}) = E_{\boldsymbol{\xi}}[f(\boldsymbol{\xi}, \mathbf{x})]
beklenen riski ifade eder ve :math:`R^*`, :math:`\mathbf{x}`'e göre en
düşük değerdir. Son olarak :math:`\mathbf{x}^*` küçültücü (minimizer)
olsun (:math:`\mathbf{x}`'in tanımlandığı etki alanında var olduğunu
varsayıyoruz). Bu durumda :math:`t` zamanında :math:`\mathbf{x}_t` ve
risk küçültücü :math:`\mathbf{x}^*` arasındaki mesafeyi izleyebilir ve
zamanla iyileşip iyileşmediğini görebiliriz:
.. math:: \begin{aligned} &\|\mathbf{x}_{t+1} - \mathbf{x}^*\|^2 \\ =& \|\mathbf{x}_{t} - \eta_t \partial_\mathbf{x} f(\boldsymbol{\xi}_t, \mathbf{x}) - \mathbf{x}^*\|^2 \\ =& \|\mathbf{x}_{t} - \mathbf{x}^*\|^2 + \eta_t^2 \|\partial_\mathbf{x} f(\boldsymbol{\xi}_t, \mathbf{x})\|^2 - 2 \eta_t \left\langle \mathbf{x}_t - \mathbf{x}^*, \partial_\mathbf{x} f(\boldsymbol{\xi}_t, \mathbf{x})\right\rangle. \end{aligned}
:label: eq_sgd-xt+1-xstar
Rasgele gradyan
:math:`\partial_\mathbf{x} f(\boldsymbol{\xi}_t, \mathbf{x})`'in
:math:`L_2` normunun bir :math:`L` sabiti ile sınırlandığını
varsayıyoruz, dolayısıyla
.. math:: \eta_t^2 \|\partial_\mathbf{x} f(\boldsymbol{\xi}_t, \mathbf{x})\|^2 \leq \eta_t^2 L^2.
:label: eq_sgd-L
Çoğunlukla :math:`\mathbf{x}_t` ve :math:`\mathbf{x}^*` arasındaki
mesafenin *beklenti*\ de nasıl değiştiğiyle ilgileniyoruz. Aslında,
herhangi bir belirli adım dizisi için, karşılaştığımız herhangi
:math:`\boldsymbol{\xi}_t`'ye bağlı olarak mesafe artabilir. Bu yüzden
nokta çarpımını sınırlamamız gerekiyor. Herhangi bir dışbükey fonksiyon
:math:`f` için
:math:`f(\mathbf{y}) \geq f(\mathbf{x}) + \langle f'(\mathbf{x}), \mathbf{y} - \mathbf{x} \rangle`'nin
tüm :math:`\mathbf{x}` ve :math:`\mathbf{y}` için, dışbükeylik ile şuna
varırız:
.. math:: f(\boldsymbol{\xi}_t, \mathbf{x}^*) \geq f(\boldsymbol{\xi}_t, \mathbf{x}_t) + \left\langle \mathbf{x}^* - \mathbf{x}_t, \partial_{\mathbf{x}} f(\boldsymbol{\xi}_t, \mathbf{x}_t) \right\rangle.
:label: eq_sgd-f-xi-xstar
:eq:`eq_sgd-L` ve :eq:`eq_sgd-f-xi-xstar` içindeki her iki
eşitsizliği :eq:`eq_sgd-xt+1-xstar` denklemine yerleştirerek
parametreler arasındaki mesafeye :math:`t+1` zamanında aşağıdaki gibi
sınır koyarız:
.. math:: \|\mathbf{x}_{t} - \mathbf{x}^*\|^2 - \|\mathbf{x}_{t+1} - \mathbf{x}^*\|^2 \geq 2 \eta_t (f(\boldsymbol{\xi}_t, \mathbf{x}_t) - f(\boldsymbol{\xi}_t, \mathbf{x}^*)) - \eta_t^2 L^2.
:label: eqref_sgd-xt-diff
Bu, mevcut kayıp ile optimal kayıp arasındaki fark
:math:`\eta_t L^2/2`'ten ağır bastığı sürece ilerleme kaydettiğimiz
anlamına gelir. Bu fark sıfıra yakınsamaya bağlı olduğundan,
:math:`\eta_t` öğrenme oranının da *yok olması* gerekir.
Sonrasında :eq:`eqref_sgd-xt-diff` üzerinden beklentileri alırız.
Şu sonuca varırız:
.. math:: E\left[\|\mathbf{x}_{t} - \mathbf{x}^*\|^2\right] - E\left[\|\mathbf{x}_{t+1} - \mathbf{x}^*\|^2\right] \geq 2 \eta_t [E[R(\mathbf{x}_t)] - R^*] - \eta_t^2 L^2.
Son adım :math:`t \in \{1, \ldots, T\}` için eşitsizlikler üzerinde
toplamayı içerir. Toplam içeriye daralır ve düşük terimi düşürürsek şunu
elde ederiz:
.. math:: \|\mathbf{x}_1 - \mathbf{x}^*\|^2 \geq 2 \left (\sum_{t=1}^T \eta_t \right) [E[R(\mathbf{x}_t)] - R^*] - L^2 \sum_{t=1}^T \eta_t^2.
:label: eq_sgd-x1-xstar
:math:`\mathbf{x}_1`'in verildiğini ve böylece beklentinin düştüğünü
unutmayın. Son tanımımız
.. math:: \bar{\mathbf{x}} \stackrel{\mathrm{def}}{=} \frac{\sum_{t=1}^T \eta_t \mathbf{x}_t}{\sum_{t=1}^T \eta_t}.
Çünkü
.. math:: E\left(\frac{\sum_{t=1}^T \eta_t R(\mathbf{x}_t)}{\sum_{t=1}^T \eta_t}\right) = \frac{\sum_{t=1}^T \eta_t E[R(\mathbf{x}_t)]}{\sum_{t=1}^T \eta_t} = E[R(\mathbf{x}_t)],
Jensen'in eşitsizliği ile (:math:`i=t`, :eq:`eq_jensens-inequality`
içinde :math:`\alpha_i = \eta_t/\sum_{t=1}^T \eta_t` ayarlarız) ve
:math:`R` dışbükeyliği ile
:math:`E[R(\mathbf{x}_t)] \geq E[R(\bar{\mathbf{x}})]`, şuna ulaşırız:
.. math:: \sum_{t=1}^T \eta_t E[R(\mathbf{x}_t)] \geq \sum_{t=1}^T \eta_t E\left[R(\bar{\mathbf{x}})\right].
Bunu :eq:`eq_sgd-x1-xstar` eşitsizliğinin içine koymak aşağıdaki
sınırı verir:
.. math::
\left[E[\bar{\mathbf{x}}]\right] - R^* \leq \frac{r^2 + L^2 \sum_{t=1}^T \eta_t^2}{2 \sum_{t=1}^T \eta_t},
burada
:math:`r^2 \stackrel{\mathrm{def}}{=} \|\mathbf{x}_1 - \mathbf{x}^*\|^2`,
parametrelerin ilk seçimi ile nihai sonuç arasındaki mesafeye bağlıdır.
Kısacası, yakınsama hızı, rasgele gradyanın normunun nasıl
sınırlandığına (:math:`L`) ve ilk parametre (:math:`r`) değerinin eniyi
değerden ne kadar uzakta olduğuna bağlıdır. Sınırın :math:`\mathbf{x}_T`
yerine :math:`\bar{\mathbf{x}}` cinsinden olduğuna dikkat edin.
:math:`\bar{\mathbf{x}}`'in optimizasyon yolunun yumuşatılmış bir sürümü
olduğu için bu durum böyledir. :math:`r, L` ve :math:`T` bilindiğinde
öğrenme oranını :math:`\eta = r/(L \sqrt{T})` alabiliriz. Bu, üst sınırı
:math:`rL/\sqrt{T}` olarak verir. Yani, :math:`\mathcal{O}(1/\sqrt{T})`
oranıyla eniyi çözüme yakınsıyoruz.
Rasgele Gradyanlar ve Sonlu Örnekler
------------------------------------
Şimdiye kadar, rasgele gradyan inişi hakkında konuşurken biraz hızlı ve
gevşek hareket ettik. :math:`x_i` örneklerini, tipik olarak :math:`y_i`
etiketleriyle bazı :math:`p(x, y)` dağılımlardan çektiğimizi ve bunu
model parametrelerini bir şekilde güncellemek için kullandığımızı
belirttik. Özellikle, sonlu bir örnek boyutu için
:math:`p(x, y) = \frac{1}{n} \sum_{i=1}^n \delta_{x_i}(x) \delta_{y_i}(y)`
ayrık dağılımın olduğunu savunduk. Bazı :math:`\delta_{x_i}` ve
:math:`\delta_{y_i}` fonksiyonları için üzerinde rasgele gradyan inişini
gerçekleştirmemizi sağlar.
Ancak, gerçekten yaptığımız şey bu değildi. Mevcut bölümdeki basit
örneklerde, aksi takdirde rasgele olmayan bir gradyana gürültü ekledik,
yani :math:`(x_i, y_i)` çiftleri varmış gibi davrandık. Bunun burada
haklı olduğu ortaya çıkıyor (ayrıntılı bir tartışma için alıştırmalara
bakın). Daha rahatsız edici olan, önceki tüm tartışmalarda bunu açıkça
yapmadığımızdır. Bunun neden tercih edilebilir olduğunu görmek için,
tersini düşünün, yani ayrık dağılımdan *değiştirmeli* :math:`n`
gözlemleri örnekliyoruz. Rastgele :math:`i` elemanını seçme olasılığı
:math:`1/n`'dır. Böylece onu *en azından* bir kez seçeriz:
.. math:: P(\mathrm{seç~} i) = 1 - P(\mathrm{yoksay~} i) = 1 - (1-1/n)^n \approx 1-e^{-1} \approx 0.63.
Benzer bir akıl yürütme, bir numunenin (yani eğitim örneği) *tam bir
kez* seçme olasılığının şöyle verildiğini göstermektedir:
.. math:: {n \choose 1} \frac{1}{n} \left(1-\frac{1}{n}\right)^{n-1} = \frac{n}{n-1} \left(1-\frac{1}{n}\right)^{n} \approx e^{-1} \approx 0.37.
Bu, *değiştirmesiz* örneklemeye göreceli oranla artan bir varyansa ve
azalan veri verimliliğine yol açar. Bu nedenle, pratikte ikincisini
gerçekleştiriyoruz (ve bu kitap boyunca varsayılan seçimdir). Son olarak
eğitim veri kümesindeki tekrarlanan geçişler ondan *farklı* rastgele
sırayla geçer.
Özet
----
- Dışbükey problemler için, geniş bir öğrenme oranları seçeneği için
rasgele gradyan inişinin eniyi çözüme yakınsayacağını
kanıtlayabiliriz.
- Derin öğrenme için bu genellikle böyle değildir. Bununla birlikte,
dışbükey problemlerin analizi, optimizasyona nasıl yaklaşılacağına
dair, yani öğrenme oranını çok hızlı olmasa da aşamalı olarak
azaltmak için, bize yararlı bilgiler verir.
- Öğrenme oranı çok küçük veya çok büyük olduğunda sorunlar ortaya
çıkar. Pratikte uygun bir öğrenme oranı genellikle sadece birden
fazla deneyden sonra bulunur.
- Eğitim veri kümesinde daha fazla örnek olduğunda, gradyan inişi için
her yinelemede hesaplamak daha pahalıya mal olur, bu nedenle bu
durumlarda rasgele gradyan inişi tercih edilir.
- Rasgele gradyan inişi için optimizasyon garantileri genel olarak
dışbükey olmayan durumlarda mevcut değildir, çünkü kontrol gerektiren
yerel minimum sayısı da üstel olabilir.
Alıştırmalar
------------
1. Rasgele gradyan inişini farklı sayıda yineleme ile farklı öğrenme
oranı düzenleri ile deneyin. Özellikle, yineleme sayısının bir
fonksiyonu olarak optimal çözüm :math:`(0, 0)`'dan uzaklığı çizin.
2. :math:`f(x_1, x_2) = x_1^2 + 2 x_2^2` işlevi için gradyana normal
gürültü eklemenin bir kayıp işlevini
:math:`f(\mathbf{x}, \mathbf{w}) = (x_1 - w_1)^2 + 2 (x_2 - w_2)^2`
en aza indirmeye eşdeğer olduğunu kanıtlayın, burada
:math:`\mathbf{x}` normal dağılımdan çekilmektedir.
3. :math:`\{(x_1, y_1), \ldots, (x_n, y_n)\}`'ten değiştirmeli ve
değiştirmesiz örnek aldığınızda rasgele gradyan inişinin
yakınsamasını karşılaştırın.
4. Bir gradyan (veya onunla ilişkili bir koordinat) diğer tüm
gradyanlardan tutarlı bir şekilde daha büyükse, rasgele gradyan inişi
çözücüsünü nasıl değiştirirsiniz?
5. Bunu varsayalım: :math:`f(x) = x^2 (1 + \sin x)`. :math:`f`'te kaç
tane yerel minimum vardır? :math:`f`', en aza indirgemek için tüm
yerel minimumları değerlendirmek zorunda kalacak şekilde
değiştirebilir misiniz?
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html