如何确保您的计算图是可微分的

时间:2017-08-21 12:46:18

标签: tensorflow neural-network

某些Tensorflow操作(例如tf.argmax)不可微分(即没有计算渐变并用于反向传播)。

Tensorflow what operations are differentiable and what are not?的回答建议在Tensorflow代码中搜索RegisterGradient。我还注意到Tensorflow有tf.NotDifferentiable API调用来声明操作是不可区分的。

如果我使用不可微分的功能,是否会发出警告? 是否有一种编程方式来确保我的整个计算图可以区分?

1 个答案:

答案 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)多几个数量级的梯度误差会为我提出一个假定平滑函数的红旗。