您必须为占位符张量提供一个值' c_1'与dtype浮动和形状[1]

时间:2016-07-25 17:51:01

标签: tensorflow

我读了一些关于同样问题的问题,但看起来我的问题有些不同。我想冻结图表然后使用它。

这是一个简单的例子,我是如何做到的。首先,我创建会话并保存checkpoint和GraphDef:

a = tf.Variable(tf.constant(1.), name='a')
b = tf.Variable(tf.constant(2.), name='b')
c = tf.placeholder(tf.float32, shape =[1], name="c")
add = tf.add(a, b, 'sum')
add2 = tf.add(add, c, 'sum2')

dir_path = "<full_path>/simple_store"

with tf.Session() as sess:
    tf.initialize_all_variables().run()
    sess.run([add2], feed_dict={c:[7.]})
    tf.train.Saver().save(sess, dir_path + "/" + 'simple.ckpt')
    tf.train.write_graph(graph_def=sess.graph.as_graph_def(), logdir=dir_path, name='simple_as_text.pb')

然后我使用bazel工具冻结这样的方式:

../tensorflow/bazel-bin/tensorflow/python/tools/freeze_graph --input_graph=simple_store/simple_as_text.pb --input_checkpoint=simple_store/simple.ckpt --output_graph=simple_store/freeze_out.pb --output_node_names=sum2

然后我在Python中加载freeze_out.pb并尝试运行:

import tensorflow as tf
from tensorflow.core.framework import graph_pb2, cost_graph_pb2

graph_def = graph_pb2.GraphDef()
d = None

c = tf.placeholder(tf.float32, shape=[1], name="c")
feed_dict = {c: [5.]}

with tf.Session() as session:
    print("load graph")
    with open("<somepath>/simple_store/freeze_out.pb", "rb") as f:
        graph_def.ParseFromString(f.read())
        d = tf.import_graph_def(graph_def, return_elements=["sum2:0"], name='')
    print(session.run([d[0]], feed_dict=feed_dict))

最后我得到以下错误:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-3-6345b17fba3b> in <module>()
      8         d = tf.import_graph_def(graph_def, return_elements=["sum2:0"], name='')
      9     tf.initialize_all_variables().run()
---> 10     print(session.run([d[0]], feed_dict=feed_dict))

/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.pyc in run(self, fetches, feed_dict, options, run_metadata)
    370     try:
    371       result = self._run(None, fetches, feed_dict, options_ptr,
--> 372                          run_metadata_ptr)
    373       if run_metadata:
    374         proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.pyc in _run(self, handle, fetches, feed_dict, options, run_metadata)
    634     try:
    635       results = self._do_run(handle, target_list, unique_fetches,
--> 636                              feed_dict_string, options, run_metadata)
    637     finally:
    638       # The movers are no longer used. Delete them.

/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.pyc in _do_run(self, handle, target_list, fetch_list, feed_dict, options, run_metadata)
    706     if handle is None:
    707       return self._do_call(_run_fn, self._session, feed_dict, fetch_list,
--> 708                            target_list, options, run_metadata)
    709     else:
    710       return self._do_call(_prun_fn, self._session, handle, feed_dict,

/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.pyc in _do_call(self, fn, *args)
    726         except KeyError:
    727           pass
--> 728       raise type(e)(node_def, op, message)
    729 
    730   def _extend_graph(self):

InvalidArgumentError: You must feed a value for placeholder tensor 'c_1' with dtype float and shape [1]
     [[Node: c_1 = Placeholder[dtype=DT_FLOAT, shape=[1], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
Caused by op u'c_1', defined at:
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/artem/.local/lib/python2.7/site-packages/ipykernel/__main__.py", line 3, in <module>
    app.launch_new_instance()
  File "/home/artem/.local/lib/python2.7/site-packages/traitlets/config/application.py", line 596, in launch_instance
    app.start()
  File "/home/artem/.local/lib/python2.7/site-packages/ipykernel/kernelapp.py", line 442, in start
    ioloop.IOLoop.instance().start()
  File "/home/artem/.local/lib/python2.7/site-packages/zmq/eventloop/ioloop.py", line 162, in start
    super(ZMQIOLoop, self).start()
  File "/home/artem/.local/lib/python2.7/site-packages/tornado/ioloop.py", line 887, in start
    handler_func(fd_obj, events)
  File "/home/artem/.local/lib/python2.7/site-packages/tornado/stack_context.py", line 275, in null_wrapper
    return fn(*args, **kwargs)
  File "/home/artem/.local/lib/python2.7/site-packages/zmq/eventloop/zmqstream.py", line 440, in _handle_events
    self._handle_recv()
  File "/home/artem/.local/lib/python2.7/site-packages/zmq/eventloop/zmqstream.py", line 472, in _handle_recv
    self._run_callback(callback, msg)
  File "/home/artem/.local/lib/python2.7/site-packages/zmq/eventloop/zmqstream.py", line 414, in _run_callback
    callback(*args, **kwargs)
  File "/home/artem/.local/lib/python2.7/site-packages/tornado/stack_context.py", line 275, in null_wrapper
    return fn(*args, **kwargs)
  File "/home/artem/.local/lib/python2.7/site-packages/ipykernel/kernelbase.py", line 276, in dispatcher
    return self.dispatch_shell(stream, msg)
  File "/home/artem/.local/lib/python2.7/site-packages/ipykernel/kernelbase.py", line 228, in dispatch_shell
    handler(stream, idents, msg)
  File "/home/artem/.local/lib/python2.7/site-packages/ipykernel/kernelbase.py", line 391, in execute_request
    user_expressions, allow_stdin)
  File "/home/artem/.local/lib/python2.7/site-packages/ipykernel/ipkernel.py", line 199, in do_execute
    shell.run_cell(code, store_history=store_history, silent=silent)
  File "/home/artem/.local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2705, in run_cell
    interactivity=interactivity, compiler=compiler, result=result)
  File "/home/artem/.local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2809, in run_ast_nodes
    if self.run_code(code, result):
  File "/home/artem/.local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2869, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-6345b17fba3b>", line 8, in <module>
    d = tf.import_graph_def(graph_def, return_elements=["sum2:0"], name='')
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/importer.py", line 274, in import_graph_def
    op_def=op_def)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 2260, in create_op
    original_op=self._default_original_op, op_def=op_def)
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1230, in __init__
    self._traceback = _extract_stack()

我做错了什么?我该怎么纠正这个?

2 个答案:

答案 0 :(得分:2)

除非您传递input_map 参数,否则tf.import_graph_def()函数会维护导入图形的结构

在传递给freeze_graph的原始图表中,名为"sum2:0"的张量取决于名为"c"的占位符操作,该操作位于同一图表中。导入冻结图时,TensorFlow首先导入名为"c"

的节点

使用tf.import_graph_def()导入冻结图时,TensorFlow首先导入"c"中名为freeze_out.pb的节点。但是,因为您在第二个程序中创建了另一个名为"c"的节点,所以导入的节点将重命名为"c_1"(自动生成的唯一名称),并且导入的"sum_2"版本将被重写为取决于"c_1"。值得注意的是,取决于您正在喂食的占位符(名为"c")。

有两种解决方案。更直接的解决方案是从导入的图形中提取先前创建的占位符,而不是创建新的占位符。您可以将"c:0"添加到return_elements

列表中,从而实现此目的
graph_def = tf.GraphDef()

with open("<somepath>/simple_store/freeze_out.pb", "rb") as f:
    graph_def.ParseFromString(f.read())

# Also extract the placeholder "c" from the imported graph.
c, d = tf.import_graph_def(graph_def, return_elements=["c:0", "sum2:0"])

with tf.Session() as session:
    print(session.run([d[0]], feed_dict={c: [5.]}))

或者,您可以在导入的图形中重新映射占位符,以在新图形中使用占位符。 (进行此替换没有太大意义,但是当新图更复杂并且包括一些新的预处理时,它可能很有用。)这使用input_map参数tf.import_graph_def():< / p>

graph_def = tf.GraphDef()

# Create a new placeholder that we will map into the imported graph.
# (N.B. This has no advantage, but could be useful if `c` were a more interesting
# function.)
c = tf.placeholder(tf.float32, shape=[1], name="c")
feed_dict = {c: [5.]}

with open("<somepath>/simple_store/freeze_out.pb", "rb") as f:
    graph_def.ParseFromString(f.read())

# Also remap the placeholder in the imported graph to use the placeholder created
# above. Notice that the syntax is like the feed_dict, but this performs a static 
# remapping of one tensor to another at graph construction time.
d = tf.import_graph_def(graph_def, input_map={"c:0": c}, return_elements=["sum2:0"])

with tf.Session() as session:
    print(session.run([d[0]], feed_dict={c: [5.]}))

答案 1 :(得分:0)

在我尝试上述方法的情况下,节点自动重命名。那么,这对我有用。首先,我使用

打印出所有节点
[n.name for n in tf.get_default_graph().as_graph_def().node] 

我没有在训练我的模型时命名我的占位符但是看看上面代码的输出我可以知道它们是自动命名的&#39;占位符&#39;和&#39; Placeholder_1&#39;

然后我使用以下行来获得张量

x = tf.get_default_graph().get_tensor_by_name("Placeholder:0")
y = tf.get_default_graph().get_tensor_by_name("Placeholder_1:0")

这给了我所需的占位符。如果出现上述问题,在导入图形def之后,就行了  c = tf.get_default_graph().get_tensor_by_name("c:0")应该有用。