tf.gradient와 tf.train.Optimizer.compute_gradient의 TensorFlow 공식 문서 설명을 번역하고, Stackoverflow를 참고하여 이들의 차이점을 정리합니다.

tf.gradient

xs에 관한 ys 의 symbolic derivative를 계산합니다. 텐서 리스트를 반환(return)하며, 각 텐서는 sum(dy/dx)의 계산 결과를 의미합니다.

tf.gradients(
    ys, xs, grad_ys=None, name='gradients', colocate_gradients_with_ops=False,
    gate_gradients=False, aggregation_method=None, stop_gradients=None,
    unconnected_gradients=tf.UnconnectedGradients.NONE
)

ysxs는 텐서 혹은 텐서 리스트입니다. grad_ys는 텐서 리스트 타입이며 ys의 초기 gradient 값을 가집니다. 그러므로 ys와 같은 길이 값을 갖습니다.

stop_gradientsxs에 대해 Constant로 취급되어야 할 텐서 혹은 텐서 리스트입니다. 이 텐서 값들은 학습 과정 중에 역전파되지 않습니다.

a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b], stop_gradients=[a, b])

위의 예시에서는 g는 [1.0, 1.0]의 계산 결과를 갖습니다. tf.gradients(a + b, [a, b]) 라고 코드를 바꾼다면 [3.0, 1.0]의 계산 결과를 갖게 됩니다. 아래의 예시는 위의 예시와 동일한 의미를 가집니다.

a = tf.stop_gradient(tf.constant(0.))
b = tf.stop_gradient(2 * a)
g = tf.gradients(a + b, [a, b])

tf.stop_gradient그래프를 빌드하는 과정에 있어서 사용하는 대신, stop_gradients 인자는 이미 그래프가 빌드된 이후에도 gradient 계산을 멈추는 방법을 제공합니다.

tf.train.Optimizer.compute_gradients

var_list에 관한 loss의 gradient를 계산합니다.

compute_gradients(
    loss, var_list=None, gate_gradients=GATE_OP, aggregation_method=None,
    colocate_gradients_with_ops=False, grad_loss=None
)

이 함수는 minimize()의 첫 번째 파트로 사용되기도 합니다. var_list 내 variable에 대한 gradient를 (gradient, variable) 페어로 이루어진 리스트에 담아 반환(return)합니다.

차이점

tf.train.Optimizer.compute_gradients(이하 compute_gradients)는 tf.gradients를 래핑합니다. 따라서 추가적인 asserts를 가지고 있습니다. compute_gradients실제 코드상에서 tf.gradientsgradients.gradients라는 이름으로 호출하여 사용하고, 추적 또는 디버깅과 같은 보조 목적으로의 서브클래스로 확장 가능한 기능을 허용합니다.

반환하는 값에 대해서 비교를 하자면 compute_gradients는 (gradient, variable) 페어로 이루어진 리스트를 반환합니다. 이 때에 variable은 항상 존재하지만 gradient는 존재하지 않을 수 있습니다. 만약 variable에 대한 gradient 변화를 적용하려 한다면 compute_gradients를 통해 반환된 리스트를 그대로 가져다가 가중치 업데이트에 사용하면 됩니다.

하지만 tf.gradients는 오직 각 variable에 대한 sum(dy/dx) 계산 결과만을 반환하기 때문에 variable 리스트가 추가적으로 제공되어야 가중치 업데이트에 사용할 수 있습니다.

두 가지 방법은 아래 예시처럼 사용이 가능합니다.

### Approach 1 ###
variable_list = desired_list_of_variables
gradients = optimizer.compute_gradients(loss,var_list=variable_list)
optimizer.apply_gradients(gradients)

### Approach 2 ###
variable_list = desired_list_of_variables
gradients = tf.gradients(loss, var_list=variable_list)
optimizer.apply_gradients(zip(gradients, variable_list))

Reference