为什么 TensorFlow eager execution API 给出了这个函数的错误答案?
Why TensorFlow eager execution API give a wrong answer for this function?
我有这个函数来获取它的微分值。
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
我使用 TensorFlow eager execution 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 eager execution API 无法处理像 math.pow 这样的函数。我必须提供一个函数来告诉TensorFlow eager executionAPI如何得到函数的导数。为了解决这个问题,我必须将 math.pow 更改为我自己的函数,如下所示:
@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 eager execution 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
希望对您有所帮助。
(似乎在 GitHub 上也有人问过这个问题)
我有这个函数来获取它的微分值。
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
我使用 TensorFlow eager execution 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 eager execution API 无法处理像 math.pow 这样的函数。我必须提供一个函数来告诉TensorFlow eager executionAPI如何得到函数的导数。为了解决这个问题,我必须将 math.pow 更改为我自己的函数,如下所示:
@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 eager execution 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
希望对您有所帮助。
(似乎在 GitHub 上也有人问过这个问题)