TensorFlow에서 그라디언트 클리핑을 적용하는 방법은 무엇입니까?


96

예제 코드를 고려하십시오 .

그라디언트가 폭발 할 가능성이있는 RNN에서이 네트워크에 그라디언트 클리핑을 적용하는 방법을 알고 싶습니다.

tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)

이것은 사용할 수있는 예이지만 어디에서 소개해야합니까? RNN의 정의

    lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)
    # Split data because rnn cell needs a list of inputs for the RNN inner loop
    _X = tf.split(0, n_steps, _X) # n_steps
tf.clip_by_value(_X, -1, 1, name=None)

그러나 이것은 텐서 _X가 입력이고 무엇을 잘라야 할 졸업생이 아니기 때문에 의미가 없습니다.

이를 위해 고유 한 Optimizer를 정의해야합니까? 아니면 더 간단한 옵션이 있습니까?

답변:


143

그래디언트 클리핑은 그래디언트를 계산 한 후 모델의 매개 변수를 업데이트하기 위해 적용하기 전에 발생해야합니다. 귀하의 예에서 두 가지 모두 AdamOptimizer.minimize()메서드에 의해 처리됩니다 .

그라디언트를 자르려면 TensorFlow의 API 문서의이 섹션에 설명 된대로 그라디언트를 명시 적으로 계산, 자르고 적용해야 합니다 . 특히 minimize()메서드 호출을 다음과 같이 대체해야합니다 .

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
gvs = optimizer.compute_gradients(cost)
capped_gvs = [(tf.clip_by_value(grad, -1., 1.), var) for grad, var in gvs]
train_op = optimizer.apply_gradients(capped_gvs)

4
Styrke, 게시물 주셔서 감사합니다. 실제로 최적화 프로그램의 반복을 실행하기위한 다음 단계가 무엇인지 알고 있습니까? 일반적으로 옵티마이 저는 optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) 다음과 같이 인스턴스화되고 옵티마이 저의 반복이 수행 optimizer.run()되지만 optimizer.run()이 경우 사용이 작동하지 않는 것 같습니다.
애플 사이다

6
좋아, 그것을 가지고 optimizer.apply_gradients(capped_gvs)필요가 무엇인가에 할당 할 것을 x = optimizer.apply_gradients(capped_gvs)다음 세션에서이 같은 훈련을 할 수x.run(...)
애플 사이다

3
멋진 편집 제안을 위해 @ remi-cuingnet에게 외쳐주세요 . (어떤 불행하게도 성급한 검토에 의해 거부되었다)
Styrke

이것은 나에게 제공 UserWarning: Converting sparse IndexedSlices to a dense Tensor with 148331760 elements. This may consume a large amount of memory.되므로 어떻게 든 내 희소 그라디언트가 조밀하게 변환됩니다. 이 문제를 극복하는 방법을 아십니까?
Pekka

8
실제로 클립 그라데이션 (tensorflow 워드 프로세서, 컴퓨터 과학자, 그리고 논리에 따라)에 대한 권리 방법은 함께 tf.clip_by_global_norm@danijar에 의해 제안,
gdelab

116

인기가있는 것처럼 보이지만 전체 그라디언트를 글로벌 표준으로 자르고 싶을 것입니다.

optimizer = tf.train.AdamOptimizer(1e-3)
gradients, variables = zip(*optimizer.compute_gradients(loss))
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimize = optimizer.apply_gradients(zip(gradients, variables))

각 그래디언트 행렬을 개별적으로 클리핑하면 상대적 배율이 변경되지만 가능합니다.

optimizer = tf.train.AdamOptimizer(1e-3)
gradients, variables = zip(*optimizer.compute_gradients(loss))
gradients = [
    None if gradient is None else tf.clip_by_norm(gradient, 5.0)
    for gradient in gradients]
optimize = optimizer.apply_gradients(zip(gradients, variables))

TensorFlow 2에서 테이프는 기울기를 계산하고 옵티마이 저는 Keras에서 제공되며 세션으로 전달하지 않고 자동으로 실행되기 때문에 업데이트 작업을 저장할 필요가 없습니다.

optimizer = tf.keras.optimizers.Adam(1e-3)
# ...
with tf.GradientTape() as tape:
  loss = ...
variables = ...
gradients = tape.gradient(loss, variables)
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimizer.apply_gradients(zip(gradients, variables))

10
좋은 예 clip_by_global_norm()! 이것은 또한 the correct way to perform gradient clippingtensorflow 문서 에서처럼 설명됩니다 : tensorflow.org/versions/r1.2/api_docs/python/tf/…
MZHm

9
@Escachator 경험적이며 모델과 작업에 따라 다릅니다. 내가하는 일은 그라디언트 표준을 시각화하여 tf.global_norm(gradients)일반적인 범위를 확인한 다음 이상 치가 훈련을 엉망으로 만드는 것을 방지하기 위해 약간 더 클립하는 것입니다.
danijar

1
여전히 전화 opt.minimize()를 걸 opt.run()겠습니까, 아니면 다른 답변에 대한 일부 의견에서 제안 된 것과 같이 다른 전화를 걸 겠습니까?
reese0106

3
@ reese0106 아니요, optimizer.minimize(loss)그래디언트를 계산하고 적용하기위한 속기입니다. 내 대답에서 예제를 실행할 수 있습니다 sess.run(optimize).
danijar

1
그래서 내가 tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)실험 기능 내에서 사용한다면 optimizetrain_op올바른 것을 대체 할 것 입니까? 지금 당장은 train_op = optimizer.minimize(loss, global_step=global_step))그에 따라 조정하도록 노력하고 있습니다 ...
reese0106

10

이것은 실제로 문서에 제대로 설명되어 있습니다. :

최소화 ()를 호출하면 그래디언트를 계산하고 변수에 적용 할 수 있습니다. 그라디언트를 적용하기 전에 처리하려면 대신 최적화 프로그램을 세 단계로 사용할 수 있습니다.

  • compute_gradients ()를 사용하여 기울기를 계산합니다.
  • 원하는대로 그라디언트를 처리합니다.
  • apply_gradients ()를 사용하여 처리 된 그라디언트를 적용합니다.

그리고 예제에서는 다음 3 단계를 사용합니다.

# Create an optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)

# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss, <list of variables>)

# grads_and_vars is a list of tuples (gradient, variable).  Do whatever you
# need to the 'gradient' part, for example cap them, etc.
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]

# Ask the optimizer to apply the capped gradients.
opt.apply_gradients(capped_grads_and_vars)

다음 MyCapper은 그라디언트를 제한하는 모든 기능입니다. 유용한 기능 (외) 목록 tf.clip_by_value()여기에 있습니다 .


여전히 전화 opt.minimize()를 걸 opt.run()겠습니까, 아니면 다른 답변에 대한 일부 의견에서 제안 된 것과 같이 다른 전화를 걸 겠습니까?
reese0106

@ reese0106 아니요, 예를 들어 opt.apply_gradients(...)변수에 를 할당해야합니다 train_step(예 : 에서처럼 opt.minimize(). 그리고 메인 루프에서 평소처럼 훈련을 호출합니다sess.run([train_step, ...], feed_dict)
dsalaj

기울기는 모델의 모든 매개 변수에 대한 손실 wrt의 미분 벡터로 정의됩니다. TensorFlow는이를 각 변수 및 해당 그라디언트에 대한 튜플을 포함하는 Python 목록으로 나타냅니다. 즉, 그래디언트 노름을 클리핑하는 것을 의미합니다. 각 텐서를 개별적으로 클리핑 할 수 없습니다 tf.clip_by_global_norm(list_of_tensors). 한 번에 목록을 고려해야합니다 (예 : 사용 ).
danijar

8

그래디언트 클리핑 (표준 기준)의 개념을 이해하려는 사람들을 위해 :

그래디언트 노름이 특정 임계 값보다 클 때마다 그래디언트 노름을 클리핑하여 임계 값 내에 유지합니다. 이 임계 값은 때때로로 설정됩니다 5.

그래디언트를 g 로하고 max_norm_threshold를 j로 둡니다 .

자, 만약 || g || > j , 우리는 다음을 수행합니다.

g = ( j * g ) / || g ||

이 구현은 tf.clip_by_norm


임계 값을 직접 선택해야하는 경우이를 수행하는 일반적인 방법이 있습니까?
ningyuwhut

이것은 일부 논문에서 제안 된 일종의 흑 마법입니다. 그렇지 않으면 많은 실험을하고 어떤 것이 더 잘 작동하는지 찾아야합니다.
kmario23

4

IMO는 최적의 솔루션을 TF의 추정기 데코레이터로 래핑하는 것입니다 tf.contrib.estimator.clip_gradients_by_norm.

original_optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer = tf.contrib.estimator.clip_gradients_by_norm(original_optimizer, clip_norm=5.0)
train_op = optimizer.minimize(loss)

이렇게하면 한 번만 정의하면되고 모든 그라디언트 계산 후에 실행하지 않습니다.

문서 : https://www.tensorflow.org/api_docs/python/tf/contrib/estimator/clip_gradients_by_norm


2

Gradient Clipping은 기본적으로 그라디언트가 폭발하거나 사라지는 경우에 도움이됩니다. 손실이 너무 높아서 네트워크를 통해 지수 그라디언트가 흐르게되어 Nan 값이 발생할 수 있습니다. 이를 극복하기 위해 특정 범위 (-1에서 1 또는 조건에 따라 임의의 범위) 내에서 그라디언트를 자릅니다.

clipped_value=tf.clip_by_value(grad, -range, +range), var) for grad, var in grads_and_vars

여기서 grads _and_vars는 그라디언트 쌍 (tf.compute_gradients를 통해 계산)과 적용 할 변수입니다.

클리핑 후 옵티 마이저를 사용하여 값을 적용합니다. optimizer.apply_gradients(clipped_value)

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