某些Tensorflow操作(例如tf.argmax
)不可微分(即没有计算渐变并用于反向传播)。
对Tensorflow what operations are differentiable and what are not?的回答建议在Tensorflow代码中搜索RegisterGradient
。我还注意到Tensorflow有tf.NotDifferentiable
API调用来声明操作是不可区分的。
如果我使用不可微分的功能,是否会发出警告? 是否有一种编程方式来确保我的整个计算图可以区分?
答案 0 :(得分:3)
大多数浮点运算都有渐变,所以第一遍答案就是检查图中没有int32 / int64 dtype张量。这很容易做到,但可能没有用(即任何非平凡的模型都会进行不可微分的索引操作)。
您可以进行某种类型的内省,循环遍历GraphDef中的操作并检查它们是否已注册渐变。我认为这也不是非常有用;如果我们不相信渐变是首先注册的,为什么要相信如果注册它们会更正?
相反,我会为您的模型在几个点进行数值梯度检查。例如,让我们说我们注册一个没有渐变的PyFunc:
import tensorflow as tf
import numpy
def my_func(x):
return numpy.sinh(x)
with tf.Graph().as_default():
inp = tf.placeholder(tf.float32)
y = tf.py_func(my_func, [inp], tf.float32) + inp
grad, = tf.gradients(y, inp)
with tf.Session() as session:
print(session.run([y, grad], feed_dict={inp: 3}))
print("Gradient error:", tf.test.compute_gradient_error(inp, [], y, []))
这让我输出如下:
[13.017875, 1.0]
Gradient error: 1.10916996002
数值梯度可能有点棘手,但通常任何比机器epsilon(浮动32的~1e-7)多几个数量级的梯度误差会为我提出一个假定平滑函数的红旗。