这个问题对于这个报错,首先可以确定的一点,是由于把之前TensorFlow1.x中的程序迁移到2.0+版本造成的,在之前1.x版本中有函数tf.placeholder()
我们可以先把报错的位置进行修改
原代码

 self.input_low = tf.placeholder(tf.float32, [None, None, None, 3], name='input_low')

修改为

 self.input_low = tf.compat.v1.placeholder(tf.float32, [None, None, None, 3], name='input_low')

但是这样可能会引起新的错误
RuntimeError: tf.placeholder() is not compatible with eager execution

Tensorflow中的palceholder,中文翻译为占位符,什么意思呢?
在Tensoflow2.0以前,还是静态图的设计思想,整个设计理念是计算流图,在编写程序时,首先构筑整个系统的graph,代码并不会直接生效,这一点和python的其他数值计算库(如Numpy等)不同,graph为静态的,在实际的运行时,启动一个session,程序才会真正的运行。这样做的好处就是:避免反复地切换底层程序实际运行的上下文,tensorflow帮你优化整个系统的代码。我们知道,很多python程序的底层为C语言或者其他语言,执行一行脚本,就要切换一次,是有成本的,tensorflow通过计算流图的方式,可以帮你优化整个session需要执行的代码。
在代码层面,每一个tensor值在graph上都是一个op,当我们将train数据分成一个个minibatch然后传入网络进行训练时,每一个minibatch都将是一个op,这样的话,一副graph上的op未免太多,也会产生巨大的开销;于是就有了tf.placeholder(),我们每次可以将 一个minibatch传入到x = tf.placeholder(tf.float32,[None,32])上,下一次传入的x都替换掉上一次传入的x,这样就对于所有传入的minibatch x就只会产生一个op,不会产生其他多余的op,进而减少了graph的开销。
插入占位符,用于始终将被加载的张量。
重要:如果评估,该张量将产生错误。 它的值必须使用Session.run(),Tensor.eval()或Operation.run()的feed_dict可选参数提供。
如果name_or_scope不为None,则按原样使用。 如果name_or_scope为None,则使用default_name。 在这种情况下,如果先前在同一作用域中使用了相同的名称,则将_N附加到其后将使其唯一。

tf.placeholder()意味着被提供给会话,该会话在运行时从feed dict接收值并执行所需的操作。通常你会创建一个带有’with’关键字的Session()并运行它。但是这可能不适合你需要立即执行的所有情况。这称为急切执行。例:
通常这是运行会话的过程:
所以在调用时,要加上下面这一句,才可以成功运行

tf.compat.v1.disable_eager_execution()

tf.compat.v1.disable_eager_execution()
        # build the model
self.input_low = tf.compat.v1.placeholder(tf.float32, [None, None, None, 3], name='input_low')
self.input_high = tf.compat.v1.placeholder(tf.float32, [None, None, None, 3], name='input_high')
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐