利用LSTM(長短期記憶網絡)來處理腦電數據

本分享爲腦機學習者Rose整理髮表於公衆號:腦機接口社區(微信號:Brain_Computer).QQ交流羣:903290195

Rose小哥今天介紹一下用LSTM來處理腦電數據。

LSTM 原理介紹

LSTMs(Long Short Term Memory networks,長短期記憶網絡)簡稱LSTMs,很多地方用LSTM來指代它。本文也使用LSTM來表示長短期記憶網絡。LSTM是一種特殊的RNN網絡(循環神經網絡)。想要說清楚LSTM,就很有必要先介紹一下RNN。下面我將簡略介紹一下RNN原理。

所有循環神經網絡都具有神經網絡的重複模塊鏈的形式。在標準的RNN中,該重複模塊將具有非常簡單的結構,比如單個tanh層。標準的RNN網絡如下圖所示:
在這裏插入圖片描述
LSTM也具有這種鏈式結構,不過它的重複單元與標準RNN網絡裏的單元只有一個網絡層不同,它的內部有四個網絡層。LSTM的結構如下圖所示。
在這裏插入圖片描述
在解釋LSTM的詳細結構時先定義一下圖中各個符號的含義,符號包括下面幾種,圖中黃色類似於CNN裏的激活函數操作,粉色圓圈表示點操作,單箭頭表示數據流向,箭頭合併表示向量的合併(concat)操作,箭頭分叉表示向量的拷貝操作。
在這裏插入圖片描述

LSTM的核心思想

LSTM的核心是細胞狀態,用貫穿細胞的水平線表示。
細胞狀態像傳送帶一樣。它貫穿整個細胞卻只有很少的分支,這樣能保證信息不變的流過整個RNNs。細胞狀態如下圖所示。
在這裏插入圖片描述
LSTM網絡能通過一種被稱爲門的結構對細胞狀態進行刪除或者添加信息。
門能夠有選擇性的決定讓哪些信息通過。

而門的結構很簡單,就是一個sigmoid層和一個點乘操作的組合。如下圖所示
在這裏插入圖片描述
因爲sigmoid層的輸出是0-1的值,這代表有多少信息能夠流過sigmoid層。0表示都不能通過,1表示都能通過。
一個LSTM裏面包含三個門來控制細胞狀態。

一步一步理解LSTM

前面提到LSTM由三個門來控制細胞狀態,這三個門分別稱爲忘記門、輸入門和輸出門。下面將分別講述。

LSTM的第一步就是決定細胞狀態需要丟棄哪些信息。這部分操作是通過一個稱爲忘記門的sigmoid單元來處理的。它通過查看ht1h_{t-1}xtx_t信息來輸出一個0-1之間的向量,該向量裏面的0-1值表示細胞狀態Ct1C_{t-1}中的哪些信息保留或丟棄多少。
其中0表示不保留,1表示都保留。忘記門如下圖所示。
在這裏插入圖片描述
這一步是決定給細胞狀態添加哪些新的信息。
該步又分爲兩個步驟,首先,利用ht1h_{t-1}xtx_t通過一個稱爲輸入門的操作來決定更新哪些信息。然後利用ht1h_{t-1}xtx_t通過一個tanh層得到新的候選細胞信息C~t\tilde C_{t},這些信息可能會被更新到細胞信息中。這兩步描述如下圖所示。
在這裏插入圖片描述
下面將更新舊的細胞信息Ct1C_{t-1},變爲新的細胞信息CtC_{t}
更新的規則就是通過忘記門選擇忘記舊細胞信息的一部分,通過輸入門選擇添加候選細胞信息C~t\tilde C_{t}的一部分得到新的細胞信息CtC_{t}。更新操作如下圖所示。
在這裏插入圖片描述

更新完細胞狀態後需要根據輸入的ht1h_{t-1}xtx_t來判斷輸出細胞的哪些狀態特徵,這裏需要將輸入經過一個稱爲輸出門的sigmoid層得到判斷條件,然後將細胞狀態經過tanh層得到一個-1~1之間值的向量,該向量與輸出門得到的判斷條件相乘就得到了最終該RNN單元的輸出。該步驟如下圖所示。
在這裏插入圖片描述

代碼案例

上面描述的是最普通的LSTM結構。隨着研究人員對LSTM的研究,在實際的文章中提出了很多LSTM結構的各種變式,這裏就不討論了。

下面將從代碼的角度來看一下LSTM對腦電數據進行分類效果。

數據集來源於BCI Competition II。使用的深度學習框架爲Keras。

# 導入工具包
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.layers import Embedding
from keras.layers import SimpleRNN, LSTM, GRU
from keras.optimizers import SGD, Nadam, Adam, RMSprop
from keras.callbacks import TensorBoard
from keras.utils import np_utils
import scipy.io 
import numpy as np

第一步:導入數據

data = scipy.io.loadmat('F:\BCI Competition II\sp1s_aa_1000Hz.mat')
y_test = np.loadtxt('F:\BCI Competition II\labels_data_set_iv.txt',encoding="utf-8")

第二步:預處理數據

"""
將訓練數據調整爲LSTM的正確輸入尺寸
並將數據轉換爲float 32
"""
x_train = data['x_train'].reshape((316,500,28))
x_train /= 200
x_train = x_train.astype('float32')
"""
將測試數據調整爲LSTM的正確輸入尺寸
並將數據轉換爲float 32
"""
x_test = data['x_test'].reshape((100,500,28))
x_test /= 200
x_test = x_test.astype('float32')

"""
將標籤數據調整爲LSTM的正確輸入尺寸
並將數據轉換爲float 32
"""
y_train = data['y_train'].reshape(316,1)
tmp_train = []
for i in y_train:
    if i == 1:
        tmp_train.append(1)
    elif i == 0:
        tmp_train.append(-1)
y_train = np.array(tmp_train)
y_train = np_utils.to_categorical(y_train, 2)
y_train = y_train.astype('float32')

y_test = y_test.reshape(100,1)
tmp_test = []
for i in y_test:
    if i == 1:
        tmp_test.append(1)
    elif i == 0:
        tmp_test.append(-1)       
y_test = np.array(tmp_test)
y_test = np_utils.to_categorical(y_test, 2)
y_test = y_test.astype('float32')

第三步:構建訓練模型

model = Sequential()
model.add(LSTM(10, return_sequences = True, input_shape=(500, 28)))
model.add(LSTM(10, return_sequences = True))
model.add(LSTM(5))
model.add(Dense(2, activation = 'softmax'))

model.summary()

"""
優化器設置
學習率爲0.001
"""
optim = Nadam(lr = 0.001)
# 設置損失函數爲交叉熵損失函數
model.compile(loss = 'categorical_crossentropy', optimizer = optim, metrics = ['accuracy'])

第四步:訓練模型

"""
epochs設置爲10
batch_size設置爲20
"""
model.fit(x_train, y_train, epochs=15, batch_size=20)  

第五步:計算最後得分和精度

score, acc = model.evaluate(x_test, y_test,
                            batch_size=1)
print('測試得分:', score)
print('測試精度:', acc)

在這裏插入圖片描述
在這裏插入圖片描述

參考:
利用LSTM(長短期記憶網絡)來處理腦電數據
1.https://www.jianshu.com/p/95d5c461924c
2.http://colah.github.io/posts/2015-08-Understanding-LSTMs/
3.https://github.com/kevinchangwang

本文章由腦機學習者Rose筆記分享,QQ交流羣:903290195
更多分享,請關注公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章