TensorFlow dynamic_rnn 回归器:ValueError 维度不匹配。

6
我希望您能够为回归构建一个玩具LSTM模型。这篇优秀的教程对于初学者来说已经太复杂了。
给定长度为time_steps的序列,预测下一个值。考虑time_steps=3和以下序列:
array([
   [[  1.],
    [  2.],
    [  3.]],

   [[  2.],
    [  3.],
    [  4.]],
    ...

目标值应该是:
array([  4.,   5., ...

I define the following model:

# Network Parameters
time_steps = 3 
num_neurons= 64 #(arbitrary)
n_features = 1

# tf Graph input
x = tf.placeholder("float", [None, time_steps, n_features])
y = tf.placeholder("float", [None, 1])

# Define weights
weights = {
   'out': tf.Variable(tf.random_normal([n_hidden, 1]))
} 
biases = {
   'out': tf.Variable(tf.random_normal([1]))
}

#LSTM model
def lstm_model(X, weights, biases, learning_rate=0.01, optimizer='Adagrad'):

  # Prepare data shape to match `rnn` function requirements
  # Current data input shape: (batch_size, time_steps, n_features)
  # Required shape: 'time_steps' tensors list of shape (batch_size, n_features)
  # Permuting batch_size and time_steps
  input dimension: Tensor("Placeholder_:0", shape=(?, 3, 1), dtype=float32)

  X = tf.transpose(X, [1, 0, 2])
  transposed dimension: Tensor("transpose_41:0", shape=(3, ?, 1), dtype=float32)

  # Reshaping to (time_steps*batch_size, n_features)
  X = tf.reshape(X, [-1, n_features])
  reshaped dimension: Tensor("Reshape_:0", shape=(?, 1), dtype=float32)

  # Split to get a list of 'time_steps' tensors of shape (batch_size, n_features)
  X = tf.split(0, time_steps, X)
  splitted dimension: [<tf.Tensor 'split_:0' shape=(?, 1) dtype=float32>, <tf.Tensor 'split_:1' shape=(?, 1) dtype=float32>, <tf.Tensor 'split_:2' shape=(?, 1) dtype=float32>]

  # LSTM cell
  cell = tf.nn.rnn_cell.LSTMCell(num_neurons) #Or GRUCell(num_neurons)

  output, state = tf.nn.dynamic_rnn(cell=cell, inputs=X, dtype=tf.float32)

  output = tf.transpose(output, [1, 0, 2])
  last = tf.gather(output, int(output.get_shape()[0]) - 1)


  return tf.matmul(last, weights['out']) + biases['out']

我们使用pred = lstm_model(x, weights, biases)来实例化LSTM模型,得到以下结果:
---> output, state = tf.nn.dynamic_rnn(cell=cell, inputs=X, dtype=tf.float32)
ValueError: Dimension must be 2 but is 3 for 'transpose_42' (op: 'Transpose') with input shapes: [?,1], [3]

1) 你知道问题是什么吗?

2) 把LSTM输出乘以权重会得到回归结果吗?


你能分享一下错误的完整堆栈跟踪吗?从错误信息来看,似乎对一个二维张量应用了一些 tf.transpose() 操作,但是维度置换(第二个参数)有三个值。我猜它来自于这一行,问题在于 tf.nn.dynamic_rnn() 期望所有时间步都被打包到单个张量中。尝试删除 tf.split() 并将原始的 X 值传递给 tf.nn.dynamic_rnn() - mrry
@mrry我相信dynamic_rdd()的输入维度应该是(batch_size,time_steps,n_features)。因此,在那里执行“预处理”步骤是没有必要的。 - mastro
好的,我认为这是一个糟糕的错误信息。您正在传递一个 time_steps 二维张量列表,但正确的输入应该是单个三维张量(而第一维应该是 batch_size 而不是 time_steps,因此转置也不必要)。 - mrry
@mrry 在这种情况下,weights['out'] 只是一个标量,我理解的对吗? - mastro
我原以为它会是一个 n_output x target_features 的矩阵,但我想这可能是一个 1x1 的矩阵,并且相当于使用标量进行 tf.multiply() 运算,对吗? - mrry
显示剩余5条评论
1个回答

8
如评论中所讨论的那样,tf.nn.dynamic_rnn(cell, inputs, ...)函数期望将三维张量列表作为其inputs参数,其中默认情况下这些维度被解释为batch_size x num_timesteps x num_features。(如果传递time_major=True,则它们被解释为num_timesteps x batch_size x num_features。)因此,您在原始占位符中进行的预处理是不必要的,您可以直接将原始的X值传递给tf.nn.dynamic_rnn()
* 从技术上讲,除了列表之外,它还可以接受复杂的嵌套结构,但叶元素必须是三维张量。** ** 调查发现了tf.nn.dynamic_rnn()实现中的一个错误。原则上,输入至少应具有两个维度,但当它将输入转置为时间主导形式时,time_major=False路径假定它们恰好具有三个维度,并且正是由于这个错误而导致的错误消息出现在您的程序中。我们正在努力解决这个问题。

如果我不对X进行预处理并直接传递它,则会抛出错误: ValueError: 不支持None值。 @ outputs, = tf.nn.bidirectional_dynamic_rnn(lstm_fw_cell_m,lstm_bw_cell_m,x,dtype = tf.float32) - neel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接