【问题标题】:Tensorflow: modify shape of placeholder when retrieving metagraphTensorflow:检索元图时修改占位符的形状
【发布时间】:2016-12-25 14:29:19
【问题描述】:

我训练了一个循环神经网络 (LSTM) 并保存了权重和元图。当我检索元图进行预测时,只要序列长度与训练期间相同,一切正常。

LSTM 的一个好处是输入的序列长度可以变化(例如,如果输入是构成句子的字母,则句子的长度可以变化)。

从元图检索图时如何更改输入的序列长度?

更多细节代码:

在训练期间,我使用占位符 xy 来提供数据。为了进行预测,我检索了这些占位符,但无法更改它们的形状(从 [None, previous_sequence_length=100, n_input][None, new_sequence_length=50, n_input])。

在文件model.py中,定义架构和占位符:

 self.x = tf.placeholder("float32", [None, self.n_steps, self.n_input], name='x_input')
 self.y = tf.placeholder("float32", [None, self.n_classes], name='y_labels')
 tf.add_to_collection('x', self.x)
 tf.add_to_collection('y', self.y)
 ...

 def build_model(self):
     #using the placeholder self.x to build the model
     ...
     tf.split(0, self.n_input, self.x) # split input for RNN cell
     ...

在文件prediction.py 中我检索元图进行预测:

with tf.Session() as sess:
    latest_checkpoint = tf.train.latest_checkpoint(checkpoint_dir=checkpoint_dir)
    new_saver = tf.train.import_meta_graph(latest_checkpoint + '.meta')
    new_saver.restore(sess, latest_checkpoint)
    x = tf.get_collection('x')[0]
    y = tf.get_collection('y')[0]
    ...
    sess.run(..., feed_dict={x: batch_x})

这是我得到的错误:

ValueError: Cannot feed value of shape (128, 50, 2) for Tensor u'placeholders/x_input:0', which has shape '(?, 100, 2)'

注意:当不使用元图而是从头开始重建模型并仅加载保存的权重(而不是元图)时,我设法解决了这个问题。

编辑:将self.n_steps 替换为None 并将tf.split(0, self.n_input, self.x) 修改为tf.split(0, self.x.get_shape()[1], self.x) 时出现以下错误:TypeError: Expected int for argument 'num_split' not Dimension(None).

【问题讨论】:

  • 事后通常不能改变张量的形状。但是,您可以做的一件事是在训练期间固定所有维度的形状,而是不指定它们。您输入的张量的尺寸必须与占位符的形状兼容,但您不必首先指定所有占位符的尺寸。在这里,尝试用“None”代替 self.n_steps。
  • 我在实际发布问题之前尝试过这样做,但在创建模型的某个时刻,我有tf.split(0, self.n_input, self.x)。当我不知道/修复self.n_input 时,我改为使用self.x.get_shape()[1] (tf.split(0, self.x.get_shape()[1], self.x))。但是,我收到以下错误:TypeError: Expected int for argument 'num_split' not Dimension(None)..

标签: neural-network tensorflow deep-learning lstm


【解决方案1】:

当你定义你的变量时,我建议你这样写

[None, None, n_input]

代替:

[None, new_sequence_length=50, n_input]

它适用于我的情况。希望对你有帮助

【讨论】:

  • 我试过了(参见初始帖子中的 cmets),但在我的情况下它不起作用,因为 tf.split 函数将所需的拆分数量作为输入,即 @ 987654324@ 使用此解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多