ValueError:变量cudnn_gru / opaque_kernel /的初始化器来自控制流构造内部,例如循环或条件

时间:2018-04-04 22:37:19

标签: python tensorflow

系统信息

  • 我是否编写过自定义代码(与使用TensorFlow中提供的库存示例脚本相反):是
  • 操作系统平台和分发:Ubuntu 16.04
  • 安装的TensorFlow:二进制
  • TensorFlow版本:1.5.0
  • Python版:3.5.2
  • CUDA / cuDNN版本:9.0 / 7
  • GPU型号和内存:NVIDIA GTX 1080 8GB x 4
  • 重现的确切命令:代码如下

我一直在尝试使用在die[2]上应用tf.cond的for循环在输入上运行多次,最小错误可重现代码如下:

cudnn_gru

错误堆栈跟踪如下:

import tensorflow as tf
max_para = tf.placeholder(tf.int32)
num_units = 150
inputs = tf.placeholder(tf.float32,shape=[15,8,num_units])
class cudnn_gru:
    def __init__(self):
        self.gru_fw = tf.contrib.cudnn_rnn.CudnnGRU(1, num_units, 
            kernel_initializer=tf.random_normal_initializer(stddev=0.1))
        with tf.variable_scope('CUDNN_GRU', reuse=tf.AUTO_REUSE):
            self.init_fw = tf.get_variable("init_fw",shape=[1, 8, num_units],initializer=
                tf.zeros_initializer())
            self.init_bw = tf.get_variable("init_bw",shape=[1, 8, num_units],initializer=
                tf.zeros_initializer())
    def __call__(self,inputs):
        out_fw, _ = self.gru_fw(inputs, initial_state=(self.init_fw,))

class cudnn_gru2:
    def __init__(self):
        self.gru_fw = tf.contrib.cudnn_rnn.CudnnGRU(1, num_units-1, 
            kernel_initializer=tf.random_normal_initializer(stddev=0.1))
        with tf.variable_scope('CUDNN_GRU', reuse=tf.AUTO_REUSE):
            self.init_fw = tf.get_variable("init_fw",shape=[1, 8, num_units],initializer=
                tf.zeros_initializer())
            self.init_bw = tf.get_variable("init_bw",shape=[1, 8, num_units],initializer=
                tf.zeros_initializer())
    def __call__(self,inputs):
        out_fw, _ = self.gru_fw(inputs, initial_state=(self.init_fw,))

def get_output():
    gru = cudnn_gru()
    out = gru(inputs)
    return tf.constant(1)

def get_output2():
    gru = cudnn_gru2()
    out = gru(inputs)
    return tf.constant(2)

for i in range(3):
    i_ = tf.constant(i)
    out = tf.cond(i_<max_para,get_output,get_output2)

如何在模型构建期间不会导致编译错误的情况下实现此目的?

1 个答案:

答案 0 :(得分:1)

tf.condtf.while循环通过调用true / false函数或仅循环条件/正文函数一次来工作。这些函数返回一些OP,或者OP组执行一些功能,例如检查条件并返回true / false,或者在while体的情况下执行一些操作。

Tensorflow只需调用您的函数一次即可获得所需操作的定义。 Tensorflow将在循环中或必要时处理该组操作。

请注意,这意味着依赖图是静态的,循环执行时没有任何变化。 Tensorflow只是简单地调整依赖关系,以及依赖关系图中的下一步是什么。

因此,如果你要创建一个变量作为循环的一部分,你将改变依赖图的结构 - 这不是设计使用循环/条件的方式。

您需要在条件或循环函数之外定义变量。您可以从循环函数中访问变量,但不能在那里创建变量。

请注意,在RNN / GRU中,您只有一组在每个时间步应用的权重。因此,您不需要在条件/ while函数内调用tf.get_variable,您当然可以创建一次需要的3个变量。

另外,我希望您将函数定义为类的方式是错误的。因为只有当整个班级过度杀戮并且可能令人困惑时,tensorflow才是每个函数的调用。

这是一个tf while循环的例子,我编写了一段时间,可能会给你一个很好的例子。我会尝试简化它以遵循此示例格式(例如删除该类)。

Tensorflow: How to implement cumulative maximum?