11.9. Adadelta
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in SageMaker Studio Lab

Adadelta, AdaGrad’ın başka bir çeşididir (Section 11.7). Temel fark, öğrenme oranının koordinatlara uyarlanabilir olduğu miktarı azaltmasıdır. Ayrıca, gelecekteki değişim için kalibrasyon olarak değişiklik miktarını kullandığından, geleneksel olarak bir öğrenme oranına sahip olmamak olarak adlandırılır. Algoritma (Zeiler, 2012) çalışmasında önerildi. Şimdiye kadar önceki algoritmaların tartışılması göz önüne alındığında oldukça basittir.

11.9.1. Algoritma

Özetle, Adadelta, gradyanın ikinci momentinin sızıntılı ortalamasını depolamak için \(\mathbf{s}_t\) ve modeldeki parametrelerin değişiminin ikinci momentinin sızıntılı ortalamasını depolamak için \(\Delta\mathbf{x}_t\) diye iki durum değişkeni kullanır. Yazarların orijinal gösterimini ve adlandırmalarını diğer yayınlarla ve uygulamalarla uyumluluk için kullandığımızı unutmayın (momentum, Adagrad, RMSProp ve Adadelta, Adagrad, RMSProp ve Adadelta’da aynı amaca hizmet eden bir parametreyi belirtmek için farklı Yunan değişkenleri kullanılmasının başka bir gerçek nedeni yoktur).

İşte Adadelta’nın teknik detayları verelim. Servis edilen parametre \(\rho\) olduğu göz önüne alındığında, Section 11.8’a benzer şekilde aşağıdaki sızdıran güncellemeleri elde ediyoruz:

(11.9.1)\[\begin{aligned} \mathbf{s}_t & = \rho \mathbf{s}_{t-1} + (1 - \rho) \mathbf{g}_t^2. \end{aligned}\]

Section 11.8 ile arasındaki fark, güncellemeleri yeniden ölçeklendirilmiş \(\mathbf{g}_t'\) gradyanı ile gerçekleştirmemizdir, yani

(11.9.2)\[\begin{split}\begin{aligned} \mathbf{x}_t & = \mathbf{x}_{t-1} - \mathbf{g}_t'. \\ \end{aligned}\end{split}\]

Peki yeniden ölçeklendirilmiş gradyan \(\mathbf{g}_t'\) nedir? Bunu aşağıdaki gibi hesaplayabiliriz:

(11.9.3)\[\begin{split}\begin{aligned} \mathbf{g}_t' & = \frac{\sqrt{\Delta\mathbf{x}_{t-1} + \epsilon}}{\sqrt{{\mathbf{s}_t + \epsilon}}} \odot \mathbf{g}_t, \\ \end{aligned}\end{split}\]

burada \(\Delta \mathbf{x}_{t-1}\) karesi yeniden ölçeklendirilmiş gradyanların sızdıran ortalaması \(\mathbf{g}_t'\) dir. \(\Delta \mathbf{x}_{0}\)’ı \(0\) olacak şekilde ilkleriz ve her adımda \(\mathbf{g}_t'\) ile güncelleriz, yani,

(11.9.4)\[\begin{aligned} \Delta \mathbf{x}_t & = \rho \Delta\mathbf{x}_{t-1} + (1 - \rho) {\mathbf{g}_t'}^2, \end{aligned}\]

ve \(\epsilon\) (\(10^{-5}\) gibi küçük bir değerdir) sayısal kararlılığı korumak için eklenir.

11.9.2. Uygulama

Adadelta, her değişken için iki durum değişkenini, \(\mathbf{s}_t\) ve \(\Delta\mathbf{x}_t\), korumalıdır. Bu, aşağıdaki uygulamayı verir.

%matplotlib inline
from d2l import mxnet as d2l
from mxnet import np, npx

npx.set_np()

def init_adadelta_states(feature_dim):
    s_w, s_b = np.zeros((feature_dim, 1)), np.zeros(1)
    delta_w, delta_b = np.zeros((feature_dim, 1)), np.zeros(1)
    return ((s_w, delta_w), (s_b, delta_b))

def adadelta(params, states, hyperparams):
    rho, eps = hyperparams['rho'], 1e-5
    for p, (s, delta) in zip(params, states):
        # [:] aracılığıyla yerinde güncellemeler
        s[:] = rho * s + (1 - rho) * np.square(p.grad)
        g = (np.sqrt(delta + eps) / np.sqrt(s + eps)) * p.grad
        p[:] -= g
        delta[:] = rho * delta + (1 - rho) * g * g
%matplotlib inline
import torch
from d2l import torch as d2l


def init_adadelta_states(feature_dim):
    s_w, s_b = torch.zeros((feature_dim, 1)), torch.zeros(1)
    delta_w, delta_b = torch.zeros((feature_dim, 1)), torch.zeros(1)
    return ((s_w, delta_w), (s_b, delta_b))

def adadelta(params, states, hyperparams):
    rho, eps = hyperparams['rho'], 1e-5
    for p, (s, delta) in zip(params, states):
        with torch.no_grad():
            # [:] aracılığıyla yerinde güncellemeler
            s[:] = rho * s + (1 - rho) * torch.square(p.grad)
            g = (torch.sqrt(delta + eps) / torch.sqrt(s + eps)) * p.grad
            p[:] -= g
            delta[:] = rho * delta + (1 - rho) * g * g
        p.grad.data.zero_()
%matplotlib inline
import tensorflow as tf
from d2l import tensorflow as d2l


def init_adadelta_states(feature_dim):
    s_w = tf.Variable(tf.zeros((feature_dim, 1)))
    s_b = tf.Variable(tf.zeros(1))
    delta_w = tf.Variable(tf.zeros((feature_dim, 1)))
    delta_b = tf.Variable(tf.zeros(1))
    return ((s_w, delta_w), (s_b, delta_b))

def adadelta(params, grads, states, hyperparams):
    rho, eps = hyperparams['rho'], 1e-5
    for p, (s, delta), grad in zip(params, states, grads):
        s[:].assign(rho * s + (1 - rho) * tf.math.square(grad))
        g = (tf.math.sqrt(delta + eps) / tf.math.sqrt(s + eps)) * grad
        p[:].assign(p - g)
        delta[:].assign(rho * delta + (1 - rho) * g * g)

\(\rho = 0.9\) seçilmesi, her parametre güncelleştirmesi için 10’luk yarı ömür süresine ulaşır. Bu oldukça iyi çalışma eğilimindedir. Aşağıdaki davranışları görürüz.

data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
d2l.train_ch11(adadelta, init_adadelta_states(feature_dim),
               {'rho': 0.9}, data_iter, feature_dim);
loss: 0.246, 0.121 sec/epoch
../_images/output_adadelta_0b41cb_15_1.svg
data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
d2l.train_ch11(adadelta, init_adadelta_states(feature_dim),
               {'rho': 0.9}, data_iter, feature_dim);
loss: 0.246, 0.016 sec/epoch
../_images/output_adadelta_0b41cb_18_1.svg
data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
d2l.train_ch11(adadelta, init_adadelta_states(feature_dim),
               {'rho': 0.9}, data_iter, feature_dim);
loss: 0.243, 0.151 sec/epoch
../_images/output_adadelta_0b41cb_21_1.svg

Kısa bir uygulama için Trainer sınıfından adadelta algoritmasını kullanıyoruz. Bu, çok daha sıkılmıştır bir çağırma için aşağıdaki tek-satırlık kodu verir.

d2l.train_concise_ch11('adadelta', {'rho': 0.9}, data_iter)
loss: 0.243, 0.123 sec/epoch
../_images/output_adadelta_0b41cb_27_1.svg
trainer = torch.optim.Adadelta
d2l.train_concise_ch11(trainer, {'rho': 0.9}, data_iter)
loss: 0.244, 0.014 sec/epoch
../_images/output_adadelta_0b41cb_30_1.svg
# adadelta is not converging at default learning rate
# but it's converging at lr = 5.0
trainer = tf.keras.optimizers.Adadelta
d2l.train_concise_ch11(trainer, {'learning_rate':5.0, 'rho': 0.9}, data_iter)
loss: 0.245, 0.106 sec/epoch
../_images/output_adadelta_0b41cb_33_1.svg

11.9.3. Özet

  • Adadelta’nın öğrenme oranı parametresi yoktur. Bunun yerine, öğrenme oranını uyarlamak için parametrelerin kendisindeki değişim oranını kullanır.

  • Adadelta, gradyanın ikinci momentleri ve parametrelerdeki değişikliği depolamak için iki durum değişkenine ihtiyaç duyar.

  • Adadelta, uygun istatistiklerin işleyen bir tahminini tutmak için sızdıran ortalamaları kullanır.

11.9.4. Alıştırmalar

  1. \(\rho\) değerini ayarlayın. Ne olur?

  2. \(\mathbf{g}_t'\) kullanmadan algoritmanın nasıl uygulanacağını gösterin. Bu neden iyi bir fikir olabilir?

  3. Adadelta gerçekten oranını bedavaya mı öğreniyor? Adadelta’yı bozan optimizasyon problemlerini bulabilir misin?

  4. Yakınsama davranışlarını tartışmak için Adadelta’yı Adagrad ve RMSprop ile karşılaştırın.