LSTM调用tensorflow提示 raise ValueError("Ambiguous dimension: %s" % value),怎么解决?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LSTM调用tensorflow提示 raise ValueError("Ambiguous dimension: %s" % value),怎么解决?相关的知识,希望对你有一定的参考价值。

参考技术A 张量的维度必须是整数

TensorFlow:为下一批记住 LSTM 状态(有状态 LSTM)

【中文标题】TensorFlow:为下一批记住 LSTM 状态(有状态 LSTM)【英文标题】:TensorFlow: Remember LSTM state for next batch (stateful LSTM) 【发布时间】:2016-11-09 12:46:39 【问题描述】:

给定一个训练有素的 LSTM 模型,我想对单个时间步执行推理,即以下示例中的 seq_length = 1。在每个时间步之后,需要为下一个“批次”记住内部 LSTM(内存和隐藏)状态。在推理的最开始,给定输入计算内部 LSTM 状态init_c, init_h。然后将它们存储在传递给 LSTM 的 LSTMStateTuple 对象中。在训练期间,每个时间步都会更新此状态。但是,对于推理,我希望将state 保存在批次之间,即只需要在开始时计算初始状态,然后在每个“批次”(n = 1)之后保存 LSTM 状态。

我发现了这个相关的 *** 问题:Tensorflow, best way to save state in RNNs?。然而,这只适用于state_is_tuple=False,但这种行为很快就会被 TensorFlow 弃用(参见rnn_cell.py)。 Keras 似乎有一个很好的包装器来使 stateful LSTMs 成为可能,但我不知道在 TensorFlow 中实现这一点的最佳方法。 TensorFlow GitHub上的这个issue也和我的问题有关:https://github.com/tensorflow/tensorflow/issues/2838

对于构建有状态 LSTM 模型有什么好的建议吗?

inputs  = tf.placeholder(tf.float32, shape=[None, seq_length, 84, 84], name="inputs")
targets = tf.placeholder(tf.float32, shape=[None, seq_length], name="targets")

num_lstm_layers = 2

with tf.variable_scope("LSTM") as scope:

    lstm_cell  = tf.nn.rnn_cell.LSTMCell(512, initializer=initializer, state_is_tuple=True)
    self.lstm  = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * num_lstm_layers, state_is_tuple=True)

    init_c = # compute initial LSTM memory state using contents in placeholder 'inputs'
    init_h = # compute initial LSTM hidden state using contents in placeholder 'inputs'
    self.state = [tf.nn.rnn_cell.LSTMStateTuple(init_c, init_h)] * num_lstm_layers

    outputs = []

    for step in range(seq_length):

        if step != 0:
            scope.reuse_variables()

        # CNN features, as input for LSTM
        x_t = # ... 

        # LSTM step through time
        output, self.state = self.lstm(x_t, self.state)
        outputs.append(output)

【问题讨论】:

Tensorflow, best way to save state in RNNs?的可能重复 【参考方案1】:

我发现将所有图层的整个状态保存在占位符中是最简单的方法。

init_state = np.zeros((num_layers, 2, batch_size, state_size))

...

state_placeholder = tf.placeholder(tf.float32, [num_layers, 2, batch_size, state_size])

然后解压并创建一个 LSTMStateTuples 元组,然后再使用原生 tensorflow RNN Api。

l = tf.unpack(state_placeholder, axis=0)
rnn_tuple_state = tuple(
[tf.nn.rnn_cell.LSTMStateTuple(l[idx][0], l[idx][1])
 for idx in range(num_layers)]
)

RNN 传入 API:

cell = tf.nn.rnn_cell.LSTMCell(state_size, state_is_tuple=True)
cell = tf.nn.rnn_cell.MultiRNNCell([cell]*num_layers, state_is_tuple=True)
outputs, state = tf.nn.dynamic_rnn(cell, x_input_batch, initial_state=rnn_tuple_state)

state - 变量随后将作为占位符输入下一批。

【讨论】:

【参考方案2】:

Tensorflow,在 RNN 中保存状态的最佳方式?实际上是我最初的问题。下面的代码是我如何使用状态元组。

with tf.variable_scope('decoder') as scope:
    rnn_cell = tf.nn.rnn_cell.MultiRNNCell \
    ([
        tf.nn.rnn_cell.LSTMCell(512, num_proj = 256, state_is_tuple = True),
        tf.nn.rnn_cell.LSTMCell(512, num_proj = WORD_VEC_SIZE, state_is_tuple = True)
    ], state_is_tuple = True)

    state = [[tf.zeros((BATCH_SIZE, sz)) for sz in sz_outer] for sz_outer in rnn_cell.state_size]

    for t in range(TIME_STEPS):
        if t:
            last = y_[t - 1] if TRAINING else y[t - 1]
        else:
            last = tf.zeros((BATCH_SIZE, WORD_VEC_SIZE))

        y[t] = tf.concat(1, (y[t], last))
        y[t], state = rnn_cell(y[t], state)

        scope.reuse_variables()

我没有使用tf.nn.rnn_cell.LSTMStateTuple,而是创建了一个可以正常工作的列表。在这个例子中,我没有保存状态。但是,您可以轻松地从变量中创建状态并使用 assign 来保存值。

【讨论】:

以上是关于LSTM调用tensorflow提示 raise ValueError("Ambiguous dimension: %s" % value),怎么解决?的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow Serving - 有状态的 LSTM

TensorFlow学习(十三):构造LSTM超长简明教程

数值预测案例 LSTM 时间序列气温数据预测,附TensorFlow完整代码

Tensorflow——keras model.save() raise NotImplementedError

Tensorflow神经网络之LSTM

tensorflow 如何确定将选择哪些 LSTM 单元作为输出?