Тензорный поток: путаница в отношении оптимизатора adam

Я смущен относительно того, как оптимизатор adam работает в тензорном потоке.

Как я читал docs, он говорит, что скорость обучения меняется на каждую итерацию с градиентным спусками.

Но когда я вызываю функцию, я даю ей скорость обучения. И я не вызываю функцию, чтобы сказать, сделайте одну эпоху (неявно вызывая # итерации, чтобы пройти через обучение данным). Я вызываю функцию для каждой партии явно, как

for epoch in epochs
     for batch in data
          sess.run(train_adam_step, feed_dict={eta:1e-3})

Так что моя эта не может меняться. И я не передаю переменную времени. Или это какой-то тип типа генератора, где при создании сеанса t увеличивается каждый раз, когда я вызываю оптимизатор?

Предполагая, что это какая-то вещь типа генератора, и скорость обучения невидимо снижается: как я могу запустить оптимизатор adam, не разлагая скорость обучения? Мне кажется, что RMSProp в основном то же самое, единственное, что мне нужно сделать, чтобы сделать его равным (скорость обучения не учитывается) заключается в изменении гиперпараметров momentum и decay для соответствия beta1 и beta2 соответственно. Это правильно?

Ответ 1

Я нахожу документацию совершенно ясной, я вложу здесь алгоритм в псевдокод:

Параметры:

  • learning_rate: между 1е-4 и 1е-2 стандартно
  • beta1: 0.9 по умолчанию
  • beta2: 0.999 по умолчанию
  • epsilon: 1e-08 по умолчанию

    Значение по умолчанию 1e-8 для epsilon не может быть хорошим дефолтом в целом. Например, при обучении начальной сети в ImageNet текущий хороший выбор - 1,0 или 0,1.


Инициализация:

m_0 <- 0 (Initialize initial 1st moment vector)
v_0 <- 0 (Initialize initial 2nd moment vector)
t <- 0 (Initialize timestep)

m_t и v_t будут отслеживать скользящее среднее градиента и его квадрата для каждого параметра сети. (Итак, если у вас есть 1M-параметры, Adam сохранит в памяти 2M больше параметров)


На каждой итерации t и для каждого параметра модели:

t <- t + 1
lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t)

m_t <- beta1 * m_{t-1} + (1 - beta1) * gradient
v_t <- beta2 * v_{t-1} + (1 - beta2) * gradient ** 2
variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)

Здесь lr_t немного отличается от learning_rate, потому что для ранних итераций скользящие средние еще не сходились, поэтому нам нужно нормализовать, умножив на sqrt(1 - beta2^t) / (1 - beta1^t). Когда t высокий (t > 1./(1.-beta2)), lr_t почти равен learning_rate


Чтобы ответить на ваш вопрос, вам просто нужно пройти фиксированную скорость обучения, сохранить beta1 и beta2 значения по умолчанию, возможно изменить epsilon, и Адам сделает магию:)


Ссылка с RMSProp

Адам с beta1=1 эквивалентен RMSProp с momentum=0. Аргумент beta2 Адама и аргумент decay RMSProp одинаковы.

Однако RMSProp не сохраняет скользящее среднее градиента. Но он может поддерживать импульс, например MomentumOptimizer.

Подробное описание rmsprop.

  • поддерживать перемещаемое (дисконтированное) среднее значение квадрата градиентов
  • разделите градиент на корень этого среднего
  • (может поддерживать импульс)

Вот псевдокод:

v_t <- decay * v_{t-1} + (1-decay) * gradient ** 2
mom = momentum * mom{t-1} + learning_rate * gradient / sqrt(v_t + epsilon)
variable <- variable - mom

Ответ 2

RMS_PROP и ADAM имеют адаптивную скорость обучения.

Основной RMS_PROP

cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

Вы можете видеть, что изначально это имеет два параметра: decay_rate и eps

Тогда мы можем добавить импульс, чтобы сделать наш градиент более устойчивым. Тогда мы можем написать

cache = decay_rate * cache + (1 - decay_rate) * dx**2
**m = beta1*m + (1-beta1)*dx**  [beta1 =momentum parameter in the doc ]
x += - learning_rate * dx / (np.sqrt(cache) + eps)

Теперь вы можете увидеть здесь, если мы будем держать beta1 = o Затем он rms_prop без импульса.

Затем Основы ADAM

В cs-231 Andrej Karpathy изначально описал адама как это

Адам - ​​недавно появившееся обновление, которое немного похоже на RMSProp с импульс

Итак, да! Тогда чем это отличается от rms_prop с импульсом?

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
**x += - learning_rate * m / (np.sqrt(v) + eps)**

Он снова упомянул в уравнении обновления m, v более гладкие.

Таким образом, отличие от rms_prop - это обновление менее шумно.

Что делает этот шум?

Хорошо в процедуре инициализации мы инициализируем m и v как ноль.

т = у = 0

Чтобы уменьшить этот эффект инициализации, всегда нужно провести разминку. Итак, уравнение похоже на

m = beta1*m + (1-beta1)*dx          beta1 -o.9 beta2-0.999
**mt = m / (1-beta1**t)**
v = beta2*v + (1-beta2)*(dx**2)
**vt = v / (1-beta2**t)**
x += - learning_rate * mt / (np.sqrt(vt) + eps)

Теперь мы запускаем это для нескольких итераций. Четко обратите внимание на жирные линии, вы можете видеть, когда t увеличивается (номер итерации), следующая вещь с mt,

mt = m