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