2017-04-05 106 views
4

請考慮這個簡單的例子keras狀態LSTM

nb_samples = 100000 
X = np.random.randn(nb_samples) 
Y = X[1:] 
X = X[:-1] 
X = X.reshape((len(Y), 1, 1)) 
Y = Y.reshape((len(Y), 1)) 

所以我們基本上

Y[i] = X[i-1] 

和模型只是一個滯後算。

我可以用無狀態的LSTM學習這個模型,但我想在這裏瞭解並應用Keras中的有狀態LSTM。

所以我試圖通過一個(batch_size = 1)

model = Sequential() 
model.add(LSTM(batch_input_shape=(1, 1, 1), 
       output_dim =10, 
       activation='tanh', stateful=True 
     ) 
    ) 
model.add(Dense(output_dim=1, activation='linear')) 
model.compile(loss='mse', optimizer='adam') 


for epoch in range(50): 
    model.fit(X_train, 
       Y_train, 
       nb_epoch = 1, 
       verbose = 2, 
       batch_size = 1, 
       shuffle = False) 
    model.reset_states() 

學習這種模式有狀態LSTM,通過給對值(x, y)之一,但該模型沒有學到什麼東西。

按馬辛建議,我修改了訓練代碼如下:

for epoch in range(10000): 
    model.reset_states() 
    train_loss = 0 
    for i in range(Y_train.shape[0]): 
     train_loss += model.train_on_batch(X_train[i:i+1], 
         Y_train[i:i+1], 
         ) 
    print '# epoch', epoch, ' loss ', train_loss/float(Y_train.shape[0]) 

,但我仍然看到周圍1的平均損失,這是我的隨機生成數據的標準差,因此模型做似乎沒有學習。

我有什麼問題嗎?

+1

你試過增加單位數嗎?你希望你的網絡能夠完全隨機地記憶長度爲10000的模式 - 所以實際上它應該作爲一個序列被完全記憶。這10個單位可能根本不夠用。您也可以減少序列長度或嘗試檢查一些連續函數(如'sin'或polynomial)。在這個時刻,你的架構似乎對你的任務來說很簡單。 –

+0

@volatile LSTM經常學習運行平均值。 randn的運行平均值爲0.如果這是你的輸出,那麼學習實際上是成功的。嘗試學習有意義的東西 – nemo

+0

@nemo:謝謝你的回答。我不是在學習一個長度爲10000的隨機模式,而是一個模式,其中t的輸出應該是t-1的輸入。我希望網絡將學會簡單地將輸入x [t]置於其隱藏狀態,然後在t + 1將隱藏狀態返回爲輸出y [t + 1],並將隱藏狀態替換爲x [ t + 1],並且以遞歸方式進行。顯然,我可以通過使用帶有移動窗口的無狀態LSTM來實現此目的,但希望將結果與有狀態的結果一起使用。 – volatile

回答

1

即使您的模型狀態由於網絡的狀態性而未被重置 - 您的優化器的參數是 - 並且由於優化器在遞歸神經網絡訓練中非常重要 - 您可能會讀取here - 重置其狀態可能會對您的訓練造成極大的傷害。爲了防止嘗試:

for epoch in range(50): 
    model.train_on_batch(X_train, 
       Y_train) 
    model.reset_states() 

一個train_on_batch方法不會重置您的優化狀態有什麼可以讓你的訓練可能。

+0

謝謝。我嘗試過,但似乎沒有工作。我更新了我的問題,告訴我正在做什麼 – volatile