【问题标题】:Building multiple models in the same graph在同一个图中构建多个模型
【发布时间】:2016-08-03 17:58:12
【问题描述】:

我正在尝试构建两个相似的模型来预测不同的输出类型。一个在两个类别之间进行预测,另一个有六个输出类别。它们的输入相同,都是 LSTM RNN。

我已经在他们的每个文件 model1.py 和 model2.py 中将训练和预测分离到单独的函数中。

我犯了将每个模型中的变量命名为同一件事的错误,因此当我分别从模型 1 和模型 2 调用 predict1 和 predict2 时,我得到以下命名空间错误: ValueError:变量 W 已经存在,不允许。您的意思是在 VarScope 中设置 reuse=True 吗?最初定义于:

其中 W 是权重矩阵的名称。

有没有一种从同一个地方运行这些预测的好方法?我试图重命名所涉及的变量,但仍然出现以下错误。似乎不可能在创建时命名 lstm_cell,是吗?

ValueError: Variable RNN/BasicLSTMCell/Linear/Matrix already exists

编辑:在预测文件中确定 model1pred 和 model2pred 的范围后,在调用 model1pred() 然后调用 model2pred() 时出现以下错误

tensorflow.python.framework.errors.NotFoundError: Tensor name model1/model1/BasicLSTMCell/Linear/Matrix" not found in checkpoint files './variables/model1.chk

编辑:代码包含在此处。 model2.py 中的代码缺失,但与 model1.py 中的代码相同,但 n_classes=2 除外,并且在 dynamicRNN 函数和 pred 内部,范围设置为“model2”。

解决方案:问题是保护程序试图从第一次 pred() 执行中恢复包含变量的图形。我能够将 pred 函数的调用包装在不同的图表中来解决问题,从而无需变量范围。

在收集预测文件中:

def model1pred(test_x, test_seqlen):
    from model1 import pred
    with tf.Graph().as_default():
        return pred(test_x, test_seqlen)

def model2pred(test_x, test_seqlen):
    from model2 import pred
    with tf.Graph().as_default():
        return pred(test_x, test_seqlen)

##Import test_x, test_seqlen

probs1, preds1 = model1pred(test_x, test_seq)
probs2, cpreds2 = model2Pred(test_x, test_seq)

在model1.py中

def dynamicRNN(x, seqlen, weights, biases):
    n_steps = 10
    n_input = 14
    n_classes = 6
    n_hidden = 100

    # Prepare data shape to match `rnn` function requirements
    # Current data input shape: (batch_size, n_steps, n_input)
    # Required shape: 'n_steps' tensors list of shape (batch_size, n_input)

    # Permuting batch_size and n_steps
    x = tf.transpose(x, [1, 0, 2])
    # Reshaping to (n_steps*batch_size, n_input)
    x = tf.reshape(x, [-1,n_input])
    # Split to get a list of 'n_steps' tensors of shape (batch_size, n_input)
    x = tf.split(0, n_steps, x)

    # Define a lstm cell with tensorflow
    lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)

    # Get lstm cell output, providing 'sequence_length' will perform dynamic calculation.
    outputs, states = tf.nn.rnn(lstm_cell, x, dtype=tf.float32, sequence_length=seqlen)

    # When performing dynamic calculation, we must retrieve the last
    # dynamically computed output, i.e, if a sequence length is 10, we need
    # to retrieve the 10th output.
    # However TensorFlow doesn't support advanced indexing yet, so we build
    # a custom op that for each sample in batch size, get its length and
    # get the corresponding relevant output.

    # 'outputs' is a list of output at every timestep, we pack them in a Tensor
    # and change back dimension to [batch_size, n_step, n_input]
    outputs = tf.pack(outputs)
    outputs = tf.transpose(outputs, [1, 0, 2])

    # Hack to build the indexing and retrieve the right output.
    batch_size = tf.shape(outputs)[0]
    # Start indices for each sample
    index = tf.range(0, batch_size) * n_steps + (seqlen - 1)
    # Indexing
    outputs = tf.gather(tf.reshape(outputs, [-1, n_hidden]), index)

    # Linear activation, using outputs computed above
    return tf.matmul(outputs, weights['out']) + biases['out']

def pred(test_x, test_seqlen):
     with tf.Session() as sess:
        n_steps = 10
        n_input = 14
        n_classes = 6
        n_hidden = 100
        weights = {'out': tf.Variable(tf.random_normal([n_hidden, n_classes]), name='W1')}
        biases = {'out': tf.Variable(tf.random_normal([n_classes]), name='b1')}
        x = tf.placeholder("float", [None, n_steps, n_input])
        y = tf.placeholder("float", [None, n_classes])
        seqlen = tf.placeholder(tf.int32, [None])

        pred = dynamicRNN(x, seqlen, weights, biases)
        saver = tf.train.Saver(tf.all_variables())
        y_p =tf.argmax(pred,1)

        init = tf.initialize_all_variables()
        sess.run(init)

        saver.restore(sess,'./variables/model1.chk')
        y_prob, y_pred= sess.run([pred, y_p], feed_dict={x: test_x, seqlen: test_seqlen})
        y_prob = np.array([softmax(x) for x in y_prob])
        return y_prob, y_pred

'

【问题讨论】:

  • 也许在自定义 variable_scope 块中创建模型之一?
  • 你真的需要庞大的散文来解释你的问题吗?考虑将问题划分为易于查看问题核心的部分,而不是抛出大量代码行或解释问题的动机。这个网站更多的是关于编码,所以尽量专注于此。
  • 此外,您的问题标题似乎相当广泛,而细节似乎相当具体。您能否更改标题以更好地反映您的问题?

标签: tensorflow recurrent-neural-network lstm


【解决方案1】:

您可以通过在两段模型构造代码周围添加with tf.variable_scope(): 块来实现此目的。这具有为变量名称添加不同前缀的效果,从而避免了冲突。

例如(使用问题中定义的model1pred()model2pred() 函数):

with tf.variable_scope('model1'):
  # Variables created in here will be named 'model1/W', etc.
  probs1, preds1 = model1pred(test_x, test_seq)

with tf.variable_scope('model2'):
  # Variables created in here will be named 'model2/W', etc.
  probs2, cpreds2 = model2Pred(test_x, test_seq)

更多详情,请参阅深入了解HOWTO on variable sharing in TensorFlow

【讨论】:

  • 我会注意到模型是单独的文件,如果这有什么改变的话。我用 variable_scopes 包装了每个模型的训练和预测方法。在创建 LSTM 单元的单独方法中,我还设置了 tf.nn.rnn(...., scope='model1')。每个模型在另一个模型不运行时运行,如前所述,但如果连续运行,第二个模型将失败。
  • 在不同的最外层变量范围内调用代码是否有效? (该文件应该对变量范围没有影响。)如果没有,您可以使用程序的顶级代码更新问题吗?
  • 我假设通过在不同的最外层变量范围中调用代码,您的意思是在调用函数时将模型1pred 和model2pred 中的pred 函数包装在预测文件的变量范围中?这并没有解决错误。我在原始帖子中的代码中进行了编辑
  • 我更新了答案,以显示您如何根据代码中的函数来确定这两个模型的范围。如果这不起作用,请告诉我。
  • 我尝试了这个,从 model1/2.py pred() 函数内部删除范围,以便每个函数在独立调用时都可以工作。第二个模型似乎在第一个模型的保存文件中查找变量?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多