6

我想为回归建立一个玩具LSTM模型。 This不错的教程对初学者来说已经太复杂了。TensorFlow dynamic_rnn regressor:ValueError尺寸不匹配

给定长度为time_steps的序列,预测下一个值。考虑time_steps=3和序列:

array([ 
    [[ 1.], 
    [ 2.], 
    [ 3.]], 

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

目标值应该是:

array([ 4., 5., ... 

我定义了以下模型:

# 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'] 

我们实例化LSTM模型pred = lstm_model(x, weights, biases)我得到以下:

---> 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输出产生回归?

+0

你能分享错误的完整堆栈跟踪吗?从错误消息看来,有些'tf.transpose()'op被应用于2-D张量,但维度排列(第二个参数)有三个值。我猜想它来自[此行](https://github.com/tensorflow/tensorflow/blob/dc7293fe0f8084af1f608a5f0d4e93acd9f597f6/tensorflow/python/ops/rnn.py#L488),问题是'tf.nn .dynamic_rnn()'期望所有的时间步长被打包在一个张量中。尝试删除'tf.split()'并将原始的'X'值传递给'tf.nn.dynamic_rnn()'。 – mrry

+0

@mrry我相信dynamic_rdd()的输入维度应该是(batch_size,time_steps,n_features)。因此,我不应该需要“预处理”步骤 – mastro

+0

正确。我认为这是一个糟糕的错误消息。您正在传递'time_steps'二维张量列表,但正确的输入将是一个单一的3D张量(并且第一个维度应该是'batch_size'而不是'time_steps',所以不需要转置其一)。 – mrry

回答

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()实施。原则上,输入至少有两个维度应该足够,但路径假定它们在将输入转换为时间主要形式时确实具有三个维度,并且错误消息是该错误无意中导致你的程序出现。我们正在努力解决这个问题。

+0

如果我没有在X上进行预处理并直接传递,然后抛出错误: ValueError:无值不受支持。 @ outputs,_,_ = tf.nn.bidirectional_dynamic_rnn(lstm_fw_cell_m,lstm_bw_cell_m,x,dtype = tf.float32) – neel