Esta página foi traduzida pela API Cloud Translation.
Switch to English

tf.custom_gradient

Versão do TensorFlow 1 Ver fonte no GitHub

Decorator para definir uma função com um gradiente personalizado.

Esse decorador permite controle refinado sobre os gradientes de uma sequência para operações. Isso pode ser útil por vários motivos, incluindo o fornecimento de um gradiente mais eficiente ou numericamente estável para uma sequência de operações.

Por exemplo, considere a seguinte função que normalmente ocorre no cálculo de entropia cruzada e probabilidade de log:

 def log1pexp(x):
  return tf.math.log(1 + tf.exp(x))
 

Devido à instabilidade numérica, o gradiente dessa função avaliada em x = 100 é NaN. Por exemplo:

 x = tf.constant(100.)
y = log1pexp(x)
dy = tf.gradients(y, x) # Will be NaN when evaluated.
 

A expressão do gradiente pode ser simplificada analiticamente para fornecer estabilidade numérica:

 @tf.custom_gradient
def log1pexp(x):
  e = tf.exp(x)
  def grad(dy):
    return dy * (1 - 1 / (1 + e))
  return tf.math.log(1 + e), grad
 

Com essa definição, o gradiente em x = 100 será avaliado corretamente como 1,0.

Aninhar gradientes personalizados pode levar a resultados não intuitivos. O comportamento padrão não corresponde aos derivados de n-ésima ordem. Por exemplo

 @tf.custom_gradient
def op(x):
  y = op1(x)
  @tf.custom_gradient
  def grad_fn(dy):
    gdy = op2(x, y, dy)
    def grad_grad_fn(ddy):  # Not the 2nd order gradient of op w.r.t. x.
      return op3(x, y, dy, ddy)
    return gdy, grad_grad_fn
  return y, grad_fn
 

A função grad_grad_fn calculará o gradiente de primeira ordem de grad_fn em relação a dy , que é usado para gerar gráficos de gradiente de modo progressivo a partir de gráficos de gradiente de modo regressivo, mas não é o mesmo que o gradiente de segunda ordem de op em relação a x .

Em vez disso, envolva nested @tf.custom_gradients em outra função:

 @tf.custom_gradient
def op_with_fused_backprop(x):
  y, x_grad = fused_op(x)
  def first_order_gradient(dy):
    @tf.custom_gradient
    def first_order_custom(unused_x):
      def second_order_and_transpose(ddy):
        return second_order_for_x(...), gradient_wrt_dy(...)
      return x_grad, second_order_and_transpose
    return dy * first_order_custom(x)
  return y, first_order_gradient
 

Argumentos adicionais para a função @tf.custom_gradient interno controlam os valores de retorno esperados da função mais interna.

Consulte também tf.RegisterGradient que registra uma função de gradiente para uma operação primitiva do TensorFlow. tf.custom_gradient por outro lado, permite um controle refinado sobre o cálculo do gradiente de uma sequência de operações.

Observe que se a função decorada usa Variable s, o escopo da variável envolvente deve usar ResourceVariable s.

f função f(*x) que retorna uma tupla (y, grad_fn) que:

  • x é uma sequência de (estruturas aninhadas de) entradas do Tensor para a função.
  • y é uma (estrutura aninhada de) saídas do Tensor de aplicação de operações do TensorFlow em f a x .
  • grad_fn é uma função com a assinatura g(*grad_ys) que retorna uma lista de Tensor s do mesmo tamanho que (achatada) x - as derivadas do Tensor s em y em relação ao Tensor s em x . grad_ys é uma sequência de Tensor s do mesmo tamanho que (achatada) y segurando os gradientes de valor inicial para cada Tensor em y .

Em um sentido matemático puro, um vector-argumento vectorial função f derivados 's devem ser sua matriz Jacobiana J . Aqui, estamos expressando o J jacobiano como uma função grad_fn que define como J transformará um vetor grad_ys quando multiplicado à esquerda com ele ( grad_ys * J , o produto vetor jacobiano ou VJP). Essa representação funcional de uma matriz é conveniente para o cálculo de regras de cadeia (por exemplo, o algoritmo de retropropagação).

Se f usa a Variable s (que não faz parte das entradas), ou seja, através de get_variable , então grad_fn deve ter a assinatura g(*grad_ys, variables=None) , em que variables é uma lista das Variable s e retorna uma tupla de 2 (grad_xs, grad_vars) , onde grad_xs é o mesmo que acima, e grad_vars é uma list<Tensor> com as derivadas de Tensor s em y em relação às variáveis ​​(ou seja, grad_vars tem um Tensor por variável em variáveis).

Uma função h(x) que retorna o mesmo valor que f(x)[0] e cujo gradiente (conforme calculado por tf.gradients ) é determinado por f(x)[1] .