为什么TensorFlow急切执行API对此函数给出了错误的答案?

为什么TensorFlow急切执行API对此函数给出了错误的答案?,tensorflow,autodiff,Tensorflow,Autodiff,我用这个函数得到它的微分值 def dp1_f1(x): return 64*x*(1-x)*(math.pow((1-2*x),2) )*math.pow((1-8*x+8*x*x), 2) 我想得到dy/dx值。 我可以通过数字方法获得该值,如下所示: def dp_numeric_diff(x): delta_x = 0.0001 return (dp1_f1(x+delta_x)-dp1_f1(x))/delta_x @tf.custom_gradient def f

我用这个函数得到它的微分值

def dp1_f1(x):
return 64*x*(1-x)*(math.pow((1-2*x),2) )*math.pow((1-8*x+8*x*x), 2)
我想得到dy/dx值。 我可以通过数字方法获得该值,如下所示:

def dp_numeric_diff(x):
    delta_x = 0.0001
    return (dp1_f1(x+delta_x)-dp1_f1(x))/delta_x
@tf.custom_gradient
def f3(x, n):
    v = tf.pow(x, n)
    def grad(dy):
        return (dy* (n*tf.pow(x, n-1)) ).numpy()
    return v.numpy(), grad
def dp1_f1(x):
    return 64*x*(1-x)*f3(1-2*x,2)*f3(1-8*x+8*x*x, 2)
我使用TensorFlow急切执行API计算此值:

def dp_ad_tfe(x):
    tf.enable_eager_execution()
    tfe = tf.contrib.eager
    grad_lx = tfe.gradients_function(dp1_f1)
    x = 3.0
    y = dp1_f1(x)
    rst = grad_lx(x)
    return y, rst[0]
我使用下面的代码调用此函数:

numeric_diff = dp_numeric_diff(x)
print('Numeric method:{0}'.format(numeric_diff))
v, d = dp_ad_tfe(x)
print('TFE:{0}'.format(d))
它将显示如下内容:

Numeric method:-75290405.66440672
TFE:-19208000.0

我确信数值方法是正确的。我的TensorFlow急切执行代码有什么问题?顺便说一下,同样的TensorFlow急切执行代码可以为x^2这样的简单函数得到正确答案。

我发现TensorFlow急切执行API不能处理math.pow这样的函数。我必须提供一个函数来告诉TensorFlow执行API如何获得函数的导数。为了解决这个问题,我必须将math.pow更改为我自己的函数,如下所示:

def dp_numeric_diff(x):
    delta_x = 0.0001
    return (dp1_f1(x+delta_x)-dp1_f1(x))/delta_x
@tf.custom_gradient
def f3(x, n):
    v = tf.pow(x, n)
    def grad(dy):
        return (dy* (n*tf.pow(x, n-1)) ).numpy()
    return v.numpy(), grad
def dp1_f1(x):
    return 64*x*(1-x)*f3(1-2*x,2)*f3(1-8*x+8*x*x, 2)
并且必须修改原始功能,如下所示:

def dp_numeric_diff(x):
    delta_x = 0.0001
    return (dp1_f1(x+delta_x)-dp1_f1(x))/delta_x
@tf.custom_gradient
def f3(x, n):
    v = tf.pow(x, n)
    def grad(dy):
        return (dy* (n*tf.pow(x, n-1)) ).numpy()
    return v.numpy(), grad
def dp1_f1(x):
    return 64*x*(1-x)*f3(1-2*x,2)*f3(1-8*x+8*x*x, 2)

现在,TensorFlow急切执行API将给出正确的答案,就像数值方法一样。

TensorFlow的自动微分API只能通过TensorFlow操作的组合进行微分,而不能通过math.pow或其他库等函数进行微分。如果将math.pow替换为tf.pow,结果应该很好

比如:

import tensorflow as tf
tf.enable_eager_execution()

def dp1_f1(x):
    return 64*x*(1-x)*(tf.pow((1-2*x),2) )*tf.pow((1-8*x+8*x*x), 2)

def dp_numeric_diff(x):
    delta_x = 0.0001
    return (dp1_f1(x+delta_x)-dp1_f1(x))/delta_x

grad = tf.contrib.eager.gradients_function(dp1_f1)

print(dp_numeric_diff(3.0).numpy()) # Prints -75300000.0
print(grad(3.0)[0].numpy())         # Prints -75279680.0
希望有帮助

似乎这也被问到了