【技術筆記─ 時序資料的機器學習建模 Day3】

王柏鈞
7 min readMay 1, 2020

--

針對單變量時間序列使用Vanilla LSTM, Stacked LSTM, Bidirectional LSTM, CNN+LSTM的的模型架構與介紹

單變量的時間序列資料

首先單變量的時間序列不論因、果,都應該只有一個變數。而因為是時間序列,所以形式會如下所示:

X= [10, 20, 30], y = [40]

X裡面的3個元素不代表3個不同的變量,而是單一變量在不同時間步的數值。

Vanilla LSTM

首先我們會可以用一個最為單純的LSTM(Vanilla LSTM)來進行預測,視為BaseLine,或者也可以先用昨天提到的Zero-Rule Algorithm做一個BaseLine。

Note: 這是一個回歸(Regression)問題,所以Zero-Rule Algorithm可能會是取y的平均值或中位數進行預測。

Vanilla LSTM的架構如下所示:

# define model
model = Sequential()
model.add(LSTM(50, activation=’relu’, input_shape=(n_steps, n_features)))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)

要特別注意的是Input-shape

假設你是使用Keras來搭建LSTM Layer,其預設的Input-shape應該要是

[Batch-size, TimeSteps, Features]

這邊需要確定時間序列的產生是否符合規範。

但最單純的LSTM也許效果不夠好,這時候我們可以考慮採用Stacked LSTM。

Stacked LSTM

Stack LSTM是把兩個LSTM的模型連續的串接在一起。

需要注意,我們必須把第一層LSTM Layer的return_sequence參數設成True,因為LSTM預設的輸入會是3維,包含batch_size, timesteps, features,但預設的LSTM輸出是最後一個TimeStep的時間序列,所以會變成

[batch_size, units]這樣的輸出,units表示LSTM Layer中的神經元數量。

而如果有把return_sequence設成True,輸出會是n個2維的陣列(n = TimeSteps),這滿足了LSTM對於3維輸入的需求。

Stacked LSTM的優點

儘管沒有明確的理論表示Stacked的優勢,但根據經驗,他有幾個優點:

  1. 能夠對輸入的時間序列資料產生更複雜的特徵表示
  2. 由於LSTM不論是否Stacked,最後一層LSTM的輸出總是一個序列的常數項,這表示在這個過程是在壓縮一個序列,而我們相信透過Stacked LSTM可以更好的對序列進行壓縮

Stacked LSTM的架構如下所示

# define model
model = Sequential()
model.add(LSTM(50, activation=’relu’, return_sequences=True, input_shape=(n_steps, n_features)))
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)

Bidirectional LSTM(雙向LSTM)

他可以讓時間序列同時以順向和反向的方式輸入LSTM Layer並進行訓練。

他是否具有優勢需視問題而定,但我們可以討論他應該產生的效果:

不只是理解從過去的資料如何產生現在的資料,同時也會分析未來的資料如何對應到過去的資料。

這在翻譯或文本問題上是很需要的功能,事實上,他在image caption, future prediction, language translation等等的問題上都已被證明比單純的Vanilla LSTM或Stacked LSTM有更好的效果。

Bidirectional LSTM的模型架構如下所示

# define model
model = Sequential()
model.add(Bidirectional(LSTM(50, activation=’relu’), input_shape=(n_steps, n_features)))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)

CNN LSTM

CNN與LSTM的結合是一種很有效率的模型架構。

CNN可以有效地在一維序列上萃取特徵,例如在單變量時間序列的資料上,也就是從每個時間步中分別進行特徵萃取,並找出跨時間步的特徵。

LSTM可以學習不同時間步之間的資料相關性,並可以視為將資料時間序列的資料跨時間步的壓縮成一個低維表示。

為了讓CNN能夠讀取時間序列資料,我們需要使用TimeDistributed封裝器來讓每個時間步的資料可以被卷積層處理。

但由於TimeDistributed的輸入需要加上一個TimeStep的參數,表示有幾個TimeSteps,而CNN預設的輸入是3維的,所以要先把原始的時間序列資料轉換成如下格式:

[samples, subsequences, timesteps, features]

每一個sample就是每一個Timestep的輸入資料,會一個一個Timestep輸入CNNLayer中。

一個簡單的Timedistributed CNN+LSTM的架構如下所示:

# define model
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’), input_shape=(None, n_steps, n_features)))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)

參考

--

--

No responses yet