最近做一個(gè)關(guān)于用電負(fù)荷預(yù)測的項(xiàng)目,想用循環(huán)神經(jīng)網(wǎng)絡(luò)試一下,具有時(shí)間特性的數(shù)據(jù)預(yù)測當(dāng)然非LSTM莫屬了啦,但是感覺自己對(duì)LSTM的輸入和輸出不是很明白,就學(xué)習(xí)順便整理一下吧。
此處屬于我個(gè)人理解,可能有不正確的地方歡迎大家指正。
Cell
說到LSTM當(dāng)然先來一張cell的圖了:

圖中看起來是三個(gè)cell,其實(shí)是一個(gè)cell在不同時(shí)刻上的拼接,也就是說其實(shí)是一個(gè)cell在不同時(shí)刻的狀態(tài)。我們就以中間那個(gè)cell為例進(jìn)行說明吧。
其中,四個(gè)黃色的小矩形就是普通神經(jīng)網(wǎng)絡(luò)的隱藏層結(jié)構(gòu),其中第一、二和四的激活函數(shù)是
sigmoid,第三個(gè)的激活函數(shù)是tanh。t時(shí)刻的輸入X和t-1時(shí)刻的輸出h(t-1)進(jìn)行拼接,然后輸入cell中,其實(shí)可以這樣理解,我們的輸入X(t)分別feed進(jìn)了四個(gè)小黃矩形中,每個(gè)小黃矩形中進(jìn)行的運(yùn)算和正常的神經(jīng)網(wǎng)絡(luò)的計(jì)算一樣(矩陣乘法),有關(guān)記憶的部分完全由各種門結(jié)構(gòu)來控制(就是0和1),同時(shí)在輸入時(shí)不僅僅有原始的數(shù)據(jù)集,同時(shí)還加入了上一個(gè)數(shù)據(jù)的輸出結(jié)果,也就是h(t-1),那么講來LSTM和正常的神經(jīng)網(wǎng)絡(luò)類似,只是在輸入和輸出上加入了一點(diǎn)東西。cell中可以大體分為兩條橫線,上面的橫線用來控制長時(shí)記憶,下面的橫線用來控制短時(shí)記憶。關(guān)于LSTM我通過參考畫了一張圖,如下:
輸入和輸出
輸入
下面我們就來說說輸入問題,在Keras中,LSTM的輸入shape=(samples, time_steps, input_dim),其中samples表示樣本數(shù)量,time_steps表示時(shí)間步長,input_dim表示每一個(gè)時(shí)間步上的維度。我舉一個(gè)例子吧,現(xiàn)在有一個(gè)數(shù)據(jù)集有四個(gè)屬性(A,B, C, D),我們希望的預(yù)測標(biāo)簽式D,假設(shè)這里的樣本數(shù)量為N。如果時(shí)間步長為1,那么此時(shí)的輸入shape=(N, 1, 4),具體的數(shù)據(jù)是這樣的[A(t-1), B(t-1), C(t-1), D(t-1)](此處表示一個(gè)數(shù)據(jù)樣本),樣本標(biāo)簽為[D(t)];如果時(shí)間步長為2,那么此時(shí)的輸入shape=(N, 2, 4),具體的數(shù)據(jù)是[[A(t-2), B(t-2), C(t-2), D(t-2)], [A(t-1), B(t-1), C(t-1), D(t-1)]](此處仍表示一個(gè)樣本數(shù)據(jù))。輸出
關(guān)于Keras中LSTM的輸出問題,在搭建網(wǎng)絡(luò)時(shí)有兩個(gè)參數(shù),一個(gè)是output_dim表示輸出的維度,這個(gè)參數(shù)其實(shí)就是確定了四個(gè)小黃矩形中權(quán)重矩陣的大小。另一個(gè)可選參數(shù)return_sequence,這個(gè)參數(shù)表示LSTM返回的時(shí)一個(gè)時(shí)間序列還是最后一個(gè),也就是說當(dāng)return_sequence=True時(shí)返回的是(samples, time_steps, output_dim)的3D張量,如果return_sequence=Flase時(shí)返回的是(samples, output_dim)的2D張量。比如輸入shape=(N, 2, 8),同時(shí)output_dim=32,當(dāng)return_sequence=True時(shí)返回(N, 2, 32);當(dāng)return_sequence=False時(shí)返回(N, 32),這里表示的時(shí)輸出序列的最后一個(gè)輸出。
多層LSTM
使用LSTM搭建多層LSTM網(wǎng)絡(luò)還是比較方便的,我們只需要使用Sequential()進(jìn)行堆疊即可。
在進(jìn)行多層LSTM網(wǎng)絡(luò)時(shí),需要注意一下幾點(diǎn):
需要對(duì)第一層的LSTM指定
input_shape參數(shù)。將前N-1層LSTM的
return_sequence設(shè)置為True,保證每一曾都會(huì)想下一層傳播所有時(shí)間步長上的預(yù)測,同時(shí)保證最后一層的return_sequence為False(如果只需要最后一個(gè)輸出的話)。其實(shí),在第二層時(shí),不用指定
input_shape,因?yàn)楦鶕?jù)上一層的output_dim和當(dāng)前層的output_dim可以得出當(dāng)前層中權(quán)重矩陣的大小。
def build_model(lstm_layers, dense_layers):
model = Sequential()
model.add(LSTM(output_dim=32,
input_shape=(2, 3),
activation='relu',
return_sequences=True))
for i in range(lstm_layers - 1):
model.add(LSTM(output_dim=32 * (i+1),
activation='relu',
return_sequences=True))
for i in range(dense_layers - 1):
model.add(Dense(output_dim=256,
activation='relu'))
model.add(Dropout(0.5))
model.compile(loss='mae', optimizer='adam', metrics=['accuracy'])
model.summary()
return model
參數(shù)lstm_layers=5, dense_layers=3,結(jié)果如下:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm_1 (LSTM) (None, 2, 32) 4608
_________________________________________________________________
lstm_2 (LSTM) (None, 2, 32) 8320
_________________________________________________________________
lstm_3 (LSTM) (None, 2, 64) 24832
_________________________________________________________________
lstm_4 (LSTM) (None, 2, 96) 61824
_________________________________________________________________
lstm_5 (LSTM) (None, 2, 128) 115200
_________________________________________________________________
dense_1 (Dense) (None, 2, 256) 33024
_________________________________________________________________
dropout_1 (Dropout) (None, 2, 256) 0
_________________________________________________________________
dense_2 (Dense) (None, 2, 256) 65792
_________________________________________________________________
dropout_2 (Dropout) (None, 2, 256) 0
=================================================================
Total params: 313,600
Trainable params: 313,600
Non-trainable params: 0
_________________________________________________________________
參數(shù)量計(jì)算
前面提到了LSTM的計(jì)算其實(shí)和普通神經(jīng)網(wǎng)絡(luò)類似,那我們就來推一下參數(shù)量,看是否符合我們的預(yù)期。
1. 輸入的shape=(N, 2, 3)
2. 網(wǎng)絡(luò)結(jié)構(gòu):
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm_1 (LSTM) (None, 2, 4) 128
=================================================================
Total params: 128
Trainable params: 128
Non-trainable params: 0
_________________________________________________________________
3. 輸出的shape=(N, 2, 4)
- 首先cell的輸出為
[2, 4],也就是輸出的維度為4(其中2表示步長),輸入的數(shù)據(jù)為[2, 3],所以真正輸入cell中的數(shù)據(jù)維度應(yīng)該是[2, 7],也就是[2, 3+4](因?yàn)橐唇觮-1時(shí)刻的輸出和t時(shí)刻的輸入); - 接下來每個(gè)cell中有四個(gè)小黃矩形,也就是四次矩陣乘法,又因?yàn)檩敵龅木S度是
4,所以矩陣乘法就是[2, 7]*[7, 4]=[2, 4],所以一個(gè)小黃矩形所需的參數(shù)為7x4=28,四個(gè)也就是28x4=112; - 最后加上每一個(gè)小黃矩形后的激活函數(shù)的偏置
4x4=16。
最終,總共的參數(shù)值為112+16=128。和程序打印出來的結(jié)果一致。
通過上面的推導(dǎo)我們發(fā)現(xiàn),其實(shí)實(shí)際的參數(shù)量和步長是沒有關(guān)系的,這一點(diǎn)我也驗(yàn)證了一下,通過改變輸入shape=(samples, time_steps, input_dim)中的time_stpes的值,參數(shù)量不會(huì)發(fā)生變化。如下(輸入shape=[N, 2, 3],time_steps=10):
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm_1 (LSTM) (None, 10, 4) 128
=================================================================
Total params: 128
Trainable params: 128
Non-trainable params: 0
_________________________________________________________________