簡體   English   中英

用於多元時間序列的Keras遞歸神經網絡

[英]Keras Recurrent Neural Networks For Multivariate Time Series

我一直在閱讀有關Keras RNN模型(LSTM和GRU)的信息,作者似乎主要集中在語言數據或使用由先前時間步組成的訓練實例的單變量時間序列。 我的數據有些不同。

我有10個十年中每年測量的20個變量(作為輸入數據),為100,000個人,第11年中有20個變量(作為輸出數據)。 我想做的是預測第11年變量之一(而不是其他19個)的值。

我的數據結構為X.shape = [persons, years, variables] = [100000, 10, 20] Y.shape = [persons, variable] = [100000, 1] X.shape = [persons, years, variables] = [100000, 10, 20]Y.shape = [persons, variable] = [100000, 1] 以下是我的LSTM模型的Python代碼。

## LSTM model.

# Define model.

network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(128, activation = 'tanh', 
     input_shape = (X.shape[1], X.shape[2])))
network_lstm.add(layers.Dense(1, activation = None))

# Compile model.

network_lstm.compile(optimizer = 'adam', loss = 'mean_squared_error')

# Fit model.

history_lstm = network_lstm.fit(X, Y, epochs = 25, batch_size = 128)

我有四個(相關)問題,請:

  1. 我是否為我擁有的數據結構正確編碼了Keras模型? 我從完全連接的網絡(使用平坦的數據)以及LSTM,GRU和1D CNN模型獲得的性能幾乎相同,並且我不知道我是否在Keras中犯了錯誤,或者是否是循環模型簡單地在這種情況下沒有幫助。

  2. 我是否應該將Y作為形狀為Y.shape = [persons, years] = [100000, 11]的序列,而不是將變量包括在X中,則變量將具有形狀X.shape = [persons, years, variables] = [100000, 10, 19] 如果是這樣,如何獲取RNN以輸出預測的序列? 當我使用return_sequences = True ,Keras返回錯誤。

  3. 這是預測我擁有的數據的最佳方法嗎? Keras RNN模型甚至其他模型中是否有更好的選項選擇?

  4. 如何模擬類似於我現有數據結構的數據,以使RNN模型優於完全連接的網絡?

更新:

我已經嘗試了一個模擬,我希望這是一個非常簡單的情況,其中應該期望RNN優於FNN。

當LSTM的隱藏層較少時(4),其性能往往優於FNN,而隱藏層較多(8+)時,性能變得相同。 誰能想到一個更好的模擬,在這種模擬中,預期RNN會在數據結構相似的情況下勝過FNN?

from keras import models
from keras import layers

from keras.layers import Dense, LSTM

import numpy as np
import matplotlib.pyplot as plt

下面的代碼模擬10,000個實例,10個時間步和2個變量的數據。 如果第二個變量在第一個時間步中具有0,則Y是最后一個時間步的第一個變量的值乘以3。如果第二個變量在第一個時間步中具有1,則Y為最后一個時間步的第一個變量的值乘以9。

我希望RNN將第二個變量的值保留在內存中的第一個時間步,並使用該值知道哪個值(3或9)將最后一個時間步的第一個變量相乘。

## Simulate data.

instances = 10000

sequences = 10

X = np.zeros((instances, sequences * 2))

X[:int(instances / 2), 1] = 1

for i in range(instances):

    for j in range(0, sequences * 2, 2):

        X[i, j] = np.random.random()

Y = np.zeros((instances, 1))

for i in range(len(Y)):

    if X[i, 1] == 0:

        Y[i] = X[i, -2] * 3

    if X[i, 1] == 1:

        Y[i] = X[i, -2] * 9

以下是FNN的代碼:

## Densely connected model.

# Define model.

network_dense = models.Sequential()
network_dense.add(layers.Dense(4, activation = 'relu', 
     input_shape = (X.shape[1],)))
network_dense.add(Dense(1, activation = None))

# Compile model.

network_dense.compile(optimizer = 'rmsprop', loss = 'mean_absolute_error')

# Fit model.

history_dense = network_dense.fit(X, Y, epochs = 100, batch_size = 256, verbose = False)

plt.scatter(Y[X[:, 1] == 0, :], network_dense.predict(X[X[:, 1] == 0, :]), alpha = 0.1)
plt.plot([0, 3], [0, 3], color = 'black', linewidth = 2)
plt.title('FNN, Second Variable has a 0 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')

plt.show()

plt.scatter(Y[X[:, 1] == 1, :], network_dense.predict(X[X[:, 1] == 1, :]), alpha = 0.1)
plt.plot([0, 9], [0, 9], color = 'black', linewidth = 2)
plt.title('FNN, Second Variable has a 1 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')

plt.show()

以下是LSTM的代碼:

## Structure X data for LSTM.

X_lstm = X.reshape(X.shape[0], X.shape[1] // 2, 2)

X_lstm.shape

## LSTM model.

# Define model.

network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(4, activation = 'relu', 
     input_shape = (X_lstm.shape[1], 2)))
network_lstm.add(layers.Dense(1, activation = None))

# Compile model.

network_lstm.compile(optimizer = 'rmsprop', loss = 'mean_squared_error')

# Fit model.

history_lstm = network_lstm.fit(X_lstm, Y, epochs = 100, batch_size = 256, verbose = False)

plt.scatter(Y[X[:, 1] == 0, :], network_lstm.predict(X_lstm[X[:, 1] == 0, :]), alpha = 0.1)
plt.plot([0, 3], [0, 3], color = 'black', linewidth = 2)
plt.title('LSTM, FNN, Second Variable has a 0 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')

plt.show()

plt.scatter(Y[X[:, 1] == 1, :], network_lstm.predict(X_lstm[X[:, 1] == 1, :]), alpha = 0.1)
plt.plot([0, 9], [0, 9], color = 'black', linewidth = 2)
plt.title('LSTM, FNN, Second Variable has a 1 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')

plt.show()
  1. 是的,使用的代碼對您要執行的操作是正確的。 10年是用來預測下一年的時間窗口,因此應該是模型中20個變量中每個變量的輸入數量。 100,000個觀測值的樣本大小與模型的輸入形狀無關。

  2. 您最初塑造因變量Y的方式是正確的。 您正在預測1年的1個變量的窗口,並且您有100,000個觀測值。 關鍵字參數return_sequences=True將導致引發錯誤,因為您只有一個LSTM層。 如果要實現多個LSTM層,並且將所討論的層后跟另一個LSTM層,則將此參數設置為True

我希望可以為3提供一些指導,但實際上沒有您的數據集,我不知道是否可以肯定地回答這個問題。

我將說LSTM旨在解決常規RNN中存在的長期依賴問題。 這個問題歸結為,隨着觀察相關信息到該信息將變得有用之間的差距越來越大,標准RNN將很難學習它們之間的關系。 考慮基於活動的3天相對於全年預測股票價格。

這導致了第4個問題。如果我寬松地使用“相似”一詞並將您的時間范圍擴展到50年而不是10年,那么使用LSTM所獲得的優勢將變得更加明顯。 盡管我確信經驗豐富的人將能夠提供更好的答案,但我很期待看到它。

我發現此頁面有助於理解LSTM:

https://colah.github.io/posts/2015-08-Understanding-LSTMs/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM