数字相同的代码产生了截然不同的结果

时间:2017-04-18 02:02:34

标签: tensorflow

与以下内容有关: tensorflow modify variables in py_func (and its grad func)

我使用此函数在TensorFlow中定义自己的op及其渐变。

    # define gradient of a python function
def py_func_with_grad(func, inp, Tout, stateful=True, name=None, grad=None): 
    num = []
    for i in range(100):
        num.append(str(np.random.randint(0,10)))
    rnd_name = 'PyFuncGrad' + ''.join(num)
    tf.RegisterGradient(rnd_name)(grad)
    g = tf.get_default_graph()
    with g.gradient_override_map({"PyFunc": rnd_name}):
        return tf.py_func(func, inp, Tout, stateful=stateful, name=name)

我有一个神经网络,其中包含以下代码片段,其中我有5条数字相同的行(我使用其中一行)。它们会产生截然不同的结果。我想知道是否有人有任何线索。谢谢!

例如,在(1)和(2)中仅仅用TF变量(s_final)替换x就可以产生这样的差异,这很奇怪。我认为,因为它们在数字上是相同的,所以应该没有任何区别。

s_final是Tensorflow 不可训练的变量。

    def _idenity_func(x,s): 
        return s
    def _dummy_grad(op,grad):
        return grad*0,grad*0

    assign_op_s_final_2 = s_final.assign(x)
    with tf.control_dependencies( [assign_op_s_final_2] ):
        x = tf.identity(x)

    x = tf.stop_gradient(x)

    # the three following lines should be numerically identical. since s_final has been assigned the value of x. but...
    # (1) use the following line, the network does not learn AT ALL!!
    x_revised = py_func_with_grad(_idenity_func, [x, s_final], [tf.float32], name=name, grad=lambda op,grad: _dummy_grad(op,grad) )
    # (2) use the following line, the network learns, even if x does not need any gradient (since there is tf.stop_gradient)
    # x_revised = py_func_with_grad(_idenity_func, [x, x], [tf.float32], name=name, grad=lambda op,grad: _dummy_grad(op,grad)) 
    # (3) use the following line, the network learns as well as (2)
    # x_revised = tf.stop_gradient(x) 
    # (4) use the following line, the network learns, but seems not as well as (2)  
    # x_revised = tf.stop_gradient(s_final)
    # (5) use the following line, the network does not learn AT ALL!!
    # x_revised = py_func_with_grad(_idenity_func, [x, tf.stop_gradient(s_final)], [tf.float32], name=name, grad=lambda op,grad: _dummy_grad(op,grad) )

提供了代码(需要tensorflow 0.12.1。不适用于版本> = 1,因为HyperNetworks的实现不支持tensorflow版本> = 1):

https://www.dropbox.com/s/58khyqdy3mtnri7/tensorflow_clean_ver01.zip?dl=0

以上几行是我们提供的代码。更改它们并运行模型以查看差异。让我知道有关代码的任何问题。

您可以将tensorflow 0.12.1安装到临时文件夹:

export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-0.12.1-cp27-none-linux_x86_64.whl
pip install --target=$HOME/tensorflow_versions/tf-0.12.1  --upgrade $TF_BINARY_URL

然后在运行提供的代码时添加路径。我使用这种方法在我的计算机上有多个版本的Tensorflow。

2 个答案:

答案 0 :(得分:0)

在我的实验中运行良好:我添加了使用x_revised的代码,并查看了涉及其他变量的渐变值。错误必须在未发布的代码中。

答案 1 :(得分:0)

我的猜测是分配并没有真正执行。请注意,您只是构建图形,尚未执行任何操作(不像pytorch)...