GradientDescentOptimizer의 적응 형 학습률을 설정하는 방법은 무엇입니까?


104

저는 TensorFlow를 사용하여 신경망을 훈련하고 있습니다. 이것이 내가 초기화하는 방법입니다 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)

여기서 중요한 것은 학습률에 대한 업데이트 규칙이나 그에 대한 감쇠 값을 설정하는 방법을 모른다는 것입니다.

여기서 적응 형 학습률을 어떻게 사용할 수 있습니까?


3
AdamOptimizer와 같은 일부 옵티마이 저는 초기화해야하는 자체 변수를 사용하기 때문에 옵티 마이저를 지정한 모든 변수를 초기화하는 것이 좋습니다 . 그렇지 않으면 다음과 같은 오류가 발생할 수 있습니다.FailedPreconditionError (see above for traceback): Attempting to use uninitialized value beta2_power
JYun

Tensorflow에서 새로운 학습률을 설정하려고 할 때 위에서 언급 한 오류가 발생합니다 tf.train.GradientDescentOptimizer(new_lr).minimize(loss). 새로운 학습률을 설정하려면 이미 학습 된 변수로 모델을 초기화해야합니다. 그러나 그것을 수행하는 방법을 알 수 없습니다.
Siladittya

답변:


193

우선, tf.train.GradientDescentOptimizer모든 단계의 모든 변수에 대해 일정한 학습률을 사용하도록 설계되었습니다. TensorFlow는 또한 및를 포함하여 즉시 사용 가능한 적응 형 최적화 도구를 제공 tf.train.AdagradOptimizer하며 tf.train.AdamOptimizer, 이들은 드롭 인 대체물로 사용할 수 있습니다.

그러나 그렇지 않은 경우 기본 경사 하강 법을 사용하여 학습률을 제어 learning_rate하려면 tf.train.GradientDescentOptimizer생성자에 대한 인수가 Tensor객체 가 될 수 있다는 사실을 활용할 수 있습니다 . 이를 통해 각 단계의 학습률에 대해 다른 값을 계산할 수 있습니다. 예를 들면 다음과 같습니다.

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})

또는 tf.Variable학습률을 유지 하는 스칼라 를 생성 하고 학습률을 변경할 때마다 할당 할 수 있습니다.


좋은 대답입니다. 그래디언트 클리핑에 동일한 기술을 사용할 수 있습니까? tf.clip_by_norm클립 규범에 대한 텐서을 받아, 어떻게 수행에 대한하지 않는 [(tf.minimum(gv[0], ct), gv[1]) for gv in optimizer.compute_gradients(cost, vars)]경우,ct = tf.placeholder('float32', shape=[])
richizy

그래, 작동해야합니다. (를 보더라도 tf.clip_by_norm텐서를 입력으로 받아들이는 것을 막는 유일한 방법은 constant_op.constant(1.0 / clip_norm)입니다. 해당 표현식을로 math_ops.inv(clip_norm)
바꾸면

@mrry 나는 당신이 말한 것처럼 훈련 속도가 훨씬 느립니다. 제발 기대합니까?
tnq177

89

Tensorflow는 학습률 tensor에 지수 감쇠를 자동으로 적용하는 연산을 제공합니다 : tf.train.exponential_decay. 사용중인 예제는 MNIST 컨볼 루션 모델 예제의이 줄을 참조하십시오 . 그런 다음 위의 @mrry의 제안을 사용하여이 변수를 선택한 최적화 프로그램에 learning_rate 매개 변수로 제공하십시오.

살펴볼 핵심 발췌 부분은 다음과 같습니다.

# 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)

global_step=batch최소화 할 매개 변수에 유의하십시오 . 이는 최적화 프로그램이 학습 할 때마다 '배치'매개 변수를 유용하게 증가 시키도록 지시합니다.


3
일반적으로, 당신이 호출 변수 batch라고 global_step여러 편의 기능을 만드는 일이 있습니다 tf.train.create_global_step()(단순히 정수를 생성하는 tf.Variable과에 추가 tf.GraphKeys.GLOBAL_STEP컬렉션)와 tf.train.get_global_step().
Lenar Hoyt

86

경사 하강 법 알고리즘은 초기화 중에 제공 할 수있는 일정한 학습률을 사용합니다 . Mrry가 보여준 방식으로 다양한 학습률을 통과 할 수 있습니다.

그러나 그 대신 더 빠른 수렴 속도를 가지고 상황에 적응하는 고급 최적화 프로그램 을 사용할 수도 있습니다 .

내 이해를 바탕으로 한 간단한 설명은 다음과 같습니다.

  • 모멘텀 SGD가 관련 방향을 따라 탐색하고 관련없는 진동을 완화하는 데 도움 이됩니다. 단순히 이전 단계의 방향의 일부를 현재 단계에 추가합니다. 이를 통해 올바른 방향으로 속도를 증폭하고 잘못된 방향의 진동을 부드럽게합니다. 이 분수는 일반적으로 (0, 1) 범위에 있습니다. 적응 형 운동량을 사용하는 것도 의미가 있습니다. 학습 초기에 큰 운동량은 진행을 방해 할 뿐이므로 0.01과 같은 것을 사용하는 것이 의미가 있으며 모든 높은 기울기가 사라지면 더 큰 운동량을 사용할 수 있습니다. 운동량에는 한 가지 문제가 있습니다. 목표에 매우 가까워지면 대부분의 경우 운동량이 매우 높고 속도를 늦춰야한다는 사실을 모릅니다. 이로 인해 최소값을 놓치거나 진동 할 수 있습니다.
  • nesterov 가속 그라디언트 는 일찍 속도를 늦추기 시작하여이 문제를 극복합니다. 운동량에서 우리는 먼저 기울기를 계산 한 다음 이전에 가졌던 운동량으로 증폭 된 방향으로 점프합니다. NAG는 동일한 작업을 수행하지만 다른 순서로 수행합니다. 처음에는 저장된 정보를 기반으로 크게 점프 한 다음 그래디언트를 계산하고 작은 수정을합니다. 겉보기에 무관 해 보이는이 변화는 실질적인 속도 향상을 가져옵니다.
  • AdaGrad 또는 적응 형 기울기를 사용하면 매개 변수에 따라 학습률을 조정할 수 있습니다. 자주 사용하지 않는 매개 변수에 대해서는 더 큰 업데이트를 수행하고 빈번한 매개 변수에 대해서는 작은 업데이트를 수행합니다. 이 때문에 희소 데이터 (NLP 또는 이미지 인식)에 적합합니다. 또 다른 장점은 기본적으로 학습률을 조정할 필요가 없다는 것입니다. 각 매개 변수에는 자체 학습률이 있으며 알고리즘의 특성으로 인해 학습률은 단조롭게 감소합니다. 이로 인해 가장 큰 문제가 발생합니다. 어느 시점에서 학습률이 너무 낮아 시스템이 학습을 중단합니다.
  • AdaDelta 는 AdaGrad에서 학습률이 단조롭게 감소하는 문제를 해결합니다. AdaGrad에서 학습률은 대략 1을 제곱근의 합으로 나눈 값으로 계산되었습니다. 각 단계에서 합계에 또 다른 제곱근을 추가하면 분모가 지속적으로 감소합니다. AdaDelta에서는 과거 제곱근을 모두 합하는 대신 합계를 줄일 수있는 슬라이딩 윈도우를 사용합니다. RMSpropAdaDelta 와 매우 유사합니다.
  • Adam 또는 적응 운동량은 AdaDelta와 유사한 알고리즘입니다. 그러나 각 매개 변수에 대한 학습률을 저장하는 것 외에도 각 매개 변수에 대한 운동량 변화를 개별적으로 저장합니다.

    몇 시각화 : 여기에 이미지 설명 입력 여기에 이미지 설명 입력


2
: TensorFlow 다른 최적화의 비교를 위해 노트북 ipython 다음 봐 가지고 github.com/vsmolyakov/experiments_with_python/blob/master/chp03/... 에 대한
바딤 Smolyakov

고급 옵티 마이저를 "대신"으로 사용 해서는 안되지만
Dima Lituiev 2018 년

@DimaLituiev 두 개의 옵티 마이저를 동시에 사용할 수 있습니까? 아니라면 optimizer2 대신 optimizer1을 사용하는 것입니다.
Salvador Dali

1
그것은 내가 말하는 것이 아니며 여기서 질문이 아닙니다. 적응 형 학습률 대신 고급 최적화 프로그램을 사용하는 것이 좋습니다. 적응 형 학습률 외에도 고급 옵티 마이저를 사용하고 싶다고 말하고 있습니다
Dima Lituiev

7

에서 tensorflow 공식 문서

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))

0

다음과 같은 시대의 간격에 대한 특정 학습률을 설정하려면 0 < a < b < c < ... . 그런 다음 학습률을 조건부 텐서로 정의하고 전역 단계에서 조건부로이를 옵티 마이저에 정상적으로 제공 할 수 있습니다.

여러 개의 중첩 된 tf.cond문으로 이를 달성 할 수 있지만 재귀 적으로 텐서를 빌드하는 것이 더 쉽습니다.

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,)
            )

그런 다음이를 사용하려면 글로벌 단계를 사용하여 적시에 전환하고 마지막으로 원하는 시대와 학습률을 정의 할 수 있도록 단일 시대에 몇 개의 교육 단계가 있는지 알아야합니다. 따라서 각각 [0.1, 0.01, 0.001, 0.0001]의 에포크 간격 동안 학습률을 원한다면 다음 [0, 19], [20, 59], [60, 99], [100, \infty]을 수행합니다.

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.