TensorFlow报错:tf.placeholder() is not compatible with eager execution.

1、报错背景

对于这个报错,首先可以确定的一点,是由于把之前TensorFlow1.x中的程序迁移到2.0+版本造成的,在之前1.x版本中有函数tf.placeholder(),但是到了2.0+版本就没有了,这时候发现在2.0+版本中有一个tf.compat.v1.placeholder,ok,这时候有些会很兴奋,找到了,于是乎就把他替代成了tf.placeholder(),然后就报了如下错误:

RuntimeError: tf.placeholder() is not compatible with eager execution.

2、tf.placeholder()介绍

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的开销。

函数类型:

 tf.placeholder(
       dtype,
       shape=None,
       name=None
    )

参数:

  • dtype:数据类型。常用的是tf.float32,tf.float64等数值类型
  • shape:数据形状。默认是None,就是一维值,也可以是多维(如[2,3], [None, 3]表示列是3,行不定)
  • name:名称
    返回类型:Tensor类型

3、tf.compat.v1.placeholder()介绍

插入占位符,用于始终将被加载的张量。
重要:如果评估,该张量将产生错误。 它的值必须使用Session.run(),Tensor.eval()或Operation.run()的feed_dict可选参数提供。

如果name_or_scope不为None,则按原样使用。 如果name_or_scope为None,则使用default_name。 在这种情况下,如果先前在同一作用域中使用了相同的名称,则将_N附加到其后将使其唯一。

关于函数的具体内容,详见:官方手册:https://tensorflow.google.cn/api_docs/python/tf/compat/v1/placeholder

4、报错原因

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

import tensorflow as tf

def square(num):
    return tf.square(num) 

p = tf.placeholder(tf.float32)
q = square(num)

with tf.Session() as sess:
    print(sess.run(q, feed_dict={num: 10})

但是当我们以急切的执行方式运行时,我们将其运行为:

import tensorflow as tf

tf.enable_eager_execution()

def square(num):
   return tf.square(num)

print(square(10)) 

因此,我们不需要在会话中明确地运行它,并且在大多数情况下可以更直观。这提供了更多的交互式执行。有关详细信息,请访问:https: //www.tensorflow.org/guide/eager

5、解决方法

所以在调用时,要加上下面这一句,才可以成功运行

tf.compat.v1.disable_eager_execution()

实例程序:

import tensorflow as tf
import numpy as np
 
tf.compat.v1.disable_eager_execution()
a = tf.compat.v1.placeholder(dtype=tf.int32)  # 定义一个占位符Tensor
b = tf.compat.v1.placeholder(dtype=tf.int32)
c = a + b
 
a_ = input("a = ")  # 从终端读入一个整数并放入变量a_
b_ = input("b = ")
 
sess = tf.compat.v1.Session()
c_ = sess.run(c, feed_dict={a: a_, b: b_})  # feed_dict参数传入为了计算c所需要的张量的值
print("a + b = %d" % c_)
发布了35 篇原创文章 · 获赞 14 · 访问量 6856

猜你喜欢

转载自blog.csdn.net/caoyuan666/article/details/104706756
今日推荐