本分享為腦機學習者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結構。隨着研究人員對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
更多分享,請關注公眾號

