Jak ustawić adaptacyjną szybkość uczenia się dla GradientDescentOptimizer?

Używam TensorFlow do treningu sieci neuronowej. W ten sposób inicjalizuję GradientDescentOptimizer:

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

mse        = tf.reduce_mean(tf.square(out - out_))
train_step = tf.train.GradientDescentOptimizer(0.3).minimize(mse)

Rzecz w tym, że nie wiem, jak ustawić regułę aktualizacji dla szybkości uczenia się lub wartość zaniku dla tego.

Jak mogę wykorzystać wskaźnik adaptacyjny?

Author: Stefan Falk, 2015-11-25

5 answers

Po Pierwsze, tf.train.GradientDescentOptimizer ma na celu wykorzystanie stałej szybkości uczenia się dla wszystkich zmiennych we wszystkich krokach. TensorFlow zapewnia również gotowe do użycia optymalizatory adaptacyjne, w tym tf.train.AdagradOptimizer oraz tf.train.AdamOptimizer, a te mogą być używane jako zamienniki drop-in.

Jeśli jednak chcesz kontrolować szybkość uczenia się z obniżeniem gradientu inaczej-waniliowego, możesz skorzystać z faktu, że argument learning_rate do tf.train.GradientDescentOptimizer Konstruktor może być obiektem Tensor. To pozwala obliczyć inną wartość dla szybkości uczenia się w każdym kroku, na przykład:

learning_rate = tf.placeholder(tf.float32, shape=[])
# ...
train_step = tf.train.GradientDescentOptimizer(
    learning_rate=learning_rate).minimize(mse)

sess = tf.Session()

# Feed different values for learning rate to each training step.
sess.run(train_step, feed_dict={learning_rate: 0.1})
sess.run(train_step, feed_dict={learning_rate: 0.1})
sess.run(train_step, feed_dict={learning_rate: 0.01})
sess.run(train_step, feed_dict={learning_rate: 0.01})

Alternatywnie możesz utworzyć Skalar tf.Variable, który przechowuje szybkość uczenia się i przypisywać ją za każdym razem, gdy chcesz zmienić szybkość uczenia się.

 196
Author: mrry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 05:10:59

Tensorflow zapewnia op, aby automatycznie zastosować rozkład wykładniczy do tensora szybkości uczenia się: tf.train.exponential_decay. Przykład tego, co jest w użyciu, zobacz Ten wiersz w przykładzie modelu konvolutional MNIST. Następnie użyj powyższej sugestii @mrry, aby dostarczyć tę zmienną jako parametr learning_rate wybranemu optymalizatorowi.

Kluczowy fragment do obejrzenia to:

# Optimizer: set up a variable that's incremented once per batch and
# controls the learning rate decay.
batch = tf.Variable(0)

learning_rate = tf.train.exponential_decay(
  0.01,                # Base learning rate.
  batch * BATCH_SIZE,  # Current index into the dataset.
  train_size,          # Decay step.
  0.95,                # Decay rate.
  staircase=True)
# Use simple momentum for the optimization.
optimizer = tf.train.MomentumOptimizer(learning_rate,
                                     0.9).minimize(loss,
                                                   global_step=batch)

Zwróć uwagę na parametr global_step=batch, aby zminimalizować. To mówi optymalizatorowi, aby pomógł zwiększyć "partię" parametr dla Ciebie za każdym razem, gdy trenuje.

 89
Author: dga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-16 12:10:27

Algorytm zniżania gradientu wykorzystuje stałą szybkość uczenia się, którą można podać w podczas inicjalizacji. Możesz zdać różne kursy nauki w sposób pokazany przez Mrry.

Ale zamiast niego można również użyć bardziej zaawansowanych optymalizatorów , które mają szybszą zbieżność i dostosowują się do sytuacji.

Oto krótkie wyjaśnienie oparte na moim zrozumieniu:

  • momentum pomaga SGD poruszać się po odpowiednich kierunki i zmiękcza oscylacje w nieistotnych. Po prostu dodaje ułamek kierunku poprzedniego kroku do bieżącego kroku. Osiąga to wzmocnienie prędkości we właściwym kierunku i łagodzi oscylacje w niewłaściwych kierunkach. Ułamek ten zwykle mieści się w przedziale (0, 1). Sensowne jest również użycie pędu adaptacyjnego. Na początku nauki duży pęd tylko utrudni Twoje postępy, więc ma sens używać czegoś takiego jak 0.01 i gdy wszystkie wysokie gradienty / align = "left" / Jest jeden problem z rozmachem: kiedy jesteśmy bardzo blisko celu, nasz rozmach w większości przypadków jest bardzo wysoki i nie wie, że powinien spowolnić. Może to spowodować pominięcie lub oscylację wokół minima
  • Nesterov przyspieszony gradient przezwycięża ten problem, zaczynając wcześnie zwalniać. W momencie pędu najpierw obliczamy gradient, a następnie wykonujemy skok w tym kierunku wzmacniany przez dowolny moment pędu poprzednio. NAG robi to samo, ale w innej kolejności: najpierw wykonujemy duży skok na podstawie naszych przechowywanych informacji, a następnie obliczamy gradient i dokonujemy małej korekty. Ta pozornie nieistotna zmiana daje znaczne praktyczne przyspieszenie.
  • AdaGrad lub gradient adaptacyjny pozwala na dostosowanie szybkości uczenia się w oparciu o parametry. Wykonuje większe aktualizacje dla rzadkich parametrów i mniejsze aktualizacje dla częstych. Z tego powodu dobrze nadaje się do rzadkich danych (NLP lub rozpoznawanie obrazów). Kolejną zaletą jest to, że w zasadzie illiminates potrzebę dostroić szybkość uczenia się. Każdy parametr ma swój własny wskaźnik uczenia się i ze względu na specyfikę algorytmu szybkość uczenia się jest monotonicznie malejąca. To powoduje największy problem: w pewnym momencie szybkość uczenia się jest tak mała, że system przestaje się uczyć [16]}
  • AdaDelta rozwiązuje problem monotonicznie malejącego wskaźnika uczenia się w Adagradzie. W Adagradzie szybkość uczenia się została obliczona w przybliżeniu jako jedna podzielona przez sumę pierwiastków kwadratowych. Na każdym etapie dodaje się kolejny pierwiastek kwadratowy do sumy, co powoduje, że mianownik stale maleje. W Adadelcie zamiast sumowania wszystkich przeszłych korzeni kwadratowych używa się okna przesuwnego, które pozwala na zmniejszenie sumy. RMSprop jest bardzo podobny do AdaDelta
  • Adam lub Adaptive momentum jest algorytmem podobnym do Adadelty. Ale oprócz przechowywania wskaźników uczenia się dla każdego z parametry przechowuje również zmiany pędu dla każdego z nich osobno

    A kilka wizualizacji : Tutaj wpisz opis obrazka Tutaj wpisz opis obrazka

 86
Author: Salvador Dali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 08:53:56

From TensorFlow official docs

global_step = tf.Variable(0, trainable=False)
starter_learning_rate = 0.1
learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step,
                                       100000, 0.96, staircase=True)

# Passing global_step to minimize() will increment it at each step.
learning_step = (
tf.train.GradientDescentOptimizer(learning_rate)
.minimize(...my loss..., global_step=global_step))
 7
Author: Prakash Vanapalli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 00:08:37

Jeśli chcesz ustawić określone tempo uczenia się dla interwałów epok, takich jak 0 < a < b < c < .... Następnie można zdefiniować szybkość uczenia się jako tensor warunkowy, zależny od kroku globalnego i przekazać to jako normalne optymalizatorowi.

Można to osiągnąć za pomocą kilku zagnieżdżonych instrukcji tf.cond, ale łatwiej jest zbudować tensor rekurencyjnie:

def make_learning_rate_tensor(reduction_steps, learning_rates, global_step):
    assert len(reduction_steps) + 1 == len(learning_rates)
    if len(reduction_steps) == 1:
        return tf.cond(
            global_step < reduction_steps[0],
            lambda: learning_rates[0],
            lambda: learning_rates[1]
        )
    else:
        return tf.cond(
            global_step < reduction_steps[0],
            lambda: learning_rates[0],
            lambda: make_learning_rate_tensor(
                reduction_steps[1:],
                learning_rates[1:],
                global_step,)
            )

Następnie, aby go użyć, musisz wiedzieć, ile kroków treningowych jest w jednej epoce, abyśmy mogli użyć globalnego kroku, aby zmienić w odpowiednim czasie, i wreszcie określić epoki i stawki uczenia się chcesz. Więc jeśli chcę, aby wskaźniki uczenia się [0.1, 0.01, 0.001, 0.0001] w odstępach czasu [0, 19], [20, 59], [60, 99], [100, \infty] odpowiednio, zrobiłbym:

global_step = tf.train.get_or_create_global_step()
learning_rates = [0.1, 0.01, 0.001, 0.0001]
steps_per_epoch = 225
epochs_to_switch_at = [20, 60, 100]
epochs_to_switch_at = [x*steps_per_epoch for x in epochs_to_switch_at ]
learning_rate = make_learning_rate_tensor(epochs_to_switch_at , learning_rates, global_step)
 0
Author: Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-05 17:37:20